IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 5, 2012, 5:19:48 PM (14 years ago)
Author:
mhuber
Message:

merging latest r33407 trunk changes to meh_branches/ppstack_test

Location:
branches/meh_branches/ppstack_test
Files:
62 edited
22 copied

Legend:

Unmodified
Added
Removed
  • branches/meh_branches/ppstack_test

  • branches/meh_branches/ppstack_test/psphot

  • branches/meh_branches/ppstack_test/psphot/src

  • branches/meh_branches/ppstack_test/psphot/src/Makefile.am

    r31452 r33415  
    2525libpsphot_la_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
    2626
    27 bin_PROGRAMS = psphot psphotForced psphotMakePSF psphotStack
     27bin_PROGRAMS = psphot psphotForced psphotMakePSF psphotStack psphotModelTest
    2828# bin_PROGRAMS = psphotPetrosianStudy psphotTest psphotMomentsStudy
    2929
     
    4343psphotStack_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
    4444psphotStack_LDADD = libpsphot.la
     45
     46psphotModelTest_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
     47psphotModelTest_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
     48psphotModelTest_LDADD = libpsphot.la
    4549
    4650# psphotMomentsStudy_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
     
    102106        psphotCleanup.c
    103107
     108# a psphot-variant that simply generates the PSF model
     109psphotModelTest_SOURCES = \
     110        psphotModelTest.c            \
     111        psphotModelTestArguments.c   \
     112        psphotParseCamera.c        \
     113        psphotImageLoop.c   \
     114        psphotMosaicChip.c         \
     115        psphotCleanup.c
     116
    104117# psphotTest_SOURCES = \
    105118#         psphotTest.c
     
    117130        psphotVisual.c                 \
    118131        psphotCullPeaks.c              \
     132        psphotFootprintSaddles.c       \
    119133        psphotVersion.c                \
    120134        psphotModelGroupInit.c         \
     
    129143        psphotMakePSFReadout.c         \
    130144        psphotModelBackground.c        \
     145        psphotModelTestReadout.c       \
    131146        psphotMaskBackground.c         \
    132147        psphotSubtractBackground.c     \
     
    157172        psphotExtendedSourceAnalysisByObject.c \
    158173        psphotExtendedSourceFits.c     \
     174        psphotSersicModelClass.c       \
    159175        psphotKernelFromPSF.c          \
    160176        psphotFitSet.c                 \
     
    168184        psphotRadialPlot.c             \
    169185        psphotKronMasked.c             \
     186        psphotKronIterate.c            \
     187        psphotRadialProfileWings.c     \
    170188        psphotDeblendSatstars.c        \
    171189        psphotMosaicSubimage.c         \
     
    184202        psphotRadialBins.c             \
    185203        psphotRadialApertures.c        \
    186         psphotRadialAperturesByObject.c \
    187204        psphotPetrosian.c              \
    188205        psphotPetrosianRadialBins.c    \
     
    190207        psphotPetrosianVisual.c        \
    191208        psphotEfficiency.c
    192 
    193 # XXX need to fix this for the new apis
    194 #       psphotModelTest.c             
    195209
    196210# re-instate these
  • branches/meh_branches/ppstack_test/psphot/src/psphot.c

    r31673 r33415  
    2727    }
    2828
    29     psLogMsg ("psphot", 3, "complete psphot run: %f sec\n", psTimerMark ("complete"));
     29    psLogMsg ("psphot", PS_LOG_WARN, "complete psphot run: %f sec\n", psTimerMark ("complete"));
    3030
    3131    psErrorCode exit_status = psphotGetExitStatus();
  • branches/meh_branches/ppstack_test/psphot/src/psphot.h

    r31452 r33415  
    1919    PSPHOT_FORCED,
    2020    PSPHOT_MAKE_PSF,
     21    PSPHOT_MODEL_TEST,
    2122} psphotImageLoopMode;
    2223
     
    107108bool            psphotBlendFit_Threaded (psThreadJob *job);
    108109
    109 bool            psphotReplaceAllSources (pmConfig *config, const pmFPAview *view, const char *filerule);
    110 bool            psphotReplaceAllSourcesReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe);
     110bool            psphotReplaceAllSources (pmConfig *config, const pmFPAview *view, const char *filerule, bool ignoreState);
     111bool            psphotReplaceAllSourcesReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, bool ignoreState);
    111112
    112113bool            psphotAddNoise (pmConfig *config, const pmFPAview *view, const char *filerule);
     
    117118bool            psphotExtendedSourceAnalysis (pmConfig *config, const pmFPAview *view, const char *filerule);
    118119bool            psphotExtendedSourceAnalysisReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe);
     120bool            psphotExtendedSourceAnalysis_Threaded (psThreadJob *job);
    119121
    120122bool            psphotExtendedSourceFits (pmConfig *config, const pmFPAview *view, const char *filerule);
     
    174176
    175177// in psphotReplaceUnfit.c:
    176 bool            psphotRemoveAllSources (const psArray *sources, const psMetadata *recipe);
     178bool            psphotRemoveAllSourcesByArray (const psArray *sources, const psMetadata *recipe);
     179bool            psphotRemoveAllSources (pmConfig *config, const pmFPAview *view, const char *filerule, bool ignoreState);
     180bool            psphotRemoveAllSourcesReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool ignoreState);
    177181bool            psphotReplaceUnfitSources (psArray *sources, psImageMaskType maskVal);
    178182
     
    327331bool psphotMakePSFReadout(pmConfig *config, const pmFPAview *view, const char *filerule);
    328332
     333pmConfig *psphotModelTestArguments(int argc, char **argv);
     334bool psphotModelTestReadout(pmConfig *config, const pmFPAview *view, const char *filerule);
     335
    329336int psphotFileruleCount(const pmConfig *config, const char *filerule);
    330337bool psphotFileruleCountSet(const pmConfig *config, const char *filerule, int num);
     
    372379    bool convolve;                      // Convolve images?
    373380    psphotStackConvolveSource convolveSource;
    374     // psArray *convImages, *convMasks, *convVariances; // Filenames for the temporary convolved images
    375 
    376     // bool matchZPs;                      // Adjust relative fluxes based on transparency analysis?
    377     // bool photometry;                    // Perform photometry?
    378     // psMetadata *stats;                  // Statistics for output
    379     // FILE *statsFile;                    // File to which to write statistics
    380     // psArray *origImages, *origMasks, *origVariances; // Filenames of the original images
    381     // psArray *origCovars;                // Original covariances matrices
    382     // int quality;                        // Bad data quality flag
    383381
    384382    // Prepare
     
    387385    psVector *inputMask;                // Mask for inputs
    388386
    389     float targetSeeing;                 // Target seeing FWHM
     387    psVector *targetSeeing;             // Target seeing FWHMs
    390388    psArray *sourceLists;               // Individual lists of sources for matching
    391389    psVector *norm;                     // Normalisation for each image
    392390    psArray *psfs;
    393 
    394     // psVector *exposures;                // Exposure times
    395     // float sumExposure;                  // Sum of exposure times
    396     // float zp;                           // Zero point for output
    397     // psVector *inputMask;                // Mask for inputs
    398     // psArray *sources;                   // Matched sources
    399391
    400392    // Convolve
     
    402394    psArray *regions;                   // PSF-matching regions --- required in the stacking
    403395    psVector *matchChi2;                // chi^2 for stamps from matching
    404     psVector *weightings;               // Combination weightings for images (1/noise^2)
    405     // psArray *cells;                     // Cells for convolved images --- a handle for reading again
    406     // int numCols, numRows;               // Size of image
    407     // psArray *convCovars;                // Convolved covariance matrices
    408 
    409     // Combine initial
    410     // pmReadout *outRO;                   // Output readout
    411     // pmReadout *expRO;                   // Exposure readout
    412     // psArray *inspect;                   // Array of arrays of pixels to inspect
    413 
    414     // Rejection
    415     // psArray *rejected;                  // Rejected pixels
    416396} psphotStackOptions;
    417397
     
    420400bool psphotStackMatchPSFsReadout (pmConfig *config, const pmFPAview *view, psphotStackOptions *options, int index);
    421401bool psphotStackMatchPSFsPrepare (pmConfig *config, const pmFPAview *view, psphotStackOptions *options, int index);
    422 bool psphotStackMatchPSFsNext (bool *smoothAgain, pmConfig *config, const pmFPAview *view, const char *filerule, int lastSize);
    423 bool psphotStackMatchPSFsNextReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, psVector *fwhmValues, int lastSize);
     402
     403bool psphotStackMatchPSFsNext (pmConfig *config, const pmFPAview *view, const char *filerule, int lastSize);
     404bool psphotStackMatchPSFsNextReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, int lastSize);
     405int psphotStackMatchPSFsEntries (pmConfig *config, const pmFPAview *view, const char *filerule);
    424406
    425407// psphotStackMatchPSFsUtils
    426 psVector *SetOptWidths (bool *optimum, psMetadata *recipe);
    427 pmReadout *makeFakeReadout(pmConfig *config, pmReadout *raw, psArray *sources, pmPSF *psf, psImageMaskType maskVal, int fullSize);
    428 bool rescaleData(pmReadout *readout, pmConfig *config, psphotStackOptions *options, int index);
    429 bool renormKernel(pmReadout *readout, psphotStackOptions *options, int index);
     408// psVector *SetOptWidths (bool *optimum, psMetadata *recipe);
     409// pmReadout *makeFakeReadout(pmConfig *config, pmReadout *raw, psArray *sources, pmPSF *psf, psImageMaskType maskVal, int fullSize);
     410// bool rescaleData(pmReadout *readout, pmConfig *config, psphotStackOptions *options, int index);
     411// bool renormKernel(pmReadout *readout, psphotStackOptions *options, int index);
    430412bool saveMatchData (pmReadout *readout, psphotStackOptions *options, int index);
    431413bool matchKernel(pmConfig *config, pmReadout *cnv, pmReadout *raw, psphotStackOptions *options, int index);
    432 bool dumpImageDiff(pmReadout *readoutConv, pmReadout *readoutFake, pmReadout *readoutRef, int index, char *rootname);
    433 bool dumpImage(pmReadout *readoutOut, pmReadout *readoutRef, int index, char *rootname);
    434 bool loadKernel (pmConfig *config, pmReadout *readoutCnv, psphotStackOptions *options, int index);
    435 
    436 pmPSF *psphotStackPSF(const pmConfig *config, int numCols, int numRows, const psArray *psfs, const psVector *inputMask);
     414// bool dumpImageDiff(pmReadout *readoutConv, pmReadout *readoutFake, pmReadout *readoutRef, int index, char *rootname);
     415// bool dumpImage(pmReadout *readoutOut, pmReadout *readoutRef, int index, char *rootname);
     416// bool loadKernel (pmConfig *config, pmReadout *readoutCnv, psphotStackOptions *options, int index);
     417
     418bool psphotStackRenormaliseVariance(const pmConfig *config, pmReadout *readout);
     419
     420bool psphotStackPSF(const pmConfig *config, psphotStackOptions *options);
    437421
    438422psphotStackOptions *psphotStackOptionsAlloc (int num);
     
    443427bool psphotCopySourcesReadout (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc, int index);
    444428
    445 bool psphotRadialApertures (pmConfig *config, const pmFPAview *view, const char *filerule);
    446 bool psphotRadialAperturesReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe);
    447 bool psphotRadialApertureSource (pmSource *source, psMetadata *recipe, psImageMaskType maskVal, const psVector *radMax, int entry);
     429bool psphotRadialApertures (pmConfig *config, const pmFPAview *view, const char *filerule, int entry);
     430bool psphotRadialAperturesReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, int entry);
     431bool psphotRadialApertures_Threaded (psThreadJob *job);
     432bool psphotRadialApertureSource (pmSource *source, pmReadout *readout, int entry, psVector *pixRadius2, psVector *pixFlux, psVector *pixVer);
     433// bool psphotRadialApertureSource (pmSource *source, int entry);
    448434
    449435bool psphotExtendedSourceAnalysisByObject (pmConfig *config, psArray *objects, const pmFPAview *view, const char *filerule);
     
    469455psArray *psphotSourceChildrenByObject (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objectsSrc);
    470456
     457bool psphotSourceParents (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc);
     458bool psphotSourceParentsReadout (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc, int index);
     459
     460bool psphotCopyPeaks (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc);
     461bool psphotCopyPeaksReadout (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc, int index);
     462
     463bool psphotSersicModelClassGuessPCM (pmPCMdata *pcm, pmSource *source);
     464void psphotSersicModelClassInit ();
     465void psphotSersicModelClassCleanup ();
     466
     467bool psphotSetRadiusMoments (float *fitRadius, float *windowRadius, pmReadout *readout, pmSource *source, psImageMaskType markVal);
     468bool psphotSetRadiusMomentsExact (float *fitRadius, float *windowRadius, pmReadout *readout, pmSource *source, psImageMaskType markVal);
     469
     470bool psphotFootprintSaddles(pmReadout *readout, psArray *footprints);
     471bool psphotMaskFootprint (pmReadout *readout, pmSource *source, psImageMaskType markVal);
     472
     473bool psphotKronIterate (pmConfig *config, const pmFPAview *view, const char *filerule);
     474bool psphotKronIterateReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, pmReadout *readout, psArray *sources, pmPSF *psf);
     475bool psphotKronIterate_Threaded (psThreadJob *job);
     476
     477bool psphotRadialProfileWings (pmConfig *config, const pmFPAview *view, const char *filerule);
     478bool psphotRadialProfileWingsReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, pmReadout *readout, psArray *sources);
     479bool psphotRadialProfileWings_Threaded (psThreadJob *job);
     480
     481bool psphotStackObjectsSelectForAnalysis (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects);
     482
    471483#endif
  • branches/meh_branches/ppstack_test/psphot/src/psphotAddNoise.c

    r29936 r33415  
    8585    }
    8686    if (add) {
    87         psLogMsg ("psphot.noise", PS_LOG_INFO, "add noise for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.noise"));
     87        psLogMsg ("psphot.noise", PS_LOG_WARN, "add noise for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.noise"));
    8888    } else {
    89         psLogMsg ("psphot.noise", PS_LOG_INFO, "sub noise for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.noise"));
     89        psLogMsg ("psphot.noise", PS_LOG_WARN, "sub noise for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.noise"));
    9090    }
    9191
  • branches/meh_branches/ppstack_test/psphot/src/psphotApResid.c

    r31452 r33415  
    11# include "psphotInternal.h"
    2 # define DEBUG
     2// # define DEBUG
    33
    44# define SKIPSTAR(MSG) { psTrace ("psphot", 3, "invalid : %s", MSG); continue; }
     
    99{
    1010    bool status = true;
     11
     12    fprintf (stdout, "\n");
     13    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Aperture Residuals ---");
    1114
    1215    // select the appropriate recipe information
     
    151154
    152155        // wait for the threads to finish and manage results
    153         if (!psThreadPoolWait (false)) {
     156        if (!psThreadPoolWait (false, true)) {
    154157            psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     158            psFree(cellGroups);
    155159            return false;
    156160        }
     
    347351
    348352    psLogMsg ("psphot.apresid", PS_LOG_DETAIL, "aperture residual: %f +/- %f\n", psf->ApResid, psf->dApResid);
    349     psLogMsg ("psphot.apresid", PS_LOG_INFO, "measure full-frame aperture residuals for %d sources: %f sec\n", Npsf, psTimerMark ("psphot.apresid"));
     353    psLogMsg ("psphot.apresid", PS_LOG_WARN, "measure full-frame aperture residuals for %d sources: %f sec\n", Npsf, psTimerMark ("psphot.apresid"));
    350354
    351355    psFree (xPos);
  • branches/meh_branches/ppstack_test/psphot/src/psphotBlendFit.c

    r31452 r33415  
    55{
    66    bool status = true;
     7
     8    fprintf (stdout, "\n");
     9    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Fit Sources (Non-Linear) ---");
    710
    811    // select the appropriate recipe information
     
    148151
    149152        // wait for the threads to finish and manage results
    150         if (!psThreadPoolWait (false)) {
     153        if (!psThreadPoolWait (false, true)) {
    151154            psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
    152155            psFree (fitOptions);
     
    186189    psFree (fitOptions);
    187190
    188     psLogMsg ("psphot.psphotBlendFit", PS_LOG_INFO, "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);
     191    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);
    189192
    190193    psphotVisualShowResidualImage (readout, false);
     
    233236        pmSource *source = sources->data[i];
    234237
     238# if (0)
     239# define TEST_X 34
     240# define TEST_Y 28
     241   
     242        if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) {
     243            fprintf (stderr, "test object\n");
     244        }
     245
     246# undef TEST_X
     247# undef TEST_Y
     248# endif
     249
    235250        // skip non-astronomical objects (very likely defects)
    236251        if (source->mode &  PM_SOURCE_MODE_BLEND) continue;
     
    246261
    247262        // limit selection to some SN limit
    248         if (sqrt(source->peak->detValue) < FIT_SN_LIM) continue;
    249 
     263        if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
     264            if (source->moments->KronFlux < FIT_SN_LIM * source->moments->KronFluxErr) continue;
     265        } else {
     266            if (sqrt(source->peak->detValue) < FIT_SN_LIM) continue;
     267        }
    250268        // exclude sources outside optional analysis region
    251269        if (source->peak->xf < AnalysisRegion.x0) continue;
     
    267285        }
    268286
    269         // replace object in image
     287        // replace object in image & remove excess noise
    270288        if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {
    271289            pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
     
    305323        Nfail ++;
    306324
    307         // re-subtract the object, leave local sky
     325        // re-subtract the object, leave local sky, re-bump noise
    308326        pmSourceCacheModel (source, maskVal);
    309327        pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
  • branches/meh_branches/ppstack_test/psphot/src/psphotChoosePSF.c

    r31673 r33415  
    55{
    66    bool status = true;
     7
     8    fprintf (stdout, "\n");
     9    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Choose PSF ---");
    710
    811    // select the appropriate recipe information
     
    376379
    377380    char *modelName = pmModelClassGetName (psf->type);
    378     psLogMsg ("psphot.pspsf", PS_LOG_INFO, "select psf model: %f sec\n", psTimerMark ("psphot.choose.psf"));
     381    psLogMsg ("psphot.pspsf", PS_LOG_WARN, "select psf model: %f sec\n", psTimerMark ("psphot.choose.psf"));
    379382    psLogMsg ("psphot.pspsf", PS_LOG_INFO, "psf model %s, ApResid: %f +/- %f\n", modelName, psf->ApResid, psf->dApResid);
    380383
     
    443446            psVectorAppend (fwhmMinor, FWHM_MINOR);
    444447
    445             if (modelPSF->params->n >= 7) {
     448            if (modelPSF->params->n > 7) {
    446449              psVectorAppend (psfExtra1, modelPSF->params->data.F32[7]);
    447450            }
    448             if (modelPSF->params->n >= 8) {
     451            if (modelPSF->params->n > 8) {
    449452              psVectorAppend (psfExtra2, modelPSF->params->data.F32[8]);
    450453            }
     
    517520    }
    518521
    519     // psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "ANGLE",    PS_META_REPLACE, "PSF angle",           axes.theta);
     522    psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "ANGLE",    PS_META_REPLACE, "PSF angle",           axes.theta);
    520523    psMetadataAddS32 (readout->analysis, PS_LIST_TAIL, "NPSFSTAR", PS_META_REPLACE, "Number of stars used to make PSF", psf->nPSFstars);
    521524
  • branches/meh_branches/ppstack_test/psphot/src/psphotEfficiency.c

    r31452 r33415  
    9999
    100100/// Generate a fake image and add it in to the existing readout
    101 static bool effGenerate(psImage **xSrc, psImage **ySrc, // Positions of sources
     101static pmReadout *effGenerate(psImage **xSrc, psImage **ySrc, // Positions of sources
    102102                        const pmReadout *ro,            // Readout of interest
    103103                        const pmPSF *psf,               // Point-spread function
     
    152152        psFree(xAll);
    153153        psFree(yAll);
    154         return false;
     154        return NULL;
    155155    }
    156156    psFree(magAll);
     
    161161
    162162    psBinaryOp(ro->image, ro->image, "+", fakeRO->image);
    163     psFree(fakeRO);
    164 
    165     return true;
     163
     164    // return the readout so we can subtract it later
     165    return fakeRO;
    166166}
    167167
     
    169169{
    170170    bool status = true;
     171
     172    fprintf (stdout, "\n");
     173    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Efficiency ---");
    171174
    172175    // select the appropriate recipe information
     
    252255
    253256    // remove all sources, adding noise for subtracted sources
    254     psphotRemoveAllSources(realSources, recipe);
     257    psphotRemoveAllSourcesByArray(realSources, recipe);
    255258
    256259#if TESTING
     
    290293
    291294    psImage *xFake = NULL, *yFake = NULL; // Coordinates of sources, each bin in a row
    292     if (!effGenerate(&xFake, &yFake, readout, psf, magOffsets,
    293                      numSources, magLim, radius, minFlux)) {
     295    pmReadout *fakeRO = effGenerate(&xFake, &yFake, readout, psf, magOffsets, numSources, magLim, radius, minFlux);
     296    if (!fakeRO) {
    294297        psError(PS_ERR_UNKNOWN, false, "Unable to generate fake sources");
    295298        psFree(xFake);
     
    416419    psFree(significance);
    417420
     421    // psphotFitSourcesLinearReadout subtracts the model fits
    418422    if (!psphotFitSourcesLinearReadout(recipe, readout, fakeSourcesAll, psf, true)) {
    419423        psError(PS_ERR_UNKNOWN, false, "Unable to perform linear fit on fake sources.");
     
    427431    psf->ApTrend = NULL;
    428432
     433    // measure the magnitudes and fluxes for the sources
    429434    if (!psphotMagnitudesReadout(config, recipe, view, readout, fakeSourcesAll, psf)) {
    430435        psError(PS_ERR_UNKNOWN, false, "Unable to measure magnitudes of fake sources.");
     
    433438        psf->ApTrend = apTrend; // Casting away const!
    434439        return false;
     440    }
     441
     442    // replace the subtracted model fits
     443    for (int i = 0; i < fakeSourcesAll->n; i++) {
     444        pmSource *source = fakeSourcesAll->data[i];
     445
     446        // replace other sources?
     447        if (!(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED)) continue;
     448       
     449        pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
    435450    }
    436451    psFree(fakeSourcesAll);
     
    515530    psFree(fakeSources);
    516531
     532    // subtract the faked sources from the original image
     533    psBinaryOp(readout->image, readout->image, "-", fakeRO->image);
     534    psFree(fakeRO);
     535
    517536    pmDetEff *de = pmDetEffAlloc(magLim, numSources, numBins); // Detection efficiency
    518537    de->magOffsets = psVectorCopy(NULL, magOffsets, PS_TYPE_F32);
     
    529548    psFree(de);
    530549
    531     psLogMsg("psphot", PS_LOG_INFO, "Detection efficiency: %lf sec\n", psTimerClear("psphot.fake"));
     550    psLogMsg("psphot", PS_LOG_WARN, "Detection efficiency: %lf sec\n", psTimerClear("psphot.fake"));
    532551
    533552    return true;
  • branches/meh_branches/ppstack_test/psphot/src/psphotEllipticalContour.c

    r29004 r33415  
    127127psF32 psphotEllipticalContourFunc (psVector *deriv, const psVector *params, const psVector *coord) {
    128128
    129     static int pass = 0;
    130 
    131129    psF32 *par = params->data.F32;
    132130
     
    145143
    146144    // value is X
    147     // if (coord->data.F32[1] == 0) {
    148     if (pass == 0) {
    149         pass = 1;
    150 
     145    if (coord->data.F32[1] < 0.5) {
    151146        float value = par[PAR_RMIN]*cs_alpha*r;
    152147
     
    161156
    162157    // value is Y
    163     // if (coord->data.F32[1] == 1) {
    164     if (pass == 1) {
    165         pass = 0;
    166 
     158    if (coord->data.F32[1] > 0.5) {
    167159        float value = par[PAR_RMIN]*sn_alpha*r;
    168160
  • branches/meh_branches/ppstack_test/psphot/src/psphotExtendedSourceAnalysis.c

    r31154 r33415  
    22
    33// measure the elliptical radial profile and use this to measure the petrosian parameters for the sources
    4 // XXX this function needs to be threaded
    54
    65// for now, let's store the detections on the readout->analysis for each readout
     
    87{
    98    bool status = true;
     9
     10    fprintf (stdout, "\n");
     11    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Extended Source Analysis (Petrosians) ---");
    1012
    1113    // select the appropriate recipe information
     
    5961    }
    6062
    61     // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
    62     psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels
    63     assert (maskVal);
     63    // determine the number of allowed threads
     64    int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads
     65    if (!status) {
     66        nThreads = 0;
     67    }
    6468
    6569    // get the sky noise from the background analysis; if this is missing, get the user-supplied value
     
    7074    }
    7175
     76    // source analysis is done in S/N order (brightest first)
     77    sources = psArraySort (sources, pmSourceSortByFlux);
     78
     79    // option to limit analysis to a specific region
     80    char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION");
     81    psRegion *AnalysisRegion = psRegionAlloc(0,0,0,0);
     82    *AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region));
     83    if (psRegionIsNaN (*AnalysisRegion)) psAbort("analysis region mis-defined");
     84
     85    // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts)
     86    int Cx = 1, Cy = 1;
     87    psphotChooseCellSizes (&Cx, &Cy, readout, nThreads);
     88
     89    psArray *cellGroups = psphotAssignSources (Cx, Cy, sources);
     90
     91    for (int i = 0; i < cellGroups->n; i++) {
     92
     93        psArray *cells = cellGroups->data[i];
     94
     95        for (int j = 0; j < cells->n; j++) {
     96
     97            // allocate a job -- if threads are not defined, this just runs the job
     98            psThreadJob *job = psThreadJobAlloc ("PSPHOT_EXTENDED_ANALYSIS");
     99
     100            psArrayAdd(job->args, 1, readout);
     101            psArrayAdd(job->args, 1, cells->data[j]); // sources
     102            psArrayAdd(job->args, 1, AnalysisRegion);
     103            psArrayAdd(job->args, 1, recipe);
     104
     105            PS_ARRAY_ADD_SCALAR(job->args, skynoise, PS_TYPE_F32);
     106
     107            PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Next
     108            PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Npetro
     109            PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nannuli
     110
     111// set this to 0 to run without threading
     112# if (1)           
     113            if (!psThreadJobAddPending(job)) {
     114                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     115                psFree(AnalysisRegion);
     116                return false;
     117            }
     118# else
     119            if (!psphotExtendedSourceAnalysis_Threaded(job)) {
     120                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     121                psFree(AnalysisRegion);
     122                return false;
     123            }
     124            psScalar *scalar = NULL;
     125            scalar = job->args->data[5];
     126            Next += scalar->data.S32;
     127            scalar = job->args->data[6];
     128            Npetro += scalar->data.S32;
     129            scalar = job->args->data[7];
     130            Nannuli += scalar->data.S32;
     131            psFree(job);
     132# endif
     133        }
     134
     135        // wait for the threads to finish and manage results
     136        if (!psThreadPoolWait (false, true)) {
     137            psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     138            psFree(AnalysisRegion);
     139            return false;
     140        }
     141
     142        // we have only supplied one type of job, so we can assume the types here
     143        psThreadJob *job = NULL;
     144        while ((job = psThreadJobGetDone()) != NULL) {
     145            if (job->args->n < 1) {
     146                fprintf (stderr, "error with job\n");
     147            } else {
     148                psScalar *scalar = NULL;
     149                scalar = job->args->data[5];
     150                Next += scalar->data.S32;
     151                scalar = job->args->data[6];
     152                Npetro += scalar->data.S32;
     153                scalar = job->args->data[7];
     154                Nannuli += scalar->data.S32;
     155            }
     156            psFree(job);
     157        }
     158    }
     159    psFree (cellGroups);
     160    psFree(AnalysisRegion);
     161
     162    psLogMsg ("psphot", PS_LOG_WARN, "extended source analysis: %f sec for %d objects\n", psTimerMark ("psphot.extended"), Next);
     163    psLogMsg ("psphot", PS_LOG_INFO, "  %d petrosian\n", Npetro);
     164    psLogMsg ("psphot", PS_LOG_INFO, "  %d annuli\n", Nannuli);
     165
     166    psphotVisualShowResidualImage (readout, false);
     167
     168    bool doPetrosian    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PETROSIAN");
     169    if (doPetrosian) {
     170        psphotVisualShowPetrosians (sources);
     171    }
     172
     173    return true;
     174}
     175
     176bool psphotExtendedSourceAnalysis_Threaded (psThreadJob *job) {
     177
     178    bool status;
     179
     180    int Next = 0;
     181    int Npetro = 0;
     182    int Nannuli = 0;
     183
     184    // arguments: readout, sources, models, region, psfSize, maskVal, markVal
     185    pmReadout *readout      = job->args->data[0];
     186    psArray *sources        = job->args->data[1];
     187    psRegion *region        = job->args->data[2];
     188    psMetadata *recipe      = job->args->data[3];
     189
     190    float skynoise          = PS_SCALAR_VALUE(job->args->data[4],F32);
     191
    72192    // S/N limit to perform full non-linear fits
    73193    float SN_LIM = psMetadataLookupF32 (&status, recipe, "EXTENDED_SOURCE_SN_LIM");
     
    78198    bool doPetroStars   = psMetadataLookupBool (&status, recipe, "PETROSIAN_FOR_STARS");
    79199
    80     // source analysis is done in S/N order (brightest first)
    81     sources = psArraySort (sources, pmSourceSortByFlux);
    82 
    83     // option to limit analysis to a specific region
    84     char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION");
    85     psRegion AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region));
    86     if (psRegionIsNaN (AnalysisRegion)) psAbort("analysis region mis-defined");
     200    // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
     201    psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels
     202    assert (maskVal);
    87203
    88204    // choose the sources of interest
     
    90206
    91207        pmSource *source = sources->data[i];
     208
     209        // if we have checked the source validity on the basis of the object set, then
     210        // we either skip these tests below or we skip the source completely
     211        if (source->tmpFlags & PM_SOURCE_TMPF_PETRO_SKIP) continue;
     212        if (source->tmpFlags & PM_SOURCE_TMPF_PETRO_KEEP) goto keepSource;
    92213
    93214        // skip PSF-like and non-astronomical objects
     
    104225
    105226        // limit selection to some SN limit
    106         assert (source->peak); // how can a source not have a peak?
    107         if (sqrt(source->peak->detValue) < SN_LIM) continue;
    108 
    109         // limit selection by analysis region
    110         if (source->peak->x < AnalysisRegion.x0) continue;
    111         if (source->peak->y < AnalysisRegion.y0) continue;
    112         if (source->peak->x > AnalysisRegion.x1) continue;
    113         if (source->peak->y > AnalysisRegion.y1) continue;
     227        // assert (source->peak); // how can a source not have a peak?
     228        // limit selection to some SN limit
     229        bool skipSource = false;
     230        if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
     231            skipSource = (source->moments->KronFlux < SN_LIM * source->moments->KronFluxErr);
     232        } else {
     233            skipSource = (sqrt(source->peak->detValue) < SN_LIM);
     234        }
     235        if (skipSource) continue;
     236
     237        // limit selection by analysis region (this automatically apply
     238        if (source->peak->x < region->x0) continue;
     239        if (source->peak->y < region->y0) continue;
     240        if (source->peak->x > region->x1) continue;
     241        if (source->peak->y > region->y1) continue;
     242
     243    keepSource:
    114244
    115245        // replace object in image
     
    159289    }
    160290
    161     psLogMsg ("psphot", PS_LOG_INFO, "extended source analysis: %f sec for %d objects\n", psTimerMark ("psphot.extended"), Next);
    162     psLogMsg ("psphot", PS_LOG_INFO, "  %d petrosian\n", Npetro);
    163     psLogMsg ("psphot", PS_LOG_INFO, "  %d annuli\n", Nannuli);
    164 
    165     psphotVisualShowResidualImage (readout, false);
    166 
    167     if (doPetrosian) {
    168         psphotVisualShowPetrosians (sources);
    169     }
    170 
    171     // fprintf (stderr, "xsrc : tried %ld objects\n", sources->n);
     291    psScalar *scalar = NULL;
     292
     293    // change the value of a scalar on the array (wrap this and put it in psArray.h)
     294    scalar = job->args->data[5];
     295    scalar->data.S32 = Next;
     296
     297    scalar = job->args->data[6];
     298    scalar->data.S32 = Npetro;
     299
     300    scalar = job->args->data[7];
     301    scalar->data.S32 = Nannuli;
    172302
    173303    return true;
  • branches/meh_branches/ppstack_test/psphot/src/psphotExtendedSourceFits.c

    r31673 r33415  
    66    bool status = true;
    77
     8    fprintf (stdout, "\n");
     9    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Extended Source Fits ---");
     10
    811    // select the appropriate recipe information
    912    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     
    1215    // perform full extended source non-linear fits?
    1316    if (!psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_FITS")) {
    14         psLogMsg ("psphot", PS_LOG_INFO, "skipping extended source measurements\n");
     17        psLogMsg ("psphot", PS_LOG_INFO, "skipping extended source fits\n");
    1518        return true;
    1619    }
     
    4548    int Nfail = 0;
    4649
     50    psphotSersicModelClassInit();
     51
    4752    psTimerStart ("psphot.extended");
    4853
     
    103108
    104109      if (item->type != PS_DATA_METADATA) {
     110        // XXX we could cull the bad entries or build a validated model folder
    105111        psAbort ("Invalid type for EXTENDED_SOURCE_MODEL entry %s, not a metadata folder", item->name);
    106         // XXX we could cull the bad entries or build a validated model folder
    107112      }
    108113
     
    213218
    214219        // wait for the threads to finish and manage results
    215         if (!psThreadPoolWait (false)) {
     220        if (!psThreadPoolWait (false, true)) {
    216221            psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
    217222            psFree(AnalysisRegion);
     
    247252    psFree(AnalysisRegion);
    248253
    249     psLogMsg ("psphot", PS_LOG_INFO, "extended source model fits: %f sec for %d objects\n", psTimerMark ("psphot.extended"), Next);
     254    psphotSersicModelClassCleanup();
     255
     256    psphotVisualShowResidualImage (readout, false);
     257
     258    psLogMsg ("psphot", PS_LOG_WARN, "extended source model fits: %f sec for %d objects\n", psTimerMark ("psphot.extended"), Next);
    250259    psLogMsg ("psphot", PS_LOG_INFO, "  %d convolved models (%d passed)\n", Nconvolve, NconvolvePass);
    251260    psLogMsg ("psphot", PS_LOG_INFO, "  %d plain models (%d passed)\n", Nplain, NplainPass);
     
    265274    int Nplain = 0;
    266275    int NplainPass = 0;
    267     bool savePics = false;
    268     float radius;
     276    float fitRadius, windowRadius;
    269277    psScalar *scalar = NULL;
    270     pmMoments psfMoments;
    271278
    272279    // arguments: readout, sources, models, region, psfSize, maskVal, markVal
     
    275282    psMetadata *models      = job->args->data[2];
    276283    psRegion *region        = job->args->data[3];
    277     int psfSize             = PS_SCALAR_VALUE(job->args->data[4],PS_TYPE_IMAGE_MASK_DATA);
     284    int psfSize             = PS_SCALAR_VALUE(job->args->data[4],S32);
    278285    psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[5],PS_TYPE_IMAGE_MASK_DATA);
    279286    psImageMaskType markVal = PS_SCALAR_VALUE(job->args->data[6],PS_TYPE_IMAGE_MASK_DATA);
    280 
    281     // pthread_t tid = pthread_self();     // Thread identifier
    282287
    283288    // Define source fitting parameters for extended source fits
     
    299304
    300305        // skip PSF-like and non-astronomical objects
    301         if (source->type == PM_SOURCE_TYPE_STAR) continue;
     306        if (!(source->mode & PM_SOURCE_MODE_EXT_LIMIT)) continue;
    302307        if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
    303308        if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
     
    309314        if (source->peak->y > region->y1) continue;
    310315
    311         // if model is NULL, we don't have a starting guess
    312         // XXX use the parameters guessed from moments
    313         // if (source->modelEXT == NULL) continue;
    314 
    315         // fprintf (stderr, "fit %d,%d in thread %d\n", source->peak->x, source->peak->y, (int) tid);
    316 
    317316        // replace object in image
    318317        if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {
     
    321320        Next ++;
    322321
    323         // set the radius based on the footprint (also sets the mask pixels)
    324         if (!psphotSetRadiusFootprint(&radius, readout, source, markVal, 1.0)) {
    325             fprintf (stderr, "skipping (1) %f, %f\n", source->peak->xf, source->peak->yf);
    326             pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    327             // XXX raise an error of some kind
    328             continue;
    329         }
    330 
    331         // XXX note that this changes the source moments that are published...
    332         // recalculate the source moments using the larger extended-source moments radius
    333         // at this stage, skip Gaussian windowing, and do not clip pixels by S/N
    334         // this uses the footprint to judge both radius and aperture?
    335         // XXX save the psf-based moments for output
    336         psfMoments = *source->moments;
    337         if (!pmSourceMoments (source, radius, 0.0, 0.0, 0.0, maskVal)) {
    338             // subtract the best fit from the object, leave local sky
    339             fprintf (stderr, "skipping (2) %f, %f\n", source->peak->xf, source->peak->yf);
    340             *source->moments = psfMoments;
    341             pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    342             // XXX raise an error flag of some kind
    343             continue;
    344         }
    345 
    346         // save the modelFlux here in case we need to subtract it (for failure)
    347         psImage *modelFluxStart = psMemIncrRefCounter (source->modelFlux);
    348         if (!modelFluxStart) {
    349             pmSourceCacheModel (source, maskVal);
    350             modelFluxStart = psMemIncrRefCounter (source->modelFlux);
    351             if (!modelFluxStart) {
    352                 fprintf (stderr, "skipping (3) %f, %f\n", source->peak->xf, source->peak->yf);
    353                 *source->moments = psfMoments;
    354                 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    355                 // XXX raise an error of some kind?
    356                 continue;
    357             }
    358         }
    359        
    360         if (savePics) {
    361           psphotSaveImage (NULL, readout->image, "image.xp.fits");
    362         }
    363 
    364         // array to store the pointers to the model flux images while the models are being fitted
    365         psArray *modelFluxes = psArrayAllocEmpty (models->list->n);
     322        // set the fit radius based on the first radial moment (also sets the mask pixels)
     323        psphotSetRadiusMomentsExact(&fitRadius, &windowRadius, readout, source, markVal); // NOTE : 6 allocs
     324
     325        // UPDATE : we have changed the moments calculation.  There is now an iteration within
     326        // psphotKronMasked to determine moments appropriate for a larger object.  The values
     327        // Mrf, KronFlux, and KronFluxErr are calculated for the iterated radius.  The other
     328        // values are left at the psf-based values.
    366329
    367330        // allocate the array to store the model fits
     
    380343
    381344          // check the SNlim and skip model if source is too faint
    382           float SNlim = psMetadataLookupF32 (&status, model, "SNLIM_VALUE");
     345          float FIT_SN_LIM = psMetadataLookupF32 (&status, model, "SNLIM_VALUE");
    383346          assert (status);
    384347
    385348          // limit selection to some SN limit
    386349          // assert (source->peak); // how can a source not have a peak?
    387           if (sqrt(source->peak->detValue) < SNlim) {
     350          // limit selection to some SN limit
     351          bool skipSource = false;
     352          if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
     353              skipSource = (source->moments->KronFlux < FIT_SN_LIM * source->moments->KronFluxErr);
     354          } else {
     355              skipSource = (sqrt(source->peak->detValue) < FIT_SN_LIM);
     356          }
     357          if (skipSource) {
    388358              Nfaint ++;
    389359              continue;
     
    398368          assert (status);
    399369
    400           // XXX psTraceSetLevel ("psLib.math.psMinimizeLMChi2", 6);
    401           // XXX psTraceSetLevel ("psphot.psphotModelWithPSF_LMM", 6);
    402 
    403370          // fit the model as convolved or not
    404371          pmModel *modelFit = NULL;
    405372          if (convolved) {
    406               modelFit = psphotFitPCM (readout, source, fitOptions, modelType, maskVal, markVal, psfSize);
     373              // NOTE : 4 more allocs to here
     374              modelFit = psphotFitPCM (readout, source, fitOptions, modelType, maskVal, markVal, psfSize); // NOTE : 2313 allocs in here
    407375              if (!modelFit) {
    408376                  psTrace ("psphot", 5, "failed to fit psf-conv model for object at %f, %f", source->moments->Mx, source->moments->My);
     
    410378                  continue;
    411379              }
    412               psTrace ("psphot", 4, "fit psf-conv model for %f, %f : %s chisq = %f\n", source->moments->Mx, source->moments->My, pmModelClassGetName (modelFit->type), modelFit->chisq);
     380              psTrace ("psphot", 4, "fit psf-conv model for %f, %f : %s chisq = %f (npix: %d, niter: %d)\n",
     381                       source->moments->Mx, source->moments->My, pmModelClassGetName (modelFit->type), modelFit->chisq, modelFit->nPix, modelFit->nIter);
    413382              Nconvolve ++;
    414383              if (!(modelFit->flags & (PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE))) {
     
    425394                  continue;
    426395              }
    427               pmSourceCacheModel (source, maskVal);
    428               psTrace ("psphot", 4, "fit plain model for %f, %f : %s chisq = %f\n", source->moments->Mx, source->moments->My, pmModelClassGetName (modelFit->type), modelFit->chisq);
     396              psTrace ("psphot", 4, "fit plain model for %f, %f : %s chisq = %f (npix: %d, niter: %d)\n",
     397                       source->moments->Mx, source->moments->My, pmModelClassGetName (modelFit->type), modelFit->chisq, modelFit->nPix, modelFit->nIter);
    429398              Nplain ++;
    430399              if (!(modelFit->flags & (PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE))) {
     
    434403          }
    435404
    436           // save each of the model flux images and store the best
    437           psArrayAdd (modelFluxes, 4, source->modelFlux);
     405          // XXX deprecate?
     406          // XXX pmSourceExtFitPars *extFitPars = pmSourceExtFitParsAlloc();
     407          // XXX extFitPars->Mxx = source->moments->Mxx;
     408          // XXX extFitPars->Mxy = source->moments->Mxy;
     409          // XXX extFitPars->Myy = source->moments->Myy;
     410          // XXX extFitPars->Mrf = source->moments->Mrf;
     411          // XXX extFitPars->Mrh = source->moments->Mrh;
     412          // XXX extFitPars->peakMag = (source->peak->rawFlux > 0) ? -2.5*log10(source->peak->rawFlux) : NAN;
     413         
     414          // save kron mag, but assign apMag & psfMag on output (not yet calculated)
     415          // XXX extFitPars->krMag = -2.5*log10(source->moments->KronFlux);
     416
     417          // psArrayAdd (source->extFitPars, 4, extFitPars);
     418          // psFree (extFitPars);
    438419
    439420          // test for fit quality / result
    440           modelFit->fitRadius = radius;
     421          modelFit->fitRadius = fitRadius;
    441422          psArrayAdd (source->modelFits, 4, modelFit);
    442423
     
    463444        }
    464445
     446        // clear the circular mask
     447        psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
     448
    465449        if (minModel == -1) {
    466           // re-subtract the object, leave local sky
     450          // no valid extended fit; re-subtract the object, leave local sky
    467451          psTrace ("psphot", 5, "failed to fit extended source model to object at %f, %f", source->moments->Mx, source->moments->My);
    468452
    469           // replace original model, subtract it
    470           psFree (source->modelFlux);
    471           source->modelFlux = modelFluxStart;
    472 
    473           *source->moments = psfMoments;
     453          // ensure the modelEXT is cached
     454          pmSourceCacheModel (source, maskVal);
     455
    474456          pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    475457
    476           psFree (modelFluxes);
    477 
    478           if (savePics) {
    479               psphotSaveImage (NULL, readout->image, "image.xp.fits");
    480               char key[10];
    481               fprintf (stdout, "continue? ");
    482               if (!fgets (key, 8, stdin)) {
    483                   psWarning("Couldn't read anything.");
    484               } else if (key[0] == 'n') {
    485                   savePics = false;
    486               }
    487           }
    488458          continue;
    489459        }
     
    493463        source->modelEXT = psMemIncrRefCounter (source->modelFits->data[minModel]);
    494464
    495         // save the modelFlux for the best model
    496         psFree (source->modelFlux);
    497         source->modelFlux = psMemIncrRefCounter (modelFluxes->data[minModel]);
    498 
    499         // replace the original moments
    500         *source->moments = psfMoments;
     465        // adjust the window so the subtraction covers the faint wings
     466        psphotSetRadiusMoments(&fitRadius, &windowRadius, readout, source, markVal);
     467
     468        // cache the model flux
     469        if (source->modelEXT->isPCM) {
     470            pmPCMCacheModel (source, maskVal, psfSize);
     471        } else {
     472            pmSourceCacheModel (source, maskVal);
     473        }
    501474
    502475        // subtract the best fit from the object, leave local sky
    503476        pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    504477
    505         // the initial model flux is no longer needed
    506         psFree (modelFluxStart);
    507         psFree (modelFluxes);
    508 
    509478        psTrace ("psphot", 4, "best ext model for %f, %f : %s chisq = %f\n", source->moments->Mx, source->moments->My, pmModelClassGetName (source->modelEXT->type), source->modelEXT->chisq);
    510479        psTrace ("psphot", 5, "extended source model for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
    511 
    512         if (savePics) {
    513           psphotSaveImage (NULL, readout->image, "image.xm.fits");
    514           char key[10];
    515           fprintf (stdout, "continue? ");
    516           if (!fgets (key, 8, stdin)) {
    517               psWarning("Couldn't read anything.");
    518           } else if (key[0] == 'n') {
    519               savePics = false;
    520           }
    521         }
    522480    }
    523481    psFree (fitOptions);
    524 
    525     // fprintf (stderr, "xfit : tried %ld objects\n", sources->n);
    526482
    527483    // change the value of a scalar on the array (wrap this and put it in psArray.h)
  • branches/meh_branches/ppstack_test/psphot/src/psphotFake.c

    r26894 r33415  
    166166
    167167    // remove all sources, adding noise for subtracted sources
    168     psphotRemoveAllSources(realSources, recipe);
     168    psphotRemoveAllSourcesByArray(realSources, recipe);
    169169    psphotAddNoise(readout, realSources, recipe);
    170170
  • branches/meh_branches/ppstack_test/psphot/src/psphotFindDetections.c

    r31154 r33415  
    77{
    88    bool status = true;
     9
     10    fprintf (stdout, "\n");
     11    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Find Detections ---");
    912
    1013    // select the appropriate recipe information
  • branches/meh_branches/ppstack_test/psphot/src/psphotFindFootprints.c

    r31154 r33415  
    3535        psArray *tmp = pmFootprintArrayGrow(footprints, growRadius);
    3636        psImageConvolveSetThreads(oldThreads);
    37         psLogMsg ("psphot", PS_LOG_MINUTIA, "grow footprint coverage by %d pixels, %ld footprints become %ld footprints: %f sec\n", growRadius, footprints->n, tmp->n, psTimerMark ("psphot.footprints"));
    38         psFree(footprints);
    39         footprints = tmp;
     37        psLogMsg ("psphot", PS_LOG_MINUTIA, "grow footprint coverage by %d pixels, %ld footprints become %ld footprints: %f sec\n", growRadius, footprints->n, tmp ? tmp->n : 0, psTimerMark ("psphot.footprints"));
     38        if (tmp) {
     39            psFree(footprints);
     40            footprints = tmp;
     41        } else {
     42            psLogMsg ("psphot", PS_LOG_WARN, "pmFootprintArray grow returned NULL\n");
     43        }
     44           
    4045    }
    4146
     
    5863    psphotCullPeaks(readout, significance, recipe, detections->footprints);
    5964    detections->peaks = pmFootprintArrayToPeaks(detections->footprints);
    60     psLogMsg ("psphot", PS_LOG_INFO, "%ld peaks, %ld total footprints: %f sec\n", detections->peaks->n, detections->footprints->n, psTimerMark ("psphot.footprints"));
     65
     66    // psphotFootprintSaddles (readout, detections->footprints);
     67    //
     68    // int nSaddle = 0;
     69    // for (int i = 0; i < detections->peaks->n; i++) {
     70    //  pmPeak *peak = detections->peaks->data[i];
     71    // 
     72    //  if (peak->saddlePoints) nSaddle += peak->saddlePoints->n;
     73    // }
     74    // fprintf (stderr, "%d saddle points for %ld peaks\n", nSaddle, detections->peaks->n);
     75
     76    psLogMsg ("psphot", PS_LOG_WARN, "%ld peaks, %ld total footprints: %f sec\n", detections->peaks->n, detections->footprints->n, psTimerMark ("psphot.footprints"));
    6177
    6278    return detections;
  • branches/meh_branches/ppstack_test/psphot/src/psphotFindPeaks.c

    r31154 r33415  
    6868        pmPeaksWriteText (peaks, output);
    6969    }
    70     psLogMsg ("psphot", PS_LOG_INFO, "%ld peaks: %f sec\n", peaks->n, psTimerMark ("psphot.peaks"));
     70    psLogMsg ("psphot", PS_LOG_WARN, "%ld peaks: %f sec\n", peaks->n, psTimerMark ("psphot.peaks"));
    7171
    7272    return peaks;
  • branches/meh_branches/ppstack_test/psphot/src/psphotFitSourcesLinear.c

    r31452 r33415  
    1717    bool status = true;
    1818
     19    fprintf (stdout, "\n");
     20    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Fit Source (Linear) ---");
     21
    1922    // select the appropriate recipe information
    2023    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     
    2326    int num = psphotFileruleCount(config, filerule);
    2427
     28    // skip the chisq image (optionally?)
     29    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
     30    if (!status) chisqNum = -1;
     31
    2532    // loop over the available readouts
    2633    for (int i = 0; i < num; i++) {
     34        if (i == chisqNum) continue; // skip chisq image
    2735
    2836        // find the currently selected readout
     
    126134    for (int i = 0; i < sources->n; i++) {
    127135        pmSource *source = sources->data[i];
     136
     137        // psAssert (source->peak, "source without peak??");
     138        // psAssert (source->peak->footprint, "peak without footprint??");
    128139
    129140        // turn this bit off and turn it on again if we pass this test
     
    190201        pmModel *model = pmSourceGetModel (&isPSF, source);
    191202
     203        // clear the 'mark' pixels and remask on the fit aperture
    192204        psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
    193205        psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, model->fitRadius, "OR", markVal);
     
    203215    }
    204216    psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "built fitSources: %f sec (%ld objects)\n", psTimerMark ("psphot.linear"), sources->n);
    205 
    206     // fprintf (stderr, "****** Nsat : %d ********\n", Nsat);
    207217
    208218    if (fitSources->n == 0) {
     
    330340    psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "solve matrix: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem);
    331341
    332     // XXXX **** philosophical question:
    333     // we measure bright objects in three passes: 1) linear fit; 2) non-linear fit; 3) linear fit:
    334     // should retain the chisq and errors from the intermediate non-linear fit?
    335     // the non-linear fit provides better values for the position errors, and for
    336     // extended sources, the shape errors
     342    // Philosophical question: we measure bright objects in three passes: 1) linear fit; 2)
     343    // non-linear fit; 3) linear fit: should we retain the chisq and errors from the
     344    // intermediate non-linear fit?  the non-linear fit provides better values for the position
     345    // errors, and for extended sources, the shape errors
    337346
    338347    // adjust I0 for fitSources and subtract
     
    349358        model->dparams->data.F32[PM_PAR_I0] = errors->data.F32[i];
    350359
    351         // subtract object
     360        // clear the 'mark' pixels so the subtraction covers the full window
     361        psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
     362
     363        // subtract object & add noise
    352364        pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    353365    }
     
    374386    psFree (border);
    375387
    376     psLogMsg ("psphot.ensemble", PS_LOG_INFO, "measure ensemble of PSFs: %f sec\n", psTimerMark ("psphot.linear"));
     388    psLogMsg ("psphot.ensemble", PS_LOG_WARN, "measure ensemble of PSFs: %f sec\n", psTimerMark ("psphot.linear"));
    377389
    378390    psphotVisualPlotChisq (sources);
  • branches/meh_branches/ppstack_test/psphot/src/psphotFitSourcesLinearStack.c

    r31452 r33415  
    6464          // turn this bit off and turn it on again if we keep this source
    6565          source->mode &= ~PM_SOURCE_MODE_LINEAR_FIT;
     66
     67          // skip non-astronomical objects (very likely defects)
     68          if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
     69          if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
     70
     71          // do not include CRs in the full ensemble fit
     72          if (source->mode & PM_SOURCE_MODE_CR_LIMIT) continue;
     73
     74          // do not include MOMENTS_FAILURES in the fit
     75          if (source->mode & PM_SOURCE_MODE_MOMENTS_FAILURE) continue;
     76
     77          if (final) {
     78              if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) continue;
     79          } else {
     80              // if (source->mode & PM_SOURCE_MODE_BLEND) continue;
     81          }
    6682
    6783          // generate model for sources without, or skip if we can't
     
    8399          }
    84100
    85           source->mode |= PM_SOURCE_MODE_LINEAR_FIT;
     101          bool isPSF = false;
     102          pmModel *model = pmSourceGetModel (&isPSF, source);
     103
     104          // clear the 'mark' pixels and remask on the fit aperture
     105          psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
     106          psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, model->fitRadius, "OR", markVal);
     107
     108          // we call this function multiple times. for the first time, we have only PSF models for all objects
     109          // the second time has extended sources.  If we ever fit the PSF model, we should raise this bit
     110          source->mode |= PM_SOURCE_MODE_LINEAR_FIT;
     111          if (isPSF) {
     112              source->mode |= PM_SOURCE_MODE_PSFMODEL;
     113          }         
    86114          psArrayAdd (fitSources, 100, source);
    87115        }
     
    166194        model->params->data.F32[PM_PAR_I0] = norm->data.F32[i];
    167195        model->dparams->data.F32[PM_PAR_I0] = errors->data.F32[i];
     196
     197        // clear the 'mark' pixels so the subtraction covers the full window
     198        psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
    168199
    169200        // subtract object
     
    190221    psFree (errors);
    191222
    192     psLogMsg ("psphot.ensemble", PS_LOG_INFO, "measure ensemble of PSFs: %f sec\n", psTimerMark ("psphot.linear"));
     223    psLogMsg ("psphot.ensemble", PS_LOG_WARN, "measure ensemble of PSFs: %f sec\n", psTimerMark ("psphot.linear"));
    193224    return true;
    194225}
  • branches/meh_branches/ppstack_test/psphot/src/psphotForcedReadout.c

    r29936 r33415  
    5555    psphotLoadExtSources (config, view, filerule);
    5656
    57     // construct an initial model for each object, set the radius to fitRadius, set circular fit mask
    58     psphotGuessModels (config, view, filerule);
    59 
    6057    // merge the newly selected sources into the existing list
    6158    // NOTE: merge OLD and NEW
    6259    psphotMergeSources (config, view, filerule);
     60
     61    // Construct an initial model for each object, set the radius to fitRadius, set circular
     62    // fit mask.  NOTE: only applied to sources without guess models
     63    psphotGuessModels (config, view, filerule);
    6364
    6465    // linear PSF fit to source peaks, subtract the models from the image (in PSF mask)
  • branches/meh_branches/ppstack_test/psphot/src/psphotGuessModels.c

    r31452 r33415  
    4646    psAssert (detections, "missing detections?");
    4747
    48     psArray *sources = detections->newSources;
     48    psArray *sources = detections->allSources;
    4949    psAssert (sources, "missing sources?");
    5050
     
    112112        // wait here for the threaded jobs to finish
    113113        // fprintf (stderr, "wait for threads (%d, %d)\n", jx, jy);
    114         if (!psThreadPoolWait (false)) {
     114        if (!psThreadPoolWait (false, true)) {
     115            // harvest our jobs
     116            psFree(cellGroups);
    115117            psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
    116118            return false;
     
    141143    psFree (cellGroups);
    142144
    143     psLogMsg ("psphot.models", 4, "built models for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.models"));
     145    psLogMsg ("psphot.models", PS_LOG_WARN, "built models for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.models"));
    144146    return true;
    145147}
     
    159161    for (int i = 0; i < sources->n; i++) {
    160162        pmSource *source = sources->data[i];
     163
     164        // do not redo sources already guessed
     165        if (source->tmpFlags & PM_SOURCE_TMPF_MODEL_GUESS) continue;
    161166
    162167        // this is used to mark sources for which the model is measured. We check later that
     
    169174        if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
    170175        if (!source->peak) continue;
     176
     177        // psAssert (source->peak->footprint, "peak without footprint??");
    171178
    172179        nSrc ++;
  • branches/meh_branches/ppstack_test/psphot/src/psphotImageLoop.c

    r31154 r33415  
    129129                    }
    130130                    break;
     131                  case PSPHOT_MODEL_TEST:
     132                    if (!psphotModelTestReadout (config, view, "PSPHOT.INPUT")) {
     133                        psError(psErrorCodeLast(), false, "failure in psphotReadout for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout);
     134                        psFree (view);
     135                        return false;
     136                    }
     137                    break;
    131138                }
    132139            }
  • branches/meh_branches/ppstack_test/psphot/src/psphotImageQuality.c

    r30624 r33415  
    289289#endif
    290290
    291     psLogMsg ("psphot", PS_LOG_INFO, "Image Quality Stats from %ld psf stars : FWHM (major, minor) [pixels]: %f, %f\n",
     291    psLogMsg ("psphot", PS_LOG_WARN, "Image Quality Stats from %ld psf stars : FWHM (major, minor) [pixels]: %f, %f\n",
    292292              M2->n, fwhm_major, fwhm_minor);
    293293
  • branches/meh_branches/ppstack_test/psphot/src/psphotKronMasked.c

    r31673 r33415  
    11# include "psphotInternal.h"
    2 
     2# ifndef ROUND
     3# define ROUND(X) ((int) ((X) + 0.5*SIGN(X)))
     4# endif
     5
     6bool psphotKronMask (pmSource *source, psImage *kronMask, psImageMaskType markVal);
    37bool psphotKronMag (pmSource *source, float radius, float minKronRadius, psImageMaskType maskVal);
    48
     
    4549}
    4650
     51int psphotKapaChannel (int channel);
     52bool psphotVisualShowMask (int kapaFD, psImage *inImage, const char *name, int channel);
     53bool psphotVisualRangeImage (int kapaFD, psImage *inImage, const char *name, int channel, float min, float max);
     54
    4755bool psphotKronMaskedReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, pmReadout *readout, psArray *sources, pmPSF *psf) {
    4856
     
    7280    }
    7381
     82    float EXT_FIT_MAX_RADIUS = psMetadataLookupF32 (&status, recipe, "EXT_FIT_MAX_RADIUS");
     83
    7484    // bit-masks to test for good/bad pixels
    7585    psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT");
     
    8393    maskVal |= markVal;
    8494
     95    // psphotSaveImage (NULL, readout->mask, "kron.unmasked.fits");
     96
     97    pmSourcePhotometryMode photMode = PM_SOURCE_PHOT_PSFONLY;
     98
     99    // XXX tmp visualization
     100    // int kapa = psphotKapaChannel (1);
     101
    85102    // generate the mask image: increment counter for every source overlapping the pixel
    86     psImage *kronMask = psImageAlloc (readout->image->numCols, readout->image->numRows, PS_TYPE_U8);
     103    psImage *kronMask = psImageAlloc (readout->image->numCols, readout->image->numRows, PS_TYPE_S32);
    87104    psImageInit (kronMask, 0);
    88     int Nx = kronMask->numCols;
    89     int Ny = kronMask->numRows;
    90105    for (int i = 0; i < sources->n; i++) {
    91106
     
    96111        if (!source->moments) continue;
    97112
    98         // replace object in image
    99         if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {
    100             pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
    101         }
    102 
    103         psphotKronMag (source, RADIUS, MIN_KRON_RADIUS, maskVal);
    104 
    105         // re-subtract the object, leave local sky
    106         pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    107 
    108         continue;
    109 
    110         // XXX skip this code
    111         // generate the pixel masks
    112         // int Xo = source->moments->Mx;
    113         // int Yo = source->moments->My;
    114         float dX = source->moments->Mx - source->peak->xf;
    115         float dY = source->moments->My - source->peak->yf;
    116         float dR = hypot(dX, dY);
    117        
    118         float Xo = (dR < 2.0) ? source->moments->Mx : source->peak->xf;
    119         float Yo = (dR < 2.0) ? source->moments->My : source->peak->yf;
    120        
    121         int Kr = 2.5*source->moments->Mrf;
    122         int Kr2 = Kr*Kr;
    123        
    124         for (int iy = Yo - Kr; iy < Yo + Kr + 1; iy++) {
    125             if (iy < 0) continue;
    126             if (iy >= Ny) continue;
    127             for (int ix = Xo - Kr; ix < Xo + Kr + 1; ix++) {
    128                 if (ix < 0) continue;
    129                 if (ix >= Nx) continue;
    130 
    131                 if (PS_SQR(ix - Xo) + PS_SQR(iy - Yo) > Kr2) continue;
    132                 if (kronMask->data.U8[iy][ix] < 0xff) {
    133                     kronMask->data.U8[iy][ix] ++;
    134                 }
    135             }
    136         }
    137     }           
     113        // replace object in image
     114        if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {
     115            pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
     116        }
     117
     118        // save the PSF-based values
     119        // source->moments->KronFluxPSF    = source->moments->KronFlux;
     120        // source->moments->KronFluxPSFErr = source->moments->KronFluxErr;
     121        // source->moments->KronRadiusPSF  = source->moments->Mrf;
     122
     123        // iterate to the window radius
     124        float windowRadius = RADIUS;
     125        for (int j = 0; j < 4; j++) {
     126            // XXX use some S/N criterion to limit?
     127            // if (source->moments->KronFlux / source->moments->KronFluxErr > 10.0) {
     128            // windowRadius = PS_MAX (RADIUS, 10*source->moments->Mrf);
     129            // }
     130
     131            // re-allocate image, weight, mask arrays for each peak with box big enough to fit BIG_RADIUS
     132            pmSourceRedefinePixels (source, readout, source->peak->x, source->peak->y, windowRadius + 2);
     133
     134            // mask the pixels not contained by the footprint
     135            // if (psphotMaskFootprint (readout, source, markVal)) {
     136            //  // psphotVisualShowMask (kapa, source->maskObj, "mask", 2);
     137            //  // psphotVisualRangeImage (kapa, source->pixels, "image", 1, -50, 300);
     138            //  // fprintf (stderr, "masked\n");
     139            // }           
     140
     141            // mask the pixels associated with near neighbors
     142            if (psphotKronMask (source, kronMask, markVal)) {
     143                // psphotVisualShowMask (kapa, source->maskObj, "mask", 2);
     144                // psphotVisualRangeImage (kapa, source->pixels, "image", 1, -50, 300);
     145                // fprintf (stderr, "masked\n");
     146            }       
     147            // this function populates moments->Mrf,KronFlux,KronFluxErr
     148            // XXX what about KronInner, KronOuter, etc?
     149            psphotKronMag (source, windowRadius, MIN_KRON_RADIUS, maskVal);
     150            windowRadius = PS_MIN(PS_MAX(RADIUS, 4.0*source->moments->Mrf), EXT_FIT_MAX_RADIUS);
     151            psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
     152        }
     153        pmSourceMagnitudes (source, psf, photMode, maskVal, markVal, source->apRadius);
     154        float kmag = -2.5*log10(source->moments->KronFlux);
     155        if (source->psfMag - kmag > 0.25) {
     156            // psphotVisualShowMask (kapa, source->maskObj, "mask", 1);
     157            // psphotVisualRangeImage (kapa, source->pixels, "image", 0, -50, 300);
     158            // fprintf (stderr, "psf: %f, kron: %f, dmag: %f\n", source->psfMag, kmag, source->psfMag - kmag);
     159            // fprintf (stderr, "continue\n");
     160        }
     161        // re-subtract the object, leave local sky
     162        pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
     163    }
     164
     165    // psphotSaveImage (NULL, readout->mask, "kron.masked.fits");
    138166    // psphotSaveImage (NULL, kronMask, "kronmask.fits");
     167
    139168    psLogMsg ("psphot.kron", PS_LOG_DETAIL, "measure masked kron magnitudes : %f sec for %ld objects\n", psTimerMark ("psphot.kron"), sources->n);
    140169
     
    142171    return true;
    143172}
     173
     174# define WEIGHTED 0
    144175
    145176bool psphotKronMag (pmSource *source, float radius, float minKronRadius, psImageMaskType maskVal) {
     
    150181    PS_ASSERT_FLOAT_LARGER_THAN(radius, 0.0, false);
    151182
    152     psF32 Sum = 0.0;
    153     psF32 Var = 0.0;
    154183    psF32 R2 = PS_SQR(radius);
     184
     185# if (WEIGHTED)
     186    float rsigma2 = 0.5 / PS_SQR(radius / 4.0); // use a Gaussian window with sigma = R_window / 2
     187# endif
    155188
    156189    // a note about coordinates: coordinates of objects throughout psphot refer to the primary
     
    168201    psF32 RS = 0.0;
    169202
    170 # if (1)
     203    // the peak position is less accurate but less subject to extreme deviations
    171204    float dX = source->moments->Mx - source->peak->xf;
    172205    float dY = source->moments->My - source->peak->yf;
     
    174207    float Xo = (dR < 2.0) ? source->moments->Mx : source->peak->xf;
    175208    float Yo = (dR < 2.0) ? source->moments->My : source->peak->yf;
    176 # else
    177     float Xo = source->moments->Mx;
    178     float Yo = source->moments->My;
    179 # endif
    180209
    181210    // center of mass in subimage.  Note: the calculation below uses pixel index, so we correct
     
    210239            if (r2 > R2) continue;
    211240
     241# if (WEIGHTED)
     242            float z = r2 * rsigma2;
     243            assert (z >= 0.0);
     244            float weight  = exp(-z);
     245            psF32 pDiff = *vPix * weight;
     246# else
    212247            psF32 pDiff = *vPix;
    213 
    214             Sum += pDiff;
    215 
    216             // Kron Flux uses the 1st radial moment (NOT Gaussian windowed)
     248# endif
     249
     250            // Kron Flux uses the 1st radial moment (maybe Gaussian windowed?)
    217251            psF32 rf = pDiff * sqrt(r2);
    218252            psF32 rs = pDiff;
     
    234268
    235269    int nKronPix = 0;
    236     Sum = Var = 0.0;
     270    float Sum = 0.0;
     271    float Var = 0.0;
    237272
    238273    for (psS32 row = 0; row < source->pixels->numRows ; row++) {
     
    263298            if (r2 > radKron2) continue;
    264299
     300# if (WEIGHTED)
     301            float z = r2 * rsigma2;
     302            assert (z >= 0.0);
     303            float weight  = exp(-z);
     304            psF32 pDiff = *vPix * weight;
     305            psF32 wDiff = *vWgt * weight;
     306# else
    265307            psF32 pDiff = *vPix;
    266308            psF32 wDiff = *vWgt;
     309# endif
    267310
    268311            Sum += pDiff;
     
    272315    }
    273316
    274     source->moments->Mrh = Mrf;
    275 
    276     // XXX for a test, save the old values here:
    277     source->moments->KronFouter    = source->moments->KronFlux;
    278     source->moments->KronCoreErr = source->moments->KronFluxErr;
    279 
    280     source->moments->KronFlux    = Sum       * M_PI * PS_SQR(radKron) / nKronPix;
    281     source->moments->KronFluxErr = sqrt(Var) * M_PI * PS_SQR(radKron) / nKronPix;
     317    source->moments->Mrf = Mrf;
     318    source->moments->KronFlux    = Sum;
     319    source->moments->KronFluxErr = sqrt(Var);
     320    // source->moments->KronFlux    = Sum       * M_PI * PS_SQR(radKron) / nKronPix;
     321    // source->moments->KronFluxErr = sqrt(Var) * M_PI * PS_SQR(radKron) / nKronPix;
    282322
    283323    return true;
    284324}
     325
     326enum {Y_P, Y_M, X_P, X_M};
     327
     328bool psphotKronMask (pmSource *source, psImage *kronMask, psImageMaskType markVal) {
     329
     330    int X, Y, e, dXs, dYs;
     331
     332    if (!source->peak) return false;
     333    if (!source->peak->saddlePoints) return false;
     334    if (!source->peak->saddlePoints->n) return false;
     335
     336    // return true;
     337
     338    int xMax = source->maskObj->numCols;
     339    int yMax = source->maskObj->numRows;
     340    // int xOff = source->maskObj->col0;
     341    // int yOff = source->maskObj->row0;
     342
     343    int Xo = ROUND(source->peak->xf) - source->maskObj->col0;
     344    int Yo = ROUND(source->peak->yf) - source->maskObj->row0;
     345
     346    for (int i = 0; i < source->peak->saddlePoints->n; i++) {
     347
     348        psVector *saddlePoint = source->peak->saddlePoints->data[i];
     349        int Xs = ROUND(saddlePoint->data.S32[0]) - source->maskObj->col0;
     350        int Ys = ROUND(saddlePoint->data.S32[1]) - source->maskObj->row0;
     351       
     352        // fprintf (stderr, "mask %d,%d @ %d,%d (%d,%d)\n", Xo, Yo, Xs, Ys, saddlePoint->data.S32[0], saddlePoint->data.S32[1]);
     353
     354        // We want to mask the pixels between the edge of the image and the line perpendicular
     355        // to the connecting line.  Call dX,dY = (Xs-Xo,Ys-Yo).  There are 4 cases:
     356        // +y : dY > 0, fabs(dY) > fabs(dX)
     357        // -y : dY < 0, fabs(dY) > fabs(dX)
     358        // +x : dX > 0, fabs(dX) > fabs(dY)
     359        // -x : dX < 0, fabs(dX) > fabs(dY)
     360
     361        int dX = Xs - Xo;
     362        int dY = Ys - Yo;
     363
     364        // +y : dY > 0, fabs(dY) > fabs(dX)
     365        // -y : dY < 0, fabs(dY) > fabs(dX)
     366        if (fabs(dY) > fabs(dX)) {
     367            // points to right of saddle
     368            Y = Ys;
     369            e = 0;
     370            dXs = (dY > 0) ? +dY : -dY;  // this forces dXs > 0
     371            dYs = (dY > 0) ? -dX : +dX;
     372            for (X = Xs; X < xMax; X++) {
     373                if (dY > 0) {
     374                    for (int Ym = Y; Ym < yMax; Ym++) {
     375                        source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[Ym][X] |= markVal;
     376                        // kronMask->data.S32[Ym+yOff][X+xOff] = source->id;
     377                    }
     378                } else {
     379                    for (int Ym = Y; Ym >= 0; Ym--) {
     380                        source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[Ym][X] |= markVal;
     381                        // kronMask->data.S32[Ym+yOff][X+xOff] = source->id;
     382                    }
     383                }
     384                e += dYs;
     385                int e2 = 2 * e;
     386                if (e2 > dXs) {
     387                    Y ++;
     388                    e -= dXs;
     389                }
     390                if (e2 < -dXs) {
     391                    Y --;
     392                    e += dXs;
     393                }
     394                if (Y >= yMax) break;
     395                if (Y < 0) break;
     396            }
     397            // points to left of saddle
     398            Y = Ys;
     399            e = 0;
     400            for (X = Xs; X >= 0; X--) {
     401                if (dY > 0) {
     402                    for (int Ym = Y; Ym < yMax; Ym++) {
     403                        source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[Ym][X] |= markVal;
     404                        // kronMask->data.S32[Ym+yOff][X+xOff] = source->id;
     405                    }
     406                } else {
     407                    for (int Ym = Y; Ym >= 0; Ym--) {
     408                        source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[Ym][X] |= markVal;
     409                        // kronMask->data.S32[Ym+yOff][X+xOff] = source->id;
     410                    }
     411                }
     412                e -= dYs;
     413                int e2 = 2 * e;
     414                if (e2 > dXs) {
     415                    Y ++;
     416                    e -= dXs;
     417                }
     418                if (e2 < -dXs) {
     419                    Y --;
     420                    e += dXs;
     421                }
     422                if (Y >= yMax) break;
     423                if (Y < 0) break;
     424            }
     425        } else {
     426            // points to right of saddle
     427            X = Xs;
     428            e = 0;
     429            dXs = (dX > 0) ? -dY : +dY;
     430            dYs = (dX > 0) ? +dX : -dX;  // this forces dYs > 0
     431            for (Y = Ys; Y < yMax; Y++) {
     432                if (dX > 0) {
     433                    for (int Xm = X; Xm < xMax; Xm++) {
     434                        source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[Y][Xm] |= markVal;
     435                        // kronMask->data.S32[Y+yOff][Xm+xOff] = source->id;
     436                    }
     437                } else {
     438                    for (int Xm = X; Xm >= 0; Xm--) {
     439                        source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[Y][Xm] |= markVal;
     440                        // kronMask->data.S32[Y+yOff][Xm+xOff] = source->id;
     441                    }
     442                }
     443                e += dXs;
     444                int e2 = 2 * e;
     445                if (e2 > dYs) {
     446                    X ++;
     447                    e -= dYs;
     448                }
     449                if (e2 < -dYs) {
     450                    X --;
     451                    e += dYs;
     452                }
     453                if (X >= yMax) break;
     454                if (X < 0) break;
     455            }
     456            // points to left of saddle
     457            X = Xs;
     458            e = 0;
     459            for (Y = Ys; Y >= 0; Y--) {
     460                if (dX > 0) {
     461                    for (int Xm = X; Xm < xMax; Xm++) {
     462                        source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[Y][Xm] |= markVal;
     463                        // kronMask->data.S32[Y+yOff][Xm+xOff] = source->id;
     464                    }
     465                } else {
     466                    for (int Xm = X; Xm >= 0; Xm--) {
     467                        source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[Y][Xm] |= markVal;
     468                        // kronMask->data.S32[Y+yOff][Xm+xOff] = source->id;
     469                    }
     470                }
     471                e -= dXs;
     472                int e2 = 2 * e;
     473                if (e2 > dYs) {
     474                    X ++;
     475                    e -= dYs;
     476                }
     477                if (e2 < -dYs) {
     478                    X --;
     479                    e += dYs;
     480                }
     481                if (X >= yMax) break;
     482                if (X < 0) break;
     483            }
     484        }
     485    }
     486    return true;
     487}
  • branches/meh_branches/ppstack_test/psphot/src/psphotLoadSRCTEXT.c

    r31452 r33415  
    7373            dPAR[PM_PAR_I0]   = 0.0;
    7474
    75             pmPSF_AxesToModel (PAR, axes);
     75            pmPSF_AxesToModel (PAR, axes, modelType);
    7676
    7777            float peakFlux    = 1.0;
  • branches/meh_branches/ppstack_test/psphot/src/psphotMagnitudes.c

    r31673 r33415  
    44{
    55    bool status = true;
     6
     7    fprintf (stdout, "\n");
     8    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Magnitudes ---");
    69
    710    // select the appropriate recipe information
     
    126129
    127130        // wait for the threads to finish and manage results
    128         if (!psThreadPoolWait (false)) {
     131        if (!psThreadPoolWait (false, true)) {
    129132            psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
    130133            return false;
     
    146149    psFree (cellGroups);
    147150
    148     psLogMsg ("psphot.magnitudes", PS_LOG_DETAIL, "measure magnitudes : %f sec for %ld objects (%d with apertures)\n", psTimerMark ("psphot.mags"), sources->n, Nap);
     151    psLogMsg ("psphot.magnitudes", PS_LOG_WARN, "measure magnitudes : %f sec for %ld objects (%d with apertures)\n", psTimerMark ("psphot.mags"), sources->n, Nap);
    149152    return true;
    150153}
     
    306309
    307310        // wait for the threads to finish and manage results
    308         if (!psThreadPoolWait (false)) {
     311        if (!psThreadPoolWait (false, true)) {
    309312            psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
    310313            return false;
  • branches/meh_branches/ppstack_test/psphot/src/psphotMergeSources.c

    r31452 r33415  
    520520}
    521521
     522// copy the newPeaks from the detections of one pmFPAfile to another
     523bool psphotCopyPeaks (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc)
     524{
     525    bool status = true;
     526
     527    int num = psphotFileruleCount(config, ruleSrc);
     528
     529    // skip the chisq image because it is a duplicate of the detection version
     530    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
     531    if (!status) chisqNum = -1;
     532
     533    // loop over the available readouts
     534    for (int i = 0; i < num; i++) {
     535        if (i == chisqNum) continue; // skip chisq image
     536        if (!psphotCopyPeaksReadout (config, view, ruleOut, ruleSrc, i)) {
     537            psError (PSPHOT_ERR_CONFIG, false, "failed to copy peaks from %s to %s entry %d", ruleSrc, ruleOut, i);
     538            return false;
     539        }
     540    }
     541    return true;
     542}
     543
     544// add newly detected peaks to the existing list of sources
     545bool psphotCopyPeaksReadout (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc, int index) {
     546
     547    bool status;
     548
     549    // find the currently selected readout
     550    pmFPAfile *fileSrc = pmFPAfileSelectSingle(config->files, ruleSrc, index); // File of interest
     551    psAssert (fileSrc, "missing file?");
     552
     553    pmReadout *readoutSrc = pmFPAviewThisReadout(view, fileSrc->fpa);
     554    psAssert (readoutSrc, "missing readout?");
     555
     556    pmDetections *detections = psMetadataLookupPtr (&status, readoutSrc->analysis, "PSPHOT.DETECTIONS");
     557    psAssert (detections, "missing detections?");
     558
     559    // find the currently selected readout
     560    pmFPAfile *fileOut = pmFPAfileSelectSingle(config->files, ruleOut, index); // File of interest
     561    psAssert (fileOut, "missing file?");
     562
     563    pmReadout *readoutOut = pmFPAviewThisReadout(view, fileOut->fpa);
     564    psAssert (readoutOut, "missing readout?");
     565
     566    // generate a new detection structure for the output filerule
     567    pmDetections *detectionsOut = psMetadataLookupPtr (&status, readoutOut->analysis, "PSPHOT.DETECTIONS");
     568    psAssert (detectionsOut, "missing PSPHOT.DETECTIONS?");
     569
     570    psAssert (detectionsOut->peaks, "programming error");
     571    psAssert (!detectionsOut->oldPeaks, "programming error");
     572    psAssert (detections->peaks, "programming error");
     573
     574    // save the OUT existing peaks on oldPeaks
     575    detectionsOut->oldPeaks = detectionsOut->peaks;
     576    detectionsOut->peaks = psArrayAllocEmpty(detections->peaks->n);
     577
     578    for (int i = 0; i < detections->peaks->n; i++) {
     579        psAssert (detections->peaks->data[i], "programming error");
     580        pmPeak *peak = pmPeakAlloc (0, 0, 0.0, PM_PEAK_LONE);
     581        pmPeakCopy(peak, detections->peaks->data[i]);
     582        psArrayAdd (detectionsOut->peaks, 100, peak);
     583        psFree (peak);
     584    }
     585    return true;
     586}
     587
     588// create source parents children from ruleSrc for ruleOut for orphans
     589bool psphotSourceParents (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc)
     590{
     591    bool status = true;
     592
     593    int num = psphotFileruleCount(config, ruleSrc);
     594
     595    // skip the chisq image because it is a duplicate of the detection version
     596    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
     597    if (!status) chisqNum = -1;
     598
     599    // loop over the available readouts
     600    for (int i = 0; i < num; i++) {
     601        if (i == chisqNum) continue; // skip chisq image
     602        if (!psphotSourceParentsReadout (config, view, ruleOut, ruleSrc, i)) {
     603            psError (PSPHOT_ERR_CONFIG, false, "failed to copy sources from %s to %s entry %d", ruleSrc, ruleOut, i);
     604            return false;
     605        }
     606    }
     607    return true;
     608}
     609
     610// create source parents from ruleSrc for ruleOut for orphaned children for this readout. 
     611bool psphotSourceParentsReadout (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc, int index) {
     612
     613    bool status;
     614    int nParents = 0;
     615    int nNonOrphans = 0;
     616
     617    // find the currently selected readout
     618    pmFPAfile *fileSrc = pmFPAfileSelectSingle(config->files, ruleSrc, index); // File of interest
     619    psAssert (fileSrc, "missing file?");
     620
     621    pmReadout *readoutSrc = pmFPAviewThisReadout(view, fileSrc->fpa);
     622    psAssert (readoutSrc, "missing readout?");
     623
     624    pmDetections *detectionsSrc = psMetadataLookupPtr (&status, readoutSrc->analysis, "PSPHOT.DETECTIONS");
     625    psAssert (detectionsSrc, "missing detections?");
     626
     627    psArray *sourcesSrc = detectionsSrc->allSources;
     628    psAssert (sourcesSrc, "missing sources?");
     629
     630    // find the currently selected readout
     631    pmFPAfile *fileOut = pmFPAfileSelectSingle(config->files, ruleOut, index); // File of interest
     632    psAssert (fileOut, "missing file?");
     633
     634    pmReadout *readoutOut = pmFPAviewThisReadout(view, fileOut->fpa);
     635    psAssert (readoutOut, "missing readout?");
     636
     637    // generate a new detection structure for the output filerule
     638    pmDetections *detectionsOut = psMetadataLookupPtr (&status, readoutOut->analysis, "PSPHOT.DETECTIONS");
     639    psAssert (detectionsOut, "missing PSPHOT.DETECTIONS?");
     640
     641    // loop over the sources, redefine their pixels to point at the new filerule image,
     642    // copy the source data, and add a reference back to the original source
     643   
     644    // copy the sources from sourceSrcs to the new detection structure
     645    for (int i = 0; i < sourcesSrc->n; i++) {
     646      pmSource *sourceSrc = sourcesSrc->data[i];
     647      if (sourceSrc->parent) {
     648          nNonOrphans ++;
     649          continue; // Not an orphan
     650      }
     651
     652      pmSource *sourceOut = pmSourceCopy(sourceSrc);
     653      sourceOut->parent = sourceSrc;
     654     
     655      // keep the original source flags
     656      sourceOut->seq      = sourceSrc->seq;
     657      sourceOut->type     = sourceSrc->type;
     658      sourceOut->mode     = sourceSrc->mode;
     659      sourceOut->mode2    = sourceSrc->mode2;
     660      sourceOut->tmpFlags = sourceSrc->tmpFlags;
     661
     662      // does this copy all model data? (NO)
     663      sourceOut->modelPSF = pmModelCopy(sourceSrc->modelPSF);
     664      sourceOut->modelEXT = pmModelCopy(sourceSrc->modelEXT);
     665
     666      if (sourceSrc->modelFits) {
     667          sourceOut->modelFits = psArrayAlloc(sourceSrc->modelFits->n);
     668          for (int j = 0; j < sourceSrc->modelFits->n; j++) {
     669              sourceOut->modelFits->data[j] = pmModelCopy(sourceSrc->modelFits->data[j]);
     670          }
     671      }
     672
     673      // drop the references to the original image pixels:
     674      pmSourceFreePixels (sourceOut);
     675
     676      // allocate image, weight, mask for the new image for each peak
     677      if (sourceOut->modelPSF) {
     678        pmSourceRedefinePixels (sourceOut, readoutOut, sourceOut->peak->x, sourceOut->peak->y, sourceOut->modelPSF->fitRadius);
     679      }
     680
     681      // child sources have not been subtracted in this image, but this flag may be raised if
     682      // they were subtracted in the parent's image
     683      sourceOut->tmpFlags &= ~PM_SOURCE_TMPF_SUBTRACTED;
     684
     685      nParents ++;
     686      psArrayAdd (detectionsOut->allSources, 100, sourceOut);
     687      psFree (sourceOut);
     688    }
     689    psLogMsg ("psphot", 3, "%d parents created, %d unorphaned children, %ld input vs %ld output", nParents, nNonOrphans, sourcesSrc->n, detectionsOut->allSources->n);
     690
     691    return true;
     692}
     693
    522694// create source children from ruleSrc for ruleOut
    523695bool psphotSourceChildren (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc)
     
    542714}
    543715
    544 // create source children from ruleSrc for ruleOut for this entry.  XXX currently, this is only
     716// Create source children from ruleSrc for ruleOut for this entry.  Currently, this is only
    545717// used by psphotStackReadout (sources go on allSources so that psphotChoosePSF can be called
    546 // repeatedly)
     718// repeatedly).
    547719bool psphotSourceChildrenReadout (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc, int index) {
    548720
     
    569741    psAssert (readoutOut, "missing readout?");
    570742
    571     // generate a new detection structure for the output filerule
    572     pmDetections *detectionsOut = psMetadataLookupPtr (&status, readoutOut->analysis, "PSPHOT.DETECTIONS");
    573     if (!detectionsOut) {
    574         detectionsOut = pmDetectionsAlloc();
    575         detectionsOut->allSources = psArrayAllocEmpty (100);
    576         // save detections on the readout->analysis
    577         if (!psMetadataAddPtr (readoutOut->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_META_REPLACE | PS_DATA_UNKNOWN, "psphot detections", detectionsOut)) {
    578             psError (PSPHOT_ERR_CONFIG, false, "problem saving detections on readout");
    579             return false;
    580         }
    581         psFree(detectionsOut); // a copy remains on the analysis metadata
     743    // replace any existing DETECTION container on readoutOut->analysis with the new one
     744    pmDetections *detectionsOut = pmDetectionsAlloc();
     745    detectionsOut->allSources = psArrayAllocEmpty (100);
     746    if (!psMetadataAddPtr (readoutOut->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_META_REPLACE | PS_DATA_UNKNOWN, "psphot detections", detectionsOut)) {
     747        psError (PSPHOT_ERR_CONFIG, false, "problem saving detections on readout");
     748        return false;
    582749    }
    583750
     
    593760     
    594761      // keep the original source flags
     762      sourceOut->seq      = sourceSrc->seq;
    595763      sourceOut->type     = sourceSrc->type;
    596764      sourceOut->mode     = sourceSrc->mode;
     
    612780      pmSourceFreePixels (sourceOut);
    613781
     782      // XXX do we need to skip the Chisq image sources?
     783
    614784      // allocate image, weight, mask for the new image for each peak
    615       if (sourceOut->modelPSF) {
    616         pmSourceRedefinePixels (sourceOut, readoutOut, sourceOut->peak->x, sourceOut->peak->y, sourceOut->modelPSF->fitRadius);
    617       }
     785      pmSourceRedefinePixels (sourceOut, readoutOut, sourceOut->peak->x, sourceOut->peak->y, sourceOut->windowRadius);
    618786
    619787      // child sources have not been subtracted in this image, but this flag may be raised if
     
    624792      psFree (sourceOut);
    625793    }
    626     psLogMsg ("psphot", 3, "%ld known sources supplied", detectionsOut->allSources->n);
    627 
    628 
    629     return true;
    630 }
    631 
    632 // create source children associated with 'filerule' from the objectsSrc.  XXX currently, this
    633 // is only used by psphotStackReadout (sources go on allSources so that psphotChoosePSF can be
    634 // called repeatedly)
     794    psLogMsg ("psphot", 3, "created %ld children", detectionsOut->allSources->n);
     795
     796    psFree(detectionsOut); // a copy remains on the analysis metadata
     797
     798    return true;
     799}
     800
     801// create source children associated with 'filerule' from the objectsSrc.  returns a new object
     802// array containing the child sources.  XXX currently, this is only used by psphotStackReadout
     803// (sources go on allSources so that psphotChoosePSF can be called repeatedly)
    635804psArray *psphotSourceChildrenByObject (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objectsSrc) {
    636805
     
    652821        psAssert (readout, "missing readout?");
    653822
     823        // create DETECTIONS containers for each image, in case one lacks it
    654824        pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
    655825        if (!detections) {
     
    665835            psAssert (detections, "missing detections?");
    666836        }
     837
     838        // we need to save the new sources on the detection arrays of the appropriate image
    667839        detArrays->data[i] = psMemIncrRefCounter(detections);
    668840        readouts->data[i] = psMemIncrRefCounter(readout);
     
    695867
    696868            pmSource *sourceOut = pmSourceCopy(sourceSrc);
     869            sourceOut->parent = sourceSrc;
     870
     871            // save on the output object array at the same location
    697872            objectOut->sources->data[i] = sourceOut;
    698 
    699             sourceOut->parent = sourceSrc;
    700873
    701874            // keep the original source flags and sequence ID (if set)
     
    720893            pmSourceFreePixels (sourceOut);
    721894
    722             // set the output readotu
     895            // set the output readout
    723896            int index = sourceOut->imageID;
    724897            if (index >= readouts->n) continue; // skip the sources generated by the chisq image
  • branches/meh_branches/ppstack_test/psphot/src/psphotModelBackground.c

    r31154 r33415  
    145145    psMetadataAddPtr(analysis, PS_LIST_TAIL, "PSPHOT.BACKGROUND.BINNING", PS_DATA_UNKNOWN | PS_META_REPLACE, "Background binning", binning);
    146146
     147    psVector *dQ = psVectorAllocEmpty (100, PS_TYPE_F32);
    147148    psF32 **modelData = model->data.F32;
    148149    psF32 **modelStdevData = modelStdev->data.F32;
     
    216217                }
    217218                modelStdevData[iy][ix] = psStatsGetValue(stats, statsOptionWidth);
     219                // fprintf (stderr, "dQ : %f - %f - %f = %f\n", stats->robustLQ, stats->robustMedian, stats->robustUQ, stats->robustUQ + stats->robustLQ - 2*stats->robustMedian);
     220                psVectorAppend (dQ, stats->robustUQ + stats->robustLQ - 2*stats->robustMedian);
    218221
    219222                // supply sample to plotting routing
     
    322325    }
    323326
    324     psLogMsg ("psphot", PS_LOG_INFO, "built background image: %f sec\n", psTimerMark ("psphot.background"));
    325 
    326     psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "SKY_MEAN", PS_META_REPLACE, "sky mean", Value);
     327    psLogMsg ("psphot", PS_LOG_WARN, "built background image: %f sec\n", psTimerMark ("psphot.background"));
     328
     329    psStats *statsDQ = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN);
     330    psVectorStats (statsDQ, dQ, NULL, NULL, 0);
     331
     332    psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "SKY_MEAN",  PS_META_REPLACE, "sky mean", Value);
    327333    psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "SKY_STDEV", PS_META_REPLACE, "sky stdev", ValueStdev);
    328     psLogMsg ("psphot", PS_LOG_INFO, "image sky : mean %f stdev %f", Value, ValueStdev);
     334    psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "SKY_DQ",    PS_META_REPLACE, "sky quartile slope", statsDQ->sampleMedian);
     335    psLogMsg ("psphot", PS_LOG_INFO, "image sky : mean %f, stdev %f, dQ %f", Value, ValueStdev, statsDQ->sampleMedian);
    329336
    330337    // measure image and background stats and save for later output
     
    334341                                      PS_STAT_MAX);
    335342    psImageStats (statsBck, model, NULL, 0);
    336     psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_MN", PS_META_REPLACE, "sky model mean",          statsBck->sampleMean);
     343    psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_MN",  PS_META_REPLACE, "sky model mean",          statsBck->sampleMean);
    337344    psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_SIG", PS_META_REPLACE, "sky model stdev",         statsBck->sampleStdev);
     345    psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_DEV", PS_META_REPLACE, "sky stdev",               ValueStdev);
     346    psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_DQ",  PS_META_REPLACE, "sky quartile slope",      statsDQ->sampleMedian);
    338347    psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_MAX", PS_META_REPLACE, "sky model maximum value", statsBck->max);
    339348    psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_MIN", PS_META_REPLACE, "sky model minimum value", statsBck->min);
     
    343352              statsBck->min, statsBck->sampleMean, statsBck->max, statsBck->sampleStdev);
    344353
     354    psFree(statsDQ);
     355    psFree(dQ);
     356
    345357    psFree(stats);
    346358    psFree(statsBck);
     
    401413    int num = psphotFileruleCount(config, filerule);
    402414
     415    fprintf (stdout, "\n");
     416    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Model Background ---");
     417
    403418    // loop over the available readouts
    404419    for (int i = 0; i < num; i++) {
  • branches/meh_branches/ppstack_test/psphot/src/psphotModelTest.c

    r31452 r33415  
    1 # include "psphotInternal.h"
    2 # define PM_SOURCE_FIT_PSF_X_EXT PM_SOURCE_FIT_PSF_AND_SKY
     1# include "psphotStandAlone.h"
    32
    4 // XXX add more test information?
    5 bool psphotModelTest (pmConfig *config, const pmFPAview *view, const char *filerule, psMetadata *recipe) {
     3int main (int argc, char **argv) {
    64
    7     bool status;
    8     int modelType = -1;
    9     float obsMag, fitMag, value;
    10     char name[64];
    11     pmPSF *psf = NULL;
    12     pmSourceFitMode fitMode;
     5    psMemInit();
     6    psTimerStart ("complete");
     7    pmErrorRegister();                  // register psModule's error codes/messages
     8    psphotInit();
    139
    14     // bit-masks to test for good/bad pixels
    15     psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT");
    16     assert (maskVal);
     10    // load command-line arguments, options, and system config data
     11    pmConfig *config = psphotModelTestArguments (argc, argv);
     12    assert(config);
    1713
    18     // bit-mask to mark pixels not used in analysis
    19     psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT");
    20     assert (markVal);
     14    psphotVersionPrint();
    2115
    22     // maskVal is used to test for rejected pixels, and must include markVal
    23     maskVal |= markVal;
    24 
    25     // run model fitting tests on a single source?
    26     if (!psMetadataLookupBool (&status, recipe, "TEST_FIT")) return false;
    27 
    28     psTimerStart ("modelTest");
    29 
    30     // find the currently selected readout
    31     pmReadout  *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT");
    32     PS_ASSERT_PTR_NON_NULL (readout, false);
    33 
    34     // use poissonian errors or local-sky errors
    35     bool POISSON_ERRORS = psMetadataLookupBool (&status, recipe, filerule);
    36     if (!status) POISSON_ERRORS = true;
    37     pmSourceFitModelInit (15, 0.1, 1.0, POISSON_ERRORS);
    38 
    39     // find the various fitting parameters (try test values first)
    40     float INNER = psMetadataLookupF32 (&status, recipe, "TEST_FIT_INNER_RADIUS");
    41     if (!status || !isfinite(INNER)) {
    42         INNER = psMetadataLookupF32 (&status, recipe, "SKY_INNER_RADIUS");
    43     }
    44     float OUTER = psMetadataLookupF32 (&status, recipe, "TEST_FIT_OUTER_RADIUS");
    45     if (!status || !isfinite(OUTER)) {
    46         OUTER = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS");
    47     }
    48     float RADIUS = psMetadataLookupF32 (&status, recipe, "TEST_FIT_RADIUS");
    49     if (!status || !isfinite(RADIUS)) {
    50         RADIUS = psMetadataLookupF32 (&status, recipe, "PSF_FIT_RADIUS");
    51     }
    52     float mRADIUS = psMetadataLookupF32 (&status, recipe, "TEST_MOMENTS_RADIUS");
    53     if (!status || !isfinite(mRADIUS)) {
    54         mRADIUS = psMetadataLookupF32 (&status, recipe, "PSF_MOMENTS_RADIUS");
     16    // load input data (config and images (signal, noise, mask)
     17    if (!psphotParseCamera (config)) {
     18        psErrorStackPrint(stderr, "Error setting up the camera\n");
     19        exit (psphotGetExitStatus());
    5520    }
    5621
    57     // define the source of interest
    58     float xObj     = psMetadataLookupF32 (&status, recipe, "TEST_FIT_X");
    59     float yObj     = psMetadataLookupF32 (&status, recipe, "TEST_FIT_Y");
    60     if (!isfinite(xObj) || !isfinite(yObj)) psAbort ("object position is not defined");
    61 
    62     // what fitting mode to use?
    63     fitMode = PM_SOURCE_FIT_EXT;
    64     char *fitModeWord = psMetadataLookupStr (&status, recipe, "TEST_FIT_MODE");
    65     if (fitModeWord && !strcasecmp (fitModeWord, "PSF")) fitMode = PM_SOURCE_FIT_PSF;
    66     if (fitModeWord && !strcasecmp (fitModeWord, "CONV")) fitMode = PM_SOURCE_FIT_PSF_X_EXT;
    67     if (fitModeWord && !strcasecmp (fitModeWord, "DEFAULT")) fitMode = PM_SOURCE_FIT_EXT;
    68 
    69     // construct the source structures
    70     pmSource *source = pmSourceAlloc();
    71     source->peak = pmPeakAlloc (xObj, yObj, 0, 0);
    72     pmSourceDefinePixels (source, readout, xObj, yObj, OUTER);
    73 
    74     // in fitMode, psf sets the model type
    75     if (fitMode == PM_SOURCE_FIT_PSF) {
    76         psf = psphotLoadPSF (config, view, recipe);
    77         if (!psf) psAbort("PSF_INPUT_FILE not supplied");
    78         modelType = psf->type;
    79         source->type = PM_SOURCE_TYPE_STAR;
    80     }
    81     if (fitMode == PM_SOURCE_FIT_EXT) {
    82         // find the model: supplied by user or first in the PSF_MODEL list
    83         char *modelName  = psMetadataLookupStr (&status, recipe, "TEST_FIT_MODEL");
    84         if (!status || !strcasecmp (modelName, "DEFAULT")) {
    85             // get the list pointers for the PSF_MODEL entries
    86 
    87             psList *list = NULL;
    88             psMetadataItem *mdi = psMetadataLookup (recipe, "PSF_MODEL");
    89             if (mdi == NULL) psAbort("missing PSF_MODEL selection");
    90             if (mdi->type == PS_DATA_STRING) {
    91                 list = psListAlloc(NULL);
    92                 psListAdd (list, PS_LIST_HEAD, mdi);
    93             } else {
    94                 if (mdi->type != PS_DATA_METADATA_MULTI) psAbort("missing PSF_MODEL selection");
    95                 list = psMemIncrRefCounter(mdi->data.list);
    96             }
    97 
    98             // take the first list element
    99             psMetadataItem *item = psListGet (list, PS_LIST_HEAD);
    100             modelName = item->data.V;
    101         }
    102         modelType = pmModelClassGetType (modelName);
    103         if (modelType < 0) psAbort("unknown model %s", modelName);
    104         source->type = PM_SOURCE_TYPE_EXTENDED;
    105     }
    106     if (fitMode == PM_SOURCE_FIT_PSF_X_EXT) {
    107         // we need to load BOTH a psf and an ext model
    108         psf = psphotLoadPSF (config, view, recipe);
    109         if (!psf) psAbort("PSF_INPUT_FILE not supplied");
    110 
    111         // find the model: supplied by user or first in the PSF_MODEL list
    112         char *modelName  = psMetadataLookupStr (&status, recipe, "TEST_FIT_MODEL");
    113         if (!status || !strcasecmp (modelName, "DEFAULT")) {
    114             // get the list pointers for the PSF_MODEL entries
    115 
    116             psList *list = NULL;
    117             psMetadataItem *mdi = psMetadataLookup (recipe, "PSF_MODEL");
    118             if (mdi == NULL) psAbort("missing PSF_MODEL selection");
    119             if (mdi->type == PS_DATA_STRING) {
    120                 list = psListAlloc(NULL);
    121                 psListAdd (list, PS_LIST_HEAD, mdi);
    122             } else {
    123                 if (mdi->type != PS_DATA_METADATA_MULTI) psAbort("missing PSF_MODEL selection");
    124                 list = psMemIncrRefCounter(mdi->data.list);
    125             }
    126 
    127             // take the first list element
    128             psMetadataItem *item = psListGet (list, PS_LIST_HEAD);
    129             modelName = item->data.V;
    130         }
    131         modelType = pmModelClassGetType (modelName);
    132         if (modelType < 0) psAbort("unknown model %s", modelName);
    133         source->type = PM_SOURCE_TYPE_EXTENDED;
     22    // call psphot for each readout
     23    if (!psphotImageLoop (config, PSPHOT_MODEL_TEST)) {
     24        psErrorStackPrint(stderr, "Error in the psphot image loop\n");
     25        exit (psphotGetExitStatus());
    13426    }
    13527
    136     // find the local sky
    137     status = pmSourceLocalSky (source, PS_STAT_SAMPLE_MEDIAN, INNER, maskVal, markVal);
    138     if (!status) psAbort("pmSourceLocalSky error");
     28    psLogMsg ("psphot", 3, "complete psphot run: %f sec\n", psTimerMark ("complete"));
    13929
    140     // get the source moments
    141     status = pmSourceMoments (source, mRADIUS, 0.0, 1.0, maskVal);
    142     if (!status) psAbort("psSourceMoments error");
    143     source->peak->value = source->moments->Peak;
     30    psErrorCode exit_status = psphotGetExitStatus();
     31    psphotCleanup (config);
     32    exit (exit_status);
     33}
    14434
    145     fprintf (stderr, "sum: %f @ (%f, %f)\n", source->moments->Sum, source->moments->Mx, source->moments->My);
    146     fprintf (stderr, "moments: %f, %f - %f\n", source->moments->Mxx, source->moments->Myy, source->moments->Mxy);
    147 
    148     psEllipseMoments moments;
    149     moments.x2 = source->moments->Mxx;
    150     moments.y2 = source->moments->Myy;
    151     moments.xy = source->moments->Mxy;
    152     psEllipseAxes axes = psEllipseMomentsToAxes (moments, 20.0);
    153 
    154     fprintf (stderr, "axes: %f @ (%f, %f)\n", axes.theta*180/M_PI, axes.major, axes.minor);
    155 
    156     // get the initial model parameter guess
    157     pmModel *model = pmSourceModelGuess (source, modelType);
    158     source->modelEXT = model;
    159 
    160     // if any parameters are defined by the user, take those values
    161     int nParams = pmModelClassParameterCount (modelType);
    162     psF32 *params = model->params->data.F32;
    163     params[PM_PAR_XPOS] = xObj; // XXX use the user-supplied value,
    164     params[PM_PAR_YPOS] = yObj; // XXX or use the centroid
    165     for (int i = 0; i < nParams; i++) {
    166         if (i == PM_PAR_XPOS) continue;
    167         if (i == PM_PAR_YPOS) continue;
    168 
    169         sprintf (name, "TEST_FIT_PAR%d", i);
    170         value = psMetadataLookupF32 (&status, recipe, name);
    171         if (status && isfinite (value)) {
    172             params[i] = value;
    173         }
    174     }
    175 
    176     float area = params[4]*params[5];
    177     fprintf (stderr, "peak: %f @ (%f, %f)\n", source->moments->Sum*area, (double)source->peak->x, (double)source->peak->y);
    178 
    179     // for PSF fitting, set the shape parameters based on the PSF & source position
    180     if (fitMode == PM_SOURCE_FIT_PSF) {
    181         source->modelPSF = pmModelFromPSF (model, psf);
    182         psFree (model);
    183         model = source->modelPSF;
    184         params = model->params->data.F32;
    185     }
    186 
    187     // list model input shape
    188     psEllipseShape shape;
    189     shape.sx  = 1.4 / model->params->data.F32[4];
    190     shape.sy  = 1.4 / model->params->data.F32[5];
    191     shape.sxy = model->params->data.F32[6];
    192     axes = psEllipseShapeToAxes (shape, 20.0);
    193 
    194     fprintf (stderr, "guess: %f @ (%f, %f)\n", axes.theta*180/M_PI, axes.major, axes.minor);
    195 
    196     fprintf (stderr, "input parameters: \n");
    197     for (int i = 0; i < nParams; i++) {
    198         fprintf (stderr, "%d : %f\n", i, params[i]);
    199     }
    200 
    201     // define the pixels used for the fit
    202     psImageKeepCircle (source->maskObj, xObj, yObj, RADIUS, "OR", markVal);
    203     psphotSaveImage (NULL, source->maskObj, "mask1.fits");
    204 
    205     char *fitset = psMetadataLookupStr (&status, recipe, "TEST_FIT_SET");
    206     if (status) {
    207         status = psphotFitSet (source, model, fitset, fitMode, maskVal);
    208         exit (0);
    209     }
    210 
    211     if (fitMode == PM_SOURCE_FIT_PSF_X_EXT) {
    212         // build the psf for the object
    213         source->modelPSF = pmModelFromPSF (model, psf);
    214         source->modelEXT = model;
    215 
    216         // what fraction of the PSF is used? (radius in pixels : 2 -> 5x5 box)
    217         int psfSize = psMetadataLookupS32 (&status, recipe, "PCM_BOX_SIZE");
    218         assert (status);
    219 
    220         model = psphotPSFConvModel (readout, source, modelType, maskVal, markVal, psfSize);
    221         params = model->params->data.F32;
    222     } else {
    223         status = pmSourceFitModel (source, model, fitMode, maskVal);
    224     }
    225 
    226     // measure the source mags
    227     pmSourcePhotometryModel (&fitMag, model);
    228     pmSourcePhotometryAper  (NULL, &obsMag, NULL, NULL, model, source->pixels, source->variance, source->maskObj, maskVal);
    229     fprintf (stderr, "ap: %f, fit: %f, apmifit: %f, nIter: %d\n", obsMag, fitMag, obsMag - fitMag, model->nIter);
    230 
    231     // write out positive object
    232     psphotSaveImage (NULL, source->pixels, "object.fits");
    233 
    234     // subtract object, leave local sky
    235     // pmModelSub (source->pixels, source->maskObj, model, PM_MODEL_OP_FULL, maskVal);
    236     pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    237 
    238     fprintf (stderr, "output parameters: \n");
    239     for (int i = 0; i < nParams; i++) {
    240         fprintf (stderr, "%d : %f\n", i, params[i]);
    241     }
    242 
    243     // write out
    244     psphotSaveImage (NULL, source->pixels, "resid.fits");
    245     psphotSaveImage (NULL, source->maskObj, "mask.fits");
    246 
    247     psLogMsg ("psphot", PS_LOG_INFO, "model test : %f sec\n", psTimerMark ("modelTest"));
    248 
    249     exit (0);
    250 }
     35// all functions which return to this level must raise one of the top-level error codes if they
     36// exit with an error.  these error codes are used to specify the program exit status
  • branches/meh_branches/ppstack_test/psphot/src/psphotOutput.c

    r31452 r33415  
    325325    psMetadataItemSupplement (&status, header, analysis, "MSKY_NY");
    326326
     327    psMetadataItemSupplement (&status, header, analysis, "MSKY_DEV");
     328    psMetadataItemSupplement (&status, header, analysis, "MSKY_DQ");
     329
    327330    psMetadataItemSupplement (&status, header, analysis, "DETEFF.MAGREF");
    328331
     
    404407    return true;
    405408}
     409
     410// for now, let's store the detections on the readout->analysis for each readout
     411bool psphotDumpTest (pmConfig *config, const pmFPAview *view, const char *filerule)
     412{
     413    static int npass = 0;
     414    char filename[64];
     415
     416    // XXX dump tests are disabled unless this is commented out:
     417    return true;
     418
     419    bool status = true;
     420
     421    int num = psphotFileruleCount(config, filerule);
     422
     423    snprintf (filename, 64, "testdump.%02d.dat", npass);
     424    FILE *f = fopen (filename, "w");
     425
     426    // loop over the available readouts
     427    for (int i = 0; i < num; i++) {
     428
     429        // find the currently selected readout
     430        pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, i); // File of interest
     431        psAssert (file, "missing file?");
     432
     433        pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
     434        psAssert (readout, "missing readout?");
     435
     436        pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
     437        psAssert (detections, "missing detections?");
     438
     439        psArray *sources = detections->newSources ? detections->newSources : detections->allSources;
     440        psAssert (sources, "missing sources?");
     441
     442        if (detections->newSources) {
     443            fprintf (f, "## --- from new sources ---\n");
     444        } else {
     445            fprintf (f, "## --- from all sources ---\n");
     446        }
     447
     448        for (int i = 0; i < sources->n; i++) {
     449            pmSource *source = sources->data[i];
     450            if (!source) continue;
     451
     452            pmPeak *peak = source->peak;
     453            if (!peak) continue;
     454
     455            // XXX only dump a given region
     456            // if (peak->xf < 20) continue;
     457            // if (peak->yf < 20) continue;
     458            // if (peak->xf > 40) continue;
     459            // if (peak->yf > 70) continue;
     460
     461            float Msum = source->moments ? source->moments->Sum : NAN;
     462            float Mx   = source->moments ? source->moments->Mx : NAN;
     463            float My   = source->moments ? source->moments->My : NAN;
     464            // float Npix = source->moments ? source->moments->nPixels : NAN;
     465            float Io = source->modelPSF ? source->modelPSF->params->data.F32[PM_PAR_I0] : NAN;
     466            fprintf (f, "%d %f %f  : %f %f : %f %f\n", source->imageID, peak->xf, peak->yf, Mx, My, Msum, Io);
     467        }
     468    }
     469    fclose (f);
     470    npass ++;
     471
     472    return true;
     473}
     474
     475# if (0)
    406476bool psphotDumpTest (pmConfig *config, const pmFPAview *view, const char *filerule, char *filename) {
    407477
     
    446516    return true;
    447517}
    448 
     518# endif
  • branches/meh_branches/ppstack_test/psphot/src/psphotPSFConvModel.c

    r29004 r33415  
    4343    // adjust the pixels based on the footprint
    4444    float radius = psphotSetRadiusEXT (readout, source, markVal);
    45     if (!pmSourceMoments (source, radius, 0.0, 0.0, maskVal)) return false;
     45    if (!pmSourceMoments (source, radius, 0.25*radius, 0.0, maskVal)) return false;
    4646
    4747    // XXX test : modify the Io, SXX, SYY terms based on the psf SXX, SYY terms:
  • branches/meh_branches/ppstack_test/psphot/src/psphotPetrosianProfile.c

    r30624 r33415  
    3838    // convert the isophotal radius vs angle measurements to an elliptical contour
    3939    if (!psphotEllipticalContour (source, petrosian)) {
    40         psLogMsg ("psphot", 3, "failed to measure elliptical contour");
     40        // psLogMsg ("psphot", 3, "failed to measure elliptical contour");
    4141        psFree (petrosian);
    4242        return false;
  • branches/meh_branches/ppstack_test/psphot/src/psphotPetrosianStats.c

    r31452 r33415  
    143143    // if we failed to reach the PETROSIAN_RATIO, use the lowest significant ratio instead (flag this!)
    144144    if (!anyPetro) {
    145         // interpolate Rvec between i-1 and i to PETROSIAN_RATIO to get flux (Fvec) and radius (rvec)
    146         if (lowestSignificantRadius == 0) {
    147             // assume Fmax @ R = 0.0
    148             petRadius    = InterpolateValues     (1.0, 0.0, petRatio->data.F32[lowestSignificantRadius], refRadius->data.F32[lowestSignificantRadius], PETROSIAN_RATIO);
    149             petRadiusErr = InterpolateValuesErrX (1.0, 0.0, petRatio->data.F32[lowestSignificantRadius], refRadius->data.F32[lowestSignificantRadius], PETROSIAN_RATIO, 0.0, petRatioErr->data.F32[lowestSignificantRadius]);
    150 
    151         } else {
    152             int n0 = lowestSignificantRadius-1;
    153             int n1 = lowestSignificantRadius;
    154             petRadius    = InterpolateValues     (petRatio->data.F32[n0], refRadius->data.F32[n0], petRatio->data.F32[n1], refRadius->data.F32[n1], PETROSIAN_RATIO);
    155             petRadiusErr = InterpolateValuesErrX (petRatio->data.F32[n0], refRadius->data.F32[n0], petRatio->data.F32[n1], refRadius->data.F32[n1], PETROSIAN_RATIO, petRatioErr->data.F32[n0], petRatioErr->data.F32[n1]);
     145        petRadius = refRadius->data.F32[lowestSignificantRadius];
     146        petRadiusErr = NAN;
     147        if (!isfinite(petRadius)) {
     148            fprintf (stderr, "nan pet radius\n");
    156149        }
    157150    }
     
    170163                petArea    = InterpolateValues     (refRadius->data.F32[i-1], areaSum->data.F32[i-1], refRadius->data.F32[i], areaSum->data.F32[i], apRadius);
    171164                petApix    = InterpolateValues     (refRadius->data.F32[i-1], apixSum->data.F32[i-1], refRadius->data.F32[i], apixSum->data.F32[i], apRadius);
     165                if (!isfinite(petFlux)) {
     166                    fprintf (stderr, "nan pet flux\n");
     167                }
    172168                break;
    173169            }
     
    188184        if (!found50 && (fluxSum->data.F32[i] > flux50)) {
    189185            if (i == 0) {
    190                 psWarning ("does this case make any sense? (fluxSum[0] %f > flux50 %f)", fluxSum->data.F32[i], flux50);
    191                 continue;
     186                R50    = InterpolateValues     (fluxSum->data.F32[i], refRadius->data.F32[i], fluxSum->data.F32[i+1], refRadius->data.F32[i+1], flux50);
     187                R50err = InterpolateValuesErrX (fluxSum->data.F32[i], refRadius->data.F32[i], fluxSum->data.F32[i+1], refRadius->data.F32[i+1], flux50, sqrt(fluxSumErr2->data.F32[i]), sqrt(fluxSumErr2->data.F32[i+1]));
     188                found50 = true;
    192189            } else {
    193190                R50    = InterpolateValues     (fluxSum->data.F32[i-1], refRadius->data.F32[i-1], fluxSum->data.F32[i], refRadius->data.F32[i], flux50);
     
    198195        if (!found90 && (fluxSum->data.F32[i] > flux90)) {
    199196            if (i == 0) {
    200                 psWarning ("does this case make any sense? (fluxSum[0] %f > flux90 %f)", fluxSum->data.F32[i], flux90);
    201                 continue;
     197                R90    = InterpolateValues     (fluxSum->data.F32[i], refRadius->data.F32[i], fluxSum->data.F32[i+1], refRadius->data.F32[i+1], flux90);
     198                R90err = InterpolateValuesErrX (fluxSum->data.F32[i], refRadius->data.F32[i], fluxSum->data.F32[i+1], refRadius->data.F32[i+1], flux90, sqrt(fluxSumErr2->data.F32[i]), sqrt(fluxSumErr2->data.F32[i+1]));
     199                found90 = true;
    202200            } else {
    203201                R90    = InterpolateValues     (fluxSum->data.F32[i-1], refRadius->data.F32[i-1], fluxSum->data.F32[i], refRadius->data.F32[i], flux90);
  • branches/meh_branches/ppstack_test/psphot/src/psphotRadialApertures.c

    r31452 r33415  
    33bool psphotRadialAperturesSortFlux (psVector *radius, psVector *pixFlux, psVector *pixVar);
    44
     5// this function measures the radial aperture fluxes for the set of readouts.  this function
     6// may be called multiple times, presumably for different versions of PSF-matched or unmatched images. 
     7
    58// for now, let's store the detections on the readout->analysis for each readout
    6 bool psphotRadialApertures (pmConfig *config, const pmFPAview *view, const char *filerule)
     9bool psphotRadialApertures (pmConfig *config, const pmFPAview *view, const char *filerule, int entry)
    710{
    811    bool status = true;
     12
     13    fprintf (stdout, "\n");
     14    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Radial Apertures ---");
    915
    1016    // select the appropriate recipe information
     
    2026    int num = psphotFileruleCount(config, filerule);
    2127
     28    // skip the chisq image (optionally?)
     29    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
     30    if (!status) chisqNum = -1;
     31
    2232    // loop over the available readouts
    2333    for (int i = 0; i < num; i++) {
    24         if (!psphotRadialAperturesReadout (config, view, filerule, i, recipe)) {
     34        if (i == chisqNum) continue; // skip chisq image
     35
     36        if (!psphotRadialAperturesReadout (config, view, filerule, i, recipe, entry)) {
    2537            psError (PSPHOT_ERR_CONFIG, false, "failed on measure extended source aperture-like parameters for %s entry %d", filerule, i);
    2638            return false;
     
    3042}
    3143
     44// these values are used by all threads repeatedly (and are not modified)
     45static psVector *aperRadii = NULL;
     46static psVector *aperRadii2 = NULL;
     47static float outerRadius = NAN;
     48static float SN_LIM = NAN;
     49static psImageMaskType maskVal = 0;
     50
    3251// aperture-like measurements for extended sources
    3352// flux in simple, circular apertures
    34 bool psphotRadialAperturesReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe) {
     53// 'entry' tells us which of the matched-PSF images we are working on (0 == unmatched image, also non-stack psphot)
     54bool psphotRadialAperturesReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, int entry) {
    3555
    3656    bool status;
     
    6383    }
    6484
    65     // radMax stores the upper bounds of the annuli
     85    // determine the number of allowed threads
     86    int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads
     87    if (!status) {
     88        nThreads = 0;
     89    }
     90
     91    // aperRadii stores the upper bounds of the annuli
    6692    // XXX keep the same name here as for the petrosian / elliptical apertures?
    67     psVector *radMax = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER");
    68     psAssert (radMax, "annular bins (RADIAL.ANNULAR.BINS.UPPER) are not defined in the recipe");
    69     psAssert (radMax->n, "no valid annular bins (RADIAL.ANNULAR.BINS.UPPER) are define");
    70     float outerRadius = radMax->data.F32[radMax->n - 1];
     93    aperRadii = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER");
     94    psAssert (aperRadii, "annular bins (RADIAL.ANNULAR.BINS.UPPER) are not defined in the recipe");
     95    psAssert (aperRadii->n, "no valid annular bins (RADIAL.ANNULAR.BINS.UPPER) are define");
     96
     97    outerRadius = aperRadii->data.F32[aperRadii->n - 1];
     98
     99    // save the R^2 values as well for quicker comparison
     100    aperRadii2 = psVectorAlloc(aperRadii->n, PS_TYPE_F32);
     101    for (int i = 0; i < aperRadii->n; i++) {
     102        aperRadii2->data.F32[i] = PS_SQR(aperRadii->data.F32[i]);
     103    }
    71104
    72105    // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
    73     psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels
     106    maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels
    74107    assert (maskVal);
    75108
    76109    // S/N limit to perform full non-linear fits
    77     float SN_LIM = psMetadataLookupF32 (&status, recipe, "RADIAL_APERTURES_SN_LIM");
     110    SN_LIM = psMetadataLookupF32 (&status, recipe, "RADIAL_APERTURES_SN_LIM");
    78111
    79112    // source analysis is done in S/N order (brightest first)
     
    81114    sources = psArraySort (sources, pmSourceSortByFlux);
    82115
     116    // XXX make this consistent with entry 0 == unmatched
     117    int nEntry = 1;
     118    psVector *fwhmValues = psMetadataLookupVector(&status, readout->analysis, "STACK.PSF.FWHM.VALUES");
     119    if (fwhmValues) {
     120        psAssert (entry < fwhmValues->n, "inconsistent matched-PSF entry");
     121        nEntry = fwhmValues->n;
     122    }
     123    if (entry > 0) {
     124        psLogMsg ("psphot", PS_LOG_DETAIL, "Radial Apertures for matched image %s : PSF FWHM = %f pixels\n", file->name, fwhmValues->data.F32[entry]);
     125    } else {
     126        psLogMsg ("psphot", PS_LOG_DETAIL, "Radial Apertures for unmatched image %s\n", file->name);
     127    }
     128
    83129    // option to limit analysis to a specific region
    84130    char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION");
    85     psRegion AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region));
    86     if (psRegionIsNaN (AnalysisRegion)) psAbort("analysis region mis-defined");
     131    psRegion *AnalysisRegion = psRegionAlloc(0,0,0,0);
     132    *AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region));
     133    if (psRegionIsNaN (*AnalysisRegion)) psAbort("analysis region mis-defined");
     134
     135    // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts)
     136    int Cx = 1, Cy = 1;
     137    psphotChooseCellSizes (&Cx, &Cy, readout, nThreads);
     138
     139    psArray *cellGroups = psphotAssignSources (Cx, Cy, sources);
     140
     141    for (int i = 0; i < cellGroups->n; i++) {
     142
     143        psArray *cells = cellGroups->data[i];
     144
     145        for (int j = 0; j < cells->n; j++) {
     146
     147            // allocate a job -- if threads are not defined, this just runs the job
     148            psThreadJob *job = psThreadJobAlloc ("PSPHOT_RADIAL_APERTURES");
     149
     150            psArrayAdd(job->args, 1, readout);
     151            psArrayAdd(job->args, 1, cells->data[j]); // sources
     152            psArrayAdd(job->args, 1, AnalysisRegion);
     153            PS_ARRAY_ADD_SCALAR(job->args, entry,  PS_TYPE_S32);
     154            PS_ARRAY_ADD_SCALAR(job->args, nEntry, PS_TYPE_S32);
     155            PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nradial
     156
     157            // set this to 0 to run without threading
     158# if (1)           
     159            if (!psThreadJobAddPending(job)) {
     160                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     161                psFree(AnalysisRegion);
     162                return false;
     163            }
     164# else
     165            if (!psphotRadialApertures_Threaded(job)) {
     166                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     167                psFree(AnalysisRegion);
     168                return false;
     169            }
     170            psScalar *scalar = NULL;
     171            scalar = job->args->data[5];
     172            Nradial += scalar->data.S32;
     173            psFree(job);
     174# endif
     175        }
     176
     177        // wait for the threads to finish and manage results
     178        if (!psThreadPoolWait (false, true)) {
     179            psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     180            psFree(AnalysisRegion);
     181            return false;
     182        }
     183
     184        // we have only supplied one type of job, so we can assume the types here
     185        psThreadJob *job = NULL;
     186        while ((job = psThreadJobGetDone()) != NULL) {
     187            if (job->args->n < 1) {
     188                fprintf (stderr, "error with job\n");
     189            } else {
     190                psScalar *scalar = NULL;
     191                scalar = job->args->data[5];
     192                Nradial += scalar->data.S32;
     193            }
     194            psFree(job);
     195        }
     196    }
     197    psFree (cellGroups);
     198    psFree(AnalysisRegion);
     199    psFree (aperRadii2);
     200
     201    psLogMsg ("psphot", PS_LOG_WARN, "radial source apertures: %f sec for %d objects\n", psTimerMark ("psphot.radial"), Nradial);
     202    return true;
     203}
     204 
     205bool psphotRadialApertures_Threaded (psThreadJob *job) {
     206
     207    int Nradial = 0;
     208
     209    // arguments: readout, sources, models, region, psfSize, maskVal, markVal
     210    pmReadout *readout      = job->args->data[0];
     211    psArray *sources        = job->args->data[1];
     212    psRegion *region        = job->args->data[2];
     213    int entry               = PS_SCALAR_VALUE(job->args->data[3],S32); // which psf-matched image are we working on? (0 == unmatched)
     214    int nEntry              = PS_SCALAR_VALUE(job->args->data[4],S32); // total number of psf-matched images + 1 unmatched
     215
     216    // storage for the derived pixel values (these are passed into psphotRadialApertureSource)
     217    psVector *pixRadius2 = psVectorAllocEmpty(100, PS_TYPE_F32);
     218    psVector *pixFlux    = psVectorAllocEmpty(100, PS_TYPE_F32);
     219    psVector *pixVar     = psVectorAllocEmpty(100, PS_TYPE_F32);
    87220
    88221    // choose the sources of interest
     
    90223
    91224        pmSource *source = sources->data[i];
     225
     226        // if we have checked the source validity on the basis of the object set, then
     227        // we either skip these tests below or we skip the source completely
     228        if (source->tmpFlags & PM_SOURCE_TMPF_RADIAL_SKIP) continue;
     229        if (source->tmpFlags & PM_SOURCE_TMPF_RADIAL_KEEP) goto keepSource;
    92230
    93231        // skip PSF-like and non-astronomical objects
     
    104242
    105243        // limit selection by analysis region
    106         if (source->peak->x < AnalysisRegion.x0) continue;
    107         if (source->peak->y < AnalysisRegion.y0) continue;
    108         if (source->peak->x > AnalysisRegion.x1) continue;
    109         if (source->peak->y > AnalysisRegion.y1) continue;
     244        if (source->peak->x < region->x0) continue;
     245        if (source->peak->y < region->y0) continue;
     246        if (source->peak->x > region->x1) continue;
     247        if (source->peak->y > region->y1) continue;
     248
     249    keepSource:
    110250
    111251        // allocate pmSourceExtendedParameters, if not already defined
    112         if (!source->radialAper) {
    113             source->radialAper = psArrayAlloc(1);
     252        // XXX check that nPSFsizes is consistent with targets
     253        if (source->parent) {
     254            if (!source->parent->radialAper) {
     255                source->parent->radialAper = psArrayAlloc(nEntry);
     256            }
     257        } else {
     258            if (!source->radialAper) {
     259                source->radialAper = psArrayAlloc(nEntry);
     260            }
    114261        }
    115262
     
    119266        }
    120267
    121         // we need to change the view for the radial aperture analysis, but we want to recover exactly
    122         // the original view; the following elements get destroyed by pmSourceRedefinePixels so save them:
    123         psImage *oldMaskObj   = psMemIncrRefCounter(source->maskObj);
    124         psImage *oldModelFlux = psMemIncrRefCounter(source->modelFlux);
    125         psImage *oldPSFimage  = psMemIncrRefCounter(source->psfImage);
    126         psRegion oldRegion    = source->region;
    127 
    128268        Nradial ++;
    129269
    130         // force source image to be a bit larger...
    131         pmSourceRedefinePixels (source, readout, source->peak->xf, source->peak->yf, outerRadius + 2);
    132 
    133         if (!psphotRadialApertureSource (source, recipe, maskVal, radMax, 0)) {
     270        if (!psphotRadialApertureSource (source, readout, entry, pixRadius2, pixFlux, pixVar)) {
    134271            psTrace ("psphot", 5, "failed to extract radial profile for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
    135272        } else {
     
    137274        }
    138275
    139         pmSourceRedefinePixelsByRegion (source, readout, oldRegion);
    140         psFree(source->maskObj);   source->maskObj   = oldMaskObj;
    141         psFree(source->modelFlux); source->modelFlux = oldModelFlux;
    142         psFree(source->psfImage);  source->psfImage  = oldPSFimage;
    143        
    144276        // re-subtract the object, leave local sky
    145277        pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    146278    }
    147 
    148     psLogMsg ("psphot", PS_LOG_INFO, "radial source apertures: %f sec for %d objects\n", psTimerMark ("psphot.radial"), Nradial);
     279    psScalar *scalar = job->args->data[5];
     280    scalar->data.S32 = Nradial;
     281
     282    psFree (pixRadius2);
     283    psFree (pixFlux);
     284    psFree (pixVar);
     285
    149286    return true;
    150287}
    151288
    152 bool psphotRadialApertureSource (pmSource *source, psMetadata *recipe, psImageMaskType maskVal, const psVector *aperRadii, int entry) {
    153 
     289bool psphotRadialApertureSource (pmSource *source, pmReadout *readout, int entry, psVector *pixRadius2, psVector *pixFlux, psVector *pixVar) {
     290                                           
    154291    // if we are a child source, save the results to the parent source radial aperture array
    155292    psArray *radialAperSet = source->radialAper;
     
    163300    radialAperSet->data[entry] = radialAper;
    164301
    165     // storage for the derived pixel values
    166     psVector *pixRadius2 = psVectorAllocEmpty(100, PS_TYPE_F32);
    167     psVector *pixFlux    = psVectorAllocEmpty(100, PS_TYPE_F32);
    168     psVector *pixVar     = psVectorAllocEmpty(100, PS_TYPE_F32);
     302    // find the largest aperture of interest (use only apertures with inner radii <=
     303    // source->skyRadius)
     304    int lastAp = aperRadii->n;
     305    for (int i = 0; i < aperRadii->n; i++) {
     306        if (aperRadii->data.F32[i] < source->skyRadius) continue;
     307        lastAp = i + 1;
     308        break;
     309    }
    169310
    170311    // outer-most radius for initial truncation
    171     float Rmax  = aperRadii->data.F32[aperRadii->n - 1];
     312    float Rmax  = aperRadii->data.F32[lastAp - 1];
    172313    float Rmax2 = PS_SQR(Rmax);
    173314
    174     // store the R^2 values for the apertures
    175     psVector *aperRadii2 = psVectorAlloc(aperRadii->n, PS_TYPE_F32);
    176     for (int i = 0; i < aperRadii->n; i++) {
    177         aperRadii2->data.F32[i] = PS_SQR(aperRadii->data.F32[i]);
    178     }
     315    // in this function, the operatins are relative to the full image (readout->image, etc)
    179316
    180317    float xCM = NAN, yCM = NAN;
    181318    if (pmSourcePositionUseMoments(source)) {
    182         xCM = source->moments->Mx - 0.5 - source->pixels->col0; // coord of peak in subimage
    183         yCM = source->moments->My - 0.5 - source->pixels->row0; // coord of peak in subimage
     319        xCM = source->moments->Mx; // index coord of peak in readout
     320        yCM = source->moments->My; // index coord of peak in readout
    184321    } else {
    185         xCM = source->peak->xf - 0.5 - source->pixels->col0; // coord of peak in subimage
    186         yCM = source->peak->yf - 0.5 - source->pixels->row0; // coord of peak in subimage
    187     }
     322        xCM = source->peak->xf; // index coord of peak in readout
     323        yCM = source->peak->yf; // index coord of peak in readout
     324    }
     325
     326    int Nx = readout->image->numCols;
     327    int Ny = readout->image->numRows;
     328
     329    pixRadius2->n = 0;
     330    pixFlux->n = 0;
     331    pixVar->n = 0;
    188332
    189333    // one pass through the pixels to select the valid pixels and calculate R^2
    190     for (int iy = 0; iy < source->pixels->numRows; iy++) {
    191 
    192         float yDiff = iy - yCM;
    193         if (fabs(yDiff) > Rmax) continue;
    194 
    195         float *vPix = source->pixels->data.F32[iy];
    196         float *vWgt = source->variance->data.F32[iy];
    197         psImageMaskType  *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[iy];
    198 
    199         for (int ix = 0; ix < source->pixels->numCols; ix++, vPix++, vWgt++) {
    200 
    201             if (vMsk) {
    202                 if (*vMsk & maskVal) {
    203                     vMsk++;
    204                     continue;
    205                 }
    206                 vMsk++;
    207             }
    208             if (isnan(*vPix)) continue;
    209 
    210             float xDiff = ix - xCM;
    211             if (fabs(xDiff) > Rmax) continue;
     334    for (int iy = -Rmax; iy < Rmax + 1; iy++) {
     335
     336        float yDiff = iy + 0.5 + yCM;  // y-coordinate at this offse
     337        int yPix = (int) yDiff;
     338
     339        if (yPix < 0) continue;
     340        if (yPix > Ny - 1) continue;
     341        if (fabs(iy) > Rmax) continue;
     342
     343        float *vPix = readout->image->data.F32[yPix];
     344        float *vWgt = readout->variance->data.F32[yPix];
     345        psImageMaskType  *vMsk = readout->mask->data.PS_TYPE_IMAGE_MASK_DATA[yPix];
     346
     347        for (int ix = -Rmax; ix < Rmax + 1; ix++) {
     348
     349            float xDiff = ix + 0.5 + xCM;  // x-coordinate at this offse
     350            int xPix = (int) xDiff;
     351           
     352            if (xPix < 0) continue;
     353            if (xPix > Nx - 1) continue;
     354            if (fabs(ix) > Rmax) continue;
     355           
     356            if (vMsk[xPix] & maskVal) continue;
     357            if (isnan(vPix[xPix])) continue;
    212358
    213359            // radius is just a function of (xDiff, yDiff)
    214             float r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
     360            float r2  = PS_SQR(ix) + PS_SQR(iy);
    215361            if (r2 > Rmax2) continue;
    216362
    217363            psVectorAppend(pixRadius2, r2);
    218             psVectorAppend(pixFlux, *vPix);
    219             psVectorAppend(pixVar, *vWgt);
     364            psVectorAppend(pixFlux, vPix[xPix]);
     365            psVectorAppend(pixVar, vWgt[xPix]);
    220366        }
    221367    }
     
    226372    psVector *fill    = psVectorAlloc(aperRadii->n, PS_TYPE_F32); // surface brightness of radial bin
    227373
     374    // init the apertures of interest to 0.0, the rest go to NAN
    228375    psVectorInit (flux,    0.0);
    229376    psVectorInit (fluxStd, 0.0);
    230377    psVectorInit (fluxErr, 0.0);
    231378    psVectorInit (fill,    0.0);
     379    for (int i = lastAp; i < flux->n; i++) {
     380        flux->data.F32[i] = NAN;
     381        fluxStd->data.F32[i] = NAN;
     382        fluxErr->data.F32[i] = NAN;
     383        fill->data.F32[i] = NAN;
     384    }
    232385
    233386    float *rPix2 = pixRadius2->data.F32;
     
    236389        int j = 0;
    237390        float *aRad2 = aperRadii2->data.F32;
    238         for (; (*aRad2 < *rPix2) && (j < aperRadii2->n); j++, aRad2++);
    239         for (; j < aperRadii2->n; j++, aRad2++) {
     391        for (; (*aRad2 < *rPix2) && (j < lastAp); j++, aRad2++);
     392
     393        // XXX I can speed this up by only saving this single aperture
     394        for (; j < lastAp; j++, aRad2++) {
    240395            flux->data.F32[j]    += pixFlux->data.F32[i];
    241396            fluxStd->data.F32[j] += PS_SQR(pixFlux->data.F32[i]);
     
    249404       2) the fractional fill factor (count of valid pixels / effective area of the aperture
    250405       3) the error on the flux within that aperture
    251      */
    252 
    253     for (int i = 0; i < flux->n; i++) {
     406    */
     407
     408    for (int i = 0; i < lastAp; i++) {
    254409        // calculate the total flux for bin 'nOut'
    255410        float Area = M_PI*aperRadii2->data.F32[i];
     
    261416        // XXX report the total flux or the mask-corrected flux?
    262417        // flux->data.F32[i]    = SBmean * Area;
    263         // fluxErr->data.F32[i] = sqrt(fluxErr->data.F32[i]) * Area / nPix;
     418        // fluxErr->data.F32[i] = sqrt(fluxErr->data.F32[i]) * Area / Pinx;
    264419
    265420        fluxErr->data.F32[i] = sqrt(fluxErr->data.F32[i]);
     
    271426    }
    272427   
     428# if (1)
    273429    radialAper->flux = flux;
    274430    radialAper->fluxStdev = fluxStd;
    275431    radialAper->fluxErr = fluxErr;
    276432    radialAper->fill = fill;
    277 
    278     psFree (aperRadii2);
    279     psFree (pixRadius2);
    280     psFree (pixFlux);
    281     psFree (pixVar);
     433# else
     434    // XXX TEST
     435    psFree(flux);
     436    psFree(fluxStd);
     437    psFree(fluxErr);
     438    psFree(fill);
     439# endif
    282440
    283441    return true;
    284442}
     443
     444/*** below is a test to use a sort to speed this up, not very successfully ***/
    285445
    286446static int nCalls = 0;
     
    373533// *** pmSourceRadialProfileSortPair is a utility function for sorting a pair of vectors
    374534# define COMPARE_VECT(A,B) (radius->data.F32[A] < radius->data.F32[B])
    375 # define SWAP_VECT(TYPE,A,B) { \
    376   float tmp; \
    377   if (A != B) { \
    378     tmp = radius->data.F32[A]; \
    379     radius->data.F32[A] = radius->data.F32[B];  \
    380     radius->data.F32[B] = tmp; \
    381     tmp = pixFlux->data.F32[A]; \
    382     pixFlux->data.F32[A] = pixFlux->data.F32[B]; \
    383     pixFlux->data.F32[B] = tmp; \
    384     tmp = pixVar->data.F32[A]; \
    385     pixVar->data.F32[A] = pixVar->data.F32[B]; \
    386     pixVar->data.F32[B] = tmp; \
    387   } \
    388 }
     535# define SWAP_VECT(TYPE,A,B) {                                  \
     536        float tmp;                                              \
     537        if (A != B) {                                           \
     538            tmp = radius->data.F32[A];                          \
     539            radius->data.F32[A] = radius->data.F32[B];          \
     540            radius->data.F32[B] = tmp;                          \
     541            tmp = pixFlux->data.F32[A];                         \
     542            pixFlux->data.F32[A] = pixFlux->data.F32[B];        \
     543            pixFlux->data.F32[B] = tmp;                         \
     544            tmp = pixVar->data.F32[A];                          \
     545            pixVar->data.F32[A] = pixVar->data.F32[B];          \
     546            pixVar->data.F32[B] = tmp;                          \
     547        }                                                       \
     548    }
    389549
    390550bool psphotRadialAperturesSortFlux (psVector *radius, psVector *pixFlux, psVector *pixVar) {
  • branches/meh_branches/ppstack_test/psphot/src/psphotRadialAperturesByObject.c

    r31154 r33415  
    162162            // re-subtract the object, leave local sky
    163163            pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    164 
    165             // psLogMsg("psphot", PS_LOG_INFO, "radial apertures for %d", index);
    166             // psphotVisualShowImage(readout);
    167164        }
    168165    }
  • branches/meh_branches/ppstack_test/psphot/src/psphotRadialProfile.c

    r31154 r33415  
    3939    // convert the isophotal radius vs angle measurements to an elliptical contour
    4040    if (!psphotEllipticalContour (source)) {
    41         psLogMsg ("psphot", 3, "failed to measure elliptical contour");
     41        // psLogMsg ("psphot", 3, "failed to measure elliptical contour");
    4242        return false;
    4343    }
  • branches/meh_branches/ppstack_test/psphot/src/psphotRadiusChecks.c

    r31452 r33415  
    142142}
    143143
     144# define MIN_WINDOW 5.0
     145# define SCALE1 5.0
     146# define SCALE2 12.0
     147
     148// call this function whenever you (re)-define the EXT model
     149// XXX this function does not shrink the window
     150bool psphotSetRadiusMoments (float *fitRadius, float *windowRadius, pmReadout *readout, pmSource *source, psImageMaskType markVal) {
     151
     152    psAssert (source, "source not defined??");
     153    psAssert (source->moments, "moments not defined??");
     154
     155    *fitRadius = SCALE1 * source->moments->Mrf;
     156    *fitRadius = PS_MIN (PS_MAX(*fitRadius, MIN_WINDOW), EXT_FIT_MAX_RADIUS);
     157
     158    *windowRadius = SCALE2 * source->moments->Mrf;
     159    *windowRadius = PS_MIN (PS_MAX(*windowRadius, 2.5*MIN_WINDOW), 2.5*EXT_FIT_MAX_RADIUS);
     160
     161    // redefine the pixels if needed
     162    pmSourceRedefinePixels (source, readout, source->peak->xf, source->peak->yf, *windowRadius);
     163
     164    // set the mask to flag the excluded pixels
     165    psImageKeepCircle (source->maskObj, source->peak->xf, source->peak->yf, *fitRadius, "OR", markVal);
     166
     167    return true;
     168}
     169# undef SCALE1
     170# undef SCALE2
     171# undef MIN_WINDOW
     172
     173# define MIN_WINDOW 5.0
     174# define SCALE1 5.0
     175# define PAD_WINDOW 3.0
     176
     177// call this function whenever you (re)-define the EXT model
     178// XXX alternate function to set exactly the desired window size
     179bool psphotSetRadiusMomentsExact (float *fitRadius, float *windowRadius, pmReadout *readout, pmSource *source, psImageMaskType markVal) {
     180
     181    psRegion newRegion;
     182
     183    psAssert (source, "source not defined??");
     184    psAssert (source->moments, "moments not defined??");
     185
     186    *fitRadius = SCALE1 * source->moments->Mrf;
     187    *fitRadius = PS_MIN (PS_MAX(*fitRadius, MIN_WINDOW), EXT_FIT_MAX_RADIUS);
     188
     189    *windowRadius = *fitRadius + PAD_WINDOW;
     190
     191    // check to see if new region is completely contained within old region
     192    newRegion = psRegionForSquare (source->peak->xf, source->peak->yf, *windowRadius);
     193    newRegion = psRegionForImage (readout->image, newRegion);
     194
     195    // redefine the pixels to match
     196    pmSourceRedefinePixelsByRegion (source, readout, newRegion);
     197
     198    // set the mask to flag the excluded pixels
     199    psImageKeepCircle (source->maskObj, source->peak->xf, source->peak->yf, *fitRadius, "OR", markVal);
     200
     201    return true;
     202}
     203
    144204// call this function whenever you (re)-define the EXT model
    145205bool psphotSetRadiusFootprint (float *radius, pmReadout *readout, pmSource *source, psImageMaskType markVal, float factor) {
     
    181241}
    182242
     243// call this function whenever you (re)-define the EXT model
     244bool psphotMaskFootprint (pmReadout *readout, pmSource *source, psImageMaskType markVal) {
     245
     246    psAssert (source, "source not defined??");
     247    psAssert (source->peak, "peak not defined??");
     248
     249    pmPeak *peak = source->peak;
     250
     251    // set the radius based on the footprint:
     252    if (!peak->footprint) return false;
     253    pmFootprint *footprint = peak->footprint;
     254    if (!footprint->spans) return false;
     255    if (footprint->spans->n < 1) return false;
     256
     257    int Xo = source->maskObj->col0;
     258    int Yo = source->maskObj->row0;
     259
     260    // mark all pixels
     261    for (int j = 0; j < source->maskObj->numRows; j++) {
     262        for (int i = 0; i < source->maskObj->numCols; i++) {
     263            source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[j][i] |= markVal;
     264        }
     265    }
     266
     267    psImageMaskType clearVal = PS_NOT_IMAGE_MASK(markVal);
     268
     269    for (int j = 0; j < footprint->spans->n; j++) {
     270        pmSpan *span = footprint->spans->data[j];
     271
     272        // mask the rows before and after each span
     273        int minX = span->x0 - Xo - 2;
     274        int maxX = span->x1 - Xo + 2;
     275        int myY = span->y - Yo;
     276
     277        // unmark pixels inside the footprint
     278        for (int i = minX; i <= maxX; i++) {
     279            source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[myY][i] &= clearVal;
     280        }
     281    }
     282    return true;
     283}
     284
    183285// alternative EXT radius based on model guess (for use without footprints)
    184286bool psphotSetRadiusModel (pmModel *model, pmReadout *readout, pmSource *source, psImageMaskType markVal, bool deep) {
  • branches/meh_branches/ppstack_test/psphot/src/psphotReadout.c

    r31452 r33415  
    99}
    1010
    11 // for now, let's store the detections on the readout->analysis for each readout
    12 bool psphotDumpChisqs (pmConfig *config, const pmFPAview *view, const char *filerule)
    13 {
    14     static int npass = 0;
    15     char filename[64];
    16 
    17     return true;
    18 
    19     bool status = true;
    20 
    21     int num = psphotFileruleCount(config, filerule);
    22 
    23     snprintf (filename, 64, "chisq.%02d.dat", npass);
    24     FILE *f = fopen (filename, "w");
    25 
    26     // loop over the available readouts
    27     for (int i = 0; i < num; i++) {
    28 
    29         // find the currently selected readout
    30         pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, i); // File of interest
    31         psAssert (file, "missing file?");
    32 
    33         pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
    34         psAssert (readout, "missing readout?");
    35 
    36         pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
    37         psAssert (detections, "missing detections?");
    38 
    39         psArray *sources = detections->allSources;
    40         psAssert (sources, "missing sources?");
    41 
    42         for (int i = 0; i < sources->n; i++) {
    43             pmSource *source = sources->data[i];
    44             if (!source) continue;
    45 
    46             pmModel *model = pmSourceGetModel (NULL, source);
    47             if (!model) continue;
    48        
    49             if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) {
    50                 fprintf (f, "%f %f %f %d %d %f  1 NONLINEAR\n", model->mag, model->params->data.F32[1], model->chisq, model->nDOF, model->nPix, model->chisqNorm);
    51             } else {
    52                 fprintf (f, "%f %f %f %d %d %f  0 LINEAR\n", model->mag, model->params->data.F32[1], model->chisq, model->nDOF, model->nPix, model->chisqNorm);
    53             }
    54         }
    55     }
    56     fclose (f);
    57     npass ++;
    58 
    59     return true;
    60 }
    61 
    6211bool psphotReadout(pmConfig *config, const pmFPAview *view, const char *filerule) {
    6312
     
    10251        return psphotReadoutCleanup (config, view, filerule);
    10352    }
    104 
    105 # if (0)
    106     // XXX test to mask outliers, not very helpful
    107     // mask the high values in the image (with MARK)
    108     if (!psphotMaskBackground (config, view, filerule)) {
    109         return psphotReadoutCleanup (config, view, filerule);
    110     }
    111 
    112     // generate a background model (median, smoothed image)
    113     if (!psphotModelBackground (config, view, filerule)) {
    114         return psphotReadoutCleanup (config, view, filerule);
    115     }
    116 # endif
    117 
    11853    if (!psphotSubtractBackground (config, view, filerule)) {
    11954        return psphotReadoutCleanup (config, view, filerule);
     
    13772    }
    13873
    139     // construct sources and measure basic stats (saved on detections->newSources)
     74    // construct sources and measure moments and other basic stats (saved on detections->newSources)
     75    // all sources use the auto-scaled window appropriate to a PSF, except for the saturated
     76    // stars : these use a larger window (3x the basic window)
    14077    if (!psphotSourceStats (config, view, filerule, true)) { // pass 1
    14178        psError(PSPHOT_ERR_UNKNOWN, false, "failure to generate sources");
     
    15390
    15491    // mark blended peaks PS_SOURCE_BLEND (detections->newSources)
    155     if (!psphotBasicDeblend (config, view, filerule)) {
     92    // XXX I've deactivated this because it was preventing galaxies close to stars from being
     93    // XXX fitted as an extended source.
     94    if (false && !psphotBasicDeblend (config, view, filerule)) {
    15695        psError (PSPHOT_ERR_UNKNOWN, false, "failed on deblend analysis");
    15796        return psphotReadoutCleanup (config, view, filerule);
     
    188127    // psphotLoadExtSources (config, view, filerule); // pass 1
    189128
    190     // construct an initial model for each object, set the radius to fitRadius, set circular
    191     // fit mask (detections->newSources)
    192     psphotGuessModels (config, view, filerule); // pass 1
    193 
    194129    // merge the newly selected sources into the existing list
    195130    // NOTE: merge OLD and NEW
    196131    psphotMergeSources (config, view, filerule);
    197132
     133    // Construct an initial model for each object, set the radius to fitRadius, set circular
     134    // fit mask.  NOTE: only applied to sources without guess models
     135    // pass 1
     136    if (!psphotGuessModels (config, view, filerule)) {
     137        psLogMsg ("psphot", 3, "failure to Guess Model - pass 1");
     138        return psphotReadoutCleanup (config, view, filerule);
     139    }
     140
    198141    // linear PSF fit to source peaks, subtract the models from the image (in PSF mask)
    199142    psphotFitSourcesLinear (config, view, filerule, false); // pass 1 (detections->allSources)
    200     psphotDumpChisqs (config, view, filerule);
    201 
    202     // XXX re-measure the kron mags with models subtracted
    203     psphotKronMasked(config, view, filerule);
     143
     144    // measure the radial profiles to the sky
     145    psphotRadialProfileWings (config, view, filerule);
     146
     147    // re-measure the kron mags with models subtracted.  this pass uses a circular window of size PSF_MOMENTS_RADIUS (same window used to measure the psf-scale moments)
     148   
     149    // but this is chosen above to be appropriate for the PSF objects (not galaxies)
     150    // psphotKronMasked(config, view, filerule);
     151    psphotKronIterate(config, view, filerule);
    204152
    205153    // identify CRs and extended sources (only unmeasured sources are measured)
     
    211159    // non-linear PSF and EXT fit to brighter sources
    212160    // replace model flux, adjust mask as needed, fit, subtract the models (full stamp)
     161    // XXX: can leave faulted job in done queue
    213162    psphotBlendFit (config, view, filerule); // pass 1 (detections->allSources)
    214     psphotDumpChisqs (config, view, filerule);
    215163
    216164    // replace all sources
    217     psphotReplaceAllSources (config, view, filerule); // pass 1 (detections->allSources)
     165    psphotReplaceAllSources (config, view, filerule, false); // pass 1 (detections->allSources)
    218166
    219167    // linear fit to include all sources (subtract again)
    220168    // NOTE : apply to ALL sources (extended + psf)
    221169    psphotFitSourcesLinear (config, view, filerule, true); // pass 2 (detections->allSources)
    222     psphotDumpChisqs (config, view, filerule);
    223170
    224171    // if we only do one pass, skip to extended source analysis
     
    240187        psphotSubNoise (config, view, filerule); // pass 1 (detections->allSources)
    241188
    242         // define new sources based on only the new peaks
     189        // define new sources based on only the new peaks & measure moments
    243190        // NOTE: new sources are saved on detections->newSources
    244191        psphotSourceStats (config, view, filerule, false); // pass 2 (detections->newSources)
     
    251198        }
    252199
    253         // create full input models, set the radius to fitRadius, set circular fit mask
    254         // NOTE: apply only to detections->newSources
    255         psphotGuessModels (config, view, filerule); // pass 2 (detections->newSources)
    256 
    257200        // replace all sources so fit below applies to all at once
    258201        // NOTE: apply only to OLD sources (which have been subtracted)
    259         psphotReplaceAllSources (config, view, filerule); // pass 2
     202        psphotReplaceAllSources (config, view, filerule, false); // pass 2
    260203
    261204        // merge the newly selected sources into the existing list
     
    264207        psphotMergeSources (config, view, filerule); // (detections->newSources + detections->allSources -> detections->allSources)
    265208
     209        // Construct an initial model for each object, set the radius to fitRadius, set circular
     210        // fit mask.  NOTE: only applied to sources without guess models
     211        psphotGuessModels (config, view, filerule); // pass 1
     212
    266213        // NOTE: apply to ALL sources
    267214        psphotFitSourcesLinear (config, view, filerule, true); // pass 3 (detections->allSources)
    268         psphotDumpChisqs (config, view, filerule);
    269215    }
    270216
     
    293239        }
    294240
    295         // create full input models, set the radius to fitRadius, set circular fit mask
    296         // NOTE: apply only to detections->newSources
    297         psphotGuessModels (config, view, filerule); // pass 2 (detections->newSources)
    298 
    299241        // replace all sources so fit below applies to all at once
    300242        // NOTE: apply only to OLD sources (which have been subtracted)
    301         psphotReplaceAllSources (config, view, filerule); // pass 2
     243        psphotReplaceAllSources (config, view, filerule, false); // pass 2
    302244
    303245        // merge the newly selected sources into the existing list
     
    306248        psphotMergeSources (config, view, filerule); // (detections->newSources + detections->allSources -> detections->allSources)
    307249
     250        // Construct an initial model for each object, set the radius to fitRadius, set circular
     251        // fit mask.  NOTE: only applied to sources without guess models
     252        psphotGuessModels (config, view, filerule); // pass 1
     253
    308254        // NOTE: apply to ALL sources
    309255        psphotFitSourcesLinear (config, view, filerule, true); // pass 3 (detections->allSources)
     
    312258pass1finish:
    313259
    314     // XXX re-measure the kron mags with models subtracted
    315     psphotKronMasked(config, view, filerule);
     260    // measure the radial profiles to the sky (only measures new objects)
     261    psphotRadialProfileWings (config, view, filerule);
     262
     263    // re-measure the kron mags with models subtracted
     264    // psphotKronMasked(config, view, filerule);
     265    psphotKronIterate(config, view, filerule);
    316266
    317267    // measure source size for the remaining sources
     
    321271    psphotExtendedSourceAnalysis (config, view, filerule); // pass 1 (detections->allSources)
    322272    psphotExtendedSourceFits (config, view, filerule); // pass 1 (detections->allSources)
    323     psphotRadialApertures(config, view, filerule);
     273    psphotRadialApertures(config, view, filerule, 0);
    324274
    325275finish:
     
    359309    }
    360310
     311    psLogMsg ("psphot.readout", PS_LOG_WARN, "complete psphot readout : %f sec\n", psTimerMark ("psphotReadout"));
     312
    361313    // create the exported-metadata and free local data
    362314    return psphotReadoutCleanup(config, view, filerule);
  • branches/meh_branches/ppstack_test/psphot/src/psphotReadoutFindPSF.c

    r30624 r33415  
    5454    }
    5555
     56    // merge the newly selected sources into the existing list
     57    // NOTE: merge OLD and NEW
     58    psphotMergeSources (config, view, filerule);
     59
    5660# if 0
    5761    // XXX if we want to determine the aperture residual correction here, we either
     
    6165    psphotGuessModels (config, view, filerule);
    6266# endif
    63 
    64     // merge the newly selected sources into the existing list
    65     // NOTE: merge OLD and NEW
    66     psphotMergeSources (config, view, filerule);
    6767
    6868# if 0
  • branches/meh_branches/ppstack_test/psphot/src/psphotReadoutForcedKnownSources.c

    r29936 r33415  
    3636    }
    3737
    38     // construct an initial model for each object
    39     psphotGuessModels (config, view, filerule);
    40 
    4138    // merge the newly selected sources into the existing list
    4239    // NOTE: merge OLD and NEW
    4340    psphotMergeSources (config, view, filerule);
     41
     42    // Construct an initial model for each object, set the radius to fitRadius, set circular
     43    // fit mask.  NOTE: only applied to sources without guess models
     44    psphotGuessModels (config, view, filerule);
    4445
    4546    // linear PSF fit to source peaks
  • branches/meh_branches/ppstack_test/psphot/src/psphotReadoutKnownSources.c

    r30624 r33415  
    4848    }
    4949
    50     // construct an initial model for each object
    51     psphotGuessModels (config, view, filerule);
    52 
    5350    // merge the newly selected sources into the existing list
    5451    // NOTE: merge OLD and NEW
    5552    psphotMergeSources (config, view, filerule);
     53
     54    // Construct an initial model for each object, set the radius to fitRadius, set circular
     55    // fit mask.  NOTE: only applied to sources without guess models
     56    psphotGuessModels (config, view, filerule);
    5657
    5758    // linear PSF fit to source peaks
  • branches/meh_branches/ppstack_test/psphot/src/psphotReadoutMinimal.c

    r29936 r33415  
    5959    }
    6060
    61     // construct an initial model for each object
    62     psphotGuessModels (config, view, filerule);
    63 
    6461    // merge the newly selected sources into the existing list
    6562    psphotMergeSources (config, view, filerule);
     63
     64    // Construct an initial model for each object, set the radius to fitRadius, set circular
     65    // fit mask.  NOTE: only applied to sources without guess models
     66    psphotGuessModels (config, view, filerule);
    6667
    6768    // linear PSF fit to source peaks
  • branches/meh_branches/ppstack_test/psphot/src/psphotReplaceUnfit.c

    r31452 r33415  
    99
    1010    for (int i = 0; i < sources->n; i++) {
    11       source = sources->data[i];
    12 
    13       // replace other sources?
    14       if (source->mode & PM_SOURCE_MODE_FAIL) goto replace;
    15       continue;
     11        source = sources->data[i];
     12
     13        // replace other sources?
     14        if (source->mode & PM_SOURCE_MODE_FAIL) goto replace;
     15        continue;
    1616
    1717    replace:
     
    2323
    2424// for now, let's store the detections on the readout->analysis for each readout
    25 bool psphotReplaceAllSources (pmConfig *config, const pmFPAview *view, const char *filerule)
     25bool psphotReplaceAllSources (pmConfig *config, const pmFPAview *view, const char *filerule, bool ignoreState)
    2626{
    2727    bool status = true;
     
    3535    // loop over the available readouts
    3636    for (int i = 0; i < num; i++) {
    37         if (!psphotReplaceAllSourcesReadout (config, view, filerule, i, recipe)) {
     37        if (!psphotReplaceAllSourcesReadout (config, view, filerule, i, recipe, ignoreState)) {
    3838            psError (PSPHOT_ERR_CONFIG, false, "failed to replace all sources for %s entry %d", filerule, i);
    3939            return false;
     
    4343}
    4444
    45 bool psphotReplaceAllSourcesReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) {
    46 
    47     bool status;
    48     pmSource *source;
     45bool psphotReplaceAllSourcesReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool ignoreState) {
     46
     47    bool status;
    4948
    5049    psTimerStart ("psphot.replace");
     
    7574
    7675    for (int i = 0; i < sources->n; i++) {
    77       source = sources->data[i];
    78 
    79       // replace other sources?
    80       if (!(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED)) continue;
    81 
    82       pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
     76        pmSource *source = sources->data[i];
     77
     78        if (ignoreState) {
     79            // rely on the type of source to decide if we subtract it or not
     80
     81            // skip non-astronomical objects (very likely defects)
     82            if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
     83            if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
     84     
     85            // do not include CRs in the full ensemble fit
     86            if (source->mode & PM_SOURCE_MODE_CR_LIMIT) continue;
     87       
     88            // do not include MOMENTS_FAILURES in the fit
     89            if (source->mode & PM_SOURCE_MODE_MOMENTS_FAILURE) continue;
     90        } else {
     91            // if we respect the state, do not replace unsubtracted sources
     92            if (!(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED)) continue;
     93        }
     94
     95        pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
    8396    }
    8497
     
    88101}
    89102
    90 bool psphotRemoveAllSources (const psArray *sources, const psMetadata *recipe) {
     103// for now, let's store the detections on the readout->analysis for each readout
     104bool psphotRemoveAllSources (pmConfig *config, const pmFPAview *view, const char *filerule, bool ignoreState)
     105{
     106    bool status = true;
     107
     108    // select the appropriate recipe information
     109    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     110    psAssert (recipe, "missing recipe?");
     111
     112    int num = psphotFileruleCount(config, filerule);
     113
     114    // loop over the available readouts
     115    for (int i = 0; i < num; i++) {
     116        if (!psphotRemoveAllSourcesReadout (config, view, filerule, i, recipe, ignoreState)) {
     117            psError (PSPHOT_ERR_CONFIG, false, "failed to replace all sources for %s entry %d", filerule, i);
     118            return false;
     119        }
     120    }
     121    return true;
     122}
     123
     124bool psphotRemoveAllSourcesReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool ignoreState) {
     125
     126    bool status;
     127
     128    psTimerStart ("psphot.replace");
     129
     130    // find the currently selected readout
     131    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
     132    psAssert (file, "missing file?");
     133
     134    pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
     135    psAssert (readout, "missing readout?");
     136
     137    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
     138    psAssert (detections, "missing detections?");
     139
     140    psArray *sources = detections->allSources;
     141    psAssert (sources, "missing sources?");
     142
     143    // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
     144    psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels
     145    psAssert (maskVal, "missing mask value?");
     146
     147    // bit-mask to mark pixels not used in analysis
     148    psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT");
     149    assert (markVal);
     150
     151    // maskVal is used to test for rejected pixels, and must include markVal
     152    maskVal |= markVal;
     153
     154    for (int i = 0; i < sources->n; i++) {
     155        pmSource *source = sources->data[i];
     156
     157        if (ignoreState) {
     158            // rely on the type of source to decide if we subtract it or not
     159
     160            // skip non-astronomical objects (very likely defects)
     161            if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
     162            if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
     163     
     164            // do not include CRs in the full ensemble fit
     165            if (source->mode & PM_SOURCE_MODE_CR_LIMIT) continue;
     166       
     167            // do not include MOMENTS_FAILURES in the fit
     168            if (source->mode & PM_SOURCE_MODE_MOMENTS_FAILURE) continue;
     169        } else {
     170            // if we respect the state, only remove unsubtracted sources
     171            if ((source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED)) continue;
     172        }
     173
     174        pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
     175    }
     176
     177    psphotVisualShowImage(readout);
     178    psLogMsg ("psphot.replace", PS_LOG_INFO, "replaced models for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.replace"));
     179    return true;
     180}
     181
     182bool psphotRemoveAllSourcesByArray (const psArray *sources, const psMetadata *recipe) {
    91183
    92184    bool status;
     
    100192
    101193    for (int i = 0; i < sources->n; i++) {
    102       source = sources->data[i];
    103 
    104       // replace other sources?
    105       if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) continue;
    106 
    107       pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
     194        source = sources->data[i];
     195
     196        // replace other sources?
     197        if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) continue;
     198
     199        pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    108200    }
    109201    psLogMsg ("psphot.replace", PS_LOG_INFO, "replaced models for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.replace"));
     
    158250
    159251    for (int i = 0; i < sources->n; i++) {
    160       source = sources->data[i];
    161 
    162       // sources have not yet been subtracted in this image (but this flag may be raised)
    163       source->tmpFlags &= ~PM_SOURCE_TMPF_SUBTRACTED;
    164       if (!source->modelPSF) continue;
    165 
    166       float Xo = source->modelPSF->params->data.F32[PM_PAR_XPOS];
    167       float Yo = source->modelPSF->params->data.F32[PM_PAR_YPOS];
    168       float radius = source->modelPSF->fitRadius;
    169 
    170       // force a redefine to this image
    171       pmSourceFreePixels(source);
    172       pmSourceRedefinePixels (source, readout, Xo, Yo, radius);
     252        source = sources->data[i];
     253
     254        // sources have not yet been subtracted in this image (but this flag may be raised)
     255        source->tmpFlags &= ~PM_SOURCE_TMPF_SUBTRACTED;
     256        if (!source->modelPSF) continue;
     257
     258        float Xo = source->modelPSF->params->data.F32[PM_PAR_XPOS];
     259        float Yo = source->modelPSF->params->data.F32[PM_PAR_YPOS];
     260        float radius = source->modelPSF->fitRadius;
     261
     262        // force a redefine to this image
     263        pmSourceFreePixels(source);
     264        pmSourceRedefinePixels (source, readout, Xo, Yo, radius);
    173265    }
    174266    return true;
     
    229321
    230322    for (int i = 0; i < sources->n; i++) {
    231       source = sources->data[i];
    232 
    233       // *** we need to cache the 'best' model, and we have 3 cases:
    234       // 1) model is the psf model --> generate from the new psf
    235       // 2) model is an unconvolved extended model --> just cache the copy (not perfect)
    236       // 3) model is a convolved extended model --> re-generate
    237 
    238       // use the 'best' model to cache the model (PSF or EXT : EXT may point at one of modelFits
    239       bool isPSF = false;
    240       pmModel *model = pmSourceGetModel(&isPSF, source);
    241       if (!model) continue;
    242 
    243       float radius = model->fitRadius; // save for future use below
    244 
    245       // regenerate the PSF if the model is a PSF, or if we need the PSF for a PCM
    246       if (isPSF || model->isPCM) {
    247           // the guess central intensity comes from the peak:
    248           float Io = source->peak->rawFlux;
    249           float Xo = source->modelPSF->params->data.F32[PM_PAR_XPOS];
    250           float Yo = source->modelPSF->params->data.F32[PM_PAR_YPOS];
    251 
    252           // generate a model for this object with Io = 1.0
    253           pmModel *modelPSF = pmModelFromPSFforXY(psf, Xo, Yo, Io);
    254           if (modelPSF == NULL) {
    255               psWarning ("Failed to determine PSF model for source at (%f,%f), skipping", Xo, Yo);
    256               continue;
    257           }
    258 
    259           // set the source PSF model
    260           psFree (source->modelPSF);
    261           source->modelPSF = modelPSF;
    262           source->modelPSF->fitRadius = radius;
    263       }
    264 
    265       if (model->isPCM) {
    266           psAssert(false, "this section is not complete");
    267 
    268           pmSourceCachePSF (source, maskVal);
    269 
    270           psKernel *psfKernel = pmPCMkernelFromPSF(source, psfSize);
    271           if (!psfKernel) {
    272               psWarning ("no psf kernel");
    273           }
    274 
    275           // generate an image of the right size
    276           psImage *rawModelFlux = psImageCopy (NULL, source->pixels, PS_TYPE_F32);
    277           psImageInit (rawModelFlux, 0.0);
     323        source = sources->data[i];
     324
     325        // *** we need to cache the 'best' model, and we have 3 cases:
     326        // 1) model is the psf model --> generate from the new psf
     327        // 2) model is an unconvolved extended model --> just cache the copy (not perfect)
     328        // 3) model is a convolved extended model --> re-generate
     329
     330        // use the 'best' model to cache the model (PSF or EXT : EXT may point at one of modelFits
     331        bool isPSF = false;
     332        pmModel *model = pmSourceGetModel(&isPSF, source);
     333        if (!model) continue;
     334
     335        float radius = model->fitRadius; // save for future use below
     336
     337        // regenerate the PSF if the model is a PSF, or if we need the PSF for a PCM
     338        if (isPSF || model->isPCM) {
     339            // the guess central intensity comes from the peak:
     340            float Io = source->peak->rawFlux;
     341            float Xo = source->modelPSF->params->data.F32[PM_PAR_XPOS];
     342            float Yo = source->modelPSF->params->data.F32[PM_PAR_YPOS];
     343
     344            // generate a model for this object with Io = 1.0
     345            pmModel *modelPSF = pmModelFromPSFforXY(psf, Xo, Yo, Io);
     346            if (modelPSF == NULL) {
     347                psWarning ("Failed to determine PSF model for source at (%f,%f), skipping", Xo, Yo);
     348                continue;
     349            }
     350
     351            // set the source PSF model
     352            psFree (source->modelPSF);
     353            source->modelPSF = modelPSF;
     354            source->modelPSF->fitRadius = radius;
     355            model = source->modelPSF;
     356        }
     357
     358        if (model->isPCM) {
     359            psAssert(false, "this section is not complete");
     360
     361            pmSourceCachePSF (source, maskVal);
     362
     363            psKernel *psfKernel = pmPCMkernelFromPSF(source, psfSize);
     364            if (!psfKernel) {
     365                psWarning ("no psf kernel");
     366            }
     367
     368            // generate an image of the right size
     369            psImage *rawModelFlux = psImageCopy (NULL, source->pixels, PS_TYPE_F32);
     370            psImageInit (rawModelFlux, 0.0);
    278371         
    279           // insert the model image normalized to 1.0
    280           pmModelAdd (rawModelFlux, NULL, model, PM_MODEL_OP_FULL | PM_MODEL_OP_NORM, maskVal);
    281 
    282           psImageConvolveFFT (source->modelFlux, rawModelFlux, NULL, 0, psfKernel);
     372            // insert the model image normalized to 1.0
     373            pmModelAdd (rawModelFlux, NULL, model, PM_MODEL_OP_FULL | PM_MODEL_OP_NORM, maskVal);
     374
     375            psImageConvolveFFT (source->modelFlux, rawModelFlux, NULL, 0, psfKernel);
    283376         
    284           psFree (psfKernel);
    285           psFree (rawModelFlux);
    286       }
    287 
    288       pmSourceCacheModel (source, maskVal);  // ALLOC x14 (!)
     377            psFree (psfKernel);
     378            psFree (rawModelFlux);
     379        }
     380
     381        pmSourceCacheModel (source, maskVal);  // ALLOC x14 (!)
    289382    }
    290383
  • branches/meh_branches/ppstack_test/psphot/src/psphotRoughClass.c

    r31673 r33415  
    1111{
    1212    bool status = true;
     13
     14    fprintf (stdout, "\n");
     15    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Rough Class ---");
    1316
    1417    // select the appropriate recipe information
     
    128131    psphotDumpMoments (recipe, sources);
    129132
    130     psLogMsg ("psphot.roughclass", PS_LOG_INFO, "rough classification: %f sec\n", psTimerMark ("psphot.rough"));
     133    psLogMsg ("psphot.roughclass", PS_LOG_WARN, "rough classification: %f sec\n", psTimerMark ("psphot.rough"));
    131134
    132135    psphotVisualPlotMoments (recipe, readout->analysis, sources);
  • branches/meh_branches/ppstack_test/psphot/src/psphotSetThreads.c

    r31452 r33415  
    3030    psFree(task);
    3131
     32    task = psThreadTaskAlloc("PSPHOT_KRON_ITERATE", 7);
     33    task->function = &psphotKronIterate_Threaded;
     34    psThreadTaskAdd(task);
     35    psFree(task);
     36
    3237    task = psThreadTaskAlloc("PSPHOT_BLEND_FIT", 10);
    3338    task->function = &psphotBlendFit_Threaded;
     
    4045    psFree(task);
    4146
     47    task = psThreadTaskAlloc("PSPHOT_EXTENDED_ANALYSIS", 8);
     48    task->function = &psphotExtendedSourceAnalysis_Threaded;
     49    psThreadTaskAdd(task);
     50    psFree(task);
     51
     52    task = psThreadTaskAlloc("PSPHOT_RADIAL_APERTURES", 6);
     53    task->function = &psphotRadialApertures_Threaded;
     54    psThreadTaskAdd(task);
     55    psFree(task);
     56
     57    task = psThreadTaskAlloc("PSPHOT_RADIAL_PROFILE_WINGS", 3);
     58    task->function = &psphotRadialProfileWings_Threaded;
     59    psThreadTaskAdd(task);
     60    psFree(task);
     61
    4262    return true;
    4363}
  • branches/meh_branches/ppstack_test/psphot/src/psphotSourceFits.c

    r31452 r33415  
    211211bool psphotFitBlob (pmReadout *readout, pmSource *source, psArray *newSources, pmPSF *psf, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal) {
    212212
    213     float radius;
     213    float fitRadius, windowRadius;
    214214    bool okEXT, okDBL;
    215215    pmModel *ONE = NULL;
     
    217217    pmModel *EXT = NULL;
    218218    psArray *DBL = NULL;
    219     pmMoments psfMoments;
     219    // pmMoments psfMoments;
    220220
    221221    // skip the source if we don't think it is extended
     
    225225    if (source->type == PM_SOURCE_TYPE_SATURATED) return false;
    226226
     227# define TEST_X -420.0
     228# define TEST_Y 300.0
     229   
     230    if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) {
     231        fprintf (stderr, "test galaxy\n");
     232    }
     233
     234# undef TEST_X
     235# undef TEST_Y
     236
    227237    // set the radius based on the footprint (also sets the mask pixels)
    228     if (!psphotSetRadiusFootprint(&radius, readout, source, markVal, 1.0)) return false;
    229 
    230     // XXX note that this changes the source moments that are published...
    231     // XXX all published moments should use the same measurement
    232     // recalculate the source moments using the larger extended-source moments radius
    233     // at this stage, skip Gaussian windowing, and do not clip pixels by S/N
    234     // this uses the footprint to judge both radius and aperture?
    235     // XXX save the psf-based moments for output
    236     psfMoments = *source->moments;
    237     if (!pmSourceMoments (source, radius, 0.0, 0.5, 0.0, maskVal)) {
    238       *source->moments = psfMoments;
    239       return false;
    240     }
     238    if (!psphotSetRadiusMoments(&fitRadius, &windowRadius, readout, source, markVal)) return false;
     239    // fprintf (stderr, "rad: %6.1f %6.1f  | %5.2f %5.2f %5.2f  ", source->peak->xf, source->peak->yf, source->moments->Mrf, fitRadius, windowRadius);
    241240
    242241    psTrace ("psphot", 5, "trying blob...\n");
     
    258257        okDBL  = psphotEvalDBL (tmpSrc, DBL->data[0]);
    259258        okDBL &= psphotEvalDBL (tmpSrc, DBL->data[1]);
     259        okDBL = false; // XXX this is failing badly...
    260260        // XXX should I keep / save the flags set in the eval functions?
    261261
     
    263263        ONE = DBL->data[0];
    264264        if (ONE) {
    265             if (!isfinite(ONE->params->data.F32[PM_PAR_I0])) psAbort("nan in fit");
     265            psAssert (isfinite(ONE->params->data.F32[PM_PAR_I0]), "nan in fit");
    266266            chiDBL = ONE->chisqNorm; // save chisq for double-star/galaxy comparison
    267             ONE->fitRadius = radius;
     267            ONE->fitRadius = fitRadius;
    268268        }
    269269
     
    271271        ONE = DBL->data[1];
    272272        if (ONE) {
    273             if (!isfinite(ONE->params->data.F32[PM_PAR_I0])) psAbort("nan in fit");
    274             ONE->fitRadius = radius;
     273            psAssert (isfinite(ONE->params->data.F32[PM_PAR_I0]), "nan in fit");
     274            ONE->fitRadius = fitRadius;
    275275        }
    276276    }
     
    284284        okEXT = psphotEvalEXT (tmpSrc, EXT);
    285285        chiEXT = EXT ? EXT->chisqNorm : NAN;
     286        EXT->fitRadius = fitRadius;
    286287    }
    287288
     
    294295
    295296    if (okEXT && okDBL) {
    296         psTrace ("psphot", 5, "blob chisq: %f vs %f\n", chiEXT, chiDBL);
    297297        // XXX EAM : a bogus bias: need to examine this better
    298298        if (3*chiEXT > chiDBL) goto keepDBL;
     
    303303    if (!okEXT && okDBL) goto keepDBL;
    304304
     305    psTrace ("psphot", 4, "both failed: blob chisq: %f vs %f for %f,%f\n", chiEXT, chiDBL, source->peak->xf, source->peak->yf);
     306
    305307    // both models failed; reject them both
    306308    // XXX -- change type flags to psf in this case, and make sure we subtract it?
    307309    // reset the psf moments
    308     *source->moments = psfMoments;
     310    // XXX *source->moments = psfMoments;
    309311
    310312    psFree (EXT);
     
    313315
    314316keepEXT:
     317    psTrace ("psphot", 4, "goto EXT : blob chisq: %f vs %f for %f,%f\n", chiEXT, chiDBL, source->peak->xf, source->peak->yf);
    315318    // sub EXT
    316319    psFree (DBL);
     
    338341
    339342    // reset the psf moments
    340     *source->moments = psfMoments;
     343    // XXX *source->moments = psfMoments;
    341344    return true;
    342345
    343346keepDBL:
     347    psTrace ("psphot", 4, "goto DBL : blob chisq: %f vs %f for %f,%f\n", chiEXT, chiDBL, source->peak->xf, source->peak->yf);
    344348    // sub DLB
    345349    psFree (EXT);
     
    354358    pmSource *newSrc = pmSourceCopy (source);
    355359    newSrc->modelPSF = psMemIncrRefCounter (DBL->data[1]);
     360    newSrc->peak->footprint = source->peak->footprint; // just a reference; the peak does not own the footprint
     361    psArrayAdd(newSrc->peak->footprint->peaks, 1, newSrc->peak); // the footprint owns the peak
    356362
    357363    // build cached models and subtract
     
    372378            psLogMsg ("psphot", 1, "PAR %d : %f +/- %f\n", i, source->modelPSF->params->data.F32[i], source->modelPSF->dparams->data.F32[i]);
    373379        }
    374         psphotVisualShowResidualImage (readout, false);
    375380    }
    376381# endif
    377 
    378     // reset the (original) psf moments
    379     *source->moments = psfMoments;
    380     *newSrc->moments = psfMoments;
    381382
    382383    psArrayAdd (newSources, 100, newSrc);
     
    386387
    387388escape:
    388     // reset the psf moments
    389     *source->moments = psfMoments;
    390389    psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
    391390    psFree (tmpSrc);
     
    476475    // for sersic models, use a grid search to choose an index, then float the params there
    477476    if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) {
    478         // for the test fits, use a somewhat smaller radius
    479         psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 0.5);
    480477        psphotFitSersicIndex (model, readout, source, fitOptions, maskVal, markVal);
    481     }
    482 
    483     if (!psphotSetRadiusModel (model, readout, source, markVal, true)) {
    484         psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 1.0);
    485478    }
    486479
     
    494487    pmSourceFitModel (source, model, &options, maskVal);
    495488    // fprintf (stderr, "chisq: %f, nIter: %d, radius: %f, npix: %d\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix);
    496 
    497489    // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0);
     490
    498491    return (model);
    499492}
     493
     494# define TIMING 0
    500495
    501496pmModel *psphotFitPCM (pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, pmModelType modelType, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) {
     
    517512        return NULL;
    518513    }
     514
     515# define TEST_X -540.0
     516# define TEST_Y 540.0
     517   
     518    if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) {
     519        psTraceSetLevel("psModules.objects.pmPCM_MinimizeChisq", 5);
     520    }
     521
     522    float t1, t2, t4, t5;
     523    if (TIMING) { psTimerStart ("psphotFitPCM"); }
    519524
    520525    pmPCMdata *pcm = pmPCMinit (source, &options, model, maskVal, psfSize);
     
    524529        return model;
    525530    }
    526 
    527     // use the source moments, etc to guess basic model parameters
    528     if (!pmSourceModelGuessPCM (pcm, source, maskVal, markVal)) {
    529         psFree (pcm);
    530         model->flags |= PM_MODEL_STATUS_BADARGS;
    531         return model;
    532     }
    533 
    534     // for sersic models, use a grid search to choose an index, then float the params there
     531    if (TIMING) { t1 = psTimerMark ("psphotFitPCM"); }
     532
     533    // NOTE : 65 allocs to here
     534    // get the guess for sersic models
    535535    if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) {
    536         // for the test fits, use a somewhat smaller radius
    537         psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 0.5);
    538 
    539         if (!psphotFitSersicIndexPCM (pcm, readout, source, fitOptions, maskVal, markVal, psfSize)) {
     536        // use the source moments, etc to guess basic model parameters
     537        if (!psphotSersicModelClassGuessPCM (pcm, source)) {
    540538            psFree (pcm);
    541539            model->flags |= PM_MODEL_STATUS_BADARGS;
    542540            return model;
    543541        }
    544     }
    545 
    546     if (!psphotSetRadiusModel (model, readout, source, markVal, true)) {
    547         psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 1.0);
    548     }
     542    } else {
     543        // use the source moments, etc to guess basic model parameters
     544        if (!pmSourceModelGuessPCM (pcm, source, maskVal, markVal)) {
     545            psFree (pcm);
     546            model->flags |= PM_MODEL_STATUS_BADARGS;
     547            return model;
     548        }
     549    }
     550
     551    if (TIMING) { t2 = psTimerMark ("psphotFitPCM"); }
    549552
    550553    if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) {
     
    555558    // update the pcm elements if we have changed the circumstance (options.mode or source->pixels)
    556559    pmPCMupdate(pcm, source, &options, model);
     560    if (TIMING) { t4 = psTimerMark ("psphotFitPCM"); }
    557561
    558562    // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 5);
    559     pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
    560     // fprintf (stderr, "chisq: %f, nIter: %d, radius: %f, npix: %d\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix);
     563    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);  // NOTE : 1687 allocs in here
     564    if (TIMING) { t5 = psTimerMark ("psphotFitPCM"); }
     565
     566    if (TIMING) {
     567        int nPixBig = source->pixels->numCols * source->pixels->numRows;
     568        fprintf (stderr, "psphotFitPCM : nIter: %2d, radius: %6.1f, npix: %5d of %5d, t1: %6.4f, t2: %6.4f, t4: %6.4f, t5: %6.4f\n", model->nIter, model->fitRadius, model->nPix, nPixBig, t1, t2, t4, t5);
     569    }
     570
     571    if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) {
     572        psTraceSetLevel("psModules.objects.pmPCM_MinimizeChisq", 0);
     573    }
    561574
    562575    // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0);
     
    566579}
    567580
     581# undef TEST_X
     582# undef TEST_Y
     583
    568584// note that these should be 1/2n of the standard sersic index
    569 float indexGuess[] = {0.5, 0.33, 0.25, 0.167, 0.125, 0.083};
    570 # define N_INDEX_GUESS 6
     585// float indexGuess[] = {0.8, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0};
     586// float indexGuess[] = {0.5, 0.33, 0.25, 0.167, 0.125, 0.083};
     587float indexGuess[] = {1.0, 2.0, 3.0, 4.0};
     588# define N_INDEX_GUESS 4
    571589
    572590// A sersic model is very sensitive to the index.  attempt to find the index first by grid search in just the index
     
    586604    float chiSquare[N_INDEX_GUESS];
    587605
     606# define TEST_X -540.0
     607# define TEST_Y 540.0
     608   
     609    if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) {
     610        psTraceSetLevel("psModules.objects.pmPCM_MinimizeChisq", 5);
     611    }
     612
    588613    for (int i = 0; i < N_INDEX_GUESS; i++) {
    589         model->params->data.F32[PM_PAR_7] = indexGuess[i];
     614        model->params->data.F32[PM_PAR_7] = 0.5/indexGuess[i];
    590615
    591616        if (!model->modelGuess(model, source)) {
     
    594619        }
    595620
    596         // each time we change the model guess, we need to adjust the radius
    597         // XXX this did not work : we do not need such a large radius -- just uses moments-based radius
    598         if (false && !psphotSetRadiusModel (model, readout, source, markVal, false)) {
    599             psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 0.5);
    600         }
    601        
    602621        pmSourceFitModel (source, model, &options, maskVal);
    603         // fprintf (stderr, "chisq: %f, nIter: %d, radius: %f, npix: %d\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix);
     622        // fprintf (stderr, "index: %f, chisq: %f, nIter: %d, radius: %f, npix: %d\n", indexGuess[i], model->chisqNorm, model->nIter, model->fitRadius, model->nPix);
    604623
    605624        chiSquare[i] = model->chisqNorm;
     
    616635    assert (iMin >= 0);
    617636
     637    if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) {
     638        psTraceSetLevel("psModules.objects.pmPCM_MinimizeChisq", 0);
     639    }
     640
    618641    model->flags = PM_MODEL_STATUS_NONE; // do not attempt to handle failures here, let the next iteration deal with it
    619     model->params->data.F32[PM_PAR_7] = indexGuess[iMin];
     642    model->params->data.F32[PM_PAR_7] = 0.5/indexGuess[iMin];
    620643    model->modelGuess(model, source);
    621 
    622     // each time we change the model guess, we need to adjust the radius
    623     // if (!psphotSetRadiusModel (model, readout, source, markVal, true)) {
    624     //  psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal);
    625     // }
    626644
    627645    return true;
     
    648666    float xMin = NAN;
    649667    float chiSquare[N_INDEX_GUESS];
     668
     669    if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) {
     670        psTraceSetLevel("psModules.objects.pmPCM_MinimizeChisq", 5);
     671    }
    650672
    651673    for (int i = 0; i < N_INDEX_GUESS; i++) {
     
    657679        }
    658680
    659         // each time we change the model guess, we need to adjust the radius
    660         // XXX this did not work : we do not need such a large radius -- just uses moments-based radius
    661         if (false && !psphotSetRadiusModel (model, readout, source, markVal, false)) {
    662             psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 0.5);
    663         }
    664        
    665681# if (0)
     682        // this block is to test the relative speed of straight and PCM fits
    666683        pmSourceFitModel (source, model, &options, maskVal);
    667684# else
     
    669686        pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
    670687# endif
     688        fprintf (stderr, "index: %f, chisq: %f, nIter: %d, radius: %f, npix: %d\n", indexGuess[i], model->chisqNorm, model->nIter, model->fitRadius, model->nPix);
    671689        // fprintf (stderr, "chisq: %f, nIter: %d, radius: %f, npix: %d\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix);
    672690
     
    684702    assert (iMin >= 0);
    685703   
     704    if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) {
     705        psTraceSetLevel("psModules.objects.pmPCM_MinimizeChisq", 0);
     706    }
     707
    686708    model->flags = PM_MODEL_STATUS_NONE; // do not attempt to handle failures here, let the next iteration deal with it
    687709    model->params->data.F32[PM_PAR_7] = indexGuess[iMin];
  • branches/meh_branches/ppstack_test/psphot/src/psphotSourceMatch.c

    r31154 r33415  
    4848    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
    4949    psAssert (detections, "missing detections?");
    50     psAssert (detections->newSources, "new sources not defined?");
    51     psAssert (!detections->allSources, "all sources already defined?");
    52 
    53     // XXX TEST:
    54     if (detections->newSources) {
    55         psphotMatchSourcesToObjects(objects, detections->newSources, RADIUS);
    56     }
     50    psAssert (detections->allSources, "all sources not defined?");
     51
     52    psphotMatchSourcesToObjects(objects, detections->allSources, RADIUS);
    5753
    5854    return true;
     
    7167    objects = psArraySort (objects, pmPhotObjSortByX);
    7268 
    73     psVector *found = psVectorAlloc(sources->n, PS_TYPE_U8);
    74     psVectorInit (found, 0);
     69    psVector *foundSrc = psVectorAlloc(sources->n, PS_TYPE_U8);
     70    psVectorInit (foundSrc, 0);
     71
     72    psVector *foundObj = psVectorAlloc(objects->n, PS_TYPE_U8);
     73    psVectorInit (foundObj, 0);
    7574
    7675    // match sources to existing objects
     
    9796        if (dx > +1.02*RADIUS) NEXT2;
    9897 
     98        /* this block will match a given detection to the closest object within range of that detection.
     99           XXX note that this matches ALL detections within range of the single object to that same object
     100           this is bad, but I cannot just go in linear order (ie, mark off each object as they are
     101           used).  I should make a list of all Nobj * Ndet pairs in range and choose the matches
     102           based on their separations.  UGH
     103        */
     104   
    99105        // we are within match range, look for matches:
    100106        int Jmin = -1;
     
    102108        for (int J = j; (dx > -1.02*RADIUS) && (J < objects->n); J++) {
    103109 
     110            // skip objects that are already assigned:
     111            if (foundObj->data.U8[J]) continue;
    104112            obj = objects->data[J];
    105113           
     
    121129        }
    122130        obj = objects->data[Jmin];
     131        foundObj->data.U8[Jmin] = 1;
    123132
    124133        // add to object
    125134        pmPhotObjAddSource (obj, src);
    126         found->data.U8[i] = 1;
     135        foundSrc->data.U8[i] = 1;
    127136        i++;
    128137    }
     
    132141    for (i = 0; i < sources->n; i++) {
    133142
    134         if (found->data.U8[i]) continue;
     143        if (foundSrc->data.U8[i]) continue;
    135144
    136145        pmSource *src = sources->data[i];
     
    143152    psLogMsg ("psphot", PS_LOG_DETAIL, "matched sources (%ld vs %ld)", sources->n, objects->n);
    144153
    145     psFree (found);
     154    psFree (foundSrc);
     155    psFree (foundObj);
    146156    return true;
    147157}
     
    238248           
    239249            // assign to a footprint on this readout->image
    240             peak->footprint = pmFootprintCopyData(footprint, readout->image);
    241 
    242             // the peak does not claim ownership of the footprint (it does not free it). save a copy of this
    243             // footprint on detections->footprints so we can free it later
    244             psArrayAdd(detections->footprints, 100, peak->footprint);
    245             psFree (peak->footprint);
     250            if (footprint) {
     251                peak->footprint = pmFootprintCopyData(footprint, readout->image);
     252
     253                // the peak does not claim ownership of the footprint (it does not free it). save a copy of this
     254                // footprint on detections->footprints so we can free it later
     255                psArrayAdd(detections->footprints, 100, peak->footprint);
     256                psFree (peak->footprint);
     257            }
    246258           
    247259            // create a new source
     
    249261            source->imageID = index;
    250262            source->mode2 |= PM_SOURCE_MODE2_MATCHED; // source is generated based on another image
     263            source->type = PM_SOURCE_TYPE_STAR; // until we know more, assume a PSF fit
    251264
    252265            // add the peak
     
    261274            peak->assigned = true;
    262275            pmPhotObjAddSource(obj, source);
    263             psArrayAdd (detections->newSources, 100, source);
     276            psArrayAdd (detections->allSources, 100, source);
    264277            psFree (source);
    265278        }
     
    272285        pmPhotObj *obj = objects->data[i];
    273286        nSources += obj->sources->n;
     287        psAssert (obj->sources->n == nImages, "failed to match sources?");
    274288    }
    275289    psLogMsg ("psphot", PS_LOG_DETAIL, "total of %d sources for %d images", nSources, nImages);
  • branches/meh_branches/ppstack_test/psphot/src/psphotSourceSize.c

    r31452 r33415  
    4545    bool status = true;
    4646
     47    fprintf (stdout, "\n");
     48    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Source Size ---");
     49
    4750    // select the appropriate recipe information
    4851    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     
    153156
    154157    // XXX fix this (was source->n  - first)
    155     psLogMsg ("psphot.size", PS_LOG_INFO, "measure source sizes for %ld sources: %f sec\n", sources->n, psTimerMark ("psphot.size"));
     158    psLogMsg ("psphot.size", PS_LOG_WARN, "measure source sizes for %ld sources: %f sec\n", sources->n, psTimerMark ("psphot.size"));
    156159
    157160    psphotVisualPlotSourceSize (recipe, readout->analysis, sources);
     
    209212        pmSourceMagnitudes (source, psf, photMode, maskVal, markVal, source->apRadius);
    210213
    211         float kMag = -2.5*log10(source->moments->KronFlux);
     214        float kMag = -2.5*log10(source->moments->KronFluxPSF);
    212215        float dMag = source->psfMag - kMag;
    213216
     
    334337        psF32 Mxy = source->moments->Mxy;
    335338
    336         float KronMag = -2.5*log10(source->moments->KronFlux);
     339        float KronMag = -2.5*log10(source->moments->KronFluxPSF);
    337340
    338341        float Mminor = 0.5*(Mxx + Myy) - 0.5*sqrt(PS_SQR(Mxx - Myy) + 4.0*PS_SQR(Mxy));
     
    509512        pmSourceSub (source, PM_MODEL_OP_FULL, options->maskVal);
    510513
    511         float kMag = -2.5*log10(source->moments->KronFlux);
     514        float kMag = -2.5*log10(source->moments->KronFluxPSF);
    512515        float dMag = source->psfMag - kMag;
    513516
  • branches/meh_branches/ppstack_test/psphot/src/psphotSourceStats.c

    r31673 r33415  
    1010    bool status = true;
    1111
     12    fprintf (stdout, "\n");
     13    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Source Stats ---");
     14
    1215    // select the appropriate recipe information
    1316    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     
    98101
    99102    // generate the array of sources, define the associated pixel
    100     bool firstPass = false;
    101     if (!detections->newSources) {
    102         detections->newSources = psArrayAllocEmpty (peaks->n);
    103         firstPass = true;
    104     }
    105     sources = detections->newSources;
     103    psAssert (!detections->newSources, "programming error");
     104    sources = detections->newSources = psArrayAllocEmpty (peaks->n);
     105
     106    bool firstPass = (detections->allSources == NULL);
    106107
    107108    // if there are no peaks, we save the empty source array and return
     
    121122        // add the peak
    122123        source->peak = psMemIncrRefCounter(peak);
     124
     125        // psAssert (source->peak->footprint, "peak without footprint??");
    123126
    124127        // allocate space for moments
     
    213216
    214217        // wait for the threads to finish and manage results
    215         if (!psThreadPoolWait (false)) {
     218        if (!psThreadPoolWait (false, true)) {
    216219            psError(PS_ERR_UNKNOWN, false, "Failure in thread job PSPHOT_SOURCE_STATS");
    217220            psFree(detections->newSources);
     
    239242    psFree (cellGroups);
    240243
    241     psLogMsg ("psphot", PS_LOG_INFO, "%ld sources, %d moments, %d faint, %d failed: %f sec\n", sources->n, Nmoments, Nfaint, Nfail, psTimerMark ("psphot.stats"));
     244    psLogMsg ("psphot", PS_LOG_WARN, "%ld sources, %d moments, %d faint, %d failed: %f sec\n", sources->n, Nmoments, Nfaint, Nfail, psTimerMark ("psphot.stats"));
    242245
    243246    psphotVisualShowMoments (sources);
     
    344347
    345348        // wait for the threads to finish and manage results
    346         if (!psThreadPoolWait (false)) {
     349        if (!psThreadPoolWait (false, true)) {
    347350            psError(PS_ERR_UNKNOWN, false, "Failure in thread job PSPHOT_SOURCE_STATS");
    348351            return NULL;
     
    554557        // determine the PSF parameters from the source moment values
    555558        pmPSFClump psfClump = pmSourcePSFClump (NULL, NULL, sources, PSF_SN_LIM, PSF_CLUMP_GRID_SCALE, MOMENTS_SX_MAX, MOMENTS_SY_MAX, MOMENTS_SX_MIN, MOMENTS_SY_MIN, MOMENTS_AR_MAX);
    556         psLogMsg ("psphot", 3, "radius %.1f, nStars: %d of %d in clump, nSigma: %5.2f, X,  Y: %f, %f (%f, %f)\n", sigma[i], psfClump.nStars, psfClump.nTotal, psfClump.nSigma, psfClump.X, psfClump.Y, sqrt(psfClump.X) / sigma[i], sqrt(psfClump.Y) / sigma[i]);
     559        psLogMsg ("psphot", 3, "sigma guess (pix) %.1f, nStars: %d of %d in clump, nSigma: %5.2f, X,  Y: %f, %f (%f, %f)\n", sigma[i], psfClump.nStars, psfClump.nTotal, psfClump.nSigma, psfClump.X, psfClump.Y, sqrt(psfClump.X) / sigma[i], sqrt(psfClump.Y) / sigma[i]);
    557560
    558561        Rmin[i] = pmSourceMinKronRadius(sources, PSF_SN_LIM);
  • branches/meh_branches/ppstack_test/psphot/src/psphotStackChisqImage.c

    r31154 r33415  
    1313    psAssert (chisqFile, "missing chisq image FPA?");
    1414
     15    // the readout containing the chisq image is generated in the first pass of this loop and
     16    // used by the successive passes
    1517    pmReadout *chiReadout = NULL;
    1618
  • branches/meh_branches/ppstack_test/psphot/src/psphotStackImageLoop.c

    r31154 r33415  
    1010bool UpdateHeadersForFPA (pmConfig *config, pmFPAview *view);
    1111bool UpdateHeadersForChip (pmConfig *config, pmFPAview *view);
     12bool UpdateHeadersForReadout (pmConfig *config, pmFPAview *view);
    1213
    1314bool psphotStackImageLoop (pmConfig *config) {
     
    5253                psMemDump("load");
    5354
    54                 // PSF matching
     55                // Generate the 1st PSF-matched image set (larger target PSFs are generated by smoothing this image)
    5556                if (!psphotStackMatchPSFs (config, view)) {
    5657                    psError(psErrorCodeLast(), false, "failure in psphotStackMatchPSFs for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout);
     
    6667                    return false;
    6768                }
     69
     70                UpdateHeadersForReadout(config, view);
     71
    6872                psMemDump("psphot");
    6973            }
     
    101105}
    102106
     107bool UpdateHeadersForReadout (pmConfig *config, pmFPAview *view) {
     108
     109    psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE);
     110    bool useRaw = psMetadataLookupBool (NULL, recipe, "PSPHOT.STACK.USE.RAW");
     111
     112    int num = psphotFileruleCount(config, "PSPHOT.INPUT");
     113
     114    // loop over the available readouts
     115    for (int i = 0; i < num; i++) {
     116
     117        // find the currently selected readout
     118        pmFPAfile *output = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.OUTPUT.IMAGE", i); // File of interest
     119        psAssert (output, "missing file?");
     120
     121        pmFPAfile *inputRaw = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.RAW", i); // File of interest
     122        pmFPAfile *inputCnv = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.CNV", i); // File of interest
     123        pmFPAfile *input = useRaw ? inputRaw : inputCnv;
     124        psAssert (input, "missing input file");
     125
     126        // just copy the input headers to the output headers, then update version info
     127        pmReadout *inReadout = pmFPAviewThisReadout(view, input->fpa); ///< Chip in the input
     128        pmReadout *outReadout = pmFPAviewThisReadout(view, output->fpa); ///< Chip in the output
     129
     130        psMetadata *header = psMetadataLookupPtr (NULL, inReadout->analysis, "PSPHOT.HEADER");
     131        psMetadataAdd (outReadout->analysis, PS_LIST_TAIL, "PSPHOT.HEADER",  PS_DATA_METADATA, "header stats", header);
     132    }
     133    return true;
     134}
     135
    103136bool UpdateHeadersForChip (pmConfig *config, pmFPAview *view) {
    104137
     
    131164            outHDU->header = psMetadataCopy(NULL, inHDU->header);
    132165        }
     166        psphotVersionHeaderFull(outHDU->header);
    133167        outChip->toFPA = psMemIncrRefCounter(inChip->toFPA);
    134168        outChip->fromFPA = psMemIncrRefCounter(inChip->fromFPA);
  • branches/meh_branches/ppstack_test/psphot/src/psphotStackMatchPSFs.c

    r31154 r33415  
    2525    }
    2626
    27     // loop over the available readouts (ignore chisq image)
     27    // loop over the available readouts
    2828    for (int i = 0; i < num; i++) {
     29        // set up the PSF-matching parameters describing the input images
    2930        if (!psphotStackMatchPSFsPrepare (config, view, options, i)) {
    3031            psError (PSPHOT_ERR_CONFIG, false, "failed to set PSF matching options for entry %d", i);
     
    3334    }
    3435
    35     // Generate target PSF
     36    // XXX convolve == false might not be valid at the moment
    3637    if (options->convolve) {
    37         options->psf = psphotStackPSF(config, options->numCols, options->numRows, options->psfs, options->inputMask);
    38         if (!options->psf) {
     38        // Determine the 1st target PSF (either AUTO or defined by PSPHOT.STACK.TARGET.PSF.FWHM)
     39        // NOTE: this also set the full list of target FWHMs (options->targetSeeing)
     40        if (!psphotStackPSF(config, options)) {
    3941            psError(psErrorCodeLast(), false, "Unable to determine output PSF.");
    4042            return false;
    4143        }
    42         psMetadataAddPtr(config->arguments, PS_LIST_TAIL, "PSF.TARGET", PS_DATA_UNKNOWN, "Target PSF for stack", options->psf);
    43         options->targetSeeing = pmPSFtoFWHM(options->psf, 0.5 * options->numCols, 0.5 * options->numRows); // FWHM for target
    44         psLogMsg("psphotStack", PS_LOG_INFO, "Target seeing FWHM: %f\n", options->targetSeeing);
    45 
    46         // XXX is this needed to supply the psf to psphot??
    47         // pmChip *outChip = pmFPAfileThisChip(config->files, view, "PPSTACK.TARGET.PSF"); // Output chip
    48         // psMetadataAddPtr(outChip->analysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_DATA_UNKNOWN, "Target PSF", options->psf);
    49         // outChip->data_exists = true;
    5044    }
    5145
     
    6357
    6458// convolve the image to match desired PSF
     59// XXX is this code consistent with 'convolve' = false?
    6560bool psphotStackMatchPSFsReadout (pmConfig *config, const pmFPAview *view, psphotStackOptions *options, int index) {
    6661
     
    106101    // Image Matching (PSFs or just flux)
    107102    if (options->convolve) {
    108         matchKernel(config, readoutOut, readoutSrc, options, index);
     103        if (!matchKernel(config, readoutOut, readoutSrc, options, index)){
     104            psError(psErrorCodeLast(), false, "Unable to match image PSF in readout.");
     105            return false;
     106        }
    109107        saveMatchData(readoutOut, options, index);
    110108    }
    111     rescaleData(readoutOut, config, options, index);
     109
     110    // renormalize the stack variances to have sigma = 1.0
     111    if (!psphotStackRenormaliseVariance(config, readoutOut)) {
     112        psError(psErrorCodeLast(), false, "Unable to renormalise variance.");
     113        return false;
     114    }
    112115
    113116    // save the output fwhm values in the readout->analysis.  we may have / will have multiple output PSF sizes,
    114117    // so we save this in a vector.  if the vector is not yet defined, create it
    115     bool mdok = false;
    116     psVector *fwhmValues = psMetadataLookupVector(&mdok, readoutOut->analysis, "STACK.PSF.FWHM.VALUES");
    117     if (!fwhmValues) {
    118         fwhmValues = psVectorAllocEmpty(10, PS_TYPE_F32);
    119         psMetadataAddVector(readoutOut->analysis, PS_LIST_TAIL, "STACK.PSF.FWHM.VALUES", PS_META_REPLACE, "PSF sizes", fwhmValues);
    120         psFree(fwhmValues); // drops the extra copy
     118    // NOTE: fwhmValues as defined here has 1 + nMatched PSF : 0 == unmatched
     119    psVector *fwhmValues = psVectorAllocEmpty(10, PS_TYPE_F32);
     120    psVectorAppend(fwhmValues, NAN); // XXX this corresponds to the unmatched image set
     121    for (int i = 0; i < options->targetSeeing->n; i++) {
     122        psVectorAppend(fwhmValues, options->targetSeeing->data.F32[i]);
    121123    }
    122     psVectorAppend(fwhmValues, options->targetSeeing);
     124    psMetadataAddVector(readoutSrc->analysis, PS_LIST_TAIL, "STACK.PSF.FWHM.VALUES", PS_META_REPLACE, "PSF sizes", fwhmValues);
     125    psMetadataAddVector(readoutOut->analysis, PS_LIST_TAIL, "STACK.PSF.FWHM.VALUES", PS_META_REPLACE, "PSF sizes", fwhmValues);
     126    psFree(fwhmValues); // drops the extra copy
    123127
    124128    return true;
  • branches/meh_branches/ppstack_test/psphot/src/psphotStackMatchPSFsNext.c

    r30624 r33415  
    11# include "psphotInternal.h"
     2
     3// NOTE : element 0 of fwhmValues if the unmatched image, 
     4
     5int psphotStackMatchPSFsEntries (pmConfig *config, const pmFPAview *view, const char *filerule) {
     6
     7    int nRadialEntries = 0;
     8
     9    // find the currently selected readout
     10    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, 0); // File of interest
     11    psAssert (file, "missing file?");
     12   
     13    pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
     14    psAssert (readout, "missing readout?");
     15   
     16    bool status = false;
     17    psVector *fwhmValues = psMetadataLookupVector(&status, readout->analysis, "STACK.PSF.FWHM.VALUES");
     18    if (!fwhmValues) {
     19        return 1;
     20    }
     21   
     22    nRadialEntries = fwhmValues->n;
     23    return nRadialEntries;
     24}
    225
    326// smooth the input image to match the next target PSF
     
    528// and that the smoothing can use a 1D Gaussian kernel of width sqrt(TARGET^2 - CURRENT^2)
    629// each subsequent call
    7 bool psphotStackMatchPSFsNext(bool *smoothAgain, pmConfig *config, const pmFPAview *view, const char *filerule, int lastSize)
     30bool psphotStackMatchPSFsNext(pmConfig *config, const pmFPAview *view, const char *filerule, int lastSize)
    831{
    9     bool status = true;
    10 
    11     // select the appropriate recipe information
    12     psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
    13     psAssert (recipe, "missing recipe?");
    14 
    15     psVector *fwhmValues = psMetadataLookupVector(&status, recipe, "PSPHOT.STACK.TARGET.PSF.FWHM"); // Magnitude offsets
    16     if (!status) {
    17         // must not be a vector, only one value requested
    18         *smoothAgain = false;
    19         return true;
    20     }
    21 
    22     if (lastSize + 1 >= fwhmValues->n) {
    23         // all done with target FWHM values
    24         *smoothAgain = false;
    25         return true;
    26     }
    27 
    2832    int num = psphotFileruleCount(config, filerule);
    2933
     
    3337    // loop over the available readouts
    3438    for (int i = 0; i < num; i++) {
    35         if (!psphotStackMatchPSFsNextReadout (config, view, filerule, i, recipe, fwhmValues, lastSize)) {
    36             psError (PSPHOT_ERR_CONFIG, false, "failed to smooth image %s (%d) to target PSF %f", filerule, i, fwhmValues->data.F32[lastSize+1]);
     39        if (!psphotStackMatchPSFsNextReadout (config, view, filerule, i, lastSize)) {
     40            psError (PSPHOT_ERR_CONFIG, false, "failed to smooth image %s (%d) to target PSF", filerule, i);
    3741            psImageConvolveSetThreads(oldThreads);
    3842            return false;
     
    4448}
    4549
    46 bool psphotStackMatchPSFsNextReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, psVector *fwhmValues, int lastSize) {
     50bool psphotStackMatchPSFsNextReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, int lastSize) {
    4751
    4852    bool status = false;
     53
     54    psTimerStart ("psphot.smooth");
    4955
    5056    // find the currently selected readout
     
    5864    psphotVisualShowImage(readout);
    5965
     66    // select the appropriate recipe information
     67    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     68    psAssert (recipe, "missing recipe?");
     69
    6070    // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
    6171    psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels
     
    6676        psWarning("PEAKS_MIN_GAUSS is not set in recipe; using default value");
    6777        minGauss = 0.5;
     78    }
     79
     80    psVector *fwhmValues = psMetadataLookupVector(&status, readout->analysis, "STACK.PSF.FWHM.VALUES");
     81    psAssert (fwhmValues, "need target PSFs");
     82
     83    if (lastSize + 1 >= fwhmValues->n) {
     84        return true;
    6885    }
    6986
     
    128145    // psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "SIGNIFICANCE_SCALE_FACTOR", PS_META_REPLACE, "Signicance scale factor", factor);
    129146
    130     // save the output fwhm values in the readout->analysis.  we may have / will have multiple output PSF sizes,
    131     // so we save this in a vector.  if the vector is not yet defined, create it
    132 
    133     psVector *fwhmValuesOut = psMetadataLookupVector(&status, readout->analysis, "STACK.PSF.FWHM.VALUES");
    134     psAssert(fwhmValuesOut, "should already exist..");
    135     psVectorAppend(fwhmValuesOut, targetFWHM);
    136 
    137147    // do not generate a PSF if we already were supplied one
    138148    pmPSF *psfOld = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF");
  • branches/meh_branches/ppstack_test/psphot/src/psphotStackMatchPSFsPrepare.c

    r28013 r33415  
    44bool determineSeeing (pmPSF *psf, psphotStackOptions *options, int index);
    55
    6 // set up the stacking parameters
     6// set up the PSF-matching parameters describing the input images
    77bool psphotStackMatchPSFsPrepare (pmConfig *config, const pmFPAview *view, psphotStackOptions *options, int index) {
    88
  • branches/meh_branches/ppstack_test/psphot/src/psphotStackMatchPSFsUtils.c

    r31154 r33415  
    22# define ARRAY_BUFFER 16                 // Number to add to array at a time
    33
    4 // XXX better name
    5 bool readImage(psImage **target, // Target for image
    6                const char *name, // Name of FITS file
    7                const pmConfig *config // Configuration
    8     )
    9 {
    10     psString resolved = pmConfigConvertFilename(name, config, false, false); // Resolved filename
    11     psFits *fits = psFitsOpen(resolved, "r");
    12     psFree(resolved);
    13     if (!fits) {
    14         psError(PSPHOT_ERR_IO, false, "Unable to open previously produced image: %s", name);
    15         return false;
    16     }
    17     psImage *image = psFitsReadImage(fits, psRegionSet(0,0,0,0), 0); // Image of interest
    18     if (!image) {
    19         psError(PSPHOT_ERR_IO, false, "Unable to read previously produced image: %s", name);
    20         psFitsClose(fits);
    21         return false;
    22     }
    23     psFitsClose(fits);
    24 
    25     psFree(*target);
    26     *target = image;
    27 
    28     return true;
    29 }
     4psVector *SetOptWidths (bool *optimum, psMetadata *recipe);
     5pmReadout *makeFakeReadout(pmConfig *config, pmReadout *raw, psArray *sources, pmPSF *psf, psImageMaskType maskVal, int fullSize);
     6bool saveMatchData (pmReadout *readout, psphotStackOptions *options, int index);
     7bool matchKernel(pmConfig *config, pmReadout *cnv, pmReadout *raw, psphotStackOptions *options, int index);
     8bool dumpImageDiff(pmReadout *readoutConv, pmReadout *readoutFake, pmReadout *readoutRef, int index, char *rootname);
     9bool dumpImage(pmReadout *readoutOut, pmReadout *readoutRef, int index, char *rootname);
    3010
    3111// Get coordinates from a source
     
    148128
    149129// Renormalise a readout's variance map
    150 bool stackRenormaliseReadout(const pmConfig *config, // Configuration
    151                              pmReadout *readout      // Readout to renormalise
     130bool psphotStackRenormaliseVariance(const pmConfig *config, // Configuration
     131                              pmReadout *readout      // Readout to renormalise
    152132    )
    153133{
     
    180160    return pmReadoutVarianceRenormalise(readout, maskBad, num, minValid, maxValid);
    181161}
    182 
    183 // This is a hack to use the temporary convolved images and kernel generated previously.
    184 // This makes the 'matching' operation much faster, allowing debugging of the stack process easier.
    185 // It implicitly assumes the output root name is the same between invocations.
    186 
    187 # if (0)
    188 bool loadKernel (pmConfig *config, pmReadout *readoutCnv, psphotStackOptions *options, int index) {
    189 
    190     // Read the convolution kernel from the saved file
    191     pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPSTACK.CONV.KERNEL", index);
    192     psAssert(file, "Require file");
    193 
    194     pmFPAview *view = pmFPAviewAlloc(0); // View to readout of interest
    195     view->chip = view->cell = view->readout = 0;
    196     psString filename = pmFPAfileNameFromRule(file->filerule, file, view); // Filename of interest
    197 
    198     // Read convolution kernel data
    199     psString resolved = pmConfigConvertFilename(filename, config, false, false); // Resolved filename
    200     psFree(filename);
    201     psFits *fits = psFitsOpen(resolved, "r"); // FITS file for subtraction kernel
    202     psFree(resolved);
    203     if (!fits || !pmReadoutReadSubtractionKernels(readoutCnv, fits)) {
    204         psError(PSPHOT_ERR_IO, false, "Unable to read previously produced kernel");
    205         psFitsClose(fits);
    206         return false;
    207     }
    208     psFitsClose(fits);
    209 
    210     // read the convolved pixels (image, mask, variance) -- names are pre-defined
    211     if (!readImage(&readoutCnv->image,    options->convImages->data[index],    config) ||
    212         !readImage(&readoutCnv->mask,     options->convMasks->data[index],     config) ||
    213         !readImage(&readoutCnv->variance, options->convVariances->data[index], config)) {
    214         psError(PSPHOT_ERR_IO, false, "Unable to read previously produced image.");
    215         return false;
    216     }
    217 
    218     // XXX ??? not sure what is happening here -- consult Paul
    219     psRegion *region = psMetadataLookupPtr(NULL, readoutCnv->analysis, PM_SUBTRACTION_ANALYSIS_REGION); // Convolution region
    220     pmSubtractionKernels *kernels = psMetadataLookupPtr(NULL, readoutCnv->analysis, PM_SUBTRACTION_ANALYSIS_KERNEL);
    221 
    222     pmSubtractionAnalysis(readoutCnv->analysis, NULL, kernels, region, readoutCnv->image->numCols, readoutCnv->image->numRows);
    223 
    224     psKernel *kernel = pmSubtractionKernel(kernels, 0.0, 0.0, false); // Convolution kernel
    225 
    226     // update the covariance matrix
    227     // XXX why is this needed if we have correctly read the saved data?
    228     bool oldThreads = psImageCovarianceSetThreads(true);              // Old thread setting
    229     psKernel *covar = psImageCovarianceCalculate(kernel, readoutCnv->covariance); // Covariance matrix
    230     psImageCovarianceSetThreads(oldThreads);
    231     psFree(readoutCnv->covariance);
    232     readoutCnv->covariance = covar;
    233     psFree(kernel);
    234     return true;
    235 }
    236 # endif
    237162
    238163bool dumpImage(pmReadout *readoutOut, pmReadout *readoutRef, int index, char *rootname) {
     
    362287        widthsCopy = psVectorCopy(NULL, widths, PS_TYPE_F32); // Copy of kernel widths
    363288
    364         // we need to register the FWHM values for use downstream
    365         pmSubtractionSetFWHMs(options->targetSeeing, options->inputSeeing->data.F32[index]);
     289        // we need to register the FWHM values for use by pmSubtraction code
     290        pmSubtractionSetFWHMs(options->targetSeeing->data.F32[0], options->inputSeeing->data.F32[index]);
    366291
    367292        pmSubtractionParamScaleOptions(scale, scaleRef, scaleMin, scaleMax);
     
    469394}
    470395
    471 // Kernel normalisation for convolved readout
    472 bool renormKernel(pmReadout *readout, psphotStackOptions *options, int index) {
    473 
    474     double sum = 0.0;           // Sum of chi^2
    475     int num = 0;                // Number of measurements of chi^2
    476     psString regex = NULL;      // Regular expression
    477     psStringAppend(&regex, "^%s$", PM_SUBTRACTION_ANALYSIS_NORM);
    478     psMetadataIterator *iter = psMetadataIteratorAlloc(readout->analysis, PS_LIST_HEAD, regex);
    479     psFree(regex);
    480     psMetadataItem *item = NULL;// Item from iteration
    481     while ((item = psMetadataGetAndIncrement(iter))) {
    482         assert(item->type == PS_TYPE_F32);
    483         float norm = item->data.F32; // Normalisation
    484         sum += norm;
    485         num++;
    486     }
    487     psFree(iter);
    488     float conv = sum/num;       // Mean normalisation from convolution
    489     float stars = powf(10.0, -0.4 * options->norm->data.F32[index]); // Normalisation from stars
    490     float renorm =  stars / conv; // Renormalisation to apply
    491     psLogMsg("psphotStack", PS_LOG_INFO, "Renormalising image %d by %f (kernel: %f, stars: %f)\n", index, renorm, conv, stars);
    492 
    493     psBinaryOp(readout->image, readout->image, "*", psScalarAlloc(renorm, PS_TYPE_F32));
    494     psBinaryOp(readout->variance, readout->variance, "*", psScalarAlloc(PS_SQR(renorm), PS_TYPE_F32));
    495     return true;
    496 }
    497 
    498 // adjust scaling for readout (remove background, ..., determine weighting)
    499 bool rescaleData(pmReadout *readout, pmConfig *config, psphotStackOptions *options, int index) {
    500 
    501     psMetadata *stackRecipe = psMetadataLookupMetadata(NULL, config->recipes, "PPSTACK"); // ppStack recipe
    502     psAssert(stackRecipe, "We've thrown an error on this before.");
    503 
    504     // Look up appropriate values from the ppSub recipe
    505     psMetadata *subRecipe = psMetadataLookupMetadata(NULL, config->recipes, "PPSUB"); // PPSUB recipe
    506     psAssert(subRecipe, "recipe missing");
    507 
    508     psString maskValStr = psMetadataLookupStr(NULL, subRecipe, "MASK.VAL"); // Name of bits to mask going in
    509     psString maskBadStr = psMetadataLookupStr(NULL, stackRecipe, "MASK.BAD"); // Name of bits to mask for bad
    510 
    511     psImageMaskType maskVal = pmConfigMaskGet(maskValStr, config); // Bits to mask going in to pmSubtractionMatch
    512     psImageMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels
    513 
    514     // Ensure the background value is zero
    515     psStats *bg = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics for background
    516     psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator
    517 
    518     // XXX why is this in config->arguments and not recipe?
    519     if (!psMetadataLookupBool(NULL, config->arguments, "PPSTACK.SKIP.BG.SUB")) {
    520         if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal | maskBad, rng)) {
    521             psAbort("Can't measure background for image.");
    522             // XXX we used to clear error: why is this acceptable? psErrorClear();
    523         }
    524 
    525         float value = psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN);
    526         float stdev = psStatsGetValue(bg, PS_STAT_ROBUST_STDEV);
    527 
    528         psLogMsg("psphotStack", PS_LOG_INFO, "Correcting convolved image background by %lf (+/- %lf)", value, stdev);
    529         psBinaryOp(readout->image, readout->image, "-", psScalarAlloc(value, PS_TYPE_F32));
    530     }
    531 
    532     if (!stackRenormaliseReadout(config, readout)) {
    533         psFree(rng);
    534         psFree(bg);
    535         return false;
    536     }
    537 
    538     // Measure the variance level for the weighting
    539     if (psMetadataLookupBool(NULL, stackRecipe, "WEIGHTS")) {
    540         if (!psImageBackground(bg, NULL, readout->variance, readout->mask, maskVal | maskBad, rng)) {
    541             psError(PSPHOT_ERR_DATA, false, "Can't measure mean variance for image.");
    542             psFree(rng);
    543             psFree(bg);
    544             return false;
    545         }
    546         options->weightings->data.F32[index] = 1.0 / (psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN) * psImageCovarianceFactor(readout->covariance));
    547     } else {
    548         options->weightings->data.F32[index] = 1.0;
    549     }
    550     psLogMsg("psphotStack", PS_LOG_INFO, "Weighting for image %d is %f\n", index, options->weightings->data.F32[index]);
    551 
    552     psFree(rng);
    553     psFree(bg);
    554     return true;
    555 }
    556 
    557396# define NOISE_FRACTION 0.01             // Set minimum flux to this fraction of noise
    558397# define SOURCE_MASK (PM_SOURCE_MODE_FAIL | PM_SOURCE_MODE_DEFECT | PM_SOURCE_MODE_SATURATED | PM_SOURCE_MODE_CR_LIMIT | PM_SOURCE_MODE_EXT_LIMIT) // Mask to apply to input sources
  • branches/meh_branches/ppstack_test/psphot/src/psphotStackObjects.c

    r28013 r33415  
    4747    return true;
    4848}
     49
     50// mark good vs bad objects
     51bool psphotStackObjectsSelectForAnalysis (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects) {
     52
     53    bool status = false;
     54
     55    // find the currently selected readout
     56    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, 0); // use the 0-index image to represent the image area
     57    psAssert (file, "missing file?");
     58
     59    pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
     60    psAssert (readout, "missing readout?");
     61
     62    // select the appropriate recipe information
     63    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     64    psAssert (recipe, "missing recipe?");
     65
     66    // option to limit analysis to a specific region
     67    char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION");
     68    psRegion AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region));
     69    if (psRegionIsNaN (AnalysisRegion)) psAbort("analysis region mis-defined");
     70
     71    // S/N limit to perform full non-linear fits
     72    float SN_LIM_PETRO  = psMetadataLookupF32 (&status, recipe, "EXTENDED_SOURCE_SN_LIM");
     73    float SN_LIM_RADIAL = psMetadataLookupF32 (&status, recipe, "RADIAL_APERTURES_SN_LIM");
     74
     75    bool doPetroStars   = psMetadataLookupBool (&status, recipe, "PETROSIAN_FOR_STARS");
     76
     77    for (int i = 0; i < objects->n; i++) {
     78        pmPhotObj *object = objects->data[i];
     79        if (!object) continue;
     80        if (!object->sources) continue;
     81
     82        // we check each source for an object and keep the object if any source is valid
     83
     84        bool keepObjectRadial = false;
     85        bool keepObjectPetro = false;
     86        for (int j = 0; j < object->sources->n; j++) {
     87
     88            pmSource *source = object->sources->data[j];
     89            if (!source) continue;
     90            if (!source->peak) continue;
     91
     92            // skip PSF-like and non-astronomical objects
     93            if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
     94            if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
     95            if (source->mode & PM_SOURCE_MODE_DEFECT) continue;
     96            if (source->mode & PM_SOURCE_MODE_SATSTAR) continue;
     97           
     98            // limit selection by analysis region (this automatically apply
     99            if (source->peak->x < AnalysisRegion.x0) continue;
     100            if (source->peak->y < AnalysisRegion.y0) continue;
     101            if (source->peak->x > AnalysisRegion.x1) continue;
     102            if (source->peak->y > AnalysisRegion.y1) continue;
     103           
     104            // SN limit tests for RADIAL APERTURES:
     105            bool skipSourceRadial = false;
     106            if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
     107                skipSourceRadial = (source->moments->KronFlux < SN_LIM_RADIAL * source->moments->KronFluxErr);
     108            } else {
     109                skipSourceRadial = (sqrt(source->peak->detValue) < SN_LIM_RADIAL);
     110            }
     111            if (!skipSourceRadial) keepObjectRadial = true;
     112
     113            // SN limit tests for PETRO
     114            bool skipSourcePetro = false;
     115            if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
     116                skipSourcePetro = (source->moments->KronFlux < SN_LIM_PETRO * source->moments->KronFluxErr);
     117            } else {
     118                skipSourcePetro = doPetroStars ? (sqrt(source->peak->detValue) < SN_LIM_PETRO) : true;
     119            }
     120            if (!skipSourcePetro) keepObjectPetro = true;
     121
     122            keepObjectPetro = true;
     123        }
     124
     125        for (int j = 0; j < object->sources->n; j++) {
     126            pmSource *source = object->sources->data[j];
     127            if (!source) continue;
     128            if (!source->peak) continue;
     129
     130            // we have to set a bit in either case to tell psphotExtendedSourceAnalysis to
     131            // avoid the single-detection tests
     132
     133            if (keepObjectPetro) {
     134                source->tmpFlags |=  PM_SOURCE_TMPF_PETRO_KEEP;
     135                source->tmpFlags &= ~PM_SOURCE_TMPF_PETRO_SKIP;
     136            } else {
     137                source->tmpFlags |=  PM_SOURCE_TMPF_PETRO_SKIP;
     138                source->tmpFlags &= ~PM_SOURCE_TMPF_PETRO_KEEP;
     139            }       
     140
     141            if (keepObjectRadial) {
     142                source->tmpFlags |=  PM_SOURCE_TMPF_RADIAL_KEEP;
     143                source->tmpFlags &= ~PM_SOURCE_TMPF_RADIAL_SKIP;
     144            } else {
     145                source->tmpFlags |=  PM_SOURCE_TMPF_RADIAL_SKIP;
     146                source->tmpFlags &= ~PM_SOURCE_TMPF_RADIAL_KEEP;
     147            }       
     148        }
     149    }
     150
     151    psLogMsg ("psphot", PS_LOG_INFO, "marked good vs bad objects\n");
     152    return true;
     153}
  • branches/meh_branches/ppstack_test/psphot/src/psphotStackOptions.c

    r28160 r33415  
    1919    psFree (options->norm);
    2020    psFree (options->matchChi2);
    21     psFree (options->weightings);
     21    psFree (options->targetSeeing);
    2222
    2323    return;
     
    3636    options->convolve = false;
    3737    options->convolveSource = PSPHOT_CNV_SRC_NONE;
    38     options->targetSeeing = NAN;
     38    options->targetSeeing = NULL;
    3939
    4040    options->psfs        = psArrayAlloc(num);
     
    4747    options->norm        = psVectorAlloc(num, PS_TYPE_F32);
    4848    options->matchChi2   = psVectorAlloc(num, PS_TYPE_F32); // chi^2 for stamps when matching
    49     options->weightings  = psVectorAlloc(num, PS_TYPE_F32); // Combination weightings for images (1/noise^2)
    5049
    5150    psVectorInit(options->inputMask,   0);
     
    5352    psVectorInit(options->norm,        NAN);
    5453    psVectorInit(options->matchChi2,   NAN);
    55     psVectorInit(options->weightings,  NAN);
    5654
    5755    return options;
  • branches/meh_branches/ppstack_test/psphot/src/psphotStackPSF.c

    r31154 r33415  
    11# include "psphotInternal.h"
    22
    3 pmPSF *psphotStackPSF(const pmConfig *config, int numCols, int numRows, const psArray *psfs, const psVector *inputMask)
    4 {
     3// determine the 1st target PSF (either AUTO or defined by PSPHOT.STACK.TARGET.PSF.FWHM)
     4bool psphotStackPSF(const pmConfig *config, psphotStackOptions *options)  {
     5
    56    bool mdok = false;
    6     pmPSF *psf = NULL;
     7
     8    int numCols = options->numCols;
     9    int numRows = options->numRows;
     10    psArray *psfs = options->psfs;
     11    psVector *inputMask = options->inputMask;
    712
    813    // Get the recipe values
     
    1722       
    1823    char *psfModel = psMetadataLookupStr(NULL, recipe, "PSF.MODEL"); // Model for PSF
     24
     25    options->targetSeeing = psVectorAllocEmpty(4, PS_TYPE_F32);
    1926
    2027    if (autoPSF) {
     
    3845
    3946        // Solve for the target PSF
    40         psf = pmPSFEnvelope(numCols, numRows, psfs, psfInstances, psfRadius, psfModel, psfOrder, psfOrder, maskVal);
    41         if (!psf) {
     47        options->psf = pmPSFEnvelope(numCols, numRows, psfs, psfInstances, psfRadius, psfModel, psfOrder, psfOrder, maskVal);
     48        if (!options->psf) {
    4249            psError(PSPHOT_ERR_PSF, false, "Unable to determine output PSF.");
    43             return NULL;
     50            return false;
    4451        }
    4552
    46     } else {
    47 
    48         // externally-defined PSF
    49         // XXX need to test for compatibility of target with inputs
    50 
    51         float targetFWHM = psMetadataLookupF32 (&mdok, psphotRecipe, "PSPHOT.STACK.TARGET.PSF.FWHM");
    52         if (!mdok) {
    53             psVector *fwhmValues = psMetadataLookupVector(&mdok, psphotRecipe, "PSPHOT.STACK.TARGET.PSF.FWHM"); // Magnitude offsets
    54             psAssert (mdok, "missing psphot recipe value PSPHOT.STACK.TARGET.PSF.FWHM");
    55             targetFWHM = fwhmValues->data.F32[0];
    56         }
    57 
    58         // measured scale factors (fwhm = Sxx * 2.35 * scaleFactor / sqrt(2.0))
    59         // GAUSS  : 1.000
    60         // PGAUSS : 1.006
    61         // QGAUSS : 1.151
    62         // RGAUSS : 0.883
    63         // PS1_V1 : 1.134
    64        
    65         float scaleFactor = NAN;
    66         if (!strcmp(psfModel, "PS_MODEL_GAUSS")) {
    67             scaleFactor = 1.000;
    68         }
    69         if (!strcmp(psfModel, "PS_MODEL_PGAUSS")) {
    70             scaleFactor = 1.0006;
    71         }
    72         if (!strcmp(psfModel, "PS_MODEL_QGAUSS")) {
    73             scaleFactor = 1.151;
    74         }
    75         if (!strcmp(psfModel, "PS_MODEL_RGAUSS")) {
    76             scaleFactor = 0.883;
    77         }
    78         if (!strcmp(psfModel, "PS_MODEL_PS1_V1")) {
    79             scaleFactor = 1.134;
    80         }
    81         psAssert (isfinite(scaleFactor), "invalid model for PSF");
    82 
    83         float Sxx = sqrt(2.0)*targetFWHM / 2.35 / scaleFactor;
    84 
    85         // XXX probably should make the model type (and par 7) optional from recipe
    86         // psf = pmPSFBuildSimple(psfModel, Sxx, Sxx, 0.0, 1.0);
    87         psf = pmPSFBuildSimple(psfModel, Sxx, Sxx, 0.0, 0.2);
    88         if (!psf) {
    89             psError(PSPHOT_ERR_PSF, false, "Unable to build dummy PSF.");
    90             return NULL;
    91         }
     53        psMetadataAddPtr(config->arguments, PS_LIST_TAIL, "PSF.TARGET", PS_DATA_UNKNOWN, "Target PSF for stack", options->psf);
     54        float targetSeeing = pmPSFtoFWHM(options->psf, 0.5 * options->numCols, 0.5 * options->numRows); // FWHM for target
     55        psVectorAppend(options->targetSeeing, targetSeeing);
     56        psLogMsg("psphotStack", PS_LOG_INFO, "Target seeing FWHM (auto-scaled): %f\n", targetSeeing);
     57        return true;
    9258    }
    9359
    94     return psf;
     60    // externally-defined PSF
     61    // XXX need to test for compatibility of target with inputs
     62
     63    // is a single target FWHM specified, or a set of values?  set up the vector options->targetSeeing and the local 1st value
     64    float targetSeeing = psMetadataLookupF32 (&mdok, psphotRecipe, "PSPHOT.STACK.TARGET.PSF.FWHM");
     65    if (!mdok) {
     66        psVector *fwhmValues = psMetadataLookupVector(&mdok, psphotRecipe, "PSPHOT.STACK.TARGET.PSF.FWHM"); // Magnitude offsets
     67        psAssert (mdok, "missing psphot recipe value PSPHOT.STACK.TARGET.PSF.FWHM");
     68        for (int i = 0; i < fwhmValues->n; i++) {
     69            psVectorAppend(options->targetSeeing, fwhmValues->data.F32[i]);
     70        }           
     71        targetSeeing = fwhmValues->data.F32[0];
     72    } else {
     73        psVectorAppend(options->targetSeeing, targetSeeing);
     74    }
     75
     76    // measured scale factors (fwhm = Sxx * 2.35 * scaleFactor / sqrt(2.0))
     77    // GAUSS  : 1.000
     78    // PGAUSS : 1.006
     79    // QGAUSS : 1.151
     80    // RGAUSS : 0.883
     81    // PS1_V1 : 1.134
     82       
     83    float scaleFactor = NAN;
     84    if (!strcmp(psfModel, "PS_MODEL_GAUSS")) {
     85        scaleFactor = 1.000;
     86    }
     87    if (!strcmp(psfModel, "PS_MODEL_PGAUSS")) {
     88        scaleFactor = 1.0006;
     89    }
     90    if (!strcmp(psfModel, "PS_MODEL_QGAUSS")) {
     91        scaleFactor = 1.151;
     92    }
     93    if (!strcmp(psfModel, "PS_MODEL_RGAUSS")) {
     94        scaleFactor = 0.883;
     95    }
     96    if (!strcmp(psfModel, "PS_MODEL_PS1_V1")) {
     97        scaleFactor = 1.134;
     98    }
     99    psAssert (isfinite(scaleFactor), "invalid model for PSF");
     100
     101    float Sxx = sqrt(2.0)*targetSeeing / 2.35 / scaleFactor;
     102
     103    // XXX probably should make the model type (and par 7) optional from recipe
     104    // psf = pmPSFBuildSimple(psfModel, Sxx, Sxx, 0.0, 1.0);
     105    options->psf = pmPSFBuildSimple(psfModel, Sxx, Sxx, 0.0, 0.2);
     106    if (!options->psf) {
     107        psError(PSPHOT_ERR_PSF, false, "Unable to build dummy PSF.");
     108        return false;
     109    }
     110
     111    psMetadataAddPtr(config->arguments, PS_LIST_TAIL, "PSF.TARGET", PS_DATA_UNKNOWN, "Target PSF for stack", options->psf);
     112    psLogMsg("psphotStack", PS_LOG_INFO, "Target seeing FWHM (1 of %ld): %f\n", options->targetSeeing->n, targetSeeing);
     113    return true;
    95114}
  • branches/meh_branches/ppstack_test/psphot/src/psphotStackReadout.c

    r31154 r33415  
    4444bool psphotStackReadout (pmConfig *config, const pmFPAview *view) {
    4545
     46    psArray *objects = NULL; // used below after 'pass1finish' label
     47
     48    // measure the total elapsed time in psphotReadout.  dtime is the elapsed time used jointly
     49    // by the multiple threads, not the total time used by all threads.
    4650    psTimerStart ("psphotReadout");
    4751
     
    5660    // optional break-point for processing
    5761    char *breakPt = psMetadataLookupStr (NULL, recipe, "BREAK_POINT");
    58     PS_ASSERT_PTR_NON_NULL (breakPt, false);
    59 
    60     // XXX or do I set OUT to be a pmFPAfile pointing at the input of interest?
     62    psAssert (breakPt, "configuration error: set BREAK_POINT");
     63
     64    // we have 3 relevant files: RAW (unconvolved), CNV (convolved stack), OUT (psf-matched stack)
     65    // select which image (RAW or CNV) is used for analysis (RAW always used for detection)
    6166    bool useRaw = psMetadataLookupBool (NULL, recipe, "PSPHOT.STACK.USE.RAW");
    6267    char *STACK_SRC = useRaw ? STACK_RAW : STACK_CNV;
    63     char *STACK_DET = STACK_RAW; // XXX optionally allow this to be CNV?
    64 
    65     // we have 3 relevant files: RAW, CNV, OUT
     68    char *STACK_DET = STACK_RAW;
    6669
    6770    // set the photcode for each image
     
    7174    }
    7275
    73     // Generate the mask and weight images
    74     // XXX this should be done before we perform the convolutions
     76    // Generate the mask and weight images (if not supplied) and set mask bits
    7577    if (!psphotSetMaskAndVariance (config, view, STACK_DET)) {
    7678        return psphotReadoutCleanup (config, view, STACK_SRC);
     
    8183
    8284    // generate a background model (median, smoothed image)
    83     // XXX I think this is not defined correctly for an array of images.
    84     // XXX probably need to subtract the model (same model?) for both RAW and OUT
    8585    if (!psphotModelBackground (config, view, STACK_DET)) {
    8686        return psphotReadoutCleanup (config, view, STACK_SRC);
     
    8989        return psphotReadoutCleanup (config, view, STACK_SRC);
    9090    }
     91    if (!psphotSubtractBackground (config, view, STACK_SRC)) {
     92        return psphotReadoutCleanup (config, view, STACK_SRC);
     93    }
    9194    if (!strcasecmp (breakPt, "BACKMDL")) {
    9295        return psphotReadoutCleanup (config, view, STACK_SRC);
    9396    }
    9497
     98    // also make the chisq detection image
    9599    if (!psphotStackChisqImage(config, view, STACK_DET, STACK_SRC)) {
    96100        psError (PSPHOT_ERR_UNKNOWN, false, "failure to generate chisq image");
     
    109113    }
    110114
    111     // copy the detections from DET to SRC
     115    // If DET and SRC are different images, copy the detections from DET to SRC.  This 'copy'
     116    // is just a copy of the container pointer; the sources on both DET and SRC are the same
     117    // memory objects
    112118    if (strcmp(STACK_SRC, STACK_DET)) {
    113119        if (!psphotCopySources (config, view, STACK_SRC, STACK_DET)) {
     
    122128        return psphotReadoutCleanup (config, view, STACK_SRC);
    123129    }
    124 
    125     if (!strcasecmp (breakPt, "TEST1")) {
    126         return psphotReadoutCleanup (config, view, STACK_SRC);
    127     }
    128 
     130    if (!strcasecmp (breakPt, "PEAKS")) {
     131        return psphotReadoutCleanup (config, view, STACK_SRC);
     132    }
     133    // psphotDumpTest (config, view, STACK_SRC);
    129134    psMemDump("sourcestats");
    130 
    131     // generate the objects (object unify the sources from the different images)
    132     // XXX this could just match the detections for the chisq image, and not bother measuring the
    133     // source stats in that case...
    134     psArray *objects = psphotMatchSources (config, view, STACK_SRC);
    135 
    136     psMemDump("matchsources");
    137 
    138     if (!strcasecmp (breakPt, "TEST2")) {
    139         psFree(objects);
    140         return psphotReadoutCleanup (config, view, STACK_SRC);
    141     }
    142 
    143     // construct sources for the newly-generated sources (from other images)
    144     if (!psphotSourceStats (config, view, STACK_SRC, false)) { // pass 1
    145         psFree(objects);
    146         psError(PSPHOT_ERR_UNKNOWN, false, "failure to generate sources");
    147         return psphotReadoutCleanup (config, view, STACK_SRC);
    148     }
    149 
    150     psMemDump("sourcestats");
    151 
    152     // find blended neighbors of very saturated stars (detections->newSources)
    153     // if (!psphotDeblendSatstars (config, view)) {
    154     //     psError (PSPHOT_ERR_UNKNOWN, false, "failed on satstar deblend analysis");
    155     //     return psphotReadoutCleanup (config, view, STACK_SRC);
    156     // }
    157 
    158     // mark blended peaks PS_SOURCE_BLEND (detections->newSources)
    159     // if (!psphotBasicDeblend (config, view)) {
    160     //     psError (PSPHOT_ERR_UNKNOWN, false, "failed on deblend analysis");
    161     //     return psphotReadoutCleanup (config, view, STACK_SRC);
    162     // }
    163135
    164136    // classify sources based on moments, brightness
    165137    // only run this on detections from the input images, not chisq image
    166138    if (!psphotRoughClass (config, view, STACK_SRC)) {
    167         psFree(objects);
    168139        psError (PSPHOT_ERR_UNKNOWN, false, "failed to determine rough classifications");
    169140        return psphotReadoutCleanup (config, view, STACK_SRC);
    170141    }
     142
    171143    // if we were not supplied a PSF model, determine the IQ stats here (detections->newSources)
    172144    // only run this on detections from the input images, not chisq image
    173145    if (!psphotImageQuality (config, view, STACK_SRC)) { // pass 1
    174         psFree(objects);
    175146        psError (PSPHOT_ERR_UNKNOWN, false, "failed to measure image quality");
    176147        return psphotReadoutCleanup (config, view, STACK_SRC);
    177148    }
    178149    if (!strcasecmp (breakPt, "MOMENTS")) {
    179         psFree(objects);
    180         return psphotReadoutCleanup (config, view, STACK_SRC);
    181     }
    182 
    183     // use bright stellar objects to measure PSF if we were supplied a PSF for any input file,
    184     // this step is skipped
     150        return psphotReadoutCleanup (config, view, STACK_SRC);
     151    }
     152
     153    // use bright stellar objects to measure PSF
    185154    if (!psphotChoosePSF (config, view, STACK_SRC, true)) { // pass 1
    186         psFree(objects);
    187155        psLogMsg ("psphot", 3, "failure to construct a psf model");
    188156        return psphotReadoutCleanup (config, view, STACK_SRC);
    189157    }
    190158    if (!strcasecmp (breakPt, "PSFMODEL")) {
    191         psFree(objects);
    192         return psphotReadoutCleanup (config, view, STACK_SRC);
    193     }
    194 
    195     // construct an initial model for each object, set the radius to fitRadius, set circular fit mask
    196     psphotGuessModels (config, view, STACK_SRC);
     159        return psphotReadoutCleanup (config, view, STACK_SRC);
     160    }
    197161
    198162    // merge the newly selected sources into the existing list
     
    200164    psphotMergeSources (config, view, STACK_SRC);
    201165
     166    // Construct an initial model for each object, set the radius to fitRadius, set circular
     167    // fit mask.  NOTE: only applied to sources without guess models
     168    psphotGuessModels (config, view, STACK_SRC);
     169
    202170    // linear PSF fit to source peaks, subtract the models from the image (in PSF mask)
    203     psphotFitSourcesLinearStack (config, objects, FALSE);
     171    psphotFitSourcesLinear (config, view, STACK_SRC, false);
    204172    psphotStackVisualFilerule(config, view, STACK_SRC);
    205173
     174    // measure the radial profiles to the sky
     175    psphotRadialProfileWings (config, view, STACK_SRC);
     176
     177    // re-measure the kron mags with models subtracted.  this pass starts with a circular
     178    // window of size PSF_MOMENTS_RADIUS (same window used to measure the psf-scale moments)
     179    // but iterates to an appropriately larger size
     180    psphotKronIterate(config, view, STACK_SRC);
     181
    206182    // identify CRs and extended sources
    207     psphotSourceSize (config, view, STACK_SRC, TRUE);
    208 
    209     // XXX do we want to do a preliminary (unconvolved) model fit here, and then
    210     // do a second detection pass? (like standard psphot)
    211 
    212     // measure aperture photometry corrections
    213     if (!psphotApResid (config, view, STACK_SRC)) {
    214         psFree (objects);
    215         psLogMsg ("psphot", 3, "failed on psphotApResid");
    216         return psphotReadoutCleanup (config, view, STACK_SRC);
    217     }
     183    psphotSourceSize (config, view, STACK_SRC, true);
     184
     185    // non-linear PSF and EXT fit to brighter sources
     186    // replace model flux, adjust mask as needed, fit, subtract the models (full stamp)
     187    psphotBlendFit (config, view, STACK_SRC); // pass 1 (detections->allSources)
     188
     189    // replace all sources (do NOT ignore subtraction state)
     190    psphotReplaceAllSources (config, view, STACK_SRC, false); // pass 1 (detections->allSources)
     191
     192    // if we only do one pass, skip to extended source analysis
     193    if (!strcasecmp (breakPt, "PASS1")) goto pass1finish;
     194
     195    // linear fit to include all sources (subtract again)
     196    // NOTE : apply to ALL sources (extended + psf)
     197    // NOTE 2 : this function subtracts the models from the given filerule (SRC), not DET
     198    psphotFitSourcesLinear (config, view, STACK_SRC, true); // pass 2 (detections->allSources)
     199
     200    // NOTE: possibly re-measure background model here with objects subtracted / or masked
     201
     202    // NOTE: this block performs the 2nd pass low-significance PSF detection stage
     203    {
     204        // if DET and SRC are different images, generate children sources for all sources in
     205        // the SRC image.  This operation replaces the existing DETECTION container on DET
     206        // which is currently a view to the one on SRC).  children sources go to
     207        // det->allSources
     208        if (strcmp(STACK_SRC, STACK_DET)) {
     209            psphotSourceChildren (config, view, STACK_DET, STACK_SRC);
     210
     211            //  subtract all sources from DET (this will subtract using the psf model for SRC, which
     212            //  will somewhat oversubtract the sources -- this is OK
     213            psphotRemoveAllSources (config, view, STACK_DET, false); // ignore subtraction state for sources
     214        }
     215
     216        // add noise for subtracted objects
     217        psphotAddNoise (config, view, STACK_DET); // pass 1 (detections->allSources)
     218
     219        // find fainter sources
     220        // NOTE: finds new peaks and new footprints, OLD and FULL set are saved on detections
     221        psphotFindDetections (config, view, STACK_DET, false); // pass 2 (detections->peaks, detections->footprints)
     222
     223        // remove noise for subtracted objects (ie, return to normal noise level)
     224        // NOTE: this needs to operate only on the OLD sources
     225        psphotSubNoise (config, view, STACK_DET); // pass 1 (detections->allSources)
     226
     227        // if DET and SRC are different images, copy the detections from DET to SRC
     228        // (this operation just ensures the metadata container has a view on SRC as well
     229        if (strcmp(STACK_SRC, STACK_DET)) {
     230            // replace all sources in DET
     231            psphotReplaceAllSources (config, view, STACK_DET, false); // ignore subtraction state for sources
     232
     233            // copy the newly detected peaks from DET to SRC so SourceStats below can operate on them
     234            if (!psphotCopyPeaks (config, view, STACK_SRC, STACK_DET)) {
     235                psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis");
     236                return psphotReadoutCleanup (config, view, STACK_SRC);
     237            }
     238        }
     239
     240        // define new sources based on only the new peaks & measure moments
     241        // NOTE: new sources are saved on detections->newSources
     242        psphotSourceStats (config, view, STACK_SRC, false); // pass 2 (detections->newSources)
     243
     244        // set source type
     245        // NOTE: apply only to detections->newSources
     246        if (!psphotRoughClass (config, view, STACK_SRC)) { // pass 2 (detections->newSources)
     247            psLogMsg ("psphot", 3, "failed to find a valid PSF clump for image");
     248            return psphotReadoutCleanup (config, view, STACK_SRC);
     249        }
     250
     251        // replace all sources so fit below applies to all at once
     252        // NOTE: apply only to OLD sources (which have been subtracted)
     253        psphotReplaceAllSources (config, view, STACK_SRC, false); // pass 2
     254
     255        // merge the newly selected sources into the existing list
     256        // NOTE: merge OLD and NEW
     257        // XXX check on free of sources...
     258        psphotMergeSources (config, view, STACK_SRC); // (detections->newSources + detections->allSources -> detections->allSources)
     259
     260        // Construct an initial model for each object, set the radius to fitRadius, set circular
     261        // fit mask.  NOTE: only applied to sources without guess models
     262        psphotGuessModels (config, view, STACK_SRC);
     263    }
     264
     265pass1finish:
     266
     267    // generate the objects (objects unify the sources from the different images) NOTE: could
     268    // this just match the detections for the chisq image, and not bother measuring the source
     269    // stats in that case...?
     270    objects = psphotMatchSources (config, view, STACK_SRC);
     271    psMemDump("matchsources");
     272
     273    // Construct an initial model for each object, set the radius to fitRadius, set circular
     274    // fit mask.  NOTE: only applied to sources without guess models
     275    psphotGuessModels (config, view, STACK_SRC);
     276
     277    psphotStackObjectsUnifyPosition (objects);
     278
     279    psphotStackObjectsSelectForAnalysis (config, view, STACK_SRC, objects);
     280
     281    // NOTE: apply to ALL sources
     282    psphotFitSourcesLinear (config, view, STACK_SRC, true); // pass 3 (detections->allSources)
     283
     284    // measure the radial profiles to the sky (only measures new objects)
     285    psphotRadialProfileWings (config, view, STACK_SRC);
     286
     287    // re-measure the kron mags with models subtracted
     288    // psphotKronMasked(config, view, STACK_SRC);
     289    psphotKronIterate(config, view, STACK_SRC);
     290
     291    // measure source size for the remaining sources
     292    // NOTE: applies only to NEW (unmeasured) sources
     293    psphotSourceSize (config, view, STACK_SRC, false); // pass 2 (detections->allSources)
    218294
    219295    psMemDump("psfstats");
    220296
    221     psphotStackObjectsUnifyPosition (objects);
    222 
    223297    // measure elliptical apertures, petrosians (objects sorted by S/N)
    224     psphotExtendedSourceAnalysisByObject (config, objects, view, STACK_SRC); // pass 1 (detections->allSources)
     298    // psphotExtendedSourceAnalysisByObject (config, objects, view, STACK_SRC); // pass 1 (detections->allSources)
     299    psphotExtendedSourceAnalysis (config, view, STACK_SRC); // pass 1 (detections->allSources)
    225300
    226301    // measure non-linear extended source models (exponential, deVaucouleur, Sersic) (sources sorted by S/N)
    227302    psphotExtendedSourceFits (config, view, STACK_SRC); // pass 1 (detections->allSources)
    228 
    229     // calculate source magnitudes
    230     psphotMagnitudes(config, view, STACK_SRC);
    231303
    232304    // create source children for the OUT filerule (for radial aperture photometry)
     
    238310    }
    239311
     312    // measure circular, radial apertures (objects sorted by S/N)
     313    // this forces photometry on the undetected sources from other images
     314    psphotRadialApertures (config, view, STACK_SRC, 0); // XXX entry 0 == unmatched?
    240315    psMemDump("extmeas");
    241316
    242     bool smoothAgain = true;
    243     for (int nMatchedPSF = 0; smoothAgain; nMatchedPSF++) {
     317    int nRadialEntries = psphotStackMatchPSFsEntries(config, view, STACK_OUT);
     318
     319    for (int entry = 1; entry < nRadialEntries; entry++) {
     320        // NOTE: entry 0 is the unmatched image set
    244321
    245322        // re-measure the PSF for the smoothed image (using entries in 'allSources')
     
    253330
    254331        // measure circular, radial apertures (objects sorted by S/N)
    255         psphotRadialAperturesByObject (config, objectsRadial, view, STACK_OUT, nMatchedPSF);
     332        // entry 0 == unmatched? pass entry + 1?
     333        psphotRadialApertures (config, view, STACK_OUT, entry);
    256334
    257335        // replace the flux in the image so it is returned to its original state
    258         psphotReplaceAllSources (config, view, STACK_OUT);
     336        psphotReplaceAllSources (config, view, STACK_OUT, false);
    259337
    260338        // smooth to the next FWHM, or set 'smoothAgain' to false if no more
    261         psphotStackMatchPSFsNext(&smoothAgain, config, view, STACK_OUT, nMatchedPSF);
     339        psphotStackMatchPSFsNext(config, view, STACK_OUT, entry);
    262340        psMemDump("matched");
    263341    }
    264342
    265     if (0 && !psphotEfficiency(config, view, STACK_OUT)) {
     343    // measure aperture photometry corrections
     344    if (!psphotApResid (config, view, STACK_SRC)) {
     345        psFree (objects);
     346        psLogMsg ("psphot", 3, "failed on psphotApResid");
     347        return psphotReadoutCleanup (config, view, STACK_SRC);
     348    }
     349
     350    // calculate source magnitudes
     351    psphotMagnitudes(config, view, STACK_SRC);
     352
     353    // XXX NOTE: this function wants to have the PSF of the image, but we (so far) only measure the
     354    // PSF of the SRC image.  can we fake it by generating the PSF for DET as well (up above)?
     355    if (false && !psphotEfficiency(config, view, STACK_DET)) {
    266356        psErrorStackPrint(stderr, "Unable to determine detection efficiencies from fake sources");
    267357        psErrorClear();
  • branches/meh_branches/ppstack_test/psphot/src/psphotSubtractBackground.c

    r31154 r33415  
    103103        psphotSaveImage (NULL, image, name);
    104104    }
    105     psLogMsg ("psphot", PS_LOG_INFO, "subtracted background model: %f sec\n", psTimerMark ("psphot.background"));
     105    psLogMsg ("psphot", PS_LOG_WARN, "subtracted background model: %f sec\n", psTimerMark ("psphot.background"));
    106106
    107107    // the pmReadout selected in this function are all view on entries in config->files
  • branches/meh_branches/ppstack_test/psphot/src/psphotTest.c

    r29936 r33415  
    8585
    8686    // wait for the threads to finish and manage results
    87     if (!psThreadPoolWait (true)) {
     87    if (!psThreadPoolWait (true, true)) {
    8888        fprintf (stderr, "failure to run FillImage (2)");
    8989        exit (1);
Note: See TracChangeset for help on using the changeset viewer.