IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Apr 21, 2014, 5:42:34 AM (12 years ago)
Author:
eugene
Message:

merge changes from trunk

Location:
branches/eam_branches/ps2-tc3-20130727
Files:
36 edited
14 copied

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ps2-tc3-20130727

  • branches/eam_branches/ps2-tc3-20130727/psphot

    • Property svn:mergeinfo deleted
  • branches/eam_branches/ps2-tc3-20130727/psphot/src

  • branches/eam_branches/ps2-tc3-20130727/psphot/src/Makefile.am

    r34317 r36680  
    2525libpsphot_la_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
    2626
    27 bin_PROGRAMS = psphot psphotForced psphotMinimal psphotMakePSF psphotStack psphotModelTest
     27bin_PROGRAMS = psphot psphotForced psphotFullForce psphotFullForceSummary 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
     42psphotFullForceSummary_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
     43psphotFullForceSummary_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
     44psphotFullForceSummary_LDADD = libpsphot.la
     45
    3846psphotMinimal_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
    3947psphotMinimal_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
     
    5159psphotModelTest_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
    5260psphotModelTest_LDADD = libpsphot.la
     61
     62psmakecff_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
     63psmakecff_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
     64psmakecff_LDADD = libpsphot.la
     65
    5366
    5467# psphotMomentsStudy_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
     
    8194        psphotMosaicChip.c         \
    8295        psphotCleanup.c
     96
     97# generalized forced photometry (including Kron, Petro, and Models) of specified positions given a specified psf
     98psphotFullForce_SOURCES = \
     99        psphotFullForce.c             \
     100        psphotFullForceArguments.c    \
     101        psphotParseCamera.c        \
     102        psphotImageLoop.c          \
     103        psphotMosaicChip.c         \
     104        psphotCleanup.c
     105
     106# combine full force results from several inputs
     107psphotFullForceSummary_SOURCES = \
     108        psphotFullForceSummary.c \
     109        psphotFullForceSummaryReadout.c
    83110
    84111# forced photometry of specified positions given a specified psf
     
    129156        psphotCleanup.c
    130157
     158# a program that takes a cmf file and makes a cff file (input file for psphotFullForce
     159psmakecff_SOURCES = \
     160        psmakecff.c
     161
    131162# psphotTest_SOURCES = \
    132163#         psphotTest.c
     
    155186        psphotReadoutMinimal.c         \
    156187        psphotForcedReadout.c          \
     188        psphotFullForceReadout.c       \
     189        psphotFullForce.SourceStats.c \
    157190        psphotMakePSFReadout.c         \
    158191        psphotModelBackground.c        \
     
    175208        psphotMakeGrowthCurve.c        \
    176209        psphotMagnitudes.c             \
     210        psphotLensing.c        \
    177211        psphotSetMaskBits.c            \
    178212        psphotSkyReplace.c             \
     
    181215        psphotSourceFits.c             \
    182216        psphotRadiusChecks.c           \
     217        psphotChooseAnalysisOptions.c  \
    183218        psphotOutput.c                 \
    184219        psphotFakeSources.c            \
     
    198233        psphotRadialPlot.c             \
    199234        psphotKronIterate.c            \
     235        psphotKronFlux.c            \
     236        psphotPetroFlux.c            \
     237        psphotGalaxyShape.c            \
    200238        psphotRadialProfileWings.c     \
    201239        psphotDeblendSatstars.c        \
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphot.h

    r35769 r36680  
    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);
     
    122126bool            psphotAddOrSubNoise_Threaded (psThreadJob *job);
    123127
     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);
     131
    124132bool            psphotExtendedSourceAnalysis (pmConfig *config, const pmFPAview *view, const char *filerule);
    125133bool            psphotExtendedSourceAnalysisReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe);
     
    136144bool            psphotMagnitudesReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, pmReadout *readout, psArray *sources, pmPSF *psf);
    137145bool            psphotMagnitudes_Threaded (psThreadJob *job);
     146
     147bool            psphotLensing (pmConfig *config, const pmFPAview *view, const char *filerule);
     148bool            psphotLensingReadout(pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe);
     149bool            psphotLensingPSFtrendsReadout(pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe);
    138150
    139151bool            psphotEfficiency (pmConfig *config, const pmFPAview *view, const char *filerule);
     
    341353bool psphotForcedReadout(pmConfig *config, const pmFPAview *view, const char *filerule);
    342354
     355pmConfig *psphotFullForceArguments(int argc, char **argv);
     356bool psphotFullForceReadout(pmConfig *config, const pmFPAview *view, const char *filerule);
     357
    343358pmConfig *psphotMinimalArguments(int argc, char **argv);
    344359bool psphotReadoutMinimal(pmConfig *config, const pmFPAview *view, const char *filerule);
     
    349364pmConfig *psphotModelTestArguments(int argc, char **argv);
    350365bool psphotModelTestReadout(pmConfig *config, const pmFPAview *view, const char *filerule);
     366
     367bool psphotFullForceSummaryReadout (pmConfig * config, const pmFPAview *view);
    351368
    352369int psphotFileruleCount(const pmConfig *config, const char *filerule);
     
    414431} psphotStackOptions;
    415432
     433typedef struct {
     434    float fRmajorMin;
     435    float fRmajorMax;
     436    float fRmajorDel;
     437    float fRminorMin;
     438    float fRminorMax;
     439    float fRminorDel;
     440} psphotGalaxyShapeOptions;
     441
    416442/*** psphotStackMatchPSF prototypes ***/
    417443bool psphotStackMatchPSFs (pmConfig *config, const pmFPAview *view);
     
    475501bool psphotSourceChildren (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc);
    476502bool psphotSourceChildrenReadout (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc, int index);
    477 psArray *psphotSourceChildrenByObject (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objectsSrc);
     503psArray *psphotSourceChildrenByObject (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objectsSrc, bool sourcesSubtracted);
    478504
    479505bool psphotSourceParents (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc);
     
    496522bool psphotKronIterateReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char * filerule, pmReadout *readout, psArray *sources, pmPSF *psf, int index, int pass);
    497523bool psphotKronIterate_Threaded (psThreadJob *job);
     524
     525bool psphotKronFlux (pmConfig *config, const pmFPAview *view, const char *filerule);
     526bool psphotKronFluxReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char *filerule, pmReadout *readout, psArray *sources);
     527bool psphotKronFlux_Threaded (psThreadJob *job);
     528bool psphotKronFluxSource (pmSource *source, psImageMaskType maskVal);
     529
     530bool psphotPetroFlux (pmConfig *config, const pmFPAview *view, const char *filerule);
     531bool psphotPetroFluxReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char * filerule, pmReadout *readout, psArray *sources);
     532bool psphotPetroFlux_Threaded (psThreadJob *job);
     533bool psphotPetroFluxSource (pmSource *source, psImageMaskType maskVal);
     534
     535bool psphotGalaxyShape (pmConfig *config, const pmFPAview *view, const char *filerule);
     536bool psphotGalaxyShapeReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char * filerule, pmReadout *readout, psArray *sources, pmPSF *psf);
     537bool psphotGalaxyShape_Threaded (psThreadJob *job);
     538bool psphotGalaxyShapeGrid (pmSource *source, pmSourceFitOptions *fitOptions, psphotGalaxyShapeOptions *opt, psImageMaskType maskVal, int psfSize);
     539bool psphotGalaxyShapeSource (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, int psfSize, bool saveResults);
     540psphotGalaxyShapeOptions *psphotGalaxyShapeOptionsAlloc();
    498541
    499542bool psphotRadialProfileWings (pmConfig *config, const pmFPAview *view, const char *filerule);
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotApResid.c

    r34404 r36680  
    214214
    215215        // XXX make this user-configurable?
    216         if (source->psfMagErr > 0.01) continue;
     216        if (source->psfMagErr > 0.03) continue;
    217217
    218218        // aperture residual for this source
     
    267267
    268268    // set the max order (0 = constant) which the number of psf stars can support:
    269     // rule of thumb: require 3 stars per 'cell' (order+1)^2
     269    // we require only 3 stars for n = 0, increase stars / cell for higher order
    270270    int MaxOrderForStars = 0;
    271     if (Npsf >= 12) MaxOrderForStars = 1; // 4 cells
    272     if (Npsf >= 27) MaxOrderForStars = 2; // 9 cells
    273     if (Npsf >= 48) MaxOrderForStars = 3; // 16 cells
    274     if (Npsf >  75) MaxOrderForStars = 4; // 25 cells
     271    if (Npsf >=  16) MaxOrderForStars = 1; // 4 cells
     272    if (Npsf >=  54) MaxOrderForStars = 2; // 9 cells
     273    if (Npsf >= 128) MaxOrderForStars = 3; // 16 cells
     274    if (Npsf >= 300) MaxOrderForStars = 4; // 25 cells
     275    if (Npsf >  576) MaxOrderForStars = 5; // 36 cells
    275276
    276277    pmTrend2DMode mode = PM_TREND_MAP;
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotArguments.c

    r33690 r36680  
    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
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotBlendFit.c

    r35769 r36680  
    273273        pmSource *source = sources->data[i];
    274274
    275         int TEST_ON = false;
    276 # if (0)
     275# if (PS_TRACE_ON)
    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);
     
    342343        if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
    343344            if (psphotFitBlob (readout, source, newSources, psf, fitOptions, maskVal, markVal)) {
     345# if (PS_TRACE_ON)
    344346                if (TEST_ON) {
    345347                    psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0);
    346348                }
     349# endif
    347350                psTrace ("psphot", 5, "source at %7.1f, %7.1f is ext", source->peak->xf, source->peak->yf);
    348351                Next ++;
     
    351354        } else {
    352355            if (psphotFitBlend (readout, source, psf, fitOptions, maskVal, markVal)) {
     356# if (PS_TRACE_ON)
    353357                if (TEST_ON) {
    354358                    psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0);
    355359                }
     360# endif
    356361                source->type = PM_SOURCE_TYPE_STAR;
    357362                psTrace ("psphot", 5, "source at %7.1f, %7.1f is psf", source->peak->xf, source->peak->yf);
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotChoosePSF.c

    r35769 r36680  
    399399    char *modelName = pmModelClassGetName (psf->type);
    400400    psLogMsg ("psphot.pspsf", PS_LOG_WARN, "select psf model: %f sec\n", psTimerMark ("psphot.choose.psf"));
    401     psLogMsg ("psphot.pspsf", PS_LOG_INFO, "psf model %s, ApResid: %f +/- %f\n", modelName, psf->ApResid, psf->dApResid);
     401    psLogMsg ("psphot.pspsf", PS_LOG_INFO, "psf model %s, ApResid: %f +/- %f (%d x %d model)\n", modelName, psf->ApResid, psf->dApResid, psf->trendNx, psf->trendNy);
    402402
    403403    psFree (options);
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotCleanup.c

    r34086 r36680  
    2222    pmVisualCleanup ();
    2323    psLibFinalize();
     24#if (PS_TRACE_ON)
     25    // don't display memory leaks unless trace is on.
    2426    // fprintf (stderr, "found %d leaks at %s\n", psMemCheckLeaks (0, NULL, NULL, false), "psphot");
    2527    fprintf (stderr, "found %d leaks at %s\n", psMemCheckLeaks (0, NULL, stdout, false), "psphot");
     28#endif
    2629    return;
    2730}
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotDeblendSatstars.c

    r34708 r36680  
    128128    // int display = psphotKapaChannel (1);
    129129    // psphotVisualScaleImage (display, (psImage *) source->pixels->parent, NULL, "image", 1.0, 0);
     130
     131    int Nsatstar = 0;
    130132
    131133    // examine sources in decreasing SN order
     
    179181        source->mode2 |= PM_SOURCE_MODE2_SATSTAR_PROFILE; // and we have in fact subtracted the profile
    180182
     183        Nsatstar ++;
     184
    181185        // XXX visualize, model, and subtract
    182186        // if (!psphotVisualRadialProfileSatstar (source, maskVal)) {
     
    192196    psFree (index);
    193197
    194     psLogMsg ("psphot", PS_LOG_INFO, "deblend satstar: %f sec\n", psTimerMark ("psphot.deblend.sat"));
     198    psLogMsg ("psphot", PS_LOG_INFO, "deblend %d satstars: %f sec\n", Nsatstar, psTimerMark ("psphot.deblend.sat"));
    195199    return true;
    196200}
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotDefineFiles.c

    r34528 r36680  
    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
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotEllipticalContour.c

    r32348 r36680  
    6464        psFree (y);
    6565        psFree (yErr);
     66        source->mode2 |= PM_SOURCE_MODE2_ECONTOUR_FEW_PTS;
    6667        return false;
    6768    }
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotExtendedSourceAnalysis.c

    r34404 r36680  
    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
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotExtendedSourceFits.c

    r35769 r36680  
    111111    }
    112112
     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;
     116    }
     117
    113118    bool chisqConvergence = psMetadataLookupBool (&status, recipe, "LMM_FIT_CHISQ_CONVERGENCE"); // Fit tolerance
    114119    if (!status) {
     
    123128    }
    124129
     130    // perform full extended source non-linear fits?
     131    bool isInteractive = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_FITS_INTERACTIVE");
     132    if (!status) isInteractive = false;
     133
    125134    // Define source fitting parameters for extended source fits
    126135    pmSourceFitOptions *fitOptions = pmSourceFitOptionsAlloc();
    127     fitOptions->mode           = PM_SOURCE_FIT_EXT;
     136    fitOptions->mode           = PM_SOURCE_FIT_EXT_AND_SKY;
    128137    fitOptions->saveCovariance = true;  // XXX make this a user option?
    129138    fitOptions->covarFactor    = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix
     
    131140    fitOptions->minTol         = fitMinTol;
    132141    fitOptions->maxTol         = fitMaxTol;
     142    fitOptions->nsigma         = fitNsigmaConv;
    133143
    134144    fitOptions->gainFactorMode   = gainFactorMode;
    135145    fitOptions->chisqConvergence = chisqConvergence;
     146    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;
    136151
    137152    // maskVal is used to test for rejected pixels, and must include markVal
     
    278293            psArrayAdd(job->args, 1, cells->data[j]); // sources
    279294            psArrayAdd(job->args, 1, models);
     295
    280296            // Allocate a metadata iterator here because psMetadataIteratorAlloc/Free are not thread safe
    281297            psMetadataIterator *iter = psMetadataIteratorAlloc (models, PS_LIST_HEAD, NULL);
     
    296312            PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfail
    297313
    298 // set this to 0 to run without threading
    299 # if (1)           
    300             if (!psThreadJobAddPending(job)) {
    301                 psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
    302                 psFree(AnalysisRegion);
    303                 psFree (fitOptions);
    304                 psFree (models);
    305                 psphotSersicModelClassCleanup();
    306                 return false;
    307             }
    308 # else
    309             if (!psphotExtendedSourceFits_Threaded(job)) {
    310                 psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
    311                 psFree(AnalysisRegion);
    312                 psFree (fitOptions);
    313                 psFree (models);
    314                 psphotSersicModelClassCleanup();
    315                 return false;
     314// XXX TEST
     315            if (!isInteractive) {
     316                if (!psThreadJobAddPending(job)) {
     317                    psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     318                    psFree(AnalysisRegion);
     319                    psFree (fitOptions);
     320                    psFree (models);
     321                    psphotSersicModelClassCleanup();
     322                    return false;
     323                }
     324            } else {
     325                // run without threading
     326                if (!psphotExtendedSourceFits_Threaded(job)) {
     327                    psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     328                    psFree(AnalysisRegion);
     329                    psFree (fitOptions);
     330                    psFree (models);
     331                    psphotSersicModelClassCleanup();
     332                    return false;
     333                }
     334                psScalar *scalar = NULL;
     335                scalar = job->args->data[9];
     336                Next += scalar->data.S32;
     337                scalar = job->args->data[10];
     338                Nconvolve += scalar->data.S32;
     339                scalar = job->args->data[11];
     340                NconvolvePass += scalar->data.S32;
     341                scalar = job->args->data[12];
     342                Nplain += scalar->data.S32;
     343                scalar = job->args->data[13];
     344                NplainPass += scalar->data.S32;
     345                scalar = job->args->data[14];
     346                Nfaint += scalar->data.S32;
     347                scalar = job->args->data[15];
     348                Nfail += scalar->data.S32;
     349                psFree(job->args->data[3]); // iterator allocated above
     350                psFree(job);
    316351            }
    317             psScalar *scalar = NULL;
    318             scalar = job->args->data[9];
    319             Next += scalar->data.S32;
    320             scalar = job->args->data[10];
    321             Nconvolve += scalar->data.S32;
    322             scalar = job->args->data[11];
    323             NconvolvePass += scalar->data.S32;
    324             scalar = job->args->data[12];
    325             Nplain += scalar->data.S32;
    326             scalar = job->args->data[13];
    327             NplainPass += scalar->data.S32;
    328             scalar = job->args->data[14];
    329             Nfaint += scalar->data.S32;
    330             scalar = job->args->data[15];
    331             Nfail += scalar->data.S32;
    332             psFree(job->args->data[3]); // iterator allocated above
    333             psFree(job);
    334 # endif
    335352        }
    336353
     
    418435    // psTraceSetLevel ("psLib.math.psMinimizeLMChi2_Alt", 5);
    419436
     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
    420445    // choose the sources of interest
    421446    for (int i = 0; i < sources->n; i++) {
     
    423448        pmSource *source = sources->data[i];
    424449
    425         // skip PSF-like and non-astronomical objects
    426         if (!(source->mode & PM_SOURCE_MODE_EXT_LIMIT)) continue;
    427         if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
    428         if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
    429 
    430         // skip saturated stars modeled with a radial profile
    431         if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue;
    432 
    433         // 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?)
    434455        if (source->peak->x < region->x0) continue;
    435456        if (source->peak->y < region->y0) continue;
    436457        if (source->peak->x > region->x1) continue;
    437458        if (source->peak->y > region->y1) continue;
    438 
    439 
    440         // XXX for a test, just do the obvious trail
    441         // XXX if (source->peak->xf < 1100) continue;
    442         // XXX if (source->peak->xf > 1400) continue;
    443         // XXX if (source->peak->yf >  245) continue;
    444459
    445460        // replace object in image
     
    452467        psphotSetRadiusMomentsExact(&fitRadius, &windowRadius, readout, source, markVal); // NOTE : 6 allocs
    453468
    454         // XXX WATCH OUT HERE!!
    455         // fitRadius = 30;
    456 
    457469        // UPDATE : we have changed the moments calculation.  There is now an iteration within
    458470        // psphotKronMasked to determine moments appropriate for a larger object.  The values
     
    464476            source->modelFits = psArrayAllocEmpty (models->list->n);
    465477        }
     478
     479# ifdef TEST_OBJECT
     480        bool testObject = false;
     481        testObject |= ((fabs(source->peak->xf -  179) < 5) && (fabs(source->peak->yf - 1138) < 5));
     482        if (testObject) {
     483            fprintf (stderr, "test object @ %f, %f\n", source->peak->xf, source->peak->yf);
     484            psTraceSetLevel ("psModules.objects.pmPCM_MinimizeChisq", 5);
     485            psTraceSetLevel ("psphot.psphotExtendedSourceFits_Threaded", 5);
     486        }
     487# endif
    466488
    467489        // loop here over the models chosen for each source (exclude by S/N)
     
    479501          assert (status);
    480502
    481           // limit selection to some SN limit
    482           bool skipSource = false;
    483           if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
    484               skipSource = (source->moments->KronFlux < FIT_SN_LIM * source->moments->KronFluxErr);
    485           } else {
    486               skipSource = (sqrt(source->peak->detValue) < FIT_SN_LIM);
    487           }
    488           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) {
    489506              Nfaint ++;
    490507              continue;
     508            }
    491509          }
     510
     511          source->mode2 |= PM_SOURCE_MODE2_EXT_FITS_RUN;
    492512
    493513          // check on the model type
     
    507527                  psTrace ("psphot", 5, "failed to fit psf-conv model for object at %f, %f", source->moments->Mx, source->moments->My);
    508528                  Nfail ++;
     529                  source->mode2 |= PM_SOURCE_MODE2_EXT_FITS_FAIL;
    509530                  continue;
    510531              }
     
    512533                       source->moments->Mx, source->moments->My, pmModelClassGetName (modelFit->type), modelFit->chisq, modelFit->nPix, modelFit->nIter);
    513534              Nconvolve ++;
    514               if (!(modelFit->flags & (PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE))) {
     535              if (!(modelFit->flags & badModel)) {
    515536                  NconvolvePass ++;
    516537                  source->mode |= PM_SOURCE_MODE_EXTENDED_FIT;
     
    526547                      Nfail ++;
    527548                      doneFits = true;
     549                      source->mode2 |= PM_SOURCE_MODE2_EXT_FITS_FAIL;
    528550                      continue;
    529551                  }
    530552                  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);
    531553                  Nplain ++;
    532                   if (!(modelFit->flags & (PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE))) {
     554                  if (!(modelFit->flags & badModel)) {
    533555                      NplainPass ++;
    534556                      source->mode |= PM_SOURCE_MODE_EXTENDED_FIT;
     
    544566                      float Ymax = PAR[PM_PAR_YPOS] + 0.5*PAR[PM_PAR_LENGTH]*cos(PAR[PM_PAR_THETA]);
    545567
    546                       if (false && (source->peak->xf > 1100) &&
    547                           (source->peak->xf < 1400) &&
    548                           (source->peak->yf < 245)) {
     568                      if ((fabs(source->peak->xf - 2572) < 20) && (fabs(source->peak->yf - 5874) < 20)) {
    549569                          fprintf (stderr, "src vs fit : %d %d - %d %d | %f %f - %f %f\n",
    550570                                   source->pixels->col0, source->pixels->row0,
     
    556576                          fprintf (stderr, "update window : %f %f : %f -> %f\n", source->peak->xf, source->peak->yf, fitRadius, 2*fitRadius);
    557577                          psphotSetWindowTrail (&fitRadius, &windowRadius, readout, source, markVal, fitRadius*2.0);
     578                          source->mode2 |= PM_SOURCE_MODE2_EXT_FITS_RETRY;
    558579                      }
    559580                  }
    560581              }
    561582          }
    562           // XXX really need to do this in a cleaner way:
    563           if (!modelFit) continue;
     583          psAssert (modelFit, "modelFit not set?");
    564584
    565585          // test for fit quality / result
     
    570590        }
    571591
     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
    572602        // evaluate the relative quality of the models, choose one
     603        // the PSF model might be the best fit : allow it to succeed
    573604        float minChisq = NAN;
    574605        int minModel = -1;
     
    576607            pmModel *model = source->modelFits->data[i];
    577608
     609            // skip the really bad fits
    578610            if (!(model->flags & PM_MODEL_STATUS_FITTED)) continue;
    579 
    580             if (model->flags & (PM_MODEL_STATUS_BADARGS)) continue;
    581             if (model->flags & (PM_MODEL_STATUS_NONCONVERGE)) continue;
    582             if (model->flags & (PM_MODEL_STATUS_OFFIMAGE)) continue;
     611            if (model->flags & badModel) continue;
     612
     613            // if (model->flags & (PM_MODEL_STATUS_NONCONVERGE)) continue;
    583614
    584615            if ((minModel < 0) || (model->chisq < minChisq)) {
     
    598629          pmSourceCacheModel (source, maskVal);
    599630
     631# if (PS_TRACE_ON)
     632          pmModel *model = source->modelFits->data[0];
     633          int flags = 0xffffffff;
     634          if (model) {
     635            flags = model->flags;
     636          }
     637          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
    600639          pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    601640
     641          source->mode2 |= PM_SOURCE_MODE2_EXT_FITS_NONE;
    602642          continue;
    603643        }
     
    615655        // cache the model flux
    616656        if (source->modelEXT->isPCM) {
    617             pmPCMCacheModel (source, maskVal, psfSize);
     657            // fprintf (stderr, "subtract PCM extended source model for object %d @ %f, %f\n", source->id, source->moments->Mx, source->moments->My);
     658            pmPCMCacheModel (source, maskVal, psfSize, fitOptions->nsigma);
    618659        } else {
     660            // fprintf (stderr, "subtract non-PCM extended source model for object %d @ %f, %f\n", source->id, source->moments->Mx, source->moments->My);
    619661            pmSourceCacheModel (source, maskVal);
    620662        }
     663        source->modelEXT->flags |= PM_MODEL_BEST_FIT;
    621664
    622665        // subtract the best fit from the object, leave local sky
     
    625668        psTrace ("psphot", 4, "best ext model for %f, %f : %s chisq = %f\n", source->moments->Mx, source->moments->My, pmModelClassGetName (source->modelEXT->type), source->modelEXT->chisq);
    626669        psTrace ("psphot", 5, "extended source model for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
     670
     671# ifdef TEST_OBJECT
     672        if (testObject) {
     673            psTraceSetLevel ("psModules.objects.pmPCM_MinimizeChisq", 0);
     674            psTraceSetLevel ("psphot.psphotExtendedSourceFits_Threaded", 0);
     675        }
     676# endif
    627677    }
    628678
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotImageLoop.c

    r34258 r36680  
    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")) {
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotKronIterate.c

    r35769 r36680  
    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
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotLoadPSF.c

    r29936 r36680  
    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 }
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotMergeSources.c

    r34266 r36680  
    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}
     
    812842// array containing the child sources.  XXX currently, this is only used by psphotStackReadout
    813843// (sources go on allSources so that psphotChoosePSF can be called repeatedly)
    814 psArray *psphotSourceChildrenByObject (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objectsSrc) {
     844psArray *psphotSourceChildrenByObject (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objectsSrc, bool sourcesSubtracted) {
    815845
    816846    bool status;
     
    919949            // child sources have not been subtracted in this image, but this flag may be raised if
    920950            // they were subtracted in the parent's image
    921             sourceOut->tmpFlags &= ~PM_SOURCE_TMPF_SUBTRACTED;
     951            // XXX NOTE : in the pre-20130914 version of psphotStack, we carried a copy of the pixels
     952            // generated before the subtraction took place (and then we smoothed to match the desired PSF). 
     953            // in the new version, we copy the image after subtraction; we need to distinguish these cases
     954            if (!sourcesSubtracted) {
     955                sourceOut->tmpFlags &= ~PM_SOURCE_TMPF_SUBTRACTED;
     956            }
    922957
    923958            // set the output detections:
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotModelTestReadout.c

    r35769 r36680  
    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
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotPetrosianRadialBins.c

    r31154 r36680  
    3636    pmSourceRadialProfile *profile = source->extpars->petProfile;
    3737
    38     float skyModelErrorSQ = PS_SQR(skynoise);
     38    // float skyModelErrorSQ = PS_SQR(skynoise);
    3939
    4040    int nMax = radiusMax;
     
    133133        if (radius->data.F32[i] > Rmax) {
    134134            // calculate the value for the nOut bin
    135             float value, dvalue;
     135            float value; // , dvalue;
    136136            if (values->n > 0) {
    137137                psVectorStats (stats, values, NULL, NULL, 0);
    138138                value = stats->robustMedian;
    139                 dvalue = stats->robustStdev;
     139                // dvalue = stats->robustStdev;
    140140            } else {
    141141                value = NAN;
    142                 dvalue = NAN;
     142                // dvalue = NAN;
    143143            }
    144144
    145145            binSB->data.F32[nOut] = value;
    146             binSBstdev->data.F32[nOut] = sqrt(PS_SQR(dvalue) / values->n + skyModelErrorSQ);
     146            // binSBstdev->data.F32[nOut] = sqrt(PS_SQR(dvalue) / values->n + skyModelErrorSQ);
     147            binSBstdev->data.F32[nOut] = skynoise / sqrt(values->n);
    147148            binFill->data.F32[nOut] = values->n / binArea->data.F32[nOut];
    148149
     
    185186        psFree(values);
    186187        psFree(stats);
     188        source->mode2 |= PM_SOURCE_MODE2_RADBIN_NAN_CENTER;
    187189        return true;
    188190    }
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotPetrosianStats.c

    r34086 r36680  
    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);
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotRadialBins.c

    r34226 r36680  
    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    }
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotRadialProfile.c

    r32348 r36680  
    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}
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotRadiusChecks.c

    r32348 r36680  
    171171# undef MIN_WINDOW
    172172
     173// XXX EAM : 20130724 : for a test, double the window size parameters
     174// # define MIN_WINDOW 10.0
     175// # define SCALE1 7.0
    173176# define MIN_WINDOW 5.0
    174 # define SCALE1 5.0
     177# define SCALE1 3.0
    175178# define PAD_WINDOW 3.0
    176179
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotReadout.c

    r34418 r36680  
    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)
     
    333340    // calculate source magnitudes
    334341    if (!psphotMagnitudes(config, view, filerule)) { // pass 1 (detections->allSources)
    335       psErrorStackPrint(stderr, "Unable to do magnitudes.");
     342        psErrorStackPrint(stderr, "Unable to do magnitudes.");
    336343        psErrorClear();
    337344    }
     345
     346    // calculate lensing parameters
     347    if (!psphotLensing(config, view, filerule)) {
     348        psErrorStackPrint(stderr, "Unable to do lensing parameters.");
     349        psErrorClear();
     350    }
     351
    338352    if (!psphotEfficiency(config, view, filerule)) { // pass 1
    339353        psErrorStackPrint(stderr, "Unable to determine detection efficiencies from fake sources");
     
    346360    // replace background in residual image
    347361    if (!psphotSkyReplace (config, view, filerule)) { // pass 1
    348       psErrorStackPrint(stderr, "Unable to replace sky");
    349       psErrorClear();
     362        psErrorStackPrint(stderr, "Unable to replace sky");
     363        psErrorClear();
    350364    }
    351365
    352366    // drop the references to the image pixels held by each source
    353367    if (!psphotSourceFreePixels (config, view, filerule)) { // pass 1
    354       psErrorStackPrint(stderr, "Unable to free source pixels");
    355       psErrorClear();
     368        psErrorStackPrint(stderr, "Unable to free source pixels");
     369        psErrorClear();
    356370    }
    357371
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotRoughClass.c

    r32348 r36680  
    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;
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotSetThreads.c

    r35769 r36680  
    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;
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotSourceFits.c

    r35769 r36680  
    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) {
     
    559562
    560563# define TIMING 0
     564# define EXTRA_VERBOSE 0
     565
     566bool psphotSersicModelGuessPCM (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, float psfSize);
     567bool psphotFitSersicShapeAndIndex (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize);
     568bool psphotFitSersicShapeAndIndexGrid (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize);
     569bool psphotFitSersicShapeAndIndexGridAuto (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize);
    561570
    562571pmModel *psphotFitPCM (pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, pmModelType modelType, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) {
     
    573582    maskVal |= markVal;
    574583
    575     // allocate the model
     584    // allocate the model (this can only fail on a config error)
    576585    pmModel *model = pmModelAlloc(modelType);
    577     if (!model) {
    578         return NULL;
    579     }
    580 
    581     float t1, t2, t4, t5;
     586    psAssert (model, "invalid extended model name");
     587
     588    float t1, t2, t3, t4, t5;
     589    t1 = t2 = t3 = t4 = t5 = 0.0;
    582590    if (TIMING) { psTimerStart ("psphotFitPCM"); }
     591
     592    // if we are ever (in a given psphot implementation) going to fit a parameter, we must set the options here to include
     593    // that parameter (otherwise pmPCMupdate will fail to allocate the dmodelFlux image)
     594    // thus, if the sersic analysis below uses an index fit, need to use this EXT_AND_SKY mode for init
     595
     596    options.mode = PM_SOURCE_FIT_EXT;
     597    if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) {
     598        options.mode = PM_SOURCE_FIT_EXT_AND_SKY;
     599    }
     600    if (modelType == pmModelClassGetType("PS_MODEL_DEV")) {
     601        options.mode = PM_SOURCE_FIT_SHAPE;
     602        options.mode = PM_SOURCE_FIT_EXT_AND_SKY;
     603    }
     604    if (modelType == pmModelClassGetType("PS_MODEL_EXP")) {
     605        options.mode = PM_SOURCE_FIT_EXT_AND_SKY;
     606    }
    583607
    584608    pmPCMdata *pcm = pmPCMinit (source, &options, model, maskVal, psfSize);
     
    594618    if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) {
    595619        // use the source moments, etc to guess basic model parameters
    596         if (!psphotSersicModelClassGuessPCM (pcm, source)) {
     620        if (!psphotSersicModelGuessPCM (pcm, source, maskVal, psfSize)) {
    597621            psFree (pcm);
    598             model->flags |= PM_MODEL_STATUS_BADARGS;
     622            model->flags |= PM_MODEL_SERSIC_PCM_FAIL_GUESS;
     623            return model;
     624        }
     625        if (TIMING) { t2 = psTimerMark ("psphotFitPCM"); }
     626
     627        // psphotFitSersicShapeAndIndex (pcm, readout, source, fitOptions, maskVal, markVal, psfSize);
     628        options.mode = PM_SOURCE_FIT_NO_INDEX;
     629        if (!psphotFitSersicShapeAndIndexGridAuto (pcm, readout, source, &options, maskVal, markVal, psfSize)) {
     630            psFree (pcm);
     631            model->flags |= PM_MODEL_SERSIC_PCM_FAIL_GRID;
     632            psError(PS_ERR_UNKNOWN, true, "Failed to find a index & shape");
     633            psErrorClear (); // clear the polynomial error
    599634            return model;
    600635        }
     
    603638        if (!pmSourceModelGuessPCM (pcm, source, maskVal, markVal)) {
    604639            psFree (pcm);
    605             model->flags |= PM_MODEL_STATUS_BADARGS;
     640            model->flags |= PM_MODEL_PCM_FAIL_GUESS;
    606641            return model;
    607642        }
    608643    }
    609644
    610     if (TIMING) { t2 = psTimerMark ("psphotFitPCM"); }
    611 
    612     if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) {
    613         options.mode = PM_SOURCE_FIT_NO_INDEX;
    614     } else {
    615         options.mode = PM_SOURCE_FIT_EXT;
    616     }
    617     // update the pcm elements if we have changed the circumstance (options.mode or source->pixels)
    618     pmPCMupdate(pcm, source, &options, model);
    619     if (TIMING) { t4 = psTimerMark ("psphotFitPCM"); }
     645    if (TIMING) { t3 = psTimerMark ("psphotFitPCM"); }
    620646
    621647    // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 5);
     
    623649    NfitIterPCM += pcm->modelConv->nIter;
    624650    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    // }
    625660    if (TIMING) { t5 = psTimerMark ("psphotFitPCM"); }
    626661
    627662    if (TIMING) {
    628663        int nPixBig = source->pixels->numCols * source->pixels->numRows;
    629         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);
    630     }
    631 
    632     // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0);
     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);
     665    }
     666    if (EXTRA_VERBOSE && !TIMING) {
     667        int nPixBig = source->pixels->numCols * source->pixels->numRows;
     668        float *PAR = model->params->data.F32;
     669        fprintf (stderr, "source %d : %f - %f %f - %f %f %f - %f | nIter: %2d, radius: %6.1f, npix: %5d of %5d, chisq %f\n", source->id, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1], model->nIter, model->fitRadius, model->nPix, nPixBig, model->chisqNorm);
     670    }
     671
    633672    psFree (pcm);
    634673
     
    748787    return true;
    749788}
     789
     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};
     800# define N_REFF_GUESS 5
     801
     802// A sersic model is very sensitive to the index.  attempt to find the index first by grid search in just the index
     803// for a sersic model, attempt to fit just the index and normalization with a modest number of iterations
     804bool psphotSersicModelGuessPCM (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, float psfSize) {
     805
     806    // we get a reasonable guess from:
     807    // * Reff = Kron R1 / Q(index) -- Q comes from Graham & Driver
     808    // * Rmajor / Rminor & Theta from moments
     809    // * Io from total Kron flux
     810
     811    // the guesses are used to fill in PAR:
     812    psF32 *PAR = pcm->modelConv->params->data.F32;
     813
     814    // convert the moments to Major,Minor,Theta
     815    psEllipseMoments moments;
     816
     817    if (!isfinite(source->moments->Mrf)) return false;
     818    if (!isfinite(source->moments->Mxx)) return false;
     819    if (!isfinite(source->moments->Mxy)) return false;
     820    if (!isfinite(source->moments->Myy)) return false;
     821
     822    moments.x2 = source->moments->Mxx;
     823    moments.y2 = source->moments->Myy;
     824    moments.xy = source->moments->Mxy;
     825   
     826    // limit axis ratio < 20.0
     827    psEllipseAxes momentAxes = psEllipseMomentsToAxes (moments, 20.0);
     828
     829    // set the model position
     830    if (!pmModelSetPosition(&PAR[PM_PAR_XPOS], &PAR[PM_PAR_YPOS], source)) {
     831      return false;
     832    }
     833
     834    // sky is zero (no longer fitted, but not yet deprecated)
     835    PAR[PM_PAR_SKY]  = 0.0;
     836
     837    // for the index loop, use Io = 1.0, use fitted values to determine Io
     838    PAR[PM_PAR_I0] = 1.0;
     839
     840    float xMin = NAN;
     841    float iMin = NAN;
     842    float sMin = NAN;
     843    float rMin = NAN;
     844
     845    // loop over index and Reff, keeping the ARatio and Theta constant?
     846    // loop over index guesses and find the best fit
     847    for (int j = 0; j < N_REFF_GUESS; j++) {
     848        for (int i = 0; i < N_INDEX_GUESS_INV; i++) {
     849            PAR[PM_PAR_7] = indexGuessInv[i];
     850
     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
     863            // generated the modelFlux
     864            // XXX note that this does not add sky to model
     865            pmPCMMakeModel (source, pcm->modelConv, pcm->nsigma, maskVal, psfSize);
     866       
     867            float YY = 0.0;
     868            float YM = 0.0;
     869            float MM = 0.0;
     870            bool usePoisson = false;
     871
     872            for (int iy = 0; iy < source->pixels->numRows; iy++) {
     873                for (int ix = 0; ix < source->pixels->numCols; ix++) {
     874                    // skip masked points
     875                    if (source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix]) {
     876                        continue;
     877                    }
     878                    // skip zero-variance points
     879                    if (source->variance->data.F32[iy][ix] == 0) {
     880                        continue;
     881                    }
     882                    // skip nan value points
     883                    if (!isfinite(source->pixels->data.F32[iy][ix])) {
     884                        continue;
     885                    }
     886
     887                    float fy = source->pixels->data.F32[iy][ix];
     888                    float fm = source->modelFlux->data.F32[iy][ix];
     889                    float wt = (usePoisson) ? 1.0 / source->variance->data.F32[iy][ix] : 1.0;
     890
     891                    YY += PS_SQR(fy) * wt;
     892                    YM += fm * fy * wt;
     893                    MM += PS_SQR(fm) * wt;
     894                }
     895            }
     896
     897            float Io = YM / MM;
     898            float Chisq = YY - 2 * Io * YM + Io * Io * MM;
     899            if (isnan(xMin) || (Chisq < xMin)) {
     900                xMin = Chisq;
     901                iMin = Io;
     902                sMin = indexGuessInv[i];
     903                rMin = reffGuess[j] / indexGuessR1q[i];
     904            }
     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            }
     909        }
     910    }
     911
     912    {
     913        psEllipseAxes guessAxes;
     914        guessAxes.major = rMin * source->moments->Mrf;
     915        guessAxes.minor = guessAxes.major * (momentAxes.minor / momentAxes.major);
     916        guessAxes.theta = momentAxes.theta;
     917
     918        if (!isfinite(guessAxes.major)) return false;
     919        if (!isfinite(guessAxes.minor)) return false;
     920        if (!isfinite(guessAxes.theta)) return false;
     921
     922        // convert the major,minor,theta to shape parameters for an Reff-like model
     923        pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true);
     924    }
     925
     926    PAR[PM_PAR_I0] = iMin;
     927    PAR[PM_PAR_7] = sMin;
     928
     929    return true;
     930}
     931
     932// we have a set of guess parameters, do a small number of iterations fitting only SHAPE then only INDEX
     933bool psphotFitSersicShapeAndIndex (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) {
     934
     935    pmModel *model = pcm->modelConv;
     936
     937    assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC"));
     938
     939    pmSourceFitOptions options = *fitOptions;
     940   
     941    for (int i = 0; i < 3; i++) {
     942      // fit EXT (not PSF) model (set/unset the pixel mask)
     943      options.mode = PM_SOURCE_FIT_SHAPE;
     944      options.nIter = 2;
     945
     946      // update the pcm elements if we have changed the circumstance (here, options.mode)
     947      pmPCMupdate(pcm, source, &options, model);
     948     
     949      pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     950      if (EXTRA_VERBOSE) {
     951        float *PAR = model->params->data.F32;
     952        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]);
     953      }
     954     
     955      // fit EXT (not PSF) model (set/unset the pixel mask)
     956      options.mode = PM_SOURCE_FIT_INDEX;
     957      // options.mode = PM_SOURCE_FIT_EXT_AND_SKY;
     958      options.nIter = 30;
     959     
     960      // update the pcm elements if we have changed the circumstance (here, options.mode)
     961      pmPCMupdate(pcm, source, &options, model);
     962     
     963      pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     964      if (EXTRA_VERBOSE) {
     965        float *PAR = model->params->data.F32;
     966        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]);
     967      }
     968    }
     969
     970    // update the pcm elements if we have changed the circumstance (here, options.mode)
     971    pmPCMupdate(pcm, source, fitOptions, model);
     972
     973    return true;
     974}
     975
     976// we have a set of guess parameters, do a small number of iterations fitting only SHAPE then only INDEX
     977bool psphotFitSersicShapeAndIndexGridAuto (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) {
     978
     979    pmModel *model = pcm->modelConv;
     980
     981    assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC"));
     982
     983    pmSourceFitOptions options = *fitOptions;
     984   
     985    psF32 *PAR = pcm->modelConv->params->data.F32;
     986
     987    options.mode = PM_SOURCE_FIT_SHAPE;
     988    options.nIter = 7;
     989   
     990    // update the pcm elements if we have changed the circumstance (here, options.mode)
     991    pmPCMupdate(pcm, source, &options, model);
     992   
     993    // we have been provided a guess at the index (P[7]) from the list of indexGuessInv
     994
     995    // find the matching indexGuessInv
     996    int nStart = -1;
     997    for (int i = 0; i < N_INDEX_GUESS_INV; i++) {
     998        if (fabs(PAR[PM_PAR_7] - indexGuessInv[i]) < 0.01) {
     999            nStart = i;
     1000            break;
     1001        }
     1002    }
     1003    if (nStart == -1) {
     1004        fprintf (stderr, "WARNING: could not find start guess %f\n", PAR[PM_PAR_7]);
     1005        return false;
     1006    }
     1007
     1008    psVector *chi2 = psVectorAllocEmpty (16, PS_TYPE_F32);
     1009    psVector *Sidx = psVectorAllocEmpty (16, PS_TYPE_F32);
     1010
     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;
     1027    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1028    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]);
     1029    psVectorAppend (Sidx, 100*PAR[PM_PAR_7]);
     1030    psVectorAppend (chi2, model->chisqNorm);
     1031
     1032    PAR[PM_PAR_7] = So;
     1033    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1034    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]);
     1035    psVectorAppend (Sidx, 100*PAR[PM_PAR_7]);
     1036    psVectorAppend (chi2, model->chisqNorm);
     1037
     1038    PAR[PM_PAR_7] = Sp;
     1039    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1040    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]);
     1041    psVectorAppend (Sidx, 100*PAR[PM_PAR_7]);
     1042    psVectorAppend (chi2, model->chisqNorm);
     1043
     1044    psPolynomial1D *poly = psPolynomial1DAlloc (PS_POLYNOMIAL_ORD, 2);
     1045    if (!psVectorFitPolynomial1D (poly, NULL, 0, chi2, NULL, Sidx)) {
     1046        psError(PS_ERR_UNKNOWN, true, "Failed to find a good chisq parabola");
     1047        psFree (chi2);
     1048        psFree (Sidx);
     1049        psFree (poly);
     1050        return false;
     1051    }
     1052
     1053    // where is the minimum of this polynomial fit?
     1054    float Smin = -0.5 * poly->coeff[1] / poly->coeff[2] / 100.0;
     1055
     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);
     1060    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
     1063
     1064    // return to the original fitting mode (fitOptions)
     1065    pmPCMupdate(pcm, source, fitOptions, model);
     1066
     1067    psFree (chi2);
     1068    psFree (Sidx);
     1069    psFree (poly);
     1070
     1071    return true;
     1072}
     1073
     1074 
     1075// we have a set of guess parameters, do a small number of iterations fitting only SHAPE then only INDEX
     1076bool psphotFitSersicShapeAndIndexGridAutoScaled (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) {
     1077
     1078    pmModel *model = pcm->modelConv;
     1079
     1080    assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC"));
     1081
     1082    pmSourceFitOptions options = *fitOptions;
     1083   
     1084    psF32 *PAR = pcm->modelConv->params->data.F32;
     1085
     1086    options.mode = PM_SOURCE_FIT_SHAPE;
     1087    options.nIter = 5;
     1088   
     1089    // update the pcm elements if we have changed the circumstance (here, options.mode)
     1090    pmPCMupdate(pcm, source, &options, model);
     1091   
     1092    float parStart[8];
     1093    for (int i = 0; i < 8; i++) parStart[i] = PAR[i];
     1094
     1095    // we start with a guess at the index (P[7])
     1096
     1097    // get chisq for P[7], P[7]*1.1, P[7]*1.25 (or *0.75 depending on the result of 1.1)
     1098
     1099    psVector *chi2 = psVectorAllocEmpty (16, PS_TYPE_F32);
     1100    psVector *Sidx = psVectorAllocEmpty (16, PS_TYPE_F32);
     1101
     1102    PAR[PM_PAR_7] = parStart[7];
     1103    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1104      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]);
     1105    psVectorAppend (Sidx, 100*PAR[PM_PAR_7]);
     1106    psVectorAppend (chi2, model->chisqNorm);
     1107
     1108    float fI = 1.1;
     1109    PAR[PM_PAR_7] = parStart[7]*fI;
     1110    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1111      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]);
     1112    psVectorAppend (Sidx, 100*PAR[PM_PAR_7]);
     1113    psVectorAppend (chi2, model->chisqNorm);
     1114
     1115    if (chi2->data.F32[1] < chi2->data.F32[0]) {
     1116      fI = 1.3;
     1117    } else {
     1118      fI = 1.0 / 1.3;
     1119    }
     1120   
     1121    PAR[PM_PAR_7] = parStart[7]*fI;
     1122    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1123      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]);
     1124    psVectorAppend (Sidx, 100*PAR[PM_PAR_7]);
     1125    psVectorAppend (chi2, model->chisqNorm);
     1126
     1127    // can we fit the 3 pts with a parabola?
     1128    int nTry = 0;
     1129    psPolynomial1D *poly = psPolynomial1DAlloc (PS_POLYNOMIAL_ORD, 2);
     1130    while (!psVectorFitPolynomial1D (poly, NULL, 0, chi2, NULL, Sidx)) {
     1131      psErrorClear (); // clear the polynomial error
     1132      if (nTry > 4) {
     1133        psError(PS_ERR_UNKNOWN, true, "Failed to find a good chisq parabola");
     1134        psFree (chi2);
     1135        psFree (Sidx);
     1136        psFree (poly);
     1137        return false;
     1138      }
     1139      fI = (fI < 1.0) ? fI / 1.3 : fI * 1.3;
     1140      PAR[PM_PAR_7] = parStart[7]*fI;
     1141      pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1142      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]);
     1143      psVectorAppend (Sidx, 100*PAR[PM_PAR_7]);
     1144      psVectorAppend (chi2, model->chisqNorm);
     1145      nTry ++;
     1146    }
     1147
     1148    // where is the minimum of this polynomial fit?
     1149    float Smin = -0.5 * poly->coeff[1] / poly->coeff[2] / 100.0;
     1150
     1151    // constrain Smin to be in a valid range (1.0 - 0.1, corresponding to 0.5 (Gauss) to 5.0 (slightly peakier than Dev)
     1152    Smin = PS_MAX(PS_MIN(Smin, 1.0), 0.1);
     1153    PAR[PM_PAR_7] = Smin;
     1154
     1155    // pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1156    // 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]);
     1157   
     1158    //// for (int i = 0; i < 8; i++) PAR[i] = parStart[i];
     1159    ////
     1160    //// for (float fI = 0.0; fI < 0.15; fI += 0.01) {
     1161    ////   PAR[PM_PAR_7] = parStart[7] - fI;
     1162    ////
     1163    ////   // fit EXT (not PSF) model (set/unset the pixel mask)
     1164    ////   
     1165    ////   pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1166    ////   if (TIMING) {
     1167    ////        float *PAR = model->params->data.F32;
     1168    ////        fprintf (stderr, "%d %f : %f - %f %f %f - %f\n", model->nIter, model->chisqNorm, PAR[7], PAR[4], PAR[5], PAR[6], PAR[1]);
     1169    ////   }
     1170    //// }
     1171
     1172    // return to the original fitting mode (fitOptions)
     1173    pmPCMupdate(pcm, source, fitOptions, model);
     1174
     1175    psFree (chi2);
     1176    psFree (Sidx);
     1177    psFree (poly);
     1178
     1179    return true;
     1180}
     1181
     1182 
     1183// we have a set of guess parameters, do a small number of iterations fitting only SHAPE then only INDEX
     1184bool psphotFitSersicShapeAndIndexGrid (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) {
     1185
     1186    pmModel *model = pcm->modelConv;
     1187
     1188    assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC"));
     1189
     1190    pmSourceFitOptions options = *fitOptions;
     1191   
     1192    psF32 *PAR = pcm->modelConv->params->data.F32;
     1193
     1194    options.mode = PM_SOURCE_FIT_SHAPE;
     1195    options.nIter = 10;
     1196   
     1197    // update the pcm elements if we have changed the circumstance (here, options.mode)
     1198    pmPCMupdate(pcm, source, &options, model);
     1199   
     1200    psVector *chi2 = psVectorAllocEmpty (16, PS_TYPE_F32);
     1201    psVector *Sidx = psVectorAllocEmpty (16, PS_TYPE_F32);
     1202
     1203    float par7[] = {0.100, 0.125, 0.150, 0.175, 0.200, 0.225, 0.250};
     1204    for (int i = 0; i < 7; i++) {
     1205      PAR[PM_PAR_7] = par7[i];
     1206      pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1207      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]);
     1208      psVectorAppend (Sidx, PAR[PM_PAR_7]);
     1209      psVectorAppend (chi2, model->chisqNorm);
     1210    }
     1211
     1212    psPolynomial1D *poly = psPolynomial1DAlloc (PS_POLYNOMIAL_ORD, 2);
     1213    if (!psVectorFitPolynomial1D (poly, NULL, 0, chi2, NULL, Sidx)) {
     1214      psError(PS_ERR_UNKNOWN, true, "Failed to find a good chisq parabola");
     1215      psFree (chi2);
     1216      psFree (Sidx);
     1217      psFree (poly);
     1218      return false;
     1219    }
     1220
     1221    // where is the minimum of this polynomial fit?
     1222    fprintf (stderr, "fit1d: %f + %f x + %f x^2\n", poly->coeff[0], poly->coeff[1], poly->coeff[2]);
     1223    float Smin = -0.5 * poly->coeff[1] / poly->coeff[2];
     1224
     1225    // constrain Smin to be in a valid range (1.0 - 0.1, corresponding to 0.5 (Gauss) to 5.0 (slightly peakier than Dev)
     1226    Smin = PS_MAX(PS_MIN(Smin, 1.0), 0.1);
     1227    PAR[PM_PAR_7] = Smin;
     1228    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1229    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]);
     1230   
     1231    //// for (int i = 0; i < 8; i++) PAR[i] = parStart[i];
     1232    ////
     1233    //// for (float fI = 0.0; fI < 0.15; fI += 0.01) {
     1234    ////   PAR[PM_PAR_7] = parStart[7] - fI;
     1235    ////
     1236    ////   // fit EXT (not PSF) model (set/unset the pixel mask)
     1237    ////   
     1238    ////   pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1239    ////   if (TIMING) {
     1240    ////        float *PAR = model->params->data.F32;
     1241    ////        fprintf (stderr, "%d %f : %f - %f %f %f - %f\n", model->nIter, model->chisqNorm, PAR[7], PAR[4], PAR[5], PAR[6], PAR[1]);
     1242    ////   }
     1243    //// }
     1244
     1245    // return to the original fitting mode (fitOptions)
     1246    pmPCMupdate(pcm, source, fitOptions, model);
     1247
     1248    psFree (chi2);
     1249    psFree (Sidx);
     1250    psFree (poly);
     1251
     1252    return true;
     1253}
     1254
     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
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotSourceSize.c

    r35180 r36680  
    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
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotSourceStats.c

    r35112 r36680  
    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        }
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotStackImageLoop.c

    r35769 r36680  
    2222
    2323    pmFPAview *view = pmFPAviewAlloc (0);
    24     pmFPAfile *inputRaw = psMetadataLookupPtr (&status, config->files, "PSPHOT.STACK.INPUT.RAW");
    25     pmFPAfile *inputCnv = psMetadataLookupPtr (&status, config->files, "PSPHOT.STACK.INPUT.CNV");
    26     pmFPAfile *input = inputRaw ? inputRaw : inputCnv;
     24    pmFPAfile *input = psMetadataLookupPtr (&status, config->files, "PSPHOT.STACK.INPUT.RAW");
    2725
    2826    if (!input) {
     
    3230
    3331    psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE);
    34     bool useRaw = psMetadataLookupBool (NULL, recipe, "PSPHOT.STACK.USE.RAW");
    35     if (useRaw && inputRaw == NULL) {
    36         psLogMsg ("psphot", 1, "PSPHOT.STACK.USE.RAW set but no raw input.");
    37         useRaw = false;
    38     }
    39 
    40     bool radial_apertures = psMetadataLookupBool(NULL, recipe, "RADIAL_APERTURES");
    41     bool match_psfs = radial_apertures;
    42     bool needConvolved = radial_apertures || !useRaw;
    43     if (!needConvolved) {
    44         pmFPAfileActivate (config->files, false, "PSPHOT.STACK.INPUT.CNV");
    45         pmFPAfileActivate (config->files, false, "PSPHOT.STACK.MASK.CNV");
    46         pmFPAfileActivate (config->files, false, "PSPHOT.STACK.VARIANCE.CNV");
    47         pmFPAfileActivate (config->files, false, "PSPHOT.STACK.PSF.CNV");
    48     }
    4932
    5033    // just load the full set of images up front except for EXPNUM which we defer
    5134    pmFPAfileActivate (config->files, false, "PSPHOT.STACK.EXPNUM.RAW");
    52     pmFPAfileActivate (config->files, false, "PSPHOT.STACK.EXPNUM.CNV");
    5335    if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) ESCAPE ("failed input for fpa in psphot.");
    5436
     
    7153                psMemDump("load");
    7254
    73                 if (match_psfs) {
    74                     // Generate the 1st PSF-matched image set (larger target PSFs are generated by smoothing this image)
    75                     if (!psphotStackMatchPSFs (config, view)) {
    76                         psError(psErrorCodeLast(), false, "failure in psphotStackMatchPSFs for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout);
    77                         psFree (view);
    78                         return false;
    79                     }
    80                 } else {
    81                     if (!psphotStackAllocateOutput (config, view, recipe)) {
    82                         psError(psErrorCodeLast(), false, "failure in psphotStackAllocateOutput for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout);
    83                         psFree (view);
    84                         return false;
    85                     }
     55                if (!psphotStackAllocateOutput (config, view, recipe)) {
     56                    psError(psErrorCodeLast(), false, "failure in psphotStackAllocateOutput for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout);
     57                    psFree (view);
     58                    return false;
    8659                }
    8760                psMemDump("stackmatch");
     
    12699
    127100    // Load the appropriate EXPNUM image
    128     pmFPAfileActivate (config->files, true, useRaw ? "PSPHOT.STACK.EXPNUM.RAW" : "PSPHOT.STACK.EXPNUM.CNV");
     101    pmFPAfileActivate (config->files, true, "PSPHOT.STACK.EXPNUM.RAW");
    129102
    130103    if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) ESCAPE ("failed input for fpa EXPNUM in psphot.");
     
    146119                if (! readout->data_exists) { continue; }
    147120
    148                 if (!psphotSetNFrames (config, view, useRaw ? inputRaw->name : inputCnv->name)) ESCAPE ("failed to setNFrames.");
     121                if (!psphotSetNFrames (config, view, input->name)) ESCAPE ("failed to setNFrames.");
    149122            }
    150123        }
     
    167140bool UpdateHeadersForReadout (pmConfig *config, pmFPAview *view) {
    168141
    169     psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE);
    170     bool useRaw = psMetadataLookupBool (NULL, recipe, "PSPHOT.STACK.USE.RAW");
    171 
    172142    int num = psphotFileruleCount(config, "PSPHOT.INPUT");
    173143
     
    179149        psAssert (output, "missing file?");
    180150
    181         pmFPAfile *inputRaw = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.RAW", i); // File of interest
    182         pmFPAfile *inputCnv = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.CNV", i); // File of interest
    183         pmFPAfile *input = useRaw ? inputRaw : inputCnv;
     151        pmFPAfile *input = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.RAW", i); // File of interest
    184152        psAssert (input, "missing input file");
    185153
     
    205173        psAssert (output, "missing file?");
    206174
    207         pmFPAfile *inputRaw = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.RAW", i); // File of interest
    208         pmFPAfile *inputCnv = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.CNV", i); // File of interest
    209         pmFPAfile *input = inputRaw ? inputRaw : inputCnv;
     175        pmFPAfile *input = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.RAW", i); // File of interest
    210176        psAssert (input, "missing input file");
    211177
     
    242208        psAssert (output, "missing file?");
    243209
    244         pmFPAfile *inputRaw = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.RAW", i); // File of interest
    245         pmFPAfile *inputCnv = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.CNV", i); // File of interest
    246         pmFPAfile *input = inputRaw ? inputRaw : inputCnv;
     210        pmFPAfile *input = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.RAW", i); // File of interest
    247211        psAssert (input, "missing input file");
    248212
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotStackMatchPSFsNext.c

    r34317 r36680  
    4343    for (int i = 0; i < num; i++) {
    4444        if (!psphotStackMatchPSFsNextReadout (config, view, filerule, i, lastSize)) {
    45             psError (PSPHOT_ERR_CONFIG, false, "failed to smooth image %s (%d) to target PSF", filerule, i);
     45            psLogMsg ("psphot", PS_LOG_INFO, "failed to smooth image %s (%d) to target PSF", filerule, i);
    4646            psImageConvolveSetThreads(oldThreads);
    4747            return false;
     
    102102
    103103    if (targetFWHM <= currentFWHM) {
    104         psError (PSPHOT_ERR_CONFIG, true, "target FWHM cannot be smaller than current FWHM");
     104        // psError (PSPHOT_ERR_CONFIG, true, "target FWHM cannot be smaller than current FWHM");
     105        psLogMsg ("psphot", PS_LOG_INFO, "target FWHM (%f) is smaller than current FWHM (%f), not smoothing\n", targetFWHM, currentFWHM);
     106        fwhmValues->data.F32[lastSize + 1] = currentFWHM;
     107        pmReadoutMaskInvalid(readout, maskVal, maskSat);
    105108        return false;
    106109    }
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotStackMatchPSFsUtils.c

    r34721 r36680  
    325325    if (deconv > deconvLimit) {
    326326        rejectReadout = true;
    327         psLogMsg("psphot", PS_LOG_WARN, "Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting image for matched psf analysis%d\n", deconv, deconvLimit, index);
     327        psLogMsg("psphot", PS_LOG_WARN, "Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting input %d for matched psf analysis\n", deconv, deconvLimit, index);
    328328    }
    329329   
  • branches/eam_branches/ps2-tc3-20130727/psphot/src/psphotStackReadout.c

    r34721 r36680  
    11# include "psphotInternal.h"
    22
     3static bool psphotStackMatchPSFsetup (pmConfig *config, const pmFPAview *view, const char *filerule, const char *fPSF);
     4static bool psphotStackMatchPSFsetupReadout (pmConfig *config, const pmFPAview *view, const char *filerule, const char *fPSF, int index);
    35static bool psphotStackLoadWCS(pmConfig *config, const pmFPAview *view, const char *filerule);
    46static void logMemStats(const char *heading);
    57
    6 // we have 3 possible real filesets:
     8// relevant filesets:
    79# define STACK_RAW "PSPHOT.STACK.INPUT.RAW"
    8 # define STACK_CNV "PSPHOT.STACK.INPUT.CNV"
    9 # define STACK_OUT "PSPHOT.STACK.OUTPUT.IMAGE"  /* the psf-matched image */
    10 
    11 // we have 3 files on which we operate:
    12 // DET (detection image)       : nominally RAW (optionally CNV?)
    13 // SRC (source analysis image) : nominally CNV (optionally RAW)
    14 // OUT (psf-matched images)    : always OUT
     10# define STACK_OUT "PSPHOT.STACK.OUTPUT.IMAGE"
     11
     12// XXX STACK_OUT currently is a copy of STACK_RAW, but should be a pointer to is as in psphot (single)
     13
     14// TEST CODE, can be removed
     15bool psphotDumpImages (pmConfig *config, const pmFPAview *view, const char *filerule, char *base) {
     16
     17    // XXX do nothing
     18    return true;
     19
     20    int num = psphotFileruleCount(config, "PSPHOT.INPUT");
     21
     22    for (int i = 0; i < num; i++) {
     23        // find the currently selected readout
     24        pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, i); // File of interest
     25        psAssert (file, "missing file?");
     26
     27        pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
     28        psAssert (readout, "missing readout?");
     29
     30        char line[256];
     31        snprintf (line, 256, "%s.%d.im.fits", base, i);
     32        psphotSaveImage (NULL, readout->image, line);
     33
     34        snprintf (line, 256, "%s.%d.wt.fits", base, i);
     35        psphotSaveImage (NULL, readout->variance, line);
     36
     37        snprintf (line, 256, "%s.%d.mk.fits", base, i);
     38        psphotSaveImage (NULL, readout->mask, line);
     39    }
     40    return true;
     41}
    1542
    1643bool psphotStackVisualFilerule(pmConfig *config, const pmFPAview *view, const char *filerule) {
     
    6794    psAssert (breakPt, "configuration error: set BREAK_POINT");
    6895
    69     // we have 3 relevant files: RAW (unconvolved), CNV (convolved stack), OUT (psf-matched stack)
    70     // select which image (RAW or CNV) is used for analysis (RAW always used for detection)
    71     bool useRaw = psMetadataLookupBool (NULL, recipe, "PSPHOT.STACK.USE.RAW");
    72     char *STACK_SRC = useRaw ? STACK_RAW : STACK_CNV;
    73     char *STACK_DET = STACK_RAW;
    74 
    7596    // load WCS
    76     if (!psphotStackLoadWCS(config, view, STACK_SRC)) {
    77         psError (PSPHOT_ERR_CONFIG, false, "trouble loading WCS for %s", STACK_SRC);
     97    if (!psphotStackLoadWCS(config, view, STACK_RAW)) {
     98        psError (PSPHOT_ERR_CONFIG, false, "trouble loading WCS for %s", STACK_RAW);
    7899        return false;
    79100    }
    80101
    81102    // set the photcode for each image
    82     if (!psphotAddPhotcode (config, view, STACK_SRC)) {
     103    if (!psphotAddPhotcode (config, view, STACK_RAW)) {
    83104        psError (PSPHOT_ERR_CONFIG, false, "trouble defining the photcode");
    84105        return false;
     
    86107
    87108    // Generate the mask and weight images (if not supplied) and set mask bits.
    88     // This also insures that all invalid pixels are masked (this is done for STACK_CNV in psphotStackMatchPSFs)
    89     if (!psphotSetMaskAndVariance (config, view, STACK_DET)) {
    90         return psphotReadoutCleanup (config, view, STACK_SRC);
    91     }
    92     if (!psphotSetMaskAndVariance (config, view, STACK_OUT)) {
    93         return psphotReadoutCleanup (config, view, STACK_SRC);
     109    if (!psphotSetMaskAndVariance (config, view, STACK_RAW)) {
     110        return psphotReadoutCleanup (config, view, STACK_RAW);
    94111    }
    95112    if (!strcasecmp (breakPt, "NOTHING")) {
    96         return psphotReadoutCleanup (config, view, STACK_SRC);
     113        return psphotReadoutCleanup (config, view, STACK_RAW);
    97114    }
    98115
    99116    // generate a background model (median, smoothed image)
    100     if (!psphotModelBackground (config, view, STACK_DET)) {
    101         return psphotReadoutCleanup (config, view, STACK_SRC);
    102     }
    103     if (!psphotSubtractBackground (config, view, STACK_DET)) {
    104         return psphotReadoutCleanup (config, view, STACK_SRC);
    105     }
    106     if (strcmp(STACK_SRC, STACK_DET)) {
    107 #define MODEL_BACKGROUND_SRC 1
    108 #ifdef MODEL_BACKGROUND_SRC
    109         // work around the fact that the background levels on the convolved
    110         // and unconvolved stacks can be different
    111         if (!psphotModelBackground (config, view, STACK_SRC)) {
    112             return psphotReadoutCleanup (config, view, STACK_SRC);
    113         }
    114 #endif
    115         if (!psphotSubtractBackground (config, view, STACK_SRC)) {
    116             return psphotReadoutCleanup (config, view, STACK_SRC);
    117         }
     117    if (!psphotModelBackground (config, view, STACK_RAW)) {
     118        return psphotReadoutCleanup (config, view, STACK_RAW);
     119    }
     120    if (!psphotSubtractBackground (config, view, STACK_RAW)) {
     121        return psphotReadoutCleanup (config, view, STACK_RAW);
    118122    }
    119123    if (!strcasecmp (breakPt, "BACKMDL")) {
    120         return psphotReadoutCleanup (config, view, STACK_SRC);
     124        return psphotReadoutCleanup (config, view, STACK_RAW);
    121125    }
    122126
    123127#ifdef MAKE_CHISQ_IMAGE
    124128    // also make the chisq detection image
    125     if (!psphotStackChisqImage(config, view, STACK_DET, STACK_SRC)) {
     129    if (!psphotStackChisqImage(config, view, STACK_RAW, STACK_RAW)) {
    126130        psError (PSPHOT_ERR_UNKNOWN, false, "failure to generate chisq image");
    127         return psphotReadoutCleanup (config, view, STACK_SRC);
     131        return psphotReadoutCleanup (config, view, STACK_RAW);
     132    }
     133    if (!strcasecmp (breakPt, "CHISQ")) {
     134        return psphotReadoutCleanup (config, view, STACK_RAW);
    128135    }
    129136#endif
    130     if (!strcasecmp (breakPt, "CHISQ")) {
    131         return psphotReadoutCleanup (config, view, STACK_SRC);
    132     }
    133137
    134138    // find the detections (by peak and/or footprint) in the image.
    135139    // This finds the detections on Chisq image as well as the individuals
    136     if (!psphotFindDetections (config, view, STACK_DET, true)) { // pass 1
    137         // this only happens if we had an error in psphotFindDetections
     140    if (!psphotFindDetections (config, view, STACK_RAW, true)) { // pass 1
    138141        psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis");
    139         return psphotReadoutCleanup (config, view, STACK_SRC);
    140     }
    141 
    142     // If DET and SRC are different images, copy the detections from DET to SRC.  This 'copy'
    143     // is just a copy of the container pointer; the sources on both DET and SRC are the same
    144     // memory objects
    145     if (strcmp(STACK_SRC, STACK_DET)) {
    146         if (!psphotCopySources (config, view, STACK_SRC, STACK_DET)) {
    147             psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis");
    148             return psphotReadoutCleanup (config, view, STACK_SRC);
    149         }
     142        return psphotReadoutCleanup (config, view, STACK_RAW);
    150143    }
    151144
    152145    // construct sources and measure basic stats (saved on detections->newSources)
    153     if (!psphotSourceStats (config, view, STACK_SRC, true)) { // pass 1
     146    if (!psphotSourceStats (config, view, STACK_RAW, true)) { // pass 1
    154147        psError(PSPHOT_ERR_UNKNOWN, false, "failure to generate sources");
    155         return psphotReadoutCleanup (config, view, STACK_SRC);
     148        return psphotReadoutCleanup (config, view, STACK_RAW);
    156149    }
    157150    if (!strcasecmp (breakPt, "PEAKS")) {
    158         return psphotReadoutCleanup (config, view, STACK_SRC);
    159     }
    160     // psphotDumpTest (config, view, STACK_SRC);
     151        return psphotReadoutCleanup (config, view, STACK_RAW);
     152    }
     153    // psphotDumpTest (config, view, STACK_RAW);
    161154    psMemDump("sourcestats");
    162155    logMemStats("sourcestats");
     
    164157    // classify sources based on moments, brightness
    165158    // only run this on detections from the input images, not chisq image
    166     if (!psphotRoughClass (config, view, STACK_SRC)) {
     159    if (!psphotRoughClass (config, view, STACK_RAW)) {
    167160        psError (PSPHOT_ERR_UNKNOWN, false, "failed to determine rough classifications");
    168         return psphotReadoutCleanup (config, view, STACK_SRC);
    169     }
    170 
    171     // If DET and SRC are different images, subtract radial profiles for the convolved
    172     // image first.  The profiles found on the convolved image will be replaced by those
    173     // found for the unconvolved image.  Downstream, in psphotFindDetections, we will
    174     // replace the the profiles (and re-subtract them) for the detection image, so we want
    175     // to keep those versions of the profiles on the sources.
    176     if (strcmp(STACK_SRC, STACK_DET)) {
    177       // find and subtract radial profile models for saturated stars (XXX change name eventually)
    178       if (!psphotDeblendSatstars (config, view, STACK_SRC)) {
     161        return psphotReadoutCleanup (config, view, STACK_RAW);
     162    }
     163
     164    // find and subtract radial profile models for saturated stars (XXX change name eventually)
     165    if (!psphotDeblendSatstars (config, view, STACK_RAW)) {
    179166        psError (PSPHOT_ERR_UNKNOWN, false, "failed on satstar deblend analysis");
    180         return psphotReadoutCleanup (config, view, STACK_SRC);
    181       }
    182     }
    183     // find and subtract radial profile models for saturated stars (XXX change name eventually)
    184     if (!psphotDeblendSatstars (config, view, STACK_DET)) {
    185         psError (PSPHOT_ERR_UNKNOWN, false, "failed on satstar deblend analysis");
    186         return psphotReadoutCleanup (config, view, STACK_SRC);
     167        return psphotReadoutCleanup (config, view, STACK_RAW);
    187168    }
    188169
    189170    // if we were not supplied a PSF model, determine the IQ stats here (detections->newSources)
    190171    // only run this on detections from the input images, not chisq image
    191     if (!psphotImageQuality (config, view, STACK_SRC)) { // pass 1
     172    if (!psphotImageQuality (config, view, STACK_RAW)) { // pass 1
    192173        psError (PSPHOT_ERR_UNKNOWN, false, "failed to measure image quality");
    193         return psphotReadoutCleanup (config, view, STACK_SRC);
     174        return psphotReadoutCleanup (config, view, STACK_RAW);
    194175    }
    195176    if (!strcasecmp (breakPt, "MOMENTS")) {
    196         return psphotReadoutCleanup (config, view, STACK_SRC);
     177        return psphotReadoutCleanup (config, view, STACK_RAW);
    197178    }
    198179
    199180    // use bright stellar objects to measure PSF
    200     if (!psphotChoosePSF (config, view, STACK_SRC, true)) { // pass 1
     181    if (!psphotChoosePSF (config, view, STACK_RAW, true)) { // pass 1
    201182        psLogMsg ("psphot", 3, "failure to construct a psf model");
    202         return psphotReadoutCleanup (config, view, STACK_SRC);
     183        return psphotReadoutCleanup (config, view, STACK_RAW);
    203184    }
    204185    if (!strcasecmp (breakPt, "PSFMODEL")) {
    205         return psphotReadoutCleanup (config, view, STACK_SRC);
     186        return psphotReadoutCleanup (config, view, STACK_RAW);
    206187    }
    207188
    208189    // merge the newly selected sources into the existing list
    209190    // NOTE: merge OLD and NEW
    210     psphotMergeSources (config, view, STACK_SRC);
     191    psphotMergeSources (config, view, STACK_RAW);
    211192
    212193    // Construct an initial model for each object, set the radius to fitRadius, set circular
    213194    // fit mask.  NOTE: only applied to sources without guess models
    214     psphotGuessModels (config, view, STACK_SRC);
     195    psphotGuessModels (config, view, STACK_RAW);
    215196
    216197    // linear PSF fit to source peaks, subtract the models from the image (in PSF mask)
    217     psphotFitSourcesLinear (config, view, STACK_SRC, false, false);
    218     psphotStackVisualFilerule(config, view, STACK_SRC);
     198    psphotFitSourcesLinear (config, view, STACK_RAW, false, false);
     199    psphotStackVisualFilerule(config, view, STACK_RAW);
    219200
    220201    // measure the radial profiles to the sky
    221     psphotRadialProfileWings (config, view, STACK_SRC);
     202    psphotRadialProfileWings (config, view, STACK_RAW);
    222203
    223204    // re-measure the kron mags with models subtracted.  this pass starts with a circular
     
    225206    // but iterates to an appropriately larger size
    226207    logMemStats("before.kron.1");
    227     psphotKronIterate(config, view, STACK_SRC, 1);
     208    psphotKronIterate(config, view, STACK_RAW, 1);
    228209    logMemStats("after.kron.1");
    229210       
    230211    // identify CRs and extended sources
    231     psphotSourceSize (config, view, STACK_SRC, true);
     212    psphotSourceSize (config, view, STACK_RAW, true);
    232213
    233214    // non-linear PSF and EXT fit to brighter sources
    234215    // replace model flux, adjust mask as needed, fit, subtract the models (full stamp)
    235     psphotBlendFit (config, view, STACK_SRC); // pass 1 (detections->allSources)
     216    psphotBlendFit (config, view, STACK_RAW); // pass 1 (detections->allSources)
    236217
    237218    // replace all sources (do NOT ignore subtraction state)
    238     psphotReplaceAllSources (config, view, STACK_SRC, false); // pass 1 (detections->allSources)
     219    psphotReplaceAllSources (config, view, STACK_RAW, false); // pass 1 (detections->allSources)
    239220
    240221    logMemStats("pass1");
     
    245226    // linear fit to include all sources (subtract again)
    246227    // NOTE : apply to ALL sources (extended + psf)
    247     // NOTE 2 : this function subtracts the models from the given filerule (SRC), not DET
    248     psphotFitSourcesLinear (config, view, STACK_SRC, true, false); // pass 2 (detections->allSources)
     228    // NOTE 2 : this function subtracts the models from the given filerule
     229    psphotFitSourcesLinear (config, view, STACK_RAW, true, false); // pass 2 (detections->allSources)
    249230
    250231    // NOTE: possibly re-measure background model here with objects subtracted / or masked
     
    252233    // NOTE: this block performs the 2nd pass low-significance PSF detection stage
    253234    {
    254         // if DET and SRC are different images, generate children sources for all sources in
    255         // the SRC image.  This operation replaces the existing DETECTION container on DET
    256         // which is currently a view to the one on SRC).  children sources go to
    257         // det->allSources
    258         if (strcmp(STACK_SRC, STACK_DET)) {
    259             psphotSourceChildren (config, view, STACK_DET, STACK_SRC);
    260 
    261             //  subtract all sources from DET (this will subtract using the psf model for SRC, which
    262             //  will somewhat oversubtract the sources -- this is OK
    263             psphotRemoveAllSources (config, view, STACK_DET, false); // do not ignore subtraction state for sources
    264         }
    265 
    266235        // add noise for subtracted objects
    267         psphotAddNoise (config, view, STACK_DET); // pass 1 (detections->allSources)
     236        psphotAddNoise (config, view, STACK_RAW); // pass 1 (detections->allSources)
    268237
    269238        // find fainter sources
    270239        // NOTE: finds new peaks and new footprints, OLD and FULL set are saved on detections
    271         psphotFindDetections (config, view, STACK_DET, false); // pass 2 (detections->peaks, detections->footprints)
     240        psphotFindDetections (config, view, STACK_RAW, false); // pass 2 (detections->peaks, detections->footprints)
    272241
    273242        // remove noise for subtracted objects (ie, return to normal noise level)
     
    276245        bool footprintsUseUnsubtracted = psMetadataLookupBool(NULL, recipe, "FOOTPRINT_USE_UNSUBTRACTED");
    277246        if (!footprintsUseUnsubtracted) {
    278             psphotSubNoise (config, view, STACK_DET); // pass 1 (detections->allSources)
     247            psphotSubNoise (config, view, STACK_RAW); // pass 1 (detections->allSources)
    279248        }
    280 
    281         // if DET and SRC are different images, copy the detections from DET to SRC
    282         // (this operation just ensures the metadata container has a view on SRC as well
    283         if (strcmp(STACK_SRC, STACK_DET)) {
    284             // replace all sources in DET
    285             psphotReplaceAllSources (config, view, STACK_DET, false); // ignore subtraction state for sources
    286 
    287             // copy the newly detected peaks from DET to SRC so SourceStats below can operate on them
    288             if (!psphotCopyPeaks (config, view, STACK_SRC, STACK_DET)) {
    289                 psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis");
    290                 return psphotReadoutCleanup (config, view, STACK_SRC);
    291             }
    292         }
    293249
    294250        // define new sources based on only the new peaks & measure moments
    295251        // NOTE: new sources are saved on detections->newSources
    296         psphotSourceStats (config, view, STACK_SRC, false); // pass 2 (detections->newSources)
     252        psphotSourceStats (config, view, STACK_RAW, false); // pass 2 (detections->newSources)
    297253
    298254        // set source type
    299255        // NOTE: apply only to detections->newSources
    300         if (!psphotRoughClass (config, view, STACK_SRC)) { // pass 2 (detections->newSources)
     256        if (!psphotRoughClass (config, view, STACK_RAW)) { // pass 2 (detections->newSources)
    301257            psLogMsg ("psphot", 3, "failed to find a valid PSF clump for image");
    302             return psphotReadoutCleanup (config, view, STACK_SRC);
     258            return psphotReadoutCleanup (config, view, STACK_RAW);
    303259        }
    304260
    305261        // replace all sources so fit below applies to all at once
    306262        // NOTE: apply only to OLD sources (which have been subtracted)
    307         psphotReplaceAllSources (config, view, STACK_SRC, false); // pass 2
     263        psphotReplaceAllSources (config, view, STACK_RAW, false); // pass 2
    308264
    309265        // merge the newly selected sources into the existing list
    310266        // NOTE: merge OLD and NEW
    311267        // XXX check on free of sources...
    312         psphotMergeSources (config, view, STACK_SRC); // (detections->newSources + detections->allSources -> detections->allSources)
     268        psphotMergeSources (config, view, STACK_RAW); // (detections->newSources + detections->allSources -> detections->allSources)
    313269
    314270        // Construct an initial model for each object, set the radius to fitRadius, set circular
    315271        // fit mask.  NOTE: only applied to sources without guess models
    316         psphotGuessModels (config, view, STACK_SRC);
     272        psphotGuessModels (config, view, STACK_RAW);
    317273    }
    318274
     
    325281    if (splitLinearFit) {
    326282        psLogMsg ("psphot", 3, "splitting fit of detected and matched soures\n");
    327         // Fit the detected sources separately from matched that wea are about to create.
     283        // Fit the detected sources separately from matched ones that we are about to create.
    328284        // NOTE: apply to ALL sources but only include sources with postitive flux in the fit
    329         psphotFitSourcesLinear (config, view, STACK_SRC, true, true); // pass 3 (detections->allSources)
     285        psphotFitSourcesLinear (config, view, STACK_RAW, true, true); // pass 3 (detections->allSources)
    330286    }
    331287
     
    335291    // this just match the detections for the chisq image, and not bother measuring the source
    336292    // stats in that case...?
    337     objects = psphotMatchSources (config, view, STACK_SRC);
     293    objects = psphotMatchSources (config, view, STACK_RAW);
    338294    psMemDump("matchsources");
    339295
     
    344300    // Construct an initial model for each object, set the radius to fitRadius, set circular
    345301    // fit mask.  NOTE: only applied to sources without guess models
    346     psphotGuessModels (config, view, STACK_SRC);
     302    psphotGuessModels (config, view, STACK_RAW);
    347303
    348304    psphotStackObjectsUnifyPosition (objects);
    349305
    350     psphotStackObjectsSelectForAnalysis (config, view, STACK_SRC, objects);
     306    // psphotStackObjectsSelectForAnalysis (config, view, STACK_RAW, objects);
    351307
    352308    // final linear fit. NOTE: if splitLinearFit is true above, this pass will only fit
    353309    // the unsubtracted (matched) sources (the sources that we fit above are subtracted)
    354     psphotFitSourcesLinear (config, view, STACK_SRC, true, false); // pass 4 (detections->allSources)
     310    psphotFitSourcesLinear (config, view, STACK_RAW, true, false); // pass 4 (detections->allSources)
    355311
    356312    // measure the radial profiles to the sky (only measures new objects)
    357     psphotRadialProfileWings (config, view, STACK_SRC);
     313    psphotRadialProfileWings (config, view, STACK_RAW);
    358314
    359315    // re-measure the kron mags with models subtracted
    360316    // psphotKronMasked(config, view, STACK_SRC);
    361317    logMemStats("before.kron.2");
    362     psphotKronIterate(config, view, STACK_SRC, 2);
     318    psphotKronIterate(config, view, STACK_RAW, 2);
    363319    logMemStats("after.kron.2");
    364320
    365321    // measure source size for the remaining sources
    366322    // NOTE: applies only to NEW (unmeasured) sources
    367     psphotSourceSize (config, view, STACK_SRC, false); // pass 2 (detections->allSources)
     323    psphotSourceSize (config, view, STACK_RAW, false); // pass 2 (detections->allSources)
    368324
    369325    psMemDump("psfstats");
     
    371327    // drop matched sources without any useful measurements and set kron radii for the ones
    372328    // we decide to keep
    373     psphotFilterMatchedSources (config, view, STACK_SRC, objects);
     329    psphotFilterMatchedSources (config, view, STACK_RAW, objects);
    374330
    375331    // measure kron fluxes for the matched sources only
    376     psphotKronIterate(config, view, STACK_SRC, 3);
     332    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);
    377336
    378337    // measure elliptical apertures, petrosians (objects sorted by S/N)
    379338    // psphotExtendedSourceAnalysisByObject (config, objects, view, STACK_SRC); // pass 1 (detections->allSources)
    380     psphotExtendedSourceAnalysis (config, view, STACK_SRC); // pass 1 (detections->allSources)
     339    psphotExtendedSourceAnalysis (config, view, STACK_RAW); // pass 1 (detections->allSources)
    381340
    382341    // measure non-linear extended source models (exponential, deVaucouleur, Sersic) (sources sorted by S/N)
    383     psphotExtendedSourceFits (config, view, STACK_SRC); // pass 1 (detections->allSources)
     342    psphotExtendedSourceFits (config, view, STACK_RAW); // pass 1 (detections->allSources)
    384343
    385344    // create source children for the OUT filerule (for radial aperture photometry and output)
    386     psArray *objectsOut = psphotSourceChildrenByObject (config, view, STACK_OUT, objects);
     345    // NOTE: The new source children have image arrays pointing to the readout associated with
     346    // STACK_OUT.  in psphotStackMatchPSFsetup, we copy the current pixel values from RAW to OUT,
     347    // but keep the pointers the same so we do not break these source image references
     348    // XXX NOTE : if we use the pre-20130914 psphotStackReadout code, we need to use 'false' for the
     349    // sourcesSubtracted argument
     350    psArray *objectsOut = psphotSourceChildrenByObject (config, view, STACK_OUT, objects, true);
    387351    if (!objectsOut) {
    388352        psFree(objects);
    389353        psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis");
    390         return psphotReadoutCleanup (config, view, STACK_SRC);
     354        return psphotReadoutCleanup (config, view, STACK_RAW);
    391355    }
    392356
     
    396360        // this forces photometry on the undetected sources from other images
    397361
    398         // NOTE: we always do the radial apertures analysis on the convolved image since
    399         // those are the ones that are psf matched and are the source of STACK_OUT's pixels
    400         // XXX: Actually if PSPHOT.STACK.MATCH.PSF.SOURCE were set to RAW this wouldn't be true.
    401         // but in that case we don't get past the psf matching step because there is no
    402         // target psf for the RAW inputs
    403 
    404         // If useRaw copy the sources to the convolved readout
    405         if (strcmp(STACK_SRC, STACK_CNV)) {
    406             if (!psphotCopySources (config, view, STACK_CNV, STACK_SRC)) {
    407                 psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis");
    408                 return psphotReadoutCleanup (config, view, STACK_SRC);
    409             }
    410         }
    411         // mark any inputs that we want to skip the matched apertures for
    412         psphotStackSetInputsToSkip(config, view, STACK_CNV, true);
    413         psphotStackSetInputsToSkip(config, view, STACK_OUT, true);
    414         psphotRadialApertures (config, view, STACK_CNV, 0); // entry 0 == unmatched
    415         psMemDump("extmeas");
    416 
     362        // set up the FWHM vector
     363        psphotStackMatchPSFsetup (config, view, STACK_OUT, STACK_RAW);
     364        psphotDumpImages (config, view, STACK_RAW, "raw.t0");
     365        psphotDumpImages (config, view, STACK_OUT, "out.t0");
    417366
    418367        int nRadialEntries = psphotStackMatchPSFsEntries(config, view, STACK_OUT);
    419         for (int entry = 1; entry < nRadialEntries; entry++) {
     368
     369        for (int entry = 0; entry < nRadialEntries; entry++) {
    420370            // NOTE: entry 0 is the unmatched image set
    421371
    422             // re-measure the PSF for the smoothed image (using entries in 'allSources')
    423             psphotChoosePSF (config, view, STACK_OUT, false);
    424 
    425             // this is necessary to update the models based on the new PSF
    426             psphotResetModels (config, view, STACK_OUT);
    427 
    428             // this is necessary to get the right normalization for the new models
    429             psphotFitSourcesLinear (config, view, STACK_OUT, false, false);
     372            char line[256];
    430373
    431374            // measure circular, radial apertures (objects sorted by S/N)
    432375            psphotRadialApertures (config, view, STACK_OUT, entry);
     376            snprintf (line, 256, "%s.%d", "out.t1", entry);
     377            psphotDumpImages (config, view, STACK_OUT, line);
    433378
    434379            // replace the flux in the image so it is returned to its original state
    435380            psphotReplaceAllSources (config, view, STACK_OUT, false);
    436 
    437             // smooth to the next FWHM, or set 'smoothAgain' to false if no more
    438             psphotStackMatchPSFsNext(config, view, STACK_OUT, entry);
    439             psMemDump("matched");
     381            snprintf (line, 256, "%s.%d", "out.t2", entry);
     382            psphotDumpImages (config, view, STACK_OUT, line);
     383
     384            if (entry < nRadialEntries - 1) {
     385                // smooth to the next FWHM
     386                // this function does nothing if the targetFWHM is smaller than the currentFWHM
     387                psphotStackMatchPSFsNext(config, view, STACK_OUT, entry);
     388                snprintf (line, 256, "%s.%d", "out.t3", entry);
     389                psphotDumpImages (config, view, STACK_OUT, line);
     390                psMemDump("matched");
     391
     392                // re-measure the PSF for the smoothed image (using entries in 'allSources')
     393                if (!psphotChoosePSF (config, view, STACK_OUT, false)) {
     394                    psLogMsg ("psphot", 3, "failure to construct a psf model in radial aperture loop for entry :%d", entry);
     395                    return psphotReadoutCleanup (config, view, STACK_RAW);
     396                }
     397
     398                // this is necessary to update the models based on the new PSF
     399                psphotResetModels (config, view, STACK_OUT);
     400
     401                // this is necessary to get the right normalization for the new models
     402                // and to subtract the sources
     403                psphotFitSourcesLinear (config, view, STACK_OUT, false, false);
     404                snprintf (line, 256, "%s.%d", "out.t4", entry);
     405                psphotDumpImages (config, view, STACK_OUT, line);
     406            }
    440407        }
    441408    }
    442     psphotStackSetInputsToSkip(config, view, STACK_CNV, false);
    443     psphotStackSetInputsToSkip(config, view, STACK_OUT, false);
    444409
    445410    // measure aperture photometry corrections
    446     if (!psphotApResid (config, view, STACK_SRC)) {
     411    if (!psphotApResid (config, view, STACK_RAW)) {
    447412        psFree (objects);
    448413        psFree (objectsOut);
    449414        psLogMsg ("psphot", 3, "failed on psphotApResid");
    450         return psphotReadoutCleanup (config, view, STACK_SRC);
     415        return psphotReadoutCleanup (config, view, STACK_RAW);
    451416    }
    452417
    453418    // calculate source magnitudes
    454     psphotMagnitudes(config, view, STACK_SRC);
    455 
    456     if (!useRaw) {
    457         // psphotEfficiency wants to have the PSF of the image, but since we are measuring on
    458         // the convolved images we need to generate PSFs for the DET images
    459         if (!psphotChoosePSF (config, view, STACK_DET, false)) {
    460             psLogMsg ("psphot", 3, "failure to construct a psf model for raw input");
    461             return psphotReadoutCleanup (config, view, STACK_DET);
    462         }
    463     }
    464     if (!psphotEfficiency(config, view, STACK_DET)) {
     419    psphotMagnitudes(config, view, STACK_RAW);
     420
     421    // calculate lensing parameters
     422    if (!psphotLensing(config, view, STACK_RAW)) {
     423        psErrorStackPrint(stderr, "Unable to do lensing parameters.");
     424        psErrorClear();
     425    }
     426
     427    if (!psphotEfficiency(config, view, STACK_RAW)) {
    465428        psErrorStackPrint(stderr, "Unable to determine detection efficiencies from fake sources");
    466429        psErrorClear();
    467430    }
    468     psphotCopyEfficiency (config, view, STACK_OUT, STACK_DET);
     431    psphotCopyEfficiency (config, view, STACK_OUT, STACK_RAW);
    469432
    470433    logMemStats("final");
    471434#if (1)
    472     psphotSourceMemory(config, view, STACK_SRC);
     435    psphotSourceMemory(config, view, STACK_RAW);
    473436    psphotSourceMemory(config, view, STACK_OUT);
    474437#endif
    475438
    476     // replace failed sources?
    477     // psphotReplaceUnfitSources (sources);
    478 
    479439    // replace background in residual image
    480     psphotSkyReplace (config, view, STACK_DET);
     440    psphotSkyReplace (config, view, STACK_RAW);
    481441
    482442    // drop the references to the image pixels held by each source
     443    psphotSourceFreePixels (config, view, STACK_RAW);
    483444    psphotSourceFreePixels (config, view, STACK_OUT);
    484     psphotSourceFreePixels (config, view, STACK_SRC);
    485445
    486446#ifdef MAKE_CHISQ_IMAGE
    487447    // remove chisq image from config->file:PSPHOT.INPUT
    488     psphotStackRemoveChisqFromInputs(config, STACK_DET);
    489     if (strcmp(STACK_SRC, STACK_DET)) {
    490         psphotStackRemoveChisqFromInputs(config, STACK_SRC);
    491     }
     448    psphotStackRemoveChisqFromInputs(config, STACK_RAW);
    492449#endif
    493450
     
    496453
    497454    // create the exported-metadata and free local data
    498     return psphotReadoutCleanup (config, view, STACK_SRC);
     455    return psphotReadoutCleanup (config, view, STACK_RAW);
    499456}
    500457
     
    552509}
    553510
    554 
    555 
    556511/* here is the process:
    557512
    558  * we have three(*) images:
    559  * RAW : unconvolved image stack
    560  * CNV : input convolved image
     513 * we have two image sets:
     514 * RAW : unconvolved image stacks
    561515
    562516 * OUT : psf-matched output image (there may be more than one of
     
    649603
    650604   */
     605
     606
     607// generate a vector fwhmValues where the first has the fwhm of the raw image and the
     608// successive entries have the target values
     609
     610bool psphotStackMatchPSFsetup (pmConfig *config, const pmFPAview *view, const char *filerule, const char *filerulePSF) {
     611
     612    bool status;
     613
     614    int num = psphotFileruleCount(config, filerule);
     615
     616    // skip the chisq image (optionally?)
     617    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
     618    if (!status) chisqNum = -1;
     619
     620    // loop over the available readouts
     621    for (int i = 0; i < num; i++) {
     622        if (i == chisqNum) continue; // skip chisq image
     623
     624        if (!psphotStackMatchPSFsetupReadout (config, view, filerule, filerulePSF, i)) {
     625            psError (PSPHOT_ERR_CONFIG, false, "failed to define target PSF sizes");
     626            return false;
     627        }
     628    }
     629
     630    return true;
     631}
     632
     633float psphotPSFseeing (pmPSF *psf, pmReadout *readout, int index);
     634
     635// copy the pixels from RAW to OUT (
     636
     637bool psphotStackMatchPSFsetupReadout (pmConfig *config, const pmFPAview *view, const char *fileruleOut, const char *fileruleRaw, int index) {
     638
     639    bool status;
     640
     641    // select the appropriate recipe information
     642    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     643
     644    // find the currently selected readout
     645    pmFPAfile *fileOut = pmFPAfileSelectSingle(config->files, fileruleOut, index); // File of interest
     646    psAssert (fileOut, "missing file?");
     647
     648    pmReadout *readoutOut = pmFPAviewThisReadout(view, fileOut->fpa);
     649    psAssert (readoutOut, "missing readout?");
     650
     651    // find the currently selected readout
     652    pmFPAfile *fileRaw = pmFPAfileSelectSingle(config->files, fileruleRaw, index); // File of interest
     653    psAssert (fileRaw, "missing file?");
     654
     655    pmReadout *readoutRaw = pmFPAviewThisReadout(view, fileRaw->fpa);
     656    psAssert (readoutRaw, "missing readout?");
     657
     658    readoutOut->image = psImageCopy(readoutOut->image, readoutRaw->image, PS_TYPE_F32);
     659    if (readoutRaw->variance) {
     660        readoutOut->variance = psImageCopy(readoutOut->variance, readoutRaw->variance, PS_TYPE_F32);
     661    }
     662    if (readoutRaw->mask) {
     663        readoutOut->mask = psImageCopy(readoutOut->mask, readoutRaw->mask, PS_TYPE_IMAGE_MASK);
     664    }
     665
     666    // pmChip *chipRaw = pmFPAviewThisChip(view, fileRaw->fpa); // The chip holds the PSF
     667    // psAssert (chipRaw, "missing chip");
     668
     669    pmPSF *psf = psMetadataLookupPtr(&status, readoutRaw->analysis, "PSPHOT.PSF"); // PSF
     670    if (!psf) {
     671        // we should have a PSF by this point in psphot
     672        psError(PSPHOT_ERR_PROG, true, "Unable to find PSF.");
     673        return false;
     674    }
     675
     676    float fwhmRaw = psphotPSFseeing (psf, readoutRaw, index);
     677
     678    psVector *fwhmValues = psVectorAllocEmpty(10, PS_TYPE_F32);
     679    psVectorAppend(fwhmValues, fwhmRaw);
     680
     681    // is a single target FWHM specified, or a set of values?  set up the vector options->targetSeeing and the local 1st value
     682    float targetSeeing = psMetadataLookupF32 (&status, recipe, "PSPHOT.STACK.TARGET.PSF.FWHM");
     683    if (!status) {
     684        psVector *targetSeeing = psMetadataLookupVector(&status, recipe, "PSPHOT.STACK.TARGET.PSF.FWHM"); // Magnitude offsets
     685        psAssert (status, "missing psphot recipe value PSPHOT.STACK.TARGET.PSF.FWHM");
     686        for (int i = 0; i < targetSeeing->n; i++) {
     687            psVectorAppend(fwhmValues, targetSeeing->data.F32[i]);
     688        }           
     689    } else {
     690        psVectorAppend(fwhmValues, targetSeeing);
     691    }
     692
     693    psMetadataAddVector(readoutOut->analysis, PS_LIST_TAIL, "STACK.PSF.FWHM.VALUES", PS_META_REPLACE, "PSF sizes", fwhmValues);
     694    psFree (fwhmValues);
     695
     696    return true;
     697}
     698
     699float psphotPSFseeing (pmPSF *psf, pmReadout *readout, int index) {
     700
     701    psImage *image = readout->image;
     702
     703    int Nx = image->numCols;
     704    int Ny = image->numRows;
     705
     706    float sumFWHM = 0.0;                  // FWHM for image
     707    int numFWHM = 0;                      // Number of FWHM measurements
     708    for (float x = 0; x < Nx; x += 0.25*Nx) {
     709        for (float y = 0; y < Ny; y += 0.25*Ny) {
     710            float fwhm = pmPSFtoFWHM(psf, x, y);
     711            if (isfinite(fwhm)) {
     712                sumFWHM += fwhm;
     713                numFWHM++;
     714            }
     715        }
     716    }
     717    if (numFWHM == 0) {
     718        psLogMsg("ppStack", PS_LOG_INFO, "Unable to measure PSF FWHM for image %d --- rejected.", index);
     719        return NAN;
     720    }
     721
     722    float fwhm = sumFWHM / (float) numFWHM;
     723    psLogMsg ("psphotStack", PS_LOG_INFO, "Input Seeing for %d: %f\n", index, fwhm);
     724
     725    return fwhm;
     726}
  • branches/eam_branches/ps2-tc3-20130727/psphot/test/tap_psphot_galaxygrid.pro

    r35769 r36680  
    2828$RefOptions = $RefOptions -Df STARS.DENSITY 10.0
    2929$RefOptions = $RefOptions -Df STARS.SIGMA.LIM 0.5
    30 
     30$RefOptions = $RefOptions -nx 3000 -ny 3000
     31
     32if (not($?PSFMODEL))
     33  $PSFMODEL = PS1_V1
     34end
     35
     36macro reset.options
    3137# options for the simulated images (using the refimage for the stars)
    3238$FakeOptions = $BaseOptions
    3339$FakeOptions = $FakeOptions -exptime 30.0
    34 $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
     42$FakeOptions = $FakeOptions -nx 3000 -ny 3000
    3543 
    3644# sample alternate options:
     
    6573$FakeConfig = $FakeConfig -Df GALAXY.INDEX.MIN 1.66
    6674$FakeConfig = $FakeConfig -Df GALAXY.INDEX.MAX 1.66
    67 $FakeConfig = $FakeConfig -Di GALAXY.GRID.DX 120
    68 $FakeConfig = $FakeConfig -Di GALAXY.GRID.DY 120
     75$FakeConfig = $FakeConfig -Di GALAXY.GRID.DX 300
     76$FakeConfig = $FakeConfig -Di GALAXY.GRID.DY 300
     77end
     78
     79if (not($?FakeConfig)) reset.options
    6980
    7081list fwhm
     
    7586end
    7687
    77 macro go.grid.set.devexp
     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
    78104  $FakeConfig = -camera SIMTEST
    79105  $FakeConfig = $FakeConfig -recipe PPSIM STACKTEST.RUN
     
    84110  $FakeConfig = $FakeConfig -Db GALAXY.FAKE T                        ; # generate a "realistic" distribution of galaxies
    85111  $FakeConfig = $FakeConfig -Df GALAXY.MAG 17.0
     112  $FakeConfig = $FakeConfig -Df GALAXY.GRID.MAG 14.5
    86113  $FakeConfig = $FakeConfig -Db GALAXY.GRID T                        ; # generate a grid of galaxies (constant mag)
    87114  $FakeConfig = $FakeConfig -Df GALAXY.THETA.MIN 0
    88115  $FakeConfig = $FakeConfig -Df GALAXY.THETA.MAX 180
    89   $FakeConfig = $FakeConfig -Di GALAXY.GRID.DX 120
    90   $FakeConfig = $FakeConfig -Di GALAXY.GRID.DY 120
     116  $FakeConfig = $FakeConfig -Di GALAXY.GRID.DX 300
     117  $FakeConfig = $FakeConfig -Di GALAXY.GRID.DY 300
    91118  $FakeConfig = $FakeConfig -Df GALAXY.INDEX.MIN 1.0
    92119  $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
     130end
     131
     132# generate fake images and run psphot on them
     133macro normtest.mkexp.devexp
     134  $FakeConfig = -camera SIMTEST
     135  $FakeConfig = $FakeConfig -recipe PPSIM STACKTEST.RUN
     136  $FakeConfig = $FakeConfig -D PSASTRO:PSASTRO.CATDIR catdir.ref
     137  $FakeConfig = $FakeConfig -Db STARS.FAKE F                         ; # only use stars from catdir.ref
     138  $FakeConfig = $FakeConfig -Db MATCH.DENSITY F
     139  $FakeConfig = $FakeConfig -Db PSF.CONVOLVE T
     140  $FakeConfig = $FakeConfig -Db GALAXY.FAKE T                        ; # generate a "realistic" distribution of galaxies
     141  $FakeConfig = $FakeConfig -Df GALAXY.MAG 17.0
     142  $FakeConfig = $FakeConfig -Df GALAXY.GRID.MAG 14.5
     143  $FakeConfig = $FakeConfig -Db GALAXY.GRID T                        ; # generate a grid of galaxies (constant mag)
     144  $FakeConfig = $FakeConfig -Df GALAXY.THETA.MIN 0
     145  $FakeConfig = $FakeConfig -Df GALAXY.THETA.MAX 180
     146  $FakeConfig = $FakeConfig -Di GALAXY.GRID.DX 300
     147  $FakeConfig = $FakeConfig -Di GALAXY.GRID.DY 300
     148  $FakeConfig = $FakeConfig -Df GALAXY.INDEX.MIN 1.0
     149  $FakeConfig = $FakeConfig -Df GALAXY.INDEX.MAX 1.0
     150  $BaseConfig = $FakeConfig
    93151
    94152  # $FakeConfig = $FakeConfig -D GALAXY.MODEL PS_MODEL_GAUSS
     
    103161  # $FakeConfig = $FakeConfig -Df GALAXY.INDEX.MAX 1.66
    104162
     163  mkdir normtest
     164
    105165  $Nseq = 0
    106166  foreach type EXP DEV
    107167    foreach Rmajor 3 10 30
    108168      foreach Aratio 0.25 0.5 1.0
    109         foreach fwhm 0.8 1.0 1.5
     169        foreach fwhm 1.0
     170          $FakeConfig = $BaseConfig
    110171          $FakeConfig = $FakeConfig -Df GALAXY.RMAJOR.MIN $Rmajor
    111172          $FakeConfig = $FakeConfig -Df GALAXY.RMAJOR.MAX $Rmajor
     
    113174          $FakeConfig = $FakeConfig -Df GALAXY.ARATIO.MAX $Aratio
    114175         
    115           sprint name "sample.%02d" $Nseq
     176          sprint name "normtest/test.%02d" $Nseq
    116177          mkexp $name $fwhm $type
    117           fitexp $name $name.fit $type\_CONV
    118178          $Nseq ++
    119179        end
     
    123183end
    124184
    125 macro go.grid.set.sersic
     185# generate fake images and run psphot on them
     186macro grid.mkexp.devexp
     187  if ($0 != 2)
     188    echo "USAGE: grid.mkexp.devexp (dir)"
     189    break
     190  end
     191
     192  mkdir $1
     193
    126194  $FakeConfig = -camera SIMTEST
    127195  $FakeConfig = $FakeConfig -recipe PPSIM STACKTEST.RUN
     
    132200  $FakeConfig = $FakeConfig -Db GALAXY.FAKE T                        ; # generate a "realistic" distribution of galaxies
    133201  $FakeConfig = $FakeConfig -Df GALAXY.MAG 17.0
     202  $FakeConfig = $FakeConfig -Df GALAXY.GRID.MAG 14.5
    134203  $FakeConfig = $FakeConfig -Db GALAXY.GRID T                        ; # generate a grid of galaxies (constant mag)
    135204  $FakeConfig = $FakeConfig -Df GALAXY.THETA.MIN 0
    136205  $FakeConfig = $FakeConfig -Df GALAXY.THETA.MAX 180
    137   $FakeConfig = $FakeConfig -Di GALAXY.GRID.DX 120
    138   $FakeConfig = $FakeConfig -Di GALAXY.GRID.DY 120
     206  $FakeConfig = $FakeConfig -Di GALAXY.GRID.DX 300
     207  $FakeConfig = $FakeConfig -Di GALAXY.GRID.DY 300
     208  $FakeConfig = $FakeConfig -Df GALAXY.INDEX.MIN 1.0
     209  $FakeConfig = $FakeConfig -Df GALAXY.INDEX.MAX 1.0
     210  $BaseConfig = $FakeConfig
     211
     212  $Nseq = 0
     213  foreach type EXP DEV
     214    foreach Rmajor 3 10 30
     215      foreach Aratio 0.25 0.5 1.0
     216        foreach fwhm 0.8 1.0 1.5
     217          $FakeConfig = $BaseConfig
     218          $FakeConfig = $FakeConfig -Df GALAXY.RMAJOR.MIN $Rmajor
     219          $FakeConfig = $FakeConfig -Df GALAXY.RMAJOR.MAX $Rmajor
     220          $FakeConfig = $FakeConfig -Df GALAXY.ARATIO.MIN $Aratio
     221          $FakeConfig = $FakeConfig -Df GALAXY.ARATIO.MAX $Aratio
     222         
     223          sprint name "$1/sample.%02d" $Nseq
     224          mkexp $name $fwhm $type
     225          $Nseq ++
     226        end
     227      end
     228    end
     229  end
     230end
     231
     232# generate fake images and run psphot on them
     233macro grid.fitexp.devexp
     234  if ($0 != 3)
     235    echo "USAGE: grid.fitexp.devexp (srcdir) (outdir)"
     236    break
     237  end
     238
     239   #$Nseq = 0
     240   #foreach type EXP DEV
     241
     242  mkdir $2
     243
     244  $Nseq = 0
     245  foreach type EXP DEV
     246    foreach Rmajor 3 10 30
     247      foreach Aratio 0.25 0.5 1.0
     248        foreach fwhm 0.8 1.0 1.5
     249          sprint srcname "$1/sample.%02d" $Nseq
     250          sprint outname "$2/sample.%02d.fit" $Nseq
     251          fitexp $srcname $outname $type\_CONV
     252          $Nseq ++
     253        end
     254      end
     255    end
     256  end
     257end
     258
     259macro grid.load.devexp
     260  if ($0 != 3)
     261    echo "USAGE: grid.load.devexp (srcdir) (fitdir)"
     262    break
     263  end
     264
     265  delete -q Xin_s Yin_s Min_s Tin_s Rin_s rin_s
     266  delete -q Xot_s Yot_s Mot_s Tot_s Rot_s rot_s
     267  delete -q min_S Min_S
     268
     269  $Nseq = 0
     270  foreach type EXP DEV
     271    foreach Rmajor 3 10 30
     272      foreach Aratio 0.25 0.5 1.0
     273        foreach fwhm 0.8 1.0 1.5
     274          sprint name "sample.%02d" $Nseq
     275          cmf.load.concat $1/$name.dat $2/$name.fit.cmf $type
     276          $Nseq ++
     277        end
     278      end
     279    end
     280  end
     281end
     282
     283macro grid.plots.devexp
     284  if ($0 != 2)
     285    echo "USAGE: grid.plot.devexp (version)"
     286    break
     287  end
     288  # things to examine: theta, Rmajor, AR
     289
     290  # go.grid.check.devexp
     291
     292  # check on theta
     293  set dT = Tot_s - Tin_s
     294  set ARin = rin_s / Rin_s
     295  # lim ARin dT; clear; box; plot ARin dT
     296
     297  subset dTx = dT if (ARin < 0.95)
     298  histogram dTx NdT -8 8 0.1 -range dTi
     299  lim -n 0$1 dTi NdT; clear; box; plot -x 1 dTi NdT
     300  label -x "angle offset (degrees, only non-circular)" -y "number count"
     301  resize 700 320
     302
     303  # check on Rmajor
     304  set dR = Rin_s - Rot_s
     305  # lim Rin_s dR; clear; box; plot Rin_s dR
     306  # lim Rot_s dR; clear; box; plot Rot_s dR
     307  # lim Rin_s dR; clear; box; plot Rin_s dR
     308  create n 0 dR[]
     309  set dRf = dR / Rin_s
     310  lim -n 1$1 n -0.5 0.5; clear; box; plot n dRf
     311  label -x sequence -y "1 - R_out| / R_in|"
     312  resize 700 320
     313
     314  # check on A.Ratio
     315  set ARot = rot_s / Rot_s
     316  # lim ARin ARot; clear; box; plot ARin ARot
     317  set fAR = ARot / ARin
     318  lim -n 2$1 n 0.5 1.5; clear; box; plot n fAR
     319  label -x sequence -y "AR_out| / AR_in|"
     320  resize 700 320
     321
     322  # check on magnitude
     323  set dM = Mot_s - Min_s
     324  lim -n 3$1 n -0.5 0.5; clear; box; plot n dM   
     325  label -x sequence -y "M_out| - M_in|"
     326  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
     377end
     378
     379macro grid.mkexp.sersic
     380  if ($0 != 2)
     381    echo "USAGE: grid.mkexp.devexp (dir)"
     382    break
     383  end
     384
     385  mkdir $1
     386
     387  $FakeConfig = -camera SIMTEST
     388  $FakeConfig = $FakeConfig -recipe PPSIM STACKTEST.RUN
     389  $FakeConfig = $FakeConfig -D PSASTRO:PSASTRO.CATDIR catdir.ref
     390  $FakeConfig = $FakeConfig -Db STARS.FAKE F                         ; # only use stars from catdir.ref
     391  $FakeConfig = $FakeConfig -Db MATCH.DENSITY F
     392  $FakeConfig = $FakeConfig -Db PSF.CONVOLVE T
     393  $FakeConfig = $FakeConfig -Db GALAXY.FAKE T                        ; # generate a "realistic" distribution of galaxies
     394  $FakeConfig = $FakeConfig -Df GALAXY.MAG 17.0
     395  $FakeConfig = $FakeConfig -Df GALAXY.GRID.MAG 14.5
     396  $FakeConfig = $FakeConfig -Db GALAXY.GRID T                        ; # generate a grid of galaxies (constant mag)
     397  $FakeConfig = $FakeConfig -Df GALAXY.THETA.MIN 0
     398  $FakeConfig = $FakeConfig -Df GALAXY.THETA.MAX 180
     399  $FakeConfig = $FakeConfig -Di GALAXY.GRID.DX 300
     400  $FakeConfig = $FakeConfig -Di GALAXY.GRID.DY 300
    139401  $FakeConfig = $FakeConfig -D GALAXY.MODEL PS_MODEL_SERSIC
    140 
    141   # $FakeConfig = $FakeConfig -Df GALAXY.INDEX.MIN 1.0
    142   # $FakeConfig = $FakeConfig -Df GALAXY.INDEX.MAX 1.0
    143   # $FakeConfig = $FakeConfig -Df GALAXY.RMAJOR.MIN 10.0
    144   # $FakeConfig = $FakeConfig -Df GALAXY.RMAJOR.MAX 10.0
    145   # $FakeConfig = $FakeConfig -Df GALAXY.ARATIO.MIN 0.25
    146   # $FakeConfig = $FakeConfig -Df GALAXY.ARATIO.MAX 0.25
    147   # $FakeConfig = $FakeConfig -Df GALAXY.INDEX.MIN 1.66
    148   # $FakeConfig = $FakeConfig -Df GALAXY.INDEX.MAX 1.66
     402  $BaseConfig = $FakeConfig
    149403
    150404  $Nseq = 0
     
    153407      foreach Aratio 0.25 0.5 1.0
    154408        foreach fwhm 0.8 1.0 1.5
     409          $FakeConfig = $BaseConfig
    155410          $FakeConfig = $FakeConfig -Df GALAXY.RMAJOR.MIN $Rmajor
    156411          $FakeConfig = $FakeConfig -Df GALAXY.RMAJOR.MAX $Rmajor
     
    160415          $FakeConfig = $FakeConfig -Df GALAXY.INDEX.MAX $index
    161416         
    162           sprint name "sersic.%02d" $Nseq
     417          sprint name "$1/sersic.%02d" $Nseq
    163418          mkexp $name $fwhm SERSIC
    164           fitexp $name $name.fit SER\_CONV
     419          echo "$Nseq : $index $Rmajor $Aratio $fwhm"
    165420          $Nseq ++
    166421        end
     
    170425end
    171426
    172 macro go.grid.check.devexp
    173   delete -q Xin_s Yin_s Min_s Tin_s Rin_s rin_s
    174   delete -q Xot_s Yot_s Mot_s Tot_s Rot_s rot_s
     427macro grid.fitexp.sersic.devexp
     428  if ($0 != 3)
     429    echo "USAGE: grid.fitexp.sersic.devexp (srcdir) (outdir)"
     430    break
     431  end
     432
     433  mkdir $2
    175434
    176435  $Nseq = 0
    177   foreach type EXP DEV
     436  foreach index 1 2 3 4
    178437    foreach Rmajor 3 10 30
    179438      foreach Aratio 0.25 0.5 1.0
    180439        foreach fwhm 0.8 1.0 1.5
    181           sprint name "sample.%02d" $Nseq
    182           ckgalaxy.load $name.dat $name.fit.cmf
     440          sprint name "sersic.%02d" $Nseq
     441          fitexp $1/$name $2/$name.fit EXP_CONV,DEV_CONV
    183442          $Nseq ++
    184443        end
     
    188447end
    189448
    190 macro go
    191   mkexp test.exp 1.0 EXP
    192   fitexp test.exp test.exp.fit EXP_CONV
    193 
    194   mkexp test.ser 1.0 SERSIC
    195   fitexp test.ser test.ser.fit SER_CONV
    196 
    197   mkexp test.dev 1.0 DEV
    198   fitexp test.dev test.dev.fit DEV_CONV
    199 
    200   mkexp test.gau 1.0 GAUSS
    201   fitexp test.gau test.gau.fit GAU_CONV
    202 
    203   mkexp test.pg 1.0 PGAUSS
    204   fitexp test.pg test.pg.fit PGA_CONV
    205 
    206   mkexp test.qga 1.0 QGAUSS
    207   fitexp test.qga test.qga.fit QGA_CONV
    208 
    209   mkexp test.p1 1.0 PS1_V1
    210   fitexp test.p1 test.p1.fit PS1_CONV
    211 end
    212 
    213 macro go.ckgalaxy
    214   foreach type exp ser dev gau pg qga p1
    215     ckgalaxy test.$type.dat test.$type.fit.cmf
    216     wait $type
    217   end
     449macro grid.fitexp.sersic
     450  if ($0 != 3)
     451    echo "USAGE: grid.fitexp.sersic (srcdir) (outdir)"
     452    break
     453  end
     454
     455  mkdir $2
     456
     457  $Nseq = 0
     458  foreach index 1 2 3 4
     459    foreach Rmajor 3 10 30
     460      foreach Aratio 0.25 0.5 1.0
     461        foreach fwhm 0.8 1.0 1.5
     462          sprint name "sersic.%02d" $Nseq
     463          fitexp $1/$name $2/$name.fit SER\_CONV
     464          $Nseq ++
     465        end
     466      end
     467    end
     468  end
     469end
     470
     471macro grid.load.sersic
     472  if ($0 != 3)
     473    echo "USAGE: grid.load.devexp (srcdir) (fitdir)"
     474    break
     475  end
     476
     477  delete -q Xin_s Yin_s Min_s Tin_s Rin_s rin_s MTin_s Iin_s
     478  delete -q Xot_s Yot_s Mot_s Tot_s Rot_s rot_s MTot_s Iot_s
     479
     480  $Nseq = 0
     481  foreach index 1 2 3 4
     482    foreach Rmajor 3 10 30
     483      foreach Aratio 0.25 0.5 1.0
     484        foreach fwhm 0.8 1.0 1.5
     485          sprint name "sersic.%02d" $Nseq
     486          cmf.load.concat $1/$name.dat $2/$name.fit.cmf SERSIC
     487          $Nseq ++
     488        end
     489      end
     490    end
     491  end
     492end
     493
     494# I want to make plots of Iin_s vs Mkron, Mxx, and similar things
     495# this means I need to be able to join Chip.xfit things against Chip.psf
     496# and to join Chip.xfit(DEV) to Chip.xfit(EXP)
     497
     498# I think I need a generic 'JOIN' function
     499
     500macro grid.plots.sersic
     501  if ($0 != 2)
     502    echo "USAGE: grid.plot.devexp (version)"
     503    break
     504  end
     505  # things to examine: theta, Rmajor, AR
     506
     507  # go.grid.check.devexp
     508
     509  # check on theta
     510  set dT = Tot_s - Tin_s
     511  set ARin = rin_s / Rin_s
     512  # lim ARin dT; clear; box; plot ARin dT
     513
     514  subset dTx = dT if (ARin < 0.95)
     515  histogram dTx NdT -8 8 0.1 -range dTi
     516  lim -n 0$1 dTi NdT; clear; box; plot -x 1 dTi NdT
     517  label -x "angle offset (degrees, only non-circular)" -y "number count"
     518  resize 700 320
     519
     520  # check on Rmajor
     521  set dR = Rin_s - Rot_s
     522  # lim Rin_s dR; clear; box; plot Rin_s dR
     523  # lim Rot_s dR; clear; box; plot Rot_s dR
     524  # lim Rin_s dR; clear; box; plot Rin_s dR
     525  create n 0 dR[]
     526  set dRf = dR / Rin_s
     527  lim -n 1$1 n -0.5 0.5; clear; box; plot n dRf
     528  label -x sequence -y "1 - R_out| / R_in|"
     529  resize 700 320
     530
     531  # check on A.Ratio
     532  set ARot = rot_s / Rot_s
     533  # lim ARin ARot; clear; box; plot ARin ARot
     534  set fAR = ARot / ARin
     535  lim -n 2$1 n 0.5 1.5; clear; box; plot n fAR
     536  label -x sequence -y "AR_out| / AR_in|"
     537  resize 700 320
     538
     539  # check on magnitude
     540  set dM = Mot_s - Min_s
     541  lim -n 3$1 n -0.5 0.5; clear; box; plot n dM   
     542  label -x sequence -y "M_out| - M_in|"
     543  resize 700 320
     544
     545  # check on index
     546  set dI = Iot_s - Iin_s
     547  lim -n 4$1 n -0.5 0.5; clear; box; plot n dI   
     548  label -x sequence -y "I_out| - I_in|"
     549  resize 700 320
    218550end
    219551
     
    258590end
    259591
     592if (not($?NSIGMA_CONV)) set NSIGMA_CONV = 5.0
     593
    260594# create a realistic distribution of fake stars, GAUSS PSF
    261595macro fitexp
     
    278612  $psphotConfig = $psphotConfig -Db PSPHOT:SAVE.RESID T
    279613  $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
    280622
    281623  # ppImage / psphot on the output
     624  break -auto off
    282625  echo ppImage $ppImageConfig $psphotConfig -file $basename.fits $outname
    283   exec ppImage $ppImageConfig $psphotConfig -file $basename.fits $outname
    284 end
    285 
    286 macro ckchip
    287   if ($0 != 5)
    288     echo "USAGE: ckchip (raw) (out) (output) (zpt_off)"
    289     break
    290   end
    291 
    292   load.cmf $1 Chip.psf raw
    293   load.cmf $2 Chip.psf out
    294 
    295   # images generated with convolution will not have the right output positions
    296   set X_raw = int(X_PSF_raw) + 0.5
    297   set Y_raw = int(Y_PSF_raw) + 0.5
    298   set M_raw = PSF_INST_MAG_raw + $4
    299   set K_out = -2.5*log(KRON_FLUX_out)
    300   match2d X_PSF_out Y_PSF_out X_PSF_raw Y_PSF_raw 1.5 -index1 index1 -index2 index2
    301 
    302   local i NX NY nx ny N
    303 
    304   device -n compare
    305   resize 1000 1000
    306 
    307   # plot trends as a function of mag
    308   $NX = 2
    309   $NY = 5
    310   $nx = 0
    311   $ny = 0
    312   $N = 0
    313   clear -s
    314   for i 0 $pairs:n
    315     section a$nx\$ny {$nx/$NX} {$ny/$NY} {1/$NX} {1/$NY}
    316     show.pair $i
    317     $ny ++
    318     if ($ny == $NY)
    319       $ny = 0
    320       $nx ++
    321     end
    322     if ($nx == $NX)
    323       png -name $3.$N.png
    324       clear -s
    325       $nx = 0
    326       $ny = 0
    327       $N ++
    328     end
    329   end
    330 
    331   # plot (input - output) vs mag
    332 end
    333 
    334 macro ckgalaxy.load
    335   if ($0 != 3)
    336     echo "USAGE: ckgalaxy (dat) (cmf)"
     626  exec echo ppImage $ppImageConfig $psphotConfig -file $basename.fits $outname >& $outname.log
     627  exec ppImage $ppImageConfig $psphotConfig -file $basename.fits $outname >>& $outname.log
     628  break -auto on
     629end
     630
     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
     642macro cmf.load.concat
     643  if ($0 != 4)
     644    echo "USAGE: cmf.load.concat (dat) (cmf) (inType)"
    337645    break
    338646  end
    339647
    340648  data $1
    341   read Xin_all 1 Yin_all 2 Type 4 Min_all 5 RmajIn_all 7 RminIn_all 8 ThetaIn_all 9
    342 
     649  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
     650
     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
    343667  subset Xin = Xin_all if (Type == 1)
    344668  subset Yin = Yin_all if (Type == 1)
    345669  subset Min = Min_all if (Type == 1)
     670  subset Fin = Fin_all if (Type == 1)
     671  set min = -2.5*log(Fin)
    346672
    347673  subset Tin_rad = ThetaIn_all if (Type == 1)
     
    351677  subset RminIn = RminIn_all if (Type == 1)
    352678
     679  subset IndexIn = IndexIn_all if (Type == 1)
     680
    353681  data $2
    354   read -fits Chip.xfit X_EXT Y_EXT EXT_INST_MAG EXT_WIDTH_MAJ EXT_WIDTH_MIN EXT_THETA
     682
     683  break -auto off
     684  output -err /dev/null
     685  read -fits Chip.xfit X_EXT Y_EXT EXT_INST_MAG EXT_WIDTH_MAJ EXT_WIDTH_MIN EXT_THETA MODEL_TYPE EXT_PAR_07
     686  $reread = not($STATUS)
     687  output -err stderr
     688  break -auto on
     689  if ($reread)
     690    read -fits Chip.xfit X_EXT Y_EXT EXT_INST_MAG EXT_WIDTH_MAJ EXT_WIDTH_MIN EXT_THETA MODEL_TYPE
     691    set EXT_PAR_07 = (MODEL_TYPE:9 == 68)*0.125 + (MODEL_TYPE:9 == 69)*0.5
     692  end
     693
    355694  set EXT_THETA_ALT = EXT_THETA * (EXT_THETA >= 0.0) + (EXT_THETA + 3.14159265) * (EXT_THETA < 0.0)
    356695  set EXT_THETA = EXT_THETA_ALT * 180 / 3.14159265
     
    364703  reindex Yin_m = Yin using index2
    365704
     705  set MTin_m = $InType + zero(Xin_m)
     706  reindex MTot_m = MODEL_TYPE:9 using index1
     707
    366708  reindex Mot_m = EXT_INST_MAG using index1
    367709  reindex Tot_m = EXT_THETA using index1
     
    376718  reindex rin_m = RminIn using index2
    377719 
    378   foreach field X Y M T R r
     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
     723 
     724  foreach field $fields
    379725    foreach set in ot
    380726      concat $field\$set\_m $field\$set\_s
    381727    end
    382728  end
    383 end
    384 
    385 macro stats.pair
     729
     730  concat min min_S
     731  concat Min Min_S
     732end
     733
     734macro cmf.load.stars.concat
    386735  if ($0 != 3)
    387     echo "USAGE: stats.pair (N) (output)"
    388     break
    389   end
    390 
    391   list word -split $spairs:$1
    392   if ($word:n != 8)
    393     echo "invalid pair $1"
    394     break
    395   end
    396 
    397   $Nr = $word:3
    398 
    399   reindex v1 = $word:0 using index1
    400   reindex v2 = $word:1 using index2
    401   reindex rv = $word:2 using index$Nr
    402 
    403   set delta = v1 - v2
    404   subset d1 = delta if ($word:4 < rv) && (rv < $word:5) && (abs(delta) < $word:7)
    405   subset d2 = delta if ($word:5 < rv) && (rv < $word:6) && (abs(delta) < $word:7)
    406 
    407   vstats -q d1 -sigma-clip 3.0
    408   $M1 = $MEAN
    409   $S1 = $SIGMA
    410   vstats -q d2 -sigma-clip 3.0
    411   $M2 = $MEAN
    412   $S2 = $SIGMA
    413 
    414   output $2
    415   fprintf "%-18s  %7.4f %7.4f  %7.4f %7.4f" $word:0  $M1 $S1  $M2 $S2
    416   output stdout
    417 end
    418 
    419 macro show.pair
    420   if ($0 != 2)
    421     echo "USAGE: show.pair (N)"
    422     break
    423   end
    424 
    425   list word -split $pairs:$1
    426   if ($word:n != 7)
    427     echo "invalid pair $1"
    428     break
    429   end
    430 
    431   $Nr = $word:3
    432 
    433   reindex v1 = $word:0 using index1
    434   if ("$word:6" == "V")
    435     reindex v2 = $word:1 using index2
    436   end
    437   if ("$word:6" == "S")
    438     set v2 = $word:1 + zero(index1)
    439   end
    440   reindex rv = $word:2 using index$Nr
    441 
    442   set delta = v1 - v2
    443   if (("$word:4" == "def") || ("$word:5" == "def"))
    444     lim rv delta; box; plot rv delta
    445   else
    446     lim rv $word:4 $word:5; box; plot rv delta
    447   end
    448   label -y '$word:0' -x '$word:2'
    449 end
    450 
    451 # This list is used to compare a pair of vectors (sans error) or a
    452 # vector and an expected (constant) value.  The last field defines a
    453 # vector or constant for the comparison.  It is assumed that the
    454 # vector sets have been loaded and matched with match2d to generate
    455 # index vectors 'index1' and index2'.  The macro 'show.pair' generates
    456 # a plot of the range vector vs (v1 - v2).  The indices for v1, v2 are
    457 # index1 and 2 respectively.  The index for the range vector is defined
    458 # by the integer following that vector.  the y-limits of the plot are
    459 # given by the last two numbers
    460 list pairs
    461   X_PSF_out             X_raw                 PSF_INST_MAG_raw 2 -1.01 1.01 V
    462   Y_PSF_out             Y_raw                 PSF_INST_MAG_raw 2 -1.01 1.01 V
    463   X_PSF_out             X_PSF_raw             PSF_INST_MAG_raw 2 -1.01 1.01 V
    464   Y_PSF_out             Y_PSF_raw             PSF_INST_MAG_raw 2 -1.01 1.01 V
    465   X_PSF_SIG_out         X_PSF_SIG_raw         PSF_INST_MAG_raw 2 -1.01 1.01 V
    466   Y_PSF_SIG_out         Y_PSF_SIG_raw         PSF_INST_MAG_raw 2 -1.01 1.01 V
    467   #PSF_INST_MAG_out      PSF_INST_MAG_raw      PSF_INST_MAG_raw 2 -1.01 1.01 V
    468   PSF_INST_MAG_out      M_raw                 PSF_INST_MAG_raw 2 -1.01 1.01 V
    469   PSF_INST_MAG_SIG_out  PSF_INST_MAG_SIG_raw  PSF_INST_MAG_raw 2 -1.01 1.01 V
    470   #PSF_INST_FLUX_out     PSF_INST_FLUX_raw     PSF_INST_MAG_raw 2   def  def V
    471   #PSF_INST_FLUX_SIG_out PSF_INST_FLUX_SIG_raw PSF_INST_MAG_raw 2   def  def V
    472   AP_MAG_out            M_raw                 PSF_INST_MAG_raw 2 -1.01 1.01 V
    473   AP_MAG_RAW_out        M_raw                 PSF_INST_MAG_raw 2 -1.01 1.01 V
    474   AP_MAG_RADIUS_out     0.0                   PSF_INST_MAG_raw 2 -0.01 20.1 S
    475   SKY_out               0.0                   PSF_INST_MAG_raw 2   def  def S
    476   SKY_SIGMA_out         0.0                   PSF_INST_MAG_raw 2   def  def S
    477   PSF_CHISQ_out         1.0                   PSF_INST_MAG_raw 2   def  def S
    478   CR_NSIGMA_out         0.0                   PSF_INST_MAG_raw 2   def  def S
    479   EXT_NSIGMA_out        0.0                   PSF_INST_MAG_raw 2 -5.01 5.01 S
    480   PSF_MAJOR_out         0.0                   PSF_INST_MAG_raw 2 -0.01 5.01 S
    481   PSF_MINOR_out         0.0                   PSF_INST_MAG_raw 2 -0.01 5.01 S
    482   PSF_THETA_out         0.0                   PSF_INST_MAG_raw 2 -1.61 1.61 S
    483   PSF_QF_out            0.0                   PSF_INST_MAG_raw 2 -0.10 1.10 S
    484   PSF_QF_PERFECT_out    0.0                   PSF_INST_MAG_raw 2 -0.10 1.10 S
    485   PSF_NDOF_out          0.0                   PSF_INST_MAG_raw 2  def  def  S
    486   PSF_NPIX_out          0.0                   PSF_INST_MAG_raw 2  def  def  S
    487   MOMENTS_XX_out        0.0                   PSF_INST_MAG_raw 2 -0.01 3.01 S
    488   MOMENTS_XY_out        0.0                   PSF_INST_MAG_raw 2 -3.01 3.01 S
    489   MOMENTS_YY_out        0.0                   PSF_INST_MAG_raw 2 -0.01 3.01 S
    490   MOMENTS_M3C_out       0.0                   PSF_INST_MAG_raw 2 -3.01 3.01 S
    491   MOMENTS_M3S_out       0.0                   PSF_INST_MAG_raw 2 -3.01 3.01 S
    492   MOMENTS_M4C_out       0.0                   PSF_INST_MAG_raw 2 -2.01 2.01 S
    493   MOMENTS_M4S_out       0.0                   PSF_INST_MAG_raw 2 -2.01 2.01 S
    494   MOMENTS_R1_out        0.0                   PSF_INST_MAG_raw 2 -5.01 5.01 S
    495   MOMENTS_RH_out        0.0                   PSF_INST_MAG_raw 2 -5.01 5.01 S
    496   K_out                 M_raw                 PSF_INST_MAG_raw 2  def  def  V
    497   KRON_FLUX_ERR_out     0.0                   PSF_INST_MAG_raw 2  def  def  S
    498   KRON_FLUX_INNER_out   0.0                   PSF_INST_MAG_raw 2  def  def  S
    499   KRON_FLUX_OUTER_out   0.0                   PSF_INST_MAG_raw 2  def  def  S
    500 # CAL_PSF_MAG          CAL_PSF_MAG          none Mraw 2 -1.01 1.01 V
    501 # CAL_PSF_MAG_SIG      CAL_PSF_MAG_SIG      none Mraw 2 -1.01 1.01 V
    502 # RA_PSF               RA_PSF               none Mraw 2 -1.01 1.01 V
    503 # DEC_PSF              DEC_PSF              none Mraw 2 -1.01 1.01 V
    504 # PEAK_FLUX_AS_MAG     PEAK_FLUX_AS_MAG     none Mraw 2 -1.01 1.01 V
    505 # FLAGS                FLAGS                0.0  Mraw 2 -1.01 1.01 S
    506 # FLAGS2               FLAGS2               0.0  Mraw 2 -1.01 1.01 S
    507 end
    508 
    509 macro load.cmf
    510   if ($0 != 4)
    511    echo "load.cmf (filename) (ext) (label)"
    512    break
     736    echo "USAGE: cmf.load.concat (dat) (cmf)"
     737    break
    513738  end
    514739
    515740  data $1
    516 
    517   # create the list of fields to load
    518   delete -q myFields
    519   for i 0 $fields:n
    520     if ($?myFields)
    521       $myFields = $myFields $fields:$i
    522     else
    523       $myFields = $fields:$i
    524     end
    525   end
    526 
    527   read -fits $2 $myFields
    528 
    529   # rename the loaded vectors appending the supplied lable
    530   for i 0 $fields:n
    531     set $fields:$i\_$3 = $fields:$i
    532     delete $fields:$i
    533   end
    534 end
    535 
    536 # this list defines the fields to be loaded from file
    537 list fields
    538   X_PSF             
    539   Y_PSF             
    540   X_PSF_SIG         
    541   Y_PSF_SIG         
    542   PSF_INST_MAG       
    543   PSF_INST_MAG_SIG   
    544   PSF_INST_FLUX     
    545   PSF_INST_FLUX_SIG 
    546   AP_MAG             
    547   AP_MAG_RAW         
    548   AP_MAG_RADIUS     
    549   SKY               
    550   SKY_SIGMA         
    551   PSF_CHISQ         
    552   CR_NSIGMA         
    553   EXT_NSIGMA         
    554   PSF_MAJOR         
    555   PSF_MINOR         
    556   PSF_THETA         
    557   PSF_QF             
    558   PSF_QF_PERFECT     
    559   PSF_NDOF           
    560   PSF_NPIX           
    561   MOMENTS_XX         
    562   MOMENTS_XY         
    563   MOMENTS_YY         
    564   MOMENTS_M3C       
    565   MOMENTS_M3S       
    566   MOMENTS_M4C       
    567   MOMENTS_M4S       
    568   MOMENTS_R1         
    569   MOMENTS_RH         
    570   KRON_FLUX         
    571   KRON_FLUX_ERR     
    572   KRON_FLUX_INNER   
    573   KRON_FLUX_OUTER   
    574 #   CAL_PSF_MAG     
    575 #   CAL_PSF_MAG_SIG 
    576 #   RA_PSF           
    577 #   DEC_PSF         
    578 #   PEAK_FLUX_AS_MAG
    579 #  FLAGS           
    580 #  FLAGS2           
    581 end
    582 
    583 # use these cmf entries to measure average stats of the given pairs
    584 list spairs
    585   X_PSF_out             X_raw                 PSF_INST_MAG_raw 2 -15 -10 -8.5  0.1
    586   Y_PSF_out             Y_raw                 PSF_INST_MAG_raw 2 -15 -10 -8.5  0.1
    587   PSF_INST_MAG_out      M_raw                 PSF_INST_MAG_raw 2 -15 -10 -8.5  0.1
    588   AP_MAG_out            M_raw                 PSF_INST_MAG_raw 2 -15 -10 -8.5  0.1
    589 end
    590 
    591 macro show.dpair
    592   if ($0 != 2)
    593     echo "USAGE: show.dpair (N)"
    594     break
    595   end
    596 
    597   list word -split $dpairs:$1
    598   if ($word:n != 7)
    599     echo "invalid dpair $1"
    600     break
    601   end
    602 
    603   $Nr = $word:4
    604 
    605   reindex v1 = $word:0 using index1
    606   reindex dv = $word:1 using index1
    607   reindex v2 = $word:2 using index2
    608   reindex rv = $word:3 using index$Nr
    609 
    610   set delta = (v1 - v2) / dv
    611   if (("$word:5" == "def") || ("$word:6" == "def"))
    612     lim rv delta; box; plot rv delta
    613   else
    614     lim rv $word:5 $word:6; box; plot rv delta
    615   end
    616   label -y '$word:0' -x '$word:3'
    617 end
    618 
    619 # this list is used to compare a pair of vectors with an error it is
    620 # assumed that the vector sets have been loaded and matched with
    621 # match2d to generate index vectors 'index1' and index2'.  the macro
    622 # show.dpair generates a plot of the range vector vs (v1 - v2) / dv1.
    623 # The indices for v1, dv1, and v2 are index1,1, and 2 respectively.  The
    624 # index for the range vector is defined by the integer following that
    625 # vector.  The y-limits of the plot are given by the last two numbers
    626 # (use 'def') for the full default range of the delta vector
    627 list dpairs
    628   # v1              dv                v2   range
    629   X_PSF             X_PSF_SIG         Xraw Mraw  2 -10.0 10.0
    630   Y_PSF             Y_PSF_SIG         Yraw Mraw  2 -10.0 10.0
    631   PSF_INST_MAG      PSF_INST_MAG_SIG  Mraw Mraw  2 -10.0 10.0
    632   PSF_INST_FLUX     PSF_INST_FLUX_SIG Fraw Mraw  2 -10.0 10.0
    633   AP_MAG            PSF_INST_MAG_SIG  Mraw Mraw  2 -10.0 10.0
    634   AP_MAG_RAW        PSF_INST_MAG_SIG  Mraw Mraw  2 -10.0 10.0
     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
     785end
     786
     787macro grid.load.sersic.test
     788  if ($0 != 3)
     789    echo "USAGE: grid.load.devexp.test (srcdir) (fitdir)"
     790    break
     791  end
     792
     793  $fields_bt = X Y M T R r I
     794  $fields_ot = Pmag Kmag Amag IDx MTot
     795
     796  foreach field $fields_bt
     797    foreach set in ot
     798      delete -q $field\$set\_dev_s
     799      delete -q $field\$set\_exp_s
     800    end
     801  end
     802  foreach field $fields_ot
     803    delete -q $field\_dev_s
     804    delete -q $field\_exp_s
     805  end
     806
     807  $Nseq = 0
     808  foreach index 1 2 3 4
     809    foreach Rmajor 3 10 30
     810      foreach Aratio 0.25 0.5 1.0
     811        foreach fwhm 0.8 1.0 1.5
     812          sprint name "sersic.%02d" $Nseq
     813          cmf.load.sersic.test $1/$name.dat $2/$name.fit.cmf
     814          $Nseq ++
     815        end
     816      end
     817    end
     818  end
     819end
     820
     821# I have run DEV and EXP against input models of type SERSIC
     822macro cmf.load.sersic.test
     823  if ($0 != 3)
     824    echo "USAGE: cmf.load.sersic.test (dat) (cmf)"
     825    break
     826  end
     827
     828  # input parameters
     829  data $1
     830  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
     831
     832  # galaxies only
     833  subset Xin = Xin_all if (Type == 1)
     834  subset Yin = Yin_all if (Type == 1)
     835  subset Min = Min_all if (Type == 1)
     836  subset Fin = Fin_all if (Type == 1)
     837  set min = -2.5*log(Fin)
     838
     839  subset Tin_rad = ThetaIn_all if (Type == 1)
     840  set Tin = Tin_rad * 180 / 3.14159265
     841
     842  subset RmajIn = RmajIn_all if (Type == 1)
     843  subset RminIn = RminIn_all if (Type == 1)
     844
     845  subset IndexIn = IndexIn_all if (Type == 1)
     846
     847  $TYPE_S = 83
     848  $TYPE_D = 68
     849  $TYPE_E = 69
     850
     851  data $2
     852
     853  # load measured values from xfit
     854  read -fits Chip.xfit IPP_IDET X_EXT Y_EXT EXT_INST_MAG EXT_WIDTH_MAJ EXT_WIDTH_MIN EXT_THETA MODEL_TYPE PSF_INST_MAG AP_MAG KRON_MAG
     855  set EXT_PAR_07 = (MODEL_TYPE:9 == $TYPE_D)*4 + (MODEL_TYPE:9 == $TYPE_E)
     856
     857  set EXT_THETA_ALT = EXT_THETA * (EXT_THETA >= 0.0) + (EXT_THETA + 3.14159265) * (EXT_THETA < 0.0)
     858  set EXT_THETA = EXT_THETA_ALT * 180 / 3.14159265
     859  set IPP_IDET_EXT = IPP_IDET
     860 
     861  match2d X_EXT Y_EXT Xin Yin 1.0 -index1 index1 -index2 index2
     862
     863  reindex Xot_m = X_EXT using index1
     864  reindex Yot_m = Y_EXT using index1
     865
     866  reindex Xin_m = Xin using index2
     867  reindex Yin_m = Yin using index2
     868
     869  reindex Mot_m = EXT_INST_MAG using index1
     870  reindex Tot_m = EXT_THETA using index1
     871
     872  reindex Min_m = Min using index2
     873  reindex Tin_m = Tin using index2
     874
     875  reindex Rot_m = EXT_WIDTH_MAJ using index1
     876  reindex rot_m = EXT_WIDTH_MIN using index1
     877
     878  reindex Rin_m = RmajIn using index2
     879  reindex rin_m = RminIn using index2
     880 
     881  reindex Pmag_m = PSF_INST_MAG using index1
     882  reindex Kmag_m = KRON_MAG using index1
     883  reindex Amag_m = AP_MAG using index1
     884
     885  reindex IDx_m = IPP_IDET_EXT using index1
     886
     887  reindex MTot_m = MODEL_TYPE:9 using index1
     888
     889  reindex Iot_m = EXT_PAR_07 using index1
     890  reindex Iin_m = IndexIn using index2
     891 
     892  # load moments and other kron values from Chip.psf
     893  read -fits Chip.psf IPP_IDET X_PSF Y_PSF MOMENTS_XX MOMENTS_XY MOMENTS_YY KRON_FLUX_INNER MOMENTS_R1 MOMENTS_RH
     894  set IPP_IDET_PSF = IPP_IDET
     895
     896  join -outer IPP_IDET_PSF IDx_m
     897  reindex Xp = X_PSF using index2
     898  reindex Yp = Y_PSF using index2
     899
     900  reindex Mxx_m = MOMENTS_XX using index2
     901  reindex Mxy_m = MOMENTS_XY using index2
     902  reindex Myy_m = MOMENTS_YY using index2
     903  reindex Mr1_m = MOMENTS_R1 using index2
     904  reindex Mrh_m = MOMENTS_RH using index2
     905  reindex Kfi_m = KRON_FLUX_INNER using index2
     906  set Kmi_m = -2.5*log(Kfi_m)
     907
     908  $fields_bt = X Y M T R r I
     909  $fields_ot = Pmag Kmag Amag IDx MTot Mxx Mxy Myy Mr1 Mrh Kmi
     910
     911  foreach field $fields_ot
     912    subset $field\_exp_m = $field\_m where (MTot_m == $TYPE_E)
     913    subset $field\_dev_m = $field\_m where (MTot_m == $TYPE_D)
     914  end
     915  foreach field $fields_bt
     916    foreach set in ot
     917      subset $field\$set\_exp_m = $field\$set\_m where (MTot_m == $TYPE_E)
     918      subset $field\$set\_dev_m = $field\$set\_m where (MTot_m == $TYPE_D)
     919    end
     920  end
     921
     922  join IDx_exp_m IDx_dev_m
     923  foreach field $fields_ot
     924    reindex $field\_exp_mr = $field\_exp_m using index1
     925    reindex $field\_dev_mr = $field\_dev_m using index2
     926  end
     927  foreach field $fields_bt
     928    foreach set in ot
     929      reindex $field\$set\_exp_mr = $field\$set\_exp_m using index1
     930      reindex $field\$set\_dev_mr = $field\$set\_dev_m using index2
     931    end
     932  end
     933
     934  # concat
     935  foreach field $fields_bt
     936    foreach set in ot
     937      concat $field\$set\_dev_mr $field\$set\_dev_s
     938      concat $field\$set\_exp_mr $field\$set\_exp_s
     939    end
     940  end
     941  foreach field $fields_ot
     942    concat $field\_dev_mr $field\_dev_s
     943    concat $field\_exp_mr $field\_exp_s
     944  end
     945
     946  concat min min_S
     947  concat Min Min_S
    635948end
    636949
     
    659972end
    660973
    661 macro plot.angles
     974macro sersic.integral
    662975  if ($0 != 2)
    663     echo "USAGE: plot.angles (file.dat)"
     976    echo "sersic.integral (index)"
     977    break
     978  end
     979
     980  $index = $1
     981  create r 0.0 200.0 0.001
     982  set q = r^(1/$index)
     983  set f = exp(-q)
     984  set rf = f*r
     985  integrate r rf r[0] r[-1]
     986end
     987
     988macro sersic.integral.rmax
     989  if ($0 != 4)
     990    echo "sersic.integral.rmax (index) (kappa) (rmax)"
     991    echo "kappa is a guess for kappa"
     992    break
     993  end
     994
     995  local index kappa
     996
     997  $index = $1
     998  $kappa = $2
     999
     1000  create r 0.0 $3 0.003
     1001  set q = r^(1/$index)
     1002  set f = exp(-$kappa*q)
     1003  set rf = f*r
     1004  integrate r rf r[0] r[-1]
     1005end
     1006
     1007# S(r) = exp(-kappa*(r/Reff)^(1/index))
     1008# integrate S(r) r dr [ignores 2pi and change-of-variable factors (Rmaj*Rmin)]
     1009macro sersic.integral.reff.rmax
     1010  if ($0 != 5)
     1011    echo "sersic.integral.rmax (index) (kappa) (reff) (rmax)"
     1012    echo "kappa is a guess for kappa"
     1013    break
     1014  end
     1015
     1016  local index kappa Reff
     1017
     1018  $index = $1
     1019  $kappa = $2
     1020  $Reff = $3
     1021
     1022  create r 0.0 $4 0.01
     1023  set q = (r/$Reff)^(1/$index)
     1024  set f = exp(-$kappa*q)
     1025  set rf = f*r
     1026  integrate r rf r[0] r[-1]
     1027end
     1028
     1029# integrate to r = reff (rho = 1), applying kappa
     1030macro sersic.integral.reff
     1031  if ($0 != 3)
     1032    echo "sersic.integral.reff (index) (kappa)"
     1033    break
     1034  end
     1035
     1036  local index kappa
     1037
     1038  $index = $1
     1039  $kappa = $2
     1040  create r 0.0 100.0 0.001
     1041  set q = r^(1/$index)
     1042  set f = exp(-$kappa*q)
     1043  set rf = f*r
     1044  integrate r rf r[0] r[-1]
     1045  $S0 = $sum
     1046  integrate r rf r[0] 1.0
     1047  $S1 = $sum
     1048  echo $S0 $S1 {$S1 / $S0}
     1049end
     1050
     1051macro sersic.integral.find.reff
     1052  if ($0 != 3)
     1053    echo "sersic.integral.find.reff (index) (kappa)"
     1054    echo "kappa is a guess for kappa"
     1055    break
     1056  end
     1057
     1058  local kappa index Rmax i
     1059  $index = $1
     1060  $kappa = $1
     1061
     1062  $Rmin = 0; $Vmin = 0
     1063  $Rmax = 4000
     1064  sersic.integral.rmax $index $kappa $Rmax
     1065  $Vmax = $sum
     1066
     1067  $Rtry = 0.5*($Rmin + $Rmax)
     1068
     1069  while (abs($Rmax - $Rmin) > 0.001)
     1070    sersic.integral.rmax $index $kappa $Rtry
     1071    $Vtry = $sum
     1072
     1073    $Rold = $Rtry
     1074    if ($Vtry > 0.5*$Vmax)
     1075      $Rtry = 0.5*($Rmin + $Rtry)
     1076      $Rmax = $Rold
     1077    else
     1078      $Rtry = 0.5*($Rmax + $Rtry)
     1079      $Rmin = $Rold
     1080    end
     1081    # fprintf "%5.2f %5.2f %5.2f | %5.2f | %6.3f %6.3f | %6.3f" $Rmin $Rold $Rmax $Rtry {$Vtry / $Vmax} $Vmax $Vtry
     1082  end
     1083  # echo $Rtry
     1084  # echo {$kappa * $Rtry ^ (1.0/$index)}
     1085  $KappaReal = $kappa * $Rtry ^ (1.0/$index)
     1086end
     1087
     1088macro sersic.integral.index
     1089
     1090  local i kappa
     1091
     1092  delete -q sersic_sum sersic_norm
     1093  # vlist idx 0.5 0.75 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0
     1094  # create idx 0.5 5.1 0.1
     1095  vlist idx 1 2 4
     1096  for i 0 idx[]
     1097    $kappa =  -0.275552 + 1.972625*idx[$i] + 0.003487*idx[$i]*idx[$i]
     1098    sersic.integral.rmax idx[$i] $kappa 300
     1099    concat $sum sersic_sum
     1100
     1101    $bn = 1.9992*idx[$i] - 0.3271;
     1102    $Io = exp($bn);
     1103           
     1104    # the integral of a Sersic (supposedly) has an analytical form as follows:
     1105    $logGamma = lgamma(2.0*idx[$i]);
     1106    $bnFactor = $bn^(2.0*idx[$i]);
     1107    $norm = idx[$i] * $Io * exp($logGamma) / $bnFactor;
     1108    concat $norm sersic_norm
     1109
     1110    echo idx[$i] $kappa $sum $logGamma $bn $bnFactor $norm
     1111  end
     1112  set lsersic_sum = ln(sersic_sum)
     1113  break
     1114 
     1115  $order = 2
     1116  delete -q sersic_fit fit_idx
     1117
     1118  # fit to ranges:
     1119  delete lsersic_fit fit_idx
     1120  vlist bound 0.0 1.0 2.0 3.0 4.0 5.5
     1121  for i 0 {bound[] - 1}
     1122    subset idxs = idx if (idx >= bound[$i]) && (idx < bound[$i+1])
     1123    subset sums = lsersic_sum if (idx >= bound[$i]) && (idx < bound[$i+1])
     1124    fit idxs sums $order
     1125    applyfit idxs fits
     1126    concat fits lsersic_fit
     1127    concat idxs fit_idx
     1128  end
     1129  set sersic_fit = exp(lsersic_fit)
     1130
     1131  lim -n 1 idx sersic_sum; clear; box; plot idx sersic_sum; plot -c blue -pt 7 idx sersic_norm; plot -x 0 -c red fit_idx sersic_fit
     1132  lim -n 2 idx lsersic_sum; clear; box; plot idx lsersic_sum; plot -x 0 -c red fit_idx lsersic_fit
     1133end
     1134
     1135macro sersic.kappa.index
     1136
     1137  local i
     1138
     1139  delete -q sersic_kappa
     1140  # vlist idx 0.5 0.75 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0
     1141  create idx 0.5 5.1 0.1
     1142  for i 0 idx[]
     1143    sersic.integral.find.reff idx[$i] 10
     1144    concat $KappaReal sersic_kappa
     1145  end
     1146 
     1147  # $order = 2
     1148  # delete -q sersic_kfit kfit_idx
     1149  #
     1150  # # fit to ranges:
     1151  # vlist bound 0.0 1.0 2.0 3.0 4.0 5.5
     1152  # for i 0 {bound[] - 1}
     1153  #   subset idxs = idx if (idx >= bound[$i]) && (idx < bound[$i+1])
     1154  #   subset sums = lsersic_sum if (idx >= bound[$i]) && (idx < bound[$i+1])
     1155  #   fit idxs sums $order
     1156  #   applyfit idxs fits
     1157  #   concat fits lsersic_fit
     1158  #   concat idxs fit_idx
     1159  # end
     1160  # set sersic_fit = exp(lsersic_fit)
     1161
     1162  lim -n 1 idx sersic_kappa; clear; box; plot idx sersic_kappa; # plot -c blue -pt 7 idx sersic_norm; plot -x 0 -c red fit_idx sersic_fit
     1163  # lim -n 2 idx lsersic_sum; clear; box; plot idx lsersic_sum; plot -x 0 -c red fit_idx lsersic_fit
     1164
     1165  # kappa(index) :
     1166  # y = -0.275552 x^0 1.972625 x^1 0.003487 x^2
     1167end
     1168
     1169macro sersic.central.pixel
     1170  if ($0 != 3)
     1171    echo "USAGE: sersic.central.pixel (index) (Reff)"
     1172    break
     1173  end
     1174
     1175  local index Reff
     1176
     1177  $index = $1
     1178  $Reff = $2
     1179
     1180  $kappa = -0.275552 + 1.972625*$index + 0.003487 * $index^2
     1181  # echo "kappa: $kappa"
     1182
     1183  sersic.norm $index
     1184  sersic.integral.reff.rmax $index $kappa $Reff {10*$Reff}; set sumFull = $sum; echo $sum {$Reff^2*$myNorm} {$sum / ($Reff^2*$myNorm)}
     1185  # sersic.integral.reff.rmax $index $kappa $Reff $Reff     ; # echo $sum {$sum / $sumFull}
     1186  # sersic.integral.reff.rmax $index $kappa $Reff 0.1       ; # echo $sum {$sum / $sumFull}
     1187  # sersic.integral.reff.rmax $index $kappa $Reff 0.2       ; # echo $sum {$sum / $sumFull}
     1188  # sersic.integral.reff.rmax $index $kappa $Reff 0.5       ; # echo $sum {$sum / $sumFull}
     1189  # sersic.integral.reff.rmax $index $kappa $Reff 1.0       ; # echo $sum {$sum / $sumFull}
     1190  # sersic.integral.reff.rmax $index $kappa $Reff 2.0       ; # echo $sum {$sum / $sumFull}
     1191  sersic.integral.reff.rmax $index $kappa $Reff 0.564     ; echo $index $Reff {$sum / $sumFull}
     1192
     1193end
     1194
     1195macro sersic.norm
     1196  if ($0 != 2)
     1197    echo "USAGE: sersic.norm (index)"
     1198    break
     1199  end
     1200
     1201  local index
     1202  $index = $1
     1203
     1204  if (($index >= 0.0) && ($index < 1.0))
     1205      $norm = 0.201545  - 0.950965 * $index - 0.315248 * $index^2
     1206      echo $norm {exp($norm)}
     1207      $myNorm = exp($norm)
     1208      return
     1209  end
     1210
     1211  if (($index >= 1.0) && ($index < 2.0))
     1212      $norm = 0.402084  - 1.357775 * $index - 0.105102 * $index^2
     1213      echo $norm {exp($norm)}
     1214      $myNorm = exp($norm)
     1215      return
     1216  end
     1217
     1218  if (($index >= 2.0) && ($index < 3.0))
     1219      $norm = 0.619093 - 1.591674 * $index - 0.041576 * $index^2
     1220      echo $norm {exp($norm)}
     1221      $myNorm = exp($norm)
     1222      return
     1223  end
     1224
     1225  if (($index >= 3.0) && ($index < 4.0))
     1226      $norm = 0.770263 - 1.696421 * $index - 0.023363 * $index^2
     1227      echo $norm {exp($norm)}
     1228      $myNorm = exp($norm)
     1229      return
     1230  end
     1231
     1232  if (($index >= 4.0) && ($index < 5.5))
     1233      $norm = 0.885891 - 1.755684 * $index - 0.015753 * $index^2
     1234      echo $norm {exp($norm)}
     1235      $myNorm = exp($norm)
     1236      return
     1237  end
     1238end
     1239
     1240macro load.model.im
     1241  if ($0 != 2)
     1242    echo "USAGE: load.model.im (N)"
     1243    break
     1244  end
     1245
     1246  rd obj$1 obj.$1.fits
     1247  rd cnv$1 cnv.$1.fits
     1248  rd var$1 var.$1.fits
     1249  rd msk$1 msk.$1.fits
     1250  for i 1 7
     1251    rd dpar$i.$1 dpar.$i.$1.fits
     1252  end
     1253  set dC$1 = (msk$1 == 0) * (obj$1 - cnv$1)^2 / var$1
     1254  tv dC$1 -0.01 3.0
     1255end
     1256
     1257macro load.normdata
     1258  if ($0 != 3)
     1259    echo "USAGE: load.normdata (file) [clear/noclear]"
    6641260    break
    6651261  end
    6661262
    6671263  data $1
    668   read x 1 y 2 type 4 trad 9
    669   set t = trad * 180 / 3.14159265
    670   subset xs = x if (type == 1)
    671   subset ys = y if (type == 1)
    672   subset ts = t if (type == 1)
    673 
    674   set cs = dcos(ts)
    675   set sn = dsin(ts)
    676 
    677   delete xp yp
    678   erase red
    679   for i 0 xs[]
    680     point red LINE xs[$i] ys[$i] {10*cs[$i]} {10*sn[$i]}
    681   end
    682   plot xp yp -pt 100
    683 end
    684 
    685 macro check.flux
    686   if ($0 != 2)
    687     echo "USAGE: plot.angles (file.dat)"
    688     break
    689   end
    690 
    691   data $1
    692   read f 3 type 4
    693   subset F = f if (type == 1)
    694   set M = -2.5*log(F)
    695   vstat M
     1264  read f 3 t 4 m 5
     1265  set M = -2.5*log(f)
     1266  subset Mg = M if (t == 1)
     1267  subset mg = m if (t == 1)
     1268  set dm = mg - Mg
     1269  set n = ramp(dm)
     1270  if ("$2" == "clear")
     1271    lim n dm; clear; box;
     1272  end
     1273  plot n dm
    6961274end
    6971275
     
    7001278  exit 0
    7011279end
     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.