- Timestamp:
- Apr 21, 2011, 4:21:45 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20110404/psModules/src/objects/pmPSF_IO.c
r31336 r31339 63 63 64 64 bool pmPSFmodelReadPSFClump (psMetadata *analysis, psMetadata *header); 65 bool pmPSFmodelRead_ApTrend (pmPSF *psf, pmFPAfile *file); 66 bool pmPSFmodelWrite_ApTrend (pmFPAfile *file, pmPSF *psf); 65 67 66 68 bool pmPSFmodelCheckDataStatusForView (const pmFPAview *view, const pmFPAfile *file) … … 197 199 psError(psErrorCodeLast(), false, "Failed to write PSF for chip"); 198 200 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 206 bool 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 249 bool 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"); 199 277 } 200 278 return true; … … 403 481 404 482 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; 407 485 } else { 408 nX = trend->poly->nX;409 nY = trend->poly->nY;486 nX = trend->poly->nX; 487 nY = trend->poly->nY; 410 488 } 411 489 snprintf (name, 9, "PAR%02d_NX", i); … … 441 519 for (int i = 0; i < nPar; i++) { 442 520 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); 480 522 } 481 523 … … 556 598 } 557 599 600 if (!pmPSFmodelWrite_ApTrend(file, psf)) { 601 psError(psErrorCodeLast(), false, "Unable to write PSF ApTrend"); 602 return false; 603 } 604 558 605 // write a representation of the psf model 559 606 { 560 607 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 }574 608 575 609 int DX = 65; … … 660 694 } 661 695 696 697 662 698 // if this file needs to have a PHU written out, write one 663 699 bool pmPSFmodelWritePHU (const pmFPAview *view, pmFPAfile *file, pmConfig *config) … … 967 1003 for (int i = 0; i < table->n; i++) { 968 1004 psMetadata *row = table->data[i]; 1005 969 1006 int iPar = psMetadataLookupS32 (&status, row, "MODEL_TERM"); 970 int xPow = psMetadataLookupS32 (&status, row, "X_POWER");971 int yPow = psMetadataLookupS32 (&status, row, "Y_POWER");972 1007 973 1008 pmTrend2D *trend = psf->params->data[iPar]; … … 977 1012 } 978 1013 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); 1001 1015 } 1002 1016 psFree (header); … … 1085 1099 } 1086 1100 1101 if (!pmPSFmodelRead_ApTrend (psf, file)) { 1102 psError(psErrorCodeLast(), false, "Unable to read PSF ApTrend data."); 1103 return false; 1104 } 1105 1087 1106 psMetadataAdd (chipAnalysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_DATA_UNKNOWN, "psphot psf", psf); 1088 1107 psFree (psf); … … 1092 1111 psFree (header); 1093 1112 1113 return true; 1114 } 1115 1116 // write aperture trend to a FITS table 1117 bool 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 1168 bool 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); 1094 1229 return true; 1095 1230 }
Note:
See TracChangeset
for help on using the changeset viewer.
