IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 9822


Ignore:
Timestamp:
Nov 1, 2006, 12:39:53 PM (20 years ago)
Author:
Paul Price
Message:

Adding functions to read/write an array of fringe statistics to a single table. This allows us to use multiple readouts as the different fringe components, and then add a table containing the fringe measurements.

Location:
trunk/psModules/src/detrend
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/detrend/pmFringeStats.c

    r9730 r9822  
    122122    // Vectors: x, y, mask
    123123
    124     psMetadata *scalars = psMetadataAlloc(); // Metadata to hold the scalars; will be the header
     124    psMetadata *scalars = psMemIncrRefCounter(header); // Metadata to hold the scalars; will be the header
     125    if (!scalars) {
     126        scalars = psMetadataAlloc();
     127    }
    125128    psMetadataAddS32(scalars, PS_LIST_TAIL, "PSFRNGDX", PS_META_REPLACE, "Median box half-width",
    126129                     regions->dX);
     
    503506}
    504507
     508//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     509// pmFringeIO
     510//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     511
     512bool pmFringesWriteFits(psFits *fits, psMetadata *header, const psArray *fringes, const char *extname)
     513{
     514    PS_ASSERT_PTR_NON_NULL(fits, false);
     515    PS_ASSERT_ARRAY_NON_NULL(fringes, false);
     516
     517    // Check the regions are all identical
     518    pmFringeRegions *regions = ((pmFringeStats*)fringes->data[0])->regions; // First region
     519    for (int i = i; i < fringes->n; i++) {
     520        pmFringeStats *stats = fringes->data[i];
     521        if (stats->regions != regions) {
     522            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Regions for fringe statistics are not identical.\n");
     523            return false;
     524        }
     525    }
     526
     527    // Ensure the region is legit
     528    psVector *x = regions->x;           // The x positions
     529    psVector *y = regions->y;           // The y positions
     530    psVector *mask = regions->mask;     // The region mask
     531    int numRows = regions->nRequested;  // Number of rows in the table
     532    PS_ASSERT_INT_POSITIVE(numRows, false);
     533    PS_ASSERT_VECTOR_NON_NULL(x, false);
     534    PS_ASSERT_VECTOR_NON_NULL(y, false);
     535    PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_F32, false);
     536    PS_ASSERT_VECTOR_TYPE(y, PS_TYPE_F32, false);
     537    PS_ASSERT_VECTOR_SIZE(x, (long)numRows, false);
     538    PS_ASSERT_VECTOR_SIZE(y, (long)numRows, false);
     539    if (mask) {
     540        PS_ASSERT_VECTOR_NON_NULL(mask, false);
     541        PS_ASSERT_VECTOR_TYPE(mask, PS_TYPE_U8, false);
     542        PS_ASSERT_VECTOR_SIZE(mask, (long)numRows, false);
     543    }
     544
     545    // We need to write:
     546    // Scalars: dX, dY, nX, nY
     547    // Vectors: x, y, mask, f, df
     548
     549    psMetadata *scalars = psMemIncrRefCounter(header); // Metadata to hold the scalars; will be the header
     550    if (!scalars) {
     551        scalars = psMetadataAlloc();
     552    }
     553    psMetadataAddS32(scalars, PS_LIST_TAIL, "PSFRNGDX", PS_META_REPLACE, "Median box half-width",
     554                     regions->dX);
     555    psMetadataAddS32(scalars, PS_LIST_TAIL, "PSFRNGDY", PS_META_REPLACE, "Median box half-height",
     556                     regions->dY);
     557    psMetadataAddS32(scalars, PS_LIST_TAIL, "PSFRNGNX", PS_META_REPLACE, "Large-scale smoothing in x",
     558                     regions->nX);
     559    psMetadataAddS32(scalars, PS_LIST_TAIL, "PSFRNGNY", PS_META_REPLACE, "Large-scale smoothing in y",
     560                     regions->nY);
     561
     562    psArray *table = psArrayAlloc(numRows); // The table
     563    // Translate the vectors into the required format for psFitsWriteTable()
     564    for (long i = 0; i < numRows; i++) {
     565        psMetadata *row = psMetadataAlloc();
     566        psMetadataAddF32(row, PS_LIST_TAIL, "x", PS_META_REPLACE, "Fringe position in x", x->data.F32[i]);
     567        psMetadataAddF32(row, PS_LIST_TAIL, "y", PS_META_REPLACE, "Fringe position in y", y->data.F32[i]);
     568        psU8 maskValue = 0;             // Mask value
     569        if (mask && mask->data.U8[i]) {
     570            maskValue = 0xff;
     571        }
     572
     573        psVector *f = psVectorAlloc(fringes->n, PS_TYPE_F32); // Measurements for each fringe component
     574        psVector *df = psVectorAlloc(fringes->n, PS_TYPE_F32); // Errors in measurements
     575        for (long j = 0; j < fringes->n; j++) {
     576            pmFringeStats *stats = fringes->data[j]; // Fringe statistics of interest
     577            f->data.F32[j] = stats->f->data.F32[i];
     578            df->data.F32[j] = stats->df->data.F32[i];
     579            if (!isfinite(f->data.F32[j]) || !isfinite(df->data.F32[j])) {
     580                maskValue = 0xff;
     581            }
     582        }
     583        psMetadataAdd(row, PS_LIST_TAIL, "f", PS_DATA_VECTOR | PS_META_REPLACE, "Fringe measurements", f);
     584        psMetadataAdd(row, PS_LIST_TAIL, "df", PS_DATA_VECTOR | PS_META_REPLACE, "Fringe errors", df);
     585        // Drop references
     586        psFree(f);
     587        psFree(df);
     588
     589        psMetadataAddU8(row, PS_LIST_TAIL, "mask", PS_META_REPLACE, "Mask", maskValue);
     590        table->data[i] = row;
     591    }
     592
     593    bool success;                       // Success of operation
     594    if (!(success = psFitsWriteTable(fits, scalars, table, extname))) {
     595        psError(PS_ERR_IO, false, "Unable to write fringe data to extension %s\n", extname);
     596    }
     597    psFree(scalars);
     598    psFree(table);
     599
     600    return success;
     601}
     602
     603
     604psArray *pmFringesReadFits(psMetadata *header, psFits *fits, const char *extname)
     605{
     606    PS_ASSERT_PTR_NON_NULL(fits, NULL);
     607
     608    if (extname && strlen(extname) > 0 && !psFitsMoveExtName(fits, extname)) {
     609        psError(PS_ERR_IO, false, "Unable to move to extension %s\n", extname);
     610        return NULL;
     611    }
     612
     613    psMetadata *headerCopy = psMemIncrRefCounter(header); // Copy of the header, or NULL
     614    headerCopy = psFitsReadHeader(headerCopy, fits); // The FITS header
     615    if (!headerCopy) {
     616        psError(PS_ERR_IO, false, "Unable to read header for extension %s\n", extname);
     617        psFree(headerCopy);
     618        return NULL;
     619    }
     620
     621    // Read the scalars from the header
     622    #define READ_FRINGES_SCALAR(SCALAR, NAME) \
     623    int SCALAR = psMetadataLookupS32(&mdok, headerCopy, NAME); \
     624    if (!mdok || SCALAR <= 0) { \
     625        psError(PS_ERR_IO, true, "Unable to find " NAME " in header of extension %s\n", extname); \
     626        psFree(headerCopy); \
     627        return NULL; \
     628    }
     629
     630    // Need to retrieve the scalars: dX, dY, nX, nY
     631    bool mdok = true;                   // Status of MD lookup
     632    READ_SCALAR(dX, "PSFRNGDX");
     633    READ_SCALAR(dY, "PSFRNGDY");
     634    READ_SCALAR(nX, "PSFRNGNX");
     635    READ_SCALAR(nY, "PSFRNGNY");
     636    psFree(headerCopy);
     637
     638    // Now the vectors: x, y, mask, f, df
     639    psArray *table = psFitsReadTable(fits); // The table
     640    long numRows = table->n;            // Number of rows
     641
     642    pmFringeRegions *regions = pmFringeRegionsAlloc(numRows, dX, dY, nX, nY); // The fringe regions
     643    psVector *x = psVectorAlloc(numRows, PS_TYPE_F32); // x position
     644    psVector *y = psVectorAlloc(numRows, PS_TYPE_F32); // y position
     645    psVector *mask = psVectorAlloc(numRows, PS_TYPE_U8); // mask
     646    regions->x = x;
     647    regions->y = y;
     648    regions->mask = mask;
     649    psArray *f = psArrayAlloc(numRows); // Array of fringe measurements
     650    psArray *df = psArrayAlloc(numRows);// Array of errors
     651    psArray *fringes = NULL; // Array of fringes, to return
     652
     653    #define READ_FRINGES_VECTOR_ROW(VECTOR, TYPE, NAME, DESCRIPTION) \
     654    VECTOR->data.TYPE[i] = psMetadataLookup##TYPE(&mdok, row, NAME); \
     655    if (!mdok) { \
     656        psError(PS_ERR_IO, true, "Unable to find " #DESCRIPTION " .\n"); \
     657        goto READ_FRINGES_DONE; \
     658    }
     659
     660    #define READ_FRINGES_ARRAY_ROW(ARRAY, NAME, DESCRIPTION) \
     661    ARRAY->data[i] = psMetadataLookupPtr(&mdok, row, NAME); \
     662    if (!ARRAY->data[i] || !mdok) { \
     663        psError(PS_ERR_IO, true, "Unable to find " #DESCRIPTION " .\n"); \
     664        goto READ_FRINGES_DONE; \
     665    }
     666
     667    // Translate the table into vectors
     668    for (long i = 0; i < numRows; i++) {
     669        psMetadata *row = table->data[i]; // Table row
     670        READ_FRINGES_VECTOR_ROW(x, F32, "x", "x position");
     671        READ_FRINGES_VECTOR_ROW(y, F32, "y", "y position");
     672        READ_FRINGES_VECTOR_ROW(mask, U8, "mask", "mask");
     673        READ_FRINGES_ARRAY_ROW(f, "f", "fringe measurement");
     674        READ_FRINGES_ARRAY_ROW(df, "df", "fringe error");
     675    }
     676
     677    // Get f,df into pmFringeStats
     678    long numFringes = ((psVector*)(f->data[0]))->n; // Number of fringe components
     679    fringes = psArrayAlloc(numFringes);
     680    for (int j = 0; j < numFringes; j++) {
     681        fringes->data[j] = pmFringeStatsAlloc(regions);
     682    }
     683
     684    for (long i = 0; i < numRows; i++) {
     685        psVector *measurements = f->data[i]; // Vector of measurements
     686        psVector *errors = df->data[i]; // Vector of errors
     687        for (int j = 0; j < numFringes; j++) {
     688            pmFringeStats *fringe = fringes->data[j];
     689            fringe->f->data.F32[i] = measurements->data.F32[j];
     690            fringe->df->data.F32[i] = errors->data.F32[j];
     691        }
     692    }
     693
     694READ_FRINGES_DONE:
     695    psFree(table);
     696    psFree(regions);
     697    psFree(x);
     698    psFree(y);
     699    psFree(mask);
     700    psFree(f);
     701    psFree(df);
     702
     703    return fringes;
     704}
     705
    505706
    506707//////////////////////////////////////////////////////////////////////////////////////////////////////////////
  • trunk/psModules/src/detrend/pmFringeStats.h

    r9615 r9822  
    88/// @author Paul Price, IfA
    99///
    10 /// @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
    11 /// @date $Date: 2006-10-17 22:03:32 $
     10/// @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
     11/// @date $Date: 2006-11-01 22:39:53 $
    1212///
    1313/// Copyright 2004-2006 Institute for Astronomy, University of Hawaii
     
    142142
    143143//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     144// Input/output for multiple pmFringeStats
     145//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     146
     147/// Write an array of fringes measurements to a FITS table.
     148///
     149/// Writes an array of fringe measurements for the same FPA component as a FITS table.  The array of fringe
     150/// statistics must all use the same fringe regions (or there is no point in storing them all together).  The
     151/// header is supplemented with scalar values dX, dY, nX and nY (as PSFRNGDX, PSFRNGDY, PSFRNGNX, PSFRNGNY)
     152/// from the fringe regions, while the fringe coordinates and mask are written as a FITS table (as x, y,
     153/// mask, f, df; f and df are vectors).
     154bool pmFringesWriteFits(psFits *fits,    ///< FITS file to which to write
     155                        psMetadata *header, ///< Header, or NULL
     156                        const psArray *fringes, ///< Array of pmFringeStats, all for the same pmFringeRegion
     157                        const char *extname ///< Extension name for table
     158                       );
     159
     160/// Reads an array of fringes measurements from a FITS table.
     161///
     162/// The fringes are read from the FITS file, at the given extension name.  The table provides the region and
     163/// the (possibly multiple) fringe statistics for that region.  The current extension is used if the extension
     164/// name is not provided.
     165psArray *pmFringesReadFits(psMetadata *header, ///< Header to read, or NULL
     166                           psFits *fits,///< FITS file from which to read
     167                           const char *extname ///< Extension name to read, or NULL
     168                          );
     169
     170
     171//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    144172// pmFringeScale
    145173//////////////////////////////////////////////////////////////////////////////////////////////////////////////
Note: See TracChangeset for help on using the changeset viewer.