IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Apr 21, 2011, 4:21:45 PM (15 years ago)
Author:
eugene
Message:

add ApTrend I/O code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20110404/psModules/src/objects/pmPSF_IO.c

    r31336 r31339  
    6363
    6464bool pmPSFmodelReadPSFClump (psMetadata *analysis, psMetadata *header);
     65bool pmPSFmodelRead_ApTrend (pmPSF *psf, pmFPAfile *file);
     66bool pmPSFmodelWrite_ApTrend (pmFPAfile *file, pmPSF *psf);
    6567
    6668bool pmPSFmodelCheckDataStatusForView (const pmFPAview *view, const pmFPAfile *file)
     
    197199        psError(psErrorCodeLast(), false, "Failed to write PSF for chip");
    198200        return false;
     201    }
     202    return true;
     203}
     204
     205// XXX we save the model term identifiers (item) as S32, but they probably should be more flexible
     206bool pmTrend2DtoTable (psArray *table, pmTrend2D *trend, char *label, int item) {
     207
     208    if (trend == NULL) return true;
     209
     210    if (trend->mode == PM_TREND_MAP) {
     211        // write the image components into a table: this is needed because they may each be a different size
     212        psImageMap *map = trend->map;
     213        for (int ix = 0; ix < map->map->numCols; ix++) {
     214            for (int iy = 0; iy < map->map->numRows; iy++) {
     215                psMetadata *row = psMetadataAlloc ();
     216                psMetadataAddS32 (row, PS_LIST_TAIL, label,        0, "", item);
     217                psMetadataAddS32 (row, PS_LIST_TAIL, "X_POWER",    0, "", ix);
     218                psMetadataAddS32 (row, PS_LIST_TAIL, "Y_POWER",    0, "", iy);
     219                psMetadataAddF32 (row, PS_LIST_TAIL, "VALUE",      0, "", map->map->data.F32[iy][ix]);
     220                psMetadataAddF32 (row, PS_LIST_TAIL, "ERROR",      0, "", map->error->data.F32[iy][ix]);
     221                psMetadataAddU8  (row, PS_LIST_TAIL, "MASK",       0, "", 0); // no cells are masked
     222
     223                psArrayAdd (table, 100, row);
     224                psFree (row);
     225            }
     226        }
     227    } else {
     228        // write the polynomial components into a table
     229        psPolynomial2D *poly = trend->poly;
     230        for (int ix = 0; ix <= poly->nX; ix++) {
     231            for (int iy = 0; iy <= poly->nY; iy++) {
     232                psMetadata *row = psMetadataAlloc ();
     233                psMetadataAddS32 (row, PS_LIST_TAIL, label,        0, "", item);
     234                psMetadataAddS32 (row, PS_LIST_TAIL, "X_POWER",    0, "", ix);
     235                psMetadataAddS32 (row, PS_LIST_TAIL, "Y_POWER",    0, "", iy);
     236                psMetadataAddF32 (row, PS_LIST_TAIL, "VALUE",      0, "", poly->coeff[ix][iy]);
     237                psMetadataAddF32 (row, PS_LIST_TAIL, "ERROR",      0, "", poly->coeffErr[ix][iy]);
     238                psMetadataAddU8  (row, PS_LIST_TAIL, "MASK",       0, "", poly->coeffMask[ix][iy]);
     239
     240                psArrayAdd (table, 100, row);
     241                psFree (row);
     242            }
     243        }
     244    }
     245    return true;
     246}
     247
     248// extra trend2D elements from a row
     249bool pmTrend2DfromTableRow (pmTrend2D *trend, psMetadata *row) {
     250
     251    bool status = false;
     252
     253    int xPow = psMetadataLookupS32 (&status, row, "X_POWER");
     254    int yPow = psMetadataLookupS32 (&status, row, "Y_POWER");
     255
     256    if (trend->mode == PM_TREND_MAP) {
     257        psImageMap *map = trend->map;
     258        assert (map);
     259        assert (map->map);
     260        assert (map->error);
     261        assert (xPow >= 0);
     262        assert (yPow >= 0);
     263        assert (xPow < map->map->numCols);
     264        assert (yPow < map->map->numRows);
     265        map->map->data.F32[yPow][xPow]    = psMetadataLookupF32 (&status, row, "VALUE");
     266        map->error->data.F32[yPow][xPow]  = psMetadataLookupF32 (&status, row, "ERROR");
     267    } else {
     268        psPolynomial2D *poly = trend->poly;
     269        assert (poly);
     270        assert (xPow >= 0);
     271        assert (yPow >= 0);
     272        assert (xPow <= poly->nX);
     273        assert (yPow <= poly->nY);
     274        poly->coeff[xPow][yPow]     = psMetadataLookupF32 (&status, row, "VALUE");
     275        poly->coeffErr[xPow][yPow]  = psMetadataLookupF32 (&status, row, "ERROR");
     276        poly->coeffMask[xPow][yPow] = psMetadataLookupU8  (&status, row, "MASK");
    199277    }
    200278    return true;
     
    403481
    404482            if (trend->mode == PM_TREND_MAP) {
    405               nX = trend->map->map->numCols;
    406               nY = trend->map->map->numRows;
     483                nX = trend->map->map->numCols;
     484                nY = trend->map->map->numRows;
    407485            } else {
    408               nX = trend->poly->nX;
    409               nY = trend->poly->nY;
     486                nX = trend->poly->nX;
     487                nY = trend->poly->nY;
    410488            }
    411489            snprintf (name, 9, "PAR%02d_NX", i);
     
    441519        for (int i = 0; i < nPar; i++) {
    442520            pmTrend2D *trend = psf->params->data[i];
    443             if (trend == NULL) continue; // skip unset parameters (eg, XPOS)
    444 
    445             if (trend->mode == PM_TREND_MAP) {
    446                 // write the image components into a table: this is needed because they may each be a different size
    447                 psImageMap *map = trend->map;
    448                 for (int ix = 0; ix < map->map->numCols; ix++) {
    449                     for (int iy = 0; iy < map->map->numRows; iy++) {
    450                         psMetadata *row = psMetadataAlloc ();
    451                         psMetadataAddS32 (row, PS_LIST_TAIL, "MODEL_TERM", 0, "", i);
    452                         psMetadataAddS32 (row, PS_LIST_TAIL, "X_POWER",    0, "", ix);
    453                         psMetadataAddS32 (row, PS_LIST_TAIL, "Y_POWER",    0, "", iy);
    454                         psMetadataAddF32 (row, PS_LIST_TAIL, "VALUE",      0, "", map->map->data.F32[iy][ix]);
    455                         psMetadataAddF32 (row, PS_LIST_TAIL, "ERROR",      0, "", map->error->data.F32[iy][ix]);
    456                         psMetadataAddU8  (row, PS_LIST_TAIL, "MASK",       0, "", 0); // no cells are masked
    457 
    458                         psArrayAdd (psfTable, 100, row);
    459                         psFree (row);
    460                     }
    461                 }
    462             } else {
    463                 // write the polynomial components into a table
    464                 psPolynomial2D *poly = trend->poly;
    465                 for (int ix = 0; ix <= poly->nX; ix++) {
    466                     for (int iy = 0; iy <= poly->nY; iy++) {
    467                         psMetadata *row = psMetadataAlloc ();
    468                         psMetadataAddS32 (row, PS_LIST_TAIL, "MODEL_TERM", 0, "", i);
    469                         psMetadataAddS32 (row, PS_LIST_TAIL, "X_POWER",    0, "", ix);
    470                         psMetadataAddS32 (row, PS_LIST_TAIL, "Y_POWER",    0, "", iy);
    471                         psMetadataAddF32 (row, PS_LIST_TAIL, "VALUE",      0, "", poly->coeff[ix][iy]);
    472                         psMetadataAddF32 (row, PS_LIST_TAIL, "ERROR",      0, "", poly->coeffErr[ix][iy]);
    473                         psMetadataAddU8  (row, PS_LIST_TAIL, "MASK",       0, "", poly->coeffMask[ix][iy]);
    474 
    475                         psArrayAdd (psfTable, 100, row);
    476                         psFree (row);
    477                     }
    478                 }
    479             }
     521            pmTrend2DtoTable (psfTable, trend, "MODEL_TERM", i);
    480522        }
    481523
     
    556598    }
    557599
     600    if (!pmPSFmodelWrite_ApTrend(file, psf)) {
     601        psError(psErrorCodeLast(), false, "Unable to write PSF ApTrend");
     602        return false;
     603    }
     604
    558605    // write a representation of the psf model
    559606    {
    560607        psMetadata *header = psMetadataAlloc ();
    561 
    562         if (0) {
    563             // set some header keywords to make it clear there are no residuals?
    564             if (!psFitsWriteBlank (file->fits, header, residName)) {
    565                 psError(psErrorCodeLast(), false, "Unable to write blank PSF residuals.");
    566                 psFree(residName);
    567                 psFree(header);
    568                 return false;
    569             }
    570             psFree (residName);
    571             psFree (header);
    572             return true;
    573         }
    574608
    575609        int DX = 65;
     
    660694}
    661695
     696
     697
    662698// if this file needs to have a PHU written out, write one
    663699bool pmPSFmodelWritePHU (const pmFPAview *view, pmFPAfile *file, pmConfig *config)
     
    9671003    for (int i = 0; i < table->n; i++) {
    9681004        psMetadata *row = table->data[i];
     1005
    9691006        int iPar = psMetadataLookupS32 (&status, row, "MODEL_TERM");
    970         int xPow = psMetadataLookupS32 (&status, row, "X_POWER");
    971         int yPow = psMetadataLookupS32 (&status, row, "Y_POWER");
    9721007
    9731008        pmTrend2D *trend = psf->params->data[iPar];
     
    9771012        }
    9781013
    979         if (trend->mode == PM_TREND_MAP) {
    980             psImageMap *map = trend->map;
    981             assert (map);
    982             assert (map->map);
    983             assert (map->error);
    984             assert (xPow >= 0);
    985             assert (yPow >= 0);
    986             assert (xPow < map->map->numCols);
    987             assert (yPow < map->map->numRows);
    988             map->map->data.F32[yPow][xPow]    = psMetadataLookupF32 (&status, row, "VALUE");
    989             map->error->data.F32[yPow][xPow]  = psMetadataLookupF32 (&status, row, "ERROR");
    990         } else {
    991             psPolynomial2D *poly = trend->poly;
    992             assert (poly);
    993             assert (xPow >= 0);
    994             assert (yPow >= 0);
    995             assert (xPow <= poly->nX);
    996             assert (yPow <= poly->nY);
    997             poly->coeff[xPow][yPow]     = psMetadataLookupF32 (&status, row, "VALUE");
    998             poly->coeffErr[xPow][yPow]  = psMetadataLookupF32 (&status, row, "ERROR");
    999             poly->coeffMask[xPow][yPow] = psMetadataLookupU8  (&status, row, "MASK");
    1000         }
     1014        pmTrend2DfromTableRow(trend, row);
    10011015    }
    10021016    psFree (header);
     
    10851099    }
    10861100
     1101    if (!pmPSFmodelRead_ApTrend (psf, file)) {
     1102        psError(psErrorCodeLast(), false, "Unable to read PSF ApTrend data.");
     1103        return false;
     1104    }
     1105
    10871106    psMetadataAdd (chipAnalysis, PS_LIST_TAIL, "PSPHOT.PSF",     PS_DATA_UNKNOWN,  "psphot psf", psf);
    10881107    psFree (psf);
     
    10921111    psFree (header);
    10931112
     1113    return true;
     1114}
     1115
     1116// write aperture trend to a FITS table
     1117bool pmPSFmodelWrite_ApTrend (pmFPAfile *file, pmPSF *psf) {
     1118
     1119    pmTrend2D *trend = psf->ApTrend;
     1120    if (trend == NULL) {
     1121        psWarning ("no PSF ApTrend to write out, skipping");
     1122        return true;
     1123    }
     1124
     1125    // we need to write a header for the table,
     1126    psMetadata *header = psMetadataAlloc();
     1127
     1128    int nX = 0, nY = 0;
     1129    if (trend->mode == PM_TREND_MAP) {
     1130        nX = trend->map->map->numCols;
     1131        nY = trend->map->map->numRows;
     1132    } else {
     1133        nX = trend->poly->nX;
     1134        nY = trend->poly->nY;
     1135    }
     1136    psMetadataAddS32 (header, PS_LIST_TAIL, "TREND_NX", 0, "", nX);
     1137    psMetadataAddS32 (header, PS_LIST_TAIL, "TREND_NY", 0, "", nY);
     1138    char *modeName = pmTrend2DModeToString (trend->mode);
     1139    psMetadataAddStr (header, PS_LIST_TAIL, "TREND_MD", 0, "", modeName);
     1140    psFree (modeName);
     1141
     1142    // build a FITS table of the ApTrend (only 1)
     1143    psArray *table = psArrayAllocEmpty (100);
     1144    pmTrend2DtoTable (table, trend, "APTREND", 0);
     1145
     1146    // write an empty FITS segment if we have no PSF information
     1147    if (table->n == 0) {
     1148        psError(PM_ERR_PROG, true, "No PSF data to write.");
     1149        psFree(table);
     1150        psFree(header);
     1151        return false;
     1152    }
     1153
     1154    psTrace ("pmFPAfile", 5, "writing psf ApTrend data %s\n", "AP_TREND");
     1155    if (!psFitsWriteTable(file->fits, header, table, "AP_TREND")) {
     1156        psError(psErrorCodeLast(), false, "Error writing psf table data %s\n", "AP_TREND");
     1157        psFree(table);
     1158        psFree(header);
     1159        return false;
     1160    }
     1161
     1162    psFree (table);
     1163    psFree (header);
     1164    return true;
     1165}
     1166
     1167// read aperture trend to a FITS table
     1168bool pmPSFmodelRead_ApTrend (pmPSF *psf, pmFPAfile *file) {
     1169
     1170    bool status;
     1171
     1172    // move fits pointer to AP_TREND section
     1173    // advance to the table data extension
     1174    if (!psFitsMoveExtNameClean (file->fits, "AP_TREND")) {
     1175        psWarning ("no Aperture Trend data in PSF file, skipping");
     1176        return true;
     1177    }
     1178
     1179    psMetadata *header = psFitsReadHeader (NULL, file->fits);
     1180    if (!header) {
     1181        psError(psErrorCodeLast(), false, "Unable to read AP_TREND header.");
     1182        return false;
     1183    }
     1184       
     1185    // read the raw table data
     1186    psArray *table = psFitsReadTable (file->fits);
     1187    if (!table) {
     1188        psError(psErrorCodeLast(), false, "Unable to read AP_TREND table.");
     1189        psFree(header);
     1190        return false;
     1191    }
     1192
     1193    // XXX allow user to set this optionally?
     1194    psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV);
     1195
     1196    psImageBinning *binning = psImageBinningAlloc();
     1197    binning->nXfine = psf->fieldNx;
     1198    binning->nYfine = psf->fieldNy;
     1199    binning->nXruff = psMetadataLookupS32 (&status, header, "TREND_NX");
     1200    binning->nYruff = psMetadataLookupS32 (&status, header, "TREND_NY");
     1201    psImageBinningSetScale (binning, PS_IMAGE_BINNING_CENTER);
     1202    char *modeName  = psMetadataLookupStr (&status, header, "TREND_MD");
     1203    if (!status) {
     1204        psError(PM_ERR_PROG, true, "inconsistent PSF header: NX & NY defined for AP TREND, but not MD");
     1205        psFree (header);
     1206        psFree (stats);
     1207        psFree (table);
     1208        return false;
     1209    }
     1210    pmTrend2DMode psfTrendMode = pmTrend2DModeFromString (modeName);
     1211    if (psfTrendMode == PM_TREND_NONE) {
     1212        psfTrendMode = PM_TREND_POLY_ORD;
     1213    }
     1214
     1215    // measure Trend2D for the current spatial scale
     1216    pmTrend2D *apTrend = pmTrend2DNoImageAlloc (PM_TREND_MAP, binning, stats);
     1217
     1218    // fill in the matching psf->params entries
     1219    for (int i = 0; i < table->n; i++) {
     1220        psMetadata *row = table->data[i];
     1221        pmTrend2DfromTableRow(apTrend, row);
     1222    }
     1223    psf->ApTrend = apTrend;
     1224
     1225    psFree (binning);
     1226    psFree (header);
     1227    psFree (stats);
     1228    psFree (table);
    10941229    return true;
    10951230}
Note: See TracChangeset for help on using the changeset viewer.