IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jul 17, 2014, 12:30:45 PM (12 years ago)
Author:
eugene
Message:

merge changes (from past YEAR) into trunk

Location:
branches/eam_branches/ipp-ops-20130712/psModules
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-ops-20130712/psModules

    • Property svn:mergeinfo deleted
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects

    • Property svn:ignore
      •  

        old new  
        1212pmSourceIO_CMF_PS1_V1.v1.c
        1313pmSourceIO_CMF_PS1_V4.c
         14pmSourceIO_CMF_PS1_V5.c
        1415pmSourceIO_CMF_PS1_SV1.c
        1516pmSourceIO_CMF_PS1_SV2.c
         17pmSourceIO_CMF_PS1_SV3.c
        1618pmSourceIO_CMF_PS1_DV1.c
        1719pmSourceIO_CMF_PS1_DV2.c
        1820pmSourceIO_CMF_PS1_DV3.c
        19 
         21pmSourceIO_CMF_PS1_DV4.c
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmPCMdata.c

    r35768 r37066  
    3131#include "pmMoments.h"
    3232#include "pmModelFuncs.h"
     33#include "pmModelClass.h"
    3334#include "pmModel.h"
    3435#include "pmModelUtils.h"
    35 #include "pmModelClass.h"
    3636#include "pmSourceMasks.h"
    3737#include "pmSourceExtendedPars.h"
    3838#include "pmSourceDiffStats.h"
    3939#include "pmSourceSatstar.h"
     40#include "pmSourceLensing.h"
    4041#include "pmSource.h"
    4142#include "pmSourceFitModel.h"
     
    4344
    4445# define USE_DELTA_PSF 0
    45 # define USE_1D_GAUSS 1
    4646
    4747static void pmPCMdataFree (pmPCMdata *pcm) {
     
    5858    psFree (pcm->psfFFT);
    5959    psFree (pcm->constraint);
     60
    6061    psFree (pcm->smdata); // pre-allocated data for psImageSmooth_PreAlloc
     62    psFree (pcm->smdata2d); // pre-allocated data for psImageSmooth_PreAlloc
    6163    return;
    6264}
     
    8890    }
    8991
     92    pcm->smdata = NULL;
     93    pcm->smdata2d = NULL;
     94
    9095    pcm->modelConv = NULL;
    9196    pcm->psf = NULL;
     
    9499    pcm->nDOF = 0;
    95100
     101    pcm->poissonErrors = true;
     102
    96103    // full convolution with the PSF is expensive.  if we have to save time, we can do a 1D
    97104    // convolution with a Gaussian approximation to the kernel
    98105    pcm->use1Dgauss = false;
    99     pcm->nsigma = 3.0;
     106    pcm->nsigma = NAN; // this is set to something defined by the user
    100107    pcm->sigma = 1.0; // this should be set to something sensible when the psf is known
    101108
     
    173180}
    174181
     182int pmPCMsetParams (psMinConstraint *constraint, pmSourceFitMode mode) {
     183
     184    // set parameter mask based on fitting mode
     185    int nParams = 0;
     186    int nParAll = constraint->paramMask->n;
     187
     188    switch (mode) {
     189      case PM_SOURCE_FIT_NORM:
     190        // fits only source normalization (Io)
     191        nParams = 1;
     192        psVectorInit (constraint->paramMask, 1);
     193        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
     194        break;
     195
     196      case PM_SOURCE_FIT_PSF:
     197        // fits only x,y,Io
     198        nParams = 3;
     199        psVectorInit (constraint->paramMask, 1);
     200        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
     201        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_XPOS] = 0;
     202        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_YPOS] = 0;
     203        break;
     204
     205      case PM_SOURCE_FIT_EXT:
     206        // fits all params except sky
     207        nParams = nParAll - 1;
     208        psVectorInit (constraint->paramMask, 0);
     209        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1;
     210        break;
     211
     212      case PM_SOURCE_FIT_EXT_AND_SKY:
     213        // fits all params including sky
     214        nParams = nParAll;
     215        psVectorInit (constraint->paramMask, 0);
     216        break;
     217
     218      case PM_SOURCE_FIT_SHAPE:
     219        // fits shape (Sxx, Sxy, Syy) and Io
     220        nParams = 5;
     221        psVectorInit (constraint->paramMask, 1);
     222        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 0;
     223        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
     224        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SXX] = 0;
     225        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SXY] = 0;
     226        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SYY] = 0;
     227        break;
     228
     229      case PM_SOURCE_FIT_INDEX:
     230        // fits only Io, index (PAR7) -- only Io for models with < 8 params
     231        psVectorInit (constraint->paramMask, 1);
     232        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
     233        if (nParAll == 7) {
     234            nParams = 1;
     235        } else {
     236            nParams = 2;
     237            constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 0;
     238        }
     239        break;
     240
     241      case PM_SOURCE_FIT_NO_INDEX:
     242        // fits all but index (PAR7) including sky
     243        psVectorInit (constraint->paramMask, 0);
     244        if (nParAll == 7) {
     245            nParams = nParAll;
     246        } else {
     247            nParams = nParAll - 1;
     248            constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 1;
     249        }
     250        break;
     251      default:
     252        psAbort("invalid fitting mode");
     253    }
     254    return nParams;
     255}
     256
     257static int modelType_GAUSS = -1;
     258static int modelType_PS1_V1 = -1;
     259
     260// generate a Gaussian smoothing kernel for supplied sigma.  sigma here does not need to match
     261// that used to allocate the structure, but it is recommended
     262bool psImageSmoothCacheKernel_PS1_V1 (psImageSmoothCacheData *smdata, float sigma, float kappa) {
     263    // check for NULL structure elements?
     264
     265    int size = smdata->Nrange;
     266
     267    psFree (smdata->kernel);
     268    smdata->kernel = psVectorAlloc(2 * smdata->Nrange + 1, PS_TYPE_F32);
     269
     270    double sum = 0.0;                   // Sum of Gaussian, for normalization
     271    double factor = 1.0 / (sigma * M_SQRT2);    // Multiplier for i -> z
     272
     273    // PS1_V1 is a power-law with fitted linear term:
     274    // 1 / (1 + kappa z + z^1.666)  where z = (r/sigma)^2
     275
     276    // generate the kernel (not normalized)
     277    for (int i = -size, j = 0; i <= size; i++, j++) {
     278        float z = PS_SQR(i * factor);
     279        sum += smdata->kernel->data.F32[j] = 1.0 / (1 + kappa * z + pow(z,1.666));
     280    }
     281
     282    // renormalize kernel to integral of 1.0
     283    for (int i = 0; i < 2 * size + 1; i++) {
     284        smdata->kernel->data.F32[i] /= sum;
     285    }
     286
     287    return true;
     288}
     289
     290psImageSmoothCacheData *psImageSmoothCacheSetKernel (float *sigma, float *kappa, float nsigma, psImage *flux, pmModel *modelPSF) {
     291
     292    psAssert (modelPSF, "psf model must be defined");
     293   
     294    psEllipseAxes axes;
     295    bool useReff = modelPSF->class->useReff;
     296    psF32 *PAR = modelPSF->params->data.F32;
     297    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], useReff);
     298   
     299    *sigma = NAN;
     300    *kappa = NAN;
     301
     302    // XXX need to do this more carefully
     303    if (modelPSF->type == modelType_GAUSS) {
     304        float FWHM_MAJOR = 2*modelPSF->class->modelRadius (modelPSF->params, 0.5*PAR[PM_PAR_I0]);
     305        float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major);
     306        *sigma = 0.50 * (FWHM_MAJOR + FWHM_MINOR) / 2.35;
     307    }
     308    if (modelPSF->type == modelType_PS1_V1) {
     309        *sigma = 0.5 * (axes.major + axes.minor);
     310        *kappa = PAR[PM_PAR_7];
     311    }
     312    psAssert (isfinite(*sigma), "invalid model type");
     313
     314    // psImageSmoothCacheAlloc generates a structure but does not assign the smoothing vector
     315    psImageSmoothCacheData *smdata = psImageSmoothCacheAlloc (flux, *sigma, nsigma);
     316
     317    if (modelPSF->type == modelType_GAUSS) {
     318        psImageSmoothCacheKernel_Gauss (smdata, *sigma);
     319    }
     320    if (modelPSF->type == modelType_PS1_V1) {
     321        psImageSmoothCacheKernel_PS1_V1 (smdata, *sigma, *kappa);
     322    }
     323
     324    return smdata;
     325}
     326
     327psImageSmooth2dCacheData *psImageSmooth2dCacheSetKernel (float *sigma, float *kappa, float nsigma, psImage *flux, pmModel *modelPSF) {
     328
     329    psAssert (modelPSF, "psf model must be defined");
     330   
     331    psEllipseAxes axes;
     332    bool useReff = modelPSF->class->useReff;
     333    psF32 *PAR = modelPSF->params->data.F32;
     334    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], useReff);
     335   
     336    *sigma = NAN;
     337    *kappa = NAN;
     338
     339    // XXX need to do this more carefully
     340    if (modelPSF->type == modelType_GAUSS) {
     341        float FWHM_MAJOR = 2*modelPSF->class->modelRadius (modelPSF->params, 0.5*PAR[PM_PAR_I0]);
     342        float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major);
     343        *sigma = 0.50 * (FWHM_MAJOR + FWHM_MINOR) / 2.35;
     344    }
     345    if (modelPSF->type == modelType_PS1_V1) {
     346        *sigma = 0.5 * (axes.major + axes.minor);
     347        *kappa = PAR[PM_PAR_7];
     348    }
     349    psAssert (isfinite(*sigma), "invalid model type");
     350
     351    // psImageSmoothCacheAlloc generates a structure but does not assign the smoothing vector
     352    psImageSmooth2dCacheData *smdata = psImageSmooth2dCacheAlloc (nsigma);
     353
     354    if (modelPSF->type == modelType_GAUSS) {
     355        psImageSmooth2dCacheKernel_Gauss (smdata, *sigma);
     356    }
     357    if (modelPSF->type == modelType_PS1_V1) {
     358        psImageSmooth2dCacheKernel_PS1_V1 (smdata, *sigma, *kappa);
     359    }
     360
     361    return smdata;
     362}
     363
    175364pmPCMdata *pmPCMinit(pmSource *source, pmSourceFitOptions *fitOptions, pmModel *model, psImageMaskType maskVal, float psfSize) {
    176365
    177     // make sure we save a cached copy of the psf flux
    178     pmSourceCachePSF (source, maskVal);
    179 
    180     // convert the cached cached psf model for this source to a psKernel
    181     psKernel *psf = pmPCMkernelFromPSF (source, psfSize);
    182     if (!psf) {
    183         // NOTE: this only happens if the source is too close to an edge
    184         model->flags |= PM_MODEL_STATUS_BADARGS;
    185         return NULL;
    186     }
    187 
    188 # if (USE_DELTA_PSF)
    189     psImageInit (psf->image, 0.0);
    190     psf->image->data.F32[(int)(0.5*psf->image->numRows)][(int)(0.5*psf->image->numCols)] = 1.0;
    191 # endif
     366    modelType_GAUSS = pmModelClassGetType ("PS_MODEL_GAUSS");
     367    modelType_PS1_V1 = pmModelClassGetType ("PS_MODEL_PS1_V1");
    192368
    193369    // count the number of unmasked pixels:
     
    217393    psMinConstraint *constraint = psMinConstraintAlloc();
    218394    constraint->paramMask = psVectorAlloc (params->n, PS_TYPE_VECTOR_MASK);
    219     constraint->checkLimits = model->modelLimits;
    220 
    221     // set parameter mask based on fitting mode
    222     int nParams = 0;
    223     switch (fitOptions->mode) {
    224       case PM_SOURCE_FIT_NORM:
    225         // NORM-only model fits only source normalization (Io)
    226         nParams = 1;
    227         psVectorInit (constraint->paramMask, 1);
    228         constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
    229         break;
    230       case PM_SOURCE_FIT_PSF:
    231         // PSF model only fits x,y,Io
    232         nParams = 3;
    233         psVectorInit (constraint->paramMask, 1);
    234         constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
    235         constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_XPOS] = 0;
    236         constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_YPOS] = 0;
    237         break;
    238       case PM_SOURCE_FIT_EXT:
    239         // EXT model fits all params (except sky)
    240         nParams = params->n - 1;
    241         psVectorInit (constraint->paramMask, 0);
    242         constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1;
    243         break;
    244       case PM_SOURCE_FIT_INDEX:
    245         // PSF model only fits Io, index (PAR7) -- only Io for models with < 8 params
    246         psVectorInit (constraint->paramMask, 1);
    247         constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
    248         if (params->n == 7) {
    249             nParams = 1;
    250         } else {
    251             nParams = 2;
    252             constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 0;
    253         }
    254         break;
    255       case PM_SOURCE_FIT_NO_INDEX:
    256         // PSF model only fits Io, index (PAR7) -- only Io for models with < 8 params
    257         psVectorInit (constraint->paramMask, 0);
    258         constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1;
    259         if (params->n == 7) {
    260             nParams = params->n - 1;
    261         } else {
    262             nParams = params->n - 2;
    263             constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 1;
    264         }
    265         break;
    266       default:
    267         psAbort("invalid fitting mode");
    268     }
     395    constraint->checkLimits = model->class->modelLimits;
     396
     397    int nParams = pmPCMsetParams (constraint, fitOptions->mode);
    269398
    270399    if (nPix <  nParams + 1) {
    271400        psTrace ("psModules.objects", 4, "insufficient valid pixels\n");
    272         psFree (psf);
    273401        psFree (constraint);
    274402        model->flags |= PM_MODEL_STATUS_BADARGS;
     
    278406    // generate PCM data storage structure
    279407    pmPCMdata *pcm = pmPCMdataAlloc (params, constraint->paramMask, source);
    280 
    281     pcm->psf = psf;
    282408    pcm->modelConv = psMemIncrRefCounter(model);
    283409    pcm->constraint = constraint;
     410
     411    pcm->poissonErrors = fitOptions->poissonErrors;
     412    pcm->nsigma = fitOptions->nsigma;
    284413
    285414    pcm->nPix = nPix;
     
    288417
    289418# if (USE_1D_GAUSS)
    290     pmModel *modelPSF = source->modelPSF;
    291     psAssert (modelPSF, "psf model must be defined");
    292    
    293     psEllipseAxes axes;
    294     bool useReff = pmModelUseReff (modelPSF->type);
    295     psF32 *PAR = modelPSF->params->data.F32;
    296     pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], useReff);
    297    
    298     float FWHM_MAJOR = 2*modelPSF->modelRadius (modelPSF->params, 0.5*PAR[PM_PAR_I0]);
    299     float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major);
    300419
    301420    pcm->use1Dgauss = true;
    302     pcm->sigma = 0.5 * (FWHM_MAJOR + FWHM_MINOR) / 2.35;
    303     pcm->nsigma = 2.0;
    304 
    305     pcm->smdata = psImageSmooth_PreAlloc_DataAlloc (source->pixels, pcm->sigma, pcm->nsigma);
     421    if (USE_1D_CACHE) {
     422        pcm->smdata = psImageSmoothCacheSetKernel (&pcm->sigma, &pcm->kappa, pcm->nsigma, source->pixels, source->modelPSF);
     423    } else {
     424        pcm->smdata2d = psImageSmooth2dCacheSetKernel (&pcm->sigma, &pcm->kappa, pcm->nsigma, source->pixels, source->modelPSF);
     425    }
     426
    306427# else
     428    // make sure we save a cached copy of the psf flux
     429    pmSourceCachePSF (source, maskVal);
     430
     431    // convert the cached cached psf model for this source to a psKernel
     432    psKernel *psf = pmPCMkernelFromPSF (source, psfSize);
     433    if (!psf) {
     434        // NOTE: this only happens if the source is too close to an edge
     435        model->flags |= PM_MODEL_STATUS_BADARGS;
     436        return NULL;
     437    }
     438
     439# if (USE_DELTA_PSF)
     440    psImageInit (psf->image, 0.0);
     441    psf->image->data.F32[(int)(0.5*psf->image->numRows)][(int)(0.5*psf->image->numCols)] = 1.0;
     442# endif
     443    pcm->psf = psf;
    307444    pcm->smdata = NULL;
    308445# endif
     
    341478    }
    342479
    343     // if we changed the fit mode, we need to update nDOF
    344     int nParams = 0;
    345     // set parameter mask based on fitting mode
    346     switch (fitOptions->mode) {
    347       case PM_SOURCE_FIT_NORM:
    348         // NORM-only model fits only source normalization (Io)
    349         nParams = 1;
    350         psVectorInit (pcm->constraint->paramMask, 1);
    351         pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
    352         break;
    353       case PM_SOURCE_FIT_PSF:
    354         // PSF model only fits x,y,Io
    355         nParams = 3;
    356         psVectorInit (pcm->constraint->paramMask, 1);
    357         pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
    358         pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_XPOS] = 0;
    359         pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_YPOS] = 0;
    360         break;
    361       case PM_SOURCE_FIT_EXT:
    362         // EXT model fits all params (except sky)
    363         nParams = model->params->n - 1;
    364         psVectorInit (pcm->constraint->paramMask, 0);
    365         pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1;
    366         break;
    367       case PM_SOURCE_FIT_INDEX:
    368         // PSF model only fits Io, index (PAR7) -- only Io for models with < 8 params
    369         psVectorInit (pcm->constraint->paramMask, 1);
    370         pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
    371         if (model->params->n == 7) {
    372             nParams = 1;
    373         } else {
    374             nParams = 2;
    375             pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 0;
    376         }
    377         break;
    378       case PM_SOURCE_FIT_NO_INDEX:
    379         // PSF model only fits Io, index (PAR7) -- only Io for models with < 8 params
    380         psVectorInit (pcm->constraint->paramMask, 0);
    381         pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1;
    382         if (model->params->n == 7) {
    383             nParams = model->params->n - 1;
    384         } else {
    385             nParams = model->params->n - 2;
    386             pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 1;
    387         }
    388         break;
    389       default:
    390         psAbort("invalid fitting mode");
    391     }
     480    int nParams = pmPCMsetParams (pcm->constraint, fitOptions->mode);
    392481
    393482    if (pcm->nPix <  nParams + 1) {
     
    415504            pcm->dmodelsConvFlux->data[n] = psImageCopy (pcm->dmodelsConvFlux->data[n], source->pixels, PS_TYPE_F32);
    416505        }
    417         psFree(pcm->smdata);
    418         pcm->smdata = psImageSmooth_PreAlloc_DataAlloc (source->pixels, pcm->sigma, pcm->nsigma);
     506
     507        // If we have changed the window, we need to redefine the smoothing target vectors (but pcm->sigma,kappa,nsigma remain)
     508        if (USE_1D_CACHE) {
     509            psFree(pcm->smdata);
     510            pcm->smdata = psImageSmoothCacheAlloc (source->pixels, pcm->sigma, pcm->nsigma);
     511
     512            pmModel *modelPSF = source->modelPSF;
     513            if (modelPSF->type == modelType_GAUSS) {
     514                psImageSmoothCacheKernel_Gauss (pcm->smdata, pcm->sigma);
     515            }
     516            if (modelPSF->type == modelType_PS1_V1) {
     517                psImageSmoothCacheKernel_PS1_V1 (pcm->smdata, pcm->sigma, pcm->kappa);
     518            }
     519        } else {
     520            psFree(pcm->smdata2d);
     521            pcm->smdata2d = psImageSmooth2dCacheAlloc (pcm->nsigma);
     522
     523            pmModel *modelPSF = source->modelPSF;
     524            if (modelPSF->type == modelType_GAUSS) {
     525                // psImageSmooth2dCacheKernel_Gauss (pcm->smdata2d, pcm->sigma);
     526            }
     527            if (modelPSF->type == modelType_PS1_V1) {
     528                psImageSmooth2dCacheKernel_PS1_V1 (pcm->smdata2d, pcm->sigma, pcm->kappa);
     529            }
     530        }
    419531    }
    420532
     
    423535
    424536// construct a realization of the source model
    425 bool pmPCMCacheModel (pmSource *source, psImageMaskType maskVal, int psfSize) {
     537bool pmPCMCacheModel (pmSource *source, psImageMaskType maskVal, int psfSize, float nsigma) {
    426538
    427539    PS_ASSERT_PTR_NON_NULL(source, false);
     
    440552    // convolve the model image with the PSF
    441553    if (USE_1D_GAUSS) {
    442         // do not use the threaded, mask-aware version of this code (psImageSmoothMaskPixelsThread):
    443         // * the model flux is not masked
    444         // * threading takes place above this level
    445554       
    446         // define the Gauss parameters from the psf
    447         pmModel *modelPSF = source->modelPSF;
    448         psAssert (modelPSF, "psf model must be defined");
    449    
    450         psEllipseAxes axes;
    451         bool useReff = pmModelUseReff (modelPSF->type);
    452         psF32 *PAR = modelPSF->params->data.F32;
    453         pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], useReff);
    454    
    455         float FWHM_MAJOR = 2*modelPSF->modelRadius (modelPSF->params, 0.5*PAR[PM_PAR_I0]);
    456         float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major);
    457 
    458         float sigma = 0.5 * (FWHM_MAJOR + FWHM_MINOR) / 2.35;
    459         float nsigma = 2.0;
    460 
    461         psImageSmooth (source->modelFlux, sigma, nsigma);
     555        float sigma = NAN;
     556        float kappa = NAN;
     557
     558        if (USE_1D_CACHE) {
     559            psImageSmoothCacheData *smdata = psImageSmoothCacheSetKernel (&sigma, &kappa, nsigma, source->modelFlux, source->modelPSF);
     560            psImageSmoothCache_F32 (source->modelFlux, smdata);
     561            psFree (smdata);
     562        } else {
     563            psImageSmooth2dCacheData *smdata = psImageSmooth2dCacheSetKernel (&sigma, &kappa, nsigma, source->modelFlux, source->modelPSF);
     564            psImageSmooth2dCache_F32 (source->modelFlux, smdata);
     565            psFree (smdata);
     566        }
     567        // old call: psImageSmooth (source->modelFlux, sigma, nsigma);
    462568    } else {
    463569        // make sure we save a cached copy of the psf flux
     
    478584}
    479585
     586// construct a realization of the source model
     587bool pmPCMMakeModel (pmSource *source, pmModel *model, float Nsigma, psImageMaskType maskVal, int psfSize) {
     588
     589    PS_ASSERT_PTR_NON_NULL(source, false);
     590
     591    // if we already have a cached image, re-use that memory
     592    source->modelFlux = psImageCopy (source->modelFlux, source->pixels, PS_TYPE_F32);
     593    psImageInit (source->modelFlux, 0.0);
     594
     595    // modelFlux always has unity normalization (I0 = 1.0)
     596    // pmModelAdd (source->modelFlux, source->maskObj, model, PM_MODEL_OP_FULL | PM_MODEL_OP_NORM, maskVal);
     597    pmModelAdd (source->modelFlux, NULL, model, PM_MODEL_OP_FULL | PM_MODEL_OP_SKY | PM_MODEL_OP_NORM, maskVal);
     598
     599    // convolve the model image with the PSF
     600    if (USE_1D_GAUSS) {
     601
     602        float sigma = NAN;
     603        float kappa = NAN;
     604
     605        if (USE_1D_CACHE) {
     606            psImageSmoothCacheData *smdata = psImageSmoothCacheSetKernel (&sigma, &kappa, Nsigma, source->modelFlux, source->modelPSF);
     607            psImageSmoothCache_F32 (source->modelFlux, smdata);
     608            psFree (smdata);
     609        } else {
     610            psImageSmooth2dCacheData *smdata = psImageSmooth2dCacheSetKernel (&sigma, &kappa, Nsigma, source->modelFlux, source->modelPSF);
     611            psImageSmooth2dCache_F32 (source->modelFlux, smdata);
     612            psFree (smdata);
     613        }
     614        // old call: psImageSmooth (source->modelFlux, sigma, nsigma);
     615    } else {
     616        // make sure we save a cached copy of the psf flux
     617        pmSourceCachePSF (source, maskVal);
     618
     619        // convert the cached cached psf model for this source to a psKernel
     620        psKernel *psf = pmPCMkernelFromPSF (source, psfSize);
     621        if (!psf) {
     622            // NOTE: this only happens if the source is too close to an edge
     623            model->flags |= PM_MODEL_STATUS_BADARGS;
     624            return NULL;
     625        }
     626
     627        // XXX not sure if I can place the output on top of the input
     628        psImageConvolveFFT (source->modelFlux, source->modelFlux, NULL, 0, psf);
     629    }
     630    return true;
     631}
Note: See TracChangeset for help on using the changeset viewer.