Changeset 23573
- Timestamp:
- Mar 27, 2009, 11:49:17 AM (17 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
-
ippconfig/recipes/ppStack.config (modified) (1 diff)
-
ppStack/src/ppStack.h (modified) (3 diffs)
-
ppStack/src/ppStackCombineInitial.c (modified) (3 diffs)
-
ppStack/src/ppStackConvolve.c (modified) (5 diffs)
-
ppStack/src/ppStackMatch.c (modified) (15 diffs)
-
ppStack/src/ppStackOptions.c (modified) (3 diffs)
-
ppStack/src/ppStackOptions.h (modified) (2 diffs)
-
ppStack/src/ppStackPrepare.c (modified) (3 diffs)
-
ppStack/src/ppStackReject.c (modified) (3 diffs)
-
ppStack/src/ppStackSetup.c (modified) (3 diffs)
-
ppStack/src/ppStackSources.c (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ippconfig/recipes/ppStack.config
r23498 r23573 1 1 # Recipe configuration for ppStack (image combination) 2 2 3 CONVOLVE BOOL TRUE # Convolve images when stacking? 3 4 ITER S32 1 # Number of rejection iterations 4 5 COMBINE.REJ F32 3.0 # Rejection threshold in combination (sigma) -
trunk/ppStack/src/ppStack.h
r23341 r23573 7 7 #include <pslib.h> 8 8 #include <psmodules.h> 9 10 #include "ppStackOptions.h" 9 11 10 12 // Mask values for inputs … … 106 108 /// Convolve image to match specified seeing 107 109 bool ppStackMatch(pmReadout *readout, // Readout to be convolved; replaced with output 108 psArray **regions, // Array of regions used in each PSF matching, returned 109 psArray **kernels, // Array of kernels used in each PSF matching, returned 110 float *chi2, // Chi^2 from the stamps 111 float *weighting, // Stack weighting (1/noise^2) 112 psArray *sources, // Array of sources 113 const pmPSF *psf, // Target PSF 114 psRandom *rng, // Random number generator 110 ppStackOptions *options, // Options for stacking 111 int index, // Index of image to match 115 112 const pmConfig *config // Configuration 116 113 ); … … 120 117 /// 121 118 /// Corrects the source PSF photometry to a common system. Return the sum of the exposure times. 122 float ppStackSourcesTransparency(const psArray *sourceLists, // Sources for each input 123 psVector *inputMask, // Indicates bad input 124 const pmFPAview *view, // View to readout 125 const pmConfig *config // Configuration 119 bool ppStackSourcesTransparency(ppStackOptions *options, // Stacking options 120 const pmFPAview *view, // View to readout 121 const pmConfig *config // Configuration 126 122 ); 127 123 -
trunk/ppStack/src/ppStackCombineInitial.c
r23341 r23573 16 16 psAssert(config, "Require configuration"); 17 17 18 psTimerStart("PPSTACK_FINAL"); 18 if (!options->convolve) { 19 // No need to do initial combination when we haven't convolved 20 return true; 21 } 22 23 psTimerStart("PPSTACK_INITIAL"); 19 24 20 25 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe … … 69 74 } 70 75 71 // call: ppStackReadoutInitial(config, outRO, readouts, subRegions, subKernels)72 76 psThreadJob *job = psThreadJobAlloc("PPSTACK_INITIAL_COMBINE"); // Job to start 73 77 psArrayAdd(job->args, 1, thread); … … 128 132 129 133 if (options->stats) { 130 psMetadataAddF32(options->stats, PS_LIST_TAIL, "TIME_ FINAL", 0,131 "Time to make final stack", psTimerMark("PPSTACK_ FINAL"));134 psMetadataAddF32(options->stats, PS_LIST_TAIL, "TIME_INITIAL", 0, 135 "Time to make final stack", psTimerMark("PPSTACK_INITIAL")); 132 136 } 133 137 -
trunk/ppStack/src/ppStackConvolve.c
r23341 r23573 30 30 int num = options->num; // Number of inputs 31 31 options->cells = psArrayAlloc(num); // Cells for convolved images --- a handle for reading again 32 options-> subKernels = psArrayAlloc(num); // Subtractionkernels --- required in the stacking33 options-> subRegions = psArrayAlloc(num); // Subtractionregions --- required in the stacking32 options->kernels = psArrayAlloc(num); // PSF-matching kernels --- required in the stacking 33 options->regions = psArrayAlloc(num); // PSF-matching regions --- required in the stacking 34 34 int numGood = 0; // Number of good frames 35 35 options->numCols = 0; … … 38 38 psVectorInit(options->matchChi2, NAN); 39 39 options->weightings = psVectorAlloc(num, PS_TYPE_F32); // Combination weightings for images (1/noise^2) 40 psVectorInit(options->weightings, NAN);40 psVectorInit(options->weightings, 0.0); 41 41 options->covariances = psArrayAlloc(num); // Covariance matrices 42 42 … … 78 78 79 79 // Background subtraction, scaling and normalisation is performed automatically by the image matching 80 psArray *regions = NULL, *kernels = NULL; // Regions and kernels used in subtraction81 80 psTimerStart("PPSTACK_MATCH"); 82 83 if (!ppStackMatch(readout, ®ions, &kernels, &options->matchChi2->data.F32[i], 84 &options->weightings->data.F32[i], options->sourceLists->data[i], 85 options->psf, rng, config)) { 81 if (!ppStackMatch(readout, options, i, config)) { 86 82 psErrorStackPrint(stderr, "Unable to match image %d --- ignoring.", i); 87 options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PPSTACK_MASK_MATCH;83 options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= PPSTACK_MASK_MATCH; 88 84 psErrorClear(); 89 85 continue; … … 92 88 93 89 if (options->stats) { 94 pmSubtractionKernels *kernels = psMetadataLookupPtr(NULL, readout->analysis,95 PM_SUBTRACTION_ANALYSIS_KERNEL);// Conv kernel96 90 psMetadataAddF32(options->stats, PS_LIST_TAIL, "TIME_MATCH", PS_META_DUPLICATE_OK, 97 91 "Time to match PSF", psTimerMark("PPSTACK_MATCH")); 98 psMetadataAddF32(options->stats, PS_LIST_TAIL, "STAMP.MEAN", PS_META_DUPLICATE_OK,99 "Mean deviation for stamps", kernels->mean);100 psMetadataAddF32(options->stats, PS_LIST_TAIL, "STAMP.RMS", PS_META_DUPLICATE_OK,101 "RMS deviation for stamps", kernels->rms);102 psMetadataAddF32(options->stats, PS_LIST_TAIL, "STAMP.NUM", PS_META_DUPLICATE_OK,103 "Number of stamps", kernels->numStamps);104 float deconv = psMetadataLookupF32(NULL, readout->analysis,105 PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Deconvolution fraction106 psMetadataAddF32(options->stats, PS_LIST_TAIL, "KERNEL.DECONV", PS_META_DUPLICATE_OK,107 "Deconvolution fraction for kernel", deconv);108 92 psMetadataAddF32(options->stats, PS_LIST_TAIL, "PPSTACK.WEIGHTING", PS_META_DUPLICATE_OK, 109 93 "Weighting for image", options->weightings->data.F32[i]); 94 95 if (options->convolve) { 96 // Pull parameters out of convolution kernel 97 pmSubtractionKernels *kernels = psMetadataLookupPtr(NULL, readout->analysis, 98 PM_SUBTRACTION_ANALYSIS_KERNEL); 99 psMetadataAddF32(options->stats, PS_LIST_TAIL, "STAMP.MEAN", PS_META_DUPLICATE_OK, 100 "Mean deviation for stamps", kernels->mean); 101 psMetadataAddF32(options->stats, PS_LIST_TAIL, "STAMP.RMS", PS_META_DUPLICATE_OK, 102 "RMS deviation for stamps", kernels->rms); 103 psMetadataAddF32(options->stats, PS_LIST_TAIL, "STAMP.NUM", PS_META_DUPLICATE_OK, 104 "Number of stamps", kernels->numStamps); 105 float deconv = psMetadataLookupF32(NULL, readout->analysis, 106 PM_SUBTRACTION_ANALYSIS_DECONV_MAX); 107 psMetadataAddF32(options->stats, PS_LIST_TAIL, "KERNEL.DECONV", PS_META_DUPLICATE_OK, 108 "Deconvolution fraction for kernel", deconv); 109 } 110 110 } 111 111 psLogMsg("ppStack", PS_LOG_INFO, "Time to match image %d: %f sec", i, psTimerClear("PPSTACK_MATCH")); 112 112 113 options->subRegions->data[i] = regions;114 options->subKernels->data[i] = kernels;115 116 113 // Write the temporary convolved files 117 pmHDU *hdu = readout->parent->parent->parent->hdu; // HDU for convolved image 118 assert(hdu); 119 ppStackWriteImage(options->imageNames->data[i], hdu->header, readout->image, config); 120 psMetadata *maskHeader = psMetadataCopy(NULL, hdu->header); // Copy of header, for mask 121 pmConfigMaskWriteHeader(config, maskHeader); 122 ppStackWriteImage(options->maskNames->data[i], maskHeader, readout->mask, config); 123 psFree(maskHeader); 124 psImageCovarianceTransfer(readout->variance, readout->covariance); 125 ppStackWriteImage(options->varianceNames->data[i], hdu->header, readout->variance, config); 114 if (options->convolve) { 115 pmHDU *hdu = readout->parent->parent->parent->hdu; // HDU for convolved image 116 assert(hdu); 117 ppStackWriteImage(options->imageNames->data[i], hdu->header, readout->image, config); 118 psMetadata *maskHeader = psMetadataCopy(NULL, hdu->header); // Copy of header, for mask 119 pmConfigMaskWriteHeader(config, maskHeader); 120 ppStackWriteImage(options->maskNames->data[i], maskHeader, readout->mask, config); 121 psFree(maskHeader); 122 psImageCovarianceTransfer(readout->variance, readout->covariance); 123 ppStackWriteImage(options->varianceNames->data[i], hdu->header, readout->variance, config); 126 124 #ifdef TESTING 127 {128 psString name = NULL;129 psStringAppend(&name, "covariance_%d.fits", i);130 ppStackWriteImage(name, hdu->header, readout->covariance->image, config);131 pmStackVisualPlotTestImage(readout->covariance->image, name);132 psFree(name);133 }125 { 126 psString name = NULL; 127 psStringAppend(&name, "covariance_%d.fits", i); 128 ppStackWriteImage(name, hdu->header, readout->covariance->image, config); 129 pmStackVisualPlotTestImage(readout->covariance->image, name); 130 psFree(name); 131 } 134 132 #endif 133 } 135 134 136 135 pmCell *inCell = readout->parent; // Input cell … … 152 151 psFree(rng); 153 152 153 psFree(options->norm); options->norm = NULL; 154 154 psFree(options->sourceLists); options->sourceLists = NULL; 155 155 psFree(options->psf); options->psf = NULL; -
trunk/ppStack/src/ppStackMatch.c
r23379 r23573 163 163 164 164 165 bool ppStackMatch(pmReadout *readout, psArray **regions, psArray **kernels, float *chi2, float *weighting, 166 psArray *sources, const pmPSF *psf, psRandom *rng, const pmConfig *config) 165 bool ppStackMatch(pmReadout *readout, ppStackOptions *options, int index, const pmConfig *config) 167 166 { 168 167 assert(readout); 169 assert(regions && !*regions); 170 assert(kernels && !*kernels); 168 assert(options); 171 169 assert(config); 172 *weighting = 0.0;173 170 174 171 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe … … 197 194 } 198 195 199 pmReadout *output = pmReadoutAlloc(NULL); // Output readout, for holding results temporarily 200 201 static int numInput = -1; // Index of input file 202 numInput++; 196 // Match the PSF 197 if (options->convolve) { 198 pmReadout *conv = pmReadoutAlloc(NULL); // Conv readout, for holding results temporarily 203 199 #ifdef TESTING 204 // Read previously produced kernel 205 if (psMetadataLookupBool(NULL, config->arguments, "PPSTACK.DEBUG.STACK")) { 206 const char *outName = psMetadataLookupStr(NULL, config->arguments, "OUTPUT"); // Output root 207 assert(outName); 208 // Read convolution kernel 209 psString filename = NULL; // Output filename 210 psStringAppend(&filename, "%s.%d.kernel", outName, numInput); 211 psString resolved = pmConfigConvertFilename(filename, config, false, false); // Resolved filename 212 psFree(filename); 213 psFits *fits = psFitsOpen(resolved, "r"); // FITS file for subtraction kernel 214 psFree(resolved); 215 if (!fits || !pmReadoutReadSubtractionKernels(output, fits)) { 216 psError(PS_ERR_IO, false, "Unable to read previously produced kernel"); 200 // This is a hack to use the temporary convolved images and kernel generated previously. 201 // This makes the 'matching' operation much faster, allowing debugging of the stack process easier. 202 // It implicitly assumes the output root name is the same between invocations. 203 204 // Read previously produced kernel 205 if (psMetadataLookupBool(NULL, config->arguments, "PPSTACK.DEBUG.STACK")) { 206 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPSTACK.CONV.KERNEL", index); 207 psAssert(file, "Require file"); 208 209 pmFPAview *view = pmFPAviewAlloc(0); // View to readout of interest 210 view->chip = view->cell = view->readout = 0; 211 psString filename = pmFPAfileNameFromRule(filerule->rule, file, view); // Filename of interest 212 213 // Read convolution kernel 214 psString resolved = pmConfigConvertFilename(filename, config, false, false); // Resolved filename 215 psFree(filename); 216 psFits *fits = psFitsOpen(resolved, "r"); // FITS file for subtraction kernel 217 psFree(resolved); 218 if (!fits || !pmReadoutReadSubtractionKernels(conv, fits)) { 219 psError(PS_ERR_IO, false, "Unable to read previously produced kernel"); 220 psFitsClose(fits); 221 return false; 222 } 217 223 psFitsClose(fits); 218 return false; 219 } 220 psFitsClose(fits); 221 222 // Add in variance factor 223 pmSubtractionKernels *kernels = psMetadataLookupPtr(NULL, output->analysis, 224 PM_SUBTRACTION_ANALYSIS_KERNEL); // Kernels 225 float vf = pmSubtractionVarianceFactor(kernels, 0.0, 0.0, false); // Variance factor 226 psMetadataItem *vfItem = psMetadataLookup(readout->parent->concepts, "CELL.VARFACTOR"); 227 if (!isfinite(vf)) { 228 vf = 1.0; 229 } 230 if (isfinite(vfItem->data.F32)) { 231 vfItem->data.F32 *= vf; 232 } else { 233 vfItem->data.F32 = vf; 234 } 235 236 // Read image, mask, variance 237 const char *tempImage = psMetadataLookupStr(NULL, recipe, "TEMP.IMAGE"); // Suffix for image 238 const char *tempMask = psMetadataLookupStr(NULL, recipe, "TEMP.MASK"); // Suffix for mask 239 const char *tempVariance = psMetadataLookupStr(NULL, recipe, "TEMP.VARIANCE"); // Suffix for variance map 240 psString imageName = NULL, maskName = NULL, varianceName = NULL; // Names for convolved images 241 psStringAppend(&imageName, "%s.%d.%s", outName, numInput, tempImage); 242 psStringAppend(&maskName, "%s.%d.%s", outName, numInput, tempMask); 243 psStringAppend(&varianceName, "%s.%d.%s", outName, numInput, tempVariance); 244 245 if (!readImage(&readout->image, imageName, config) || !readImage(&readout->mask, maskName, config) || 246 !readImage(&readout->variance, varianceName, config)) { 247 psError(PS_ERR_IO, false, "Unable to read previously produced image."); 224 225 // Add in variance factor 226 pmSubtractionKernels *kernels = psMetadataLookupPtr(NULL, conv->analysis, 227 PM_SUBTRACTION_ANALYSIS_KERNEL); // Kernels 228 float vf = pmSubtractionVarianceFactor(kernels, 0.0, 0.0, false); // Variance factor 229 psMetadataItem *vfItem = psMetadataLookup(readout->parent->concepts, "CELL.VARFACTOR"); 230 if (!isfinite(vf)) { 231 vf = 1.0; 232 } 233 if (isfinite(vfItem->data.F32)) { 234 vfItem->data.F32 *= vf; 235 } else { 236 vfItem->data.F32 = vf; 237 } 238 239 if (!readImage(&readout->image, options->imageNames->data[index], config) || 240 !readImage(&readout->mask, options->maskNames->data[index], config) || 241 !readImage(&readout->variance, options->varianceNames->data[index], config)) { 242 psError(PS_ERR_IO, false, "Unable to read previously produced image."); 243 psFree(imageName); 244 psFree(maskName); 245 psFree(varianceName); 246 return false; 247 } 248 248 psFree(imageName); 249 249 psFree(maskName); 250 250 psFree(varianceName); 251 return false; 252 } 253 psFree(imageName); 254 psFree(maskName); 255 psFree(varianceName); 256 257 psRegion *region = psMetadataLookupPtr(NULL, output->analysis, 258 PM_SUBTRACTION_ANALYSIS_REGION); // Convolution region 259 260 pmSubtractionAnalysis(readout->analysis, kernels, region, 261 readout->image->numCols, readout->image->numRows); 262 263 psKernel *kernel = pmSubtractionKernel(kernels, 0.0, 0.0, false); // Convolution kernel 264 psKernel *covar = psImageCovarianceCalculate(kernel, readout->covariance); // New covariance matrix 265 psFree(readout->covariance); 266 readout->covariance = covar; 267 psFree(kernel); 268 269 } else { 270 #endif 271 272 // Normal operations here 273 if (psMetadataLookupBool(&mdok, config->arguments, "HAVE.PSF")) { 274 assert(psf); 275 assert(sources); 251 252 psRegion *region = psMetadataLookupPtr(NULL, conv->analysis, 253 PM_SUBTRACTION_ANALYSIS_REGION); // Convolution region 254 255 pmSubtractionAnalysis(readout->analysis, kernels, region, 256 readout->image->numCols, readout->image->numRows); 257 258 psKernel *kernel = pmSubtractionKernel(kernels, 0.0, 0.0, false); // Convolution kernel 259 psKernel *covar = psImageCovarianceCalculate(kernel, readout->covariance); // Covariance matrix 260 psFree(readout->covariance); 261 readout->covariance = covar; 262 psFree(kernel); 263 } else { 264 #endif 265 266 // Normal operations here 267 psAssert(options->psf, "Require target PSF"); 268 psAssert(options->sourceLists && options->sourceLists->data[index], "Require source list"); 276 269 277 270 int order = psMetadataLookupS32(NULL, ppsub, "SPATIAL.ORDER"); // Spatial polynomial order … … 284 277 float rej = psMetadataLookupF32(NULL, ppsub, "REJ"); // Rejection threshold 285 278 float sysError = psMetadataLookupF32(NULL, ppsub, "SYS"); // Relative systematic error in kernel 286 pmSubtractionKernelsType type = pmSubtractionKernelsTypeFromString(287 psMetadataLookupStr(NULL, ppsub, "KERNEL.TYPE")); // Kernel type279 const char *typeStr = psMetadataLookupStr(NULL, ppsub, "KERNEL.TYPE"); // Kernel type 280 pmSubtractionKernelsType type = pmSubtractionKernelsTypeFromString(typeStr); // Kernel type 288 281 psVector *widths = psMetadataLookupPtr(NULL, ppsub, "ISIS.WIDTHS"); // ISIS Gaussian widths 289 282 psVector *orders = psMetadataLookupPtr(NULL, ppsub, "ISIS.ORDERS"); // ISIS Polynomial orders … … 308 301 } 309 302 310 #if 0311 // Testing the normalisation of the fake image312 {313 pmReadout *test = pmReadoutAlloc(NULL); // Test readout314 psArray *sources = psArrayAlloc(1); // Array of sources315 pmSource *source = pmSourceAlloc(); // Source316 sources->data[0] = source;317 source->peak = pmPeakAlloc(500, 500, 10000, PM_PEAK_LONE);318 source->psfMag = -13.0;319 pmReadoutFakeFromSources(test, 1000, 1000, sources, NULL, NULL, psf, 0.1, 0, false, true);320 float sum = 0.0;321 for (int y = 0; y < test->image->numRows; y++) {322 for (int x = 0; x < test->image->numCols; x++) {323 sum += test->image->data.F32[y][x];324 }325 }326 fprintf(stderr, "Photometry: %f --> %f = -13.0 ???\n", sum, -2.5*log10(sum));327 328 psFits *fits = psFitsOpen("testphot.fits", "w");329 psFitsWriteImage(fits, NULL, test->image, 0, NULL);330 psFitsClose(fits);331 exit(0);332 }333 #endif334 335 303 pmReadout *fake = pmReadoutAlloc(NULL); // Fake readout with target PSF 336 304 337 305 // For the sake of stamps, remove nearby sources 338 psArray *stampSources = stackSourcesFilter(sources, footprint); // Filtered list of sources 306 psArray *stampSources = stackSourcesFilter(options->sourceLists->data[index], 307 footprint); // Filtered list of sources 339 308 340 309 if (!pmReadoutFakeFromSources(fake, readout->image->numCols, readout->image->numRows, 341 stampSources, NULL, NULL, psf, NAN, footprint + size,310 stampSources, NULL, NULL, options->psf, NAN, footprint + size, 342 311 false, true)) { 343 312 psError(PS_ERR_UNKNOWN, false, "Unable to generate fake image with target PSF."); 344 313 psFree(fake); 345 314 psFree(optWidths); 346 psFree( output);315 psFree(conv); 347 316 return false; 348 317 } … … 357 326 pmHDU *hdu = pmHDUFromCell(readout->parent); 358 327 psString name = NULL; 359 psStringAppend(&name, "fake_%03d.fits", numInput);328 psStringAppend(&name, "fake_%03d.fits", index); 360 329 pmStackVisualPlotTestImage(fake->image, name); 361 330 psFits *fits = psFitsOpen(name, "w"); … … 367 336 pmHDU *hdu = pmHDUFromCell(readout->parent); 368 337 psString name = NULL; 369 psStringAppend(&name, "real_%03d.fits", numInput);338 psStringAppend(&name, "real_%03d.fits", index); 370 339 pmStackVisualPlotTestImage(readout->image, name); 371 340 psFits *fits = psFitsOpen(name, "w"); … … 384 353 PM_SUBTRACTION_ANALYSIS_KERNEL); // Conv kernel 385 354 if (kernel) { 386 if (!pmSubtractionMatchPrecalc( output, NULL, readout, fake, readout->analysis,355 if (!pmSubtractionMatchPrecalc(conv, NULL, readout, fake, readout->analysis, 387 356 stride, sysError, maskVal, maskBad, maskPoor, 388 357 poorFrac, badFrac)) { … … 391 360 psFree(optWidths); 392 361 psFree(stampSources); 393 psFree( output);362 psFree(conv); 394 363 return false; 395 364 } 396 365 } else { 397 if (!pmSubtractionMatch( output, NULL, readout, fake, footprint, stride, regionSize, spacing,366 if (!pmSubtractionMatch(conv, NULL, readout, fake, footprint, stride, regionSize, spacing, 398 367 threshold, stampSources, stampsName, type, size, order, widths, 399 368 orders, inner, ringsOrder, binning, penalty, … … 405 374 psFree(optWidths); 406 375 psFree(stampSources); 407 psFree( output);376 psFree(conv); 408 377 return false; 409 378 } … … 414 383 pmHDU *hdu = pmHDUFromCell(readout->parent); 415 384 psString name = NULL; 416 psStringAppend(&name, "conv_%03d.fits", numInput);417 pmStackVisualPlotTestImage( output->image, name);385 psStringAppend(&name, "conv_%03d.fits", index); 386 pmStackVisualPlotTestImage(conv->image, name); 418 387 psFits *fits = psFitsOpen(name, "w"); 419 388 psFree(name); 420 psFitsWriteImage(fits, hdu->header, output->image, 0, NULL);389 psFitsWriteImage(fits, hdu->header, conv->image, 0, NULL); 421 390 psFitsClose(fits); 422 391 } … … 424 393 pmHDU *hdu = pmHDUFromCell(readout->parent); 425 394 psString name = NULL; 426 psStringAppend(&name, "diff_%03d.fits", numInput);395 psStringAppend(&name, "diff_%03d.fits", index); 427 396 pmStackVisualPlotTestImage(fake->image, name); 428 397 psFits *fits = psFitsOpen(name, "w"); 429 398 psFree(name); 430 psBinaryOp(fake->image, output->image, "-", fake->image);399 psBinaryOp(fake->image, conv->image, "-", fake->image); 431 400 psFitsWriteImage(fits, hdu->header, fake->image, 0, NULL); 432 401 psFitsClose(fits); … … 444 413 // Set the variance factor 445 414 psMetadataItem *vfItem = psMetadataLookup(readout->parent->concepts, "CELL.VARFACTOR"); 446 float vf = psMetadataLookupF32(NULL, output->analysis, PM_SUBTRACTION_ANALYSIS_VARFACTOR_1);415 float vf = psMetadataLookupF32(NULL, conv->analysis, PM_SUBTRACTION_ANALYSIS_VARFACTOR_1); 447 416 if (!isfinite(vf)) { 448 417 vf = 1.0; … … 459 428 psFree(readout->variance); 460 429 psFree(readout->covariance); 461 readout->image = psMemIncrRefCounter(output->image); 462 readout->mask = psMemIncrRefCounter(output->mask); 463 readout->variance = psMemIncrRefCounter(output->variance); 464 readout->covariance = psImageCovarianceTruncate(output->covariance, COVAR_FRAC); 465 } else { 466 // Fake the convolution 467 psRegion *region = psRegionAlloc(0, readout->image->numCols - 1, 0, readout->image->numRows - 1); 468 psMetadataAddPtr(output->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_REGION, 469 PS_DATA_REGION | PS_META_DUPLICATE_OK, "Fake subtraction region", region); 470 psFree(region); 471 pmSubtractionKernels *kernels = pmSubtractionKernelsPOIS(FAKE_SIZE, 0, penalty, 472 PM_SUBTRACTION_MODE_1); 473 // Set solution to delta function 474 kernels->solution1 = psVectorAlloc(kernels->num + 2, PS_TYPE_F64); 475 psVectorInit(kernels->solution1, 0.0); 476 int normIndex = PM_SUBTRACTION_INDEX_NORM(kernels); // Index for normalisation 477 kernels->solution1->data.F64[normIndex] = 1.0; 478 psMetadataAddPtr(output->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_KERNEL, 479 PS_DATA_UNKNOWN | PS_META_DUPLICATE_OK, "Fake subtraction kernel", kernels); 480 psFree(kernels); 481 } 482 430 readout->image = psMemIncrRefCounter(conv->image); 431 readout->mask = psMemIncrRefCounter(conv->mask); 432 readout->variance = psMemIncrRefCounter(conv->variance); 433 readout->covariance = psImageCovarianceTruncate(conv->covariance, COVAR_FRAC); 483 434 #ifdef TESTING 484 // Write convolution kernel 435 } 436 #endif 437 438 // Extract the regions and solutions used in the image matching 439 // This stops them from being freed when we iterate back up the FPA 440 psArray *regions = options->regions->data[index] = psArrayAllocEmpty(ARRAY_BUFFER); // Match regions 485 441 { 486 const char *outName = psMetadataLookupStr(NULL, config->arguments, "OUTPUT"); // Output root 487 assert(outName); 488 489 psString filename = NULL; // Output filename 490 psStringAppend(&filename, "%s.%d.kernel", outName, numInput); 491 psString resolved = pmConfigConvertFilename(filename, config, true, false); // Resolved filename 492 psFree(filename); 493 psFits *fits = psFitsOpen(resolved, "w"); // FITS file for subtraction kernel 494 psFree(resolved); 495 pmReadoutWriteSubtractionKernels(output, fits); 496 psFitsClose(fits); 497 } 498 } 499 #endif 500 501 readout->analysis = psMetadataCopy(readout->analysis, output->analysis); 502 503 // Extract the regions and solutions used in the image matching 504 // This stops them from being freed when we iterate back up the FPA 505 *regions = psArrayAllocEmpty(ARRAY_BUFFER); // Array of regions 506 { 507 psString regex = NULL; // Regular expression 508 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_REGION); 509 psMetadataIterator *iter = psMetadataIteratorAlloc(output->analysis, PS_LIST_HEAD, regex); // Iterator 510 psFree(regex); 511 psMetadataItem *item = NULL;// Item from iteration 512 while ((item = psMetadataGetAndIncrement(iter))) { 513 assert(item->type == PS_DATA_REGION); 514 *regions = psArrayAdd(*regions, ARRAY_BUFFER, item->data.V); 515 } 516 psFree(iter); 517 } 518 *kernels = psArrayAllocEmpty(ARRAY_BUFFER); // Array of kernels 519 { 520 psString regex = NULL; // Regular expression 521 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_KERNEL); 522 psMetadataIterator *iter = psMetadataIteratorAlloc(output->analysis, PS_LIST_HEAD, regex); // Iterator 523 psFree(regex); 524 psMetadataItem *item = NULL;// Item from iteration 525 while ((item = psMetadataGetAndIncrement(iter))) { 526 assert(item->type == PS_DATA_UNKNOWN); 527 // Set the normalisation dimensions, since these will be otherwise unavailable when reading the 528 // images by scans. 529 pmSubtractionKernels *kernel = item->data.V; // Kernel used in subtraction 530 kernel->numCols = readout->image->numCols; 531 kernel->numRows = readout->image->numRows; 532 533 *kernels = psArrayAdd(*kernels, ARRAY_BUFFER, kernel); 534 } 535 psFree(iter); 536 } 537 assert((*regions)->n == (*kernels)->n); 538 539 // Record chi^2 540 { 541 *chi2 = 0.0; 542 int num = 0; // Number of measurements of chi^2 543 psString regex = NULL; // Regular expression 544 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_KERNEL); 545 psMetadataIterator *iter = psMetadataIteratorAlloc(output->analysis, PS_LIST_HEAD, regex); // Iterator 546 psFree(regex); 547 psMetadataItem *item = NULL;// Item from iteration 548 while ((item = psMetadataGetAndIncrement(iter))) { 549 assert(item->type == PS_DATA_UNKNOWN); 550 pmSubtractionKernels *kernels = item->data.V; // Convolution kernels 551 *chi2 += kernels->mean; 552 num++; 553 } 554 psFree(iter); 555 *chi2 /= psImageCovarianceFactor(readout->covariance) * num; 556 } 557 558 // Reject image completely if the maximum deconvolution fraction exceeds the limit 559 float deconv = psMetadataLookupF32(NULL, output->analysis, 560 PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Maximum deconvolution fraction 561 if (deconv > deconvLimit) { 562 psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting\n", 563 deconv, deconvLimit); 564 psFree(output); 565 return NULL; 442 psString regex = NULL; // Regular expression 443 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_REGION); 444 psMetadataIterator *iter = psMetadataIteratorAlloc(conv->analysis, PS_LIST_HEAD, regex); 445 psFree(regex); 446 psMetadataItem *item = NULL;// Item from iteration 447 while ((item = psMetadataGetAndIncrement(iter))) { 448 assert(item->type == PS_DATA_REGION); 449 regions = psArrayAdd(regions, ARRAY_BUFFER, item->data.V); 450 } 451 psFree(iter); 452 } 453 psArray *kernels = options->kernels->data[index] = psArrayAllocEmpty(ARRAY_BUFFER); // Match kernels 454 { 455 psString regex = NULL; // Regular expression 456 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_KERNEL); 457 psMetadataIterator *iter = psMetadataIteratorAlloc(conv->analysis, PS_LIST_HEAD, regex); 458 psFree(regex); 459 psMetadataItem *item = NULL;// Item from iteration 460 while ((item = psMetadataGetAndIncrement(iter))) { 461 assert(item->type == PS_DATA_UNKNOWN); 462 // Set the normalisation dimensions, since these will be otherwise unavailable when reading 463 // the images by scans. 464 pmSubtractionKernels *kernel = item->data.V; // Kernel used in subtraction 465 kernel->numCols = readout->image->numCols; 466 kernel->numRows = readout->image->numRows; 467 468 kernels = psArrayAdd(kernels, ARRAY_BUFFER, kernel); 469 } 470 psFree(iter); 471 } 472 psAssert((regions)->n == (kernels)->n, "Number of match regions and kernels should match"); 473 474 // Record chi^2 475 { 476 double sum = 0.0; // Sum of chi^2 477 int num = 0; // Number of measurements of chi^2 478 psString regex = NULL; // Regular expression 479 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_KERNEL); 480 psMetadataIterator *iter = psMetadataIteratorAlloc(conv->analysis, PS_LIST_HEAD, regex); 481 psFree(regex); 482 psMetadataItem *item = NULL;// Item from iteration 483 while ((item = psMetadataGetAndIncrement(iter))) { 484 assert(item->type == PS_DATA_UNKNOWN); 485 pmSubtractionKernels *kernels = item->data.V; // Convolution kernels 486 sum += kernels->mean; 487 num++; 488 } 489 psFree(iter); 490 options->matchChi2->data.F32[index] = sum / (psImageCovarianceFactor(readout->covariance) * num); 491 } 492 493 // Reject image completely if the maximum deconvolution fraction exceeds the limit 494 float deconv = psMetadataLookupF32(NULL, conv->analysis, 495 PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Max deconvolution fraction 496 if (deconv > deconvLimit) { 497 psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting\n", 498 deconv, deconvLimit); 499 psFree(conv); 500 return NULL; 501 } 502 503 readout->analysis = psMetadataCopy(readout->analysis, conv->analysis); 504 505 psFree(conv); 506 } else { 507 // Match the normalisation 508 float norm = powf(10.0, -0.4 * options->norm->data.F32[index]); // Normalisation 509 psBinaryOp(readout->image, readout->image, "*", psScalarAlloc(norm, PS_TYPE_F32)); 510 psBinaryOp(readout->variance, readout->variance, "*", psScalarAlloc(PS_SQR(norm), PS_TYPE_F32)); 566 511 } 567 512 568 513 // Ensure the background value is zero 569 514 psStats *bg = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics for background 515 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator 570 516 if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal | maskBad, rng)) { 571 517 psWarning("Can't measure background for image."); … … 581 527 if (!psImageBackground(bg, NULL, readout->variance, readout->mask, maskVal | maskBad, rng)) { 582 528 psError(PS_ERR_UNKNOWN, false, "Can't measure mean variance for image."); 583 psFree(output); 529 psFree(rng); 530 psFree(bg); 584 531 return false; 585 532 } 586 *weighting= 1.0 / (psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN) *587 psImageCovarianceFactor(readout->covariance));533 options->weightings->data.F32[index] = 1.0 / (psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN) * 534 psImageCovarianceFactor(readout->covariance)); 588 535 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "PPSTACK.WEIGHTING", 0, 589 "Weighting by 1/noise^2 for stack", *weighting); 590 536 "Weighting by 1/noise^2 for stack", options->weightings->data.F32[index]); 537 538 psFree(rng); 591 539 psFree(bg); 592 593 #if 0594 #define RADIUS 10 // Radius of photometry595 #define MIN_ERR 0.05 // Minimum photometric error, mag596 #define MAX_MAG -13 // Maximum magnitude for source597 598 // Ensure the normalisation is correct599 // XXX Ideally, would like to do proper PSF-fit photometry, but will settle for aperture photometry600 int numSources = sources->n; // Number of sources601 psVector *ratio = psVectorAlloc(numSources, PS_TYPE_F32); // Flux ratios for sources602 psVector *ratioMask = psVectorAlloc(numSources, PS_TYPE_MASK); // Mask for flux ratios603 psVectorInit(ratioMask, 0xFF);604 psImage *image = readout->image; // Image of interest605 psImage *mask = readout->mask; // Mask of interest606 int numCols = image->numCols, numRows = image->numRows; // Size of image607 for (int i = 0; i < numSources; i++) {608 pmSource *source = sources->data[i]; // Source of interest609 if (!source || source->mode & SOURCE_MASK || !isfinite(source->psfMag) || !isfinite(source->errMag) ||610 source->errMag > MIN_ERR || source->psfMag > MAX_MAG) {611 continue;612 }613 614 float xSrc, ySrc; // Source coordinates615 coordsFromSource(&xSrc, &ySrc, source);616 int xMin = PS_MAX(0, xSrc - RADIUS), xMax = PS_MIN(numCols - 1, xSrc + RADIUS); // Bounds in x617 int yMin = PS_MAX(0, ySrc - RADIUS), yMax = PS_MIN(numRows - 1, ySrc + RADIUS); // Bounds in y618 int numPix = 0; // Number of pixels619 float sum = 0.0; // Sum of pixels620 for (int y = yMin; y <= yMax; y++) {621 for (int x = xMin; x <= xMax; x++) {622 if (mask->data.PS_TYPE_MASK_DATA[y][x] & maskBad) {623 continue;624 }625 sum += image->data.F32[y][x];626 numPix++;627 }628 }629 if (sum >= 0 && numPix > 0) {630 float mag = -2.5 * log10(sum * M_PI * PS_SQR(RADIUS) / numPix); // Instrumental magnitude631 ratio->data.F32[i] = mag - source->psfMag;632 ratioMask->data.PS_TYPE_MASK_DATA[i] = 0;633 }634 }635 636 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics637 if (!psVectorStats(stats, ratio, NULL, ratioMask, 0xFF)) {638 psWarning("Unable to measure normalisation --- assuming correct.");639 } else {640 psLogMsg("ppStack", PS_LOG_INFO, "Renormalising image by %f (+/- %f) mag\n",641 stats->robustMedian, stats->robustStdev);642 float norm = powf(10.0, -0.4 * stats->robustMedian); // Normalisation to apply643 psBinaryOp(image, image, "*", psScalarAlloc(norm, PS_TYPE_F32));644 }645 psFree(stats);646 psFree(ratio);647 psFree(ratioMask);648 #endif649 540 650 541 #ifdef TESTING … … 652 543 pmHDU *hdu = pmHDUFromCell(readout->parent); 653 544 psString name = NULL; 654 psStringAppend(&name, "convolved_%03d.fits", numInput);655 pmStackVisualPlotTestImage( output->image, name);545 psStringAppend(&name, "convolved_%03d.fits", index); 546 pmStackVisualPlotTestImage(readout->image, name); 656 547 psFits *fits = psFitsOpen(name, "w"); 657 548 psFree(name); 658 psFitsWriteImage(fits, hdu->header, output->image, 0, NULL);549 psFitsWriteImage(fits, hdu->header, readout->image, 0, NULL); 659 550 psFitsClose(fits); 660 551 } 661 552 #endif 662 663 psFree(output);664 553 665 554 return true; -
trunk/ppStack/src/ppStackOptions.c
r23341 r23573 18 18 psFree(options->inputMask); 19 19 psFree(options->sourceLists); 20 psFree(options->norm); 20 21 psFree(options->cells); 21 psFree(options-> subKernels);22 psFree(options-> subRegions);22 psFree(options->kernels); 23 psFree(options->regions); 23 24 psFree(options->matchChi2); 24 25 psFree(options->weightings); … … 35 36 psMemSetDeallocator(options, (psFreeFunc)stackOptionsFree); 36 37 38 options->convolve = true; 37 39 options->stats = NULL; 38 40 options->statsFile = NULL; … … 44 46 options->inputMask = NULL; 45 47 options->sourceLists = NULL; 48 options->norm = NULL; 46 49 options->cells = NULL; 47 options-> subKernels = NULL;48 options-> subRegions = NULL;50 options->kernels = NULL; 51 options->regions = NULL; 49 52 options->numCols = 0; 50 53 options->numRows = 0; -
trunk/ppStack/src/ppStackOptions.h
r23341 r23573 8 8 typedef struct { 9 9 // Setup 10 bool convolve; // Convolve images? 10 11 psMetadata *stats; // Statistics for output 11 12 FILE *statsFile; // File to which to write statistics … … 17 18 psVector *inputMask; // Mask for inputs 18 19 psArray *sourceLists; // Individual lists of sources for matching 20 psVector *norm; // Normalisation for each image 19 21 // Convolve 20 22 psArray *cells; // Cells for convolved images --- a handle for reading again 21 psArray * subKernels; // Subtractionkernels --- required in the stacking22 psArray * subRegions; // Subtractionregions --- required in the stacking23 psArray *kernels; // PSF-matching kernels --- required in the stacking 24 psArray *regions; // PSF-matching regions --- required in the stacking 23 25 int numCols, numRows; // Size of image 24 26 psVector *matchChi2; // chi^2 for stamps from matching -
trunk/ppStack/src/ppStackPrepare.c
r23341 r23573 127 127 psVectorInit(options->inputMask, 0); 128 128 129 if (psMetadataLookupBool(NULL, config->arguments, "HAVE.PSF")) {130 pmFPAfileActivate(config->files, false, NULL);131 ppStackFileActivation(config, PPSTACK_FILES_PREPARE, true);132 pmFPAview *view = ppStackFilesIterateDown(config);133 if (!view) {134 return false;135 } 136 137 // Generate list of PSFs138 psMetadataIterator *fileIter = psMetadataIteratorAlloc(config->files, PS_LIST_HEAD,139 "^PPSTACK.INPUT$"); // Iterator140 psMetadataItem *fileItem; // Item from iteration141 psArray *psfs = psArrayAlloc(num); // PSFs for PSF envelope142 int numCols = 0, numRows = 0; // Size of image143 int index = 0; // Index forfile144 while ((fileItem = psMetadataGetAndIncrement(fileIter))) { 145 assert(fileItem->type == PS_DATA_UNKNOWN);146 pmFPAfile *inputFile = fileItem->data.V; // An input file129 pmFPAfileActivate(config->files, false, NULL); 130 ppStackFileActivation(config, PPSTACK_FILES_PREPARE, true); 131 pmFPAview *view = ppStackFilesIterateDown(config); 132 if (!view) { 133 return false; 134 } 135 136 psMetadataIterator *fileIter = psMetadataIteratorAlloc(config->files, PS_LIST_HEAD, "^PPSTACK.INPUT$"); 137 psMetadataItem *fileItem; // Item from iteration 138 psArray *psfs = psArrayAlloc(num); // PSFs for PSF envelope 139 int numCols = 0, numRows = 0; // Size of image 140 int index = 0; // Index for file 141 while ((fileItem = psMetadataGetAndIncrement(fileIter))) { 142 assert(fileItem->type == PS_DATA_UNKNOWN); 143 pmFPAfile *inputFile = fileItem->data.V; // An input file 144 145 // Get list of PSFs, to determine target PSF 146 if (options->convolve) { 147 147 pmChip *chip = pmFPAviewThisChip(view, inputFile->fpa); // The chip: holds the PSF 148 148 pmPSF *psf = psMetadataLookupPtr(NULL, chip->analysis, "PSPHOT.PSF"); // PSF … … 173 173 numRows = naxis2; 174 174 } 175 176 pmReadout *ro = pmFPAviewThisReadout(view, inputFile->fpa); // Readout with sources 177 psArray *sources = psMetadataLookupPtr(NULL, ro->analysis, "PSPHOT.SOURCES"); // Sources 178 if (!sources) { 179 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find sources in readout."); 180 return NULL; 181 } 182 options->sourceLists->data[index] = psMemIncrRefCounter(sources); 183 184 // Re-do photometry if we don't trust the source lists 185 if (psMetadataLookupBool(NULL, recipe, "PHOT")) { 186 psTrace("ppStack", 2, "Photometering input %d of %d....\n", index, num); 187 pmFPAfileActivate(config->files, false, NULL); 188 ppStackFileActivationSingle(config, PPSTACK_FILES_CONVOLVE, true, index); 189 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPSTACK.INPUT", index); // File 190 pmFPAview *photView = ppStackFilesIterateDown(config); 191 if (!photView) { 192 psFree(view); 193 return false; 194 } 195 196 pmReadout *ro = pmFPAviewThisReadout(view, file->fpa); // Readout of interest 197 198 if (!ppStackInputPhotometer(ro, sources, config)) { 199 psError(PS_ERR_UNKNOWN, false, "Unable to do photometry on input sources"); 200 psFree(view); 201 psFree(photView); 202 return false; 203 } 204 175 } 176 177 178 pmReadout *ro = pmFPAviewThisReadout(view, inputFile->fpa); // Readout with sources 179 psArray *sources = psMetadataLookupPtr(NULL, ro->analysis, "PSPHOT.SOURCES"); // Sources 180 if (!sources) { 181 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find sources in readout."); 182 return NULL; 183 } 184 options->sourceLists->data[index] = psMemIncrRefCounter(sources); 185 186 // Re-do photometry if we don't trust the source lists 187 if (psMetadataLookupBool(NULL, recipe, "PHOT")) { 188 psTrace("ppStack", 2, "Photometering input %d of %d....\n", index, num); 189 pmFPAfileActivate(config->files, false, NULL); 190 ppStackFileActivationSingle(config, PPSTACK_FILES_CONVOLVE, true, index); 191 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPSTACK.INPUT", index); // File 192 pmFPAview *photView = ppStackFilesIterateDown(config); 193 if (!photView) { 194 psFree(view); 195 return false; 196 } 197 198 pmReadout *ro = pmFPAviewThisReadout(view, file->fpa); // Readout of interest 199 200 if (!ppStackInputPhotometer(ro, sources, config)) { 201 psError(PS_ERR_UNKNOWN, false, "Unable to do photometry on input sources"); 202 psFree(view); 205 203 psFree(photView); 206 if (!ppStackFilesIterateUp(config)) { 207 psFree(view); 208 return false; 209 } 210 pmFPAfileActivate(config->files, false, NULL); 211 ppStackFileActivation(config, PPSTACK_FILES_PREPARE, true); 212 } 213 214 index++; 215 } 216 psFree(fileIter); 217 218 // Zero point calibration 219 options->sumExposure = ppStackSourcesTransparency(options->sourceLists, options->inputMask, 220 view, config); 221 if (!isfinite(options->sumExposure) || options->sumExposure <= 0) { 222 psError(PS_ERR_UNKNOWN, false, "Unable to calculate transparency differences"); 223 psFree(view); 224 return false; 225 } 226 227 // Generate target PSF 204 return false; 205 } 206 207 psFree(photView); 208 if (!ppStackFilesIterateUp(config)) { 209 psFree(view); 210 return false; 211 } 212 pmFPAfileActivate(config->files, false, NULL); 213 ppStackFileActivation(config, PPSTACK_FILES_PREPARE, true); 214 } 215 216 index++; 217 } 218 psFree(fileIter); 219 220 // Generate target PSF 221 if (options->convolve) { 228 222 options->psf = ppStackPSF(config, numCols, numRows, psfs, options->inputMask); 229 223 psFree(psfs); … … 240 234 "Target PSF", options->psf); 241 235 outChip->data_exists = true; 242 236 } 237 238 // Zero point calibration 239 if (!ppStackSourcesTransparency(options, view, config)) { 240 psError(PS_ERR_UNKNOWN, false, "Unable to calculate transparency differences"); 243 241 psFree(view); 244 245 if (!ppStackFilesIterateUp(config)) { 246 return false; 247 } 242 return false; 243 } 244 psFree(view); 245 246 if (!ppStackFilesIterateUp(config)) { 247 return false; 248 248 } 249 249 -
trunk/ppStack/src/ppStackReject.c
r23341 r23573 14 14 psAssert(options, "Require options"); 15 15 psAssert(config, "Require configuration"); 16 17 if (!options->convolve) { 18 // No need to do complicated rejection when we haven't convolved 19 return true; 20 } 16 21 17 22 int num = options->num; // Number of inputs … … 86 91 87 92 psPixels *reject = pmStackReject(options->inspect->data[i], options->numCols, options->numRows, 88 threshold, poorFrac, stride, options-> subRegions->data[i],89 options-> subKernels->data[i]); // Rejected pixels93 threshold, poorFrac, stride, options->regions->data[i], 94 options->kernels->data[i]); // Rejected pixels 90 95 91 96 #ifdef TESTING … … 141 146 142 147 psFree(options->inspect); options->inspect = NULL; 143 psFree(options-> subKernels); options->subKernels = NULL;144 psFree(options-> subRegions); options->subRegions = NULL;148 psFree(options->kernels); options->kernels = NULL; 149 psFree(options->regions); options->regions = NULL; 145 150 146 151 if (numRejected >= num - 1) { -
trunk/ppStack/src/ppStackSetup.c
r23341 r23573 11 11 #include "ppStackLoop.h" 12 12 13 #define BUFFER 16 // Buffer for name array 14 15 // Generate an array of input filenames 16 static psArray *stackNameArray(pmConfig *config, // Configuration 17 const char *name // Name of file 18 ) 19 { 20 psAssert(config, "Require configuration"); 21 psAssert(config, "Require file name"); 22 23 psString regex = NULL; // Regular expression for selecting file 24 psStringAppend(®ex, "^%s$", name); 25 psMetadataIterator *iter = psMetadataIteratorAlloc(config->files, PS_LIST_HEAD, regex); // Iterator 26 psFree(regex); 27 psMetadataItem *item; // Item from iteration 28 psArray *array = psArrayAlloc(BUFFER); // Array of file names 29 while ((item = psMetadataGetAndIncrement(iter))) { 30 psAssert(item->type == PS_DATA_UNKNOWN, "Should be this type"); 31 pmFPAfile *file = item->data.V; // An input file 32 33 psString filename = psStringCopy(file->filename); // Filename of interest 34 psArrayAdd(array, array->n, filename); 35 psFree(filename); // Drop reference 36 } 37 psFree(iter); 38 39 return array; 40 } 41 42 13 43 bool ppStackSetup(ppStackOptions *options, pmConfig *config) 14 44 { … … 18 48 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe 19 49 psAssert(recipe, "We've thrown an error on this before."); 50 51 options->convolve = psMetadataLookupBool(NULL, config->arguments, "CONVOLVE"); // Convolve images? 52 if (!psMetadataLookupBool(NULL, config->arguments, "HAVE.PSF")) { 53 psWarning("No PSFs provided --- unable to convolve to common PSF."); 54 options->convolve = false; 55 } 20 56 21 57 int num = psMetadataLookupS32(NULL, config->arguments, "INPUTS.NUM"); // Number of inputs … … 36 72 } 37 73 38 const char *tempDir = psMetadataLookupStr(NULL, recipe, "TEMP.DIR"); // Directory for temporary images 39 if (!tempDir) { 40 psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Unable to find TEMP.DIR in recipe"); 41 return false; 74 // Generate temporary names for convolved images 75 if (options->convolve) { 76 const char *tempDir = psMetadataLookupStr(NULL, recipe, "TEMP.DIR"); // Directory for temporary images 77 if (!tempDir) { 78 psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Unable to find TEMP.DIR in recipe"); 79 return false; 80 } 81 82 psString outputName = psStringCopy(psMetadataLookupStr(NULL, config->arguments, 83 "OUTPUT")); // Name for temporary files 84 const char *tempName = basename(outputName); 85 if (!tempName) { 86 psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Unable to construct basename for temporary files."); 87 psFree(outputName); 88 return false; 89 } 90 91 const char *tempImage = psMetadataLookupStr(NULL, recipe, "TEMP.IMAGE"); // Suffix for images 92 const char *tempMask = psMetadataLookupStr(NULL, recipe, "TEMP.MASK"); // Suffix for masks 93 const char *tempVariance = psMetadataLookupStr(NULL, recipe, "TEMP.VARIANCE"); // Suffix for var maps 94 if (!tempImage || !tempMask || !tempVariance) { 95 psError(PS_ERR_BAD_PARAMETER_VALUE, false, 96 "Unable to find TEMP.IMAGE, TEMP.MASK and TEMP.VARIANCE in recipe"); 97 psFree(outputName); 98 return false; 99 } 100 101 options->imageNames = psArrayAlloc(num); 102 options->maskNames = psArrayAlloc(num); 103 options->varianceNames = psArrayAlloc(num); 104 for (int i = 0; i < num; i++) { 105 psString imageName = NULL, maskName = NULL, varianceName = NULL; // Names for convolved images 106 psStringAppend(&imageName, "%s/%s.%d.%s", tempDir, tempName, i, tempImage); 107 psStringAppend(&maskName, "%s/%s.%d.%s", tempDir, tempName, i, tempMask); 108 psStringAppend(&varianceName, "%s/%s.%d.%s", tempDir, tempName, i, tempVariance); 109 psTrace("ppStack", 5, "Temporary files: %s %s %s\n", imageName, maskName, varianceName); 110 options->imageNames->data[i] = imageName; 111 options->maskNames->data[i] = maskName; 112 options->varianceNames->data[i] = varianceName; 113 } 114 psFree(outputName); 115 } else { 116 options->imageNames = stackNameArray(config, "PPSTACK.INPUT"); 117 options->maskNames = stackNameArray(config, "PPSTACK.INPUT.MASK"); 118 options->varianceNames = stackNameArray(config, "PPSTACK.INPUT.VARIANCE"); 42 119 } 43 44 psString outputName = psStringCopy(psMetadataLookupStr(NULL, config->arguments,45 "OUTPUT")); // Name for temporary files46 const char *tempName = basename(outputName);47 if (!tempName) {48 psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Unable to construct basename for temporary files.");49 psFree(outputName);50 return false;51 }52 53 const char *tempImage = psMetadataLookupStr(NULL, recipe, "TEMP.IMAGE"); // Suffix for temporary images54 const char *tempMask = psMetadataLookupStr(NULL, recipe, "TEMP.MASK"); // Suffix for temporary masks55 const char *tempVariance = psMetadataLookupStr(NULL, recipe, "TEMP.VARIANCE"); // Suffix for temp var maps56 if (!tempImage || !tempMask || !tempVariance) {57 psError(PS_ERR_BAD_PARAMETER_VALUE, false,58 "Unable to find TEMP.IMAGE, TEMP.MASK and TEMP.VARIANCE in recipe");59 psFree(outputName);60 return false;61 }62 63 options->imageNames = psArrayAlloc(num);64 options->maskNames = psArrayAlloc(num);65 options->varianceNames = psArrayAlloc(num);66 for (int i = 0; i < num; i++) {67 psString imageName = NULL, maskName = NULL, varianceName = NULL; // Names for convolved images68 psStringAppend(&imageName, "%s/%s.%d.%s", tempDir, tempName, i, tempImage);69 psStringAppend(&maskName, "%s/%s.%d.%s", tempDir, tempName, i, tempMask);70 psStringAppend(&varianceName, "%s/%s.%d.%s", tempDir, tempName, i, tempVariance);71 psTrace("ppStack", 5, "Temporary files: %s %s %s\n", imageName, maskName, varianceName);72 options->imageNames->data[i] = imageName;73 options->maskNames->data[i] = maskName;74 options->varianceNames->data[i] = varianceName;75 }76 psFree(outputName);77 120 78 121 if (!pmConfigMaskSetBits(NULL, NULL, config)) { -
trunk/ppStack/src/ppStackSources.c
r23242 r23573 9 9 //#define TESTING // Enable debugging output 10 10 11 #ifdef TESTING 11 12 // Size of fake image; set by hand because it's trouble to get it from other places 12 13 #define FAKE_COLS 4861 13 14 #define FAKE_ROWS 4913 15 #endif 14 16 15 17 #ifdef TESTING … … 53 55 54 56 55 float ppStackSourcesTransparency(const psArray *sourceLists, psVector *inputMask, 56 const pmFPAview *view, const pmConfig *config) 57 bool ppStackSourcesTransparency(ppStackOptions *options, const pmFPAview *view, const pmConfig *config) 57 58 { 58 PS_ASSERT_ARRAY_NON_NULL(sourceLists, NAN); 59 PS_ASSERT_VECTOR_NON_NULL(inputMask, NAN); 60 PS_ASSERT_VECTOR_TYPE(inputMask, PS_TYPE_U8, NAN); 61 PS_ASSERT_VECTOR_SIZE(inputMask, sourceLists->n, NAN); 62 PS_ASSERT_PTR_NON_NULL(view, NAN); 63 PS_ASSERT_PTR_NON_NULL(config, NAN); 59 PS_ASSERT_PTR_NON_NULL(options, false); 60 PS_ASSERT_PTR_NON_NULL(view, false); 61 PS_ASSERT_PTR_NON_NULL(config, false); 62 63 psArray *sourceLists = options->sourceLists; // Source lists for each input 64 psVector *inputMask = options->inputMask; // Mask for inputs 65 66 PS_ASSERT_ARRAY_NON_NULL(sourceLists, false); 67 PS_ASSERT_VECTOR_NON_NULL(inputMask, false); 68 PS_ASSERT_VECTOR_TYPE(inputMask, PS_TYPE_U8, false); 69 PS_ASSERT_VECTOR_SIZE(inputMask, sourceLists->n, false); 64 70 65 71 #if defined(TESTING) && 0 … … 100 106 if (!airmassZP) { 101 107 psError(PS_ERR_UNKNOWN, false, "Unable to find ZP.AIRMASS in recipe."); 102 return NAN;108 return false; 103 109 } 104 110 … … 139 145 exptime, airmass, expFilter); 140 146 psFree(zp); 141 return NAN;147 return false; 142 148 } 143 149 … … 149 155 "Unable to find airmass term (ZP.AIRMASS) for filter %s", filter); 150 156 psFree(zp); 151 return NAN;157 return false; 152 158 } 153 159 } else if (strcmp(filter, expFilter) != 0) { 154 160 psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Filters don't match: %s vs %s", filter, expFilter); 155 161 psFree(zp); 156 return NAN;162 return false; 157 163 } 158 164 … … 160 166 sumExpTime += exptime; 161 167 } 168 169 options->sumExposure = sumExpTime; 162 170 163 171 psArray *matches = pmSourceMatchSources(sourceLists, radius, true); // List of matches … … 165 173 psError(PS_ERR_UNKNOWN, false, "Unable to match sources"); 166 174 psFree(zp); 167 return NAN;175 return false; 168 176 } 169 177 … … 177 185 if (!trans) { 178 186 psError(PS_ERR_UNKNOWN, false, "Unable to measure transparencies"); 179 return NAN;187 return false; 180 188 } 181 189 … … 186 194 for (int i = 0; i < trans->n; i++) { 187 195 if (!isfinite(trans->data.F32[i])) { 188 inputMask->data.U8[i] = PPSTACK_MASK_CAL;196 inputMask->data.U8[i] |= PPSTACK_MASK_CAL; 189 197 } 190 198 } … … 223 231 // m_0 = m_1 + zp_1 + trans_1 - c1 * airmass_0 - 2.5log(t_0) 224 232 // We don't need to know the magnitude zero point for the filter, since it cancels out 233 options->norm = psVectorAlloc(num, PS_TYPE_F32); 225 234 for (int i = 0; i < num; i++) { 226 235 if (!isfinite(trans->data.F32[i])) { … … 229 238 psArray *sources = sourceLists->data[i]; // Sources of interest 230 239 float magCorr = airmassTerm - 2.5*log10(sumExpTime) - zp->data.F32[i] - trans->data.F32[i]; 240 options->norm->data.F32[i] = magCorr; 231 241 psLogMsg("ppStack", PS_LOG_INFO, "Applying magnitude correction to image %d: %f\n", i, magCorr); 232 242 … … 248 258 psError(PS_ERR_UNKNOWN, false, "Unable to match sources"); 249 259 psFree(zp); 250 return NAN;260 return false; 251 261 } 252 262 psVector *trans = pmSourceMatchRelphot(matches, zp, iter, tol, starLimit, transIter, transRej, … … 259 269 #endif 260 270 261 return sumExpTime;271 return true; 262 272 }
Note:
See TracChangeset
for help on using the changeset viewer.
