IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 34399


Ignore:
Timestamp:
Sep 5, 2012, 4:04:34 PM (14 years ago)
Author:
eugene
Message:

merge changes from trunk

Location:
branches/eam_branches/ipp-20120805/psphot
Files:
19 edited
2 copied

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20120805/psphot

  • branches/eam_branches/ipp-20120805/psphot/src

  • branches/eam_branches/ipp-20120805/psphot/src/Makefile.am

    r34258 r34399  
    117117        psphotStackObjects.c          \
    118118        psphotStackPSF.c              \
     119        psphotStackAllocateOutput.c   \
    119120        psphotCleanup.c
    120121
     
    219220        psphotPetrosianVisual.c        \
    220221        psphotEfficiency.c             \
    221         psphotSetNFrames.c
     222        psphotSetNFrames.c             \
     223        psphotSourceMemory.c
    222224
    223225# not currently used
  • branches/eam_branches/ipp-20120805/psphot/src/psphot.h

    r34378 r34399  
    364364                                     pmReadout **chiReadout,
    365365                                     int index);
     366bool psphotStackAllocateOutput( const pmConfig *config, pmFPAview *view, psMetadata *recipe);
    366367
    367368bool psphotStackRemoveChisqFromInputs (pmConfig *config, const char *filerule);
     
    371372bool psphotMatchSourcesReadout (psArray *objects, pmConfig *config, const pmFPAview *view, const char *filerule, int index);
    372373bool psphotMatchSourcesToObjects (psArray *objects, psArray *sources, float RADIUS);
     374bool psphotDropBadMatchedSources (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects);
    373375
    374376bool psphotFitSourcesLinearStack (pmConfig *config, psArray *objects, bool final);
     
    487489bool psphotMaskFootprint (pmReadout *readout, pmSource *source, psImageMaskType markVal);
    488490
    489 bool psphotKronIterate (pmConfig *config, const pmFPAview *view, const char *filerule);
    490 bool psphotKronIterateReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char * filerule, pmReadout *readout, psArray *sources, pmPSF *psf, int index);
     491bool psphotKronIterate (pmConfig *config, const pmFPAview *view, const char *filerule, int pass);
     492bool psphotKronIterateReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char * filerule, pmReadout *readout, psArray *sources, pmPSF *psf, int index, int pass);
    491493bool psphotKronIterate_Threaded (psThreadJob *job);
    492494
     
    520522bool psphotSatstarPhotometry (pmSource *source);
    521523
     524bool psphotSourceMemory(pmConfig *config, const pmFPAview *view, const char *filerule);
     525bool psphotSourceMemoryReadout(pmConfig *config, const pmFPAview *view, const char *filerule, int index);
     526
    522527#endif
  • branches/eam_branches/ipp-20120805/psphot/src/psphotApResid.c

    r34378 r34399  
    207207        if (source->mode &  PM_SOURCE_MODE_CR_LIMIT) SKIPSTAR ("COSMIC RAY");
    208208        if (source->mode &  PM_SOURCE_MODE_DEFECT) SKIPSTAR ("DEFECT");
     209        if (source->mode2 & PM_SOURCE_MODE2_MATCHED) SKIPSTAR ("MATCHED");
    209210
    210211        if (!isfinite(source->apMag) || !isfinite(source->psfMag)) {
  • branches/eam_branches/ipp-20120805/psphot/src/psphotBlendFit.c

    r34380 r34399  
    9494    assert (status && isfinite(skySig) && skySig > 0);
    9595
     96# if (0)
    9697    // **** test block : generate an ID image where pixels are set based the source models (flux > 0.1 peak && flux > 2.0 skySig)
    9798    psImage *IDimage = psImageAlloc (readout->image->numCols, readout->image->numRows, PS_TYPE_S32);
     
    104105    }
    105106    psphotSaveImage (NULL, IDimage, "idimage.fits");
     107# endif
    106108
    107109    // Define source fitting parameters for extended source fits
  • branches/eam_branches/ipp-20120805/psphot/src/psphotEfficiency.c

    r34215 r34399  
    5757    psFree(stats);
    5858
     59#ifndef USE_SINGLE_POINT_FOR_MODEL
    5960    // Need to normalise out difference between Gaussian and real PSF
     61    int sizeX = ro->variance->numCols / 16;
     62    int sizeY = ro->variance->numRows / 16;
     63    int numPoints = 0;
     64    float sum =  0;
     65    for (int y = sizeY * 0.5 ; y < ro->variance->numRows; y += sizeY) {
     66        for (int x = sizeX * 0.5 ; x < ro->variance->numCols; x += sizeX) {
     67            pmModel *normModel = pmModelFromPSFforXY(psf, (float) x, (float) y, 1.0); // model for normalization
     68
     69            if (!normModel || (normModel->flags & MODEL_MASK)) {
     70                psFree(normModel);
     71                continue;
     72            }
     73            float flux = normModel->modelFlux(normModel->params); // Total flux for peak of 1.0
     74            psFree(normModel);
     75            if (!isfinite(flux)) {
     76                continue;
     77            }
     78            numPoints++;
     79            sum += flux;
     80        }
     81    }
     82    if (!isfinite(sum) || numPoints == 0) {
     83        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate PSF model for any of %d points.", sizeX * sizeY);
     84        return false;
     85    }
     86    *norm = sum / numPoints;
     87#else
     88    // This can fail for readout that has few good pixels. It's better to sample many points.
    6089    pmModel *normModel = pmModelFromPSFforXY(psf, 0.5 * ro->variance->numCols,
    61                                              0.5 * ro->variance->numRows, 1.0); // Model for normalisation
     90                                         0.5 * ro->variance->numRows, 1.0); // Model for normalisation
     91    psFree(normModel);
    6292    if (!normModel || (normModel->flags & MODEL_MASK)) {
    6393        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate PSF model.");
     
    6797    *norm = normModel->modelFlux(normModel->params); // Total flux for peak of 1.0
    6898    psFree(normModel);
     99#endif
    69100
    70101    // The signal-to-noise of the smoothed image is: S/N ~ I_smooth / sqrt(variance * factor)
     
    188219        if (!psphotEfficiencyReadout (config, view, filerule, i, recipe)) {
    189220            psError (PSPHOT_ERR_CONFIG, false, "failed to measure detection efficiency for %s entry %d", filerule, i);
    190             return false;
     221            psErrorStackPrint(stderr, " ");
     222            psErrorClear();
     223            // send message to log as well
     224            psLogMsg ("psphot", PS_LOG_WARN, "failed to measure detection efficiency for %s entry %d", filerule, i);
    191225        }
    192226    }
     
    376410        float mag = magLim + magOffsets->data.F32[i]; // Magnitude for bin
    377411        float peak = powf(10.0, -0.4 * mag) / norm;   // Peak flux
     412#ifndef USE_SINGLE_POINT_FOR_MODEL
     413        int sizeX = numCols / 16;
     414        int sizeY = numRows / 16;
     415        int numPoints = 0;
     416        float sum =  0;
     417        for (int y = sizeY * 0.5 ; y < numRows; y += sizeY) {
     418            for (int x = sizeX * 0.5 ; x < numCols; x += sizeX) {
     419                // Need to normalise out difference between Gaussian and real PSF
     420                pmModel *model = pmModelFromPSFforXY(psf, (float) x, (float) y, peak);
     421
     422                if (!model || (model->flags & MODEL_MASK)) {
     423                    psFree(model);
     424                    continue;
     425                }
     426                float sourceRadius = PS_MAX(radius, model->modelRadius(model->params, minFlux)); // Radius for source
     427                psFree(model);
     428                if (!isfinite(sourceRadius)) {
     429                    continue;
     430                }
     431                numPoints++;
     432                sum += sourceRadius;
     433            }
     434        }
     435        if (!isfinite(sum) || numPoints == 0) {
     436            psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate PSF model for any of %d points.", sizeX * sizeY);
     437            return false;
     438        }
     439        float sourceRadius = sum / numPoints;
     440#else
     441        // This old way can fail for heavily masked images
    378442        pmModel *model = pmModelFromPSFforXY(psf, numCols / 2.0, numRows / 2.0, peak); // Model for source
    379443        if (!model || (model->flags & MODEL_MASK)) {
     
    384448        float sourceRadius = PS_MAX(radius, model->modelRadius(model->params, minFlux)); // Radius for source
    385449        psFree(model);
     450#endif
    386451
    387452        psArray *sources = psArrayAllocEmpty(numSources); // Sources in this bin
     
    401466                source->peak->yf = y;
    402467                source->modelPSF = pmModelFromPSFforXY(psf, x, y, 2.0 * sqrtf(sig));
    403                 source->type = PM_SOURCE_TYPE_STAR;
    404 
    405                 source->modelPSF->fitRadius = sourceRadius;
    406                 source->apRadius = sourceRadius;
    407 
    408                 numFound++;
    409                 psArrayAdd(sources, sources->n, source);
    410                 psArrayAdd(fakeSourcesAll, fakeSourcesAll->n, source);
     468                if (source->modelPSF) {
     469                    source->type = PM_SOURCE_TYPE_STAR;
     470
     471                    source->modelPSF->fitRadius = sourceRadius;
     472                    source->apRadius = sourceRadius;
     473
     474                    numFound++;
     475                    psArrayAdd(sources, sources->n, source);
     476                    psArrayAdd(fakeSourcesAll, fakeSourcesAll->n, source);
     477                } else {
     478                    psLogMsg("psphot", PS_LOG_WARN, "pmModelFromPSFforXY failed for sig: %f x: %6.1f y: %6.1f\n",
     479                        sig, x, y);
     480                }
    411481                psFree(source);
    412482            }
  • branches/eam_branches/ipp-20120805/psphot/src/psphotKronIterate.c

    r34378 r34399  
    55
    66
    7 bool psphotKronIterate (pmConfig *config, const pmFPAview *view, const char *filerule)
     7bool psphotKronIterate (pmConfig *config, const pmFPAview *view, const char *filerule, int pass)
    88{
    99    bool status = true;
     
    4242        // psAssert (psf, "missing psf?");
    4343
    44         if (!psphotKronIterateReadout (config, recipe, view, filerule, readout, sources, psf, i)) {
     44        if (!psphotKronIterateReadout (config, recipe, view, filerule, readout, sources, psf, i, pass)) {
    4545            psError (PSPHOT_ERR_CONFIG, false, "failed to measure magnitudes for %s entry %d", filerule, i);
    4646            return false;
     
    5454bool psphotVisualRangeImage (int kapaFD, psImage *inImage, const char *name, int channel, float min, float max);
    5555
    56 bool psphotKronIterateReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char * filerule, pmReadout *readout, psArray *sources, pmPSF *psf, int index) {
     56#ifdef DUMP_KRS
     57FILE *dumpFile = NULL;
     58#endif
     59
     60bool psphotKronIterateReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char * filerule, pmReadout *readout, psArray *sources, pmPSF *psf, int index, int pass) {
    5761
    5862    bool status = false;
     63
     64#ifdef DUMP_KRS
     65    if (!dumpFile) {
     66        dumpFile = fopen("kr.txt", "w");
     67        psAssert (dumpFile, "failed to open kr.txt");
     68    }
     69    fprintf(dumpFile, "\n\n Input %d\n", index);
     70#endif
    5971
    6072    if (!sources->n) {
     
    6476
    6577    psTimerStart ("psphot.kron");
    66 
    6778
    6879    // determine the number of allowed threads
     
    160171
    161172    // 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
    162174    psImage *kronWindow = psImageAlloc (readout->image->numCols, readout->image->numRows, PS_TYPE_F32);
    163175    psImageInit (kronWindow, 1.0);
     
    235247            PS_ARRAY_ADD_SCALAR(job->args, KRON_SMOOTH_SIGMA,  PS_TYPE_F32);
    236248            PS_ARRAY_ADD_SCALAR(job->args, KRON_SB_MIN_DIVISOR,PS_TYPE_F32);
     249            PS_ARRAY_ADD_SCALAR(job->args, pass,               PS_TYPE_S32);
    237250
    238251// set this to 0 to run without threading
     
    297310    float KRON_SMOOTH_SIGMA         = PS_SCALAR_VALUE(job->args->data[11],F32);
    298311    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
    299316
    300317    for (int j = 0; j < KRON_ITERATIONS; j++) {
     
    308325            if (!(source->tmpFlags & PM_SOURCE_TMPF_MOMENTS_MEASURED)) continue;
    309326            if (source->mode & PM_SOURCE_MODE_MOMENTS_FAILURE) continue;
     327            if (!isfinite(source->moments->Mrf)) {
     328                // 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
     330                continue;
     331            }
    310332
    311333            // skip saturated stars modeled with a radial profile
     
    324346            }
    325347
    326             // On first iteration set window radius to sky radius (if valid) on second iteration
    327             // use a factor times the previous radial moment value up to a maximum value that
    328             // depends on the surface brightness of the source
    329             float maxWindow;
    330             if (j == 0) {
    331                 maxWindow = isfinite(source->skyRadius) ? source->skyRadius : RADIUS;
    332             } else {
     348            // On first iteration set window radius to sky radius (if valid). We also use this on subsequent
     349            // iterations if we cannot find a better limit
     350            float maxWindow = isfinite(source->skyRadius) ? source->skyRadius : RADIUS;
     351            if (j > 0) {
     352                // on subsequent iterations we use a factor times the previous radial moment value
     353                // limited to a maximum value that depends on the surface brightness of the source
    333354                if (KRON_SB_MIN_DIVISOR) {
    334                     if (isfinite(source->moments->KronFlux) && (source->moments->KronFlux > 0)) {
    335                         // Limit window radius based on surface brightness
     355                    // Limit window radius based on surface brightness if we have a good measurement of kron flux
     356                    if (isfinite(source->moments->KronFlux)  && (source->moments->KronFlux > 0)) {
    336357                        float Rmax = sqrt(source->moments->KronFlux) / KRON_SB_MIN_DIVISOR;
    337358
    338                         if (source->moments->Mrf > 0) {
     359                        if (isfinite(source->moments->Mrf) && source->moments->Mrf > 0) {
    339360                            maxWindow = PS_MIN(6.0*source->moments->Mrf, Rmax);
    340361                        } else {
    341                             maxWindow = Rmax;
     362                            maxWindow = PS_MIN(Rmax, maxWindow);
    342363                        }
    343                     } else {
    344                         maxWindow = RADIUS;
    345364                    }
    346365                } else {
    347                     // old code
     366                    // old recipe, no surface brightness cut
    348367                    maxWindow = isfinite(source->moments->Mrf) ? 6.0*source->moments->Mrf : RADIUS;
    349368                }
    350369            }
    351370            float windowRadius = PS_MAX(RADIUS, maxWindow);
     371
     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
    352378
    353379            // re-allocate image, weight, mask arrays for each peak with box big enough to fit BIG_RADIUS
     
    376402            }
    377403
     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
     415#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);
     420#endif
     421
    378422            // if we subtracted it above, re-subtract the object, leave local sky
    379423            if (reSubtract) {
     
    494538    }
    495539
     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);
    496550    // Saturate the 1st radial moment
    497     float Mrf = MAX(minKronRadius, RF/RS);
    498551    if (sqrt(source->peak->detValue) < 10.0) {
    499552        Mrf = MIN (radius, Mrf);
     
    544597    }
    545598
    546     source->moments->Mrf = Mrf;
     599    source->moments->Mrf         = Mrf;
    547600    source->moments->KronFlux    = Sum;
    548601    source->moments->KronFluxErr = sqrt(Var);
     
    562615    psAssert(kronWindow, "need a window");
    563616
     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
    564620    if (!isfinite(source->moments->Mrf) || source->moments->Mrf < 0 ) return false;
    565621
  • branches/eam_branches/ipp-20120805/psphot/src/psphotMaskReadout.c

    r34086 r34399  
    5858            return false;
    5959        }
     60    }
     61
     62    // insure than any non-finite pixels in image or variance are masked
     63    // get the PSPHOT.MASK value from the config
     64    psImageMaskType maskValue;
     65    if (!pmConfigMaskSetBits (&maskValue, NULL, config)) {
     66        psError (PS_ERR_UNKNOWN, false, "Unable to define the mask bit values");
     67        return false;
     68    }
     69    if (!pmReadoutMaskInvalid(readout, maskValue, maskSat)) {
     70        psError (PS_ERR_UNKNOWN, false,  "Unable to mask invalid pixels in readout.");
     71        return false;
    6072    }
    6173
  • branches/eam_branches/ipp-20120805/psphot/src/psphotReadout.c

    r34378 r34399  
    194194    // but this is chosen above to be appropriate for the PSF objects (not galaxies)
    195195    // psphotKronMasked(config, view, filerule);
    196     psphotKronIterate(config, view, filerule);
     196    psphotKronIterate(config, view, filerule, 1);
    197197
    198198    // identify CRs and extended sources (only unmeasured sources are measured)
     
    310310    // re-measure the kron mags with models subtracted
    311311    // psphotKronMasked(config, view, filerule);
    312     psphotKronIterate(config, view, filerule);
     312    psphotKronIterate(config, view, filerule, 2);
    313313
    314314    // measure source size for the remaining sources
  • branches/eam_branches/ipp-20120805/psphot/src/psphotReadoutMinimal.c

    r34258 r34399  
    8888
    8989    // re-measure the kron mags with models subtracted and more appropriate windows
    90     psphotKronIterate(config, view, filerule);
     90    psphotKronIterate(config, view, filerule, 1);
    9191
    9292    // measure source size for the remaining sources
  • branches/eam_branches/ipp-20120805/psphot/src/psphotSetThreads.c

    r34218 r34399  
    3030    psFree(task);
    3131
    32     task = psThreadTaskAlloc("PSPHOT_KRON_ITERATE", 13);
     32    task = psThreadTaskAlloc("PSPHOT_KRON_ITERATE", 14);
    3333    task->function = &psphotKronIterate_Threaded;
    3434    psThreadTaskAdd(task);
  • branches/eam_branches/ipp-20120805/psphot/src/psphotSourceMatch.c

    r33587 r34399  
    11# include "psphotInternal.h"
    22
    3 bool psphotMatchSourcesAddMissing (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects);
     3// Structure for storing the contents of the PSPHOT.STACK.MATCH.FILTERS list from recipe
     4#define MATCH_INFO_FILTER_STR_LEN 16
     5typedef struct {
     6    int     inputNum;
     7    int     order;
     8    bool    matchAll;
     9    char    filterID[MATCH_INFO_FILTER_STR_LEN];
     10} psphotStackMatchInfo;
     11
     12static psphotStackMatchInfo * psphotStackGetMatchInfo (pmConfig *config, const pmFPAview *view, const char *filerule);
     13
     14// functions for sorting the match info array
     15static int compareMatchInfoByInputNum(const void *a, const void *b);
     16static int compareMatchInfoByOrder(const void *a, const void *b);
     17
     18bool psphotMatchSourcesAddMissing (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects, psphotStackMatchInfo *matchInfo);
    419bool psphotMatchSourcesSetIDs (psArray *objects);
    520
     
    1429    int num = psphotFileruleCount(config, filerule);
    1530
    16     // loop over the available readouts
    17     for (int i = 0; i < num; i++) {
     31    psphotStackMatchInfo *matchInfo = psphotStackGetMatchInfo(config, view, filerule);
     32   
     33    // loop over the available readouts matching sources found to objects. The inputs are processed
     34    // in the order specified by the recipe
     35    for (int j = 0; j < num; j++) {
     36        int i = matchInfo[j].inputNum;
    1837        if (!psphotMatchSourcesReadout (objects, config, view, filerule, i)) {
    1938            psError (PSPHOT_ERR_CONFIG, false, "failed to merge sources for %s entry %d", filerule, i);
     
    2342    }
    2443
     44    // Now re-order the matchInfo array by input number so we can find each inputs entry easily
     45    qsort(matchInfo, num, sizeof(psphotStackMatchInfo), compareMatchInfoByInputNum);
     46
    2547    // create sources for images where an object has been detected in the other images
    26     psphotMatchSourcesAddMissing (config, view, filerule, objects);
     48    psphotMatchSourcesAddMissing (config, view, filerule, objects, matchInfo);
    2749
    2850    // choose a consistent position; set common sequence values
    2951    psphotMatchSourcesSetIDs (objects);
    3052
     53    psFree(matchInfo);
     54
    3155    return objects;
    3256}
    3357
    34 bool psphotMatchSourcesReadout (psArray *objects, pmConfig *config, const pmFPAview *view, const char *filerule, int index) { 
     58bool psphotMatchSourcesReadout (psArray *objects, pmConfig *config, const pmFPAview *view, const char *filerule, int index) {
    3559 
    3660    bool status = false;
     
    6185# define NEXT1 { i++; continue; }
    6286# define NEXT2 { j++; continue; }
    63 bool psphotMatchSourcesToObjects (psArray *objects, psArray *sources, float RADIUS) { 
     87bool psphotMatchSourcesToObjects (psArray *objects, psArray *sources, float RADIUS) {
    6488 
    6589    float dx, dy;
     
    7094    sources = psArraySort (sources, pmSourceSortByX);
    7195    objects = psArraySort (objects, pmPhotObjSortByX);
    72  
     96
    7397    psVector *foundSrc = psVectorAlloc(sources->n, PS_TYPE_U8);
    7498    psVectorInit (foundSrc, 0);
     
    87111        pmPhotObj *obj = objects->data[j];
    88112 
    89         if (!src) NEXT1; 
     113        if (!src) NEXT1;
    90114        if (!src->peak) NEXT1;
    91115        if (!isfinite(src->peak->xf)) NEXT1;
    92116        if (!isfinite(src->peak->yf)) NEXT1;
    93  
     117
    94118        if (!obj) NEXT2;
    95119        if (!isfinite(obj->x)) NEXT2;
     
    141165    }
    142166
    143     // add missed sources to new objects
    144 
     167    // create new objects for unmatched sources
    145168    for (i = 0; i < sources->n; i++) {
    146169
    147         if (foundSrc->data.U8[i]) continue;
     170        if (foundSrc->data.U8[i]) continue;
    148171
    149172        pmSource *src = sources->data[i];
    150173
    151         pmPhotObj *obj = pmPhotObjAlloc();
    152         pmPhotObjAddSource(obj, src);
    153         psArrayAdd (objects, 100, obj);
    154         psFree (obj);
     174        pmPhotObj *obj = pmPhotObjAlloc();
     175        pmPhotObjAddSource(obj, src);
     176        psArrayAdd (objects, 100, obj);
     177        psFree (obj);
    155178    }
    156179    psLogMsg ("psphot", PS_LOG_DETAIL, "matched sources (%ld vs %ld)", sources->n, objects->n);
     
    161184}
    162185
    163 bool psphotMatchSourcesAddMissing (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects) {
     186bool psphotMatchSourcesAddMissing (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects, psphotStackMatchInfo *matchInfo) {
    164187
    165188    bool status = false;
     
    169192    psAssert (recipe, "missing recipe?");
    170193
     194    int minDetectionsForForced = psMetadataLookupS32 (&status, recipe, "PSPHOT.STACK.MIN.DETECT.FOR.FORCED");
     195    if (!status) {
     196        minDetectionsForForced = 2;
     197    }
     198
    171199    // determine properties (sky, moments) of initial sources
    172200    float OUTER = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS");
     
    205233        int nSpansMax = 0;
    206234        int iSpansMax = -1;
     235
     236        bool matchAll = false;
    207237
    208238        // mark the images for which sources have been found
     
    219249                iSpansMax = j;
    220250            }
     251            // If this detection was on an input that has the matchAll flag set we create matched sources
     252            // irespective of the number of inputs in which the object was found.
     253            if (matchInfo[index].matchAll) {
     254                matchAll = true;
     255            }
    221256
    222257            found->data.U8[index] = 1;
    223258        }
     259
     260        // skip adding matched sources for this object if the number of detections for less than
     261        // the supplied mininum unless one of the detections was in a band for which the matchAll flag is set
     262        if (!matchAll && obj->sources->n < minDetectionsForForced) {
     263            continue;
     264        }
    224265
    225266        // we make a copy of the largest footprint; this will be used for all new sources associated with this object
     
    299340        pmPhotObj *obj = objects->data[i];
    300341        nSources += obj->sources->n;
    301         psAssert (obj->sources->n == nImages, "failed to match sources?");
     342        if (minDetectionsForForced <= 1) {
     343            psAssert (obj->sources->n == nImages, "failed to match sources?");
     344        }
    302345    }
    303346    psLogMsg ("psphot", PS_LOG_DETAIL, "total of %d sources for %d images", nSources, nImages);
     
    375418    return copy;
    376419}
     420
     421// qsort function to sort match info by order
     422static int compareMatchInfoByOrder(const void *a, const void *b) {
     423    psphotStackMatchInfo *infoA = (psphotStackMatchInfo *) a;
     424    psphotStackMatchInfo *infoB = (psphotStackMatchInfo *) b;
     425
     426    int     result;
     427    if (infoA->order < infoB->order) {
     428        result = -1;
     429    } else if (infoA->order == infoB->order) {
     430        result = 0;
     431    } else {
     432        result = 1;
     433    }
     434    return result;
     435}
     436
     437// qsort function to sort match info by input number
     438static int compareMatchInfoByInputNum(const void *a, const void *b) {
     439    psphotStackMatchInfo *infoA = (psphotStackMatchInfo *) a;
     440    psphotStackMatchInfo *infoB = (psphotStackMatchInfo *) b;
     441
     442    int     result;
     443    if (infoA->inputNum < infoB->inputNum) {
     444        result = -1;
     445    } else if (infoA->inputNum == infoB->inputNum) {
     446        result = 0;
     447    } else {
     448        result = 1;
     449    }
     450    return result;
     451}
     452
     453// psphotStackGetMatchInfo
     454// process the recipe PSPHOT.STACK.MATCH.FILTERS which controls the order that the inputs
     455// are processed for source matching and the rules for creating matched sources for sources that
     456// are only detected in a single band.
     457static psphotStackMatchInfo *psphotStackGetMatchInfo (pmConfig *config, const pmFPAview *view, const char *filerule) {
     458
     459    bool status = false;
     460    psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     461
     462    psMetadata *filterInfo = psMetadataLookupPtr (&status, recipe, "PSPHOT.STACK.MATCH.FILTERS");
     463    if (!status || !filterInfo) {   
     464        psLogMsg ("psphot", PS_LOG_WARN, "PSPHOT.MATCH.STACK.FILTERS not found in the recipe. Will process inputs in order supplied.");
     465        filterInfo = NULL;
     466    }
     467
     468    int num = psphotFileruleCount(config, filerule);
     469    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
     470    if (!status) chisqNum = -1;
     471
     472    // Find the filter for each of the inputs in fpa concepts
     473    psArray *inputFilters = psArrayAlloc(num);
     474    for (int i = 0 ; i < num; i++) {
     475        if (i != chisqNum) {
     476            pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, i);
     477            psAssert (file, "missing file?");
     478
     479            psString filterid = psMetadataLookupStr(&status, file->fpa->concepts, "FPA.FILTERID");
     480            psAssert (filterid, "missing FPA.FILTERID?");
     481            psArraySet(inputFilters, i, filterid);
     482        } else {
     483            // The chisq image inherits its filterid from the first input so we shouldn't use that.
     484            psString tmp  = psStringCopy("chisq");
     485            psArraySet(inputFilters, i, tmp);
     486            psFree(tmp);
     487        }
     488    }
     489    // Allocate the match info array
     490    psphotStackMatchInfo *matchInfo = psAlloc(num *sizeof(psphotStackMatchInfo));
     491    memset(matchInfo, 0, num*sizeof(psphotStackMatchInfo));
     492    int highest_order = -1;
     493    if (filterInfo) {
     494        // PSPHOT.STACK.MATCH.FILTERS is a metadata which contains a list of metadata objects each
     495        // entry pertaining to a filter.
     496        // The objects contained in each filter's metadata are strings.
     497     
     498        // Loop over the entries in the recipe and find the entry for each our our input readouts.
     499        // XXX: Will this work if more than one input with a given filter is supplied?
     500        // I think so.
     501        psMetadataIterator *iter = psMetadataIteratorAlloc(filterInfo, PS_LIST_HEAD, NULL);
     502        psMetadataItem *item = NULL;
     503        while ((item = psMetadataGetAndIncrement (iter)) != NULL) {
     504            if (item->type != PS_DATA_METADATA) {
     505                psAbort ("Invalid type for PSPHOT.STACK.MATCH.FILTER: %s, not a metadata folder", item->name);
     506            }
     507            psString thisFilter = psMetadataLookupStr (&status, item->data.md, "FILTER.ID");
     508            psAssert(thisFilter, "missing FILTER.ID");
     509
     510            psString orderStr = psMetadataLookupStr (&status, item->data.md, "ORDER");
     511            psAssert(orderStr, "missing ORDER");
     512            psS32 order = atoi(orderStr);
     513
     514            psString matchAllStr = psMetadataLookupStr (&status, item->data.md, "MATCH.ALL");
     515            psAssert(matchAllStr, "missing MATCH.ALL");
     516            bool matchAll = (strcasecmp("true", matchAllStr) == 0);
     517
     518            // look for this filter in the inputs
     519            for (int i = 0; i < num; i++) {
     520                if (!strcmp((char *)inputFilters->data[i], thisFilter)) {
     521                    // We have an input for this one
     522                    matchInfo[i].inputNum = i;
     523                    strncpy(matchInfo[i].filterID, thisFilter, MATCH_INFO_FILTER_STR_LEN - 1 );
     524                    matchInfo[i].order = order;
     525                    matchInfo[i].matchAll = matchAll;
     526                    psLogMsg ("psphot", PS_LOG_DETAIL, "input: %d %s match order: %d match all: %d\n",
     527                                                               i, thisFilter, order, matchAll);
     528                    if (order > highest_order) {
     529                        highest_order = order;
     530                    }
     531                    break;
     532                }
     533            }
     534        }
     535        psFree(iter);
     536    }
     537
     538    // Make sure we have a matchInfo for all of the inputs. Fill in an entry for any that were not found.
     539    for (int i = 0; i < num; i++) {
     540        if (!*matchInfo[i].filterID) {
     541            matchInfo[i].inputNum = i;
     542            strncpy(matchInfo[i].filterID, inputFilters->data[i], MATCH_INFO_FILTER_STR_LEN - 1);
     543            matchInfo[i].order = ++highest_order;
     544            matchInfo[i].matchAll = false;
     545            psLogMsg ("psphot", PS_LOG_WARN, "Entry in PSPHOT.MATCH.STACK.FILTERS not found for input: %d filter: %s using order %d",
     546                i, (char *) inputFilters->data[i], highest_order);
     547        }
     548    }
     549    psFree(inputFilters);
     550
     551    if (filterInfo) {
     552        // Sort the array by ORDER.
     553        qsort(matchInfo, num, sizeof(psphotStackMatchInfo), compareMatchInfoByOrder);
     554    } else {
     555        // no need to sort we just built the list in the order that the inputs were supplied
     556    }
     557
     558    return matchInfo;
     559}
     560
     561bool psphotDropBadMatchedSources (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects) {
     562
     563    bool status = false;
     564
     565    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Drop Bad Matched Sources ---");
     566
     567    psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     568
     569    // select the appropriate recipe information
     570    bool keepBadMatches = psMetadataLookupBool (&status, recipe, "PSPHOT.STACK.KEEP.BAD.MATCHES");
     571    if (!status) {
     572        keepBadMatches = true;
     573    }
     574
     575    if (keepBadMatches) {
     576        psLogMsg ("psphot", PS_LOG_INFO, "keeping bad matches");
     577        return true;
     578    }
     579
     580    int numImages = psphotFileruleCount(config, filerule);
     581    psVector *dropped = psVectorAlloc(numImages, PS_TYPE_U32);
     582    psVectorInit(dropped, 0);
     583
     584    int nDropped = 0;
     585    for (int i = 0; i < objects->n; i++) {
     586        pmPhotObj *obj = objects->data[i];
     587
     588        // traverse the array from the end so that sources don't move until after we've processed them
     589        for (int j = obj->sources->n - 1; j >= 0; j--) {
     590
     591            pmSource *source = obj->sources->data[j];
     592            // This applies only to matched sources
     593            if (!(source->mode2 & PM_SOURCE_MODE2_MATCHED)) continue;
     594
     595            if (isfinite(source->apFlux)) continue;
     596
     597            psTrace ("psphot", 7, "Dropping matched source from image %d at (%d, %d) no valid flux",
     598                source->imageID, source->peak->x, source->peak->y);
     599
     600            psAssert(source->imageID >= 0 && source->imageID < numImages, "bad imageID %d", source->imageID);
     601
     602            dropped->data.U32[source->imageID]++;
     603           
     604            nDropped++;
     605
     606            psArrayRemoveIndex(obj->sources, j);
     607        }
     608    }
     609
     610    psLogMsg ("psphot", PS_LOG_DETAIL, "Dropped %d matched sources with no valid flux", nDropped);
     611    psLogMsg ("psphot", PS_LOG_DETAIL, "       Input  Num Dropped");
     612    for (int i=0; i<numImages; i++) {
     613        psLogMsg ("psphot", PS_LOG_DETAIL, "    %8d     %8d", i, dropped->data.U32[i]);
     614    }
     615    psFree(dropped);
     616
     617    return true;
     618}
     619
     620
  • branches/eam_branches/ipp-20120805/psphot/src/psphotSourceStats.c

    r34378 r34399  
    524524    float PSF_SN_LIM = 2.0*psMetadataLookupF32(&status, recipe, "PSF_SN_LIM"); psAssert (status, "missing PSF_SN_LIM");
    525525
    526     // XXX move this to a config file?
     526    // XXX this will cause an error in the vector length is > 8
    527527    # define NSIGMA 8
    528     float sigma[NSIGMA] = {1.0, 2.0, 3.0, 4.5, 6.0, 9.0, 12.0, 18.0};
     528    // moved to config file
     529    psVector  *sigmavec = psMetadataLookupPtr (&status, recipe, "PSF.SIGMA.VALUES");
     530
     531    float sigma[NSIGMA];
    529532    float Sout[NSIGMA];
    530533    float Rmin[NSIGMA];
    531534    int   Nout[NSIGMA]; // number of stars found in clump : use this to control the number of regions measured by psphotRoughClass
    532535
     536    int nsigma;
     537    if (sigmavec) {
     538        psAssert(sigmavec->n <= NSIGMA, "too many sigma values in recipe %ld maximum is %d", sigmavec->n, NSIGMA);
     539        // copy the data from vector to local array to keep the code below easier to read
     540        for (int i = 0 ; i < sigmavec->n; i++) {
     541            sigma[i] = sigmavec->data.F32[i];
     542        }
     543        assert (sigmavec->n <= 8);
     544        nsigma = sigmavec->n;
     545    } else {
     546        // requiring this causes updates to pop an assertion
     547        //  psAssert(status, "missing PSF.SIGMA.VALUES");
     548        float defaultsigma[NSIGMA]  = {1.0, 2.0, 3.0, 4.5, 6.0, 9.0, 12.0, 18.0};
     549        for (int i = 0 ; i < NSIGMA; i++) {
     550            sigma[i] = defaultsigma[i];
     551        }
     552        nsigma = NSIGMA;
     553    }
     554
    533555    // this sorts by peak->rawFlux
    534556    sources = psArraySort (sources, pmSourceSortByFlux);
    535557
    536558    // loop over radii:
    537     for (int i = 0; i < NSIGMA; i++) {
     559    for (int i = 0; i < nsigma; i++) {
    538560
    539561        // XXX move max source number to config
     
    592614    float minS = Sout[0];
    593615    float maxS = Sout[0];
    594     for (int i = 0; i < NSIGMA; i++) {
     616    for (int i = 0; i < nsigma; i++) {
    595617        minS = PS_MIN(Sout[i], minS);
    596618        maxS = PS_MAX(Sout[i], maxS);
    597619    }
    598     if (minS > 0.65) Sigma = sigma[NSIGMA-1];
     620    if (minS > 0.65) Sigma = sigma[nsigma-1];
    599621    if (maxS < 0.65) Sigma = sigma[0];
    600622
    601     for (int i = 0; i < NSIGMA - 1 && isnan(Sigma); i++) {
     623    for (int i = 0; i < nsigma - 1 && isnan(Sigma); i++) {
    602624        if (!isfinite(Sout[i]) || !isfinite(Sout[i+1])) continue;
    603625        if ((Sout[i] > 0.65) && (Sout[i+1] > 0.65)) continue;
  • branches/eam_branches/ipp-20120805/psphot/src/psphotStackImageLoop.c

    r34258 r34399  
    2121    psMemDump("startloop");
    2222
     23    pmFPAview *view = pmFPAviewAlloc (0);
    2324    pmFPAfile *inputRaw = psMetadataLookupPtr (&status, config->files, "PSPHOT.STACK.INPUT.RAW");
    2425    pmFPAfile *inputCnv = psMetadataLookupPtr (&status, config->files, "PSPHOT.STACK.INPUT.CNV");
     
    3738    }
    3839
    39     pmFPAview *view = pmFPAviewAlloc (0);
    40 
    41 
    42     // XXX for now, just load the full set of images up front except for EXPNUM which we defer
     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    }
     46
     47    // just load the full set of images up front except for EXPNUM which we defer
    4348    pmFPAfileActivate (config->files, false, "PSPHOT.STACK.EXPNUM.RAW");
    4449    pmFPAfileActivate (config->files, false, "PSPHOT.STACK.EXPNUM.CNV");
     
    6368                psMemDump("load");
    6469
    65                 // Generate the 1st PSF-matched image set (larger target PSFs are generated by smoothing this image)
    66                 if (!psphotStackMatchPSFs (config, view)) {
    67                     psError(psErrorCodeLast(), false, "failure in psphotStackMatchPSFs for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout);
    68                     psFree (view);
    69                     return false;
    70                 }
     70                if (match_psfs) {
     71                    // Generate the 1st PSF-matched image set (larger target PSFs are generated by smoothing this image)
     72                    if (!psphotStackMatchPSFs (config, view)) {
     73                        psError(psErrorCodeLast(), false, "failure in psphotStackMatchPSFs for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout);
     74                        psFree (view);
     75                        return false;
     76                    }
     77                } else {
     78                    if (!psphotStackAllocateOutput (config, view, recipe)) {
     79                        psError(psErrorCodeLast(), false, "failure in psphotStackAllocateOutput for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout);
     80                        psFree (view);
     81                        return false;
     82                    }
     83                }
    7184                psMemDump("stackmatch");
    7285
  • branches/eam_branches/ipp-20120805/psphot/src/psphotStackMatchPSFs.c

    r34136 r34399  
    44{
    55    bool status = true;
     6
     7    psLogMsg ("psphot", PS_LOG_INFO, "--- psphotStack Match PSFs ---");
    68
    79    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, "PSPHOT");
     
    5759
    5860// convolve the image to match desired PSF
    59 // XXX is this code consistent with 'convolve' = false?
     61// XXX is this code consistent with 'convolve' = false?  XXX: No
    6062bool psphotStackMatchPSFsReadout (pmConfig *config, const pmFPAview *view, psphotStackOptions *options, int index) {
    6163
    6264    psImageMaskType maskValue;
    6365    psImageMaskType markValue;
     66
     67    psLogMsg("psphot", PS_LOG_DETAIL, "-- starting PSF matching for readout %d --", index);
    6468
    6569    // get the PSPHOT.MASK value from the config
     
    102106        saveMatchData(readoutOut, options, index);
    103107    }
     108    bool notMatched = psMetadataLookupBool(NULL, readoutOut->analysis, "NOT.PSF.MATCHED");
     109    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            }
     122        }
     123    }
    104124
    105125    // renormalize the stack variances to have sigma = 1.0
     
    111131    // save the output fwhm values in the readout->analysis.  we may have / will have multiple output PSF sizes,
    112132    // so we save this in a vector.  if the vector is not yet defined, create it
    113     // Skip this if the readout deconvolution fraction was over the limit.
     133    // Skip this if psf matching failed for this readout. For example if deconvolution fraction was over the limit.
    114134    // NOTE: fwhmValues as defined here has 1 + nMatched PSF : 0 == unmatched
    115135    psVector *fwhmValues = psVectorAllocEmpty(10, PS_TYPE_F32);
    116136    psVectorAppend(fwhmValues, NAN); // XXX this corresponds to the unmatched image set
    117137
    118     bool overLimit = psMetadataLookupBool(NULL, readoutOut->analysis, "DECONV.OVERLIMIT");
    119     if (!overLimit) {
     138    if (!notMatched) {
    120139        for (int i = 0; i < options->targetSeeing->n; i++) {
    121140            psVectorAppend(fwhmValues, options->targetSeeing->data.F32[i]);
     
    124143    psMetadataAddVector(readoutSrc->analysis, PS_LIST_TAIL, "STACK.PSF.FWHM.VALUES", PS_META_REPLACE, "PSF sizes", fwhmValues);
    125144    psMetadataAddVector(readoutOut->analysis, PS_LIST_TAIL, "STACK.PSF.FWHM.VALUES", PS_META_REPLACE, "PSF sizes", fwhmValues);
    126     psFree(fwhmValues); // drops the extra copy
     145    psFree(fwhmValues); // drops this function's reference
    127146
    128147    return true;
  • branches/eam_branches/ipp-20120805/psphot/src/psphotStackMatchPSFsNext.c

    r34136 r34399  
    8181    psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels
    8282    psAssert (maskVal, "missing mask value?");
     83    psImageMaskType maskSat = psMetadataLookupImageMask(&status, recipe, "MASK.SAT"); // Mask value for bad pixels
     84    psAssert (maskSat, "missing mask value?");
     85
    8386
    8487    float minGauss = psMetadataLookupF32(NULL, recipe, "PEAKS_MIN_GAUSS"); // Minimum valid fraction of kernel
     
    123126    psImageSmoothMask_Threaded(readout->variance, readout->variance, readout->mask, maskVal, SIGMA_SMTH * M_SQRT1_2, NSIGMA_SMTH, minGauss);
    124127    psLogMsg("psphot", PS_LOG_MINUTIA, "smooth variance: %f sec\n", psTimerMark("psphot.smooth"));
     128
     129    // Insure that invalid pixels are masked
     130    // XXX: the smoothing seems to generate nan pixels in the variance image
     131    // XXX: We may need to loop over the cached sources and redefine the maskObj images...
     132    pmReadoutMaskInvalid(readout, maskVal, maskSat);
     133    {
     134        // Now go rebuild the sources' copies of the mask
     135        pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
     136        psAssert (detections, "missing detections?");
     137
     138        psArray *sources = detections->allSources;
     139
     140        if (sources && sources->n) {
     141            for (int i = 0 ; i < sources->n; i++) {
     142                // XXX: move this to a function in pmSource.c
     143                pmSource *source = sources->data[i];
     144                if (source->maskObj && source->maskView) {
     145                    psFree(source->maskObj);
     146                    source->maskObj = psImageCopy (source->maskObj, source->maskView, PS_TYPE_IMAGE_MASK);
     147                }
     148            }
     149        }
     150    }
    125151
    126152    psLogMsg("psphot", PS_LOG_INFO, "smoothed");
  • branches/eam_branches/ipp-20120805/psphot/src/psphotStackMatchPSFsUtils.c

    r34136 r34399  
    280280
    281281    // Do the image matching
     282    bool rejectReadout = false;
    282283    pmSubtractionKernels *kernel = psMetadataLookupPtr(&mdok, readoutSrc->analysis, PM_SUBTRACTION_ANALYSIS_KERNEL); // Conv kernel
    283284    if (kernel) {
     
    301302
    302303        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)) {
    303             psError(psErrorCodeLast(), false, "Unable to match images.");
    304             goto escape;
     304            int errorCode = psErrorCodeLast();
     305            if (errorCode == PM_ERR_SMALL_AREA) {
     306                // failed to match but, don't fault. Just drop this input from measurements that need the
     307                // matched readout.
     308                rejectReadout = true;
     309                psLogMsg("psphot", PS_LOG_WARN, "PSF match failed for input %d. Too few pixels.", index);
     310            } else {
     311                psError(psErrorCodeLast(), false, "Unable to match images.");
     312                goto escape;
     313            }
    305314        }
    306315    }
    307316
    308     // Reject image completely if the maximum deconvolution fraction exceeds the limit
     317    // If the maximum deconvolution fraction exceeds the limit, reject this input for analyses that require PSF matching
    309318    float deconvLimit = psMetadataLookupF32(NULL, stackRecipe, "DECONV.LIMIT"); // Limit on deconvolution fraction
    310319    float deconv = psMetadataLookupF32(NULL, readoutOut->analysis, PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Max deconvolution fraction
    311320    if (deconv > deconvLimit) {
    312 #if (1)
    313         // XXX: don't reject the image set
    314         psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting image for matched psf analysis%d\n", deconv, deconvLimit, index);
    315         psMetadataAddBool(readoutOut->analysis, PS_LIST_TAIL, "DECONV.OVERLIMIT", PS_META_REPLACE, "", true);
    316 #else
    317         psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting image %d\n", deconv, deconvLimit, index);
    318         goto escape;
    319 #endif
     321        rejectReadout = true;
     322        psLogMsg("psphot", PS_LOG_WARN, "Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting image for matched psf analysis%d\n", deconv, deconvLimit, index);
     323    }
     324   
     325    if (rejectReadout) {
     326        psMetadataAddBool(readoutOut->analysis, PS_LIST_TAIL, "NOT.PSF.MATCHED", PS_META_REPLACE, "", true);
    320327    } else {
    321         psMetadataAddBool(readoutOut->analysis, PS_LIST_TAIL, "DECONV.OVERLIMIT", PS_META_REPLACE, "", false);
    322     }
    323 
     328        psMetadataAddBool(readoutOut->analysis, PS_LIST_TAIL, "NOT.PSF.MATCHED", PS_META_REPLACE, "", false);
     329    }
    324330    // save the PSF on the new readout->analysis:
    325331    // if (!psMetadataAddPtr (readoutOut->analysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_META_REPLACE | PS_DATA_UNKNOWN, "psphot psf model", options->psf)) {
     
    470476}
    471477
    472 // Set input to be skipped if the decovolution fraction was overlimit. Use for radial apertures
    473 // This interface can be potentiall be extended for other uses
     478// Set input to be skipped if the analysis reports that psf matching has failed for some reason.
     479// For exmaple if decovolution fraction was overlimit or the bad fraction was too high.
     480//
    474481bool psphotStackSetInputsToSkip(pmConfig *config, const pmFPAview *view, const char *filerule, bool set) {
    475482    int num = psphotFileruleCount(config, filerule);
     
    487494        psAssert (readout, "missing readout?");
    488495        if (set) {
    489             bool overLimit = psMetadataLookupBool(&status, readout->analysis, "DECONV.OVERLIMIT");
    490             psMetadataAddBool(readout->analysis, PS_LIST_TAIL, "PSPHOT.SKIP.INPUT", PS_META_REPLACE, "Skip analysis", overLimit);
     496            bool notMatched = psMetadataLookupBool(&status, readout->analysis, "NOT.PSF.MATCHED");
     497            psMetadataAddBool(readout->analysis, PS_LIST_TAIL, "PSPHOT.SKIP.INPUT", PS_META_REPLACE, "Skip analysis", notMatched);
    491498        } else {
    492499            psMetadataAddBool(readout->analysis, PS_LIST_TAIL, "PSPHOT.SKIP.INPUT", PS_META_REPLACE, "Skip analysis", false);
  • branches/eam_branches/ipp-20120805/psphot/src/psphotStackReadout.c

    r34266 r34399  
    22
    33static bool psphotStackLoadWCS(pmConfig *config, const pmFPAview *view, const char *filerule);
     4static void logMemStats(const char *heading);
    45
    56// we have 3 possible real filesets:
     
    5152    // by the multiple threads, not the total time used by all threads.
    5253    psTimerStart ("psphotReadout");
     54
     55    logMemStats("Start");
    5356
    5457    pmModelClassSetLimits(PM_MODEL_LIMITS_LAX); // allow models to have ugly fits (eg, central cusp)
     
    8285    }
    8386
    84     // Generate the mask and weight images (if not supplied) and set mask bits
     87    // 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)
    8589    if (!psphotSetMaskAndVariance (config, view, STACK_DET)) {
     90        return psphotReadoutCleanup (config, view, STACK_SRC);
     91    }
     92    if (!psphotSetMaskAndVariance (config, view, STACK_OUT)) {
    8693        return psphotReadoutCleanup (config, view, STACK_SRC);
    8794    }
     
    114121    }
    115122
     123#ifdef MAKE_CHISQ_IMAGE
    116124    // also make the chisq detection image
    117125    if (!psphotStackChisqImage(config, view, STACK_DET, STACK_SRC)) {
     
    119127        return psphotReadoutCleanup (config, view, STACK_SRC);
    120128    }
     129#endif
    121130    if (!strcasecmp (breakPt, "CHISQ")) {
    122131        return psphotReadoutCleanup (config, view, STACK_SRC);
     
    151160    // psphotDumpTest (config, view, STACK_SRC);
    152161    psMemDump("sourcestats");
     162    logMemStats("sourcestats");
    153163
    154164    // classify sources based on moments, brightness
     
    196206    // window of size PSF_MOMENTS_RADIUS (same window used to measure the psf-scale moments)
    197207    // but iterates to an appropriately larger size
    198     psphotKronIterate(config, view, STACK_SRC);
     208        logMemStats("before.kron.1");
     209    psphotKronIterate(config, view, STACK_SRC, 1);
     210        logMemStats("after.kron.1");
    199211
    200212    // identify CRs and extended sources
     
    208220    psphotReplaceAllSources (config, view, STACK_SRC, false); // pass 1 (detections->allSources)
    209221
     222    logMemStats("pass1");
    210223
    211224    // if we only do one pass, skip to extended source analysis
     
    299312    }
    300313
     314    logMemStats("prematch");
     315
    301316    // generate the objects (objects unify the sources from the different images) NOTE: could
    302317    // this just match the detections for the chisq image, and not bother measuring the source
     
    331346    // re-measure the kron mags with models subtracted
    332347    // psphotKronMasked(config, view, STACK_SRC);
    333     psphotKronIterate(config, view, STACK_SRC);
     348    logMemStats("before.kron.2");
     349    psphotKronIterate(config, view, STACK_SRC, 2);
     350    logMemStats("after.kron.2");
    334351
    335352    // measure source size for the remaining sources
     
    338355
    339356    psMemDump("psfstats");
     357
     358    // drop matched sources without any useful measurements
     359    psphotDropBadMatchedSources (config, view, STACK_SRC, objects);
    340360
    341361    // measure elliptical apertures, petrosians (objects sorted by S/N)
     
    354374    }
    355375
    356 
    357376    bool radial_apertures = psMetadataLookupBool(NULL, recipe, "RADIAL_APERTURES");
    358377    if (radial_apertures) {
     
    361380
    362381        // NOTE: we always do the radial apertures analysis on the convolved image since
    363         // those are the ones that are psf matched and the source of STACK_OUT's pixels
     382        // those are the ones that are psf matched and are the source of STACK_OUT's pixels
    364383        // XXX: Actually if PSPHOT.STACK.MATCH.PSF.SOURCE were set to RAW this wouldn't be true.
    365384        // but in that case we don't get past the psf matching step because there is no
     
    419438        // psphotEfficiency wants to have the PSF of the image, but since we are measuring on
    420439        // the convolved images we need to generate PSFs for the DET images
    421         if (!psphotChoosePSF (config, view, STACK_DET, false)) { // pass 1
     440        if (!psphotChoosePSF (config, view, STACK_DET, false)) {
    422441            psLogMsg ("psphot", 3, "failure to construct a psf model for raw input");
    423442            return psphotReadoutCleanup (config, view, STACK_DET);
     
    430449    psphotCopyEfficiency (config, view, STACK_OUT, STACK_DET);
    431450
     451    logMemStats("final");
     452#if (1)
     453    psphotSourceMemory(config, view, STACK_SRC);
     454    psphotSourceMemory(config, view, STACK_OUT);
     455#endif
     456
    432457    // replace failed sources?
    433458    // psphotReplaceUnfitSources (sources);
     
    440465    psphotSourceFreePixels (config, view, STACK_SRC);
    441466
     467#ifdef MAKE_CHISQ_IMAGE
    442468    // remove chisq image from config->file:PSPHOT.INPUT
    443469    psphotStackRemoveChisqFromInputs(config, STACK_DET);
     
    445471        psphotStackRemoveChisqFromInputs(config, STACK_SRC);
    446472    }
     473#endif
    447474
    448475    psFree (objects);
     
    474501    return true;
    475502}
     503
     504// read the memory usage data from /proc and log them out
     505// This will only work on a system that has /proc (not MacOS for instance) but since this function just
     506// tries to open and read from a file it is safe
     507// XXX: refine this and move it to psLib
     508static void logMemStats(const char *heading) {
     509
     510    // file containing memory statistics for this process proc. See proc(5)
     511    const char* statm_path = "/proc/self/statm";
     512
     513    FILE *f = fopen(statm_path,"r");
     514    if (!f) {
     515        psLogMsg ("psphot", PS_LOG_WARN, "failed to open %s", statm_path);
     516        return;
     517    }
     518
     519    unsigned long vmSize, resident, share, text, lib, data;
     520
     521    int nread;
     522    nread = fscanf(f,"%ld %ld %ld %ld %ld %ld", &vmSize, &resident, &share, &text, &lib, &data);
     523    fclose(f);
     524    if (nread != 6) {
     525        psLogMsg ("psphot", PS_LOG_WARN, "failed to read 6 items from %s", statm_path);
     526        return;
     527    }
     528 
     529    // XXX: assuming 4 KB page size here
     530#   define PAGES_TO_MB(_v) (_v * 4.096 / 1024.)
     531    psLogMsg ("psphot", PS_LOG_INFO, "Memory usage at %20s: Total VmSize: %8.2f MB   Resident %8.2f MB   Data: %8.2f MB\n",
     532        heading, PAGES_TO_MB(vmSize), PAGES_TO_MB(resident), PAGES_TO_MB(data));
     533}
     534
     535
    476536
    477537/* here is the process:
Note: See TracChangeset for help on using the changeset viewer.