IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Oct 27, 2008, 4:27:35 PM (18 years ago)
Author:
Paul Price
Message:

Adding function to re-do photometry of input sources

File:
1 edited

Legend:

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

    r18612 r20427  
    99
    1010#include "ppStack.h"
     11
     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
     16bool ppStackInputPhotometry(const pmReadout *ro, const psArray *sources, const pmConfig *config)
     17{
     18    PM_ASSERT_READOUT_NON_NULL(ro, false);
     19    PS_ASSERT_ARRAY_NON_NULL(sources, false);
     20
     21    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe
     22    psAssert(recipe, "We've thrown an error on this before.");
     23
     24    bool mdok;                          // Status of MD lookup
     25
     26    float zpRadius = psMetadataLookupS32(&mdok, recipe, "ZP.RADIUS"); // Radius for ZP measurement
     27    if (!mdok) {
     28        psError(PS_ERR_UNKNOWN, true, "Unable to find ZP.RADIUS in recipe");
     29        return false;
     30    }
     31    float zpSigma = psMetadataLookupF32(&mdok, recipe, "ZP.SIGMA"); // Gaussian sigma for photometry
     32    if (!mdok) {
     33        psError(PS_ERR_UNKNOWN, true, "Unable to find ZP.SIGMA in recipe");
     34        return false;
     35    }
     36    float zpFrac = psMetadataLookupF32(&mdok, recipe, "ZP.FRAC"); // Fraction of good pixels for photometry
     37    if (!mdok) {
     38        psError(PS_ERR_UNKNOWN, true, "Unable to find ZP.FRAC in recipe");
     39        return false;
     40    }
     41
     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    psMaskType maskVal = pmConfigMaskGet(maskValStr, config); // Bits to mask
     48
     49    psImage *image = ro->image, *mask = ro->mask; // Image and mask from readout
     50
     51    // Measure background
     52    psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS, 0); // 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_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            numGood++;
     103            maxMag = PS_MAX(maxMag, source->psfMag);
     104        }
     105    }
     106    psLogMsg("ppStack", PS_LOG_INFO, "Photometered %d good sources in image; max mag %f", numGood, maxMag);
     107
     108    return true;
     109}
     110
     111
    11112
    12113bool ppStackPhotometry(pmConfig *config, const pmReadout *readout, const pmFPAview *view)
Note: See TracChangeset for help on using the changeset viewer.