Changeset 5786 for trunk/archive/scripts/src/phase2/pmChipMosaic.c
- Timestamp:
- Dec 13, 2005, 5:47:35 PM (21 years ago)
- File:
-
- 1 edited
-
trunk/archive/scripts/src/phase2/pmChipMosaic.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/archive/scripts/src/phase2/pmChipMosaic.c
r5621 r5786 1 1 #include <stdio.h> 2 #include <assert.h> 2 3 3 4 #include "pslib.h" … … 14 15 } 15 16 16 psImage *pmChipMosaic(pmChip *chip, // Chip to mosaic 17 int xBinChip, int yBinChip // Binning of mosaic image in x and y 17 // Mosaic multiple images, with flips, binning and offsets 18 psImage *p_pmImageMosaic(const psArray *source, // Images to splice in 19 const psVector *xFlip, const psVector *yFlip, // Need to flip x and y? 20 const psVector *xBinSource, const psVector *yBinSource, // Binning in x and y of 21 // source images 22 int xBinTarget, int yBinTarget, // Binning in x and y of target images 23 const psVector *x0, const psVector *y0 // Offsets for source images on target 18 24 ) 19 25 { 20 psArray *cells = chip->cells; // The array of cells 21 psVector *x0 = psVectorAlloc(cells->n, PS_TYPE_S32); // Origin x coordinates 22 psVector *y0 = psVectorAlloc(cells->n, PS_TYPE_S32); // Origin y coordinates 23 psVector *xBin = psVectorAlloc(cells->n, PS_TYPE_S32); // Binning in x 24 psVector *yBin = psVectorAlloc(cells->n, PS_TYPE_S32); // Binning in y 25 psVector *xParity = psVectorAlloc(cells->n, PS_TYPE_S32); // Parity in x 26 psVector *yParity = psVectorAlloc(cells->n, PS_TYPE_S32); // Parity in y 27 psArray *trimsec = psArrayAlloc(cells->n); // Trim section 26 assert(source); 27 assert(xFlip && xFlip->type.type == PS_TYPE_U8); 28 assert(yFlip && yFlip->type.type == PS_TYPE_U8); 29 assert(xBinSource && xBinSource->type.type == PS_TYPE_S32); 30 assert(yBinSource && yBinSource->type.type == PS_TYPE_S32); 31 assert(x0 && x0->type.type == PS_TYPE_S32); 32 assert(y0 && y0->type.type == PS_TYPE_S32); 28 33 29 34 // Get the maximum extent of the mosaic image … … 32 37 int yMin = INT_MAX; 33 38 int yMax = 0; 34 for (int i = 0; i < cells->n; i++) { 35 pmCell *cell = cells->data[i]; // The cell of interest 36 x0->data.S32[i] = psMetadataLookupS32(NULL, cell->concepts, "CELL.X0"); 37 y0->data.S32[i] = psMetadataLookupS32(NULL, cell->concepts, "CELL.Y0"); 38 xBin->data.S32[i] = psMetadataLookupS32(NULL, cell->concepts, "CELL.XBIN"); 39 yBin->data.S32[i] = psMetadataLookupS32(NULL, cell->concepts, "CELL.XBIN"); 40 xParity->data.S32[i] = psMetadataLookupS32(NULL, cell->concepts, "CELL.XPARITY"); 41 yParity->data.S32[i] = psMetadataLookupS32(NULL, cell->concepts, "CELL.YPARITY"); 42 trimsec->data[i] = psMemIncrRefCounter(psMetadataLookupPtr(NULL, cell->concepts, "CELL.TRIMSEC")); 43 psTrace(__func__, 7, "Cell %d trimsec: [%.0f:%.0f,%.0f:%.0f]\n", i, ((psRegion*)trimsec->data[i])->x0, 44 ((psRegion*)trimsec->data[i])->x1, ((psRegion*)trimsec->data[i])->y0, 45 ((psRegion*)trimsec->data[i])->y1); 46 // Size of cell in x and y 47 int nx = (int)(((psRegion*)trimsec->data[i])->x1 - (int)((psRegion*)trimsec->data[i])->x0); 48 int ny = (int)(((psRegion*)trimsec->data[i])->y1 - (int)((psRegion*)trimsec->data[i])->y0); 49 psTrace(__func__, 5, "Extent of cell %d: %d -> %d , %d -> %d\n", i, x0->data.S32[i], 50 x0->data.S32[i] + xParity->data.S32[i] * xBin->data.S32[i] * nx, y0->data.S32[i], 51 y0->data.S32[i] + yParity->data.S32[i] * yBin->data.S32[i] * ny); 39 for (int i = 0; i < source->n; i++) { 40 psImage *image = source->data[i]; // The image of interest 52 41 53 COMPARE(x0->data.S32[i], xMin, xMax); 54 COMPARE(y0->data.S32[i], yMin, yMax); 55 // Subtract the parity to get the inclusive limit (not exclusive) 56 COMPARE(x0->data.S32[i] + xParity->data.S32[i] * xBin->data.S32[i] * nx - xParity->data.S32[i], xMin, xMax); 57 COMPARE(y0->data.S32[i] + yParity->data.S32[i] * yBin->data.S32[i] * ny - yParity->data.S32[i], yMin, yMax); 42 assert(image->type.type == PS_TYPE_F32); // Only implemented for F32 images so far. 43 44 // Size of cell in x and y 45 int xParity = xFlip->data.U8[i] ? -1 : 1; 46 int yParity = yFlip->data.U8[i] ? -1 : 1; 47 psTrace(__func__, 5, "Extent of cell %d: %d -> %d , %d -> %d\n", i, x0->data.S32[i], 48 x0->data.S32[i] + xParity * xBinSource->data.S32[i] * image->numCols, y0->data.S32[i], 49 y0->data.S32[i] + yParity * yBinSource->data.S32[i] * image->numRows); 50 51 COMPARE(x0->data.S32[i], xMin, xMax); 52 COMPARE(y0->data.S32[i], yMin, yMax); 53 // Subtract the parity to get the inclusive limit (not exclusive) 54 COMPARE(x0->data.S32[i] + xParity * xBinSource->data.S32[i] * image->numCols - xParity, xMin, xMax); 55 COMPARE(y0->data.S32[i] + yParity * yBinSource->data.S32[i] * image->numRows - yParity, yMin, yMax); 58 56 } 59 57 60 58 // Set up the image 61 59 // Since both upper and lower values are inclusive, we need to add one to the size 62 float xSize = (float)(xMax - xMin + 1) / (float)xBin Chip;60 float xSize = (float)(xMax - xMin + 1) / (float)xBinTarget; 63 61 if (xSize - (int)xSize > 0) { 64 xSize += 1;62 xSize += 1; 65 63 } 66 float ySize = (float)(yMax - yMin + 1) / (float)yBin Chip;64 float ySize = (float)(yMax - yMin + 1) / (float)yBinTarget; 67 65 if (ySize - (int)ySize > 0) { 68 ySize += 1;66 ySize += 1; 69 67 } 70 68 71 psTrace(__func__, 3, " Mosaicked chipwill be %dx%d\n", (int)xSize, (int)ySize);69 psTrace(__func__, 3, "Spliced image will be %dx%d\n", (int)xSize, (int)ySize); 72 70 psImage *mosaic = psImageAlloc((int)xSize, (int)ySize, PS_TYPE_F32); // The mosaic image 73 71 psImageInit(mosaic, 0.0); 74 72 75 // Set the image 73 // Next pass through the images to do the mosaicking 74 for (int i = 0; i < source->n; i++) { 75 psImage *image = source->data[i]; // The image of interest 76 if (xBinSource->data.S32[i] == xBinTarget && yBinSource->data.S32[i] == yBinTarget && 77 xFlip->data.U8[i] == 0 && yFlip->data.U8[i] == 0) { 78 // Let someone else do the hard work; useful to test psImageOverlaySection if no other reason 79 psImageOverlaySection(mosaic, image, x0->data.S32[i], y0->data.S32[i], "+"); 80 } else { 81 // We have to do the hard work ourself 82 for (int y = 0; y < image->numRows; y++) { 83 int yParity = yFlip->data.U8[i] ? -1 : 1; 84 float yTargetBase = (y0->data.S32[i] + yParity * yBinSource->data.S32[i] * y) / yBinTarget; 85 for (int x = 0; x < image->numCols; x++) { 86 int xParity = xFlip->data.U8[i] ? -1 : 1; 87 float xTargetBase = (x0->data.S32[i] + xParity * xBinSource->data.S32[i] * x) / 88 xBinTarget; 89 90 // In case the original image is binned but the mosaic is not, we need to fill in the 91 // values in the mosaic. 92 for (int j = 0; j < yBinSource->data.S32[i]; j++) { 93 int yTarget = (int)(yTargetBase + yParity * (float)j / (float)yBinTarget); 94 for (int i = 0; i < xBinSource->data.S32[i]; i++) { 95 int xTarget = (int)(xTargetBase + xParity * (float)i / (float)xBinTarget); 96 97 mosaic->data.F32[yTarget][xTarget] += image->data.F32[y][x]; 98 } 99 } // Iterating over mosaic image for binned input image 100 } 101 } // Iterating over input image 102 } 103 } 104 105 return mosaic; 106 } 107 108 psImage *pmChipMosaic(pmChip *chip, // Chip to mosaic 109 int xBinChip, int yBinChip // Binning of mosaic image in x and y 110 ) 111 { 112 psArray *cells = chip->cells; // The array of cells 113 psArray *images = psArrayAlloc(cells->n); // Array of images that will be mosaicked 114 psVector *x0 = psVectorAlloc(cells->n, PS_TYPE_S32); // Origin x coordinates 115 psVector *y0 = psVectorAlloc(cells->n, PS_TYPE_S32); // Origin y coordinates 116 psVector *xBin = psVectorAlloc(cells->n, PS_TYPE_S32); // Binning in x 117 psVector *yBin = psVectorAlloc(cells->n, PS_TYPE_S32); // Binning in y 118 psVector *xFlip = psVectorAlloc(cells->n, PS_TYPE_U8); // Flip in x? 119 psVector *yFlip = psVectorAlloc(cells->n, PS_TYPE_U8); // Flip in y? 120 121 // Set up the required inputs 76 122 for (int i = 0; i < cells->n; i++) { 77 pmCell *cell = cells->data[i]; // The cell of interest 78 psArray *readouts = cell->readouts; // The array of readouts 79 if (readouts->n > 1) { 80 psLogMsg(__func__, PS_LOG_WARN, "Cell %d contains more than one readout --- only the first will " 81 "be mosaicked.\n", i); 82 } 83 psImage *image = ((pmReadout*)readouts->data[0])->image; // The image to put into the mosaic 84 psImage *trimmed = psImageSubset(image, *(psRegion*)(trimsec->data[i])); // Trimmed image (no overscan) 123 pmCell *cell = cells->data[i]; // The cell of interest 124 x0->data.S32[i] = psMetadataLookupS32(NULL, cell->concepts, "CELL.X0"); 125 y0->data.S32[i] = psMetadataLookupS32(NULL, cell->concepts, "CELL.Y0"); 126 xBin->data.S32[i] = psMetadataLookupS32(NULL, cell->concepts, "CELL.XBIN"); 127 yBin->data.S32[i] = psMetadataLookupS32(NULL, cell->concepts, "CELL.XBIN"); 128 int xParity = psMetadataLookupS32(NULL, cell->concepts, "CELL.XPARITY"); 129 int yParity = psMetadataLookupS32(NULL, cell->concepts, "CELL.YPARITY"); 130 if (xParity == 1) { 131 xFlip->data.U8[i] = 0; 132 } else if (xParity == -1) { 133 xFlip->data.U8[i] = 1; 134 } else { 135 psLogMsg(__func__, PS_LOG_WARN, "The x parity of cell %d is not +/- 1 (it's %d) --- " 136 "assuming +1.\n", i, xParity); 137 xFlip->data.U8[i] = 0; 138 } 139 if (yParity == 1) { 140 yFlip->data.U8[i] = 0; 141 } else if (yParity == -1) { 142 yFlip->data.U8[i] = 1; 143 } else { 144 psLogMsg(__func__, PS_LOG_WARN, "The y parity of cell %d is not +/- 1 (it's %d) --- " 145 "assuming +1.\n", i, yParity); 146 yFlip->data.U8[i] = 0; 147 } 85 148 86 if (xBin->data.S32[i] == xBinChip && yBin->data.S32[i] == yBinChip && xParity->data.S32[i] == 1 && 87 yParity->data.S32[i] == 1) { 88 // Let someone else do the hard work; useful to test psImageOverlaySection if no other reason 89 psImageOverlaySection(mosaic, trimmed, x0->data.S32[i], y0->data.S32[i], "+");90 } else { 91 // We have to do the hard work ourself 92 for (int y = 0; y < trimmed->numRows; y++) { 93 float yTargetBase = (y0->data.S32[i] + yParity->data.S32[i] * yBin->data.S32[i] * y) / 94 yBinChip; 95 for (int x = 0; x < trimmed->numCols; x++) { 96 float xTargetBase = (x0->data.S32[i] + xParity->data.S32[i] * xBin->data.S32[i] * x) / 97 xBinChip; 149 // Trim the image to get rid of the overscan 150 psRegion *trimsec = psMetadataLookupPtr(NULL, cell->concepts, "CELL.TRIMSEC"); 151 psTrace(__func__, 7, "Cell %d trimsec: [%.0f:%.0f,%.0f:%.0f]\n", i, trimsec->x0, trimsec->x1, 152 trimsec->y0, trimsec->y1); 153 psArray *readouts = cell->readouts; // The array of readouts 154 if (readouts->n > 1) { 155 psLogMsg(__func__, PS_LOG_WARN, "Cell %d contains more than one readout --- only the first will " 156 "be mosaicked.\n", i); 157 } 158 psImage *image = ((pmReadout*)readouts->data[0])->image; // The image to put into the mosaic 159 images->data[i] = psImageSubset(image, *trimsec); // Trimmed image 160 } 98 161 99 // In case the original image is binned but the mosaic is not, we need to fill in the 100 // values in the mosaic. 101 for (int j = 0; j < yBin->data.S32[i]; j++) { 102 int yTarget = (int)(yTargetBase + yParity->data.S32[i] * (float)j / (float)yBinChip); 103 for (int i = 0; i < xBin->data.S32[i]; i++) { 104 int xTarget = (int)(xTargetBase + 105 xParity->data.S32[i] * (float)i / (float)xBinChip); 162 // Mosaic the images together and we're done 163 psImage *mosaic = p_pmImageMosaic(images, xFlip, yFlip, xBin, yBin, xBinChip, yBinChip, x0, y0); 106 164 107 mosaic->data.F32[yTarget][xTarget] += trimmed->data.F32[y][x]; 108 } 109 } // Iterating over mosaic image for binned input image 110 } 111 } // Iterating over input image 112 } 113 psFree(trimmed); 114 } // Iterating over cells 115 165 // Clean up 116 166 psFree(x0); 117 167 psFree(y0); 118 168 psFree(xBin); 119 169 psFree(yBin); 120 psFree(x Parity);121 psFree(y Parity);122 psFree( trimsec);170 psFree(xFlip); 171 psFree(yFlip); 172 psFree(images); 123 173 124 174 return mosaic;
Note:
See TracChangeset
for help on using the changeset viewer.
