Changeset 7168 for trunk/psModules/src/camera/pmFPACopy.c
- Timestamp:
- May 22, 2006, 2:23:08 PM (20 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/camera/pmFPACopy.c (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/camera/pmFPACopy.c
r7017 r7168 10 10 #include "pmHDU.h" 11 11 #include "pmHDUUtils.h" 12 #include "pmHDUGenerate.h" 13 12 14 #include "pmFPACopy.h" 13 15 14 #define MAX(x,y) ((x) > (y) ? (x) : (y))15 16 17 16 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 18 17 // File-static functions 19 18 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 20 19 21 // Add cells in a chip to a list 22 static bool addCellsFromChip(psList *list, // List of cells 23 const pmChip *chip // The chip from which to add cells 24 ) 25 { 26 assert(list); 27 assert(chip); 28 29 psArray *cells = chip->cells; // Array of cells 30 bool result = true; // Result of adding cells 31 for (int i = 0; i < cells->n; i++) { 32 pmCell *cell = cells->data[i]; // A cell 33 result |= psListAdd(list, PS_LIST_TAIL, cell); 34 } 35 36 return result; 37 } 38 39 // Add cells in an FPA to a list 40 static bool addCellsFromFPA(psList *list, // List of cells 41 const pmFPA *fpa // The FPA from which to add cells 42 ) 43 { 44 assert(list); 45 assert(fpa); 46 47 psArray *chips = fpa->chips; // Array of chips 48 bool result = true; // Result of adding cells 49 for (int i = 0; i < chips->n; i++) { 50 pmChip *chip = chips->data[i]; // A chip 51 result |= addCellsFromChip(list, chip); 52 } 53 54 return result; 55 } 56 57 // Get a list of cells that share the HDU for the target cell 58 static bool cellList(psList *targets, // The list of target cells 59 psList *sources, // The list of source cells 60 pmCell *targetCell, // The target cell 61 pmCell *sourceCell // The source cell 62 ) 63 { 64 assert(targetCell); 65 assert(sourceCell); 66 67 if (targetCell->hdu) { 68 if (targets) { 69 psListAdd(targets, PS_LIST_TAIL, targetCell); 70 } 71 if (sources) { 72 psListAdd(sources, PS_LIST_TAIL, sourceCell); 73 } 74 } else { 75 pmChip *targetChip = targetCell->parent; // The target parent chip 76 pmChip *sourceChip = sourceCell->parent; // The source parent chip 77 if (targetChip->hdu) { 78 if (targets) { 79 addCellsFromChip(targets, targetChip); 80 } 81 if (sources) { 82 addCellsFromChip(sources, sourceChip); 83 } 84 } else { 85 pmFPA *targetFPA = targetChip->parent; // The target parent FPA 86 pmFPA *sourceFPA = sourceChip->parent; // The source parent FPA 87 if (targetFPA->hdu) { 88 if (targets) { 89 addCellsFromFPA(targets, targetFPA); 90 } 91 if (sources) { 92 addCellsFromFPA(sources, sourceFPA); 93 } 94 } else { 95 psError(PS_ERR_IO, true, "Unable to find HDU for cell to generate list!\n"); 96 return false; 97 } 98 } 99 } 100 101 return true; 102 } 103 104 // Get the maximum extent of the HDU from the trimsec and biassecs 105 static bool sizeHDU(int *xSize, int *ySize, // Size of HDU 106 psList *cells // List of cells 107 ) 108 { 109 psListIterator *cellsIter = psListIteratorAlloc(cells, PS_LIST_HEAD, false); // Iterator for cells 110 pmCell *cell = NULL; // The cell from iteration 111 bool mdok = true; // Status of MD lookup 112 *xSize = 0; 113 *ySize = 0; 114 while ((cell = psListGetAndIncrement(cellsIter))) { 115 psRegion *trimsec = psMetadataLookupPtr(&mdok, cell->concepts, "CELL.TRIMSEC"); // Trim section 116 if (mdok && trimsec && !psRegionIsBad(*trimsec)) { 117 *xSize = MAX(trimsec->x1, *xSize); 118 *ySize = MAX(trimsec->y1, *ySize); 119 } else { 120 psFree(cellsIter); 121 return false; 122 } 123 psList *biassecs = psMetadataLookupPtr(&mdok, cell->concepts, "CELL.BIASSEC"); // Bias sections 124 if (mdok && biassecs) { 125 psListIterator *biassecsIter = psListIteratorAlloc(biassecs, PS_LIST_HEAD, false); // Iterator 126 psRegion *biassec = NULL; // The bias section 127 while ((biassec = psListGetAndIncrement(biassecsIter))) { 128 if (!psRegionIsBad(*trimsec)) { 129 *xSize = MAX(biassec->x1, *xSize); 130 *ySize = MAX(biassec->y1, *ySize); 131 } else { 132 psFree(biassecsIter); 133 psFree(cellsIter); 134 return false; 135 } 136 } 137 psFree(biassecsIter); 138 } 139 } 140 psFree(cellsIter); 141 142 return (*xSize != 0 && *ySize != 0); 143 } 144 145 146 static psRegion sectionForImage(int *position, // Position on the output image, updated 147 const psImage *image, // Image containing the sizes and offsets 148 int readdir // Read direction, 1=rows, 2=cols 149 ) 150 { 151 psRegion region; 152 switch (readdir) { 153 case 1: // Read direction is rows 154 region = psRegionSet(*position, *position + image->numCols, image->row0, 155 image->row0 + image->numRows); 156 *position += image->numCols; 157 break; 158 case 2: // Read direction is columns 159 region = psRegionSet(image->col0, image->col0 + image->numCols, *position, 160 *position + image->numRows); 161 *position += image->numRows; 162 break; 163 default: 164 psAbort(__func__, "Shouldn't ever get here!\n"); 165 } 166 167 return region; 168 } 169 170 static bool doBiasSections(int *position, // Position on the output image, updated 171 pmCell *target, // Target cell 172 const pmCell *source // Source cell 20 // Copy pixels from a target image to a source image, with flips 21 static psImage *copyPixels(psImage *source, // Source image (from source cell) 22 bool xFlip, // Flip in x? 23 bool yFlip // Flip in y? 173 24 ) 174 25 { 175 psMetadataItem *biassecItem = psMetadataLookup(target->concepts, "CELL.BIASSEC"); // Bias sections 176 if (!biassecItem) { 177 psLogMsg(__func__, PS_LOG_WARN, "CELL.BIASSEC has not been initialised in target cell --- " 178 "ignored.\n"); 179 return false; 180 } 181 psFree(biassecItem->data.V); // Blow away the old list 182 psList *biassecs = psListAlloc(NULL); 183 biassecItem->data.V = biassecs; 184 185 bool mdok = true; // Status of MD lookup 186 int readdir = psMetadataLookupS32(&mdok, source->concepts, "CELL.READDIR"); // Read direction 187 if (!mdok || (readdir != 1 && readdir != 2)) { 188 // Probably unnecessary, but just in case.... 189 psLogMsg(__func__, PS_LOG_WARN, "CELL.READDIR is not set in source cell --- ignored.\n"); 190 return false; 191 } 192 193 pmReadout *readout = source->readouts->data[0]; // The first source readout, as representative 194 psList *biases = readout->bias; // The bias images from the source readout 195 196 psListIterator *biasIter = psListIteratorAlloc(biases, PS_LIST_HEAD, true); // Iterator for biases 197 psImage *bias = NULL; // Bias image from iteration 198 while ((bias = psListGetAndIncrement(biasIter))) { 199 // Construct a region 200 psRegion *biassec = psAlloc(sizeof(psRegion)); // The new region; need a psMemBlock 201 *biassec = sectionForImage(position, bias, readdir); 202 psListAdd(biassecs, PS_LIST_TAIL, biassec); 203 psFree(biassec); // Drop reference 204 } 205 psFree(biasIter); 206 207 return true; 208 } 209 210 // Generate CELL.TRIMSEC and CELL.BIASSEC for the target cells 211 static bool generateTrimBias(psList *targets, // List of target cells 212 psList *sources // List of source cells 213 ) 214 { 215 pmCell *target = NULL, *source = NULL; // Cells from iteration 216 int numCells = targets->n; // Number of cells 217 int cellNum = 0; // The cell number 218 int position = 0; // Position on the image 219 bool mdok = true; // Status of MD lookup 220 221 // First run through to do the LHS biases 222 psListIterator *targetsIter = psListIteratorAlloc(targets, PS_LIST_HEAD, false); // Iterator for targets 223 psListIterator *sourcesIter = psListIteratorAlloc(sources, PS_LIST_HEAD, false); // Iterator for sources 224 bool done = false; // Done with iteration? 225 while ((target = psListGetAndIncrement(targetsIter)) && (source = psListGetAndIncrement(sourcesIter)) && 226 !done) { 227 if (cellNum <= numCells/2 - 1) { 228 doBiasSections(&position, target, source); 229 cellNum++; 230 } else { 231 done = true; 232 } 233 } 234 235 // Second run through to do the trim sections 236 psListIteratorSet(targetsIter, PS_LIST_HEAD); 237 psListIteratorSet(sourcesIter, PS_LIST_HEAD); 238 while ((target = psListGetAndIncrement(targetsIter)) && (source = psListGetAndIncrement(sourcesIter))) { 239 psRegion *trimsec = psMetadataLookupPtr(&mdok, target->concepts, "CELL.TRIMSEC"); // Trim section 240 if (!mdok || !trimsec) { 241 psLogMsg(__func__, PS_LOG_WARN, "CELL.TRIMSEC has not been initialised in target cell --- " 242 "ignored.\n"); 243 continue; 244 } 245 246 int readdir = psMetadataLookupS32(&mdok, source->concepts, "CELL.READDIR"); // Read direction 247 if (!mdok || (readdir != 1 && readdir != 2)) { 248 // Probably unnecessary, but just in case.... 249 psLogMsg(__func__, PS_LOG_WARN, "CELL.READDIR is not set in source cell --- ignored.\n"); 250 continue; 251 } 252 253 pmReadout *readout = source->readouts->data[0]; // The first source readout, as representative 254 psImage *image = readout->image;// The proper image 255 *trimsec = sectionForImage(&position, image, readdir); 256 } 257 258 // A final run through to do the RHS biases 259 psListIteratorSet(targetsIter, cellNum); 260 psListIteratorSet(sourcesIter, cellNum); 261 while ((target = psListGetAndIncrement(targetsIter)) && (source = psListGetAndIncrement(sourcesIter))) { 262 doBiasSections(&position, target, source); 263 } 264 265 // Clean up 266 psFree(targetsIter); 267 psFree(sourcesIter); 268 269 return (position > 0); 270 } 271 272 273 // Generate an HDU with the pixels 274 static bool generateHDU(pmCell *target, // The target cell 275 pmCell *source, // The source cell 276 int xBin, int yBin // Binning in x and y 277 ) 278 { 279 // Get the HDU and a list of cells below it 280 pmHDU *hdu = pmHDUFromCell(target); // The HDU in the target cell 281 psList *targetCells = psListAlloc(NULL); // List of target cells below the target HDU 282 psList *sourceCells = psListAlloc(NULL); // List of source cells below the target HDU 283 if (! cellList(targetCells, sourceCells, target, source)) { 284 psError(PS_ERR_IO, true, "Unable to find cells to generate HDU!\n"); 285 return false; 286 } 287 288 // Check the number of readouts 289 int numReadouts = -1; // Number of readouts 290 { 291 psListIterator *iter = psListIteratorAlloc(sourceCells, PS_LIST_HEAD, false); // Iterator for cells 292 pmCell *cell = NULL; // The cell from iteration 293 while ((cell = psListGetAndIncrement(iter))) 294 { 295 psArray *readouts = cell->readouts; 296 if (numReadouts == -1) { 297 numReadouts = readouts->n; 298 } else if (readouts->n != numReadouts) { 299 psError(PS_ERR_IO, true, "Number of readouts doesn't match: %d vs %d\n", readouts->n, 300 numReadouts); 301 return false; 302 } 303 304 } 305 psFree(iter); 306 } 307 308 // Get the size of the HDU, either from existing trimsec and biassec, or generate these and try again 309 int xSize = 0, ySize = 0; // Size of HDU 310 if (!sizeHDU(&xSize, &ySize, targetCells) && !(generateTrimBias(targetCells, sourceCells) && 311 sizeHDU(&xSize, &ySize, targetCells))) { 312 psError(PS_ERR_IO, true, "Unable to determine size of HDU!\n"); 313 return false; 314 } 315 psFree(targetCells); 316 psFree(sourceCells); 317 318 xSize = (int)ceilf((float)xSize/(float)xBin); 319 ySize = (int)ceilf((float)ySize/(float)yBin); 320 321 hdu->images = psArrayAlloc(numReadouts); 322 hdu->images->n = numReadouts; 323 for (int i = 0; i < numReadouts; i++) { 324 psImage *image = psImageAlloc(xSize, ySize, PS_TYPE_F32); 325 psImageInit(image, 0.0); 326 hdu->images->data[i] = image; 327 } 328 329 return true; 330 } 331 332 // Copy pixels from a target image to a source image, with flips 333 static bool copyPixels(psImage *target, // Target image (HDU pixels) 334 psImage *source, // Source image (from source cell) 335 psRegion region, // Region for pasting 336 bool xFlip, // Flip in x? 337 bool yFlip // Flip in y? 338 ) 339 { 340 psImage *overlay = psMemIncrRefCounter(source); 26 psImage *copy = psMemIncrRefCounter(source); 27 bool copied = false; // Have the pixels been copied? 341 28 if (xFlip) { 342 psImage *temp = psImageFlipX(overlay); 343 psFree(overlay); 344 overlay = temp; 29 psImage *temp = psImageFlipX(copy); // Flipped version 30 psFree(copy); 31 copy = temp; 32 copied = true; 345 33 } 346 34 if (yFlip) { 347 psImage *temp = psImageFlipY(overlay); 348 psFree(overlay); 349 overlay = temp; 350 } 351 int numPix = psImageOverlaySection(target, overlay, region.x0, region.y0, "="); 352 psFree(overlay); 353 return (numPix > 0); 35 psImage *temp = psImageFlipY(copy); // Flipped version 36 psFree(copy); 37 copy = temp; 38 copied = true; 39 } 40 if (!copied) { 41 psFree(copy); 42 copy = psImageCopy(NULL, source, source->type.type); 43 } 44 45 return copy; 354 46 } 355 47 … … 367 59 } 368 60 369 370 61 static pmHDU *findPHU(const pmCell *cell// The cell for which to find the PHU 371 62 ) … … 387 78 } 388 79 389 390 static bool copyPHU(pmCell *targetCell, // The target cell391 pmCell *sourceCell // The source cell392 )393 {394 // Find the respective PHUs395 pmHDU *targetPHU = findPHU(targetCell); // The target PHU396 if (targetPHU->header) {397 return false; // No work required398 }399 // Copy the header over400 pmHDU *sourcePHU = findPHU(sourceCell); // The source PHU401 targetPHU->header = psMetadataCopy(NULL, sourcePHU->header);402 return true;403 }404 405 406 80 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 407 81 // File-static engine functions --- these do all the work. Actually, cellCopy does all the work; the others … … 409 83 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 410 84 411 static intcellCopy(pmCell *target, // The target cell412 pmCell *source, // The source cell, to be copied413 bool pixels, // Copy the pixels?414 int xBin, int yBin // (Relative) binning factors in x and y415 )85 static bool cellCopy(pmCell *target, // The target cell 86 pmCell *source, // The source cell, to be copied 87 bool pixels, // Copy the pixels? 88 int xBin, int yBin // (Relative) binning factors in x and y 89 ) 416 90 { 417 91 assert(target); 418 92 assert(source); 93 assert(xBin > 0 && yBin > 0); 419 94 420 95 psArray *sourceReadouts = source->readouts; // The source readouts 421 96 int numReadouts = sourceReadouts->n; // Number of readouts copied 422 97 423 // Copy any headers424 if (target->hdu && !target->hdu->phu) {425 pmHDU *sourceHDU = pmHDUFromCell(source);426 target->hdu->header = psMetadataCopy(target->hdu->header, sourceHDU->header);427 }428 429 pmHDU *hdu = pmHDUFromCell(target); // The target HDU; we need to fix this up430 if (!hdu->images) {431 generateHDU(target, source, xBin, yBin);432 }433 if (!hdu->header) {434 hdu->header = psMetadataAlloc();435 }436 // Copy the PHU over as well, if required437 copyPHU(target, source);438 439 98 // Need to check/change CELL.XPARITY and CELL.YPARITY 440 bool xFlip = (psMetadataLookupS32(NULL, target->concepts, "CELL.XPARITY") !=441 psMetadataLookupS32(NULL, source->concepts, "CELL.XPARITY")); // Switch parity in x?442 bool yFlip = (psMetadataLookupS32(NULL, target->concepts, "CELL.YPARITY") !=443 psMetadataLookupS32(NULL, source->concepts, "CELL.YPARITY")); // Switch parity in y?444 psTrace(__func__, 3, "xFlip: %d; yFlip: %d\n", xFlip, yFlip);445 446 99 bool mdok = true; // Status of MD lookup 447 psRegion *trimsec = psMetadataLookupPtr(&mdok, target->concepts, "CELL.TRIMSEC"); // The trim section 448 if (!mdok || !trimsec || psRegionIsBad(*trimsec)) { 449 psError(PS_ERR_IO, true, "CELL.TRIMSEC isn't set!\n"); 450 return 0; 451 } 452 psList *biassecs = psMetadataLookupPtr(&mdok, target->concepts, "CELL.BIASSEC"); // The bias sections 453 if (!mdok || !biassecs) { 454 psError(PS_ERR_IO, true, "CELL.BIASSEC isn't set!\n"); 455 return 0; 456 } 457 100 bool xFlip = false; // Switch parity in x? 101 bool yFlip = false; // Switch parity in y? 102 { 103 int xParityTarget = psMetadataLookupS32(&mdok, target->concepts, "CELL.XPARITY"); // Target x parity 104 if (mdok && (xParityTarget == 1 || xParityTarget == -1)) 105 { 106 int xParitySource = psMetadataLookupS32(&mdok, source->concepts, "CELL.XPARITY"); // Source parity 107 if (mdok && (xParitySource == 1 || xParitySource == -1) && xParityTarget != xParitySource) { 108 xFlip = true; 109 } 110 } 111 int yParityTarget = psMetadataLookupS32(&mdok, target->concepts, "CELL.YPARITY"); // Target y parity 112 if (mdok && (yParityTarget == 1 || yParityTarget == -1)) 113 { 114 int yParitySource = psMetadataLookupS32(&mdok, source->concepts, "CELL.YPARITY"); // Source parity 115 if (mdok && (yParitySource == 1 || yParitySource == -1) && yParityTarget != yParitySource) { 116 yFlip = true; 117 } 118 } 119 psTrace(__func__, 3, "xFlip: %d; yFlip: %d\n", xFlip, yFlip); 120 } 121 122 if (pixels && (xBin != 1 || yBin != 1)) { 123 psLogMsg(__func__, PS_LOG_WARN, "Unable to copy pixels if binning is set --- copy turned off.\n"); 124 pixels = false; 125 } 126 127 // Perform deep copy of the images. I would prefer *not* to do a deep copy, in the interests of speed (we 128 // still need to do another deep copy into the HDU for when we write out), but this is the only way I can 129 // think of to provide security against copying a cell and then unknowingly changing the source when 130 // manipulating the target. 458 131 for (int i = 0; i < numReadouts; i++) { 459 132 pmReadout *sourceReadout = sourceReadouts->data[i]; // The source readout 460 psImage *sourceImage = sourceReadout->image; // The source image461 133 pmReadout *targetReadout = pmReadoutAlloc(target); // The target readout; this adds it to the cell 462 if (sourceImage->numCols != trimsec->x1 - trimsec->x0 || 463 sourceImage->numRows != trimsec->y1 - trimsec->y0) { 464 psString trimsecString = psRegionToString(*trimsec); // String with the trim section 465 psLogMsg(__func__, PS_LOG_WARN, "Source image size (%dx%d) for readout %d doesn't match " 466 "CELL.TRIMSEC for target (%s) -- ignored.\n", sourceImage->numCols, sourceImage->numRows, 467 i, trimsecString); 468 psFree(trimsecString); 469 } else { 470 binRegion(trimsec, xBin, yBin); 471 if (pixels) { 472 copyPixels(hdu->images->data[i], sourceImage, *trimsec, xFlip, yFlip); 473 } 474 targetReadout->image = psImageSubset(hdu->images->data[i], *trimsec); 475 } 476 477 psListIterator *biassecsIter = psListIteratorAlloc(biassecs, PS_LIST_HEAD, false); // Iterator 478 psRegion *biassec = NULL; // Bias section from iteration 479 psListIterator *biasIter = psListIteratorAlloc(sourceReadout->bias, PS_LIST_HEAD, false); // Iterator 480 psImage *bias = NULL; // Bias image from iteration 481 while ((biassec = psListGetAndIncrement(biassecsIter)) && (bias = psListGetAndIncrement(biasIter))) { 482 if (psRegionIsBad(*biassec)) { 483 psString biassecString = psRegionToString(*biassec); // String for bias section 484 psLogMsg(__func__, PS_LOG_WARN, "Bias section (%s) isn't set --- ignored.\n", biassecString); 485 psFree(biassecString); 486 continue; 487 } 488 if (bias->numCols != biassec->x1 - biassec->x0 || 489 bias->numRows != biassec->y1 - biassec->y0) { 490 psString biassecString = psRegionToString(*biassec); // String with the bias section 491 psLogMsg(__func__, PS_LOG_WARN, "Source image size (%dx%d) for readout %d doesn't match " 492 "CELL.BIASSEC for target (%s) -- ignored.\n", bias->numCols, bias->numRows, i, 493 biassecString); 494 psFree(biassecString); 495 } else { 496 binRegion(biassec, xBin, yBin); 497 if (pixels) { 498 copyPixels(hdu->images->data[i], bias, *biassec, xFlip, yFlip); 134 135 // Copy attributes 136 targetReadout->col0 = sourceReadout->col0; 137 targetReadout->row0 = sourceReadout->row0; 138 targetReadout->process = sourceReadout->process; 139 targetReadout->file_exists = sourceReadout->file_exists; 140 targetReadout->data_exists = sourceReadout->data_exists; 141 142 if (pixels) { 143 // Copy image 144 if (sourceReadout->image) { 145 if (targetReadout->image) { 146 psFree(targetReadout->image); 499 147 } 500 psImage *newBias = psImageSubset(hdu->images->data[i], *biassec); 501 psListAdd(targetReadout->bias, PS_LIST_TAIL, newBias); 502 psFree(newBias); // Drop reference 503 } 148 targetReadout->image = copyPixels(sourceReadout->image, xFlip, yFlip); 149 } 150 151 // Copy mask 152 if (sourceReadout->mask) { 153 if (targetReadout->mask) { 154 psFree(targetReadout->mask); 155 } 156 targetReadout->mask = copyPixels(sourceReadout->mask, xFlip, yFlip); 157 } 158 159 // Copy weight 160 if (sourceReadout->weight) { 161 if (targetReadout->weight) { 162 psFree(targetReadout->weight); 163 } 164 targetReadout->weight = copyPixels(sourceReadout->weight, xFlip, yFlip); 165 } 166 167 // Copy bias 168 while (targetReadout->bias->n > 0) { 169 psListRemove(targetReadout->bias, PS_LIST_HEAD); 170 } 171 // Iterate over the biases 172 psListIterator *biasIter = psListIteratorAlloc(sourceReadout->bias, PS_LIST_HEAD, false); 173 psImage *bias = NULL; // Bias image from iteration 174 while ((bias = psListGetAndIncrement(biasIter))) { 175 psImage *biasCopy = copyPixels(bias, xFlip, yFlip); 176 psListAdd(targetReadout->bias, PS_LIST_TAIL, biasCopy); 177 psFree(biasCopy); // Drop reference 178 } 179 psFree(biasIter); 504 180 } 505 181 psFree(targetReadout); // Drop reference 506 psFree(biassecsIter); 507 psFree(biasIter); 508 } 509 510 // Copy the remaining "concepts" over 182 } 183 184 // Copy the remaining "concepts" over. Don't copy the TRIMSEC or BIASSEC, since these will be created by 185 // pmHDUGenerate if they don't already exist in the target. Don't copy the XPARITY or YPARITY, since 186 // we've used those to do the flips. Don't copy the X0 and Y0 because they are updated below (and are 187 // dependent upon the flips we've done above). 511 188 psMetadataIterator *conceptsIter = psMetadataIteratorAlloc(source->concepts, PS_LIST_HEAD, NULL); 512 189 psMetadataItem *conceptItem = NULL; // Item from iteration … … 520 197 } 521 198 psFree(conceptsIter); 199 200 // Need to update CELL.TRIMSEC and CELL.BIASSEC if we changed the binning and they exist already. 201 if (xBin != 1 || yBin != 1) { 202 psRegion *trimsec = psMetadataLookupPtr(&mdok, target->concepts, "CELL.TRIMSEC"); // The trim section 203 if (mdok && trimsec && !psRegionIsBad(*trimsec)) { 204 binRegion(trimsec, xBin, yBin); 205 } 206 psList *biassecs = psMetadataLookupPtr(&mdok, target->concepts, "CELL.BIASSEC"); // The bias sections 207 if (mdok && biassecs && biassecs->n > 0) { 208 psListIterator *biassecsIter = psListIteratorAlloc(biassecs, PS_LIST_HEAD, true); // Iterator 209 psRegion *biassec = NULL; // Bias section, from iteration 210 while ((biassec = psListGetAndIncrement(biassecsIter))) { 211 if (!psRegionIsBad(*biassec)) { 212 binRegion(biassec, xBin, yBin); 213 } 214 } 215 psFree(biassecsIter); 216 } 217 } 522 218 523 219 // Need to update CELL.X0 and CELL.Y0 if we flipped … … 553 249 binItem->data.S32 *= yBin; 554 250 555 return numReadouts; 556 } 557 558 static int chipCopy(pmChip *target, // The target chip 559 pmChip *source, // The source chip, to be copied 560 bool pixels, // Copy the pixels? 561 int xBin, int yBin // (Relative) binning factors in x and y 562 ) 251 252 // Copy any headers 253 pmHDU *targetHDU = pmHDUFromCell(target); // The target HDU 254 if (targetHDU && !targetHDU->header) { 255 pmHDU *sourceHDU = pmHDUFromCell(source); // The source HDU 256 targetHDU->header = psMetadataCopy(targetHDU->header, sourceHDU->header); 257 } 258 // Copy the PHU over as well, if required 259 pmHDU *targetPHU = findPHU(target); // The target PHU 260 if (targetPHU && targetPHU != targetHDU && !targetPHU->header) { 261 pmHDU *sourcePHU = findPHU(source); // The source PHU 262 targetPHU->header = psMetadataCopy(targetPHU->header, sourcePHU->header); 263 } 264 265 return true; 266 } 267 268 static bool chipCopy(pmChip *target, // The target chip 269 pmChip *source, // The source chip, to be copied 270 bool pixels, // Copy the pixels? 271 int xBin, int yBin // (Relative) binning factors in x and y 272 ) 563 273 { 564 274 assert(target); … … 573 283 } 574 284 575 // Copy any headers 576 if (target->hdu && !target->hdu->phu) { 577 pmHDU *sourceHDU = pmHDUFromChip(source); 578 target->hdu->header = psMetadataCopy(target->hdu->header, sourceHDU->header); 579 } 580 581 int numCells = 0; // Number of cells copied 285 bool status = true; // Status of copy 582 286 for (int i = 0; i < targetCells->n; i++) { 583 287 pmCell *targetCell = targetCells->data[i]; // The target cell … … 586 290 if (cellNum >= 0) { 587 291 pmCell *sourceCell = sourceCells->data[cellNum]; // The source cell 588 int numReadouts = cellCopy(targetCell, sourceCell, pixels, xBin, yBin); // Number of readouts 589 // copied 590 psTrace(__func__, 5, "Copied %d readouts for cell %s\n", numReadouts, cellName); 591 numCells++; 292 status &= cellCopy(targetCell, sourceCell, pixels, xBin, yBin); 592 293 } 593 294 } … … 596 297 psMetadataCopy(target->concepts, source->concepts); 597 298 598 return numCells; 599 299 return status; 600 300 } 601 301 … … 617 317 } 618 318 619 // Copy any headers 620 if (target->hdu && !target->hdu->phu) { 621 pmHDU *sourceHDU = pmHDUFromFPA(source); 622 target->hdu->header = psMetadataCopy(target->hdu->header, sourceHDU->header); 623 } 624 625 int numChips = 0; // Number of chips copied 319 bool status = true; // Status of copy 626 320 for (int i = 0; i < targetChips->n; i++) { 627 321 pmChip *targetChip = targetChips->data[i]; // The target chip … … 630 324 if (chipNum >= 0) { 631 325 pmChip *sourceChip = sourceChips->data[chipNum]; // The source chip 632 int numCells = chipCopy(targetChip, sourceChip, pixels, xBin, yBin); // Number of cells copied 633 psTrace(__func__, 5, "Copied %d cells for chip %s\n", numCells, chipName); 634 numChips++; 326 status &= chipCopy(targetChip, sourceChip, pixels, xBin, yBin); 635 327 } 636 328 } … … 639 331 psMetadataCopy(target->concepts, source->concepts); 640 332 641 return numChips;333 return status; 642 334 } 643 335 … … 645 337 // Public functions 646 338 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 647 648 339 649 340 int pmFPACopy(pmFPA *target, // The target FPA
Note:
See TracChangeset
for help on using the changeset viewer.
