IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 34317


Ignore:
Timestamp:
Aug 16, 2012, 2:38:37 PM (14 years ago)
Author:
bills
Message:

Several changes to psphot and psphotStack

  1. Add function to compute the memory used by all of the sources
  2. Add function to log memory stats in psphotStack
  3. Don't load or psf match the convolved images into psphotStack unless they are needed.

This saves a lot of time if RADIAL_APERTURES are not enabled and we are measuring on the raw images

  1. Several improvements to the error handling in the Kron measurements. In particular the Mrf value

was being treated as positive when both the numerator and denomiator were negative. This is the cause
of many of the very large kron radius measurements. Set Mrf to NAN in these cases.

  1. Skip kron measurments for source if the previous Mrf measurement was NAN earlier in the process.

This saves memory by not expanding the source images when the kron measurements were actually going
to be skipped

  1. Remove the hack cut on fwhmMaj. Managing the kron radius measurements better fixes the memory explosion

that that helped to reduce.

Location:
trunk/psphot/src
Files:
2 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/psphot/src/Makefile.am

    r34258 r34317  
    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
  • trunk/psphot/src/psphot.h

    r34266 r34317  
    360360                                     pmReadout **chiReadout,
    361361                                     int index);
     362bool psphotStackAllocateOutput( const pmConfig *config, pmFPAview *view, psMetadata *recipe);
    362363
    363364bool psphotStackRemoveChisqFromInputs (pmConfig *config, const char *filerule);
     
    483484bool psphotMaskFootprint (pmReadout *readout, pmSource *source, psImageMaskType markVal);
    484485
    485 bool psphotKronIterate (pmConfig *config, const pmFPAview *view, const char *filerule);
    486 bool psphotKronIterateReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char * filerule, pmReadout *readout, psArray *sources, pmPSF *psf, int index);
     486bool psphotKronIterate (pmConfig *config, const pmFPAview *view, const char *filerule, int pass);
     487bool psphotKronIterateReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char * filerule, pmReadout *readout, psArray *sources, pmPSF *psf, int index, int pass);
    487488bool psphotKronIterate_Threaded (psThreadJob *job);
    488489
     
    509510    );
    510511
     512bool psphotSourceMemory(pmConfig *config, const pmFPAview *view, const char *filerule);
     513bool psphotSourceMemoryReadout(pmConfig *config, const pmFPAview *view, const char *filerule, int index);
     514
    511515#endif
  • trunk/psphot/src/psphotKronIterate.c

    r34311 r34317  
    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
     
    236247            PS_ARRAY_ADD_SCALAR(job->args, KRON_SMOOTH_SIGMA,  PS_TYPE_F32);
    237248            PS_ARRAY_ADD_SCALAR(job->args, KRON_SB_MIN_DIVISOR,PS_TYPE_F32);
     249            PS_ARRAY_ADD_SCALAR(job->args, pass,               PS_TYPE_S32);
    238250
    239251// set this to 0 to run without threading
     
    298310    float KRON_SMOOTH_SIGMA         = PS_SCALAR_VALUE(job->args->data[11],F32);
    299311    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
    300316
    301317    for (int j = 0; j < KRON_ITERATIONS; j++) {
     
    309325            if (!(source->tmpFlags & PM_SOURCE_TMPF_MOMENTS_MEASURED)) continue;
    310326            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            }
    311332
    312333            // replace object in image
     
    322343            }
    323344
    324             // On first iteration set window radius to sky radius (if valid) on second iteration
    325             // use a factor times the previous radial moment value up to a maximum value that
    326             // depends on the surface brightness of the source
    327             float maxWindow;
    328             if (j == 0) {
    329                 maxWindow = isfinite(source->skyRadius) ? source->skyRadius : RADIUS;
    330             } else {
     345            // On first iteration set window radius to sky radius (if valid). We also use this on subsequent
     346            // iterations if we cannot find a better limit
     347            float maxWindow = isfinite(source->skyRadius) ? source->skyRadius : RADIUS;
     348            if (j > 0) {
     349                // on subsequent iterations we use a factor times the previous radial moment value
     350                // limited to a maximum value that depends on the surface brightness of the source
    331351                if (KRON_SB_MIN_DIVISOR) {
    332352                    // Limit window radius based on surface brightness if we have a good measurement of kron flux
    333                     if (isfinite(source->moments->Mrf) && source->moments->Mrf > 0 &&
    334                         isfinite(source->moments->KronFlux)  && (source->moments->KronFlux > 0)) {
     353                    if (isfinite(source->moments->KronFlux)  && (source->moments->KronFlux > 0)) {
    335354                        float Rmax = sqrt(source->moments->KronFlux) / KRON_SB_MIN_DIVISOR;
    336355
    337                         maxWindow = PS_MIN(6.0*source->moments->Mrf, Rmax);
    338                     } else {
    339                         maxWindow = RADIUS;
     356                        if (isfinite(source->moments->Mrf) && source->moments->Mrf > 0) {
     357                            maxWindow = PS_MIN(6.0*source->moments->Mrf, Rmax);
     358                        } else {
     359                            maxWindow = PS_MIN(Rmax, maxWindow);
     360                        }
    340361                    }
    341362                } else {
     
    345366            }
    346367            float windowRadius = PS_MAX(RADIUS, maxWindow);
     368
     369#ifdef REVERT_ON_BAD_MEASURMENT
     370            // save previous measurements. We might revert back to them if this round fails
     371            float MrfPrior = source->moments->Mrf;
     372            float KronFluxPrior = source->moments->KronFlux;
     373            float KronFluxErrPrior = source->moments->KronFluxErr;
     374#endif
    347375
    348376            // re-allocate image, weight, mask arrays for each peak with box big enough to fit BIG_RADIUS
     
    371399            }
    372400
     401#ifdef REVERT_ON_BAD_MEASUREMENT
     402            // on pass 2 if we get an invalid measurement on a pass 1 source where we had a good one previously
     403            // in pass 1 keep that measurement
     404            bool reverted = false;
     405            if (pass > 1 && !isfinite(source->moments->Mrf) && (source->mode2 & PM_SOURCE_MODE2_PASS1_SRC)) {
     406                source->moments->Mrf = MrfPrior;    // This is finite otherwise we wouldn't have gotten here
     407                source->moments->KronFlux = KronFluxPrior;
     408                source->moments->KronFluxErr = KronFluxErrPrior;
     409                reverted = true;
     410            }
     411#endif
     412#ifdef DUMP_KRS
     413#ifndef REVERT_ON_BAD_MEASUREMENT
     414            bool reverted = false;
     415#endif
     416            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);
     417#endif
     418
    373419            // if we subtracted it above, re-subtract the object, leave local sky
    374420            if (reSubtract) {
     
    490536
    491537    float MrfTry = RF/RS;
    492     if (!isfinite(MrfTry)) {
    493         // We did not get a successul measurement of the kron radius.
    494         // Leave the current values unchanged.
     538    if (RF <= 0. || RS <= 0 || !isfinite(MrfTry)) {
     539        // We did not get a good measurement
     540        source->moments->Mrf = NAN;
     541        source->moments->KronFlux  = NAN;
     542        source->moments->KronFluxErr  = NAN;
    495543        return false;
    496544    }
     
    546594    }
    547595
    548     source->moments->Mrf = Mrf;
     596    source->moments->Mrf         = Mrf;
    549597    source->moments->KronFlux    = Sum;
    550598    source->moments->KronFluxErr = sqrt(Var);
     
    564612    psAssert(kronWindow, "need a window");
    565613
    566     // If we are not applying the window then we don't need to check for valid Mrf here.
     614    // XXX: If we are not applying the window then we don't need to check for valid Mrf here.
    567615    // We should give the this module a chance to measure a good value.
    568     // Not yet though. We need to test the effect of this
     616    // However experiments show that it hardly ever succeeds in getting a better value
    569617    if (!isfinite(source->moments->Mrf) || source->moments->Mrf < 0 ) return false;
    570618
  • trunk/psphot/src/psphotReadout.c

    r34215 r34317  
    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)
     
    312312    // re-measure the kron mags with models subtracted
    313313    // psphotKronMasked(config, view, filerule);
    314     psphotKronIterate(config, view, filerule);
     314    psphotKronIterate(config, view, filerule, 2);
    315315
    316316    // measure source size for the remaining sources
  • trunk/psphot/src/psphotReadoutMinimal.c

    r34258 r34317  
    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
  • trunk/psphot/src/psphotSetThreads.c

    r34218 r34317  
    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);
  • trunk/psphot/src/psphotStackImageLoop.c

    r34258 r34317  
    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
  • trunk/psphot/src/psphotStackMatchPSFsNext.c

    r34136 r34317  
    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");
  • trunk/psphot/src/psphotStackReadout.c

    r34266 r34317  
    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    }
     
    151158    // psphotDumpTest (config, view, STACK_SRC);
    152159    psMemDump("sourcestats");
     160    logMemStats("sourcestats");
    153161
    154162    // classify sources based on moments, brightness
     
    196204    // window of size PSF_MOMENTS_RADIUS (same window used to measure the psf-scale moments)
    197205    // but iterates to an appropriately larger size
    198     psphotKronIterate(config, view, STACK_SRC);
     206    logMemStats("before.kron.1");
     207    psphotKronIterate(config, view, STACK_SRC, 1);
     208    logMemStats("after.kron.1");
    199209
    200210    // identify CRs and extended sources
     
    208218    psphotReplaceAllSources (config, view, STACK_SRC, false); // pass 1 (detections->allSources)
    209219
     220    logMemStats("pass1");
    210221
    211222    // if we only do one pass, skip to extended source analysis
     
    299310    }
    300311
     312    logMemStats("prematch");
     313
    301314    // generate the objects (objects unify the sources from the different images) NOTE: could
    302315    // this just match the detections for the chisq image, and not bother measuring the source
     
    331344    // re-measure the kron mags with models subtracted
    332345    // psphotKronMasked(config, view, STACK_SRC);
    333     psphotKronIterate(config, view, STACK_SRC);
     346    logMemStats("before.kron.2");
     347    psphotKronIterate(config, view, STACK_SRC, 2);
     348    logMemStats("after.kron.2");
    334349
    335350    // measure source size for the remaining sources
     
    353368        return psphotReadoutCleanup (config, view, STACK_SRC);
    354369    }
    355 
    356370
    357371    bool radial_apertures = psMetadataLookupBool(NULL, recipe, "RADIAL_APERTURES");
     
    419433        // psphotEfficiency wants to have the PSF of the image, but since we are measuring on
    420434        // the convolved images we need to generate PSFs for the DET images
    421         if (!psphotChoosePSF (config, view, STACK_DET, false)) { // pass 1
     435        if (!psphotChoosePSF (config, view, STACK_DET, false)) {
    422436            psLogMsg ("psphot", 3, "failure to construct a psf model for raw input");
    423437            return psphotReadoutCleanup (config, view, STACK_DET);
     
    429443    }
    430444    psphotCopyEfficiency (config, view, STACK_OUT, STACK_DET);
     445
     446    logMemStats("final");
     447#if (1)
     448    psphotSourceMemory(config, view, STACK_SRC);
     449    psphotSourceMemory(config, view, STACK_OUT);
     450#endif
    431451
    432452    // replace failed sources?
     
    474494    return true;
    475495}
     496
     497// read the memory usage data from /proc and log them out
     498// This will only work on a system that has /proc (not MacOS for instance) but since this function just
     499// tries to open and read from a file it is safe
     500static void logMemStats(const char *heading) {
     501
     502    // file containing memory statistics for this process proc. See proc(5)
     503    const char* statm_path = "/proc/self/statm";
     504
     505    FILE *f = fopen(statm_path,"r");
     506    if (!f) {
     507        psLogMsg ("psphot", PS_LOG_WARN, "failed to open %s", statm_path);
     508        return;
     509    }
     510
     511    unsigned long vmSize, resident, share, text, lib, data;
     512
     513    int nread;
     514    nread = fscanf(f,"%ld %ld %ld %ld %ld %ld", &vmSize, &resident, &share, &text, &lib, &data);
     515    fclose(f);
     516    if (nread != 6) {
     517        psLogMsg ("psphot", PS_LOG_WARN, "failed to read 6 items from %s", statm_path);
     518        return;
     519    }
     520 
     521    // assuming 4 KB page size here
     522#   define PAGES_TO_MB(_v) (_v * 4.096 / 1024.)
     523    psLogMsg ("psphot", PS_LOG_INFO, "Memory usage at %20s: Total VmSize: %8.2f MB   Resident %8.2f MB   Data: %8.2f MB\n",
     524        heading, PAGES_TO_MB(vmSize), PAGES_TO_MB(resident), PAGES_TO_MB(data));
     525}
     526
     527
    476528
    477529/* here is the process:
Note: See TracChangeset for help on using the changeset viewer.