IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 17, 2009, 10:00:02 AM (17 years ago)
Author:
Paul Price
Message:

Reorganising ppStackLoop: splitting into multiple separate functions which are joined using a common data carrier, ppStackOptions (which aren't really 'options', but that's the word I chose...).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ppStack/src/ppStackPhotometry.c

    r23259 r23341  
    99
    1010#include "ppStack.h"
     11#include "ppStackLoop.h"
    1112
    12 #define PHOT_SOURCE_MASK (PM_SOURCE_MODE_FAIL | PM_SOURCE_MODE_SATSTAR | PM_SOURCE_MODE_BLEND | \
    13                           PM_SOURCE_MODE_BADPSF | PM_SOURCE_MODE_DEFECT | PM_SOURCE_MODE_SATURATED | \
    14                           PM_SOURCE_MODE_CR_LIMIT | PM_SOURCE_MODE_EXT_LIMIT) // Mask to apply to sources
    15 
    16 bool ppStackInputPhotometry(const pmReadout *ro, const psArray *sources, const pmConfig *config)
     13bool ppStackPhotometry(ppStackOptions *options, pmConfig *config)
    1714{
    18     PM_ASSERT_READOUT_NON_NULL(ro, false);
    19     PS_ASSERT_ARRAY_NON_NULL(sources, false);
     15    psAssert(options, "Require options");
     16    psAssert(config, "Require configuration");
    2017
    2118    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe
     
    2320
    2421    bool mdok;                          // Status of MD lookup
    25 
    26     float zpRadius = psMetadataLookupS32(&mdok, recipe, "PHOT.RADIUS"); // Radius for PHOT measurement
    27     if (!mdok) {
    28         psError(PS_ERR_UNKNOWN, true, "Unable to find PHOT.RADIUS in recipe");
    29         return false;
    30     }
    31     float zpSigma = psMetadataLookupF32(&mdok, recipe, "PHOT.SIGMA"); // Gaussian sigma for photometry
    32     if (!mdok) {
    33         psError(PS_ERR_UNKNOWN, true, "Unable to find PHOT.SIGMA in recipe");
    34         return false;
    35     }
    36     float zpFrac = psMetadataLookupF32(&mdok, recipe, "PHOT.FRAC"); // Fraction of good pixels for photometry
    37     if (!mdok) {
    38         psError(PS_ERR_UNKNOWN, true, "Unable to find PHOT.FRAC in recipe");
    39         return false;
     22    if (!psMetadataLookupBool(&mdok, recipe, "PHOTOMETRY")) {
     23        // Nothing to do
     24        return true;
    4025    }
    4126
    42     psString maskValStr = psMetadataLookupStr(&mdok, recipe, "MASK.VAL"); // Name of bits to mask going in
    43     if (!mdok || !maskValStr) {
    44         psError(PS_ERR_UNKNOWN, false, "Unable to find MASK.VAL in recipe");
    45         return false;
    46     }
    47     psImageMaskType maskVal = pmConfigMaskGet(maskValStr, config); // Bits to mask
     27    psTimerStart("PPSTACK_PHOT");
    4828
    49     psImage *image = ro->image, *mask = ro->mask; // Image and mask from readout
     29    ppStackFileActivation(config, PPSTACK_FILES_COMBINE, false);
     30    ppStackFileActivation(config, PPSTACK_FILES_PHOT, true);
     31    pmFPAview *photView = ppStackFilesIterateDown(config); // View to readout
     32    ppStackFileActivation(config, PPSTACK_FILES_COMBINE, true);
    5033
    51     // Measure background
    52     psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator
    53     psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics
    54     if (!psImageBackground(stats, NULL, image, mask, maskVal, rng)) {
    55         psError(PS_ERR_UNKNOWN, false, "Unable to measure background for image");
    56         psFree(stats);
    57         psFree(rng);
    58         return false;
    59     }
    60     float bg = stats->robustMedian; // Background level
    61     psFree(stats);
    62     psFree(rng);
    63 
    64     // Photometer sources
    65     int numCols = image->numCols, numRows = image->numRows; // Size of image
    66     int numSources = sources->n; // Number of sources
    67     int numGood = 0;            // Number of good sources
    68     float maxMag = -INFINITY;   // Maximum magnitude
    69     for (int j = 0; j < numSources; j++) {
    70         pmSource *source = sources->data[j]; // Source of interest
    71         if (source->mode & PHOT_SOURCE_MASK || !isfinite(source->psfMag)) {
    72             source->psfMag = NAN;
    73             continue;
    74         }
    75         float x = source->peak->xf, y = source->peak->yf; // Coordinates of source
    76         int xCentral = x + 0.5, yCentral = y + 0.5; // Central pixel
    77         // Range of integration
    78         int xMin = PS_MAX(0, xCentral - zpRadius), xMax = PS_MIN(numCols - 1, xCentral + zpRadius);
    79         int yMin = PS_MAX(0, yCentral - zpRadius), yMax = PS_MIN(numRows - 1, yCentral + zpRadius);
    80 
    81         // Integrate
    82         double sumImage = 0.0, sumKernel = 0.0; // Sums from integration
    83         int numBadPix = 0;         // Number of bad pixels
    84         for (int v = yMin; v <= yMax; v++) {
    85             float dy2 = PS_SQR(y - v); // Distance from centroid
    86             for (int u = xMin; u <= xMax; u++) {
    87                 if (mask->data.PS_TYPE_IMAGE_MASK_DATA[v][u] & maskVal) {
    88                     numBadPix++;
    89                     continue;
    90                 }
    91                 float dx2 = PS_SQR(x - u); // Distance from centroid
    92                 double kernel = exp(-0.5 * (dx2 + dy2) / PS_SQR(zpSigma)); // Kernel value
    93                 sumImage += (image->data.F32[v][u] - bg) * kernel;
    94                 sumKernel += kernel;
    95             }
    96         }
    97 
    98         if (numBadPix > zpFrac * M_PI * PS_SQR(zpRadius) || !isfinite(sumImage)) {
    99             source->psfMag = NAN;
    100         } else {
    101             source->psfMag = - 2.5 * log10(sumImage / sumKernel * M_PI * PS_SQR(zpRadius));
    102             if (isfinite(source->psfMag)) {
    103                 numGood++;
    104                 maxMag = PS_MAX(maxMag, source->psfMag);
    105             }
    106         }
    107     }
    108     psLogMsg("ppStack", PS_LOG_INFO, "Photometered %d good sources in image; max mag %f", numGood, maxMag);
    109 
    110     return true;
    111 }
    112 
    113 
    114 
    115 bool ppStackPhotometry(pmConfig *config, const pmReadout *readout, const pmFPAview *view)
    116 {
    117     pmFPAfile *photFile = psMetadataLookupPtr(NULL, config->files, "PSPHOT.INPUT");
    118     pmFPACopy(photFile->fpa, readout->parent->parent->parent);
     34    pmFPAfile *photFile = psMetadataLookupPtr(NULL, config->files, "PSPHOT.INPUT"); // File for photometry
     35    pmFPACopy(photFile->fpa, options->outRO->parent->parent->parent);
    11936
    12037    if (psMetadataLookupBool(NULL, config->arguments, "-visual")) {
     
    12239    }
    12340
     41#if 0
    12442    // Need to ensure aperture residual is not calculated
    12543    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PSPHOT_RECIPE); // Recipe
     
    13149        item->data.B = false;
    13250    }
     51#endif
    13352
    13453    // set maskValue and markValue in the psphot recipe
    13554    psImageMaskType maskValue = pmConfigMaskGet("BLANK", config); // Bits to mask
    13655    psImageMaskType markValue = pmConfigMaskGet("MARK.VALUE", config); // Bits to use for marking
    137     psMetadataAddImageMask (recipe, PS_LIST_TAIL, "MASK.PSPHOT", PS_META_REPLACE, "Bits to mask", maskValue);
    138     psMetadataAddImageMask (recipe, PS_LIST_TAIL, "MARK.PSPHOT", PS_META_REPLACE, "Bits to use for mark", markValue);
     56    psMetadataAddImageMask(recipe, PS_LIST_TAIL, "MASK.PSPHOT", PS_META_REPLACE,
     57                            "Bits to mask", maskValue);
     58    psMetadataAddImageMask(recipe, PS_LIST_TAIL, "MARK.PSPHOT", PS_META_REPLACE,
     59                           "Bits to use for mark", markValue);
    13960
    140     // XXX replace with psphotReadoutKnownSources (config, view)
    141     // XXX this function requires that we construct the input source list and place it on PSPHOT.INPUT.CMF
    142     pmCell *sourcesCell = pmFPAfileThisCell(config->files, view, "PPSTACK.OUTPUT");
    143     psArray *inSources = psMetadataLookupPtr (NULL, sourcesCell->analysis, "PSPHOT.SOURCES");
     61    pmCell *sourcesCell = pmFPAfileThisCell(config->files, photView, "PPSTACK.OUTPUT");
     62    psArray *inSources = psMetadataLookupPtr(NULL, sourcesCell->analysis, "PSPHOT.SOURCES");
    14463    if (!inSources) {
    14564        psError(PS_ERR_UNKNOWN, false, "Unable to find input sources");
     65        psFree(photView);
    14666        return false;
    14767    }
    14868
    149     if (!psphotReadoutKnownSources(config, view, inSources)) {
     69    if (!psphotReadoutKnownSources(config, photView, inSources)) {
    15070        // Clear the error, so that the output files are written.
    15171        psError(PS_ERR_UNKNOWN, false, "Unable to perform photometry on stacked image.");
     72        psFree(photView);
    15273        return false;
    15374    }
     75    psFree(photView);
    15476
    15577    if (!pmFPAfileDropInternal(config->files, "PSPHOT.BACKMDL") ||
     
    16284    pmFPAfileActivate(config->files, false, "PSPHOT.INPUT");
    16385
     86    if (options->stats) {
     87        pmReadout *photRO = pmFPAviewThisReadout(photView, photFile->fpa); // Readout with the sources
     88        psArray *sources = psMetadataLookupPtr(NULL, photRO->analysis, "PSPHOT.SOURCES"); // Sources
     89        psMetadataAddS32(options->stats, PS_LIST_TAIL, "NUM_SOURCES", 0,
     90                         "Number of sources detected", sources->n);
     91        psMetadataAddF32(options->stats, PS_LIST_TAIL, "TIME_PHOT", 0,
     92                         "Time to do photometry", psTimerMark("PPSTACK_PHOT"));
     93    }
     94    psLogMsg("ppStack", PS_LOG_INFO, "Time to do photometry: %f sec", psTimerClear("PPSTACK_PHOT"));
     95
    16496    return true;
    16597}
Note: See TracChangeset for help on using the changeset viewer.