Changeset 19235
- Timestamp:
- Aug 27, 2008, 9:48:44 AM (18 years ago)
- File:
-
- 1 edited
-
trunk/ppStack/src/ppStackMatch.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ppStack/src/ppStackMatch.c
r19231 r19235 15 15 PM_SOURCE_MODE_CR_LIMIT) // Mask to apply to input sources 16 16 17 //#define TESTING // Enable debugging output17 #define TESTING // Enable debugging output 18 18 19 19 … … 83 83 } 84 84 85 pmReadout *output = pmReadoutAlloc(NULL); // Output readout, for holding results temporarily 86 85 87 #ifdef TESTING 86 88 // Read previously produced kernel 87 static int numInput = 0; // Index of input file 89 static int numInput = -1; // Index of input file 90 numInput++; 88 91 if (psMetadataLookupBool(NULL, config->arguments, "PPSTACK.DEBUG.STACK")) { 89 92 const char *outName = psMetadataLookupStr(NULL, config->arguments, "OUTPUT"); // Output root … … 97 100 psFits *fits = psFitsOpen(resolved, "r"); // FITS file for subtraction kernel 98 101 psFree(resolved); 99 if (!fits || !pmReadoutReadSubtractionKernels( readout, fits)) {102 if (!fits || !pmReadoutReadSubtractionKernels(output, fits)) { 100 103 psError(PS_ERR_IO, false, "Unable to read previously produced kernel"); 101 104 psFitsClose(fits); 102 numInput++;103 105 return false; 104 106 } … … 115 117 psStringAppend(&weightName, "%s.%d.%s", outName, numInput, tempWeight); 116 118 117 if (!readImage(& readout->image, imageName, config) || !readImage(&readout->mask, maskName, config) ||118 !readImage(& readout->weight, weightName, config)) {119 if (!readImage(&output->image, imageName, config) || !readImage(&output->mask, maskName, config) || 120 !readImage(&output->weight, weightName, config)) { 119 121 psError(PS_ERR_IO, false, "Unable to read previously produced image."); 120 122 psFree(imageName); 121 123 psFree(maskName); 122 124 psFree(weightName); 123 numInput++;124 125 return false; 125 126 } … … 127 128 psFree(maskName); 128 129 psFree(weightName); 129 130 numInput++; 131 return true; 132 } 133 #endif 134 135 // Normal operations here 136 pmReadout *output = pmReadoutAlloc(NULL); // Output readout, for holding results temporarily 137 if (psMetadataLookupBool(&mdok, config->arguments, "HAVE.PSF")) { 138 assert(psf); 139 assert(sources); 140 141 int order = psMetadataLookupS32(NULL, ppsub, "SPATIAL.ORDER"); // Spatial polynomial order 142 float regionSize = psMetadataLookupF32(NULL, ppsub, "REGION.SIZE"); // Size of iso-kernel regs 143 float spacing = psMetadataLookupF32(NULL, ppsub, "STAMP.SPACING"); // Typical stamp spacing 144 int footprint = psMetadataLookupS32(NULL, ppsub, "STAMP.FOOTPRINT"); // Stamp half-size 145 float threshold = psMetadataLookupF32(NULL, ppsub, "STAMP.THRESHOLD"); // Threshold for stmps 146 int iter = psMetadataLookupS32(NULL, ppsub, "ITER"); // Rejection iterations 147 float rej = psMetadataLookupF32(NULL, ppsub, "REJ"); // Rejection threshold 148 pmSubtractionKernelsType type = pmSubtractionKernelsTypeFromString( 149 psMetadataLookupStr(NULL, ppsub, "KERNEL.TYPE")); // Kernel type 150 psVector *widths = psMetadataLookupPtr(NULL, ppsub, "ISIS.WIDTHS"); // ISIS Gaussian widths 151 psVector *orders = psMetadataLookupPtr(NULL, ppsub, "ISIS.ORDERS"); // ISIS Polynomial orders 152 int inner = psMetadataLookupS32(NULL, ppsub, "INNER"); // Inner radius 153 int ringsOrder = psMetadataLookupS32(NULL, ppsub, "RINGS.ORDER"); // RINGS polynomial order 154 int binning = psMetadataLookupS32(NULL, ppsub, "SPAM.BINNING"); // Binning for SPAM kernel 155 float badFrac = psMetadataLookupF32(NULL, ppsub, "BADFRAC"); // Maximum bad fraction 156 bool optimum = psMetadataLookupBool(&mdok, ppsub, "OPTIMUM"); // Derive optimum parameters? 157 float optMin = psMetadataLookupF32(&mdok, ppsub, "OPTIMUM.MIN"); // Minimum width for search 158 float optMax = psMetadataLookupF32(&mdok, ppsub, "OPTIMUM.MAX"); // Maximum width for search 159 float optStep = psMetadataLookupF32(&mdok, ppsub, "OPTIMUM.STEP"); // Step for search 160 float optThresh = psMetadataLookupF32(&mdok, ppsub, "OPTIMUM.TOL"); // Tolerance for search 161 int optOrder = psMetadataLookupS32(&mdok, ppsub, "OPTIMUM.ORDER"); // Order for search 162 float poorFrac = psMetadataLookupF32(&mdok, ppsub, "POOR.FRACTION"); // Fraction for "poor" 163 164 // These values are specified specifically for stacking 165 const char *stampsName = psMetadataLookupStr(NULL, config->arguments, "STAMPS"); // Stamps filename 166 167 psVector *optWidths = NULL; // Vector with FWHMs for optimum search 168 if (optimum) { 169 optWidths = psVectorCreate(optWidths, optMin, optMax, optStep, PS_TYPE_F32); 170 } 171 172 float minFlux = INFINITY; // Minimum flux for fake image 173 { 174 psStats *bg = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics for bg 175 if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal, rng)) { 176 psWarning("Can't measure background for image."); 177 psErrorClear(); 178 } else { 179 minFlux = 0.1 * bg->robustStdev; 180 } 181 psFree(bg); 182 } 183 184 // Generate a fake image to match to 185 if (!isfinite(minFlux)) { 186 float maxMag = -INFINITY; // Maximum magnitude of sources 187 for (int i = 0; i < sources->n; i++) { 188 pmSource *source = sources->data[i]; // Source of interest 189 if (source->psfMag > maxMag && source->psfMag <= MAG_IGNORE && 190 !(source->mode & SOURCE_MASK)) { 191 maxMag = source->psfMag; 130 } else { 131 #endif 132 133 // Normal operations here 134 if (psMetadataLookupBool(&mdok, config->arguments, "HAVE.PSF")) { 135 assert(psf); 136 assert(sources); 137 138 int order = psMetadataLookupS32(NULL, ppsub, "SPATIAL.ORDER"); // Spatial polynomial order 139 float regionSize = psMetadataLookupF32(NULL, ppsub, "REGION.SIZE"); // Size of iso-kernel regs 140 float spacing = psMetadataLookupF32(NULL, ppsub, "STAMP.SPACING"); // Typical stamp spacing 141 int footprint = psMetadataLookupS32(NULL, ppsub, "STAMP.FOOTPRINT"); // Stamp half-size 142 float threshold = psMetadataLookupF32(NULL, ppsub, "STAMP.THRESHOLD"); // Threshold for stmps 143 int iter = psMetadataLookupS32(NULL, ppsub, "ITER"); // Rejection iterations 144 float rej = psMetadataLookupF32(NULL, ppsub, "REJ"); // Rejection threshold 145 pmSubtractionKernelsType type = pmSubtractionKernelsTypeFromString( 146 psMetadataLookupStr(NULL, ppsub, "KERNEL.TYPE")); // Kernel type 147 psVector *widths = psMetadataLookupPtr(NULL, ppsub, "ISIS.WIDTHS"); // ISIS Gaussian widths 148 psVector *orders = psMetadataLookupPtr(NULL, ppsub, "ISIS.ORDERS"); // ISIS Polynomial orders 149 int inner = psMetadataLookupS32(NULL, ppsub, "INNER"); // Inner radius 150 int ringsOrder = psMetadataLookupS32(NULL, ppsub, "RINGS.ORDER"); // RINGS polynomial order 151 int binning = psMetadataLookupS32(NULL, ppsub, "SPAM.BINNING"); // Binning for SPAM kernel 152 float badFrac = psMetadataLookupF32(NULL, ppsub, "BADFRAC"); // Maximum bad fraction 153 bool optimum = psMetadataLookupBool(&mdok, ppsub, "OPTIMUM"); // Derive optimum parameters? 154 float optMin = psMetadataLookupF32(&mdok, ppsub, "OPTIMUM.MIN"); // Minimum width for search 155 float optMax = psMetadataLookupF32(&mdok, ppsub, "OPTIMUM.MAX"); // Maximum width for search 156 float optStep = psMetadataLookupF32(&mdok, ppsub, "OPTIMUM.STEP"); // Step for search 157 float optThresh = psMetadataLookupF32(&mdok, ppsub, "OPTIMUM.TOL"); // Tolerance for search 158 int optOrder = psMetadataLookupS32(&mdok, ppsub, "OPTIMUM.ORDER"); // Order for search 159 float poorFrac = psMetadataLookupF32(&mdok, ppsub, "POOR.FRACTION"); // Fraction for "poor" 160 161 // These values are specified specifically for stacking 162 const char *stampsName = psMetadataLookupStr(NULL, config->arguments, "STAMPS"); // Stamps filename 163 164 psVector *optWidths = NULL; // Vector with FWHMs for optimum search 165 if (optimum) { 166 optWidths = psVectorCreate(optWidths, optMin, optMax, optStep, PS_TYPE_F32); 167 } 168 169 float minFlux = INFINITY; // Minimum flux for fake image 170 { 171 psStats *bg = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics for bg 172 if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal, rng)) { 173 psWarning("Can't measure background for image."); 174 psErrorClear(); 175 } else { 176 minFlux = 0.1 * bg->robustStdev; 192 177 } 193 } 194 minFlux = 0.01 * powf(10.0, -0.4 * maxMag); 195 } 196 197 pmReadout *fake = pmReadoutAlloc(NULL); // Fake readout with target PSF 198 199 if (!pmReadoutFakeFromSources(fake, readout->image->numCols, readout->image->numRows, sources, 200 NULL, NULL, psf, minFlux, 0, false)) { 201 psError(PS_ERR_UNKNOWN, false, "Unable to generate fake image with target PSF."); 178 psFree(bg); 179 } 180 181 // Generate a fake image to match to 182 if (!isfinite(minFlux)) { 183 float maxMag = -INFINITY; // Maximum magnitude of sources 184 for (int i = 0; i < sources->n; i++) { 185 pmSource *source = sources->data[i]; // Source of interest 186 if (source->psfMag > maxMag && source->psfMag <= MAG_IGNORE && 187 !(source->mode & SOURCE_MASK)) { 188 maxMag = source->psfMag; 189 } 190 } 191 minFlux = 0.01 * powf(10.0, -0.4 * maxMag); 192 } 193 194 pmReadout *fake = pmReadoutAlloc(NULL); // Fake readout with target PSF 195 196 if (!pmReadoutFakeFromSources(fake, readout->image->numCols, readout->image->numRows, sources, 197 NULL, NULL, psf, minFlux, 0, false)) { 198 psError(PS_ERR_UNKNOWN, false, "Unable to generate fake image with target PSF."); 199 psFree(fake); 200 psFree(optWidths); 201 psFree(output); 202 return false; 203 } 204 205 #ifdef TESTING 206 { 207 psFits *fits = psFitsOpen("fake.fits", "w"); 208 psFitsWriteImage(fits, NULL, fake->image, 0, NULL); 209 psFitsClose(fits); 210 } 211 #endif 212 213 if (threads > 0) { 214 pmSubtractionThreadsInit(output, NULL, readout, fake); 215 } 216 217 // Do the image matching 218 if (!pmSubtractionMatch(output, NULL, readout, fake, footprint, regionSize, spacing, threshold, 219 sources, stampsName, type, size, order, widths, orders, inner, ringsOrder, 220 binning, penalty, optimum, optWidths, optOrder, optThresh, iter, rej, 221 maskVal, maskBad, maskPoor, poorFrac, badFrac, PM_SUBTRACTION_MODE_1)) { 222 psError(PS_ERR_UNKNOWN, false, "Unable to match images."); 223 psFree(fake); 224 psFree(optWidths); 225 psFree(output); 226 return false; 227 } 202 228 psFree(fake); 203 229 psFree(optWidths); 204 psFree(output); 205 return false; 230 231 if (threads > 0) { 232 pmSubtractionThreadsFinalize(output, NULL, readout, fake); 233 } 234 235 // Set the variance factor 236 psMetadataItem *vfItem = psMetadataLookup(readout->parent->concepts, "CELL.VARFACTOR"); 237 float vf = psMetadataLookupF32(NULL, output->analysis, PM_SUBTRACTION_ANALYSIS_VARFACTOR); 238 if (!isfinite(vf)) { 239 vf = 1.0; 240 } 241 if (isfinite(vfItem->data.F32)) { 242 vfItem->data.F32 *= vf; 243 } else { 244 vfItem->data.F32 = vf; 245 } 246 247 // Replace original images with convolved 248 psFree(readout->image); 249 psFree(readout->mask); 250 psFree(readout->weight); 251 readout->image = psMemIncrRefCounter(output->image); 252 readout->mask = psMemIncrRefCounter(output->mask); 253 readout->weight = psMemIncrRefCounter(output->weight); 254 } else { 255 // Fake the convolution 256 psRegion *region = psRegionAlloc(0, readout->image->numCols - 1, 0, readout->image->numRows - 1); 257 psMetadataAddPtr(output->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_REGION, 258 PS_DATA_REGION | PS_META_DUPLICATE_OK, "Fake subtraction region", region); 259 psFree(region); 260 pmSubtractionKernels *kernels = pmSubtractionKernelsPOIS(FAKE_SIZE, 0, penalty, 261 PM_SUBTRACTION_MODE_1); 262 // Set solution to delta function 263 kernels->solution1 = psVectorAlloc(kernels->num + 2, PS_TYPE_F64); 264 psVectorInit(kernels->solution1, 0.0); 265 int normIndex = PM_SUBTRACTION_INDEX_NORM(kernels); // Index for normalisation 266 kernels->solution1->data.F64[normIndex] = 1.0; 267 psMetadataAddPtr(output->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_KERNEL, 268 PS_DATA_UNKNOWN | PS_META_DUPLICATE_OK, "Fake subtraction kernel", kernels); 269 psFree(kernels); 206 270 } 207 271 208 272 #ifdef TESTING 273 // Write convolution kernel 209 274 { 210 psFits *fits = psFitsOpen("fake.fits", "w"); 211 psFitsWriteImage(fits, NULL, fake->image, 0, NULL); 275 const char *outName = psMetadataLookupStr(NULL, config->arguments, "OUTPUT"); // Output root 276 assert(outName); 277 278 psString filename = NULL; // Output filename 279 psStringAppend(&filename, "%s.%d.kernel", outName, numInput); 280 psString resolved = pmConfigConvertFilename(filename, config, true, false); // Resolved filename 281 psFree(filename); 282 psFits *fits = psFitsOpen(resolved, "w"); // FITS file for subtraction kernel 283 psFree(resolved); 284 pmReadoutWriteSubtractionKernels(output, fits); 212 285 psFitsClose(fits); 213 286 } 214 #endif215 216 if (threads > 0) {217 pmSubtractionThreadsInit(output, NULL, readout, fake);218 }219 220 // Do the image matching221 if (!pmSubtractionMatch(output, NULL, readout, fake, footprint, regionSize, spacing, threshold,222 sources, stampsName, type, size, order, widths, orders, inner, ringsOrder,223 binning, penalty, optimum, optWidths, optOrder, optThresh, iter, rej,224 maskVal, maskBad, maskPoor, poorFrac, badFrac, PM_SUBTRACTION_MODE_1)) {225 psError(PS_ERR_UNKNOWN, false, "Unable to match images.");226 psFree(fake);227 psFree(optWidths);228 psFree(output);229 return false;230 }231 psFree(fake);232 psFree(optWidths);233 234 if (threads > 0) {235 pmSubtractionThreadsFinalize(output, NULL, readout, fake);236 }237 238 // Set the variance factor239 psMetadataItem *vfItem = psMetadataLookup(readout->parent->concepts, "CELL.VARFACTOR");240 float vf = psMetadataLookupF32(NULL, output->analysis, PM_SUBTRACTION_ANALYSIS_VARFACTOR);241 if (!isfinite(vf)) {242 vf = 1.0;243 }244 if (isfinite(vfItem->data.F32)) {245 vfItem->data.F32 *= vf;246 } else {247 vfItem->data.F32 = vf;248 }249 250 // Replace original images with convolved251 psFree(readout->image);252 psFree(readout->mask);253 psFree(readout->weight);254 readout->image = psMemIncrRefCounter(output->image);255 readout->mask = psMemIncrRefCounter(output->mask);256 readout->weight = psMemIncrRefCounter(output->weight);257 } else {258 // Fake the convolution259 psRegion *region = psRegionAlloc(0, readout->image->numCols - 1, 0, readout->image->numRows - 1);260 psMetadataAddPtr(output->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_REGION,261 PS_DATA_REGION | PS_META_DUPLICATE_OK, "Fake subtraction region", region);262 psFree(region);263 pmSubtractionKernels *kernels = pmSubtractionKernelsPOIS(FAKE_SIZE, 0, penalty,264 PM_SUBTRACTION_MODE_1);265 // Set solution to delta function266 kernels->solution1 = psVectorAlloc(kernels->num + 2, PS_TYPE_F64);267 psVectorInit(kernels->solution1, 0.0);268 int normIndex = PM_SUBTRACTION_INDEX_NORM(kernels); // Index for normalisation269 kernels->solution1->data.F64[normIndex] = 1.0;270 psMetadataAddPtr(output->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_KERNEL,271 PS_DATA_UNKNOWN | PS_META_DUPLICATE_OK, "Fake subtraction kernel", kernels);272 psFree(kernels);273 }274 275 #ifdef TESTING276 {277 psString filename = NULL; // Output filename278 psStringAppend(&filename, "stack_kernel_%d.fits", numInput);279 psFits *fits = psFitsOpen(filename, "w"); // FITS file for subtraction kernel280 psFree(filename);281 pmReadoutWriteSubtractionKernels(output, fits);282 psFitsClose(fits);283 287 } 284 288 #endif
Note:
See TracChangeset
for help on using the changeset viewer.
