Changeset 12098
- Timestamp:
- Feb 27, 2007, 4:14:42 PM (19 years ago)
- Location:
- trunk/psModules/src/detrend
- Files:
-
- 3 edited
-
Makefile.am (modified) (2 diffs)
-
pmShifts.c (modified) (4 diffs)
-
pmShifts.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/detrend/Makefile.am
r10610 r12098 11 11 pmBias.c \ 12 12 pmDetrendDB.c \ 13 pmShutterCorrection.c 13 pmShutterCorrection.c \ 14 pmShifts.c 14 15 15 16 # pmSkySubtract.c … … 23 24 pmBias.h \ 24 25 pmDetrendDB.h \ 25 pmShutterCorrection.h 26 pmShutterCorrection.h \ 27 pmShifts.h 26 28 27 29 # pmSkySubtract.h -
trunk/psModules/src/detrend/pmShifts.c
r12010 r12098 8 8 #include <pslib.h> 9 9 10 #include "pmFPALevel.h" 11 #include "pmFPAUtils.h" 10 12 #include "pmShifts.h" 11 13 … … 13 15 #define SHIFTS_BUFFER 100 // Buffer size for shifts 14 16 #define ANALYSIS_NAME "OT.KERNEL" // Name for kernel on the analysis metadata 17 #define TRACE "psModules.detrend" // Trace facility 18 19 // XXX To do: 20 // * Make the table column names configurable, by having a SHIFTS metadata in the camera format, with entries 21 // specifying the column names. 15 22 16 23 … … 23 30 } otShifts; 24 31 25 26 bool pmShiftsRead(psFits *fits, pmFPA *fpa, const pmFPAview *phuView) 32 // Allocator for otShifts 33 static otShifts *otShiftsAlloc(void) 34 { 35 otShifts *shifts = psAlloc(sizeof(otShifts)); 36 shifts->x = psVectorAllocEmpty(SHIFTS_BUFFER, PS_TYPE_S32); 37 shifts->y = psVectorAllocEmpty(SHIFTS_BUFFER, PS_TYPE_S32); 38 shifts->t = psVectorAllocEmpty(SHIFTS_BUFFER, PS_TYPE_F32); 39 shifts->num = 0; 40 return shifts; 41 } 42 43 // Look up the cell within a hash; supplement the hash with a new value if it doesn't exist 44 static otShifts *cellVectors(psHash *shifts, // Hash of shifts 45 const char *cellName // Key for hash 46 ) 47 { 48 assert(shifts); 49 assert(cellName); 50 51 // Find the appropriate cell 52 otShifts *vectors = psHashLookup(shifts, cellName); 53 if (!vectors) { 54 vectors = otShiftsAlloc(); 55 psHashAdd(shifts, cellName, vectors); 56 psFree(vectors); // Drop reference 57 } 58 return vectors; 59 } 60 61 // Generate a kernel and stuff it on the cell metadata 62 static bool stuffKernel(pmCell *cell, // Cell to which the shifts belong 63 const otShifts *shifts // Shifts to apply 64 ) 65 { 66 assert(cell); 67 assert(shifts); 68 69 psKernel *kernel = psKernelGenerate(shifts->t, shifts->x, shifts->y, false, true); // Shift kernel 70 if (!kernel) { 71 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate kernel from OT shifts"); 72 return false; 73 } 74 psMetadataAddPtr(cell->analysis, PS_LIST_TAIL, ANALYSIS_NAME, PS_DATA_KERNEL, 75 "Orthogonal transfer kernel, calculated from shifts", kernel); 76 psFree(kernel); 77 78 return true; 79 } 80 81 82 bool pmShiftsRead(pmCell *cell, psFits *fits) 27 83 { 28 84 PS_ASSERT_PTR_NON_NULL(fits, false); 29 PS_ASSERT_PTR_NON_NULL(fpa, false); 30 PS_ASSERT_PTR_NON_NULL(phuView, false); 31 32 pmHDU *phu = pmFPAviewThisHDU(phuView, fpa); // The primary header 33 if (!phu) { 34 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Provided view does not correspond to an HDU.\n"); 35 return false; 36 } 37 38 psMetadata *format = phu->format; // Camera format 85 PS_ASSERT_PTR_NON_NULL(cell, false); 86 39 87 bool mdok; // Status of MD lookup 40 psMetadata *fileInfo = psMetadataLookupMetadata(&mdok, format, "FILE"); // FILE information from format 88 psKernel *check = psMetadataLookupPtr(&mdok, cell->analysis, ANALYSIS_NAME); // Kernel, or NULL 89 if (check) { 90 psTrace(TRACE, 2, "Cell already has OT kernel present.\n"); 91 return true; // No error 92 } 93 psTrace(TRACE, 2, "Reading FITS file for OT kernels.\n"); 94 95 pmChip *chip = cell->parent; // The parent chip 96 pmFPA *fpa = chip->parent; // The parent FPA 97 pmHDU *phu = NULL; // The primary header 98 pmFPALevel phuLevel = PM_FPA_LEVEL_NONE; // Level of the PHU 99 long numChips = 0; // Number of chips below the PHU; for setting efficient hash size 100 long numCells = 0; // Number of cells below the PHU; for setting efficient hash size 101 if (fpa->hdu) { 102 phu = fpa->hdu; 103 // Count the cells 104 psArray *chips = fpa->chips; // Array of chips 105 numChips = chips->n; 106 for (int i = 0; i < chips->n; i++) { 107 pmChip *chip = chips->data[i]; // Chip of interest 108 numCells += chip->cells->n; 109 } 110 numCells = (float)numCells / (float)numChips + 0.5; // Average number of cells per chip 111 phuLevel = PM_FPA_LEVEL_FPA; 112 } 113 if (!phu && chip->hdu) { 114 phu = chip->hdu; 115 numChips = 1; 116 numCells = chip->cells->n; 117 phuLevel = PM_FPA_LEVEL_CHIP; 118 } 119 if (!phu && cell->hdu) { 120 phu = cell->hdu; 121 numChips = 0; 122 numCells = 1; 123 phuLevel = PM_FPA_LEVEL_CELL; 124 } 125 126 if (!phu || phuLevel == PM_FPA_LEVEL_NONE) { 127 psError(PS_ERR_UNEXPECTED_NULL, true, "Can't find the PHU.\n"); 128 return false; 129 } 130 131 // Find out what to read 132 psMetadata *fileInfo = psMetadataLookupMetadata(&mdok, phu->format, "FILE"); // FILE in the format 41 133 if (!mdok || !fileInfo) { 42 134 psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find FILE information in camera format.\n"); … … 49 141 } 50 142 51 int numExt = psFitsGetSize(fits); // Number of extensions inFITS file143 // Read the FITS file 52 144 int origExt = psFitsGetExtNum(fits); // Original extension number; to preserve position 53 54 for (int i = 1; i < numExt; i++) { // Note: shifts table cannot be in PHU! 55 psFitsMoveExtNum(fits, i, false); 56 const char *extname = psFitsGetExtName(fits); // Name of extension 57 if (strcmp(extname, shiftsExt) == 0) { 58 psArray *table = psFitsReadTable(fits); // The table of shifts 59 if (!table) { 60 psError(PS_ERR_IO, false, "Unable to read shifts table.\n"); 145 if (!psFitsMoveExtName(fits, shiftsExt)) { 146 psError(PS_ERR_IO, false, "Unable to move to shifts extension %s", shiftsExt); 147 return false; 148 } 149 psArray *table = psFitsReadTable(fits); // The table of shifts 150 if (!table) { 151 psError(PS_ERR_IO, false, "Unable to read shifts table.\n"); 152 return false; 153 } 154 155 // More sensible storage 156 otShifts *singleShifts = NULL; // Shifts for a single cell 157 psHash *multipleShifts = NULL; // Shifts for multiple cells, stored by cell name 158 switch (phuLevel) { 159 case PM_FPA_LEVEL_FPA: 160 multipleShifts = psHashAlloc(2 * numChips); 161 break; 162 case PM_FPA_LEVEL_CHIP: 163 multipleShifts = psHashAlloc(2 * numCells); 164 break; 165 case PM_FPA_LEVEL_CELL: 166 singleShifts = otShiftsAlloc(); 167 break; 168 default: 169 psAbort("Should never get here.\n"); 170 } 171 172 // Pull values out of the table into something a bit more sensible 173 for (int i = 0; i < table->n; i++) { 174 psMetadata *row = table->data[i]; // The row of interest 175 176 const char *chipName; // Name of chip 177 if (phuLevel == PM_FPA_LEVEL_FPA) { 178 // Only care about the chip name if there's more than one chip 179 chipName = psMetadataLookupStr(&mdok, row, "Chip"); 180 if (!mdok || !chipName) { 181 psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find Chip in row %d of shifts table\n", i); 182 psFree(multipleShifts); 183 psFree(table); 61 184 return false; 62 185 } 63 64 // Pull values out of the table into something a bit more sensible 65 psHash *shifts = psHashAlloc(HASH_SIZE); // Shifts for each cell 66 for (int i = 0; i < table->n; i++) { 67 psMetadata *row = table->data[i]; // The row of interest 68 const char *name = psMetadataLookupStr(&mdok, row, "Cell"); // Name of cell 69 if (!mdok || !name) { 70 psError(PS_ERR_UNEXPECTED_NULL, true, 71 "Unable to find Cell in row %d of shifts table\n", i); 72 psFree(shifts); 73 psFree(table); 74 return false; 75 } 76 float x = psMetadataLookupS32(&mdok, row, "X"); // Shift in x 77 if (!mdok) { 78 psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find X in row %d of shifts table\n", i); 79 psFree(shifts); 80 psFree(table); 81 return false; 82 } 83 float y = psMetadataLookupF32(&mdok, row, "Y"); // Shift in y 84 if (!mdok) { 85 psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find Y in row %d of shifts table\n", i); 86 psFree(shifts); 87 psFree(table); 88 return false; 89 } 90 float t = psMetadataLookupF32(&mdok, row, "Time"); // Time of shift 91 if (!mdok) { 92 psError(PS_ERR_UNEXPECTED_NULL, true, 93 "Unable to find Time in row %d of shifts table\n", i); 94 psFree(shifts); 95 psFree(table); 96 return false; 97 } 98 99 // Find the appropriate cell 100 otShifts *vectors = psHashLookup(shifts, name); // Shifts for the cell of interest 101 if (!vectors) { 102 vectors = psAlloc(sizeof(otShifts)); 103 vectors->x = psVectorAllocEmpty(SHIFTS_BUFFER, PS_TYPE_S32); 104 vectors->y = psVectorAllocEmpty(SHIFTS_BUFFER, PS_TYPE_S32); 105 vectors->t = psVectorAllocEmpty(SHIFTS_BUFFER, PS_TYPE_F32); 106 vectors->num = 0; 107 psHashAdd(shifts, name, vectors); 108 } 109 110 // Add the shift 111 psVectorExtend(cell->x, 1, SHIFTS_BUFFER); 112 psVectorExtend(cell->y, 1, SHIFTS_BUFFER); 113 psVectorExtend(cell->t, 1, SHIFTS_BUFFER); 114 vectors->x->data.S32[vectors->num] = (int)x; 115 vectors->y->data.S32[vectors->num] = (int)y; 116 vectors->t->data.F32[vectors->num] = t; 117 vectors->num++; 186 } 187 const char *cellName; // Name of cell 188 if (phuLevel <= PM_FPA_LEVEL_CHIP) { 189 // Only care about the cell name if there's a chip 190 cellName = psMetadataLookupStr(&mdok, row, "Cell"); 191 if (!mdok || !cellName) { 192 psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find Cell in row %d of shifts table\n", i); 193 psFree(multipleShifts); 194 psFree(table); 195 return false; 118 196 } 197 } 198 float x = psMetadataLookupS32(&mdok, row, "X"); // Shift in x 199 if (!mdok) { 200 psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find X in row %d of shifts table\n", i); 201 psFree(multipleShifts); 119 202 psFree(table); 120 121 // Put the kernels into their own cells 122 psList *names = psHashKeyList(shifts); // List of cells 123 psListIterator *namesIter = psListIteratorAlloc(names, PS_LIST_HEAD, false); // Iterator for names 124 while ((name = psListGetAndIncrement(namesIter))) { 125 pmChip *chip = NULL; // Chip of interest 126 pmCell *cell = NULL; // Cell of interest 127 if (phuView->chip != -1) { 128 chip = pmFPAviewThisChip(phuView, chip); 129 cell = pmChipFindCell(chip, name); 130 } else { 131 psList *chipCell = psStringSplit(name, ":|,", false); // The chip and cell 132 if (chipCell->n != 2) { 133 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 134 "Cannot determine chip and cell names from %s\n", name); 135 psFree(chipCell); 136 psFree(namesIter); 137 psFree(names); 138 psFree(shifts); 139 return false; 140 } 141 const char *chipName = psListGet(chipCell, PS_LIST_HEAD); // Name of chip 142 const char *cellName = psListGet(chipCell, PS_LIST_TAIL); // Name of cell 143 chip = pmFPAFindChip(fpa, chipName); 144 if (!chip) { 145 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find chip %s", chipName); 146 psFree(chipCell); 147 psFree(namesIter); 148 psFree(names); 149 psFree(shifts); 150 return false; 151 } 152 cell = pmChipFindCell(chip, cellName); 153 psFree(chipCell); 154 } 155 156 if (!cell) { 157 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find chip %s", chipName); 158 psFree(namesIter); 159 psFree(names); 160 psFree(shifts); 161 return false; 162 } 163 164 otShifts *vectors = psHashLookup(shifts, name); // Shifts for the cell of interest 165 psKernel *kernel = psKernelGenerate(vectors->t, vectors->x, vectors->y, 166 false, true); // Shift kernel 167 if (!kernel) { 168 psError(PS_ERR_UNEXPECTED_NULL, false, 169 "Unable to generate kernel from OT shifts for %s", name); 170 psFree(shifts); 171 psFree(namesIter); 172 psFree(names); 173 return false; 174 } 175 psMetadataAddPtr(cell->analysis, PS_LIST_TAIL, ANALYSIS_NAME, PS_DATA_KERNEL, 176 "Orthogonal transfer kernel, calculated from shifts", kernel); 177 psFree(kernel); 203 return false; 204 } 205 float y = psMetadataLookupF32(&mdok, row, "Y"); // Shift in y 206 if (!mdok) { 207 psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find Y in row %d of shifts table\n", i); 208 psFree(multipleShifts); 209 psFree(table); 210 return false; 211 } 212 float t = psMetadataLookupF32(&mdok, row, "Time"); // Time of shift 213 if (!mdok) { 214 psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find Time in row %d of shifts table\n", i); 215 psFree(multipleShifts); 216 psFree(table); 217 return false; 218 } 219 220 otShifts *shifts = NULL; // Shifts for the cell of interest 221 switch (phuLevel) { 222 case PM_FPA_LEVEL_FPA: { 223 psHash *cells = psHashLookup(multipleShifts, chipName); // Hash of cells 224 if (!cells) { 225 cells = psHashAlloc(numCells); 226 psHashAdd(multipleShifts, chipName, cells); 227 psFree(cells); // Drop reference 228 } 229 shifts = cellVectors(cells, cellName); 230 break; 231 } 232 case PM_FPA_LEVEL_CHIP: 233 shifts = cellVectors(multipleShifts, cellName); 234 break; 235 case PM_FPA_LEVEL_CELL: 236 shifts = singleShifts; 237 break; 238 default: 239 psAbort("Should never get here.\n"); 240 } 241 242 // Add the shift 243 psVectorExtend(shifts->x, 1, SHIFTS_BUFFER); 244 psVectorExtend(shifts->y, 1, SHIFTS_BUFFER); 245 psVectorExtend(shifts->t, 1, SHIFTS_BUFFER); 246 shifts->x->data.S32[shifts->num] = (int)x; 247 shifts->y->data.S32[shifts->num] = (int)y; 248 shifts->t->data.F32[shifts->num] = t; 249 shifts->num++; 250 } 251 psFree(table); 252 253 // Put the kernels into their own cells 254 if (phuLevel == PM_FPA_LEVEL_CELL) { 255 // Only a single cell 256 if (!stuffKernel(cell, singleShifts)) { 257 psFree(singleShifts); 258 return false; 259 } 260 psFree(singleShifts); 261 } else { 262 psList *names = psHashKeyList(multipleShifts); // List of hash keys (chip/cell names) 263 psListIterator *namesIter = psListIteratorAlloc(names, PS_LIST_HEAD, false); // Iterator for names 264 const char *name; // Name, from iteration 265 while ((name = psListGetAndIncrement(namesIter))) { 266 switch (phuLevel) { 267 case PM_FPA_LEVEL_FPA: { 268 int chipNum = pmFPAFindChip(fpa, name); // Number of chip of interest 269 if (chipNum < 0) { 270 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find chip %s", name); 271 psFree(namesIter); 272 psFree(names); 273 psFree(multipleShifts); 274 return false; 275 } 276 pmChip *chip = fpa->chips->data[chipNum]; // Chip of interest 277 278 // Loop over component cells 279 psHash *cells = psHashLookup(multipleShifts, name); // Hash of cells 280 psList *cellNames = psHashKeyList(multipleShifts); // List of hash keys (cell names) 281 psListIterator *cellNamesIter = psListIteratorAlloc(cellNames, PS_LIST_HEAD, false); 282 const char *cellName; // Cell name, from iteration 283 while ((cellName = psListGetAndIncrement(cellNamesIter))) { 284 int cellNum = pmChipFindCell(chip, cellName); // Number of cell of interest 285 if (!cell) { 286 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find cell %s", cellName); 287 psFree(cellNamesIter); 288 psFree(cellNames); 289 psFree(namesIter); 290 psFree(names); 291 psFree(multipleShifts); 292 return false; 293 } 294 pmCell *cell = chip->cells->data[cellNum]; // Cell of interest 295 296 otShifts *vectors = psHashLookup(cells, cellName); // Shifts for the cell of interest 297 if (!stuffKernel(cell, vectors)) { 298 psFree(cellNamesIter); 299 psFree(cellNames); 300 psFree(namesIter); 301 psFree(names); 302 psFree(multipleShifts); 303 return false; 304 } 305 } 306 psFree(cellNamesIter); 307 psFree(cellNames); 308 break; 309 } 310 case PM_FPA_LEVEL_CHIP: { 311 int cellNum = pmChipFindCell(chip, name); // Number of cell of interest 312 if (!cell) { 313 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find cell %s", name); 314 psFree(namesIter); 315 psFree(names); 316 psFree(multipleShifts); 317 return false; 318 } 319 pmCell *cell = chip->cells->data[cellNum]; // Cell of interest 320 321 otShifts *vectors = psHashLookup(multipleShifts, name); // Shifts for this cell 322 if (!stuffKernel(cell, vectors)) { 323 psFree(namesIter); 324 psFree(names); 325 psFree(multipleShifts); 326 return false; 327 } 328 break; 329 } 330 default: 331 psAbort("Should never get here.\n"); 178 332 } 179 psFree(namesIter); 180 psFree(names); 181 psFree(shifts); 182 183 break; 184 } 185 } 186 187 // reposition to the original position 333 } 334 psFree(namesIter); 335 psFree(names); 336 psFree(multipleShifts); 337 } 338 339 // Go back to the original position in the FITS file 188 340 return psFitsMoveExtNum(fits, origExt, false); 189 341 } -
trunk/psModules/src/detrend/pmShifts.h
r12010 r12098 4 4 #include <pslib.h> 5 5 #include "pmFPA.h" 6 #include "pmFPAview.h"7 6 8 /// Read any orthogonal transfer shifts extension in a FITS file7 /// Read orthogonal transfer shifts table for a cell 9 8 /// 10 /// Given a FITS file (typically newly opened ready for processing), this function searches for the extension 11 /// specified by the SHIFTS keyword within the FILE information in the camera format. If the extension is 12 /// found, the shifts table is read and translated into kernels which are placed in the analysis metadata of 13 /// each cell. 14 bool pmShiftsRead(psFits *fits, ///< FITS file in which to search for OT shifts extension 15 pmFPA *fpa, ///< FPA containing the cells that own the shifts 16 const pmFPAview *phuView ///< View of the PHU; specifies which chip(s) owns the cells 17 ); 9 /// Given a cell, this function searches for the orthogonal transfer shifts for this cell in the supplied FITS 10 /// file. The FITS extension containing the shifts table is specified by the SHIFTS keyword within the FILE 11 /// information in the camera format. If the extension is found, the shifts table is read and translated into 12 /// kernels which are placed in the analysis metadata of each cell. Note that this operation is performed on 13 /// all cells within the FITS file (or at least, those contained within the shifts table), not just the cell 14 /// provided --- if we have to read the whole table, we may as well translate the whole lot. If a kernel is 15 /// already present in the cell analysis metadata, the function returns true without doing any work. 16 bool pmShiftsRead(pmCell *cell, ///< Cell for which to search for shifts 17 psFits *fits ///< FITS file in which to search for OT shifts extension 18 ); 18 19 19 20
Note:
See TracChangeset
for help on using the changeset viewer.
