Changeset 5786 for trunk/archive/scripts/src/phase2/pmFPAMorph.c
- Timestamp:
- Dec 13, 2005, 5:47:35 PM (21 years ago)
- File:
-
- 1 edited
-
trunk/archive/scripts/src/phase2/pmFPAMorph.c (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/archive/scripts/src/phase2/pmFPAMorph.c
r5651 r5786 14 14 // Flip the chip in x 15 15 static psImage *xFlipImage(psImage *image, // Image to be flipped 16 int size// Size of image in flip dimension16 int size // Size of image in flip dimension 17 17 ) 18 18 { … … 20 20 switch (image->type.type) { 21 21 case PS_TYPE_U16: 22 for (int y = 0; y < image->numRows; y++) {23 for (int x = 0; x < image->numCols; x++) {24 flipped->data.U16[y][size - x - 1] = image->data.U16[y][x];25 }26 }27 break;22 for (int y = 0; y < image->numRows; y++) { 23 for (int x = 0; x < image->numCols; x++) { 24 flipped->data.U16[y][size - x - 1] = image->data.U16[y][x]; 25 } 26 } 27 break; 28 28 case PS_TYPE_F32: 29 for (int y = 0; y < image->numRows; y++) {30 for (int x = 0; x < image->numCols; x++) {31 flipped->data.F32[y][size - x - 1] = image->data.F32[y][x];32 }33 }34 break;29 for (int y = 0; y < image->numRows; y++) { 30 for (int x = 0; x < image->numCols; x++) { 31 flipped->data.F32[y][size - x - 1] = image->data.F32[y][x]; 32 } 33 } 34 break; 35 35 default: 36 psError(PS_ERR_IO, true, "Image type %x not yet supported for flip.\n", image->type.type);36 psError(PS_ERR_IO, true, "Image type %x not yet supported for flip.\n", image->type.type); 37 37 } 38 38 … … 42 42 // Flip the chip in y 43 43 static psImage *yFlipImage(psImage *image, // Image to be flipped 44 int size// Size of image in flip dimension44 int size // Size of image in flip dimension 45 45 ) 46 46 { … … 48 48 switch (image->type.type) { 49 49 case PS_TYPE_U16: 50 for (int y = 0; y < image->numRows; y++) {51 for (int x = 0; x < image->numCols; x++) {52 flipped->data.U16[size - y - 1][x] = image->data.U16[y][x];53 }54 }55 break;50 for (int y = 0; y < image->numRows; y++) { 51 for (int x = 0; x < image->numCols; x++) { 52 flipped->data.U16[size - y - 1][x] = image->data.U16[y][x]; 53 } 54 } 55 break; 56 56 default: 57 psError(PS_ERR_IO, true, "Image type %x not yet supported for flip.\n", image->type.type);57 psError(PS_ERR_IO, true, "Image type %x not yet supported for flip.\n", image->type.type); 58 58 } 59 59 … … 65 65 // Return a list of the region strings and the method for interpreting them 66 66 static psList *getRegions(psString *method, // Method for evaluating the regions 67 psString methodValues // The METHOD:VALUES string67 psString methodValues // The METHOD:VALUES string 68 68 ) 69 69 { 70 70 char *values = strchr(methodValues, ':'); // The VALUES 71 71 *method = psStringNCopy(methodValues, strlen(methodValues) - strlen(values)); // The METHOD 72 psList *regionStrings = NULL; // List of the region strings72 psList *regionStrings = NULL; // List of the region strings 73 73 if (strncmp(*method, "HEADER", 6) == 0 || strncmp(*method, "HD", 2) == 0) { 74 regionStrings = papSplit(values, ", ");74 regionStrings = papSplit(values, ", "); 75 75 } else if (strncmp(*method, "VALUE", 5) == 0 || strncmp(*method, "VAL", 3) == 0) { 76 regionStrings = papSplit(values, "; ");76 regionStrings = papSplit(values, "; "); 77 77 } 78 78 … … 84 84 // Splice an image into another image 85 85 static psRegion *spliceImage(psImage *target, // Target image onto which to splice 86 int *x0, int *y0, // Starting coordinates to splice to87 psImage *source, // Source image from which to splice88 const psRegion *from, // Region to splice from89 int readdir, // Read direction90 bool xFlip, bool yFlip // Flip x and y axes?91 )86 int *x0, int *y0, // Starting coordinates to splice to 87 psImage *source, // Source image from which to splice 88 const psRegion *from, // Region to splice from 89 int readdir, // Read direction 90 bool xFlip, bool yFlip // Flip x and y axes? 91 ) 92 92 { 93 93 psImage *toSplice = psImageSubset(source, *from); // Subimage, to splice into target 94 94 if (xFlip) { 95 int size = 0;// Size of flipped image96 if (readdir == 1) {97 size = toSplice->numCols;98 } else if (readdir == 2) {99 size = target->numCols;100 }101 psImage *temp = xFlipImage(toSplice, size);102 psFree(toSplice);103 toSplice = temp;95 int size = 0; // Size of flipped image 96 if (readdir == 1) { 97 size = toSplice->numCols; 98 } else if (readdir == 2) { 99 size = target->numCols; 100 } 101 psImage *temp = xFlipImage(toSplice, size); 102 psFree(toSplice); 103 toSplice = temp; 104 104 } 105 105 if (yFlip) { 106 int size = 0; // Size of flipped image 107 if (readdir == 1) { 108 size = target->numRows; 109 } else if (readdir == 2) { 110 size = toSplice->numRows; 111 } 112 psImage *temp = yFlipImage(toSplice, size); 113 psFree(toSplice); 114 toSplice = temp; 115 } 116 106 int size = 0; // Size of flipped image 107 if (readdir == 1) { 108 size = target->numRows; 109 } else if (readdir == 2) { 110 size = toSplice->numRows; 111 } 112 psImage *temp = yFlipImage(toSplice, size); 113 psFree(toSplice); 114 toSplice = temp; 115 } 116 117 psTrace(__func__, 5, "Splicing %dx%d image in at %d,%d\n", toSplice->numCols, toSplice->numRows, 118 *x0, *y0); 117 119 (void)psImageOverlaySection(target, toSplice, *x0, *y0, "="); 118 120 119 121 if (readdir == 1) { 120 *x0 += toSplice->numCols;122 *x0 += toSplice->numCols; 121 123 } else if (readdir == 2) { 122 *y0 += toSplice->numRows;124 *y0 += toSplice->numRows; 123 125 } 124 126 … … 136 138 137 139 // Splice bias regions (overscans) 138 static bool spliceBias(psImage *splice, // Image to which to splice139 int *x0, int *y0, // Starting position for splice140 const pmCell *in, // Input cell141 pmCell *out,// Output cell142 int xFlip, int yFlip, // Flip the image?143 int readNum,// Number of readout144 int readdir// Read direction145 )140 static bool spliceBias(psImage *splice, // Image to which to splice 141 int *x0, int *y0, // Starting position for splice 142 const pmCell *in, // Input cell 143 pmCell *out, // Output cell 144 int xFlip, int yFlip, // Flip the image? 145 int readNum, // Number of readout 146 int readdir // Read direction 147 ) 146 148 { 147 149 psArray *readouts = in->readouts; // The readouts; … … 152 154 psList *outBiassecs = psListAlloc(NULL); // List of biassecs for output 153 155 while (inBiassec = psListGetAndIncrement(inBiassecsIter)) { 154 psRegion *outBiassec = spliceImage(splice, x0, y0, readout->image, inBiassec, readdir, xFlip,155 yFlip);156 psListAdd(outBiassecs, PS_LIST_TAIL, outBiassec);156 psRegion *outBiassec = spliceImage(splice, x0, y0, readout->image, inBiassec, readdir, xFlip, 157 yFlip); 158 psListAdd(outBiassecs, PS_LIST_TAIL, outBiassec); 157 159 } 158 160 psFree(inBiassecsIter); 159 161 psMetadataAdd(out->concepts, PS_LIST_TAIL, "CELL.BIASSEC", PS_DATA_LIST | PS_META_REPLACE, 160 "BIASSEC from pmFPAMorph", outBiassecs);161 162 "BIASSEC from pmFPAMorph", outBiassecs); 163 162 164 return true; 163 165 } 164 166 167 psImage *p_pmImageMosaic(const psArray *source, // Images to splice in 168 const psVector *xFlip, const psVector *yFlip, // Need to flip x and y? 169 const psVector *xBinSource, const psVector *yBinSource, // Binning in x and y of 170 // source images 171 int xBinTarget, int yBinTarget, // Binning in x and y of target images 172 const psVector *x0, const psVector *y0 // Offsets for source images on target 173 ); 165 174 166 175 // Splice a list of cells together 176 // We need to do the following: 177 // 1. Copy the contents of the cells (i.e., the readouts) over from the in to the out 178 // 2. Splice together everything in the bucket for the image that we will write out 167 179 static psArray *spliceCells(psList *outCells, // List of target cells (required for parity info) 168 psList *inCells, // List of cells to splice together169 bool posDep// Position dependent placement of overscans?180 psList *inCells, // List of cells to splice together 181 bool posDep // Position dependent placement of overscans? 170 182 ) 171 183 { … … 176 188 177 189 if (inCells->n != outCells->n) { 178 psError(PS_ERR_IO, true, "Sizes of input (%d) and output (%d) lists of cells don't match.\n", 179 inCells->n, outCells->n); 180 return NULL; 181 } 182 183 int numCells = inCells->n; // Number of cells 184 int readdir = 0; // Read direction for CCD; currently unknown 185 int numReadouts = 0; // Number of readouts in a cell 186 psArray *spliced = NULL; // Array of spliced readouts 187 psElemType type = 0; // Image type (U16, S32, F32, etc) 188 189 psVector *xSize = NULL; // Size of spliced image in x 190 psVector *ySize = NULL; // Size of spliced image in y 190 psError(PS_ERR_IO, true, "Sizes of input (%d) and output (%d) lists of cells don't match.\n", 191 inCells->n, outCells->n); 192 return NULL; 193 } 194 195 int numCells = inCells->n; // Number of cells 196 int readdir = 0; // Read direction for CCD; currently unknown 197 int numReadouts = 0; // Number of readouts in a cell 198 psArray *spliced = NULL; // Array of spliced readouts 199 psElemType type = 0; // Image type (U16, S32, F32, etc) 191 200 192 201 psVector *xFlip = psVectorAlloc(numCells, PS_TYPE_U8); // Do we need to flip in x? 193 202 psVector *yFlip = psVectorAlloc(numCells, PS_TYPE_U8); // Do we need to flip in y? 194 203 psVector *xBin = psVectorAlloc(numCells, PS_TYPE_S32); // Binning in x 204 psVector *yBin = psVectorAlloc(numCells, PS_TYPE_S32); // Binning in y 205 psVector *x0 = psVectorAlloc(numCells, PS_TYPE_S32); // Offset in x 206 psVector *y0 = psVectorAlloc(numCells, PS_TYPE_S32); // Offset in y 207 int xBinOut = 0; // Binning in x for output 208 int yBinOut = 0; // Binning in y for output 195 209 196 210 // We go through the cells to make sure everything's kosher, and to get the sizes. 197 211 psListIterator *inCellsIter = psListIteratorAlloc(inCells, PS_LIST_HEAD, false); // Iterator for cells 198 pmCell *inCell = NULL; // Cell from list of input cells199 212 psListIterator *outCellsIter = psListIteratorAlloc(outCells, PS_LIST_HEAD, false); // Iterator for cells 200 int cellNum = 0; // Cell number; 213 pmCell *inCell = NULL; // Cell from list of input cells 214 pmCell *outCell = NULL; // Cell from list of output cells 215 int cellNum = -1; // Cell number 216 while (inCell = psListGetAndIncrement(inCellsIter) && outCell = psListGetAndIncrement(outCellsIter)) { 217 cellNum++; 218 psArray *inReadouts = inCell->readouts; // The readouts comprising the cell 219 220 // Get and check the read direction 221 int cellReaddir = psMetadataLookupS32(NULL, inCell->concepts, "CELL.READDIR"); 222 psTrace(__func__, 10, "Checking read direction for cell %d: %d\n", cellNum, cellReaddir); 223 if (cellNum == 0) { 224 // First run through; set it. 225 readdir = cellReaddir; 226 } else if (readdir != cellReaddir) { 227 psError(PS_ERR_IO, true, "Trying to splice cells with different read directions (%d vs %d). I " 228 "don't know how to do that!\n", readdir, cellReaddir); 229 // XXX Clean up before returning 230 return NULL; 231 } 232 233 // Get and check the number of readouts 234 if (! spliced) { 235 numReadouts = inReadouts->n; 236 spliced = psArrayAlloc(numReadouts); 237 xSize = psVectorAlloc(numReadouts, PS_TYPE_S32); 238 ySize = psVectorAlloc(numReadouts, PS_TYPE_S32); 239 for (int i = 0; i < numReadouts; i++) { 240 xSize->data.S32[i] = 0; 241 ySize->data.S32[i] = 0; 242 } 243 } else if (inReadouts->n != numReadouts) { 244 psError(PS_ERR_IO, true, "Trying to splice cells with different number of reads (%d vs %d)\n", 245 numReadouts, readouts->n); 246 // XXX Clean up before returning 247 return NULL; 248 } 249 250 // Get and check the binning --- we can't splice to cells that have different binnings, because 251 // the spliced image can't be defined. Hence all the "to" cells must have the same binning. 252 xBinIn = psMetadataLookupS32(NULL, inCell->concepts, "CELL.XBIN"); 253 yBinIn = psMetadataLookupS32(NULL, inCell->concepts, "CELL.YBIN"); 254 int xBinCheck = psMetadataLookupS32(NULL, outCell->concepts, "CELL.XBIN"); 255 int yBinCheck = psMetadataLookupS32(NULL, outCell->concepts, "CELL.YBIN"); 256 if (xBinOut == 0) { 257 xBinOut = xBinCheck; 258 } else if (xBinCheck != xBinOut) { 259 psError(PS_ERR_IO, true, "Trying to splice to cells with different x binnings (%d vs %d)\n", 260 xBinOut, xBinCheck); 261 // XXX Clean up before returning 262 return NULL; 263 } 264 if (yBinOut == 0) { 265 yBinOut = yBinCheck; 266 } else if (yBinCheck != yBinOut) { 267 psError(PS_ERR_IO, true, "Trying to splice to cells with different y binnings (%d vs %d)\n", 268 yBinOut, yBinCheck); 269 // XXX Clean up before returning 270 return NULL; 271 } 272 273 // Copy the readouts over 274 psArray *outReadouts = psArrayAlloc(inReadouts->n); // Array of readouts for the output cell 275 for (int i = 0; i < inReadouts->n; i++) { 276 outReadouts->data[i] = psMemIncrRefCounter(inReadouts->data[i]); 277 } 278 279 // Get the offsets 280 x0->data.S32[i] = psMetadataLookupS32(NULL, inCell->concepts, "CELL.X0"); 281 y0->data.S32[i] = psMetadataLookupS32(NULL, inCell->concepts, "CELL.Y0"); 282 283 // Get and check the parity 284 int xParityIn = psMetadataLookupS32(NULL, inCell->concepts, "CELL.XPARITY"); 285 int yParityIn = psMetadataLookupS32(NULL, inCell->concepts, "CELL.YPARITY"); 286 int xParityOut = psMetadataLookupS32(NULL, outCell->concepts, "CELL.XPARITY"); 287 int yParityOut = psMetadataLookupS32(NULL, outCell->concepts, "CELL.YPARITY"); 288 if (xParityIn == 0 || xParityOut == 0 || yParityIn == 0 || yParityOut == 0) { 289 psError(PS_ERR_IO, false, "Unable to determine parity of cell!\n"); 290 // XXX Clean up before returning 291 return NULL; 292 } 293 if (xParityIn != xParityOut) { 294 for (int i = 0; i < outReadouts->n; i++) { 295 psImage *image = outReadouts->data[i]; 296 outReadouts->data[i] = xFlipImage(image); 297 psFree(image); 298 } 299 // Correct CELL.X0 for the parity shift 300 psMetadataItem *x0item = psMetadataLookup(inCell->concepts, "CELL.X0"); 301 x0item->data.S32 -= xSize->data.S32[cellNum]; 302 } 303 if (yParityIn != yParityOut) { 304 for (int i = 0; i < outReadouts->n; i++) { 305 psImage *image = outReadouts->data[i]; 306 outReadouts->data[i] = xFlipImage(image); 307 psFree(image); 308 } 309 // Correct CELL.Y 0 for the parity shift 310 psMetadataItem *y0item = psMetadataLookup(inCell->concepts, "CELL.Y0"); 311 y0item->data.S32 -= ySize->data.S32[cellNum]; 312 } 313 314 ////////////////////////////////////////////////////////////////////////////////////////////////////// 315 // DO I WANT TO DO THIS???? 316 // Wouldn't it be better to splice all the images together first, and then divvy up the components? 317 ////////////////////////////////////////////////////////////////////////////////////////////////////// 318 319 320 // Manipulate the images, if required 321 for (int i = 0; i < outReadouts->n; i++) { 322 psImage *image = manipulate(outReadouts 323 324 psImage *image = psMemIncrRefCounter(outReadouts->data[i]); 325 if (xParityIn != xParityOut) { 326 psImage *image = xFlipImage(image); 327 } 328 329 330 // THIS ISN'T SO SIMPLE: we need to SET the output x0,y0 based on where the image actually gets pasted 331 // Get the offsets 332 x0->data.S32[i] = psMetadataLookupS32(NULL, outCell->concepts, "CELL.X0"); 333 y0->data.S32[i] = psMetadataLookupS32(NULL, outCell->concepts, "CELL.Y0"); 334 335 336 337 338 // Splice a list of cells together 339 static psArray *spliceCells(psList *outCells, // List of target cells (required for parity info) 340 psList *inCells, // List of cells to splice together 341 bool posDep // Position dependent placement of overscans? 342 ) 343 { 344 assert(outCells); 345 assert(inCells); 346 347 psTrace(__func__, 5, "Splicing together all cells in the bucket.\n"); 348 349 if (inCells->n != outCells->n) { 350 psError(PS_ERR_IO, true, "Sizes of input (%d) and output (%d) lists of cells don't match.\n", 351 inCells->n, outCells->n); 352 return NULL; 353 } 354 355 int numCells = inCells->n; // Number of cells 356 int readdir = 0; // Read direction for CCD; currently unknown 357 int numReadouts = 0; // Number of readouts in a cell 358 psArray *spliced = NULL; // Array of spliced readouts 359 psElemType type = 0; // Image type (U16, S32, F32, etc) 360 361 psVector *xSize = NULL; // Size of spliced image in x 362 psVector *ySize = NULL; // Size of spliced image in y 363 364 psVector *xFlip = psVectorAlloc(numCells, PS_TYPE_U8); // Do we need to flip in x? 365 psVector *yFlip = psVectorAlloc(numCells, PS_TYPE_U8); // Do we need to flip in y? 366 367 368 // We go through the cells to make sure everything's kosher, and to get the sizes. 369 psListIterator *inCellsIter = psListIteratorAlloc(inCells, PS_LIST_HEAD, false); // Iterator for cells 370 psListIterator *outCellsIter = psListIteratorAlloc(outCells, PS_LIST_HEAD, false); // Iterator for cells 371 pmCell *inCell = NULL; // Cell from list of input cells 372 int cellNum = 0; // Cell number; 201 373 while (inCell = psListGetAndIncrement(inCellsIter)) { 202 psArray *readouts = inCell->readouts; // The readouts comprising the cell 203 204 // Get and check the read direction 205 int cellReaddir = psMetadataLookupS32(NULL, inCell->concepts, "CELL.READDIR"); 206 if (readdir == 0) { 207 // Zero means unknown; set it. 208 readdir = cellReaddir; 209 } else if (readdir != cellReaddir) { 210 psError(PS_ERR_IO, true, "Trying to splice cells with different read directions (%d vs %d). I " 211 "don't know how to do that!\n", readdir, cellReaddir); 212 // XXX Clean up before returning 213 return NULL; 214 } 215 216 // Get and check the number of readouts 217 if (! spliced) { 218 numReadouts = readouts->n; 219 spliced = psArrayAlloc(numReadouts); 220 xSize = psVectorAlloc(numReadouts, PS_TYPE_S32); 221 ySize = psVectorAlloc(numReadouts, PS_TYPE_S32); 222 for (int i = 0; i < numReadouts; i++) { 223 xSize->data.S32[i] = 0; 224 ySize->data.S32[i] = 0; 225 } 226 } else if (readouts->n != numReadouts) { 227 psError(PS_ERR_IO, true, "Trying to splice cells with different number of reads (%d vs %d)\n", 228 numReadouts, readouts->n); 229 // XXX Clean up before returning 230 return NULL; 231 } 232 233 // Get and check the cell parities 234 pmCell *outCell = psListGetAndIncrement(outCellsIter); // Corresponding output cell 235 int xParityIn = psMetadataLookupS32(NULL, inCell->concepts, "CELL.XPARITY"); 236 int yParityIn = psMetadataLookupS32(NULL, inCell->concepts, "CELL.YPARITY"); 237 int xParityOut = psMetadataLookupS32(NULL, outCell->concepts, "CELL.XPARITY"); 238 int yParityOut = psMetadataLookupS32(NULL, outCell->concepts, "CELL.YPARITY"); 239 if (xParityIn == 0 || xParityOut == 0 || yParityIn == 0 || yParityOut == 0) { 240 psError(PS_ERR_IO, false, "Unable to determine parity of cell!\n"); 241 // XXX Clean up before returning 242 return NULL; 243 } 244 245 if (yParityIn == yParityOut) { 246 yFlip->data.U8[cellNum] = 0; 247 } else { 248 psTrace(__func__, 7, "Need to flip y.\n"); 249 yFlip->data.U8[cellNum] = 1; 250 } 251 if (xParityIn == xParityOut) { 252 xFlip->data.U8[cellNum] = 0; 253 } else { 254 psTrace(__func__, 7, "Need to flip x.\n"); 255 xFlip->data.U8[cellNum] = 1; 256 } 257 cellNum++; 258 259 // Calculate the sizes of the spliced images 260 for (int i = 0; i < numReadouts; i++) { 261 pmReadout *readout = readouts->data[i]; // The readout of interest 262 psImage *image = readout->image; // The image pixels 263 264 // Check image type 265 if (type == 0) { 266 type = image->type.type; 267 } else if (image->type.type != type) { 268 psError(PS_ERR_IO, true, "Trying to splice readouts with different image types (%d vs %d)\n", 269 type, image->type.type); 270 // XXX Clean up before returning 271 return NULL; 272 } 273 274 psRegion *trimsec = psMetadataLookupPtr(NULL, inCell->concepts, "CELL.TRIMSEC"); // Trim section 275 psList *biassecs = psMetadataLookupPtr(NULL, inCell->concepts, "CELL.BIASSEC"); // Bias section 276 psListIterator *biassecsIter = psListIteratorAlloc(biassecs, PS_LIST_HEAD, false); // Iterator 277 psRegion *biassec = NULL; // Bias section from list iteration 278 279 // Get the size of the spliced image 280 if (readdir == 1) { 281 xSize->data.S32[i] += trimsec->x1 - trimsec->x0; 282 ySize->data.S32[i] = MAX(ySize->data.S32[i], trimsec->y1 - trimsec->y0); 283 while (biassec = psListGetAndIncrement(biassecsIter)) { 284 xSize->data.S32[i] += biassec->x1 - biassec->x0; 285 ySize->data.S32[i] = MAX(ySize->data.S32[i], biassec->y1 - biassec->y0); 286 } 287 } else if (readdir == 2) { 288 ySize->data.S32[i] += trimsec->y1 - trimsec->y0; 289 xSize->data.S32[i] = MAX(xSize->data.S32[i], trimsec->x1 - trimsec->x0); 290 while (biassec = psListGetAndIncrement(biassecsIter)) { 291 ySize->data.S32[i] += biassec->y1 - biassec->y0; 292 xSize->data.S32[i] = MAX(ySize->data.S32[i], biassec->x1 - biassec->x0); 293 } 294 } else { 295 psError(PS_ERR_IO, true, "Invalid read direction: %d\n", readdir); 296 // XXX Clean up before returning 297 return NULL; 298 } 299 psFree(biassecsIter); 300 } 301 302 // Copy the concepts over 303 psMetadataCopy(outCell->concepts, inCell->concepts); 374 psArray *readouts = inCell->readouts; // The readouts comprising the cell 375 376 // Get and check the read direction 377 int cellReaddir = psMetadataLookupS32(NULL, inCell->concepts, "CELL.READDIR"); 378 psTrace(__func__, 10, "Checking read direction for cell %d: %d\n", cellNum, cellReaddir); 379 if (cellNum == 0) { 380 // First run through; set it. 381 readdir = cellReaddir; 382 } else if (readdir != cellReaddir) { 383 psError(PS_ERR_IO, true, "Trying to splice cells with different read directions (%d vs %d). I " 384 "don't know how to do that!\n", readdir, cellReaddir); 385 // XXX Clean up before returning 386 return NULL; 387 } 388 389 // Get and check the number of readouts 390 if (! spliced) { 391 numReadouts = readouts->n; 392 spliced = psArrayAlloc(numReadouts); 393 xSize = psVectorAlloc(numReadouts, PS_TYPE_S32); 394 ySize = psVectorAlloc(numReadouts, PS_TYPE_S32); 395 for (int i = 0; i < numReadouts; i++) { 396 xSize->data.S32[i] = 0; 397 ySize->data.S32[i] = 0; 398 } 399 } else if (readouts->n != numReadouts) { 400 psError(PS_ERR_IO, true, "Trying to splice cells with different number of reads (%d vs %d)\n", 401 numReadouts, readouts->n); 402 // XXX Clean up before returning 403 return NULL; 404 } 405 406 // Get and check the cell parities 407 pmCell *outCell = psListGetAndIncrement(outCellsIter); // Corresponding output cell 408 int xParityIn = psMetadataLookupS32(NULL, inCell->concepts, "CELL.XPARITY"); 409 int yParityIn = psMetadataLookupS32(NULL, inCell->concepts, "CELL.YPARITY"); 410 int xParityOut = psMetadataLookupS32(NULL, outCell->concepts, "CELL.XPARITY"); 411 int yParityOut = psMetadataLookupS32(NULL, outCell->concepts, "CELL.YPARITY"); 412 if (xParityIn == 0 || xParityOut == 0 || yParityIn == 0 || yParityOut == 0) { 413 psError(PS_ERR_IO, false, "Unable to determine parity of cell!\n"); 414 // XXX Clean up before returning 415 return NULL; 416 } 417 418 if (yParityIn == yParityOut) { 419 yFlip->data.U8[cellNum] = 0; 420 } else { 421 psTrace(__func__, 7, "Need to flip y.\n"); 422 yFlip->data.U8[cellNum] = 1; 423 } 424 if (xParityIn == xParityOut) { 425 xFlip->data.U8[cellNum] = 0; 426 } else { 427 psTrace(__func__, 7, "Need to flip x.\n"); 428 xFlip->data.U8[cellNum] = 1; 429 } 430 cellNum++; 431 432 // Calculate the sizes of the spliced images 433 for (int i = 0; i < numReadouts; i++) { 434 pmReadout *readout = readouts->data[i]; // The readout of interest 435 psImage *image = readout->image; // The image pixels 436 437 // Check image type 438 if (type == 0) { 439 type = image->type.type; 440 } else if (image->type.type != type) { 441 psError(PS_ERR_IO, true, "Trying to splice readouts with different image types (%d vs %d)\n", 442 type, image->type.type); 443 // XXX Clean up before returning 444 return NULL; 445 } 446 447 psRegion *trimsec = psMetadataLookupPtr(NULL, inCell->concepts, "CELL.TRIMSEC"); // Trim section 448 psList *biassecs = psMetadataLookupPtr(NULL, inCell->concepts, "CELL.BIASSEC"); // Bias section 449 psListIterator *biassecsIter = psListIteratorAlloc(biassecs, PS_LIST_HEAD, false); // Iterator 450 psRegion *biassec = NULL; // Bias section from list iteration 451 452 // Get the size of the spliced image 453 if (readdir == 1) { 454 psTrace(__func__, 7, "TRIMSEC is %.0fx%.0f\n", trimsec->x1 - trimsec->x0, 455 trimsec->y1 - trimsec->y0); 456 xSize->data.S32[i] += trimsec->x1 - trimsec->x0; 457 ySize->data.S32[i] = MAX(ySize->data.S32[i], trimsec->y1 - trimsec->y0); 458 while (biassec = psListGetAndIncrement(biassecsIter)) { 459 psTrace(__func__, 9, "BIASSEC is %.0fx%.0f\n", biassec->x1 - biassec->x0, 460 biassec->y1 - biassec->y0); 461 xSize->data.S32[i] += biassec->x1 - biassec->x0; 462 ySize->data.S32[i] = MAX(ySize->data.S32[i], biassec->y1 - biassec->y0); 463 } 464 } else if (readdir == 2) { 465 ySize->data.S32[i] += trimsec->y1 - trimsec->y0; 466 xSize->data.S32[i] = MAX(xSize->data.S32[i], trimsec->x1 - trimsec->x0); 467 while (biassec = psListGetAndIncrement(biassecsIter)) { 468 ySize->data.S32[i] += biassec->y1 - biassec->y0; 469 xSize->data.S32[i] = MAX(ySize->data.S32[i], biassec->x1 - biassec->x0); 470 } 471 } else { 472 psError(PS_ERR_IO, true, "Invalid read direction: %d\n", readdir); 473 // XXX Clean up before returning 474 return NULL; 475 } 476 psFree(biassecsIter); 477 } 304 478 } 305 479 psFree(inCellsIter); … … 308 482 309 483 // Make sure all the readouts have the same size 310 int numRows = ySize->data.S32[0]; // Number of rows for spliced image311 int numCols = xSize->data.S32[0]; // Number of columns for spliced image484 int numRows = ySize->data.S32[0]; // Number of rows for spliced image 485 int numCols = xSize->data.S32[0]; // Number of columns for spliced image 312 486 for (int i = 1; i < numReadouts; i++) { 313 if (xSize->data.S32[i] != numCols || ySize->data.S32[i] != numRows) {314 psError(PS_ERR_IO, true, "Spliced readouts would have different sizes: %dx%d vs %dx%d\n",315 numCols, numRows, xSize->data.S32[i], ySize->data.S32[i]);316 }487 if (xSize->data.S32[i] != numCols || ySize->data.S32[i] != numRows) { 488 psError(PS_ERR_IO, true, "Spliced readouts would have different sizes: %dx%d vs %dx%d\n", 489 numCols, numRows, xSize->data.S32[i], ySize->data.S32[i]); 490 } 317 491 } 318 492 … … 321 495 // Now we have done the requisite checks, and know the sizes; we just go through and splice together 322 496 for (int i = 0; i < numReadouts; i++) { 323 psImage *splice = psImageAlloc(numCols, numRows, type); // The spliced image 324 int x0 = 0, y0 = 0; // Position at which the splice begins 325 326 // Position-dependent overscans first 327 if (posDep) { 328 for (int cellNum = 0; cellNum < inCells->n / 2; cellNum++) { 329 pmCell *inCell = psListGet(inCells, cellNum); // Input cell of interest 330 pmCell *outCell = psListGet(outCells, cellNum); // Output cell of interest 331 spliceBias(splice, &x0, &y0, inCell, outCell, xFlip->data.U8[i], yFlip->data.U8[i], i, 332 readdir); 333 } 334 } 335 336 // Then the images 337 psListIterator *inCellsIter = psListIteratorAlloc(inCells, PS_LIST_HEAD, false);// Iterator for cells 338 pmCell *inCell = NULL; // Cell from the list of cells 339 psListIterator *outCellsIter = psListIteratorAlloc(outCells, PS_LIST_HEAD, false); // Iterator 340 int cellNum = 0; // Cell number 341 while (inCell = psListGetAndIncrement(inCellsIter)) { 342 psArray *readouts = inCell->readouts; // The readouts comprising the cell 343 pmReadout *readout = readouts->data[i]; // The specific readout of interest 344 pmCell *outCell = psListGetAndIncrement(outCellsIter); // Output cell 345 psRegion *inTrimsec = psMetadataLookupPtr(NULL, inCell->concepts, "CELL.TRIMSEC"); // TRIMSEC 346 psRegion *outTrimsec = spliceImage(splice, &x0, &y0, readout->image, inTrimsec, readdir, 347 xFlip->data.U8[cellNum], yFlip->data.U8[cellNum]); 348 349 // Update the output TRIMSEC 350 psMetadataAdd(outCell->concepts, PS_LIST_TAIL, "CELL.TRIMSEC", PS_DATA_UNKNOWN | PS_META_REPLACE, 351 "TRIMSEC from pmFPAMorph", outTrimsec); 352 } 353 psFree(inCellsIter); 354 psFree(outCellsIter); 355 356 // Then the biases 357 if (! posDep) { 358 // Need to only do half the biases 359 for (int cellNum = inCells->n / 2; cellNum < inCells->n; cellNum++) { 360 pmCell *inCell = psListGet(inCells, cellNum); // Input cell of interest 361 pmCell *outCell = psListGet(outCells, cellNum); // Output cell of interest 362 spliceBias(splice, &x0, &y0, inCell, outCell, xFlip->data.U8[i], yFlip->data.U8[i], i, 363 readdir); 364 } 365 } else { 366 // Need to do all the biases 367 for (int cellNum = 0; cellNum < inCells->n; cellNum++) { 368 pmCell *inCell = psListGet(inCells, cellNum); // Input cell of interest 369 pmCell *outCell = psListGet(outCells, cellNum); // Output cell of interest 370 spliceBias(splice, &x0, &y0, inCell, outCell, xFlip->data.U8[i], yFlip->data.U8[i], i, 371 readdir); 372 } 373 } 374 375 spliced->data[i] = splice; 497 psImage *splice = psImageAlloc(numCols, numRows, type); // The spliced image 498 int x0 = 0, y0 = 0; // Position at which the splice begins 499 500 // Position-dependent overscans first 501 if (posDep) { 502 psTrace(__func__, 8, "Doing first position-dependent biases...\n"); 503 for (int cellNum = 0; cellNum < inCells->n / 2; cellNum++) { 504 psTrace(__func__, 9, "Cell %d...\n", cellNum); 505 pmCell *inCell = psListGet(inCells, cellNum); // Input cell of interest 506 pmCell *outCell = psListGet(outCells, cellNum); // Output cell of interest 507 spliceBias(splice, &x0, &y0, inCell, outCell, xFlip->data.U8[i], yFlip->data.U8[i], i, 508 readdir); 509 } 510 } 511 512 // Then the images 513 psListIterator *inCellsIter = psListIteratorAlloc(inCells, PS_LIST_HEAD, false);// Iterator for cells 514 pmCell *inCell = NULL; // Cell from the list of cells 515 psListIterator *outCellsIter = psListIteratorAlloc(outCells, PS_LIST_HEAD, false); // Iterator 516 int cellNum = 0; // Cell number 517 while (inCell = psListGetAndIncrement(inCellsIter)) { 518 psArray *readouts = inCell->readouts; // The readouts comprising the cell 519 pmReadout *readout = readouts->data[i]; // The specific readout of interest 520 pmCell *outCell = psListGetAndIncrement(outCellsIter); // Output cell 521 psRegion *inTrimsec = psMetadataLookupPtr(NULL, inCell->concepts, "CELL.TRIMSEC"); // TRIMSEC 522 psRegion *outTrimsec = spliceImage(splice, &x0, &y0, readout->image, inTrimsec, readdir, 523 xFlip->data.U8[cellNum], yFlip->data.U8[cellNum]); 524 525 // Update the output TRIMSEC 526 psMetadataAdd(outCell->concepts, PS_LIST_TAIL, "CELL.TRIMSEC", PS_DATA_UNKNOWN | PS_META_REPLACE, 527 "TRIMSEC from pmFPAMorph", outTrimsec); 528 } 529 psFree(inCellsIter); 530 psFree(outCellsIter); 531 532 // Then the biases 533 if (posDep) { 534 // Need to only do half the biases 535 psTrace(__func__, 8, "Doing second position-dependent biases...\n"); 536 for (int cellNum = inCells->n / 2; cellNum < inCells->n; cellNum++) { 537 psTrace(__func__, 9, "Cell %d...\n", cellNum); 538 pmCell *inCell = psListGet(inCells, cellNum); // Input cell of interest 539 pmCell *outCell = psListGet(outCells, cellNum); // Output cell of interest 540 spliceBias(splice, &x0, &y0, inCell, outCell, xFlip->data.U8[i], yFlip->data.U8[i], i, 541 readdir); 542 } 543 } else { 544 // Need to do all the biases 545 for (int cellNum = 0; cellNum < inCells->n; cellNum++) { 546 pmCell *inCell = psListGet(inCells, cellNum); // Input cell of interest 547 pmCell *outCell = psListGet(outCells, cellNum); // Output cell of interest 548 spliceBias(splice, &x0, &y0, inCell, outCell, xFlip->data.U8[i], yFlip->data.U8[i], i, 549 readdir); 550 } 551 } 552 553 spliced->data[i] = splice; 376 554 377 555 } // Iterating over readouts … … 384 562 385 563 386 bool pmFPAMorph(pmFPA *toFPA, // FPA structure to which to morph387 pmFPA *fromFPA,// FPA structure from which to morph388 bool positionDependent, // Is the position of the overscan dependent on the position?389 int chipNum,// Chip number, in case the scopes are different390 int cellNum// Cell number, in case the scopes are different564 bool pmFPAMorph(pmFPA *toFPA, // FPA structure to which to morph 565 pmFPA *fromFPA, // FPA structure from which to morph 566 bool positionDependent, // Is the position of the overscan dependent on the position? 567 int chipNum, // Chip number, in case the scopes are different 568 int cellNum // Cell number, in case the scopes are different 391 569 ) 392 570 { … … 394 572 psList *sourceCells = psListAlloc(NULL); // List of source cells 395 573 396 psArray *toChips = toFPA->chips; // Array of chips 397 psArray *fromChips = fromFPA->chips;// Array of chips 574 psArray *toChips = toFPA->chips; // Array of chips 575 psArray *fromChips = fromFPA->chips;// Array of chips 576 577 psTrace(__func__, 1, "Copying FPA concepts over...\n"); 578 pap_psMetadataCopy(toFPA->concepts, fromFPA->concepts); 579 pap_psMetadataCopy(toFPA->phu, fromFPA->phu); 398 580 399 581 for (int i = 0; i < toChips->n; i++) { 400 pmChip *toChip = toChips->data[i]; 401 pmChip *fromChip = NULL; 402 // Select the correct chip 403 if (toChips->n == 1 && fromChips->n > chipNum) { 404 fromChip = fromChips->data[chipNum]; 405 } else if (fromChips->n == 1 && toChips->n > chipNum) { 406 fromChip = fromChips->data[0]; 407 } else if (toChips->n == fromChips->n) { 408 fromChip = fromChips->data[i]; 409 } else { 410 psError(PS_ERR_IO, true, "Unable to discern intended chip.\n"); 411 return false; 412 } 413 414 psArray *toCells = toChip->cells; // Array of cells 415 psArray *fromCells = fromChip->cells; // Array of cells 416 417 for (int j = 0; j < toCells->n; j++) { 418 pmCell *toCell = toCells->data[j]; 419 pmCell *fromCell = NULL; 420 // Select the correct cell 421 if (toCells->n == 1 && fromCells->n > cellNum) { 422 fromCell = fromCells->data[cellNum]; 423 } else if (fromCells->n == 1 && toCells->n > cellNum) { 424 fromCell = fromCells->data[0]; 425 } else if (toCells->n == fromCells->n) { 426 fromCell = fromCells->data[j]; 427 } else { 428 psError(PS_ERR_IO, true, "Unable to discern intended cell.\n"); 429 return false; 430 } 431 432 psTrace(__func__, 5, "Putting chip %d, cell %d in the bucket.\n", i, j); 433 psListAdd(targetCells, PS_LIST_TAIL, toCell); 434 psListAdd(sourceCells, PS_LIST_TAIL, fromCell); 435 436 #if 1 437 int xParityIn = psMetadataLookupS32(NULL, fromCell->concepts, "CELL.XPARITY"); 438 int yParityIn = psMetadataLookupS32(NULL, fromCell->concepts, "CELL.YPARITY"); 439 int xParityOut = psMetadataLookupS32(NULL, toCell->concepts, "CELL.XPARITY"); 440 int yParityOut = psMetadataLookupS32(NULL, toCell->concepts, "CELL.YPARITY"); 441 psTrace(__func__, 3, "Chip %d, cell %d: in (%d,%d) out (%d,%d)\n", i, j, xParityIn, yParityIn, 442 xParityOut, yParityOut); 582 pmChip *toChip = toChips->data[i]; 583 pmChip *fromChip = NULL; 584 // Select the correct chip 585 if (toChips->n == 1 && fromChips->n > chipNum) { 586 fromChip = fromChips->data[chipNum]; 587 } else if (fromChips->n == 1 && toChips->n > chipNum) { 588 fromChip = fromChips->data[0]; 589 } else if (toChips->n == fromChips->n) { 590 fromChip = fromChips->data[i]; 591 } else { 592 psError(PS_ERR_IO, true, "Unable to discern intended chip.\n"); 593 return false; 594 } 595 596 if (! fromChip->valid) { 597 toChip->valid = false; 598 continue; 599 } 600 601 psTrace(__func__, 2, "Copying chip %d concepts over...\n", i); 602 pap_psMetadataCopy(toChip->concepts, fromChip->concepts); 603 604 psArray *toCells = toChip->cells; // Array of cells 605 psArray *fromCells = fromChip->cells; // Array of cells 606 607 for (int j = 0; j < toCells->n; j++) { 608 pmCell *toCell = toCells->data[j]; 609 pmCell *fromCell = NULL; 610 // Select the correct cell 611 if (toCells->n == 1 && fromCells->n > cellNum) { 612 fromCell = fromCells->data[cellNum]; 613 } else if (fromCells->n == 1 && toCells->n > cellNum) { 614 fromCell = fromCells->data[0]; 615 } else if (toCells->n == fromCells->n) { 616 fromCell = fromCells->data[j]; 617 } else { 618 psError(PS_ERR_IO, true, "Unable to discern intended cell.\n"); 619 return false; 620 } 621 622 if (! fromCell->valid) { 623 toCell->valid = false; 624 continue; 625 } 626 627 #ifdef TESTING 628 int xParityIn = psMetadataLookupS32(NULL, fromCell->concepts, "CELL.XPARITY"); 629 int yParityIn = psMetadataLookupS32(NULL, fromCell->concepts, "CELL.YPARITY"); 630 int xParityOut = psMetadataLookupS32(NULL, toCell->concepts, "CELL.XPARITY"); 631 int yParityOut = psMetadataLookupS32(NULL, toCell->concepts, "CELL.YPARITY"); 632 psTrace(__func__, 3, "Chip %d, cell %d: in (%d,%d) out (%d,%d)\n", i, j, xParityIn, yParityIn, 633 xParityOut, yParityOut); 443 634 #endif 444 635 445 // Copy the cell contents over 446 toCell->readouts = psMemIncrRefCounter(fromCell->readouts); 447 448 if (toCell->hdu && strlen(toCell->hdu->extname) > 0) { 449 // Splice the component cells 450 p_pmHDU *hdu = toCell->hdu; 451 if (! hdu->header) { 452 hdu->header = psMetadataAlloc(); 453 } 454 hdu->images = spliceCells(targetCells, sourceCells, positionDependent); 455 // Purge the lists 456 while (psListRemove(targetCells, PS_LIST_TAIL)); 457 while (psListRemove(sourceCells, PS_LIST_TAIL)); 458 } 459 460 } 461 462 if (toChip->hdu && strlen(toChip->hdu->extname) > 0) { 463 // Splice the component cells 464 p_pmHDU *hdu = toChip->hdu; 465 if (! hdu->header) { 466 hdu->header = psMetadataAlloc(); 467 } 468 hdu->images = spliceCells(targetCells, sourceCells, positionDependent); 469 // Purge the lists 470 while (psListRemove(targetCells, PS_LIST_TAIL)); 471 while (psListRemove(sourceCells, PS_LIST_TAIL)); 472 } 636 #ifdef TESTING 637 psMetadataPrint(toCell->concepts, 7); 638 #endif 639 640 // Copy the concepts over 641 642 // Need to be a little tricky here --- some concepts are already set from the camera configuration 643 // file (e.g., CELL.NAME), and we want to preserve these, not replace it with the old value. 644 psTrace(__func__, 3, "Copying cell %d concepts over...\n", j); 645 psMetadata *newConcepts = pap_psMetadataCopy(NULL, fromCell->concepts); 646 pap_psMetadataCopy(newConcepts, toCell->concepts); // This preserves any already existing concepts 647 psFree(toCell->concepts); 648 toCell->concepts = newConcepts; 649 650 // Now, we need to check if the following concepts for the target cell are defined statically: 651 // CELL.XPARITY, CELL.YPARITY, CELL.XBIN, CELL.YBIN, CELL.X0, CELL.Y0 652 // 1. If they are specified by the header, we can do what we want (because we can set the header). 653 // 2. If they are not specified by the header, we use those values. 654 const char *checkConcepts[4] = { "CELL.XPARITY", 655 "CELL.YPARITY", 656 "CELL.XBIN", 657 "CELL.YBIN", 658 "CELL.X0", 659 "CELL.Y0" }; // Concepts that we need to check 660 bool mdok = false; // Result of MD lookup 661 psMetadata *translation = psMetadataLookupMD(&mdok, toFPA->camera, "TRANSLATION"); // Header 662 // translation table 663 if (!mdok || ! translation) { 664 psError(PS_ERR_IO, true, "Unable to find TRANSLATION in camera configuration!\n"); 665 return false; 666 } 667 for (int c = 0; c < 4; c++) { 668 psString headerName = psMetadataLookupString(&mdok, translation, checkConcepts[c]); // Name of 669 // header holding the concept, or NULL 670 if (!mdok || strlen(headerName) <= 0) { 671 p_pmCellIngestConcept(toFPA, toChip, toCell, db, checkConcepts[c]); 672 } 673 } 674 675 #ifdef TESTING 676 psMetadataPrint(toCell->concepts, 7); 677 #endif 678 679 psTrace(__func__, 5, "Putting chip %d, cell %d in the bucket.\n", i, j); 680 psListAdd(targetCells, PS_LIST_TAIL, toCell); 681 psListAdd(sourceCells, PS_LIST_TAIL, fromCell); 682 683 // Copy the cell contents over 684 toCell->readouts = psMemIncrRefCounter(fromCell->readouts); 685 686 if (toCell->hdu && strlen(toCell->hdu->extname) > 0) { 687 // Splice the component cells 688 p_pmHDU *hdu = toCell->hdu; 689 if (! hdu->header) { 690 hdu->header = psMetadataAlloc(); 691 } 692 hdu->images = spliceCells(targetCells, sourceCells, positionDependent); 693 // Purge the lists 694 while (psListRemove(targetCells, PS_LIST_TAIL)); 695 while (psListRemove(sourceCells, PS_LIST_TAIL)); 696 } 697 698 } 699 700 if (toChip->hdu && strlen(toChip->hdu->extname) > 0) { 701 // Splice the component cells 702 p_pmHDU *hdu = toChip->hdu; 703 if (! hdu->header) { 704 hdu->header = psMetadataAlloc(); 705 } 706 hdu->images = spliceCells(targetCells, sourceCells, positionDependent); 707 // Purge the lists 708 while (psListRemove(targetCells, PS_LIST_TAIL)); 709 while (psListRemove(sourceCells, PS_LIST_TAIL)); 710 } 473 711 474 712 } 475 713 476 714 if (toFPA->hdu && strlen(toFPA->hdu->extname) > 0) { 477 // Splice the component cells478 p_pmHDU *hdu = toFPA->hdu;479 if (! hdu->header) {480 hdu->header = psMetadataAlloc();481 }482 hdu->images = spliceCells(targetCells, sourceCells, positionDependent);483 // Purge the lists484 while (psListRemove(targetCells, PS_LIST_TAIL));485 while (psListRemove(sourceCells, PS_LIST_TAIL));715 // Splice the component cells 716 p_pmHDU *hdu = toFPA->hdu; 717 if (! hdu->header) { 718 hdu->header = psMetadataAlloc(); 719 } 720 hdu->images = spliceCells(targetCells, sourceCells, positionDependent); 721 // Purge the lists 722 while (psListRemove(targetCells, PS_LIST_TAIL)); 723 while (psListRemove(sourceCells, PS_LIST_TAIL)); 486 724 } 487 725
Note:
See TracChangeset
for help on using the changeset viewer.
