IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jul 20, 2010, 7:21:53 PM (16 years ago)
Author:
eugene
Message:

update PCM fitting (not quite ready)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20100621/psModules/src/objects/pmPCMdata.c

    r28687 r28692  
    1 static void pmPCMDataFree (pmPCMData *pcm) {
     1/* @file  pmPCMdata.c
     2 * structures and functions to support PSF-convolved model fitting
     3 *
     4 * @author EAM, IfA
     5 *
     6 * @version $Revision: 1.29 $
     7 * @date $Date: 2009-02-16 22:30:50 $
     8 * Copyright 2010 Institute for Astronomy, University of Hawaii
     9 */
     10
     11#ifdef HAVE_CONFIG_H
     12#include <config.h>
     13#endif
     14
     15#include <stdio.h>
     16#include <math.h>
     17#include <string.h>
     18#include <strings.h>
     19#include <pslib.h>
     20#include "pmHDU.h"
     21#include "pmFPA.h"
     22#include "pmFPAMaskWeight.h"
     23
     24#include "pmTrend2D.h"
     25#include "pmResiduals.h"
     26#include "pmGrowthCurve.h"
     27#include "pmSpan.h"
     28#include "pmFootprintSpans.h"
     29#include "pmFootprint.h"
     30#include "pmPeaks.h"
     31#include "pmMoments.h"
     32#include "pmModelFuncs.h"
     33#include "pmModel.h"
     34#include "pmModelUtils.h"
     35#include "pmModelClass.h"
     36#include "pmSourceMasks.h"
     37#include "pmSourceExtendedPars.h"
     38#include "pmSourceDiffStats.h"
     39#include "pmSource.h"
     40#include "pmSourceFitModel.h"
     41#include "pmPCMdata.h"
     42
     43static void pmPCMdataFree (pmPCMdata *pcm) {
    244
    345    if (pcm == NULL) return;
    446
    5     psFree (pcm->model);
     47    psFree (pcm->modelFlux);
     48    psFree (pcm->modelConvFlux);
     49    psFree (pcm->dmodelsFlux);
     50    psFree (pcm->dmodelsConvFlux);
     51
    652    psFree (pcm->modelConv);
    7     psFree (pcm->dmodels);
    8     psFree (pcm->dmodelsConv);
     53    psFree (pcm->psf);
     54    psFree (pcm->constraint);
    955    return;
    1056}
    1157
    12 pmPCMData *pmPCMDataAlloc (
     58pmPCMdata *pmPCMdataAlloc (
    1359    const psVector *params,
    1460    const psVector *paramMask,
    1561    pmSource *source) {
    1662
    17     pmPCMData *pcm = (pmPCMData *) psAlloc(sizeof(pmPCMData));
    18     psMemSetDeallocator(pcm, (psFreeFunc) pmPCMDataFree);
     63    pmPCMdata *pcm = (pmPCMdata *) psAlloc(sizeof(pmPCMdata));
     64    psMemSetDeallocator(pcm, (psFreeFunc) pmPCMdataFree);
    1965
    2066    // Allocate storage images for raw model and derivative images
    21     pcm->model = psImageCopy (NULL, source->pixels, PS_TYPE_F32);
    22     pcm->dmodels = psArrayAlloc (params->n);
     67    pcm->modelFlux = psImageCopy (NULL, source->pixels, PS_TYPE_F32);
     68    pcm->dmodelsFlux = psArrayAlloc (params->n);
    2369    for (psS32 n = 0; n < params->n; n++) {
    24         pcm->dmodels->data[n] = NULL;
     70        pcm->dmodelsFlux->data[n] = NULL;
    2571        if ((paramMask != NULL) && (paramMask->data.PS_TYPE_VECTOR_MASK_DATA[n])) { continue; }
    26         pcm->dmodels->data[n] = psImageCopy (NULL, source->pixels, PS_TYPE_F32);
     72        pcm->dmodelsFlux->data[n] = psImageCopy (NULL, source->pixels, PS_TYPE_F32);
    2773    }
    2874
    2975    // Allocate storage images for convolved model and derivative images
    30     pcm->modelConv = psImageCopy (NULL, source->pixels, PS_TYPE_F32);
    31     pcm->dmodelsConv = psArrayAlloc (params->n);
     76    pcm->modelConvFlux = psImageCopy (NULL, source->pixels, PS_TYPE_F32);
     77    pcm->dmodelsConvFlux = psArrayAlloc (params->n);
    3278    for (psS32 n = 0; n < params->n; n++) {
    33         pcm->dmodelsConv->data[n] = NULL;
     79        pcm->dmodelsConvFlux->data[n] = NULL;
    3480        if ((paramMask != NULL) && (paramMask->data.PS_TYPE_VECTOR_MASK_DATA[n])) { continue; }
    35         pcm->dmodelsConv->data[n] = psImageCopy (NULL, source->pixels, PS_TYPE_F32);
    36     }
     81        pcm->dmodelsConvFlux->data[n] = psImageCopy (NULL, source->pixels, PS_TYPE_F32);
     82    }
     83
     84    pcm->modelConv = NULL;
     85    pcm->psf = NULL;
     86    pcm->constraint = NULL;
     87    pcm->nDOF = 0;
    3788
    3889    return pcm;
    3990}
    4091
    41 psImage *pmPCMDataSaveImage (pmPCMData *pcm) {
    42 
    43     psImage *model = psImageCopy (NULL, pcm->modelConv, PS_TYPE_F32);
     92psImage *pmPCMdataSaveImage (pmPCMdata *pcm) {
     93
     94    psImage *model = psImageCopy (NULL, pcm->modelConvFlux, PS_TYPE_F32);
    4495
    4596    return model;
    4697}
    4798
     99psKernel *pmPCMkernelFromPSF (pmSource *source, int nPix) {
     100
     101    assert (source);
     102    assert (source->psfImage); // XXX build if needed?
     103
     104    int x0 = source->peak->xf - source->psfImage->col0;
     105    int y0 = source->peak->yf - source->psfImage->row0;
     106
     107    // need to decide on the size: dynamically? statically?
     108    psKernel *psf = psKernelAlloc (-nPix, +nPix, -nPix, +nPix);
     109
     110    // XXX we should just re-construct a PSF at this location
     111    // psModelAdd (psf->image, NULL, source->modelPSF, PM_MODEL_OP_FULL | PM_MODEL_OP_NORM | PM_MODEL_OP_CENTER);
     112 
     113    // if the realized PSF for this object does not cover the full kernel, give up for now
     114    if (x0 + psf->xMin < 0) goto escape;
     115    if (x0 + psf->xMax >= source->psfImage->numCols) goto escape;
     116    if (y0 + psf->yMin < 0) goto escape;
     117    if (y0 + psf->yMax >= source->psfImage->numRows) goto escape;
     118
     119    double sum = 0.0;
     120    for (int j = psf->yMin; j <= psf->yMax; j++) {
     121        for (int i = psf->xMin; i <= psf->xMax; i++) {
     122            double value = source->psfImage->data.F32[y0 + j][x0 + i];
     123            psf->kernel[j][i] = value;
     124            sum += value;
     125        }
     126    }
     127    assert (sum > 0.0);
     128
     129    // psf must be normalized (integral = 1.0)
     130    for (int i = 0; i < psf->image->numRows; i++) {
     131        for (int j = 0; j < psf->image->numCols; j++) {
     132            psf->image->data.F32[i][j] /= sum;
     133        }
     134    }
     135
     136    return psf;
     137
     138escape:
     139    psFree (psf);
     140    return NULL;
     141}
     142
     143pmPCMdata *pmPCMinit(pmSource *source, pmSourceFitOptions *fitOptions, pmModelType modelType, psImageMaskType maskVal, float psfSize) {
     144
     145    // make sure we savep a cached copy of the psf flux
     146    pmSourceCachePSF (source, maskVal);
     147
     148    // convert the cached cached psf model for this source to a psKernel
     149    psKernel *psf = pmPCMkernelFromPSF (source, psfSize);
     150    if (!psf) return NULL;
     151
     152# if (USE_DELTA_PSF)
     153    psImageInit (psf->image, 0.0);
     154    psf->image->data.F32[(int)(0.5*psf->image->numRows)][(int)(0.5*psf->image->numCols)] = 1.0;
     155# endif
     156
     157    // allocate the model
     158    pmModel *modelConv = pmModelAlloc(modelType);
     159    if (!modelConv) {
     160        psFree (psf);
     161        return NULL;
     162    }
     163
     164    // count the number of unmasked pixels:
     165    int nPix = 0;
     166    for (psS32 i = 0; i < source->pixels->numRows; i++) {
     167        for (psS32 j = 0; j < source->pixels->numCols; j++) {
     168            // XXX are we doing the right thing with the mask?
     169            // skip masked points
     170            if (source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[i][j]) {
     171                continue;
     172            }
     173            // skip zero-variance points
     174            if (source->variance->data.F32[i][j] == 0) {
     175                continue;
     176            }
     177            // skip nan value points
     178            if (!isfinite(source->pixels->data.F32[i][j])) {
     179                continue;
     180            }
     181            nPix ++;
     182        }
     183    }   
     184
     185    psVector *params  = modelConv->params;
     186
     187    // create the minimization constraints
     188    psMinConstraint *constraint = psMinConstraintAlloc();
     189    constraint->paramMask = psVectorAlloc (params->n, PS_TYPE_VECTOR_MASK);
     190    constraint->checkLimits = modelConv->modelLimits;
     191
     192    // set parameter mask based on fitting mode
     193    int nParams = 0;
     194    switch (fitOptions->mode) {
     195      case PM_SOURCE_FIT_NORM:
     196        // NORM-only model fits only source normalization (Io)
     197        nParams = 1;
     198        psVectorInit (constraint->paramMask, 1);
     199        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
     200        break;
     201      case PM_SOURCE_FIT_PSF:
     202        // PSF model only fits x,y,Io
     203        nParams = 3;
     204        psVectorInit (constraint->paramMask, 1);
     205        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
     206        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_XPOS] = 0;
     207        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_YPOS] = 0;
     208        break;
     209      case PM_SOURCE_FIT_EXT:
     210        // EXT model fits all params (except sky)
     211        nParams = params->n - 1;
     212        psVectorInit (constraint->paramMask, 0);
     213        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1;
     214        break;
     215      case PM_SOURCE_FIT_INDEX:
     216        // PSF model only fits Io, index (PAR7) -- only Io for models with < 8 params
     217        psVectorInit (constraint->paramMask, 1);
     218        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
     219        if (params->n == 7) {
     220            nParams = 1;
     221        } else {
     222            nParams = 2;
     223            constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 0;
     224        }
     225        break;
     226      case PM_SOURCE_FIT_NO_INDEX:
     227        // PSF model only fits Io, index (PAR7) -- only Io for models with < 8 params
     228        psVectorInit (constraint->paramMask, 0);
     229        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1;
     230        if (params->n == 7) {
     231            nParams = params->n - 1;
     232        } else {
     233            nParams = params->n - 2;
     234            constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 1;
     235        }
     236        break;
     237      default:
     238        psAbort("invalid fitting mode");
     239    }
     240
     241    // generate PCM data storage structure
     242    pmPCMdata *pcm = pmPCMdataAlloc (params, constraint->paramMask, source);
     243
     244    pcm->modelConv = modelConv;
     245    pcm->psf = psf;
     246    pcm->constraint = constraint;
     247
     248    if (nPix <  nParams + 1) {
     249        psTrace ("psModules.objects", 4, "insufficient valid pixels\n");
     250        pcm->modelConv->flags |= PM_MODEL_STATUS_BADARGS;
     251        abort ();
     252        // XXX This should not be an abort!!
     253    }
     254    pcm->nPix = nPix;
     255    pcm->nDOF = nPix - nParams - 1;
     256
     257    return pcm;
     258}
Note: See TracChangeset for help on using the changeset viewer.