IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Feb 5, 2009, 4:31:25 PM (17 years ago)
Author:
Paul Price
Message:

Merging pap_branch_20090128. Resolved a small number of conflicts. Compiles, but not tested in detail.

Location:
trunk/psModules/src/camera
Files:
22 edited

Legend:

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

    r19013 r21363  
    3232    psFree(readout->image);
    3333    psFree(readout->mask);
    34     psFree(readout->weight);
     34    psFree(readout->variance);
     35    psFree(readout->covariance);
    3536    psFree(readout->analysis);
    3637    psFree(readout->bias);
     
    163164    psFree(readout->image);
    164165    psFree(readout->mask);
    165     psFree(readout->weight);
     166    psFree(readout->variance);
     167    psFree(readout->covariance);
    166168    psFree(readout->bias);
    167169
     
    169171
    170172    readout->image = NULL;
    171     readout->weight = NULL;
     173    readout->variance = NULL;
     174    readout->covariance = NULL;
    172175    readout->mask = NULL;
    173176
     
    179182    readout->thisImageScan = 0;
    180183    readout->thisMaskScan = 0;
    181     readout->thisWeightScan = 0;
     184    readout->thisVarianceScan = 0;
    182185
    183186    readout->lastImageScan = 0;
    184187    readout->lastMaskScan = 0;
    185     readout->lastWeightScan = 0;
     188    readout->lastVarianceScan = 0;
    186189}
    187190
     
    197200    if (cell->hdu) {
    198201        psFree(cell->hdu->images);
    199         psFree(cell->hdu->weights);
     202        psFree(cell->hdu->variances);
    200203        psFree(cell->hdu->masks);
    201204        // psFree(cell->hdu->header);
    202205
    203206        cell->hdu->images = NULL;
    204         cell->hdu->weights = NULL;
     207        cell->hdu->variances = NULL;
    205208        cell->hdu->masks = NULL;
    206209        // cell->hdu->header = NULL;
     
    219222    if (chip->hdu) {
    220223        psFree(chip->hdu->images);
    221         psFree(chip->hdu->weights);
     224        psFree(chip->hdu->variances);
    222225        psFree(chip->hdu->masks);
    223226        // psFree(chip->hdu->header);
    224227
    225228        chip->hdu->images = NULL;
    226         chip->hdu->weights = NULL;
     229        chip->hdu->variances = NULL;
    227230        chip->hdu->masks = NULL;
    228231        // chip->hdu->header = NULL;
     
    241244    if (fpa->hdu) {
    242245        psFree(fpa->hdu->images);
    243         psFree(fpa->hdu->weights);
     246        psFree(fpa->hdu->variances);
    244247        psFree(fpa->hdu->masks);
    245248        // psFree(fpa->hdu->header);
    246249
    247250        fpa->hdu->images = NULL;
    248         fpa->hdu->weights = NULL;
     251        fpa->hdu->variances = NULL;
    249252        fpa->hdu->masks = NULL;
    250253        // fpa->hdu->header = NULL;
     
    259262    tmpReadout->image = NULL;
    260263    tmpReadout->mask = NULL;
    261     tmpReadout->weight = NULL;
     264    tmpReadout->variance = NULL;
     265    tmpReadout->covariance = NULL;
    262266    tmpReadout->bias = psListAlloc(NULL);
    263267    tmpReadout->analysis = psMetadataAlloc();
     
    276280    tmpReadout->thisImageScan = 0;
    277281    tmpReadout->thisMaskScan = 0;
    278     tmpReadout->thisWeightScan = 0;
     282    tmpReadout->thisVarianceScan = 0;
    279283
    280284    tmpReadout->lastImageScan = 0;
    281285    tmpReadout->lastMaskScan = 0;
    282     tmpReadout->lastWeightScan = 0;
     286    tmpReadout->lastVarianceScan = 0;
    283287
    284288    tmpReadout->forceScan = false;
  • trunk/psModules/src/camera/pmFPA.h

    r19013 r21363  
    66 * @author Eugene Magnier, IfA
    77 *
    8  * @version $Revision: 1.25 $ $Name: not supported by cvs2svn $
    9  * @date $Date: 2008-08-12 02:51:20 $
     8 * @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
     9 * @date $Date: 2009-02-06 02:31:24 $
    1010 * Copyright 2005-2006 Institute for Astronomy, University of Hawaii
    1111 */
     
    113113///
    114114/// A readout corresponds to an individual read of a cell (e.g., a single image as part of a video sequence,
    115 /// or one of multiple coadds).  It contains the actual pixels used in analysis (along with mask and weight
     115/// or one of multiple coadds).  It contains the actual pixels used in analysis (along with mask and variance
    116116/// maps).  When reading from a FITS file, the images are subimages (from CELL.TRIMSEC) of the pixels read
    117117/// from the appropriate HDU (at the FPA, chip or cell level).  The readout also contains a list of bias
     
    123123    psImage *image;                     ///< Imaging area of readout (corresponds to CELL.TRIMSEC region)
    124124    psImage *mask;                      ///< Mask of input image (corresponds to CELL.TRIMSEC region)
    125     psImage *weight;                    ///< Weight of input image (corresponds to CELL.TRIMSEC region)
     125    psImage *variance;                  ///< Variance of input image (corresponds to CELL.TRIMSEC region)
     126    psKernel *covariance;               ///< Covariance pseudo-matrix (covariance factors for single pixel)
    126127    psList *bias;                       ///< List of bias (prescan/overscan) images
    127128    psMetadata *analysis;               ///< Readout-level analysis metadata
     
    130131    bool file_exists;                   ///< Does the file for this readout exist (read case only)?
    131132    bool data_exists;                   ///< Does the data for this readout exist (read case only)?
    132     int thisImageScan;                  ///< start scan for next/current read
    133     int lastImageScan;                  ///< start scan of the last read
    134     int thisMaskScan;                   ///< start scan for next/current read
    135     int lastMaskScan;                   ///< start scan of the last read
    136     int thisWeightScan;                 ///< start scan for next/current read
    137     int lastWeightScan;                 ///< start scan of the last read
     133    int thisImageScan;                  ///< start scan for next/current read of image
     134    int lastImageScan;                  ///< start scan of the last read of image
     135    int thisMaskScan;                   ///< start scan for next/current read of mask
     136    int lastMaskScan;                   ///< start scan of the last read of mask
     137    int thisVarianceScan;               ///< start scan for next/current read of variance
     138    int lastVarianceScan;               ///< start scan of the last read of variance
    138139    bool forceScan;                     ///< Force pmFPARead to obey the above commanded this and last scans.
    139140} pmReadout;
     
    217218        } \
    218219    } \
    219     psImage *weight = (READOUT)->weight; /* Weight map pixels */ \
    220     if (weight) { \
    221         PS_ASSERT_IMAGE_NON_NULL((READOUT)->weight, RETVAL); \
    222         if ((numCols != 0 || numRows != 0) && (weight->numCols != numCols || weight->numRows != numRows)) { \
    223             psError(PS_ERR_BAD_PARAMETER_SIZE, true, "Weight in readout %s has wrong size (%dx%d vs %dx%d)", \
    224                     #READOUT, weight->numCols, weight->numRows, numCols, numRows); \
     220    psImage *variance = (READOUT)->variance; /* Variance map pixels */ \
     221    if (variance) { \
     222        PS_ASSERT_IMAGE_NON_NULL((READOUT)->variance, RETVAL); \
     223        if ((numCols != 0 || numRows != 0) && \
     224            (variance->numCols != numCols || variance->numRows != numRows)) { \
     225            psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
     226                    "Variance in readout %s has wrong size (%dx%d vs %dx%d)", \
     227                    #READOUT, variance->numCols, variance->numRows, numCols, numRows); \
    225228            return RETVAL; \
    226229        } \
     
    236239    PS_ASSERT_IMAGE_NON_NULL((READOUT)->mask, RETVAL);
    237240
    238 /// Assert that a readout contains a weight map
    239 #define PM_ASSERT_READOUT_WEIGHT(READOUT, RETVAL) \
    240     PS_ASSERT_IMAGE_NON_NULL((READOUT)->weight, RETVAL);
     241/// Assert that a readout contains a variance map
     242#define PM_ASSERT_READOUT_VARIANCE(READOUT, RETVAL) \
     243    PS_ASSERT_IMAGE_NON_NULL((READOUT)->variance, RETVAL);
     244
     245/// Assert that a readout contains a covariance matrix
     246#define PM_ASSERT_READOUT_COVARIANCE(READOUT, RETVAL) \
     247    PS_ASSERT_KERNEL_NON_NULL((READOUT)->covariance, RETVAL);
    241248
    242249/// @}
  • trunk/psModules/src/camera/pmFPAConstruct.c

    r17911 r21363  
    14991499                psImage *image = readout->image; // The image
    15001500                psImage *mask = readout->mask; // The mask
    1501                 psImage *weight = readout->weight; // The weight
     1501                psImage *variance = readout->variance; // The variance
    15021502                psList *bias = readout->bias; // The list of bias images
    15031503                if (image) {
    15041504                    INDENT(fd, 7);
    1505                     fprintf(fd, "Image: [%d:%d,%d:%d] (%dx%d)\n", image->col0, image->col0 +
    1506                             image->numCols, image->row0, image->row0 + image->numRows, image->numCols,
    1507                             image->numRows);
     1505                    fprintf(fd, "Image: [%d:%d,%d:%d] (%dx%d)\n",
     1506                            image->col0, image->col0 + image->numCols,
     1507                            image->row0, image->row0 + image->numRows,
     1508                            image->numCols, image->numRows);
    15081509                }
    15091510                if (bias) {
     
    15121513                    while ((biasImage = psListGetAndIncrement(biasIter))) {
    15131514                        INDENT(fd, 7);
    1514                         fprintf(fd, "Bias:  [%d:%d,%d:%d] (%dx%d)\n", biasImage->col0,
    1515                                 biasImage->col0 + biasImage->numCols, biasImage->row0,
    1516                                 biasImage->row0 + biasImage->numRows, biasImage->numCols, biasImage->numRows);
     1515                        fprintf(fd, "Bias:  [%d:%d,%d:%d] (%dx%d)\n",
     1516                                biasImage->col0, biasImage->col0 + biasImage->numCols,
     1517                                biasImage->row0, biasImage->row0 + biasImage->numRows,
     1518                                biasImage->numCols, biasImage->numRows);
    15171519                    }
    15181520                    psFree(biasIter);
     
    15201522                if (mask) {
    15211523                    INDENT(fd, 7);
    1522                     fprintf(fd, "Mask: [%d:%d,%d:%d] (%dx%d)\n", mask->col0, mask->col0 +
    1523                             mask->numCols, mask->row0, mask->row0 + mask->numRows, mask->numCols,
    1524                             mask->numRows);
     1524                    fprintf(fd, "Mask: [%d:%d,%d:%d] (%dx%d)\n",
     1525                            mask->col0, mask->col0 + mask->numCols,
     1526                            mask->row0, mask->row0 + mask->numRows,
     1527                            mask->numCols, mask->numRows);
    15251528                }
    1526                 if (weight) {
     1529                if (variance) {
    15271530                    INDENT(fd, 7);
    1528                     fprintf(fd, "Weight: [%d:%d,%d:%d] (%dx%d)\n", weight->col0, weight->col0 +
    1529                             weight->numCols, weight->row0, weight->row0 + weight->numRows, weight->numCols,
    1530                             weight->numRows);
     1531                    fprintf(fd, "Variance: [%d:%d,%d:%d] (%dx%d)\n",
     1532                            variance->col0, variance->col0 + variance->numCols,
     1533                            variance->row0, variance->row0 + variance->numRows,
     1534                            variance->numCols, variance->numRows);
    15311535                }
    15321536            } // Iterating over cell
  • trunk/psModules/src/camera/pmFPACopy.c

    r20634 r21363  
    224224        targetReadout->data_exists = sourceReadout->data_exists;
    225225
    226         // Copy all three image components (image, mask, weight)
    227         readoutCopyComponent(&targetReadout->image,  sourceReadout->image,  binning, xFlip, yFlip, pixels);
    228         readoutCopyComponent(&targetReadout->mask,   sourceReadout->mask,   binning, xFlip, yFlip, pixels);
    229         readoutCopyComponent(&targetReadout->weight, sourceReadout->weight, binning, xFlip, yFlip, pixels);
     226        // Copy all three image components (image, mask, variance)
     227        readoutCopyComponent(&targetReadout->image, sourceReadout->image, binning, xFlip, yFlip, pixels);
     228        readoutCopyComponent(&targetReadout->mask, sourceReadout->mask, binning, xFlip, yFlip, pixels);
     229        readoutCopyComponent(&targetReadout->variance, sourceReadout->variance, binning, xFlip, yFlip,
     230                             pixels);
    230231
    231232        // Copy bias
     
    328329        int xSize = psMetadataLookupS32(NULL, source->concepts, "CELL.XSIZE"); // CELL.XSIZE of source
    329330
    330         psAssert (abs(xParity) == 1, "CELL.XPARITY not set for source");
     331        psAssert (abs(xParity) == 1, "CELL.XPARITY not set for source");
    331332
    332333        if (sourceBin == 0) {
     
    478479        pmCell *targetCell = pmCellAlloc (targetChip, cellName);
    479480        int xParityTarget = psMetadataLookupS32(&status, sourceCell->concepts, "CELL.XPARITY"); // Target x parity
    480         psAssert (abs(xParityTarget) == 1, "CELL.XPARITY not set for target");
     481        psAssert (abs(xParityTarget) == 1, "CELL.XPARITY not set for target");
    481482        psMetadataAddS32 (targetCell->concepts, PS_LIST_TAIL, "CELL.XPARITY", PS_META_REPLACE, "", xParityTarget);
    482483        int yParityTarget = psMetadataLookupS32(&status, sourceCell->concepts, "CELL.YPARITY"); // Target y parity
    483         psAssert (abs(xParityTarget) == 1, "CELL.YPARITY not set for target");
     484        psAssert (abs(xParityTarget) == 1, "CELL.YPARITY not set for target");
    484485        psMetadataAddS32 (targetCell->concepts, PS_LIST_TAIL, "CELL.YPARITY", PS_META_REPLACE, "", yParityTarget);
    485486        if (!cellCopy(targetCell, sourceCell, true, 1, 1)) {
  • trunk/psModules/src/camera/pmFPAExtent.c

    r20635 r21363  
    1616    }
    1717    if (!image) {
    18         image = readout->weight;
     18        image = readout->variance;
    1919    }
    2020
     
    2323
    2424    if (!image) {
    25         pmHDU *hdu = pmHDUFromReadout (readout);
    26         if (hdu && hdu->header) {
    27             bool status;
    28             xSize = psMetadataLookupS32(&status, hdu->header, "NAXIS1");
    29             if (!status) {
    30                 xSize = psMetadataLookupS32(&status, hdu->header, "IMNAXIS1");
    31                 if (!status) return NULL;
    32             }           
    33             ySize = psMetadataLookupS32(&status, hdu->header, "NAXIS2");
    34             if (!status) {
    35                 ySize = psMetadataLookupS32(&status, hdu->header, "IMNAXIS2");
    36                 if (!status) return NULL;
    37             }           
    38         } else {
     25        pmHDU *hdu = pmHDUFromReadout (readout);
     26        if (hdu && hdu->header) {
     27            bool status;
     28            xSize = psMetadataLookupS32(&status, hdu->header, "NAXIS1");
     29            if (!status) {
     30                xSize = psMetadataLookupS32(&status, hdu->header, "IMNAXIS1");
     31                if (!status) return NULL;
     32            }
     33            ySize = psMetadataLookupS32(&status, hdu->header, "NAXIS2");
     34            if (!status) {
     35                ySize = psMetadataLookupS32(&status, hdu->header, "IMNAXIS2");
     36                if (!status) return NULL;
     37            }
     38        } else {
    3939        // Don't have anything to base the true extent on, so have to give the hardwired value (largest possible extent)
    40             xSize = psMetadataLookupS32(NULL, readout->parent->concepts, "CELL.XSIZE");
    41             ySize = psMetadataLookupS32(NULL, readout->parent->concepts, "CELL.YSIZE");
    42         }
     40            xSize = psMetadataLookupS32(NULL, readout->parent->concepts, "CELL.XSIZE");
     41            ySize = psMetadataLookupS32(NULL, readout->parent->concepts, "CELL.YSIZE");
     42        }
    4343        return psRegionAlloc(0, xSize, 0, ySize);
    4444    }
     
    7070    // Don't have anything to base the true extent on, so have to give the hardwired value (largest possible extent)
    7171    if (readouts->n == 0) {
    72         int xSize = psMetadataLookupS32(NULL, cell->concepts, "CELL.XSIZE");
    73         int ySize = psMetadataLookupS32(NULL, cell->concepts, "CELL.YSIZE");
    74         cellExtent->x0 = 0;
    75         cellExtent->x1 = xSize;
    76         cellExtent->y0 = 0;
    77         cellExtent->y1 = ySize;
     72        int xSize = psMetadataLookupS32(NULL, cell->concepts, "CELL.XSIZE");
     73        int ySize = psMetadataLookupS32(NULL, cell->concepts, "CELL.YSIZE");
     74        cellExtent->x0 = 0;
     75        cellExtent->x1 = xSize;
     76        cellExtent->y0 = 0;
     77        cellExtent->y1 = ySize;
    7878    }
    7979
     
    9797    // CELL.X0,Y0 are the coordinate of the amp on the chip, subtract size if parity flipped
    9898    if (xParityCell > 0) {
    99         cellExtent->x0 += x0;
    100         cellExtent->x1 += x0;
     99        cellExtent->x0 += x0;
     100        cellExtent->x1 += x0;
    101101    } else {
    102         float x0Cell = x0 - cellExtent->x1;
    103         float x1Cell = x0 - cellExtent->x0;
    104         cellExtent->x0 = x0Cell;
    105         cellExtent->x1 = x1Cell;
     102        float x0Cell = x0 - cellExtent->x1;
     103        float x1Cell = x0 - cellExtent->x0;
     104        cellExtent->x0 = x0Cell;
     105        cellExtent->x1 = x1Cell;
    106106    }
    107107    if (yParityCell > 0) {
    108         cellExtent->y0 += y0;
    109         cellExtent->y1 += y0;
     108        cellExtent->y0 += y0;
     109        cellExtent->y1 += y0;
    110110    } else {
    111         float y0Cell = y0 - cellExtent->y1;
    112         float y1Cell = y0 - cellExtent->y0;
    113         cellExtent->y0 = y0Cell;
    114         cellExtent->y1 = y1Cell;
     111        float y0Cell = y0 - cellExtent->y1;
     112        float y1Cell = y0 - cellExtent->y0;
     113        cellExtent->y0 = y0Cell;
     114        cellExtent->y1 = y1Cell;
    115115    }
    116116
  • trunk/psModules/src/camera/pmFPAMaskWeight.c

    r21183 r21363  
    4949}
    5050
    51 // Create the parent weight images that reside in the HDU
    52 static void createParentWeights(pmHDU *hdu // The HDU for which to create
     51// Create the parent variance images that reside in the HDU
     52static void createParentVariances(pmHDU *hdu // The HDU for which to create
    5353                               )
    5454{
     
    5858    // Generate the parent mask images
    5959    psArray *images = hdu->images;      // Array of images
    60     psArray *weights = hdu->weights;    // Array of weight images
    61     if (!weights) {
    62         weights = psArrayAlloc(images->n);
    63         hdu->weights = weights;
     60    psArray *variances = hdu->variances;    // Array of variance images
     61    if (!variances) {
     62        variances = psArrayAlloc(images->n);
     63        hdu->variances = variances;
    6464    }
    6565
    6666    for (long i = 0; i < images->n; i++) {
    6767        psImage *image = images->data[i]; // The image for this readout
    68         if (!image || weights->data[i]) {
     68        if (!image || variances->data[i]) {
    6969            continue;
    7070        }
    71         weights->data[i] = psImageAlloc(image->numCols, image->numRows, PS_TYPE_F32);
     71        variances->data[i] = psImageAlloc(image->numCols, image->numRows, PS_TYPE_F32);
    7272    }
    7373
     
    199199}
    200200
    201 bool pmReadoutSetWeight(pmReadout *readout, bool poisson)
     201bool pmReadoutSetVariance(pmReadout *readout, bool poisson)
    202202{
    203203    PS_ASSERT_PTR_NON_NULL(readout, false);
     
    209209    float gain = psMetadataLookupF32(&mdok, cell->concepts, "CELL.GAIN"); // Cell gain
    210210    if (!mdok || isnan(gain)) {
    211         psError(PS_ERR_IO, true, "CELL.GAIN is not set --- unable to set weight.\n");
     211        psError(PS_ERR_IO, true, "CELL.GAIN is not set --- unable to set variance.\n");
    212212        return false;
    213213    }
    214214    float readnoise = psMetadataLookupF32(&mdok, cell->concepts, "CELL.READNOISE"); // Cell read noise
    215215    if (!mdok || isnan(readnoise)) {
    216         psError(PS_ERR_IO, true, "CELL.READNOISE is not set --- unable to set weight.\n");
     216        psError(PS_ERR_IO, true, "CELL.READNOISE is not set --- unable to set variance.\n");
    217217        return false;
    218218    }
     
    223223
    224224    if (poisson) {
    225         // Set weight image to the variance in ADU = f/g + rn^2
     225        // Set variance image to the variance in ADU = f/g + rn^2
    226226        psImage *image = readout->image;    // The image pixels
    227         readout->weight = (psImage*)psBinaryOp(readout->weight, image, "/", psScalarAlloc(gain, PS_TYPE_F32));
    228 
    229         // a negative weight is non-sensical. if the image value drops below 1, the weight must be 1.
    230         readout->weight = (psImage*)psUnaryOp(readout->weight, readout->weight, "abs");
    231         readout->weight = (psImage*)psBinaryOp(readout->weight, readout->weight, "max",
     227        readout->variance = (psImage*)psBinaryOp(readout->variance, image, "/", psScalarAlloc(gain, PS_TYPE_F32));
     228
     229        // a negative variance is non-sensical. if the image value drops below 1, the variance must be 1.
     230        readout->variance = (psImage*)psUnaryOp(readout->variance, readout->variance, "abs");
     231        readout->variance = (psImage*)psBinaryOp(readout->variance, readout->variance, "max",
    232232                                               psScalarAlloc(1, PS_TYPE_F32));
    233233    } else {
    234234        // Just use the read noise
    235         if (!readout->weight) {
    236             readout->weight = psImageAlloc(readout->image->numCols, readout->image->numRows, PS_TYPE_F32);
    237         }
    238         psImageInit(readout->weight, 0.0);
    239     }
    240 
    241     readout->weight = (psImage*)psBinaryOp(readout->weight, readout->weight, "+",
     235        if (!readout->variance) {
     236            readout->variance = psImageAlloc(readout->image->numCols, readout->image->numRows, PS_TYPE_F32);
     237        }
     238        psImageInit(readout->variance, 0.0);
     239    }
     240
     241    readout->variance = (psImage*)psBinaryOp(readout->variance, readout->variance, "+",
    242242                                           psScalarAlloc(readnoise*readnoise/gain/gain, PS_TYPE_F32));
    243243
     
    245245}
    246246
    247 // this function creates the weight pixels, or uses the existing weight pixels.  it will set
    248 // the noise pixel values only if the weight image is not supplied
    249 bool pmReadoutGenerateWeight(pmReadout *readout, bool poisson)
     247// this function creates the variance pixels, or uses the existing variance pixels.  it will set
     248// the noise pixel values only if the variance image is not supplied
     249bool pmReadoutGenerateVariance(pmReadout *readout, bool poisson)
    250250{
    251251    PS_ASSERT_PTR_NON_NULL(readout, false);
     
    254254    bool mdok = true;                   // Status of MD lookup
    255255
    256     // Create the weight image if required
    257     if (readout->weight)
     256    // Create the variance image if required
     257    if (readout->variance)
    258258        return true;
    259259
    260260    psRegion *trimsec = psMetadataLookupPtr(&mdok, cell->concepts, "CELL.TRIMSEC"); // Trim section
    261261    if (!mdok || psRegionIsNaN(*trimsec)) {
    262         psError(PS_ERR_IO, true, "CELL.TRIMSEC is not set --- unable to set weight.\n");
     262        psError(PS_ERR_IO, true, "CELL.TRIMSEC is not set --- unable to set variance.\n");
    263263        return false;
    264264    }
     
    271271    }
    272272
    273     createParentWeights(hdu);
     273    createParentVariances(hdu);
    274274
    275275    // Need to identify which readout we're working with....
     
    280280    }
    281281
    282     psImage *weight = psImageSubset(hdu->weights->data[index], *trimsec); // The weight pixels
    283     if (!weight) {
     282    psImage *variance = psImageSubset(hdu->variances->data[index], *trimsec); // The variance pixels
     283    if (!variance) {
    284284        psString trimsecString = psRegionToString(*trimsec);
    285         psError(PS_ERR_UNKNOWN, false, "Unable to set weight from HDU with trimsec: %s.\n",
     285        psError(PS_ERR_UNKNOWN, false, "Unable to set variance from HDU with trimsec: %s.\n",
    286286                trimsecString);
    287287        psFree(trimsecString);
    288288        return false;
    289289    }
    290     psImageInit(weight, 0);
    291     readout->weight = weight;
    292 
    293     return pmReadoutSetWeight(readout, poisson);
    294 }
    295 
    296 bool pmReadoutGenerateMaskWeight(pmReadout *readout, psImageMaskType satMask, psImageMaskType badMask, bool poisson)
     290    psImageInit(variance, 0);
     291    readout->variance = variance;
     292
     293    return pmReadoutSetVariance(readout, poisson);
     294}
     295
     296bool pmReadoutGenerateMaskVariance(pmReadout *readout, psImageMaskType satMask, psImageMaskType badMask, bool poisson)
    297297{
    298298    PS_ASSERT_PTR_NON_NULL(readout, false);
     
    301301
    302302    success &= pmReadoutGenerateMask(readout, satMask, badMask);
    303     success &= pmReadoutGenerateWeight(readout, poisson);
     303    success &= pmReadoutGenerateVariance(readout, poisson);
    304304
    305305    return success;
    306306}
    307307
    308 bool pmCellGenerateMaskWeight(pmCell *cell, psImageMaskType satMask, psImageMaskType badMask, bool poisson)
     308bool pmCellGenerateMaskVariance(pmCell *cell, psImageMaskType satMask, psImageMaskType badMask, bool poisson)
    309309{
    310310    PS_ASSERT_PTR_NON_NULL(cell, false);
     
    314314    for (int i = 0; i < readouts->n; i++) {
    315315        pmReadout *readout = readouts->data[i]; // The readout
    316         success &= pmReadoutGenerateMaskWeight(readout, poisson, satMask, badMask);
     316        success &= pmReadoutGenerateMaskVariance(readout, poisson, satMask, badMask);
    317317    }
    318318
     
    321321
    322322
    323 bool pmReadoutWeightRenormPixels(const pmReadout *readout, psImageMaskType maskVal,
     323bool pmReadoutVarianceRenormPixels(const pmReadout *readout, psImageMaskType maskVal,
    324324                                 psStatsOptions meanStat, psStatsOptions stdevStat, psRandom *rng)
    325325{
    326326    PM_ASSERT_READOUT_NON_NULL(readout, false);
    327327    PM_ASSERT_READOUT_IMAGE(readout, false);
    328     PM_ASSERT_READOUT_WEIGHT(readout, false);
    329 
    330     psImage *image = readout->image, *mask = readout->mask, *weight = readout->weight; // Readout parts
     328    PM_ASSERT_READOUT_VARIANCE(readout, false);
     329
     330    psImage *image = readout->image, *mask = readout->mask, *variance = readout->variance; // Readout parts
    331331
    332332    if (!psMemIncrRefCounter(rng)) {
     
    334334    }
    335335
    336     psStats *weightStats = psStatsAlloc(meanStat);// Statistics for mean
    337     if (!psImageBackground(weightStats, NULL, weight, mask, maskVal, rng)) {
    338         psError(PS_ERR_UNKNOWN, false, "Unable to measure mean weight for image");
    339         psFree(weightStats);
     336    psStats *varianceStats = psStatsAlloc(meanStat);// Statistics for mean
     337    if (!psImageBackground(varianceStats, NULL, variance, mask, maskVal, rng)) {
     338        psError(PS_ERR_UNKNOWN, false, "Unable to measure mean variance for image");
     339        psFree(varianceStats);
    340340        psFree(rng);
    341341        return false;
    342342    }
    343     float meanVariance = weightStats->robustMedian; // Mean variance
    344     psFree(weightStats);
     343    float meanVariance = varianceStats->robustMedian; // Mean variance
     344    psFree(varianceStats);
    345345
    346346    psStats *imageStats = psStatsAlloc(stdevStat);// Statistics for mean
     
    356356
    357357    float correction = PS_SQR(stdevImage) / meanVariance; // Correction to take variance to what it should be
    358     psLogMsg("psModules.camera", PS_LOG_INFO, "Renormalising weight map by %f", correction);
    359     psBinaryOp(weight, weight, "*", psScalarAlloc(correction, PS_TYPE_F32));
     358    psLogMsg("psModules.camera", PS_LOG_INFO, "Renormalising variance map by %f", correction);
     359    psBinaryOp(variance, variance, "*", psScalarAlloc(correction, PS_TYPE_F32));
    360360
    361361    return true;
     
    363363
    364364
    365 bool pmReadoutWeightRenormPhot(const pmReadout *readout, psImageMaskType maskVal, int num, float width,
     365bool pmReadoutVarianceRenormPhot(const pmReadout *readout, psImageMaskType maskVal, int num, float width,
    366366                               psStatsOptions meanStat, psStatsOptions stdevStat, psRandom *rng)
    367367{
    368368    PM_ASSERT_READOUT_NON_NULL(readout, false);
    369369    PM_ASSERT_READOUT_IMAGE(readout, false);
    370     PM_ASSERT_READOUT_WEIGHT(readout, false);
     370    PM_ASSERT_READOUT_VARIANCE(readout, false);
    371371
    372372    if (!psMemIncrRefCounter(rng)) {
     
    374374    }
    375375
    376     psImage *image = readout->image, *mask = readout->mask, *weight = readout->weight; // Readout images
     376    psImage *image = readout->image, *mask = readout->mask, *variance = readout->variance; // Readout images
    377377
    378378    // Measure background
     
    424424        float sumNoise = 0.0;       // Sum for noise measurement
    425425        float sumSource = 0.0;      // Sum for source measurement
    426         float sumWeight = 0.0;      // Sum for weight measurement
     426        float sumVariance = 0.0;      // Sum for variance measurement
    427427        float sumGauss = 0.0, sumGauss2 = 0.0; // Sums of Gaussian kernels
    428428        for (int v = 0, y = yPix - size; v < fullSize; v++, y++) {
    429429            float xSumNoise = 0.0;  // Sum for noise measurement in x
    430430            float xSumSource = 0.0; // Sum for source measurement in x
    431             float xSumWeight = 0.0; // Sum for weight measurement in x
     431            float xSumVariance = 0.0; // Sum for variance measurement in x
    432432            float xSumGauss = 0.0, xSumGauss2 = 0.0; // Sums of Gaussian kernels in x
    433433            float yGauss = gauss->data.F32[v]; // Value of Gaussian in y
     
    441441                xSumNoise += value * xGauss;
    442442                xSumSource += (value + peakFlux * xGauss * yGauss) * xGauss;
    443                 xSumWeight += weight->data.F32[y][x] * xGauss2;
     443                xSumVariance += variance->data.F32[y][x] * xGauss2;
    444444                xSumGauss += xGauss;
    445445                xSumGauss2 += xGauss2;
     
    448448            sumNoise += xSumNoise * yGauss;
    449449            sumSource += xSumSource * yGauss;
    450             sumWeight += xSumWeight * yGauss2;
     450            sumVariance += xSumVariance * yGauss2;
    451451            sumGauss += xSumGauss * yGauss;
    452452            sumGauss2 += xSumGauss2 * yGauss2;
     
    454454
    455455        photMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = ((isfinite(sumNoise) && isfinite(sumSource) &&
    456                                                 isfinite(sumWeight) && sumGauss > 0 && sumGauss2 > 0) ?
     456                                                isfinite(sumVariance) && sumGauss > 0 && sumGauss2 > 0) ?
    457457                                               0 : 0xFF);
    458458
    459459        float smoothImageNoise = sumNoise / sumGauss; // Value of smoothed image pixel for noise
    460460        float smoothImageSource = sumSource / sumGauss; // Value of smoothed image pixel for source
    461         float smoothWeight = sumWeight / sumGauss2; // Value of smoothed weight pixel
     461        float smoothVariance = sumVariance / sumGauss2; // Value of smoothed variance pixel
    462462
    463463        noise->data.F32[i] = smoothImageNoise;
    464464        source->data.F32[i] = smoothImageSource;
    465         guess->data.F32[i] = (sumSource > 0) ? sigFactor * PS_SQR(smoothImageSource) / smoothWeight : 0.0;
     465        guess->data.F32[i] = (sumSource > 0) ? sigFactor * PS_SQR(smoothImageSource) / smoothVariance : 0.0;
    466466        psTrace("psModules.camera", 10, "Flux %d (%d,%d): %f, %f, %f\n",
    467                 i, xPix, yPix, smoothImageNoise, smoothImageSource, smoothWeight);
     467                i, xPix, yPix, smoothImageNoise, smoothImageSource, smoothVariance);
    468468    }
    469469    psFree(gauss);
     
    516516    psFree(photMask);
    517517
    518     psLogMsg("psModules.camera", PS_LOG_INFO, "Renormalising weight map by %f", meanRatio);
    519     psBinaryOp(weight, weight, "*", psScalarAlloc(meanRatio, PS_TYPE_F32));
     518    psLogMsg("psModules.camera", PS_LOG_INFO, "Renormalising variance map by %f", meanRatio);
     519    psBinaryOp(variance, variance, "*", psScalarAlloc(meanRatio, PS_TYPE_F32));
    520520
    521521    return true;
     
    523523
    524524
    525 bool pmReadoutWeightRenorm(const pmReadout *readout, psImageMaskType maskVal, psStatsOptions meanStat,
     525bool pmReadoutVarianceRenorm(const pmReadout *readout, psImageMaskType maskVal, psStatsOptions meanStat,
    526526                           psStatsOptions stdevStat, int width, psRandom *rng)
    527527{
    528528    PM_ASSERT_READOUT_NON_NULL(readout, false);
    529529    PM_ASSERT_READOUT_IMAGE(readout, false);
    530     PM_ASSERT_READOUT_WEIGHT(readout, false);
     530    PM_ASSERT_READOUT_VARIANCE(readout, false);
    531531    PS_ASSERT_INT_POSITIVE(width, false);
    532532
     
    535535    }
    536536
    537     psImage *image = readout->image, *mask = readout->mask, *weight = readout->weight; // Readout images
     537    psImage *image = readout->image, *mask = readout->mask, *variance = readout->variance; // Readout images
    538538    int numCols = image->numCols, numRows = image->numRows; // Size of images
    539539    int xNum = numCols / width + 1, yNum = numRows / width + 1; // Number of renormalisation regions
     
    554554            psRegion region = psRegionSet(xMin, xMax, yMin, yMax); // Region of interest
    555555            psImage *subImage = psImageSubset(image, region); // Sub-image of the image pixels
    556             psImage *subWeight = psImageSubset(weight, region); // Sub image of the weight pixels
     556            psImage *subVariance = psImageSubset(variance, region); // Sub image of the variance pixels
    557557            psImage *subMask = mask ? psImageSubset(mask, region) : NULL; // Sub-image of the mask pixels
    558558
    559559            if (!psImageBackground(stdevStats, &buffer, subImage, subMask, maskVal, rng) ||
    560                 !psImageBackground(meanStats, &buffer, subWeight, subMask, maskVal, rng)) {
     560                !psImageBackground(meanStats, &buffer, subVariance, subMask, maskVal, rng)) {
    561561                // Nothing we can do about it, but don't want to keel over and die, so do our best to flag it.
    562562                psString regionStr = psRegionToString(region); // String with region
     
    564564                psFree(regionStr);
    565565                psErrorClear();
    566                 psImageInit(subWeight, NAN);
     566                psImageInit(subVariance, NAN);
    567567                if (subMask) {
    568568                    psImageInit(subMask, maskVal);
     
    574574                        "Region [%d:%d,%d:%d] has variance %lf, but mean of variance map is %lf\n",
    575575                        xMin, xMax, yMin, yMax, PS_SQR(stdev), meanVar);
    576                 psBinaryOp(subWeight, subWeight, "*", psScalarAlloc(PS_SQR(stdev) / meanVar, PS_TYPE_F32));
     576                psBinaryOp(subVariance, subVariance, "*", psScalarAlloc(PS_SQR(stdev) / meanVar, PS_TYPE_F32));
    577577            }
    578578
    579579            psFree(subImage);
    580             psFree(subWeight);
     580            psFree(subVariance);
    581581            psFree(subMask);
    582582        }
     
    597597
    598598    psImage *image = readout->image;    // Readout's image
    599     psImage *weight = readout->weight;  // Readout's weight
     599    psImage *variance = readout->variance;  // Readout's variance
    600600    int numCols = image->numCols, numRows = image->numRows; // Size of image
    601601
     
    607607    for (int y = 0; y < numRows; y++) {
    608608        for (int x = 0; x < numCols; x++) {
    609             if (!isfinite(image->data.F32[y][x]) || (weight && !isfinite(weight->data.F32[y][x]))) {
     609            if (!isfinite(image->data.F32[y][x]) || (variance && !isfinite(variance->data.F32[y][x]))) {
    610610                mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= maskVal;
    611611            }
     
    627627    psImageMaskType **maskData = readout->mask->data.PS_TYPE_IMAGE_MASK_DATA; // Dereference mask
    628628    psF32 **imageData = readout->image->data.F32;// Dereference image
    629     psF32 **weightData = readout->weight ? readout->weight->data.F32 : NULL; // Dereference weight map
     629    psF32 **varianceData = readout->variance ? readout->variance->data.F32 : NULL; // Dereference variance map
    630630
    631631    for (int y = 0; y < numRows; y++) {
     
    633633            if (maskData[y][x] & maskVal) {
    634634                imageData[y][x] = NAN;
    635                 if (weightData) {
    636                     weightData[y][x] = NAN;
     635                if (varianceData) {
     636                    varianceData[y][x] = NAN;
    637637                }
    638638            }
     
    656656    psImage *image = readout->image;    // Image
    657657    psImage *mask = readout->mask;      // Mask
    658     psImage *weight = readout->weight;  // Weight map
    659 
    660     psImageInterpolation *interp = psImageInterpolationAlloc(mode, image, weight, mask, maskVal,
     658    psImage *variance = readout->variance;  // Variance map
     659
     660    psImageInterpolation *interp = psImageInterpolationAlloc(mode, image, variance, mask, maskVal,
    661661                                                             NAN, NAN, maskBad, maskPoor, poorFrac, 0);
    662662    interp->shifting = false;           // Turn off "exact shifts" so we get proper interpolation
     
    666666    psPixels *pixels = psPixelsAllocEmpty(PIXELS_BUFFER); // Pixels that have been interpolated
    667667    psVector *imagePix = psVectorAllocEmpty(PIXELS_BUFFER, PS_TYPE_F32); // Corresponding values for image
    668     psVector *weightPix = psVectorAllocEmpty(PIXELS_BUFFER, PS_TYPE_F32); // Corresponding values for weight
     668    psVector *variancePix = psVectorAllocEmpty(PIXELS_BUFFER, PS_TYPE_F32); // Corresponding values for variance
    669669    psVector *maskPix = psVectorAllocEmpty(PIXELS_BUFFER, PS_TYPE_IMAGE_MASK); // Corresponding values for mask
    670670    // NOTE: maskPix carries the actual image mask values -- do NOT use
     
    675675        for (int x = 0; x < numCols; x++) {
    676676            if (mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal) {
    677                 double imageValue, weightValue; // Image and weight value from interpolation
     677                double imageValue, varianceValue; // Image and variance value from interpolation
    678678                psImageMaskType maskValue = 0; // Mask value from interpolation
    679                 psImageInterpolateStatus status = psImageInterpolate(&imageValue, &weightValue, &maskValue, x, y, interp);
     679                psImageInterpolateStatus status = psImageInterpolate(&imageValue, &varianceValue, &maskValue, x, y, interp);
    680680                if (status == PS_INTERPOLATE_STATUS_ERROR || status == PS_INTERPOLATE_STATUS_OFF) {
    681681                    psError(PS_ERR_UNKNOWN, false, "Unable to interpolate readout at %d,%d", x, y);
     
    683683                    psFree(pixels);
    684684                    psFree(imagePix);
    685                     psFree(weightPix);
     685                    psFree(variancePix);
    686686                    psFree(maskPix);
    687687                    return false;
     
    694694                pixels = psPixelsAdd(pixels, PIXELS_BUFFER, x, y);
    695695                imagePix = psVectorExtend(imagePix, PIXELS_BUFFER, 1);
    696                 weightPix = psVectorExtend(weightPix, PIXELS_BUFFER, 1);
     696                variancePix = psVectorExtend(variancePix, PIXELS_BUFFER, 1);
    697697                maskPix = psVectorExtend(maskPix, PIXELS_BUFFER, 1);
    698698                imagePix->data.F32[numBad] = imageValue;
    699                 weightPix->data.F32[numBad] = weightValue;
     699                variancePix->data.F32[numBad] = varianceValue;
    700700                maskPix->data.PS_TYPE_IMAGE_MASK_DATA[numBad] = maskValue;
    701701                numBad++;
     
    709709        int x = pixels->data[i].x, y = pixels->data[i].y; // Coordinates of pixel
    710710        image->data.F32[y][x] = imagePix->data.F32[i];
    711         weight->data.F32[y][x] = weightPix->data.F32[i];
     711        variance->data.F32[y][x] = variancePix->data.F32[i];
    712712        mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] = maskPix->data.PS_TYPE_IMAGE_MASK_DATA[i];
    713713    }
     
    715715    psFree(pixels);
    716716    psFree(imagePix);
    717     psFree(weightPix);
     717    psFree(variancePix);
    718718    psFree(maskPix);
    719719
  • trunk/psModules/src/camera/pmFPAMaskWeight.h

    r21183 r21363  
    55 * @author Eugene Magnier, IfA
    66 *
    7  * @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
    8  * @date $Date: 2009-01-27 06:39:38 $
     7 * @version $Revision: 1.18 $ $Name: not supported by cvs2svn $
     8 * @date $Date: 2009-02-06 02:31:24 $
    99 * Copyright 2005-2006 Institute for Astronomy, University of Hawaii
    1010 */
     
    4747
    4848
    49 /// Set a temporary readout weight map using CELL.GAIN and CELL.READNOISE
     49/// Set a temporary readout variance map using CELL.GAIN and CELL.READNOISE
    5050///
    51 /// Calculates weights (actually variances) for each pixel using photon statistics and the cell gain
    52 /// (CELL.GAIN) and read noise (CELL.READNOISE).  The weight map that is produced within the readout is
    53 /// temporary --- it is not added to the HDU.  This is intended for when the user is iterating using
    54 /// pmReadoutReadNext, in which case the HDU can't be generated.
    55 bool pmReadoutSetWeight(pmReadout *readout, ///< Readout for which to set weight
    56                         bool poisson    ///< Use poisson weights (in addition to read noise)?
    57                        );
     51/// Calculates variances for each pixel using photon statistics and the cell gain (CELL.GAIN) and read noise
     52/// (CELL.READNOISE).  The weight map that is produced within the readout is temporary --- it is not added to
     53/// the HDU.  This is intended for when the user is iterating using pmReadoutReadNext, in which case the HDU
     54/// can't be generated.
     55bool pmReadoutSetVariance(pmReadout *readout, ///< Readout for which to set variance
     56                          bool poisson    ///< Include poisson variance (in addition to read noise)?
     57    );
    5858
    5959/// Generate a readout mask (suitable for output) using CELL.SATURATION and CELL.BAD
     
    6666    );
    6767
    68 /// Generate a weight map (suitable for output) using CELL.GAIN and CELL.READNOISE
     68/// Generate a variance map (suitable for output) using CELL.GAIN and CELL.READNOISE
    6969///
    70 /// Calculates weights (actually variances) for each pixel using photon statistics and the cell gain
    71 /// (CELL.GAIN) and read noise (CELL.READNOISE).  The weight map that is produced within the readout is
    72 /// suitable for output (complete with HDU entry).  This is intended for most operations.
    73 bool pmReadoutGenerateWeight(pmReadout *readout, ///< Readout for which to generate weight
    74                              bool poisson    ///< Use poisson weights (in addition to read noise)?
    75                             );
     70/// Calculates variances for each pixel using photon statistics and the cell gain (CELL.GAIN) and read noise
     71/// (CELL.READNOISE).  The variance map that is produced within the readout is suitable for output (complete
     72/// with HDU entry).  This is intended for most operations.
     73bool pmReadoutGenerateVariance(pmReadout *readout, ///< Readout for which to generate variance
     74                               bool poisson    ///< Include poisson variance (in addition to read noise)?
     75    );
    7676
    77 /// Generate mask and weight map for a readout
     77/// Generate mask and variance map for a readout
    7878///
    79 /// Calls pmReadoutGenerateMask and pmReadoutGenerateWeight for the readout
    80 bool pmReadoutGenerateMaskWeight(pmReadout *readout, ///< Readout for which to generate mask and weights
    81                                  psImageMaskType sat, ///< Mask value to give saturated pixels
    82                                  psImageMaskType bad, ///< Mask value to give bad (low) pixels
    83                                  bool poisson ///< Use poisson weights (in addition to read noise)?
    84                                 );
     79/// Calls pmReadoutGenerateMask and pmReadoutGenerateVariance for the readout
     80bool pmReadoutGenerateMaskVariance(pmReadout *readout, ///< Readout for which to generate mask and variance
     81                                   psImageMaskType sat, ///< Mask value to give saturated pixels
     82                                   psImageMaskType bad, ///< Mask value to give bad (low) pixels
     83                                   bool poisson ///< Include poisson variance (in addition to read noise)?
     84    );
    8585
    86 /// Generate mask and weight maps for all readouts within a cell
     86/// Generate mask and variance maps for all readouts within a cell
    8787///
    88 /// Calls pmReadoutGenerateMaskWeight for each readout within the cell.
    89 bool pmCellGenerateMaskWeight(pmCell *cell, ///< Cell for which to generate mask and weights
    90                               psImageMaskType sat, ///< Mask value to give saturated pixels
    91                               psImageMaskType bad, ///< Mask value to give bad (low) pixels
    92                               bool poisson ///< Use poisson weights (in addition to read noise)?
    93                              );
     88/// Calls pmReadoutGenerateMaskVariance for each readout within the cell.
     89bool pmCellGenerateMaskVariance(pmCell *cell, ///< Cell for which to generate mask and variance
     90                                psImageMaskType sat, ///< Mask value to give saturated pixels
     91                                psImageMaskType bad, ///< Mask value to give bad (low) pixels
     92                                bool poisson ///< Include poisson variance (in addition to read noise)?
     93    );
    9494
    95 /// Renormalise the weight map to match the actual pixel variance
     95/// Renormalise the variance map to match the actual pixel variance
    9696///
    97 /// The weight (variance) map is adjusted so that the mean matches the actual pixel variance in the image
    98 bool pmReadoutWeightRenormPixels(
     97/// The variance map is adjusted so that the mean matches the actual pixel variance in the image
     98bool pmReadoutVarianceRenormPixels(
    9999    const pmReadout *readout,           ///< Readout to normalise
    100100    psImageMaskType maskVal,                 ///< Value to mask
     
    104104    );
    105105
    106 /// Renormalise the weight map to match the actual photometry variance
     106/// Renormalise the variance map to match the actual photometry variance
    107107///
    108 /// The weight (variance) map is adjusted so that the actual significance of fake sources matches the
     108/// The variance map is adjusted so that the actual significance of fake sources matches the
    109109/// guestimated significance
    110 bool pmReadoutWeightRenormPhot(
     110bool pmReadoutVarianceRenormPhot(
    111111    const pmReadout *readout,           ///< Readout to normalise
    112     psImageMaskType maskVal,                 ///< Value to mask
     112    psImageMaskType maskVal,            ///< Value to mask
    113113    int num,                            ///< Number of instances to measure over the image
    114114    float width,                        ///< Photometry width
     
    118118    );
    119119
    120 /// Renormalise the weight map to match the actual variance
     120/// Renormalise the variance map to match the actual variance
    121121///
    122122/// The variance in the image is measured in patches, and the variance map is adjusted so that the mean for
    123123/// that patch corresponds.
    124 bool pmReadoutWeightRenorm(const pmReadout *readout, // Readout to normalise
    125                            psImageMaskType maskVal, // Value to mask
    126                            psStatsOptions meanStat, // Statistic to measure the mean (of the variance map)
    127                            psStatsOptions stdevStat, // Statistic to measure the stdev (of the image)
    128                            int width,   // Width of patch (pixels)
    129                            psRandom *rng // Random number generator (for sub-sampling images)
     124bool pmReadoutVarianceRenorm(const pmReadout *readout, // Readout to normalise
     125                             psImageMaskType maskVal, // Value to mask
     126                             psStatsOptions meanStat, // Statistic to measure the mean (of the variance map)
     127                             psStatsOptions stdevStat, // Statistic to measure the stdev (of the image)
     128                             int width,   // Width of patch (pixels)
     129                             psRandom *rng // Random number generator (for sub-sampling images)
    130130    );
    131131
     
    133133///
    134134/// Since unmasked non-finite pixels can occur (e.g., by out-of-range in quantisation), it is sometimes
    135 /// necessary to mask them explicitly.  Non-finite pixels in the image or weight have their mask OR-ed with
     135/// necessary to mask them explicitly.  Non-finite pixels in the image or variance have their mask OR-ed with
    136136/// the provided value.
    137137bool pmReadoutMaskNonfinite(pmReadout *readout, ///< Readout to mask
     
    139139    );
    140140
    141 /// Apply a mask to the image and weight map
     141/// Apply a mask to the image and variance map
    142142///
    143143/// Unfortunately, image subtraction may result in a bi-modal image in masked areas, which can upset image
    144144/// statistics (very important for quantising images so that a product can be written out!).  This function
    145 /// sets masked areas to NAN in the image and weight.
     145/// sets masked areas to NAN in the image and variance.
    146146bool pmReadoutMaskApply(pmReadout *readout, ///< Readout to mask
    147147                        psImageMaskType maskVal ///< Mask value for which to apply mask
  • trunk/psModules/src/camera/pmFPAMosaic.c

    r21183 r21363  
    554554        // We have to do all of the hard work ourselves
    555555        switch (type) {
    556             FILL_IN(U8);
    557             FILL_IN(U16);
    558             FILL_IN(U32);
    559             FILL_IN(U64);
    560             FILL_IN(S8);
    561             FILL_IN(S16);
    562             FILL_IN(S32);
    563             FILL_IN(S64);
    564             FILL_IN(F32);
    565             FILL_IN(F64);
     556            FILL_IN(U8);
     557            FILL_IN(U16);
     558            FILL_IN(U32);
     559            FILL_IN(U64);
     560            FILL_IN(S8);
     561            FILL_IN(S16);
     562            FILL_IN(S32);
     563            FILL_IN(S64);
     564            FILL_IN(F32);
     565            FILL_IN(F64);
    566566          default:
    567567            psAbort("Should never get here.\n");
     
    575575static bool addCell(psArray *images,    // Array of images
    576576                    psArray *masks,     // Array of masks
    577                     psArray *weights,   // Array of weights
     577                    psArray *variances,   // Array of variances
    578578                    psVector *x0,       // Array of X0
    579579                    psVector *y0,       // Array of Y0
     
    604604        images  = psArrayRealloc(images,  index + CELL_LIST_BUFFER);
    605605        masks   = psArrayRealloc(masks,   index + CELL_LIST_BUFFER);
    606         weights = psArrayRealloc(weights, index + CELL_LIST_BUFFER);
     606        variances = psArrayRealloc(variances, index + CELL_LIST_BUFFER);
    607607        x0    = psVectorRealloc(x0,    index+ CELL_LIST_BUFFER);
    608608        y0    = psVectorRealloc(y0,    index+ CELL_LIST_BUFFER);
     
    615615    images->n = index + 1;
    616616    masks->n = index + 1;
    617     weights->n = index + 1;
     617    variances->n = index + 1;
    618618    x0->n = index + 1;
    619619    y0->n = index + 1;
     
    726726    // The images to put into the mosaic
    727727    images->data[index]  = psMemIncrRefCounter(readout->image);
    728     weights->data[index] = psMemIncrRefCounter(readout->weight);
     728    variances->data[index] = psMemIncrRefCounter(readout->variance);
    729729    masks->data[index]   = psMemIncrRefCounter(readout->mask);
    730730
     
    740740static bool chipMosaic(psImage **mosaicImage, // The mosaic image, to be returned
    741741                       psImage **mosaicMask, // The mosaic mask, to be returned
    742                        psImage **mosaicWeights, // The mosaic weights, to be returned
     742                       psImage **mosaicVariances, // The mosaic variances, to be returned
    743743                       int *xBinChip, int *yBinChip, // The binning in x and y, to be returned
    744744                       const pmChip *chip, // Chip to mosaic
     
    749749    assert(mosaicImage);
    750750    assert(mosaicMask);
    751     assert(mosaicWeights);
     751    assert(mosaicVariances);
    752752    assert(xBinChip);
    753753    assert(yBinChip);
     
    756756
    757757    psArray *images = psArrayAlloc(0); // Array of images that will be mosaicked
    758     psArray *weights = psArrayAlloc(0); // Array of weight images to be mosaicked
     758    psArray *variances = psArrayAlloc(0); // Array of variance images to be mosaicked
    759759    psArray *masks = psArrayAlloc(0); // Array of mask images to be mosaicked
    760760    psVector *x0 = psVectorAlloc(0, PS_TYPE_S32); // Origin x coordinates
     
    802802            continue;
    803803        }
    804         allGood &= addCell(images, masks, weights, x0, y0, xBin, yBin, xFlip, yFlip,
     804        allGood &= addCell(images, masks, variances, x0, y0, xBin, yBin, xFlip, yFlip,
    805805                           cell, xBinChip, yBinChip, false, x0Target, y0Target,
    806806                           xParityTarget, yParityTarget);
     
    826826    if (allGood) {
    827827        *mosaicImage = imageMosaic(images, xFlip, yFlip, xBin, yBin, *xBinChip, *yBinChip, x0, y0, BLANK_VALUE);
    828         *mosaicWeights = imageMosaic(weights, xFlip, yFlip, xBin, yBin, *xBinChip, *yBinChip, x0, y0, BLANK_VALUE);
     828        *mosaicVariances = imageMosaic(variances, xFlip, yFlip, xBin, yBin, *xBinChip, *yBinChip, x0, y0, BLANK_VALUE);
    829829        *mosaicMask = imageMosaic(masks, xFlip, yFlip, xBin, yBin, *xBinChip, *yBinChip, x0, y0, blank);
    830830    }
     
    832832    // Clean up
    833833    psFree(images);
    834     psFree(weights);
     834    psFree(variances);
    835835    psFree(masks);
    836836    psFree(xFlip);
     
    847847static bool fpaMosaic(psImage **mosaicImage, // The mosaic image, to be returned
    848848                      psImage **mosaicMask, // The mosaic mask, to be returned
    849                       psImage **mosaicWeights, // The mosaic weights, to be returned
     849                      psImage **mosaicVariances, // The mosaic variances, to be returned
    850850                      int *xBinFPA, int *yBinFPA, // The binning in x and y, to be returned
    851851                      const pmFPA *fpa,  // FPA to mosaic
     
    857857    assert(mosaicImage);
    858858    assert(mosaicMask);
    859     assert(mosaicWeights);
     859    assert(mosaicVariances);
    860860    assert(xBinFPA);
    861861    assert(yBinFPA);
     
    865865
    866866    psArray *images = psArrayAlloc(0); // Array of images that will be mosaicked
    867     psArray *weights = psArrayAlloc(0); // Array of weight images to be mosaicked
     867    psArray *variances = psArrayAlloc(0); // Array of variance images to be mosaicked
    868868    psArray *masks = psArrayAlloc(0); // Array of mask images to be mosaicked
    869869    psVector *x0 = psVectorAlloc(0, PS_TYPE_S32); // Origin x coordinates
     
    941941                continue;
    942942            }
    943             allGood |= addCell(images, masks, weights, x0, y0, xBin, yBin, xFlip, yFlip,
     943            allGood |= addCell(images, masks, variances, x0, y0, xBin, yBin, xFlip, yFlip,
    944944                               cell, xBinFPA, yBinFPA, true, x0Target, y0Target,
    945945                               xParityTarget, yParityTarget);
     
    960960    if (allGood) {
    961961        *mosaicImage = imageMosaic(images, xFlip, yFlip, xBin, yBin, *xBinFPA, *yBinFPA, x0, y0, BLANK_VALUE);
    962         *mosaicWeights = imageMosaic(weights, xFlip, yFlip, xBin, yBin, *xBinFPA, *yBinFPA, x0, y0, BLANK_VALUE);
     962        *mosaicVariances = imageMosaic(variances, xFlip, yFlip, xBin, yBin, *xBinFPA, *yBinFPA, x0, y0, BLANK_VALUE);
    963963        *mosaicMask = imageMosaic(masks, xFlip, yFlip, xBin, yBin, *xBinFPA, *yBinFPA, x0, y0, blank);
    964964    }
     
    966966    // Clean up
    967967    psFree(images);
    968     psFree(weights);
     968    psFree(variances);
    969969    psFree(masks);
    970970    psFree(xFlip);
     
    10251025    psImage *mosaicImage   = NULL;      // The mosaic image
    10261026    psImage *mosaicMask    = NULL;      // The mosaic mask
    1027     psImage *mosaicWeights = NULL;      // The mosaic weights
     1027    psImage *mosaicVariances = NULL;      // The mosaic variances
    10281028
    10291029    // Find the HDU
     
    10511051            }
    10521052        }
    1053         if (hdu->weights) {
    1054             mosaicWeights = psImageSubset(hdu->weights->data[0], bounds);
    1055             if (!mosaicWeights) {
    1056                 psError(PS_ERR_UNKNOWN, false, "Unable to select weight pixels.\n");
     1053        if (hdu->variances) {
     1054            mosaicVariances = psImageSubset(hdu->variances->data[0], bounds);
     1055            if (!mosaicVariances) {
     1056                psError(PS_ERR_UNKNOWN, false, "Unable to select variance pixels.\n");
    10571057                return false;
    10581058            }
     
    10611061        // Case 2 --- we need to mosaic by cut and paste
    10621062        psTrace("psModules.camera", 1, "Case 2 mosaicking: cut and paste.\n");
    1063         if (!chipMosaic(&mosaicImage, &mosaicMask, &mosaicWeights, &xBin, &yBin, source, targetCell, blank)) {
     1063        if (!chipMosaic(&mosaicImage, &mosaicMask, &mosaicVariances, &xBin, &yBin, source, targetCell, blank)) {
    10641064            psError(PS_ERR_UNKNOWN, false, "Unable to mosaic cells.\n");
    10651065            return false;
     
    10941094    newReadout->image  = mosaicImage;
    10951095    newReadout->mask   = mosaicMask;
    1096     newReadout->weight = mosaicWeights;
     1096    newReadout->variance = mosaicVariances;
    10971097    psFree(newReadout);                 // Drop reference
    10981098
     
    12621262    psImage *mosaicImage   = NULL;      // The mosaic image
    12631263    psImage *mosaicMask    = NULL;      // The mosaic mask
    1264     psImage *mosaicWeights = NULL;      // The mosaic weights
     1264    psImage *mosaicVariances = NULL;      // The mosaic variances
    12651265
    12661266    // Find the HDU
     
    12751275            mosaicMask = psImageSubset(hdu->masks->data[0], *fpaRegion);
    12761276        }
    1277         if (hdu->weights) {
    1278             mosaicWeights = psImageSubset(hdu->weights->data[0], *fpaRegion);
     1277        if (hdu->variances) {
     1278            mosaicVariances = psImageSubset(hdu->variances->data[0], *fpaRegion);
    12791279        }
    12801280    } else {
    12811281        // Case 2 --- we need to mosaic by cut and paste
    12821282        psTrace("psModules.camera", 1, "Case 2 mosaicking: cut and paste.\n");
    1283         if (!fpaMosaic(&mosaicImage, &mosaicMask, &mosaicWeights, &xBin, &yBin, source,
     1283        if (!fpaMosaic(&mosaicImage, &mosaicMask, &mosaicVariances, &xBin, &yBin, source,
    12841284                       targetChip, targetCell, blank)) {
    12851285            psError(PS_ERR_UNKNOWN, false, "Unable to mosaic chips.\n");
     
    13381338    newReadout->image  = mosaicImage;
    13391339    newReadout->mask   = mosaicMask;
    1340     newReadout->weight = mosaicWeights;
     1340    newReadout->variance = mosaicVariances;
    13411341    psFree(newReadout);                 // Drop reference
    13421342
  • trunk/psModules/src/camera/pmFPARead.c

    r21183 r21363  
    99#include <pslib.h>
    1010
     11#include "pmConfig.h"
     12#include "pmConfigMask.h"
    1113#include "pmHDU.h"
    1214#include "pmFPA.h"
     
    2830    FPA_READ_TYPE_IMAGE,                // Read image
    2931    FPA_READ_TYPE_MASK,                 // Read mask
    30     FPA_READ_TYPE_WEIGHT,               // Read weight map
     32    FPA_READ_TYPE_VARIANCE,             // Read variance map
    3133    FPA_READ_TYPE_HEADER                // Read header
    3234} fpaReadType;
     
    5456      case FPA_READ_TYPE_MASK:
    5557        return readout->thisMaskScan;
    56       case FPA_READ_TYPE_WEIGHT:
    57         return readout->thisWeightScan;
     58      case FPA_READ_TYPE_VARIANCE:
     59        return readout->thisVarianceScan;
    5860      default:
    5961        psAbort("Unknown read type: %x\n", type);
     
    7476        readout->thisMaskScan = thisScan;
    7577        return readout->lastMaskScan;
    76       case FPA_READ_TYPE_WEIGHT:
    77         readout->thisWeightScan = thisScan;
    78         return readout->lastWeightScan;
     78      case FPA_READ_TYPE_VARIANCE:
     79        readout->thisVarianceScan = thisScan;
     80        return readout->lastVarianceScan;
    7981      default:
    8082        psAbort("Unknown read type: %x\n", type);
     
    9395      case FPA_READ_TYPE_MASK:
    9496        return readout->lastMaskScan;
    95       case FPA_READ_TYPE_WEIGHT:
    96         return readout->lastWeightScan;
     97      case FPA_READ_TYPE_VARIANCE:
     98        return readout->lastVarianceScan;
    9799      default:
    98100        psAbort("Unknown read type: %x\n", type);
     
    113115        readout->lastMaskScan = lastScan;
    114116        return readout->lastMaskScan;
    115       case FPA_READ_TYPE_WEIGHT:
    116         readout->lastWeightScan = lastScan;
    117         return readout->lastWeightScan;
     117      case FPA_READ_TYPE_VARIANCE:
     118        readout->lastVarianceScan = lastScan;
     119        return readout->lastVarianceScan;
    118120      default:
    119121        psAbort("Unknown read type: %x\n", type);
     
    132134      case FPA_READ_TYPE_MASK:
    133135        return &readout->mask;
    134       case FPA_READ_TYPE_WEIGHT:
    135         return &readout->weight;
     136      case FPA_READ_TYPE_VARIANCE:
     137        return &readout->variance;
    136138      default:
    137139        psAbort("Unknown read type: %x\n", type);
     
    193195
    194196    return naxis3;
     197}
     198
     199// Determine whether a FITS file contains covariance matrices
     200static bool hduCovariance(pmHDU *hdu,   // Header data unit
     201                          psFits *fits  // FITS file
     202    )
     203{
     204    if (hdu->extname && !psFitsMoveExtName(fits, hdu->extname)) {
     205        psError(PS_ERR_IO, false, "Unable to move to extension %s", hdu->extname);
     206        return false;
     207    }
     208    // Need to explicitly read the header, since the HDU may not contain the variance header
     209    psMetadata *header = psFitsReadHeader(NULL, fits); // Header
     210    if (!header) {
     211        psError(PS_ERR_IO, false, "Unable to read variance header.");
     212        return false;
     213    }
     214    bool mdok;                          // Status of MD lookup
     215    bool covar = psMetadataLookupBool(&mdok, header, PM_HDU_COVARIANCE_KEYWORD); // Got covariance?
     216    psFree(header);
     217    return covar;
    195218}
    196219
     
    350373    *target = psImageSubset(image, region);
    351374
    352     // Get the list of overscans: only for IMAGE types (no overscan for MASK and WEIGHT)
     375    // Get the list of overscans: only for IMAGE types (no overscan for MASK and VARIANCE)
    353376    if (type == FPA_READ_TYPE_IMAGE) {
    354377        if (readout->bias->n != 0) {
     
    515538    }
    516539
    517     // XXX for IMAGE, we need the CELL.BAD value, but for MASK, we need the BAD mask value
    518 
    519     float bad = 0;
    520     if (type == FPA_READ_TYPE_MASK) {
    521       bad = 1.0;
    522     } else {
    523       bad = psMetadataLookupF32(&mdok, cell->concepts, "CELL.BAD"); // Bad level
     540    // Need to set the invalid (unread) pixels appropriately, and to read the mask bits
     541    float bad = 0;                      // Bad level
     542    switch (type) {
     543      case FPA_READ_TYPE_MASK: {
     544          // Need to explicitly read the header, since what's in the pmHDU may not correspond to the mask
     545          psMetadata *header = psFitsReadHeader(NULL, fits);
     546          if (!header) {
     547              psError(PS_ERR_IO, false, "Unable to read mask header.");
     548              return false;
     549          }
     550          if (!pmConfigMaskReadHeader(config, header)) {
     551              psError(PS_ERR_IO, false, "Unable to determine mask bits");
     552              psFree(header);
     553              return false;
     554          }
     555          psFree(header);
     556          bad = pmConfigMaskGet("BAD", config);
     557          break;
     558      }
     559      case FPA_READ_TYPE_IMAGE:
     560      case FPA_READ_TYPE_VARIANCE:
     561        bad = psMetadataLookupF32(&mdok, cell->concepts, "CELL.BAD");
     562        break;
     563      default:
     564        psAbort("Unrecognised type: %x", type);
    524565    }
    525566
     
    582623    *image = readoutReadComponent(*image, fits, trimsec, readdir, thisScan, lastScan, z, bad, pixelTypes[type]);
    583624
    584     // Read overscans only for "image" type --- weights and masks shouldn't record overscans
     625    // Read overscans only for "image" type --- variances and masks shouldn't record overscans
    585626    if (type == FPA_READ_TYPE_IMAGE) {
    586627        // Blow away existing data
     
    608649}
    609650
    610 // Read into an cell; this is the engine for pmCellRead, pmCellReadMask, pmCellReadWeight
     651// Read into an cell; this is the engine for pmCellRead, pmCellReadMask, pmCellReadVariance
    611652// Does most of the work for the reading --- reads the HDU, and portions the HDU into readouts.
    612653static bool cellRead(pmCell *cell,      // Cell into which to read
     
    640681        dataPointer = hdu->masks;
    641682        break;
    642       case FPA_READ_TYPE_WEIGHT:
    643         hduReadFunc = pmHDUReadWeight;
    644         dataPointer = hdu->weights;
     683      case FPA_READ_TYPE_VARIANCE:
     684        hduReadFunc = pmHDUReadVariance;
     685        dataPointer = hdu->variances;
    645686        break;
    646687      default:
     
    680721        imageArray = hdu->masks;
    681722        break;
    682       case FPA_READ_TYPE_WEIGHT:
    683         imageArray = hdu->weights;
     723      case FPA_READ_TYPE_VARIANCE:
     724        imageArray = hdu->variances;
    684725        break;
    685726      default:
     
    729770
    730771
    731 // Read into an chip; this is the engine for pmChipRead, pmChipReadMask, pmChipReadWeight
     772// Read into an chip; this is the engine for pmChipRead, pmChipReadMask, pmChipReadVariance
    732773// Iterates over component cells, reading each
    733774static bool chipRead(pmChip *chip,      // Chip into which to read
     
    760801
    761802
    762 // Read into an FPA; this is the engine for pmFPARead, pmFPAReadMask, pmFPAReadWeight
     803// Read into an FPA; this is the engine for pmFPARead, pmFPAReadMask, pmFPAReadVariance
    763804// Iterates over component chips, reading each
    764805static bool fpaRead(pmFPA *fpa,         // FPA into which to read
     
    852893    float bad = psMetadataLookupF32(&mdok, cell->concepts, "CELL.BAD"); // Bad level
    853894    if (!mdok) {
    854         psLogMsg(__func__, PS_LOG_WARN, "CELL.BAD is not set --- assuming zero.\n");
     895        psWarning("CELL.BAD is not set --- assuming zero.\n");
    855896        bad = 0.0;
    856897    }
     
    10911132
    10921133//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1093 // Reading the weight map
    1094 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1095 
    1096 bool pmReadoutMoreWeight(pmReadout *readout, psFits *fits, int z, int numScans, pmConfig *config)
     1134// Reading the variance map
     1135//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     1136
     1137bool pmReadoutMoreVariance(pmReadout *readout, psFits *fits, int z, int numScans, pmConfig *config)
    10971138{
    10981139    PS_ASSERT_PTR_NON_NULL(readout, false);
    10991140    PS_ASSERT_FITS_NON_NULL(fits, false);
    11001141
    1101     return readoutMore(readout, fits, z, numScans, FPA_READ_TYPE_WEIGHT, config);
    1102 }
    1103 
    1104 bool pmReadoutReadChunkWeight(pmReadout *readout, psFits *fits, int z, int numScans, int overlap,
     1142    return readoutMore(readout, fits, z, numScans, FPA_READ_TYPE_VARIANCE, config);
     1143}
     1144
     1145bool pmReadoutReadChunkVariance(pmReadout *readout, psFits *fits, int z, int numScans, int overlap,
    11051146                              pmConfig *config)
    11061147{
     
    11101151    PS_ASSERT_INT_NONNEGATIVE(numScans, false);
    11111152
    1112     return readoutReadChunk(readout, fits, z, numScans, overlap, FPA_READ_TYPE_WEIGHT, config);
    1113 }
    1114 
    1115 bool pmReadoutReadWeight(pmReadout *readout, psFits *fits, int z, pmConfig *config)
     1153    return readoutReadChunk(readout, fits, z, numScans, overlap, FPA_READ_TYPE_VARIANCE, config);
     1154}
     1155
     1156bool pmReadoutReadVariance(pmReadout *readout, psFits *fits, int z, pmConfig *config)
    11161157{
    11171158    PS_ASSERT_PTR_NON_NULL(readout, false);
    11181159    PS_ASSERT_FITS_NON_NULL(fits, false);
    11191160
    1120     return readoutReadChunk(readout, fits, z, 0, 0, FPA_READ_TYPE_WEIGHT, config);
    1121 }
    1122 
    1123 bool pmCellReadWeight(pmCell *cell, psFits *fits, pmConfig *config)
     1161    return readoutReadChunk(readout, fits, z, 0, 0, FPA_READ_TYPE_VARIANCE, config);
     1162}
     1163
     1164bool pmCellReadVariance(pmCell *cell, psFits *fits, pmConfig *config)
    11241165{
    11251166    PS_ASSERT_PTR_NON_NULL(cell, false);
    11261167    PS_ASSERT_FITS_NON_NULL(fits, false);
    11271168
    1128     return cellRead(cell, fits, config, FPA_READ_TYPE_WEIGHT);
    1129 }
    1130 
    1131 bool pmChipReadWeight(pmChip *chip, psFits *fits, pmConfig *config)
     1169    if (!cellRead(cell, fits, config, FPA_READ_TYPE_VARIANCE)) {
     1170        return false;
     1171    }
     1172    pmHDU *hdu = pmHDUFromCell(cell);   // Header data unit
     1173    if (hduCovariance(hdu, fits)) {
     1174        return pmCellReadCovariance(cell, fits);
     1175    }
     1176    return true;
     1177}
     1178
     1179bool pmChipReadVariance(pmChip *chip, psFits *fits, pmConfig *config)
    11321180{
    11331181    PS_ASSERT_PTR_NON_NULL(chip, false);
    11341182    PS_ASSERT_FITS_NON_NULL(fits, false);
    11351183
    1136     return chipRead(chip, fits, config, FPA_READ_TYPE_WEIGHT);
    1137 }
    1138 
    1139 bool pmFPAReadWeight(pmFPA *fpa, psFits *fits, pmConfig *config)
     1184    if (!chipRead(chip, fits, config, FPA_READ_TYPE_VARIANCE)) {
     1185        return false;
     1186    }
     1187    pmHDU *hdu = pmHDUFromChip(chip);   // Header data unit
     1188    if (hduCovariance(hdu, fits)) {
     1189        return pmChipReadCovariance(chip, fits);
     1190    }
     1191    return true;
     1192}
     1193
     1194bool pmFPAReadVariance(pmFPA *fpa, psFits *fits, pmConfig *config)
    11401195{
    11411196    PS_ASSERT_PTR_NON_NULL(fpa, false);
    11421197    PS_ASSERT_FITS_NON_NULL(fits, false);
    11431198
    1144     return fpaRead(fpa, fits, config, FPA_READ_TYPE_WEIGHT);
     1199    if (!fpaRead(fpa, fits, config, FPA_READ_TYPE_VARIANCE)) {
     1200        return false;
     1201    }
     1202    pmHDU *hdu = pmHDUFromFPA(fpa);     // Header data unit
     1203    if (hduCovariance(hdu, fits)) {
     1204        return pmFPAReadCovariance(fpa, fits);
     1205    }
     1206    return true;
    11451207}
    11461208
     
    12681330    return numRead;
    12691331}
     1332
     1333
     1334//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     1335// Reading covariance matrices
     1336//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     1337
     1338bool pmCellReadCovariance(pmCell *cell, psFits *fits)
     1339{
     1340    PS_ASSERT_PTR_NON_NULL(cell, false);
     1341    PS_ASSERT_FITS_NON_NULL(fits, false);
     1342
     1343    const char *chipName = psMetadataLookupStr(NULL, cell->parent->concepts, "CHIP.NAME"); // Name of chip
     1344    const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME"); // Name of cell
     1345    psString extname = NULL;            // Extension name
     1346    psStringAppend(&extname, "COVAR_%s_%s", chipName, cellName);
     1347
     1348    if (!psFitsMoveExtName(fits, extname)) {
     1349        psError(PS_ERR_IO, false, "Unable to move to extension %s\n", extname);
     1350        psFree(extname);
     1351        return false;
     1352    }
     1353    psFree(extname);
     1354
     1355    psMetadata *header = psFitsReadHeader(NULL, fits); // The FITS header
     1356    if (!header) {
     1357        psError(PS_ERR_IO, false, "Unable to read header for extension %s\n", extname);
     1358        psFree(header);
     1359        return false;
     1360    }
     1361
     1362    bool mdok;                          // Status of MD lookup
     1363    int x0 = psMetadataLookupS32(&mdok, header, "COVARIANCE.CENTRE.X"); // Centre of matrix in x
     1364    if (!mdok) {
     1365        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unable to read covariance centre");
     1366        psFree(header);
     1367        return false;
     1368    }
     1369    int y0 = psMetadataLookupS32(&mdok, header, "COVARIANCE.CENTRE.Y"); // Centre of matrix in y
     1370    if (!mdok) {
     1371        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unable to read covariance centre");
     1372        psFree(header);
     1373        return false;
     1374    }
     1375    psFree(header);
     1376
     1377    psArray *images = psFitsReadImageCube(fits, psRegionSet(0,0,0,0)); // Covariance matrices
     1378    if (!images) {
     1379        psError(PS_ERR_IO, false, "Unable to read covariance matrices for chip %s, cell %s",
     1380                chipName, cellName);
     1381        return false;
     1382    }
     1383
     1384    psArray *readouts = cell->readouts; // Readouts of cell
     1385    if (images->n != readouts->n) {
     1386        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
     1387                "Number of covariance matrices (%ld) doesn't match number of readouts (%ld)",
     1388                images->n, readouts->n);
     1389        psFree(images);
     1390        return false;
     1391    }
     1392
     1393    for (int i = 0; i < readouts->n; i++) {
     1394        pmReadout *ro = readouts->data[i]; // Readout of interest
     1395        psImage *image = images->data[i]; // Image of interest
     1396        if (ro->covariance) {
     1397            psWarning("Clobbering extant covariance matrix in chip %s, cell %s, readout %d",
     1398                      chipName, cellName, i);
     1399            psFree(ro->covariance);
     1400        }
     1401        ro->covariance = psKernelAllocFromImage(image, x0, y0);
     1402    }
     1403    psFree(images);
     1404
     1405    return true;
     1406}
     1407
     1408
     1409bool pmChipReadCovariance(pmChip *chip, psFits *fits)
     1410{
     1411    PS_ASSERT_PTR_NON_NULL(chip, false);
     1412    PS_ASSERT_FITS_NON_NULL(fits, false);
     1413
     1414    psArray *cells = chip->cells;       // Array of cells
     1415    for (int i = 0; i < cells->n; i++) {
     1416        pmCell *cell = cells->data[i];  // Cell of interest
     1417        if (!pmCellReadCovariance(cell, fits)) {
     1418            return false;
     1419        }
     1420    }
     1421
     1422    return true;
     1423}
     1424
     1425
     1426bool pmFPAReadCovariance(pmFPA *fpa, psFits *fits)
     1427{
     1428    PS_ASSERT_PTR_NON_NULL(fpa, false);
     1429    PS_ASSERT_FITS_NON_NULL(fits, false);
     1430
     1431    psArray *chips = fpa->chips;        // Array of chips
     1432    for (int i = 0; i < chips->n; i++) {
     1433        pmChip *chip = chips->data[i];  // Chip of interest
     1434        if (!pmChipReadCovariance(chip, fits)) {
     1435            return false;
     1436        }
     1437    }
     1438
     1439    return true;
     1440}
  • trunk/psModules/src/camera/pmFPARead.h

    r18163 r21363  
    44 * @author Paul Price, IfA
    55 *
    6  * @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
    7  * @date $Date: 2008-06-17 22:16:38 $
     6 * @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
     7 * @date $Date: 2009-02-06 02:31:24 $
    88 * Copyright 2005-2006 Institute for Astronomy, University of Hawaii
    99 */
     
    6060                       int numRows,      // The number of rows to read
    6161                       pmConfig *config
    62                       );
     62    );
    6363
    6464/// Return the number of readouts within a cell
    6565///
    66 /// This function is type-independent (doesn't matter if you are interested in the image/mask/weight).
     66/// This function is type-independent (doesn't matter if you are interested in the image/mask/variance).
    6767int pmCellNumReadouts(pmCell *cell, psFits *fits, pmConfig *config);
    6868
     
    7474                psFits *fits,           // FITS file from which to read
    7575                pmConfig *config        // Configuration
    76                );
     76    );
    7777
    7878/// Read a chip
     
    8282                psFits *fits,           // FITS file from which to read
    8383                pmConfig *config        // Configuration
    84                );
     84    );
    8585
    8686/// Read an FPA
     
    9090               psFits *fits,            // FITS file from which to read
    9191               pmConfig *config         // Configuration
    92               );
     92    );
    9393
    9494// Mask functions follow
     
    126126                    psFits *fits,       // FITS file from which to read
    127127                    pmConfig *config    // Configuration
    128                    );
     128    );
    129129
    130130/// Read an entire chip into the mask
     
    134134                    psFits *fits,       // FITS file from which to read
    135135                    pmConfig *config    // Configuration
    136                    );
     136    );
    137137
    138138/// Read an entire FPA into the mask
     
    142142                   psFits *fits,        // FITS file from which to read
    143143                   pmConfig *config     // Configuration
    144                   );
    145 
    146 // Weight functions follow
    147 
    148 /// Check to see if there is more to read when reading a readout incrementally into the weight
    149 bool pmReadoutMoreWeight(pmReadout *readout, ///< Readout of interest
    150                          psFits *fits, ///< FITS file from which to read
    151                          int z,         ///< Readout number/plane; zero-offset indexing
    152                          int numScans, ///< Number of scans (rows/cols) to read
    153                          pmConfig *config ///< Configuration
    154     );
    155 
    156 /// Read a chunk of a readout into the weight
     144    );
     145
     146// Variance functions follow
     147
     148/// Check to see if there is more to read when reading a readout incrementally into the variance
     149bool pmReadoutMoreVariance(pmReadout *readout, ///< Readout of interest
     150                           psFits *fits, ///< FITS file from which to read
     151                           int z,       ///< Readout number/plane; zero-offset indexing
     152                           int numScans, ///< Number of scans (rows/cols) to read
     153                           pmConfig *config ///< Configuration
     154    );
     155
     156/// Read a chunk of a readout into the variance
    157157///
    158158/// Allows reading the readout incrementally
    159 bool pmReadoutReadChunkWeight(pmReadout *readout, ///< Readout of interest
    160                               psFits *fits, ///< FITS file from which to read
    161                               int z,    ///< Readout number/plane; zero-offset indexing
    162                               int numScans, ///< Number of scans (rows/cols) to read
    163                               int overlap, ///< Overlap between consecutive reads
    164                               pmConfig *config ///< Configuration
    165     );
    166 
    167 /// Read the entire readout into the weight
    168 bool pmReadoutReadWeight(pmReadout *readout, ///< Readout of interest
    169                          psFits *fits,  ///< FITS file from which to read
    170                          int z,         ///< Readout number/plane; zero-offset indexing
    171                          pmConfig *config ///< Configuration
    172     );
    173 
    174 /// Read an entire cell into the weight
    175 ///
    176 /// Same as pmCellRead, but reads into the weight element of the readouts.
    177 bool pmCellReadWeight(pmCell *cell,     // Cell to read into
    178                       psFits *fits,     // FITS file from which to read
    179                       pmConfig *config  // Configuration
    180                      );
    181 
    182 /// Read an entire chip into the weight
    183 ///
    184 /// Same as pmChipRead, but reads into the weight element of the readouts.
    185 bool pmChipReadWeight(pmChip *chip,     // Chip to read into
    186                       psFits *fits,     // FITS file from which to read
    187                       pmConfig *config  // Configuration
    188                      );
    189 
    190 /// Read an entire FPA into the weight
    191 ///
    192 /// Same as pmFPARead, but reads into the weight element of the readouts.
    193 bool pmFPAReadWeight(pmFPA *fpa,        // FPA to read into
    194                      psFits *fits,      // FITS file from which to read
    195                      pmConfig *config   // Configuration
    196                     );
     159bool pmReadoutReadChunkVariance(pmReadout *readout, ///< Readout of interest
     160                                psFits *fits, ///< FITS file from which to read
     161                                int z,    ///< Readout number/plane; zero-offset indexing
     162                                int numScans, ///< Number of scans (rows/cols) to read
     163                                int overlap, ///< Overlap between consecutive reads
     164                                pmConfig *config ///< Configuration
     165    );
     166
     167/// Read the entire readout into the variance
     168bool pmReadoutReadVariance(pmReadout *readout, ///< Readout of interest
     169                           psFits *fits,  ///< FITS file from which to read
     170                           int z,         ///< Readout number/plane; zero-offset indexing
     171                           pmConfig *config ///< Configuration
     172    );
     173
     174/// Read an entire cell into the variance
     175///
     176/// Same as pmCellRead, but reads into the variance element of the readouts.
     177bool pmCellReadVariance(pmCell *cell,     // Cell to read into
     178                        psFits *fits,     // FITS file from which to read
     179                        pmConfig *config  // Configuration
     180    );
     181
     182/// Read an entire chip into the variance
     183///
     184/// Same as pmChipRead, but reads into the variance element of the readouts.
     185bool pmChipReadVariance(pmChip *chip,     // Chip to read into
     186                        psFits *fits,     // FITS file from which to read
     187                        pmConfig *config  // Configuration
     188    );
     189
     190/// Read an entire FPA into the variance
     191///
     192/// Same as pmFPARead, but reads into the variance element of the readouts.
     193bool pmFPAReadVariance(pmFPA *fpa,        // FPA to read into
     194                       psFits *fits,      // FITS file from which to read
     195                       pmConfig *config   // Configuration
     196    );
    197197
    198198/// Read cell headers
     
    226226/// also read and included in the cell analysis metadata under "name.HEADER".
    227227int pmCellReadTable(pmCell *cell,       ///< Cell for which to read table
    228                     psFits *fits,       ///< FITS file from which the table
     228                    psFits *fits,       ///< FITS file from which to read the table
    229229                    const char *name    ///< Specifies the extension name, and target in the analysis metadata
    230230                   );
     
    233233///
    234234/// Iterates over component cells, calling pmCellReadTable.
    235 int pmChipReadTable(pmChip *chip,       ///< Cell for which to read table
    236                     psFits *fits,       ///< FITS file from which the table
     235int pmChipReadTable(pmChip *chip,       ///< Chip for which to read table
     236                    psFits *fits,       ///< FITS file from which to read the table
    237237                    const char *name    ///< Specifies the extension name, and target in the analysis metadata
    238238                   );
     
    241241///
    242242/// Iterates over component chips, calling pmChipReadTable.
    243 int pmFPAReadTable(pmFPA *fpa,          ///< Cell for which to read table
    244                    psFits *fits,        ///< FITS file from which the table
     243int pmFPAReadTable(pmFPA *fpa,          ///< FPA for which to read table
     244                   psFits *fits,        ///< FITS file from which to read the table
    245245                   const char *name     ///< Specifies the extension name, and target in the analysis metadata
    246246                  );
     247
     248/// Read covariance matrices for a cell
     249bool pmCellReadCovariance(pmCell *cell, ///< Cell for which to read covariance matrices
     250                          psFits *fits  ///< FITS file from which to read
     251    );
     252
     253/// Read covariance matrices for a chip
     254bool pmChipReadCovariance(pmChip *chip, ///< Chip for which to read covariance matrices
     255                          psFits *fits  ///< FITS file from which to read
     256    );
     257
     258/// Read covariance matrices for a cell
     259bool pmFPAReadCovariance(pmFPA *fpa,    ///< FPA for which to read covariance matrices
     260                         psFits *fits   ///< FITS file from which to read
     261    );
     262
     263
     264
    247265/// @}
    248266#endif
  • trunk/psModules/src/camera/pmFPAWrite.c

    r21279 r21363  
    99
    1010#include "pmConfig.h"
     11#include "pmConfigMask.h"
    1112#include "pmHDU.h"
    1213#include "pmFPA.h"
     
    2930    FPA_WRITE_TYPE_IMAGE,               // Write image
    3031    FPA_WRITE_TYPE_MASK,                // Write mask
    31     FPA_WRITE_TYPE_WEIGHT               // Write weight map
     32    FPA_WRITE_TYPE_VARIANCE             // Write variance map
    3233} fpaWriteType;
    3334
     
    4647    case FPA_WRITE_TYPE_MASK:
    4748        return &hdu->masks;
    48     case FPA_WRITE_TYPE_WEIGHT:
    49         return &hdu->weights;
     49    case FPA_WRITE_TYPE_VARIANCE:
     50        return &hdu->variances;
    5051    default:
    5152        psAbort("Unknown write type: %x\n", type);
     
    6667    case FPA_WRITE_TYPE_MASK:
    6768        return pmHDUWriteMask(hdu, fits, config);
    68     case FPA_WRITE_TYPE_WEIGHT:
    69         return pmHDUWriteWeight(hdu, fits, config);
     69    case FPA_WRITE_TYPE_VARIANCE:
     70        return pmHDUWriteVariance(hdu, fits, config);
    7071    default:
    7172        psAbort("Unknown write type: %x\n", type);
     
    7475}
    7576
    76 // Write a cell image/mask/weight
     77// Indicate whether a covariance matrix is defined
     78static bool readoutSearchCovariances(pmReadout *ro)
     79{
     80    return ro->covariance ? true : false;
     81}
     82
     83// Search for a covariance matrix
     84#define SEARCH_COVARIANCES(NAME, PARENT, CHILD, CHILDREN, TESTFUNC) \
     85static bool NAME(PARENT *parent) \
     86{ \
     87    if (!parent || !parent->CHILDREN) { \
     88        return false; \
     89    } \
     90    psArray *children = parent->CHILDREN; /* Array of children */ \
     91    for (int i = 0; i < children->n; i++) { \
     92        CHILD *child = children->data[i]; /* Child of interest */ \
     93        if (child && TESTFUNC(child)) { \
     94            return true; \
     95        } \
     96    } \
     97    return false; \
     98}
     99
     100SEARCH_COVARIANCES(cellSearchCovariances, pmCell, pmReadout, readouts, readoutSearchCovariances);
     101SEARCH_COVARIANCES(chipSearchCovariances, pmChip, pmCell,    cells,    cellSearchCovariances);
     102SEARCH_COVARIANCES(fpaSearchCovariances,  pmFPA,  pmChip,    chips,    chipSearchCovariances);
     103
     104// Some type-specific additions to the header
     105static bool writeUpdateHeader(pmFPA *fpa, // FPA of interest
     106                              pmChip *chip, // Chip of interest, or NULL
     107                              pmCell *cell, // Cell of interest, or NULL
     108                              fpaWriteType type, // Type to write
     109                              pmConfig *config // Configuration
     110                              )
     111{
     112    switch (type) {
     113      case FPA_WRITE_TYPE_MASK: {
     114          pmHDU *phu = pmHDUGetHighest(fpa, chip, cell); // Primary header
     115          if (!pmConfigMaskWriteHeader(config, phu->header)) {
     116              psError(PS_ERR_UNKNOWN, false, "Unable to set the mask names in the PHU header");
     117              return false;
     118          }
     119          break;
     120      }
     121      case FPA_WRITE_TYPE_VARIANCE: {
     122          bool covar = false;           // Are covariances present?
     123          if ((cell && cellSearchCovariances(cell)) ||
     124              (!cell && ((chip && chipSearchCovariances(chip)) ||
     125                         (!chip && fpa && fpaSearchCovariances(fpa))))) {
     126              covar = true;
     127          }
     128
     129          pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // Header being written
     130          psMetadataAddBool(hdu->header, PS_LIST_TAIL, PM_HDU_COVARIANCE_KEYWORD, PS_META_REPLACE,
     131                            "Is a covariance matrix present?", covar);
     132          break;
     133      }
     134      default:
     135        break;
     136    }
     137
     138    return true;
     139}
     140
     141
     142// Write a cell image/mask/variance
    77143static bool cellWrite(pmCell *cell,     // Cell to write
    78144                      psFits *fits,     // FITS file to which to write
     
    97163    // generate the HDU, but only copies the structure.
    98164    if (!blank && !hdu->blankPHU && !*imageArray && (!pmHDUGenerateForCell(cell) || !*imageArray)) {
    99         psError(PS_ERR_UNKNOWN, false, "Unable to generate HDU for cell --- likely programming error.\n");
     165        psError(PS_ERR_UNKNOWN, false, "Unable to generate HDU for cell --- likely programming error.");
    100166        return false;
    101167    }
     
    106172
    107173    if (writeBlank || writeImage) {
    108 
    109174        pmConceptSource source = PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CELLS |
    110175                                 PM_CONCEPT_SOURCE_DEFAULTS | PM_CONCEPT_SOURCE_DATABASE;
    111176        if (!pmConceptsWriteCell(cell, source, true, config)) {
    112             psError(PS_ERR_IO, false, "Unable to write concepts for cell.\n");
     177            psError(PS_ERR_IO, false, "Unable to write concepts for cell.");
     178            return false;
     179        }
     180        if (!writeUpdateHeader(NULL, NULL, cell, type, config)) {
     181            psError(PS_ERR_UNKNOWN, false, "Unable to update header for writing");
    113182            return false;
    114183        }
     
    123192}
    124193
    125 // Write a chip image/mask/weight
     194// Write a chip image/mask/variance
    126195static bool chipWrite(pmChip *chip,     // Chip to write
    127196                      psFits *fits,     // FITS file to which to write
     
    162231                return false;
    163232            }
     233
     234            if (!writeUpdateHeader(NULL, chip, NULL, type, config)) {
     235                psError(PS_ERR_UNKNOWN, false, "Unable to update header for writing");
     236                return false;
     237            }
     238
    164239            if (!appropriateWriteFunc(hdu, fits, config, type)) {
    165240                psError(PS_ERR_IO, false, "Unable to write HDU for chip.\n");
     
    186261
    187262
    188 // Write an FPA image/mask/weight
     263// Write an FPA image/mask/variance
    189264static bool fpaWrite(pmFPA *fpa,        // FPA to write
    190265                     psFits *fits,      // FITS file to which to write
     
    223298            if (!pmConceptsWriteFPA(fpa, source, true, config)) {
    224299                psError(PS_ERR_IO, false, "Unable to write concepts for FPA.\n");
     300                return false;
     301            }
     302            if (!writeUpdateHeader(fpa, NULL, NULL, type, config)) {
     303                psError(PS_ERR_UNKNOWN, false, "Unable to update header for writing");
    225304                return false;
    226305            }
     
    433512
    434513
    435 bool pmCellWriteWeight(pmCell *cell, psFits *fits, pmConfig *config, bool blank)
     514bool pmCellWriteVariance(pmCell *cell, psFits *fits, pmConfig *config, bool blank)
    436515{
    437516    PS_ASSERT_PTR_NON_NULL(cell, false);
    438517    PS_ASSERT_PTR_NON_NULL(fits, false);
    439     return cellWrite(cell, fits, config, blank, FPA_WRITE_TYPE_WEIGHT);
    440 }
    441 
    442 bool pmChipWriteWeight(pmChip *chip, psFits *fits, pmConfig *config, bool blank, bool recurse)
     518    if (!cellWrite(cell, fits, config, blank, FPA_WRITE_TYPE_VARIANCE)) {
     519        return false;
     520    }
     521    if (!pmCellWriteCovariance(fits, cell)) {
     522        return false;
     523    }
     524    return true;
     525}
     526
     527bool pmChipWriteVariance(pmChip *chip, psFits *fits, pmConfig *config, bool blank, bool recurse)
    443528{
    444529    PS_ASSERT_PTR_NON_NULL(chip, false);
    445530    PS_ASSERT_PTR_NON_NULL(fits, false);
    446     return chipWrite(chip, fits, config, blank, recurse, FPA_WRITE_TYPE_WEIGHT);
    447 }
    448 
    449 bool pmFPAWriteWeight(pmFPA *fpa, psFits *fits, pmConfig *config, bool blank, bool recurse)
     531    if (!chipWrite(chip, fits, config, blank, recurse, FPA_WRITE_TYPE_VARIANCE)) {
     532        return false;
     533    }
     534    if (!pmChipWriteCovariance(fits, chip)) {
     535        return false;
     536    }
     537    return true;
     538}
     539
     540bool pmFPAWriteVariance(pmFPA *fpa, psFits *fits, pmConfig *config, bool blank, bool recurse)
    450541{
    451542    PS_ASSERT_PTR_NON_NULL(fpa, false);
    452543    PS_ASSERT_PTR_NON_NULL(fits, false);
    453     return fpaWrite(fpa, fits, config, blank, recurse, FPA_WRITE_TYPE_WEIGHT);
     544    if (!fpaWrite(fpa, fits, config, blank, recurse, FPA_WRITE_TYPE_VARIANCE)) {
     545        return false;
     546    }
     547    if (!pmFPAWriteCovariance(fits, fpa)) {
     548        return false;
     549    }
     550    return true;
    454551}
    455552
     
    526623    return numWrite;
    527624}
     625
     626bool pmCellWriteCovariance(psFits *fits, const pmCell *cell)
     627{
     628    PS_ASSERT_PTR_NON_NULL(cell, false);
     629    PS_ASSERT_PTR_NON_NULL(fits, false);
     630
     631    int numCovar = 0;
     632    psArray *readouts = cell->readouts; // Array of readouts
     633    for (int i = 0; i < readouts->n; i++) {
     634        pmReadout *readout = readouts->data[i]; // The readout of interest
     635        if (readout && readout->covariance) {
     636            numCovar++;
     637        }
     638    }
     639    if (numCovar == 0) {
     640        return true;
     641    }
     642    if (numCovar != readouts->n) {
     643        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     644                "Number of covariances (%d) doesn't match number of readouts (%ld)",
     645                numCovar, readouts->n);
     646        return false;
     647    }
     648
     649    // Check size of covariances
     650    int xMinCovar = INT_MAX, xMaxCovar = INT_MIN, yMinCovar = INT_MAX, yMaxCovar = INT_MIN; // Size
     651    for (int i = 0; i < readouts->n; i++) {
     652        pmReadout *readout = readouts->data[i]; // The readout of interest
     653        psAssert(readout, "Should be defined.");
     654        psKernel *covar = readout->covariance; // Covariance matrix
     655        psAssert(covar, "Should be defined.");
     656        xMinCovar = PS_MIN(xMinCovar, covar->xMin);
     657        xMaxCovar = PS_MAX(xMaxCovar, covar->xMax);
     658        yMinCovar = PS_MIN(yMinCovar, covar->yMin);
     659        yMaxCovar = PS_MAX(yMaxCovar, covar->yMax);
     660    }
     661
     662    // Correct covariances to common size
     663    psArray *images = psArrayAlloc(numCovar); // Array of images
     664    for (int i = 0; i < readouts->n; i++) {
     665        pmReadout *readout = readouts->data[i]; // The readout of interest
     666        psAssert(readout, "Should be defined.");
     667        psKernel *covar = readout->covariance; // Covariance matrix
     668        psAssert(covar, "Should be defined.");
     669        int xMin = covar->xMin, xMax = covar->xMax, yMin = covar->yMin, yMax = covar->yMax;// Size
     670        if (xMin == xMinCovar && xMax == xMaxCovar && yMin == yMinCovar && yMax == yMaxCovar) {
     671            images->data[i] = psMemIncrRefCounter(covar->image);
     672        } else {
     673            psImage *new = psImageAlloc(xMaxCovar - xMinCovar + 1, yMaxCovar - yMinCovar + 1, PS_TYPE_F32);
     674            psImageInit(new, 0);
     675            psImageOverlaySection(new, covar->image, xMinCovar - xMin, yMinCovar - yMin, "=");
     676            images->data[i] = new;
     677        }
     678    }
     679
     680    // Determine extension name
     681    const char *chipName = psMetadataLookupStr(NULL, cell->parent->concepts, "CHIP.NAME"); // Name of chip
     682    const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME"); // Name of cell
     683    psString extname = NULL;            // Extension name
     684    psStringAppend(&extname, "COVAR_%s_%s", chipName, cellName);
     685
     686    // Generate header
     687    pmHDU *hdu = pmHDUFromCell(cell);   // HDU for cell
     688    psMetadata *header = psMetadataCopy(NULL, hdu->header); // Header to write
     689    psMetadataAddS32(header, PS_LIST_TAIL, "COVARIANCE.CENTRE.X", PS_META_REPLACE,
     690                     "Centre of covariance matrix in x", -xMinCovar);
     691    psMetadataAddS32(header, PS_LIST_TAIL, "COVARIANCE.CENTRE.Y", PS_META_REPLACE,
     692                     "Centre of covariance matrix in y", -yMinCovar);
     693
     694    // Write images
     695    if (!psFitsWriteImageCube(fits, header, images, extname)) {
     696        psError(PS_ERR_UNKNOWN, false, "Unable to write covariances from chip %s, cell %s to extension %s",
     697                chipName, cellName, extname);
     698        psFree(extname);
     699        psFree(header);
     700        psFree(images);
     701        return 0;
     702    }
     703    psFree(extname);
     704    psFree(header);
     705    psFree(images);
     706
     707    return true;
     708}
     709
     710
     711bool pmChipWriteCovariance(psFits *fits, const pmChip *chip)
     712{
     713    PS_ASSERT_PTR_NON_NULL(chip, false);
     714    PS_ASSERT_PTR_NON_NULL(fits, false);
     715
     716    psArray *cells = chip->cells;       // Array of cells
     717    for (int i = 0; i < cells->n; i++) {
     718        pmCell *cell = cells->data[i];  // Cell of interest
     719        if (!pmCellWriteCovariance(fits, cell)) {
     720            return false;
     721        }
     722    }
     723
     724    return true;
     725}
     726
     727
     728bool pmFPAWriteCovariance(psFits *fits, const pmFPA *fpa)
     729{
     730    PS_ASSERT_PTR_NON_NULL(fpa, false);
     731    PS_ASSERT_PTR_NON_NULL(fits, false);
     732
     733    psArray *chips = fpa->chips;        // Array of chips
     734    for (int i = 0; i < chips->n; i++) {
     735        pmChip *chip = chips->data[i];  // Chip of interest
     736        if (!pmChipWriteCovariance(fits, chip)) {
     737            return false;
     738        }
     739    }
     740
     741    return true;
     742}
  • trunk/psModules/src/camera/pmFPAWrite.h

    r21279 r21363  
    44 * @author Paul Price, IfA
    55 *
    6  * @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
    7  * @date $Date: 2009-02-04 02:39:36 $
     6 * @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
     7 * @date $Date: 2009-02-06 02:31:24 $
     8 *
    89 * Copyright 2005-2006 Institute for Astronomy, University of Hawaii
    910 */
     
    2425                        psFits *fits,   ///<  FITS file to which to write
    2526                        int z           ///<  Image plane to write
    26                        );
     27    );
    2728
    2829/// Write a cell to a FITS file
     
    3637                 pmConfig *config,      ///<  Configuration
    3738                 bool blank             ///<  Write a blank PHU?
    38                 );
     39    );
    3940
    4041/// Write a chip to a FITS file
     
    4950                 bool blank,            ///<  Write a blank PHU?
    5051                 bool recurse           ///<  Recurse to lower levels?
    51                 );
     52    );
    5253
    5354/// Write an FPA to a FITS file
     
    6263                bool blank,             ///<  Write a blank PHU?
    6364                bool recurse            ///<  Recurse to lower levels?
    64                );
     65    );
    6566
    6667/// Write a cell mask to a FITS file
     
    7475                     pmConfig *config,  ///<  Configuration
    7576                     bool blank         ///<  Write a blank PHU?
    76                     );
     77    );
    7778
    7879/// Write a chip mask to a FITS file
     
    8889                     bool blank,        ///<  Write a blank PHU?
    8990                     bool recurse       ///<  Recurse to lower levels?
    90                     );
     91    );
    9192
    9293/// Write an FPA mask to a FITS file
     
    102103                    bool blank,         ///<  Write a blank PHU?
    103104                    bool recurse        ///<  Recurse to lower levels?
    104                    );
     105    );
    105106
    106 /// Write a cell weight to a FITS file
     107/// Write a cell variance to a FITS file
    107108///
    108 /// Generates CELL.TRIMSEC, CELL.BIASSEC and the HDU weight pixels if required.  A blank (i.e., image-less
     109/// Generates CELL.TRIMSEC, CELL.BIASSEC and the HDU variance pixels if required.  A blank (i.e., image-less
    109110/// header) is written only if specifically requested.  Writes the concepts to the various locations, and then
    110 /// the HDU weight to the FITS file.  This function should be called at the beginning of the output cell loop
    111 /// with blank=true in order to produce the correct file structure.
    112 bool pmCellWriteWeight(pmCell *cell,    ///<  Cell to write
    113                        psFits *fits,    ///<  FITS file to which to write
    114                        pmConfig *config, ///<  Configuration
    115                        bool blank       ///<  Write a blank PHU?
    116                       );
     111/// the HDU variance to the FITS file.  This function should be called at the beginning of the output cell
     112/// loop with blank=true in order to produce the correct file structure.
     113bool pmCellWriteVariance(pmCell *cell,    ///<  Cell to write
     114                         psFits *fits,    ///<  FITS file to which to write
     115                         pmConfig *config, ///<  Configuration
     116                         bool blank       ///<  Write a blank PHU?
     117    );
    117118
    118 /// Write a chip weight to a FITS file
     119/// Write a chip variance to a FITS file
    119120///
    120 /// Generates CELL.TRIMSEC, CELL.BIASSEC and the HDU weight pixels if required.  A blank (i.e., image-less
     121/// Generates CELL.TRIMSEC, CELL.BIASSEC and the HDU variance pixels if required.  A blank (i.e., image-less
    121122/// header) is written only if specifically requested.  Writes the concepts to the various locations, and then
    122 /// the HDU weight to the FITS file, optionally recursing to lower levels.  This function should be called at
    123 /// the beginning of the output chip loop with blank=true and recurse=false in order to produce the correct
     123/// the HDU variance to the FITS file, optionally recursing to lower levels.  This function should be called
     124/// at the beginning of the output chip loop with blank=true and recurse=false in order to produce the correct
    124125/// file structure.
    125 bool pmChipWriteWeight(pmChip *chip,    ///<  Chip to write
    126                        psFits *fits,    ///<  FITS file to which to write
    127                        pmConfig *config, ///<  Configuration
    128                        bool blank,      ///<  Write a blank PHU?
    129                        bool recurse     ///<  Recurse to lower levels?
    130                       );
     126bool pmChipWriteVariance(pmChip *chip,    ///<  Chip to write
     127                         psFits *fits,    ///<  FITS file to which to write
     128                         pmConfig *config, ///<  Configuration
     129                         bool blank,      ///<  Write a blank PHU?
     130                         bool recurse     ///<  Recurse to lower levels?
     131    );
    131132
    132 /// Write an FPA weight to a FITS file
     133/// Write an FPA variance to a FITS file
    133134///
    134 /// Generates CELL.TRIMSEC, CELL.BIASSEC and the HDU weight pixels if required.  A blank (i.e., image-less
     135/// Generates CELL.TRIMSEC, CELL.BIASSEC and the HDU variance pixels if required.  A blank (i.e., image-less
    135136/// header) is written only if specifically requested.  Writes the concepts to the various locations, and then
    136 /// the HDU weight to the FITS file, optionally recursing to lower levels.  This function should be called at
    137 /// the beginning of the output FPA loop with blank=true and recurse=false in order to produce the correct
     137/// the HDU variance to the FITS file, optionally recursing to lower levels.  This function should be called
     138/// at the beginning of the output FPA loop with blank=true and recurse=false in order to produce the correct
    138139/// file structure.
    139 bool pmFPAWriteWeight(pmFPA *fpa,       ///<  FPA to write
    140                       psFits *fits,     ///<  FITS file to which to write
    141                       pmConfig *config, ///<  Configuration
    142                       bool blank,       ///<  Write a blank PHU?
    143                       bool recurse      ///<  Recurse to lower levels?
    144                      );
     140bool pmFPAWriteVariance(pmFPA *fpa,       ///<  FPA to write
     141                        psFits *fits,     ///<  FITS file to which to write
     142                        pmConfig *config, ///<  Configuration
     143                        bool blank,       ///<  Write a blank PHU?
     144                        bool recurse      ///<  Recurse to lower levels?
     145    );
    145146
    146147
     
    153154                     const pmCell *cell, ///< Cell containing FITS table in the analysis metadata
    154155                     const char *name   ///< Name for the table data, and the extension name
    155                     );
     156    );
    156157
    157158int pmChipWriteTable(psFits *fits,      ///< FITS file to which to write
    158159                     const pmChip *chip, ///< Chip containing cells with tables to write
    159160                     const char *name   ///< Name for the table data, and the extension name
    160                     );
     161    );
    161162
    162163int pmFPAWriteTable(psFits *fits,       ///< FITS file to which to write
    163164                    const pmFPA *fpa,   ///< FPA containing cells with tables to write
    164165                    const char *name    ///< Name for the table data, and the extension name
    165                    );
     166    );
     167
     168/// Write covariance matrix to a FITS file
     169///
     170/// The covariance matrices for a cell are written to an independent extension, named after the chip and cell
     171/// name.
     172bool pmCellWriteCovariance(psFits *fits,///< FITS file to which to write
     173                           const pmCell *cell ///< Cell for which to write covariance
     174    );
     175
     176bool pmChipWriteCovariance(psFits *fits,///< FITS file to which to write
     177                           const pmChip *chip ///< Chip for which to write covariance
     178    );
     179
     180bool pmFPAWriteCovariance(psFits *fits,///< FITS file to which to write
     181                          const pmFPA *fpa ///< FPA for which to write covariance
     182    );
    166183
    167184// Update the header before writing to be consistent
  • trunk/psModules/src/camera/pmFPAfile.c

    r21279 r21363  
    476476        return PM_FPA_FILE_MASK;
    477477    }
    478     if (!strcasecmp(type, "WEIGHT"))     {
    479         return PM_FPA_FILE_WEIGHT;
     478    if (!strcasecmp(type, "VARIANCE"))     {
     479        return PM_FPA_FILE_VARIANCE;
    480480    }
    481481    if (!strcasecmp(type, "FRINGE")) {
     
    530530      case PM_FPA_FILE_MASK:
    531531        return ("MASK");
    532       case PM_FPA_FILE_WEIGHT:
    533         return ("WEIGHT");
     532      case PM_FPA_FILE_VARIANCE:
     533        return ("VARIANCE");
    534534      case PM_FPA_FILE_FRINGE:
    535535        return ("FRINGE");
  • trunk/psModules/src/camera/pmFPAfile.h

    r21279 r21363  
    44 * @author EAM, IfA
    55 *
    6  * @version $Revision: 1.34 $ $Name: not supported by cvs2svn $
    7  * @date $Date: 2009-02-04 02:39:36 $
     6 * @version $Revision: 1.35 $ $Name: not supported by cvs2svn $
     7 * @date $Date: 2009-02-06 02:31:24 $
     8 *
    89 * Copyright 2004-2005 Institute for Astronomy, University of Hawaii
    910 */
     
    3738    PM_FPA_FILE_IMAGE,
    3839    PM_FPA_FILE_MASK,
    39     PM_FPA_FILE_WEIGHT,
     40    PM_FPA_FILE_VARIANCE,
    4041    PM_FPA_FILE_FRINGE,
    4142    PM_FPA_FILE_DARK,
  • trunk/psModules/src/camera/pmFPAfileFitsIO.c

    r21279 r21363  
    148148      case PM_FPA_FILE_IMAGE:
    149149      case PM_FPA_FILE_MASK:
    150       case PM_FPA_FILE_WEIGHT:
     150      case PM_FPA_FILE_VARIANCE:
    151151      case PM_FPA_FILE_HEADER:
    152152      case PM_FPA_FILE_FRINGE:
     
    329329}
    330330
    331 bool pmFPAviewReadFitsWeight(const pmFPAview *view, pmFPAfile *file, pmConfig *config)
    332 {
    333     PS_ASSERT_PTR_NON_NULL(view, false);
    334     PS_ASSERT_PTR_NON_NULL(file, false);
    335     return fpaViewReadFitsImage(view, file, config, pmFPAReadWeight, pmChipReadWeight, pmCellReadWeight);
     331bool pmFPAviewReadFitsVariance(const pmFPAview *view, pmFPAfile *file, pmConfig *config)
     332{
     333    PS_ASSERT_PTR_NON_NULL(view, false);
     334    PS_ASSERT_PTR_NON_NULL(file, false);
     335    return fpaViewReadFitsImage(view, file, config, pmFPAReadVariance, pmChipReadVariance,
     336                                pmCellReadVariance);
    336337}
    337338
     
    347348    PS_ASSERT_PTR_NON_NULL(view, false);
    348349    PS_ASSERT_PTR_NON_NULL(file, false);
    349     return fpaViewReadFitsImage(view, file, config, pmFPAReadHeaderSet, pmChipReadHeaderSet, pmCellReadHeaderSet);
     350    return fpaViewReadFitsImage(view, file, config, pmFPAReadHeaderSet, pmChipReadHeaderSet,
     351                                pmCellReadHeaderSet);
    350352}
    351353
     
    432434}
    433435
    434 bool pmFPAviewWriteFitsWeight(const pmFPAview *view, pmFPAfile *file, pmConfig *config)
    435 {
    436     PS_ASSERT_PTR_NON_NULL(view, false);
    437     PS_ASSERT_PTR_NON_NULL(file, false);
    438     return fpaViewWriteFitsImage(view, file, config, pmFPAWriteWeight, pmChipWriteWeight, pmCellWriteWeight);
     436bool pmFPAviewWriteFitsVariance(const pmFPAview *view, pmFPAfile *file, pmConfig *config)
     437{
     438    PS_ASSERT_PTR_NON_NULL(view, false);
     439    PS_ASSERT_PTR_NON_NULL(file, false);
     440    return fpaViewWriteFitsImage(view, file, config, pmFPAWriteVariance, pmChipWriteVariance,
     441                                 pmCellWriteVariance);
    439442}
    440443
  • trunk/psModules/src/camera/pmFPAfileFitsIO.h

    r18601 r21363  
    55 * @author PAP, IfA
    66 *
    7  * @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
    8  * @date $Date: 2008-07-17 22:38:15 $
     7 * @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
     8 * @date $Date: 2009-02-06 02:31:24 $
    99 * Copyright 2004-2005 Institute for Astronomy, University of Hawaii
    1010 */
     
    2727                            pmConfig *config
    2828                          );
    29 /// Read a weight map into the current view
    30 bool pmFPAviewReadFitsWeight(const pmFPAview *view,  ///< View specifying level of interest
     29/// Read a variance map into the current view
     30bool pmFPAviewReadFitsVariance(const pmFPAview *view,  ///< View specifying level of interest
    3131                             pmFPAfile *file, ///< FPA file into which to read
    3232                            pmConfig *config
     
    5757                           );
    5858
    59 /// Write the weight map for the specified view
    60 bool pmFPAviewWriteFitsWeight(const pmFPAview *view, ///< View specifying level of interest
     59/// Write the variance map for the specified view
     60bool pmFPAviewWriteFitsVariance(const pmFPAview *view, ///< View specifying level of interest
    6161                              pmFPAfile *file, ///< FPA file to write
    6262                              pmConfig *config ///< Configuration
  • trunk/psModules/src/camera/pmFPAfileIO.c

    r20937 r21363  
    173173        status = pmFPAviewReadFitsMask(view, file, config);
    174174        break;
    175       case PM_FPA_FILE_WEIGHT:
    176         status = pmFPAviewReadFitsWeight(view, file, config);
     175      case PM_FPA_FILE_VARIANCE:
     176        status = pmFPAviewReadFitsVariance(view, file, config);
    177177        break;
    178178      case PM_FPA_FILE_HEADER:
     
    262262      case PM_FPA_FILE_IMAGE:
    263263      case PM_FPA_FILE_MASK:
    264       case PM_FPA_FILE_WEIGHT:
     264      case PM_FPA_FILE_VARIANCE:
    265265      case PM_FPA_FILE_FRINGE:
    266266      case PM_FPA_FILE_DARK: {
     
    427427        status = pmFPAviewWriteFitsMask(view, file, config);
    428428        break;
    429       case PM_FPA_FILE_WEIGHT:
    430         status = pmFPAviewWriteFitsWeight(view, file, config);
     429      case PM_FPA_FILE_VARIANCE:
     430        status = pmFPAviewWriteFitsVariance(view, file, config);
    431431        break;
    432432      case PM_FPA_FILE_HEADER:
     
    524524      case PM_FPA_FILE_IMAGE:
    525525      case PM_FPA_FILE_MASK:
    526       case PM_FPA_FILE_WEIGHT:
     526      case PM_FPA_FILE_VARIANCE:
    527527      case PM_FPA_FILE_HEADER:
    528528      case PM_FPA_FILE_FRINGE:
     
    589589      case PM_FPA_FILE_IMAGE:
    590590      case PM_FPA_FILE_MASK:
    591       case PM_FPA_FILE_WEIGHT:
     591      case PM_FPA_FILE_VARIANCE:
    592592      case PM_FPA_FILE_HEADER:
    593593      case PM_FPA_FILE_FRINGE:
     
    730730    psString tmpName = pmConfigConvertFilename (file->filename, config, create, false);
    731731    if (!tmpName) {
    732         psError(PS_ERR_IO, false, "failed to determine real name from template for %s\n", file->filename);
    733         return false;
     732        psError(PS_ERR_IO, false, "failed to determine real name from template for %s\n", file->filename);
     733        return false;
    734734    }
    735735    psFree (file->filename);
     
    740740      case PM_FPA_FILE_IMAGE:
    741741      case PM_FPA_FILE_MASK:
    742       case PM_FPA_FILE_WEIGHT:
     742      case PM_FPA_FILE_VARIANCE:
    743743      case PM_FPA_FILE_HEADER:
    744744      case PM_FPA_FILE_FRINGE:
     
    771771          }
    772772
    773           // XXX if we have a mask file, then we need to read the mask bit names
    774           // defined for this file
    775           if (file->type == PM_FPA_FILE_MASK) {
    776             if (!pmConfigMaskReadHeader (config, phu)) {
    777                 psError(PS_ERR_IO, false, "error in mask bits");
    778                 return false;
    779             }
    780           }
    781 
    782773          // determine the current format from the header
    783774          // determine camera if not specified already
    784775          // XXX can I actually reach this with camera not specified??
    785           psMetadata *camera = NULL;
    786           psString formatName = NULL;
    787           psString cameraName = NULL;
    788           file->format = pmConfigCameraFormatFromHeader (&camera, &cameraName, &formatName, config, phu, true);
     776          psMetadata *camera = NULL;
     777          psString formatName = NULL;
     778          psString cameraName = NULL;
     779          file->format = pmConfigCameraFormatFromHeader(&camera, &cameraName, &formatName, config, phu, true);
    789780          if (!file->format) {
    790781            psError(PS_ERR_IO, false, "Failed to read CCD format from %s\n", file->filename);
     
    794785          psFree(phu);
    795786
    796           pmFPA *newFPA = pmFPAConstruct (camera, formatName);
    797           if (!newFPA) {
    798               psError(PS_ERR_IO, false, "Failed to construct FPA from %s for %s", file->filename, formatName);
    799               psFree(camera);
    800               psFree(formatName);
    801               return NULL;
    802           }
    803           psFree(camera);
    804           psFree(formatName);
    805           psFree(cameraName);
    806 
    807           // XXX this is really dangerous...
    808           psFree (file->fpa);
    809           file->fpa = newFPA;
     787          pmFPA *newFPA = pmFPAConstruct (camera, formatName);
     788          if (!newFPA) {
     789              psError(PS_ERR_IO, false, "Failed to construct FPA from %s for %s", file->filename, formatName);
     790              psFree(camera);
     791              psFree(formatName);
     792              return NULL;
     793          }
     794          psFree(camera);
     795          psFree(formatName);
     796          psFree(cameraName);
     797
     798          // XXX this is really dangerous...
     799          psFree (file->fpa);
     800          file->fpa = newFPA;
    810801        }
    811802
     
    938929      case PM_FPA_FILE_IMAGE:
    939930      case PM_FPA_FILE_MASK:
    940       case PM_FPA_FILE_WEIGHT:
     931      case PM_FPA_FILE_VARIANCE:
    941932      case PM_FPA_FILE_DARK:
    942933      case PM_FPA_FILE_FRINGE:
  • trunk/psModules/src/camera/pmHDU.c

    r21313 r21363  
    4545    psFree(hdu->header);
    4646    psFree(hdu->images);
    47     psFree(hdu->weights);
     47    psFree(hdu->variances);
    4848    psFree(hdu->masks);
    4949}
     
    6969    hdu->header  = NULL;
    7070    hdu->images  = NULL;
    71     hdu->weights = NULL;
     71    hdu->variances = NULL;
    7272    hdu->masks   = NULL;
    7373
     
    155155}
    156156
    157 bool pmHDUReadWeight(pmHDU *hdu, psFits *fits)
    158 {
    159     PS_ASSERT_PTR_NON_NULL(hdu, false);
    160     PS_ASSERT_PTR_NON_NULL(fits, false);
    161 
    162     return hduRead(hdu, &hdu->weights, fits);
     157bool pmHDUReadVariance(pmHDU *hdu, psFits *fits)
     158{
     159    PS_ASSERT_PTR_NON_NULL(hdu, false);
     160    PS_ASSERT_PTR_NON_NULL(fits, false);
     161
     162    return hduRead(hdu, &hdu->variances, fits);
    163163}
    164164
     
    235235}
    236236
    237 bool pmHDUWriteWeight(pmHDU *hdu, psFits *fits, const pmConfig *config)
     237bool pmHDUWriteVariance(pmHDU *hdu, psFits *fits, const pmConfig *config)
    238238{
    239239    PS_ASSERT_PTR_NON_NULL(hdu, false);
     
    241241
    242242    psImageMaskType maskVal = pmConfigMaskGet("MASK.VALUE", config); // Value to mask
    243     return hduWrite(hdu, hdu->weights, hdu->masks, maskVal, fits);
     243    return hduWrite(hdu, hdu->variances, hdu->masks, maskVal, fits);
    244244}
    245245
  • trunk/psModules/src/camera/pmHDU.h

    r21279 r21363  
    44 * @author Paul Price, IfA
    55 *
    6  * @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
    7  * @date $Date: 2009-02-04 02:39:36 $
     6 * @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
     7 * @date $Date: 2009-02-06 02:31:24 $
     8 *
    89 * Copyright 2005-2006 Institute for Astronomy, University of Hawaii
    910 */
     
    1819/// @{
    1920
     21#define PM_HDU_COVARIANCE_KEYWORD "PS_COVAR" // FITS keyword to indicate presence of a covariance matrix
     22
    2023/// An instance of the FITS Header Data Unit
    2124///
    22 /// Of course, it is not an exact replica of a FITS HDU --- they have no mask and weight data, but these are
     25/// Of course, it is not an exact replica of a FITS HDU --- they have no mask and variance data, but these are
    2326/// stored here for convenience --- it keeps all the relevant data about the image in one place.
    24 typedef struct
    25 {
     27typedef struct {
    2628    psString extname;                   ///< The extension name
    2729    bool blankPHU;                      ///< Is this a blank FITS Primary Header Unit, i.e., no data?
    2830    psMetadata *format;                 ///< The camera format
    2931    psMetadata *header;                 ///< The FITS header, or NULL if primary for FITS; or section info
    30     psArray *images;                    ///< The pixel data
    31     psArray *weights;                   ///< The pixel data
    32     psArray *masks;                     ///< The pixel data
    33 }
    34 pmHDU;
     32    psArray *images;                    ///< Pixel data
     33    psArray *variances;                 ///< Variance in the pixel data, or NULL
     34    psArray *masks;                     ///< Mask for the pixel data, or NULL
     35} pmHDU;
    3536
    3637
     
    6061                  );
    6162
    62 /// Read the HDU header and weight map
     63/// Read the HDU header and variance map
    6364///
    6465/// Moves to the appropriate extension
    65 bool pmHDUReadWeight(pmHDU *hdu,        ///< HDU to read
    66                      psFits *fits       ///< FITS file to read from
     66bool pmHDUReadVariance(pmHDU *hdu,        ///< HDU to read
     67                       psFits *fits       ///< FITS file to read from
    6768    );
    6869
     
    7980    );
    8081
    81 /// Write the HDU header and weight map
    82 bool pmHDUWriteWeight(pmHDU *hdu,       ///< HDU to write
    83                       psFits *fits,     ///< FITS file to write to
    84                       const pmConfig *config  ///< Configuration
     82/// Write the HDU header and variance map
     83bool pmHDUWriteVariance(pmHDU *hdu,       ///< HDU to write
     84                        psFits *fits,     ///< FITS file to write to
     85                        const pmConfig *config  ///< Configuration
    8586    );
    8687
  • trunk/psModules/src/camera/pmHDUGenerate.c

    r18227 r21363  
    274274        pmReadout *readout = cell->readouts->data[0]; // The first readout, as representative
    275275        // The proper image, used to get the size
    276         psImage *image = readout->image ? readout->image : (readout->mask ? readout->mask : readout->weight);
     276        psImage *image = readout->image ? readout->image : (readout->mask ? readout->mask : readout->variance);
    277277        if (!image) {
    278278            continue;
     
    283283                     image->numCols, image->numRows, readout->mask->numCols, readout->mask->numRows);
    284284        }
    285         if (readout->weight &&
    286                 (readout->weight->numCols != image->numCols || readout->weight->numRows != image->numRows)) {
    287             psWarning("Image and weight have different sizes (%dx%d vs %dx%d)!\n",
    288                      image->numCols, image->numRows, readout->weight->numCols, readout->weight->numRows);
     285        if (readout->variance &&
     286                (readout->variance->numCols != image->numCols || readout->variance->numRows != image->numRows)) {
     287            psWarning("Image and variance have different sizes (%dx%d vs %dx%d)!\n",
     288                     image->numCols, image->numRows, readout->variance->numCols, readout->variance->numRows);
    289289        }
    290290        // New reference
     
    355355    psElemType imageType = 0;           // Type of readout images
    356356    psElemType maskType = 0;            // Type of readout masks
    357     psElemType weightType = 0;          // Type of readout weights
     357    psElemType varianceType = 0;        // Type of readout variances
    358358    {
    359359        psListIterator *iter = psListIteratorAlloc(cells, PS_LIST_HEAD, false); // Iterator for cells
     
    381381                    maskType = checkTypes(maskType, readout->mask->type.type);
    382382                }
    383                 if (!hdu->weights && readout->weight) {
    384                     weightType = checkTypes(weightType, readout->weight->type.type);
     383                if (!hdu->variances && readout->variance) {
     384                    varianceType = checkTypes(varianceType, readout->variance->type.type);
    385385                }
    386386            }
     
    388388        psFree(iter);
    389389    }
    390     if (numReadouts == 0 || (imageType == 0 && maskType == 0 && weightType == 0)) {
     390    if (numReadouts == 0 || (imageType == 0 && maskType == 0 && varianceType == 0)) {
    391391        // Nothing from which to create an HDU
    392392        psFree(cells);
     
    421421        }
    422422    }
    423     if (weightType) {
    424         hdu->weights = psArrayAlloc(numReadouts);
     423    if (varianceType) {
     424        hdu->variances = psArrayAlloc(numReadouts);
    425425        for (int i = 0; i < numReadouts; i++) {
    426             psImage *weight = psImageAlloc(xSize, ySize, weightType);
    427             psImageInit(weight, 0.0);
    428             hdu->weights->data[i] = weight;
     426            psImage *variance = psImageAlloc(xSize, ySize, varianceType);
     427            psImageInit(variance, 0.0);
     428            hdu->variances->data[i] = variance;
    429429        }
    430430    }
     
    448448
    449449            psArray *readouts = cell->readouts; // Array of readouts
     450
    450451            psArray *hduImages = hdu->images; // Array of images in the HDU
    451452            psArray *hduMasks = hdu->masks; // Array of masks in the HDU
    452             psArray *hduWeights = hdu->weights; // Array of weights in the HDU
     453            psArray *hduVariances = hdu->variances; // Array of variances in the HDU
    453454            for (int i = 0; i < readouts->n; i++) {
    454455                pmReadout *readout = readouts->data[i]; // The readout of interest
     
    467468                    readout->mask = new;
    468469                }
    469                 if (readout->weight) {
    470                     psImage *new = pasteImage(hduWeights->data[i], readout->weight, trimsec);
    471                     psFree(readout->weight);
    472                     readout->weight = new;
     470                if (readout->variance) {
     471                    psImage *new = pasteImage(hduVariances->data[i], readout->variance, trimsec);
     472                    psFree(readout->variance);
     473                    readout->variance = new;
    473474                }
    474475
     
    504505
    505506// Return the level that an extension applies to
    506 static pmFPALevel extensionLevel(pmHDU *hdu // HDU to check
     507static pmFPALevel extensionLevel(const pmHDU *hdu // HDU to check
    507508                                )
    508509{
     
    512513    }
    513514    bool mdok = true;                   // Status of MD lookup
    514     psMetadata *file = psMetadataLookupMetadata(&mdok, hdu->format, "FILE"); // File information for camera format
     515    psMetadata *file = psMetadataLookupMetadata(&mdok, hdu->format, "FILE"); // File info for camera format
    515516    if (!mdok || !file) {
    516517        psError(PS_ERR_UNEXPECTED_NULL, true, "Can't file FILE information for camera format "
     
    581582        return false;
    582583    }
    583     if (hdu->images && hdu->masks && hdu->weights) {
     584    if (hdu->images && hdu->masks && hdu->variances) {
    584585        // It's already here!
    585586        return true;
     
    631632        return generateForCells(chip);
    632633    }
    633     if (hdu->images && hdu->masks && hdu->weights) {
     634    if (hdu->images && hdu->masks && hdu->variances) {
    634635        // It's already here!
    635636        return true;
     
    680681        return generateForChips(fpa);
    681682    }
    682     if (hdu->images && hdu->masks && hdu->weights) {
     683    if (hdu->images && hdu->masks && hdu->variances) {
    683684        // It's already here!
    684685        return true;
  • trunk/psModules/src/camera/pmHDUUtils.c

    r18554 r21363  
    1818
    1919    for (int i = 0; i < fpa->chips->n; i++) {
    20         pmChip *chip = fpa->chips->data[i];
    21         if (!chip) continue;
    22         if (chip->hdu) return chip->hdu;
    23         if (!chip->cells) continue;
    24         for (int j = 0; j < chip->cells->n; j++) {
    25             pmCell *cell = chip->cells->data[j];
    26             if (!cell) continue;
    27             if (cell->hdu) return cell->hdu;
    28         }
     20        pmChip *chip = fpa->chips->data[i];
     21        if (!chip) continue;
     22        if (chip->hdu) return chip->hdu;
     23        if (!chip->cells) continue;
     24        for (int j = 0; j < chip->cells->n; j++) {
     25            pmCell *cell = chip->cells->data[j];
     26            if (!cell) continue;
     27            if (cell->hdu) return cell->hdu;
     28        }
    2929    }
    3030    return NULL;
     
    158158
    159159    INDENT(fd, level + 1);
    160     if (hdu->weights) {
    161         fprintf(fd, "Weights:\n");
    162         for (long i = 0; i < hdu->weights->n; i++) {
    163             psImage *weight = hdu->weights->data[i]; // Weight image of interest
     160    if (hdu->variances) {
     161        fprintf(fd, "Variances:\n");
     162        for (long i = 0; i < hdu->variances->n; i++) {
     163            psImage *variance = hdu->variances->data[i]; // Variance image of interest
    164164            INDENT(fd, level + 2);
    165             fprintf(fd, "%ld: %dx%d\n", i, weight->numCols, weight->numRows);
     165            fprintf(fd, "%ld: %dx%d\n", i, variance->numCols, variance->numRows);
    166166        }
    167167    } else {
    168         fprintf(fd, "NO weights.\n");
     168        fprintf(fd, "NO variances.\n");
    169169    }
    170170
  • trunk/psModules/src/camera/pmReadoutStack.c

    r21183 r21363  
    1212// XXX should it be an error for the image to exist?
    1313psImage *pmReadoutSetAnalysisImage(pmReadout *readout, // Readout containing image
    14                                    const char *name, // Name of image in analysis metadata
    15                                    int numCols, int numRows, // Expected size of image
    16                                    psElemType type, // Expected type of image
    17                                    double init // Initial value
     14                                   const char *name, // Name of image in analysis metadata
     15                                   int numCols, int numRows, // Expected size of image
     16                                   psElemType type, // Expected type of image
     17                                   double init // Initial value
    1818    )
    1919{
     
    2424
    2525    if (!psMetadataAddImage(readout->analysis, PS_LIST_TAIL, name, 0, "Analysis image from " __FILE__, image)) {
    26         psAbort ("analysis image already exists");
     26        psAbort ("analysis image already exists");
    2727    }
    2828    psImageInit(image, init);
     
    3535// XXX not sure why this should call psMemIncrRefCounter
    3636psImage *pmReadoutGetAnalysisImage(pmReadout *readout, // Readout containing image
    37                                    const char *name       // Name of image in analysis metadata
     37                                   const char *name       // Name of image in analysis metadata
    3838    )
    3939{
     
    7878
    7979// XXX for the moment, use col0, row0, numCols, numRows supplied from the outside
    80 bool pmReadoutStackDefineOutput(pmReadout *readout, int col0, int row0, int numCols, int numRows, bool mask, bool weight, psImageMaskType blank)
     80bool pmReadoutStackDefineOutput(pmReadout *readout, int col0, int row0, int numCols, int numRows, bool mask, bool variance, psImageMaskType blank)
    8181{
    8282    PS_ASSERT_PTR_NON_NULL(readout, false);
     
    9292
    9393    if (mask) {
    94         // XXX is this an error?
     94        // XXX is this an error?
    9595        if (readout->mask) return false;
    96         readout->mask = psImageAlloc(numCols, numRows, PS_TYPE_IMAGE_MASK);
    97         psImageInit(readout->mask, blank);
    98     }
    99 
    100     if (weight) {
    101         // XXX is this an error?
    102         if (readout->weight) return false;
    103         readout->weight = psImageAlloc(numCols, numRows, PS_TYPE_F32);
    104         psImageInit(readout->weight, NAN);
     96        readout->mask = psImageAlloc(numCols, numRows, PS_TYPE_IMAGE_MASK);
     97        psImageInit(readout->mask, blank);
     98    }
     99
     100    if (variance) {
     101        // XXX is this an error?
     102        if (readout->variance) return false;
     103        readout->variance = psImageAlloc(numCols, numRows, PS_TYPE_F32);
     104        psImageInit(readout->variance, NAN);
    105105    }
    106106
     
    162162
    163163bool pmReadoutUpdateSize(pmReadout *readout, int minCols, int minRows,
    164                          int numCols, int numRows, bool mask, bool weight,
     164                         int numCols, int numRows, bool mask, bool variance,
    165165                         psImageMaskType blank)
    166166{
     
    203203    }
    204204
    205     if (weight) {
    206         if (!readout->weight) {
    207             readout->weight = psImageAlloc(numCols, numRows, PS_TYPE_F32);
    208             psImageInit(readout->weight, NAN);
    209         }
    210         if (readout->weight->numCols < numCols || readout->weight->numRows < numRows) {
    211             psImage *newWeight = psImageAlloc(numCols, numRows, PS_TYPE_F32);
    212             psImageInit(newWeight, NAN);
    213             psImageOverlaySection(newWeight, readout->weight, readout->col0, readout->row0, "=");
    214             psFree(readout->weight);
    215             readout->weight = newWeight;
     205    if (variance) {
     206        if (!readout->variance) {
     207            readout->variance = psImageAlloc(numCols, numRows, PS_TYPE_F32);
     208            psImageInit(readout->variance, NAN);
     209        }
     210        if (readout->variance->numCols < numCols || readout->variance->numRows < numRows) {
     211            psImage *newVariance = psImageAlloc(numCols, numRows, PS_TYPE_F32);
     212            psImageInit(newVariance, NAN);
     213            psImageOverlaySection(newVariance, readout->variance, readout->col0, readout->row0, "=");
     214            psFree(readout->variance);
     215            readout->variance = newVariance;
    216216        }
    217217    }
Note: See TracChangeset for help on using the changeset viewer.