Changeset 27838 for branches/tap_branches/ppStack/src
- Timestamp:
- May 3, 2010, 8:41:49 AM (16 years ago)
- Location:
- branches/tap_branches
- Files:
-
- 28 edited
- 3 copied
-
. (modified) (1 prop)
-
ppStack/src (modified) (1 prop)
-
ppStack/src/Makefile.am (modified) (2 diffs)
-
ppStack/src/ppStack.c (modified) (2 diffs)
-
ppStack/src/ppStack.h (modified) (6 diffs)
-
ppStack/src/ppStackArguments.c (modified) (11 diffs)
-
ppStack/src/ppStackCamera.c (modified) (22 diffs)
-
ppStack/src/ppStackCleanup.c (modified) (5 diffs)
-
ppStack/src/ppStackCombineFinal.c (modified) (4 diffs)
-
ppStack/src/ppStackCombineInitial.c (modified) (8 diffs)
-
ppStack/src/ppStackCombinePrepare.c (modified) (4 diffs)
-
ppStack/src/ppStackConvolve.c (modified) (15 diffs)
-
ppStack/src/ppStackErrorCodes.c.in (copied) (copied from trunk/ppStack/src/ppStackErrorCodes.c.in )
-
ppStack/src/ppStackErrorCodes.dat (copied) (copied from trunk/ppStack/src/ppStackErrorCodes.dat )
-
ppStack/src/ppStackErrorCodes.h.in (copied) (copied from trunk/ppStack/src/ppStackErrorCodes.h.in )
-
ppStack/src/ppStackFiles.c (modified) (5 diffs)
-
ppStack/src/ppStackFinish.c (modified) (2 diffs)
-
ppStack/src/ppStackLoop.c (modified) (7 diffs)
-
ppStack/src/ppStackLoop.h (modified) (3 diffs)
-
ppStack/src/ppStackMatch.c (modified) (26 diffs)
-
ppStack/src/ppStackOptions.c (modified) (4 diffs)
-
ppStack/src/ppStackOptions.h (modified) (2 diffs)
-
ppStack/src/ppStackPSF.c (modified) (4 diffs)
-
ppStack/src/ppStackPhotometry.c (modified) (6 diffs)
-
ppStack/src/ppStackPrepare.c (modified) (12 diffs)
-
ppStack/src/ppStackReadout.c (modified) (16 diffs)
-
ppStack/src/ppStackReject.c (modified) (10 diffs)
-
ppStack/src/ppStackSetup.c (modified) (7 diffs)
-
ppStack/src/ppStackSources.c (modified) (7 diffs)
-
ppStack/src/ppStackThread.c (modified) (10 diffs)
-
ppStack/src/ppStackThread.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/tap_branches
- Property svn:mergeinfo changed
-
branches/tap_branches/ppStack/src
- Property svn:ignore
-
old new 10 10 stamp-h1 11 11 ppStackVersionDefinitions.h 12 ppStackErrorCodes.c 13 ppStackErrorCodes.h
-
- Property svn:ignore
-
branches/tap_branches/ppStack/src/Makefile.am
r23808 r27838 47 47 ppStackCleanup.c \ 48 48 ppStackPhotometry.c \ 49 ppStackFinish.c 49 ppStackFinish.c \ 50 ppStackErrorCodes.c 50 51 51 52 noinst_HEADERS = \ … … 53 54 ppStackLoop.h \ 54 55 ppStackOptions.h \ 55 ppStackThread.h 56 ppStackThread.h \ 57 ppStackErrorCodes.h 56 58 57 CLEANFILES = *~ 59 ### Error codes. 60 BUILT_SOURCES = ppStackErrorCodes.h ppStackErrorCodes.c 61 CLEANFILES = ppStackErrorCodes.h ppStackErrorCodes.c 62 63 ppStackErrorCodes.h : ppStackErrorCodes.dat ppStackErrorCodes.h.in 64 $(ERRORCODES) --data=ppStackErrorCodes.dat --outdir=. ppStackErrorCodes.h 65 66 ppStackErrorCodes.c : ppStackErrorCodes.dat ppStackErrorCodes.c.in ppStackErrorCodes.h 67 $(ERRORCODES) --data=ppStackErrorCodes.dat --outdir=. ppStackErrorCodes.c 68 58 69 59 70 clean-local: -
branches/tap_branches/ppStack/src/ppStack.c
r23341 r27838 15 15 int main(int argc, char *argv[]) 16 16 { 17 ps Exit exitValue = PS_EXIT_SUCCESS; // Exit value17 psLibInit(NULL); 18 18 psTimerStart(TIMER_NAME); 19 19 psTimerStart("PPSTACK_STEPS"); 20 psLibInit(NULL); 20 21 pmErrorRegister(); 22 ppStackErrorRegister(); 23 psphotErrorRegister(); 21 24 22 25 pmConfig *config = pmConfigRead(&argc, argv, PPSTACK_RECIPE); // Configuration 26 ppStackOptions *options = NULL; // Options for stacking 23 27 if (!config) { 24 psErrorStackPrint(stderr, "Error reading configuration.");25 exitValue = PS_EXIT_CONFIG_ERROR;26 goto die;27 }28 29 (void) psTraceSetLevel("ppStack", 5);30 31 if (!ppStackArgumentsSetup(argc, argv, config)) {32 psErrorStackPrint(stderr, "Error reading arguments.\n");33 exitValue = PS_EXIT_CONFIG_ERROR;34 28 goto die; 35 29 } … … 38 32 39 33 if (!pmModelClassInit()) { 40 psErrorStackPrint(stderr, "Error initialising model classes.\n"); 41 exitValue = PS_EXIT_PROG_ERROR; 34 psError(PPSTACK_ERR_PROG, false, "Unable to initialise model classes."); 42 35 goto die; 43 36 } 44 37 45 38 if (!psphotInit()) { 46 psErrorStackPrint(stderr, "Error initialising psphot.\n"); 47 exitValue = PS_EXIT_PROG_ERROR; 39 psError(PPSTACK_ERR_PROG, false, "Error initialising psphot."); 40 goto die; 41 } 42 43 (void)psTraceSetLevel("ppStack", 5); 44 45 if (!ppStackArgumentsSetup(argc, argv, config)) { 48 46 goto die; 49 47 } 50 48 51 49 if (!ppStackCamera(config)) { 52 psErrorStackPrint(stderr, "Error setting up input files.\n");53 exitValue = PS_EXIT_CONFIG_ERROR;54 50 goto die; 55 51 } 56 52 57 53 if (!ppStackArgumentsParse(config)) { 58 psErrorStackPrint(stderr, "Error reading arguments.\n");59 exitValue = PS_EXIT_CONFIG_ERROR;60 54 goto die; 61 55 } 62 56 63 if (!ppStackLoop(config)) { 64 psErrorStackPrint(stderr, "Error performing combination.\n"); 65 exitValue = PS_EXIT_DATA_ERROR; 57 options = ppStackOptionsAlloc(); 58 if (!ppStackLoop(config, options)) { 66 59 goto die; 67 60 } 68 61 69 62 70 // Common code for the death.71 die: 72 psTrace("ppStack", 1, "Finished at %f sec\n", psTimerMark(TIMER_NAME));73 psTimerStop();63 die: 64 // Common code for the death. 65 { 66 psExit exitValue = ppStackExitCode(PS_EXIT_SUCCESS); // Exit code 74 67 75 psFree(config); 76 pmModelClassCleanup(); 77 pmConfigDone(); 78 psLibFinalize(); 79 pmVisualClose(); 80 exit(exitValue); 68 // Ensure everything closes 69 if (config) { 70 ppStackFileActivation(config, PPSTACK_FILES_PREPARE, true); 71 ppStackFileActivation(config, PPSTACK_FILES_CONVOLVE, true); 72 ppStackFileActivation(config, PPSTACK_FILES_STACK, true); 73 ppStackFileActivation(config, PPSTACK_FILES_UNCONV, true); 74 ppStackFileActivation(config, PPSTACK_FILES_PHOT, true); 75 if (!ppStackFilesIterateUp(config)) { 76 psError(psErrorCodeLast(), false, "Unable to close files."); 77 exitValue = ppStackExitCode(exitValue); 78 pmFPAfileFreeSetStrict(false); 79 } 80 } 81 82 // Write out summary statistics 83 if (options && options->stats) { 84 85 psMetadataAddS32(options->stats, PS_LIST_TAIL, "QUALITY", PS_META_REPLACE, 86 "Bad data quality flag", options->quality); 87 psMetadataAddF32(options->stats, PS_LIST_TAIL, "TIME_STACK", 0, 88 "Total time", psTimerClear("PPSTACK_TOTAL")); 89 90 const char *statsMDC = psMetadataConfigFormat(options->stats); 91 if (!statsMDC || strlen(statsMDC) == 0) { 92 psError(PS_ERR_IO, false, "Unable to get statistics MDC file."); 93 return false; 94 } 95 if (fprintf(options->statsFile, "%s", statsMDC) != strlen(statsMDC)) { 96 psError(PS_ERR_IO, false, "Unable to write statistics MDC file."); 97 return false; 98 } 99 psFree(statsMDC); 100 if (fclose(options->statsFile) == EOF) { 101 psError(PS_ERR_IO, false, "Unable to close statistics MDC file."); 102 return false; 103 } 104 options->statsFile = NULL; 105 pmConfigRunFilenameAddWrite(config, "STATS", 106 psMetadataLookupStr(NULL, config->arguments, "STATS")); 107 } 108 psFree(options); 109 110 // Dump configuration 111 bool mdok; // Status of MD lookup 112 psString dump = psMetadataLookupStr(&mdok, config->arguments, "DUMP_CONFIG"); // File for config 113 if (dump && !pmConfigDump(config, dump)) { 114 psError(psErrorCodeLast(), false, "Unable to dump configuration."); 115 exitValue = ppStackExitCode(exitValue); 116 } 117 118 psTrace("ppStack", 1, "Finished at %f sec\n", psTimerMark(TIMER_NAME)); 119 psTimerStop(); 120 121 psFree(config); 122 pmModelClassCleanup(); 123 pmConfigDone(); 124 psLibFinalize(); 125 pmVisualClose(); 126 127 exitValue = ppStackExitCode(exitValue); 128 exit(exitValue); 129 } 81 130 } 82 131 -
branches/tap_branches/ppStack/src/ppStack.h
r23573 r27838 9 9 10 10 #include "ppStackOptions.h" 11 #include "ppStackErrorCodes.h" 11 12 12 13 // Mask values for inputs 13 14 typedef enum { 15 PPSTACK_MASK_NONE = 0x00, // Nothing wrong 14 16 PPSTACK_MASK_CAL = 0x01, // Photometric calibration failed 15 PPSTACK_MASK_MATCH = 0x02, // PSF-matching failed 16 PPSTACK_MASK_CHI2 = 0x04, // Chi^2 too deviant 17 PPSTACK_MASK_REJECT = 0x08, // Rejection failed 18 PPSTACK_MASK_BAD = 0x10, // Bad image (too many pixels rejected) 17 PPSTACK_MASK_PSF = 0x02, // PSF measurement failed 18 PPSTACK_MASK_MATCH = 0x04, // PSF-matching failed 19 PPSTACK_MASK_CHI2 = 0x08, // Chi^2 too deviant 20 PPSTACK_MASK_REJECT = 0x10, // Rejection failed 21 PPSTACK_MASK_BAD = 0x20, // Bad image (too many pixels rejected) 19 22 PPSTACK_MASK_ALL = 0xff // All errors 20 23 } ppStackMask; … … 24 27 PPSTACK_FILES_PREPARE, // Files for preparation 25 28 PPSTACK_FILES_CONVOLVE, // Files for convolution 26 PPSTACK_FILES_COMBINE, // Files for combination 29 PPSTACK_FILES_STACK, // Stack files 30 PPSTACK_FILES_UNCONV, // Unconvolved stack files 27 31 PPSTACK_FILES_PHOT // Files for photometry 28 32 } ppStackFileList; … … 59 63 // Perform stacking on a readout 60 64 // 61 // Returns an array of pixels to inspect for each input image65 // Returns two arrays: pixels to inspect for each input image, and pixels to reject for each input image. 62 66 psArray *ppStackReadoutInitial(const pmConfig *config, // Configuration 63 67 pmReadout *outRO, // Output readout … … 65 69 const psVector *mask, // Mask for input readouts 66 70 const psVector *weightings, // Weighting factors for each image 71 const psVector *exposures, // Exposure time for each image 67 72 const psVector *addVariance // Additional variance for rejection 68 73 ); … … 79 84 bool ppStackReadoutFinal(const pmConfig *config, // Configuration 80 85 pmReadout *outRO, // Output readout 86 pmReadout *expRO, // Exposure readout 81 87 const psArray *readouts, // Input readouts 82 88 const psVector *mask, // Mask for input readouts 83 89 const psArray *rejected, // Array with pixels rejected in each image 84 90 const psVector *weightings, // Weighting factors for each image 85 const psVector *addVariance // Additional variance for rejection 91 const psVector *exposures, // Exposure times for each image 92 const psVector *addVariance, // Additional variance for rejection 93 bool safety, // Enable safety switch? 94 const psVector *norm // Normalisations to apply 86 95 ); 87 96 … … 164 173 ); 165 174 175 /// Return an appropriate exit code based on the error code 176 psExit ppStackExitCode(psExit exitValue); 166 177 167 178 #endif -
branches/tap_branches/ppStack/src/ppStackArguments.c
r23841 r27838 43 43 value = psMetadataLookup##TYPE(&mdok, recipe, RECIPENAME); \ 44 44 if (!mdok) { \ 45 psError(P S_ERR_BAD_PARAMETER_VALUE, true, "Unable to find %s in recipe %s", \45 psError(PPSTACK_ERR_CONFIG, true, "Unable to find %s in recipe %s", \ 46 46 RECIPENAME, PPSTACK_RECIPE); \ 47 47 goto ERROR; \ … … 58 58 value = psMetadataLookup##TYPE(&mdok, recipe, RECIPENAME); \ 59 59 if (!mdok) { \ 60 psError(P S_ERR_BAD_PARAMETER_VALUE, true, "Unable to find %s in recipe %s", \60 psError(PPSTACK_ERR_CONFIG, true, "Unable to find %s in recipe %s", \ 61 61 RECIPENAME, PPSTACK_RECIPE); \ 62 62 goto ERROR; \ … … 73 73 name = psMetadataLookupStr(NULL, recipe, RECIPENAME); \ 74 74 if (!name) { \ 75 psError(P S_ERR_BAD_PARAMETER_VALUE, true, "Unable to find %s in recipe %s", \76 RECIPENAME, PPSTACK_RECIPE);\75 psError(PPSTACK_ERR_CONFIG, true, "Unable to find %s in recipe %s", \ 76 RECIPENAME, PPSTACK_RECIPE); \ 77 77 goto ERROR; \ 78 78 } \ … … 108 108 value = psMetadataLookupStr(NULL, recipe, mdName); 109 109 if (!value) { 110 psError(P S_ERR_BAD_PARAMETER_VALUE, true, "Unable to find %s in recipe %s",110 psError(PPSTACK_ERR_CONFIG, true, "Unable to find %s in recipe %s", 111 111 mdName, PPSTACK_RECIPE); 112 112 return false; … … 148 148 psMetadataAddStr(arguments, PS_LIST_TAIL, "-stamps", 0, "Stamps file with x,y,flux per line", NULL); 149 149 psMetadataAddStr(arguments, PS_LIST_TAIL, "-stats", 0, "Statistics file", NULL); 150 psMetadataAdd S32(arguments, PS_LIST_TAIL, "-iter", 0, "Number of rejection iterations", 0);150 psMetadataAddF32(arguments, PS_LIST_TAIL, "-combine-iter", 0, "Number of rejection iterations per input", NAN); 151 151 psMetadataAddF32(arguments, PS_LIST_TAIL, "-combine-rej", 0, 152 152 "Combination rejection thresold (sigma)", NAN); … … 185 185 psMetadataAddF32(arguments, PS_LIST_TAIL, "-zp-star-sys-1", 0, "Estimated systematic error; pass 1", NAN); 186 186 psMetadataAddF32(arguments, PS_LIST_TAIL, "-zp-star-sys-2", 0, "Estimated systematic error; pass 2", NAN); 187 psMetadataAddStr(arguments, PS_LIST_TAIL, "-temp-dir", 0, "Directory for temporary images", NULL); 187 188 psMetadataAddStr(arguments, PS_LIST_TAIL, "-temp-image", 0, "Suffix for temporary images", NULL); 188 189 psMetadataAddStr(arguments, PS_LIST_TAIL, "-temp-mask", 0, "Suffix for temporary masks", NULL); … … 206 207 psMetadata *inputs = psMetadataConfigRead(NULL, &numBad, argv[argNum], false); // Input file info 207 208 if (!inputs || numBad > 0) { 208 psError(P S_ERR_BAD_PARAMETER_VALUE, false, "Unable to cleanly read MDC file with inputs.");209 psError(PPSTACK_ERR_ARGUMENTS, false, "Unable to cleanly read MDC file with inputs."); 209 210 return false; 210 211 } … … 228 229 int numThreads = psMetadataLookupS32(NULL, arguments, "-threads"); // Number of threads 229 230 if (numThreads > 0 && !psThreadPoolInit(numThreads)) { 230 psError(P S_ERR_UNKNOWN, false, "Unable to setup %d threads", numThreads);231 psError(PPSTACK_ERR_ARGUMENTS, false, "Unable to setup %d threads", numThreads); 231 232 return false; 232 233 } … … 246 247 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // Recipe 247 248 if (!recipe) { 248 psError(P S_ERR_UNEXPECTED_NULL, false, "Unable to find recipe %s", PPSTACK_RECIPE);249 psError(PPSTACK_ERR_CONFIG, false, "Unable to find recipe %s", PPSTACK_RECIPE); 249 250 goto ERROR; 250 251 } 251 252 252 VALUE_ARG_RECIPE_ INT("-iter", "ITER", S32, 0);253 VALUE_ARG_RECIPE_FLOAT("-combine-iter", "COMBINE.ITER", F32); 253 254 VALUE_ARG_RECIPE_FLOAT("-combine-rej", "COMBINE.REJ", F32); 254 255 VALUE_ARG_RECIPE_FLOAT("-combine-sys", "COMBINE.SYS", F32); … … 260 261 VALUE_ARG_RECIPE_FLOAT("-poor-frac", "POOR.FRACTION", F32); 261 262 262 valueArgRecipeStr(arguments, recipe, "-mask-val", "MASK. VAL",recipe);263 valueArgRecipeStr(arguments, recipe, "-mask-val", "MASK.IN", recipe); 263 264 valueArgRecipeStr(arguments, recipe, "-mask-bad", "MASK.BAD", recipe); 264 265 valueArgRecipeStr(arguments, recipe, "-mask-poor", "MASK.POOR", recipe); … … 316 317 317 318 pmConfigCamerasCull(config, NULL); 318 pmConfigRecipesCull(config, "PPSTACK,PPSUB,PPSTATS,PSPHOT, MASKS,JPEG");319 pmConfigRecipesCull(config, "PPSTACK,PPSUB,PPSTATS,PSPHOT,PSASTRO,MASKS,JPEG"); 319 320 320 321 return true; -
branches/tap_branches/ppStack/src/ppStackCamera.c
r25519 r27838 30 30 pmFPAfileDefineFromArgs(&found, config, name, "FILENAMES"); 31 31 if (!file || !found) { 32 psError( PS_ERR_UNKNOWN, false, "Unable to define file %s from %s", name, filename);32 psError(psErrorCodeLast(), false, "Unable to define file %s from %s", name, filename); 33 33 return NULL; 34 34 } 35 35 if (file->type != type) { 36 psError(PS_ERR_IO, true, "%s is not of type %s", name, pmFPAfileStringFromType(type));36 psError(PS_ERR_IO, PPSTACK_ERR_CONFIG, "%s is not of type %s", name, pmFPAfileStringFromType(type)); 37 37 return NULL; 38 38 } … … 53 53 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // Recipe for ppSim 54 54 if (!recipe) { 55 psError(P S_ERR_UNEXPECTED_NULL, false, "Unable to find recipe %s", PPSTACK_RECIPE);55 psError(PPSTACK_ERR_CONFIG, false, "Unable to find recipe %s", PPSTACK_RECIPE); 56 56 return false; 57 57 } … … 67 67 "PPSTACK.INPUT.MASK"); // Input masks 68 68 if (!status) { 69 psError( PS_ERR_UNKNOWN, false, "Unable to define input masks from RUN metadata.");69 psError(psErrorCodeLast(), false, "Unable to define input masks from RUN metadata."); 70 70 psFree(runImages); 71 71 return false; … … 76 76 "PPSTACK.INPUT.VARIANCE"); // Input variances 77 77 if (!status) { 78 psError( PS_ERR_UNKNOWN, false, "Unable to define input variances from RUN metadata.");78 psError(psErrorCodeLast(), false, "Unable to define input variances from RUN metadata."); 79 79 psFree(runImages); 80 80 return false; … … 88 88 "PPSTACK.INPUT.SOURCES"); // Input sources 89 89 if (!status) { 90 psError( PS_ERR_UNKNOWN, false, "Unable to define input sources from RUN metadata.");90 psError(psErrorCodeLast(), false, "Unable to define input sources from RUN metadata."); 91 91 psFree(runImages); 92 92 return false; 93 93 } 94 94 if (!runSrc) { 95 psError(P S_ERR_UNEXPECTED_NULL, true, "Unable to define input sources from RUN metadata.");95 psError(PPSTACK_ERR_CONFIG, true, "Unable to define input sources from RUN metadata."); 96 96 psFree(runImages); 97 97 return false; … … 104 104 "PPSTACK.INPUT.PSF"); // Input PSFs 105 105 if (!status) { 106 psError( PS_ERR_UNKNOWN, false, "Unable to define input PSFs from RUN metadata.");106 psError(psErrorCodeLast(), false, "Unable to define input PSFs from RUN metadata."); 107 107 psFree(runImages); 108 108 return false; … … 118 118 "PPSTACK.CONV.KERNEL"); // Conv'n kernels 119 119 if (!status) { 120 psError(PS_ERR_UNKNOWN, false, "Unable to define convolution kernels from RUN metadata."); 120 psError(psErrorCodeLast(), false, 121 "Unable to define convolution kernels from RUN metadata."); 121 122 psFree(runImages); 122 123 return false; 123 124 } 124 125 if (!runKernel) { 125 psError(P S_ERR_UNEXPECTED_NULL, true,126 psError(PPSTACK_ERR_CONFIG, true, 126 127 "Unable to define convolution kernels from RUN metadata."); 127 128 psFree(runImages); … … 137 138 psMetadata *inputs = psMetadataLookupMetadata(NULL, config->arguments, "INPUTS"); // The inputs info 138 139 if (!inputs) { 139 psError(P S_ERR_UNEXPECTED_NULL, false, "Unable to find inputs.");140 psError(PPSTACK_ERR_ARGUMENTS, false, "Unable to find inputs."); 140 141 return false; 141 142 } … … 145 146 while ((item = psMetadataGetAndIncrement(iter))) { 146 147 if (item->type != PS_DATA_METADATA) { 147 psError(P S_ERR_BAD_PARAMETER_TYPE, true,148 psError(PPSTACK_ERR_ARGUMENTS, true, 148 149 "Component %s of the input metadata is not of type METADATA", item->name); 149 150 psFree(iter); … … 155 156 psString image = psMetadataLookupStr(NULL, input, "IMAGE"); // Name of image 156 157 if (!image || strlen(image) == 0) { 157 psError(P S_ERR_BAD_PARAMETER_VALUE, true, "Component %s lacks IMAGE of type STR", item->name);158 psError(PPSTACK_ERR_ARGUMENTS, true, "Component %s lacks IMAGE of type STR", item->name); 158 159 psFree(iter); 159 160 return false; … … 169 170 image, PM_FPA_FILE_IMAGE); // File for image 170 171 if (!imageFile) { 171 psError( PS_ERR_UNKNOWN, false, "Unable to define file from image %d (%s)", i, image);172 psError(psErrorCodeLast(), false, "Unable to define file from image %d (%s)", i, image); 172 173 return false; 173 174 } … … 175 176 if (mask && strlen(mask) > 0 && 176 177 !defineFile(config, imageFile, "PPSTACK.INPUT.MASK", mask, PM_FPA_FILE_MASK)) { 177 psError( PS_ERR_UNKNOWN, false, "Unable to define file from mask %d (%s)", i, mask);178 psError(psErrorCodeLast(), false, "Unable to define file from mask %d (%s)", i, mask); 178 179 return false; 179 180 } … … 183 184 if (!defineFile(config, imageFile, "PPSTACK.INPUT.VARIANCE", variance, 184 185 PM_FPA_FILE_VARIANCE)) { 185 psError( PS_ERR_UNKNOWN, false,186 psError(psErrorCodeLast(), false, 186 187 "Unable to define file from variance %d (%s)", i, variance); 187 188 return false; … … 195 196 havePSFs = true; 196 197 if (!defineFile(config, imageFile, "PPSTACK.INPUT.PSF", psf, PM_FPA_FILE_PSF)) { 197 psError( PS_ERR_UNKNOWN, false, "Unable to define file from psf %d (%s)", i, psf);198 psError(psErrorCodeLast(), false, "Unable to define file from psf %d (%s)", i, psf); 198 199 return false; 199 200 } 200 201 } 201 202 } else if (havePSFs) { 202 psError(P S_ERR_UNEXPECTED_NULL, true, "Unable to find PSF %d", i);203 psError(PPSTACK_ERR_CONFIG, true, "Unable to find PSF %d", i); 203 204 return false; 204 205 } 205 206 206 207 if (!sources || strlen(sources) == 0) { 207 psError(P S_ERR_UNEXPECTED_NULL, true, "SOURCES not provided for file %d", i);208 psError(PPSTACK_ERR_CONFIG, true, "SOURCES not provided for file %d", i); 208 209 return false; 209 210 } 210 211 if (!defineFile(config, imageFile, "PPSTACK.INPUT.SOURCES", sources, PM_FPA_FILE_CMF)) { 211 psError( PS_ERR_UNKNOWN, false, "Unable to define file from sources %d (%s)",212 psError(psErrorCodeLast(), false, "Unable to define file from sources %d (%s)", 212 213 i, sources); 213 214 return false; … … 217 218 pmFPAfile *kernel = pmFPAfileDefineOutput(config, imageFile->fpa, "PPSTACK.CONV.KERNEL"); 218 219 if (!kernel) { 219 psError(PS_ERR_IO, false, _("Unable to generate output file from PPSTACK.CONV.KERNEL")); 220 psError(psErrorCodeLast(), false, 221 "Unable to generate output file from PPSTACK.CONV.KERNEL"); 220 222 return false; 221 223 } … … 233 235 234 236 // Output image 235 pmFPA * fpa= pmFPAConstruct(config->camera, config->cameraName); // FPA to contain the output236 if (! fpa) {237 psError( PS_ERR_UNEXPECTED_NULL, false, "Unable to construct an FPA from camera configuration.");238 return false; 239 } 240 pmFPAfile *output = pmFPAfileDefineOutput(config, fpa, "PPSTACK.OUTPUT");241 psFree( fpa); // Drop reference237 pmFPA *outFPA = pmFPAConstruct(config->camera, config->cameraName); // FPA to contain the output 238 if (!outFPA) { 239 psError(psErrorCodeLast(), false, "Unable to construct an FPA from camera configuration."); 240 return false; 241 } 242 pmFPAfile *output = pmFPAfileDefineOutput(config, outFPA, "PPSTACK.OUTPUT"); 243 psFree(outFPA); // Drop reference 242 244 if (!output) { 243 psError( PS_ERR_IO, false, _("Unable to generate output file from PPSTACK.OUTPUT"));245 psError(psErrorCodeLast(), false, _("Unable to generate output file from PPSTACK.OUTPUT")); 244 246 return false; 245 247 } 246 248 if (output->type != PM_FPA_FILE_IMAGE) { 247 psError(P S_ERR_IO, true, "PPSTACK.OUTPUT is not of type IMAGE");249 psError(PPSTACK_ERR_CONFIG, true, "PPSTACK.OUTPUT is not of type IMAGE"); 248 250 return false; 249 251 } 250 252 output->save = true; 251 253 252 if (!pmFPAAddSourceFromFormat(fpa, "Stack", output->format)) { 253 psError(PS_ERR_UNKNOWN, false, "Unable to generate output FPA."); 254 psFree(fpa); 254 if (!pmFPAAddSourceFromFormat(outFPA, "Stack", output->format)) { 255 psError(psErrorCodeLast(), false, "Unable to generate output FPA."); 255 256 return false; 256 257 } … … 259 260 pmFPAfile *outMask = pmFPAfileDefineOutput(config, output->fpa, "PPSTACK.OUTPUT.MASK"); 260 261 if (!outMask) { 261 psError( PS_ERR_IO, false, _("Unable to generate output file from PPSTACK.OUTPUT.MASK"));262 psError(psErrorCodeLast(), false, _("Unable to generate output file from PPSTACK.OUTPUT.MASK")); 262 263 return false; 263 264 } 264 265 if (outMask->type != PM_FPA_FILE_MASK) { 265 psError(P S_ERR_IO, true, "PPSTACK.OUTPUT.MASK is not of type MASK");266 psError(PPSTACK_ERR_CONFIG, true, "PPSTACK.OUTPUT.MASK is not of type MASK"); 266 267 return false; 267 268 } … … 272 273 pmFPAfile *outVariance = pmFPAfileDefineOutput(config, output->fpa, "PPSTACK.OUTPUT.VARIANCE"); 273 274 if (!outVariance) { 274 psError( PS_ERR_IO, false, _("Unable to generate output file from PPSTACK.OUTPUT.VARIANCE"));275 psError(psErrorCodeLast(), false, "Unable to generate output file from PPSTACK.OUTPUT.VARIANCE"); 275 276 return false; 276 277 } 277 278 if (outVariance->type != PM_FPA_FILE_VARIANCE) { 278 psError(P S_ERR_IO, true, "PPSTACK.OUTPUT.VARIANCE is not of type VARIANCE");279 psError(PPSTACK_ERR_CONFIG, true, "PPSTACK.OUTPUT.VARIANCE is not of type VARIANCE"); 279 280 return false; 280 281 } … … 282 283 } 283 284 285 286 // Exposure image 287 pmFPA *expFPA = pmFPAConstruct(config->camera, config->cameraName); // FPA to contain the output 288 if (!expFPA) { 289 psError(psErrorCodeLast(), false, "Unable to construct an FPA from camera configuration."); 290 return false; 291 } 292 pmFPAfile *exp = pmFPAfileDefineOutput(config, expFPA, "PPSTACK.OUTPUT.EXP"); 293 psFree(expFPA); // Drop reference 294 if (!exp) { 295 psError(psErrorCodeLast(), false, _("Unable to generate output file from PPSTACK.OUTPUT.EXP")); 296 return false; 297 } 298 if (exp->type != PM_FPA_FILE_IMAGE) { 299 psError(PPSTACK_ERR_CONFIG, true, "PPSTACK.OUTPUT.EXP is not of type IMAGE"); 300 return false; 301 } 302 exp->save = true; 303 304 if (!pmFPAAddSourceFromFormat(expFPA, "Stack", exp->format)) { 305 psError(psErrorCodeLast(), false, "Unable to generate output FPA."); 306 return false; 307 } 308 309 // Exposure numbers 310 pmFPAfile *expNum = pmFPAfileDefineOutput(config, exp->fpa, "PPSTACK.OUTPUT.EXPNUM"); 311 if (!expNum) { 312 psError(psErrorCodeLast(), false, _("Unable to generate output file from PPSTACK.OUTPUT.EXPNUM")); 313 return false; 314 } 315 if (expNum->type != PM_FPA_FILE_MASK) { 316 psError(PPSTACK_ERR_CONFIG, true, "PPSTACK.OUTPUT.EXPNUM is not of type MASK"); 317 return false; 318 } 319 expNum->save = true; 320 321 // Weighted exposure 322 pmFPAfile *expWt = pmFPAfileDefineOutput(config, exp->fpa, "PPSTACK.OUTPUT.EXPWT"); 323 if (!expWt) { 324 psError(psErrorCodeLast(), false, _("Unable to generate output file from PPSTACK.OUTPUT.EXPWT")); 325 return false; 326 } 327 if (expWt->type != PM_FPA_FILE_VARIANCE) { 328 psError(PPSTACK_ERR_CONFIG, true, "PPSTACK.OUTPUT.EXPWT is not of type VARIANCE"); 329 return false; 330 } 331 expWt->save = true; 332 333 284 334 if (havePSFs) { 285 pmFPAfile *targetPSF = pmFPAfileDefineOutput(config, output->fpa, "PPSTACK.TARGET.PSF"); 335 pmFPA *psfFPA = pmFPAConstruct(config->camera, config->cameraName); // FPA to contain PSF 336 if (!psfFPA) { 337 psError(psErrorCodeLast(), false, "Unable to construct an FPA from camera configuration."); 338 return false; 339 } 340 pmFPAfile *targetPSF = pmFPAfileDefineOutput(config, psfFPA, "PPSTACK.TARGET.PSF"); 286 341 if (!targetPSF) { 287 psError(PS_ERR_IO, false, _("Unable to generate output file from PPSTACK.TARGET.PSF")); 288 return false; 289 } 342 psError(psErrorCodeLast(), false, _("Unable to generate output file from PPSTACK.TARGET.PSF")); 343 return false; 344 } 345 psFree(psfFPA); 290 346 if (targetPSF->type != PM_FPA_FILE_PSF) { 291 psError(P S_ERR_IO, true, "PPSTACK.TARGET.PSF is not of type PSF");347 psError(PPSTACK_ERR_CONFIG, true, "PPSTACK.TARGET.PSF is not of type PSF"); 292 348 return false; 293 349 } 294 350 targetPSF->save = true; 295 351 } 352 353 // Unconvolved stack 354 pmFPA *unconvFPA = pmFPAConstruct(config->camera, config->cameraName); // FPA to contain unconvolved output 355 if (!unconvFPA) { 356 psError(psErrorCodeLast(), false, "Unable to construct an FPA from camera configuration."); 357 return false; 358 } 359 pmFPAfile *unConv = pmFPAfileDefineOutput(config, unconvFPA, "PPSTACK.UNCONV"); 360 psFree(unconvFPA); // Drop reference 361 if (!unConv) { 362 psError(psErrorCodeLast(), false, _("Unable to generate output file from PPSTACK.UNCONV")); 363 return false; 364 } 365 if (unConv->type != PM_FPA_FILE_IMAGE) { 366 psError(PPSTACK_ERR_CONFIG, true, "PPSTACK.UNCONV is not of type IMAGE"); 367 return false; 368 } 369 unConv->save = true; 370 371 if (!pmFPAAddSourceFromFormat(unconvFPA, "Stack", unConv->format)) { 372 psError(psErrorCodeLast(), false, "Unable to generate output FPA."); 373 return false; 374 } 375 376 // Unconvolved mask 377 pmFPAfile *unconvMask = pmFPAfileDefineOutput(config, unconvFPA, "PPSTACK.UNCONV.MASK"); 378 if (!unconvMask) { 379 psError(psErrorCodeLast(), false, _("Unable to generate output file from PPSTACK.UNCONV.MASK")); 380 return false; 381 } 382 if (unconvMask->type != PM_FPA_FILE_MASK) { 383 psError(PPSTACK_ERR_CONFIG, true, "PPSTACK.UNCONV.MASK is not of type MASK"); 384 return false; 385 } 386 unconvMask->save = true; 387 388 // Unconvolved variance 389 if (haveVariances) { 390 pmFPAfile *unconvVariance = pmFPAfileDefineOutput(config, unconvFPA, "PPSTACK.UNCONV.VARIANCE"); 391 if (!unconvVariance) { 392 psError(psErrorCodeLast(), false, "Unable to generate output file from PPSTACK.UNCONV.VARIANCE"); 393 return false; 394 } 395 if (unconvVariance->type != PM_FPA_FILE_VARIANCE) { 396 psError(PPSTACK_ERR_CONFIG, true, "PPSTACK.UNCONV.VARIANCE is not of type VARIANCE"); 397 return false; 398 } 399 unconvVariance->save = true; 400 } 401 402 403 // Exposure image 404 pmFPA *unconvExpFPA = pmFPAConstruct(config->camera, config->cameraName); // FPA to contain the output 405 if (!unconvExpFPA) { 406 psError(psErrorCodeLast(), false, "Unable to construct an FPA from camera configuration."); 407 return false; 408 } 409 pmFPAfile *unconvExp = pmFPAfileDefineOutput(config, unconvExpFPA, "PPSTACK.UNCONV.EXP"); 410 psFree(unconvExpFPA); // Drop reference 411 if (!unconvExp) { 412 psError(psErrorCodeLast(), false, _("Unable to generate output file from PPSTACK.UNCONV.EXP")); 413 return false; 414 } 415 if (unconvExp->type != PM_FPA_FILE_IMAGE) { 416 psError(PPSTACK_ERR_CONFIG, true, "PPSTACK.UNCONV.EXP is not of type IMAGE"); 417 return false; 418 } 419 unconvExp->save = true; 420 421 if (!pmFPAAddSourceFromFormat(unconvExpFPA, "Stack", unconvExp->format)) { 422 psError(psErrorCodeLast(), false, "Unable to generate output FPA."); 423 return false; 424 } 425 426 // Exposure numbers 427 pmFPAfile *unconvExpNum = pmFPAfileDefineOutput(config, unconvExp->fpa, "PPSTACK.UNCONV.EXPNUM"); 428 if (!unconvExpNum) { 429 psError(psErrorCodeLast(), false, _("Unable to generate output file from PPSTACK.UNCONV.MASK")); 430 return false; 431 } 432 if (unconvExpNum->type != PM_FPA_FILE_MASK) { 433 psError(PPSTACK_ERR_CONFIG, true, "PPSTACK.UNCONV.EXPNUM is not of type MASK"); 434 return false; 435 } 436 unconvExpNum->save = true; 437 438 // Weighted exposure 439 pmFPAfile *unconvExpWt = pmFPAfileDefineOutput(config, unconvExp->fpa, "PPSTACK.UNCONV.EXPWT"); 440 if (!unconvExpWt) { 441 psError(psErrorCodeLast(), false, _("Unable to generate output file from PPSTACK.UNCONV.EXPWT")); 442 return false; 443 } 444 if (unconvExpWt->type != PM_FPA_FILE_VARIANCE) { 445 psError(PPSTACK_ERR_CONFIG, true, "PPSTACK.UNCONV.EXPWT is not of type VARIANCE"); 446 return false; 447 } 448 unconvExpWt->save = true; 296 449 297 450 // Output JPEGs 298 451 pmFPAfile *jpeg1 = pmFPAfileDefineOutput(config, NULL, "PPSTACK.OUTPUT.JPEG1"); 299 452 if (!jpeg1) { 300 psError( PS_ERR_IO, false, _("Unable to generate output file from PPSTACK.OUTPUT.JPEG1"));453 psError(psErrorCodeLast(), false, _("Unable to generate output file from PPSTACK.OUTPUT.JPEG1")); 301 454 return false; 302 455 } 303 456 if (jpeg1->type != PM_FPA_FILE_JPEG) { 304 psError(P S_ERR_IO, true, "PPSTACK.OUTPUT.JPEG1 is not of type JPEG");457 psError(PPSTACK_ERR_CONFIG, true, "PPSTACK.OUTPUT.JPEG1 is not of type JPEG"); 305 458 return false; 306 459 } … … 308 461 pmFPAfile *jpeg2 = pmFPAfileDefineOutput(config, NULL, "PPSTACK.OUTPUT.JPEG2"); 309 462 if (!jpeg2) { 310 psError( PS_ERR_IO, false, _("Unable to generate output file from PPSTACK.OUTPUT.JPEG2"));463 psError(psErrorCodeLast(), false, _("Unable to generate output file from PPSTACK.OUTPUT.JPEG2")); 311 464 return false; 312 465 } 313 466 if (jpeg2->type != PM_FPA_FILE_JPEG) { 314 psError(P S_ERR_IO, true, "PPSTACK.OUTPUT.JPEG2 is not of type JPEG");467 psError(PPSTACK_ERR_CONFIG, true, "PPSTACK.OUTPUT.JPEG2 is not of type JPEG"); 315 468 return false; 316 469 } … … 323 476 psMetadataLookupBool(&mdok, config->arguments, "-photometry"); // perform photometry 324 477 if (doPhotom) { 325 // This file, PSPHOT.INPUT, is just used as a carrier; output files (eg, PSPHOT.RESID) are defined by326 // psphotDefineFiles478 // This pmFPAfile, PSPHOT.INPUT, is just used as a carrier; output files (eg, 479 // PSPHOT.RESID) are defined by psphotDefineFiles 327 480 pmFPAfile *psphotInput = pmFPAfileDefineFromFPA(config, output->fpa, 1, 1, "PSPHOT.INPUT"); 328 481 if (!psphotInput) { 329 psError(PS_ERR_IO, false, _("Unable to generate output file from PSPHOT.INPUT")); 330 return false; 331 } 482 psError(psErrorCodeLast(), false, _("Unable to generate output file from PSPHOT.INPUT")); 483 return false; 484 } 485 // specify the number of psphot input images 486 psMetadataAddS32 (config->arguments, PS_LIST_TAIL, "PSPHOT.INPUT.NUM", PS_META_REPLACE, "number of inputs", 1); 332 487 333 488 // Define associated psphot input/output files 334 489 if (!psphotDefineFiles(config, psphotInput)) { 335 psError( PSPHOT_ERR_CONFIG, false,490 psError(psErrorCodeLast(), false, 336 491 "Trouble defining the additional input/output files for psphot"); 337 492 return false; … … 341 496 pmFPAfile *outPSF = pmFPAfileDefineOutputFromFile(config, output, "PSPHOT.PSF.SAVE"); 342 497 if (!outPSF) { 343 psError( PS_ERR_IO, false, _("Unable to generate output file from PSPHOT.PSF.SAVE"));498 psError(psErrorCodeLast(), false, _("Unable to generate output file from PSPHOT.PSF.SAVE")); 344 499 return false; 345 500 } 346 501 if (outPSF->type != PM_FPA_FILE_PSF) { 347 psError(P S_ERR_IO, true, "PSPHOT.PSF.SAVE is not of type PSF");502 psError(PPSTACK_ERR_CONFIG, true, "PSPHOT.PSF.SAVE is not of type PSF"); 348 503 return false; 349 504 } -
branches/tap_branches/ppStack/src/ppStackCleanup.c
r23341 r27838 4 4 5 5 #include <stdio.h> 6 #include <unistd.h>7 6 #include <pslib.h> 8 7 #include <psmodules.h> 8 #include <ppStats.h> 9 9 10 10 #include "ppStack.h" 11 11 #include "ppStackLoop.h" 12 13 #define WCS_TOLERANCE 0.001 // Tolerance for WCS14 12 15 13 … … 22 20 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe 23 21 psAssert(recipe, "We've thrown an error on this before."); 24 25 bool mdok; // Status of MD lookup26 bool tempDelete = psMetadataLookupBool(&mdok, recipe, "TEMP.DELETE"); // Delete temporary files?27 22 28 23 #if 0 … … 37 32 #endif 38 33 39 // Close up40 bool wcsDone = false; // Have we done the WCS?41 for (int i = 0; i < options->num; i++) {42 if (options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) {43 continue;44 }45 46 ppStackThread *thread = stack->threads->data[0]; // Representative stack47 pmReadout *inRO = thread->readouts->data[i]; // Template readout48 if (inRO && !wcsDone) {49 // Copy astrometry over50 wcsDone = true;51 pmHDU *inHDU = pmHDUFromCell(inRO->parent); // Template HDU52 pmHDU *outHDU = pmHDUFromCell(options->outRO->parent); // Output HDU53 pmChip *outChip = options->outRO->parent->parent; // Output chip54 pmFPA *outFPA = outChip->parent; // Output FPA55 if (!outHDU || !inHDU) {56 psWarning("Unable to find HDU at FPA level to copy astrometry.");57 } else {58 if (!pmAstromReadWCS(outFPA, outChip, inHDU->header, 1.0)) {59 psErrorClear();60 psWarning("Unable to read WCS astrometry from input FPA.");61 wcsDone = false;62 } else {63 if (!outHDU->header) {64 outHDU->header = psMetadataAlloc();65 }66 if (!pmAstromWriteWCS(outHDU->header, outFPA, outChip, WCS_TOLERANCE)) {67 psErrorClear();68 psWarning("Unable to write WCS astrometry to output FPA.");69 wcsDone = false;70 }71 }72 }73 }74 75 if (tempDelete) {76 psString imageResolved = pmConfigConvertFilename(options->imageNames->data[i],77 config, false, false);78 psString maskResolved = pmConfigConvertFilename(options->maskNames->data[i],79 config, false, false);80 psString varianceResolved = pmConfigConvertFilename(options->varianceNames->data[i],81 config, false, false);82 if (unlink(imageResolved) == -1 || unlink(maskResolved) == -1 ||83 unlink(varianceResolved) == -1) {84 psWarning("Unable to delete temporary files for image %d", i);85 }86 psFree(imageResolved);87 psFree(maskResolved);88 psFree(varianceResolved);89 }90 }91 92 ppStackMemDump("cleanup");93 94 34 // Generate binned JPEGs 95 35 { … … 103 43 pmCell *cell2 = pmFPAfileThisCell(config->files, view, "PPSTACK.OUTPUT.JPEG2"); 104 44 psImageMaskType maskValue = pmConfigMaskGet("BLANK", config); // Bits to mask 45 psFree(view); 105 46 106 47 pmReadout *ro1 = pmReadoutAlloc(cell1), *ro2 = pmReadoutAlloc(cell2); // Binned readouts 107 48 if (!pmReadoutRebin(ro1, options->outRO, maskValue, bin1, bin1) || 108 49 !pmReadoutRebin(ro2, ro1, 0, bin2, bin2)) { 109 psError(P S_ERR_UNKNOWN, false, "Unable to bin output.");50 psError(PPSTACK_ERR_DATA, false, "Unable to bin output."); 110 51 psFree(ro1); 111 52 psFree(ro2); … … 116 57 } 117 58 118 // Put version information into the header 119 pmHDU *hdu = pmHDUFromCell(options->outRO->parent); 120 if (!hdu) { 121 psError(PS_ERR_UNKNOWN, false, "Unable to find HDU for output."); 59 // Statistics on output 60 if (options->stats) { 61 psTrace("ppStack", 1, "Gathering statistics on stacked image....\n"); 62 psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits for bad 63 psImageMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels 64 65 pmFPAview *view = pmFPAviewAlloc(0); // View to readout 66 view->chip = view->cell = view->readout = 0; 67 68 ppStatsFPA(options->stats, options->outRO->parent->parent->parent, view, maskBad, config); 69 70 psFree(view); 71 } 72 73 if (!ppStackFilesIterateUp(config)) { 74 psError(psErrorCodeLast(), false, "Unable to close files."); 122 75 return false; 123 76 } 124 if (!hdu->header) { 125 hdu->header = psMetadataAlloc(); 77 ppStackFileActivation(config, PPSTACK_FILES_STACK, false); 78 ppStackFileActivation(config, PPSTACK_FILES_PHOT, false); 79 80 // Ensure files are freed 81 { 82 options->outRO->data_exists = false; 83 options->outRO->parent->data_exists = false; 84 options->outRO->parent->parent->data_exists = false; 85 psFree(options->outRO); 86 options->outRO = NULL; 87 88 options->expRO->data_exists = false; 89 options->expRO->parent->data_exists = false; 90 options->expRO->parent->parent->data_exists = false; 91 psFree(options->expRO); 92 options->expRO = NULL; 93 94 pmFPAview *view = pmFPAviewAlloc(0);// Pointer into FPA hierarchy 95 view->chip = view->cell = 0; // pmFPAviewFreeData doesn't want to deal with readouts 96 pmFPAfile *jpeg1 = pmFPAfileSelectSingle(config->files, "PPSTACK.OUTPUT.JPEG1", 0); // JPEG file 97 pmFPAviewFreeData(view, jpeg1); 98 pmFPAfile *jpeg2 = pmFPAfileSelectSingle(config->files, "PPSTACK.OUTPUT.JPEG2", 0); // JPEG file 99 pmFPAviewFreeData(view, jpeg2); 100 pmFPAfile *phot = NULL; // Photometry file 101 if (options->photometry) { 102 phot = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT", 0); // Photometry file 103 pmFPAviewFreeData(view, phot); 104 } 105 106 view->readout = 0; 107 pmReadout *ro1 = pmFPAviewThisReadout(view, jpeg1->fpa); // JPEG readout 108 ro1->data_exists = ro1->parent->data_exists = ro1->parent->parent->data_exists = false; 109 pmReadout *ro2 = pmFPAviewThisReadout(view, jpeg2->fpa); // JPEG readout 110 ro2->data_exists = ro2->parent->data_exists = ro2->parent->parent->data_exists = false; 111 if (options->photometry) { 112 pmReadout *ro = pmFPAviewThisReadout(view, phot->fpa); // Photometry readout 113 ro->data_exists = ro->parent->data_exists = ro->parent->parent->data_exists = false; 114 } 115 psFree(view); 126 116 } 127 ppStackVersionHeader(hdu->header);128 117 129 118 return true; -
branches/tap_branches/ppStack/src/ppStackCombineFinal.c
r25096 r27838 10 10 #include "ppStackLoop.h" 11 11 12 bool ppStackCombineFinal(ppStackThreadData *stack, ppStackOptions *options, pmConfig *config) 12 #define WCS_TOLERANCE 0.001 // Tolerance for WCS 13 14 //#define TESTING // Enable test output 15 16 bool ppStackCombineFinal(ppStackThreadData *stack, psArray *covariances, ppStackOptions *options, 17 pmConfig *config, bool safe, bool normalise, bool grow) 13 18 { 14 19 psAssert(stack, "Require stack"); 15 20 psAssert(options, "Require options"); 16 21 psAssert(config, "Require configuration"); 22 23 pmReadout *outRO = options->outRO; // Output readout 24 pmReadout *expRO = options->expRO; // Exposure readout 25 int numCols = outRO->image->numCols, numRows = outRO->image->numRows; // Size of image 26 27 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe 28 psAssert(recipe, "We've thrown an error on this before."); 29 float poorFrac = psMetadataLookupF32(NULL, recipe, "POOR.FRACTION"); // Fraction for "poor" 30 31 // Grow the list of rejected pixels, if desired 32 psArray *reject = psArrayAlloc(options->num); // Pixels rejected for each image 33 for (int i = 0; i < options->num; i++) { 34 if (options->inputMask->data.U8[i]) { 35 continue; 36 } 37 if (grow) { 38 reject->data[i] = pmStackRejectGrow(options->rejected->data[i], numCols, numRows, poorFrac, 39 options->regions->data[i], options->kernels->data[i]); 40 if (!reject->data[i]) { 41 psError(psErrorCodeLast(), false, "Unable to grow rejected pixels for image %d", i); 42 psFree(reject); 43 return false; 44 } 45 } else { 46 reject->data[i] = psMemIncrRefCounter(options->rejected->data[i]); 47 } 48 } 49 50 if (!outRO->mask) { 51 outRO->mask = psImageAlloc(numCols, numRows, PS_TYPE_IMAGE_MASK); 52 } 53 if (!expRO->mask) { 54 expRO->mask = psImageAlloc(numCols, numRows, PS_TYPE_IMAGE_MASK); 55 } 17 56 18 57 stack->lastScan = 0; // Reset read … … 22 61 if (!status) { 23 62 // Something went wrong 24 psError(PS_ERR_UNKNOWN, false, "Unable to read chunk %d", numChunk); 63 psError(psErrorCodeLast(), false, "Unable to read chunk %d", numChunk); 64 psFree(reject); 25 65 return false; 26 66 } … … 33 73 psThreadJob *job = psThreadJobAlloc("PPSTACK_FINAL_COMBINE"); // Job to start 34 74 psArrayAdd(job->args, 1, thread); 75 psArrayAdd(job->args, 1, reject); 35 76 psArrayAdd(job->args, 1, options); 36 77 psArrayAdd(job->args, 1, config); 78 PS_ARRAY_ADD_SCALAR(job->args, safe, PS_TYPE_U8); 79 PS_ARRAY_ADD_SCALAR(job->args, normalise, PS_TYPE_U8); 37 80 if (!psThreadJobAddPending(job)) { 38 81 psFree(job); 82 psFree(reject); 39 83 return false; 40 84 } … … 43 87 44 88 if (!psThreadPoolWait(true)) { 45 psError(PS_ERR_UNKNOWN, false, "Unable to do final combination."); 89 psError(psErrorCodeLast(), false, "Unable to do final combination."); 90 psFree(reject); 46 91 return false; 47 92 } 48 93 94 psFree(reject); 95 49 96 // Sum covariance matrices 50 double sumWeights = 0.0; // Sum of weights 51 for (int i = 0; i < options->num; i++) { 52 if (options->inputMask->data.U8[i]) { 53 psFree(options->covariances->data[i]); 54 options->covariances->data[i] = NULL; 97 if (covariances) { 98 outRO->covariance = psImageCovarianceAverageWeighted(covariances, options->weightings); 99 } else { 100 outRO->covariance = psImageCovarianceNone(); 101 } 102 103 // Propagate WCS 104 bool wcsDone = false; // Have we done the WCS? 105 for (int i = 0; i < options->num && !wcsDone; i++) { 106 if (options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) { 55 107 continue; 56 108 } 57 psKernel *covar = options->covariances->data[i]; // Covariance matrix 58 if (!covar) { 59 continue; 109 110 ppStackThread *thread = stack->threads->data[0]; // Representative stack 111 pmReadout *inRO = thread->readouts->data[i]; // Template readout 112 if (inRO && !wcsDone) { 113 // Copy astrometry over 114 wcsDone = true; 115 pmHDU *inHDU = pmHDUFromCell(inRO->parent); // Template HDU 116 pmHDU *outHDU = pmHDUFromCell(outRO->parent); // Output HDU 117 pmChip *outChip = outRO->parent->parent; // Output chip 118 pmFPA *outFPA = outChip->parent; // Output FPA 119 if (!outHDU || !inHDU) { 120 psWarning("Unable to find HDU at FPA level to copy astrometry."); 121 } else { 122 if (!pmAstromReadWCS(outFPA, outChip, inHDU->header, 1.0)) { 123 psErrorClear(); 124 psWarning("Unable to read WCS astrometry from input FPA."); 125 wcsDone = false; 126 } else { 127 if (!outHDU->header) { 128 outHDU->header = psMetadataAlloc(); 129 } 130 if (!pmAstromWriteWCS(outHDU->header, outFPA, outChip, WCS_TOLERANCE)) { 131 psErrorClear(); 132 psWarning("Unable to write WCS astrometry to output FPA."); 133 wcsDone = false; 134 } 135 } 136 } 60 137 } 61 float weight = options->weightings->data.F32[i]; // Weight to apply62 psBinaryOp(covar->image, covar->image, "*", psScalarAlloc(weight, PS_TYPE_F32));63 sumWeights += weight;64 }65 if (sumWeights > 0.0) {66 pmReadout *outRO = options->outRO; // Output readout67 outRO->covariance = psImageCovarianceSum(options->covariances);68 psBinaryOp(outRO->covariance->image, outRO->covariance->image, "/",69 psScalarAlloc(sumWeights, PS_TYPE_F32));70 psFree(options->covariances); options->covariances = NULL;71 psImageCovarianceTransfer(outRO->variance, outRO->covariance);72 138 } 73 139 140 // Set exposure time correctly 141 { 142 float exptime = 0.0; // Summed exposure time 143 for (int i = 0; i < options->num; i++) { 144 if (options->inputMask->data.U8[i]) { 145 continue; 146 } 147 exptime += options->exposures->data.F32[i]; 148 } 149 150 { 151 psMetadataItem *item = psMetadataLookup(outRO->parent->concepts, "CELL.EXPOSURE"); 152 item->data.F32 = exptime; 153 } 154 { 155 psMetadataItem *item = psMetadataLookup(outRO->parent->parent->parent->concepts, "FPA.EXPOSURE"); 156 item->data.F32 = exptime; 157 } 158 } 159 160 // Put version information into the header 161 pmHDU *hdu = pmHDUFromCell(outRO->parent); 162 if (!hdu) { 163 psError(PPSTACK_ERR_PROG, false, "Unable to find HDU for output."); 164 return false; 165 } 166 if (!hdu->header) { 167 hdu->header = psMetadataAlloc(); 168 } 169 ppStackVersionHeader(hdu->header); 170 171 74 172 #ifdef TESTING 75 pmStackVisualPlotTestImage(outRO->image, "combined_initial.fits"); 76 ppStackWriteImage("combined_final.fits", NULL, outRO->image, config); 173 static int pass = 0; // Pass through 174 psString name = NULL; // Name of file 175 psStringAppend(&name, "combined_image_final_%d.fits", pass); 176 pass++; 177 ppStackWriteImage(name, NULL, outRO->image, config); 178 psStringSubstitute(&name, "mask", "image"); 179 ppStackWriteImage(name, NULL, outRO->mask, config); 180 psStringSubstitute(&name, "variance", "mask"); 181 ppStackWriteImage(name, NULL, outRO->variance, config); 182 psFree(name); 183 184 pmStackVisualPlotTestImage(outRO->image, "combined_image_final.fits"); 77 185 #endif 78 186 -
branches/tap_branches/ppStack/src/ppStackCombineInitial.c
r23767 r27838 10 10 #include "ppStackLoop.h" 11 11 12 //#define TESTING // Enable test output 13 12 14 bool ppStackCombineInitial(ppStackThreadData *stack, ppStackOptions *options, pmConfig *config) 13 15 { … … 18 20 if (!options->convolve) { 19 21 // No need to do initial combination when we haven't convolved 22 // XXX either allocate inspect and rejected here, or do not require them downstream 20 23 return true; 21 24 } … … 34 37 if (!status) { 35 38 // Something went wrong 36 psError( PS_ERR_UNKNOWN, false, "Unable to read chunk %d", numChunk);39 psError(psErrorCodeLast(), false, "Unable to read chunk %d", numChunk); 37 40 return false; 38 41 } … … 54 57 55 58 if (!psThreadPoolWait(false)) { 56 psError( PS_ERR_UNKNOWN, false, "Unable to do initial combination.");59 psError(psErrorCodeLast(), false, "Unable to do initial combination."); 57 60 return false; 58 61 } … … 60 63 // Harvest the jobs, gathering the inspection lists 61 64 options->inspect = psArrayAlloc(options->num); 65 options->rejected = psArrayAlloc(options->num); 62 66 for (int i = 0; i < options->num; i++) { 63 67 if (options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) { … … 65 69 } 66 70 options->inspect->data[i] = psArrayAllocEmpty(numChunk); 71 options->rejected->data[i] = psArrayAllocEmpty(numChunk); 67 72 } 68 73 psThreadJob *job; // Completed job … … 71 76 "Job has incorrect type: %s", job->type); 72 77 psArray *results = job->results; // Results of job 78 psAssert(results->n == 2, "Results array has wrong size!"); 79 psArray *inspect = results->data[0]; // Pixels to inspect 80 psArray *reject = results->data[1]; // Pixels to reject 73 81 for (int i = 0; i < options->num; i++) { 74 82 if (options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) { 75 83 continue; 76 84 } 77 options->inspect->data[i] = psArrayAdd(options->inspect->data[i], 1, results->data[i]); 85 options->inspect->data[i] = psArrayAdd(options->inspect->data[i], 1, inspect->data[i]); 86 options->rejected->data[i] = psArrayAdd(options->rejected->data[i], 1, reject->data[i]); 78 87 } 79 88 psFree(job); … … 83 92 84 93 #ifdef TESTING 85 ppStackWriteImage("combined_initial.fits", NULL, outRO->image, config); 86 pmStackVisualPlotTestImage(outRO->image, "combined_initial.fits"); 94 ppStackWriteImage("combined_image_initial.fits", NULL, options->outRO->image, config); 95 ppStackWriteImage("combined_mask_initial.fits", NULL, options->outRO->mask, config); 96 ppStackWriteImage("combined_variance_initial.fits", NULL, options->outRO->variance, config); 97 98 pmStackVisualPlotTestImage(options->outRO->image, "combined_image_initial.fits"); 87 99 #endif 88 89 psFree(options->matchChi2); options->matchChi2 = NULL;90 91 100 92 101 if (options->stats) { -
branches/tap_branches/ppStack/src/ppStackCombinePrepare.c
r23576 r27838 10 10 #include "ppStackLoop.h" 11 11 12 bool ppStackCombinePrepare(ppStackThreadData *stack, ppStackOptions *options, pmConfig *config) 12 bool ppStackCombinePrepare(const char *outName, const char *expName, 13 ppStackFileList files, ppStackThreadData *stack, 14 ppStackOptions *options, pmConfig *config) 13 15 { 14 16 psAssert(stack, "Require stack"); … … 20 22 ppStackThread *thread = stack->threads->data[0]; // Representative thread 21 23 if (!pmReadoutStackSetOutputSize(&col0, &row0, &numCols, &numRows, thread->readouts)) { 22 psError(P S_ERR_UNKNOWN, false, "problem setting output readout size.");24 psError(PPSTACK_ERR_ARGUMENTS, false, "problem setting output readout size."); 23 25 return false; 24 26 } 25 27 26 28 pmFPAfileActivate(config->files, false, NULL); 27 ppStackFileActivation(config, PPSTACK_FILES_COMBINE, true);29 ppStackFileActivation(config, files, true); 28 30 pmFPAview *view = ppStackFilesIterateDown(config); // View to readout 29 31 if (!view) { … … 31 33 } 32 34 33 pmCell *outCell = pmFPAfileThisCell(config->files, view, "PPSTACK.OUTPUT"); // Output cell 34 options->outRO = pmReadoutAlloc(outCell); // Output readout 35 pmCell *cell = pmFPAfileThisCell(config->files, view, outName); // Output cell 36 options->outRO = pmReadoutAlloc(cell); // Output readout 37 38 pmCell *expCell = pmFPAfileThisCell(config->files, view, expName); // Exposure cell 39 options->expRO = pmReadoutAlloc(expCell); // Output readout 40 35 41 psFree(view); 36 42 … … 39 45 psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits to mask for bad 40 46 psImageMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels 47 41 48 if (!pmReadoutStackDefineOutput(options->outRO, col0, row0, numCols, numRows, true, true, maskBad)) { 42 psError(PS_ERR_UNKNOWN, false, "Unable to prepare output."); 49 psError(PPSTACK_ERR_ARGUMENTS, false, "Unable to prepare output."); 50 return false; 51 } 52 53 if (!pmReadoutStackDefineOutput(options->expRO, col0, row0, numCols, numRows, true, true, 0)) { 54 psError(PPSTACK_ERR_ARGUMENTS, false, "Unable to prepare output."); 43 55 return false; 44 56 } -
branches/tap_branches/ppStack/src/ppStackConvolve.c
r23602 r27838 9 9 #include "ppStack.h" 10 10 #include "ppStackLoop.h" 11 12 //#define TESTING 13 11 14 12 15 // Update the value of a concept … … 39 42 options->weightings = psVectorAlloc(num, PS_TYPE_F32); // Combination weightings for images (1/noise^2) 40 43 psVectorInit(options->weightings, 0.0); 41 options->covariances = psArrayAlloc(num); // Covariance matrices 44 options->origCovars = psArrayAlloc(num); 45 options->convCovars = psArrayAlloc(num); // Covariance matrices 46 47 psVector *renorms = psVectorAlloc(num, PS_TYPE_F32); // Renormalisation values for variances 48 psVectorInit(renorms, NAN); 42 49 43 50 psList *fpaList = psListAlloc(NULL); // List of input FPAs, for concept averaging … … 52 59 pmFPAfileActivate(config->files, false, NULL); 53 60 ppStackFileActivationSingle(config, PPSTACK_FILES_CONVOLVE, true, i); 61 if (options->convolve) { 62 // XXX PPSTACK.CONV.KERNEL not defined unless convolve 63 // pmFPAfileActivate(config->files, true, "PPSTACK.CONV.KERNEL"); 64 pmFPAfileActivateSingle(config->files, true, "PPSTACK.CONV.KERNEL", i); // Activated file 65 } 66 54 67 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPSTACK.INPUT", i); // File of interest 55 68 pmFPAview *view = ppStackFilesIterateDown(config); … … 69 82 } else if (options->numCols != readout->image->numCols || 70 83 options->numRows != readout->image->numRows) { 71 psError(P S_ERR_UNKNOWN, true, "Sizes of input images don't match: %dx%d vs %dx%d",84 psError(PPSTACK_ERR_ARGUMENTS, true, "Sizes of input images don't match: %dx%d vs %dx%d", 72 85 readout->image->numCols, readout->image->numRows, options->numCols, options->numRows); 73 86 psFree(rng); … … 79 92 // Background subtraction, scaling and normalisation is performed automatically by the image matching 80 93 psTimerStart("PPSTACK_MATCH"); 94 options->origCovars->data[i] = psMemIncrRefCounter(readout->covariance); 81 95 if (!ppStackMatch(readout, options, i, config)) { 82 psErrorStackPrint(stderr, "Unable to match image %d --- ignoring.", i); 83 options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= PPSTACK_MASK_MATCH; 84 psErrorClear(); 85 continue; 86 } 87 options->covariances->data[i] = psMemIncrRefCounter(readout->covariance); 96 // XXX many things can cause a failure of ppStackMatch -- should some be handled differently? 97 psErrorCode error = psErrorCodeLast(); // Error code 98 switch (error) { 99 // Fatal errors 100 case PM_ERR_CONFIG: 101 case PPSTACK_ERR_CONFIG: 102 case PPSTACK_ERR_IO: 103 psError(error, false, "Unable to match image %d due to fatal error.", i); 104 return false; 105 // Non-fatal errors 106 case PM_ERR_STAMPS: 107 case PM_ERR_SMALL_AREA: 108 case PPSTACK_ERR_DATA: 109 default: 110 psErrorStackPrint(stderr, "Unable to match image %d --- ignoring.", i); 111 options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= PPSTACK_MASK_MATCH; 112 psErrorClear(); 113 continue; 114 } 115 } 116 options->convCovars->data[i] = psMemIncrRefCounter(readout->covariance); 117 118 float renorm = psMetadataLookupF32(NULL, readout->analysis, PM_READOUT_ANALYSIS_RENORM); 119 if (!isfinite(renorm)) { 120 renorm = 1.0; 121 } 122 renorms->data.F32[i] = renorm; 88 123 89 124 if (options->stats) { … … 114 149 pmHDU *hdu = readout->parent->parent->parent->hdu; // HDU for convolved image 115 150 assert(hdu); 116 ppStackWriteImage(options->imageNames->data[i], hdu->header, readout->image, config); 151 if (!ppStackWriteImage(options->convImages->data[i], hdu->header, readout->image, config)) { 152 psError(PPSTACK_ERR_IO, false, "Unable to write convolved image %d", i); 153 psFree(fpaList); 154 psFree(cellList); 155 psFree(rng); 156 return false; 157 } 117 158 psMetadata *maskHeader = psMetadataCopy(NULL, hdu->header); // Copy of header, for mask 118 159 pmConfigMaskWriteHeader(config, maskHeader); 119 ppStackWriteImage(options->maskNames->data[i], maskHeader, readout->mask, config); 160 if (!ppStackWriteImage(options->convMasks->data[i], maskHeader, readout->mask, config)) { 161 psError(PPSTACK_ERR_IO, false, "Unable to write convolved mask %d", i); 162 psFree(fpaList); 163 psFree(cellList); 164 psFree(rng); 165 psFree(maskHeader); 166 return false; 167 } 120 168 psFree(maskHeader); 121 psImageCovarianceTransfer(readout->variance, readout->covariance); 122 ppStackWriteImage(options->varianceNames->data[i], hdu->header, readout->variance, config); 169 if (!ppStackWriteImage(options->convVariances->data[i], hdu->header, readout->variance, config)) { 170 psError(PPSTACK_ERR_IO, false, "Unable to write convolved variance %d", i); 171 psFree(fpaList); 172 psFree(cellList); 173 psFree(rng); 174 return false; 175 } 123 176 #ifdef TESTING 124 177 { … … 129 182 psFree(name); 130 183 } 184 { 185 int numCols = readout->image->numCols, numRows = readout->image->numRows; 186 psImage *sn = psImageAlloc(numCols, numRows, PS_TYPE_F32); 187 for (int y = 0; y < numRows; y++) { 188 for (int x = 0; x < numCols; x++) { 189 sn->data.F32[y][x] = readout->image->data.F32[y][x] / 190 sqrtf(readout->variance->data.F32[y][x]); 191 } 192 } 193 psString name = NULL; 194 psStringAppend(&name, "signoise_%d.fits", i); 195 ppStackWriteImage(name, hdu->header, sn, config); 196 psFree(name); 197 psFree(sn); 198 } 131 199 #endif 132 200 … … 136 204 psListAdd(fpaList, PS_LIST_TAIL, inCell->parent->parent); 137 205 206 // Correct ZP 207 if (options->matchZPs) { 208 // I think I need to take off the exposure time because we're going to set the new exposure time 209 psMetadataItem *zpItem = psMetadataLookup(inCell->parent->parent->concepts, "FPA.ZP"); 210 zpItem->data.F32 += options->norm->data.F32[i] + 2.5*log10(options->sumExposure); 211 212 psMetadataItem *expItem = psMetadataLookup(inCell->parent->parent->concepts, "FPA.EXPOSURE"); 213 expItem->data.F32 = options->sumExposure; 214 215 expItem = psMetadataLookup(inCell->concepts, "CELL.EXPOSURE"); 216 expItem->data.F32 = options->sumExposure; 217 } 218 138 219 options->cells->data[i] = psMemIncrRefCounter(inCell); 139 220 if (!ppStackFilesIterateUp(config)) { … … 149 230 psFree(rng); 150 231 151 psFree(options->norm); options->norm = NULL;152 232 psFree(options->sourceLists); options->sourceLists = NULL; 153 233 psFree(options->psf); options->psf = NULL; … … 155 235 156 236 if (numGood == 0) { 157 psError(P S_ERR_UNKNOWN, false, "No good images to combine.");237 psError(PPSTACK_ERR_REJECTED, false, "No good images to combine."); 158 238 psFree(fpaList); 159 239 psFree(cellList); … … 167 247 pmFPAview view; // View for output 168 248 view.chip = view.cell = view.readout = 0; 249 169 250 pmCell *outCell = pmFPAfileThisCell(config->files, &view, "PPSTACK.OUTPUT"); // Output cell 170 251 pmFPA *outFPA = outCell->parent->parent; // Output FPA 252 253 pmCell *unconvCell = pmFPAfileThisCell(config->files, &view, "PPSTACK.UNCONV"); // Unconvolved cell 254 pmFPA *unconvFPA = unconvCell->parent->parent; // Unconvolved FPA 255 171 256 pmConceptsAverageFPAs(outFPA, fpaList); 172 257 pmConceptsAverageCells(outCell, cellList, NULL, NULL, true); 258 259 pmConceptsAverageFPAs(unconvFPA, fpaList); 260 pmConceptsAverageCells(unconvCell, cellList, NULL, NULL, true); 261 173 262 psFree(fpaList); 174 263 psFree(cellList); … … 177 266 UPDATE_CONCEPT(outCell, "CELL.EXPOSURE", options->sumExposure); 178 267 UPDATE_CONCEPT(outCell, "CELL.DARKTIME", NAN); 268 UPDATE_CONCEPT(outFPA, "FPA.ZP", options->zp); 269 270 UPDATE_CONCEPT(unconvFPA, "FPA.EXPOSURE", options->sumExposure); 271 UPDATE_CONCEPT(unconvCell, "CELL.EXPOSURE", options->sumExposure); 272 UPDATE_CONCEPT(unconvCell, "CELL.DARKTIME", NAN); 273 UPDATE_CONCEPT(unconvFPA, "FPA.ZP", options->zp); 179 274 } 180 275 … … 191 286 assert(values->n == numGood); 192 287 if (!psVectorSortInPlace(values)) { 193 psError(P S_ERR_UNKNOWN, false, "Unable to sort vector.");288 psError(PPSTACK_ERR_PROG, false, "Unable to sort vector."); 194 289 psFree(values); 195 290 return false; … … 211 306 numGood = 0; // Number of good images 212 307 for (int i = 0; i < num; i++) { 213 if (options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PPSTACK_MASK_ALL) {308 if (options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PPSTACK_MASK_ALL) { 214 309 continue; 215 310 } … … 229 324 230 325 if (numGood == 0) { 231 psError(P S_ERR_UNKNOWN, false, "No good images to combine.");326 psError(PPSTACK_ERR_REJECTED, false, "No good images to combine."); 232 327 return false; 233 328 } 329 330 // Correct chi^2 for renormalisation 331 psBinaryOp(options->matchChi2, options->matchChi2, "/", renorms); 332 for (int i = 0; i < num; i++) { 333 psLogMsg("ppStack", PS_LOG_INFO, "Additional variance for image %d: %f\n", 334 i, options->matchChi2->data.F32[i]); 335 } 336 psFree(renorms); 234 337 235 338 return true; -
branches/tap_branches/ppStack/src/ppStackFiles.c
r23357 r27838 17 17 18 18 /// Files required for the convolution 19 static char *filesConvolve[] = { "PPSTACK.INPUT", "PPSTACK.INPUT.MASK", "PPSTACK.INPUT.VARIANCE", 20 "PPSTACK.CONV.KERNEL", NULL }; 21 22 /// Output files for the combination 23 static char *filesCombine[] = { "PPSTACK.OUTPUT", "PPSTACK.OUTPUT.MASK", "PPSTACK.OUTPUT.VARIANCE", 24 "PPSTACK.OUTPUT.JPEG1", "PPSTACK.OUTPUT.JPEG2", NULL }; 19 static char *filesConvolve[] = { "PPSTACK.INPUT", "PPSTACK.INPUT.MASK", "PPSTACK.INPUT.VARIANCE", NULL }; 20 21 // "PPSTACK.CONV.KERNEL", NULL }; 22 23 /// Regular (convolved) stack files 24 static char *filesStack[] = { "PPSTACK.OUTPUT", "PPSTACK.OUTPUT.MASK", "PPSTACK.OUTPUT.VARIANCE", 25 "PPSTACK.OUTPUT.EXP", "PPSTACK.OUTPUT.EXPNUM", "PPSTACK.OUTPUT.EXPWT", 26 "PPSTACK.OUTPUT.JPEG1", "PPSTACK.OUTPUT.JPEG2", 27 NULL }; 28 /// Unconvolved stack files 29 static char *filesUnconv[] = { "PPSTACK.UNCONV", "PPSTACK.UNCONV.MASK", "PPSTACK.UNCONV.VARIANCE", 30 "PPSTACK.UNCONV.EXP", "PPSTACK.UNCONV.EXPNUM", "PPSTACK.UNCONV.EXPWT", 31 NULL }; 25 32 26 33 /// Files for photometry … … 35 42 case PPSTACK_FILES_PREPARE: return filesPrepare; 36 43 case PPSTACK_FILES_CONVOLVE: return filesConvolve; 37 case PPSTACK_FILES_COMBINE: return filesCombine; 44 case PPSTACK_FILES_STACK: return filesStack; 45 case PPSTACK_FILES_UNCONV: return filesUnconv; 38 46 case PPSTACK_FILES_PHOT: return filesPhot; 39 47 default: … … 113 121 pmFPAview *view = pmFPAviewAlloc(0);// Pointer into FPA hierarchy 114 122 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 123 psError(PPSTACK_ERR_IO, false, "File checks failed."); 115 124 return NULL; 116 125 } 117 126 view->chip = 0; 118 127 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 128 psError(PPSTACK_ERR_IO, false, "File checks failed."); 119 129 return NULL; 120 130 } 121 131 view->cell = 0; 122 132 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 133 psError(PPSTACK_ERR_IO, false, "File checks failed."); 123 134 return NULL; 124 135 } 125 136 view->readout = 0; 126 137 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 138 psError(PPSTACK_ERR_IO, false, "File checks failed."); 127 139 return NULL; 128 140 } … … 139 151 view->chip = view->cell = view->readout = 0; 140 152 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 153 psError(PPSTACK_ERR_IO, false, "File checks failed."); 141 154 return false; 142 155 } 143 156 view->readout = -1; 144 157 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 158 psError(PPSTACK_ERR_IO, false, "File checks failed."); 145 159 return false; 146 160 } 147 161 view->cell = -1; 148 162 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 163 psError(PPSTACK_ERR_IO, false, "File checks failed."); 149 164 return false; 150 165 } 151 166 view->chip = -1; 152 167 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 168 psError(PPSTACK_ERR_IO, false, "File checks failed."); 153 169 return false; 154 170 } … … 170 186 psFits *fits = psFitsOpen(resolved, "w"); 171 187 if (!fits) { 172 psError(P S_ERR_IO, false, "Unable to open FITS file %s to write image.", resolved);188 psError(PPSTACK_ERR_IO, false, "Unable to open FITS file %s to write image.", resolved); 173 189 psFree(resolved); 174 190 return false; 175 191 } 176 192 if (!psFitsWriteImage(fits, header, image, 0, NULL)) { 177 psError(P S_ERR_IO, false, "Unable to write FITS image %s.", resolved);193 psError(PPSTACK_ERR_IO, false, "Unable to write FITS image %s.", resolved); 178 194 psFitsClose(fits); 179 195 psFree(resolved); 180 196 return false; 181 197 } 182 psFitsClose(fits); 198 if (!psFitsClose(fits)) { 199 psError(PPSTACK_ERR_IO, false, "Unable to close FITS image %s.", resolved); 200 psFree(resolved); 201 return false; 202 } 183 203 psFree(resolved); 184 204 return true; -
branches/tap_branches/ppStack/src/ppStackFinish.c
r25847 r27838 4 4 5 5 #include <stdio.h> 6 #include <unistd.h> 6 7 #include <pslib.h> 7 8 #include <psmodules.h> 8 #include <p pStats.h>9 #include <psphot.h> 9 10 10 11 #include "ppStack.h" … … 21 22 psAssert(recipe, "We've thrown an error on this before."); 22 23 23 // Statistics on output 24 if (options->stats) { 25 psTrace("ppStack", 1, "Gathering statistics on stacked image....\n"); 26 psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits for bad 27 psImageMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels 24 bool mdok; // Status of MD lookup 25 bool tempDelete = psMetadataLookupBool(&mdok, recipe, "TEMP.DELETE"); // Delete temporary files? 28 26 29 pmFPAview *view = pmFPAviewAlloc(0); // View to readout 30 view->chip = view->cell = view->readout = 0; 27 // Delete temporary images 28 if (tempDelete && options->convolve) { 29 for (int i = 0; i < options->num; i++) { 30 if (options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) { 31 continue; 32 } 31 33 32 ppStatsFPA(options->stats, options->outRO->parent->parent->parent, view, maskBad, config); 33 34 psFree(view); 35 } 36 37 ppStackMemDump("stats"); 38 39 psFree(options->outRO); options->outRO = NULL; 40 41 // Write out the output files 42 if (!ppStackFilesIterateUp(config)) { 43 return false; 34 psString imageResolved = pmConfigConvertFilename(options->convImages->data[i], 35 config, false, false); 36 psString maskResolved = pmConfigConvertFilename(options->convMasks->data[i], 37 config, false, false); 38 psString varianceResolved = pmConfigConvertFilename(options->convVariances->data[i], 39 config, false, false); 40 if (unlink(imageResolved) == -1 || unlink(maskResolved) == -1 || 41 unlink(varianceResolved) == -1) { 42 psWarning("Unable to delete temporary files for image %d", i); 43 } 44 psFree(imageResolved); 45 psFree(maskResolved); 46 psFree(varianceResolved); 47 } 44 48 } 45 49 46 50 47 // Write out summary statistics 48 if (options->stats) { 49 psMetadataAddF32(options->stats, PS_LIST_TAIL, "TIME_STACK", 0, 50 "Total time", psTimerClear("PPSTACK_TOTAL")); 51 return true; 52 } 51 53 52 const char *statsMDC = psMetadataConfigFormat(options->stats); 53 if (!statsMDC || strlen(statsMDC) == 0) { 54 psError(PS_ERR_IO, false, "Unable to get statistics MDC file.\n"); 55 } else { 56 fprintf(options->statsFile, "%s", statsMDC); 57 } 58 psFree((void *)statsMDC); 59 fclose(options->statsFile); options->statsFile = NULL; 60 pmConfigRunFilenameAddWrite(config, "STATS", psMetadataLookupStr(NULL, config->arguments, "STATS")); 54 55 psExit ppStackExitCode(psExit exitValue) 56 { 57 if (exitValue != PS_EXIT_SUCCESS) { 58 return exitValue; 61 59 } 62 60 63 64 // Dump configuration 65 bool mdok; // Status of MD lookup 66 psString dump = psMetadataLookupStr(&mdok, config->arguments, "DUMP_CONFIG"); // File for config 67 if (dump) { 68 if (!pmConfigDump(config, dump)) { 69 psError(PS_ERR_IO, false, "Unable to dump configuration."); 70 return false; 61 psErrorCode errorCode = psErrorCodeLast(); // Error code 62 if (errorCode != PS_ERR_NONE) { 63 psErrorStackPrint(stderr, "Unable to perform stack."); 64 switch (errorCode) { 65 case PPSTACK_ERR_UNKNOWN: 66 case PS_ERR_UNKNOWN: 67 psLogMsg("ppStack", PS_LOG_WARN, "Unknown error code: %x", errorCode); 68 exitValue = PS_EXIT_UNKNOWN_ERROR; 69 break; 70 case PS_ERR_IO: 71 case PS_ERR_DB_CLIENT: 72 case PS_ERR_DB_SERVER: 73 case PS_ERR_BAD_FITS: 74 case PS_ERR_OS_CALL_FAILED: 75 case PM_ERR_SYS: 76 case PPSTACK_ERR_IO: 77 psLogMsg("ppStack", PS_LOG_WARN, "I/O error code: %x", errorCode); 78 exitValue = PS_EXIT_SYS_ERROR; 79 break; 80 case PS_ERR_BAD_PARAMETER_VALUE: 81 case PS_ERR_BAD_PARAMETER_TYPE: 82 case PS_ERR_BAD_PARAMETER_NULL: 83 case PS_ERR_BAD_PARAMETER_SIZE: 84 case PPSTACK_ERR_ARGUMENTS: 85 case PPSTACK_ERR_CONFIG: 86 psLogMsg("ppStack", PS_LOG_WARN, "Configuration error code: %x", errorCode); 87 exitValue = PS_EXIT_CONFIG_ERROR; 88 break; 89 case PPSTACK_ERR_PSF: 90 case PSPHOT_ERR_PSF: 91 case PM_ERR_STAMPS: 92 case PM_ERR_SMALL_AREA: 93 case PPSTACK_ERR_REJECTED: 94 case PPSTACK_ERR_DATA: 95 psLogMsg("ppStack", PS_LOG_WARN, "Data error code: %x", errorCode); 96 exitValue = PS_EXIT_DATA_ERROR; 97 break; 98 case PS_ERR_UNEXPECTED_NULL: 99 case PS_ERR_PROGRAMMING: 100 case PPSTACK_ERR_NOT_IMPLEMENTED: 101 case PPSTACK_ERR_PROG: 102 psLogMsg("ppStack", PS_LOG_WARN, "Programming error code: %x", errorCode); 103 exitValue = PS_EXIT_PROG_ERROR; 104 break; 105 default: 106 // It's a programming error if we're not dealing with the error correctly 107 psLogMsg("ppStack", PS_LOG_WARN, "Unrecognised error code: %x", errorCode); 108 exitValue = PS_EXIT_PROG_ERROR; 109 break; 71 110 } 72 111 } 73 74 return true; 112 return exitValue; 75 113 } -
branches/tap_branches/ppStack/src/ppStackLoop.c
r25738 r27838 10 10 #include "ppStackLoop.h" 11 11 12 bool ppStackLoop(pmConfig *config) 12 /// Print a summary of the inputs, and return the number of good inputs 13 static int stackSummary(const ppStackOptions *options, // Stack options, with input mask 14 const char *place // Place in code 15 ) 16 { 17 int numGood = 0; // Number of good inputs 18 psString summary = NULL; // Summary of images 19 for (int i = 0; i < options->num; i++) { 20 psString reason = NULL; // Reason for rejecting 21 if (options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i] == 0) { 22 psStringAppend(&reason, " Good."); 23 numGood++; 24 } else { 25 if (options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PPSTACK_MASK_CAL) { 26 psStringAppend(&reason, " Calibration failed."); 27 } 28 if (options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PPSTACK_MASK_PSF) { 29 psStringAppend(&reason, " PSF measurement failed."); 30 } 31 if (options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PPSTACK_MASK_MATCH) { 32 psStringAppend(&reason, " PSF matching failed."); 33 } 34 if (options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PPSTACK_MASK_CHI2) { 35 psStringAppend(&reason, " PSF matching chi^2 deviant."); 36 } 37 if (options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PPSTACK_MASK_REJECT) { 38 psStringAppend(&reason, " Rejection exceeded threshold."); 39 } 40 } 41 psStringAppend(&summary, "Image %d: %s\n", i, reason); 42 psFree(reason); 43 } 44 psLogMsg("ppStack", PS_LOG_INFO, "Summary of images for %s:\n%s", place, summary); 45 psFree(summary); 46 47 return numGood; 48 } 49 50 51 52 bool ppStackLoop(pmConfig *config, ppStackOptions *options) 13 53 { 14 54 assert(config); … … 16 56 psTimerStart("PPSTACK_TOTAL"); 17 57 psTimerStart("PPSTACK_STEPS"); 18 19 ppStackOptions *options = ppStackOptionsAlloc(); // Options for stacking20 58 21 59 // Setup 22 60 psTrace("ppStack", 1, "Setup....\n"); 23 61 if (!ppStackSetup(options, config)) { 24 psError(PS_ERR_UNKNOWN, false, "Unable to setup."); 25 psFree(options); 62 psError(psErrorCodeLast(), false, "Unable to setup."); 26 63 return false; 27 64 } … … 33 70 psTrace("ppStack", 1, "Preparation for stacking: merging sources, determining target PSF....\n"); 34 71 if (!ppStackPrepare(options, config)) { 35 psError(PS_ERR_UNKNOWN, false, "Unable to prepare for stacking."); 36 psFree(options); 72 psError(psErrorCodeLast(), false, "Unable to prepare for stacking."); 37 73 return false; 38 74 } … … 40 76 psTimerClear("PPSTACK_STEPS")); 41 77 ppStackMemDump("prepare"); 42 78 if (options->quality) { 79 // Can't do anything else 80 return true; 81 } 43 82 44 83 // Convolve inputs 45 84 psTrace("ppStack", 1, "Convolving inputs to target PSF....\n"); 46 85 if (!ppStackConvolve(options, config)) { 47 psError(PS_ERR_UNKNOWN, false, "Unable to convolve images."); 48 psFree(options); 86 psError(psErrorCodeLast(), false, "Unable to convolve images."); 49 87 return false; 50 88 } … … 53 91 ppStackMemDump("convolve"); 54 92 93 // Ensure sufficient inputs 94 { 95 int numGood = stackSummary(options, "initial combination"); 96 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe 97 bool safe = psMetadataLookupBool(NULL, recipe, "SAFE"); // Be safe when combining 98 if (safe && numGood <= 1) { 99 psError(PPSTACK_ERR_REJECTED, true, "Insufficient inputs for combination with safety on"); 100 return false; 101 } 102 } 55 103 56 104 // Start threading 57 105 ppStackThreadInit(); 58 ppStackThreadData *stack = ppStackThreadDataSetup(options, config );106 ppStackThreadData *stack = ppStackThreadDataSetup(options, config, true); 59 107 if (!stack) { 60 psError(PS_ERR_IO, false, "Unable to initialise stack threads."); 61 psFree(options); 62 return false; 63 } 64 psFree(options->cells); options->cells = NULL; 108 psError(psErrorCodeLast(), false, "Unable to initialise stack threads."); 109 return false; 110 } 65 111 66 112 // Prepare for combination 67 if (!ppStackCombinePrepare( stack, options, config)) {68 psError(PS_ERR_UNKNOWN, false, "Unable to prepare for combination.");69 ps Free(stack);70 psFree( options);113 if (!ppStackCombinePrepare("PPSTACK.OUTPUT", "PPSTACK.OUTPUT.EXP", PPSTACK_FILES_STACK, 114 stack, options, config)) { 115 psError(psErrorCodeLast(), false, "Unable to prepare for combination."); 116 psFree(stack); 71 117 return false; 72 118 } … … 75 121 psTrace("ppStack", 1, "Initial stack of convolved images....\n"); 76 122 if (!ppStackCombineInitial(stack, options, config)) { 77 psError(PS_ERR_UNKNOWN, false, "Unable to perform initial combination."); 78 psFree(stack); 79 psFree(options); 80 return false; 81 } 82 ppStackMemDump("convolve"); 123 psError(psErrorCodeLast(), false, "Unable to perform initial combination."); 124 psFree(stack); 125 return false; 126 } 127 ppStackMemDump("initial"); 83 128 psLogMsg("ppStack", PS_LOG_INFO, "Stage 3: Make Initial Stack: %f sec", psTimerClear("PPSTACK_STEPS")); 84 129 130 // Done with stack inputs for now 131 for (int i = 0; i < options->num; i++) { 132 pmCellFreeData(options->cells->data[i]); 133 } 134 psFree(stack); 85 135 86 136 // Pixel rejection 87 137 psTrace("ppStack", 1, "Reject pixels....\n"); 88 138 if (!ppStackReject(options, config)) { 89 psError(PS_ERR_UNKNOWN, false, "Unable to reject pixels."); 90 psFree(stack); 91 psFree(options); 139 psError(psErrorCodeLast(), false, "Unable to reject pixels."); 140 psFree(stack); 92 141 return false; 93 142 } 94 143 psLogMsg("ppStack", PS_LOG_INFO, "Stage 4: Pixel Rejection: %f sec", psTimerClear("PPSTACK_STEPS")); 95 ppStackMemDump("reject"); 96 144 145 // Check inputs 146 { 147 int numGood = stackSummary(options, "final combination"); 148 if (numGood <= 0) { 149 psError(PPSTACK_ERR_REJECTED, true, "Insufficient inputs for combination"); 150 return false; 151 } 152 } 153 154 stack = ppStackThreadDataSetup(options, config, true); 155 if (!stack) { 156 psError(psErrorCodeLast(), false, "Unable to initialise stack threads."); 157 return false; 158 } 97 159 98 160 // Final combination 99 161 psTrace("ppStack", 2, "Final stack of convolved images....\n"); 100 if (!ppStackCombineFinal(stack, options, config)) { 101 psError(PS_ERR_UNKNOWN, false, "Unable to perform final combination."); 102 psFree(stack); 103 psFree(options); 162 if (!ppStackCombineFinal(stack, options->convCovars, options, config, false, false, true)) { 163 psError(psErrorCodeLast(), false, "Unable to perform final combination."); 164 psFree(stack); 104 165 return false; 105 166 } … … 107 168 ppStackMemDump("final"); 108 169 170 // Photometry 171 psTrace("ppStack", 1, "Photometering stacked image....\n"); 172 if (!ppStackPhotometry(options, config)) { 173 psError(psErrorCodeLast(), false, "Unable to perform photometry."); 174 return false; 175 } 176 psLogMsg("ppStack", PS_LOG_INFO, "Stage 6: Photometry Analysis: %f sec", psTimerClear("PPSTACK_STEPS")); 177 ppStackMemDump("photometry"); 109 178 110 179 // Clean up 111 180 psTrace("ppStack", 2, "Cleaning up after combination....\n"); 112 181 if (!ppStackCleanup(stack, options, config)) { 113 psError(PS_ERR_UNKNOWN, false, "Unable to clean up."); 114 psFree(stack); 115 psFree(options); 116 return false; 117 } 118 psLogMsg("ppStack", PS_LOG_INFO, "Stage 6: WCS & JPEGS: %f sec", psTimerClear("PPSTACK_STEPS")); 182 psError(psErrorCodeLast(), false, "Unable to clean up."); 183 psFree(stack); 184 return false; 185 } 186 for (int i = 0; i < options->num; i++) { 187 pmCellFreeData(options->cells->data[i]); 188 } 189 psFree(stack); 190 psLogMsg("ppStack", PS_LOG_INFO, "Stage 7: Cleanup, WCS & JPEGS: %f sec", psTimerClear("PPSTACK_STEPS")); 119 191 ppStackMemDump("cleanup"); 120 192 121 psFree(stack); 122 123 124 // Photometry 125 psTrace("ppStack", 1, "Photometering stacked image....\n"); 126 if (!ppStackPhotometry(options, config)) { 127 psError(PS_ERR_UNKNOWN, false, "Unable to perform photometry."); 128 psFree(options); 129 return false; 130 } 131 psLogMsg("ppStack", PS_LOG_INFO, "Stage 7: Photometry Analysis: %f sec", psTimerClear("PPSTACK_STEPS")); 132 ppStackMemDump("photometry"); 133 193 #if 1 194 // Unconvolved stack --- it's cheap to calculate, compared to everything else! 195 if (options->convolve) { 196 // Start threading 197 ppStackThreadData *stack = ppStackThreadDataSetup(options, config, false); 198 if (!stack) { 199 psError(psErrorCodeLast(), false, "Unable to initialise stack threads."); 200 return false; 201 } 202 203 // Prepare for combination 204 if (!ppStackCombinePrepare("PPSTACK.UNCONV", "PPSTACK.UNCONV.EXP", PPSTACK_FILES_UNCONV, 205 stack, options, config)) { 206 psError(psErrorCodeLast(), false, "Unable to prepare for combination."); 207 psFree(stack); 208 return false; 209 } 210 211 psTrace("ppStack", 2, "Stack of unconvolved images....\n"); 212 if (!ppStackCombineFinal(stack, options->origCovars, options, config, 213 false, true, false)) { 214 psError(psErrorCodeLast(), false, "Unable to perform unconvolved combination."); 215 psFree(stack); 216 return false; 217 } 218 psLogMsg("ppStack", PS_LOG_INFO, "Stage 8: Unconvolved Stack: %f sec", psTimerClear("PPSTACK_STEPS")); 219 ppStackMemDump("unconv"); 220 221 if (!ppStackFilesIterateUp(config)) { 222 psError(psErrorCodeLast(), false, "Unable to close files."); 223 psFree(stack); 224 return false; 225 } 226 ppStackFileActivation(config, PPSTACK_FILES_UNCONV, false); 227 options->outRO->data_exists = false; 228 options->outRO->parent->data_exists = false; 229 options->outRO->parent->parent->data_exists = false; 230 psFree(options->outRO); 231 options->outRO = NULL; 232 options->expRO->data_exists = false; 233 options->expRO->parent->data_exists = false; 234 options->expRO->parent->parent->data_exists = false; 235 psFree(options->expRO); 236 options->expRO = NULL; 237 238 for (int i = 0; i < options->num; i++) { 239 pmCellFreeData(options->cells->data[i]); 240 } 241 psFree(stack); 242 } 243 psFree(options->cells); options->cells = NULL; 244 #endif 134 245 135 246 // Finish up 136 247 psTrace("ppStack", 1, "Finishing up....\n"); 137 248 if (!ppStackFinish(options, config)) { 138 psError(PS_ERR_UNKNOWN, false, "Unable to finish up."); 139 psFree(options); 140 return false; 141 } 142 psLogMsg("ppStack", PS_LOG_INFO, "Stage 8: Final output: %f sec", psTimerClear("PPSTACK_STEPS")); 249 psError(psErrorCodeLast(), false, "Unable to finish up."); 250 return false; 251 } 143 252 ppStackMemDump("finish"); 144 253 145 psFree(options);146 254 return true; 147 255 } -
branches/tap_branches/ppStack/src/ppStackLoop.h
r23576 r27838 7 7 #include "ppStackOptions.h" 8 8 #include "ppStackThread.h" 9 #include "ppStack.h" 9 10 10 11 11 12 // Loop over the inputs, doing the combination 12 13 bool ppStackLoop( 13 pmConfig *config // Configuration 14 pmConfig *config, // Configuration 15 ppStackOptions *options // Options for stacking 14 16 ); 15 17 … … 36 38 // Prepare for combination 37 39 bool ppStackCombinePrepare( 40 const char *outName, // Name of output file 41 const char *expName, // Name of exposure file 42 ppStackFileList files, // Files of interest 38 43 ppStackThreadData *stack, // Stack 39 44 ppStackOptions *options, // Options … … 57 62 bool ppStackCombineFinal( 58 63 ppStackThreadData *stack, // Stack 64 psArray *covariances, // Covariances 59 65 ppStackOptions *options, // Options 60 pmConfig *config // Configuration 66 pmConfig *config, // Configuration 67 bool safe, // Allow safe combination? 68 bool norm, // Normalise images? 69 bool grow // Grow rejection masks? 61 70 ); 62 71 -
branches/tap_branches/ppStack/src/ppStackMatch.c
r25467 r27838 18 18 #define COVAR_FRAC 0.01 // Truncation fraction for covariance matrix 19 19 20 // #define TESTING // Enable debugging output20 // #define TESTING // Enable debugging output 21 21 22 22 #ifdef TESTING … … 31 31 psFree(resolved); 32 32 if (!fits) { 33 psError(P S_ERR_IO, false, "Unable to open previously produced image: %s", name);33 psError(PPSTACK_ERR_IO, false, "Unable to open previously produced image: %s", name); 34 34 return false; 35 35 } 36 36 psImage *image = psFitsReadImage(fits, psRegionSet(0,0,0,0), 0); // Image of interest 37 37 if (!image) { 38 psError(P S_ERR_IO, false, "Unable to read previously produced image: %s", name);38 psError(PPSTACK_ERR_IO, false, "Unable to read previously produced image: %s", name); 39 39 psFitsClose(fits); 40 40 return false; … … 115 115 psFree(coords); 116 116 psFree(tree); 117 psFree(x); 118 psFree(y); 117 119 118 120 psLogMsg("ppStack", PS_LOG_INFO, "Filtered out %d of %d sources", numFiltered, numGood); … … 144 146 psMetadataAddU8(psphotRecipe, PS_LIST_TAIL, "MASK.PSPHOT", PS_META_REPLACE, "user-defined mask", maskBad); 145 147 146 psImage *binned = psphot BackgroundModel(ro, config); // Binned background model148 psImage *binned = psphotModelBackgroundReadoutNoFile(ro, config); // Binned background model 147 149 psImageBinning *binning = psMetadataLookupPtr(NULL, ro->analysis, 148 150 "PSPHOT.BACKGROUND.BINNING"); // Binning for model … … 150 152 psImage *unbinned = psImageAlloc(numCols, numRows, PS_TYPE_F32); // Unbinned background model 151 153 if (!psImageUnbin(unbinned, binned, binning)) { 152 psError(PS_ERR_UNKNOWN, false, "Unable to unbin background model"); 154 psError(PPSTACK_ERR_DATA, false, "Unable to unbin background model"); 155 psFree(binned); 153 156 psFree(unbinned); 154 157 return NULL; 155 158 } 156 157 // XXX should these really be here?? (probably not...) 158 // pmFPAfileDropInternal(config->files, "PSPHOT.BACKMDL"); 159 // pmFPAfileDropInternal(config->files, "PSPHOT.BACKMDL.STDEV"); 160 161 return unbinned; 159 psFree(binned); 160 161 return unbinned; 162 162 } 163 163 … … 167 167 ) 168 168 { 169 #if 1 169 170 bool mdok; // Status of metadata lookups 170 171 … … 176 177 int num = psMetadataLookupS32(&mdok, recipe, "RENORM.NUM"); 177 178 if (!mdok) { 178 psError(P S_ERR_BAD_PARAMETER_VALUE, true, "RENORM.NUM is not set in the recipe");179 psError(PPSTACK_ERR_CONFIG, true, "RENORM.NUM is not set in the recipe"); 179 180 return false; 180 181 } 181 182 float minValid = psMetadataLookupF32(&mdok, recipe, "RENORM.MIN"); 182 183 if (!mdok) { 183 psError(P S_ERR_BAD_PARAMETER_VALUE, true, "RENORM.MIN is not set in the recipe");184 psError(PPSTACK_ERR_CONFIG, true, "RENORM.MIN is not set in the recipe"); 184 185 return false; 185 186 } 186 187 float maxValid = psMetadataLookupF32(&mdok, recipe, "RENORM.MAX"); 187 188 if (!mdok) { 188 psError(P S_ERR_BAD_PARAMETER_VALUE, true, "RENORM.MAX is not set in the recipe");189 psError(PPSTACK_ERR_CONFIG, true, "RENORM.MAX is not set in the recipe"); 189 190 return false; 190 191 } … … 192 193 psImageMaskType maskBad = pmConfigMaskGet("BLANK", config); // Bits to mask 193 194 195 psImageCovarianceTransfer(readout->variance, readout->covariance); 194 196 return pmReadoutVarianceRenormalise(readout, maskBad, num, minValid, maxValid); 197 #else 198 return true; 199 #endif 195 200 } 196 201 … … 212 217 int size = psMetadataLookupS32(NULL, ppsub, "KERNEL.SIZE"); // Kernel half-size 213 218 214 psString maskValStr = psMetadataLookupStr(NULL, recipe, "MASK.VAL"); // Name of bits to mask going in219 psString maskValStr = psMetadataLookupStr(NULL, ppsub, "MASK.VAL"); // Name of bits to mask going in 215 220 psImageMaskType maskVal = pmConfigMaskGet(maskValStr, config); // Bits to mask going in to pmSubtractionMatch 216 221 psString maskPoorStr = psMetadataLookupStr(NULL, recipe, "MASK.POOR"); // Name of bits to mask for poor … … 224 229 225 230 if (!pmReadoutMaskNonfinite(readout, maskVal)) { 226 psError( PS_ERR_UNKNOWN, false, "Unable to mask non-finite pixels in readout.");231 psError(psErrorCodeLast(), false, "Unable to mask non-finite pixels in readout."); 227 232 return false; 228 233 } … … 251 256 psFree(resolved); 252 257 if (!fits || !pmReadoutReadSubtractionKernels(conv, fits)) { 253 psError(P S_ERR_IO, false, "Unable to read previously produced kernel");258 psError(PPSTACK_ERR_IO, false, "Unable to read previously produced kernel"); 254 259 psFitsClose(fits); 255 260 return false; … … 257 262 psFitsClose(fits); 258 263 259 if (!readImage(&readout->image, options-> imageNames->data[index], config) ||260 !readImage(&readout->mask, options-> maskNames->data[index], config) ||261 !readImage(&readout->variance, options-> varianceNames->data[index], config)) {262 psError(P S_ERR_IO, false, "Unable to read previously produced image.");264 if (!readImage(&readout->image, options->convImages->data[index], config) || 265 !readImage(&readout->mask, options->convMasks->data[index], config) || 266 !readImage(&readout->variance, options->convVariances->data[index], config)) { 267 psError(PPSTACK_ERR_IO, false, "Unable to read previously produced image."); 263 268 return false; 264 269 } … … 269 274 PM_SUBTRACTION_ANALYSIS_KERNEL); 270 275 271 pmSubtractionAnalysis( readout->analysis, NULL, kernels, region,276 pmSubtractionAnalysis(conv->analysis, NULL, kernels, region, 272 277 readout->image->numCols, readout->image->numRows); 273 278 274 279 psKernel *kernel = pmSubtractionKernel(kernels, 0.0, 0.0, false); // Convolution kernel 280 bool oldThreads = psImageCovarianceSetThreads(true); // Old thread setting 275 281 psKernel *covar = psImageCovarianceCalculate(kernel, readout->covariance); // Covariance matrix 282 psImageCovarianceSetThreads(oldThreads); 276 283 psFree(readout->covariance); 277 284 readout->covariance = covar; … … 292 299 int iter = psMetadataLookupS32(NULL, ppsub, "ITER"); // Rejection iterations 293 300 float rej = psMetadataLookupF32(NULL, ppsub, "REJ"); // Rejection threshold 294 float sysError = psMetadataLookupF32(NULL, ppsub, "SYS"); // Relative systematic error in kernel 301 float kernelError = psMetadataLookupF32(NULL, ppsub, "KERNEL.ERR"); // Relative systematic error in kernel 302 float normFrac = psMetadataLookupF32(NULL, ppsub, "NORM.FRAC"); // Fraction of window for normalisn windw 303 float sysError = psMetadataLookupF32(NULL, ppsub, "SYS.ERR"); // Relative systematic error in images 304 float skyErr = psMetadataLookupF32(NULL, ppsub, "SKY.ERR"); // Additional error in sky 305 float covarFrac = psMetadataLookupF32(NULL, ppsub, "COVAR.FRAC"); // Fraction for covariance calculation 306 295 307 const char *typeStr = psMetadataLookupStr(NULL, ppsub, "KERNEL.TYPE"); // Kernel type 296 308 pmSubtractionKernelsType type = pmSubtractionKernelsTypeFromString(typeStr); // Kernel type … … 309 321 float poorFrac = psMetadataLookupF32(&mdok, ppsub, "POOR.FRACTION"); // Fraction for "poor" 310 322 323 bool scale = psMetadataLookupBool(NULL, ppsub, "SCALE"); // Scale kernel parameters? 324 float scaleRef = psMetadataLookupF32(NULL, ppsub, "SCALE.REF"); // Reference for scaling 325 float scaleMin = psMetadataLookupF32(NULL, ppsub, "SCALE.MIN"); // Minimum for scaling 326 float scaleMax = psMetadataLookupF32(NULL, ppsub, "SCALE.MAX"); // Maximum for scaling 327 if (!isfinite(scaleRef) || !isfinite(scaleMin) || !isfinite(scaleMax)) { 328 psError(PPSTACK_ERR_CONFIG, false, 329 "Scale parameters (SCALE.REF=%f, SCALE.MIN=%f, SCALE.MAX=%f) not set in PPSUB recipe.", 330 scaleRef, scaleMin, scaleMax); 331 return false; 332 } 333 334 311 335 // These values are specified specifically for stacking 312 336 const char *stampsName = psMetadataLookupStr(NULL, config->arguments, "STAMPS");// Stamps filename … … 322 346 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator 323 347 if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal | maskBad, rng)) { 324 psError(P S_ERR_UNKNOWN, false, "Can't measure background for image.");348 psError(PPSTACK_ERR_DATA, false, "Can't measure background for image."); 325 349 psFree(fake); 326 350 psFree(optWidths); … … 338 362 footprint); // Filtered list of sources 339 363 364 bool oldThreads = pmReadoutFakeThreads(true); // Old threading state 340 365 if (!pmReadoutFakeFromSources(fake, readout->image->numCols, readout->image->numRows, 341 366 stampSources, SOURCE_MASK, NULL, NULL, options->psf, 342 367 minFlux, footprint + size, false, true)) { 343 psError(P S_ERR_UNKNOWN, false, "Unable to generate fake image with target PSF.");368 psError(PPSTACK_ERR_DATA, false, "Unable to generate fake image with target PSF."); 344 369 psFree(fake); 345 370 psFree(optWidths); … … 347 372 return false; 348 373 } 374 pmReadoutFakeThreads(oldThreads); 349 375 350 376 fake->mask = psImageCopy(NULL, readout->mask, PS_TYPE_IMAGE_MASK); 351 377 378 #if 1 352 379 // Add the background into the target image 353 380 psImage *bgImage = stackBackgroundModel(readout, config); // Image of background 354 381 psBinaryOp(fake->image, fake->image, "+", bgImage); 355 382 psFree(bgImage); 383 #endif 356 384 357 385 #ifdef TESTING … … 379 407 380 408 if (threads > 0) { 381 pmSubtractionThreadsInit( readout, fake);409 pmSubtractionThreadsInit(); 382 410 } 383 411 … … 387 415 if (kernel) { 388 416 if (!pmSubtractionMatchPrecalc(NULL, conv, fake, readout, readout->analysis, 389 stride, sysError, maskVal, maskBad, maskPoor,417 stride, kernelError, covarFrac, maskVal, maskBad, maskPoor, 390 418 poorFrac, badFrac)) { 391 psError( PS_ERR_UNKNOWN, false, "Unable to convolve images.");419 psError(psErrorCodeLast(), false, "Unable to convolve images."); 392 420 psFree(fake); 393 421 psFree(optWidths); … … 395 423 psFree(conv); 396 424 if (threads > 0) { 397 pmSubtractionThreadsFinalize( readout, fake);425 pmSubtractionThreadsFinalize(); 398 426 } 399 427 return false; 400 428 } 401 429 } else { 402 if (!pmSubtractionMatch(NULL, conv, fake, readout, footprint, stride, regionSize, spacing, 403 threshold, stampSources, stampsName, type, size, order, widths, 404 orders, inner, ringsOrder, binning, penalty, 405 optimum, optWidths, optOrder, optThresh, iter, rej, sysError, 406 maskVal, maskBad, maskPoor, poorFrac, badFrac, 407 PM_SUBTRACTION_MODE_2)) { 408 psError(PS_ERR_UNKNOWN, false, "Unable to match images."); 430 // Scale the input parameters 431 psVector *widthsCopy = psVectorCopy(NULL, widths, PS_TYPE_F32); // Copy of kernel widths 432 if (scale && !pmSubtractionParamsScale(&size, &footprint, widthsCopy, 433 options->inputSeeing->data.F32[index], 434 options->targetSeeing, scaleRef, scaleMin, scaleMax)) { 435 psError(psErrorCodeLast(), false, "Unable to scale kernel parameters"); 409 436 psFree(fake); 410 437 psFree(optWidths); 411 438 psFree(stampSources); 412 439 psFree(conv); 440 psFree(widthsCopy); 413 441 if (threads > 0) { 414 pmSubtractionThreadsFinalize( readout, fake);442 pmSubtractionThreadsFinalize(); 415 443 } 416 444 return false; 417 445 } 418 } 446 447 if (!pmSubtractionMatch(NULL, conv, fake, readout, footprint, stride, regionSize, spacing, 448 threshold, stampSources, stampsName, type, size, order, widthsCopy, 449 orders, inner, ringsOrder, binning, penalty, 450 optimum, optWidths, optOrder, optThresh, iter, rej, normFrac, 451 sysError, skyErr, kernelError, covarFrac, maskVal, maskBad, maskPoor, 452 poorFrac, badFrac, PM_SUBTRACTION_MODE_2)) { 453 psError(psErrorCodeLast(), false, "Unable to match images."); 454 psFree(fake); 455 psFree(optWidths); 456 psFree(stampSources); 457 psFree(conv); 458 psFree(widthsCopy); 459 if (threads > 0) { 460 pmSubtractionThreadsFinalize(); 461 } 462 return false; 463 } 464 psFree(widthsCopy); 465 } 466 419 467 420 468 #ifdef TESTING … … 447 495 448 496 if (threads > 0) { 449 pmSubtractionThreadsFinalize( readout, fake);497 pmSubtractionThreadsFinalize(); 450 498 } 451 499 … … 487 535 while ((item = psMetadataGetAndIncrement(iter))) { 488 536 assert(item->type == PS_DATA_UNKNOWN); 489 // Set the normalisation dimensions, since these will be otherwise unavailable when reading490 // the images by scans.491 537 pmSubtractionKernels *kernel = item->data.V; // Kernel used in subtraction 492 kernel->numCols = readout->image->numCols;493 kernel->numRows = readout->image->numRows;494 495 538 kernels = psArrayAdd(kernels, ARRAY_BUFFER, kernel); 496 539 } … … 518 561 } 519 562 563 // Kernel normalisation 564 { 565 double sum = 0.0; // Sum of chi^2 566 int num = 0; // Number of measurements of chi^2 567 psString regex = NULL; // Regular expression 568 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_NORM); 569 psMetadataIterator *iter = psMetadataIteratorAlloc(conv->analysis, PS_LIST_HEAD, regex); 570 psFree(regex); 571 psMetadataItem *item = NULL;// Item from iteration 572 while ((item = psMetadataGetAndIncrement(iter))) { 573 assert(item->type == PS_TYPE_F32); 574 float norm = item->data.F32; // Normalisation 575 sum += norm; 576 num++; 577 } 578 psFree(iter); 579 float conv = sum/num; // Mean normalisation from convolution 580 float stars = powf(10.0, -0.4 * options->norm->data.F32[index]); // Normalisation from stars 581 float renorm = stars / conv; // Renormalisation to apply 582 psLogMsg("ppStack", PS_LOG_INFO, "Renormalising image %d by %f (kernel: %f, stars: %f)\n", 583 index, renorm, conv, stars); 584 psBinaryOp(readout->image, readout->image, "*", psScalarAlloc(renorm, PS_TYPE_F32)); 585 psBinaryOp(readout->variance, readout->variance, "*", psScalarAlloc(PS_SQR(renorm), PS_TYPE_F32)); 586 } 587 520 588 // Reject image completely if the maximum deconvolution fraction exceeds the limit 521 589 float deconv = psMetadataLookupF32(NULL, conv->analysis, 522 590 PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Max deconvolution fraction 523 591 if (deconv > deconvLimit) { 524 psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting \n",525 deconv, deconvLimit );592 psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting image %d\n", 593 deconv, deconvLimit, index); 526 594 psFree(conv); 527 595 return NULL; … … 542 610 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator 543 611 if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal | maskBad, rng)) { 544 psWarning("Can't measure background for image.");545 psErrorClear();612 psWarning("Can't measure background for image."); 613 psErrorClear(); 546 614 } else { 547 if (!psMetadataLookupBool(NULL, config->arguments, "PPSTACK.SKIP.BG.SUB")) {548 psLogMsg("ppStack", PS_LOG_INFO, "Correcting convolved image background by %lf (+/- %lf)",549 psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), psStatsGetValue(bg, PS_STAT_ROBUST_STDEV));550 (void)psBinaryOp(readout->image, readout->image, "-",551 psScalarAlloc(psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), PS_TYPE_F32));552 }615 if (!psMetadataLookupBool(NULL, config->arguments, "PPSTACK.SKIP.BG.SUB")) { 616 psLogMsg("ppStack", PS_LOG_INFO, "Correcting convolved image background by %lf (+/- %lf)", 617 psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), psStatsGetValue(bg, PS_STAT_ROBUST_STDEV)); 618 (void)psBinaryOp(readout->image, readout->image, "-", 619 psScalarAlloc(psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), PS_TYPE_F32)); 620 } 553 621 } 554 622 … … 560 628 561 629 // Measure the variance level for the weighting 562 if (!psImageBackground(bg, NULL, readout->variance, readout->mask, maskVal | maskBad, rng)) { 563 psError(PS_ERR_UNKNOWN, false, "Can't measure mean variance for image."); 564 psFree(rng); 565 psFree(bg); 566 return false; 567 } 568 options->weightings->data.F32[index] = 1.0 / (psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN) * 569 psImageCovarianceFactor(readout->covariance)); 570 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "PPSTACK.WEIGHTING", 0, 571 "Weighting by 1/noise^2 for stack", options->weightings->data.F32[index]); 630 if (psMetadataLookupBool(NULL, recipe, "WEIGHTS")) { 631 if (!psImageBackground(bg, NULL, readout->variance, readout->mask, maskVal | maskBad, rng)) { 632 psError(PPSTACK_ERR_DATA, false, "Can't measure mean variance for image."); 633 psFree(rng); 634 psFree(bg); 635 return false; 636 } 637 options->weightings->data.F32[index] = 1.0 / (psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN) * 638 psImageCovarianceFactor(readout->covariance)); 639 } else { 640 options->weightings->data.F32[index] = 1.0; 641 } 642 psLogMsg("ppStack", PS_LOG_INFO, "Weighting for image %d is %f\n", 643 index, options->weightings->data.F32[index]); 572 644 573 645 psFree(rng); -
branches/tap_branches/ppStack/src/ppStackOptions.c
r23573 r27838 12 12 fclose(options->statsFile); 13 13 } 14 psFree(options->imageNames); 15 psFree(options->maskNames); 16 psFree(options->varianceNames); 14 psFree(options->origImages); 15 psFree(options->origMasks); 16 psFree(options->origVariances); 17 psFree(options->origCovars); 18 psFree(options->convImages); 19 psFree(options->convMasks); 20 psFree(options->convVariances); 17 21 psFree(options->psf); 22 psFree(options->inputSeeing); 23 psFree(options->exposures); 18 24 psFree(options->inputMask); 19 25 psFree(options->sourceLists); 20 26 psFree(options->norm); 27 psFree(options->sources); 21 28 psFree(options->cells); 22 29 psFree(options->kernels); … … 24 31 psFree(options->matchChi2); 25 32 psFree(options->weightings); 26 psFree(options->co variances);33 psFree(options->convCovars); 27 34 psFree(options->outRO); 35 psFree(options->expRO); 28 36 psFree(options->inspect); 29 37 psFree(options->rejected); … … 37 45 38 46 options->convolve = true; 47 options->matchZPs = true; 48 options->photometry = false; 39 49 options->stats = NULL; 40 50 options->statsFile = NULL; 41 options->imageNames = NULL; 42 options->maskNames = NULL; 43 options->varianceNames = NULL; 51 options->origImages = NULL; 52 options->origMasks = NULL; 53 options->origVariances = NULL; 54 options->origCovars = NULL; 55 options->convImages = NULL; 56 options->convMasks = NULL; 57 options->convVariances = NULL; 44 58 options->num = 0; 59 options->quality = 0; 45 60 options->psf = NULL; 61 options->sumExposure = NAN; 62 options->zp = NAN; 63 options->inputSeeing = NULL; 64 options->exposures = NULL; 65 options->targetSeeing = NAN; 46 66 options->inputMask = NULL; 47 67 options->sourceLists = NULL; 48 68 options->norm = NULL; 69 options->sources = NULL; 49 70 options->cells = NULL; 50 71 options->kernels = NULL; … … 54 75 options->matchChi2 = NULL; 55 76 options->weightings = NULL; 56 options->co variances = NULL;77 options->convCovars = NULL; 57 78 options->outRO = NULL; 79 options->expRO = NULL; 58 80 options->inspect = NULL; 59 81 options->rejected = NULL; -
branches/tap_branches/ppStack/src/ppStackOptions.h
r23573 r27838 9 9 // Setup 10 10 bool convolve; // Convolve images? 11 bool matchZPs; // Adjust relative fluxes based on transparency analysis? 12 bool photometry; // Perform photometry? 11 13 psMetadata *stats; // Statistics for output 12 14 FILE *statsFile; // File to which to write statistics 13 psArray *imageNames, *maskNames, *varianceNames; // Filenames for the temporary convolved images 15 psArray *origImages, *origMasks, *origVariances; // Filenames of the original images 16 psArray *convImages, *convMasks, *convVariances; // Filenames for the temporary convolved images 17 psArray *origCovars; // Original covariances matrices 14 18 int num; // Number of inputs 19 int quality; // Bad data quality flag 15 20 // Prepare 16 21 pmPSF *psf; // Target PSF 22 psVector *inputSeeing; // Input seeing FWHMs 23 float targetSeeing; // Target seeing FWHM 24 psVector *exposures; // Exposure times 17 25 float sumExposure; // Sum of exposure times 26 float zp; // Zero point for output 18 27 psVector *inputMask; // Mask for inputs 19 28 psArray *sourceLists; // Individual lists of sources for matching 20 29 psVector *norm; // Normalisation for each image 30 psArray *sources; // Matched sources 21 31 // Convolve 22 32 psArray *cells; // Cells for convolved images --- a handle for reading again … … 26 36 psVector *matchChi2; // chi^2 for stamps from matching 27 37 psVector *weightings; // Combination weightings for images (1/noise^2) 28 psArray *co variances; // Covariance matrices38 psArray *convCovars; // Convolved covariance matrices 29 39 // Combine initial 30 40 pmReadout *outRO; // Output readout 41 pmReadout *expRO; // Exposure readout 31 42 psArray *inspect; // Array of arrays of pixels to inspect 32 43 // Rejection -
branches/tap_branches/ppStack/src/ppStackPSF.c
r25480 r27838 14 14 const psArray *psfs, const psVector *inputMask) 15 15 { 16 bool mdok = false; 17 16 18 #ifndef TESTING 17 19 // Get the recipe values … … 24 26 int psfOrder = psMetadataLookupS32(NULL, recipe, "PSF.ORDER"); // Spatial order for PSF 25 27 28 psString maskValStr = psMetadataLookupStr(&mdok, recipe, "MASK.VAL"); // Name of bits to mask going in 29 if (!mdok || !maskValStr) { 30 psError(PPSTACK_ERR_CONFIG, false, "Unable to find MASK.VAL in recipe"); 31 return false; 32 } 33 psImageMaskType maskVal = pmConfigMaskGet(maskValStr, config); // Bits to mask 34 26 35 for (int i = 0; i < psfs->n; i++) { 27 36 if (inputMask->data.U8[i]) { … … 32 41 33 42 // Solve for the target PSF 34 pmPSF *psf = pmPSFEnvelope(numCols, numRows, psfs, psfInstances, psfRadius, psfModel, 35 psfOrder, psfOrder); 43 pmPSF *psf = pmPSFEnvelope(numCols, numRows, psfs, psfInstances, psfRadius, psfModel, psfOrder, psfOrder, maskVal); 36 44 if (!psf) { 37 psError(P S_ERR_UNKNOWN, false, "Unable to determine output PSF.");45 psError(PPSTACK_ERR_PSF, false, "Unable to determine output PSF."); 38 46 return NULL; 39 47 } … … 42 50 pmPSF *psf = pmPSFBuildSimple("PS_MODEL_PS1_V1", 4.0, 4.0, 0.0, 1.0); 43 51 if (!psf) { 44 psError(P S_ERR_UNKNOWN, false, "Unable to build dummy PSF.");52 psError(PPSTACK_ERR_PSF, false, "Unable to build dummy PSF."); 45 53 return NULL; 46 54 } -
branches/tap_branches/ppStack/src/ppStackPhotometry.c
r24216 r27838 19 19 psAssert(recipe, "We've thrown an error on this before."); 20 20 21 bool mdok; // Status of MD lookup 22 if (!psMetadataLookupBool(&mdok, recipe, "PHOTOMETRY")) { 21 if (!options->photometry) { 23 22 // Nothing to do 24 23 return true; … … 27 26 psTimerStart("PPSTACK_PHOT"); 28 27 29 p pStackFileActivation(config, PPSTACK_FILES_COMBINE, false);28 pmFPAfileActivate(config->files, false, NULL); 30 29 ppStackFileActivation(config, PPSTACK_FILES_PHOT, true); 31 30 pmFPAview *photView = ppStackFilesIterateDown(config); // View to readout 32 ppStackFileActivation(config, PPSTACK_FILES_ COMBINE, true);31 ppStackFileActivation(config, PPSTACK_FILES_STACK, true); 33 32 34 33 pmFPAfile *photFile = psMetadataLookupPtr(NULL, config->files, "PSPHOT.INPUT"); // File for photometry … … 60 59 "Bits to use for mark", markValue); 61 60 62 pmCell *sourcesCell = pmFPAfileThisCell(config->files, photView, "PPSTACK.OUTPUT"); 63 psArray *inSources = psMetadataLookupPtr(NULL, sourcesCell->analysis, "PSPHOT.SOURCES"); 61 psArray *inSources = options->sources; 64 62 if (!inSources) { 65 psError(P S_ERR_UNKNOWN, false, "Unable to find input sources");63 psError(PPSTACK_ERR_PROG, false, "Unable to find input sources"); 66 64 psFree(photView); 67 65 return false; 68 66 } 69 67 68 pmModelClassSetLimits(PM_MODEL_LIMITS_LAX); 70 69 if (!psphotReadoutKnownSources(config, photView, inSources)) { 71 70 // This is likely a data quality issue … … 73 72 psErrorStackPrint(stderr, "Unable to perform photometry on image"); 74 73 psWarning("Unable to perform photometry on image --- suspect bad data quality."); 75 if (options->stats && psMetadataLookupS32(NULL, options->stats, "QUALITY") == 0) { 76 psMetadataAddS32(options->stats, PS_LIST_TAIL, "QUALITY", PS_META_REPLACE, 77 "Unable to perform photometry on image", psErrorCodeLast()); 74 if (options->quality == 0) { 75 options->quality = psErrorCodeLast(); 78 76 } 79 77 psErrorClear(); … … 84 82 !pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL.STDEV") || 85 83 !pmFPAfileDropInternal (config->files, "PSPHOT.BACKGND")) { 86 psError(P S_ERR_UNKNOWN, false, "Unable to drop PSPHOT internal files.");84 psError(PPSTACK_ERR_PROG, false, "Unable to drop PSPHOT internal files."); 87 85 return false; 88 86 } … … 92 90 if (options->stats) { 93 91 pmReadout *photRO = pmFPAviewThisReadout(photView, photFile->fpa); // Readout with the sources 94 psArray *sources = psMetadataLookupPtr(NULL, photRO->analysis, "PSPHOT.SOURCES"); // Sources 95 psMetadataAddS32(options->stats, PS_LIST_TAIL, "NUM_SOURCES", 0, 96 "Number of sources detected", sources ? sources->n : 0); 97 psMetadataAddF32(options->stats, PS_LIST_TAIL, "TIME_PHOT", 0, 98 "Time to do photometry", psTimerMark("PPSTACK_PHOT")); 92 pmDetections *detections = psMetadataLookupPtr(NULL, photRO->analysis, "PSPHOT.DETECTIONS"); // detections 93 if (detections && detections->allSources) { 94 psMetadataAddS32(options->stats, PS_LIST_TAIL, "NUM_SOURCES", 0, "Number of sources detected", detections->allSources->n); 95 } else { 96 psMetadataAddS32(options->stats, PS_LIST_TAIL, "NUM_SOURCES", 0, "Number of sources detected", 0); 97 } 98 psMetadataAddF32(options->stats, PS_LIST_TAIL, "TIME_PHOT", 0, "Time to do photometry", psTimerMark("PPSTACK_PHOT")); 99 99 } 100 100 101 psFree(photView); 101 102 -
branches/tap_branches/ppStack/src/ppStackPrepare.c
r23573 r27838 26 26 float zpRadius = psMetadataLookupS32(&mdok, recipe, "PHOT.RADIUS"); // Radius for PHOT measurement 27 27 if (!mdok) { 28 psError(P S_ERR_UNKNOWN, true, "Unable to find PHOT.RADIUS in recipe");28 psError(PPSTACK_ERR_CONFIG, true, "Unable to find PHOT.RADIUS in recipe"); 29 29 return false; 30 30 } 31 31 float zpSigma = psMetadataLookupF32(&mdok, recipe, "PHOT.SIGMA"); // Gaussian sigma for photometry 32 32 if (!mdok) { 33 psError(P S_ERR_UNKNOWN, true, "Unable to find PHOT.SIGMA in recipe");33 psError(PPSTACK_ERR_CONFIG, true, "Unable to find PHOT.SIGMA in recipe"); 34 34 return false; 35 35 } 36 36 float zpFrac = psMetadataLookupF32(&mdok, recipe, "PHOT.FRAC"); // Fraction of good pixels for photometry 37 37 if (!mdok) { 38 psError(P S_ERR_UNKNOWN, true, "Unable to find PHOT.FRAC in recipe");38 psError(PPSTACK_ERR_CONFIG, true, "Unable to find PHOT.FRAC in recipe"); 39 39 return false; 40 40 } … … 42 42 psString maskValStr = psMetadataLookupStr(&mdok, recipe, "MASK.VAL"); // Name of bits to mask going in 43 43 if (!mdok || !maskValStr) { 44 psError(P S_ERR_UNKNOWN, false, "Unable to find MASK.VAL in recipe");44 psError(PPSTACK_ERR_CONFIG, false, "Unable to find MASK.VAL in recipe"); 45 45 return false; 46 46 } … … 53 53 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics 54 54 if (!psImageBackground(stats, NULL, image, mask, maskVal, rng)) { 55 psError(P S_ERR_UNKNOWN, false, "Unable to measure background for image");55 psError(PPSTACK_ERR_DATA, false, "Unable to measure background for image"); 56 56 psFree(stats); 57 57 psFree(rng); … … 126 126 options->inputMask = psVectorAlloc(num, PS_TYPE_VECTOR_MASK); // Mask for inputs 127 127 psVectorInit(options->inputMask, 0); 128 options->exposures = psVectorAlloc(options->num, PS_TYPE_F32); 129 psVectorInit(options->exposures, NAN); 128 130 129 131 pmFPAfileActivate(config->files, false, NULL); … … 134 136 } 135 137 136 psMetadataIterator *fileIter = psMetadataIteratorAlloc(config->files, PS_LIST_HEAD, "^PPSTACK.INPUT$");137 psMetadataItem *fileItem; // Item from iteration138 138 psArray *psfs = psArrayAlloc(num); // PSFs for PSF envelope 139 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 140 options->sumExposure = 0.0; 141 for (int i = 0; i < num; i++) { 142 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPSTACK.INPUT", i); // File of interest 143 pmCell *cell = pmFPAviewThisCell(view, file->fpa); // Cell of interest 144 145 options->exposures->data.F32[i] = psMetadataLookupF32(NULL, cell->concepts, "CELL.EXPOSURE"); 146 options->sumExposure += options->exposures->data.F32[i]; 144 147 145 148 // Get list of PSFs, to determine target PSF 146 149 if (options->convolve) { 147 pmChip *chip = pmFPAviewThisChip(view, inputFile->fpa); // The chip: holds the PSF150 pmChip *chip = pmFPAviewThisChip(view, file->fpa); // The chip: holds the PSF 148 151 pmPSF *psf = psMetadataLookupPtr(NULL, chip->analysis, "PSPHOT.PSF"); // PSF 149 152 if (!psf) { 150 psError(PS_ERR_UNKNOWN, false, "Unable to find PSF."); 151 psFree(view); 152 psFree(fileIter); 153 psError(PPSTACK_ERR_PROG, false, "Unable to find PSF."); 154 psFree(view); 153 155 psFree(psfs); 154 156 return false; 155 157 } 156 psfs->data[i ndex] = psMemIncrRefCounter(psf);158 psfs->data[i] = psMemIncrRefCounter(psf); 157 159 psMetadataRemoveKey(chip->analysis, "PSPHOT.PSF"); 158 160 159 pmCell *cell = pmFPAviewThisCell(view, inputFile->fpa); // Cell of interest161 pmCell *cell = pmFPAviewThisCell(view, file->fpa); // Cell of interest 160 162 pmHDU *hdu = pmHDUFromCell(cell); 161 163 assert(hdu && hdu->header); … … 163 165 int naxis2 = psMetadataLookupS32(NULL, hdu->header, "NAXIS2"); // Number of rows 164 166 if (naxis1 <= 0 || naxis2 <= 0) { 165 psError(PS_ERR_UNKNOWN, false, "Unable to determine size of image from PSF."); 166 psFree(view); 167 psFree(fileIter); 167 psError(PPSTACK_ERR_PROG, false, "Unable to determine size of image from PSF."); 168 psFree(view); 168 169 psFree(psfs); 169 170 return false; … … 176 177 177 178 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); 179 bool redoPhot = psMetadataLookupBool(NULL, recipe, "PHOT"); 180 181 pmDetections *detections = NULL; 182 if (options->convolve || options->matchZPs || options->photometry || redoPhot) { 183 pmReadout *ro = pmFPAviewThisReadout(view, file->fpa); // Readout with sources 184 detections = psMetadataLookupPtr(NULL, ro->analysis, "PSPHOT.DETECTIONS"); // Sources 185 if (!detections || !detections->allSources) { 186 psWarning("No detections found for image %d --- rejecting.", i); 187 options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PPSTACK_MASK_CAL; 188 continue; 189 } 190 psAssert (detections->allSources, "missing sources?"); 191 192 options->sourceLists->data[i] = psMemIncrRefCounter(detections->allSources); 193 } 185 194 186 195 // 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", i ndex, num);196 if (redoPhot) { 197 psTrace("ppStack", 2, "Photometering input %d of %d....\n", i, num); 189 198 pmFPAfileActivate(config->files, false, NULL); 190 ppStackFileActivationSingle(config, PPSTACK_FILES_CONVOLVE, true, index); 191 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPSTACK.INPUT", index); // File 199 ppStackFileActivationSingle(config, PPSTACK_FILES_CONVOLVE, true, i); 200 if (options->convolve) { 201 pmFPAfileActivate(config->files, true, "PPSTACK.CONV.KERNEL"); 202 } 203 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPSTACK.INPUT", i); // File 192 204 pmFPAview *photView = ppStackFilesIterateDown(config); 193 205 if (!photView) { … … 198 210 pmReadout *ro = pmFPAviewThisReadout(view, file->fpa); // Readout of interest 199 211 200 if (!ppStackInputPhotometer(ro, sources, config)) {201 psError( PS_ERR_UNKNOWN, false, "Unable to do photometry on input sources");212 if (!ppStackInputPhotometer(ro, detections->allSources, config)) { 213 psError(psErrorCodeLast(), false, "Unable to do photometry on input sources"); 202 214 psFree(view); 203 215 psFree(photView); … … 213 225 ppStackFileActivation(config, PPSTACK_FILES_PREPARE, true); 214 226 } 215 216 index++; 217 } 218 psFree(fileIter); 227 } 228 229 psString log = psStringCopy("Input seeing FWHMs:\n"); // Log message 230 bool havePSFs = false; // Do we have any PSFs? 231 options->inputSeeing = psVectorAlloc(num, PS_TYPE_F32); 232 psVectorInit(options->inputSeeing, NAN); 233 for (int i = 0; i < num; i++) { 234 pmPSF *psf = psfs->data[i]; // PSF for image 235 if (!psf) { 236 continue; 237 } 238 havePSFs = true; 239 240 int xNum = PS_MAX(psf->trendNx, 1), yNum = PS_MAX(psf->trendNy, 1); // Number of realisations 241 double sumFWHM = 0.0; // FWHM for image 242 int numFWHM = 0; // Number of FWHM measurements 243 for (int y = 0; y < yNum; y++) { 244 float yPos = ((float)y + 0.5) / (float)yNum * numRows; 245 for (int x = 0; x < xNum; x++) { 246 float xPos = ((float)x + 0.5) / (float)xNum * numCols; 247 float fwhm = pmPSFtoFWHM(psf, xPos, yPos); // FWHM for image 248 if (isfinite(fwhm)) { 249 sumFWHM += fwhm; 250 numFWHM++; 251 } 252 } 253 } 254 if (numFWHM == 0) { 255 options->inputSeeing->data.F32[i] = NAN; 256 options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PPSTACK_MASK_PSF; 257 psLogMsg("ppStack", PS_LOG_INFO, "Unable to measure PSF FWHM for image %d --- rejected.", i); 258 } else { 259 options->inputSeeing->data.F32[i] = sumFWHM / (float)numFWHM; 260 } 261 262 psStringAppend(&log, "Input %d: %f\n", i, options->inputSeeing->data.F32[i]); 263 } 264 if (havePSFs) { 265 psLogMsg("ppStack", PS_LOG_INFO, "%s", log); 266 } 267 psFree(log); 219 268 220 269 // Generate target PSF … … 223 272 psFree(psfs); 224 273 if (!options->psf) { 225 psError( PS_ERR_UNKNOWN, false, "Unable to determine output PSF.");274 psError(psErrorCodeLast(), false, "Unable to determine output PSF."); 226 275 psFree(view); 227 276 return false; … … 229 278 psMetadataAddPtr(config->arguments, PS_LIST_TAIL, "PSF.TARGET", PS_DATA_UNKNOWN, 230 279 "Target PSF for stack", options->psf); 231 232 pmChip *outChip = pmFPAfileThisChip(config->files, view, "PPSTACK.OUTPUT"); // Output chip 280 options->targetSeeing = pmPSFtoFWHM(options->psf, 0.5 * numCols, 0.5 * numRows); // FWHM for target 281 psLogMsg("ppStack", PS_LOG_INFO, "Target seeing FWHM: %f\n", options->targetSeeing); 282 283 pmChip *outChip = pmFPAfileThisChip(config->files, view, "PPSTACK.TARGET.PSF"); // Output chip 233 284 psMetadataAddPtr(outChip->analysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_DATA_UNKNOWN, 234 285 "Target PSF", options->psf); … … 238 289 // Zero point calibration 239 290 if (!ppStackSourcesTransparency(options, view, config)) { 240 psError(P S_ERR_UNKNOWN, false, "Unable to calculate transparency differences");291 psError(PPSTACK_ERR_DATA, false, "Unable to calculate transparency differences"); 241 292 psFree(view); 242 293 return false; -
branches/tap_branches/ppStack/src/ppStackReadout.c
r23577 r27838 23 23 psVector *mask = options->inputMask; // Mask for inputs 24 24 psVector *weightings = options->weightings; // Weightings (1/noise^2) for each image 25 psVector *exposures = options->exposures; // Exposure times for each image 25 26 psVector *addVariance = options->matchChi2; // Additional variance when rejecting 26 27 27 psArray *inspect = ppStackReadoutInitial(config, outRO, thread->readouts, mask, 28 weightings, addVariance); 29 30 job->results = inspect; 28 job->results = ppStackReadoutInitial(config, outRO, thread->readouts, mask, 29 weightings, exposures, addVariance); 31 30 thread->busy = false; 32 31 33 return inspect? true : false;32 return job->results ? true : false; 34 33 } 35 34 … … 40 39 psArray *args = job->args; // Arguments 41 40 ppStackThread *thread = args->data[0]; // Thread 42 ppStackOptions *options = args->data[1]; // Options 43 pmConfig *config = args->data[2]; // Configuration 44 45 pmReadout *outRO = options->outRO; // Output readout 41 psArray *reject = args->data[1]; // Rejected pixels for each image 42 ppStackOptions *options = args->data[2]; // Options 43 pmConfig *config = args->data[3]; // Configuration 44 bool safety = PS_SCALAR_VALUE(args->data[4], U8); // Safety switch on? 45 bool normalise = PS_SCALAR_VALUE(args->data[5], U8); // Normalise images? 46 46 47 psVector *mask = options->inputMask; // Mask for inputs 47 psArray *rejected = options->rejected; // Rejected pixels48 48 psVector *weightings = options->weightings; // Weightings (1/noise^2) for each image 49 psVector *exposures = options->exposures; // Exposure times for each image 49 50 psVector *addVariance = options->matchChi2; // Additional variance when rejecting 50 51 bool status = ppStackReadoutFinal(config, outRO, thread->readouts, mask, rejected, 52 weightings, addVariance); // Status of operation 51 psVector *norm = normalise ? options->norm : NULL; // Normalisations to apply to images 52 53 bool status = ppStackReadoutFinal(config, options->outRO, options->expRO, thread->readouts, mask, reject, 54 weightings, exposures, addVariance, safety, norm); // Status of operation 53 55 54 56 thread->busy = false; 55 57 58 psAssert(status, "Stacking failed."); 59 56 60 return status; 57 61 } … … 63 67 64 68 psArray *args = job->args; // Input arguments 65 psArray *inspect = args->data[0]; // Array of pixel arrays 66 int index = PS_SCALAR_VALUE(args->data[1], S32); // Index of interest 67 68 psArray *inputs = inspect->data[index]; // Array of interest 69 psPixels *output = NULL; // Output pixel list 70 for (int i = 0; i < inputs->n; i++) { 71 psPixels *input = inputs->data[i]; // Input pixel list 72 if (!input || input->n == 0) { 73 continue; 74 } 75 output = psPixelsConcatenate(output, input); 76 } 77 78 if (!output) { 79 // If there are no pixels to inspect, then just fake it 80 output = psPixelsAllocEmpty(0); 81 } 82 83 psFree(inputs); 84 inspect->data[index] = output; 69 psArray *inspects = args->data[0]; // Array of pixel arrays 70 psArray *rejects = args->data[1]; // Array of pixel arrays 71 int index = PS_SCALAR_VALUE(args->data[2], S32); // Index of interest 72 73 psArray *inInspects = inspects->data[index]; // Array of interest 74 psArray *inRejects = rejects->data[index]; // Array of interest 75 psAssert(inInspects->n == inRejects->n, "Size should be the same"); 76 psPixels *outInspect = NULL, *outReject = NULL; // Output pixel lists 77 for (int i = 0; i < inInspects->n; i++) { 78 psPixels *inInspect = inInspects->data[i]; // Input pixel list 79 if (inInspect && inInspect->n > 0) { 80 outInspect = psPixelsConcatenate(outInspect, inInspect); 81 } 82 psPixels *inReject = inRejects->data[i]; // Input pixel list 83 if (inReject && inReject->n > 0) { 84 outReject = psPixelsConcatenate(outReject, inReject); 85 } 86 } 87 88 // If there are no pixels to inspect, then just fake it 89 if (!outInspect) { 90 outInspect = psPixelsAllocEmpty(0); 91 } 92 if (!outReject) { 93 outReject = psPixelsAllocEmpty(0); 94 } 95 96 psFree(inspects->data[index]); 97 inspects->data[index] = outInspect; 98 psFree(rejects->data[index]); 99 rejects->data[index] = outReject; 85 100 86 101 return true; … … 89 104 90 105 psArray *ppStackReadoutInitial(const pmConfig *config, pmReadout *outRO, const psArray *readouts, 91 const psVector *mask, const psVector *weightings, const psVector *addVariance) 106 const psVector *mask, const psVector *weightings, const psVector *exposures, 107 const psVector *addVariance) 92 108 { 93 109 assert(config); … … 104 120 105 121 bool mdok; // Status of MD lookup 106 int iter = psMetadataLookupS32(NULL, recipe, "ITER"); // Rejection iterations122 float iter = psMetadataLookupF32(NULL, recipe, "COMBINE.ITER"); // Rejection iterations 107 123 float combineRej = psMetadataLookupF32(NULL, recipe, "COMBINE.REJ"); // Combination threshold 108 124 float combineSys = psMetadataLookupF32(NULL, recipe, "COMBINE.SYS"); // Combination systematic error … … 116 132 psString maskValStr = psMetadataLookupStr(NULL, recipe, "MASK.VAL"); // Name of bits to mask going in 117 133 psImageMaskType maskVal = pmConfigMaskGet(maskValStr, config); // Bits to mask going in to pmSubtractionMatch 134 psString maskSuspectStr = psMetadataLookupStr(NULL, recipe, "MASK.SUSPECT"); // Name of suspect mask bits 135 psImageMaskType maskSuspect = pmConfigMaskGet(maskSuspectStr, config); // Suspect bits 118 136 psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits to mask for bad 119 137 psImageMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels … … 129 147 } 130 148 131 #if 0132 // This doesn't seem to work, so getting the weightings directly from a vector133 float weighting = psMetadataLookupF32(&mdok, ro->analysis, "PPSTACK.WEIGHTING"); // Relative weight134 if (!mdok || !isfinite(weighting)) {135 psWarning("No weighting supplied for image %d --- set to unity.", i);136 weighting = 1.0;137 } else {138 psLogMsg("ppStack", PS_LOG_INFO, "Weighting for image %d is %f", i, weighting);139 }140 #endif141 142 149 // Ensure there is a mask, or pmStackCombine will complain 143 150 if (!ro->mask) { … … 146 153 } 147 154 148 stack->data[i] = pmStackDataAlloc(ro, weightings->data.F32[i], addVariance->data.F32[i]); 149 } 150 151 if (!pmStackCombine(outRO, stack, maskVal | maskBad, maskBad, kernelSize, iter, 152 combineRej, combineSys, combineDiscard, true, useVariance, safe, false)) { 155 stack->data[i] = pmStackDataAlloc(ro, weightings->data.F32[i], exposures->data.F32[i], 156 addVariance->data.F32[i]); 157 } 158 159 if (!pmStackCombine(outRO, NULL, stack, maskVal | maskBad, maskSuspect, maskBad, kernelSize, iter, 160 combineRej, combineSys, combineDiscard, useVariance, safe, false)) { 153 161 psError(PS_ERR_UNKNOWN, false, "Unable to combine input readouts with rejection."); 154 162 psFree(stack); … … 156 164 } 157 165 158 // Save list of pixels to inspect166 // Save lists of pixels 159 167 psArray *inspect = psArrayAlloc(num); // List of pixels to inspect 168 psArray *reject = psArrayAlloc(num); // List of pixels rejected 160 169 for (int i = 0; i < num; i++) { 161 170 pmStackData *data = stack->data[i]; // Data for this image … … 168 177 } 169 178 inspect->data[i] = psMemIncrRefCounter(data->inspect); 179 reject->data[i] = psMemIncrRefCounter(data->reject); 170 180 } 171 181 psFree(stack); … … 173 183 sectionNum++; 174 184 175 return inspect; 176 } 177 178 179 180 bool ppStackReadoutFinal(const pmConfig *config, pmReadout *outRO, const psArray *readouts, 185 psArray *results = psArrayAlloc(2); // Array of results 186 results->data[0] = inspect; 187 results->data[1] = reject; 188 189 return results; 190 } 191 192 193 194 bool ppStackReadoutFinal(const pmConfig *config, pmReadout *outRO, pmReadout *expRO, const psArray *readouts, 181 195 const psVector *mask, const psArray *rejected, const psVector *weightings, 182 const psVector *addVariance) 196 const psVector *exposures, const psVector *addVariance, bool safety, 197 const psVector *norm) 183 198 { 184 199 assert(config); 185 200 assert(outRO); 201 assert(expRO); 186 202 assert(readouts); 187 203 assert(!rejected || readouts->n == rejected->n); … … 196 212 197 213 bool mdok; // Status of MD lookup 198 int iter = psMetadataLookupS32(NULL, recipe, "ITER"); // Rejection iterations199 float combineRej = psMetadataLookupF32(NULL, recipe, "COMBINE.REJ"); // Combination threshold200 float combineSys = psMetadataLookupF32(NULL, recipe, "COMBINE.SYS"); // Combination systematic error201 float combineDiscard = psMetadataLookupF32(NULL, recipe, "COMBINE.DISCARD"); // Olympic discard fraction202 214 bool useVariance = psMetadataLookupBool(&mdok, recipe, "VARIANCE"); // Use variance for rejection? 203 215 bool safe = psMetadataLookupBool(&mdok, recipe, "SAFE"); // Be safe when combining small numbers of pixels … … 205 217 psString maskValStr = psMetadataLookupStr(NULL, recipe, "MASK.VAL"); // Name of bits to mask going in 206 218 psImageMaskType maskVal = pmConfigMaskGet(maskValStr, config); // Bits to mask going in to pmSubtractionMatch 219 psString maskSuspectStr = psMetadataLookupStr(NULL, recipe, "MASK.SUSPECT"); // Name of suspect mask bits 220 psImageMaskType maskSuspect = pmConfigMaskGet(maskSuspectStr, config); // Suspect bits 207 221 psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits to mask for bad 208 222 psImageMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels … … 211 225 psArray *stack = psArrayAlloc(num); // Array for stacking 212 226 213 bool entire = true; // Combine entire image? 214 if (rejected) { 215 // We have rejection from a previous combination: combine without flagging pixels to inspect 216 entire = false; 217 safe = false; 218 iter = 0; 219 combineRej = NAN; 220 combineSys = NAN; 221 } 227 // We have rejection from a previous combination: combine without flagging pixels to inspect 228 safe &= safety; 229 int iter = 0; 230 float combineRej = NAN; 231 float combineSys = NAN; 232 float combineDiscard = NAN; 222 233 223 234 for (int i = 0; i < num; i++) { 224 235 pmReadout *ro = readouts->data[i]; 225 if (mask->data.U8[i] & (PPSTACK_MASK_REJECT | PPSTACK_MASK_BAD)) { 226 // Image completely rejected since previous combination 227 entire = true; 228 continue; 229 } else if (mask->data.U8[i]) { 230 // Image completely rejected before original combination 231 continue; 232 } 233 234 #if 0 235 // This doesn't seem to work, so getting the weightings directly from a vector 236 bool mdok; // Status of MD lookup 237 float weighting = psMetadataLookupF32(&mdok, ro->analysis, "PPSTACK.WEIGHTING"); // Relative weight 238 if (!mdok || !isfinite(weighting)) { 239 psWarning("No WEIGHTING supplied for image %d --- set to unity.", i); 240 weighting = 1.0; 241 } 242 #endif 236 if (mask->data.U8[i]) { 237 // Image completely rejected 238 continue; 239 } 243 240 244 241 // Ensure there is a mask, or pmStackCombine will complain … … 248 245 } 249 246 250 pmStackData *data = pmStackDataAlloc(ro, weightings->data.F32[i], 247 pmStackData *data = pmStackDataAlloc(ro, weightings->data.F32[i], exposures->data.F32[i], 251 248 addVariance ? addVariance->data.F32[i] : NAN); 252 249 data->reject = rejected ? psMemIncrRefCounter(rejected->data[i]) : NULL; 253 250 stack->data[i] = data; 254 } 255 256 if (!pmStackCombine(outRO, stack, maskVal | maskBad, maskBad, 0, 257 iter, combineRej, combineSys, combineDiscard, 258 entire, useVariance, safe, !rejected)) { 251 252 if (norm) { 253 float normalise = powf(10.0, -0.4 * norm->data.F32[i]); // Normalisation 254 psBinaryOp(ro->image, ro->image, "*", psScalarAlloc(normalise, PS_TYPE_F32)); 255 psBinaryOp(ro->variance, ro->variance, "*", psScalarAlloc(PS_SQR(normalise), PS_TYPE_F32)); 256 } 257 } 258 259 if (!pmStackCombine(outRO, expRO, stack, maskVal | maskBad, maskSuspect, maskBad, 0, iter, combineRej, 260 combineSys, combineDiscard, useVariance, safe, rejected)) { 259 261 psError(PS_ERR_UNKNOWN, false, "Unable to combine input readouts."); 260 262 psFree(stack); … … 264 266 pmCell *outCell = outRO->parent; // Output cell 265 267 pmChip *outChip = outCell->parent; // Output chip 266 267 268 outRO->data_exists = true; 268 269 outCell->data_exists = true; 269 270 outChip->data_exists = true; 270 271 272 pmCell *expCell = expRO->parent; // Exposure cell 273 pmChip *expChip = expCell->parent; // Exposure chip 274 expRO->data_exists = true; 275 expCell->data_exists = true; 276 expChip->data_exists = true; 277 271 278 psFree(stack); 272 279 -
branches/tap_branches/ppStack/src/ppStackReject.c
r25466 r27838 10 10 #include "ppStackLoop.h" 11 11 12 // #define TESTING12 // #define TESTING 13 13 14 14 bool ppStackReject(ppStackOptions *options, pmConfig *config) … … 23 23 24 24 int num = options->num; // Number of inputs 25 options->rejected = psArrayAlloc(num);26 25 27 26 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe … … 32 31 33 32 float threshold = psMetadataLookupF32(NULL, recipe, "THRESHOLD.MASK"); // Threshold for mask deconvolution 34 float poorFrac = psMetadataLookupF32(NULL, recipe, "POOR.FRACTION"); // Fraction for "poor"35 33 float imageRej = psMetadataLookupF32(NULL, recipe, "IMAGE.REJ"); // Maximum fraction of image to reject 36 34 // before rejecting entire image … … 53 51 psThreadJob *job = psThreadJobAlloc("PPSTACK_INSPECT"); // Job to start 54 52 psArrayAdd(job->args, 1, options->inspect); 53 psArrayAdd(job->args, 1, options->rejected); 55 54 PS_ARRAY_ADD_SCALAR(job->args, i, PS_TYPE_S32); 56 55 if (!psThreadJobAddPending(job)) { … … 61 60 } 62 61 if (!psThreadPoolWait(true)) { 63 psError( PS_ERR_UNKNOWN, false, "Unable to concatenate inspection lists.");62 psError(psErrorCodeLast(), false, "Unable to concatenate inspection lists."); 64 63 return false; 65 64 } … … 92 91 #endif 93 92 94 psPixels *reject = pmStackReject(options->inspect->data[i], options->numCols, options->numRows,95 threshold, poorFrac, stride, options->regions->data[i],96 options->kernels->data[i]); // Rejected pixels97 98 93 #ifdef TESTING 99 94 { 100 psImage *mask = psPixelsToMask(NULL, reject,95 psImage *mask = psPixelsToMask(NULL, options->rejected->data[i], 101 96 psRegionSet(0, options->numCols - 1, 0, options->numRows - 1), 102 97 0xff); // Mask image 103 98 psString name = NULL; // Name of image 104 psStringAppend(&name, " reject_%03d.fits", i);99 psStringAppend(&name, "pre_reject_%03d.fits", i); 105 100 pmStackVisualPlotTestImage(mask, name); 106 101 psFits *fits = psFitsOpen(name, "w"); … … 111 106 } 112 107 #endif 108 109 psPixels *reject = pmStackReject(options->inspect->data[i], options->numCols, options->numRows, 110 threshold, stride, options->regions->data[i], 111 options->kernels->data[i]); // Rejected pixels 113 112 114 113 psFree(options->inspect->data[i]); … … 127 126 "exceeds limit (%.3f)", i, frac, imageRej); 128 127 psFree(reject); 129 // reject == NULL means reject image completely130 128 reject = NULL; 131 129 options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= PPSTACK_MASK_BAD; 132 130 numRejected++; 131 } else { 132 // Add to list of pixels already rejected 133 reject = psPixelsConcatenate(reject, options->rejected->data[i]); 134 options->rejected->data[i] = psPixelsDuplicates(options->rejected->data[i], reject); 133 135 } 134 136 } 135 137 136 // Images without a list of rejected pixels (the list may be empty) are rejected completely 137 options->rejected->data[i] = reject; 138 #ifdef TESTING 139 { 140 psImage *mask = psPixelsToMask(NULL, options->rejected->data[i], 141 psRegionSet(0, options->numCols - 1, 0, options->numRows - 1), 142 0xff); // Mask image 143 psString name = NULL; // Name of image 144 psStringAppend(&name, "reject_%03d.fits", i); 145 pmStackVisualPlotTestImage(mask, name); 146 psFits *fits = psFitsOpen(name, "w"); 147 psFree(name); 148 psFitsWriteImage(fits, NULL, mask, 0, NULL); 149 psFree(mask); 150 psFitsClose(fits); 151 } 152 #endif 138 153 139 154 if (options->stats) { … … 143 158 "Number of pixels rejected", reject ? reject->n : 0); 144 159 } 160 161 psFree(reject); 145 162 psLogMsg("ppStack", PS_LOG_INFO, "Time to perform rejection on image %d: %f sec", i, 146 163 psTimerClear("PPSTACK_REJECT")); … … 148 165 149 166 psFree(options->inspect); options->inspect = NULL; 150 psFree(options->kernels); options->kernels = NULL;151 psFree(options->regions); options->regions = NULL;152 167 153 if (numRejected >= num - 1) {154 psError(P S_ERR_UNKNOWN, true, "All inputs completely rejected; unable to proceed.");168 if (numRejected >= num) { 169 psError(PPSTACK_ERR_REJECTED, true, "All inputs completely rejected; unable to proceed."); 155 170 return false; 156 171 } -
branches/tap_branches/ppStack/src/ppStackSetup.c
r23688 r27838 22 22 psAssert(recipe, "We've thrown an error on this before."); 23 23 24 // XXX : switch to this name? options->matchZPs = psMetadataLookupBool(NULL, recipe, "MATCH.ZERO.POINTS"); // Adjust zero points based on tranparency analysis? 25 options->matchZPs = psMetadataLookupBool(NULL, recipe, "ZP"); // Adjust zero points? 26 27 options->photometry = psMetadataLookupBool(NULL, recipe, "PHOTOMETRY"); // Perform photometry? 28 24 29 options->convolve = psMetadataLookupBool(NULL, recipe, "CONVOLVE"); // Convolve images? 25 30 if (!psMetadataLookupBool(NULL, config->arguments, "HAVE.PSF")) { … … 37 42 options->statsFile = fopen(resolved, "w"); 38 43 if (!options->statsFile) { 39 psError(P S_ERR_IO, true, "Unable to open statistics file %s for writing.\n", resolved);44 psError(PPSTACK_ERR_IO, true, "Unable to open statistics file %s for writing.\n", resolved); 40 45 psFree(resolved); 41 46 return false; … … 43 48 psFree(resolved); 44 49 options->stats = psMetadataAlloc(); 45 psMetadataAddS32(options->stats, PS_LIST_TAIL, "QUALITY", 0, "No problems", 0);46 50 } 47 51 48 52 // Generate temporary names for convolved images 49 const char *tempDir = psMetadataLookupStr(NULL, recipe, "TEMP.DIR"); // Directory for temporary images53 const char *tempDir = psMetadataLookupStr(NULL, config->arguments, "-temp-dir"); // Directory for temps 50 54 if (!tempDir) { 51 psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Unable to find TEMP.DIR in recipe"); 55 tempDir = psMetadataLookupStr(NULL, config->site, "TEMP.DIR"); 56 } 57 if (!tempDir) { 58 psError(PPSTACK_ERR_CONFIG, false, "Unable to find TEMP.DIR in site configuration"); 52 59 return false; 53 60 } … … 57 64 const char *tempName = basename(outputName); 58 65 if (!tempName) { 59 psError(P S_ERR_BAD_PARAMETER_VALUE, false, "Unable to construct basename for temporary files.");66 psError(PPSTACK_ERR_ARGUMENTS, false, "Unable to construct basename for temporary files."); 60 67 psFree(outputName); 61 68 return false; … … 66 73 const char *tempVariance = psMetadataLookupStr(NULL, recipe, "TEMP.VARIANCE"); // Suffix for var maps 67 74 if (!tempImage || !tempMask || !tempVariance) { 68 psError(P S_ERR_BAD_PARAMETER_VALUE, false,75 psError(PPSTACK_ERR_CONFIG, false, 69 76 "Unable to find TEMP.IMAGE, TEMP.MASK and TEMP.VARIANCE in recipe"); 70 77 psFree(outputName); … … 72 79 } 73 80 74 options-> imageNames = psArrayAlloc(num);75 options-> maskNames = psArrayAlloc(num);76 options-> varianceNames = psArrayAlloc(num);81 options->convImages = psArrayAlloc(num); 82 options->convMasks = psArrayAlloc(num); 83 options->convVariances = psArrayAlloc(num); 77 84 for (int i = 0; i < num; i++) { 78 85 psString imageName = NULL, maskName = NULL, varianceName = NULL; // Names for convolved images … … 81 88 psStringAppend(&varianceName, "%s/%s.%d.%s", tempDir, tempName, i, tempVariance); 82 89 psTrace("ppStack", 5, "Temporary files: %s %s %s\n", imageName, maskName, varianceName); 83 options-> imageNames->data[i] = imageName;84 options-> maskNames->data[i] = maskName;85 options-> varianceNames->data[i] = varianceName;90 options->convImages->data[i] = imageName; 91 options->convMasks->data[i] = maskName; 92 options->convVariances->data[i] = varianceName; 86 93 } 87 94 psFree(outputName); 88 95 96 // Original images 97 options->origImages = psArrayAlloc(num); 98 options->origMasks = psArrayAlloc(num); 99 options->origVariances = psArrayAlloc(num); 100 pmFPAview *view = pmFPAviewAlloc(0); 101 for (int i = 0; i < num; i++) { 102 { 103 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPSTACK.INPUT", i); 104 options->origImages->data[i] = pmFPAfileName(file, view, config); 105 } 106 { 107 // We want the convolved mask, since that defines the area that has been tested for outliers 108 options->origMasks->data[i] = psMemIncrRefCounter(options->convMasks->data[i]); 109 } 110 { 111 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPSTACK.INPUT.VARIANCE", i); 112 options->origVariances->data[i] = pmFPAfileName(file, view, config); 113 } 114 } 115 psFree(view); 116 89 117 if (!pmConfigMaskSetBits(NULL, NULL, config)) { 90 psError(P S_ERR_UNKNOWN, false, "Unable to determine mask value.");118 psError(PPSTACK_ERR_CONFIG, false, "Unable to determine mask value."); 91 119 return false; 92 120 } -
branches/tap_branches/ppStack/src/ppStackSources.c
r25313 r27838 8 8 9 9 //#define TESTING // Enable debugging output 10 11 //#define ASTROMETRY // Correct astrometry? 10 12 11 13 #ifdef TESTING … … 61 63 PS_ASSERT_PTR_NON_NULL(config, false); 62 64 65 if (!options->matchZPs && !options->photometry) { 66 options->norm = psVectorAlloc(options->num, PS_TYPE_F32); 67 psVectorInit(options->norm, 0.0); 68 return true; 69 } 70 63 71 psArray *sourceLists = options->sourceLists; // Source lists for each input 64 72 psVector *inputMask = options->inputMask; // Mask for inputs … … 79 87 } 80 88 source->psfMag += 1.0; 89 #ifdef ASTROMETRY 90 if (source->modelPSF) { 91 source->modelPSF->params->data.F32[PM_PAR_XPOS] += 1.0; 92 source->modelPSF->params->data.F32[PM_PAR_YPOS] += 1.0; 93 } 94 if (source->peak) { 95 source->peak->xf += 1.0; 96 source->peak->yf += 1.0; 97 } 98 #endif 81 99 } 82 100 } … … 105 123 psMetadata *airmassZP = psMetadataLookupMetadata(NULL, recipe, "ZP.AIRMASS"); // Airmass terms 106 124 if (!airmassZP) { 107 psError(P S_ERR_UNKNOWN, false, "Unable to find ZP.AIRMASS in recipe.");125 psError(PPSTACK_ERR_CONFIG, false, "Unable to find ZP.AIRMASS in recipe."); 108 126 return false; 109 127 } 110 111 int num = psMetadataLookupS32(NULL, config->arguments, "INPUTS.NUM"); // Number of inputs 128 psMetadata *zpTargetMenu = psMetadataLookupMetadata(NULL, recipe, "ZP.TARGET"); // Target zero point terms 129 if (!zpTargetMenu) { 130 psError(PPSTACK_ERR_CONFIG, false, "Unable to find ZP.TARGET in recipe."); 131 return false; 132 } 133 134 int num = options->num; // Number of inputs 112 135 psAssert(num == sourceLists->n, "Wrong number of source lists: %ld\n", sourceLists->n); 113 136 114 psVector *zp = psVectorAlloc(num, PS_TYPE_F32); // Zero points for each image 137 psVector *zp = psVectorAlloc(num, PS_TYPE_F32); // Relative zero points for each image 138 psVector *zpExp = psVectorAlloc(num, PS_TYPE_F32); // Measured zero points for each image (maybe) 139 int zpExpNum = 0; // Number of measured zero points 115 140 const char *filter = NULL; // Filter name 116 141 float airmassTerm = NAN; // Airmass term 117 float sumExpTime = 0.0; // Sum of the exposure time 142 float zpTarget = NAN; // Target zero point 143 int numGoodImages = 0; // Number of good images 118 144 for (int i = 0; i < num; i++) { 145 psArray *sources = sourceLists->data[i]; // Source list 146 if (!sources || sources->n == 0) { 147 psLogMsg("ppStack", PS_LOG_WARN, "Image %d has no sources for transparency measurement.", i); 148 options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= PPSTACK_MASK_CAL; 149 zp->data.F32[i] = NAN; 150 continue; 151 } 152 numGoodImages++; 153 119 154 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPSTACK.INPUT", i); // File of interest 120 pmCell *cell = pmFPAviewThisCell(view, file->fpa); // Cell of interest121 155 122 156 #if defined(TESTING) && 0 … … 135 169 #endif 136 170 137 138 float exptime = psMetadataLookupF32(NULL, cell->concepts, "CELL.EXPOSURE"); // Exposure time 171 float exptime = options->exposures->data.F32[i]; // Exposure time 139 172 float airmass = psMetadataLookupF32(NULL, file->fpa->concepts, "FPA.AIRMASS"); // Airmass 140 173 const char *expFilter = psMetadataLookupStr(NULL, file->fpa->concepts, "FPA.FILTER"); // Filter name 174 zpExp->data.F32[i] = psMetadataLookupF32(NULL, file->fpa->concepts, "FPA.ZP"); // Exposure zero point 175 psLogMsg("ppStack", PS_LOG_INFO, 176 "Image %d: %.2f sec exposure in %s at airmass %.2f with zero point %.2f", 177 i, exptime, expFilter, airmass, zpExp->data.F32[i]); 141 178 if (!isfinite(exptime) || exptime == 0 || !isfinite(airmass) || airmass == 0 || 142 179 !expFilter || strlen(expFilter) == 0) { 143 psError(P S_ERR_UNEXPECTED_NULL, false,180 psError(PPSTACK_ERR_CONFIG, false, 144 181 "Unable to find exposure time (%f), airmass (%f) or filter (%s)", 145 182 exptime, airmass, expFilter); … … 147 184 return false; 148 185 } 186 if (isfinite(zpExp->data.F32[i])) { 187 zpExp->data.F32[i] += 2.5 * log10(exptime); 188 zpExpNum++; 189 } 149 190 150 191 if (!filter) { 151 192 filter = expFilter; 152 airmassTerm = psMetadataLookupF32(NULL, airmassZP, filter); 153 if (!isfinite(airmassTerm)) { 154 psError(PS_ERR_BAD_PARAMETER_VALUE, false, 193 bool mdok; 194 airmassTerm = psMetadataLookupF32(&mdok, airmassZP, filter); 195 if (!mdok || !isfinite(airmassTerm)) { 196 psError(PPSTACK_ERR_CONFIG, false, 155 197 "Unable to find airmass term (ZP.AIRMASS) for filter %s", filter); 156 198 psFree(zp); 157 199 return false; 158 200 } 201 zpTarget = psMetadataLookupF32(&mdok, zpTargetMenu, filter); 202 if (!mdok || !isfinite(zpTarget)) { 203 psError(PPSTACK_ERR_CONFIG, false, 204 "Unable to find target zero point (ZP.TARGET) for filter %s", filter); 205 psFree(zp); 206 return false; 207 } 159 208 } else if (strcmp(filter, expFilter) != 0) { 160 psError(P S_ERR_BAD_PARAMETER_VALUE, false, "Filters don't match: %s vs %s", filter, expFilter);209 psError(PPSTACK_ERR_CONFIG, false, "Filters don't match: %s vs %s", filter, expFilter); 161 210 psFree(zp); 162 211 return false; 163 212 } 164 213 165 zp->data.F32[i] = airmassTerm * airmass - 2.5 * log10(exptime); 166 sumExpTime += exptime; 167 } 168 169 options->sumExposure = sumExpTime; 214 zp->data.F32[i] = airmassTerm * airmass + 2.5 * log10(exptime); 215 } 216 217 if (numGoodImages == 0) { 218 psLogMsg("ppStack", PS_LOG_WARN, "No images with sources to measure transparency."); 219 options->quality = PPSTACK_ERR_REJECTED; 220 psFree(zp); 221 psFree(zpExp); 222 return true; 223 } 224 if (numGoodImages == 1) { 225 psArray *sources = NULL; // Sources 226 for (int i = 0; i < num && !sources; i++) { 227 if (options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) { 228 continue; 229 } 230 sources = sourceLists->data[i]; 231 } 232 options->quality = PPSTACK_ERR_REJECTED; 233 options->sources = psMemIncrRefCounter(sources); 234 options->norm = psVectorAlloc(num, PS_TYPE_F32); 235 psVectorInit(options->norm, 1.0); 236 options->zp = NAN; 237 psLogMsg("ppStack", PS_LOG_WARN, "Single image with sources --- cannot match transparency."); 238 psFree(zp); 239 psFree(zpExp); 240 return true; 241 } 242 243 if (zpExpNum == numGoodImages) { 244 for (int i = 0; i < num; i++) { 245 zp->data.F32[i] = zpExp->data.F32[i]; 246 } 247 } 170 248 171 249 psArray *matches = pmSourceMatchSources(sourceLists, radius, true); // List of matches 172 250 if (!matches) { 173 psError(P S_ERR_UNKNOWN, false, "Unable to match sources");251 psError(PPSTACK_ERR_DATA, false, "Unable to match sources"); 174 252 psFree(zp); 175 253 return false; … … 180 258 #endif 181 259 182 psVector *trans = pmSourceMatchRelphot(matches, zp, tol, iter1, starRej1, starSys1, 183 iter2, starRej2, starSys2, starLimit, 184 transIter, transRej, transThresh); // Transparencies for each image 185 if (!trans) { 186 psError(PS_ERR_UNKNOWN, false, "Unable to measure transparencies"); 187 return false; 188 } 260 if (options->matchZPs) { 261 psVector *trans = pmSourceMatchRelphot(matches, zp, tol, iter1, starRej1, starSys1, 262 iter2, starRej2, starSys2, starLimit, 263 transIter, transRej, transThresh); // Transparencies per image 264 if (!trans) { 265 psError(PPSTACK_ERR_DATA, false, "Unable to measure transparencies"); 266 return false; 267 } 268 for (int i = 0; i < trans->n; i++) { 269 if (!isfinite(trans->data.F32[i])) { 270 inputMask->data.U8[i] |= PPSTACK_MASK_CAL; 271 } 272 } 273 // M = m + c0 + c1 * airmass - 2.5log(t) + transparency 274 // Want sources to have m corresponding to airmass = 1 and t = sumExpTime and transparency = 0 275 // m_0 + c1 * airmass_0 + 2.5log(t_0) - trans_0 = m_1 + c1 * airmass_1 + 2.5log(t_1) - trans_1 276 // m_0 = m_1 + zp_1 + trans_1 - c1 * airmass_0 - 2.5log(t_0) 277 // We don't need to know the magnitude zero point for the filter, since it cancels out 278 if (options->matchZPs) { 279 options->norm = psVectorAlloc(num, PS_TYPE_F32); 280 for (int i = 0; i < num; i++) { 281 if (inputMask->data.U8[i] || !isfinite(trans->data.F32[i])) { 282 continue; 283 } 284 psArray *sources = sourceLists->data[i]; // Sources of interest 285 float magCorr = zp->data.F32[i] + trans->data.F32[i] - 2.5*log10(options->sumExposure); 286 if (zpExpNum == numGoodImages) { 287 // Using measured zero points, so attempt to set target zero point 288 magCorr -= zpTarget; 289 } 290 options->norm->data.F32[i] = -magCorr; 291 psLogMsg("ppStack", PS_LOG_INFO, 292 "Applying scale correction to image %d: %f mag (%f)\n", 293 i, magCorr, trans->data.F32[i]); 294 295 for (int j = 0; j < sources->n; j++) { 296 pmSource *source = sources->data[j]; // Source of interest 297 if (!source) { 298 continue; 299 } 300 source->psfMag -= magCorr; 301 } 302 } 303 } 304 305 if (zpExpNum == numGoodImages) { 306 // Producing image with target zero point 307 options->zp = zpTarget; 308 } else { 309 options->zp = NAN; 310 } 311 189 312 190 313 #ifdef TESTING 191 dumpMatches("source_mags.dat", num, matches, zp, trans); 192 #endif 193 194 for (int i = 0; i < trans->n; i++) { 195 if (!isfinite(trans->data.F32[i])) { 196 inputMask->data.U8[i] |= PPSTACK_MASK_CAL; 197 } 198 } 199 200 // Save best matches SOMEWHERE for future photometry 201 // XXX this is a really poor output location; clean up the pmFPAfiles used in ppStack 202 pmCell *sourcesCell = pmFPAfileThisCell(config->files, view, "PPSTACK.OUTPUT"); 203 psArray *sourcesBest = psArrayAllocEmpty(matches->n); 204 205 // XXX something of a hack: require at least 2 detections or the nominated fraction of the max possible 206 int minMatches = PS_MAX(2, fracMatch * num);// Minimum number of matches required 207 for (int i = 0; i < matches->n; i++) { 208 pmSourceMatch *match = matches->data[i]; // Match of interest 209 if (match->num < minMatches) { 210 continue; 211 } 212 213 // We need to grab a single instance of this source: just take the first available 214 int image = match->image->data.S32[0]; // Index of image 215 int index = match->index->data.S32[0]; // Index of source within image 216 psArray *sources = sourceLists->data[image]; // Sources for image 217 pmSource *source = sources->data[index]; // Source of interest 218 219 psArrayAdd(sourcesBest, sourcesBest->n, source); 220 } 221 psMetadataAdd(sourcesCell->analysis, PS_LIST_TAIL, "PSPHOT.SOURCES", PS_DATA_ARRAY | PS_META_REPLACE, 222 "psphot sources", sourcesBest); 223 psLogMsg("ppStack", PS_LOG_INFO, "Selected %ld sources for photometry analysis", sourcesBest->n); 224 psFree(sourcesBest); 314 dumpMatches("source_mags.dat", num, matches, zp, trans); 315 #endif 316 psFree(trans); 317 318 #ifdef TESTING 319 // Double check: all transparencies should be zero 320 { 321 psArray *matches = pmSourceMatchSources(sourceLists, radius, true); // List of matches 322 if (!matches) { 323 psError(PPSTACK_ERR_DATA, false, "Unable to match sources"); 324 psFree(zp); 325 return false; 326 } 327 psVector *trans = pmSourceMatchRelphot(matches, zp, tol, iter1, starRej1, starSys1, 328 iter2, starRej2, starSys2, starLimit, 329 transIter, transRej, transThresh); // Transparencies 330 for (int i = 0; i < num; i++) { 331 fprintf(stderr, "Transparency of image %d: %f\n", i, trans->data.F32[i]); 332 } 333 psFree(trans); 334 psFree(matches); 335 } 336 #endif 337 } 338 339 psFree(zp); 340 psFree(zpExp); 341 342 #ifdef ASTROMETRY 343 // Position offsets 344 { 345 psArray *offsets = pmSourceMatchRelastro(matches, num, tol, iter1, starRej1, 346 iter2, starRej2, starLimit); // Shifts for each image 347 if (!offsets) { 348 psError(PPSTACK_ERR_DATA, false, "Unable to measure offsets"); 349 return false; 350 } 351 for (int i = 0; i < num; i++) { 352 if (options->inputMask->data.U8[i]) { 353 continue; 354 } 355 psArray *sources = sourceLists->data[i]; // Sources of interest 356 psVector *offset = offsets->data[i]; // Offsets for image 357 float dx = offset->data.F32[0], dy = offset->data.F32[1]; // Offsets to apply 358 if (!isfinite(dx) || !isfinite(dy)) { 359 continue; 360 } 361 psLogMsg("ppStack", PS_LOG_INFO, "Applying astrometric correction to image %d: %f,%f\n", 362 i, dx, dy); 363 for (int j = 0; j < sources->n; j++) { 364 pmSource *source = sources->data[j]; // Source of interest 365 if (!source) { 366 continue; 367 } 368 if (source->modelPSF) { 369 source->modelPSF->params->data.F32[PM_PAR_XPOS] -= dx; 370 source->modelPSF->params->data.F32[PM_PAR_YPOS] -= dy; 371 } 372 if (source->peak) { 373 source->peak->xf -= dx; 374 source->peak->yf -= dy; 375 } 376 } 377 } 378 psFree(offsets); 379 } 380 #endif 381 382 #if (defined TESTING && defined ASTROMETRY) 383 // Double check: all offsets should be zero 384 { 385 psArray *matches = pmSourceMatchSources(sourceLists, radius, true); // List of matches 386 if (!matches) { 387 psError(PPSTACK_ERR_DATA, false, "Unable to match sources"); 388 psFree(zp); 389 return false; 390 } 391 psArray *offsets = pmSourceMatchRelastro(matches, num, tol, iter1, starRej1, 392 iter2, starRej2, starLimit); // Shifts for each image 393 for (int i = 0; i < num; i++) { 394 psVector *offset = offsets->data[i]; // Offsets for image 395 fprintf(stderr, "Offset of image %d: %f,%f\n", i, offset->data.F32[0], offset->data.F32[1]); 396 } 397 psFree(offsets); 398 psFree(matches); 399 } 400 #endif 401 402 403 if (options->photometry) { 404 // Save best matches for future photometry 405 psArray *sourcesBest = options->sources = psArrayAllocEmpty(matches->n); 406 407 // XXX something of a hack: require at least 2 detections or the nominated fraction of the max possible 408 int minMatches = PS_MAX(2, fracMatch * num);// Minimum number of matches required 409 for (int i = 0; i < matches->n; i++) { 410 pmSourceMatch *match = matches->data[i]; // Match of interest 411 if (match->num < minMatches) { 412 continue; 413 } 414 415 // We need to grab a single instance of this source: just take the first available 416 int image = match->image->data.S32[0]; // Index of image 417 int index = match->index->data.S32[0]; // Index of source within image 418 psArray *sources = sourceLists->data[image]; // Sources for image 419 pmSource *source = sources->data[index]; // Source of interest 420 421 psArrayAdd(sourcesBest, sourcesBest->n, source); 422 } 423 psLogMsg("ppStack", PS_LOG_INFO, "Selected %ld sources for photometry analysis", sourcesBest->n); 424 } 225 425 226 426 psFree(matches); 227 228 // M = m + c0 + c1 * airmass - 2.5log(t) + transparency229 // Want sources to have m corresponding to airmass = 1 and t = sumExpTime and transparency = 0230 // m_0 + c1 * airmass_0 + 2.5log(t_0) - trans_0 = m_1 + c1 * airmass_1 + 2.5log(t_1) - trans_1231 // m_0 = m_1 + zp_1 + trans_1 - c1 * airmass_0 - 2.5log(t_0)232 // We don't need to know the magnitude zero point for the filter, since it cancels out233 options->norm = psVectorAlloc(num, PS_TYPE_F32);234 for (int i = 0; i < num; i++) {235 if (!isfinite(trans->data.F32[i])) {236 continue;237 }238 psArray *sources = sourceLists->data[i]; // Sources of interest239 float magCorr = airmassTerm - 2.5*log10(sumExpTime) - zp->data.F32[i] - trans->data.F32[i];240 options->norm->data.F32[i] = magCorr;241 psLogMsg("ppStack", PS_LOG_INFO, "Applying magnitude correction to image %d: %f\n", i, magCorr);242 243 for (int j = 0; j < sources->n; j++) {244 pmSource *source = sources->data[j]; // Source of interest245 if (!source) {246 continue;247 }248 source->psfMag += magCorr;249 }250 }251 psFree(trans);252 253 #ifdef TESTING254 // Double check: all transparencies should be zero255 {256 psArray *matches = pmSourceMatchSources(sourceLists, radius); // List of matches257 if (!matches) {258 psError(PS_ERR_UNKNOWN, false, "Unable to match sources");259 psFree(zp);260 return false;261 }262 psVector *trans = pmSourceMatchRelphot(matches, zp, iter, tol, starLimit, transIter, transRej,263 transThresh, starRej, starSys);264 for (int i = 0; i < num; i++) {265 fprintf(stderr, "Transparency of image %d: %f\n", i, trans->data.F32[i]);266 }267 psFree(trans);268 }269 #endif270 427 271 428 return true; -
branches/tap_branches/ppStack/src/ppStackThread.c
r24796 r27838 56 56 } 57 57 58 ppStackThreadData *ppStackThreadDataSetup(const ppStackOptions *options, const pmConfig *config )58 ppStackThreadData *ppStackThreadDataSetup(const ppStackOptions *options, const pmConfig *config, bool conv) 59 59 { 60 60 psAssert(options, "Require options"); … … 62 62 63 63 const psArray *cells = options->cells; // Array of input cells 64 const psArray *imageNames = options->imageNames; // Names of images to read65 const psArray *maskNames = options->maskNames; // Names of masks to read66 const psArray *varianceNames = options->varianceNames; // Names of variance maps to read67 const psArray *covariances = options->covariances; // Covariance matrices (already read)64 const psArray *imageNames = conv ? options->convImages : options->origImages; // Names of images to read 65 const psArray *maskNames = conv ? options->convMasks : options->origMasks; // Names of masks to read 66 const psArray *varianceNames = conv ? options->convVariances : options->origVariances; // Variance names 67 const psArray *covariances = conv ? options->convCovars : options->origCovars; // Covariance matrices 68 68 69 69 PS_ASSERT_ARRAY_NON_NULL(cells, NULL); 70 PS_ASSERT_ARRAYS_SIZE_EQUAL(cells, imageNames, NULL); 71 PS_ASSERT_ARRAYS_SIZE_EQUAL(cells, maskNames, NULL); 72 PS_ASSERT_ARRAYS_SIZE_EQUAL(cells, varianceNames, NULL); 73 PS_ASSERT_ARRAYS_SIZE_EQUAL(cells, covariances, NULL); 70 if (imageNames) { 71 PS_ASSERT_ARRAYS_SIZE_EQUAL(cells, imageNames, NULL); 72 } 73 if (maskNames) { 74 PS_ASSERT_ARRAYS_SIZE_EQUAL(cells, maskNames, NULL); 75 } 76 if (varianceNames) { 77 PS_ASSERT_ARRAYS_SIZE_EQUAL(cells, varianceNames, NULL); 78 } 79 if (covariances) { 80 PS_ASSERT_ARRAYS_SIZE_EQUAL(cells, covariances, NULL); 81 } 74 82 75 83 ppStackThreadData *stack = psAlloc(sizeof(ppStackThreadData)); // Thread data, to return … … 87 95 continue; 88 96 } 89 // Resolved names 90 psString imageResolved = pmConfigConvertFilename(imageNames->data[i], config, false, false); 91 psString maskResolved = pmConfigConvertFilename(maskNames->data[i], config, false, false); 92 psString varianceResolved = pmConfigConvertFilename(varianceNames->data[i], config, false, false); 93 stack->imageFits->data[i] = psFitsOpen(imageResolved, "r"); 94 stack->maskFits->data[i] = psFitsOpen(maskResolved, "r"); 95 stack->varianceFits->data[i] = psFitsOpen(varianceResolved, "r"); 96 psFree(imageResolved); 97 psFree(maskResolved); 98 psFree(varianceResolved); 99 if (!stack->imageFits->data[i] || !stack->maskFits->data[i] || !stack->varianceFits->data[i]) { 100 psError(PS_ERR_UNKNOWN, false, "Unable to open convolved files %s, %s, %s", 101 (char*)imageNames->data[i], (char*)maskNames->data[i], (char*)varianceNames->data[i]); 102 return NULL; 103 } 97 98 // Open an image 99 #define IMAGE_OPEN(NAMES, FITS, INDEX) \ 100 if (NAMES) { \ 101 psString resolved = pmConfigConvertFilename((NAMES)->data[INDEX], config, false, false); \ 102 (FITS)->data[INDEX] = psFitsOpen(resolved, "r"); \ 103 if (!(FITS)->data[INDEX]) { \ 104 psError(PPSTACK_ERR_IO, false, "Unable to open file %s", (char*)(NAMES)->data[INDEX]); \ 105 psFree(resolved); \ 106 return NULL; \ 107 } \ 108 psFree(resolved); \ 109 } 110 111 IMAGE_OPEN(imageNames, stack->imageFits, i); 112 IMAGE_OPEN(maskNames, stack->maskFits, i); 113 IMAGE_OPEN(varianceNames, stack->varianceFits, i); 104 114 } 105 115 … … 116 126 } 117 127 pmReadout *ro = pmReadoutAlloc(cell); // Readout for thread 118 ro->covariance = psMemIncrRefCounter(covariances->data[j]); 128 if (covariances) { 129 ro->covariance = psMemIncrRefCounter(covariances->data[j]); 130 } 119 131 readouts->data[j] = ro; 120 132 } … … 140 152 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // Recipe 141 153 if (!recipe) { 142 psError(P S_ERR_UNEXPECTED_NULL, false, "Unable to find recipe %s", PPSTACK_RECIPE);154 psError(PPSTACK_ERR_CONFIG, false, "Unable to find recipe %s", PPSTACK_RECIPE); 143 155 return NULL; 144 156 } 145 157 int rows = psMetadataLookupS32(NULL, recipe, "ROWS"); // Number of rows to read per chunk 146 158 if (rows <= 0) { 147 psError(P S_ERR_BAD_PARAMETER_VALUE, false, "ROWS is not set in the recipe.");159 psError(PPSTACK_ERR_CONFIG, false, "ROWS is not set in the recipe."); 148 160 return NULL; 149 161 } … … 186 198 psFits *varianceFits = stack->varianceFits->data[i]; // FITS file for variance 187 199 188 189 int zMax = 0; 200 int zMax = 0; 190 201 bool keepReading = false; 191 if (pmReadoutMore(ro, imageFits, 0, &zMax, rows, config)) { 202 203 if (imageFits && pmReadoutMore(ro, imageFits, 0, &zMax, rows, config)) { 192 204 keepReading = true; 193 205 if (!pmReadoutReadChunk(ro, imageFits, 0, NULL, rows, overlap, config)) { 194 psError(PS_ERR_IO, false, "Unable to read chunk %d for file PPSTACK.INPUT %d", 206 psError(PPSTACK_ERR_IO, false, 207 "Unable to read chunk %d for file PPSTACK.INPUT %d", 195 208 numChunk, i); 196 209 *status = false; … … 199 212 } 200 213 201 if ( pmReadoutMoreMask(ro, maskFits, 0, &zMax, rows, config)) {214 if (maskFits && pmReadoutMoreMask(ro, maskFits, 0, &zMax, rows, config)) { 202 215 keepReading = true; 203 216 if (!pmReadoutReadChunkMask(ro, maskFits, 0, NULL, rows, overlap, config)) { 204 psError(PS_ERR_IO, false, "Unable to read chunk %d for file PPSTACK.INPUT.MASK %d", 217 psError(PPSTACK_ERR_IO, false, 218 "Unable to read chunk %d for file PPSTACK.INPUT.MASK %d", 205 219 numChunk, i); 206 220 *status = false; … … 209 223 } 210 224 211 if ( pmReadoutMoreVariance(ro, varianceFits, 0, &zMax, rows, config)) {225 if (varianceFits && pmReadoutMoreVariance(ro, varianceFits, 0, &zMax, rows, config)) { 212 226 keepReading = true; 213 227 if (!pmReadoutReadChunkVariance(ro, varianceFits, 0, NULL, rows, overlap, config)) { 214 psError(P S_ERR_IO, false,228 psError(PPSTACK_ERR_IO, false, 215 229 "Unable to read chunk %d for file PPSTACK.INPUT.VARIANCE %d", 216 230 numChunk, i); … … 263 277 264 278 { 265 psThreadTask *task = psThreadTaskAlloc("PPSTACK_INSPECT", 2);279 psThreadTask *task = psThreadTaskAlloc("PPSTACK_INSPECT", 3); 266 280 task->function = &ppStackInspect; 267 281 psThreadTaskAdd(task); … … 270 284 271 285 { 272 psThreadTask *task = psThreadTaskAlloc("PPSTACK_FINAL_COMBINE", 3);286 psThreadTask *task = psThreadTaskAlloc("PPSTACK_FINAL_COMBINE", 6); 273 287 task->function = &ppStackReadoutFinalThread; 274 288 psThreadTaskAdd(task); -
branches/tap_branches/ppStack/src/ppStackThread.h
r23341 r27838 35 35 ppStackThreadData *ppStackThreadDataSetup( 36 36 const ppStackOptions *options, // Options 37 const pmConfig *config // Configuration 37 const pmConfig *config, // Configuration 38 bool conv // Use convolved products? 38 39 ); 39 40
Note:
See TracChangeset
for help on using the changeset viewer.
