IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 26, 2007, 4:44:42 PM (19 years ago)
Author:
magnier
Message:

converted binning operations to use the common pmImageBinning methods

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/camera/pmFPACopy.c

    r12564 r12589  
    1717
    1818//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    19 // File-static functions
    20 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    21 
    22 // Bin a region down by specified factors in x and y
    23 static void binRegion(psRegion *region, // Region to be binned
    24                       int xBin, int yBin // Binning in x and y
    25                      )
    26 {
    27     assert(region);
    28     assert(xBin > 0);
    29     assert(yBin > 0);
    30 
    31     // Want to include the lower bound: 1 binned by 4 --> 0; 3 binned by 4 --> 0; 4 binned by 4 --> 1
    32     region->x0 = (int)(region->x0 / xBin);
    33     region->y0 = (int)(region->y0 / yBin);
    34     // Want to exclude the upper bound: 4 binned by 4 --> 1; 5 binned by 4 --> 2; 7 binned by 4 --> 2
    35     region->x1 = (int)((region->x1 + xBin - 1) / xBin);
    36     region->y1 = (int)((region->y1 + yBin - 1) / yBin);
    37 }
    38 
    39 #if 1
     19// File-static functions and macros
     20//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     21
     22// Copy the value for a concept
     23#define COPY_CONCEPT(TARGET, SOURCE, NAME, TYPE) { \
     24    psMetadataItem *targetItem = psMetadataLookup(TARGET, NAME); \
     25    psMetadataItem *sourceItem = psMetadataLookup(SOURCE, NAME); \
     26    targetItem->data.TYPE = sourceItem->data.TYPE; }
     27
    4028// Find the blank (image-less) PHU, given a cell.
    4129static pmHDU *findBlankPHU(const pmCell *cell // The cell for which to find the PHU
     
    5846    return NULL;
    5947}
    60 #endif
     48
     49// copy one of the psImage components of the readout
     50static void readoutCopyComponent (psImage **target, psImage *source, psImageBinning *binning, bool xFlip, bool yFlip, bool pixels) {
     51
     52    if (!source) return;
     53
     54    if (*target) {
     55        psFree(*target);
     56    }
     57    if (pixels) {
     58        *target = psImageFlip(NULL, source, xFlip, yFlip);
     59        return;
     60    }
     61
     62    // I have the fine image size, I know the binning factor, determine the ruff image size
     63    binning->nXfine = source->numCols;
     64    binning->nYfine = source->numRows;
     65    psImageBinningSetRuffSize(binning, PS_IMAGE_BINNING_CENTER);
     66    *target = psImageAlloc(binning->nXruff, binning->nYruff, source->type.type);
     67    return;
     68}
    6169
    6270//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     
    7785    assert(xBin > 0 && yBin > 0);
    7886
     87    // XXX this is a programming / config error
     88    if (pixels && (xBin != 1 || yBin != 1)) {
     89        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unable to copy pixels if binning is set\n");
     90        return false;
     91    }
     92
     93    // the binning structure carries the information no how to rebin the images if needed
     94    psImageBinning *binning = psImageBinningAlloc();
     95    binning->nXbin = xBin;
     96    binning->nYbin = yBin;
     97
    7998    psArray *sourceReadouts = source->readouts; // The source readouts
    8099    int numReadouts = sourceReadouts->n; // Number of readouts copied
    81100
    82     // Copy the value for a concept
    83     #define COPY_CONCEPT(TARGET, SOURCE, NAME, TYPE) \
    84     psMetadataItem *targetItem = psMetadataLookup(TARGET, NAME); \
    85     psMetadataItem *sourceItem = psMetadataLookup(SOURCE, NAME); \
    86     targetItem->data.TYPE = sourceItem->data.TYPE;
    87 
    88101    // Need to check/change CELL.XPARITY and CELL.YPARITY
    89     bool mdok = true;                   // Status of MD lookup
     102    bool mdokS = true;                   // Status of MD lookup
     103    bool mdokT = true;                   // Status of MD lookup
    90104    bool xFlip = false;                 // Switch parity in x?
    91105    bool yFlip = false;                 // Switch parity in y?
    92     {
    93         int xParityTarget = psMetadataLookupS32(&mdok, target->concepts, "CELL.XPARITY"); // Target x parity
    94         if (mdok && (xParityTarget == 1 || xParityTarget == -1))
    95         {
    96             int xParitySource = psMetadataLookupS32(&mdok, source->concepts, "CELL.XPARITY"); // Source parity
    97             if (mdok && (xParitySource == 1 || xParitySource == -1) && xParityTarget != xParitySource) {
    98                 xFlip = true;
    99             }
    100         } else
    101         {
    102             // Use the source parity
    103             COPY_CONCEPT(target->concepts, source->concepts, "CELL.XPARITY", S32);
    104         }
    105         int yParityTarget = psMetadataLookupS32(&mdok, target->concepts, "CELL.YPARITY"); // Target y parity
    106         if (mdok && (yParityTarget == 1 || yParityTarget == -1))
    107         {
    108             int yParitySource = psMetadataLookupS32(&mdok, source->concepts, "CELL.YPARITY"); // Source parity
    109             if (mdok && (yParitySource == 1 || yParitySource == -1) && yParityTarget != yParitySource) {
    110                 yFlip = true;
    111             }
    112         } else
    113         {
    114             // Use the source parity
    115             COPY_CONCEPT(target->concepts, source->concepts, "CELL.YPARITY", S32);
    116         }
    117         psTrace("psModules.camera", 3, "xFlip: %d; yFlip: %d\n", xFlip, yFlip);
    118     }
    119 
    120     if (pixels && (xBin != 1 || yBin != 1)) {
    121         psLogMsg(__func__, PS_LOG_WARN, "Unable to copy pixels if binning is set --- copy turned off.\n");
    122         pixels = false;
    123     }
     106
     107    // enforce the following conditions:
     108    // CELL.XPARITY is required
     109    // CELL.XPARITY must be +/- 1
     110    int xParitySource = psMetadataLookupS32(&mdokS, source->concepts, "CELL.XPARITY"); // Source parity
     111    int xParityTarget = psMetadataLookupS32(&mdokT, target->concepts, "CELL.XPARITY"); // Target x parity
     112    assert (mdokS && mdokT);
     113    assert (abs(xParitySource) == 1);
     114    assert (abs(xParityTarget) == 1);
     115    if (xParityTarget != xParitySource) {
     116        xFlip = true;
     117    } else {
     118        // Use the source parity
     119        COPY_CONCEPT(target->concepts, source->concepts, "CELL.XPARITY", S32);
     120    }
     121
     122    int yParityTarget = psMetadataLookupS32(&mdokT, target->concepts, "CELL.YPARITY"); // Target y parity
     123    int yParitySource = psMetadataLookupS32(&mdokS, source->concepts, "CELL.YPARITY"); // Source parity
     124    assert (mdokS && mdokT);
     125    assert (abs(yParitySource) == 1);
     126    assert (abs(yParityTarget) == 1);
     127    if (yParityTarget != yParitySource) {
     128        yFlip = true;
     129    } else {
     130        // Use the source parity
     131        COPY_CONCEPT(target->concepts, source->concepts, "CELL.YPARITY", S32);
     132    }
     133    psTrace("psModules.camera", 3, "xFlip: %d; yFlip: %d\n", xFlip, yFlip);
    124134
    125135    // Perform deep copy of the images.  I would prefer *not* to do a deep copy, in the interests of speed (we
     
    132142
    133143        // Copy attributes
     144        // XXX is this correct under binning?
    134145        targetReadout->col0 = sourceReadout->col0;
    135146        targetReadout->row0 = sourceReadout->row0;
     
    138149        targetReadout->data_exists = sourceReadout->data_exists;
    139150
    140         // Copy image
    141         if (sourceReadout->image) {
    142             if (targetReadout->image) {
    143                 psFree(targetReadout->image);
    144             }
    145             if (pixels) {
    146                 targetReadout->image = psImageFlip(NULL, sourceReadout->image, xFlip, yFlip);
    147             } else {
    148                 psImage *image = sourceReadout->image; // The source image
    149                 long binnedCols = (image->numCols + xBin - 1) / xBin;
    150                 long binnedRows = (image->numRows + yBin - 1) / yBin;
    151                 targetReadout->image = psImageAlloc(binnedCols, binnedRows, image->type.type);
    152             }
    153         }
    154 
    155         // Copy mask
    156         if (sourceReadout->mask) {
    157             if (targetReadout->mask) {
    158                 psFree(targetReadout->mask);
    159             }
    160             if (pixels) {
    161                 targetReadout->mask = psImageFlip(NULL, sourceReadout->mask, xFlip, yFlip);
    162             } else {
    163                 psImage *mask = sourceReadout->mask; // The source mask image
    164                 long binnedCols = (mask->numCols + xBin - 1) / xBin;
    165                 long binnedRows = (mask->numRows + yBin - 1) / yBin;
    166                 targetReadout->mask = psImageAlloc(binnedCols, binnedRows, mask->type.type);
    167             }
    168         }
    169 
    170         // Copy weight
    171         if (sourceReadout->weight) {
    172             if (targetReadout->weight) {
    173                 psFree(targetReadout->weight);
    174             }
    175             if (pixels) {
    176                 targetReadout->weight = psImageFlip(NULL, sourceReadout->weight, xFlip, yFlip);
    177             } else {
    178                 psImage *weight = sourceReadout->weight; // The source weight image
    179                 long binnedCols = (weight->numCols + xBin - 1) / xBin;
    180                 long binnedRows = (weight->numRows + yBin - 1) / yBin;
    181                 targetReadout->weight = psImageAlloc(binnedCols, binnedRows, weight->type.type);
    182             }
    183         }
     151        // Copy all three image components (image, mask, weight)
     152        readoutCopyComponent (&targetReadout->image,  sourceReadout->image,  binning, xFlip, yFlip, pixels);
     153        readoutCopyComponent (&targetReadout->mask,   sourceReadout->mask,   binning, xFlip, yFlip, pixels);
     154        readoutCopyComponent (&targetReadout->weight, sourceReadout->weight, binning, xFlip, yFlip, pixels);
    184155
    185156        // Copy bias
     
    187158            psListRemove(targetReadout->bias, PS_LIST_HEAD);
    188159        }
     160
    189161        // Iterate over the biases
    190162        psListIterator *biasIter = psListIteratorAlloc(sourceReadout->bias, PS_LIST_HEAD, false);
    191163        psImage *bias = NULL;           // Bias image from iteration
    192164        while ((bias = psListGetAndIncrement(biasIter))) {
    193             psImage *biasCopy;          // Copy of the bias
    194             if (pixels) {
    195                 biasCopy = psImageFlip(NULL, bias, xFlip, yFlip);
    196             } else {
    197                 long binnedCols = (bias->numCols + xBin - 1) / xBin;
    198                 long binnedRows = (bias->numRows + yBin - 1) / yBin;
    199                 biasCopy = psImageAlloc(binnedCols, binnedRows, bias->type.type);
    200             }
     165            psImage *biasCopy = NULL;          // Copy of the bias
     166            readoutCopyComponent (&biasCopy, bias, binning, xFlip, yFlip, pixels);
    201167            psListAdd(targetReadout->bias, PS_LIST_TAIL, biasCopy);
    202168            psFree(biasCopy);           // Drop reference
     
    216182    while ((conceptItem = psMetadataGetAndIncrement(conceptsIter))) {
    217183        psString name = conceptItem->name; // Name of concept
    218         if (strcmp(name, "CELL.TRIMSEC") != 0 && strcmp(name, "CELL.BIASSEC") != 0 &&
    219                 strcmp(name, "CELL.XPARITY") != 0 && strcmp(name, "CELL.YPARITY") != 0 &&
    220                 strcmp(name, "CELL.X0") != 0 && strcmp(name, "CELL.Y0") != 0) {
    221             psMetadataItem *copy = psMetadataItemCopy(conceptItem); // Copy of the concept
    222             psMetadataAddItem(target->concepts, copy, PS_LIST_TAIL, PS_META_REPLACE);
    223             psFree(copy);               // Drop reference
    224         }
     184        if (!strcmp(name, "CELL.TRIMSEC")) continue;
     185        if (!strcmp(name, "CELL.BIASSEC")) continue;
     186        if (!strcmp(name, "CELL.XPARITY")) continue;
     187        if (!strcmp(name, "CELL.YPARITY")) continue;
     188        if (!strcmp(name, "CELL.X0")) continue;
     189        if (!strcmp(name, "CELL.Y0")) continue;
     190
     191        psMetadataItem *copy = psMetadataItemCopy(conceptItem); // Copy of the concept
     192        psMetadataAddItem(target->concepts, copy, PS_LIST_TAIL, PS_META_REPLACE);
     193        psFree(copy);               // Drop reference
    225194    }
    226195    psFree(conceptsIter);
    227196
    228197    // Need to update CELL.TRIMSEC and CELL.BIASSEC if we changed the binning and they exist already.
    229     if (xBin != 1 || yBin != 1) {
     198    // XXX this code seems to be very similar to pmConceptsUpdate
     199    if ((binning->nXbin != 1) || (binning->nYbin != 1)) {
     200        bool mdok = false;
    230201        psRegion *trimsec = psMetadataLookupPtr(&mdok, target->concepts, "CELL.TRIMSEC"); // The trim section
    231202        if (mdok && trimsec && !psRegionIsNaN(*trimsec)) {
    232             binRegion(trimsec, xBin, yBin);
     203            *trimsec = psImageBinningSetRuffRegion(binning, *trimsec);
    233204        }
    234205        psList *biassecs = psMetadataLookupPtr(&mdok, target->concepts, "CELL.BIASSEC"); // The bias sections
     
    238209            while ((biassec = psListGetAndIncrement(biassecsIter))) {
    239210                if (!psRegionIsNaN(*biassec)) {
    240                     binRegion(biassec, xBin, yBin);
     211                    *biassec = psImageBinningSetRuffRegion(binning, *biassec);
    241212                }
    242213            }
     
    246217
    247218    // Need to update CELL.X0 and CELL.Y0 if we flipped
     219    // XXX this section should probably use a common function consistent with psImageBinning
    248220    if (xFlip) {
    249221        int xZero = psMetadataLookupS32(NULL, source->concepts, "CELL.X0"); // CELL.X0 from source
     
    254226        if (sourceBin == 0) {
    255227            // Don't know the binning; assume it is unity
    256             sourceBin = xBin;
    257         }
    258 
    259         psTrace("psModules.camera", 3, "CELL.X0: Before: %d After: %d\n", xZero,
    260                 xZero + (xSize - 1) * xParity * sourceBin);
     228            sourceBin = binning->nXbin;
     229        }
     230
     231        // XXX make sure this is consistent with the psImageBinning
     232        psTrace("psModules.camera", 3, "CELL.X0: Before: %d After: %d\n", xZero, xZero + (xSize - 1) * xParity * sourceBin);
    261233        psTrace("psModules.camera", 9, "(xParity: %d xBin: %d numCols: %d)\n", xParity, sourceBin, xSize);
    262234
     
    277249        if (sourceBin == 0) {
    278250            // Don't know the binning; assume it is unity
    279             sourceBin = yBin;
    280         }
    281 
    282         psTrace("psModules.camera", 3, "CELL.Y0: Before: %d After: %d\n", yZero,
    283                 yZero + (ySize - 1) * yParity * sourceBin);
     251            sourceBin = binning->nYbin;
     252        }
     253
     254        psTrace("psModules.camera", 3, "CELL.Y0: Before: %d After: %d\n", yZero, yZero + (ySize - 1) * yParity * sourceBin);
    284255        psTrace("psModules.camera", 9, "(yParity: %d yBin: %d numRows: %d)\n", yParity, sourceBin, ySize);
    285256
     
    295266
    296267    // Update the binning concepts
     268    // XXX this should probably be done with a common function using psImageBinning
    297269    psMetadataItem *binItem = psMetadataLookup(target->concepts, "CELL.XBIN");
    298270    binItem->data.S32 *= xBin;
     
    314286    pmHDU *targetPHU = findBlankPHU(target); // The target PHU
    315287    if (targetPHU && targetPHU != targetHDU) {
    316 //        pmHDU *sourcePHU = pmHDUGetHighest(source->parent->parent, source->parent, source); // A source HDU
     288        // pmHDU *sourcePHU = pmHDUGetHighest(source->parent->parent, source->parent, source); // A source HDU
    317289        pmHDU *sourcePHU = findBlankPHU(source); // The target PHU
    318290        if (sourcePHU && sourcePHU->header) {
     
    321293    }
    322294
     295    psFree (binning);
    323296    target->data_exists = true;
    324297    return true;
Note: See TracChangeset for help on using the changeset viewer.