IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 35769 for trunk


Ignore:
Timestamp:
Jul 3, 2013, 2:43:13 PM (13 years ago)
Author:
eugene
Message:

thread psphotModelBackground, psphotAddOrSubNoise, psphotGuessModel; add recipe options to control selection of extended models fitted; iterate on the trail window a bit

Location:
trunk/psphot
Files:
21 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/psphot

  • trunk/psphot/src

  • trunk/psphot/src/models/pmModel_STRAIL.c

    r35559 r35769  
    563563    // convert to shape terms (SXX,SYY,SXY)
    564564    // XXX user-defined value for limit?
    565     if (!pmPSF_FitToModel (PAR, 0.1)) {
     565    bool useReff = pmModelUseReff (model->type);
     566    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    566567        psError(PM_ERR_PSF, false, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
    567568        return false;
  • trunk/psphot/src/models/pmModel_TEST1.c

    r35559 r35769  
    264264    // convert to shape terms (SXX,SYY,SXY)
    265265    // XXX user-defined value for limit?
    266     if (!pmPSF_FitToModel (PAR, 0.1)) {
     266    bool useReff = pmModelUseReff (model->type);
     267    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    267268        psError(PM_ERR_PSF, false, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
    268269        return false;
  • trunk/psphot/src/psphot.h

    r34542 r35769  
    6767bool            psphotModelBackground (pmConfig *config, const pmFPAview *view, const char *filerule);
    6868bool            psphotModelBackgroundReadoutFileIndex (pmConfig *config, const pmFPAview *view, const char *filerule, int index);
     69bool            psphotModelBackground_Threaded (psThreadJob *job);
    6970
    7071bool            psphotMaskBackground (pmConfig *config, const pmFPAview *view, const char *filerule);
     
    119120bool            psphotAddOrSubNoise (pmConfig *config, const pmFPAview *view, const char *filerule, bool add);
    120121bool            psphotAddOrSubNoiseReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, bool add);
     122bool            psphotAddOrSubNoise_Threaded (psThreadJob *job);
    121123
    122124bool            psphotExtendedSourceAnalysis (pmConfig *config, const pmFPAview *view, const char *filerule);
     
    232234bool            psphotFitBlob (pmReadout *readout, pmSource *source, psArray *sources, pmPSF *psf, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal);
    233235bool            psphotFitPSF (pmReadout *readout, pmSource *source, pmPSF *psf, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal);
    234 pmModel        *psphotFitEXT (pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, pmModelType modelType, psImageMaskType maskVal, psImageMaskType markVal);
     236pmModel        *psphotFitEXT (pmModel *guessModel, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, pmModelType modelType, psImageMaskType maskVal, psImageMaskType markVal);
    235237psArray        *psphotFitDBL (pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal);
    236238
     
    243245bool            psphotFitInit (int nThreads);
    244246bool            psphotFitSummary (void);
     247bool            psphotFitSummaryExtended (void);
     248bool            psphotFitInitExtended (void);
    245249
    246250bool            psphotLoadPSF (pmConfig *config, const pmFPAview *view, const char *filerule);
  • trunk/psphot/src/psphotAddNoise.c

    r34492 r35769  
    11# include "psphotInternal.h"
    22
     3bool psphotAddOrSubNoise_Threaded (psThreadJob *job);
    34bool psphotMaskSource(pmSource *source, bool add, psImageMaskType maskVal);
    45
     
    3233}
    3334
    34 static int Nmasked = 0;
    35 
    3635// the return state indicates if any sources were actually replaced
    3736bool psphotAddOrSubNoiseReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, bool add) {
    3837
    3938    bool status = false;
     39
     40    psTimerStart ("psphot.noise");
    4041
    4142    // find the currently selected readout
     
    5556    if (!sources) return false;
    5657
    57     psTimerStart ("psphot.noise");
     58    // determine the number of allowed threads
     59    int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads
     60    if (!status) {
     61        nThreads = 0;
     62    }
    5863
    5964    // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
     
    8489
    8590    psphotVisualShowImage (readout);
     91
     92    // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts)
     93    int Cx = 1, Cy = 1;
     94    psphotChooseCellSizes (&Cx, &Cy, readout, nThreads);
     95
     96    psArray *cellGroups = psphotAssignSources (Cx, Cy, sources);
     97
     98    for (int i = 0; i < cellGroups->n; i++) {
     99
     100        psArray *cells = cellGroups->data[i];
     101
     102        for (int j = 0; j < cells->n; j++) {
     103
     104            // allocate a job -- if threads are not defined, this just runs the job
     105            psThreadJob *job = psThreadJobAlloc ("PSPHOT_ADD_NOISE");
     106            psArrayAdd(job->args, 1, cells->data[j]); // sources
     107            PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_IMAGE_MASK);
     108            PS_ARRAY_ADD_SCALAR(job->args, markVal,  PS_TYPE_IMAGE_MASK);
     109            PS_ARRAY_ADD_SCALAR(job->args, FACTOR,   PS_TYPE_F32);
     110            PS_ARRAY_ADD_SCALAR(job->args, SIZE,     PS_TYPE_F32);
     111            PS_ARRAY_ADD_SCALAR(job->args, add,      PS_TYPE_U8);
     112
     113# if (1)
     114            if (!psThreadJobAddPending(job)) {
     115                psError(PS_ERR_UNKNOWN, false, "Unable to add/sub noise.");
     116                return false;
     117            }
     118# else
     119            if (!psphotAddOrSubNoise_Threaded(job)) {
     120                psError(PS_ERR_UNKNOWN, false, "Unable to add/sub noise.");
     121                return false;
     122            }
     123            psFree(job);
     124# endif
     125        }
     126
     127        // wait for the threads to finish and manage results
     128        if (!psThreadPoolWait (false, true)) {
     129            psFree(cellGroups);
     130            psError(PS_ERR_UNKNOWN, false, "Unable to add/sub noise.");
     131            return false;
     132        }
     133
     134        // we have only supplied one type of job, so we can assume the types here
     135        psThreadJob *job = NULL;
     136        while ((job = psThreadJobGetDone()) != NULL) {
     137            // we have no returned data from this operation
     138            if (job->args->n < 1) {
     139                fprintf (stderr, "error with job\n");
     140            }
     141            psFree(job);
     142        }
     143    }
     144
     145    if (add) {
     146        psLogMsg ("psphot.noise", PS_LOG_WARN, "add noise for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.noise"));
     147    } else {
     148        psLogMsg ("psphot.noise", PS_LOG_WARN, "sub noise for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.noise"));
     149    }
     150
     151    psFree (cellGroups);
     152
     153    psphotVisualShowImage (readout);
     154
     155    return true;
     156}
     157
     158bool psphotAddOrSubNoise_Threaded (psThreadJob *job) {
     159
     160    psArray *sources = job->args->data[0];
     161    psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[1], PS_TYPE_IMAGE_MASK_DATA);
     162    psImageMaskType markVal = PS_SCALAR_VALUE(job->args->data[2], PS_TYPE_IMAGE_MASK_DATA);
     163    psF32 FACTOR = PS_SCALAR_VALUE(job->args->data[3], F32);
     164    psF32 SIZE = PS_SCALAR_VALUE(job->args->data[4], F32);
     165    psBool add  = PS_SCALAR_VALUE(job->args->data[5], U8);
    86166
    87167    // loop over all source
     
    104184        psphotMaskSource (source, add, markVal);
    105185    }
    106     if (add) {
    107         psLogMsg ("psphot.noise", PS_LOG_WARN, "add noise for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.noise"));
    108     } else {
    109         psLogMsg ("psphot.noise", PS_LOG_WARN, "sub noise for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.noise"));
    110     }
    111     fprintf (stderr, "masked %d objects\n", Nmasked);
    112 
    113     psphotVisualShowImage (readout);
    114 
    115186    return true;
    116187}
     
    142213        }
    143214    }
    144     Nmasked ++;
    145 
    146     return true;
    147 }
    148 
     215    return true;
     216}
     217
  • trunk/psphot/src/psphotBlendFit.c

    r34418 r35769  
    8686    if (!status || !isfinite(fitMaxTol) || fitMaxTol <= 0) {
    8787        fitMaxTol = 1.0;
     88    }
     89
     90    bool chisqConvergence = psMetadataLookupBool (&status, recipe, "LMM_FIT_CHISQ_CONVERGENCE"); // Fit tolerance
     91    if (!status) {
     92        // default to the old method (chisqConvergence)
     93        chisqConvergence = true;
     94    }
     95
     96    int gainFactorMode = psMetadataLookupS32 (&status, recipe, "LMM_FIT_GAIN_FACTOR_MODE"); // Fit tolerance
     97    if (!status) {
     98        // default to the old method (chisqConvergence)
     99        gainFactorMode = 0;
    88100    }
    89101
     
    119131    fitOptions->mode          = PM_SOURCE_FIT_PSF;
    120132    fitOptions->covarFactor   = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix
     133
     134    fitOptions->gainFactorMode = gainFactorMode;
     135    fitOptions->chisqConvergence = chisqConvergence;
    121136
    122137    psphotInitLimitsPSF (recipe, readout);
     
    211226
    212227    psLogMsg ("psphot.psphotBlendFit", PS_LOG_WARN, "fit models: %f sec for %d objects (%d psf, %d ext, %d failed, %ld skipped)\n", psTimerMark ("psphot.fit.nonlinear"), Nfit, Npsf, Next, Nfail, sources->n - Nfit);
     228    psphotFitSummary ();
    213229
    214230    psphotVisualShowResidualImage (readout, false);
     
    271287
    272288        // skip non-astronomical objects (very likely defects)
    273         if (source->mode &  PM_SOURCE_MODE_BLEND) continue;
    274         if (source->mode &  PM_SOURCE_MODE_CR_LIMIT) continue;
    275         if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
    276         if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
     289        if (source->mode &  PM_SOURCE_MODE_BLEND) goto skip_blend;
     290        if (source->mode &  PM_SOURCE_MODE_CR_LIMIT) goto skip_cr;
     291        if (source->type == PM_SOURCE_TYPE_DEFECT) goto skip_defect;
     292        if (source->type == PM_SOURCE_TYPE_SATURATED) goto skip_sat;
    277293
    278294        // skip saturated stars modeled with a radial profile
    279         if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue;
     295        if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) goto skip_sat;
    280296
    281297        // skip DBL second sources (ie, added by psphotFitBlob
    282         if (source->mode &  PM_SOURCE_MODE_PAIR) continue;
     298        if (source->mode &  PM_SOURCE_MODE_PAIR) goto skip_blend;
    283299
    284300        // do not include MOMENTS_FAILURES in the fit
    285         if (source->mode & PM_SOURCE_MODE_MOMENTS_FAILURE) continue;
     301        if (source->mode & PM_SOURCE_MODE_MOMENTS_FAILURE) goto skip_generic;
    286302
    287303        // limit selection to some SN limit
    288304        if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
    289             if (source->moments->KronFlux < FIT_SN_LIM * source->moments->KronFluxErr) continue;
     305            if (source->moments->KronFlux < FIT_SN_LIM * source->moments->KronFluxErr) goto skip_generic;
    290306        } else {
    291             if (sqrt(source->peak->detValue) < FIT_SN_LIM) continue;
     307            if (sqrt(source->peak->detValue) < FIT_SN_LIM) goto skip_generic;
    292308        }
    293309        // exclude sources outside optional analysis region
    294         if (source->peak->xf < AnalysisRegion.x0) continue;
    295         if (source->peak->yf < AnalysisRegion.y0) continue;
    296         if (source->peak->xf > AnalysisRegion.x1) continue;
    297         if (source->peak->yf > AnalysisRegion.y1) continue;
     310        if (source->peak->xf < AnalysisRegion.x0) goto skip_generic;
     311        if (source->peak->yf < AnalysisRegion.y0) goto skip_generic;
     312        if (source->peak->xf > AnalysisRegion.x1) goto skip_generic;
     313        if (source->peak->yf > AnalysisRegion.y1) goto skip_generic;
    298314
    299315        // if model is NULL, we don't have a starting guess
    300         if (source->modelPSF == NULL) continue;
     316        if (source->modelPSF == NULL) goto skip_generic;
    301317
    302318        // skip sources which are insignificant flux?
     
    307323                     source->modelPSF->params->data.F32[2],
    308324                     source->modelPSF->params->data.F32[3]);
    309             continue;
     325            goto skip_generic;
    310326        }
    311327
     
    357373        pmSourceCacheModel (source, maskVal);
    358374        pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
     375        continue;
     376
     377    skip_blend:
     378        psTrace ("psphot", 5, "source at %7.1f, %7.1f skipped", source->peak->xf, source->peak->yf);
     379        continue;
     380    skip_cr:
     381        psTrace ("psphot", 5, "source at %7.1f, %7.1f skipped", source->peak->xf, source->peak->yf);
     382        continue;
     383    skip_defect:
     384        psTrace ("psphot", 5, "source at %7.1f, %7.1f skipped", source->peak->xf, source->peak->yf);
     385        continue;
     386    skip_sat:
     387        psTrace ("psphot", 5, "source at %7.1f, %7.1f skipped", source->peak->xf, source->peak->yf);
     388        continue;
     389    skip_generic:
     390        psTrace ("psphot", 5, "source at %7.1f, %7.1f skipped", source->peak->xf, source->peak->yf);
     391        continue;
    359392    }
    360393
  • trunk/psphot/src/psphotChoosePSF.c

    r34317 r35769  
    158158    }
    159159    float maxChisqDOF = psMetadataLookupF32 (&status, recipe, "PSF_FIT_MAX_CHISQ"); // Fit tolerance
     160
     161    bool chisqConvergence = psMetadataLookupBool (&status, recipe, "LMM_FIT_CHISQ_CONVERGENCE"); // Fit tolerance
     162    if (!status) {
     163        // default to the old method (chisqConvergence)
     164        chisqConvergence = true;
     165    }
     166
     167    int gainFactorMode = psMetadataLookupS32 (&status, recipe, "LMM_FIT_GAIN_FACTOR_MODE"); // Fit tolerance
     168    if (!status) {
     169        // default to the old method (chisqConvergence)
     170        gainFactorMode = 0;
     171    }
    160172
    161173    // options which modify the behavior of the model fitting
     
    169181    options->fitOptions->mode          = PM_SOURCE_FIT_PSF;
    170182    options->fitOptions->covarFactor   = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix
    171 
    172183   
     184    options->fitOptions->gainFactorMode   = gainFactorMode;
     185    options->fitOptions->chisqConvergence = chisqConvergence;
     186
    173187    psArray *stars = psArrayAllocEmpty (sources->n);
    174188
  • trunk/psphot/src/psphotExtendedSourceFits.c

    r35559 r35769  
    11# include "psphotInternal.h"
     2bool psphotSetWindowTrail (float *fitRadius, float *windowRadius, pmReadout *readout, pmSource *source, psImageMaskType markVal, float newRadius);
    23
    34// for now, let's store the detections on the readout->analysis for each readout
     
    5253    psTimerStart ("psphot.extended");
    5354
     55    psphotFitInitExtended();
     56
    5457    // find the currently selected readout
    5558    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, index); // File of interest
     
    7073    if (!sources->n) {
    7174        psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping source size");
     75        psphotSersicModelClassCleanup();
    7276        return true;
    7377    }
     
    8084    // do not thread if we are trying to study the fitting process
    8185    if (psTraceGetLevel ("psphot.psphotFitEXT") >= 6) {
    82       nThreads = 0;
     86        nThreads = 0;
    8387    }
    8488
     
    107111    }
    108112
     113    bool chisqConvergence = psMetadataLookupBool (&status, recipe, "LMM_FIT_CHISQ_CONVERGENCE"); // Fit tolerance
     114    if (!status) {
     115        // default to the old method (chisqConvergence)
     116        chisqConvergence = true;
     117    }
     118
     119    int gainFactorMode = psMetadataLookupS32 (&status, recipe, "LMM_FIT_GAIN_FACTOR_MODE"); // Fit tolerance
     120    if (!status) {
     121        // default to the old method (chisqConvergence)
     122        gainFactorMode = 0;
     123    }
     124
     125    // Define source fitting parameters for extended source fits
     126    pmSourceFitOptions *fitOptions = pmSourceFitOptionsAlloc();
     127    fitOptions->mode           = PM_SOURCE_FIT_EXT;
     128    fitOptions->saveCovariance = true;  // XXX make this a user option?
     129    fitOptions->covarFactor    = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix
     130    fitOptions->nIter          = fitIter;
     131    fitOptions->minTol         = fitMinTol;
     132    fitOptions->maxTol         = fitMaxTol;
     133
     134    fitOptions->gainFactorMode   = gainFactorMode;
     135    fitOptions->chisqConvergence = chisqConvergence;
     136
    109137    // maskVal is used to test for rejected pixels, and must include markVal
    110138    maskVal |= markVal;
    111139
    112140    // select the collection of desired models
    113     psMetadata *models = psMetadataLookupMetadata (&status, recipe, "EXTENDED_SOURCE_MODELS");
     141    psMetadata *allModels = psMetadataLookupMetadata (&status, recipe, "EXTENDED_SOURCE_MODELS");
    114142    if (!status) {
    115143        psWarning ("extended source model fits requested but model model is missing (EXTENDED_SOURCE_MODELS)\n");
     144        psFree (fitOptions);
     145        psphotSersicModelClassCleanup();
    116146        return true;
    117147    }
     148    if (allModels->list->n == 0) {
     149        psWarning ("extended source model fits requested but no models are specified\n");
     150        psFree (fitOptions);
     151        psphotSersicModelClassCleanup();
     152        return true;
     153    }
     154
     155    psMetadata *models = NULL;
     156    char *modelSelection = psMetadataLookupStr (&status, recipe, "EXTENDED_SOURCE_MODELS_SELECTION");
     157    if (!modelSelection || !status) {
     158        models = psMemIncrRefCounter(allModels);
     159        goto got_models;
     160    }
     161
     162    if (!strcasecmp(modelSelection, "ALL")) {
     163        models = psMemIncrRefCounter(allModels);
     164        goto got_models;
     165    }
     166
     167    if (!strcasecmp(modelSelection, "NONE")) {
     168        psWarning ("extended source model fits requested but no models are selected (EXTENDED_SOURCE_MODELS_SELECTION = NONE)\n");
     169        psFree (fitOptions);
     170        psphotSersicModelClassCleanup();
     171        return true;
     172    }
     173
     174    psArray *selection = psStringSplitArray (modelSelection, ",", false);
     175    if (selection->n == 0) {
     176        psWarning ("extended source model fits requested but model selection string is empty (EXTENDED_SOURCE_MODELS_SELECTION)\n");
     177        psFree (fitOptions);
     178        psFree (selection);
     179        psphotSersicModelClassCleanup();
     180        return true;
     181    }
     182    models = psMetadataAlloc();
     183    for (int i = 0; i < selection->n; i++) {
     184        psMetadata *model = psMetadataLookupMetadata (&status, allModels, selection->data[i]);
     185        if (!model) {
     186            psWarning ("extended source model selection string includes an invalid name %s\n", (char *) selection->data[i]);
     187            continue;
     188        }
     189        psMetadataAddMetadata (models, PS_LIST_TAIL, selection->data[i], PS_META_REPLACE, "extended model", model);
     190    }
     191    psFree (selection);
     192
    118193    if (models->list->n == 0) {
    119         psWarning ("extended source model fits requested but no models are specified\n");
    120         return true;
    121     }
     194        psWarning ("extended source model fits requested but no valid models in selection string (EXTENDED_SOURCE_MODELS_SELECTION = %s)\n", modelSelection);
     195        psFree (fitOptions);
     196        psFree (models);
     197        psphotSersicModelClassCleanup();
     198        return true;
     199    }
     200
     201got_models:
    122202
    123203    psphotInitRadiusEXT (recipe, readout);
     
    128208    while ((item = psMetadataGetAndIncrement (iter)) != NULL) {
    129209
    130       if (item->type != PS_DATA_METADATA) {
    131         // XXX we could cull the bad entries or build a validated model folder
    132         psAbort ("Invalid type for EXTENDED_SOURCE_MODEL entry %s, not a metadata folder", item->name);
    133       }
    134 
    135       psMetadata *model = (psMetadata *) item->data.md;
    136 
    137       // check on the model type
    138       char *modelName = psMetadataLookupStr (&status, model, "MODEL");
    139       int modelType = pmModelClassGetType (modelName);
    140       if (modelType < 0) {
    141         psAbort ("Unknown model class for EXTENDED_SOURCE_MODEL entry %s: %s", item->name, modelName);
    142       }
    143       psMetadataAddS32 (model, PS_LIST_TAIL, "MODEL_TYPE", PS_META_REPLACE, "", modelType);
    144 
    145       // check on the SNLIM, set a float value
    146       char *SNword = psMetadataLookupStr (&status, model, "SNLIM");
    147       if (!status) {
    148         psAbort("SNLIM not defined for extended source model %s\n", item->name);
    149       }
    150       float SNlim = atof (SNword);
    151       psMetadataAddF32 (model, PS_LIST_TAIL, "SNLIM_VALUE", PS_META_REPLACE, "", SNlim);
    152 
    153       // check on the PSF-Convolution status
    154       char *convolvedWord = psMetadataLookupStr (&status, model, "PSF_CONVOLVED");
    155       if (!status || (strcasecmp (convolvedWord, "true") && strcasecmp (convolvedWord, "false"))) {
    156         psAbort ("PSF_CONVOLVED entry invalid or missing for EXTENDED_SOURCE_MODEL entry %s", item->name);
    157       }
    158       bool convolved = !strcasecmp (convolvedWord, "true");
    159       psMetadataAddBool (model, PS_LIST_TAIL, "PSF_CONVOLVED_VALUE", PS_META_REPLACE, "", convolved);
     210        if (item->type != PS_DATA_METADATA) {
     211            // XXX we could cull the bad entries or build a validated model folder
     212            psAbort ("Invalid type for EXTENDED_SOURCE_MODEL entry %s, not a metadata folder", item->name);
     213        }
     214
     215        psMetadata *model = (psMetadata *) item->data.md;
     216
     217        // check on the model type
     218        char *modelName = psMetadataLookupStr (&status, model, "MODEL");
     219        int modelType = pmModelClassGetType (modelName);
     220        if (modelType < 0) {
     221            psAbort ("Unknown model class for EXTENDED_SOURCE_MODEL entry %s: %s", item->name, modelName);
     222        }
     223        psMetadataAddS32 (model, PS_LIST_TAIL, "MODEL_TYPE", PS_META_REPLACE, "", modelType);
     224
     225        // check on the SNLIM, set a float value
     226        char *SNword = psMetadataLookupStr (&status, model, "SNLIM");
     227        if (!status) {
     228            psAbort("SNLIM not defined for extended source model %s\n", item->name);
     229        }
     230        float SNlim = atof (SNword);
     231        psMetadataAddF32 (model, PS_LIST_TAIL, "SNLIM_VALUE", PS_META_REPLACE, "", SNlim);
     232
     233        // check on the PSF-Convolution status
     234        char *convolvedWord = psMetadataLookupStr (&status, model, "PSF_CONVOLVED");
     235        if (!status || (strcasecmp (convolvedWord, "true") && strcasecmp (convolvedWord, "false"))) {
     236            psAbort ("PSF_CONVOLVED entry invalid or missing for EXTENDED_SOURCE_MODEL entry %s", item->name);
     237        }
     238        bool convolved = !strcasecmp (convolvedWord, "true");
     239        psMetadataAddBool (model, PS_LIST_TAIL, "PSF_CONVOLVED_VALUE", PS_META_REPLACE, "", convolved);
     240
     241        if (convolved) {
     242            psLogMsg ("psphot", PS_LOG_INFO, "using convolved model class %s (%s)", modelName, item->name);
     243        } else {
     244            psLogMsg ("psphot", PS_LOG_INFO, "using simple    model class %s (%s)", modelName, item->name);
     245        }
    160246    }
    161247    psFree (iter);
     
    195281            psMetadataIterator *iter = psMetadataIteratorAlloc (models, PS_LIST_HEAD, NULL);
    196282            psArrayAdd(job->args, 1, iter);
    197             psArrayAdd(job->args, 1, AnalysisRegion); // XXX make a pointer
     283            psArrayAdd(job->args, 1, AnalysisRegion);
     284            psArrayAdd(job->args, 1, fitOptions);
    198285
    199286            PS_ARRAY_ADD_SCALAR(job->args, psfSize, PS_TYPE_S32);
    200             PS_ARRAY_ADD_SCALAR(job->args, fitIter, PS_TYPE_S32);
    201             PS_ARRAY_ADD_SCALAR(job->args, fitMinTol, PS_TYPE_F32);
    202             PS_ARRAY_ADD_SCALAR(job->args, fitMaxTol, PS_TYPE_F32);
    203 
    204287            PS_ARRAY_ADD_SCALAR(job->args, maskVal, PS_TYPE_IMAGE_MASK);
    205288            PS_ARRAY_ADD_SCALAR(job->args, markVal, PS_TYPE_IMAGE_MASK);
     
    218301                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
    219302                psFree(AnalysisRegion);
     303                psFree (fitOptions);
     304                psFree (models);
     305                psphotSersicModelClassCleanup();
    220306                return false;
    221307            }
     
    224310                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
    225311                psFree(AnalysisRegion);
     312                psFree (fitOptions);
     313                psFree (models);
     314                psphotSersicModelClassCleanup();
    226315                return false;
    227316            }
    228317            psScalar *scalar = NULL;
    229             scalar = job->args->data[8];
     318            scalar = job->args->data[9];
    230319            Next += scalar->data.S32;
    231             scalar = job->args->data[9];
     320            scalar = job->args->data[10];
    232321            Nconvolve += scalar->data.S32;
    233             scalar = job->args->data[10];
     322            scalar = job->args->data[11];
    234323            NconvolvePass += scalar->data.S32;
    235             scalar = job->args->data[11];
     324            scalar = job->args->data[12];
    236325            Nplain += scalar->data.S32;
    237             scalar = job->args->data[12];
     326            scalar = job->args->data[13];
    238327            NplainPass += scalar->data.S32;
    239             scalar = job->args->data[13];
     328            scalar = job->args->data[14];
    240329            Nfaint += scalar->data.S32;
    241             scalar = job->args->data[14];
     330            scalar = job->args->data[15];
    242331            Nfail += scalar->data.S32;
    243332            psFree(job->args->data[3]); // iterator allocated above
     
    250339            psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
    251340            psFree(AnalysisRegion);
     341            psFree (fitOptions);
     342            psFree (models);
     343            psphotSersicModelClassCleanup();
    252344            return false;
    253345        }
     
    260352            } else {
    261353                psScalar *scalar = NULL;
    262                 scalar = job->args->data[8];
     354                scalar = job->args->data[9];
    263355                Next += scalar->data.S32;
    264                 scalar = job->args->data[9];
     356                scalar = job->args->data[10];
    265357                Nconvolve += scalar->data.S32;
    266                 scalar = job->args->data[10];
     358                scalar = job->args->data[11];
    267359                NconvolvePass += scalar->data.S32;
    268                 scalar = job->args->data[11];
     360                scalar = job->args->data[12];
    269361                Nplain += scalar->data.S32;
    270                 scalar = job->args->data[12];
     362                scalar = job->args->data[13];
    271363                NplainPass += scalar->data.S32;
    272                 scalar = job->args->data[13];
     364                scalar = job->args->data[14];
    273365                Nfaint += scalar->data.S32;
    274                 scalar = job->args->data[14];
     366                scalar = job->args->data[15];
    275367                Nfail += scalar->data.S32;
    276368                psFree(job->args->data[3]); // metadata iterator allocated above
     
    281373    psFree (cellGroups);
    282374    psFree(AnalysisRegion);
     375    psFree (fitOptions);
     376    psFree (models);
    283377
    284378    psphotSersicModelClassCleanup();
     
    290384    psLogMsg ("psphot", PS_LOG_INFO, "  %d plain models (%d passed)\n", Nplain, NplainPass);
    291385    psLogMsg ("psphot", PS_LOG_INFO, "  %d too faint to fit, %d failed\n", Nfaint, Nfail);
     386
     387    psphotFitSummaryExtended();
     388
    292389    return true;
    293390}
     
    308405
    309406    // arguments: readout, sources, models, region, psfSize, maskVal, markVal
    310     pmReadout *readout      = job->args->data[0];
    311     psArray *sources        = job->args->data[1];
    312     psMetadata *models      = job->args->data[2];
     407    pmReadout *readout       = job->args->data[0];
     408    psArray *sources         = job->args->data[1];
     409    psMetadata *models       = job->args->data[2];
    313410    psMetadataIterator *iter = job->args->data[3];
    314     psRegion *region        = job->args->data[4];
    315     int psfSize             = PS_SCALAR_VALUE(job->args->data[5],S32);
    316     int fitIter             = PS_SCALAR_VALUE(job->args->data[6],S32);
    317     float fitMinTol         = PS_SCALAR_VALUE(job->args->data[7],F32);
    318     float fitMaxTol         = PS_SCALAR_VALUE(job->args->data[8],F32);
    319     psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[9],PS_TYPE_IMAGE_MASK_DATA);
    320     psImageMaskType markVal = PS_SCALAR_VALUE(job->args->data[10],PS_TYPE_IMAGE_MASK_DATA);
    321 
    322     // Define source fitting parameters for extended source fits
    323     pmSourceFitOptions *fitOptions = pmSourceFitOptionsAlloc();
    324     fitOptions->mode           = PM_SOURCE_FIT_EXT;
    325     fitOptions->saveCovariance = true;  // XXX make this a user option?
    326     fitOptions->covarFactor    = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix
    327     fitOptions->nIter          = fitIter;
    328     fitOptions->minTol         = fitMinTol;
    329     fitOptions->maxTol         = fitMaxTol;
     411    psRegion *region         = job->args->data[4];
     412    pmSourceFitOptions *fitOptions = job->args->data[5];
     413
     414    int psfSize             = PS_SCALAR_VALUE(job->args->data[6],S32);
     415    psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[7],PS_TYPE_IMAGE_MASK_DATA);
     416    psImageMaskType markVal = PS_SCALAR_VALUE(job->args->data[8],PS_TYPE_IMAGE_MASK_DATA);
     417
     418    // psTraceSetLevel ("psLib.math.psMinimizeLMChi2_Alt", 5);
    330419
    331420    // choose the sources of interest
     
    348437        if (source->peak->y > region->y1) continue;
    349438
     439
     440        // XXX for a test, just do the obvious trail
     441        // XXX if (source->peak->xf < 1100) continue;
     442        // XXX if (source->peak->xf > 1400) continue;
     443        // XXX if (source->peak->yf >  245) continue;
     444
    350445        // replace object in image
    351446        if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {
     
    384479          assert (status);
    385480
    386           // limit selection to some SN limit
    387           // assert (source->peak); // how can a source not have a peak?
    388481          // limit selection to some SN limit
    389482          bool skipSource = false;
     
    424517              }
    425518          } else {
    426               psFree (source->modelFlux);
    427               source->modelFlux = NULL;
    428               modelFit = psphotFitEXT (readout, source, fitOptions, modelType, maskVal, markVal);
    429               if (!modelFit) {
    430                   psTrace ("psphot", 5, "failed to fit plain model for object at %f, %f", source->moments->Mx, source->moments->My);
    431                   Nfail ++;
    432                   continue;
    433               }
    434               psTrace ("psphot", 4, "fit plain model for %f, %f : %s chisq = %f (npix: %d, niter: %d)\n",
    435                        source->moments->Mx, source->moments->My, pmModelClassGetName (modelFit->type), modelFit->chisq, modelFit->nPix, modelFit->nIter);
    436               Nplain ++;
    437               if (!(modelFit->flags & (PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE))) {
    438                   NplainPass ++;
    439                   source->mode |= PM_SOURCE_MODE_EXTENDED_FIT;
    440               }
     519              bool doneFits = false;
     520              while (!doneFits) {
     521                  psFree (source->modelFlux);
     522                  source->modelFlux = NULL;
     523                  modelFit = psphotFitEXT (modelFit, readout, source, fitOptions, modelType, maskVal, markVal);
     524                  if (!modelFit) {
     525                      psTrace ("psphot", 5, "failed to fit plain model for object at %f, %f", source->moments->Mx, source->moments->My);
     526                      Nfail ++;
     527                      doneFits = true;
     528                      continue;
     529                  }
     530                  psTrace ("psphot", 4, "fit plain model for %f, %f : %s chisq = %f (npix: %d, niter: %d)\n", source->moments->Mx, source->moments->My, pmModelClassGetName (modelFit->type), modelFit->chisq, modelFit->nPix, modelFit->nIter);
     531                  Nplain ++;
     532                  if (!(modelFit->flags & (PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE))) {
     533                      NplainPass ++;
     534                      source->mode |= PM_SOURCE_MODE_EXTENDED_FIT;
     535                  }
     536                  doneFits = true;
     537
     538                  if (modelType == pmModelClassGetType("PS_MODEL_TRAIL")) {
     539                      // calculate the object end points:
     540                      float *PAR = modelFit->params->data.F32;
     541                      float Xmin = PAR[PM_PAR_XPOS] - 0.5*PAR[PM_PAR_LENGTH]*sin(PAR[PM_PAR_THETA]);
     542                      float Ymin = PAR[PM_PAR_YPOS] - 0.5*PAR[PM_PAR_LENGTH]*cos(PAR[PM_PAR_THETA]);
     543                      float Xmax = PAR[PM_PAR_XPOS] + 0.5*PAR[PM_PAR_LENGTH]*sin(PAR[PM_PAR_THETA]);
     544                      float Ymax = PAR[PM_PAR_YPOS] + 0.5*PAR[PM_PAR_LENGTH]*cos(PAR[PM_PAR_THETA]);
     545
     546                      if (false && (source->peak->xf > 1100) &&
     547                          (source->peak->xf < 1400) &&
     548                          (source->peak->yf < 245)) {
     549                          fprintf (stderr, "src vs fit : %d %d - %d %d | %f %f - %f %f\n",
     550                                   source->pixels->col0, source->pixels->row0,
     551                                   source->pixels->col0 + source->pixels->numCols, source->pixels->row0 + source->pixels->numRows,
     552                                   Xmin, Ymin, Xmax, Ymax);
     553                      }
     554                      if (PAR[PM_PAR_LENGTH] > 0.9*fitRadius) {
     555                          doneFits = false;
     556                          fprintf (stderr, "update window : %f %f : %f -> %f\n", source->peak->xf, source->peak->yf, fitRadius, 2*fitRadius);
     557                          psphotSetWindowTrail (&fitRadius, &windowRadius, readout, source, markVal, fitRadius*2.0);
     558                      }
     559                  }
     560              }
    441561          }
    442 
    443           // XXX deprecate?
    444           // XXX pmSourceExtFitPars *extFitPars = pmSourceExtFitParsAlloc();
    445           // XXX extFitPars->Mxx = source->moments->Mxx;
    446           // XXX extFitPars->Mxy = source->moments->Mxy;
    447           // XXX extFitPars->Myy = source->moments->Myy;
    448           // XXX extFitPars->Mrf = source->moments->Mrf;
    449           // XXX extFitPars->Mrh = source->moments->Mrh;
    450           // XXX extFitPars->peakMag = (source->peak->rawFlux > 0) ? -2.5*log10(source->peak->rawFlux) : NAN;
    451          
    452           // save kron mag, but assign apMag & psfMag on output (not yet calculated)
    453           // XXX extFitPars->krMag = -2.5*log10(source->moments->KronFlux);
    454 
    455           // psArrayAdd (source->extFitPars, 4, extFitPars);
    456           // psFree (extFitPars);
     562          // XXX really need to do this in a cleaner way:
     563          if (!modelFit) continue;
    457564
    458565          // test for fit quality / result
     
    519626        psTrace ("psphot", 5, "extended source model for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
    520627    }
    521     psFree (fitOptions);
    522628
    523629    // change the value of a scalar on the array (wrap this and put it in psArray.h)
     630    scalar = job->args->data[9];
     631    scalar->data.S32 = Next;
     632
     633    scalar = job->args->data[10];
     634    scalar->data.S32 = Nconvolve;
     635
    524636    scalar = job->args->data[11];
    525     scalar->data.S32 = Next;
     637    scalar->data.S32 = NconvolvePass;
    526638
    527639    scalar = job->args->data[12];
    528     scalar->data.S32 = Nconvolve;
     640    scalar->data.S32 = Nplain;
    529641
    530642    scalar = job->args->data[13];
    531     scalar->data.S32 = NconvolvePass;
     643    scalar->data.S32 = NplainPass;
    532644
    533645    scalar = job->args->data[14];
    534     scalar->data.S32 = Nplain;
     646    scalar->data.S32 = Nfaint;
    535647
    536648    scalar = job->args->data[15];
    537     scalar->data.S32 = NplainPass;
    538 
    539     scalar = job->args->data[16];
    540     scalar->data.S32 = Nfaint;
    541 
    542     scalar = job->args->data[17];
    543649    scalar->data.S32 = Nfail;
    544650
    545651    return true;
    546652}
     653
     654# define PAD_WINDOW 3.0
     655bool psphotSetWindowTrail (float *fitRadius, float *windowRadius, pmReadout *readout, pmSource *source, psImageMaskType markVal, float newRadius) {
     656
     657    psRegion newRegion;
     658
     659    psAssert (source, "source not defined??");
     660    psAssert (source->moments, "moments not defined??");
     661
     662    *fitRadius = newRadius;
     663    *windowRadius = *fitRadius + PAD_WINDOW;
     664
     665    // check to see if new region is completely contained within old region
     666    newRegion = psRegionForSquare (source->peak->xf, source->peak->yf, *windowRadius);
     667    newRegion = psRegionForImage (readout->image, newRegion);
     668
     669    // redefine the pixels to match
     670    pmSourceRedefinePixelsByRegion (source, readout, newRegion);
     671
     672    // clear the circular mask
     673    psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
     674
     675    // set the mask to flag the excluded pixels
     676    psImageKeepCircle (source->maskObj, source->peak->xf, source->peak->yf, *fitRadius, "OR", markVal);
     677
     678    return true;
     679}
  • trunk/psphot/src/psphotGuessModels.c

    r34404 r35769  
    2929}
    3030
     31int NpixTotal = 0;
     32
    3133// construct an initial PSF model for each object (new sources only)
    3234bool psphotGuessModelsReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index) {
     
    8688
    8789    psArray *cellGroups = psphotAssignSources (Cx, Cy, sources);
     90
     91    NpixTotal = 0;
    8892
    8993    for (int i = 0; i < cellGroups->n; i++) {
     
    103107            PS_ARRAY_ADD_SCALAR(job->args, markVal,  PS_TYPE_IMAGE_MASK);
    104108
     109# if (1)
    105110            if (!psThreadJobAddPending(job)) {
    106111                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
    107112                return false;
    108113            }
    109         }
     114# else
     115            if (!psphotGuessModel_Threaded(job)) {
     116                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     117                return false;
     118            }
     119            psFree(job);
     120# endif
     121        }
     122
    110123
    111124        // wait for the threads to finish and manage results
     
    143156    psFree (cellGroups);
    144157
    145     psLogMsg ("psphot.models", PS_LOG_WARN, "built models for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.models"));
     158    psLogMsg ("psphot.models", PS_LOG_WARN, "built models for %ld objects: %f sec (%d pixels)\n", sources->n, psTimerMark ("psphot.models"), NpixTotal);
    146159    return true;
    147160}
     
    240253
    241254        pmSourceCacheModel (source, maskVal);  // ALLOC x14 (!)
     255        NpixTotal += source->pixels->numCols * source->pixels->numRows;
    242256    }
    243257
  • trunk/psphot/src/psphotKronIterate.c

    r34560 r35769  
    166166    }
    167167
     168    fprintf (stderr, "--- starting KRON ---\n");
     169
    168170    // We measure the Kron Radius on a smoothed copy of the readout image
    169171    psImage *smoothedImage = NULL;
    170172    if (KRON_SMOOTH) {
     173        psTimerStart ("psphot.kron.smooth");
     174
    171175        // Build the smoothed source image
    172176        // Replace the subtracted sources
    173177        psphotReplaceAllSourcesReadout(config, view, filerule, index, recipe, false);
     178        psLogMsg ("psphot.kron", PS_LOG_INFO, "replaced %ld raw sources %f sec\n", sources->n, psTimerMark ("psphot.kron.smooth"));
     179
     180        // smoothedImage = psImageCopy(NULL, readout->image, PS_TYPE_F32);
     181        // psImageSmooth(smoothedImage, KRON_SMOOTH_SIGMA, KRON_SMOOTH_NSIGMA);
     182       
    174183        // Copy the image and smooth
    175184        psTimerStart ("psphot.kron.smooth");
    176         smoothedImage = psImageCopy(NULL, readout->image, PS_TYPE_F32);
    177         psImageSmooth(smoothedImage, KRON_SMOOTH_SIGMA, KRON_SMOOTH_NSIGMA);
     185        bool oldThreads = psImageConvolveSetThreads(true); // Old value of threading in psImageConvolve
     186        smoothedImage = psImageSmoothNoMask_Threaded (NULL, readout->image, KRON_SMOOTH_SIGMA, KRON_SMOOTH_NSIGMA, 0.25);
     187        psImageConvolveSetThreads(oldThreads);
    178188        psLogMsg ("psphot.kron", PS_LOG_INFO, "smoothed image %f sec\n", psTimerMark ("psphot.kron.smooth"));
    179189
    180190        // remove the sources
     191        psTimerStart ("psphot.kron.smooth");
    181192        psphotRemoveAllSourcesReadout( config, view, filerule, index, recipe, false );
     193        psLogMsg ("psphot.kron", PS_LOG_INFO, "removed %ld raw sources %f sec\n", sources->n, psTimerMark ("psphot.kron.smooth"));
     194
    182195        // Now subtract smooth versions of the sources from the smoothed image
    183196        psTimerStart ("psphot.kron.smooth.sources");
  • trunk/psphot/src/psphotModelBackground.c

    r34528 r35769  
    2828}
    2929
     30// track background cell failures for log reporting purposes
     31static int nFailures = 0;
    3032
    3133// Generate the background model
     
    3335// linear interpolation to generate full-scale model
    3436//
    35 // NOTE that the 'analysis' metedata pass in here is used to store the binning information.
     37// NOTE that the 'analysis' metedata passed in here is used to store the binning information.
    3638// This may be the analysis for this readout, but it may be the analysis for the pmFPAfile
    3739// corresponding to the model.  Other information about the background model is saved on the
     
    109111
    110112    const psStatsOptions statsOption = statsOptionLocation | statsOptionWidth;
    111     psStats *stats = psStatsAlloc (statsOption);
     113    psStats *statsDefaults = psStatsAlloc (statsOption);
    112114
    113115    // set range for old-version of sky statistic
    114116    if (statsOptionLocation & PS_STAT_ROBUST_QUARTILE) {
    115         stats->min = 0.25;
    116         stats->max = 0.75;
     117        statsDefaults->min = 0.25;
     118        statsDefaults->max = 0.75;
    117119    }
    118120
    119121    // set user-option for number of pixels per region
    120     stats->nSubsample = psMetadataLookupF32 (&status, recipe, "IMSTATS_NPIX");
     122    statsDefaults->nSubsample = psMetadataLookupF32 (&status, recipe, "IMSTATS_NPIX");
    121123    if (!status) {
    122         stats->nSubsample = 1000;
     124        statsDefaults->nSubsample = 1000;
    123125    }
    124126
    125127    // optionally set the binsize
    126     stats->binsize = psMetadataLookupF32 (&status, recipe, "SKY_HISTOGRAM_BINS");
     128    statsDefaults->binsize = psMetadataLookupF32 (&status, recipe, "SKY_HISTOGRAM_BINS");
    127129    if (status) {
    128         stats->options |= PS_STAT_USE_BINSIZE;
     130        statsDefaults->options |= PS_STAT_USE_BINSIZE;
    129131    }
    130132
    131133    // optionally set the sigma clipping
    132     stats->clipSigma = psMetadataLookupF32 (&status, recipe, "SKY_CLIP_SIGMA");
     134    statsDefaults->clipSigma = psMetadataLookupF32 (&status, recipe, "SKY_CLIP_SIGMA");
    133135    if (!status) {
    134         if (stats->options & PS_STAT_FITTED_MEAN) {
    135             stats->clipSigma = 1.0;
     136        if (statsDefaults->options & PS_STAT_FITTED_MEAN) {
     137            statsDefaults->clipSigma = 1.0;
    136138        } else {
    137             stats->clipSigma = 3.0;
     139            statsDefaults->clipSigma = 3.0;
    138140        }
    139141    }
    140 
    141     // stats is not initialized by psStats???  use this to save the input options
    142     // XXX re-work this to use the new psStatsInit function
    143     psStats *statsDefaults = psStatsAlloc (statsOption);
    144     *statsDefaults = *stats;
    145142
    146143    // we save the binning structure for use in psphotMagnitudes
     
    154151
    155152    // XXXX we can thread this here by running blocks in parallel
    156 
    157     int nFailures = 0;
    158153    psImageBackgroundInit();
     154    nFailures = 0; // reset for this pass
    159155
    160156    // we have Nx * Ny model points, but we can use a window which is larger (or smaller) than
     
    163159
    164160    // measure clipped median for subimages
    165     psRegion ruffRegion = psRegionSet (0,0,0,0);
    166     psRegion fineRegion = psRegionSet (0,0,0,0);
    167161    for (int iy = 0; iy < model->numRows; iy++) {
    168162        for (int ix = 0; ix < model->numCols; ix++) {
    169 
    170             // convert the ruff grid cell to the equivalent fine grid cell
    171             ruffRegion = psRegionSet (ix + 0.5 - 0.5*dXsample, ix + 0.5 + 0.5*dXsample,
    172                                       iy + 0.5 - 0.5*dYsample, iy + 0.5 + 0.5*dYsample);
    173             fineRegion = psImageBinningSetFineRegion (binning, ruffRegion);
    174             fineRegion = psRegionForImage (image, fineRegion);
    175 
    176             psImage *subset  = psImageSubset (image, fineRegion);
    177             if (!subset->numCols || !subset->numRows) {
    178                 psFree (subset);
    179                 continue;
     163           
     164            // allocate a job -- if threads are not defined, this just runs the job
     165            psThreadJob *job = psThreadJobAlloc ("PSPHOT_MODEL_BACKGROUND");
     166
     167            psArrayAdd(job->args, 1, image);
     168            psArrayAdd(job->args, 1, mask);
     169            psArrayAdd(job->args, 1, binning);
     170            psArrayAdd(job->args, 1, rng);
     171            psArrayAdd(job->args, 1, statsDefaults);
     172
     173            psArrayAdd(job->args, 1, modelData);
     174            psArrayAdd(job->args, 1, modelStdevData);
     175
     176            PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_IMAGE_MASK);
     177
     178            PS_ARRAY_ADD_SCALAR(job->args, ix, PS_TYPE_S32);
     179            PS_ARRAY_ADD_SCALAR(job->args, iy, PS_TYPE_S32);
     180
     181            PS_ARRAY_ADD_SCALAR(job->args, dXsample, PS_TYPE_F32);
     182            PS_ARRAY_ADD_SCALAR(job->args, dYsample, PS_TYPE_F32);
     183
     184            PS_ARRAY_ADD_SCALAR(job->args, statsOptionLocation, PS_TYPE_S32);
     185            PS_ARRAY_ADD_SCALAR(job->args, statsOptionWidth, PS_TYPE_S32);
     186
     187            PS_ARRAY_ADD_SCALAR(job->args, NAN, PS_TYPE_F32); // this is used as a return value for dQvalue
     188
     189# if (1)
     190            if (!psThreadJobAddPending(job)) {
     191                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     192                return NULL;
    180193            }
    181             psImage *submask = psImageSubset (mask, fineRegion);
    182 
    183             // reset the default values
    184             *stats = *statsDefaults;
    185 
    186             // Use the selected background statistic for the first pass
    187             // If it fails, fall back on the "ROBUST_MEDIAN" version
    188             // If both fail, set the pixel to NAN and (below) interpolate
    189             // XXX psImageBackground will probably be renamed psImageStats
    190             // XXX don't bother trying if there are no valid pixels...
    191 
    192             psVector *sample = NULL;
    193 
    194             // turn on stats tracing in desired cells
    195             # if (0)
    196             psMetadata *plots = psMetadataLookupPtr (&status, recipe, "DIAGNOSTIC.PLOTS");
    197             assert (plots);
    198 
    199             int xPlot = psMetadataLookupS32 (&status, plots, "IMAGE.BACKGROUND.CELL.HISTOGRAM.X");
    200             assert (status);
    201             int yPlot = psMetadataLookupS32 (&status, plots, "IMAGE.BACKGROUND.CELL.HISTOGRAM.Y");
    202             assert (status);
    203 
    204             bool gotX = (xPlot < 0) || (xPlot == ix);
    205             bool gotY = (yPlot < 0) || (yPlot == iy);
    206 
    207             if (gotX && gotY) {
    208                 (void) psTraceSetLevel ("psLib.math.vectorFittedStats", 6);
    209                 (void) psTraceSetLevel ("psLib.math.vectorRobustStats", 6);
    210             } else {
    211                 (void) psTraceSetLevel ("psLib.math.vectorFittedStats", 0);
    212                 (void) psTraceSetLevel ("psLib.math.vectorRobustStats", 0);
     194# else
     195            if (!psphotModelBackground_Threaded(job)) {
     196                psError(PS_ERR_UNKNOWN, false, "Failure to model background.");
     197                return NULL;
    213198            }
    214             # endif
    215 
    216             if (psImageBackground(stats, &sample, subset, submask, maskVal, rng)) {
    217                 if (stats->options & PS_STAT_ROBUST_QUARTILE) {
    218                     modelData[iy][ix] = stats->robustMedian;
    219                 } else {
    220                     modelData[iy][ix] = psStatsGetValue(stats, statsOptionLocation);
    221                 }
    222                 modelStdevData[iy][ix] = psStatsGetValue(stats, statsOptionWidth);
    223                 // fprintf (stderr, "dQ : %f - %f - %f = %f\n", stats->robustLQ, stats->robustMedian, stats->robustUQ, stats->robustUQ + stats->robustLQ - 2*stats->robustMedian);
    224                 psVectorAppend (dQ, stats->robustUQ + stats->robustLQ - 2*stats->robustMedian);
    225 
    226                 // supply sample to plotting routing
    227                 psphotDiagnosticPlots (config, "IMAGE.BACKGROUND.CELL.HISTOGRAM", ix, iy, modelData[iy][ix], modelStdevData[iy][ix], sample);
    228             } else {
    229                 psStatsOptions currentOptions = stats->options;
    230                 stats->options = PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV;
    231                 if (!psImageBackground(stats, &sample, subset, submask, maskVal, rng)) {
    232                     if ((nFailures < 3) || (nFailures % 100 == 0)) {
    233                         psLogMsg ("psphot", PS_LOG_WARN, "Failed to estimate background using ROBUST_MEDIAN for "
    234                                   "(%dx%d, (row0,col0) = (%d,%d)",
    235                                   subset->numRows, subset->numCols, subset->row0, subset->col0);
    236                     }
    237                     nFailures ++;
    238                     modelData[iy][ix] = modelStdevData[iy][ix] = NAN;
    239                 } else {
    240                     modelData[iy][ix] = psStatsGetValue (stats, PS_STAT_ROBUST_MEDIAN);
    241                     modelStdevData[iy][ix] = psStatsGetValue(stats, PS_STAT_ROBUST_STDEV);
    242 
    243                     // supply sample to plotting routing
    244                     psphotDiagnosticPlots (config, "IMAGE.BACKGROUND.CELL.HISTOGRAM", ix, iy, modelData[iy][ix], modelStdevData[iy][ix], sample);
    245                 }
    246                 // drop errors caused by psImageBackground failures
    247                 // XXX we probably should trap and exit on serious failures
    248                 psErrorClear();
    249                 stats->options = currentOptions;
    250             }
    251             psFree(sample);
    252             modelData[iy][ix] += SKY_BIAS;
    253             psFree (subset);
    254             psFree (submask);
     199            if (job->args->n < 1) {
     200                fprintf (stderr, "error with job\n");
     201            } else {
     202                psScalar *scalar = job->args->data[14];
     203                float dQvalue = scalar->data.F32;
     204                psVectorAppend (dQ, dQvalue);
     205            }
     206            psFree(job);
     207# endif
    255208        }
     209    }
     210
     211    // wait for the threads to finish and manage results
     212    if (!psThreadPoolWait (false, true)) {
     213        psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     214        return NULL;
     215    }
     216
     217    // we have only supplied one type of job, so we can assume the types here
     218    psThreadJob *job = NULL;
     219    while ((job = psThreadJobGetDone()) != NULL) {
     220        if (job->args->n < 1) {
     221            fprintf (stderr, "error with job\n");
     222        } else {
     223            psScalar *scalar = job->args->data[14];
     224            float dQvalue = scalar->data.F32;
     225            psVectorAppend (dQ, dQvalue);
     226        }
     227        psFree(job);
    256228    }
    257229
     
    302274    if (Count == 0) {
    303275        psError (PSPHOT_ERR_DATA, true, "failed to build background image");
    304         psFree(stats);
    305276        psFree(statsDefaults);
    306277        psFree(binning);
     
    318289            modelData[iy][ix] = Value;
    319290            modelStdevData[iy][ix] = ValueStdev;
     291        }
     292    }
     293
     294    // apply artificial offset if desired
     295    for (int iy = 0; iy < model->numRows; iy++) {
     296        for (int ix = 0; ix < model->numCols; ix++) {
     297            modelData[iy][ix] += SKY_BIAS;
    320298        }
    321299    }
     
    364342    psFree(dQ);
    365343
    366     psFree(stats);
    367344    psFree(statsDefaults);
    368345    psFree(binning);
     
    433410    return true;
    434411}
     412
     413bool psphotModelBackground_Threaded (psThreadJob *job) {
     414
     415    psImage *image          = job->args->data[0];
     416    psImage *mask           = job->args->data[1];
     417
     418    psImageBinning *binning = job->args->data[2];
     419
     420    psRandom *rng           = job->args->data[3];
     421    psStats *statsDefaults  = job->args->data[4];
     422
     423    psF32 **modelData       = job->args->data[5];
     424    psF32 **modelStdevData  = job->args->data[6];
     425
     426    psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[7],PS_TYPE_IMAGE_MASK_DATA);
     427
     428    int ix                  = PS_SCALAR_VALUE(job->args->data[8],S32);
     429    int iy                  = PS_SCALAR_VALUE(job->args->data[9],S32);
     430
     431    float dXsample          = PS_SCALAR_VALUE(job->args->data[10],F32);
     432    float dYsample          = PS_SCALAR_VALUE(job->args->data[11],F32);
     433
     434    psStatsOptions statsOptionLocation = PS_SCALAR_VALUE(job->args->data[12],S32);
     435    psStatsOptions statsOptionWidth    = PS_SCALAR_VALUE(job->args->data[13],S32);
     436
     437    // convert the ruff grid cell to the equivalent fine grid cell
     438    psRegion ruffRegion = psRegionSet (ix + 0.5 - 0.5*dXsample, ix + 0.5 + 0.5*dXsample, iy + 0.5 - 0.5*dYsample, iy + 0.5 + 0.5*dYsample);
     439    psRegion fineRegion = psImageBinningSetFineRegion (binning, ruffRegion);
     440    fineRegion = psRegionForImage (image, fineRegion);
     441
     442    psImage *subset  = psImageSubset (image, fineRegion);
     443    if (!subset->numCols || !subset->numRows) {
     444        psFree (subset);
     445        return false; // XXX do we / should we fail on this?
     446    }
     447    psImage *submask = psImageSubset (mask, fineRegion);
     448
     449    psStats *stats = psStatsAlloc (PS_STAT_NONE);
     450    *stats = *statsDefaults;
     451
     452    // Use the selected background statistic for the first pass
     453    // If it fails, fall back on the "ROBUST_MEDIAN" version
     454    // If both fail, set the pixel to NAN and (later) interpolate
     455
     456    psVector *sample = NULL;
     457    float dQvalue = NAN;
     458
     459    if (psImageBackground(stats, &sample, subset, submask, maskVal, rng)) {
     460        if (stats->options & PS_STAT_ROBUST_QUARTILE) {
     461            modelData[iy][ix] = stats->robustMedian;
     462        } else {
     463            modelData[iy][ix] = psStatsGetValue(stats, statsOptionLocation);
     464        }
     465        modelStdevData[iy][ix] = psStatsGetValue(stats, statsOptionWidth);
     466
     467        // fprintf (stderr, "dQ : %f - %f - %f = %f\n", stats->robustLQ, stats->robustMedian, stats->robustUQ, stats->robustUQ + stats->robustLQ - 2*stats->robustMedian);
     468        // XXX this operation is not thread safe -- move out somehow...
     469        // psVectorAppend (dQ, stats->robustUQ + stats->robustLQ - 2*stats->robustMedian);
     470        dQvalue = stats->robustUQ + stats->robustLQ - 2*stats->robustMedian;
     471        // return dQvalue to main thread
     472
     473        // supply sample to plotting routing
     474        // only allow in a non-threaded context -- can plot more than one cell
     475        // psphotDiagnosticPlots (config, "IMAGE.BACKGROUND.CELL.HISTOGRAM", ix, iy, modelData[iy][ix], modelStdevData[iy][ix], sample);
     476    } else {
     477        // psStatsOptions currentOptions = stats->options;
     478        stats->options = PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV;
     479        if (!psImageBackground(stats, &sample, subset, submask, maskVal, rng)) {
     480            if ((nFailures < 3) || (nFailures % 100 == 0)) {
     481                psLogMsg ("psphot", PS_LOG_WARN, "Failed to estimate background using ROBUST_MEDIAN for "
     482                          "(%dx%d, (row0,col0) = (%d,%d)",
     483                          subset->numRows, subset->numCols, subset->row0, subset->col0);
     484            }
     485            nFailures ++; // static
     486            modelData[iy][ix] = modelStdevData[iy][ix] = NAN;
     487        } else {
     488            modelData[iy][ix] = psStatsGetValue (stats, PS_STAT_ROBUST_MEDIAN);
     489            modelStdevData[iy][ix] = psStatsGetValue(stats, PS_STAT_ROBUST_STDEV);
     490
     491            // supply sample to plotting routing
     492            // only allow in a non-threaded context -- can plot more than one cell
     493            // psphotDiagnosticPlots (config, "IMAGE.BACKGROUND.CELL.HISTOGRAM", ix, iy, modelData[iy][ix], modelStdevData[iy][ix], sample);
     494        }
     495        // drop errors caused by psImageBackground failures
     496        // NOTE : psStats raises errors when it cannot find a solution; this
     497        // probably should not be errors but exit stats info only, but c'est la code
     498        // XXX we probably should trap and exit on serious failures
     499        psErrorClear();
     500        // stats->options = currentOptions; // this is not needed (set by init above)
     501    }
     502    psFree (stats);
     503    psFree (sample);
     504    psFree (subset);
     505    psFree (submask);
     506
     507    // return the dQvalue to the calling thread
     508    psScalar *scalar = job->args->data[14];
     509    scalar->data.F32 = dQvalue;
     510
     511    return true;
     512}
     513
     514// code for in-line plotting from above
     515// turn on stats tracing in desired cells
     516// XXX this code may need to be re-worked for a threaded context
     517# if (0)
     518    psMetadata *plots = psMetadataLookupPtr (&status, recipe, "DIAGNOSTIC.PLOTS");
     519    assert (plots);
     520
     521    int xPlot = psMetadataLookupS32 (&status, plots, "IMAGE.BACKGROUND.CELL.HISTOGRAM.X");
     522    assert (status);
     523    int yPlot = psMetadataLookupS32 (&status, plots, "IMAGE.BACKGROUND.CELL.HISTOGRAM.Y");
     524    assert (status);
     525
     526    bool gotX = (xPlot < 0) || (xPlot == ix);
     527    bool gotY = (yPlot < 0) || (yPlot == iy);
     528
     529    if (gotX && gotY) {
     530        (void) psTraceSetLevel ("psLib.math.vectorFittedStats", 6);
     531        (void) psTraceSetLevel ("psLib.math.vectorRobustStats", 6);
     532    } else {
     533        (void) psTraceSetLevel ("psLib.math.vectorFittedStats", 0);
     534        (void) psTraceSetLevel ("psLib.math.vectorRobustStats", 0);
     535    }
     536# endif
  • trunk/psphot/src/psphotModelGroupInit.c

    r25738 r35769  
    44// psModule/src/objects/models
    55
    6 # include "models/pmModel_TEST1.c"
    7 # include "models/pmModel_STRAIL.c"
     6// # include "models/pmModel_TEST1.c"
     7// # include "models/pmModel_STRAIL.c"
    88
    99static pmModelClass userModels[] = {
    10     {"PS_MODEL_TEST1", 7, pmModelFunc_TEST1,  pmModelFlux_TEST1,  pmModelRadius_TEST1,  pmModelLimits_TEST1,  pmModelGuess_TEST1, pmModelFromPSF_TEST1, pmModelParamsFromPSF_TEST1, pmModelFitStatus_TEST1, NULL},
    11     {"PS_MODEL_STRAIL", 9, pmModelFunc_STRAIL,  pmModelFlux_STRAIL,  pmModelRadius_STRAIL,  pmModelLimits_STRAIL,  pmModelGuess_STRAIL, pmModelFromPSF_STRAIL, pmModelParamsFromPSF_STRAIL, pmModelFitStatus_STRAIL, NULL},
     10    // {"PS_MODEL_TEST1", 7, pmModelFunc_TEST1,  pmModelFlux_TEST1,  pmModelRadius_TEST1,  pmModelLimits_TEST1,  pmModelGuess_TEST1, pmModelFromPSF_TEST1, pmModelParamsFromPSF_TEST1, pmModelFitStatus_TEST1, NULL},
     11    // {"PS_MODEL_STRAIL", 9, pmModelFunc_STRAIL,  pmModelFlux_STRAIL,  pmModelRadius_STRAIL,  pmModelLimits_STRAIL,  pmModelGuess_STRAIL, pmModelFromPSF_STRAIL, pmModelParamsFromPSF_STRAIL, pmModelFitStatus_STRAIL, NULL},
    1212};
    1313
  • trunk/psphot/src/psphotModelTestReadout.c

    r35559 r35769  
    161161    // get the initial model parameter guess
    162162    pmModel *model = pmSourceModelGuess (source, modelType, maskVal, markVal);
     163    if (!model) {
     164      fprintf (stderr, "failed to generate model guess\n");
     165      exit (2);
     166    }
     167
    163168    source->modelEXT = model;
    164169
     
    186191        fprintf (stderr, "guess: %f @ (%f, %f)\n", params[6]*180/M_PI, params[4], params[5]);
    187192    } else {
    188         // list model input shape
    189         psEllipseShape shape;
    190         shape.sx  = 1.4 / model->params->data.F32[4];
    191         shape.sy  = 1.4 / model->params->data.F32[5];
    192         shape.sxy = model->params->data.F32[6];
    193         axes = psEllipseShapeToAxes (shape, 20.0);
    194         fprintf (stderr, "guess: %f @ (%f, %f)\n", axes.theta*180/M_PI, axes.major, axes.minor);
     193        bool useReff = pmModelUseReff (modelType);
     194        pmModelParamsToAxes (&axes, params[PM_PAR_SXX], params[PM_PAR_SXY], params[PM_PAR_SYY], useReff);
     195        fprintf (stderr, "guess: %f @ (%f, %f) : %f\n", axes.theta*180/M_PI, axes.major, axes.minor, params[PM_PAR_SXY]);
    195196    }
    196197
     
    217218    fitOptions->covarFactor   = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix
    218219
     220    bool chisqConvergence = psMetadataLookupBool (&status, recipe, "LMM_FIT_CHISQ_CONVERGENCE"); // Fit tolerance
     221    if (!status) chisqConvergence = true;
     222    fitOptions->chisqConvergence = chisqConvergence;
     223
     224    int gainFactorMode = psMetadataLookupS32 (&status, recipe, "LMM_FIT_GAIN_FACTOR_MODE"); // Fit tolerance
     225    if (!status) gainFactorMode = 0;
     226    fitOptions->gainFactorMode = gainFactorMode;
     227
    219228    if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) {
    220229        fitOptions->mode = PM_SOURCE_FIT_NO_INDEX;
     
    231240        pmSourceModelGuessPCM (pcm, source, maskVal, markVal);
    232241      }
     242
     243      // if we provide a test guess value we want to use that value!
     244      for (int i = 0; i < nParams; i++) {
     245          if (i == PM_PAR_XPOS) continue;
     246          if (i == PM_PAR_YPOS) continue;
     247
     248          char name[32];
     249          sprintf (name, "TEST_FIT_PAR%d", i);
     250          float value = psMetadataLookupF32 (&status, recipe, name);
     251          if (status && isfinite (value)) {
     252              params[i] = value;
     253          }
     254      }
     255
    233256      pmPCMupdate(pcm, source, fitOptions, model);
    234257      pmSourceFitPCM (pcm, source, fitOptions, maskVal, markVal, psfSize);
     
    258281    }
    259282
     283    if (modelType == pmModelClassGetType("PS_MODEL_TRAIL")) {
     284        fprintf (stderr, "result: %f @ (%f, %f)\n", params[6]*180/M_PI, params[4], params[5]);
     285    } else {
     286        bool useReff = pmModelUseReff (modelType);
     287        pmModelParamsToAxes (&axes, params[PM_PAR_SXX], params[PM_PAR_SXY], params[PM_PAR_SYY], useReff);
     288        fprintf (stderr, "result: %f @ (%f, %f) : %f\n", axes.theta*180/M_PI, axes.major, axes.minor, params[PM_PAR_SXY]);
     289    }
     290
    260291    // write out
    261292    psphotSaveImage (NULL, source->pixels, "resid.fits");
  • trunk/psphot/src/psphotOutput.c

    r34796 r35769  
    379379        psF32 *outPar = source->modelEXT->params->data.F32;
    380380
    381         psEllipseShape shape;
    382 
    383         shape.sx  = outPar[PM_PAR_SXX] / M_SQRT2;
    384         shape.sy  = outPar[PM_PAR_SYY] / M_SQRT2;
    385         shape.sxy = outPar[PM_PAR_SXY];
    386 
    387         psEllipsePol pol = pmPSF_ModelToFit (outPar);
     381        bool useReff = pmModelUseReff (source->modelEXT->type);
     382
     383        psEllipseAxes axes1;
     384        pmModelParamsToAxes (&axes1, outPar[PM_PAR_SXX], outPar[PM_PAR_SXY], outPar[PM_PAR_SYY], useReff);
     385
     386        psEllipsePol pol = pmPSF_ModelToFit (outPar, useReff);
    388387        inPar[PM_PAR_E0] = pol.e0;
    389388        inPar[PM_PAR_E1] = pol.e1;
    390389        inPar[PM_PAR_E2] = pol.e2;
    391         pmPSF_FitToModel (inPar, 0.1);
    392 
    393         psEllipseAxes axes1 = psEllipseShapeToAxes (shape, 20.0);
     390        pmPSF_FitToModel (inPar, 0.1, useReff);
     391
    394392        psEllipseAxes axes2 = psEllipsePolToAxes(pol, 0.1);
    395393
  • trunk/psphot/src/psphotRadialPlot.c

    r21183 r35769  
    1515    if (nCount > 00) {
    1616        if (*kapa != 0) {
    17             KiiClose (*kapa);
     17            KapaClose (*kapa);
    1818            *kapa = 0;
    1919        }
  • trunk/psphot/src/psphotReplaceUnfit.c

    r34704 r35769  
    7777    // maskVal is used to test for rejected pixels, and must include markVal
    7878    maskVal |= markVal;
     79
     80    int NpixTotal = 0;
    7981
    8082    for (int i = 0; i < sources->n; i++) {
     
    99101
    100102        pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
     103        NpixTotal += source->pixels->numCols * source->pixels->numRows;
    101104    }
    102105
    103106    psphotVisualShowImage(readout);
    104     psLogMsg ("psphot.replace", PS_LOG_INFO, "replaced models for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.replace"));
     107    psLogMsg ("psphot.replace", PS_LOG_INFO, "replaced models for %ld objects: %f sec (%d pixels)\n", sources->n, psTimerMark ("psphot.replace"), NpixTotal);
    105108    return true;
    106109}
  • trunk/psphot/src/psphotSetThreads.c

    r35559 r35769  
    55    psThreadTask *task = NULL;
    66
     7    pmPSFThreads ();
     8
     9    task = psThreadTaskAlloc("PSPHOT_MODEL_BACKGROUND", 15);
     10    task->function = &psphotModelBackground_Threaded;
     11    psThreadTaskAdd(task);
     12    psFree(task);
     13
    714    task = psThreadTaskAlloc("PSPHOT_GUESS_MODEL", 5);
    815    task->function = &psphotGuessModel_Threaded;
     16    psThreadTaskAdd(task);
     17    psFree(task);
     18
     19    task = psThreadTaskAlloc("PSPHOT_ADD_NOISE", 6);
     20    task->function = &psphotAddOrSubNoise_Threaded;
    921    psThreadTaskAdd(task);
    1022    psFree(task);
     
    4052    psFree(task);
    4153
    42     task = psThreadTaskAlloc("PSPHOT_EXTENDED_FIT", 18);
     54    task = psThreadTaskAlloc("PSPHOT_EXTENDED_FIT", 16);
    4355    task->function = &psphotExtendedSourceFits_Threaded;
    4456    psThreadTaskAdd(task);
  • trunk/psphot/src/psphotSourceFits.c

    r35559 r35769  
    33// given a source with an existing modelPSF, attempt a full PSF fit, subtract if successful
    44
     5static int NfitBlend = 0;
     6
    57static int NfitPSF = 0;
    6 static int NfitBlend = 0;
     8static int NfitIterPSF = 0;
     9
    710static int NfitDBL = 0;
     11static int NfitIterDBL = 0;
     12static int NfitPixDBL = 0;
     13
    814static int NfitEXT = 0;
     15static int NfitIterEXT = 0;
     16static int NfitPixEXT = 0;
     17
    918static int NfitPCM = 0;
     19static int NfitIterPCM = 0;
     20static int NfitPixPCM = 0;
    1021
    1122bool psphotFitInit (int nThreads) {
     
    1728bool psphotFitSummary () {
    1829
    19     psLogMsg ("psphot.pspsf", PS_LOG_INFO, "fitted %5d psf, %5d blend, %5d ext, %5d dbl : %6.2f sec\n",
    20               NfitPSF, NfitBlend, NfitEXT, NfitDBL, psTimerMark ("psphot.fits"));
     30    psLogMsg ("psphot.pspsf", PS_LOG_INFO, "fitted %5d psf (%d iter), %5d blend: %5d ext (%d iter, %d pix), %5d dbl (%d iter, %d pix) : %6.2f sec\n",
     31              NfitPSF, NfitIterPSF, NfitBlend, NfitEXT, NfitIterEXT, NfitPixEXT, NfitDBL, NfitIterDBL, NfitPixDBL, psTimerMark ("psphot.fits"));
     32    return true;
     33}
     34
     35bool psphotFitSummaryExtended () {
     36
     37    psLogMsg ("psphot.pspsf", PS_LOG_INFO, "fitted %5d ext (%d iter, %d pix), %5d pcm (%d iter, %d pix)\n",
     38              NfitEXT, NfitIterEXT, NfitPixEXT, NfitPCM, NfitIterPCM, NfitPixPCM);
     39    return true;
     40}
     41
     42bool psphotFitInitExtended () {
     43    NfitEXT = 0;
     44    NfitIterEXT = 0;
     45    NfitPixEXT = 0;
     46    NfitPCM = 0;
     47    NfitIterPCM = 0;
     48    NfitPixPCM = 0;
    2149    return true;
    2250}
     
    169197    options.mode = PM_SOURCE_FIT_PSF;
    170198    pmSourceFitModel (source, PSF, &options, maskVal);
     199    NfitIterPSF += PSF->nIter;
    171200
    172201    if (!isfinite(PSF->params->data.F32[PM_PAR_I0])) psAbort("nan in fit");
     
    268297    {
    269298        // XXX need to handle failures better here
    270         EXT = psphotFitEXT (readout, source, fitOptions, modelTypeEXT, maskVal, markVal);
     299        EXT = psphotFitEXT (NULL, readout, source, fitOptions, modelTypeEXT, maskVal, markVal);
    271300        if (!EXT) goto escape;
    272301        if (!isfinite(EXT->params->data.F32[PM_PAR_I0])) goto escape;
     
    440469    options.mode = PM_SOURCE_FIT_PSF;
    441470    pmSourceFitSet (source, modelSet, &options, maskVal);
     471    NfitIterDBL += DBL->nIter;
     472    NfitPixDBL += DBL->nDOF;
     473
    442474    return (modelSet);
    443475}
    444476
    445 pmModel *psphotFitEXT (pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, pmModelType modelType, psImageMaskType maskVal, psImageMaskType markVal) {
     477pmModel *psphotFitEXT (pmModel *guessModel, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, pmModelType modelType, psImageMaskType maskVal, psImageMaskType markVal) {
    446478
    447479    if ((source->moments->Mxx < 1e-3) || (source->moments->Myy < 1e-3)) {
     
    457489
    458490    // use the source moments, etc to guess basic model parameters
    459     pmModel *model = pmSourceModelGuess (source, modelType, maskVal, markVal);
     491    pmModel *model = guessModel ? guessModel : pmSourceModelGuess (source, modelType, maskVal, markVal);
    460492    if (!model) {
    461493        psTrace ("psphot", 5, "failed to generate a model for source: moments: %f %f\n", source->moments->Mxx, source->moments->Myy);
     
    507539
    508540    pmSourceFitModel (source, model, &options, maskVal);
     541    NfitIterEXT += model->nIter;
     542    NfitPixEXT += model->nDOF;
    509543
    510544# if (PS_TRACE_ON)
     
    587621    // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 5);
    588622    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);  // NOTE : 1687 allocs in here
     623    NfitIterPCM += pcm->modelConv->nIter;
     624    NfitPixPCM += pcm->modelConv->nDOF;
    589625    if (TIMING) { t5 = psTimerMark ("psphotFitPCM"); }
    590626
  • trunk/psphot/src/psphotStackImageLoop.c

  • trunk/psphot/src/psphotVisual.c

    r34404 r35769  
    2929bool psphotVisualClose(void)
    3030{
    31     if(kapa1 != -1) KiiClose(kapa1);
    32     if(kapa2 != -1) KiiClose(kapa2);
    33     if(kapa3 != -1) KiiClose(kapa3);
     31    if(kapa1 != -1) KapaClose(kapa1);
     32    if(kapa2 != -1) KapaClose(kapa2);
     33    if(kapa3 != -1) KapaClose(kapa3);
    3434    return true;
    3535}
Note: See TracChangeset for help on using the changeset viewer.