Changeset 16605 for trunk/ppStack/src/ppStackLoop.c
- Timestamp:
- Feb 22, 2008, 9:28:00 AM (18 years ago)
- File:
-
- 1 edited
-
trunk/ppStack/src/ppStackLoop.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ppStack/src/ppStackLoop.c
r15224 r16605 11 11 #include "ppStack.h" 12 12 13 // Here follows lists of files for activation/deactivation at various stages. Each must be NULL-terminated. 14 15 #if 0 16 // All files in the system 17 static char *allFiles[] = { "PPSTACK.INPUT", "PPSTACK.INPUT.MASK", "PPSTACK.INPUT.WEIGHT", 18 "PPSTACK.OUTPUT", "PPSTACK.OUTPUT.MASK", "PPSTACK.OUTPUT.WEIGHT", 19 "PSPHOT.PSF.SAVE", "PSPHOT.PSF.LOAD", "PPSTACK.SOURCES", 20 "PSPHOT.OUTPUT", "PSPHOT.RESID", "PSPHOT.BACKMDL", "PSPHOT.BACKMDL.STDEV", 21 "PSPHOT.BACKGND", "PSPHOT.BACKSUB", "SOURCE.PLOT.MOMENTS", 22 "SOURCE.PLOT.PSFMODEL", "SOURCE.PLOT.APRESID", "PSPHOT.INPUT.CMF", 23 0 }; 24 #endif 25 26 // Files required in preparation for convolution 27 static char *prepareFiles[] = { "PSPHOT.PSF.LOAD", "PPSTACK.SOURCES", 0 }; 28 29 // Files required for the convolution 30 static char *convolveFiles[] = { "PPSTACK.INPUT", "PPSTACK.INPUT.MASK", "PPSTACK.INPUT.WEIGHT", 0 }; 31 32 // Output files for the combination 33 static char *combineFiles[] = { "PPSTACK.OUTPUT", "PPSTACK.OUTPUT.MASK", "PPSTACK.OUTPUT.WEIGHT", 0 }; 34 35 // Files for photometry 36 static char *photFiles[] = { "PSPHOT.OUTPUT", "PSPHOT.RESID", "PSPHOT.BACKMDL", 37 "PSPHOT.BACKMDL.STDEV", "PSPHOT.BACKGND", "PSPHOT.BACKSUB", 38 "SOURCE.PLOT.MOMENTS", "SOURCE.PLOT.PSFMODEL", "SOURCE.PLOT.APRESID", 39 "PSPHOT.INPUT.CMF", 0 }; 40 41 //#define CONVOLVED_ALREADY // Already have the convolution products --- testing 42 43 44 // Activate/deactivate a list of files 45 static void fileActivation(pmConfig *config, // Configuration 46 char **files, // Files to turn on/off 47 bool state // Activation state 48 ) 49 { 50 assert(config); 51 assert(files); 52 53 for (int i = 0; files[i] != NULL; i++) { 54 pmFPAfileActivate(config->files, state, files[i]); 55 } 56 return; 57 } 58 59 // Activate/deactivate a single element for a list; return array of files 60 static psArray *fileActivationSingle(pmConfig *config, // Configuration 61 char **files, // Files to turn on/off 62 bool state, // Activation state 63 int num // Number of file in sequence 64 ) 65 { 66 assert(config); 67 assert(files); 68 69 psList *list = psListAlloc(NULL); // List of files 70 71 for (int i = 0; files[i] != NULL; i++) { 72 pmFPAfile *file = pmFPAfileActivateSingle(config->files, state, files[i], num); // Activated file 73 psListAdd(list, PS_LIST_TAIL, file); 74 } 75 76 psArray *array = psListToArray(list); 77 psFree(list); 78 79 return array; 80 } 81 82 #if 0 83 // Set the data level for a list of files 84 static void fileSetDataLevel(pmConfig *config, // Configuration 85 char **files, // Files for which to set level 86 pmFPALevel level // Level to set 87 ) 88 { 89 assert(config); 90 assert(files); 91 92 for (int i = 0; files[i] != NULL; i++) { 93 psArray *selected = pmFPAfileSelect(config->files, files[i]); // Selected files of interest 94 for (int j = 0; j < selected->n; j++) { 95 pmFPAfile *file = selected->data[j]; 96 assert(file); 97 file->dataLevel = level; 98 } 99 psFree(selected); 100 } 101 return; 102 } 103 #endif 104 105 // Iterate down the hierarchy, loading files; we can get away with this because we're working on skycells 106 static pmFPAview *filesIterateDown(pmConfig *config // Configuration 107 ) 108 { 109 assert(config); 110 111 pmFPAview *view = pmFPAviewAlloc(0);// Pointer into FPA hierarchy 112 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 113 return NULL; 114 } 115 view->chip = 0; 116 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 117 return NULL; 118 } 119 view->cell = 0; 120 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 121 return NULL; 122 } 123 view->readout = 0; 124 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 125 return NULL; 126 } 127 return view; 128 } 129 130 // Iterate up the hierarchy, writing files; we can get away with this because we're working on skycells 131 static bool filesIterateUp(pmConfig *config // Configuration 132 ) 133 { 134 assert(config); 135 136 pmFPAview *view = pmFPAviewAlloc(0);// Pointer into FPA hierarchy 137 view->chip = view->cell = view->readout = 0; 138 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 139 return false; 140 } 141 view->readout = -1; 142 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 143 return false; 144 } 145 view->cell = -1; 146 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 147 return false; 148 } 149 view->chip = -1; 150 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 151 return false; 152 } 153 return true; 154 } 155 156 #ifndef CONVOLVED_ALREADY 157 // Write an image to a FITS file 158 static bool writeImage(const char *name, // Name of image 159 psMetadata *header, // Header 160 const psImage *image // Image 161 ) 162 { 163 assert(name); 164 assert(image); 165 166 psFits *fits = psFitsOpen(name, "w"); 167 if (!fits) { 168 psError(PS_ERR_IO, false, "Unable to open FITS file to write image."); 169 return false; 170 } 171 if (!psFitsWriteImage(fits, header, image, 0, NULL)) { 172 psError(PS_ERR_IO, false, "Unable to write FITS image."); 173 return false; 174 } 175 psFitsClose(fits); 176 return true; 177 } 178 #endif 179 180 13 181 bool ppStackLoop(pmConfig *config) 14 182 { 183 assert(config); 184 15 185 psMaskType maskBlank = psMetadataLookupU8(NULL, config->arguments, "MASK.BLANK"); // Mask for blank reg. 16 186 … … 32 202 } 33 203 34 pmFPAfile *input = psMetadataLookupPtr(NULL, config->files, "PPSTACK.INPUT"); // Token input file35 if (!input) {36 psError(PS_ERR_UNEXPECTED_NULL, false, "Can't find input data!\n");37 return false;38 }39 204 pmFPAfile *output = psMetadataLookupPtr(NULL, config->files, "PPSTACK.OUTPUT"); // Output file 40 205 if (!output) { 41 psError(PS_ERR_UNEXPECTED_NULL, false, "Can't find output data!\n"); 42 return false; 43 } 44 45 pmFPAview *view = pmFPAviewAlloc(0); // Pointer into FPA hierarchy 46 pmHDU *lastHDU = NULL; // Last HDU that was updated 47 48 // Iterate over the FPA hierarchy 49 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 50 return false; 51 } 52 53 pmChip *chip; // Chip of interest 54 while ((chip = pmFPAviewNextChip(view, input->fpa, 1)) != NULL) { 55 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 56 return false; 57 } 58 59 pmCell *cell; // Cell of interest 60 while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) { 61 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 206 psError(PS_ERR_UNEXPECTED_NULL, false, "Can't find output data!"); 207 return false; 208 } 209 int num = psMetadataLookupS32(NULL, config->arguments, "INPUTS.NUM"); // Number of inputs 210 int numScans = psMetadataLookupS32(NULL, config->arguments, "ROWS"); // Number of scans to read at once 211 psMetadata *ppsub = psMetadataLookupMetadata(NULL, config->recipes, "PPSUB"); // PPSUB recipe 212 int overlap = 2 * psMetadataLookupS32(NULL, ppsub, "KERNEL.SIZE"); // Overlap by kernel size between consecutive scans 213 214 // Preparation iteration: Load the sources, and get a target PSF model 215 pmReadout *sources = NULL; // Readout with sources to use for PSF matching 216 pmPSF *targetPSF = NULL; // Target PSF 217 { 218 pmFPAfileActivate(config->files, false, NULL); 219 fileActivation(config, prepareFiles, true); 220 pmFPAview *view = filesIterateDown(config); 221 if (!view) { 222 return false; 223 } 224 225 // We want to hang on to the 'sources' even when its host FPA is blown away 226 sources = psMemIncrRefCounter(pmFPAfileThisReadout(config->files, view, "PPSTACK.SOURCES")); 227 if (!sources) { 228 psError(PS_ERR_UNKNOWN, true, "Unable to find sources."); 229 psFree(view); 230 return false; 231 } 232 233 // Generate list of PSFs 234 psMetadataIterator *fileIter = psMetadataIteratorAlloc(config->files, PS_LIST_HEAD, 235 "^PPSTACK.INPUT$"); // Iterator 236 psMetadataItem *fileItem; // Item from iteration 237 psList *psfList = psListAlloc(NULL); // List of PSFs for PSF envelope 238 int numCols = 0, numRows = 0; // Size of image 239 while ((fileItem = psMetadataGetAndIncrement(fileIter))) { 240 assert(fileItem->type == PS_DATA_UNKNOWN); 241 pmFPAfile *inputFile = fileItem->data.V; // An input file 242 pmChip *chip = pmFPAviewThisChip(view, inputFile->fpa); // The chip: holds the PSF 243 pmPSF *psf = psMetadataLookupPtr(NULL, chip->analysis, "PSPHOT.PSF"); // PSF 244 if (!psf) { 245 psError(PS_ERR_UNKNOWN, false, "Unable to find PSF."); 246 psFree(view); 247 psFree(sources); 248 psFree(fileIter); 249 psFree(psfList); 62 250 return false; 63 251 } 64 65 // Put version information into the header 252 psListAdd(psfList, PS_LIST_TAIL, psf); 253 254 pmCell *cell = pmFPAviewThisCell(view, inputFile->fpa); // Cell of interest 66 255 pmHDU *hdu = pmHDUFromCell(cell); 67 if (hdu && hdu != lastHDU) { 68 if (!hdu->header) { 69 hdu->header = psMetadataAlloc(); 70 } 71 ppStackVersionMetadata(hdu->header); 72 lastHDU = hdu; 73 } 74 75 pmReadout *readout; // Readout of interest 76 while ((readout = pmFPAviewNextReadout(view, input->fpa, 1))) { 77 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 256 assert(hdu && hdu->header); 257 int naxis1 = psMetadataLookupS32(NULL, hdu->header, "NAXIS1"); // Number of columns 258 int naxis2 = psMetadataLookupS32(NULL, hdu->header, "NAXIS2"); // Number of rows 259 if (naxis1 <= 0 || naxis2 <= 0) { 260 psError(PS_ERR_UNKNOWN, false, "Unable to determine size of image from PSF."); 261 psFree(view); 262 psFree(sources); 263 psFree(fileIter); 264 psFree(psfList); 265 return false; 266 } 267 if (numCols == 0 && numRows == 0) { 268 numCols = naxis1; 269 numRows = naxis2; 270 } 271 } 272 psFree(fileIter); 273 psFree(view); 274 275 targetPSF = ppStackPSF(config, numCols, numRows, psfList); 276 psFree(psfList); 277 if (!targetPSF) { 278 psError(PS_ERR_UNKNOWN, false, "Unable to determine output PSF."); 279 psFree(sources); 280 return false; 281 } 282 283 filesIterateUp(config); 284 } 285 286 const char *suffix = "conv.fits"; // Suffix for convolved images; ultimately this will be from recipe 287 const char *outName = psMetadataLookupStr(NULL, config->arguments, "OUTPUT"); // Output root 288 assert(outName); 289 psArray *imageNames = psArrayAlloc(num); 290 psArray *maskNames = psArrayAlloc(num); 291 psArray *weightNames = psArrayAlloc(num); 292 for (int i = 0; i < num; i++) { 293 psString imageName = NULL, maskName = NULL, weightName = NULL; // Names for convolved images 294 psStringAppend(&imageName, "%s.im-%d.%s", outName, i, suffix); 295 psStringAppend(&maskName, "%s.mk-%d.%s", outName, i, suffix); 296 psStringAppend(&weightName, "%s.wt-%d.%s", outName, i, suffix); 297 imageNames->data[i] = imageName; 298 maskNames->data[i] = maskName; 299 weightNames->data[i] = weightName; 300 } 301 302 // Generate convolutions and write them to disk 303 psArray *cells = psArrayAlloc(num); // Cells for convolved images --- a handle for reading again 304 psArray *subKernels = psArrayAlloc(num); // Subtraction kernels --- required in the stacking 305 psArray *subRegions = psArrayAlloc(num); // Subtraction regions --- required in the stacking 306 for (int i = 0; i < num; i++) { 307 pmFPAfileActivate(config->files, false, NULL); 308 psArray *files = fileActivationSingle(config, convolveFiles, true, i); 309 pmFPAview *view = filesIterateDown(config); 310 if (!view) { 311 psFree(sources); 312 psFree(targetPSF); 313 return false; 314 } 315 316 pmReadout *readout = pmFPAviewThisReadout(view, ((pmFPAfile*)files->data[0])->fpa); // Input readout 317 psFree(view); 318 319 #ifndef CONVOLVED_ALREADY 320 // Background subtraction, scaling and normalisation is performed automatically by the image matching 321 psArray *regions = NULL, *kernels = NULL; // Regions and kernels used in subtraction 322 if (!ppStackMatch(readout, ®ions, &kernels, sources, targetPSF, config)) { 323 psError(PS_ERR_UNKNOWN, false, "Unable to match image %d --- ignoring.", i); 324 psFree(sources); 325 psFree(targetPSF); 326 return false; 327 } 328 329 subRegions->data[i] = regions; 330 subKernels->data[i] = kernels; 331 332 // Write the temporary convolved files 333 pmHDU *hdu = readout->parent->parent->parent->hdu; // HDU for convolved image 334 assert(hdu); 335 writeImage(imageNames->data[i], hdu->header, readout->image); 336 writeImage(maskNames->data[i], hdu->header, readout->mask); 337 writeImage(weightNames->data[i], hdu->header, readout->weight); 338 #endif 339 340 cells->data[i] = psMemIncrRefCounter(readout->parent); 341 filesIterateUp(config); 342 } 343 psFree(sources); 344 psFree(targetPSF); 345 346 // Stack the convolved files 347 { 348 pmFPAfileActivate(config->files, false, NULL); 349 fileActivation(config, combineFiles, true); 350 if (psMetadataLookupBool(&mdok, config->arguments, "PHOTOMETRY")) { 351 fileActivation(config, photFiles, true); 352 } 353 pmFPAview *view = filesIterateDown(config); 354 if (!view) { 355 psFree(cells); 356 psFree(subKernels); 357 psFree(subRegions); 358 return false; 359 } 360 pmCell *outCell = pmFPAfileThisCell(config->files, view, "PPSTACK.OUTPUT"); // Output cell 361 pmReadout *outRO = pmReadoutAlloc(outCell); // Output readout 362 363 psArray *readouts = psArrayAlloc(num); // Readouts for convolved images 364 for (int i = 0; i < num; i++) { 365 readouts->data[i] = pmReadoutAlloc(cells->data[i]); // Readout into which to read 366 } 367 psFree(cells); 368 369 // FITS files 370 psArray *imageFits = psArrayAlloc(num); 371 psArray *maskFits = psArrayAlloc(num); 372 psArray *weightFits = psArrayAlloc(num); 373 for (int i = 0; i < num; i++) { 374 imageFits->data[i] = psFitsOpen(imageNames->data[i], "r"); 375 maskFits->data[i] = psFitsOpen(maskNames->data[i], "r"); 376 weightFits->data[i] = psFitsOpen(weightNames->data[i], "r"); 377 } 378 379 // Read convolutions by chunks 380 bool more = true; // More to read? 381 for (int numChunk = 0; more; numChunk++) { 382 for (int i = 0; i < num; i++) { 383 pmReadout *readout = readouts->data[i]; 384 assert(readout); 385 386 if (!pmReadoutReadChunk(readout, imageFits->data[i], 0, numScans, overlap) || 387 !pmReadoutReadChunkMask(readout, maskFits->data[i], 0, numScans, overlap) || 388 !pmReadoutReadChunkWeight(readout, weightFits->data[i], 0, numScans, overlap)) { 389 psError(PS_ERR_IO, false, "Unable to read chunk %d for file %d", numChunk, i); 390 psFree(readouts); 391 psFree(subKernels); 392 psFree(subRegions); 393 psFree(outRO); 394 psFree(view); 78 395 return false; 79 396 } 80 81 // Perform the analysis 82 if (!ppStackReadout(config, view)) { 83 psError(PS_ERR_UNKNOWN, false, "Unable to stack images.\n"); 84 return false; 85 } 86 87 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 88 return false; 89 } 90 } 91 92 // Perform statistics on the cell 93 if (stats) { 94 ppStatsFPA(stats, output->fpa, view, maskBlank, config); 95 } 96 97 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 397 } 398 399 #ifdef TESTING 400 { 401 pmReadout *ro = readouts->data[0]; 402 psTrace("ppStack", 1, "Stack: [%d:%d,%d:%d]\n", ro->col0, ro->col0 + ro->image->numCols, 403 ro->row0, ro->row0 + ro->image->numRows); 404 } 405 #endif 406 407 if (!ppStackReadout(config, outRO, readouts, subRegions, subKernels)) { 408 psError(PS_ERR_UNKNOWN, false, "Unable to stack images.\n"); 409 psFree(readouts); 410 psFree(subKernels); 411 psFree(subRegions); 412 psFree(outRO); 413 psFree(view); 98 414 return false; 99 415 } 100 } 101 102 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 103 return false; 104 } 105 } 106 107 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 108 return false; 109 } 110 111 psFree(view); 416 417 for (int i = 0; i < num && more; i++) { 418 pmReadout *readout = readouts->data[i]; 419 assert(readout); 420 more &= pmReadoutMore(readout, imageFits->data[i], 0, numScans); 421 more &= pmReadoutMoreMask(readout, maskFits->data[i], 0, numScans); 422 more &= pmReadoutMoreWeight(readout, weightFits->data[i], 0, numScans); 423 } 424 } 425 426 psFree(readouts); 427 psFree(subKernels); 428 psFree(subRegions); 429 for (int i = 0; i < num; i++) { 430 psFitsClose(imageFits->data[i]); 431 psFitsClose(maskFits->data[i]); 432 psFitsClose(weightFits->data[i]); 433 } 434 435 if (psMetadataLookupBool(&mdok, config->arguments, "PHOTOMETRY") && 436 !ppStackPhotometry(config, outRO, view)) { 437 psError(PS_ERR_UNKNOWN, false, "Unable to perform photometry on output."); 438 psFree(outRO); 439 psFree(view); 440 return false; 441 } 442 443 // Statistics on output 444 if (stats) { 445 ppStatsFPA(stats, outCell->parent->parent, view, maskBlank, config); 446 } 447 448 // Put version information into the header 449 pmHDU *hdu = pmHDUFromCell(outRO->parent); 450 if (!hdu) { 451 psError(PS_ERR_UNKNOWN, false, "Unable to find HDU for output."); 452 return false; 453 } 454 if (!hdu->header) { 455 hdu->header = psMetadataAlloc(); 456 } 457 ppStackVersionMetadata(hdu->header); 458 459 // Write out the output files 460 fileActivation(config, combineFiles, true); 461 filesIterateUp(config); 462 463 psFree(outRO); 464 psFree(view); 465 } 466 112 467 113 468 // Write out summary statistics
Note:
See TracChangeset
for help on using the changeset viewer.
