Changeset 16605
- Timestamp:
- Feb 22, 2008, 9:28:00 AM (18 years ago)
- Location:
- trunk/ppStack/src
- Files:
-
- 2 added
- 7 edited
-
Makefile.am (modified) (1 diff)
-
ppStack.h (modified) (2 diffs)
-
ppStackArguments.c (modified) (2 diffs)
-
ppStackCamera.c (modified) (3 diffs)
-
ppStackLoop.c (modified) (2 diffs)
-
ppStackMatch.c (modified) (5 diffs)
-
ppStackPSF.c (added)
-
ppStackPhotometry.c (added)
-
ppStackReadout.c (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ppStack/src/Makefile.am
r14626 r16605 9 9 ppStackCamera.c \ 10 10 ppStackLoop.c \ 11 ppStackPSF.c \ 11 12 ppStackReadout.c \ 13 ppStackPhotometry.c \ 12 14 ppStackVersion.c \ 13 15 ppStackMatch.c -
trunk/ppStack/src/ppStack.h
r15844 r16605 19 19 ); 20 20 21 // Determine target PSF for input images 22 pmPSF *ppStackPSF(const pmConfig *config, // Configuration 23 int numCols, int numRows, // Size of image 24 const psList *list // List of input PSFs 25 ); 26 21 27 // Perform stacking on a readout 22 bool ppStackReadout(pmConfig *config, // Configuration 23 const pmFPAview *view // View for readout 28 bool ppStackReadout(const pmConfig *config, // Configuration 29 pmReadout *outRO, // Output readout 30 const psArray *readouts, // Input readouts 31 const psArray *regions, // Array with array of regions used in each PSF matching 32 const psArray *kernels // Array with array of kernels used in each PSF matching 33 ); 34 35 // Perform photometry on stack 36 bool ppStackPhotometry(pmConfig *config, // Configuration 37 const pmReadout *readout, // Readout to be photometered 38 const pmFPAview *view // View to readout 24 39 ); 25 40 … … 35 50 36 51 /// Convolve image to match specified seeing 37 bool ppStackMatch(pmReadout *output, ///< Convolved readout 38 const pmReadout *input, ///< Readout to be convolved 52 bool ppStackMatch(pmReadout *readout, ///< Readout to be convolved; replaced with output 53 psArray **regions, // Array of regions used in each PSF matching, returned 54 psArray **kernels, // Array of kernels used in each PSF matching, returned 39 55 const pmReadout *sourcesRO, ///< Readout with sources 40 56 const pmPSF *psf, ///< Target PSF -
trunk/ppStack/src/ppStackArguments.c
r16015 r16605 116 116 psMetadataAddU8(arguments, PS_LIST_TAIL, "-mask-blank", 0, "Mask value for blank region", 0); 117 117 psMetadataAddF32(arguments, PS_LIST_TAIL, "-threshold-mask", 0, "Threshold for mask deconvolution", NAN); 118 psMetadataAddS32(arguments, PS_LIST_TAIL, "-rows", 0, "Rows to read at once", 128); 118 119 psMetadataAddBool(arguments, PS_LIST_TAIL, "-photometry", 0, "Do photometry on stacked image?", false); 119 120 psMetadataAddS32(arguments, PS_LIST_TAIL, "-psf-instances", 0, "Number of instances for PSF generation", 5); … … 160 161 VALUE_ARG_RECIPE_MASK("-mask-blank", "MASK.BLANK"); 161 162 VALUE_ARG_RECIPE_FLOAT("-threshold-mask", "THRESHOLD.MASK", F32); 163 VALUE_ARG_RECIPE_INT("-rows", "ROWS", S32, 0); 162 164 163 165 VALUE_ARG_RECIPE_INT("-psf-instances", "PSF.INSTANCES", S32, 0); -
trunk/ppStack/src/ppStackCamera.c
r15844 r16605 10 10 11 11 #include "ppStack.h" 12 13 14 #if 0 15 // Define an output convolved image file 16 static pmFPAfile *defineOutputConvolved(const char *name, // FPA file name 17 pmFPA *fpa, // FPA to bind 18 const pmConfig *config, // Configuration 19 pmFPAfileType type // Expected type 20 ) 21 { 22 pmFPAfile *file = pmFPAfileDefineOutput(config, fpa, name); 23 if (!file) { 24 psError(PS_ERR_UNKNOWN, false, "Unable to define output convolved file %s", name); 25 return NULL; 26 } 27 if (file->type != PM_FPA_FILE_IMAGE) { 28 psError(PS_ERR_IO, true, "PPSTACK.OUTCONV is not of type %s", pmFPAfileStringFromType(type)); 29 return NULL; 30 } 31 32 return file; 33 } 34 35 // Define an input convolved image file, using the output as a basis 36 static pmFPAfile *defineInputConvolved(const char *inputName, // Input FPA file name 37 pmFPAfile *outFile, // Corresponding output FPA file 38 pmConfig *config, // Configuration 39 pmFPAfileType type // Expected type 40 ) 41 { 42 pmFPAview *view = pmFPAviewAlloc(0); // View into sky cells 43 view->chip = view->cell = view->readout = 0; 44 45 psString imageName = pmFPANameFromRule(outFile->filerule, outFile->fpa, view); 46 psArray *imageNames = psArrayAlloc(1); 47 imageNames->data[0] = imageName; 48 psMetadataAddArray(config->arguments, PS_LIST_TAIL, "INCONV.FILENAMES", PS_META_REPLACE, 49 "Filenames of input convolved image files", imageNames); 50 psFree(imageNames); 51 bool found = false; // Found the file? 52 pmFPAfile *imageFile = pmFPAfileDefineFromArgs(&found, config, "PPSTACK.INCONV", 53 "INCONV.FILENAMES"); 54 psMetadataRemoveKey(config->arguments, "INCONV.FILENAMES"); 55 if (!imageFile || !found) { 56 psError(PS_ERR_UNKNOWN, false, "Unable to define %s file", inputName); 57 return NULL; 58 } 59 if (imageFile->type != type) { 60 psError(PS_ERR_IO, true, "PPSTACK.INCONV is not of type %s", 61 pmFPAfileStringFromType(type)); 62 return NULL; 63 } 64 65 return imageFile; 66 } 67 #endif 68 69 12 70 13 71 bool ppStackCamera(pmConfig *config) … … 138 196 } 139 197 } 198 199 #if 0 200 // Output convolved files 201 pmFPAfile *outconvImage = defineOutputConvolved("PPSTACK.OUTCONV", imageFile->fpa, config, 202 PM_FPA_FILE_IMAGE); 203 pmFPAfile *outconvMask = defineOutputConvolved("PPSTACK.OUTCONV.MASK", imageFile->fpa, config, 204 PM_FPA_FILE_MASK); 205 pmFPAfile *outconvWeight = defineOutputConvolved("PPSTACK.OUTCONV.WEIGHT", imageFile->fpa, config, 206 PM_FPA_FILE_WEIGHT); 207 if (!outconvImage || !outconvMask || !outconvWeight) { 208 return false; 209 } 210 211 // Input convolved files 212 pmFPAfile *inconvImage = defineInputConvolved("PPSTACK.INCONV", outconvImage, config, 213 PM_FPA_FILE_IMAGE); 214 pmFPAfile *inconvMask = defineInputConvolved("PPSTACK.INCONV.MASK", outconvMask, config, 215 PM_FPA_FILE_MASK); 216 pmFPAfile *inconvWeight = defineInputConvolved("PPSTACK.INCONV.WEIGHT", outconvWeight, config, 217 PM_FPA_FILE_WEIGHT); 218 if (!inconvImage || !inconvMask || !inconvWeight) { 219 return false; 220 } 221 #endif 140 222 141 223 psMetadataAddF32(imageFile->fpa->analysis, PS_LIST_TAIL, "PPSTACK.WEIGHTING", 0, … … 241 323 } 242 324 325 243 326 // Output PSF 244 327 if (havePSFs) { -
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 -
trunk/ppStack/src/ppStackMatch.c
r15850 r16605 9 9 #include "ppStack.h" 10 10 11 #define ARRAY_BUFFER 16 // Number to add to array at a time 12 13 11 14 //#define TESTING 12 15 13 bool ppStackMatch(pmReadout * output, const pmReadout *input, const pmReadout *sourcesRO,14 const pm PSF *psf, const pmConfig *config)16 bool ppStackMatch(pmReadout *readout, psArray **regions, psArray **kernels, 17 const pmReadout *sourcesRO, const pmPSF *psf, const pmConfig *config) 15 18 { 19 assert(readout); 20 assert(regions && !*regions); 21 assert(kernels && !*kernels); 22 assert(sourcesRO); 23 assert(psf); 24 assert(config); 25 16 26 // Look up appropriate values from the ppSub recipe 17 27 bool mdok; // Status of MD lookup … … 68 78 pmReadout *fake = pmReadoutAlloc(NULL); // Fake readout with target PSF 69 79 70 if (!pmReadoutFakeFromSources(fake, input->image->numCols, input->image->numRows, sources, NULL, NULL,80 if (!pmReadoutFakeFromSources(fake, readout->image->numCols, readout->image->numRows, sources, NULL, NULL, 71 81 psf, powf(10.0, -0.4 * maxMag), 0, false)) { 72 82 psError(PS_ERR_UNKNOWN, false, "Unable to generate fake image with target PSF."); … … 85 95 86 96 // Do the image matching 87 if (!pmSubtractionMatch(output, NULL, input, fake, footprint, regionSize, spacing, threshold, 97 pmReadout *output = pmReadoutAlloc(NULL); // Output readout, for holding results temporarily 98 if (!pmSubtractionMatch(output, NULL, readout, fake, footprint, regionSize, spacing, threshold, 88 99 sources, stampsName, type, size, order, widths, orders, inner, ringsOrder, 89 100 binning, optimum, optWidths, optOrder, optThresh, iter, rej, maskBad, … … 92 103 psFree(fake); 93 104 psFree(optWidths); 105 psFree(output); 94 106 return false; 95 107 } … … 97 109 psFree(optWidths); 98 110 111 // Replace original images with convolved 112 psFree(readout->image); 113 psFree(readout->mask); 114 psFree(readout->weight); 115 readout->image = psMemIncrRefCounter(output->image); 116 readout->mask = psMemIncrRefCounter(output->mask); 117 readout->weight = psMemIncrRefCounter(output->weight); 118 119 // Extract the regions and solutions used in the image matching 120 // This stops them from being freed when we iterate back up the FPA 121 *regions = psArrayAllocEmpty(ARRAY_BUFFER); // Array of regions 122 { 123 psString regex = NULL; // Regular expression 124 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_REGION); 125 psMetadataIterator *iter = psMetadataIteratorAlloc(output->analysis, PS_LIST_HEAD, regex); // Iterator 126 psFree(regex); 127 psMetadataItem *item = NULL;// Item from iteration 128 while ((item = psMetadataGetAndIncrement(iter))) { 129 assert(item->type == PS_DATA_REGION); 130 *regions = psArrayAdd(*regions, ARRAY_BUFFER, item->data.V); 131 } 132 psFree(iter); 133 } 134 *kernels = psArrayAllocEmpty(ARRAY_BUFFER); // Array of kernels 135 { 136 psString regex = NULL; // Regular expression 137 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_KERNEL); 138 psMetadataIterator *iter = psMetadataIteratorAlloc(output->analysis, PS_LIST_HEAD, regex); // Iterator 139 psFree(regex); 140 psMetadataItem *item = NULL;// Item from iteration 141 while ((item = psMetadataGetAndIncrement(iter))) { 142 assert(item->type == PS_DATA_UNKNOWN); 143 // Set the normalisation dimensions, since these will be otherwise unavailable when reading the 144 // images by scans. 145 pmSubtractionKernels *kernel = item->data.V; // Kernel used in subtraction 146 kernel->numCols = readout->image->numCols; 147 kernel->numRows = readout->image->numRows; 148 149 *kernels = psArrayAdd(*kernels, ARRAY_BUFFER, kernel); 150 } 151 psFree(iter); 152 } 153 assert((*regions)->n == (*kernels)->n); 154 155 156 psFree(output); 157 99 158 return true; 100 159 } -
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.
