IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Feb 7, 2008, 5:16:12 PM (18 years ago)
Author:
Paul Price
Message:

Adding functions to read readouts into image/mask/weight. Reworking how readouts are read incrementally --- new functions pmReadoutReadChunk and pmReadoutMore will eventually replace pmReadoutReadNext. pmReadoutReadNext is kept for now, but I expect to retire it once I've checked that pmReadoutReadChunk and pmReadoutMore work. The idea behind having pmReadoutMore and pmReadoutReadChunk (two functions) instead of a single function is that pmReadoutMore can provide the check to see if more is desired to read, while pmReadoutReadChunk can do the work; this way the status information (was there an error reading, or was there just nothing to read) is easier. I don't believe I'm breaking anything by checking this in because I've just added new functions, but I could be wrong.

File:
1 edited

Legend:

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

    r16230 r16365  
    3232} fpaReadType;
    3333
     34// Desired type for pixels; the index corresponds to the fpaReadType, above.
     35static psElemType pixelTypes[] = {
     36    PS_TYPE_F32,
     37    PS_TYPE_MASK,
     38    PS_TYPE_F32,
     39    0
     40};
     41
    3442//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    3543// File-static functions
    3644//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     45
     46// Determine number of readouts in the FITS file
     47// In the process, reads the header and concepts
     48static bool cellNumReadouts(pmCell *cell,    // Cell of interest
     49                            psFits *fits     // FITS file
     50    )
     51{
     52    assert(cell);
     53    assert(fits);
     54
     55    // Get the HDU and read the header
     56    pmHDU *hdu = pmHDUFromCell(cell);   // The HDU
     57    if (!hdu || hdu->blankPHU) {
     58        psError(PS_ERR_IO, true, "Unable to find HDU");
     59        return false;
     60    }
     61    if (!pmCellReadHeader(cell, fits)) {
     62        psError(PS_ERR_IO, false, "Unable to read header for cell!\n");
     63        return false;
     64    }
     65    if (!pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CELLS |
     66                            PM_CONCEPT_SOURCE_DEFAULTS, true, NULL)) {
     67        psError(PS_ERR_IO, false, "Failed to read concepts for cell.\n");
     68        return false;
     69    }
     70
     71    // Get the size of the third dimension
     72    bool mdok;                          // Status of MD lookup
     73    int naxis = psMetadataLookupS32(&mdok, hdu->header, "NAXIS"); // The number of axes
     74    if (!mdok) {
     75        psError(PS_ERR_IO, true, "Unable to find NAXIS in header for extension %s\n", hdu->extname);
     76        return false;
     77    }
     78    if (naxis == 0) {
     79        // No pixels to read
     80        psError(PS_ERR_IO, true, "No pixels in extension %s.", hdu->extname);
     81        return false;
     82    }
     83    if (naxis < 2 || naxis > 3) {
     84        psError(PS_ERR_IO, true, "NAXIS in header of extension %s (= %d) is not valid.\n",
     85                hdu->extname, naxis);
     86        return false;
     87    }
     88    int naxis3;                     // Number of image planes
     89    if (naxis == 3) {
     90        naxis3 = psMetadataLookupS32(&mdok, hdu->header, "NAXIS3");
     91        if (!mdok) {
     92            psError(PS_ERR_IO, true, "Unable to find NAXIS3 in header for extension %s\n", hdu->extname);
     93            return false;
     94        }
     95    } else {
     96        naxis3 = 1;
     97    }
     98
     99    return naxis3;
     100}
     101
     102
     103// Determine readout scan properties: the next and last scans
     104// Requires that cellNumReadouts() has been called before (for header and concepts to have been read)
     105// In the process, adjusts the TRIMSEC
     106static bool readoutScanProperties(int *next, // Index of next scan
     107                                  int *last, // Index of last scan
     108                                  pmReadout *readout, // Readout of interest
     109                                  int numScans, // Number of scans to read at a time
     110                                  fpaReadType type // Type of image
     111    )
     112{
     113    assert(next);
     114    assert(last);
     115    assert(readout);
     116
     117    psImage *image;                     // Appropriate image from readout
     118    switch (type) {
     119      case FPA_READ_TYPE_IMAGE:
     120        image = readout->image;
     121        break;
     122      case FPA_READ_TYPE_MASK:
     123        image = readout->mask;
     124        break;
     125      case FPA_READ_TYPE_WEIGHT:
     126        image = readout->weight;
     127        break;
     128      default:
     129        psAbort("Unknown read type: %x\n", type);
     130    }
     131
     132    // Header and concepts have been read by a call to cellNumReadouts(), so we can just assume they're there.
     133
     134    // Get the trim and bias sections
     135    pmCell *cell = readout->parent;     // Parent cell
     136    PS_ASSERT_PTR_NON_NULL(cell, false);
     137    pmHDU *hdu = pmHDUFromCell(cell);   // HDU for data
     138    bool mdok = true;                   // Status of MD lookup
     139    psRegion *trimsec = psMetadataLookupPtr(&mdok, cell->concepts, "CELL.TRIMSEC"); // Trim sections
     140    if (!mdok || !trimsec || psRegionIsNaN(*trimsec)) {
     141        psError(PS_ERR_IO, true, "CELL.TRIMSEC is not set.\n");
     142        return false;
     143    }
     144    int readdir = psMetadataLookupS32(&mdok, cell->concepts, "CELL.READDIR"); // Read direction
     145    if (!mdok || readdir == 0 || (readdir != 1 && readdir != 2)) {
     146        psError(PS_ERR_IO, true, "CELL.READDIR is not set to -1 or +1.\n");
     147        return false;
     148    }
     149
     150    // Rationalize trimsec against naxis1, naxis2:  valid range for trimsec is 1-Nx,1-Ny
     151    if (trimsec->x1 < 1) {
     152        int naxis1 = psMetadataLookupS32(&mdok, hdu->header, "NAXIS1"); // The number of columns
     153        if (!mdok) {
     154            psError(PS_ERR_IO, true, "Unable to find NAXIS1 in header for extension %s\n", hdu->extname);
     155            return false;
     156        }
     157        trimsec->x1 = naxis1 + trimsec->x1;
     158    }
     159    if (trimsec->y1 < 1) {
     160        int naxis2 = psMetadataLookupS32(&mdok, hdu->header, "NAXIS2"); // The number of columns
     161        if (!mdok) {
     162            psError(PS_ERR_IO, true, "Unable to find NAXIS2 in header for extension %s\n", hdu->extname);
     163            return false;
     164        }
     165        trimsec->y1 = naxis2 + trimsec->y1;
     166    }
     167
     168
     169    // Calculate the segment offset and upper limit
     170    if (readdir == 1) {
     171        // Reading rows
     172        if (numScans == 0) {
     173            *next = trimsec->x0;
     174        } else {
     175            *next = image ? readout->row0 + numScans : 0;
     176        }
     177        *last = trimsec->y1;
     178    } else {
     179        // Reading cols
     180        if (numScans == 0) {
     181            *next = trimsec->y0;
     182        } else {
     183            *next = image ? readout->row0 + numScans : 0;
     184        }
     185        *last = trimsec->x1;
     186    }
     187
     188    return true;
     189}
     190
     191static psImage **readoutImageByType(pmReadout *readout, // Readout of interest
     192                                    fpaReadType type // Type of image
     193    )
     194{
     195    switch (type) {
     196      case FPA_READ_TYPE_IMAGE:
     197        return &readout->image;
     198      case FPA_READ_TYPE_MASK:
     199        return &readout->mask;
     200      case FPA_READ_TYPE_WEIGHT:
     201        return &readout->weight;
     202      default:
     203        psAbort("Unknown read type: %x\n", type);
     204    }
     205}
     206
     207
     208static bool readoutMore(pmReadout *readout, // Readout of interest
     209                        psFits *fits,    // FITS file
     210                        int z,          // Plane number
     211                        int numScans,   // Number of scans to read at a time
     212                        fpaReadType type // Type of image
     213    )
     214{
     215    assert(readout);
     216    assert(fits);
     217
     218    psImage *image = *readoutImageByType(readout, type);
     219
     220    if (!image) {
     221        return true;
     222    } else if (numScans == 0) {
     223        // Can only read the entire image once
     224        return false;
     225    }
     226
     227    pmCell *cell = readout->parent;     // Parent cell
     228    if (!cell) {
     229        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find parent cell.");
     230        return false;
     231    }
     232    int naxis3 = cellNumReadouts(cell, fits); // Number of planes
     233    if (z < naxis3) {
     234        return false;
     235    }
     236
     237    int next;                           // Next position
     238    int last;                           // Last position
     239    if (!readoutScanProperties(&next, &last, readout, numScans, type)) {
     240        psError(PS_ERR_UNKNOWN, false, "Unable to determine readout properties.");
     241        return false;
     242    }
     243
     244    return (next < last);
     245}
    37246
    38247// Carve a readout from the image pixels
     
    41250                         const psRegion *trimsec, // Trim section
    42251                         const psList *biassecs, // Bias sections
    43                          fpaReadType type
     252                         fpaReadType type // Type of image
    44253                        )
    45254{
     
    63272                                 );
    64273
    65     // place the image subset in the appropriate target location, freeing if needed
    66     switch (type) {
    67       case FPA_READ_TYPE_IMAGE:
    68         if (readout->image) {
    69             psFree (readout->image);
    70         }
    71         readout->image = psImageSubset(image, region);
    72         break;
    73       case FPA_READ_TYPE_MASK:
    74         if (readout->mask) {
    75             psFree (readout->mask);
    76         }
    77         readout->mask = psImageSubset(image, region);
    78         break;
    79       case FPA_READ_TYPE_WEIGHT:
    80         if (readout->weight) {
    81             psFree (readout->weight);
    82         }
    83         readout->weight = psImageSubset(image, region);
    84         break;
    85       default:
    86         psAbort("Unknown read type: %x\n", type);
    87     }
    88 
    89     // Get the list of overscans
    90     // XXX should this step only be performed for IMAGE, not MASK and WEIGHT types?
    91     // XXX that would allow us to overlay a MASK and WEIGHT which have been trimmed...
    92     if (readout->bias->n != 0) {
    93         // Make way!
    94         psFree(readout->bias);
    95         readout->bias = psListAlloc(NULL);
    96     }
    97     psListIterator *iter = psListIteratorAlloc((psList*)biassecs, PS_LIST_HEAD, false); // Iterator
    98     psRegion *biassec = NULL;       // A BIASSEC region from the list
    99     while ((biassec = psListGetAndIncrement(iter))) {
    100         if (psRegionIsNaN(*biassec)) {
    101             psString regionString = psRegionToString(*biassec);
    102             psError(PS_ERR_IO, true, "Invalid bias section: %s\n", regionString);
    103             psFree(regionString);
    104             psFree(readout);
    105             return false;
    106         }
    107         psRegion region = psRegionSet(PS_MAX(biassec->x0 - readout->col0, 0), // x0
    108                                       PS_MIN(biassec->x1 - readout->col0, image->numCols), // x1
    109                                       PS_MAX(biassec->y0 - readout->row0, 0), // y0
    110                                       PS_MIN(biassec->y1 - readout->row0, image->numRows) // y1
    111                                      );
    112         psImage *overscan = psImageSubset(image, region);
    113         psListAdd(readout->bias, PS_LIST_TAIL, overscan);
    114         psFree(overscan);
    115     }
    116     psFree(iter);
     274    // Place the image subset in the appropriate target location, freeing if needed
     275    psImage **target = readoutImageByType(readout, type); // Target image
     276    if (*target) {
     277        psFree(*target);
     278    }
     279    *target = psImageSubset(image, region);
     280
     281    // Get the list of overscans: only for IMAGE types (no overscan for MASK and WEIGHT)
     282    if (type == FPA_READ_TYPE_IMAGE) {
     283        if (readout->bias->n != 0) {
     284            // Make way!
     285            psFree(readout->bias);
     286            readout->bias = psListAlloc(NULL);
     287        }
     288        psListIterator *iter = psListIteratorAlloc((psList*)biassecs, PS_LIST_HEAD, false); // Iterator
     289        psRegion *biassec = NULL;       // A BIASSEC region from the list
     290        while ((biassec = psListGetAndIncrement(iter))) {
     291            if (psRegionIsNaN(*biassec)) {
     292                psString regionString = psRegionToString(*biassec);
     293                psError(PS_ERR_IO, true, "Invalid bias section: %s\n", regionString);
     294                psFree(regionString);
     295                psFree(readout);
     296                return false;
     297            }
     298            psRegion region = psRegionSet(PS_MAX(biassec->x0 - readout->col0, 0), // x0
     299                                          PS_MIN(biassec->x1 - readout->col0, image->numCols), // x1
     300                                          PS_MAX(biassec->y0 - readout->row0, 0), // y0
     301                                          PS_MIN(biassec->y1 - readout->row0, image->numRows) // y1
     302                );
     303            psImage *overscan = psImageSubset(image, region);
     304            psListAdd(readout->bias, PS_LIST_TAIL, overscan);
     305            psFree(overscan);
     306        }
     307        psFree(iter);
     308    }
    117309
    118310    return true;
     
    123315// out the edges of the region with 'bad' pixels.  The output image always has max-min rows.
    124316// The region represents the maximum bounds of the full image
    125 
    126317static psImage *readoutReadComponent(psImage *image, // Image into which to read
    127318                                     psFits *fits, // FITS file from which to read
     
    131322                                     int max,   // Maximum row/col number to read
    132323                                     int z,     // Image plane to read
    133                                      float bad // Bad value
     324                                     float bad, // Bad value
     325                                     psElemType type // Expected type for image
    134326    )
    135327{
     
    138330    assert((readdir == 1) || (readdir == 2));
    139331
    140     int nRead = 0;
    141     int nScans = max - min;
    142     assert (nScans > 0);
     332    int nRead = 0;                      // Number of scans read
     333    int nScans = max - min;             // Number of scans desired
     334    assert(nScans > 0);
    143335
    144336    psRegion toRead = *fullImage;  // full image region
    145337
    146     int dX = 0;
    147     int dY = 0;
    148     int nX = 0;
    149     int nY = 0;
     338    int dX = 0, dY = 0;                 // Offset from image in FITS file to lower left corner of what's read
     339    int nX = 0, nY = 0;                 // Size of region to read
    150340
    151341    if (readdir == 1) {
    152         toRead.y0 = PS_MAX (toRead.y0, min);
    153         toRead.y1 = PS_MIN (toRead.y1, max);
     342        toRead.y0 = PS_MAX(toRead.y0, min);
     343        toRead.y1 = PS_MIN(toRead.y1, max);
    154344        nRead = toRead.y1 - toRead.y0;
    155345        if (min < fullImage->y0) {
     
    159349        nY = nScans;
    160350    } else {
    161         toRead.x0 = PS_MAX (toRead.x0, min);
    162         toRead.x1 = PS_MIN (toRead.x1, max);
     351        toRead.x0 = PS_MAX(toRead.x0, min);
     352        toRead.x1 = PS_MIN(toRead.x1, max);
    163353        nRead = toRead.x1 - toRead.x0;
    164354        if (min < fullImage->x0) {
     
    174364    psTrace("psModules.camera", 7, "Image is %dx%d\n", image->numCols, image->numRows);
    175365
    176     // XXX: We only support F32 for now
    177     if (image->type.type != PS_TYPE_F32) {
    178         psImage *temp = psImageCopy(NULL, image, PS_TYPE_F32);
     366    // Ensure the pixel type corresponds to what we desire
     367    if (image->type.type != type) {
     368        psImage *temp = psImageCopy(NULL, image, type);
    179369        psFree(image);
    180370        image = temp;
    181371    }
    182372
     373    // Resize the image so that it matches the number of scans requested
    183374    // XXX this modification is not carried back up stream: it affects readout->row0,col0
     375    //
     376    // XXXXX Do we really want to do this???  Why???
    184377    if (nRead < nScans) {
    185378        // The region of interest is smaller than the number of pixels we want.
     
    195388}
    196389
     390// Read a chunk of a readout (or the whole lot)
     391static bool readoutReadChunk(pmReadout *readout, // Readout into which to read
     392                             psFits *fits, // FITS file
     393                             int z,     // Desired image plane
     394                             int numScans, // Number of scans (row or col depends on CELL.READDIR); 0 for all
     395                             fpaReadType type // Type of image
     396    )
     397{
     398    assert(readout);
     399    assert(fits);
     400    assert(z >= 0);
     401    assert(numScans >= 0);
     402
     403    psImage **imagePtr = readoutImageByType(readout, type); // Pointer to the image of interest
     404    if (*imagePtr && numScans == 0) {
     405        psError(PS_ERR_UNKNOWN, true, "Already read entire image --- won't clobber.");
     406        return false;
     407    }
     408
     409    pmCell *cell = readout->parent;     // The parent cell
     410    if (!cell) {
     411        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find parent cell.");
     412        return false;
     413    }
     414
     415    int naxis3 = cellNumReadouts(cell, fits); // Number of image planes
     416    if (z >= naxis3) {
     417        psError(PS_ERR_IO, false, "Desired image plane (%d) exceeds available number (%d).",
     418                z, naxis3);
     419        return false;
     420    }
     421
     422    int next;                           // Next position
     423    int last;                           // Last position
     424    if (!readoutScanProperties(&next, &last, readout, numScans, type)) {
     425        psError(PS_ERR_UNKNOWN, false, "Unable to determine readout properties.");
     426        return false;
     427    }
     428    if (next >= last) {
     429        psError(PS_ERR_IO, true, "No more of the readout to read.");
     430        return false;
     431    }
     432
     433    pmHDU *hdu = pmHDUFromCell(cell);   // The HDU
     434    assert(hdu && !hdu->blankPHU);      // Checked by cellNumReadouts()
     435
     436    bool mdok;                          // Status of MD lookup
     437    int readdir = psMetadataLookupS32(&mdok, cell->concepts, "CELL.READDIR"); // Read direction
     438    if (!mdok || readdir == 0 || (readdir != 1 && readdir != 2)) {
     439        psError(PS_ERR_IO, true, "CELL.READDIR is not set to -1 or +1.\n");
     440        return false;
     441    }
     442    float bad = psMetadataLookupF32(&mdok, cell->concepts, "CELL.BAD"); // Bad level
     443    if (!mdok) {
     444        psLogMsg(__func__, PS_LOG_WARN, "CELL.BAD is not set --- assuming zero.\n");
     445        bad = 0.0;
     446    }
     447    psRegion *trimsec = psMetadataLookupPtr(&mdok, cell->concepts, "CELL.TRIMSEC"); // Trim sections
     448    if (!mdok || !trimsec || psRegionIsNaN(*trimsec)) {
     449        psError(PS_ERR_IO, true, "CELL.TRIMSEC is not set.\n");
     450        return false;
     451    }
     452
     453    // Check the third dimension
     454    int naxis = psMetadataLookupS32(&mdok, hdu->header, "NAXIS"); // The number of axes
     455    if (!mdok) {
     456        psError(PS_ERR_IO, true, "Unable to find NAXIS in header for extension %s\n", hdu->extname);
     457        return false;
     458    }
     459    if (naxis == 0) {
     460        // No pixels to read
     461        psError(PS_ERR_IO, true, "No pixels in extension %s.", hdu->extname);
     462        return false;
     463    }
     464    if (naxis < 2 || naxis > 3) {
     465        psError(PS_ERR_IO, true, "NAXIS in header of extension %s (= %d) is not valid.\n",
     466                hdu->extname, naxis);
     467        return false;
     468    }
     469
     470    // Calculate limits, adjust readout->row0,col0
     471    if (readdir == 1) {
     472        // Reading rows
     473        readout->row0 = next;
     474        readout->col0 = trimsec->x0;
     475    } else {
     476        // Reading cols
     477        readout->col0 = next;
     478        readout->row0 = trimsec->y0;
     479    }
     480    int upper = next + numScans;        // Upper limit to next section
     481
     482    // Blow away existing data.
     483    // Do this before returning, so that we're not returning data from a previous read
     484    psImage **image = readoutImageByType(readout, type);
     485    psFree(*image);
     486    *image = NULL;
     487    *image = readoutReadComponent(*image, fits, trimsec, readdir, next, upper, z, bad, pixelTypes[type]);
     488
     489    // Read overscans only for "image" type --- weights and masks shouldn't record overscans
     490    if (type == FPA_READ_TYPE_IMAGE) {
     491        // Blow away existing data
     492        while (readout->bias->n > 0) {
     493            psListRemove(readout->bias, PS_LIST_HEAD);
     494        }
     495
     496        // Get the new bias sections
     497        psList *biassecs = psMetadataLookupPtr(&mdok, cell->concepts, "CELL.BIASSEC"); // Bias sections
     498        if (!mdok || !biassecs) {
     499            psError(PS_ERR_IO, true, "CELL.BIASSEC is not set.\n");
     500            return false;
     501        }
     502        psListIterator *biassecsIter = psListIteratorAlloc(biassecs, PS_LIST_HEAD, false); // Iterator
     503        psRegion *biassec = NULL;           // Bias section from iteration
     504        while ((biassec = psListGetAndIncrement(biassecsIter))) {
     505            psImage *bias = readoutReadComponent(NULL, fits, biassec, readdir, next, upper, z,
     506                                                 bad, pixelTypes[type]); // The bias
     507            psListAdd(readout->bias, PS_LIST_TAIL, bias);
     508            psFree(bias);                   // Drop reference
     509        }
     510        psFree(biassecsIter);
     511    }
     512
     513    return true;
     514}
    197515
    198516// Read into an cell; this is the engine for pmCellRead, pmCellReadMask, pmCellReadWeight
     
    260578    // set up pointers for the different possible image arrays
    261579    psArray *imageArray = NULL; // Array of images in the HDU
    262     psElemType imageType = PS_TYPE_F32; // Expected type for image
     580    psElemType imageType = pixelTypes[type]; // Expected type for image
    263581    switch (type) {
    264582      case FPA_READ_TYPE_IMAGE:
    265583        imageArray = hdu->images;
    266         imageType = PS_TYPE_F32;
    267584        break;
    268585      case FPA_READ_TYPE_MASK:
    269586        imageArray = hdu->masks;
    270         imageType = PS_TYPE_MASK;
    271587        break;
    272588      case FPA_READ_TYPE_WEIGHT:
    273589        imageArray = hdu->weights;
    274         imageType = PS_TYPE_F32;
    275590        break;
    276591      default:
     
    387702//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    388703
    389 // XXX need to pass back the error conditions as well as the 'keep going' state
     704// pmReadoutReadNext is maintained here (for now) to maintain backwards compatibility.
     705// pmReadoutReadNext has been replaced by pmReadoutRead, pmReadoutReadChunk, pmReadoutMore
    390706bool pmReadoutReadNext(bool *status, pmReadout *readout, psFits *fits, int z, int numScans)
    391707{
     
    405721    if (!hdu || hdu->blankPHU) {
    406722        // XXX is this an error condition?
    407         psTrace("psModules.camera", 7, "no HDU or pixel-less PHU: skipping\n");
    408723        *status = true;
    409724        return false;
     
    453768    if (naxis == 0) {
    454769        // No pixels to read, as for a PHU.
    455         psTrace("psModules.camera", 7, "pixel-less HDU: skipping\n");
    456770        *status = true;
    457771        return false;
     
    472786    if (z >= naxis3) {
    473787        // Nothing to see here.  Move along.
    474         psTrace("psModules.camera", 7, "requested plane off edge of cube: skipping\n");
    475788        *status = true;
    476789        return false;
     
    547860
    548861    // Get the new the trim section
    549     readout->image = readoutReadComponent(readout->image, fits, trimsec, readdir, offset, upper, z, bad); // The image
     862    readout->image = readoutReadComponent(readout->image, fits, trimsec, readdir, offset, upper, z, bad,
     863                                          PS_TYPE_F32); // The image
    550864
    551865    // Get the new bias sections
     
    553867    psRegion *biassec = NULL;           // Bias section from iteration
    554868    while ((biassec = psListGetAndIncrement(biassecsIter))) {
    555         psImage *bias = readoutReadComponent(NULL, fits, biassec, readdir, offset, upper, z, bad); // The bias
     869        psImage *bias = readoutReadComponent(NULL, fits, biassec, readdir, offset, upper, z, bad,
     870                                             PS_TYPE_F32); // The bias
    556871        psListAdd(readout->bias, PS_LIST_TAIL, bias);
    557872        psFree(bias);                   // Drop reference
     
    564879
    565880
     881
     882bool pmReadoutMore(pmReadout *readout, psFits *fits, int z, int numScans)
     883{
     884    PS_ASSERT_PTR_NON_NULL(readout, false);
     885    PS_ASSERT_FITS_NON_NULL(fits, false);
     886
     887    return readoutMore(readout, fits, z, numScans, FPA_READ_TYPE_IMAGE);
     888}
     889
     890bool pmReadoutReadChunk(pmReadout *readout, psFits *fits, int z, int numScans)
     891{
     892    PS_ASSERT_PTR_NON_NULL(readout, false);
     893    PS_ASSERT_FITS_NON_NULL(fits, false);
     894    PS_ASSERT_INT_NONNEGATIVE(z, false);
     895    PS_ASSERT_INT_NONNEGATIVE(numScans, false);
     896
     897    return readoutReadChunk(readout, fits, z, numScans, FPA_READ_TYPE_IMAGE);
     898}
     899
     900bool pmReadoutRead(pmReadout *readout, psFits *fits, int z)
     901{
     902    PS_ASSERT_PTR_NON_NULL(readout, false);
     903    PS_ASSERT_FITS_NON_NULL(fits, false);
     904
     905    return readoutReadChunk(readout, fits, z, 0, FPA_READ_TYPE_IMAGE);
     906}
     907
     908int pmCellNumReadouts(pmCell *cell, psFits *fits)
     909{
     910    PS_ASSERT_PTR_NON_NULL(cell, false);
     911    PS_ASSERT_FITS_NON_NULL(fits, false);
     912
     913    return cellNumReadouts(cell, fits);
     914}
     915
    566916bool pmCellRead(pmCell *cell, psFits *fits, psDB *db)
    567917{
    568918    PS_ASSERT_PTR_NON_NULL(cell, false);
    569     PS_ASSERT_PTR_NON_NULL(fits, false);
     919    PS_ASSERT_FITS_NON_NULL(fits, false);
    570920
    571921    return cellRead(cell, fits, db, FPA_READ_TYPE_IMAGE);
     
    575925{
    576926    PS_ASSERT_PTR_NON_NULL(chip, false);
    577     PS_ASSERT_PTR_NON_NULL(fits, false);
     927    PS_ASSERT_FITS_NON_NULL(fits, false);
    578928
    579929    return chipRead(chip, fits, db, FPA_READ_TYPE_IMAGE);
     
    583933{
    584934    PS_ASSERT_PTR_NON_NULL(fpa, false);
    585     PS_ASSERT_PTR_NON_NULL(fits, false);
     935    PS_ASSERT_FITS_NON_NULL(fits, false);
    586936
    587937    return fpaRead(fpa, fits, db, FPA_READ_TYPE_IMAGE);
     
    593943//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    594944
     945bool pmReadoutReadMask(pmReadout *readout, psFits *fits, int z)
     946{
     947    PS_ASSERT_PTR_NON_NULL(readout, false);
     948    PS_ASSERT_FITS_NON_NULL(fits, false);
     949
     950    return readoutReadChunk(readout, fits, z, 0, FPA_READ_TYPE_MASK);
     951}
     952
    595953bool pmCellReadMask(pmCell *cell, psFits *fits, psDB *db)
    596954{
    597955    PS_ASSERT_PTR_NON_NULL(cell, false);
    598     PS_ASSERT_PTR_NON_NULL(fits, false);
     956    PS_ASSERT_FITS_NON_NULL(fits, false);
    599957
    600958    return cellRead(cell, fits, db, FPA_READ_TYPE_MASK);
     
    604962{
    605963    PS_ASSERT_PTR_NON_NULL(chip, false);
    606     PS_ASSERT_PTR_NON_NULL(fits, false);
     964    PS_ASSERT_FITS_NON_NULL(fits, false);
    607965
    608966    return chipRead(chip, fits, db, FPA_READ_TYPE_MASK);
     
    612970{
    613971    PS_ASSERT_PTR_NON_NULL(fpa, false);
    614     PS_ASSERT_PTR_NON_NULL(fits, false);
     972    PS_ASSERT_FITS_NON_NULL(fits, false);
    615973
    616974    return fpaRead(fpa, fits, db, FPA_READ_TYPE_MASK);
     
    621979//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    622980
     981bool pmReadoutReadWeight(pmReadout *readout, psFits *fits, int z)
     982{
     983    PS_ASSERT_PTR_NON_NULL(readout, false);
     984    PS_ASSERT_FITS_NON_NULL(fits, false);
     985
     986    return readoutReadChunk(readout, fits, z, 0, FPA_READ_TYPE_WEIGHT);
     987}
     988
    623989bool pmCellReadWeight(pmCell *cell, psFits *fits, psDB *db)
    624990{
    625991    PS_ASSERT_PTR_NON_NULL(cell, false);
    626     PS_ASSERT_PTR_NON_NULL(fits, false);
     992    PS_ASSERT_FITS_NON_NULL(fits, false);
    627993
    628994    return cellRead(cell, fits, db, FPA_READ_TYPE_WEIGHT);
     
    632998{
    633999    PS_ASSERT_PTR_NON_NULL(chip, false);
    634     PS_ASSERT_PTR_NON_NULL(fits, false);
     1000    PS_ASSERT_FITS_NON_NULL(fits, false);
    6351001
    6361002    return chipRead(chip, fits, db, FPA_READ_TYPE_WEIGHT);
     
    6401006{
    6411007    PS_ASSERT_PTR_NON_NULL(fpa, false);
    642     PS_ASSERT_PTR_NON_NULL(fits, false);
     1008    PS_ASSERT_FITS_NON_NULL(fits, false);
    6431009
    6441010    return fpaRead(fpa, fits, db, FPA_READ_TYPE_WEIGHT);
     
    6521018{
    6531019    PS_ASSERT_PTR_NON_NULL(cell, false);
    654     PS_ASSERT_PTR_NON_NULL(fits, false);
     1020    PS_ASSERT_FITS_NON_NULL(fits, false);
    6551021
    6561022    return cellRead(cell, fits, db, FPA_READ_TYPE_HEADER);
     
    6601026{
    6611027    PS_ASSERT_PTR_NON_NULL(chip, false);
    662     PS_ASSERT_PTR_NON_NULL(fits, false);
     1028    PS_ASSERT_FITS_NON_NULL(fits, false);
    6631029
    6641030    return chipRead(chip, fits, db, FPA_READ_TYPE_HEADER);
     
    6681034{
    6691035    PS_ASSERT_PTR_NON_NULL(fpa, false);
    670     PS_ASSERT_PTR_NON_NULL(fits, false);
     1036    PS_ASSERT_FITS_NON_NULL(fits, false);
    6711037
    6721038    return fpaRead(fpa, fits, db, FPA_READ_TYPE_HEADER);
     
    6801046{
    6811047    PS_ASSERT_PTR_NON_NULL(cell, 0);
    682     PS_ASSERT_PTR_NON_NULL(fits, 0);
     1048    PS_ASSERT_FITS_NON_NULL(fits, 0);
    6831049    PS_ASSERT_STRING_NON_EMPTY(name, 0);
    6841050
     
    7391105{
    7401106    PS_ASSERT_PTR_NON_NULL(chip, 0);
    741     PS_ASSERT_PTR_NON_NULL(fits, 0);
     1107    PS_ASSERT_FITS_NON_NULL(fits, 0);
    7421108    PS_ASSERT_STRING_NON_EMPTY(name, 0);
    7431109
     
    7561122{
    7571123    PS_ASSERT_PTR_NON_NULL(fpa, 0);
    758     PS_ASSERT_PTR_NON_NULL(fits, 0);
     1124    PS_ASSERT_FITS_NON_NULL(fits, 0);
    7591125    PS_ASSERT_STRING_NON_EMPTY(name, 0);
    7601126
Note: See TracChangeset for help on using the changeset viewer.