Changeset 16605 for trunk/ppStack/src/ppStackReadout.c
- Timestamp:
- Feb 22, 2008, 9:28:00 AM (18 years ago)
- File:
-
- 1 edited
-
trunk/ppStack/src/ppStackReadout.c (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ppStack/src/ppStackReadout.c
r15849 r16605 10 10 #include "ppStack.h" 11 11 12 #define ARRAY_BUFFER 16 // Number to add to array at a time13 12 #define WCS_TOLERANCE 0.001 // Tolerance for WCS 14 13 15 //#define NO_CONVOLUTION // Don't perform convolutions?16 //#define CONVOLUTION_FILES // Write convolutions?17 14 //#define REJECTION_FILES // Write rejection mask? 18 15 //#define INSPECTION_FILES // Write inspection mask? 19 16 20 bool ppStackReadout(pmConfig *config, const pmFPAview *view) 17 static int sectionNum = 0; // Section number; for debugging outputs 18 19 20 bool ppStackReadout(const pmConfig *config, pmReadout *outRO, const psArray *readouts, 21 const psArray *regions, const psArray *kernels) 21 22 { 23 assert(config); 24 assert(outRO); 25 assert(readouts); 26 assert(regions); 27 assert(kernels); 28 assert(readouts->n == regions->n); 29 assert(regions->n == kernels->n); 30 31 22 32 // Get the recipe values 23 bool mdok; // Status of MD lookup24 33 int iter = psMetadataLookupS32(NULL, config->arguments, "ITER"); // Rejection iterations 25 34 float combineRej = psMetadataLookupF32(NULL, config->arguments, "COMBINE.REJ"); // Combination threshold … … 27 36 psMaskType maskBlank = psMetadataLookupU8(NULL, config->arguments, "MASK.BLANK"); // Mask for blank reg. 28 37 float threshold = psMetadataLookupF32(NULL, config->arguments, "THRESHOLD.MASK"); // Threshold for mask deconvolution 29 bool photometry = psMetadataLookupBool(&mdok, config->arguments, "PHOTOMETRY"); // Perform photometry? 30 int psfInstances = psMetadataLookupS32(&mdok, config->arguments, "PSF.INSTANCES"); // Number of instances for PSF 31 float psfRadius = psMetadataLookupF32(NULL, config->arguments, "PSF.RADIUS"); // Radius for PSF 32 const char *psfModel = psMetadataLookupStr(NULL, config->arguments, "PSF.MODEL"); // Model for PSF 33 int psfOrder = psMetadataLookupS32(&mdok, config->arguments, "PSF.ORDER"); // Spatial order for PSF 34 35 // Get the output target 36 pmCell *outCell = pmFPAfileThisCell(config->files, view, "PPSTACK.OUTPUT"); // Output cell 37 pmReadout *outRO = pmReadoutAlloc(outCell); // Output readout 38 pmFPA *outFPA = outCell->parent->parent; // Output FPA 39 40 int num = psMetadataLookupS32(NULL, config->arguments, "INPUTS.NUM"); // Number of inputs 41 assert(num > 0); 42 43 // Get the input sources 44 psArray *stack = psArrayAllocEmpty(ARRAY_BUFFER); // The stack of inputs 45 pmReadout *sources = pmFPAfileThisReadout(config->files, view, "PPSTACK.SOURCES"); // Sources for stamps 46 psMetadataIterator *fileIter = psMetadataIteratorAlloc(config->files, PS_LIST_HEAD, 47 "^PPSTACK.INPUT$"); // Iterator over input files 48 psMetadataItem *fileItem; // Item from iteration 49 int fileNum = 0; // Number of file 50 psList *psfList = psListAlloc(NULL); // List of PSFs for PSF envelope 51 pmPSF *outPSF = NULL; // Ouptut PSF 52 int numCols = 0, numRows = 0; // Size of image 53 while ((fileItem = psMetadataGetAndIncrement(fileIter))) { 54 assert(fileItem->type == PS_DATA_UNKNOWN); 55 pmFPAfile *inputFile = fileItem->data.V; // An input file 56 pmReadout *ro = pmFPAviewThisReadout(view, inputFile->fpa); // Corresponding readout 57 pmCell *cell = ro->parent; // The cell 58 pmChip *chip = cell->parent; // The chip: holds the PSF 59 60 bool mdok; // Status of MD lookup 61 pmPSF *psf = psMetadataLookupPtr(&mdok, chip->analysis, "PSPHOT.PSF"); 62 if (mdok && psf) { 63 psListAdd(psfList, PS_LIST_TAIL, psf); 64 if (numCols == 0 && numRows == 0) { 65 numCols = ro->image->numCols; 66 numRows = ro->image->numRows; 67 } 68 } 69 } 70 71 bool convolve = false; // Convolve the input images? 72 if (psfList->n > 0) { 73 psArray *psfArray = psListToArray(psfList); // Array of PSFs 74 outPSF = pmPSFEnvelope(numCols, numRows, psfArray, psfInstances, psfRadius, psfModel, 75 psfOrder, psfOrder); 76 psFree(psfArray); 77 if (!outPSF) { 78 psError(PS_ERR_UNKNOWN, false, "Unable to determine output PSF."); 79 // XXX Free stuff 80 return false; 81 } 82 convolve = true; 83 PS_ASSERT_PTR_NON_NULL(sources, false); 84 } 85 86 // Iterate through again to get the convolved images (or not) 87 88 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN); // Statistics 89 psRandom *rng = psRandomAlloc(0, PS_RANDOM_TAUS); // Random number generator 38 39 int num = readouts->n; // Number of inputs 40 psArray *stack = psArrayAlloc(num); // Array for stacking 41 42 pmCell *outCell = outRO->parent; // Output cell 43 pmChip *outChip = outCell->parent; // Output chip 44 pmFPA *outFPA = outChip->parent; // Output FPA 45 90 46 float totExposure = 0.0; // Total exposure time 91 47 psList *fpaList = psListAlloc(NULL); // List of input FPAs, for concept averaging 92 48 psList *cellList = psListAlloc(NULL); // List of input cells, for concept averaging 93 94 psMetadataIteratorSet(fileIter, PS_LIST_HEAD); 95 fileNum = 0; 96 while ((fileItem = psMetadataGetAndIncrement(fileIter))) { 97 assert(fileItem->type == PS_DATA_UNKNOWN); 98 pmFPAfile *inputFile = fileItem->data.V; // An input file 99 pmReadout *ro = pmFPAviewThisReadout(view, inputFile->fpa); // Corresponding readout 49 for (int i = 0; i < num; i++) { 50 pmReadout *ro = readouts->data[i]; 51 assert(ro); 52 pmFPA *fpa = ro->parent->parent->parent; // Parent FPA 100 53 101 54 bool mdok; // Status of MD lookup 102 float weighting = psMetadataLookupF32(&mdok, inputFile->fpa->analysis, 103 "PPSTACK.WEIGHTING"); // Relative weighting 55 float weighting = psMetadataLookupF32(&mdok, fpa->analysis, "PPSTACK.WEIGHTING"); // Relative weight 104 56 if (!mdok || !isfinite(weighting)) { 105 psWarning("No WEIGHTING supplied for image %d --- set to unity.", fileNum);57 psWarning("No WEIGHTING supplied for image %d --- set to unity.", i); 106 58 weighting = 1.0; 107 59 } 108 float scale = psMetadataLookupF32(&mdok, inputFile->fpa->analysis, "PPSTACK.SCALE"); // Rel. scale109 if (!mdok || !isfinite(scale)) {110 psWarning("No SCALE supplied for image %d --- set to unity.", fileNum);111 scale = 1.0;112 }113 60 114 61 float exposure = psMetadataLookupF32(NULL, ro->parent->concepts, "CELL.EXPOSURE"); // Exposure time 115 #if 0116 62 if (!isfinite(exposure)) { 117 63 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 118 64 "CELL.EXPOSURE is not set for input file %ld", stack->n); 119 psFree(stats);120 psFree(rng);121 psFree(fileIter);122 65 psFree(fpaList); 123 66 psFree(cellList); 124 psFree(outRO);125 67 psFree(stack); 126 68 return false; 127 69 } 128 #endif129 70 totExposure += exposure; // Total exposure time 130 71 131 // Generate convolved version of input 132 pmReadout *convolved; 133 if (convolve) { 134 convolved = pmReadoutAlloc(NULL); // Convolved version of input readout 135 // Background subtraction, scaling and normalisation is performed automatically by the image 136 // matching 137 if (!ppStackMatch(convolved, ro, sources, outPSF, config)) { 138 psWarning("Unable to match image %d --- ignoring.", fileNum); 139 psErrorClear(); 140 psFree(convolved); 141 // XXX Free the bad image so it's not taking up good memory! 142 continue; 143 } 144 145 #ifdef CONVOLUTION_FILES 146 if (convolved->image) { 147 psString name = NULL; // Name of image 148 psStringAppend(&name, "convolved%03d_image.fits", fileNum); 149 psFits *fits = psFitsOpen(name, "w"); 150 psFree(name); 151 psFitsWriteImage(fits, NULL, convolved->image, 0, NULL); 152 psFitsClose(fits); 153 } 154 if (convolved->mask) { 155 psString name = NULL; // Name of image 156 psStringAppend(&name, "convolved%03d_mask.fits", fileNum); 157 psFits *fits = psFitsOpen(name, "w"); 158 psFree(name); 159 psFitsWriteImage(fits, NULL, convolved->mask, 0, NULL); 160 psFitsClose(fits); 161 } 162 if (convolved->weight) { 163 psString name = NULL; // Name of image 164 psStringAppend(&name, "convolved%03d_weight.fits", fileNum); 165 psFits *fits = psFitsOpen(name, "w"); 166 psFree(name); 167 psFitsWriteImage(fits, NULL, convolved->weight, 0, NULL); 168 psFitsClose(fits); 169 } 170 #endif // CONVOLUTION_FILES 171 172 } else { 173 // No convolution --- just use the unconvolved images as the "convolved" images, with some tweaks 174 convolved = psMemIncrRefCounter(ro); 175 sources = NULL; 176 177 // Brain-dead background subtraction 178 if (!psImageBackground(stats, NULL, ro->image, ro->mask, maskBad, rng)) { 179 psError(PS_ERR_UNKNOWN, false, "Unable to get image background on image %ld", stack->n); 180 psFree(stats); 181 psFree(rng); 182 psFree(fileIter); 183 psFree(fpaList); 184 psFree(cellList); 185 psFree(stack); 186 psFree(outRO); 187 psFree(convolved); 188 return false; 189 } 190 psTrace("ppStack", 3, "Background for image %d is %f\n", fileNum, stats->robustMedian); 191 (void)psBinaryOp(ro->image, ro->image, "-", psScalarAlloc(stats->robustMedian, PS_TYPE_F32)); 192 193 // Apply scaling 194 (void)psBinaryOp(ro->image, ro->image, "*", psScalarAlloc(1.0 / scale, PS_TYPE_F32)); 195 196 // Normalise each input by the exposure time 197 float exposure = psMetadataLookupF32(NULL, ro->parent->concepts, "CELL.EXPOSURE");// Exposure time 198 if (!isfinite(exposure)) { 199 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 200 "CELL.EXPOSURE is not set for input file %ld", stack->n); 201 psFree(stats); 202 psFree(rng); 203 psFree(fileIter); 204 psFree(fpaList); 205 psFree(cellList); 206 psFree(outRO); 207 psFree(convolved); 208 psFree(stack); 209 return false; 210 } 211 212 (void)psBinaryOp(ro->image, ro->image, "/", psScalarAlloc(exposure, PS_TYPE_F32)); 213 if (ro->weight) { 214 (void)psBinaryOp(ro->weight, ro->weight, "/", psScalarAlloc(exposure, PS_TYPE_F32)); 215 } 216 } 217 218 if (fileNum == 0) { 72 #if 0 73 if (i == 0) { 219 74 // Copy astrometry over 220 pmFPA *fpa = ro->parent->parent->parent; // Template FPA221 75 pmHDU *hdu = fpa->hdu; // Template HDU 222 76 pmHDU *outHDU = outFPA->hdu; // Output HDU … … 224 78 psWarning("Unable to find HDU at FPA level to copy astrometry."); 225 79 } else { 226 if (!pmAstromReadWCS(outFPA, outC ell->parent, hdu->header, 1.0)) {80 if (!pmAstromReadWCS(outFPA, outChip, hdu->header, 1.0)) { 227 81 psErrorClear(); 228 82 psWarning("Unable to read WCS astrometry from input FPA."); … … 231 85 outHDU->header = psMetadataAlloc(); 232 86 } 233 if (!pmAstromWriteWCS(outHDU->header, outFPA, outC ell->parent, WCS_TOLERANCE)) {87 if (!pmAstromWriteWCS(outHDU->header, outFPA, outChip, WCS_TOLERANCE)) { 234 88 psErrorClear(); 235 89 psWarning("Unable to write WCS astrometry to output FPA."); … … 238 92 } 239 93 } 240 241 // Don't need the original any more! 242 psFree(ro); 94 #endif 243 95 244 96 // Ensure there is a mask, or pmStackCombine will complain 245 if (!convolved->mask) { 246 convolved->mask = psImageAlloc(convolved->image->numCols, convolved->image->numRows, 247 PS_TYPE_MASK); 248 psImageInit(convolved->mask, 0); 249 } 250 251 psListAdd(fpaList, PS_LIST_TAIL, inputFile->fpa); 97 if (!ro->mask) { 98 ro->mask = psImageAlloc(ro->image->numCols, ro->image->numRows, PS_TYPE_MASK); 99 psImageInit(ro->mask, 0); 100 } 101 102 psListAdd(fpaList, PS_LIST_TAIL, fpa); 252 103 psListAdd(cellList, PS_LIST_TAIL, ro->parent); 253 104 254 pmStackData *data = pmStackDataAlloc(convolved, weighting); // Data to stack 255 psFree(convolved); 256 psArrayAdd(stack, ARRAY_BUFFER, data); 257 psFree(data); // Drop reference 258 259 fileNum++; 260 } 261 psFree(fileIter); 262 psFree(stats); 263 psFree(rng); 264 265 if (fileNum == 0) { 266 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Not enough good files to combine."); 267 psFree(fpaList); 268 psFree(cellList); 269 psFree(stack); 270 psFree(outRO); 271 return false; 105 stack->data[i] = pmStackDataAlloc(ro, weighting); 272 106 } 273 107 … … 277 111 psFree(cellList); 278 112 psFree(stack); 279 psFree(outRO);280 113 return false; 281 114 } … … 283 116 #ifdef INSPECTION_FILES 284 117 { 285 psFits *fits = psFitsOpen("combined.fits", "w"); 118 psString name = NULL; // Name of image 119 psStringAppend(&name, "combined_%03d.fits", sectionNum); 120 psFits *fits = psFitsOpen(name, "w"); 121 psFree(name); 286 122 psFitsWriteImage(fits, NULL, outRO->image, 0, NULL); 287 123 psFitsClose(fits); … … 291 127 pmStackData *data = stack->data[i]; // Data for this image 292 128 psImage *inspected = psPixelsToMask(NULL, data->pixels, 293 psRegionSet(0, data->readout->image->numCols ,294 0, data->readout->image->numRows ),129 psRegionSet(0, data->readout->image->numCols - 1, 130 0, data->readout->image->numRows - 1), 295 131 maskBlank); 296 132 psString name = NULL; // Name of image 297 psStringAppend(&name, "inspect %03d.fits", i);133 psStringAppend(&name, "inspect_%03d_%03d.fits", sectionNum, i); 298 134 psFits *fits = psFitsOpen(name, "w"); 299 135 psFree(name); … … 304 140 #endif 305 141 306 for (int i = 0; i < stack->n; i++) { 142 // Reject pixels 143 for (int i = 0; i < num; i++) { 307 144 pmStackData *data = stack->data[i]; // Data for this image 308 pmReadout *readout = data->readout; // Readout for this image 309 310 // Extract the regions and solutions used in the image matching 311 psArray *regions = psArrayAllocEmpty(ARRAY_BUFFER); // Array of regions 312 { 313 psMetadataIterator *iter = psMetadataIteratorAlloc(readout->analysis, PS_LIST_HEAD, 314 "^SUBTRACTION.REGION$"); // Iterator 315 psMetadataItem *item = NULL;// Item from iteration 316 while ((item = psMetadataGetAndIncrement(iter))) { 317 assert(item->type == PS_DATA_REGION); 318 regions = psArrayAdd(regions, ARRAY_BUFFER, item->data.V); 319 } 320 psFree(iter); 321 } 322 psArray *solutions = psArrayAllocEmpty(ARRAY_BUFFER); // Array of solutions 323 { 324 psMetadataIterator *iter = psMetadataIteratorAlloc(readout->analysis, PS_LIST_HEAD, 325 "^SUBTRACTION.SOLUTION$"); // Iterator 326 psMetadataItem *item = NULL;// Item from iteration 327 while ((item = psMetadataGetAndIncrement(iter))) { 328 assert(item->type == PS_DATA_VECTOR); 329 solutions = psArrayAdd(solutions, ARRAY_BUFFER, item->data.V); 330 } 331 psFree(iter); 332 } 333 assert(regions->n == solutions->n); 334 335 pmSubtractionKernels *kernels = psMetadataLookupPtr(NULL, readout->analysis, 336 "SUBTRACTION.KERNEL"); // Kernels 337 338 psPixels *reject = pmStackReject(data->pixels, threshold, regions, 339 solutions, kernels); // List of pixels to reject 145 pmReadout *readout = data->readout; // Readout of interest 146 int col0 = readout->col0, row0 = readout->row0; // Offset for readout 147 int numCols = readout->image->numCols, numRows = readout->image->numRows; // Size of image 148 149 psRegion *valid = psRegionAlloc(col0, col0 + numCols, row0, row0 + numRows); // Valid region for rej 150 psPixels *reject = pmStackReject(data->pixels, valid, threshold, regions->data[i], 151 kernels->data[i]); // Pixels to reject 152 psFree(valid); 340 153 psFree(data->pixels); 341 154 data->pixels = reject; 342 343 psFree(solutions);344 psFree(regions);345 155 } 346 156 … … 352 162 } 353 163 psImage *rejected = psPixelsToMask(NULL, data->pixels, 354 psRegionSet(0, data->readout->image->numCols ,355 0, data->readout->image->numRows ),164 psRegionSet(0, data->readout->image->numCols - 1, 165 0, data->readout->image->numRows - 1), 356 166 maskBlank); 357 167 psString name = NULL; // Name of image 358 psStringAppend(&name, "reject %03d.fits", i);168 psStringAppend(&name, "reject_%03d_%03d.fits", sectionNum, i); 359 169 psFits *fits = psFitsOpen(name, "w"); 360 170 psFree(name); … … 370 180 psFree(cellList); 371 181 psFree(stack); 372 psFree(outRO);373 182 return false; 374 }375 376 if (!convolve) {377 // Restore image to counts using the total exposure time378 (void)psBinaryOp(outRO->image, outRO->image, "*", psScalarAlloc(totExposure, PS_TYPE_F32));379 if (outRO->weight) {380 (void)psBinaryOp(outRO->weight, outRO->weight, "*", psScalarAlloc(totExposure, PS_TYPE_F32));381 }382 183 } 383 184 … … 397 198 psFree(cellList); 398 199 399 if (photometry) {400 pmFPAfile *photFile = psMetadataLookupPtr(NULL, config->files, "PSPHOT.INPUT");401 pmFPACopy(photFile->fpa, outRO->parent->parent->parent);402 403 if (!psphotReadout(config, view)) {404 psWarning("Unable to perform photometry on stacked image.");405 psErrorStackPrint(stderr, "Error stack from photometry:");406 psErrorClear();407 }408 409 pmFPAfileActivate(config->files, false, "PSPHOT.INPUT");410 }411 412 200 psFree(stack); 413 psFree(outRO); // Drop reference 201 202 sectionNum++; 414 203 415 204 return true;
Note:
See TracChangeset
for help on using the changeset viewer.
