Changeset 17083
- Timestamp:
- Mar 20, 2008, 5:08:17 PM (18 years ago)
- Location:
- branches/pap_branch_080320/ppMerge/src
- Files:
-
- 4 added
- 20 deleted
- 5 edited
-
Makefile.am (modified) (1 diff)
-
ppMerge.c (modified) (3 diffs)
-
ppMerge.h (modified) (1 diff)
-
ppMergeArguments.c (added)
-
ppMergeCamera.c (added)
-
ppMergeCheckInputs.c (deleted)
-
ppMergeCheckInputs.h (deleted)
-
ppMergeCombine.c (deleted)
-
ppMergeCombine.h (deleted)
-
ppMergeConfig.c (deleted)
-
ppMergeConfig.h (deleted)
-
ppMergeData.c (deleted)
-
ppMergeData.h (deleted)
-
ppMergeFiles.c (added)
-
ppMergeLoop.c (added)
-
ppMergeMask.c (modified) (2 diffs)
-
ppMergeMask.h (deleted)
-
ppMergeMaskAverageConcepts.c (deleted)
-
ppMergeMaskBad.c (deleted)
-
ppMergeMaskByImageStats.c (deleted)
-
ppMergeMaskByPixelStats.c (deleted)
-
ppMergeMaskGrow.c (deleted)
-
ppMergeMaskOutput.c (deleted)
-
ppMergeMaskReadoutByPixelStats.c (deleted)
-
ppMergeMaskSuspect.c (deleted)
-
ppMergeMaskWrite.c (deleted)
-
ppMergeOptions.c (deleted)
-
ppMergeOptions.h (deleted)
-
ppMergeScaleZero.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/pap_branch_080320/ppMerge/src/Makefile.am
r15937 r17083 6 6 ppMerge_SOURCES = \ 7 7 ppMerge.c \ 8 ppMergeCheckInputs.c \ 9 ppMergeCombine.c \ 10 ppMergeConfig.c \ 11 ppMergeData.c \ 12 ppMergeMask.c \ 13 ppMergeMaskSuspect.c \ 14 ppMergeMaskBad.c \ 15 ppMergeMaskWrite.c \ 16 ppMergeMaskGrow.c \ 17 ppMergeMaskAverageConcepts.c \ 18 ppMergeOptions.c \ 8 ppMergeArguments.c \ 9 ppMergeCamera.c \ 10 ppMergeFiles.c \ 19 11 ppMergeScaleZero.c \ 20 ppMergeVersion.c 12 ppMergeLoop.c \ 13 ppMergeMask.c 21 14 22 15 23 16 noinst_HEADERS = \ 24 ppMerge.h \ 25 ppMergeCheckInputs.h \ 26 ppMergeCombine.h \ 27 ppMergeConfig.h \ 28 ppMergeData.h \ 29 ppMergeMask.h \ 30 ppMergeOptions.h \ 31 ppMergeScaleZero.h \ 32 ppMergeVersion.h 17 ppMerge.h 33 18 34 19 CLEANFILES = *~ -
branches/pap_branch_080320/ppMerge/src/ppMerge.c
r15631 r17083 4 4 5 5 #include <stdio.h> 6 #include <string.h> 6 7 #include <pslib.h> 7 8 #include <psmodules.h> 8 9 9 10 #include "ppMerge.h" 10 #include "ppMergeConfig.h"11 #include "ppMergeData.h"12 #include "ppMergeOptions.h"13 #include "ppMergeCheckInputs.h"14 #include "ppMergeCombine.h"15 #include "ppMergeScaleZero.h"16 #include "ppMergeMask.h"17 11 18 12 //#include "ppMem.h" … … 27 21 { 28 22 psLibInit(NULL); 29 psMemSetThreadSafety(false); // Turn off thread safety, for more23 psMemSetThreadSafety(false); 30 24 psTimerStart(TIMERNAME); 31 25 32 // Parse the configuration and arguments 33 // Open the input image(s) 34 // Determine camera, format from header if not already defined 35 // Construct camera in preparation for reading 36 pmConfig *config = ppMergeConfig(argc, argv); 26 psExit exitValue = PS_EXIT_SUCCESS; // Exit value for program 27 28 pmConfig *config = pmConfigRead(&argc, argv, PPMERGE_RECIPE); // Configuration 37 29 if (!config) { 38 psErrorStackPrint(stderr, "Unable to get configuration."); 39 exit(EXIT_FAILURE); 30 psErrorStackPrint(stderr, "Error reading configuration."); 31 exitValue = PS_EXIT_CONFIG_ERROR; 32 goto die; 40 33 } 41 34 35 if (!ppMergeArguments(argc, argv, config)) { 36 psErrorStackPrint(stderr, "Error reading arguments."); 37 exitValue = PS_EXIT_CONFIG_ERROR; 38 goto die; 39 } 40 41 ppMergeType type = psMetadataLookupS32(NULL, config->arguments, "TYPE"); // Type of frame 42 switch (type) { 43 case PPMERGE_TYPE_MASK: 44 if (!ppMergeMask(config)) { 45 psErrorStackPrint(stderr, "Error generating mask."); 46 exitValue = PS_EXIT_DATA_ERROR; 47 goto die; 48 } 49 break; 50 case PPMERGE_TYPE_BIAS: 51 case PPMERGE_TYPE_DARK: 52 case PPMERGE_TYPE_SHUTTER: 53 case PPMERGE_TYPE_FLAT: 54 case PPMERGE_TYPE_FRINGE: 55 if (!ppMergeScaleZero(config)) { 56 psErrorStackPrint(stderr, "Error getting scale and zero-points."); 57 exitValue = PS_EXIT_DATA_ERROR; 58 goto die; 59 } 60 if (!ppMergeLoop(config)) { 61 psErrorStackPrint(stderr, "Error performing merge."); 62 exitValue = PS_EXIT_PROG_ERROR; 63 goto die; 64 } 65 break; 66 default: 67 psAbort("Invalid frame type: %x", type); 68 } 69 70 71 // Output the statistics 72 bool mdok; // Status of MD lookup 73 psString statsName = psMetadataLookupStr(&mdok, config->arguments, "STATS.NAME"); // Statistics file name 74 if (mdok && statsName && strlen(statsName) > 0) { 75 psString resolved = pmConfigConvertFilename(statsName, config, true); // Resolved filename 76 FILE *statsFile = fopen(resolved, "w"); // Output statistics file 77 if (!statsFile) { 78 psError(PS_ERR_IO, true, "Unable to open statistics file %s for writing.", resolved); 79 psFree(resolved); 80 exitValue = PS_EXIT_CONFIG_ERROR; 81 goto die; 82 } 83 psFree(resolved); 84 psMetadata *stats = psMetadataLookupMetadata(&mdok, config->arguments, "STATS.DATA"); // Statistics 85 if (!stats) { 86 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find statistics"); 87 exitValue = PS_EXIT_PROG_ERROR; 88 goto die; 89 } 90 psString statsOut = psMetadataConfigFormat(stats); // String to write out 91 fprintf(statsFile, "%s", statsOut); 92 psFree(statsOut); 93 fclose(statsFile); 94 } 95 96 97 98 99 #if 0 42 100 // Set various tasks (define optional operations) 43 101 ppMergeOptions *options = ppMergeOptionsParse(config); … … 81 139 } 82 140 83 #if 084 pmFPAPrint(stdout, data->out, true, true);85 #endif86 87 141 // Cleaning up 88 142 psFree(data); 89 143 psFree(options); 144 #endif 145 146 die: 147 psTrace("ppSub", 1, "Finished at %f sec\n", psTimerMark("ppSub")); 148 psTimerStop(); 149 90 150 psFree(config); 91 92 pmConceptsDone();93 151 pmConfigDone(); 94 152 psLibFinalize(); 95 153 96 // ppMemCheck(); 97 98 return EXIT_SUCCESS; 154 exit(exitValue); 99 155 } -
branches/pap_branch_080320/ppMerge/src/ppMerge.h
r8405 r17083 2 2 #define PP_MERGE_H 3 3 4 #define TIMERNAME "ppMerge" 5 #define PPMERGE_RECIPE "PPMERGE" 4 #define TIMERNAME "ppMerge" // Name for timer 5 #define PPMERGE_RECIPE "PPMERGE" // Recipe name 6 7 // Type of frame to merge 8 typedef enum { 9 PPMERGE_TYPE_UNKNOWN, // Unknown type 10 PPMERGE_TYPE_BIAS, // Bias frame 11 PPMERGE_TYPE_DARK, // (Multi-)Dark frame 12 PPMERGE_TYPE_MASK, // Mask frame 13 PPMERGE_TYPE_SHUTTER, // Shutter frame 14 PPMERGE_TYPE_FLAT, // Flat-field frame (dome or sky) 15 PPMERGE_TYPE_FRINGE, // Fringe frame 16 } ppMergeType; 17 18 // Files, for activation 19 typedef enum { 20 PPMERGE_FILES_ALL, // All files 21 PPMERGE_FILES_INPUT, // Input files 22 PPMERGE_FILES_OUTPUT // Output files 23 } ppMergeFiles; 24 25 // Parse command-line arguments and recipe 26 bool ppMergeArguments(int argc, char *argv[], // Command-line arguments 27 pmConfig *config // Configuration 28 ); 29 30 // Set up camera files 31 bool ppMergeCamera(pmConfig *config // Configuration 32 ); 33 34 // Measure scale and zero-points 35 bool ppMergeScaleZero(pmConfig *config // Configuration 36 ); 37 38 // Main loop to do the merging 39 bool ppMergeLoop(pmConfig *config // Configuration 40 ); 41 42 // Main loop for masks 43 bool ppMergeMask(pmConfig *config // Configuration 44 ); 45 46 // Read nominated input file 47 bool ppMergeFileReadInput(const pmConfig *config, // Configuration 48 pmReadout *readout, // Readout into which to read 49 int num, // Number of file in sequence 50 int rows // Number of rows to read at once 51 ); 52 53 // Open nominated input file 54 bool ppMergeFileOpenInput(pmConfig *config, // Configuration 55 const pmFPAview *view, // View to open 56 int num // Number of file in sequence 57 ); 58 59 // Set the data level for files specified by name; return an array of the files 60 psArray *ppMergeFileDataLevel(const pmConfig *config, // Configuration 61 const char *name, // Name of files 62 pmFPALevel level // Level for file data level 63 ); 64 65 // Activate/deactivate a list of files 66 bool ppMergeFileActivate(const pmConfig *config, // Configuration 67 ppMergeFiles files, // Files to turn on/off 68 bool state // Activation state 69 ); 70 71 // Activate/deactivate a single element for a list; return array of files 72 psArray *ppMergeFileActivateSingle(const pmConfig *config, // Configuration 73 ppMergeFiles files, // Files to turn on/off 74 bool state, // Activation state 75 int num // Number of file in sequence 76 ); 77 78 // Return name of output pmFPAfile 79 psString ppMergeOutputFile(const pmConfig *config // Configuration 80 ); 6 81 7 82 #endif -
branches/pap_branch_080320/ppMerge/src/ppMergeMask.c
r15937 r17083 5 5 #include <stdio.h> 6 6 #include <string.h> 7 #include <unistd.h>8 7 #include <assert.h> 8 9 9 #include <pslib.h> 10 10 #include <psmodules.h> … … 12 12 13 13 #include "ppMerge.h" 14 #include "ppMergeData.h" 15 #include "ppMergeMask.h" 16 17 18 // Generate a mask 19 bool ppMergeMask(ppMergeData *data, // Data 20 ppMergeOptions *options, // Options 21 pmConfig *config // Configuration 22 ) 14 15 static bool mergeMask(pmConfig *config, // Configuration 16 const pmFPAview *view, // View to chip 17 bool writeOut, // Write output? 18 psRandom *rng, // Random number generator 19 psMetadata *stats // Statistics output 20 ) 23 21 { 24 for (int i = 0; i < 2; i++) { 25 if (!ppMergeMaskSuspect (data, options, config)) { 26 psError(PS_ERR_UNKNOWN, true, "failed on mask suspect.\n"); 27 return false; 28 } 29 30 if (!ppMergeMaskBad (data, options, config)) { 31 psError(PS_ERR_UNKNOWN, true, "failed on mask bad.\n"); 32 return false; 33 } 34 } 35 36 if (!ppMergeMaskAverageConcepts (data, options, config)) { 37 psError(PS_ERR_UNKNOWN, true, "failed on average concepts.\n"); 38 return false; 39 } 40 41 if (!ppMergeMaskGrow (data, options, config)) { 42 psError(PS_ERR_UNKNOWN, true, "failed on mask grow.\n"); 43 return false; 44 } 45 46 if (!ppMergeMaskWrite (data, options, config)) { 47 psError(PS_ERR_UNKNOWN, true, "failed on mask write.\n"); 48 return false; 49 } 50 22 assert(config); 23 assert(view); 24 assert(view->chip != -1 && view->cell == -1 && view->readout == -1); 25 26 bool mdok; // Status of MD lookup 27 int numFiles = psMetadataLookupS32(NULL, config->arguments, "INPUTS.NUM"); // Number of input files 28 psStatsOptions meanStat = psMetadataLookupS32(NULL, config->arguments, "MEAN"); // Statistic for mean 29 psStatsOptions stdevStat = psMetadataLookupS32(NULL, config->arguments, "STDEV"); // Statistic for stdev 30 psMaskType maskVal = psMetadataLookupU8(NULL, config->arguments, "MASKVAL"); // Value to mask 31 int sample = psMetadataLookupS32(NULL, config->arguments, "SAMPLE"); // Size of sample for statistics 32 bool chipStats = psMetadataLookupBool(&mdok, config->arguments, "MASK.CHIPSTATS"); // Statistics on chip? 33 float maskSuspect = psMetadataLookupF32(NULL, config->arguments, "MASK.SUSPECT"); // Threshold for suspect pixels 34 float maskBad = psMetadataLookupF32(NULL, config->arguments, "MASK.BAD"); // Threshold for bad pixels 35 pmMaskIdentifyMode maskMode = psMetadataLookupS32(NULL, config->arguments, "MASK.MODE"); // Mode for identifying bad pixels 36 int maskGrow = psMetadataLookupS32(NULL, config->arguments, "MASK.GROW"); // Radius to grow mask 37 psMaskType maskGrowVal = psMetadataLookupU8(NULL, config->arguments, "MASK.GROWVAL"); // Value for grown mask 38 39 psStats *statistics = psStatsAlloc(meanStat | stdevStat); // Statistics for background 40 41 psString outName = ppMergeOutputFile(config); // Name of output file 42 pmChip *outChip = pmFPAfileThisChip(config->files, view, outName); // Output chip 43 psFree(outName); 44 45 // For each input file, get the statistics, which can be calculated at the chip or cell levels 46 psArray *suspects = psArrayAlloc(outChip->cells->n); // Images with suspected pixels 47 psVector *values = psVectorAlloc(sample, PS_TYPE_F32); // Pixel values for statistics 48 pmFPAview *inView = pmFPAviewAlloc(0); // View for input 49 for (int i = 0; i < numFiles; i++) { 50 pmFPAfileActivate(config->files, false, NULL); 51 psArray *files = ppMergeFileActivateSingle(config, PPMERGE_FILES_INPUT, true, i); // Input files 52 pmFPAfile *input = files->data[0]; // Input file 53 psFree(files); 54 pmFPA *inFPA = input->fpa; // Input FPA 55 *inView = *view; 56 57 int valueIndex = 0; // Index for vector of pixel values 58 59 pmCell *inCell; // Input cell 60 while ((inCell = pmFPAviewNextCell(inView, inFPA, 1))) { 61 pmHDU *hdu = pmHDUFromCell(inCell); // HDU for cell 62 if (!hdu || hdu->blankPHU) { 63 // No data here 64 continue; 65 } 66 psTrace("ppMerge", 1, "Getting suspect pixels for file %d chip %d cell %d", 67 i, inView->chip, inView->cell); 68 69 if (!pmFPAfileIOChecks(config, inView, PM_FPA_BEFORE)) { 70 psFree(inView); 71 goto MERGE_MASK_ERROR; 72 } 73 74 if (!ppMergeFileOpenInput(config, view, i)) { 75 psError(PS_ERR_UNKNOWN, false, "Unable to open file %d", i); 76 psFree(inView); 77 goto MERGE_MASK_ERROR; 78 } 79 80 if (inCell->readouts->n > 1) { 81 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 82 "File %d chip %d cell %d contains more than one readout (%ld)", 83 i, inView->chip, inView->cell, inCell->readouts->n); 84 psFree(inView); 85 goto MERGE_MASK_ERROR; 86 } 87 88 pmReadout *readout; 89 if (inCell->readouts && inCell->readouts->n == 1) { 90 readout = psMemIncrRefCounter(inCell->readouts->data[0]); // Input readout 91 } else { 92 readout = pmReadoutAlloc(inCell); 93 } 94 95 if (!ppMergeFileReadInput(config, readout, i, 0)) { 96 psError(PS_ERR_UNKNOWN, false, "Unable to read readout %d", i); 97 psFree(inView); 98 psFree(readout); 99 goto MERGE_MASK_ERROR; 100 } 101 102 psImage *outMask = NULL; // Output mask image (for iterative generation of mask) 103 pmCell *outCell = pmFPAfileThisCell(config->files, inView, "PPMERGE.OUTPUT.MASK"); // Output cell 104 if (outCell->readouts && outCell->readouts->n == 1) { 105 pmReadout *outRO = outCell->readouts->data[0]; // Output readout 106 if (outRO) { 107 outMask = outRO->mask; 108 } 109 } 110 111 psImage *image = readout->image, *mask = readout->mask; // Image and mask 112 int numCols = readout->image->numCols, numRows = readout->image->numRows; // Image size 113 int numPix = numCols * numRows; // Number of pixels 114 int numCells = chipStats ? readout->parent->parent->cells->n : 1; // Number of cells 115 int num = PS_MIN(numPix, sample / numCells); // Number of values to add 116 if (!chipStats) { 117 valueIndex = 0; 118 } 119 for (int i = 0; i < num; i++) { 120 int pixel = numPix * psRandomUniform(rng); 121 int x = pixel % numCols; 122 int y = pixel / numCols; 123 if ((mask && (mask->data.PS_TYPE_MASK_DATA[y][x] & maskVal)) || 124 !isfinite(image->data.F32[y][x]) || 125 (outMask && (outMask->data.PS_TYPE_MASK_DATA[y][x] & maskVal))) { 126 continue; 127 } 128 129 values->data.F32[valueIndex++] = image->data.F32[y][x]; 130 } 131 132 if (!chipStats) { 133 values->n = valueIndex; 134 if (!psVectorStats(statistics, values, NULL, NULL, 0)) { 135 psError(PS_ERR_UNKNOWN, false, "Unable to do statistics on readout."); 136 psFree(inView); 137 psFree(readout); 138 goto MERGE_MASK_ERROR; 139 } 140 141 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, PM_MASK_ANALYSIS_MEAN, PS_META_REPLACE, 142 "Mean value of readout", psStatsGetValue(statistics, meanStat)); 143 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, PM_MASK_ANALYSIS_STDEV, PS_META_REPLACE, 144 "Stdev value of readout", psStatsGetValue(statistics, stdevStat)); 145 suspects->data[inView->cell] = pmMaskFlagSuspectPixels(suspects->data[inView->cell], 146 readout, maskSuspect, maskVal); 147 pmCellFreeData(inCell); 148 149 if (!pmFPAfileIOChecks(config, inView, PM_FPA_AFTER)) { 150 psFree(inView); 151 psFree(readout); 152 goto MERGE_MASK_ERROR; 153 } 154 } 155 psFree(readout); 156 } 157 158 // Additional run through cells if we want chip-level statistics 159 if (chipStats && valueIndex > 0) { 160 values->n = valueIndex; 161 if (!psVectorStats(statistics, values, NULL, NULL, 0)) { 162 psError(PS_ERR_UNKNOWN, false, "Unable to do statistics on chip."); 163 goto MERGE_MASK_ERROR; 164 } 165 inView->cell = -1; 166 while ((inCell = pmFPAviewNextCell(inView, inFPA, 1))) { 167 pmHDU *hdu = pmHDUFromCell(inCell); // HDU for cell 168 if (!hdu || hdu->blankPHU) { 169 // No data here 170 continue; 171 } 172 pmReadout *readout = inCell->readouts->data[0]; // Readout of interest 173 174 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, PM_MASK_ANALYSIS_MEAN, PS_META_REPLACE, 175 "Mean value of chip", psStatsGetValue(statistics, meanStat)); 176 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, PM_MASK_ANALYSIS_STDEV, PS_META_REPLACE, 177 "Stdev value of chip", psStatsGetValue(statistics, stdevStat)); 178 suspects->data[inView->cell] = pmMaskFlagSuspectPixels(suspects->data[inView->cell], 179 readout, maskSuspect, maskVal); 180 pmCellFreeData(inCell); 181 182 if (!pmFPAfileIOChecks(config, inView, PM_FPA_AFTER)) { 183 psFree(inView); 184 goto MERGE_MASK_ERROR; 185 } 186 } 187 } 188 } 189 psFree(inView); 190 psFree(statistics); statistics = NULL; 191 psFree(values); values = NULL; 192 193 194 // Another run through the chip to threshold on the suspects 195 pmFPAfileActivate(config->files, false, NULL); 196 if (writeOut) { 197 ppMergeFileActivate(config, PPMERGE_FILES_OUTPUT, true); 198 } 199 pmFPA *outFPA = outChip->parent; // Output FPA 200 pmCell *outCell; // Output cell 201 pmFPAview *outView = pmFPAviewAlloc(0); // View into output FPA 202 *outView = *view; 203 while ((outCell = pmFPAviewNextCell(outView, outFPA, 1))) { 204 pmHDU *hdu = pmHDUFromCell(outCell); // HDU for cell 205 if (!hdu || hdu->blankPHU) { 206 // No data here 207 continue; 208 } 209 210 psTrace("ppMerge", 1, "Getting bad pixels for chip %d cell %d", outView->chip, outView->cell); 211 212 pmReadout *outRO = NULL; // Output readout 213 if (outCell->readouts && outCell->readouts->n == 1) { 214 outRO = psMemIncrRefCounter(outCell->readouts->data[0]); 215 } else { 216 outRO = pmReadoutAlloc(outCell); 217 } 218 219 psImage *mask = pmMaskIdentifyBadPixels(suspects->data[outView->cell], maskVal, numFiles, maskBad, 220 maskMode); 221 psFree(suspects->data[outView->cell]); 222 suspects->data[outView->cell] = NULL; 223 if (maskGrowVal > 0) { 224 outRO->mask = psImageGrowMask(outRO->mask, mask, maskVal, maskGrow, maskGrowVal); 225 psFree(mask); 226 } else { 227 psFree(outRO->mask); 228 outRO->mask = mask; 229 } 230 231 outRO->data_exists = outCell->data_exists = outChip->data_exists = true; 232 233 if (writeOut) { 234 if (!pmFPAfileIOChecks(config, outView, PM_FPA_BEFORE)) { 235 psFree(outView); 236 goto MERGE_MASK_ERROR; 237 } 238 239 // Average concepts 240 psList *cells = psListAlloc(NULL); // List of cells, for concept averaging 241 for (int i = 0; i < numFiles; i++) { 242 pmFPAfile *inFile = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT", i); // Input file 243 pmCell *inCell = pmFPAviewThisCell(outView, inFile->fpa); // Input cell 244 psListAdd(cells, PS_LIST_TAIL, inCell); 245 } 246 if (!pmConceptsAverageCells(outCell, cells, NULL, NULL, true)) { 247 psError(PS_ERR_UNKNOWN, false, "Unable to average cell concepts."); 248 psFree(cells); 249 psFree(outRO); 250 psFree(outView); 251 return false; 252 } 253 psFree(cells); 254 255 // Statistics on the merged cell using a fake image 256 outRO->image = psImageAlloc(outRO->mask->numCols, outRO->mask->numRows, PS_TYPE_F32); 257 psImageInit(outRO->image, 1.0); 258 if (!ppStatsFPA(stats, outRO->parent->parent->parent, outView, 259 maskVal | pmConfigMask("BLANK", config), config)) { 260 psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to generate stats for image."); 261 psFree(outRO); 262 psFree(outView); 263 return false; 264 } 265 psFree(outRO->image); 266 outRO->image = NULL; 267 268 // Write 269 if (!pmFPAfileIOChecks(config, outView, PM_FPA_AFTER)) { 270 psFree(outView); 271 goto MERGE_MASK_ERROR; 272 } 273 } 274 psFree(outRO); 275 } 276 psFree(outView); 277 278 ppMergeFileActivate(config, PPMERGE_FILES_ALL, true); 279 280 psFree(suspects); 51 281 return true; 282 283 284 MERGE_MASK_ERROR: 285 psFree(suspects); 286 psFree(statistics); 287 psFree(values); 288 return false; 52 289 } 53 290 54 bool ppMergeMaskReadoutStats(const pmReadout *readout, 55 const pmReadout *output, 56 ppMergeOptions *options, // Options 57 psRandom *rng) 291 292 293 294 295 bool ppMergeMask(pmConfig *config) 58 296 { 59 PS_ASSERT_PTR_NON_NULL(readout, false); 60 PS_ASSERT_IMAGE_NON_NULL(readout->image, false); 61 PS_ASSERT_IMAGE_NON_EMPTY(readout->image, false); 62 PS_ASSERT_IMAGE_TYPE(readout->image, PS_TYPE_F32, false); 63 if (readout->mask) { 64 PS_ASSERT_IMAGE_NON_EMPTY(readout->mask, false); 65 PS_ASSERT_IMAGES_SIZE_EQUAL(readout->image, readout->mask, false); 66 PS_ASSERT_IMAGE_TYPE(readout->mask, PS_TYPE_MASK, false); 67 } 68 69 psImage *mask = NULL; 70 psImage *image = readout->image; // Image of interest 71 72 if (output) { 73 mask = output->mask; // Corresponding mask 74 } 75 76 if (rng) { 77 psMemIncrRefCounter(rng); 78 } else { 79 rng = psRandomAlloc(PS_RANDOM_TAUS, 0); 80 } 81 82 // XXX note that this now will accept any of several stats options 83 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 84 stats->nSubsample = options->sample; 85 86 if (!psImageBackground(stats, NULL, image, mask, options->combine->maskVal, rng)) { 87 psError(PS_ERR_UNKNOWN, false, "Failure to measure image statistics.\n"); 88 psFree(stats); 89 psFree(rng); 90 return false; 91 } 92 if (!isfinite(stats->robustMedian) || !isfinite(stats->robustUQ) || !isfinite(stats->robustLQ)) { 93 psError(PS_ERR_UNKNOWN, false, "invalide image statistics (nan).\n"); 94 psFree(stats); 95 psFree(rng); 96 return false; 97 } 98 99 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "READOUT.MEDIAN", PS_META_REPLACE, "image stats", stats->robustMedian); 100 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "READOUT.STDEV", PS_META_REPLACE, "image stats", stats->robustStdev); 101 297 assert(config); 298 299 bool mdok; // Status of MD lookup 300 int numFiles = psMetadataLookupS32(NULL, config->arguments, "INPUTS.NUM"); // Number of inputs 301 bool haveMasks = psMetadataLookupBool(&mdok, config->arguments, "INPUTS.MASKS"); // Do we have masks? 302 bool haveWeights = psMetadataLookupBool(&mdok, config->arguments, "INPUTS.WEIGHTS"); // Do we have weights? 303 int iter = psMetadataLookupS32(NULL, config->arguments, "ITER"); // Number of rejection iterations 304 305 PS_ASSERT_INT_POSITIVE(iter, false); 306 307 pmFPAview *view = pmFPAviewAlloc(0); // View to component of interest 308 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS, 0); // Random number generator 309 310 psMetadata *stats = NULL; // Statistics for output 311 if (psMetadataLookup(config->arguments, "STATS.NAME")) { 312 stats = psMetadataAlloc(); 313 psMetadataAddMetadata(config->arguments, PS_LIST_TAIL, "STATS.DATA", 0, "Statistics output", stats); 314 } 315 316 psArray *inputs = ppMergeFileDataLevel(config, "PPMERGE.INPUT", PM_FPA_LEVEL_READOUT); // Input images 317 psFree(inputs); 318 if (haveMasks) { 319 psArray *masks = ppMergeFileDataLevel(config, "PPMERGE.INPUT.MASK", PM_FPA_LEVEL_READOUT); 320 psFree(masks); 321 } 322 if (haveWeights) { 323 psArray *weights = ppMergeFileDataLevel(config, "PPMERGE.INPUT.WEIGHT", PM_FPA_LEVEL_READOUT); 324 psFree(weights); 325 } 326 327 if (!ppMergeFileActivate(config, PPMERGE_FILES_INPUT, true)) { 328 psError(PS_ERR_UNKNOWN, false, "Unable to activate files."); 329 goto PPMERGE_MASK_ERROR; 330 } 331 if (!ppMergeFileActivate(config, PPMERGE_FILES_OUTPUT, false)) { 332 psError(PS_ERR_UNKNOWN, false, "Unable to activate files."); 333 goto PPMERGE_MASK_ERROR; 334 } 335 336 psString outName = ppMergeOutputFile(config); // Name of output file 337 pmFPAfile *output = psMetadataLookupPtr(NULL, config->files, outName); // Output file 338 psFree(outName); 339 assert(output && output->fpa); 340 pmFPA *outFPA = output->fpa; // Output FPA 341 342 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 343 goto PPMERGE_MASK_ERROR; 344 } 345 pmChip *outChip; // Chip of interest 346 while ((outChip = pmFPAviewNextChip(view, outFPA, 1))) { 347 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 348 goto PPMERGE_MASK_ERROR; 349 } 350 351 for (int i = 0; i < iter; i++) { 352 if (!mergeMask(config, view, (i == iter - 1), rng, stats)) { 353 psError(PS_ERR_UNKNOWN, false, "Unable to merge chip %d", view->chip); 354 goto PPMERGE_MASK_ERROR; 355 } 356 } 357 358 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 359 goto PPMERGE_MASK_ERROR; 360 } 361 } 362 363 psList *fpaList = psListAlloc(NULL);// List of FPAs for concept averaging 364 for (int i = 0; i < numFiles; i++) { 365 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT", i); // Input file 366 psListAdd(fpaList, PS_LIST_TAIL, file->fpa); 367 } 368 if (!pmConceptsAverageFPAs(outFPA, fpaList)) { 369 psError(PS_ERR_UNKNOWN, false, "Unable to average FPA concepts."); 370 psFree(fpaList); 371 goto PPMERGE_MASK_ERROR; 372 } 373 psFree(fpaList); 374 375 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 376 goto PPMERGE_MASK_ERROR; 377 } 378 379 psFree(stats); 380 psFree(view); 102 381 psFree(rng); 382 103 383 return true; 384 385 PPMERGE_MASK_ERROR: 386 psFree(stats); 387 psFree(view); 388 psFree(rng); 389 return false; 104 390 } 105 391 106 bool ppMergeMaskChipStats (const pmChip *chip,107 const pmChip *output,108 ppMergeOptions *options,109 psRandom *rng)110 {111 PS_ASSERT_PTR_NON_NULL(chip, false);112 113 // XXX note that this now will accept any of several stats options114 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);115 116 if (rng) {117 psMemIncrRefCounter(rng);118 } else {119 rng = psRandomAlloc(PS_RANDOM_TAUS, 0);120 }121 122 // accumulate a vector of data values using options->sample per readout123 psVector *values = psVectorAllocEmpty(options->sample, PS_TYPE_F32); // Vector containing subsample124 125 for (int nCell = 0; nCell < chip->cells->n; nCell++) {126 pmCell *cell = chip->cells->data[nCell];127 if (cell->readouts->n == 0) continue;128 129 for (int nReadout = 0; nReadout < cell->readouts->n; nReadout++) {130 pmReadout *readout = cell->readouts->data[nReadout];131 if (!readout->image) continue;132 133 psTrace("ppMerge", 4, "Measure statistics for cell %d, readout %d\n", nCell, nReadout);134 135 psImage *image = readout->image; // Image of interest136 137 pmCell *cellOutput = output->cells->data[nCell];138 pmReadout *readoutOutput = NULL;139 psImage *mask = NULL;140 if (cellOutput->readouts->n > 0) {141 readoutOutput = cellOutput->readouts->data[0];142 mask = readoutOutput->mask; // Corresponding mask143 }144 145 // Size of image146 long nx = image->numCols;147 long ny = image->numRows;148 const int Npixels = nx*ny; // Total number of pixels149 const int Nsubset = PS_MIN(options->sample, Npixels); // Number of pixels in subset150 151 values = psVectorRealloc (values, values->n + Nsubset); // make sure we have enough space152 153 // select a subset of the image pixels to measure the stats154 for (long i = 0; i < Nsubset; i++) {155 double frnd = psRandomUniform(rng);156 int pixel = Npixels * frnd;157 int ix = pixel % nx;158 int iy = pixel / nx;159 160 if (!isfinite(image->data.F32[iy][ix])) continue;161 if (mask && (mask->data.U8[iy][ix] & options->combine->maskVal)) continue;162 163 float value = image->data.F32[iy][ix];164 values->data.F32[values->n] = value;165 values->n ++;166 }167 }168 }169 170 // no valid data, skip the chip171 if (!values->n) {172 psFree(values);173 psFree(stats);174 psFree(rng);175 return true;176 }177 178 // calculate the statistics179 if (!psVectorStats (stats, values, NULL, NULL, 0)) {180 psError(PS_ERR_UNKNOWN, false, "Unable to measure statistics for chip");181 psFree(values);182 psFree(stats);183 psFree(rng);184 return false;185 }186 if (!isfinite(stats->robustMedian) || !isfinite(stats->robustUQ) || !isfinite(stats->robustLQ)) {187 psError(PS_ERR_UNKNOWN, false, "invalid image statistics (nan).\n");188 psFree(values);189 psFree(stats);190 psFree(rng);191 return false;192 }193 194 // supply the stats to the readout analysis metadata195 for (int nCell = 0; nCell < chip->cells->n; nCell++) {196 pmCell *cell = chip->cells->data[nCell];197 if (cell->readouts->n == 0) continue;198 199 for (int nReadout = 0; nReadout < cell->readouts->n; nReadout++) {200 pmReadout *readout = cell->readouts->data[nReadout];201 if (!readout->image) continue;202 203 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "READOUT.MEDIAN", PS_META_REPLACE, "image stats", stats->robustMedian);204 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "READOUT.STDEV", PS_META_REPLACE, "image stats", stats->robustStdev);205 }206 }207 208 psLogMsg ("ppMerge", PS_LOG_INFO, "statistics for chip: %f +/- %f\n", stats->robustMedian, stats->robustStdev);209 210 psFree(values);211 psFree(stats);212 psFree(rng);213 return true;214 } -
branches/pap_branch_080320/ppMerge/src/ppMergeScaleZero.c
r16842 r17083 10 10 11 11 #include "ppMerge.h" 12 #include "ppMergeScaleZero.h"13 12 14 13 // Get the scale and zero for each chip of each input 15 bool ppMergeScaleZero(psImage **scales, // The scales for each integration/cell 16 psImage **zeros, // The zeroes for each integration/cell 17 psArray **shutters, // The shutter correction data for each cell 18 ppMergeData *data,// The data 19 const ppMergeOptions *options, // The options 20 const pmConfig *config // The configuration 21 ) 14 bool ppMergeScaleZero(pmConfig *config) 22 15 { 23 assert(data);24 assert(options);25 16 assert(config); 26 17 27 if (!options->scale && !options->zero && !options->shutter) { 28 return true; // We did everything we were asked for 18 ppMergeType type = psMetadataLookupS32(NULL, config->arguments, "TYPE"); // Type of frame 19 int numInputs = psMetadataLookupS32(NULL, config->arguments, "INPUTS.NUM"); // Number of inputs 20 int numCells = psMetadataLookupS32(NULL, config->arguments, "INPUTS.CELLS"); // Number of cells 21 psStatsOptions meanStat = psMetadataLookupS32(NULL, config->arguments, "MEAN"); // Statistic for mean 22 psStatsOptions stdevStat = psMetadataLookupS32(NULL, config->arguments, "STDEV"); // Statistic for stdev 23 psMaskType maskVal = psMetadataLookupU8(NULL, config->arguments, "MASKVAL"); // Value to mask 24 int shutterSize = psMetadataLookupS32(NULL, config->arguments, "SHUTTER.SIZE"); // Size of shutter region 25 int sample = psMetadataLookupS32(NULL, config->arguments, "SAMPLE"); // Maximum size of sample 26 bool chipStats = false; // Do statistics on full chip instead of cell? 27 28 psVector *gains = NULL; // Gains for each cell 29 psArray *shutters = NULL; // Shutter data for each cell 30 psStats *stats = NULL; // Statistics for background 31 psImage *background = NULL; // Background measurements per cell per file 32 33 switch (type) { 34 case PPMERGE_TYPE_BIAS: 35 case PPMERGE_TYPE_DARK: 36 // Nothing to measure 37 return true; 38 case PPMERGE_TYPE_FLAT: 39 case PPMERGE_TYPE_FRINGE: 40 gains = psVectorAlloc(numCells, PS_TYPE_F32); 41 background = psImageAlloc(numCells, numInputs, PS_TYPE_F32); 42 psImageInit(background, NAN); 43 stats = psStatsAlloc(meanStat); 44 break; 45 case PPMERGE_TYPE_SHUTTER: 46 shutters = psArrayAlloc(numCells); 47 break; 48 case PPMERGE_TYPE_MASK: 49 stats = psStatsAlloc(meanStat | stdevStat); 50 default: 51 break; 29 52 } 30 31 assert(config->camera); // Need the camera configuration 32 assert(config->arguments); // Need the list of files 33 34 psArray *filenames = psMetadataLookupPtr(NULL, config->arguments, "INPUT"); // The input file names 35 assert(filenames); // It should be here --- it's put here in ppMergeConfig 36 37 // Sanity checks 38 assert(!options->scale || scales); 39 assert(!scales || !*scales || ((*scales)->type.type == PS_TYPE_F32 && 40 (*scales)->numCols == data->numCells && 41 (*scales)->numRows == filenames->n)); 42 assert(!options->zero || zeros); 43 assert(!zeros || !*zeros || ((*zeros)->type.type == PS_TYPE_F32 && 44 (*zeros)->numCols == data->numCells && 45 (*zeros)->numRows == filenames->n)); 46 assert(!options->shutter || shutters); 47 assert(!shutters || !*shutters || (*shutters)->n == data->numCells); 48 49 // Allocate the outputs 50 if (options->scale) { 51 if (*scales) { 52 psFree(*scales); 53 } 54 *scales = psImageAlloc(data->numCells, filenames->n, PS_TYPE_F32); 55 } 56 if (options->zero) { 57 if (*zeros) { 58 psFree(*zeros); 59 } 60 *zeros = psImageAlloc(data->numCells, filenames->n, PS_TYPE_F32); 61 } 62 psRandom *rng = NULL; // Random number generator 63 if (options->shutter) { 64 if (*shutters) { 65 psFree(*shutters); 66 } 67 *shutters = psArrayAlloc(data->numCells); 68 rng = psRandomAlloc(PS_RANDOM_TAUS, 0); 69 } 70 71 bool fromConcepts = false; // Do we get the scale and zero points from the concepts? 72 bool first = true; // Are we on the first cell (that sets the standard for the rest)? 73 bool done = false; // Are we done going through the list? 74 bool mdok = true; // Status of MD lookup 75 for (long i = 0; i < data->in->n && !done; i++) { 76 pmFPA *fpa = data->in->data[i]; // The FPA 77 if (!fpa) { 78 continue; 79 } 80 long cellNum = -1; // Number of the cell 81 psArray *chips = fpa->chips; // The array of chips 82 for (long j = 0; j < chips->n && !done; j++) { 83 pmChip *chip = chips->data[j]; // The chip 84 if (!chip) { 85 continue; 86 } 87 psArray *cells = chip->cells; // The array of cells 88 for (long k = 0; k < cells->n && !done; k++) { 89 pmCell *cell = cells->data[k]; // The cell 90 if (!cell) { 53 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS, 0); // Random number generator 54 pmFPAview *view = NULL; // View into FPA 55 56 psVector *values = psVectorAlloc(sample, PS_TYPE_F32); // Values for statistics 57 58 for (int i = 0; i < numInputs; i++) { 59 pmFPAfileActivate(config->files, false, NULL); 60 psArray *files = ppMergeFileActivateSingle(config, PPMERGE_FILES_INPUT, true, i); // Activated files 61 pmFPAfile *input = files->data[0]; // Representative file; should be the image (not mask or weight) 62 pmFPA *fpa = input->fpa; // FPA of interest 63 view = pmFPAviewAlloc(0); // View to component of interest 64 int cellNum = 0; // Index for cell 65 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 66 goto ERROR; 67 } 68 pmChip *chip; // Chip of interest 69 while ((chip = pmFPAviewNextChip(view, fpa, 1))) { 70 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 71 goto ERROR; 72 } 73 74 int valueIndex = 0; // Index into values vector 75 76 pmCell *cell; // Cell of interest 77 while ((cell = pmFPAviewNextCell(view, fpa, 1))) { 78 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 79 goto ERROR; 80 } 81 82 if (!cell->data_exists) { 91 83 continue; 92 84 } 85 86 if (cell->readouts->n > 1) { 87 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 88 "File %d chip %d cell %d contains more than one readout (%ld)", 89 i, view->chip, view->cell, cell->readouts->n); 90 goto ERROR; 91 } 92 pmReadout *readout = cell->readouts->data[0]; // Readout of interest 93 94 switch (type) { 95 case PPMERGE_TYPE_FLAT: 96 case PPMERGE_TYPE_FRINGE: { 97 // Extract the gain 98 float gain = psMetadataLookupF32(NULL, cell->concepts, "CELL.GAIN"); // Cell gain 99 if (!isfinite(gain)) { 100 psError(PS_ERR_BAD_PARAMETER_VALUE, false, 101 "CELL.GAIN for file %d chip %d cell %d is not set.", 102 i, view->chip, view->cell); 103 goto ERROR; 104 } 105 gains->data.F32[cellNum] = gain; 106 107 // Measure the background 108 if (!psImageBackground(stats, NULL, readout->image, readout->mask, maskVal, rng)) { 109 psError(PS_ERR_UNKNOWN, false, 110 "Unable to get statistics for file %d chip %d cell %d", 111 i, view->chip, view->cell); 112 goto ERROR; 113 } 114 background->data.F32[cellNum][i] = psStatsGetValue(stats, meanStat); 115 break; 116 } 117 case PPMERGE_TYPE_SHUTTER: { 118 pmShutterCorrectionData *shutter = shutters->data[cellNum]; // Shutter correction data 119 if (!shutter) { 120 shutter = pmShutterCorrectionDataAlloc(readout->image->numCols, 121 readout->image->numRows, 122 shutterSize); 123 shutters->data[cellNum] = shutter; 124 } 125 if (!pmShutterCorrectionAddReadout(shutter, readout, meanStat, stdevStat, 126 maskVal, rng)) { 127 psError(PS_ERR_UNKNOWN, false, 128 "Can't add file %d chip %d cell %d to shutter correction.", 129 i, view->chip, view->cell); 130 goto ERROR; 131 } 132 break; 133 } 134 case PPMERGE_TYPE_MASK: { 135 psImage *image = readout->image, *mask = readout->mask; // Image and mask 136 int numCols = readout->image->numCols, numRows = readout->image->numRows; // Image size 137 int numPix = numCols * numRows; // Number of pixels 138 int numCells = chipStats ? readout->parent->parent->cells->n : 1; // Number of cells 139 int num = PS_MIN(numPix, sample / numCells); // Number of values to add 140 if (!chipStats) { 141 valueIndex = 0; 142 } 143 for (int i = 0; i < num; i++) { 144 int pixel = numPix * psRandomUniform(rng); 145 int x = pixel % numCols; 146 int y = pixel / numCols; 147 if ((mask && (mask->data.PS_TYPE_MASK_DATA[y][x] & maskVal)) || 148 !isfinite(image->data.F32[y][x])) { 149 continue; 150 } 151 152 values->data.F32[valueIndex++] = image->data.F32[y][x]; 153 } 154 155 if (!chipStats) { 156 if (!psVectorStats(stats, values, NULL, NULL, 0)) { 157 psError(PS_ERR_UNKNOWN, false, "Unable to do statistics on readout."); 158 goto ERROR; 159 } 160 161 psMetadataAddF32(cell->analysis, PS_LIST_TAIL, PM_MASK_ANALYSIS_MEAN, 0, 162 "Mean value of readout", psStatsGetValue(stats, meanStat)); 163 psMetadataAddF32(cell->analysis, PS_LIST_TAIL, PM_MASK_ANALYSIS_STDEV, 0, 164 "Stdev value of readout", psStatsGetValue(stats, stdevStat)); 165 } 166 break; 167 } 168 default: 169 psAbort("Should never get here."); 170 } 171 93 172 cellNum++; 94 173 95 if (options->scale) { 96 float scale = psMetadataLookupF32(&mdok, cell->concepts, "PPMERGE.SCALE"); // The scale 97 if (mdok && !isnan(scale)) { 98 if (!first && !fromConcepts) { 99 psWarning("PPMERGE.SCALE and PPMERGE.ZERO have been set " 100 "for some, but not all cells --- we will re-measure it for all cells."); 101 done = true; 102 continue; 103 } 104 fromConcepts = true; 105 (*scales)->data.F32[i][cellNum] = scale; 106 psTrace("ppMerge", 9, "Scale for input %ld, chip %ld, cell %ld: %f\n", 107 i, j, k, scale); 108 } else if (!first && fromConcepts) { 109 psWarning("PPMERGE.SCALE and PPMERGE.ZERO have been set " 110 "for some, but not all cells --- we will re-measure it for all cells."); 111 fromConcepts = false; 112 done = true; 174 if ((type != PPMERGE_TYPE_MASK || !chipStats) && 175 !pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 176 goto ERROR; 177 } 178 } 179 180 // Additional run through cells if we want chip-level statistics for masks 181 if (type == PPMERGE_TYPE_MASK && chipStats) { 182 if (!psVectorStats(stats, values, NULL, NULL, 0)) { 183 psError(PS_ERR_UNKNOWN, false, "Unable to do statistics on chip."); 184 goto ERROR; 185 } 186 while ((cell = pmFPAviewNextCell(view, fpa, 1))) { 187 if (!cell->data_exists) { 113 188 continue; 114 189 } 115 } 116 117 if (options->zero) { 118 float zero = psMetadataLookupF32(&mdok, cell->concepts, "PPMERGE.ZERO"); // The zero 119 if (mdok && !isnan(zero)) { 120 if (!first && !fromConcepts) { 121 psWarning("PPMERGE.SCALE and PPMERGE.ZERO have been set " 122 "for some, but not all cells --- we will re-measure it for all cells."); 123 done = true; 124 continue; 125 } 126 fromConcepts = true; 127 (*zeros)->data.F32[i][cellNum] = zero; 128 psTrace("ppMerge", 9, "Zero for input %ld, chip %ld, cell %ld: %f\n", i, j, k, zero); 129 } else if (!first && fromConcepts) { 130 psWarning("PPMERGE.SCALE and PPMERGE.ZERO have been set " 131 "for some, but not all cells --- we will re-measure it for all cells."); 132 fromConcepts = false; 133 done = true; 134 continue; 190 psMetadataAddF32(cell->analysis, PS_LIST_TAIL, PM_MASK_ANALYSIS_MEAN, 0, 191 "Mean value of chip", psStatsGetValue(stats, meanStat)); 192 psMetadataAddF32(cell->analysis, PS_LIST_TAIL, PM_MASK_ANALYSIS_STDEV, 0, 193 "Stdev value of chip", psStatsGetValue(stats, stdevStat)); 194 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 195 goto ERROR; 135 196 } 136 197 } 137 138 first = false; 139 } 140 } 198 } 199 200 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 201 goto ERROR; 202 } 203 } 204 205 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 206 goto ERROR; 207 } 208 209 psFree(view); 210 211 #if 0 212 // Reset files for reading again 213 for (int i = 0; i < files->n; i++) { 214 pmFPAfile *file = files->data[i]; // File of interest 215 } 216 #endif 217 psFree(files); 141 218 } 142 219 143 if (fromConcepts) { 144 // We've already done everything we need to 145 psFree(rng); 146 return true; 220 psFree(rng); rng = NULL; 221 psFree(stats); stats = NULL; 222 223 // Store results 224 switch (type) { 225 case PPMERGE_TYPE_FRINGE: 226 psMetadataAddImage(config->arguments, PS_LIST_TAIL, "ZEROS", 0, 227 "Zero to subtract from each input cell", background); 228 // Flow through 229 case PPMERGE_TYPE_FLAT: { 230 // Need to normalize over the focal plane 231 if (psTraceGetLevel("ppMerge") > 9) { 232 for (int i = 0; i < gains->n; i++) { 233 psTrace("ppMerge", 10, "Gain for cell %d is %f\n", i, gains->data.F32[i]); 234 } 235 } 236 psVector *fluxes = NULL; // Solution to fluxes 237 if (!pmFlatNormalize(&fluxes, &gains, background)) { 238 psError(PS_ERR_UNKNOWN, false, "Normalisation failed to converge --- continuing anyway."); 239 psFree(fluxes); 240 goto ERROR; 241 } 242 243 psMetadataAddVector(config->arguments, PS_LIST_TAIL, "SCALES", 0, 244 "Scale to divide into each input file", fluxes); 245 psFree(fluxes); // Drop reference 246 break; 247 } 248 case PPMERGE_TYPE_SHUTTER: 249 psMetadataAddArray(config->arguments, PS_LIST_TAIL, "SHUTTER", 0, 250 "Shutter data", shutters); 251 break; 252 default: 253 psAbort("Should never get here."); 147 254 } 148 255 149 psImage *background = psImageAlloc(data->numCells, filenames->n, PS_TYPE_F32); // Background measurements 150 psImageInit(background, NAN); 151 psStats *bgStats = psStatsAlloc(options->mean); // Statistic to measure the background 152 psVector *gains = NULL; // The gains for each cell 153 if (options->scale) { 154 gains = psVectorAlloc(data->numCells, PS_TYPE_F32); 155 } 156 157 pmFPAview *view = pmFPAviewAlloc(0); 158 159 bool status = true; // Status of getting the scale and zero --- did everything go right? 160 for (int i = 0; i < filenames->n; i++) { 161 psString name = filenames->data[i]; // The name of the file 162 if (!name || strlen(name) == 0) { 163 continue; 164 } 165 psTrace("ppMerge", 9, "Opening %s to get background...\n", name); 166 psFits *inFile = data->files->data[i]; // The FITS file to read 167 pmFPA *fpa = data->in->data[i]; // The FPA for this input 168 int cellNum = -1; // Number of the cell 169 psArray *chips = fpa->chips; // Array of chips 170 for (int j = 0; j < chips->n; j++) { 171 pmChip *chip = chips->data[j]; // The chip of interest 172 if (!chip) { 173 continue; 174 } 175 psArray *cells = chip->cells; // Array of cells 176 for (int k = 0; k < cells->n; k++) { 177 pmCell *cell = cells->data[k]; // The cell of interest 178 if (!cell) { 179 continue; 180 } 181 cellNum++; 182 183 if (!pmCellReadHeader(cell, inFile)) { 184 continue; 185 } 186 187 // Scaling by the background 188 if (options->scale || options->zero) { 189 if (!pmCellRead(cell, inFile, config->database)) { 190 // Nothing here 191 pmCellFreeData(cell); 192 continue; 193 } 194 195 if (cell->readouts->n > 1) { 196 psWarning("File %s chip %d cell %d contains more than one " 197 "readout --- ignoring all but the first.\n", name, j, k); 198 status = false; 199 } 200 201 pmReadout *readout = cell->readouts->data[0]; // The readout of interest 202 psImage *image = readout->image; // The pixels of interest 203 if (!image) { 204 pmCellFreeData(cell); 205 continue; 206 } 207 208 // Get the gain 209 if (options->scale) { 210 bool mdok = true; // Status of MD lookup 211 gains->data.F32[cellNum] = psMetadataLookupF32(&mdok, cell->concepts, "CELL.GAIN"); 212 if (!mdok || isnan(gains->data.F32[cellNum])) { 213 psWarning("CELL.GAIN for file %s chip %d cell %d is not " 214 "set.\n", name, j, k); 215 gains->data.F32[cellNum] = NAN; 216 status = false; 217 } 218 } 219 220 // Get the background 221 int sampleSize = (image->numCols * image->numRows) / options->sample; // Size of sample 222 psVector *sample = psVectorAlloc(sampleSize, PS_TYPE_F32); // Sample of the image 223 psVector *sampleMask = NULL; // Mask for sample 224 if (readout->mask) { 225 sampleMask = psVectorAlloc(sampleSize, PS_TYPE_U8); 226 } 227 psImage *mask = readout->mask; // The mask image 228 for (long i = 0; i < sampleSize; i++) { 229 int j = i * options->sample; // Index into image 230 int x = j % image->numCols; // x index 231 int y = j / image->numCols; // y index 232 sample->data.F32[i] = image->data.F32[y][x]; 233 if (readout->mask) { 234 sampleMask->data.U8[i] = mask->data.U8[y][x]; 235 } 236 } 237 status = psVectorStats(bgStats, sample, sampleMask, NULL, options->combine->maskVal); 238 if (!status) { 239 psTrace("ppMerge", 3, "failed to get stats for for %s, cell %d is %f\n", name, cellNum, 240 background->data.F32[i][cellNum]); 241 psErrorClear(); 242 } 243 psFree(sample); 244 psFree(sampleMask); 245 background->data.F32[i][cellNum] = psStatsGetValue(bgStats, options->mean); 246 psTrace("ppMerge", 3, "Background for %s, cell %d is %f\n", name, cellNum, 247 background->data.F32[i][cellNum]); 248 } 249 250 // Shutter correction 251 if (options->shutter) { 252 if (!pmCellRead(cell, inFile, config->database)) { 253 // Nothing here 254 pmCellFreeData(cell); 255 continue; 256 } 257 258 if (cell->readouts->n > 1) { 259 psWarning("File %s chip %d cell %d contains more than one " 260 "readout --- ignoring all but the first.\n", name, j, k); 261 status = false; 262 } 263 pmReadout *readout = cell->readouts->data[0]; // The readout of interest 264 265 pmShutterCorrectionData *shutter = (*shutters)->data[cellNum]; // Shutter correction data 266 if (!shutter) { 267 shutter = pmShutterCorrectionDataAlloc(readout->image->numCols, 268 readout->image->numRows, 269 options->shutterSize); 270 (*shutters)->data[cellNum] = shutter; 271 } 272 if (!pmShutterCorrectionAddReadout(shutter, readout, options->mean, options->stdev, 273 options->combine->maskVal, rng)) { 274 psWarning("Can't add file %s chip %d cell %d to shutter correction --- ignored.", 275 name, j, k); 276 status = false; 277 } 278 } 279 280 281 pmCellFreeData(cell); 282 } 283 pmChipFreeData(chip); 284 } 285 pmFPAFreeData(fpa); 286 } 256 psFree(background); 257 psFree(shutters); 258 return true; 259 260 ERROR: 261 // Common path for errors 262 psFree(gains); 263 psFree(background); 264 psFree(shutters); 287 265 psFree(rng); 288 psFree( bgStats);266 psFree(stats); 289 267 psFree(view); 290 291 if (options->scale) { 292 // Need to normalize over the focal plane 293 if (psTraceGetLevel("ppMerge") > 9) { 294 for (int i = 0; i < gains->n; i++) { 295 psTrace("ppMerge", 10, "Gain for cell %d is %f\n", i, gains->data.F32[i]); 296 } 297 } 298 psVector *fluxes = NULL; // Solution to fluxes 299 if (!pmFlatNormalize(&fluxes, &gains, background)) { 300 psWarning("Normalisation failed to converge --- continuing anyway.\n"); 301 status = false; 302 } 303 psFree(gains); 304 305 psImage *scalesDeref = *scales; // Dereference the pointer 306 307 for (int i = 0; i < scalesDeref->numRows; i++) { 308 psF32 bg = fluxes->data.F32[i]; 309 for (int j = 0; j < scalesDeref->numCols; j++) { 310 scalesDeref->data.F32[i][j] = bg; 311 } 312 } 313 } 314 315 if (options->zero) { 316 if (!*zeros) { 317 // This is much faster than copying! 318 *zeros = psMemIncrRefCounter(background); 319 } else { 320 *zeros = psImageCopy(*zeros, background, PS_TYPE_F32); 321 } 322 } 323 324 // Diagnostic stuff 325 if (scales && *scales && psTraceGetLevel("ppMerge") > 9) { 326 psImage *scalesDeref = *scales; // Dereference the pointer 327 for (int i = 0; i < scalesDeref->numRows; i++) { 328 for (int j = 0; j < scalesDeref->numCols; j++) { 329 psTrace("ppMerge", 9, "Scale for exposure %d, cell %d is: %f\n", i, j, 330 scalesDeref->data.F32[i][j]); 331 } 332 } 333 } 334 if (zeros && *zeros && psTraceGetLevel("ppMerge") > 9) { 335 psImage *zerosDeref = *zeros; // Dereference the pointer 336 for (int i = 0; i < zerosDeref->numRows; i++) { 337 for (int j = 0; j < zerosDeref->numCols; j++) { 338 psTrace("ppMerge", 9, "Zero for exposure %d, cell %d is: %f\n", i, j, 339 zerosDeref->data.F32[i][j]); 340 } 341 } 342 } 343 344 psFree(background); 345 346 return status; 268 return false; 347 269 } 348 270
Note:
See TracChangeset
for help on using the changeset viewer.
