IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 36375 for trunk/psphot/src


Ignore:
Timestamp:
Dec 10, 2013, 2:55:11 PM (13 years ago)
Author:
eugene
Message:

merge changes from eam_branches/ipp-20130904

Location:
trunk
Files:
28 edited
11 copied

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/psphot

  • trunk/psphot/src

  • trunk/psphot/src/Makefile.am

    r34317 r36375  
    2525libpsphot_la_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
    2626
    27 bin_PROGRAMS = psphot psphotForced psphotMinimal psphotMakePSF psphotStack psphotModelTest
     27bin_PROGRAMS = psphot psphotForced psphotFullForce psphotMinimal psphotMakePSF psphotStack psphotModelTest psmakecff
    2828# bin_PROGRAMS = psphotPetrosianStudy psphotTest psphotMomentsStudy
    2929
     
    3636psphotForced_LDADD = libpsphot.la
    3737
     38psphotFullForce_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
     39psphotFullForce_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
     40psphotFullForce_LDADD = libpsphot.la
     41
    3842psphotMinimal_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
    3943psphotMinimal_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
     
    5155psphotModelTest_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
    5256psphotModelTest_LDADD = libpsphot.la
     57
     58psmakecff_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
     59psmakecff_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
     60psmakecff_LDADD = libpsphot.la
     61
    5362
    5463# psphotMomentsStudy_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
     
    7786        psphotForced.c             \
    7887        psphotForcedArguments.c    \
     88        psphotParseCamera.c        \
     89        psphotImageLoop.c          \
     90        psphotMosaicChip.c         \
     91        psphotCleanup.c
     92
     93# generalized forced photometry (including Kron, Petro, and Models) of specified positions given a specified psf
     94psphotFullForce_SOURCES = \
     95        psphotFullForce.c             \
     96        psphotFullForceArguments.c    \
    7997        psphotParseCamera.c        \
    8098        psphotImageLoop.c          \
     
    129147        psphotCleanup.c
    130148
     149# a program that takes a cmf file and makes a cff file (input file for psphotFullForce
     150psmakecff_SOURCES = \
     151        psmakecff.c
     152
    131153# psphotTest_SOURCES = \
    132154#         psphotTest.c
     
    155177        psphotReadoutMinimal.c         \
    156178        psphotForcedReadout.c          \
     179        psphotFullForceReadout.c       \
     180        psphotFullForce.SourceStats.c \
    157181        psphotMakePSFReadout.c         \
    158182        psphotModelBackground.c        \
     
    181205        psphotSourceFits.c             \
    182206        psphotRadiusChecks.c           \
     207        psphotChooseAnalysisOptions.c  \
    183208        psphotOutput.c                 \
    184209        psphotFakeSources.c            \
     
    198223        psphotRadialPlot.c             \
    199224        psphotKronIterate.c            \
     225        psphotKronFlux.c            \
     226        psphotPetroFlux.c            \
     227        psphotGalaxyShape.c            \
    200228        psphotRadialProfileWings.c     \
    201229        psphotDeblendSatstars.c        \
  • trunk/psphot/src/psphot.h

    r36117 r36375  
    1818    PSPHOT_SINGLE,
    1919    PSPHOT_FORCED,
     20    PSPHOT_FULL_FORCE,
    2021    PSPHOT_MAKE_PSF,
    2122    PSPHOT_MODEL_TEST,
     
    8182bool            psphotSourceStatsReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, bool setWindow);
    8283
     84bool            psphotFullForceSourceStats (pmConfig *config, const pmFPAview *view, const char *filerule, bool setWindow);
     85bool            psphotFullForceSourceStatsReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, bool setWindow);
     86
    8387bool            psphotDeblendSatstars (pmConfig *config, const pmFPAview *view, const char *filerule);
    8488bool            psphotDeblendSatstarsReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe);
     
    121125bool            psphotAddOrSubNoiseReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, bool add);
    122126bool            psphotAddOrSubNoise_Threaded (psThreadJob *job);
     127
     128bool            psphotChooseAnalysisOptions (pmConfig *config, const pmFPAview *view, const char *filerule);
     129bool            psphotChooseAnalysisOptionsReadout(pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe);
     130bool            psphotChooseAnalysisOptionsByObject(pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects);
    123131
    124132bool            psphotExtendedSourceAnalysis (pmConfig *config, const pmFPAview *view, const char *filerule);
     
    341349bool psphotForcedReadout(pmConfig *config, const pmFPAview *view, const char *filerule);
    342350
     351pmConfig *psphotFullForceArguments(int argc, char **argv);
     352bool psphotFullForceReadout(pmConfig *config, const pmFPAview *view, const char *filerule);
     353
    343354pmConfig *psphotMinimalArguments(int argc, char **argv);
    344355bool psphotReadoutMinimal(pmConfig *config, const pmFPAview *view, const char *filerule);
     
    414425} psphotStackOptions;
    415426
     427typedef struct {
     428    float fRmajorMin;
     429    float fRmajorMax;
     430    float fRmajorDel;
     431    float fRminorMin;
     432    float fRminorMax;
     433    float fRminorDel;
     434} psphotGalaxyShapeOptions;
     435
    416436/*** psphotStackMatchPSF prototypes ***/
    417437bool psphotStackMatchPSFs (pmConfig *config, const pmFPAview *view);
     
    497517bool psphotKronIterate_Threaded (psThreadJob *job);
    498518
     519bool psphotKronFlux (pmConfig *config, const pmFPAview *view, const char *filerule);
     520bool psphotKronFluxReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char *filerule, pmReadout *readout, psArray *sources);
     521bool psphotKronFlux_Threaded (psThreadJob *job);
     522bool psphotKronFluxSource (pmSource *source, psImageMaskType maskVal);
     523
     524bool psphotPetroFlux (pmConfig *config, const pmFPAview *view, const char *filerule);
     525bool psphotPetroFluxReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char * filerule, pmReadout *readout, psArray *sources);
     526bool psphotPetroFlux_Threaded (psThreadJob *job);
     527bool psphotPetroFluxSource (pmSource *source, psImageMaskType maskVal);
     528
     529bool psphotGalaxyShape (pmConfig *config, const pmFPAview *view, const char *filerule);
     530bool psphotGalaxyShapeReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char * filerule, pmReadout *readout, psArray *sources, pmPSF *psf);
     531bool psphotGalaxyShape_Threaded (psThreadJob *job);
     532bool psphotGalaxyShapeGrid (pmSource *source, pmSourceFitOptions *fitOptions, psphotGalaxyShapeOptions *opt, psImageMaskType maskVal, int psfSize);
     533bool psphotGalaxyShapeSource (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, int psfSize, bool saveResults);
     534psphotGalaxyShapeOptions *psphotGalaxyShapeOptionsAlloc();
     535
    499536bool psphotRadialProfileWings (pmConfig *config, const pmFPAview *view, const char *filerule);
    500537bool psphotRadialProfileWingsReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, pmReadout *readout, psArray *sources);
  • trunk/psphot/src/psphotArguments.c

    r33690 r36375  
    217217    pmConfigFileSetsMD (config->arguments, &argc, argv, "PSPHOT.PSF", "-psf",      "-psflist");
    218218    pmConfigFileSetsMD (config->arguments, &argc, argv, "SRC",        "-src",      "-srclist");
     219    // XXX allow this format? pmConfigFileSetsMD (config->arguments, &argc, argv, "FORCE",      "-force",    "-forcelist");
    219220    pmConfigFileSetsMD (config->arguments, &argc, argv, "EXPNUM",     "-expnum",   "-expnumlist");
    220221
  • trunk/psphot/src/psphotBlendFit.c

    r36096 r36375  
    274274
    275275# if (PS_TRACE_ON)
    276         int TEST_ON = false;
    277276# define TEST_X 653
    278277# define TEST_Y 466
    279         if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) {
     278# define TESTING 1
     279        int TEST_ON = false;
     280        if (TESTING && (fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) {
    280281            fprintf (stderr, "test object\n");
    281282            psTraceSetLevel("psLib.math.psMinimizeLMChi2", 5);
  • trunk/psphot/src/psphotDefineFiles.c

    r34528 r36375  
    150150    }
    151151
     152    if (psMetadataLookupPtr(NULL, config->arguments, "FORCE")) {
     153        if (!pmFPAfileDefineFromArgs (&status, config, "PSPHOT.INPUT.CFF", "FORCE")) {
     154            psError(PSPHOT_ERR_CONFIG, false, "Failed to find/build PSPHOT.INPUT.CFF");
     155            return status;
     156        }
     157    }
     158
    152159    if (psMetadataLookupPtr(NULL, config->arguments, "SRCTEXT")) {
    153160        // XXX cannot use pmFPAfileDefineFromArgs: this is explicitly a FITS-based I/O function
  • trunk/psphot/src/psphotEllipticalContour.c

    r32348 r36375  
    6464        psFree (y);
    6565        psFree (yErr);
     66        source->mode2 |= PM_SOURCE_MODE2_ECONTOUR_FEW_PTS;
    6667        return false;
    6768    }
  • trunk/psphot/src/psphotExtendedSourceAnalysis.c

    r34404 r36375  
    11# include "psphotInternal.h"
    2 
    3 // measure the elliptical radial profile and use this to measure the petrosian parameters for the sources
     2void psphotRadialProfileShowSkips ();
     3
     4// measure the petrosian parameters for the sources
    45
    56// for now, let's store the detections on the readout->analysis for each readout
     
    1516    psAssert (recipe, "missing recipe?");
    1617
    17     // perform full non-linear fits / extended source analysis?
    18     if (!psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANALYSIS")) {
     18    bool doPetrosian = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PETROSIAN");
     19    bool doAnnuli    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANNULI");
     20
     21    // measure petrosians?
     22    if (!doPetrosian && !doAnnuli) {
    1923        psLogMsg ("psphot", PS_LOG_INFO, "skipping extended source measurements\n");
    2024        return true;
     
    3337}
    3438
     39/*** for the moment, this test code : it is not thread safe ***/
     40int    Nall = 0;
     41int  Nskip1 = 0;
     42int  Nskip2 = 0;
     43int  Nskip3 = 0;
     44int  Nskip4 = 0;
     45int  Nskip5 = 0;
     46int  Nskip6 = 0;
     47
     48# define SKIP(VALUE) { VALUE++; continue; }
     49
    3550// aperture-like measurements for extended sources
    3651bool psphotExtendedSourceAnalysisReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe) {
     
    110125
    111126// set this to 0 to run without threading
    112 # if (1)           
     127# if (0)           
    113128            if (!psThreadJobAddPending(job)) {
    114129                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     
    164179    psLogMsg ("psphot", PS_LOG_INFO, "  %d annuli\n", Nannuli);
    165180
     181# if (PS_TRACE_ON)
     182    fprintf (stderr, "ext analysis skipped @ 1  : %d\n", Nskip1);
     183    fprintf (stderr, "ext analysis skipped @ 2  : %d\n", Nskip2);
     184    fprintf (stderr, "ext analysis skipped @ 3  : %d\n", Nskip3);
     185    fprintf (stderr, "ext analysis skipped @ 4  : %d\n", Nskip4);
     186    fprintf (stderr, "ext analysis skipped @ 5  : %d\n", Nskip5);
     187    fprintf (stderr, "ext analysis skipped @ 6  : %d\n", Nskip6);
     188#endif
     189
     190    psphotRadialProfileShowSkips ();
     191
    166192    psphotVisualShowResidualImage (readout, false);
    167193
    168     bool doPetrosian    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PETROSIAN");
    169     if (doPetrosian) {
    170         psphotVisualShowPetrosians (sources);
    171     }
     194    psphotVisualShowPetrosians (sources);
    172195
    173196    return true;
     
    190213    float skynoise          = PS_SCALAR_VALUE(job->args->data[4],F32);
    191214
    192     // S/N limit to perform full non-linear fits
    193     float SN_LIM = psMetadataLookupF32 (&status, recipe, "EXTENDED_SOURCE_SN_LIM");
    194 
    195     // which extended source analyses should we perform?
    196215    bool doPetrosian    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PETROSIAN");
    197     bool doAnnuli       = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANNULI");
    198     bool doPetroStars   = psMetadataLookupBool (&status, recipe, "PETROSIAN_FOR_STARS");
    199216
    200217    // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
     
    207224        pmSource *source = sources->data[i];
    208225
    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;
    213 
    214         // skip PSF-like and non-astronomical objects
    215         if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
    216         if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
    217         if (source->mode & PM_SOURCE_MODE_DEFECT) continue;
    218         if (source->mode & PM_SOURCE_MODE_SATSTAR) continue;
    219 
    220         // skip saturated stars modeled with a radial profile
    221         if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue;
    222 
    223         // optionally allow non-extended objects to get petrosians as well
    224         if (!doPetroStars) {
    225             if (!(source->mode & PM_SOURCE_MODE_EXT_LIMIT)) continue;
    226             if (source->type == PM_SOURCE_TYPE_STAR) continue;
    227         }
    228 
    229         // limit selection to some SN limit
    230         // assert (source->peak); // how can a source not have a peak?
    231         // limit selection to some SN limit
    232         bool skipSource = false;
    233         if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
    234             skipSource = (source->moments->KronFlux < SN_LIM * source->moments->KronFluxErr);
    235         } else {
    236             skipSource = (sqrt(source->peak->detValue) < SN_LIM);
    237         }
    238         if (skipSource) continue;
    239 
    240         // limit selection by analysis region (this automatically apply
    241         if (source->peak->x < region->x0) continue;
    242         if (source->peak->y < region->y0) continue;
    243         if (source->peak->x > region->x1) continue;
    244         if (source->peak->y > region->y1) continue;
    245 
    246     keepSource:
     226        Nall ++;
     227
     228        // rules for measuring petrosian parameters for specific objects are set in
     229        // psphotChooseAnalysisOptions.c
     230        if (!(source->tmpFlags & PM_SOURCE_TMPF_PETRO)) SKIP (Nskip1);
     231
     232        // limit selection by analysis region (XXX move this into psphotChooseAnalysisOption?)
     233        if (source->peak->x < region->x0) SKIP (Nskip2);
     234        if (source->peak->y < region->y0) SKIP (Nskip3);
     235        if (source->peak->x > region->x1) SKIP (Nskip4);
     236        if (source->peak->y > region->y1) SKIP (Nskip5);
    247237
    248238        // replace object in image
     
    259249        pmSourceRedefinePixels (source, readout, source->peak->xf, source->peak->yf, 1.5*radius);
    260250
    261         // if we request any of these measurements, we require the radial profile
    262         if (doPetrosian || doAnnuli) {
    263             if (!psphotRadialProfile (source, recipe, skynoise, maskVal)) {
    264                 // all measurements below require the radial profile; skip them all
    265                 // re-subtract the object, leave local sky
    266                 psTrace ("psphot", 5, "failed to extract radial profile for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
    267                 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    268                 continue;
    269             }
    270             Nannuli ++;
    271             source->mode |= PM_SOURCE_MODE_RADIAL_FLUX;
    272         }
     251        // measure the radial profile
     252        if (!psphotRadialProfile (source, recipe, skynoise, maskVal)) {
     253          // re-subtract the object, leave local sky
     254          psTrace ("psphot", 5, "failed to extract radial profile for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
     255          pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
     256          SKIP (Nskip6);
     257        }
     258
     259        Nannuli ++;
     260        source->mode |= PM_SOURCE_MODE_RADIAL_FLUX;
    273261
    274262        // Petrosian Mags
    275263        if (doPetrosian) {
    276             if (!psphotPetrosian (source, recipe, skynoise, maskVal)) {
    277                 psTrace ("psphot", 5, "FAILED petrosian flux & radius for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
    278             } else {
    279                 psTrace ("psphot", 5, "measured petrosian flux & radius for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
    280                 Npetro ++;
    281                 source->mode |= PM_SOURCE_MODE_EXTENDED_STATS;
    282             }
     264          if (!psphotPetrosian (source, recipe, skynoise, maskVal)) {
     265            psTrace ("psphot", 5, "FAILED petrosian flux & radius for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
     266          } else {
     267            psTrace ("psphot", 5, "measured petrosian flux & radius for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
     268            Npetro ++;
     269            source->mode |= PM_SOURCE_MODE_EXTENDED_STATS;
     270          }
    283271        }
    284272
  • trunk/psphot/src/psphotExtendedSourceFits.c

    r36108 r36375  
    6565    psphotVisualShowImage(readout);
    6666
    67     // psphotSaveImage (NULL, readout->image, "test.01.fits");
    68 
    6967    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
    7068    psAssert (detections, "missing detections?");
     
    111109    if (!status || !isfinite(fitMaxTol) || fitMaxTol <= 0) {
    112110        fitMaxTol = 1.0;
     111    }
     112
     113    float fitNsigmaConv = psMetadataLookupF32 (&status, recipe, "EXT_FIT_NSIGMA_CONV"); // number of sigma for the convolution
     114    if (!status || !isfinite(fitNsigmaConv) || fitNsigmaConv <= 0) {
     115        fitNsigmaConv = 5.0;
    113116    }
    114117
     
    137140    fitOptions->minTol         = fitMinTol;
    138141    fitOptions->maxTol         = fitMaxTol;
     142    fitOptions->nsigma         = fitNsigmaConv;
    139143
    140144    fitOptions->gainFactorMode   = gainFactorMode;
    141145    fitOptions->chisqConvergence = chisqConvergence;
    142146    fitOptions->isInteractive    = isInteractive;
     147
     148    // use poissonian errors or local-sky errors
     149    fitOptions->poissonErrors = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_FITS_POISSON");
     150    if (!status) fitOptions->poissonErrors = true;
    143151
    144152    // maskVal is used to test for rejected pixels, and must include markVal
     
    285293            psArrayAdd(job->args, 1, cells->data[j]); // sources
    286294            psArrayAdd(job->args, 1, models);
     295
    287296            // Allocate a metadata iterator here because psMetadataIteratorAlloc/Free are not thread safe
    288297            psMetadataIterator *iter = psMetadataIteratorAlloc (models, PS_LIST_HEAD, NULL);
     
    386395    psphotSersicModelClassCleanup();
    387396
    388     // psphotSaveImage (NULL, readout->image, "test.02.fits");
    389 
    390397    psphotVisualShowResidualImage (readout, false);
    391398
     
    428435    // psTraceSetLevel ("psLib.math.psMinimizeLMChi2_Alt", 5);
    429436
     437    pmModelStatus badModel = PM_MODEL_STATUS_NONE;
     438    badModel |= PM_MODEL_STATUS_BADARGS;
     439    badModel |= PM_MODEL_STATUS_OFFIMAGE;
     440    badModel |= PM_MODEL_STATUS_NAN_CHISQ;
     441    badModel |= PM_MODEL_SERSIC_PCM_FAIL_GUESS;
     442    badModel |= PM_MODEL_SERSIC_PCM_FAIL_GRID;
     443    badModel |= PM_MODEL_PCM_FAIL_GUESS;
     444
    430445    // choose the sources of interest
    431446    for (int i = 0; i < sources->n; i++) {
     
    433448        pmSource *source = sources->data[i];
    434449
    435         // skip PSF-like and non-astronomical objects
    436         if (!(source->mode & PM_SOURCE_MODE_EXT_LIMIT)) continue;
    437         if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
    438         if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
    439 
    440         // skip saturated stars modeled with a radial profile
    441         if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue;
    442 
    443         // XXX this should use peak?
     450        // rules for measuring petrosian parameters for specific objects are set in
     451        // psphotChooseAnalysisOptions.c
     452        if (!(source->tmpFlags & PM_SOURCE_TMPF_EXT_FIT)) continue;
     453
     454        // limit selection by analysis region (XXX move this into psphotChooseAnalysisOption?)
    444455        if (source->peak->x < region->x0) continue;
    445456        if (source->peak->y < region->y0) continue;
    446457        if (source->peak->x > region->x1) continue;
    447458        if (source->peak->y > region->y1) continue;
    448 
    449 
    450         // XXX for a test, just do the obvious trail
    451         // XXX if (source->peak->xf < 1100) continue;
    452         // XXX if (source->peak->xf > 1400) continue;
    453         // XXX if (source->peak->yf >  245) continue;
    454459
    455460        // replace object in image
     
    462467        psphotSetRadiusMomentsExact(&fitRadius, &windowRadius, readout, source, markVal); // NOTE : 6 allocs
    463468
    464         // XXX WATCH OUT HERE!!
    465         // fitRadius = 30;
    466 
    467469        // UPDATE : we have changed the moments calculation.  There is now an iteration within
    468470        // psphotKronMasked to determine moments appropriate for a larger object.  The values
     
    475477        }
    476478
     479# ifdef TEST_OBJECT
    477480        bool testObject = false;
    478         // testObject |= ((fabs(source->peak->xf -  179) < 5) && (fabs(source->peak->yf - 1138) < 5));
    479         // testObject |= ((fabs(source->peak->xf - 5047) < 5) && (fabs(source->peak->yf -  151) < 5));
    480         // testObject |= ((fabs(source->peak->xf - 3929) < 5) && (fabs(source->peak->yf - 4109) < 5));
    481         // testObject |= ((fabs(source->peak->xf -  915) < 5) && (fabs(source->peak->yf - 5998) < 5));
    482         // testObject |= ((fabs(source->peak->xf - 5406) < 5) && (fabs(source->peak->yf -  326) < 5));
     481        testObject |= ((fabs(source->peak->xf -  179) < 5) && (fabs(source->peak->yf - 1138) < 5));
    483482        if (testObject) {
    484483            fprintf (stderr, "test object @ %f, %f\n", source->peak->xf, source->peak->yf);
     
    486485            psTraceSetLevel ("psphot.psphotExtendedSourceFits_Threaded", 5);
    487486        }
     487# endif
    488488
    489489        // loop here over the models chosen for each source (exclude by S/N)
     
    501501          assert (status);
    502502
    503           // limit selection to some SN limit
    504           bool skipSource = false;
    505           if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
    506               skipSource = (source->moments->KronFlux < FIT_SN_LIM * source->moments->KronFluxErr);
    507           } else {
    508               skipSource = (sqrt(source->peak->detValue) < FIT_SN_LIM);
    509           }
    510           if (skipSource) {
     503          // limit selection to some SN limit for specific models (this value only applies if > EXTENDED_SOURCE_SN_LIM)
     504          if (isfinite(FIT_SN_LIM)) {
     505            if (source->moments->KronFlux < FIT_SN_LIM * source->moments->KronFluxErr) {
    511506              Nfaint ++;
    512507              continue;
     508            }
    513509          }
     510
     511          source->mode2 |= PM_SOURCE_MODE2_EXT_FITS_RUN;
    514512
    515513          // check on the model type
     
    529527                  psTrace ("psphot", 5, "failed to fit psf-conv model for object at %f, %f", source->moments->Mx, source->moments->My);
    530528                  Nfail ++;
     529                  source->mode2 |= PM_SOURCE_MODE2_EXT_FITS_FAIL;
    531530                  continue;
    532531              }
     
    534533                       source->moments->Mx, source->moments->My, pmModelClassGetName (modelFit->type), modelFit->chisq, modelFit->nPix, modelFit->nIter);
    535534              Nconvolve ++;
    536               if (!(modelFit->flags & (PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE))) {
     535              if (!(modelFit->flags & badModel)) {
    537536                  NconvolvePass ++;
    538537                  source->mode |= PM_SOURCE_MODE_EXTENDED_FIT;
     
    548547                      Nfail ++;
    549548                      doneFits = true;
     549                      source->mode2 |= PM_SOURCE_MODE2_EXT_FITS_FAIL;
    550550                      continue;
    551551                  }
    552552                  psTrace ("psphot", 4, "fit plain model for %f, %f : %s chisq = %f (npix: %d, niter: %d)\n", source->moments->Mx, source->moments->My, pmModelClassGetName (modelFit->type), modelFit->chisq, modelFit->nPix, modelFit->nIter);
    553553                  Nplain ++;
    554                   if (!(modelFit->flags & (PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE))) {
     554                  if (!(modelFit->flags & badModel)) {
    555555                      NplainPass ++;
    556556                      source->mode |= PM_SOURCE_MODE_EXTENDED_FIT;
     
    576576                          fprintf (stderr, "update window : %f %f : %f -> %f\n", source->peak->xf, source->peak->yf, fitRadius, 2*fitRadius);
    577577                          psphotSetWindowTrail (&fitRadius, &windowRadius, readout, source, markVal, fitRadius*2.0);
     578                          source->mode2 |= PM_SOURCE_MODE2_EXT_FITS_RETRY;
    578579                      }
    579580                  }
    580581              }
    581582          }
    582           // XXX really need to do this in a cleaner way:
    583           if (!modelFit) continue;
     583          psAssert (modelFit, "modelFit not set?");
    584584
    585585          // test for fit quality / result
     
    590590        }
    591591
     592        // we are allowed to fit both stars and non-stars here -- if we have fitted
     593        // something which we think is a star, we should use that model to subtract the
     594        // object from the image.
     595        if (source->type == PM_SOURCE_TYPE_STAR) {
     596          // ensure the modelPSF is cached
     597          pmSourceCacheModel (source, maskVal);
     598          pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
     599          continue;
     600        }
     601
    592602        // evaluate the relative quality of the models, choose one
     603        // the PSF model might be the best fit : allow it to succeed
    593604        float minChisq = NAN;
    594605        int minModel = -1;
     
    596607            pmModel *model = source->modelFits->data[i];
    597608
     609            // skip the really bad fits
    598610            if (!(model->flags & PM_MODEL_STATUS_FITTED)) continue;
    599 
    600             if (model->flags & (PM_MODEL_STATUS_BADARGS)) continue;
     611            if (model->flags & badModel) continue;
     612
    601613            // if (model->flags & (PM_MODEL_STATUS_NONCONVERGE)) continue;
    602             if (model->flags & (PM_MODEL_STATUS_OFFIMAGE)) continue;
    603614
    604615            if ((minModel < 0) || (model->chisq < minChisq)) {
     
    618629          pmSourceCacheModel (source, maskVal);
    619630
     631# if (PS_TRACE_ON)
    620632          pmModel *model = source->modelFits->data[0];
    621633          int flags = 0xffffffff;
     
    623635            flags = model->flags;
    624636          }
    625 
    626637          fprintf (stderr, "failed to fit extended source model to object %d @ %f, %f (%x)\n", source->id, source->moments->Mx, source->moments->My, flags);
     638#endif
    627639          pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    628640
     641          source->mode2 |= PM_SOURCE_MODE2_EXT_FITS_NONE;
    629642          continue;
    630643        }
     
    643656        if (source->modelEXT->isPCM) {
    644657            // fprintf (stderr, "subtract PCM extended source model for object %d @ %f, %f\n", source->id, source->moments->Mx, source->moments->My);
    645             pmPCMCacheModel (source, maskVal, psfSize);
     658            pmPCMCacheModel (source, maskVal, psfSize, fitOptions->nsigma);
    646659        } else {
    647660            // fprintf (stderr, "subtract non-PCM extended source model for object %d @ %f, %f\n", source->id, source->moments->Mx, source->moments->My);
    648661            pmSourceCacheModel (source, maskVal);
    649662        }
     663        source->modelEXT->flags |= PM_MODEL_BEST_FIT;
    650664
    651665        // subtract the best fit from the object, leave local sky
     
    655669        psTrace ("psphot", 5, "extended source model for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
    656670
     671# ifdef TEST_OBJECT
    657672        if (testObject) {
    658673            psTraceSetLevel ("psModules.objects.pmPCM_MinimizeChisq", 0);
    659674            psTraceSetLevel ("psphot.psphotExtendedSourceFits_Threaded", 0);
    660675        }
     676# endif
    661677    }
    662678
  • trunk/psphot/src/psphotImageLoop.c

    r34258 r36375  
    132132                    }
    133133                    break;
     134                  case PSPHOT_FULL_FORCE:
     135                    if (!psphotFullForceReadout (config, view, "PSPHOT.INPUT")) {
     136                        psError(psErrorCodeLast(), false, "failure in psphotReadout for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout);
     137                        psFree (view);
     138                        return false;
     139                    }
     140                    break;
    134141                  case PSPHOT_MAKE_PSF:
    135142                    if (!psphotMakePSFReadout (config, view, "PSPHOT.INPUT")) {
  • trunk/psphot/src/psphotKronIterate.c

    r35769 r36375  
    166166    }
    167167
     168# if (PS_TRACE_ON)
    168169    fprintf (stderr, "--- starting KRON ---\n");
     170#endif
    169171
    170172    // We measure the Kron Radius on a smoothed copy of the readout image
  • trunk/psphot/src/psphotLoadPSF.c

    r29936 r36375  
    11# include "psphotInternal.h"
     2
     3// PSPHOT.PSF.LOAD vs input file -- see note at top
     4bool psphotLoadPSF (pmConfig *config, const pmFPAview *view, const char *filerule) {
     5
     6    int num = psphotFileruleCount(config, filerule);
     7
     8    // loop over the available readouts
     9    for (int i = 0; i < num; i++) {
     10
     11        // Generate the mask and weight images, including the user-defined analysis region of interest
     12        if (!psphotLoadPSFReadout (config, view, filerule, "PSPHOT.PSF.LOAD", i)) {
     13            psError (PSPHOT_ERR_CONFIG, false, "failed to load PSF model for PSPHOT.PSF.LOAD entry %d", i);
     14            return false;
     15        }
     16    }
     17    return true;
     18}
    219
    320// NOTE : pmPSF_IO.c functions must load the psf model onto the chip->analysis metadata because
     
    5875    return true;
    5976}
    60 
    61 // PSPHOT.PSF.LOAD vs input file -- see note at top
    62 bool psphotLoadPSF (pmConfig *config, const pmFPAview *view, const char *filerule) {
    63 
    64     int num = psphotFileruleCount(config, filerule);
    65 
    66     // loop over the available readouts
    67     for (int i = 0; i < num; i++) {
    68 
    69         // Generate the mask and weight images, including the user-defined analysis region of interest
    70         if (!psphotLoadPSFReadout (config, view, filerule, "PSPHOT.PSF.LOAD", i)) {
    71             psError (PSPHOT_ERR_CONFIG, false, "failed to load PSF model for PSPHOT.PSF.LOAD entry %d", i);
    72             return false;
    73         }
    74     }
    75     return true;
    76 }
  • trunk/psphot/src/psphotMergeSources.c

    r36117 r36375  
    3939    psAssert (newSources, "missing sources?");
    4040
    41     // XXX TEST:
    42     if (detections->allSources) {
    43         psphotMaskCosmicRayFootprintCheck(detections->allSources);
    44     }
    45     if (detections->newSources) {
    46         psphotMaskCosmicRayFootprintCheck(detections->newSources);
    47     }
    48 
    4941    if (!detections->allSources) {
    5042        detections->allSources = psArrayAllocEmpty(newSources->n);
     
    6557// Merge the externally supplied sources with the existing sources.  Mark them as having mode
    6658// PM_SOURCE_MODE_EXTERNAL.
     59
     60// XXX this function needs to be updated slightly for psphotFullForce:
     61// * load the additional parameters to guide the new concepts
    6762
    6863// XXX This function needs to be updated to loop over set of input files.  At the moment, we
     
    7368    bool status;
    7469    pmDetections *extCMF = NULL;
     70    pmDetections *extCFF = NULL;
    7571    psArray *extSourcesTXT = NULL;
    7672    int index = 0;
     
    10298    {
    10399        pmReadout *readoutCMF = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT.CMF");
    104         if (!readoutCMF) goto loadTXT;
     100        if (!readoutCMF) goto loadCFF;
    105101
    106102        extCMF = psMetadataLookupPtr (NULL, readoutCMF->analysis, "PSPHOT.DETECTIONS");
     
    125121    }
    126122
     123loadCFF:
     124    // load data from input CFF file:
     125    {
     126        pmReadout *readoutCFF = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT.CFF");
     127        if (!readoutCFF) goto loadTXT;
     128
     129        extCFF = psMetadataLookupPtr (NULL, readoutCFF->analysis, "PSPHOT.DETECTIONS");
     130        if (extCFF) {
     131            psF32 exptime = psMetadataLookupF32(NULL, readout->parent->concepts, "CELL.EXPOSURE");
     132            for (int i = 0; i < extCFF->allSources->n; i++) {
     133                pmSource *source = extCFF->allSources->data[i];
     134
     135                // setting this bit not only tracks the inputs, it makes pmSourceMoments
     136                // keep the Mx,My values for the centroid. 
     137                source->mode |= PM_SOURCE_MODE_EXTERNAL;
     138
     139                // source->peak->detValue,rawFlux,smoothFlux all set to input flux value which is scaled
     140                // to 1 second exposure time. Scale to this image's exposure.
     141                source->peak->rawFlux    *= exptime;
     142                source->peak->smoothFlux *= exptime;
     143                source->peak->detValue   *= exptime;
     144                // source->peak->xf,yf, moments->Mx,My all set to input position
     145
     146                // drop the loaded source modelPSF
     147                psFree (source->modelPSF);
     148                source->modelPSF = NULL;
     149                source->imageID = index;
     150
     151                psArrayAdd (detections->newSources, 100, source);
     152            }
     153        }
     154    }
     155
    127156loadTXT:
    128157
     
    157186    psFree (detections);
    158187
    159     if (!extCMF && !extSourcesTXT) {
     188    if (!(extCMF || extCFF || extSourcesTXT)) {
    160189        psLogMsg ("psphot", 3, "no external sources for this readout");
    161190        return true;
     
    163192
    164193    int nCMF = extCMF        ? extCMF->allSources->n        : 0;
    165     int nTXT = extSourcesTXT ? extSourcesTXT->n : 0;
    166 
    167     psLogMsg ("psphot", 3, "%d external sources (%d cmf, %d text) merged to yield %ld total sources",
    168               nCMF + nTXT, nCMF, nTXT, sources->n);
     194    int nCFF = extCFF        ? extCFF->allSources->n        : 0;
     195    int nTXT = extSourcesTXT ? extSourcesTXT->n             : 0;
     196
     197    psLogMsg ("psphot", 3, "%d external sources (%d cmf, %d cff, %d text) merged to yield %ld total sources",
     198              nCMF + nCFF + nTXT, nCMF, nCFF, nTXT, sources->n);
    169199    return true;
    170200}
  • trunk/psphot/src/psphotModelTestReadout.c

    r35769 r36375  
    125125
    126126            // get the source moments
    127             status = pmSourceMoments (source, radius, 0.25*radius, 0.0, MIN_KRON_RADIUS, maskVal);
     127          status = pmSourceMoments (source, radius, 0.25*radius, 0.0, MIN_KRON_RADIUS, maskVal);
    128128            if (!status) psAbort("psSourceMoments error");
    129129
  • trunk/psphot/src/psphotPetrosianRadialBins.c

    r36115 r36375  
    186186        psFree(values);
    187187        psFree(stats);
     188        source->mode2 |= PM_SOURCE_MODE2_RADBIN_NAN_CENTER;
    188189        return true;
    189190    }
  • trunk/psphot/src/psphotPetrosianStats.c

    r34086 r36375  
    66// generate the Petrosian radius and flux from the mean surface brightness (r_i)
    77
     8float InterpolateValuesQuadratic (float *Xin, float *Yin, float X);
    89float InterpolateValues     (float X0, float Y0, float X1, float Y1, float X);
    910float InterpolateValuesErrX (float X0, float Y0, float X1, float Y1, float X, float dX0, float dX1);
     
    2021    if (!profile->binSB) {
    2122        psLogMsg ("psphot", PS_LOG_DETAIL, "no petrosian profile, skipping source %f, %f", source->peak->xf, source->peak->yf);
     23        source->mode2 |= PM_SOURCE_MODE2_PETRO_NO_PROFILE;
    2224        return true;
    2325    }
     
    5355    float dFsum2 = 0.0;
    5456
    55     float nSigma = 3.0;
     57    float nSigma = 2.0;
    5658    int lowestSignificantRadius = 0;
    5759    float lowestSignificantRatio = 1.0;
     
    117119                petRadius    = InterpolateValues     (1.0, 0.0, petRatio->data.F32[nOut], refRadius->data.F32[nOut], PETROSIAN_RATIO);
    118120                petRadiusErr = InterpolateValuesErrX (1.0, 0.0, petRatio->data.F32[nOut], refRadius->data.F32[nOut], PETROSIAN_RATIO, 0.0, petRatioErr->data.F32[nOut]);
    119             } else {
    120                 petRadius    = InterpolateValues     (petRatio->data.F32[nOut-1], refRadius->data.F32[nOut-1], petRatio->data.F32[nOut], refRadius->data.F32[nOut], PETROSIAN_RATIO);
    121                 petRadiusErr = InterpolateValuesErrX (petRatio->data.F32[nOut-1], refRadius->data.F32[nOut-1], petRatio->data.F32[nOut], refRadius->data.F32[nOut], PETROSIAN_RATIO, petRatioErr->data.F32[nOut-1], petRatioErr->data.F32[nOut]);
     121                source->mode2 |= PM_SOURCE_MODE2_PETRO_RATIO_ZEROBIN;
     122            } else {
     123              // petRadius    = InterpolateValues     (petRatio->data.F32[nOut-1], refRadius->data.F32[nOut-1], petRatio->data.F32[nOut], refRadius->data.F32[nOut], PETROSIAN_RATIO);
     124              if (nOut > 1) {
     125                petRadius    = InterpolateValuesQuadratic (&petRatio->data.F32[nOut-2], &refRadius->data.F32[nOut-2],   PETROSIAN_RATIO);
     126              } else {
     127                petRadius    = InterpolateValuesQuadratic (&petRatio->data.F32[nOut-3], &refRadius->data.F32[nOut-3], PETROSIAN_RATIO);
     128              }
     129# if (PS_TRACE_ON)
     130              float petRadiusLinear = InterpolateValues     (petRatio->data.F32[nOut-1], refRadius->data.F32[nOut-1], petRatio->data.F32[nOut], refRadius->data.F32[nOut], PETROSIAN_RATIO);
     131              if (fabs(petRadius - petRadiusLinear) > fabs(refRadius->data.F32[nOut] - refRadius->data.F32[nOut-1])) {
     132                fprintf (stderr, "big difference : %f vs %f\n", petRadius, petRadiusLinear);
     133              }
     134#endif
     135              petRadiusErr = InterpolateValuesErrX (petRatio->data.F32[nOut-1], refRadius->data.F32[nOut-1], petRatio->data.F32[nOut], refRadius->data.F32[nOut], PETROSIAN_RATIO, petRatioErr->data.F32[nOut-1], petRatioErr->data.F32[nOut]);
    122136            }
    123137            above = false;
     
    148162            fprintf (stderr, "nan pet radius\n");
    149163        }
     164        source->mode2 |= PM_SOURCE_MODE2_PETRO_INSIG_RATIO;
    150165    }
    151166
     
    180195    bool found50 = false;
    181196    bool found90 = false;
     197
    182198    // XXX use bisection to do this faster:
    183199    for (int i = 0; !(found50 && found90) && i < refRadius->n; i++) {
     
    235251}
    236252
     253// Lagrange's form of the interpolating polynomial...
     254float InterpolateValuesQuadratic (float *Xin, float *Yin, float X) {
     255
     256  float dx01 = Xin[0] - Xin[1];
     257  float dx02 = Xin[0] - Xin[2];
     258  float dx12 = Xin[1] - Xin[2];
     259
     260  float dx0  = X - Xin[0];
     261  float dx1  = X - Xin[1];
     262  float dx2  = X - Xin[2];
     263
     264  float y0 = Yin[0]*dx1*dx2/(dx01*dx02);
     265  float y1 = Yin[1]*dx0*dx2/(dx01*dx12); // need - sign
     266  float y2 = Yin[2]*dx0*dx1/(dx02*dx12);
     267
     268  float Y = y0 - y1 + y2;
     269  return Y;
     270}
     271
    237272float InterpolateValues (float X0, float Y0, float X1, float Y1, float X) {
    238273    float dydx = (Y1 - Y0) / (X1 - X0);
  • trunk/psphot/src/psphotRadialBins.c

    r34226 r36375  
    4444    psVector *radMin = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.LOWER");
    4545    psVector *radMax = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER");
    46     if (!radMin || !radMin->n) {
    47         psError (PSPHOT_ERR_CONFIG, true, "error in definition of annular bins (radMin missing or empty)");
    48         return false;
    49     }
    50     if (!radMax || !radMax->n) {
    51         psError (PSPHOT_ERR_CONFIG, true, "error in definition of annular bins (radMax missing or empty)");
    52         return false;
    53     }
     46    psAssert (radMin, "RADIAL.ANNULAR.BINS.LOWER is missing from recipe");
     47    psAssert (radMin->n, "RADIAL.ANNULAR.BINS.LOWER is empty in recipe");
     48    psAssert (radMax, "RADIAL.ANNULAR.BINS.UPPER is missing from recipe");
     49    psAssert (radMax->n, "RADIAL.ANNULAR.BINS.UPPER is empty in recipe");
    5450
    5551    psVector *binSB      = psVectorAllocEmpty(radMin->n, PS_TYPE_F32); // surface brightness of radial bin
     
    161157        psFree(values);
    162158        psFree(stats);
     159        source->mode2 |= PM_SOURCE_MODE2_RADBIN_NAN_CENTER;
    163160        return true;
    164161    }
  • trunk/psphot/src/psphotRadialProfile.c

    r32348 r36375  
    11# include "psphotInternal.h"
     2
     3static int Nskip1 = 0;
     4static int Nskip2 = 0;
     5static int Nskip3 = 0;
     6static int Nskip4 = 0;
     7static int Nskip5 = 0;
     8
     9# define SKIP(VALUE) { VALUE++; return false; }
    210
    311bool psphotRadialProfile (pmSource *source, psMetadata *recipe, float skynoise, psImageMaskType maskVal) {
     
    2331    if (!psphotRadialProfilesByAngles (source, Nsec, Rmax)) {
    2432        psError (PS_ERR_UNKNOWN, false, "failed to measure radial profile for petrosian");
    25         return false;
     33        SKIP (Nskip1);
    2634    }
    2735    // allocate: extpars->radFlux->radii,fluxes,theta
     
    3240    if (!psphotRadiiFromProfiles (source, fluxMin, fluxMax)) {
    3341        psError (PS_ERR_UNKNOWN, false, "failed to measure isophotal radii from profiles");
    34         return false;
     42        SKIP (Nskip2);
    3543    }
    3644    // allocate : extpars->radFlux->isophotalRadii (use profile->radii,fluxes)
     
    4048    if (!psphotEllipticalContour (source)) {
    4149        // psLogMsg ("psphot", 3, "failed to measure elliptical contour");
    42         return false;
     50        SKIP (Nskip3);
    4351    }
    4452    // use extpars->radFlux->isophotalRadii,theta (result in extpars->axes)
     
    4856    if (!psphotEllipticalProfile (source, RAW_RADIUS)) {
    4957        psError (PS_ERR_UNKNOWN, false, "failed to generate elliptical profile");
    50         return false;
     58        SKIP (Nskip4);
    5159    }
    5260    // allocate extpars->ellipticalFlux->radiusElliptical,fluxElliptical (use axes to scale raw pixels)
     
    5563    if (!psphotRadialBins (recipe, source, Rmax, skynoise)) {
    5664        psError (PS_ERR_UNKNOWN, false, "failed to generate radial bins");
    57         return false;
     65        SKIP (Nskip5);
    5866    }
    5967    // allocate extpars->radProfile->binSB, binSBstdv, binSum, binFill, radialBins, area (small lengths)
     
    6270    return true;
    6371}
     72
     73void psphotRadialProfileShowSkips () {
     74# if (PS_TRACE_ON)
     75  fprintf (stderr, "radial profile skipped @ 1  : %d\n", Nskip1);
     76  fprintf (stderr, "radial profile skipped @ 2  : %d\n", Nskip2);
     77  fprintf (stderr, "radial profile skipped @ 3  : %d\n", Nskip3);
     78  fprintf (stderr, "radial profile skipped @ 4  : %d\n", Nskip4);
     79  fprintf (stderr, "radial profile skipped @ 5  : %d\n", Nskip5);
     80#endif
     81}
  • trunk/psphot/src/psphotReadout.c

    r34418 r36375  
    316316    psphotSourceSize (config, view, filerule, false); // pass 2 (detections->allSources)
    317317
     318    // XXX currently we are doing both the analysis of the size and the assessment of "fit ext"
     319    // in source size.  this overloads the bit MODE_EXT_LIMIT to mean "fit ext" not just
     320    // "bigger than a PSF"
     321
     322    // decide which source(s) are to be fitted with the extended source analysis code.
     323    psphotChooseAnalysisOptions (config, view, filerule);
     324
    318325    psphotExtendedSourceAnalysis (config, view, filerule); // pass 1 (detections->allSources)
    319326    psphotExtendedSourceFits (config, view, filerule); // pass 1 (detections->allSources)
  • trunk/psphot/src/psphotRoughClass.c

    r32348 r36375  
    8787    if (NX > NY) {
    8888        NXuse = ScaleForClump;
    89         NYuse = (int) (ScaleForClump * (NY / NX) + 0.5);
     89        NYuse = (int) (ScaleForClump * (NX / NY) + 0.5);
    9090    } else {
    9191        NYuse = ScaleForClump;
  • trunk/psphot/src/psphotSetThreads.c

    r35769 r36375  
    4747    psFree(task);
    4848
     49    task = psThreadTaskAlloc("PSPHOT_KRON_FLUX", 4);
     50    task->function = &psphotKronFlux_Threaded;
     51    psThreadTaskAdd(task);
     52    psFree(task);
     53
     54    task = psThreadTaskAlloc("PSPHOT_PETRO_FLUX", 4);
     55    task->function = &psphotPetroFlux_Threaded;
     56    psThreadTaskAdd(task);
     57    psFree(task);
     58
     59    task = psThreadTaskAlloc("PSPHOT_GALAXY_SHAPES", 7);
     60    task->function = &psphotGalaxyShape_Threaded;
     61    psThreadTaskAdd(task);
     62    psFree(task);
     63
    4964    task = psThreadTaskAlloc("PSPHOT_BLEND_FIT", 10);
    5065    task->function = &psphotBlendFit_Threaded;
  • trunk/psphot/src/psphotSourceFits.c

    r36107 r36375  
    1919static int NfitIterPCM = 0;
    2020static int NfitPixPCM = 0;
     21
     22bool psphotPCMfitCheckSize (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, float psfSize);
     23bool psphotPCMfitRetry (pmPCMdata *pcm, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, float psfSize);
    2124
    2225bool psphotFitInit (int nThreads) {
     
    579582    maskVal |= markVal;
    580583
    581     // allocate the model
     584    // allocate the model (this can only fail on a config error)
    582585    pmModel *model = pmModelAlloc(modelType);
    583     if (!model) {
    584         return NULL;
    585     }
    586 
    587     float t1, t2, t4, t5;
    588     t1 = t2 = t4 = t5 = 0.0;
     586    psAssert (model, "invalid extended model name");
     587
     588    float t1, t2, t3, t4, t5;
     589    t1 = t2 = t3 = t4 = t5 = 0.0;
    589590    if (TIMING) { psTimerStart ("psphotFitPCM"); }
    590591
     
    619620        if (!psphotSersicModelGuessPCM (pcm, source, maskVal, psfSize)) {
    620621            psFree (pcm);
    621             model->flags |= PM_MODEL_STATUS_BADARGS;
     622            model->flags |= PM_MODEL_SERSIC_PCM_FAIL_GUESS;
    622623            return model;
    623624        }
     
    628629        if (!psphotFitSersicShapeAndIndexGridAuto (pcm, readout, source, &options, maskVal, markVal, psfSize)) {
    629630            psFree (pcm);
    630             model->flags |= PM_MODEL_STATUS_BADARGS;
     631            model->flags |= PM_MODEL_SERSIC_PCM_FAIL_GRID;
    631632            psError(PS_ERR_UNKNOWN, true, "Failed to find a index & shape");
    632633            psErrorClear (); // clear the polynomial error
     
    637638        if (!pmSourceModelGuessPCM (pcm, source, maskVal, markVal)) {
    638639            psFree (pcm);
    639             model->flags |= PM_MODEL_STATUS_BADARGS;
     640            model->flags |= PM_MODEL_PCM_FAIL_GUESS;
    640641            return model;
    641642        }
    642643    }
    643644
    644     if (TIMING) { t4 = psTimerMark ("psphotFitPCM"); }
     645    if (TIMING) { t3 = psTimerMark ("psphotFitPCM"); }
    645646
    646647    // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 5);
     
    648649    NfitIterPCM += pcm->modelConv->nIter;
    649650    NfitPixPCM += pcm->modelConv->nDOF;
     651    if (TIMING) { t4 = psTimerMark ("psphotFitPCM"); }
     652
     653    // XXX we might make this more efficient by setting NITER to be fairly small.  if we hit the iteration
     654    // limit, then we could do a small grid search on the size and try again from the best fit
     655
     656    if (options.isInteractive) psphotPCMfitCheckSize (pcm, source, maskVal, psfSize);
     657    // if (pcm->modelConv->nIter == fitOptions->nIter) {
     658    //  psphotPCMfitRetry (pcm, source, &options, maskVal, markVal, psfSize);
     659    // }
    650660    if (TIMING) { t5 = psTimerMark ("psphotFitPCM"); }
    651661
    652662    if (TIMING) {
    653663        int nPixBig = source->pixels->numCols * source->pixels->numRows;
    654         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);
     664        fprintf (stderr, "psphotFitPCM : nIter: %2d, radius: %6.1f, npix: %5d of %5d, t1: %6.4f, t2: %6.4f, t3: %6.4f, t4: %6.4f, t5: %6.4f\n", model->nIter, model->fitRadius, model->nPix, nPixBig, t1, t2, t3, t4, t5);
    655665    }
    656666    if (EXTRA_VERBOSE && !TIMING) {
     
    778788}
    779789
    780 // float indexGuessInv[] = {0.5, 0.33, 0.25, 0.167, 0.125, 0.083};
    781 float indexGuessInv[] = {0.5, 0.4, 0.3, 0.25, 0.20, 0.15, 0.125};
    782 # define N_INDEX_GUESS_INV 7
    783 
    784 // float reffGuess[] = {3.0, 10.0, 20.0, 30.0, 40.0};
    785 float reffGuess[] = {0.5, 0.75, 1.0, 1.4, 2.0};
     790// 0.5 / n for (1.0, 1.25, 1.66, 2.0, 3.33, 4.0)
     791// float indexGuessInv[] = {0.5, 0.4, 0.3, 0.25, 0.20, 0.15, 0.125};
     792
     793// 0.5 / n for (0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 5.0, 6.0)
     794float indexGuessInv[] = {1.00, 0.50, 0.333, 0.25, 0.166, 0.125, 0.10, 0.0833};
     795float indexGuessR1q[] = {1.06, 1.19, 1.335, 1.48, 1.840, 2.290, 2.84, 3.5300};
     796# define N_INDEX_GUESS_INV 8
     797
     798// we are going to guess in fractions about the R1-based guess
     799float reffGuess[] = {0.8, 0.9, 1.0, 1.12, 1.25};
    786800# define N_REFF_GUESS 5
    787801
     
    791805
    792806    // we get a reasonable guess from:
    793     // * Reff = Kron R1
     807    // * Reff = Kron R1 / Q(index) -- Q comes from Graham & Driver
    794808    // * Rmajor / Rminor & Theta from moments
    795809    // * Io from total Kron flux
     
    813827    psEllipseAxes momentAxes = psEllipseMomentsToAxes (moments, 20.0);
    814828
    815     if (0) {
    816         psEllipseAxes guessAxes;
    817         guessAxes.major = source->moments->Mrf;
    818         guessAxes.minor = (momentAxes.minor / momentAxes.minor) * guessAxes.major;
    819         guessAxes.theta = momentAxes.theta;
    820 
    821         if (!isfinite(guessAxes.major)) return false;
    822         if (!isfinite(guessAxes.minor)) return false;
    823         if (!isfinite(guessAxes.theta)) return false;
    824 
    825         // convert the major,minor,theta to shape parameters for an Reff-like model
    826         pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true);
    827     }
    828 
    829829    // set the model position
    830830    if (!pmModelSetPosition(&PAR[PM_PAR_XPOS], &PAR[PM_PAR_YPOS], source)) {
     
    846846    // loop over index guesses and find the best fit
    847847    for (int j = 0; j < N_REFF_GUESS; j++) {
    848 
    849         psEllipseAxes guessAxes;
    850         guessAxes.major = reffGuess[j] * source->moments->Mrf;
    851         guessAxes.minor = guessAxes.major * (momentAxes.minor / momentAxes.major);
    852         guessAxes.theta = momentAxes.theta;
    853 
    854         if (!isfinite(guessAxes.major)) return false;
    855         if (!isfinite(guessAxes.minor)) return false;
    856         if (!isfinite(guessAxes.theta)) return false;
    857 
    858         // convert the major,minor,theta to shape parameters for an Reff-like model
    859         pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true);
    860 
    861848        for (int i = 0; i < N_INDEX_GUESS_INV; i++) {
    862849            PAR[PM_PAR_7] = indexGuessInv[i];
    863850
     851            psEllipseAxes guessAxes;
     852            guessAxes.major = reffGuess[j] * source->moments->Mrf / indexGuessR1q[i];
     853            guessAxes.minor = guessAxes.major * (momentAxes.minor / momentAxes.major);
     854            guessAxes.theta = momentAxes.theta;
     855
     856            if (!isfinite(guessAxes.major)) return false;
     857            if (!isfinite(guessAxes.minor)) return false;
     858            if (!isfinite(guessAxes.theta)) return false;
     859
     860            // convert the major,minor,theta to shape parameters for an Reff-like model
     861            pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true);
     862
    864863            // generated the modelFlux
    865             pmPCMMakeModel (source, pcm->modelConv, maskVal, psfSize);
     864            // XXX note that this does not add sky to model
     865            pmPCMMakeModel (source, pcm->modelConv, pcm->nsigma, maskVal, psfSize);
    866866       
    867867            float YY = 0.0;
     
    901901                iMin = Io;
    902902                sMin = indexGuessInv[i];
    903                 rMin = reffGuess[j];
     903                rMin = reffGuess[j] / indexGuessR1q[i];
    904904            }
    905             // fprintf (stderr, "%d | %f %f %f %f | %f %f %f %f", i, indexGuessInv[i], reffGuess[j], Io, Chisq, sMin, rMin, iMin, xMin);
    906             // fprintf (stderr, "\n");
     905            if (EXTRA_VERBOSE) {
     906                fprintf (stderr, "%d | %f %f %f %f | %f %f %f %f", i, indexGuessInv[i], reffGuess[j], Io, Chisq, sMin, rMin, iMin, xMin);
     907                fprintf (stderr, "\n");
     908            }
    907909        }
    908910    }
     
    10071009    psVector *Sidx = psVectorAllocEmpty (16, PS_TYPE_F32);
    10081010
    1009     PAR[PM_PAR_7] = indexGuessInv[nStart];
     1011    float Sm = NAN, Sp = NAN, So = NAN;
     1012    if (nStart == 0) {
     1013        Sm = indexGuessInv[nStart];
     1014        So = 0.5*(indexGuessInv[nStart + 1] + indexGuessInv[nStart]);
     1015        Sp = indexGuessInv[nStart + 1];
     1016    } else if (nStart == N_INDEX_GUESS_INV - 1) {
     1017        Sp = indexGuessInv[nStart];
     1018        So = 0.5*(indexGuessInv[nStart - 1] + indexGuessInv[nStart]);
     1019        Sm = indexGuessInv[nStart - 1];
     1020    } else {
     1021        Sm = 0.5*(indexGuessInv[nStart - 1] + indexGuessInv[nStart]);
     1022        So = indexGuessInv[nStart];
     1023        Sp = 0.5*(indexGuessInv[nStart + 1] + indexGuessInv[nStart]);
     1024    }
     1025   
     1026    PAR[PM_PAR_7] = Sm;
    10101027    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
    10111028    if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]);
     
    10131030    psVectorAppend (chi2, model->chisqNorm);
    10141031
    1015     PAR[PM_PAR_7] = (nStart < N_INDEX_GUESS_INV - 1) ? 0.5*(indexGuessInv[nStart + 1] + indexGuessInv[nStart]) : 0.1;
     1032    PAR[PM_PAR_7] = So;
    10161033    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
    10171034    if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]);
     
    10191036    psVectorAppend (chi2, model->chisqNorm);
    10201037
    1021     PAR[PM_PAR_7] = (nStart > 0) ? 0.5*(indexGuessInv[nStart - 1] + indexGuessInv[nStart]) : 0.55;
     1038    PAR[PM_PAR_7] = Sp;
    10221039    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
    10231040    if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]);
    10241041    psVectorAppend (Sidx, 100*PAR[PM_PAR_7]);
    10251042    psVectorAppend (chi2, model->chisqNorm);
    1026 
    1027     if (chi2->data.F32[1] < chi2->data.F32[2]) {
    1028       if (nStart == N_INDEX_GUESS_INV - 1) {
    1029         PAR[PM_PAR_7] = 0.11;
    1030       } else {
    1031         PAR[PM_PAR_7] = indexGuessInv[nStart + 1];
    1032       }
    1033     } else {
    1034       if (nStart == 0) {
    1035         PAR[PM_PAR_7] = 0.52;
    1036       } else {
    1037         PAR[PM_PAR_7] = indexGuessInv[nStart - 1];
    1038       }
    1039     }
    10401043
    10411044    psPolynomial1D *poly = psPolynomial1DAlloc (PS_POLYNOMIAL_ORD, 2);
     
    10511054    float Smin = -0.5 * poly->coeff[1] / poly->coeff[2] / 100.0;
    10521055
    1053     // constrain Smin to be in a valid range (1.0 - 0.1, corresponding to 0.5 (Gauss) to 5.0 (slightly peakier than Dev)
    1054     Smin = PS_MAX(PS_MIN(Smin, 1.0), 0.1);
     1056    // constrain Smin to be in a valid range: allow the fitted range to go a bit beyond the 3 trial points, but no further
     1057    float Smx = Sm - 0.25*(So - Sm);
     1058    float Spx = Sp + 0.25*(Sp - So);
     1059    Smin = PS_MAX(PS_MIN(Smin, Smx), Spx);
    10551060    PAR[PM_PAR_7] = Smin;
     1061
     1062    // XXX I could set the error on PAR_7 here if I knew how to roughly convert these chisq values to true chisq values
    10561063
    10571064    // return to the original fitting mode (fitOptions)
     
    12461253}
    12471254
    1248  
     1255// # define N_REFF_CHECK 11
     1256// float drefCheck[] = {-0.02, -0.04, -0.06, 0.0, 0.85, 0.90, 0.95, 1.00, 1.05, 1.10, 1.15, 1.20, 1.25};
     1257
     1258// we have an initial fit, check to see if the current size is besst
     1259bool psphotPCMfitCheckSize (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, float psfSize) {
     1260
     1261    // PAR is already at my current best guess
     1262    psF32 *PAR = pcm->modelConv->params->data.F32;
     1263
     1264    // store best guess as a shape
     1265    psEllipseAxes centerAxes;
     1266    pmModelParamsToAxes (&centerAxes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
     1267
     1268    float xMin = NAN;
     1269    float iMin = NAN;
     1270    float rMin = NAN;
     1271
     1272    // loop over Reff, keeping the ARatio and Theta constant
     1273    for (int j = -4; j <= 4; j++) {
     1274
     1275        float dref = j * 0.01;
     1276
     1277        psEllipseAxes guessAxes;
     1278        guessAxes.major = centerAxes.major + dref;
     1279        guessAxes.minor = guessAxes.major * centerAxes.minor / centerAxes.major;
     1280        guessAxes.theta = centerAxes.theta;
     1281
     1282        if (!isfinite(guessAxes.major)) return false;
     1283        if (!isfinite(guessAxes.minor)) return false;
     1284        if (!isfinite(guessAxes.theta)) return false;
     1285
     1286        // convert the major,minor,theta to shape parameters for an Reff-like model
     1287        pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true);
     1288
     1289        // generated the modelFlux
     1290            // XXX note that this does not add sky to model
     1291        pmPCMMakeModel (source, pcm->modelConv, pcm->nsigma, maskVal, psfSize);
     1292       
     1293        float YY = 0.0;
     1294        float YM = 0.0;
     1295        float MM = 0.0;
     1296        bool usePoisson = false;
     1297
     1298        for (int iy = 0; iy < source->pixels->numRows; iy++) {
     1299            for (int ix = 0; ix < source->pixels->numCols; ix++) {
     1300                // skip masked points
     1301                if (source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix]) {
     1302                    continue;
     1303                }
     1304                // skip zero-variance points
     1305                if (source->variance->data.F32[iy][ix] == 0) {
     1306                    continue;
     1307                }
     1308                // skip nan value points
     1309                if (!isfinite(source->pixels->data.F32[iy][ix])) {
     1310                    continue;
     1311                }
     1312
     1313                float fy = source->pixels->data.F32[iy][ix];
     1314                float fm = source->modelFlux->data.F32[iy][ix];
     1315                float wt = (usePoisson) ? 1.0 / source->variance->data.F32[iy][ix] : 1.0;
     1316
     1317                YY += PS_SQR(fy) * wt;
     1318                YM += fm * fy * wt;
     1319                MM += PS_SQR(fm) * wt;
     1320            }
     1321        }
     1322
     1323        float Io = YM / MM;
     1324        float Chisq = YY - 2 * Io * YM + Io * Io * MM;
     1325        if (isnan(xMin) || (Chisq < xMin)) {
     1326            xMin = Chisq;
     1327            iMin = Io;
     1328            rMin = dref;
     1329        }
     1330        // fprintf (stderr, "%d | %f %f %f | %f %f %f\n", j, dref, Io, Chisq, rMin, iMin, xMin);
     1331    }
     1332
     1333    psEllipseAxes guessAxes;
     1334    guessAxes.major = centerAxes.major + rMin;
     1335    guessAxes.minor = guessAxes.major * centerAxes.minor / centerAxes.major;
     1336    guessAxes.theta = centerAxes.theta;
     1337
     1338    if (!isfinite(guessAxes.major)) return false;
     1339    if (!isfinite(guessAxes.minor)) return false;
     1340    if (!isfinite(guessAxes.theta)) return false;
     1341
     1342    // convert the major,minor,theta to shape parameters for an Reff-like model
     1343    pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true);
     1344    PAR[PM_PAR_I0] = iMin;
     1345
     1346    return true;
     1347}
     1348
     1349// we have an initial fit, check to see if the current size is besst
     1350bool psphotPCMfitRetry (pmPCMdata *pcm, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, float psfSize) {
     1351
     1352    // PAR is already at my current best guess
     1353    psF32 *PAR = pcm->modelConv->params->data.F32;
     1354
     1355    // store best guess as a shape
     1356    psEllipseAxes centerAxes;
     1357    pmModelParamsToAxes (&centerAxes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
     1358
     1359    // retry with axes smaller by 1 pixel
     1360    psEllipseAxes guessAxes;
     1361    guessAxes.major = centerAxes.major - 0.08;
     1362    guessAxes.minor = guessAxes.major * centerAxes.minor / centerAxes.major;
     1363    guessAxes.theta = centerAxes.theta;
     1364
     1365    if (!isfinite(guessAxes.major)) return false;
     1366    if (!isfinite(guessAxes.minor)) return false;
     1367    if (!isfinite(guessAxes.theta)) return false;
     1368
     1369    // convert the major,minor,theta to shape parameters for an Reff-like model
     1370    pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true);
     1371
     1372    // generated the modelFlux
     1373            // XXX note that this does not add sky to model
     1374    pmPCMMakeModel (source, pcm->modelConv, pcm->nsigma, maskVal, psfSize);
     1375       
     1376    float YY = 0.0;
     1377    float YM = 0.0;
     1378    float MM = 0.0;
     1379    bool usePoisson = false;
     1380
     1381    for (int iy = 0; iy < source->pixels->numRows; iy++) {
     1382        for (int ix = 0; ix < source->pixels->numCols; ix++) {
     1383            // skip masked points
     1384            if (source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix]) {
     1385                continue;
     1386            }
     1387            // skip zero-variance points
     1388            if (source->variance->data.F32[iy][ix] == 0) {
     1389                continue;
     1390            }
     1391            // skip nan value points
     1392            if (!isfinite(source->pixels->data.F32[iy][ix])) {
     1393                continue;
     1394            }
     1395
     1396            float fy = source->pixels->data.F32[iy][ix];
     1397            float fm = source->modelFlux->data.F32[iy][ix];
     1398            float wt = (usePoisson) ? 1.0 / source->variance->data.F32[iy][ix] : 1.0;
     1399
     1400            YY += PS_SQR(fy) * wt;
     1401            YM += fm * fy * wt;
     1402            MM += PS_SQR(fm) * wt;
     1403        }
     1404    }
     1405
     1406    float Io = YM / MM;
     1407    PAR[PM_PAR_I0] = Io;
     1408
     1409    pmSourceFitPCM (pcm, source, fitOptions, maskVal, markVal, psfSize);  // NOTE : 1687 allocs in here
     1410
     1411    return true;
     1412}
     1413
     1414
  • trunk/psphot/src/psphotSourceSize.c

    r35180 r36375  
    11# include "psphotInternal.h"
    2 # include <gsl/gsl_sf_gamma.h>
    3 
     2
     3// this structure is only used internally to simplify the function parameters
    44typedef struct {
    55    psImageMaskType maskVal;
     
    1313    bool altDiffExt;
    1414    float altDiffExtThresh;
    15     bool extFitAll;
    16     bool extFitAllReadout;
    17     float extFitAllThresh;
    1815    float soft;
    1916    int grow;
     
    3330bool psphotSourceSelectCR (pmReadout *readout, psArray *sources, psphotSourceSizeOptions *options);
    3431bool psphotMaskCosmicRay (pmReadout *readout, pmSource *source, psImageMaskType maskVal, int maxWindowCR);
    35 bool psphotMaskCosmicRayFootprintCheck (psArray *sources);
    3632int  psphotMaskCosmicRayConnected (int xPeak, int yPeak, psImage *mymask, psImage *myvar, psImage *edges, int binning, float sigma_thresh);
    3733float psphotSourceSizeFindThreshold (psVector *value, psVector *mask, int maskValue, float minValue, float maxValue, float delta, float guess, float fraction);
     
    4137
    4238// we need to call this function after sources have been fitted to the PSF model and
    43 // subtracted.  To determine the CR-nature, this function examines the 9 pixels in the 3x3
    44 // square containing the peak and compares the observed flux to the model.  To determine
    45 // the EXT-nature, this function measures the amount of positive or negative total
    46 // deviation from the psf model at the r = FWHM/2 position
     39// subtracted. 
    4740
    4841// for now, let's store the detections on the readout->analysis for each readout
     
    121114    assert (status);
    122115
    123     // XXX recipe name is not great
     116    // XXX recipe name is not great (NOTE : not used!)
    124117    options.nSigmaMoments = psMetadataLookupF32 (&status, recipe, "PSPHOT.EXT.NSIGMA.MOMENTS");
    125118    assert (status);
    126119
    127     // Optional extended source measurement algorithm to improve diff image trails
     120    // Optional algorithm to define if a source is extended (used by DIFF analysis)
    128121    options.altDiffExt = psMetadataLookupBool(&status, recipe, "PSPHOT.EXT.DIFF.ALTERNATE");
    129122    assert (status);
     123
    130124    // Threshold for this alternate method
    131125    options.altDiffExtThresh = psMetadataLookupF32(&status, recipe, "PSPHOT.EXT.DIFF.ALTERNATE.THRESH");
    132126    assert (status);
    133     // Option to enable fitting of all objects with extended model.
    134     options.extFitAll = psMetadataLookupBool(&status, recipe, "PSPHOT.EXT.FIT.ALL.SOURCES");
    135     assert (status);
    136     // Fitting everything is fine, but if the source density is high, we probably shouldn't.
    137     options.extFitAllThresh = psMetadataLookupF32(&status, recipe, "PSPHOT.EXT.FIT.ALL.THRESH");
    138     assert (status);
    139    
     127
    140128    // location of a single test source
    141129    options.xtest = psMetadataLookupS32 (&status, recipe, "PSPHOT.CRMASK.XTEST");
     
    422410
    423411    psLogMsg("psModules.objects", PS_LOG_INFO, "Source Size classifications: %4s %4s %4s %4s %4s", "Npsf", "Next", "Nsat", "Ncr", "Nskip");
    424     // Determine if this readout is above the threshold to ext fit all sources
    425     options->extFitAllReadout = false;
    426     if (options->extFitAll) {
    427       float maskFrac = psMetadataLookupF32(&status,readout->analysis,"READOUT.MASK.FRAC");
    428       if (status) {
    429         maskFrac = 0.0;
    430       }
    431       if (sources->n * (1.0 - maskFrac) > options->extFitAllThresh) {
    432         options->extFitAllReadout = false;
    433       }
    434       else {
    435         options->extFitAllReadout = true;
    436       }
    437     }
    438    
     412
    439413    if (!psphotSourceClassRegion (NULL, &psfClump, sources, recipe, psf, options)) {
    440414        psLogMsg ("psphot", 4, "Failed to determine source classification for full image\n");
     
    444418    return true;
    445419   
     420    // NOTE : this section is deactivated (EAM : I think we were getting poor boundary effects?)
    446421    int nRegions = psMetadataLookupS32 (&status, readout->analysis, "PSF.CLUMP.NREGIONS");
    447422    for (int i = 0; i < nRegions; i ++) {
     
    582557        // * SAT stars should not be faint, but defects may?
    583558
    584         // If the recipe requests we do extended source fits to everything, set
    585         // the EXT_LIMIT flag
    586         if (options->extFitAllReadout) {
    587           psTrace("psphotSourceClassRegion.EXTALT",10,"In extFitAll: %d %d\n",options->extFitAll,options->extFitAllReadout);
    588           source->mode |= PM_SOURCE_MODE_EXT_LIMIT;
    589         }
    590559        // Defects may not always match CRs from peak curvature analysis
    591560        // Defects may also be marked as SATSTAR -- XXX deactivate this flag?
     
    595564
    596565        // saturated star (too many saturated pixels or peak above saturation limit).  These
    597         // may also be saturated galaxies, or just large saturated regions.
     566        // may also be saturated galaxies, or just large saturated regions.  They are never
     567        // marked as 'extended'
    598568        if (source->mode & PM_SOURCE_MODE_SATSTAR) {
    599569            psTrace("psphotSourceClassRegion.SAT",4,"CLASS: %g %g\t%g %g\t%g %g\t%g %g\t%g SAT\n",
     
    604574        }
    605575
    606         // any sources missing a large fraction should just be treated as PSFs
     576        // any sources missing a large fraction should just be treated as PSFs. They are never
     577        // marked as 'extended'
    607578        if ((source->pixWeightNotBad < 0.9) || (source->pixWeightNotPoor < 0.9)) {
    608579            psTrace("psphotSourceClassRegion.PSF",4,"CLASS: %g %g\t%g %g  %g %g  %g %g\t%g %g\t%g PSF\t%g %g\n",
     
    634605            psTrace("psphotSourceClassRegion.EXT",4,"CLASS: %g %g\t%g %g\t%g %g\t%g %g\t%g EXT\n",
    635606                    source->peak->xf, source->peak->yf, Mminor, kMag, dMag, nSigmaMAG, options->sizeLimitCR, options->magLimitCR, options->nSigmaApResid);
     607            source->type = PM_SOURCE_TYPE_EXTENDED;
    636608            source->mode |= PM_SOURCE_MODE_EXT_LIMIT;
    637609            source->tmpFlags |= PM_SOURCE_TMPF_SIZE_MEASURED;
     
    639611            continue;
    640612        }
     613
    641614        // Alternate extended source limit calculation
    642615        if (options->altDiffExt) {
     
    652625                    source->peak->xf, source->peak->yf, Mminor, kMag, dMag, nSigmaMAG, options->sizeLimitCR, options->magLimitCR, options->nSigmaApResid,
    653626                    momentRatioVeres,options->altDiffExtThresh);
     627            source->type = PM_SOURCE_TYPE_EXTENDED;
    654628            source->mode |= PM_SOURCE_MODE_EXT_LIMIT;
    655629            source->tmpFlags |= PM_SOURCE_TMPF_SIZE_MEASURED;
     
    968942}
    969943
    970 bool psphotMaskCosmicRayFootprintCheck (psArray *sources) {
    971 #ifdef CHECK_FOOTPRINTS
    972     // This gets really expensive for complex images
    973     for (int i = 0; i < sources->n; i++) {
    974         pmSource *source = sources->data[i];
    975         pmPeak *peak = source->peak;
    976         pmFootprint *footprint = peak->footprint;
    977         if (!footprint) continue;
    978         for (int j = 0; j < footprint->spans->n; j++) {
    979             pmSpan *sp = footprint->spans->data[j];
    980             psAssert (sp, "missing span");
    981         }
    982     }
    983 #endif
    984     return true;
    985 }
    986 
    987 /**** ------ old versions of cosmic ray masking ----- ****/
    988 
    989 bool psphotMaskCosmicRayIsophot (pmSource *source, psImageMaskType maskVal, psImageMaskType crMask);
    990 
    991 // This attempt to mask the cosmic rays used the isophotal boundary
    992 bool psphotMaskCosmicRay_V1 (psImage *mask, pmSource *source, psImageMaskType maskVal, psImageMaskType crMask) {
    993 
    994     // replace the source flux
    995     pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
    996 
    997     // flag this as a CR
    998     source->mode |= PM_SOURCE_MODE_CR_LIMIT;
    999     pmPeak *peak = source->peak;
    1000     psAssert (peak, "NULL peak");
    1001 
    1002     // grab the matching footprint
    1003     pmFootprint *footprint = peak->footprint;
    1004     if (!footprint) {
    1005       psTrace("psphot.czw",2,"Using isophot CR mask code.");
    1006 
    1007         // if we have not footprint, use the old code to mask by isophot
    1008         psphotMaskCosmicRayIsophot (source, maskVal, crMask);
    1009         return true;
    1010     }
    1011 
    1012     if (!footprint->spans) {
    1013       psTrace("psphot.czw",2,"Using isophot CR mask code.");
    1014 
    1015         // if we have no footprint, use the old code to mask by isophot
    1016         psphotMaskCosmicRayIsophot (source, maskVal, crMask);
    1017         return true;
    1018     }
    1019     psphotMaskCosmicRayIsophot (source, maskVal, crMask);
    1020     // mask all of the pixels covered by the spans of the footprint
    1021     for (int j = 1; j < footprint->spans->n; j++) {
    1022         pmSpan *span1 = footprint->spans->data[j];
    1023 
    1024         int iy = span1->y;
    1025         int xs = span1->x0;
    1026         int xe = span1->x1;
    1027 
    1028         for (int ix = xs; ix < xe; ix++) {
    1029             mask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] |= crMask;
    1030         }
    1031     }
    1032     return true;
    1033 }
    1034 
    1035944# define VERBOSE 0
    1036945int psphotMaskCosmicRayConnected (int xPeak, int yPeak, psImage *mymask, psImage *myvar, psImage *edges, int binning, float sigma_thresh) {
     
    11761085}
    11771086
    1178 bool psphotMaskCosmicRayIsophot (pmSource *source, psImageMaskType maskVal, psImageMaskType crMask) {
    1179 
    1180     source->mode |= PM_SOURCE_MODE_CR_LIMIT;
    1181     pmPeak *peak = source->peak;
    1182     psAssert (peak, "NULL peak");
    1183 
    1184     psImage *mask   = source->maskView;
    1185     psImage *pixels = source->pixels;
    1186     psImage *variance = source->variance;
    1187 
    1188     // XXX This should be a recipe variable
    1189 # define SN_LIMIT 5.0
    1190 
    1191     int xo = peak->x - pixels->col0;
    1192     int yo = peak->y - pixels->row0;
    1193 
    1194     // mark the pixels in this row to the left, then the right
    1195     for (int ix = xo; ix >= 0; ix--) {
    1196         float SN = pixels->data.F32[yo][ix] / sqrt(variance->data.F32[yo][ix]);
    1197         if (SN > SN_LIMIT) {
    1198             mask->data.PS_TYPE_IMAGE_MASK_DATA[yo][ix] |= crMask;
    1199         }
    1200     }
    1201     for (int ix = xo + 1; ix < pixels->numCols; ix++) {
    1202         float SN = pixels->data.F32[yo][ix] / sqrt(variance->data.F32[yo][ix]);
    1203         if (SN > SN_LIMIT) {
    1204             mask->data.PS_TYPE_IMAGE_MASK_DATA[yo][ix] |= crMask;
    1205         }
    1206     }
    1207 
    1208     // for each of the neighboring rows, mark the high pixels if they have a marked neighbor
    1209     // first go up:
    1210     for (int iy = PS_MIN(yo, mask->numRows-2); iy >= 0; iy--) {
    1211         // mark the pixels in this row to the left, then the right
    1212         for (int ix = 0; ix < pixels->numCols; ix++) {
    1213             float SN = pixels->data.F32[iy][ix] / sqrt(variance->data.F32[iy][ix]);
    1214             if (SN < SN_LIMIT) continue;
    1215 
    1216             bool valid = false;
    1217             valid |= (mask->data.PS_TYPE_IMAGE_MASK_DATA[iy+1][ix] & crMask);
    1218             valid |= (ix > 0) ? (mask->data.PS_TYPE_IMAGE_MASK_DATA[iy+1][ix-1] & crMask) : 0;
    1219             valid |= (ix <= mask->numCols) ? (mask->data.PS_TYPE_IMAGE_MASK_DATA[iy+1][ix+1] & crMask) : 0;
    1220 
    1221             if (!valid) continue;
    1222             mask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] |= crMask;
    1223         }
    1224     }
    1225     // next go down:
    1226     for (int iy = PS_MIN(yo+1, mask->numRows-1); iy < pixels->numRows; iy++) {
    1227         // mark the pixels in this row to the left, then the right
    1228         for (int ix = 0; ix < pixels->numCols; ix++) {
    1229             float SN = pixels->data.F32[iy][ix] / sqrt(variance->data.F32[iy][ix]);
    1230             if (SN < SN_LIMIT) continue;
    1231 
    1232             bool valid = false;
    1233             valid |= (mask->data.PS_TYPE_IMAGE_MASK_DATA[iy-1][ix] & crMask);
    1234             valid |= (ix > 0) ? (mask->data.PS_TYPE_IMAGE_MASK_DATA[iy-1][ix-1] & crMask) : 0;
    1235             valid |= (ix <= mask->numCols) ? (mask->data.PS_TYPE_IMAGE_MASK_DATA[iy-1][ix+1] & crMask) : 0;
    1236 
    1237             if (!valid) continue;
    1238             mask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] |= crMask;
    1239         }
    1240     }
    1241     return true;
    1242 }
    1243 
    1244 // given the PSF ellipse parameters, navigate around the 1sigma contour, return the total
    1245 // deviation in sigmas.  This is measured on the residual image - should we ignore negative
    1246 // deviations?  NOTE: This function was an early attempt to classify extended objects, and is
    1247 // no longer used by psphot.
    1248 float psphotModelContour(const psImage *image, const psImage *variance, const psImage *mask,
    1249                          psImageMaskType maskVal, const pmModel *model, float Ro)
    1250 {
    1251     psF32 *PAR = model->params->data.F32; // Model parameters
    1252     float sxx = PAR[PM_PAR_SXX], sxy = PAR[PM_PAR_SXY], syy = PAR[PM_PAR_SYY]; // Ellipse parameters
    1253 
    1254     // We treat the contour as an ellipse:
    1255     // Ro = (x / SXX)^2 + (y / SYY)^2 + x y SXY
    1256     // y^2 (1/SYY^2) + y (x SXY) + (x / SXX)^2 - Ro = 0;
    1257     // This is a quadratic, Ay^2 + By + C with A = 1/SYY^2, B = x*SXY, C = (x / SXX)^2 - Ro
    1258     // The solution is y = [-B +/- sqrt (B^2 - 4 A C)] / [2 A], so:
    1259     // y = [-(x SXY) +/- sqrt ((x SXY)^2 - 4 (1/SYY^2) ((x/SXX)^2 - Ro))] * [SYY^2 / 2]
    1260 
    1261     // min/max value of x is where B^2 - 4AC = 0; solve this for x
    1262     float Q = Ro * PS_SQR(sxx) / (1.0 - PS_SQR(sxx * syy * sxy) / 4.0);
    1263     if (Q < 0.0) {
    1264         // ellipse is imaginary
    1265         return NAN;
    1266     }
    1267 
    1268     int radius = sqrtf(Q) + 0.5;        // Radius of ellipse
    1269     int nPts = 0;                       // Number of points in ellipse
    1270     float nSigma = 0.0;                 //
    1271 
    1272     for (int x = -radius; x <= radius; x++) {
    1273         // Polynomial coefficients
    1274         // XXX Should we be using the centre of the pixel as x or x+0.5?
    1275         float A = PS_SQR (1.0 / syy);
    1276         float B = x * sxy;
    1277         float C = PS_SQR (x / sxx) - Ro;
    1278         float T = PS_SQR(B) - 4*A*C;
    1279         if (T < 0.0) {
    1280             continue;
    1281         }
    1282 
    1283         // y position in source frame
    1284         float yP = (-B + sqrt (T)) / (2.0 * A);
    1285         float yM = (-B - sqrt (T)) / (2.0 * A);
    1286 
    1287         // Get the closest pixel positions (image frame)
    1288         int xPix  = x  + PAR[PM_PAR_XPOS] - image->col0 + 0.5;
    1289         int yPixM = yM + PAR[PM_PAR_YPOS] - image->row0 + 0.5;
    1290         int yPixP = yP + PAR[PM_PAR_YPOS] - image->row0 + 0.5;
    1291 
    1292         if (xPix < 0 || xPix >= image->numCols) {
    1293             continue;
    1294         }
    1295 
    1296         if (yPixM >= 0 && yPixM < image->numRows &&
    1297             !(mask && (mask->data.PS_TYPE_IMAGE_MASK_DATA[yPixM][xPix] & maskVal))) {
    1298             float dSigma = image->data.F32[yPixM][xPix] / sqrtf(variance->data.F32[yPixM][xPix]);
    1299             nSigma += dSigma;
    1300             nPts++;
    1301         }
    1302 
    1303         if (yPixM == yPixP) {
    1304             continue;
    1305         }
    1306 
    1307         if (yPixP >= 0 && yPixP < image->numRows &&
    1308             !(mask && (mask->data.PS_TYPE_IMAGE_MASK_DATA[yPixP][xPix] & maskVal))) {
    1309             float dSigma = image->data.F32[yPixP][xPix] / sqrtf(variance->data.F32[yPixP][xPix]);
    1310             nSigma += dSigma;
    1311             nPts++;
    1312         }
    1313     }
    1314     nSigma /= nPts;
    1315     return nSigma;
    1316 }
    1317 
    1318 // this was an old attempt to identify cosmic rays based on the peak curvature
    1319 bool psphotSourcePeakCurvature (pmReadout *readout, psArray *sources, psphotSourceSizeOptions *options) {
    1320 
    1321     // classify the sources based on the CR test (place this in a function?)
    1322     // XXX use an internal flag to mark sources which have already been measured
    1323     for (int i = 0; i < sources->n; i++) {
    1324         pmSource *source = sources->data[i];
    1325 
    1326         // skip source if it was already measured
    1327         if (source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED) {
    1328             psTrace("psphot", 7, "Not calculating source size since it has already been measured\n");
    1329             continue;
    1330         }
    1331 
    1332         // source must have been subtracted
    1333         if (!(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED)) {
    1334             source->mode |= PM_SOURCE_MODE_SIZE_SKIPPED;
    1335             psTrace("psphot", 7, "Not calculating source size since source is not subtracted\n");
    1336             continue;
    1337         }
    1338 
    1339         psF32 **resid  = source->pixels->data.F32;
    1340         psF32 **variance = source->variance->data.F32;
    1341         psImageMaskType **mask = source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA;
    1342 
    1343         // Integer position of peak
    1344         int xPeak = source->peak->xf - source->pixels->col0 + 0.5;
    1345         int yPeak = source->peak->yf - source->pixels->row0 + 0.5;
    1346 
    1347         // Skip sources which are too close to a boundary.  These are mostly caught as DEFECT
    1348         if (xPeak < 1 || xPeak > source->pixels->numCols - 2 ||
    1349             yPeak < 1 || yPeak > source->pixels->numRows - 2) {
    1350             psTrace("psphot", 7, "Not calculating crNsigma due to edge\n");
    1351             continue;
    1352         }
    1353 
    1354         // Skip sources with masked pixels.  These are mostly caught as DEFECT
    1355         bool keep = true;
    1356         for (int iy = -1; (iy <= +1) && keep; iy++) {
    1357             for (int ix = -1; (ix <= +1) && keep; ix++) {
    1358                 if (mask[yPeak+iy][xPeak+ix] & options->maskVal) {
    1359                     keep = false;
    1360                 }
    1361             }
    1362         }
    1363         if (!keep) {
    1364             psTrace("psphot", 7, "Not calculating crNsigma due to masked pixels\n");
    1365             continue;
    1366         }
    1367 
    1368         // Compare the central pixel with those on either side, for the four possible lines through it.
    1369 
    1370         // Soften variances (add systematic error)
    1371         float softening = options->soft * PS_SQR(source->peak->rawFlux); // Softening for variances
    1372 
    1373         // Across the middle: y = 0
    1374         float cX = 2*resid[yPeak][xPeak]   - resid[yPeak+0][xPeak-1]  - resid[yPeak+0][xPeak+1];
    1375         float dcX = 4*variance[yPeak][xPeak] + variance[yPeak+0][xPeak-1] + variance[yPeak+0][xPeak+1];
    1376         float nX = cX / sqrtf(dcX + softening);
    1377 
    1378         // Up the centre: x = 0
    1379         float cY = 2*resid[yPeak][xPeak]   - resid[yPeak-1][xPeak+0]  - resid[yPeak+1][xPeak+0];
    1380         float dcY = 4*variance[yPeak][xPeak] + variance[yPeak-1][xPeak+0] + variance[yPeak+1][xPeak+0];
    1381         float nY = cY / sqrtf(dcY + softening);
    1382 
    1383         // Diagonal: x = y
    1384         float cL = 2*resid[yPeak][xPeak]   - resid[yPeak-1][xPeak-1]  - resid[yPeak+1][xPeak+1];
    1385         float dcL = 4*variance[yPeak][xPeak] + variance[yPeak-1][xPeak-1] + variance[yPeak+1][xPeak+1];
    1386         float nL = cL / sqrtf(dcL + softening);
    1387 
    1388         // Diagonal: x = - y
    1389         float cR = 2*resid[yPeak][xPeak]   - resid[yPeak+1][xPeak-1]  - resid[yPeak-1][xPeak+1];
    1390         float dcR = 4*variance[yPeak][xPeak] + variance[yPeak+1][xPeak-1] + variance[yPeak-1][xPeak+1];
    1391         float nR = cR / sqrtf(dcR + softening);
    1392 
    1393         // P(chisq > chisq_obs; Ndof) = gamma_Q (Ndof/2, chisq/2)
    1394         // Ndof = 4 ? (four measurements, no free parameters)
    1395         // XXX this value is going to be biased low because of systematic errors.
    1396         // we need to calibrate it somehow
    1397         // source->psfProb = gsl_sf_gamma_inc_Q (2, 0.5*chisq);
    1398 
    1399         // not strictly accurate: overcounts the chisq contribution from the center pixel (by
    1400         // factor of 4); also biases a bit low if any pixels are masked
    1401         // XXX I am not sure I want to keep this value...
    1402         source->psfChisq = PS_SQR(nX) + PS_SQR(nY) + PS_SQR(nL) + PS_SQR(nR);
    1403 
    1404         float fCR = 0.0;
    1405         int nCR = 0;
    1406         if (nX > 0.0) {
    1407             fCR += nX;
    1408             nCR ++;
    1409         }
    1410         if (nY > 0.0) {
    1411             fCR += nY;
    1412             nCR ++;
    1413         }
    1414         if (nL > 0.0) {
    1415             fCR += nL;
    1416             nCR ++;
    1417         }
    1418         if (nR > 0.0) {
    1419             fCR += nR;
    1420             nCR ++;
    1421         }
    1422         source->crNsigma  = (nCR > 0)  ? fCR / nCR : 0.0;
    1423         source->tmpFlags |= PM_SOURCE_TMPF_SIZE_MEASURED;
    1424 
    1425         if (!isfinite(source->crNsigma)) {
    1426             continue;
    1427         }
    1428 
    1429         // this source is thought to be a cosmic ray.  flag the detection and mask the pixels
    1430         if (source->crNsigma > options->nSigmaCR) {
    1431             source->mode |= PM_SOURCE_MODE_CR_LIMIT;
    1432             // XXX still testing... : psphotMaskCosmicRay (readout->mask, source, maskVal, crMask);
    1433             // XXX acting strange... psphotMaskCosmicRay_Old (source, maskVal, crMask);
    1434         }
    1435     }
    1436 
    1437     // now that we have masked pixels associated with CRs, we can grow the mask
    1438     if (options->grow > 0) {
    1439         bool oldThreads = psImageConvolveSetThreads(true); // Old value of threading for psImageConvolveMask
    1440         psImage *newMask = psImageConvolveMask(NULL, readout->mask, options->crMask, options->crMask, -options->grow, options->grow, -options->grow, options->grow);
    1441         psImageConvolveSetThreads(oldThreads);
    1442         if (!newMask) {
    1443             psError(PS_ERR_UNKNOWN, false, "Unable to grow CR mask");
    1444             return false;
    1445         }
    1446         psFree(readout->mask);
    1447         readout->mask = newMask;
    1448     }
    1449     return true;
    1450 }
    1451 
    14521087float psphotSourceSizeFindThreshold (psVector *value, psVector *mask, int maskValue, float minValue, float maxValue, float delta, float guess, float fraction) {
    14531088
  • trunk/psphot/src/psphotSourceStats.c

    r35112 r36375  
    5858    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
    5959    psAssert (detections, "missing detections?");
    60 
    61     // XXX TEST:
    62     if (detections->allSources) {
    63         psphotMaskCosmicRayFootprintCheck(detections->allSources);
    64     }
    65     if (detections->newSources) {
    66         psphotMaskCosmicRayFootprintCheck(detections->newSources);
    67     }
    6860
    6961    // determine the number of allowed threads
     
    246238    psphotVisualShowMoments (sources);
    247239
    248     // clear the mark bits
    249     // psImageMaskPixels (readout->mask, "AND", PS_NOT_IMAGE_MASK(markVal));
    250 
    251     if (detections->allSources) {
    252         psphotMaskCosmicRayFootprintCheck(detections->allSources);
    253     }
    254     if (detections->newSources) {
    255         psphotMaskCosmicRayFootprintCheck(detections->newSources);
    256     }
    257 
    258240    return true;
    259241}
     
    572554
    573555            // measure basic source moments (no S/N clipping on input pixels)
     556            // sources with (mode & MODE_EXTERNAL) or (mode2 & MODE2_MATCHED) use the
     557            // supplied Mx,My value for the centroid (not recalculated)
    574558            status = pmSourceMoments (source, 4*sigma[i], sigma[i], 0.0, 0.0, maskVal);
    575559        }
  • trunk/psphot/src/psphotStackImageLoop.c

  • trunk/psphot/src/psphotStackReadout.c

    r36124 r36375  
    124124        return psphotReadoutCleanup (config, view, STACK_RAW);
    125125    }
    126 
    127 // XXX TEST for background:
    128     if (!psphotModelBackground (config, view, STACK_RAW)) {
    129         return psphotReadoutCleanup (config, view, STACK_RAW);
    130     }
    131     if (!psphotSubtractBackground (config, view, STACK_RAW)) {
    132         return psphotReadoutCleanup (config, view, STACK_RAW);
    133     }
    134     if (!psphotModelBackground (config, view, STACK_RAW)) {
    135         return psphotReadoutCleanup (config, view, STACK_RAW);
    136     }
    137     if (!psphotSubtractBackground (config, view, STACK_RAW)) {
    138         return psphotReadoutCleanup (config, view, STACK_RAW);
    139     }
    140 // XXX TEST END
    141126
    142127#ifdef MAKE_CHISQ_IMAGE
     
    319304    psphotStackObjectsUnifyPosition (objects);
    320305
    321     psphotStackObjectsSelectForAnalysis (config, view, STACK_RAW, objects);
     306    // psphotStackObjectsSelectForAnalysis (config, view, STACK_RAW, objects);
    322307
    323308    // final linear fit. NOTE: if splitLinearFit is true above, this pass will only fit
     
    346331    // measure kron fluxes for the matched sources only
    347332    psphotKronIterate(config, view, STACK_RAW, 3);
     333
     334    // decide which source(s) are to be fitted with the extended source analysis code.
     335    psphotChooseAnalysisOptionsByObject (config, view, STACK_RAW, objects);
    348336
    349337    // measure elliptical apertures, petrosians (objects sorted by S/N)
Note: See TracChangeset for help on using the changeset viewer.