IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Feb 5, 2010, 1:38:43 PM (16 years ago)
Author:
eugene
Message:

updates to psphot APIs to enable stack photometry

Location:
branches/eam_branches/20091201/psphot
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/20091201/psphot

  • branches/eam_branches/20091201/psphot/src/psphotSourceStats.c

    r26596 r26788  
    11# include "psphotInternal.h"
    22
    3 bool psphotSetMomentsWindow (psMetadata *recipe, psMetadata *analysis, psArray *sources);
    4 
    5 psArray *psphotSourceStats (pmConfig *config, pmReadout *readout, pmDetections *detections, bool setWindow) {
     3// convert detections to sources and measure their basic properties (moments, local sky, sky
     4// variance) Note: this function only generates sources for the new peaks (peak->assigned)
     5bool psphotSourceStats (pmConfig *config, const pmFPAview *view, bool setWindow)
     6{
     7    bool status = true;
     8
     9    // select the appropriate recipe information
     10    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     11    psAssert (recipe, "missing recipe?");
     12
     13    int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM");
     14    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
     15
     16    // loop over the available readouts
     17    for (int i = 0; i < num; i++) {
     18        if (!psphotSourceStatsReadout (config, view, "PSPHOT.INPUT", i, recipe, setWindow)) {
     19            psError (PSPHOT_ERR_CONFIG, false, "failed to find initial detections for PSPHOT.INPUT entry %d", i);
     20            return false;
     21        }
     22    }
     23    return true;
     24}
     25
     26bool psphotSourceStatsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool setWindow) {
    627
    728    bool status = false;
     
    1031    psTimerStart ("psphot.stats");
    1132
    12     // select the appropriate recipe information
    13     psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
    14     assert (recipe);
     33    // find the currently selected readout
     34    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
     35    psAssert (file, "missing file?");
     36
     37    pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
     38    psAssert (readout, "missing readout?");
     39
     40    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
     41    psAssert (detections, "missing detections?");
     42    psAssert (!detections->newSources, "new sources already defined?");
     43
     44    // XXX TEST:
     45    if (detections->allSources) {
     46        psphotMaskCosmicRayFootprintCheck(detections->allSources);
     47    }
     48    if (detections->newSources) {
     49        psphotMaskCosmicRayFootprintCheck(detections->newSources);
     50    }
    1551
    1652    // determine the number of allowed threads
     
    2157
    2258    // determine properties (sky, moments) of initial sources
    23     float OUTER    = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS");
    24     if (!status) return NULL;
    25 
     59    float OUTER = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS");
     60    psAssert (status, "missing SKY_OUTER_RADIUS in recipe?");
     61
     62    // XXX this seems like an arbitrary number...
    2663    OUTER = PS_MAX(OUTER, 20.0); // XXX Guarantee that we can encompass the max moments radius
    2764
    2865    char *breakPt  = psMetadataLookupStr (&status, recipe, "BREAK_POINT");
    29     if (!status) return NULL;
     66    psAssert (status, "missing BREAK_POINT?");
     67
     68    float INNER        = psMetadataLookupF32 (&status, recipe, "SKY_INNER_RADIUS"); psAssert (status, "missing SKY_INNER_RADIUS");
     69    float MIN_SN       = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN"); psAssert (status, "missing MOMENTS_SN_MIN");
     70
     71    // bit-masks to test for good/bad pixels
     72    psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT");
     73    psAssert (maskVal, "missing MASK.PSPHOT");
     74
     75    // bit-mask to mark pixels not used in analysis
     76    psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT");
     77    psAssert (markVal, "missing MARK.PSPHOT");
    3078
    3179    psArray *peaks = detections->peaks;
    3280    if (!peaks) {
    3381        psError(PS_ERR_UNEXPECTED_NULL, false, "No peaks found!");
    34         return NULL;
     82        return false;
    3583    }
    3684
    3785    // generate the array of sources, define the associated pixel
    3886    sources = psArrayAllocEmpty (peaks->n);
     87
     88    // if there are no peaks, we save the empty source array and return
     89    if (!peaks->n) {
     90        // save the new sources on the detection structure:
     91        detections->newSources = sources;
     92        return true;
     93    }
    3994
    4095    for (int i = 0; i < peaks->n; i++) {
     
    58113        psArrayAdd (sources, 100, source);
    59114        psFree (source);
     115    }
     116
     117    if (!strcasecmp (breakPt, "PEAKS")) {
     118        psLogMsg ("psphot", PS_LOG_INFO, "%ld sources : %f sec\n", sources->n, psTimerMark ("psphot.stats"));
     119        psLogMsg ("psphot", PS_LOG_INFO, "break point PEAKS, skipping MOMENTS\n");
     120        psphotVisualShowMoments (sources);
     121        detections->newSources = sources;
     122        return true;
     123    }
     124
     125    if (setWindow) {
     126        if (!psphotSetMomentsWindow(recipe, readout->analysis, sources)) {
     127            psError(PS_ERR_UNEXPECTED_NULL, false, "Failed to determine Moments Window!");
     128            psFree(sources);
     129            return false;
     130        }
     131    }
     132
     133    // if we have measured the window, we will be saving the modified version of these recipe values on readout->analysis
     134    float SIGMA = psMetadataLookupF32 (&status, readout->analysis, "MOMENTS_GAUSS_SIGMA");
     135    if (!status) {
     136        SIGMA = psMetadataLookupF32 (&status, recipe, "MOMENTS_GAUSS_SIGMA");
     137    }
     138    float RADIUS = psMetadataLookupF32 (&status, readout->analysis, "PSF_MOMENTS_RADIUS");
     139    if (!status) {
     140        RADIUS = psMetadataLookupF32 (&status, recipe, "PSF_MOMENTS_RADIUS");
     141    }
     142
     143    // threaded measurement of the source magnitudes
     144    int Nfail = 0;
     145    int Nmoments = 0;
     146    int Nfaint = 0;
     147
     148    // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts)
     149    int Cx = 1, Cy = 1;
     150    psphotChooseCellSizes (&Cx, &Cy, readout, nThreads);
     151
     152    psArray *cellGroups = psphotAssignSources (Cx, Cy, sources);
     153
     154    for (int i = 0; i < cellGroups->n; i++) {
     155
     156        psArray *cells = cellGroups->data[i];
     157
     158        for (int j = 0; j < cells->n; j++) {
     159
     160            // allocate a job -- if threads are not defined, this just runs the job
     161            psThreadJob *job = psThreadJobAlloc ("PSPHOT_SOURCE_STATS");
     162
     163            psArrayAdd(job->args, 1, cells->data[j]); // sources
     164
     165            PS_ARRAY_ADD_SCALAR(job->args, INNER,   PS_TYPE_F32);
     166            PS_ARRAY_ADD_SCALAR(job->args, MIN_SN,  PS_TYPE_F32);
     167            PS_ARRAY_ADD_SCALAR(job->args, RADIUS,  PS_TYPE_F32);
     168            PS_ARRAY_ADD_SCALAR(job->args, SIGMA,   PS_TYPE_F32);
     169
     170            PS_ARRAY_ADD_SCALAR(job->args, maskVal, PS_TYPE_IMAGE_MASK);
     171            PS_ARRAY_ADD_SCALAR(job->args, markVal, PS_TYPE_IMAGE_MASK);
     172
     173            PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nmoments
     174            PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfail
     175            PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfaint
     176
     177            if (!psThreadJobAddPending(job)) {
     178                psError(PS_ERR_UNKNOWN, false, "Unable to launch thread job PSPHOT_SOURCE_STATS");
     179                psFree (job);
     180                psFree(sources);
     181                return false;
     182            }
     183            psFree(job);
     184        }
     185
     186        // wait for the threads to finish and manage results
     187        if (!psThreadPoolWait (false)) {
     188            psError(PS_ERR_UNKNOWN, false, "Failure in thread job PSPHOT_SOURCE_STATS");
     189            psFree(sources);
     190            return false;
     191        }
     192
     193        // we have only supplied one type of job, so we can assume the types here
     194        psThreadJob *job = NULL;
     195        while ((job = psThreadJobGetDone()) != NULL) {
     196            if (job->args->n < 1) {
     197                fprintf (stderr, "error with job\n");
     198            } else {
     199                psScalar *scalar = NULL;
     200                scalar = job->args->data[7];
     201                Nmoments += scalar->data.S32;
     202                scalar = job->args->data[8];
     203                Nfail += scalar->data.S32;
     204                scalar = job->args->data[9];
     205                Nfaint += scalar->data.S32;
     206            }
     207            psFree(job);
     208        }
     209    }
     210
     211    psFree (cellGroups);
     212
     213    psLogMsg ("psphot", PS_LOG_INFO, "%ld sources, %d moments, %d faint, %d failed: %f sec\n", sources->n, Nmoments, Nfaint, Nfail, psTimerMark ("psphot.stats"));
     214
     215    psphotVisualShowMoments (sources);
     216
     217    // save the new sources on the detection structure:
     218    detections->newSources = sources;
     219
     220
     221    if (detections->allSources) {
     222        psphotMaskCosmicRayFootprintCheck(detections->allSources);
     223    }
     224    if (detections->newSources) {
     225        psphotMaskCosmicRayFootprintCheck(detections->newSources);
     226    }
     227
     228    return true;
     229}
     230
     231// this function is currently only called by psphotCheckExtSources
     232bool psphotSourceStatsUpdate (psArray *sources, pmConfig *config, pmReadout *readout) {
     233
     234    bool status = false;
     235
     236    psTimerStart ("psphot.stats");
     237
     238    // select the appropriate recipe information
     239    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     240    assert (recipe);
     241
     242    // determine the number of allowed threads
     243    int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads
     244    if (!status) {
     245        nThreads = 0;
     246    }
     247
     248    // determine properties (sky, moments) of initial sources
     249    float OUTER    = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS");
     250    if (!status) return false;
     251
     252    OUTER = PS_MAX(OUTER, 20.0); // XXX Guarantee that we can encompass the max moments radius
     253
     254    char *breakPt  = psMetadataLookupStr (&status, recipe, "BREAK_POINT");
     255    if (!status) return false;
     256
     257    for (int i = 0; i < sources->n; i++) {
     258
     259        pmSource *source = sources->data[i];
     260        if (!source->peak) continue; // XXX how can we have a peak-less source?
     261
     262        // allocate space for moments
     263        if (!source->moments) {
     264            source->moments = pmMomentsAlloc();
     265        }
     266
     267        // allocate image, weight, mask arrays for each peak (square of radius OUTER)
     268        pmSourceDefinePixels (source, readout, source->peak->x, source->peak->y, OUTER);
     269        source->peak->assigned = true;
    60270    }
    61271
     
    67277    }
    68278
    69     if (setWindow) {
    70         if (!psphotSetMomentsWindow(recipe, readout->analysis, sources)) {
    71             psError(PS_ERR_UNEXPECTED_NULL, false, "Failed to determine Moments Window!");
    72             return NULL;
    73         }
     279    // XXX how else could we get the window size in?
     280    if (!psphotSetMomentsWindow(recipe, readout->analysis, sources)) {
     281        psError(PS_ERR_UNEXPECTED_NULL, false, "Failed to determine Moments Window!");
     282        return NULL;
    74283    }
    75284
     
    94303            psThreadJob *job = psThreadJobAlloc ("PSPHOT_SOURCE_STATS");
    95304
     305            // XXX: this must match the above
    96306            psArrayAdd(job->args, 1, cells->data[j]); // sources
    97307            psArrayAdd(job->args, 1, recipe);
     
    141351}
    142352
    143 bool psphotSourceStatsUpdate (psArray *sources, pmConfig *config, pmReadout *readout) {
    144 
    145     bool status = false;
    146 
    147     psTimerStart ("psphot.stats");
    148 
    149     // select the appropriate recipe information
    150     psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
    151     assert (recipe);
    152 
    153     // determine the number of allowed threads
    154     int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads
    155     if (!status) {
    156         nThreads = 0;
    157     }
    158 
    159     // determine properties (sky, moments) of initial sources
    160     float OUTER    = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS");
    161     if (!status) return NULL;
    162 
    163     OUTER = PS_MAX(OUTER, 20.0); // XXX Guarantee that we can encompass the max moments radius
    164 
    165     char *breakPt  = psMetadataLookupStr (&status, recipe, "BREAK_POINT");
    166     if (!status) return NULL;
    167 
    168     for (int i = 0; i < sources->n; i++) {
    169 
    170         pmSource *source = sources->data[i];
    171         if (!source->peak) continue; // XXX how can we have a peak-less source?
    172 
    173         // allocate space for moments
    174         if (!source->moments) {
    175             source->moments = pmMomentsAlloc();
    176         }
    177 
    178         // allocate image, weight, mask arrays for each peak (square of radius OUTER)
    179         pmSourceDefinePixels (source, readout, source->peak->x, source->peak->y, OUTER);
    180         source->peak->assigned = true;
    181     }
    182 
    183     if (!strcasecmp (breakPt, "PEAKS")) {
    184         psLogMsg ("psphot", PS_LOG_INFO, "%ld sources : %f sec\n", sources->n, psTimerMark ("psphot.stats"));
    185         psLogMsg ("psphot", PS_LOG_INFO, "break point PEAKS, skipping MOMENTS\n");
    186         psphotVisualShowMoments (sources);
    187         return sources;
    188     }
    189 
    190     // XXX how else could we get the window size in?
    191     if (!psphotSetMomentsWindow(recipe, readout->analysis, sources)) {
    192         psError(PS_ERR_UNEXPECTED_NULL, false, "Failed to determine Moments Window!");
    193         return NULL;
    194     }
    195 
    196     // threaded measurement of the source magnitudes
    197     int Nfail = 0;
    198     int Nmoments = 0;
    199     int Nfaint = 0;
    200 
    201     // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts)
    202     int Cx = 1, Cy = 1;
    203     psphotChooseCellSizes (&Cx, &Cy, readout, nThreads);
    204 
    205     psArray *cellGroups = psphotAssignSources (Cx, Cy, sources);
    206 
    207     for (int i = 0; i < cellGroups->n; i++) {
    208 
    209         psArray *cells = cellGroups->data[i];
    210 
    211         for (int j = 0; j < cells->n; j++) {
    212 
    213             // allocate a job -- if threads are not defined, this just runs the job
    214             psThreadJob *job = psThreadJobAlloc ("PSPHOT_SOURCE_STATS");
    215 
    216             psArrayAdd(job->args, 1, cells->data[j]); // sources
    217             psArrayAdd(job->args, 1, recipe);
    218             PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nmoments
    219             PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfail
    220             PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfaint
    221 
    222             if (!psThreadJobAddPending(job)) {
    223                 psError(PS_ERR_UNKNOWN, false, "Unable to launch thread job PSPHOT_SOURCE_STATS");
    224                 psFree (job);
    225                 return NULL;
    226             }
    227             psFree(job);
    228         }
    229 
    230         // wait for the threads to finish and manage results
    231         if (!psThreadPoolWait (false)) {
    232             psError(PS_ERR_UNKNOWN, false, "Failure in thread job PSPHOT_SOURCE_STATS");
    233             return NULL;
    234         }
    235 
    236         // we have only supplied one type of job, so we can assume the types here
    237         psThreadJob *job = NULL;
    238         while ((job = psThreadJobGetDone()) != NULL) {
    239             if (job->args->n < 1) {
    240                 fprintf (stderr, "error with job\n");
    241             } else {
    242                 psScalar *scalar = NULL;
    243                 scalar = job->args->data[2];
    244                 Nmoments += scalar->data.S32;
    245                 scalar = job->args->data[3];
    246                 Nfail += scalar->data.S32;
    247                 scalar = job->args->data[4];
    248                 Nfaint += scalar->data.S32;
    249             }
    250             psFree(job);
    251         }
    252     }
    253 
    254     psFree (cellGroups);
    255 
    256     psLogMsg ("psphot", PS_LOG_INFO, "%ld sources, %d moments, %d faint, %d failed: %f sec\n", sources->n, Nmoments, Nfaint, Nfail, psTimerMark ("psphot.stats"));
    257 
    258     psphotVisualShowMoments (sources);
    259 
    260     return (sources);
    261 }
    262 
    263353bool psphotSourceStats_Threaded (psThreadJob *job) {
    264354
     
    268358
    269359    psArray *sources                = job->args->data[0];
    270     psMetadata *recipe              = job->args->data[1];
    271 
    272     float INNER        = psMetadataLookupF32 (&status, recipe, "SKY_INNER_RADIUS");
    273     if (!status) return false;
    274     float MIN_SN       = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN");
    275     if (!status) return false;
    276     float RADIUS       = psMetadataLookupF32 (&status, recipe, "PSF_MOMENTS_RADIUS");
    277     if (!status) return false;
    278     float SIGMA        = psMetadataLookupF32 (&status, recipe, "MOMENTS_GAUSS_SIGMA");
    279     if (!status) return false;
    280 
    281     // bit-masks to test for good/bad pixels
    282     psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT");
    283     assert (maskVal);
    284 
    285     // bit-mask to mark pixels not used in analysis
    286     psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT");
    287     assert (markVal);
     360
     361    float INNER                     = PS_SCALAR_VALUE(job->args->data[1],F32);
     362    float MIN_SN                    = PS_SCALAR_VALUE(job->args->data[2],F32);
     363    float RADIUS                    = PS_SCALAR_VALUE(job->args->data[3],F32);
     364    float SIGMA                     = PS_SCALAR_VALUE(job->args->data[4],F32);
     365
     366    psImageMaskType maskVal         = PS_SCALAR_VALUE(job->args->data[5],PS_TYPE_IMAGE_MASK_DATA);
     367    psImageMaskType markVal         = PS_SCALAR_VALUE(job->args->data[6],PS_TYPE_IMAGE_MASK_DATA);
    288368
    289369    // maskVal is used to test for rejected pixels, and must include markVal
     
    349429
    350430    // change the value of a scalar on the array (wrap this and put it in psArray.h)
    351     scalar = job->args->data[2];
     431    scalar = job->args->data[7];
    352432    scalar->data.S32 = Nmoments;
    353433
    354     scalar = job->args->data[3];
     434    scalar = job->args->data[8];
    355435    scalar->data.S32 = Nfail;
    356436
    357     scalar = job->args->data[4];
     437    scalar = job->args->data[9];
    358438    scalar->data.S32 = Nfaint;
    359439
     
    367447    bool status;
    368448
    369     float MIN_SN = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN");
    370     if (!status) return false;
     449    float MIN_SN = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN"); psAssert (status, "missing MOMENTS_SN_MIN");
     450    float PSF_SN_LIM = psMetadataLookupF32(&status, recipe, "PSF_SN_LIM"); psAssert (status, "missing PSF_SN_LIM");
     451    psF32 MOMENTS_AR_MAX = psMetadataLookupF32(&status, recipe, "MOMENTS_AR_MAX"); psAssert (status, "missing MOMENTS_AR_MAX");
    371452
    372453    // XXX move this to a config file?
     
    398479
    399480        // choose a grid scale that is a fixed fraction of the psf sigma^2
    400         psMetadataAddF32(recipe, PS_LIST_TAIL, "PSF_CLUMP_GRID_SCALE", PS_META_REPLACE, "clump grid", 0.1*PS_SQR(sigma[i]));
    401         psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_SX_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(sigma[i]));
    402         psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_SY_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(sigma[i]));
     481        float PSF_CLUMP_GRID_SCALE = 0.1*PS_SQR(sigma[i]);
     482        float MOMENTS_SX_MAX = 2.0*PS_SQR(sigma[i]);
     483        float MOMENTS_SY_MAX = 2.0*PS_SQR(sigma[i]);
    403484
    404485        // determine the PSF parameters from the source moment values
    405         pmPSFClump psfClump = pmSourcePSFClump (NULL, sources, recipe);
     486        pmPSFClump psfClump = pmSourcePSFClump (NULL, NULL, sources, PSF_SN_LIM, PSF_CLUMP_GRID_SCALE, MOMENTS_SX_MAX, MOMENTS_SY_MAX, MOMENTS_AR_MAX);
    406487        psLogMsg ("psphot", 3, "radius %.1f, nStars: %d, nSigma: %5.2f, X,  Y: %f, %f (%f, %f)\n", sigma[i], psfClump.nStars, psfClump.nSigma, psfClump.X, psfClump.Y, sqrt(psfClump.X) / sigma[i], sqrt(psfClump.Y) / sigma[i]);
    407488
     
    442523
    443524    // choose a grid scale that is a fixed fraction of the psf sigma^2
    444     psMetadataAddF32(recipe, PS_LIST_TAIL, "PSF_CLUMP_GRID_SCALE", PS_META_REPLACE, "clump grid", 0.1*PS_SQR(Sigma));
    445     psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_SX_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(Sigma));
    446     psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_SY_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(Sigma));
    447     psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_GAUSS_SIGMA", PS_META_REPLACE, "moments limit", Sigma);
    448     psMetadataAddF32(recipe, PS_LIST_TAIL, "PSF_MOMENTS_RADIUS", PS_META_REPLACE, "moments limit", 4.0*Sigma);
     525    psMetadataAddF32(analysis, PS_LIST_TAIL, "PSF_CLUMP_GRID_SCALE", PS_META_REPLACE, "clump grid", 0.1*PS_SQR(Sigma));
     526    psMetadataAddF32(analysis, PS_LIST_TAIL, "MOMENTS_SX_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(Sigma));
     527    psMetadataAddF32(analysis, PS_LIST_TAIL, "MOMENTS_SY_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(Sigma));
     528    psMetadataAddF32(analysis, PS_LIST_TAIL, "MOMENTS_GAUSS_SIGMA", PS_META_REPLACE, "moments limit", Sigma);
     529    psMetadataAddF32(analysis, PS_LIST_TAIL, "PSF_MOMENTS_RADIUS", PS_META_REPLACE, "moments limit", 4.0*Sigma);
    449530
    450531    psLogMsg ("psphot", 3, "using window function with sigma = %f\n", Sigma);
    451532    return true;
    452533}
     534
     535// if we use the footprints, the output peaks list contains both old and new peaks,
     536// otherwise it only contains the new peaks.
     537
Note: See TracChangeset for help on using the changeset viewer.