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/pmFPARead.c

    r5633 r5786  
    77#include "pmFPARead.h"
    88
    9 #include "papStuff.h"                   // For "split"
     9#include "papStuff.h"                   // For "split"
    1010
    1111// NOTE: Need to deal with header inheritance
     
    1818// Read a FITS extension into a chip
    1919static bool readExtension(p_pmHDU *hdu, // Pixel data into which to read
    20                           psFits *fits  // The FITS file from which to read
     20                          psFits *fits  // The FITS file from which to read
    2121    )
    2222{
     
    2525    psTrace(__func__, 7, "Moving to extension %s...\n", extName);
    2626    if (strncmp(extName, "PHU", 3) == 0) {
    27         if (!psFitsMoveExtNum(fits, 0, false)) {
    28             psError(PS_ERR_IO, false, "Unable to find PHU in FITS file!\n");
    29             return false;
    30         }
     27        if (!psFitsMoveExtNum(fits, 0, false)) {
     28            psError(PS_ERR_IO, false, "Unable to find PHU in FITS file!\n");
     29            return false;
     30        }
    3131    } else if (! psFitsMoveExtName(fits, extName)) {
    32         psError(PS_ERR_IO, false, "Unable to find extension %s in FITS file!\n", extName);
    33         return false;
     32        psError(PS_ERR_IO, false, "Unable to find extension %s in FITS file!\n", extName);
     33        return false;
    3434    }
    3535    psTrace(__func__, 7, "Reading header....\n");
    3636    psMetadata *header = psFitsReadHeader(NULL, fits); // Header
    3737    if (! header) {
    38         psError(PS_ERR_IO, false, "Unable to read FITS header!\n");
    39         return false;
     38        psError(PS_ERR_IO, false, "Unable to read FITS header!\n");
     39        return false;
    4040    }
    4141
     
    4444    int nAxis = psMetadataLookupS32(&mdStatus, header, "NAXIS");
    4545    if (!mdStatus) {
    46         psLogMsg(__func__, PS_LOG_WARN, "There is no NAXIS keyword in the FITS header of extension %s!\n",
    47                 extName);
     46        psLogMsg(__func__, PS_LOG_WARN, "There is no NAXIS keyword in the FITS header of extension %s!\n",
     47                extName);
    4848    }
    4949    if (nAxis != 2 && nAxis != 3) {
    50         psLogMsg(__func__, PS_LOG_WARN, "Image is not 2- or 3-dimensional --- reading into a single image "
    51                 "anyway.\n");
     50        psLogMsg(__func__, PS_LOG_WARN, "Image is not 2- or 3-dimensional --- reading into a single image "
     51                "anyway.\n");
    5252    }
    5353    psTrace(__func__, 9, "NAXIS = %d\n", nAxis);
    5454
    55     int numPlanes = 1;                  // Number of planes
     55    int numPlanes = 1;                  // Number of planes
    5656    if (nAxis == 3) {
    57         numPlanes = psMetadataLookupS32(&mdStatus, header, "NAXIS3");
    58         if (!mdStatus) {
    59             psError(PS_ERR_IO, false, "Unable to read NAXIS3 for 3-dimensional image!\n");
    60             return false;
    61         }
    62     }
    63     psRegion region = {0, 0, 0, 0};     // Region to read is everything
     57        numPlanes = psMetadataLookupS32(&mdStatus, header, "NAXIS3");
     58        if (!mdStatus) {
     59            psError(PS_ERR_IO, false, "Unable to read NAXIS3 for 3-dimensional image!\n");
     60            return false;
     61        }
     62    }
     63    psRegion region = {0, 0, 0, 0};     // Region to read is everything
    6464
    6565    // Read each plane into the array
     
    6767    psArray *pixels = psArrayAlloc(numPlanes); // Array of images
    6868    for (int i = 0; i < numPlanes; i++) {
    69         psTrace(__func__, 9, "Reading plane %d\n", i);
    70         psMemCheckCorruption(true);
    71         psImage *image = psFitsReadImage(NULL, fits, region, i);
    72 
    73         // XXX: Type conversion here to support the modules, which don't have multiple type support yet
    74         if (image->type.type != PS_TYPE_F32) {
    75             pixels->data[i] = psImageCopy(NULL, image, PS_TYPE_F32);
     69        psTrace(__func__, 9, "Reading plane %d\n", i);
     70        psMemCheckCorruption(true);
     71        psImage *image = psFitsReadImage(NULL, fits, region, i);
     72
     73        // XXX: Type conversion here to support the modules, which don't have multiple type support yet
     74        if (image->type.type != PS_TYPE_F32) {
     75            pixels->data[i] = psImageCopy(NULL, image, PS_TYPE_F32);
    7676
    7777#ifndef PRODUCTION
    78             // XXX: Temporary fix for writing images, until psFits gets cleaned up
    79             psMetadataItem *bitpixItem = psMetadataLookup(header, "BITPIX");
    80             bitpixItem->data.S32 = -32;
    81             psMetadataRemove(header, 0, "BZERO");
    82             psMetadataRemove(header, 0, "BSCALE");
     78            // XXX: Temporary fix for writing images, until psFits gets cleaned up
     79            psMetadataItem *bitpixItem = psMetadataLookup(header, "BITPIX");
     80            bitpixItem->data.S32 = -32;
     81            psMetadataRemove(header, 0, "BZERO");
     82            psMetadataRemove(header, 0, "BSCALE");
    8383#endif
    8484
    85             psFree(image);
    86         } else {
    87             pixels->data[i] = image;
    88         }
    89         psTrace(__func__, 10, "Done\n");
     85            psFree(image);
     86        } else {
     87            pixels->data[i] = image;
     88        }
     89        psTrace(__func__, 10, "Done\n");
    9090        if (! pixels->data[i]) {
    91             psError(PS_ERR_IO, false, "Unable to read image for extension %s, plane %d\n", extName, i);
    92             return false;
    93         }
     91            psError(PS_ERR_IO, false, "Unable to read image for extension %s, plane %d\n", extName, i);
     92            return false;
     93        }
    9494    }
    9595
     
    105105// Portion out an image into the cell
    106106static bool generateReadouts(pmCell *cell, // The cell that gets its bits
    107                              p_pmHDU *hdu // Pixel data, containing image, mask, weights
     107                             p_pmHDU *hdu // Pixel data, containing image, mask, weights
    108108    )
    109109{
    110     psArray *images = hdu->images;      // Array of images (each of which is a readout)
    111     psArray *masks = hdu->masks;        // Array of masks (one for each readout)
     110    psArray *images = hdu->images;      // Array of images (each of which is a readout)
     111    psArray *masks = hdu->masks;        // Array of masks (one for each readout)
    112112    // Iterate over each of the image planes
    113113    for (int i = 0; i < images->n; i++) {
    114         psImage *image = images->data[i]; // The i-th plane
    115         psImage *mask = NULL;           // The mask
    116         if (masks) {
    117             mask = masks->data[i];
    118         }
    119 
    120         pmReadout *readout = pmReadoutAlloc(cell, image, mask, 0,0,1,1);
    121         psFree(readout);                // This seems silly, but the alloc registers it with the cell, so we
    122                                         // don't have to do anything with it.  Perhaps we should change
    123                                         // pmReadoutAlloc to pmReadoutAdd?
     114        psImage *image = images->data[i]; // The i-th plane
     115        psImage *mask = NULL;           // The mask
     116        if (masks) {
     117            mask = masks->data[i];
     118        }
     119
     120        pmReadout *readout = pmReadoutAlloc(cell, image, mask, 0,0,1,1);
     121        psFree(readout);                // This seems silly, but the alloc registers it with the cell, so we
     122                                        // don't have to do anything with it.  Perhaps we should change
     123                                        // pmReadoutAlloc to pmReadoutAdd?
    124124    }
    125125
     
    131131//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    132132
    133 bool pmFPARead(pmFPA *fpa,              // FPA to read into
    134                psFits *fits,            // FITS file from which to read
    135                psMetadata *phu,         // Primary header
    136                psDB *db                 // Database handle, for concept ingest
     133bool pmFPARead(pmFPA *fpa,              // FPA to read into
     134               psFits *fits,            // FITS file from which to read
     135               psMetadata *phu,         // Primary header
     136               psDB *db                 // Database handle, for concept ingest
    137137    )
    138138{
    139     p_pmHDU *hdu = NULL;        // Pixel data from FITS file
     139    p_pmHDU *hdu = NULL;        // Pixel data from FITS file
    140140
    141141    // Read the PHU, if required
    142142    if (! phu) {
    143         if (! psFitsMoveExtNum(fits, 0, false)) {
    144             psError(PS_ERR_IO, false, "Unable to find PHU in FITS file!\n");
    145             return false;
    146         }
    147         psTrace(__func__, 7, "Reading PHU....\n");
    148         psMetadata *phu = psFitsReadHeader(NULL, fits); // Primary header
    149     }
    150     fpa->phu = phu;
     143        if (! psFitsMoveExtNum(fits, 0, false)) {
     144            psError(PS_ERR_IO, false, "Unable to find PHU in FITS file!\n");
     145            return false;
     146        }
     147        psTrace(__func__, 7, "Reading PHU....\n");
     148        fpa->phu = psFitsReadHeader(NULL, fits); // Primary header
     149    } else {
     150        fpa->phu = psMemIncrRefCounter(phu);
     151    }
    151152
    152153    // Read in....
    153154    psTrace(__func__, 1, "Working on FPA...\n");
    154155    if (fpa->hdu) {
    155         hdu = fpa->hdu;
    156         psTrace(__func__, 3, "Reading pixels from extension %s into FPA.\n", hdu->extname);
    157         if (! readExtension(hdu, fits)) {
    158             psError(PS_ERR_IO, false, "Unable to read pixels from extension %s\n", hdu->extname);
    159             return false;
    160         }
     156        hdu = fpa->hdu;
     157        psTrace(__func__, 3, "Reading pixels from extension %s into FPA.\n", hdu->extname);
     158        if (! readExtension(hdu, fits)) {
     159            psError(PS_ERR_IO, false, "Unable to read pixels from extension %s\n", hdu->extname);
     160            return false;
     161        }
    161162    }
    162163    pmFPAIngestConcepts(fpa, db);
    163164
    164     psArray *chips = fpa->chips;        // Array of chips
     165    psArray *chips = fpa->chips;        // Array of chips
    165166    // Iterate over the FPA
    166167    for (int i = 0; i < chips->n; i++) {
    167         pmChip *chip = chips->data[i]; // The chip
    168 
    169         // Only read chips marked "valid"
    170         if (! chip->valid) {
    171             psTrace(__func__, 2, "Ignoring chip %d...\n", i);
    172             continue;
    173         }
    174         psTrace(__func__, 2, "Reading in chip %d...\n", i);
    175 
    176         if (chip->hdu) {
    177             hdu = chip->hdu;
    178             psTrace(__func__, 3, "Reading pixels from extension %s into chip %d.\n", hdu->extname, i);
    179             if (! readExtension(hdu, fits)) {
    180                 psError(PS_ERR_IO, false, "Unable to read pixels from extension %s\n", hdu->extname);
    181                 return false;
    182             }
    183         }
    184         pmChipIngestConcepts(chip, db);
    185 
    186         // Iterate over the chip
    187         psArray *cells = chip->cells;   // Array of cells
    188         for (int j = 0; j < cells->n; j++) {
    189             pmCell *cell = cells->data[j]; // The cell
    190 
    191             // Only read cells marked "valid"
    192             if (! cell->valid) {
    193                 psTrace(__func__, 3, "Ignoring chip %d...\n", i);
    194                 continue;
    195             }
    196             psTrace(__func__, 3, "Reading in cell %d...\n", j);
    197 
    198             if (cell->hdu) {
    199                 hdu = cell->hdu;
    200                 psTrace(__func__, 5, "Reading pixels from extension %s into cell %d.\n", hdu->extname,
    201                         j);
    202                 if (! readExtension(hdu, fits)) {
    203                     psError(PS_ERR_IO, false, "Unable to read pixels from extension %s\n",
    204                             hdu->extname);
    205                     return false;
    206                 }
    207             }
    208             pmCellIngestConcepts(cell, db);
    209 
    210             psTrace(__func__, 5, "Allocating readouts for chip %d cell %d...\n",
    211                     i, j);
    212             generateReadouts(cell, hdu);
    213         }
     168        pmChip *chip = chips->data[i]; // The chip
     169
     170        // Only read chips marked "valid"
     171        if (! chip->valid) {
     172            psTrace(__func__, 2, "Ignoring chip %d...\n", i);
     173            continue;
     174        }
     175        psTrace(__func__, 2, "Reading in chip %d...\n", i);
     176
     177        if (chip->hdu) {
     178            hdu = chip->hdu;
     179            psTrace(__func__, 3, "Reading pixels from extension %s into chip %d.\n", hdu->extname, i);
     180            if (! readExtension(hdu, fits)) {
     181                psError(PS_ERR_IO, false, "Unable to read pixels from extension %s\n", hdu->extname);
     182                return false;
     183            }
     184        }
     185        pmChipIngestConcepts(chip, db);
     186
     187        // Iterate over the chip
     188        psArray *cells = chip->cells;   // Array of cells
     189        for (int j = 0; j < cells->n; j++) {
     190            pmCell *cell = cells->data[j]; // The cell
     191
     192            // Only read cells marked "valid"
     193            if (! cell->valid) {
     194                psTrace(__func__, 3, "Ignoring chip %d...\n", i);
     195                continue;
     196            }
     197            psTrace(__func__, 3, "Reading in cell %d...\n", j);
     198
     199            if (cell->hdu) {
     200                hdu = cell->hdu;
     201                psTrace(__func__, 5, "Reading pixels from extension %s into cell %d.\n", hdu->extname,
     202                        j);
     203                if (! readExtension(hdu, fits)) {
     204                    psError(PS_ERR_IO, false, "Unable to read pixels from extension %s\n",
     205                            hdu->extname);
     206                    return false;
     207                }
     208            }
     209            pmCellIngestConcepts(cell, db);
     210
     211            psTrace(__func__, 5, "Allocating readouts for chip %d cell %d...\n",
     212                    i, j);
     213            generateReadouts(cell, hdu);
     214        }
    214215    }
    215216
     
    219220// Translate a name from the configuration file, containing something like "%a_%d" to a real value
    220221psString p_pmFPATranslateName(psString name, // The name to translate
    221                               pmCell *cell // The cell for which to translate
     222                              pmCell *cell // The cell for which to translate
    222223    )
    223224{
     
    230231
    231232    psString translation = psMemIncrRefCounter(name); // The translated string
    232     char *temp = NULL;                  // Temporary string
    233 
    234     pmChip *chip = cell->parent;        // Chip of interest
    235     pmFPA *fpa = chip->parent;          // FPA of interest
     233    char *temp = NULL;                  // Temporary string
     234
     235    pmChip *chip = cell->parent;        // Chip of interest
     236    pmFPA *fpa = chip->parent;          // FPA of interest
    236237
    237238    // FPA.NAME
    238239    if (temp = strstr(translation, "%a")) {
    239         // This is not particularly friendly to the memory allocation, but the cache should make it OK,
    240         // and there's not much of it anyway...
    241         psFree(translation);
    242         translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
    243         psString fpaName = psMetadataLookupString(NULL, fpa->concepts, "FPA.NAME"); // The value of FPA.NAME
    244         psStringAppend(&translation, "%s%s", fpaName, temp + 2);
    245         // So "translation" now contains the first part, the replaced string, and the last part.
     240        // This is not particularly friendly to the memory allocation, but the cache should make it OK,
     241        // and there's not much of it anyway...
     242        psFree(translation);
     243        translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
     244        psString fpaName = psMetadataLookupString(NULL, fpa->concepts, "FPA.NAME"); // The value of FPA.NAME
     245        psStringAppend(&translation, "%s%s", fpaName, temp + 2);
     246        // So "translation" now contains the first part, the replaced string, and the last part.
    246247    }
    247248
    248249    // CHIP.NAME
    249250    if (temp = strstr(translation, "%b")) {
    250         // This is not particularly friendly to the memory allocation, but the cache should make it OK,
    251         // and there's not much of it anyway...
    252         psFree(translation);
    253         translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
    254         psString chipName = psMetadataLookupString(NULL, chip->concepts, "CHIP.NAME"); // CHIP.NAME's value
    255         psStringAppend(&translation, "%s%s", chipName, temp + 2);
    256         // So "translation" now contains the first part, the replaced string, and the last part.
     251        // This is not particularly friendly to the memory allocation, but the cache should make it OK,
     252        // and there's not much of it anyway...
     253        psFree(translation);
     254        translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
     255        psString chipName = psMetadataLookupString(NULL, chip->concepts, "CHIP.NAME"); // CHIP.NAME's value
     256        psStringAppend(&translation, "%s%s", chipName, temp + 2);
     257        // So "translation" now contains the first part, the replaced string, and the last part.
    257258    }
    258259
    259260    // CELL.NAME
    260261    if (temp = strstr(translation, "%c")) {
    261         // This is not particularly friendly to the memory allocation, but the cache should make it OK,
    262         // and there's not much of it anyway...
    263         psFree(translation);
    264         translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
    265         psString cellName = psMetadataLookupString(NULL, cell->concepts, "CELL.NAME"); // CELL.NAME's value
    266         psStringAppend(&translation, "%s%s", cellName, temp + 2);
    267         // So "translation" now contains the first part, the replaced string, and the last part.
     262        // This is not particularly friendly to the memory allocation, but the cache should make it OK,
     263        // and there's not much of it anyway...
     264        psFree(translation);
     265        translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
     266        psString cellName = psMetadataLookupString(NULL, cell->concepts, "CELL.NAME"); // CELL.NAME's value
     267        psStringAppend(&translation, "%s%s", cellName, temp + 2);
     268        // So "translation" now contains the first part, the replaced string, and the last part.
    268269    }
    269270
    270271    // Chip number
    271272    if (temp = strstr(translation, "%d")) {
    272         // This is not particularly friendly to the memory allocation, but the cache should make it OK,
    273         // and there's not much of it anyway...
    274         psFree(translation);
    275         translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
    276         // Search for the pointer to get the chip number
    277         int chipNum = -1;
    278         psArray *chips = fpa->chips;    // The array of chips
    279         for (int i = 0; i < chips->n && chipNum < 0; i++) {
    280             if (chips->data[i] == chip) {
    281                 chipNum = i;
    282             }
    283         }
    284         if (chipNum < 0) {
    285             psError(PS_ERR_IO, true, "Unable to find chip to get name: %s\n", name);
    286             // Try to muddle on by leaving the number out
    287             psStringAppend(&translation, "%s", temp + 2);
    288         } else {
    289             psStringAppend(&translation, "%d%s", chipNum, temp + 2);
    290         }
    291         // So "translation" now contains the first part, the replaced string, and the last part.
     273        // This is not particularly friendly to the memory allocation, but the cache should make it OK,
     274        // and there's not much of it anyway...
     275        psFree(translation);
     276        translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
     277        // Search for the pointer to get the chip number
     278        int chipNum = -1;
     279        psArray *chips = fpa->chips;    // The array of chips
     280        for (int i = 0; i < chips->n && chipNum < 0; i++) {
     281            if (chips->data[i] == chip) {
     282                chipNum = i;
     283            }
     284        }
     285        if (chipNum < 0) {
     286            psError(PS_ERR_IO, true, "Unable to find chip to get name: %s\n", name);
     287            // Try to muddle on by leaving the number out
     288            psStringAppend(&translation, "%s", temp + 2);
     289        } else {
     290            psStringAppend(&translation, "%d%s", chipNum, temp + 2);
     291        }
     292        // So "translation" now contains the first part, the replaced string, and the last part.
    292293    }
    293294
    294295    // Cell number
    295296    if (temp = strstr(translation, "%e")) {
    296         // This is not particularly friendly to the memory allocation, but the cache should make it OK,
    297         // and there's not much of it anyway...
    298         psFree(translation);
    299         translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
    300         // Search for the pointer to get the cell number
    301         int cellNum = -1;
    302         psArray *cells = chip->cells;   // The array of cells
    303         for (int i = 0; i < cells->n && cellNum < 0; i++) {
    304             if (cells->data[i] == cell) {
    305                 cellNum = i;
    306             }
    307         }
    308         if (cellNum < 0) {
    309             psError(PS_ERR_IO, true, "Unable to find cell to get name: %s\n", name);
    310             // Try to muddle on by leaving the number out
    311             psStringAppend(&translation, "%s", temp + 2);
    312         } else {
    313             psStringAppend(&translation, "%d%s", cellNum, temp + 2);
    314         }
    315         // So "translation" now contains the first part, the replaced string, and the last part.
     297        // This is not particularly friendly to the memory allocation, but the cache should make it OK,
     298        // and there's not much of it anyway...
     299        psFree(translation);
     300        translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
     301        // Search for the pointer to get the cell number
     302        int cellNum = -1;
     303        psArray *cells = chip->cells;   // The array of cells
     304        for (int i = 0; i < cells->n && cellNum < 0; i++) {
     305            if (cells->data[i] == cell) {
     306                cellNum = i;
     307            }
     308        }
     309        if (cellNum < 0) {
     310            psError(PS_ERR_IO, true, "Unable to find cell to get name: %s\n", name);
     311            // Try to muddle on by leaving the number out
     312            psStringAppend(&translation, "%s", temp + 2);
     313        } else {
     314            psStringAppend(&translation, "%d%s", cellNum, temp + 2);
     315        }
     316        // So "translation" now contains the first part, the replaced string, and the last part.
    316317    }
    317318
    318319    // Extension name
    319320    if (temp = strstr(translation, "%f")) {
    320         // This is not particularly friendly to the memory allocation, but the cache should make it OK,
    321         // and there's not much of it anyway...
    322         psFree(translation);
    323         translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
    324         const char *extname = NULL;
    325         if (cell->hdu) {
    326             extname = cell->hdu->extname;
    327         } else if (chip->hdu) {
    328             extname = chip->hdu->extname;
    329         } else if (fpa->hdu) {
    330             extname = fpa->hdu->extname;
    331         }
    332         psStringAppend(&translation, "%s%s", extname, temp + 2);
    333         // So "translation" now contains the first part, the replaced string, and the last part.
     321        // This is not particularly friendly to the memory allocation, but the cache should make it OK,
     322        // and there's not much of it anyway...
     323        psFree(translation);
     324        translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
     325        const char *extname = NULL;
     326        if (cell->hdu) {
     327            extname = cell->hdu->extname;
     328        } else if (chip->hdu) {
     329            extname = chip->hdu->extname;
     330        } else if (fpa->hdu) {
     331            extname = fpa->hdu->extname;
     332        }
     333        psStringAppend(&translation, "%s%s", extname, temp + 2);
     334        // So "translation" now contains the first part, the replaced string, and the last part.
    334335    }
    335336
     
    338339
    339340// Read a mask into the FPA
    340 bool pmFPAReadMask(pmFPA *fpa,          // FPA to read into
    341                    psFits *source       // Source FITS file (for the original data)
     341bool pmFPAReadMask(pmFPA *fpa,          // FPA to read into
     342                   psFits *source       // Source FITS file (for the original data)
    342343    )
    343344{
    344345    const psMetadata *camera = fpa->camera; // Camera configuration for FPA
    345     bool mdok = false;                  // Status of MD lookup
     346    bool mdok = false;                  // Status of MD lookup
    346347
    347348    // Get the required information from the camera configuration
    348349    psMetadata *supps = psMetadataLookupMD(&mdok, camera, "SUPPLEMENTARY"); // Rules for supplementary data
    349350    if (! mdok || ! supps) {
    350         psError(PS_ERR_IO, false, "Unable to find SUPPLEMENTARY in camera configuration!\n");
    351         return false;
     351        psError(PS_ERR_IO, false, "Unable to find SUPPLEMENTARY in camera configuration!\n");
     352        return false;
    352353    }
    353354    psString sourceType = psMetadataLookupString(&mdok, supps, "MASK.SOURCE"); // Type of source: EXT | FILE
    354355    if (! mdok || strlen(sourceType) <= 0) {
    355         psError(PS_ERR_IO, false, "Unable to find MASK.SOURCE in SUPPLEMENTARY section of camera "
    356                 "configuration!\n");
    357         return false;
     356        psError(PS_ERR_IO, false, "Unable to find MASK.SOURCE in SUPPLEMENTARY section of camera "
     357                "configuration!\n");
     358        return false;
    358359    }
    359360    psString name = psMetadataLookupString(&mdok, supps, "MASK.NAME"); // Name of mask
    360361    if (! mdok || strlen(sourceType) <= 0) {
    361         psError(PS_ERR_IO, false, "Unable to find MASK.NAME in SUPPLEMENTARY section of camera "
    362                 "configuration!\n");
    363         return false;
     362        psError(PS_ERR_IO, false, "Unable to find MASK.NAME in SUPPLEMENTARY section of camera "
     363                "configuration!\n");
     364        return false;
    364365    }
    365366
    366367    // Go through the FPA to each cell/readout to get the mask
    367     p_pmHDU *hdu = fpa->hdu;            // The HDU into which we will read the mask
    368     psArray *chips = fpa->chips;        // Array of chips
     368    p_pmHDU *hdu = fpa->hdu;            // The HDU into which we will read the mask
     369    psArray *chips = fpa->chips;        // Array of chips
    369370    for (int chipNum = 0; chipNum < chips->n; chipNum++) {
    370         pmChip *chip = chips->data[chipNum]; // The current chip of interest
    371         if (chip->valid) {
    372             if (chip->hdu) {
    373                 hdu = chip->hdu;
    374             }
    375             psArray *cells = chip->cells;       // Array of cells
    376             for (int cellNum = 0; cellNum < cells->n; cellNum++) {
    377                 pmCell *cell = cells->data[cellNum]; // The current cell of interest
    378                 if (cell->valid) {
    379                     if (cell->hdu) {
    380                         hdu = cell->hdu;
    381                     }
    382 
    383                     // Now, need to find out where to get the pixels
    384                     psFits *maskSource = source;        // Source of mask image
    385                     if (strcasecmp(sourceType, "FILE") == 0) {
    386                         // Source is a file (with optional extension, e.g., "myMaskFile.fits:thisExt"
    387                         psString filenameExt = p_pmFPATranslateName(name, cell);
    388                         char *colon = strchr(filenameExt, ':'); // Pointer to a colon in the filename-extn
    389                         psString filename = NULL; // The filename
    390                         psString extname = NULL;// The extenstion name
    391                         if (colon) {
    392                             filename = psStringNCopy(filenameExt, strlen(filenameExt) - strlen(colon));
    393                             if (strlen(colon) > 1) {
    394                                 extname = psStringCopy(colon + 1);
    395                             }
    396                         } else {
    397                             filename = psMemIncrRefCounter(filenameExt);
    398                         }
    399                        
    400                         maskSource = psFitsAlloc(filename);
    401                         if (extname) {
    402                             if (! psFitsMoveExtName(maskSource, extname)) {
    403                                 psLogMsg(__func__, PS_LOG_WARN, "Unable to find extension %s to read mask.\n",
    404                                          extname);
    405                                 return false;
    406                             }
    407                         }
    408                         psFree(filename);
    409                         psFree(extname);
    410                         psFree(filenameExt);
    411                     } else if (strncasecmp(sourceType, "EXT", 3) == 0) {
    412                         // Source is an extension in the original file
    413                         psString extname = p_pmFPATranslateName(name, cell);
    414                         psFitsMoveExtName(maskSource, extname);
    415                     }
    416                    
    417                     // We've arrived where the pixels are.  Now we need to read them in.
    418                     psMetadata *header = psFitsReadHeader(NULL, maskSource); // The header
    419                     bool mdStatus = false;
    420                     int nAxis = psMetadataLookupS32(&mdStatus, header, "NAXIS");
    421                     if (!mdStatus) {
    422                         psLogMsg(__func__, PS_LOG_WARN, "There is no NAXIS keyword in the FITS header for "
    423                                  "mask (%s)!\n", name);
    424                     }
    425                     if (nAxis != 2 && nAxis != 3) {
    426                         psLogMsg(__func__, PS_LOG_WARN, "Image is not 2- or 3-dimensional --- reading into "
    427                                  "a single image anyway.\n");
    428                     }
    429            
    430                     int numPlanes = 1;  // Number of planes
    431                     if (nAxis == 3) {
    432                         numPlanes = psMetadataLookupS32(&mdStatus, header, "NAXIS3");
    433                         if (!mdStatus) {
    434                             psError(PS_ERR_IO, false, "Unable to read NAXIS3 for 3-dimensional image!\n");
    435                             // Try to proceed by taking only the first plane
    436                             numPlanes = 1;
    437                         }
    438                         if (numPlanes != 1 && numPlanes != cell->readouts->n) {
    439                             psError(PS_ERR_IO, false, "Number of masks (%d) does not match number of "
    440                                     "readouts (%d)\n", numPlanes, cell->readouts->n);
    441                             // Try to proceed by taking only the first plane
    442                             numPlanes = 1;
    443                         }
    444                     }
    445 
    446                     hdu->masks = psArrayAlloc(hdu->images->n);
    447                    
    448                     // Read each plane into the array
    449                     psArray *readouts = cell->readouts; // The array of readouts
    450                     for (int i = 0; i < hdu->masks->n; i++) {
    451                         psImage *mask = NULL; // The mask to be added
    452                         if (i < numPlanes) {
    453                             // Read the mask from the file
    454                             psTrace(__func__, 9, "Reading plane %d\n", i);
    455                             psRegion region = {0, 0, 0, 0};
    456                             mask = psFitsReadImage(NULL, maskSource, region, i);
    457                         } else {
    458                             // One mask in the file is provided for all planes in the original image
    459                             psTrace(__func__, 9, "Copying plane 0 into plane %d\n", i);
    460                             psImage *original = hdu->masks->data[0];
    461                             mask = psImageCopy(NULL, original, original->type.type);
    462                         }
    463                         hdu->masks->data[0] = mask;
    464                         pmReadout *readout = readouts->data[i];
    465                         readout->mask = mask;
    466                         // Check the dimensions
    467                         // XXX: Perhaps this check should be against the CELL.TRIMSEC, not the image size?
    468                         if (mask->numCols < readout->image->numCols ||
    469                             mask->numRows < readout->image->numRows)
    470                         {
    471                             psError(PS_ERR_IO, false, "Mask size (%dx%d) not compatible with image (%dx%d)\n",
    472                                     mask->numCols, mask->numRows, readout->image->numCols,
    473                                     readout->image->numRows);
    474                             return false;
    475                         }
    476                     } // Iterating over readouts
    477                 } // Valid cells
    478             } // Iterating over cells
    479         } // Valid chips
     371        pmChip *chip = chips->data[chipNum]; // The current chip of interest
     372        if (chip->valid) {
     373            if (chip->hdu) {
     374                hdu = chip->hdu;
     375            }
     376            psArray *cells = chip->cells;       // Array of cells
     377            for (int cellNum = 0; cellNum < cells->n; cellNum++) {
     378                pmCell *cell = cells->data[cellNum]; // The current cell of interest
     379                if (cell->valid) {
     380                    if (cell->hdu) {
     381                        hdu = cell->hdu;
     382                    }
     383
     384                    // Now, need to find out where to get the pixels
     385                    psFits *maskSource = psMemIncrRefCounter(source); // Source of mask image
     386                    if (strcasecmp(sourceType, "FILE") == 0) {
     387                        // Source is a file (with optional extension, e.g., "myMaskFile.fits:thisExt"
     388                        psString filenameExt = p_pmFPATranslateName(name, cell);
     389                        char *colon = strchr(filenameExt, ':'); // Pointer to a colon in the filename-extn
     390                        psString filename = NULL; // The filename
     391                        psString extname = NULL;// The extenstion name
     392                        if (colon) {
     393                            filename = psStringNCopy(filenameExt, strlen(filenameExt) - strlen(colon));
     394                            if (strlen(colon) > 1) {
     395                                extname = psStringCopy(colon + 1);
     396                            }
     397                        } else {
     398                            filename = psMemIncrRefCounter(filenameExt);
     399                        }
     400
     401                        psFree(maskSource);
     402                        maskSource = psFitsOpen(filename, "r");
     403                        if (extname) {
     404                            if (! psFitsMoveExtName(maskSource, extname)) {
     405                                psLogMsg(__func__, PS_LOG_WARN, "Unable to find extension %s to read mask.\n",
     406                                         extname);
     407                                return false;
     408                            }
     409                        }
     410                        psFree(filename);
     411                        psFree(extname);
     412                        psFree(filenameExt);
     413                    } else if (strncasecmp(sourceType, "EXT", 3) == 0) {
     414                        // Source is an extension in the original file
     415                        psString extname = p_pmFPATranslateName(name, cell);
     416                        psFitsMoveExtName(maskSource, extname);
     417                    }
     418
     419                    // We've arrived where the pixels are.  Now we need to read them in.
     420                    psMetadata *header = psFitsReadHeader(NULL, maskSource); // The header
     421                    bool mdStatus = false;
     422                    int nAxis = psMetadataLookupS32(&mdStatus, header, "NAXIS");
     423                    if (!mdStatus) {
     424                        psLogMsg(__func__, PS_LOG_WARN, "There is no NAXIS keyword in the FITS header for "
     425                                 "mask (%s)!\n", name);
     426                    }
     427                    if (nAxis != 2 && nAxis != 3) {
     428                        psLogMsg(__func__, PS_LOG_WARN, "Image is not 2- or 3-dimensional --- reading into "
     429                                 "a single image anyway.\n");
     430                    }
     431
     432                    int numPlanes = 1;  // Number of planes
     433                    if (nAxis == 3) {
     434                        numPlanes = psMetadataLookupS32(&mdStatus, header, "NAXIS3");
     435                        if (!mdStatus) {
     436                            psError(PS_ERR_IO, false, "Unable to read NAXIS3 for 3-dimensional image!\n");
     437                            // Try to proceed by taking only the first plane
     438                            numPlanes = 1;
     439                        }
     440                        if (numPlanes != 1 && numPlanes != cell->readouts->n) {
     441                            psError(PS_ERR_IO, false, "Number of masks (%d) does not match number of "
     442                                    "readouts (%d)\n", numPlanes, cell->readouts->n);
     443                            // Try to proceed by taking only the first plane
     444                            numPlanes = 1;
     445                        }
     446                    }
     447
     448                    hdu->masks = psArrayAlloc(hdu->images->n);
     449
     450                    // Read each plane into the array
     451                    psArray *readouts = cell->readouts; // The array of readouts
     452                    for (int i = 0; i < hdu->masks->n; i++) {
     453                        psImage *mask = NULL; // The mask to be added
     454                        if (i < numPlanes) {
     455                            // Read the mask from the file
     456                            psTrace(__func__, 9, "Reading plane %d\n", i);
     457                            psRegion region = {0, 0, 0, 0};
     458                            mask = psFitsReadImage(NULL, maskSource, region, i);
     459                        } else {
     460                            // One mask in the file is provided for all planes in the original image
     461                            psTrace(__func__, 9, "Copying plane 0 into plane %d\n", i);
     462                            psImage *original = hdu->masks->data[0];
     463                            mask = psImageCopy(NULL, original, original->type.type);
     464                        }
     465                        hdu->masks->data[0] = mask;
     466                        pmReadout *readout = readouts->data[i];
     467                        readout->mask = mask;
     468                        // Check the dimensions
     469                        // XXX: Perhaps this check should be against the CELL.TRIMSEC, not the image size?
     470                        if (mask->numCols < readout->image->numCols ||
     471                            mask->numRows < readout->image->numRows)
     472                        {
     473                            psError(PS_ERR_IO, false, "Mask size (%dx%d) not compatible with image (%dx%d)\n",
     474                                    mask->numCols, mask->numRows, readout->image->numCols,
     475                                    readout->image->numRows);
     476                            return false;
     477                        }
     478                    } // Iterating over readouts
     479                    psFree(maskSource);
     480                } // Valid cells
     481            } // Iterating over cells
     482        } // Valid chips
    480483    } // Iterating over chips
    481484
     
    486489// Read a mask into the FPA
    487490// This is just a copy of the above pmFPAReadMask, replacing "mask" with "weight" throughout.
    488 bool pmFPAReadWeight(pmFPA *fpa,        // FPA to read into
    489                      psFits *source     // Source FITS file (for the original data)
     491bool pmFPAReadWeight(pmFPA *fpa,        // FPA to read into
     492                     psFits *source     // Source FITS file (for the original data)
    490493    )
    491494{
    492495    const psMetadata *camera = fpa->camera; // Camera configuration for FPA
    493     bool mdok = false;                  // Status of MD lookup
     496    bool mdok = false;                  // Status of MD lookup
    494497
    495498    // Get the required information from the camera configuration
    496499    psMetadata *supps = psMetadataLookupMD(&mdok, camera, "SUPPLEMENTARY"); // Rules for supplementary data
    497500    if (! mdok || ! supps) {
    498         psError(PS_ERR_IO, false, "Unable to find SUPPLEMENTARY in camera configuration!\n");
    499         return false;
     501        psError(PS_ERR_IO, false, "Unable to find SUPPLEMENTARY in camera configuration!\n");
     502        return false;
    500503    }
    501504    psString sourceType = psMetadataLookupString(&mdok, supps, "WEIGHT.SOURCE"); // Type of source: EXT | FILE
    502505    if (! mdok || strlen(sourceType) <= 0) {
    503         psError(PS_ERR_IO, false, "Unable to find WEIGHT.SOURCE in SUPPLEMENTARY section of camera "
    504                 "configuration!\n");
    505         return false;
     506        psError(PS_ERR_IO, false, "Unable to find WEIGHT.SOURCE in SUPPLEMENTARY section of camera "
     507                "configuration!\n");
     508        return false;
    506509    }
    507510    psString name = psMetadataLookupString(&mdok, supps, "WEIGHT.NAME"); // Name of weight
    508511    if (! mdok || strlen(sourceType) <= 0) {
    509         psError(PS_ERR_IO, false, "Unable to find WEIGHT.NAME in SUPPLEMENTARY section of camera "
    510                 "configuration!\n");
    511         return false;
     512        psError(PS_ERR_IO, false, "Unable to find WEIGHT.NAME in SUPPLEMENTARY section of camera "
     513                "configuration!\n");
     514        return false;
    512515    }
    513516
    514517    // Go through the FPA to each cell/readout to get the weight
    515     p_pmHDU *hdu = fpa->hdu;            // The HDU into which we will read the weight
    516     psArray *chips = fpa->chips;        // Array of chips
     518    p_pmHDU *hdu = fpa->hdu;            // The HDU into which we will read the weight
     519    psArray *chips = fpa->chips;        // Array of chips
    517520    for (int chipNum = 0; chipNum < chips->n; chipNum++) {
    518         pmChip *chip = chips->data[chipNum]; // The current chip of interest
    519         if (chip->valid) {
    520             if (chip->hdu) {
    521                 hdu = chip->hdu;
    522             }
    523             psArray *cells = chip->cells;       // Array of cells
    524             for (int cellNum = 0; cellNum < cells->n; cellNum++) {
    525                 pmCell *cell = cells->data[cellNum]; // The current cell of interest
    526                 if (cell->valid) {
    527                     if (cell->hdu) {
    528                         hdu = cell->hdu;
    529                     }
    530 
    531                     // Now, need to find out where to get the pixels
    532                     psFits *weightSource = source;      // Source of weight image
    533                     if (strcasecmp(sourceType, "FILE") == 0) {
    534                         // Source is a file (with optional extension, e.g., "myWeightFile.fits:thisExt"
    535                         psString filenameExt = p_pmFPATranslateName(name, cell);
    536                         char *colon = strchr(filenameExt, ':'); // Pointer to a colon in the filename-extn
    537                         psString filename = NULL; // The filename
    538                         psString extname = NULL;// The extenstion name
    539                         if (colon) {
    540                             filename = psStringNCopy(filenameExt, strlen(filenameExt) - strlen(colon));
    541                             if (strlen(colon) > 1) {
    542                                 extname = psStringCopy(colon + 1);
    543                             }
    544                         } else {
    545                             filename = psMemIncrRefCounter(filenameExt);
    546                         }
    547                        
    548                         weightSource = psFitsAlloc(filename);
    549                         if (extname) {
    550                             if (! psFitsMoveExtName(weightSource, extname)) {
    551                                 psLogMsg(__func__, PS_LOG_WARN, "Unable to find extension %s to read "
    552                                          "weight.\n", extname);
    553                                 return false;
    554                             }
    555                         }
    556                         psFree(filename);
    557                         psFree(extname);
    558                         psFree(filenameExt);
    559                     } else if (strncasecmp(sourceType, "EXT", 3) == 0) {
    560                         // Source is an extension in the original file
    561                         psString extname = p_pmFPATranslateName(name, cell);
    562                         psFitsMoveExtName(weightSource, extname);
    563                     }
    564                    
    565                     // We've arrived where the pixels are.  Now we need to read them in.
    566                     psMetadata *header = psFitsReadHeader(NULL, weightSource); // The header
    567                     bool mdStatus = false;
    568                     int nAxis = psMetadataLookupS32(&mdStatus, header, "NAXIS");
    569                     if (!mdStatus) {
    570                         psLogMsg(__func__, PS_LOG_WARN, "There is no NAXIS keyword in the FITS header for "
    571                                  "weight (%s)!\n", name);
    572                     }
    573                     if (nAxis != 2 && nAxis != 3) {
    574                         psLogMsg(__func__, PS_LOG_WARN, "Image is not 2- or 3-dimensional --- reading into "
    575                                  "a single image anyway.\n");
    576                     }
    577            
    578                     int numPlanes = 1;  // Number of planes
    579                     if (nAxis == 3) {
    580                         numPlanes = psMetadataLookupS32(&mdStatus, header, "NAXIS3");
    581                         if (!mdStatus) {
    582                             psError(PS_ERR_IO, false, "Unable to read NAXIS3 for 3-dimensional image!\n");
    583                             // Try to proceed by taking only the first plane
    584                             numPlanes = 1;
    585                         }
    586                         if (numPlanes != 1 && numPlanes != cell->readouts->n) {
    587                             psError(PS_ERR_IO, false, "Number of weights (%d) does not match number of "
    588                                     "readouts (%d)\n", numPlanes, cell->readouts->n);
    589                             // Try to proceed by taking only the first plane
    590                             numPlanes = 1;
    591                         }
    592                     }
    593 
    594                     hdu->weights = psArrayAlloc(hdu->images->n);
    595                    
    596                     // Read each plane into the array
    597                     psArray *readouts = cell->readouts; // The array of readouts
    598                     for (int i = 0; i < hdu->weights->n; i++) {
    599                         psImage *weight = NULL; // The weight to be added
    600                         if (i < numPlanes) {
    601                             // Read the weight from the file
    602                             psTrace(__func__, 9, "Reading plane %d\n", i);
    603                             psRegion region = {0, 0, 0, 0};
    604                             weight = psFitsReadImage(NULL, weightSource, region, i);
    605                         } else {
    606                             // One weight in the file is provided for all planes in the original image
    607                             psTrace(__func__, 9, "Copying plane 0 into plane %d\n", i);
    608                             psImage *original = hdu->weights->data[0];
    609                             weight = psImageCopy(NULL, original, original->type.type);
    610                         }
    611                         hdu->weights->data[0] = weight;
    612                         pmReadout *readout = readouts->data[i];
    613                         readout->weight = weight;
    614                         // Check the dimensions
    615                         // XXX: Perhaps this check should be against the CELL.TRIMSEC, not the image size?
    616                         if (weight->numCols < readout->image->numCols ||
    617                             weight->numRows < readout->image->numRows)
    618                         {
    619                             psError(PS_ERR_IO, false, "Weight size (%dx%d) not compatible with image "
    620                                     "(%dx%d)\n", weight->numCols, weight->numRows, readout->image->numCols,
    621                                     readout->image->numRows);
    622                             return false;
    623                         }
    624                     } // Iterating over readouts
    625                 } // Valid cells
    626             } // Iterating over cells
    627         } // Valid chips
     521        pmChip *chip = chips->data[chipNum]; // The current chip of interest
     522        if (chip->valid) {
     523            if (chip->hdu) {
     524                hdu = chip->hdu;
     525            }
     526            psArray *cells = chip->cells;       // Array of cells
     527            for (int cellNum = 0; cellNum < cells->n; cellNum++) {
     528                pmCell *cell = cells->data[cellNum]; // The current cell of interest
     529                if (cell->valid) {
     530                    if (cell->hdu) {
     531                        hdu = cell->hdu;
     532                    }
     533
     534                    // Now, need to find out where to get the pixels
     535                    psFits *weightSource = psMemIncrRefCounter(source); // Source of weight image
     536                    if (strcasecmp(sourceType, "FILE") == 0) {
     537                        // Source is a file (with optional extension, e.g., "myWeightFile.fits:thisExt"
     538                        psString filenameExt = p_pmFPATranslateName(name, cell);
     539                        char *colon = strchr(filenameExt, ':'); // Pointer to a colon in the filename-extn
     540                        psString filename = NULL; // The filename
     541                        psString extname = NULL;// The extenstion name
     542                        if (colon) {
     543                            filename = psStringNCopy(filenameExt, strlen(filenameExt) - strlen(colon));
     544                            if (strlen(colon) > 1) {
     545                                extname = psStringCopy(colon + 1);
     546                            }
     547                        } else {
     548                            filename = psMemIncrRefCounter(filenameExt);
     549                        }
     550
     551                        psFree(weightSource);
     552                        weightSource = psFitsOpen(filename, "r");
     553                        if (extname) {
     554                            if (! psFitsMoveExtName(weightSource, extname)) {
     555                                psLogMsg(__func__, PS_LOG_WARN, "Unable to find extension %s to read "
     556                                         "weight.\n", extname);
     557                                return false;
     558                            }
     559                        }
     560                        psFree(filename);
     561                        psFree(extname);
     562                        psFree(filenameExt);
     563                    } else if (strncasecmp(sourceType, "EXT", 3) == 0) {
     564                        // Source is an extension in the original file
     565                        psString extname = p_pmFPATranslateName(name, cell);
     566                        psFitsMoveExtName(weightSource, extname);
     567                    }
     568
     569                    // We've arrived where the pixels are.  Now we need to read them in.
     570                    psMetadata *header = psFitsReadHeader(NULL, weightSource); // The header
     571                    bool mdStatus = false;
     572                    int nAxis = psMetadataLookupS32(&mdStatus, header, "NAXIS");
     573                    if (!mdStatus) {
     574                        psLogMsg(__func__, PS_LOG_WARN, "There is no NAXIS keyword in the FITS header for "
     575                                 "weight (%s)!\n", name);
     576                    }
     577                    if (nAxis != 2 && nAxis != 3) {
     578                        psLogMsg(__func__, PS_LOG_WARN, "Image is not 2- or 3-dimensional --- reading into "
     579                                 "a single image anyway.\n");
     580                    }
     581
     582                    int numPlanes = 1;  // Number of planes
     583                    if (nAxis == 3) {
     584                        numPlanes = psMetadataLookupS32(&mdStatus, header, "NAXIS3");
     585                        if (!mdStatus) {
     586                            psError(PS_ERR_IO, false, "Unable to read NAXIS3 for 3-dimensional image!\n");
     587                            // Try to proceed by taking only the first plane
     588                            numPlanes = 1;
     589                        }
     590                        if (numPlanes != 1 && numPlanes != cell->readouts->n) {
     591                            psError(PS_ERR_IO, false, "Number of weights (%d) does not match number of "
     592                                    "readouts (%d)\n", numPlanes, cell->readouts->n);
     593                            // Try to proceed by taking only the first plane
     594                            numPlanes = 1;
     595                        }
     596                    }
     597
     598                    hdu->weights = psArrayAlloc(hdu->images->n);
     599
     600                    // Read each plane into the array
     601                    psArray *readouts = cell->readouts; // The array of readouts
     602                    for (int i = 0; i < hdu->weights->n; i++) {
     603                        psImage *weight = NULL; // The weight to be added
     604                        if (i < numPlanes) {
     605                            // Read the weight from the file
     606                            psTrace(__func__, 9, "Reading plane %d\n", i);
     607                            psRegion region = {0, 0, 0, 0};
     608                            weight = psFitsReadImage(NULL, weightSource, region, i);
     609                        } else {
     610                            // One weight in the file is provided for all planes in the original image
     611                            psTrace(__func__, 9, "Copying plane 0 into plane %d\n", i);
     612                            psImage *original = hdu->weights->data[0];
     613                            weight = psImageCopy(NULL, original, original->type.type);
     614                        }
     615                        hdu->weights->data[0] = weight;
     616                        pmReadout *readout = readouts->data[i];
     617                        readout->weight = weight;
     618                        // Check the dimensions
     619                        // XXX: Perhaps this check should be against the CELL.TRIMSEC, not the image size?
     620                        if (weight->numCols < readout->image->numCols ||
     621                            weight->numRows < readout->image->numRows)
     622                        {
     623                            psError(PS_ERR_IO, false, "Weight size (%dx%d) not compatible with image "
     624                                    "(%dx%d)\n", weight->numCols, weight->numRows, readout->image->numCols,
     625                                    readout->image->numRows);
     626                            return false;
     627                        }
     628                    } // Iterating over readouts
     629                    psFree(weightSource);
     630                } // Valid cells
     631            } // Iterating over cells
     632        } // Valid chips
    628633    } // Iterating over chips
    629634
Note: See TracChangeset for help on using the changeset viewer.