IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 36375 for trunk/psphot


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:
29 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)
  • trunk/psphot/test/tap_psphot_galaxygrid.pro

    r36086 r36375  
    3030$RefOptions = $RefOptions -nx 3000 -ny 3000
    3131
     32if (not($?PSFMODEL))
     33  $PSFMODEL = PS1_V1
     34end
     35
     36macro reset.options
    3237# options for the simulated images (using the refimage for the stars)
    3338$FakeOptions = $BaseOptions
    3439$FakeOptions = $FakeOptions -exptime 30.0
    35 $FakeOptions = $FakeOptions -D PSF.MODEL PS_MODEL_GAUSS
     40# $FakeOptions = $FakeOptions -D PSF.MODEL PS_MODEL_GAUSS
     41$FakeOptions = $FakeOptions -D PSF.MODEL PS_MODEL_$PSFMODEL
    3642$FakeOptions = $FakeOptions -nx 3000 -ny 3000
    3743 
     
    6975$FakeConfig = $FakeConfig -Di GALAXY.GRID.DX 300
    7076$FakeConfig = $FakeConfig -Di GALAXY.GRID.DY 300
     77end
     78
     79if (not($?FakeConfig)) reset.options
    7180
    7281list fwhm
     
    7584 1.2
    7685 1.5
     86end
     87
     88if (not($?CONVOLVE_NSIGMA)) set CONVOLVE_NSIGMA = 5.0
     89
     90# generate fake images and run psphot on them
     91macro mkexp.devexp.single
     92  if ($0 != 5)
     93    echo "USAGE: mkexp.devexp.single (basename) (type) (Rmajor) (fwhm)" 
     94    break
     95  end
     96
     97  $basename = $1
     98  $type = $2
     99  $Rmajor = $3
     100  $fwhm = $4
     101
     102  $Aratio = 1.0
     103
     104  $FakeConfig = -camera SIMTEST
     105  $FakeConfig = $FakeConfig -recipe PPSIM STACKTEST.RUN
     106  $FakeConfig = $FakeConfig -D PSASTRO:PSASTRO.CATDIR catdir.ref
     107  $FakeConfig = $FakeConfig -Db STARS.FAKE F                         ; # only use stars from catdir.ref
     108  $FakeConfig = $FakeConfig -Db MATCH.DENSITY F
     109  $FakeConfig = $FakeConfig -Db PSF.CONVOLVE T
     110  $FakeConfig = $FakeConfig -Db GALAXY.FAKE T                        ; # generate a "realistic" distribution of galaxies
     111  $FakeConfig = $FakeConfig -Df GALAXY.MAG 17.0
     112  $FakeConfig = $FakeConfig -Df GALAXY.GRID.MAG 14.5
     113  $FakeConfig = $FakeConfig -Db GALAXY.GRID T                        ; # generate a grid of galaxies (constant mag)
     114  $FakeConfig = $FakeConfig -Df GALAXY.THETA.MIN 0
     115  $FakeConfig = $FakeConfig -Df GALAXY.THETA.MAX 180
     116  $FakeConfig = $FakeConfig -Di GALAXY.GRID.DX 300
     117  $FakeConfig = $FakeConfig -Di GALAXY.GRID.DY 300
     118  $FakeConfig = $FakeConfig -Df GALAXY.INDEX.MIN 1.0
     119  $FakeConfig = $FakeConfig -Df GALAXY.INDEX.MAX 1.0
     120  $FakeConfig = $FakeConfig -Df CONVOLVE.NSIGMA $CONVOLVE_NSIGMA
     121  $BaseConfig = $FakeConfig
     122
     123  $FakeConfig = $BaseConfig
     124  $FakeConfig = $FakeConfig -Df GALAXY.RMAJOR.MIN $Rmajor
     125  $FakeConfig = $FakeConfig -Df GALAXY.RMAJOR.MAX $Rmajor
     126  $FakeConfig = $FakeConfig -Df GALAXY.ARATIO.MIN $Aratio
     127  $FakeConfig = $FakeConfig -Df GALAXY.ARATIO.MAX $Aratio
     128         
     129  mkexp $basename $fwhm $type
    77130end
    78131
     
    272325  label -x sequence -y "M_out| - M_in|"
    273326  resize 700 320
     327
     328  # check on magnitude
     329  set dI = Iot_s - Iin_s
     330  lim -n 4$1 n -1.0 1.0; clear; box; plot n dI
     331  label -x sequence -y "I_out| - I_in|"
     332  resize 700 320
     333end
     334
     335macro grid.plot.stars
     336  if ($0 != 2)
     337    echo "USAGE: grid.plot.stars (version)"
     338    break
     339  end
     340  # things to examine: theta, Rmajor, AR
     341
     342  # go.grid.check.devexp
     343
     344  # check on position
     345  set dX = Xot_s - int(Xin_s) - 0.5
     346  set dY = Yot_s - int(Yin_s) - 0.5
     347  set ARin = rin_s / Rin_s
     348  set dR = Rin_s - Rot_s
     349
     350  create n 0 dR[]
     351  set dRf = dR / Rin_s
     352  lim -n 1$1 n -0.5 0.5; clear; box; plot n dRf
     353  label -x sequence -y "1 - R_out| / R_in|"
     354  resize 700 320
     355
     356  # check on A.Ratio
     357  set ARot = rot_s / Rot_s
     358  # lim ARin ARot; clear; box; plot ARin ARot
     359  set fAR = ARot / ARin
     360  lim -n 2$1 n 0.5 1.5; clear; box; plot n fAR
     361  label -x sequence -y "AR_out| / AR_in|"
     362  resize 700 320
     363
     364  # check on magnitude
     365  set dM = Mot_s - Min_s
     366  lim -n 3$1 n -0.5 0.5; clear; box; plot n dM   
     367  label -x sequence -y "M_out| - M_in|"
     368  resize 700 320
     369
     370  lim -n 4$1 n -1.5 1.5; clear; box; plot n dX
     371  label -x sequence -y "X_out| - X_in|"
     372  resize 700 320
     373
     374  lim -n 5$1 n -1.5 1.5; clear; box; plot n dY
     375  label -x sequence -y "Y_out| - Y_in|"
     376  resize 700 320
    274377end
    275378
     
    487590end
    488591
     592if (not($?NSIGMA_CONV)) set NSIGMA_CONV = 5.0
     593
    489594# create a realistic distribution of fake stars, GAUSS PSF
    490595macro fitexp
     
    507612  $psphotConfig = $psphotConfig -Db PSPHOT:SAVE.RESID T
    508613  $psphotConfig = $psphotConfig -D  PSPHOT:EXTENDED_SOURCE_MODELS_SELECTION $fitModel
     614  $psphotConfig = $psphotConfig -D  PSPHOT:PSF_MODEL PS_MODEL_$PSFMODEL
     615
     616  $psphotConfig = $psphotConfig -Db PSPHOT:PSF.RESIDUALS F
     617  $psphotConfig = $psphotConfig -Db PSPHOT:POISSON.ERRORS.PHOT.LMM F
     618  $psphotConfig = $psphotConfig -Db PSPHOT:EXTENDED_SOURCE_FITS_POISSON F
     619  $psphotConfig = $psphotConfig -Di PSPHOT:EXT_FIT_ITER 15
     620  $psphotConfig = $psphotConfig -Df PSPHOT:PSF_FIT_RADIUS_SCALE 3.75
     621  $psphotConfig = $psphotConfig -Df PSPHOT:EXT_FIT_NSIGMA_CONV $NSIGMA_CONV
    509622
    510623  # ppImage / psphot on the output
     
    516629end
    517630
     631macro cmf.load.reset
     632  $fields = X Y M T R r MT I
     633  foreach field $fields
     634    foreach set in ot
     635      delete -q $field\$set\_s
     636    end
     637  end
     638
     639  delete -q min_S Min_S
     640end
     641
    518642macro cmf.load.concat
    519643  if ($0 != 4)
    520     echo "USAGE: cmf.load.concat (dat) (cmf) (type)"
     644    echo "USAGE: cmf.load.concat (dat) (cmf) (inType)"
    521645    break
    522646  end
     
    525649  read Xin_all 1 Yin_all 2 Fin_all 3 Type 4 Min_all 5 RmajIn_all 7 RminIn_all 8 ThetaIn_all 9 IndexIn_all 10
    526650
     651  $TYPE_S = 83
     652  $TYPE_D = 68
     653  $TYPE_E = 69
     654  if ("$3" == "SERSIC")
     655    $InType = $TYPE_S
     656  end
     657  if ("$3" == "DEV")
     658    $InType = $TYPE_D
     659    set IndexIn_all = 0.125 + zero(Xin_all)
     660  end
     661  if ("$3" == "EXP")
     662    $InType = $TYPE_E
     663    set IndexIn_all = 0.5 + zero(Xin_all)
     664  end
     665
     666  # select only the galaxies
    527667  subset Xin = Xin_all if (Type == 1)
    528668  subset Yin = Yin_all if (Type == 1)
     
    539679  subset IndexIn = IndexIn_all if (Type == 1)
    540680
    541   $TYPE_S = 83
    542   $TYPE_D = 68
    543   $TYPE_E = 69
    544   if ("$3" == "SERSIC")
    545     $InType = $TYPE_S
    546   end
    547   if ("$3" == "DEV")
    548     $InType = $TYPE_D
    549   end
    550   if ("$3" == "EXP")
    551     $InType = $TYPE_E
    552   end
    553 
    554681  data $2
    555682
    556683  break -auto off
     684  output -err /dev/null
    557685  read -fits Chip.xfit X_EXT Y_EXT EXT_INST_MAG EXT_WIDTH_MAJ EXT_WIDTH_MIN EXT_THETA MODEL_TYPE EXT_PAR_07
    558686  $reread = not($STATUS)
     687  output -err stderr
    559688  break -auto on
    560689  if ($reread)
    561690    read -fits Chip.xfit X_EXT Y_EXT EXT_INST_MAG EXT_WIDTH_MAJ EXT_WIDTH_MIN EXT_THETA MODEL_TYPE
    562     set EXT_PAR_07 = (MODEL_TYPE:9 == 68)*4 + (MODEL_TYPE:9 == 69)
     691    set EXT_PAR_07 = (MODEL_TYPE:9 == 68)*0.125 + (MODEL_TYPE:9 == 69)*0.5
    563692  end
    564693
     
    589718  reindex rin_m = RminIn using index2
    590719 
    591   if ("$3" == "SERSIC")
    592     reindex Iot_m = EXT_PAR_07 using index1
    593     reindex Iin_m = IndexIn using index2
    594    $fields = X Y M T R r MT I
    595   else
    596    $fields = X Y M T R r MT
    597   end
     720  reindex Iot_m = EXT_PAR_07 using index1
     721  reindex Iin_m = IndexIn using index2
     722  $fields = X Y M T R r MT I
    598723 
    599724  foreach field $fields
     
    605730  concat min min_S
    606731  concat Min Min_S
     732end
     733
     734macro cmf.load.stars.concat
     735  if ($0 != 3)
     736    echo "USAGE: cmf.load.concat (dat) (cmf)"
     737    break
     738  end
     739
     740  data $1
     741  read Xin_all 1 Yin_all 2 Type 4 Min_all 5 RmajIn_all 7 RminIn_all 8 ThetaIn_all 9 IndexIn_all 10
     742
     743  subset Xin     = Xin_all     if (Type == 0)
     744  subset Yin     = Yin_all     if (Type == 0)
     745  subset Min     = Min_all     if (Type == 0)
     746  subset RmajIn  = RmajIn_all  if (Type == 0)
     747  subset RminIn  = RminIn_all  if (Type == 0)
     748  subset IndexIn = IndexIn_all if (Type == 0)
     749  subset Tin_rad = ThetaIn_all if (Type == 0)
     750  set Tin = Tin_rad * 180 / 3.14159265
     751
     752  data $2
     753
     754  break -auto off
     755  read -fits Chip.psf X_PSF Y_PSF PSF_INST_MAG PSF_MAJOR PSF_MINOR PSF_THETA
     756  set PSF_THETA_ALT = PSF_THETA * (PSF_THETA >= 0.0) + (PSF_THETA + 3.14159265) * (PSF_THETA < 0.0)
     757  set PSF_THETA = PSF_THETA_ALT * 180 / 3.14159265
     758 
     759  match2d X_PSF Y_PSF Xin Yin 1.0 -index1 index1 -index2 index2
     760
     761  reindex Xot_m = X_PSF using index1
     762  reindex Yot_m = Y_PSF using index1
     763
     764  reindex Xin_m = Xin using index2
     765  reindex Yin_m = Yin using index2
     766
     767  reindex Mot_m = PSF_INST_MAG using index1
     768  reindex Tot_m = PSF_THETA using index1
     769
     770  reindex Min_m = Min using index2
     771  reindex Tin_m = Tin using index2
     772
     773  reindex Rot_m = PSF_MAJOR using index1
     774  reindex rot_m = PSF_MINOR using index1
     775
     776  reindex Rin_m = RmajIn using index2
     777  reindex rin_m = RminIn using index2
     778 
     779  $fields = X Y M T R r
     780  foreach field $fields
     781    foreach set in ot
     782      concat $field\$set\_m $field\$set\_s
     783    end
     784  end
    607785end
    608786
     
    10781256
    10791257macro load.normdata
    1080   if ($0 != 2)
    1081     echo "USAGE: load.normdata (file)"
     1258  if ($0 != 3)
     1259    echo "USAGE: load.normdata (file) [clear/noclear]"
    10821260    break
    10831261  end
     
    10901268  set dm = mg - Mg
    10911269  set n = ramp(dm)
    1092   lim n dm; clear; box; plot n dm
     1270  if ("$2" == "clear")
     1271    lim n dm; clear; box;
     1272  end
     1273  plot n dm
    10931274end
    10941275
     
    10971278  exit 0
    10981279end
     1280
     1281# note that t1 = original confi
     1282# t2 = no residuals
     1283# t3 = const weight PSF fit
     1284# t4 = const weight galaxy fits
     1285
     1286macro run.radius.loop
     1287  local radius Nrun
     1288
     1289  if (1)
     1290    $Nrun = 0
     1291    foreach radius 1.0 1.5 2.0 2.5 3.0 4.0 6.0 8.0
     1292      mkexp.devexp.single tests.20131120/testrad.ps1v1.exp.$Nrun EXP $radius 1.0
     1293      fitexp tests.20131120/testrad.ps1v1.exp.$Nrun tests.20131120/testrad.ps1v1.exp.$Nrun.t4b EXP_CONV
     1294      $Nrun ++
     1295    end
     1296  end
     1297
     1298  $Nrun = 0
     1299  foreach radius 1.0 1.5 2.0 2.5 3.0 4.0 6.0 8.0
     1300    cmf.load.concat tests.20131120/testrad.ps1v1.exp.$Nrun.dat tests.20131120/testrad.ps1v1.exp.$Nrun.t4b.cmf EXP
     1301    echo -no-return $radius ""
     1302    check.fit tests.20131120/testrad.ps1v1.exp.$Nrun.dat tests.20131120/testrad.ps1v1.exp.$Nrun.t4b.cmf EXP
     1303    $Nrun ++
     1304  end
     1305
     1306  grid.plots.devexp a
     1307end
     1308
     1309macro check.radius.loop
     1310  if ($0 != 2)
     1311    echo "USAGE: check.radius.loop (ext)"
     1312    break
     1313  end
     1314
     1315  # cmf.load.reset
     1316
     1317  local radius Nrun
     1318
     1319  $Nrun = 0
     1320  foreach radius 1.0 1.5 2.0 2.5 3.0 4.0 6.0 8.0
     1321    echo -no-return $radius ""
     1322    check.fit tests.20131120/testrad.ps1v1.exp.$Nrun.dat tests.20131120/testrad.ps1v1.exp.$Nrun.$1.cmf EXP
     1323    $Nrun ++
     1324  end
     1325
     1326  grid.plots.devexp a
     1327end
     1328
     1329macro check.fit
     1330  if ($0 != 4)
     1331    echo "USAGE: check.fit (dat) (cmf) (type)"
     1332    break
     1333  end
     1334
     1335  cmf.load.concat $1 $2 $3
     1336  set dM_m = Mot_m - Min_m
     1337  vstat -q dM_m
     1338  $mag_off = $MEDIAN
     1339  set dR_m = Rot_m - Rin_m
     1340  vstat -q dR_m
     1341  $rad_off = $MEDIAN
     1342  echo $mag_off $rad_off
     1343end
     1344
     1345macro make.circles
     1346
     1347  delete Xo Yo Ro
     1348
     1349  for ix 0 16
     1350    for iy $ix 16
     1351      $r2 = $ix^2 + $iy^2
     1352      if ($r2 > 15^2) continue
     1353      concat $ix Xo
     1354      concat $iy Yo
     1355      concat $r2 Ro
     1356    end
     1357  end
     1358
     1359  sort Ro Xo Yo
     1360  $Rold = -1
     1361  $N = -1
     1362  for i 0 Ro[]
     1363    if (Ro[$i] != $Rold)
     1364      $N ++
     1365      $Rold = Ro[$i]
     1366    end
     1367    if ((Xo[$i] == 0) && (Yo[$i] == 0))
     1368      fprintf "// center is 0,0"
     1369      continue
     1370    end
     1371    if (Xo[$i] == 0)
     1372      fprintf "ADD_AXIS (%3d, %2d)     // r^2 = %3d" $N Yo[$i] Ro[$i]
     1373      continue
     1374    end
     1375    if (Xo[$i] == Yo[$i])
     1376      fprintf "ADD_DIAG (%3d, %2d)     // r^2 = %3d" $N Xo[$i] Ro[$i]
     1377      continue
     1378    end
     1379
     1380    fprintf "ADD_RAND (%3d, %2d, %2d) // r^2 = %3d" $N Xo[$i] Yo[$i] Ro[$i]
     1381 end
     1382end
     1383
     1384# EXP : tests.20131120/test.nsig
     1385# DEV : tests.20131120/test.dev
     1386
     1387# run.convolve.loop tests.20131120/test.nsig tests.20131120/test.nsig   EXP EXP_CONV
     1388# run.convolve.loop tests.20131120/test.dev  tests.20131120/test.dev    DEV DEV_CONV
     1389# run.convolve.loop tests.20131120/test.nsig tests.20131120/test.serexp EXP SER_CONV
     1390# run.convolve.loop tests.20131120/test.dev  tests.20131120/test.serdev DEV SER_CONV
     1391
     1392macro run.convolve.loop
     1393  if ($0 != 5)
     1394    echo "run.convolve.loop (inName) (fitName) (inType) (fitType)"
     1395    break
     1396  end
     1397
     1398  local radius
     1399  $radius = 3.0
     1400  cmf.load.reset
     1401
     1402  # foreach Cin 3 5 7 9 11
     1403  foreach Cin 11
     1404    $CONVOLVE_NSIGMA = $Cin
     1405    sprintf nameIn %s.%02d $1 $Cin
     1406    mkexp.devexp.single $nameIn $3 $radius 1.0
     1407    foreach Cot 3 5 7 9 11
     1408      $NSIGMA_CONV = $Cot
     1409      sprintf nameOt %s.%02d.%02d $2 $Cin $Cot
     1410      fitexp $nameIn $nameOt $4
     1411    end
     1412  end
     1413
     1414  # foreach Cin 3 5 7 9 11
     1415  foreach Cin 11
     1416    sprintf nameIn %s.%02d $1 $Cin
     1417    foreach Cot 3 5 7 9 11
     1418      sprintf nameOt %s.%02d.%02d $2 $Cin $Cot
     1419      check.fit $nameIn.dat $nameOt.cmf
     1420    end
     1421  end
     1422  grid.plots.devexp a
     1423end
     1424
     1425macro check.convolve.loop
     1426  if ($0 != 4)
     1427    echo "run.convolve.loop (inName) (fitName) (inType)"
     1428    break
     1429  end
     1430
     1431  local radius
     1432  $radius = 3.0
     1433  cmf.load.reset
     1434
     1435  # foreach Cin 3 5 7 9 11
     1436  foreach Cin 11
     1437    sprintf nameIn %s.%02d $1 $Cin
     1438    foreach Cot 3 5 7 9 11
     1439      sprintf nameOt %s.%02d.%02d $2 $Cin $Cot
     1440      echo -no-return $Cin $Cot " "
     1441      check.fit $nameIn.dat $nameOt.cmf $3
     1442    end
     1443  end
     1444  grid.plots.devexp a
     1445end
Note: See TracChangeset for help on using the changeset viewer.