IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Dec 6, 2012, 6:32:19 PM (14 years ago)
Author:
watersc1
Message:

merge from trunk. Preliminary versions of stacktool/warptool updates and regenerate_background.pl script. The warp code is finished and tested, and I still need to get the stack version resolved.

Location:
branches/czw_branch/20120906/psphot
Files:
26 edited

Legend:

Unmodified
Added
Removed
  • branches/czw_branch/20120906/psphot

  • branches/czw_branch/20120906/psphot/src

  • branches/czw_branch/20120906/psphot/src/psphot.h

    r34404 r34772  
    8181
    8282bool            psphotDeblendSatstars (pmConfig *config, const pmFPAview *view, const char *filerule);
    83 bool            psphotDeblendSatstarsReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index);
     83bool            psphotDeblendSatstarsReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe);
    8484
    8585bool            psphotBasicDeblend (pmConfig *config, const pmFPAview *view, const char *filerule);
     
    372372bool psphotMatchSourcesReadout (psArray *objects, pmConfig *config, const pmFPAview *view, const char *filerule, int index);
    373373bool psphotMatchSourcesToObjects (psArray *objects, psArray *sources, float RADIUS);
    374 bool psphotDropBadMatchedSources (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects);
     374bool psphotFilterMatchedSources (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects);
    375375
    376376bool psphotFitSourcesLinearStack (pmConfig *config, psArray *objects, bool final);
     
    525525bool psphotSourceMemoryReadout(pmConfig *config, const pmFPAview *view, const char *filerule, int index);
    526526
     527const char * psphotGetFilerule(const char *baseRule);
     528extern bool psphotINpsphotStack;
     529
    527530#endif
  • branches/czw_branch/20120906/psphot/src/psphotAddNoise.c

    r34404 r34772  
    11# include "psphotInternal.h"
     2
     3bool psphotMaskSource(pmSource *source, bool add, psImageMaskType maskVal);
    24
    35bool psphotAddNoise (pmConfig *config, const pmFPAview *view, const char *filerule) {
     
    3032}
    3133
     34static int Nmasked = 0;
     35
     36// the return state indicates if any sources were actually replaced
    3237bool psphotAddOrSubNoiseReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, bool add) {
    3338
     
    4752
    4853    psArray *sources = detections->allSources;
    49     //psAssert (sources, "missing sources?");
    50     // if no work, should just return true
    51     if (!sources) return true;
     54    // if no work to do, should just return true
     55    if (!sources) return false;
    5256
    5357    psTimerStart ("psphot.noise");
     
    5660    psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels
    5761    psAssert (maskVal, "missing mask value?");
     62
     63    psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT"); // Mask value for bad pixels
     64    psAssert (markVal, "missing mask value?");
    5865
    5966    // increase variance by factor*(object noise):
     
    6774
    6875    if (SIZE <= 0) {
    69        return true;
     76       return false;
    7077    }
    7178
     
    94101
    95102        pmSourceNoiseOp (source, PM_MODEL_OP_FULL | PM_MODEL_OP_NOISE, FACTOR, SIZE, add, maskVal, 0, 0);
     103
     104        psphotMaskSource (source, add, markVal);
    96105    }
    97106    if (add) {
     
    100109        psLogMsg ("psphot.noise", PS_LOG_WARN, "sub noise for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.noise"));
    101110    }
     111    fprintf (stderr, "masked %d objects\n", Nmasked);
    102112
    103113    psphotVisualShowImage (readout);
     
    105115    return true;
    106116}
     117
     118bool psphotMaskSource(pmSource *source, bool add, psImageMaskType maskVal) {
     119
     120    if (!source) return false;
     121    if (!source->peak) return false; // XXX how can we have a peak-less source?
     122    if (source->type == PM_SOURCE_TYPE_DEFECT) return false;
     123    if (source->type == PM_SOURCE_TYPE_SATURATED) return false;
     124
     125    float Xc = source->peak->xf - source->pixels->col0 - 0.5;
     126    float Yc = source->peak->yf - source->pixels->row0 - 0.5;
     127
     128    psImageMaskType notMaskVal = ~maskVal;
     129
     130    for (int iy = 0; iy < source->pixels->numRows; iy++) {
     131        for (int ix = 0; ix < source->pixels->numCols; ix++) {
     132
     133            float radius = hypot (ix - Xc, iy - Yc) ;
     134
     135            if (radius > 4) continue;
     136
     137            if (add) {
     138              source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] |= maskVal;
     139            } else {
     140              source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] &= notMaskVal;
     141            }
     142        }
     143    }
     144    Nmasked ++;
     145
     146    return true;
     147}
     148
  • branches/czw_branch/20120906/psphot/src/psphotBlendFit.c

    r34404 r34772  
    11# include "psphotInternal.h"
    22bool psphotBlendFitSetSource(pmSource *source, psImage *IDimage, float sigSigma);
     3bool psphotBlendSetSourceSatstar (psImage *image, pmSource *source);
     4float InterpolateValues (float X0, float Y0, float X1, float Y1, float X);
    35
    46// for now, let's store the detections on the readout->analysis for each readout
     
    256258
    257259        int TEST_ON = false;
    258 # if (1)
     260# if (0)
    259261# define TEST_X 653
    260262# define TEST_Y 466
    261263        if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) {
    262264            fprintf (stderr, "test object\n");
    263             //  psTraceSetLevel("psLib.math.psMinimizeLMChi2", 5);
     265            psTraceSetLevel("psLib.math.psMinimizeLMChi2", 5);
    264266            TEST_ON = true;
    265267        }
     
    377379    if (!source) return false;
    378380    if (!source->peak) return false; // XXX how can we have a peak-less source?
     381
     382# if (0)
     383# define TEST_X 653
     384# define TEST_Y 466
     385        if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) {
     386            fprintf (stderr, "test object\n");
     387        }
     388# undef TEST_X
     389# undef TEST_Y
     390# endif
     391
    379392    if (!source->moments) return false;
    380393    if (source->type == PM_SOURCE_TYPE_DEFECT) return false;
     
    385398    if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) {
    386399        // find the radius at which we hit something like 0.1*SATURATION
    387         return false;
     400        psphotBlendSetSourceSatstar (IDimage, source);
     401        return true;
    388402    }
    389403
     
    431445    float rMxx = 0.5 / PS_SQR(shape.sx);
    432446    float rMyy = 0.5 / PS_SQR(shape.sy);
    433     float Sxy = -1. * shape.sxy;    // factor of -1 is included to match the previous window function
    434                                     // implementation. XXX: Is this correct?
     447    float Sxy = shape.sxy;    // factor of -1 is included to match the previous window function
     448    // implementation. XXX: Is this correct?
    435449
    436450    int ID = source->id;
     
    443457
    444458            float z = rMxx * PS_SQR(dX) + rMyy * PS_SQR(dY) + Sxy*dX*dY;
     459            if (z > 2.311) continue;
    445460
    446461            float f = Io*exp(-z);
     
    453468    return true;
    454469}
     470
     471bool psphotBlendSetSourceSatstar (psImage *IDimage, pmSource *source) {
     472
     473    float Xo = source->satstar->Xo;
     474    float Yo = source->satstar->Yo;
     475    psVector *logRmodel = source->satstar->logRmodel;
     476    psVector *logFmodel = source->satstar->logFmodel;
     477
     478    float lPeak = logFmodel->data.F32[0];
     479    float fPeak = pow(10.0, lPeak);
     480    float threshold = 0.1*fPeak;
     481    float logThresh = log10(threshold);
     482
     483    float radius = NAN;
     484
     485    // what is the radius for a specific peak fraction?
     486    for (int i = 1; i < logFmodel->n; i++) {
     487        float logF = logFmodel->data.F32[i];
     488        if (!isfinite(logF)) continue;
     489
     490        float flux = pow(10.0, logF);
     491        if (flux > threshold) continue;
     492       
     493        float logF0 = logFmodel->data.F32[i - 1];
     494        float logR0 = logRmodel->data.F32[i - 1];
     495
     496        float logF1 = logFmodel->data.F32[i];
     497        float logR1 = logRmodel->data.F32[i];
     498
     499        float logR = InterpolateValues (logF0, logR0, logF1, logR1, logThresh);
     500        radius = pow(10.0, logR);
     501        break;
     502    }
     503
     504    if (!isfinite(radius)) {
     505        for (int i = logFmodel->n - 1; i >= 0; i--) {
     506            if (!isfinite(logFmodel->data.F32[i])) continue;
     507            float logR = logRmodel->data.F32[i];
     508            radius = pow(10.0, logR);
     509            break;
     510        }
     511    }
     512
     513    if (!isfinite(radius)) return false;
     514
     515    int Nx = IDimage->numCols;
     516    int Ny = IDimage->numRows;
     517
     518    // region to mask
     519    int minX = PS_MIN(PS_MAX(Xo - radius, 0), Nx - 1);
     520    int maxX = PS_MIN(PS_MAX(Xo + radius, 0), Nx - 1);
     521    int minY = PS_MIN(PS_MAX(Yo - radius, 0), Ny - 1);
     522    int maxY = PS_MIN(PS_MAX(Yo + radius, 0), Ny - 1);
     523
     524    int ID = source->id;
     525
     526    fprintf (stderr, "Xo,Yo: %f,%f; radius: %f\n", Xo, Yo, radius);
     527
     528    for (int iy = minY; iy < maxY; iy++) {
     529        for (int ix = minX; ix < maxX; ix++) {
     530
     531            float dX = (ix - Xo);
     532            float dY = (iy - Yo);
     533            float R = hypot (dX, dY) ;
     534            if (R > radius) continue;
     535
     536            IDimage->data.S32[iy][ix] = ID;
     537        }
     538    }
     539    return true;
     540}
     541
  • branches/czw_branch/20120906/psphot/src/psphotDeblendSatstars.c

    r34404 r34772  
    1616bool psphotDeblendSatstars (pmConfig *config, const pmFPAview *view, const char *filerule)
    1717{
     18    bool status = false;
     19
    1820    int num = psphotFileruleCount(config, filerule);
     21
     22    // select the appropriate recipe information
     23    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     24    psAssert (recipe, "missing recipe?");
     25
     26    // perform full extended source non-linear fits?
     27    if (!psMetadataLookupBool (&status, recipe, "SUBTRACT_SATSTAR_PROFILE")) {
     28        psLogMsg ("psphot", PS_LOG_INFO, "skipping extended source fits\n");
     29        return true;
     30    }
    1931
    2032    // loop over the available readouts
    2133    for (int i = 0; i < num; i++) {
    22         if (!psphotDeblendSatstarsReadout (config, view, filerule, i)) {
     34        if (!psphotDeblendSatstarsReadout (config, view, filerule, i, recipe)) {
    2335            psError (PSPHOT_ERR_CONFIG, false, "failed on saturated star deblend analysis for %s entry %d", filerule, i);
    2436            return false;
     
    4052    4) subtract the radial profile
    4153   
     54    There is also support code for calculation of magnitudes and add/subtract the profile (a la pmSourceOp)
     55
    4256    TBD:
    4357
    44     * function to replace the radial profile for a source
    4558    * recenter the profile (based on cross-correlation / convolution with 1D profile)
    46 
    47     * raise a bit somewhere for these super saturated stars (if they were so modeled)
    48     * consider the subtraction bit : when to raise it?
    49 
    5059 **/
    5160
    52 bool psphotDeblendSatstarsReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int fileIndex) {
     61bool psphotDeblendSatstarsReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int fileIndex, psMetadata *recipe) {
    5362
    5463    int N;
     
    5665    bool status;
    5766
    58     // XXX disable this function for now
    59     return true;
    60 
    6167    psTimerStart ("psphot.deblend.sat");
    6268
     
    7884        return true;
    7985    }
    80 
    81     // select the appropriate recipe information
    82     psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
    83     psAssert (recipe, "missing recipe?");
    8486
    8587    // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
     
    124126    int BIG_SIGMA = BIG_RADIUS / 4.0;
    125127
    126     int display = psphotKapaChannel (1);
    127     psphotVisualScaleImage (display, (psImage *) source->pixels->parent, NULL, "image", 1.0, 0);
     128    // int display = psphotKapaChannel (1);
     129    // psphotVisualScaleImage (display, (psImage *) source->pixels->parent, NULL, "image", 1.0, 0);
    128130
    129131    // examine sources in decreasing SN order
     
    185187    }
    186188    // show the image after object have been subtracted
    187     psphotVisualScaleImage (display, (psImage *) source->pixels->parent, NULL, "image", 1.0, 1);
     189    // psphotVisualScaleImage (display, (psImage *) source->pixels->parent, NULL, "image", 1.0, 1);
    188190
    189191    psFree (SN);
     
    451453    // XXX do something sensible here if the profile is crap
    452454
     455    // replace an existing profile
     456    psFree (source->satstar);
    453457    source->satstar = pmSourceSatstarAlloc();
    454458    source->satstar->Xo = Xo;
     
    494498    psStatsInit (fluxStats);
    495499
    496     while (logR->data.F32[bin] < lRmax) {
     500    while (bin < logR->n && logR->data.F32[bin] < lRmax) {
    497501      if (isfinite(flux->data.F32[bin])) {
    498502          psVectorAppend (fluxVals, flux->data.F32[bin]);
     
    540544    float logRdel = 0.1;
    541545
    542     float Xc = source->satstar->Xo - source->pixels->col0 - 0.5;
    543     float Yc = source->satstar->Yo - source->pixels->row0 - 0.5;
    544     psVector *logRmodel = source->satstar->logRmodel;
    545     psVector *logFmodel = source->satstar->logFmodel;
     546    pmSourceSatstar *satstar = source->satstar ? source->satstar : (source->parent ? source->parent->satstar : NULL);
     547    psAssert (satstar, "null satstar");
     548    float Xc = satstar->Xo - source->pixels->col0 - 0.5;
     549    float Yc = satstar->Yo - source->pixels->row0 - 0.5;
     550    psVector *logRmodel = satstar->logRmodel;
     551    psVector *logFmodel = satstar->logFmodel;
    546552
    547553    for (int iy = 0; iy < source->pixels->numRows; iy++) {
     
    10441050}
    10451051
     1052// the return state indicates if any sources were actually subtracted
    10461053bool psphotAddOrSubSatstarsReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int fileIndex, psMetadata *recipe, bool add) {
    10471054
    10481055    bool status;
     1056    bool modified = false;
    10491057
    10501058    psTimerStart ("psphot.deblend.sat");
     
    10611069
    10621070    psArray *sources = detections->allSources;
    1063     psAssert (sources, "missing sources?");
     1071    // if no work to do, should just return false
     1072    if (!sources) return false;
    10641073
    10651074    if (!sources->n) {
    10661075        psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping satstar blend");
    1067         return true;
     1076        return false;
    10681077    }
    10691078
     
    10781087        if (!(source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE)) continue;
    10791088
     1089        // tell the calling function that we modified the image
     1090        modified = true;
     1091
    10801092        if (!psphotSatstarProfileOp (source, maskVal, 1.0, 0, add)) continue;
    10811093    }
    10821094
    10831095    psLogMsg ("psphot", PS_LOG_DETAIL, "satstar op: %f sec\n", psTimerMark ("psphot.deblend.sat"));
    1084     return true;
     1096    return modified;
    10851097}
    10861098
  • branches/czw_branch/20120906/psphot/src/psphotDefineFiles.c

    r33963 r34772  
    11# include "psphotInternal.h"
     2
     3bool psphotINpsphotStack = false;
    24
    35// List of output files
     
    181183    return;
    182184}
     185
     186// psphotGetFilerule
     187// Since psphotStack processes multipe FPAs at a time it has a different file rule structure than regular psphot.
     188// For the background output files we define a function psphotGetFilerule which given a base psphot file rule
     189// returns the corresponding psphotStack rule *if* the program is psphotStack. That is indicated by a global
     190// boolean which defaults to false, and psphotStack only sets to true
     191
     192const char *psphotGetFilerule(const char *psphotRule) {
     193    const char *rule = psphotRule;
     194    if (psphotINpsphotStack) {
     195        if (!strcmp(psphotRule, "PSPHOT.BACKMDL")) {
     196            rule =  "PSPHOT.STACK.BACKMDL";
     197        } else if (!strcmp(psphotRule, "PSPHOT.BACKMDL.STDEV")) {
     198            rule = "PSPHOT.STACK.BACKMDL.STDEV";
     199        } else if (!strcmp(psphotRule, "PSPHOT.BACKSUB")) {
     200            rule = "PSPHOT.STACK.BACKSUB";
     201        } else if (!strcmp(psphotRule, "PSPHOT.BACKGND")) {
     202            rule = "PSPHOT.STACK.BACKGND";
     203        } else {
     204            psAssert(0, "unsupported file rule %s", psphotRule);
     205        }
     206    }
     207    return rule;
     208}
  • branches/czw_branch/20120906/psphot/src/psphotFindDetections.c

    r34404 r34772  
    4646    psAssert (maskVal, "missing mask value?");
    4747
     48    // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
     49    psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT"); // Mask value for bad pixels
     50    psAssert (markVal, "missing mark value?");
     51
     52    maskVal |= markVal;
     53
    4854    // Use the new pmFootprints approach?
    4955    const bool useFootprints = psMetadataLookupBool(NULL, recipe, "USE_FOOTPRINTS");
     
    6470        psMemIncrRefCounter(detections); // so we can free the detections below
    6571    }
     72
     73    // first pass vs other: if this is the first pass, the code will use PEAKS_NSIGMA_LIMIT and
     74    // only attempt to detect PEAKS_NMAX entries.  If 'firstPass' is false, the code will
     75    // attempt to replace the subtracted sources in order to measure the footprints.  After
     76    // replacement, it is necessary to regenerate the significance image.  If no sources are
     77    // available, the code will skip the significance image regeneration step.
    6678
    6779    bool replaceSourcesForFootprints = false;
     
    120132    if (useFootprints) {
    121133        if (replaceSourcesForFootprints) {
     134            bool modified = false;
    122135            // subtract the noise for all sources including satstars
    123             psphotAddOrSubNoiseReadout(config, view, filerule, index, recipe, false);
    124             psphotReplaceAllSourcesReadout (config, view, filerule, index, recipe, false);
     136            modified |= psphotAddOrSubNoiseReadout(config, view, filerule, index, recipe, false);
     137            modified |= psphotReplaceAllSourcesReadout (config, view, filerule, index, recipe, false);
    125138
    126139            // add in the satstars
    127             psphotAddOrSubSatstarsReadout (config, view, filerule, index, recipe, true);
     140            modified |= psphotAddOrSubSatstarsReadout (config, view, filerule, index, recipe, true);
    128141
    129             psFree (significance);
    130             significance = psphotSignificanceImage (readout, recipe, maskVal);
     142            if (modified) {
     143                psFree (significance);
     144                significance = psphotSignificanceImage (readout, recipe, maskVal);
     145            }
    131146
    132147            // display the significance image
  • branches/czw_branch/20120906/psphot/src/psphotFitSourcesLinear.c

    r34404 r34772  
    439439        model->params->data.F32[PM_PAR_I0] = norm->data.F32[i];
    440440        model->dparams->data.F32[PM_PAR_I0] = errors->data.F32[i];
     441
     442        if (norm->data.F32[i] < MIN_VALID_FLUX) {
     443          fprintf (stderr, "fit out of bounds for %f,%f : %f\n", source->peak->xf, source->peak->yf, norm->data.F32[i]);
     444          model->params->data.F32[PM_PAR_I0] = MIN_VALID_FLUX;
     445        }
    441446
    442447        // clear the 'mark' pixels so the subtraction covers the full window
  • branches/czw_branch/20120906/psphot/src/psphotKronIterate.c

    r34404 r34772  
    11# include "psphotInternal.h"
    22
    3 bool psphotKronWindowSetSource(pmSource *source, psImage *kronWindow, bool useKronRadius, bool insert, bool oldWindow);
    4 bool psphotKronWindowMag (pmSource *source, psImage *kronWindow, float radius, float minKronRadius, psImageMaskType maskVal, bool applyWeight, psImage *smoothedPixels);
    5 
    6 
    7 bool psphotKronIterate (pmConfig *config, const pmFPAview *view, const char *filerule, int pass)
    8 {
     3bool psphotKronRadiusMeasure (pmSource *source, float radius, float minKronRadius, psImageMaskType maskVal, psImage *smoothedPixels);
     4bool psphotKronFluxMeasure (pmSource *source, psImageMaskType maskVal);
     5
     6
     7bool psphotKronIterate (pmConfig *config, const pmFPAview *view, const char *filerule, int pass) {
    98    bool status = true;
    109
     
    9897    }
    9998
    100     bool KRON_APPLY_WEIGHT = psMetadataLookupBool (&status, recipe, "KRON_APPLY_WEIGHT");
    101     if (!status) {
    102         KRON_APPLY_WEIGHT = true;
    103     }
    104 
    105     bool KRON_APPLY_WINDOW = psMetadataLookupBool (&status, recipe, "KRON_APPLY_WINDOW");
    106     if (!status) {
    107         KRON_APPLY_WINDOW = false;
    108     }
    10999    bool KRON_SMOOTH = psMetadataLookupBool (&status, recipe, "KRON_SMOOTH");
    110100    if (!status) {
     
    170160    }
    171161
    172     // generate the window image: multiply the flux by this to downweight neighbors
    173     // XXX: we don't need this image if we aren't going to apply the window
    174     psImage *kronWindow = psImageAlloc (readout->image->numCols, readout->image->numRows, PS_TYPE_F32);
    175     psImageInit (kronWindow, 1.0);
    176 
    177     // start with the currently known moments (Mxx, Myy, Mxy) and generate a window image
    178     for (int i = 0; i < sources->n; i++) {
    179 
    180         pmSource *source = sources->data[i];
    181 
    182         // set a window function for each source based on the moments
    183         // (this skips really bad sources (no peak, no moments, DEFECT)
    184         psphotKronWindowSetSource (source, kronWindow, false, true, KRON_APPLY_WINDOW);
     162    // pass 3 we only measure fluxes for matched sources so we don't need smooth pixels or multiple iterations
     163    if (pass == 3) {
     164        KRON_SMOOTH = false;
     165        KRON_ITERATIONS = 1;
    185166    }
    186167
     
    235216
    236217            psArrayAdd(job->args, 1, readout);
    237             psArrayAdd(job->args, 1, kronWindow);
    238218            psArrayAdd(job->args, 1, cells->data[j]); // sources
    239219            psArrayAdd(job->args, 1, smoothedImage);
     
    243223            PS_ARRAY_ADD_SCALAR(job->args, MIN_KRON_RADIUS,    PS_TYPE_F32);
    244224            PS_ARRAY_ADD_SCALAR(job->args, KRON_ITERATIONS,    PS_TYPE_S32);
    245             PS_ARRAY_ADD_SCALAR(job->args, (psS32) KRON_APPLY_WEIGHT, PS_TYPE_S32);
    246             PS_ARRAY_ADD_SCALAR(job->args, (psS32) KRON_APPLY_WINDOW, PS_TYPE_S32);
    247225            PS_ARRAY_ADD_SCALAR(job->args, KRON_SMOOTH_SIGMA,  PS_TYPE_F32);
    248226            PS_ARRAY_ADD_SCALAR(job->args, KRON_SB_MIN_DIVISOR,PS_TYPE_F32);
     
    281259    }
    282260    psFree (cellGroups);
    283     psFree (kronWindow);
    284261    if (KRON_SMOOTH) {
    285262        for (int i = 0; i < sources->n; i++) {
     
    298275
    299276    pmReadout *readout              = job->args->data[0];
    300     psImage *kronWindow             = job->args->data[1];
    301     psArray *sources                = job->args->data[2];
    302     psImage *smoothedImage          = job->args->data[3];
    303     psImageMaskType markVal         = PS_SCALAR_VALUE(job->args->data[4],PS_TYPE_IMAGE_MASK_DATA);
    304     psImageMaskType maskVal         = PS_SCALAR_VALUE(job->args->data[5],PS_TYPE_IMAGE_MASK_DATA);
    305     float RADIUS                    = PS_SCALAR_VALUE(job->args->data[6],F32);
    306     float MIN_KRON_RADIUS           = PS_SCALAR_VALUE(job->args->data[7],F32);
    307     int KRON_ITERATIONS             = PS_SCALAR_VALUE(job->args->data[8],S32);
    308     bool KRON_APPLY_WEIGHT          = PS_SCALAR_VALUE(job->args->data[9],S32);
    309     bool KRON_APPLY_WINDOW          = PS_SCALAR_VALUE(job->args->data[10],S32);
    310     float KRON_SMOOTH_SIGMA         = PS_SCALAR_VALUE(job->args->data[11],F32);
    311     float KRON_SB_MIN_DIVISOR       = PS_SCALAR_VALUE(job->args->data[12],F32);
    312     int pass                        = PS_SCALAR_VALUE(job->args->data[13],S32);
    313 #ifndef REVERT_ON_BAD_MEASUREMENT
    314     (void) pass;
    315 #endif
     277    psArray *sources                = job->args->data[1];
     278    psImage *smoothedImage          = job->args->data[2];
     279    psImageMaskType markVal         = PS_SCALAR_VALUE(job->args->data[3],PS_TYPE_IMAGE_MASK_DATA);
     280    psImageMaskType maskVal         = PS_SCALAR_VALUE(job->args->data[4],PS_TYPE_IMAGE_MASK_DATA);
     281    float RADIUS                    = PS_SCALAR_VALUE(job->args->data[5],F32);
     282    float MIN_KRON_RADIUS           = PS_SCALAR_VALUE(job->args->data[6],F32);
     283    int KRON_ITERATIONS             = PS_SCALAR_VALUE(job->args->data[7],S32);
     284    float KRON_SMOOTH_SIGMA         = PS_SCALAR_VALUE(job->args->data[8],F32);
     285    float KRON_SB_MIN_DIVISOR       = PS_SCALAR_VALUE(job->args->data[9],F32);
     286    int pass                        = PS_SCALAR_VALUE(job->args->data[10],S32);
     287
     288    bool measureRadius = true;
     289    if (pass == 3) {
     290        measureRadius = false;
     291    }
    316292
    317293    for (int j = 0; j < KRON_ITERATIONS; j++) {
     
    320296            pmSource *source = sources->data[i];
    321297            if (!source->peak) continue; // XXX how can we have a peak-less source?
    322 
    323             // check status of this source's moments
    324             if (!source->moments) continue;
    325             if (!(source->tmpFlags & PM_SOURCE_TMPF_MOMENTS_MEASURED)) continue;
    326             if (source->mode & PM_SOURCE_MODE_MOMENTS_FAILURE) continue;
     298            if (!source->moments) continue;
     299            if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
     300            if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
     301            // skip saturated stars modeled with a radial profile
     302            if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue;
     303
     304            // in pass 3 we only measure the flux for matched sources
     305            if ((pass == 3) && !(source->mode2 & PM_SOURCE_MODE2_MATCHED)) continue;
     306
     307# if (0)
     308# define TEST_X 653
     309# define TEST_Y 466
     310            if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) {
     311                fprintf (stderr, "test object\n");
     312            }
     313# undef TEST_X
     314# undef TEST_Y
     315# endif
     316
     317            if (measureRadius) {
     318                // check status of this source's moments
     319                // XXX: I don't think that we have to apply these restrictions since we dropped the window function
     320                if (!(source->tmpFlags & PM_SOURCE_TMPF_MOMENTS_MEASURED)) continue;
     321                if (source->mode & PM_SOURCE_MODE_MOMENTS_FAILURE) continue;
     322            }
     323
    327324            if (!isfinite(source->moments->Mrf)) {
    328325                // Once we save a bad Mrf measurement we give up on this source
    329                 // checking here allows us to avoid adding and subtracting the model
     326                // XXX: is this the right thing to do?
    330327                continue;
    331328            }
    332 
    333             // skip saturated stars modeled with a radial profile
    334             if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue;
    335329
    336330            // replace object in image
     
    348342            // On first iteration set window radius to sky radius (if valid). We also use this on subsequent
    349343            // iterations if we cannot find a better limit
    350             float maxWindow = isfinite(source->skyRadius) ? source->skyRadius : RADIUS;
     344            float maxWindow;
     345            if (measureRadius) {
     346                maxWindow = isfinite(source->skyRadius) ? source->skyRadius : RADIUS;
     347            } else {
     348                maxWindow = source->moments->Mrf;
     349            }
    351350            if (j > 0) {
    352351                // on subsequent iterations we use a factor times the previous radial moment value
     
    370369            float windowRadius = PS_MAX(RADIUS, maxWindow);
    371370
    372 #ifdef REVERT_ON_BAD_MEASURMENT
    373             // save previous measurements. We might revert back to them if this round fails
    374             float MrfPrior = source->moments->Mrf;
    375             float KronFluxPrior = source->moments->KronFlux;
    376             float KronFluxErrPrior = source->moments->KronFluxErr;
    377 #endif
    378 
    379371            // re-allocate image, weight, mask arrays for each peak with box big enough to fit BIG_RADIUS
    380372            bool extend = pmSourceRedefinePixels (source, readout, source->peak->x, source->peak->y, windowRadius + 2);
    381             psAssert (source->pixels, "WTF?");
     373            psAssert (source->pixels, "redefine pixels failed?");
    382374            if (extend && smoothedPixels) {
    383375                psFree(source->tmpPtr);
    384376                smoothedPixels = psImageSubset(smoothedImage, source->region);
    385                 psAssert (smoothedPixels, "WTF?");
     377                psAssert (smoothedPixels, "redefine smoothed pixels failed?");
    386378                source->tmpPtr = (psPtr) smoothedPixels ;
    387379            }
    388380
    389 
    390             // clear the window function for this source based on the moments
    391             // Note: this function also applies cuts on the source and returns false if it
    392             // does not meet the requirements for measuring the Kron Radius or Magnitude.
    393             // Note: that it performs the cuts even if KRON_APPLY_WINDOW is false
    394             if (psphotKronWindowSetSource (source, kronWindow, (j > 0), false, KRON_APPLY_WINDOW)) {
    395 
    396                 // this function populates moments->Mrf,KronFlux,KronFluxErr
    397                 psphotKronWindowMag (source, kronWindow, windowRadius, MIN_KRON_RADIUS, maskVal, KRON_APPLY_WEIGHT, smoothedPixels);
    398                 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
    399 
    400                 // set a window function for each source based on the moments
    401                 psphotKronWindowSetSource (source, kronWindow, true, true, KRON_APPLY_WINDOW);
    402             }
    403 
    404 #ifdef REVERT_ON_BAD_MEASUREMENT
    405             // on pass 2 if we get an invalid measurement on a pass 1 source where we had a good one previously
    406             // in pass 1 keep that measurement
    407             bool reverted = false;
    408             if (pass > 1 && !isfinite(source->moments->Mrf) && (source->mode2 & PM_SOURCE_MODE2_PASS1_SRC)) {
    409                 source->moments->Mrf = MrfPrior;    // This is finite otherwise we wouldn't have gotten here
    410                 source->moments->KronFlux = KronFluxPrior;
    411                 source->moments->KronFluxErr = KronFluxErrPrior;
    412                 reverted = true;
    413             }
    414 #endif
     381            bool measureFlux = true;
     382            if (measureRadius) {
     383                measureFlux = psphotKronRadiusMeasure (source, windowRadius, MIN_KRON_RADIUS, maskVal, smoothedPixels);
     384            }
     385
     386            if (measureFlux) {
     387                // Make sure the sources images are large enough for the measured Kron Radius
     388                bool extend = pmSourceRedefinePixels (source, readout, source->peak->x, source->peak->y,
     389                    2.5 * source->moments->Mrf + 2);
     390
     391                psAssert (source->pixels, "redefine pixels failed?");
     392                if (extend && smoothedPixels) {
     393                    psFree(source->tmpPtr);
     394                    smoothedPixels = psImageSubset(smoothedImage, source->region);
     395                    psAssert (smoothedPixels, "redefine smoothed pixels failed?");
     396                    source->tmpPtr = (psPtr) smoothedPixels ;
     397                }
     398
     399                // this function populates moments->Mrf,KronFlux,KronFluxErr, KronFinner, and KronFouter
     400                psphotKronFluxMeasure (source, maskVal);
     401            }
     402
     403            psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
     404
    415405#ifdef DUMP_KRS
    416 #ifndef REVERT_ON_BAD_MEASUREMENT
    417             bool reverted = false;
    418 #endif
    419             fprintf(dumpFile, "%7d %1d %6.1f %6.1f %6.1f %6.1f %6.1f %6.1f %2d\n", source->id, reverted, source->moments->Mrf, MrfPrior, maxWindow, windowRadius, source->peak->xf, source->peak->yf, source->imageID);
     406            fprintf(dumpFile, "%7d %6.1f %6.1f %6.1f %6.1f %6.1f %6.1f %2d\n", source->id, source->moments->Mrf, MrfPrior, maxWindow, windowRadius, source->peak->xf, source->peak->yf, source->imageID);
    420407#endif
    421408
     
    433420}
    434421
    435 bool psphotKronWindowMag (pmSource *source, psImage *kronWindow, float radius, float minKronRadius, psImageMaskType maskVal,
    436     bool applyWeight, psImage *smoothedPixels) {
     422bool psphotKronRadiusMeasure (pmSource *source, float radius, float minKronRadius, psImageMaskType maskVal,
     423    psImage *smoothedPixels) {
    437424
    438425    PS_ASSERT_PTR_NON_NULL(source, false);
     
    442429
    443430    psF32 R2 = PS_SQR(radius);
    444     float rsigma2 =  applyWeight ? 0.5 / R2 : 0;
    445431
    446432    // a note about coordinates: coordinates of objects throughout psphot refer to the primary
     
    455441    // Xn  = SUM (x - xc)^n * (z - sky)
    456442
    457 
    458443    psF32 RF = 0.0;
    459444    psF32 RS = 0.0;
     
    471456    psF32 yCM = Yo - 0.5 - source->pixels->row0; // coord of peak in subimage
    472457
    473     int Xwo = source->pixels->col0;
    474     int Ywo = source->pixels->row0;
    475 
    476458    psF32 **vPix;
    477459    if (smoothedPixels) {
     
    480462        vPix = source->pixels->data.F32;
    481463    }
    482     psF32 **vWin = kronWindow->data.F32;
     464   
     465    psImageMaskType **vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA;
     466
     467    {
     468        for (psS32 row = 0; row < source->pixels->numRows ; row++) {
     469
     470            psF32 yDiff = row - yCM;
     471            if (fabs(yDiff) > radius) continue;
     472
     473            // coordinate of mirror pixel
     474            int yFlip = yCM - yDiff;
     475            if (yFlip < 0) continue;
     476            if (yFlip >= source->pixels->numRows) continue;
     477
     478            for (psS32 col = 0; col < source->pixels->numCols ; col++) {
     479                // check mask and value for this pixel
     480                if (vMsk && (vMsk[row][col] & maskVal)) continue;
     481                if (isnan(vPix[row][col])) continue;
     482
     483                psF32 xDiff = col - xCM;
     484                if (fabs(xDiff) > radius) continue;
     485
     486                // coordinate of mirror pixel
     487                int xFlip = xCM - xDiff;
     488                if (xFlip < 0) continue;
     489                if (xFlip >= source->pixels->numCols) continue;
     490
     491                // check mask and value for mirror pixel
     492                if (vMsk && (vMsk[yFlip][xFlip] & maskVal)) continue;
     493                if (isnan(vPix[yFlip][xFlip])) continue;
     494
     495                // radius is just a function of (xDiff, yDiff)
     496                psF32 r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
     497                if (r2 > R2) continue;
     498
     499                float fDiff1 = vPix[row][col];
     500                float fDiff2 = vPix[yFlip][xFlip];
     501
     502                float pDiff = (fDiff1 > 0.0) ? sqrt(fabs(fDiff1*fDiff2)) : -sqrt(fabs(fDiff1*fDiff2));
     503
     504                // Kron Flux uses the 1st radial moment
     505                psF32 rf = pDiff * sqrt(r2);
     506                psF32 rs = 0.5 * (fDiff1 + fDiff2);
     507
     508                RF  += rf;
     509                RS  += rs;
     510            }
     511        }
     512
     513        float MrfTry = RF/RS;
     514        if (RF <= 0. || RS <= 0 || !isfinite(MrfTry)) {
     515            // We did not get a good measurement
     516            source->moments->Mrf = NAN;
     517            source->moments->KronFlux  = NAN;
     518            source->moments->KronFluxErr  = NAN;
     519            return false;
     520        }
     521
     522        float Mrf = MAX(minKronRadius, MrfTry);
     523        // Saturate the 1st radial moment
     524        if (sqrt(source->peak->detValue) < 10.0) {
     525            Mrf = MIN (radius, Mrf);
     526        }
     527        source->moments->Mrf = Mrf;
     528    }
     529    return true;
     530}
     531
     532bool psphotKronFluxMeasure(pmSource *source, psImageMaskType maskVal) {
     533
     534    PS_ASSERT_PTR_NON_NULL(source, false);
     535    PS_ASSERT_PTR_NON_NULL(source->peak, false);
     536    PS_ASSERT_PTR_NON_NULL(source->pixels, false);
     537
     538    // a note about coordinates: coordinates of objects throughout psphot refer to the primary
     539    // image coordinates.  the source->pixels image has an offset relative to its parent of
     540    // col0,row0: a pixel (x,y) in the primary image has coordinates of (x-col0, y-row0) in
     541    // this subimage.  we subtract off the peak coordinates, adjusted to this subimage, to have
     542    // minimal round-off error in the sums.  since these values are subtracted just to minimize
     543    // the dynamic range and are added back below, the exact value does not matter. these are
     544    // (int) so they can be used in the image index below.
     545
     546    // Now calculate higher-order moments, using the above-calculated first moments to adjust coordinates
     547    // Xn  = SUM (x - xc)^n * (z - sky)
     548
     549    // the peak position is less accurate but less subject to extreme deviations
     550    float dX = source->moments->Mx - source->peak->xf;
     551    float dY = source->moments->My - source->peak->yf;
     552    float dR = hypot(dX, dY);
     553    float Xo = (dR < 2.0) ? source->moments->Mx : source->peak->xf;
     554    float Yo = (dR < 2.0) ? source->moments->My : source->peak->yf;
     555
     556    // center of mass in subimage.  Note: the calculation below uses pixel index, so we correct
     557    // xCM, yCM from pixel coords to pixel index here.
     558    psF32 xCM = Xo - 0.5 - source->pixels->col0; // coord of peak in subimage
     559    psF32 yCM = Yo - 0.5 - source->pixels->row0; // coord of peak in subimage
     560
     561    psF32 **vPix = source->pixels->data.F32;
    483562    psF32 **vWgt = source->variance->data.F32;
    484563   
    485564    psImageMaskType **vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA;
    486565
     566    source->moments->KronFlux  = NAN;
     567    source->moments->KronFluxErr  = NAN;
     568    source->moments->KronFinner = NAN;
     569    source->moments->KronFouter = NAN;
     570
     571    // Calculate the Kron fluxes
     572    float radKinner = 1.0 * source->moments->Mrf;
     573    float radKron   = 2.5 * source->moments->Mrf;
     574    float radKouter = 4.0 * source->moments->Mrf;
     575
     576    float limitRadius = MIN (radKouter, source->windowRadius);
     577    if (radKouter > source->windowRadius) {
     578        // This happens but the measurement isn't important enough to allocate the extra pixels
     579        // psWarning ("outer kron radius: %f is larger than windowRadius: %f for %d\n",
     580        //     radKouter, source->windowRadius, source->id);
     581        limitRadius = MIN (radKron, source->windowRadius);
     582    }
     583    if (radKron > source->windowRadius) {
     584        // caller should have prevented this from happening
     585        psWarning ("kron radius: %f is larger than windowRadius: %f for %d\n",
     586            radKron, source->windowRadius, source->id);
     587        return false;
     588    }
     589
     590    float Sum = 0.0;
     591    float Var = 0.0;
     592    float SumInner = 0.0;
     593    float SumOuter = 0.0;
     594
     595    // set vPix to the source pixels (it may have been set to the smoothed image above)
     596    vPix = source->pixels->data.F32;
     597
    487598    for (psS32 row = 0; row < source->pixels->numRows ; row++) {
    488599
    489600        psF32 yDiff = row - yCM;
    490         if (fabs(yDiff) > radius) continue;
    491 
    492         // coordinate of mirror pixel
    493         int yFlip = yCM - yDiff;
    494         if (yFlip < 0) continue;
    495         if (yFlip >= source->pixels->numRows) continue;
     601        if (fabs(yDiff) > limitRadius) continue;
    496602
    497603        for (psS32 col = 0; col < source->pixels->numCols ; col++) {
     
    501607
    502608            psF32 xDiff = col - xCM;
    503             if (fabs(xDiff) > radius) continue;
    504 
    505             // coordinate of mirror pixel
    506             int xFlip = xCM - xDiff;
    507             if (xFlip < 0) continue;
    508             if (xFlip >= source->pixels->numCols) continue;
    509 
    510             // check mask and value for mirror pixel
    511             if (vMsk && (vMsk[yFlip][xFlip] & maskVal)) continue;
    512             if (isnan(vPix[yFlip][xFlip])) continue;
    513 
    514             // radius is just a function of (xDiff, yDiff)
     609            if (fabs(xDiff) > limitRadius) continue;
     610
    515611            psF32 r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
    516             if (r2 > R2) continue;
    517 
    518             // flux * window
    519             float z = r2 * rsigma2;
    520             assert (z >= 0.0);
    521 
    522             // weight by window image and wide Gaussian
    523             float weight1  = vWin[row+Ywo][col+Xwo]*exp(-z);
    524             float weight2  = vWin[yFlip+Ywo][xFlip+Xwo]*exp(-z);
    525 
    526             float fDiff1 = vPix[row][col]*weight1;
    527             float fDiff2 = vPix[yFlip][xFlip]*weight2;
    528 
    529             float pDiff = (fDiff1 > 0.0) ? sqrt(fabs(fDiff1*fDiff2)) : -sqrt(fabs(fDiff1*fDiff2));
    530 
    531             // Kron Flux uses the 1st radial moment (maybe Gaussian windowed?)
    532             psF32 rf = pDiff * sqrt(r2);
    533             psF32 rs = 0.5 * (fDiff1 + fDiff2);
    534 
    535             RF  += rf;
    536             RS  += rs;
     612            psF32 r = sqrt(r2);
     613
     614            float pDiff = vPix[row][col];
     615            psF32 wDiff = vWgt[row][col];
     616
     617            if (r > radKinner && r < radKron) {
     618                SumInner += pDiff;
     619            }
     620            if (r < radKron) {
     621                Sum += pDiff;
     622                Var += wDiff;
     623            }
     624            if (r > radKron && r < radKouter) {
     625                SumOuter += pDiff;
     626            }
    537627        }
    538628    }
    539629
    540     float MrfTry = RF/RS;
    541     if (RF <= 0. || RS <= 0 || !isfinite(MrfTry)) {
    542         // We did not get a good measurement
    543         source->moments->Mrf = NAN;
    544         source->moments->KronFlux  = NAN;
    545         source->moments->KronFluxErr  = NAN;
    546         return false;
    547     }
    548 
    549     float Mrf = MAX(minKronRadius, MrfTry);
    550     // Saturate the 1st radial moment
    551     if (sqrt(source->peak->detValue) < 10.0) {
    552         Mrf = MIN (radius, Mrf);
    553     }
    554 
    555     // Calculate the Kron magnitude (make this block optional?)
    556     float radKron  = 2.5*Mrf;
    557     float radKron2 = radKron*radKron;
    558 
    559     int nKronPix = 0;
    560     float Sum = 0.0;
    561     float Var = 0.0;
    562     float Win = 0.0;
    563 
    564     // set vPix to the source pixels (it may have been set to the
    565     // smoothed image above)
    566     vPix = source->pixels->data.F32;
    567 
    568 
    569     for (psS32 row = 0; row < source->pixels->numRows ; row++) {
    570 
    571         psF32 yDiff = row - yCM;
    572         if (fabs(yDiff) > radKron) continue;
    573 
    574         for (psS32 col = 0; col < source->pixels->numCols ; col++) {
    575             // check mask and value for this pixel
    576             if (vMsk && (vMsk[row][col] & maskVal)) continue;
    577             if (isnan(vPix[row][col])) continue;
    578 
    579             psF32 xDiff = col - xCM;
    580             if (fabs(xDiff) > radKron) continue;
    581 
    582             // radKron is just a function of (xDiff, yDiff)
    583             psF32 r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
    584             if (r2 > radKron2) continue;
    585 
    586             float weight1  = vWin[row+Ywo][col+Xwo];
    587             float fDiff1 = vPix[row][col]*weight1;
    588 
    589             float pDiff = fDiff1;
    590             psF32 wDiff = vWgt[row][col] * weight1;
    591 
    592             Sum += pDiff;
    593             Var += wDiff;
    594             Win += weight1;
    595             nKronPix ++;
    596         }
    597     }
    598 
    599     source->moments->Mrf         = Mrf;
    600630    source->moments->KronFlux    = Sum;
    601631    source->moments->KronFluxErr = sqrt(Var);
     632    source->moments->KronFinner  = SumInner;
     633
     634    // only save radKouter if the radius is inside the integration radius limit
     635    if (radKouter <= limitRadius) {
     636        source->moments->KronFouter = SumOuter;
     637    }
    602638
    603639    return true;
    604640}
    605 
    606 bool psphotKronWindowSetSource(pmSource *source, psImage *kronWindow, bool useKronRadius, bool insert, bool applyWindow) {
    607 
    608     if (!source) return false;
    609     if (!source->peak) return false; // XXX how can we have a peak-less source?
    610     if (!source->moments) return false;
    611     if (source->type == PM_SOURCE_TYPE_DEFECT) return false;
    612     if (source->type == PM_SOURCE_TYPE_SATURATED) return false;
    613     if (!(source->tmpFlags & PM_SOURCE_TMPF_MOMENTS_MEASURED)) return false;
    614     if (source->mode & PM_SOURCE_MODE_MOMENTS_FAILURE) return false;
    615     psAssert(kronWindow, "need a window");
    616 
    617     // XXX: If we are not applying the window then we don't need to check for valid Mrf here.
    618     // We should give the this module a chance to measure a good value.
    619     // However experiments show that it hardly ever succeeds in getting a better value
    620     if (!isfinite(source->moments->Mrf) || source->moments->Mrf < 0 ) return false;
    621 
    622     if (!applyWindow) {
    623         return true;
    624     }
    625 
    626     // we have a source with moments Mx, My, Mxx, Mxy, Myy.  we just need to define a Gaussian that has
    627     // these values (and peak of 1.0)
    628 
    629     int Nx = kronWindow->numCols;
    630     int Ny = kronWindow->numRows;
    631 
    632     float Xo = source->moments->Mx;
    633     float Yo = source->moments->My;
    634 
    635     psEllipseMoments moments;
    636     moments.x2 = source->moments->Mxx;
    637     moments.y2 = source->moments->Myy;
    638     moments.xy = source->moments->Mxy;
    639 
    640     psEllipseAxes axes = psEllipseMomentsToAxes(moments, 20.0);
    641     if (! (isfinite(axes.major) && isfinite(axes.minor) && isfinite(axes.theta)) ) {
    642         // Shall we log a proper warning? This happens often with matched sources (forced photometry)
    643         // fprintf(dump, "invalid axes found id: %4d major: %f minor: %f theta: %f\n", source->id, axes.major, axes.minor, axes.theta);
    644         return false;
    645     }
    646 
    647     // Why this factor of 0.5 ?
    648     float scale = 0.5 * source->moments->Mrf / axes.major;
    649     axes.major *= scale;
    650     axes.minor *= scale;
    651 
    652     psEllipseShape shape = psEllipseAxesToShape(axes);
    653     if (! (isfinite(shape.sx) && isfinite(shape.sy) && isfinite(shape.sxy)) ) {
    654         // Shall we log a proper warning? This happens often with matched sources (forced photometry)
    655         // fprintf(dump, "invalid shape found id: %d sx: %f sy %f sxy: %f\n", source->id, shape.sx, shape.sy, shape.sxy);
    656         return false;
    657     }
    658 
    659     float Smajor = axes.major;
    660 
    661     int minX = PS_MIN(PS_MAX(Xo - 5*Smajor, 0), Nx - 1);
    662     int maxX = PS_MIN(PS_MAX(Xo + 5*Smajor, 0), Nx - 1);
    663     int minY = PS_MIN(PS_MAX(Yo - 5*Smajor, 0), Ny - 1);
    664     int maxY = PS_MIN(PS_MAX(Yo + 5*Smajor, 0), Ny - 1);
    665 
    666     float rMxx = 0.5 / PS_SQR(shape.sx);
    667     float rMyy = 0.5 / PS_SQR(shape.sy);
    668     float Sxy = -1. * shape.sxy;    // factor of -1 is included to match the previous window function
    669                                     // implementation. XXX: Is this correct?
    670 
    671     for (int iy = minY; iy < maxY; iy++) {
    672         for (int ix = minX; ix < maxX; ix++) {
    673 
    674             float dX = (ix + 0.5 - Xo);
    675             float dY = (iy + 0.5 - Yo);
    676 
    677             float z = rMxx * PS_SQR(dX) + rMyy * PS_SQR(dY) + Sxy*dX*dY;
    678 
    679             float f = insert ? 1.001 - exp(-z) : 1.0 / (1.001 - exp(-z));
    680 
    681             kronWindow->data.F32[iy][ix] *= f;
    682         }
    683     }
    684 
    685     return true;
    686 }
  • branches/czw_branch/20120906/psphot/src/psphotMaskBackground.c

    r31154 r34772  
    1717
    1818    // find the currently selected readout (XXX note that the model is saved on PSPHOT.BACKMDL regardless of 'filename'
    19     pmFPAfile *modelFile = pmFPAfileSelectSingle(config->files, "PSPHOT.BACKMDL", index); // File of interest
     19    pmFPAfile *modelFile = pmFPAfileSelectSingle(config->files, psphotGetFilerule("PSPHOT.BACKMDL"), index); // File of interest
    2020    assert (modelFile);
    2121
    22     pmFPAfile *stdevFile = pmFPAfileSelectSingle(config->files, "PSPHOT.BACKMDL.STDEV", index);
     22    pmFPAfile *stdevFile = pmFPAfileSelectSingle(config->files, psphotGetFilerule("PSPHOT.BACKMDL.STDEV"), index);
    2323    assert (stdevFile);
    2424
  • branches/czw_branch/20120906/psphot/src/psphotModelBackground.c

    r33963 r34772  
    405405
    406406    psImageBinning *binning = psphotBackgroundBinning(readout->image, config); // Image binning parameters
    407     pmReadout *model = pmFPAGenerateReadout(config, view, "PSPHOT.BACKMDL", inFPA, binning, index);
    408     pmReadout *modelStdev = pmFPAGenerateReadout(config, view, "PSPHOT.BACKMDL.STDEV", inFPA, binning, index);
     407    pmReadout *model = pmFPAGenerateReadout(config, view, psphotGetFilerule("PSPHOT.BACKMDL"), inFPA, binning, index);
     408    pmReadout *modelStdev = pmFPAGenerateReadout(config, view, psphotGetFilerule("PSPHOT.BACKMDL.STDEV"), inFPA, binning, index);
    409409
    410410    if (!psphotModelBackgroundReadout(model->image, modelStdev->image, model->analysis, readout, binning, config, false)) {
  • branches/czw_branch/20120906/psphot/src/psphotOutput.c

    r32695 r34772  
    3434   
    3535
    36     pmFPAfile *file = psMetadataLookupPtr (&status, config->files, "PSPHOT.BACKMDL");
     36    pmFPAfile *file = psMetadataLookupPtr (&status, config->files, psphotGetFilerule("PSPHOT.BACKMDL"));
    3737    if (!file) return NULL;
    3838
     
    4545    bool status;
    4646
    47     pmFPAfile *file = psMetadataLookupPtr (&status, config->files, "PSPHOT.BACKMDL.STDEV");
     47    pmFPAfile *file = psMetadataLookupPtr (&status, config->files, psphotGetFilerule("PSPHOT.BACKMDL.STDEV"));
    4848    if (!file) return NULL;
    4949
  • branches/czw_branch/20120906/psphot/src/psphotReadout.c

    r34404 r34772  
    185185
    186186    // linear PSF fit to source peaks, subtract the models from the image (in PSF mask)
    187     psphotFitSourcesLinear (config, view, filerule, false, false); // pass 1 (detections->allSources)
     187    psphotFitSourcesLinear (config, view, filerule, false, true); // pass 1 (detections->allSources)
    188188
    189189    // measure the radial profiles to the sky
     
    212212    // linear fit to include all sources (subtract again)
    213213    // NOTE : apply to ALL sources (extended + psf)
    214     psphotFitSourcesLinear (config, view, filerule, true, false); // pass 2 (detections->allSources)
     214    psphotFitSourcesLinear (config, view, filerule, true, true); // pass 2 (detections->allSources)
    215215
    216216    // if we only do one pass, skip to extended source analysis
     
    260260
    261261        // NOTE: apply to ALL sources
    262         psphotFitSourcesLinear (config, view, filerule, true, false); // pass 3 (detections->allSources)
     262        psphotFitSourcesLinear (config, view, filerule, true, true); // pass 3 (detections->allSources)
    263263    }
    264264
     
    300300
    301301        // NOTE: apply to ALL sources
    302         psphotFitSourcesLinear (config, view, filerule, true, false); // pass 3 (detections->allSources)
     302        psphotFitSourcesLinear (config, view, filerule, true, true); // pass 3 (detections->allSources)
    303303    }
    304304
  • branches/czw_branch/20120906/psphot/src/psphotReplaceUnfit.c

    r34136 r34772  
    3535    // loop over the available readouts
    3636    for (int i = 0; i < num; i++) {
    37         if (!psphotReplaceAllSourcesReadout (config, view, filerule, i, recipe, ignoreState)) {
    38             psError (PSPHOT_ERR_CONFIG, false, "failed to replace all sources for %s entry %d", filerule, i);
    39             return false;
    40         }
    41     }
    42     return true;
    43 }
    44 
     37        // ignore return value. False means "sources not subtracted", not a failure condition
     38        (void) psphotReplaceAllSourcesReadout (config, view, filerule, i, recipe, ignoreState);
     39    }
     40    return true;
     41}
     42
     43// the return state indicates if any sources were actually replaced
    4544bool psphotReplaceAllSourcesReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool ignoreState) {
    4645
     
    5857    if (psMetadataLookupBool (&status, readout->analysis, "PSPHOT.SKIP.INPUT")) {
    5958        psLogMsg ("psphot", PS_LOG_DETAIL, "skipping replace all sources for input file %d", index);
    60         return true;
     59        return false;
    6160    }
    6261
     
    6564
    6665    psArray *sources = detections->allSources;
    67     //psAssert (sources, "missing sources?");
    68     if (!sources) return true;
     66    // if no work to do, should just return false
     67    if (!sources) return false;
    6968
    7069    // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
  • branches/czw_branch/20120906/psphot/src/psphotSetThreads.c

    r34317 r34772  
    3030    psFree(task);
    3131
    32     task = psThreadTaskAlloc("PSPHOT_KRON_ITERATE", 14);
     32    task = psThreadTaskAlloc("PSPHOT_KRON_ITERATE", 11);
    3333    task->function = &psphotKronIterate_Threaded;
    3434    psThreadTaskAdd(task);
  • branches/czw_branch/20120906/psphot/src/psphotSkyReplace.c

    r31673 r34772  
    3636
    3737    // select background pixels, from output background file, or create
    38     pmReadout *background = pmFPAfileThisReadout (config->files, view, "PSPHOT.BACKGND");
     38    pmReadout *background = pmFPAfileThisReadout (config->files, view, psphotGetFilerule("PSPHOT.BACKGND"));
    3939    if (background == NULL) psAbort("background not defined");
    4040
  • branches/czw_branch/20120906/psphot/src/psphotSourceMatch.c

    r34354 r34772  
    559559}
    560560
    561 bool psphotDropBadMatchedSources (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects) {
     561bool psphotFilterMatchedSources (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects) {
    562562
    563563    bool status = false;
    564564
    565     psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Drop Bad Matched Sources ---");
     565    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Filter Matched Sources ---");
    566566
    567567    psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     
    615615    psFree(dropped);
    616616
     617    // find the "best" Mrf from the detected sources.
     618    // Currently we use the smallest positive value
     619    for (int i=0; i< objects->n; i++) {
     620        pmPhotObj *obj = objects->data[i];
     621
     622        float minMrf = 1000.;
     623        bool hasMatched = false;
     624        for (int j = 0; j < obj->sources->n; j++) {
     625            pmSource *source = obj->sources->data[j];
     626            if (source->mode2 & PM_SOURCE_MODE2_MATCHED) {
     627                hasMatched = true;
     628                continue;
     629            }
     630            float Mrf = source->moments->Mrf;
     631            if (isfinite(Mrf) && Mrf < minMrf && Mrf > 0) {
     632                minMrf = Mrf;
     633            }
     634        }
     635
     636        if (!hasMatched || minMrf > 120.) {
     637            continue;
     638        }
     639
     640        // set Mrf for matched sources to the value found above
     641        for (int j = 0; j < obj->sources->n; j++) {
     642            pmSource *source = obj->sources->data[j];
     643            if (source->mode2 & PM_SOURCE_MODE2_MATCHED) {
     644                source->moments->Mrf = minMrf;
     645            }
     646        }
     647    }
     648
    617649    return true;
    618650}
  • branches/czw_branch/20120906/psphot/src/psphotSourceSize.c

    r34404 r34772  
    675675            return false;
    676676        }
    677         psFree(readout->mask);
    678         readout->mask = newMask;
     677        // Copy the new mask pixel values to the old mask array.  NOTE: we cannot replace
     678        // the mask pointer because the source->maskView objects point to the old data
     679        // area
     680        psImage *oldMask = readout->mask;
     681        readout->mask = psImageCopy (readout->mask, newMask, PS_TYPE_IMAGE_MASK);
     682        psAssert (oldMask == readout->mask, "should have copied the values in-situ");
     683        psFree(newMask);
    679684    }
    680685
  • branches/czw_branch/20120906/psphot/src/psphotStack.c

    r34283 r34772  
    22
    33int main (int argc, char **argv) {
     4
     5    // Set flag to tell certain library functions that we are in the psphotStack program.
     6    // (This is defined in psphotDefineFiles.c)
     7    psphotINpsphotStack = true;
    48
    59    // uncomment to turn on memory dumps (move this to an option)
  • branches/czw_branch/20120906/psphot/src/psphotStackImageLoop.c

    r34404 r34772  
    4343    if (!needConvolved) {
    4444        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");
    4548    }
    4649
     
    97100            // drop all versions of the internal files
    98101            status = true;
    99             status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL");
    100             status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL.STDEV");
    101             status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKGND");
     102            status &= pmFPAfileDropInternal (config->files, psphotGetFilerule("PSPHOT.BACKMDL"));
     103            status &= pmFPAfileDropInternal (config->files, psphotGetFilerule("PSPHOT.BACKMDL.STDEV"));
     104            status &= pmFPAfileDropInternal (config->files, psphotGetFilerule("PSPHOT.BACKGND"));
    102105            if (!status) {
    103106                psError(PSPHOT_ERR_PROG, false, "trouble dropping internal files");
  • branches/czw_branch/20120906/psphot/src/psphotStackMatchPSFs.c

    r34404 r34772  
    108108    bool notMatched = psMetadataLookupBool(NULL, readoutOut->analysis, "NOT.PSF.MATCHED");
    109109    if (notMatched) {
    110         if (!readoutOut->image) {
    111             // our images got freed in the matching process. Recreate them so that they
    112             // are available when sources are copied to this readout.
    113             readoutOut->image = psImageCopy(NULL, readoutSrc->image, PS_TYPE_F32);
    114             if (readoutSrc->variance) {
    115                 psFree(readoutOut->variance);
    116                 readoutOut->variance = psImageCopy(NULL, readoutSrc->variance, PS_TYPE_F32);
    117             }
    118             if (readoutSrc->mask) {
    119                 psFree(readoutOut->mask);
    120                 readoutOut->mask = psImageCopy(NULL, readoutSrc->mask, PS_TYPE_IMAGE_MASK);
    121             }
     110        psFree(readoutOut->image);
     111        readoutOut->image = psImageCopy(NULL, readoutSrc->image, PS_TYPE_F32);
     112        psFree(readoutOut->variance);
     113        if (readoutSrc->variance) {
     114            readoutOut->variance = psImageCopy(NULL, readoutSrc->variance, PS_TYPE_F32);
     115        }
     116        psFree(readoutOut->mask);
     117        if (readoutSrc->mask) {
     118            readoutOut->mask = psImageCopy(NULL, readoutSrc->mask, PS_TYPE_IMAGE_MASK);
    122119        }
    123120    }
  • branches/czw_branch/20120906/psphot/src/psphotStackMatchPSFsUtils.c

    r34352 r34772  
    303303        if (!pmSubtractionMatch(NULL, readoutOut, fake, readoutSrc, footprint, stride, regionSize, spacing, threshold, stampSources, stampsName, type, size, order, widthsCopy, orders, inner, ringsOrder, binning, penalty, optimum, optWidths, optOrder, optThresh, iter, rej, normFrac, sysError, skyErr, kernelError, covarFrac, maskVal, maskBad, maskPoor, poorFrac, badFrac, PM_SUBTRACTION_MODE_2)) {
    304304            int errorCode = psErrorCodeLast();
    305             if (errorCode == PM_ERR_SMALL_AREA) {
     305            if (errorCode == PM_ERR_SMALL_AREA || errorCode == PM_ERR_STAMPS) {
    306306                // failed to match but, don't fault. Just drop this input from measurements that need the
    307307                // matched readout.
     308                psErrorClear();
    308309                rejectReadout = true;
    309                 psLogMsg("psphot", PS_LOG_WARN, "PSF match failed for input %d. Too few pixels.", index);
     310                if (errorCode == PM_ERR_SMALL_AREA) {
     311                    psLogMsg("psphot", PS_LOG_WARN, "PSF match failed for input %d. Too few pixels.", index);
     312                } else if (errorCode == PM_ERR_STAMPS) {
     313                    psLogMsg("psphot", PS_LOG_WARN, "PSF match failed for input %d. Failed to find stamps.", index);
     314                }
    310315            } else {
    311316                psError(psErrorCodeLast(), false, "Unable to match images.");
     
    324329   
    325330    if (rejectReadout) {
     331        psMetadataAddBool(readoutSrc->analysis, PS_LIST_TAIL, "NOT.PSF.MATCHED", PS_META_REPLACE, "", true);
    326332        psMetadataAddBool(readoutOut->analysis, PS_LIST_TAIL, "NOT.PSF.MATCHED", PS_META_REPLACE, "", true);
    327333    } else {
     334        psMetadataAddBool(readoutSrc->analysis, PS_LIST_TAIL, "NOT.PSF.MATCHED", PS_META_REPLACE, "", false);
    328335        psMetadataAddBool(readoutOut->analysis, PS_LIST_TAIL, "NOT.PSF.MATCHED", PS_META_REPLACE, "", false);
    329336    }
  • branches/czw_branch/20120906/psphot/src/psphotStackParseCamera.c

    r33913 r34772  
    1414        return false;
    1515    }
     16
     17    // select the appropriate recipe information
     18    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     19    bool savePSF = psMetadataLookupBool(&status, recipe, "SAVE.PSF");
     20    bool saveBackgroundModel = psMetadataLookupBool(&status, recipe, "SAVE.BACKMDL");
     21    bool saveBackground = psMetadataLookupBool(&status, recipe, "SAVE.BACKGND");
     22    bool saveBackSub = psMetadataLookupBool(&status, recipe, "SAVE.BACKSUB");
     23    bool saveResid = psMetadataLookupBool(&status, recipe, "SAVE.RESID");
     24
     25    bool saveCnv = psMetadataLookupBool(&status, recipe, "SAVE.CNV");
     26    bool saveChisq = psMetadataLookupBool(&status, recipe, "SAVE.CHISQ");
     27    bool useRaw = psMetadataLookupBool(&status, recipe, "PSPHOT.STACK.USE.RAW");
     28
    1629
    1730    int nRaw = 0;
     
    120133            }
    121134        }
     135        pmFPAfile *inputTemplate;
     136        if (useRaw) {
     137            inputTemplate = rawInputFile;
     138        } else {
     139            inputTemplate = cnvInputFile;
     140        }
     141        if (!inputTemplate) {
     142            psError(PS_ERR_UNKNOWN, true, "cannot determinte inputTemplate: USE.RAW: %d\n", useRaw);
     143            return false;
     144        }
    122145
    123146        psString sources = psMetadataLookupStr(&status, input, "SOURCES"); // Name of mask
     
    135158        }
    136159        // generate an pmFPAimage for the output convolved image
    137         // XXX output of these files should be optional
    138160        {
    139161            // pmFPAfile *srcInputFile = rawInputFile ? rawInputFile : cnvInputFile;
     
    143165                return false;
    144166            }
    145             outputImage->save = true;
     167            outputImage->save = saveCnv;
    146168            outputImage->fileID = stack_id;             // this is used to generate output names
    147169
     
    155177                return NULL;
    156178            }
    157             outputMask->save = true;
     179            outputMask->save = saveCnv;
    158180            outputMask->fileID = stack_id;              // this is used to generate output names
    159181
     
    167189                return NULL;
    168190            }
    169             outputVariance->save = true;
     191            outputVariance->save = saveCnv;
    170192            outputVariance->fileID = stack_id;          // this is used to generate output names
    171193
     
    178200            outsources->save = true;
    179201            outsources->fileID = stack_id;              // this is used to generate output names
     202
     203            if (savePSF) {
     204                pmFPAfile *output = pmFPAfileDefineOutputFromFile (config, inputTemplate, "PSPHOT.STACK.PSF.SAVE");
     205                if (!output) {
     206                    psError(PSPHOT_ERR_CONFIG, false, "Cannot find a rule for PSPHOT.STACK.PSF.SAVE");
     207                    return false;
     208                }
     209                output->save = true;
     210                output->fileID = stack_id;
     211            }
     212            if (saveBackgroundModel) {
     213                int DX = psMetadataLookupS32 (&status, recipe, "BACKGROUND.XBIN");
     214                int DY = psMetadataLookupS32 (&status, recipe, "BACKGROUND.YBIN");
     215                pmFPAfile *output = pmFPAfileDefineFromFile (config, inputTemplate, DX, DY, "PSPHOT.STACK.BACKMDL");
     216                if (!output) {
     217                    psError(PSPHOT_ERR_CONFIG, false, "Cannot find a rule for PSPHOT.STACK.BACKMDL");
     218                    return false;
     219                }
     220
     221                output->save = true;
     222                output->fileID = stack_id;
     223            }
     224            if (saveBackground) {
     225                pmFPAfile *output = pmFPAfileDefineFromFile (config, inputTemplate, 1, 1, "PSPHOT.STACK.BACKGND");
     226                if (!output) {
     227                    psError(PSPHOT_ERR_CONFIG, false, "Cannot find a rule for PSPHOT.STACK.STACK.BACKGND");
     228                    return false;
     229                }
     230                output->save = true;
     231                output->fileID = stack_id;
     232            }
     233            if (saveBackSub) {
     234                pmFPAfile *output = pmFPAfileDefineFromFile (config, inputTemplate, 1, 1, "PSPHOT.STACK.BACKSUB");
     235                if (!output) {
     236                    psError(PSPHOT_ERR_CONFIG, false, "Cannot find a rule for PSPHOT.STACK.STACK.BACKSUB");
     237                    return false;
     238                }
     239                output->save = true;
     240                output->fileID = stack_id;
     241            }
     242            if (saveResid) {
     243                pmFPAfile *output = pmFPAfileDefineOutputFromFile (config, inputTemplate, "PSPHOT.STACK.RESID");
     244                if (!output) {
     245                    psError(PSPHOT_ERR_CONFIG, false, "Cannot find a rule for PSPHOT.STACK.RESID");
     246                    return false;
     247                }
     248                output->save = true;
     249                output->fileID = stack_id;
     250            }
    180251        }
    181252    }
     
    191262    }
    192263
    193     // select the appropriate recipe information
    194     psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
    195     bool saveCnv = psMetadataLookupBool(&status, recipe, "SAVE.CNV");
    196     bool saveChisq = psMetadataLookupBool(&status, recipe, "SAVE.CHISQ");
    197 
    198     // loop over the available readouts
    199     for (int i = 0; i < nInputs; i++) {
    200         pmFPAfile *file = NULL;
    201 
    202         file = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.OUTPUT.IMAGE", i);
    203         file->save = saveCnv;
    204 
    205         file = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.OUTPUT.MASK", i);
    206         file->save = saveCnv;
    207 
    208         file = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.OUTPUT.VARIANCE", i);
    209         file->save = saveCnv;
    210     }
    211 
    212264    // generate an pmFPAimage for the chisqImage
    213     // XXX output of these files should be optional
    214265    {
    215266        pmFPAfile *chisqImage = pmFPAfileDefineOutput(config, NULL, "PSPHOT.CHISQ.IMAGE");
  • branches/czw_branch/20120906/psphot/src/psphotStackReadout.c

    r34354 r34772  
    169169    }
    170170
     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)) {
     179        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);
     187    }
     188
    171189    // if we were not supplied a PSF model, determine the IQ stats here (detections->newSources)
    172190    // only run this on detections from the input images, not chisq image
     
    206224    // window of size PSF_MOMENTS_RADIUS (same window used to measure the psf-scale moments)
    207225    // but iterates to an appropriately larger size
    208         logMemStats("before.kron.1");
     226    logMemStats("before.kron.1");
    209227    psphotKronIterate(config, view, STACK_SRC, 1);
    210         logMemStats("after.kron.1");
    211 
     228    logMemStats("after.kron.1");
     229       
    212230    // identify CRs and extended sources
    213231    psphotSourceSize (config, view, STACK_SRC, true);
     
    332350    psphotStackObjectsSelectForAnalysis (config, view, STACK_SRC, objects);
    333351
    334     if (splitLinearFit) {
    335         // NOTE: apply to Matched sources. Since the sources that we fit above are subtracted, they will
    336         // not be included in this fit.
    337         psphotFitSourcesLinear (config, view, STACK_SRC, true, false); // pass 4 (detections->allSources)
    338     } else {
    339         // Fit all sources together
    340         psphotFitSourcesLinear (config, view, STACK_SRC, true, false); // pass 3 (detections->allSources)
    341     }
     352    // final linear fit. NOTE: if splitLinearFit is true above, this pass will only fit
     353    // the unsubtracted (matched) sources (the sources that we fit above are subtracted)
     354    psphotFitSourcesLinear (config, view, STACK_SRC, true, false); // pass 4 (detections->allSources)
    342355
    343356    // measure the radial profiles to the sky (only measures new objects)
     
    356369    psMemDump("psfstats");
    357370
    358     // drop matched sources without any useful measurements
    359     psphotDropBadMatchedSources (config, view, STACK_SRC, objects);
     371    // drop matched sources without any useful measurements and set kron radii for the ones
     372    // we decide to keep
     373    psphotFilterMatchedSources (config, view, STACK_SRC, objects);
     374
     375    // measure kron fluxes for the matched sources only
     376    psphotKronIterate(config, view, STACK_SRC, 3);
    360377
    361378    // measure elliptical apertures, petrosians (objects sorted by S/N)
     
    392409            }
    393410        }
     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);
    394414        psphotRadialApertures (config, view, STACK_CNV, 0); // entry 0 == unmatched
    395415        psMemDump("extmeas");
    396416
    397         // mark any inputs that we want to skip the matched apertures for
    398         psphotStackSetInputsToSkip(config, view, STACK_OUT, true);
    399417
    400418        int nRadialEntries = psphotStackMatchPSFsEntries(config, view, STACK_OUT);
     
    422440        }
    423441    }
     442    psphotStackSetInputsToSkip(config, view, STACK_CNV, false);
    424443    psphotStackSetInputsToSkip(config, view, STACK_OUT, false);
    425444
  • branches/czw_branch/20120906/psphot/src/psphotSubtractBackground.c

    r32348 r34772  
    2121
    2222    // find the currently selected readout (XXX note that the model is saved on PSPHOT.BACKMDL regardless of 'filename'
    23     pmFPAfile *modelFile = pmFPAfileSelectSingle(config->files, "PSPHOT.BACKMDL", index); // File of interest
     23    pmFPAfile *modelFile = pmFPAfileSelectSingle(config->files, psphotGetFilerule("PSPHOT.BACKMDL"), index); // File of interest
    2424    assert (modelFile);
    2525
     
    3636    // select background pixels, from output background file, or create
    3737    // XXX for now, we will only allow a single background image to be generated
    38     file = psMetadataLookupPtr (&status, config->files, "PSPHOT.BACKGND");
     38    file = psMetadataLookupPtr (&status, config->files, psphotGetFilerule("PSPHOT.BACKGND"));
    3939    if (file) {
    4040        // we are using PSPHOT.BACKGND as an I/O file: select readout or create
     
    5050        }
    5151    } else {
    52         background = pmFPAfileDefineInternal (config->files, "PSPHOT.BACKGND", image->numCols, image->numRows, PS_TYPE_F32);
     52        background = pmFPAfileDefineInternal (config->files, psphotGetFilerule("PSPHOT.BACKGND"), image->numCols, image->numRows, PS_TYPE_F32);
    5353    }
    5454    psF32 **backData = background->image->data.F32;
Note: See TracChangeset for help on using the changeset viewer.