IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Dec 13, 2005, 5:47:35 PM (21 years ago)
Author:
Paul Price
Message:

Upgrading for psLib-0.9.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/archive/scripts/src/phase2/pmChipMosaic.c

    r5621 r5786  
    11#include <stdio.h>
     2#include <assert.h>
    23
    34#include "pslib.h"
     
    1415    }
    1516
    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
     18psImage *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
    1824    )
    1925{
    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);
    2833
    2934    // Get the maximum extent of the mosaic image
     
    3237    int yMin = INT_MAX;
    3338    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
    5241
    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);
    5856    }
    5957
    6058    // Set up the image
    6159    // Since both upper and lower values are inclusive, we need to add one to the size
    62     float xSize = (float)(xMax - xMin + 1) / (float)xBinChip;
     60    float xSize = (float)(xMax - xMin + 1) / (float)xBinTarget;
    6361    if (xSize - (int)xSize > 0) {
    64         xSize += 1;
     62        xSize += 1;
    6563    }
    66     float ySize = (float)(yMax - yMin + 1) / (float)yBinChip;
     64    float ySize = (float)(yMax - yMin + 1) / (float)yBinTarget;
    6765    if (ySize - (int)ySize > 0) {
    68         ySize += 1;
     66        ySize += 1;
    6967    }
    7068
    71     psTrace(__func__, 3, "Mosaicked chip will be %dx%d\n", (int)xSize, (int)ySize);
     69    psTrace(__func__, 3, "Spliced image will be %dx%d\n", (int)xSize, (int)ySize);
    7270    psImage *mosaic = psImageAlloc((int)xSize, (int)ySize, PS_TYPE_F32); // The mosaic image
    7371    psImageInit(mosaic, 0.0);
    7472
    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
     108psImage *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
    76122    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        }
    85148
    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    }
    98161
    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);
    106164
    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
    116166    psFree(x0);
    117167    psFree(y0);
    118168    psFree(xBin);
    119169    psFree(yBin);
    120     psFree(xParity);
    121     psFree(yParity);
    122     psFree(trimsec);
     170    psFree(xFlip);
     171    psFree(yFlip);
     172    psFree(images);
    123173
    124174    return mosaic;
Note: See TracChangeset for help on using the changeset viewer.