Changeset 23341 for trunk/ppStack/src/ppStackPhotometry.c
- Timestamp:
- Mar 17, 2009, 10:00:02 AM (17 years ago)
- File:
-
- 1 edited
-
trunk/ppStack/src/ppStackPhotometry.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ppStack/src/ppStackPhotometry.c
r23259 r23341 9 9 10 10 #include "ppStack.h" 11 #include "ppStackLoop.h" 11 12 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) 13 bool ppStackPhotometry(ppStackOptions *options, pmConfig *config) 17 14 { 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"); 20 17 21 18 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe … … 23 20 24 21 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; 40 25 } 41 26 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"); 48 28 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); 50 33 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); 119 36 120 37 if (psMetadataLookupBool(NULL, config->arguments, "-visual")) { … … 122 39 } 123 40 41 #if 0 124 42 // Need to ensure aperture residual is not calculated 125 43 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PSPHOT_RECIPE); // Recipe … … 131 49 item->data.B = false; 132 50 } 51 #endif 133 52 134 53 // set maskValue and markValue in the psphot recipe 135 54 psImageMaskType maskValue = pmConfigMaskGet("BLANK", config); // Bits to mask 136 55 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); 139 60 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"); 144 63 if (!inSources) { 145 64 psError(PS_ERR_UNKNOWN, false, "Unable to find input sources"); 65 psFree(photView); 146 66 return false; 147 67 } 148 68 149 if (!psphotReadoutKnownSources(config, view, inSources)) {69 if (!psphotReadoutKnownSources(config, photView, inSources)) { 150 70 // Clear the error, so that the output files are written. 151 71 psError(PS_ERR_UNKNOWN, false, "Unable to perform photometry on stacked image."); 72 psFree(photView); 152 73 return false; 153 74 } 75 psFree(photView); 154 76 155 77 if (!pmFPAfileDropInternal(config->files, "PSPHOT.BACKMDL") || … … 162 84 pmFPAfileActivate(config->files, false, "PSPHOT.INPUT"); 163 85 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 164 96 return true; 165 97 }
Note:
See TracChangeset
for help on using the changeset viewer.
