Changeset 7168
- Timestamp:
- May 22, 2006, 2:23:08 PM (20 years ago)
- Location:
- trunk/psModules/src/camera
- Files:
-
- 2 added
- 8 edited
-
Makefile.am (modified) (2 diffs)
-
pmFPAConstruct.c (modified) (6 diffs)
-
pmFPACopy.c (modified) (13 diffs)
-
pmFPARead.c (modified) (7 diffs)
-
pmFPAWrite.c (modified) (7 diffs)
-
pmHDU.c (modified) (2 diffs)
-
pmHDUGenerate.c (added)
-
pmHDUGenerate.h (added)
-
pmHDUUtils.c (modified) (1 diff)
-
pmHDUUtils.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/camera/Makefile.am
r7017 r7168 13 13 pmHDU.c \ 14 14 pmHDUUtils.c \ 15 pmHDUGenerate.c \ 15 16 pmReadout.c \ 16 17 pmChipMosaic.c \ … … 33 34 pmHDU.h \ 34 35 pmHDUUtils.h \ 36 pmHDUGenerate.h \ 35 37 pmReadout.h \ 36 38 pmChipMosaic.h \ -
trunk/psModules/src/camera/pmFPAConstruct.c
r7017 r7168 10 10 #include "pmFPAview.h" 11 11 #include "pmFPAUtils.h" 12 #include "pmHDUUtils.h" 12 13 13 14 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// … … 690 691 psTrace(__func__, 1, "FPA:\n"); 691 692 if (fpa->hdu) { 692 psTrace(__func__, 2, "---> FPA is extension %s.\n", fpa->hdu->extname); 693 if (! fpa->hdu->images) { 694 psTrace(__func__, 2, "---> NO PIXELS read in for extension %s\n", fpa->hdu->extname); 695 } 696 if (header) { 697 if (fpa->hdu->header) { 698 psTrace(__func__, 2, "---> Header:\n"); 699 psMetadataPrint(fpa->hdu->header, 8); 700 } else { 701 psTrace(__func__, 2, "---> NO HEADER read in for extension %s\n", fpa->hdu->extname); 702 } 703 } 693 pmHDUPrint(fpa->hdu, 2, header); 704 694 } 705 695 if (concepts) { … … 713 703 pmChip *chip = chips->data[i]; // The chip 714 704 if (chip->hdu) { 715 psTrace(__func__, 4, "---> Chip is extension %s.\n", chip->hdu->extname); 716 if (header) { 717 if (chip->hdu->header) { 718 psTrace(__func__, 4, "---> Header:\n"); 719 psMetadataPrint(chip->hdu->header, 8); 720 } else { 721 psTrace(__func__, 4, "---> NO HEADER read in for extension %s\n", chip->hdu->extname); 722 } 723 } 724 if (! chip->hdu->images) { 725 psTrace(__func__, 4, "---> NO PIXELS read in for extension %s\n", chip->hdu->extname); 726 } 705 pmHDUPrint(chip->hdu, 4, header); 727 706 } 728 707 if (concepts) { … … 736 715 pmCell *cell = cells->data[j]; // The cell 737 716 if (cell->hdu) { 738 psTrace(__func__, 6, "---> Cell is extension %s.\n", cell->hdu->extname); 739 if (header) { 740 if (cell->hdu->header) { 741 psTrace(__func__, 6, "---> Header:\n"); 742 psMetadataPrint(cell->hdu->header, 8); 743 } else { 744 psTrace(__func__, 6, "---> NO HEADER read in for extension %s\n", cell->hdu->extname); 745 } 746 } 747 if (! cell->hdu->images) { 748 psTrace(__func__, 6, "---> NO PIXELS read in for extension %s\n", cell->hdu->extname); 749 } 717 pmHDUPrint(cell->hdu, 6, header); 750 718 } 751 719 if (concepts) { … … 753 721 } 754 722 755 psTrace(__func__, 7, "Readouts:\n");756 723 psArray *readouts = cell->readouts; // Array of readouts 757 724 for (int k = 0; k < readouts->n; k++) { 758 725 pmReadout *readout = readouts->data[k]; // The readout 759 psTrace(__func__, 8, "row0: %d\n", readout->row0); 726 psTrace(__func__, 6, "Readout %d:\n", k); 727 psTrace(__func__, 7, "row0: %d\n", readout->row0); 728 psTrace(__func__, 7, "col0: %d\n", readout->col0); 760 729 psImage *image = readout->image; // The image 761 730 psList *bias = readout->bias; // The list of bias images 762 731 if (image) { 763 psTrace(__func__, 8, "Image: [%d:%d,%d:%d] (%dx%d)\n", image->col0, image->col0 +732 psTrace(__func__, 7, "Image: [%d:%d,%d:%d] (%dx%d)\n", image->col0, image->col0 + 764 733 image->numCols, image->row0, image->row0 + image->numRows, image->numCols, 765 734 image->numRows); … … 769 738 psImage *biasImage = NULL; // Bias image from iteration 770 739 while ((biasImage = psListGetAndIncrement(biasIter))) { 771 psTrace(__func__, 8, "Bias: [%d:%d,%d:%d] (%dx%d)\n", biasImage->col0,740 psTrace(__func__, 7, "Bias: [%d:%d,%d:%d] (%dx%d)\n", biasImage->col0, 772 741 biasImage->col0 + biasImage->numCols, biasImage->row0, 773 742 biasImage->row0 + biasImage->numRows, biasImage->numCols, biasImage->numRows); -
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 -
trunk/psModules/src/camera/pmFPARead.c
r7017 r7168 5 5 6 6 #include "pmFPA.h" 7 #include "pmFPARead.h"8 7 #include "pmHDU.h" 9 8 #include "pmHDUUtils.h" … … 11 10 #include "psRegionIsBad.h" 12 11 #include "pmFPAHeader.h" 12 13 #include "pmFPARead.h" 13 14 14 15 #define MAX(x,y) ((x) > (y) ? (x) : (y)) … … 74 75 } 75 76 77 // Read a component of a readout 78 psImage *readoutReadComponent(psFits *fits, // FITS file from which to read 79 const psRegion *region, // Region to read 80 int readdir, // Read direction (1=rows, 2=cols) 81 int min, // Minimum row/col number to read 82 int max, // Maximum row/col number to read 83 int z, // Image plane to read 84 float bad // Bad value 85 ) 86 { 87 bool resize = false; // Do we need to resize the image once read? 88 psRegion toRead = psRegionSet(region->x0, region->x1, region->y0, region->y1); // Region to read 89 psRegion fullSize = toRead; // Full sized region 90 if (readdir == 1) { 91 if (toRead.y0 <= min) { 92 toRead.y0 = min; 93 } else { 94 fullSize.y0 = min; 95 resize = true; 96 } 97 if (toRead.y1 >= max) { 98 toRead.y1 = max; 99 } else { 100 fullSize.y1 = max; 101 resize = false; 102 } 103 } else if (readdir == 2) { 104 if (toRead.x0 <= min) { 105 toRead.x0 = min; 106 } else { 107 fullSize.x0 = min; 108 resize = true; 109 } 110 if (toRead.x1 >= max) { 111 toRead.x1 = max; 112 } else { 113 fullSize.x1 = max; 114 resize = false; 115 } 116 } else { 117 psAbort(__func__, "Read direction can only be 1 (rows) or 2 (cols).\n"); 118 } 119 120 psImage *image = psFitsReadImage(fits, toRead, z); // Desired pixels 121 122 if (resize) { 123 // For some reason, the region of interest is smaller than the number of pixels we want. 124 psImage *temp = psImageAlloc(fullSize.x1 - fullSize.x0, fullSize.y1 - fullSize.y0, image->type.type); 125 psImageInit(temp, bad); 126 psImageOverlaySection(temp, image, toRead.x0, toRead.y0, "="); 127 psFree(image); 128 image = temp; 129 } 130 131 return image; 132 } 133 76 134 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 77 135 // Public functions … … 79 137 80 138 // Read the next readout; return true if we read pixels in. 139 // 140 // Note that this doesn't put pixels in the HDU. It is therefore NOT COMPATIBLE with pmCellWrite, 141 // pmChipWrite, and pmFPAWrite. Use pmReadoutWriteNext to write the data that's read by this function. 81 142 bool pmReadoutReadNext(pmReadout *readout, // Readout into which to read 82 143 psFits *fits, // FITS file from which to read … … 98 159 99 160 // Make sure we have the information we need 100 pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER, false, NULL); 161 pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS, 162 false, NULL); 101 163 102 164 // Get the trim and bias sections … … 113 175 } 114 176 int readdir = psMetadataLookupS32(&mdok, cell->concepts, "CELL.READDIR"); // Read direction 115 if (!mdok || readdir == 0 || (readdir != -1 && readdir != 1)) {177 if (!mdok || readdir == 0 || (readdir != 1 && readdir != 2)) { 116 178 psError(PS_ERR_IO, true, "CELL.READDIR is not set to -1 or +1.\n"); 117 179 return false; 180 } 181 float bad = psMetadataLookupF32(&mdok, cell->concepts, "CELL.BAD"); // Bad level 182 if (!mdok) { 183 psLogMsg(__func__, PS_LOG_WARN, "CELL.BAD is not set --- assuming zero.\n"); 184 bad = 0.0; 118 185 } 119 186 … … 159 226 160 227 // Read the FITS image 161 int offset = readout->row0; // The row number to read228 int offset = 0; // The offset from the start of the image to where we are now 162 229 if (readout->image) { 163 if (readdir > 0) {230 if (readdir == 1) { 164 231 // Reading rows 165 offset += readout->image->numRows; 232 readout->row0 += readout->image->numRows; 233 offset = readout->row0; 166 234 } else { 167 235 // Reading columns 168 offset += readout->image->numCols; 169 } 170 } 171 if ((readdir > 0 && offset >= naxis2) || (readdir < 0 && offset > naxis1)) { 236 readout->col0 += readout->image->numCols; 237 offset = readout->col0; 238 } 239 } 240 if ((readdir == 1 && offset >= naxis2) || (readdir == 2 && offset > naxis1)) { 172 241 // We've read everything there is 173 242 return false; 174 243 } 175 244 int upper = offset + numScans; // The upper limit for the pixel read 176 if (readdir > 0&& upper > naxis2) {245 if (readdir == 1 && upper > naxis2) { 177 246 upper = naxis2; 178 } else if (readdir < 0&& upper > naxis1) {247 } else if (readdir == 2 && upper > naxis1) { 179 248 upper = naxis1; 180 249 } 181 psRegion region = {0, 0, 0, 0}; // Region to be read 182 if (readdir > 0) { 183 region = psRegionSet(0, naxis1, offset, upper); // Read rows 184 } else { 185 region = psRegionSet(offset, upper, 0, naxis2); // Read columns 186 } 187 psImage *image = psFitsReadImage(fits, region, z); // The image 188 189 // Stick the image into the HDU and the readout 190 if (!hdu->images) { 191 hdu->images = psArrayAlloc(naxis3); 192 hdu->images->n = naxis3; 193 } 194 if (hdu->images->nalloc != naxis3) { 195 hdu->images = psArrayRealloc(hdu->images, naxis3); 196 hdu->images->n = naxis3; 197 } 198 if (hdu->images->data[z]) { 199 psFree(hdu->images->data[z]); 200 } 201 hdu->images->data[z] = image; 202 readout->row0 = region.y0; 203 readout->col0 = region.x0; 204 readoutCarve(readout, image, trimsec, biassecs); 250 251 // Blow away existing data 252 psFree(readout->image); 253 while (readout->bias->n > 0) { 254 psListRemove(readout->bias, PS_LIST_HEAD); 255 } 256 257 // Get the new the trim section 258 readout->image = readoutReadComponent(fits, trimsec, readdir, offset, upper, z, bad); // The image 259 260 // Get the new bias sections 261 psListIterator *biassecsIter = psListIteratorAlloc(biassecs, PS_LIST_HEAD, false); // Iterator for BIASSEC 262 psRegion *biassec = NULL; // Bias section from iteration 263 while ((biassec = psListGetAndIncrement(biassecsIter))) { 264 psImage *bias = readoutReadComponent(fits, biassec, readdir, offset, upper, z, bad); // The bias 265 psListAdd(readout->bias, PS_LIST_TAIL, bias); 266 } 267 psFree(biassecsIter); 205 268 206 269 return true; -
trunk/psModules/src/camera/pmFPAWrite.c
r7097 r7168 6 6 #include "pmHDU.h" 7 7 #include "pmHDUUtils.h" 8 #include "pmHDUGenerate.h" 8 9 #include "pmConcepts.h" 9 10 11 #include "pmFPAWrite.h" 10 12 11 13 bool pmReadoutWriteNext(pmReadout *readout, // Readout to write … … 51 53 return false; 52 54 } 53 psImage *image = hdu->images->data[z]; // The image from the HDU to write55 psImage *image = readout->image; // The image from the HDU to write 54 56 if (readout->row0 == 0 && readout->col0 == 0 && z == 0) { 55 57 // Then we can assume that nothing has been written to the FITS file for now … … 68 70 69 71 // We can simply update an existing HDU 70 if (!psFitsMoveExtName(fits, hdu->extname)) { 72 if (((hdu->phu || strcasecmp(hdu->extname, "PHU") == 0) && !psFitsMoveExtNum(fits, 0, false)) || 73 !psFitsMoveExtName(fits, hdu->extname)) { 71 74 psError(PS_ERR_IO, false, "Unable to move to extension %s\n", hdu->extname); 72 75 return false; … … 86 89 pmHDU *hdu = cell->hdu; // The HDU 87 90 if (hdu && ((!pixels && hdu->phu) || pixels)) { 91 if (pixels && !hdu->images && !pmHDUGenerateForCell(cell)) { 92 psError(PS_ERR_IO, false, "Unable to generate HDU for cell.\n"); 93 return false; 94 } 88 95 bool status = pmConceptsWriteCell(cell, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA | 89 96 PM_CONCEPT_SOURCE_DEFAULTS, false, NULL); … … 107 114 pmHDU *hdu = chip->hdu; // The HDU 108 115 if (hdu && ((!pixels && hdu->phu) || pixels)) { 116 if (pixels && !hdu->images && !pmHDUGenerateForChip(chip)) { 117 psError(PS_ERR_IO, false, "Unable to generate HDU for chip.\n"); 118 return false; 119 } 109 120 bool status = pmConceptsWriteChip(chip, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA | 110 121 PM_CONCEPT_SOURCE_DEFAULTS, false, NULL); … … 130 141 131 142 132 133 143 bool pmFPAWrite(pmFPA *fpa, // FPA to write 134 144 psFits *fits, // FITS file to which to write … … 139 149 pmHDU *hdu = fpa->hdu; // The HDU 140 150 if (hdu && ((!pixels && hdu->phu) || pixels)) { 151 if (pixels && !hdu->images && !pmHDUGenerateForFPA(fpa)) { 152 psError(PS_ERR_IO, false, "Unable to generate HDU for FPA.\n"); 153 return false; 154 } 141 155 bool status = pmConceptsWriteFPA(fpa, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA | 142 156 PM_CONCEPT_SOURCE_DEFAULTS, NULL); -
trunk/psModules/src/camera/pmHDU.c
r7017 r7168 187 187 // Only a header 188 188 if (!hdu->images && !hdu->table) { 189 #if 0 189 190 // Tell CFITSIO there's nothing there 190 191 psMetadataItem *naxis = psMetadataLookup(hdu->header, "NAXIS"); … … 192 193 naxis->data.S32 = 0; 193 194 } 195 #endif 194 196 195 197 if (!psFitsWriteHeader(hdu->header, fits)) { -
trunk/psModules/src/camera/pmHDUUtils.c
r7017 r7168 59 59 } 60 60 61 void pmHDUPrint(pmHDU *hdu, // HDU to print 62 int level, // Level at which to print 63 bool header // Print header? 64 ) 65 { 66 if (hdu->phu) { 67 psTrace(__func__, level, "HDU: %s (PHU)\n", hdu->extname); 68 } else { 69 psTrace(__func__, level, "HDU: %s\n", hdu->extname); 70 } 71 72 psTrace(__func__, level + 1, "Format: %x\n", hdu->format); 73 if (header) { 74 if (hdu->header) { 75 psTrace(__func__, level + 1, "Header:\n"); 76 psMetadataPrint(hdu->header, level + 2); 77 } else { 78 psTrace(__func__, level + 1, "No header.\n"); 79 } 80 } 81 82 if (hdu->images) { 83 psTrace(__func__, level + 1, "Images:\n"); 84 for (long i = 0; i < hdu->images->n; i++) { 85 psImage *image = hdu->images->data[i]; // Image of interest 86 psTrace(__func__, level + 2, "%ld: %dx%d\n", i, image->numCols, image->numRows); 87 } 88 } else { 89 psTrace(__func__, level + 1, "NO images.\n"); 90 } 91 92 if (hdu->masks) { 93 psTrace(__func__, level + 1, "Masks:\n"); 94 for (long i = 0; i < hdu->masks->n; i++) { 95 psImage *mask = hdu->masks->data[i]; // Mask of interest 96 psTrace(__func__, level + 2, "%ld: %dx%d\n", i, mask->numCols, mask->numRows); 97 } 98 } else { 99 psTrace(__func__, level + 1, "NO masks.\n"); 100 } 101 102 103 if (hdu->weights) { 104 psTrace(__func__, level + 1, "Weights:\n"); 105 for (long i = 0; i < hdu->masks->n; i++) { 106 psImage *weight = hdu->weights->data[i]; // Weight image of interest 107 psTrace(__func__, level + 2, "%ld: %dx%d\n", i, weight->numCols, weight->numRows); 108 } 109 } else { 110 psTrace(__func__, level + 1, "NO weights.\n"); 111 } 112 113 114 return; 115 } -
trunk/psModules/src/camera/pmHDUUtils.h
r7017 r7168 22 22 ); 23 23 24 // Print details about an HDU 25 void pmHDUPrint(pmHDU *hdu, // HDU to print 26 int level, // Level at which to print 27 bool header // Print header? 28 ); 29 24 30 #endif
Note:
See TracChangeset
for help on using the changeset viewer.
