Changeset 15228 for trunk/psModules/src/objects/pmPSF_IO.c
- Timestamp:
- Oct 5, 2007, 12:47:04 PM (19 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/objects/pmPSF_IO.c (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/objects/pmPSF_IO.c
r15053 r15228 6 6 * @author EAM, IfA 7 7 * 8 * @version $Revision: 1.2 4$ $Name: not supported by cvs2svn $9 * @date $Date: 2007- 09-28 00:38:42$8 * @version $Revision: 1.25 $ $Name: not supported by cvs2svn $ 9 * @date $Date: 2007-10-05 22:47:04 $ 10 10 * 11 11 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 126 126 bool pmPSFmodelWriteFPA (pmFPA *fpa, const pmFPAview *view, pmFPAfile *file, const pmConfig *config) 127 127 { 128 pmFPAview *thisView = pmFPAviewAlloc (view->nRows); 129 *thisView = *view; 128 130 129 131 for (int i = 0; i < fpa->chips->n; i++) { 130 132 pmChip *chip = fpa->chips->data[i]; 131 if (!pmPSFmodelWriteChip (chip, view, file, config)) { 133 thisView->chip = i; 134 if (!pmPSFmodelWriteChip (chip, thisView, file, config)) { 132 135 psError(PS_ERR_IO, false, "Failed to write PSF for %dth chip", i); 133 return false; 134 } 135 } 136 psFree(thisView); 137 return false; 138 } 139 } 140 psFree(thisView); 136 141 return true; 137 142 } … … 141 146 { 142 147 if (!pmPSFmodelWrite (chip->analysis, view, file, config)) { 143 psError(PS_ERR_IO, false, "Failed to write PSF for chip");144 return false;148 psError(PS_ERR_IO, false, "Failed to write PSF for chip"); 149 return false; 145 150 } 146 151 return true; … … 151 156 // - a PHU blank header 152 157 // - image header : FITS Image NAXIS = 0 153 // if (trendMode == MAP) 158 // if (trendMode == MAP) 154 159 // - psf resid (+header) : FITS Image 155 160 // else … … 186 191 // define the EXTNAME values used for image header, table data, and residual image segments 187 192 { 188 // lookup the EXTNAME values used for table data and image header segments189 char *rule = NULL;190 191 // Menu of EXTNAME rules192 psMetadata *menu = psMetadataLookupMetadata(&status, file->camera, "EXTNAME.RULES");193 if (!menu) {194 psError(PS_ERR_UNKNOWN, true, "missing EXTNAME.RULES in camera.config");195 return false;196 }197 198 // EXTNAME for image header199 rule = psMetadataLookupStr(&status, menu, "PSF.HEAD");200 if (!rule) {201 psError(PS_ERR_UNKNOWN, false, "missing entry for PSF.HEAD in EXTNAME.RULES in camera.config");202 return false;203 }204 headName = pmFPAfileNameFromRule (rule, file, view);205 206 // EXTNAME for table data207 rule = psMetadataLookupStr(&status, menu, "PSF.TABLE");208 if (!rule) {209 psError(PS_ERR_UNKNOWN, false, "missing entry for PSF.TABLE in EXTNAME.RULES in camera.config");210 psFree (headName);211 return false;212 }213 tableName = pmFPAfileNameFromRule (rule, file, view);214 215 // EXTNAME for resid data216 rule = psMetadataLookupStr(&status, menu, "PSF.RESID");217 if (!rule) {218 psError(PS_ERR_UNKNOWN, false, "missing entry for PSF.RESID in EXTNAME.RULES in camera.config");219 psFree (headName);220 psFree (tableName);221 return false;222 }223 residName = pmFPAfileNameFromRule (rule, file, view);193 // lookup the EXTNAME values used for table data and image header segments 194 char *rule = NULL; 195 196 // Menu of EXTNAME rules 197 psMetadata *menu = psMetadataLookupMetadata(&status, file->camera, "EXTNAME.RULES"); 198 if (!menu) { 199 psError(PS_ERR_UNKNOWN, true, "missing EXTNAME.RULES in camera.config"); 200 return false; 201 } 202 203 // EXTNAME for image header 204 rule = psMetadataLookupStr(&status, menu, "PSF.HEAD"); 205 if (!rule) { 206 psError(PS_ERR_UNKNOWN, false, "missing entry for PSF.HEAD in EXTNAME.RULES in camera.config"); 207 return false; 208 } 209 headName = pmFPAfileNameFromRule (rule, file, view); 210 211 // EXTNAME for table data 212 rule = psMetadataLookupStr(&status, menu, "PSF.TABLE"); 213 if (!rule) { 214 psError(PS_ERR_UNKNOWN, false, "missing entry for PSF.TABLE in EXTNAME.RULES in camera.config"); 215 psFree (headName); 216 return false; 217 } 218 tableName = pmFPAfileNameFromRule (rule, file, view); 219 220 // EXTNAME for resid data 221 rule = psMetadataLookupStr(&status, menu, "PSF.RESID"); 222 if (!rule) { 223 psError(PS_ERR_UNKNOWN, false, "missing entry for PSF.RESID in EXTNAME.RULES in camera.config"); 224 psFree (headName); 225 psFree (tableName); 226 return false; 227 } 228 residName = pmFPAfileNameFromRule (rule, file, view); 224 229 } 225 230 … … 227 232 // if this header block is new, write it to disk 228 233 if (hdu->header != file->header) { 229 // add EXTNAME, EXTHEAD, EXTTYPE to header230 psMetadataAddStr (hdu->header, PS_LIST_TAIL, "EXTTABLE", PS_META_REPLACE, "name of table extension", tableName);231 psMetadataAddStr (hdu->header, PS_LIST_TAIL, "EXTRESID", PS_META_REPLACE, "name of resid extension", residName);232 psMetadataAddStr (hdu->header, PS_LIST_TAIL, "EXTTYPE", PS_META_REPLACE, "extension type", "IMAGE");233 if (!file->wrote_phu) {234 // this hdu->header acts as the PHU: set EXTEND to be true235 psMetadataAddBool (hdu->header, PS_LIST_TAIL, "EXTEND", PS_META_REPLACE, "this file has extensions", true);236 file->wrote_phu = true;237 }238 239 psFitsWriteBlank (file->fits, hdu->header, headName);240 psTrace ("pmFPAfile", 5, "wrote ext head %s (type: %d)\n", file->filename, file->type);241 file->header = hdu->header;242 psFree (headName);234 // add EXTNAME, EXTHEAD, EXTTYPE to header 235 psMetadataAddStr (hdu->header, PS_LIST_TAIL, "EXTTABLE", PS_META_REPLACE, "name of table extension", tableName); 236 psMetadataAddStr (hdu->header, PS_LIST_TAIL, "EXTRESID", PS_META_REPLACE, "name of resid extension", residName); 237 psMetadataAddStr (hdu->header, PS_LIST_TAIL, "EXTTYPE", PS_META_REPLACE, "extension type", "IMAGE"); 238 if (!file->wrote_phu) { 239 // this hdu->header acts as the PHU: set EXTEND to be true 240 psMetadataAddBool (hdu->header, PS_LIST_TAIL, "EXTEND", PS_META_REPLACE, "this file has extensions", true); 241 file->wrote_phu = true; 242 } 243 244 psFitsWriteBlank (file->fits, hdu->header, headName); 245 psTrace ("pmFPAfile", 5, "wrote ext head %s (type: %d)\n", file->filename, file->type); 246 file->header = hdu->header; 247 psFree (headName); 243 248 } 244 249 … … 246 251 pmPSF *psf = psMetadataLookupPtr (&status, analysis, "PSPHOT.PSF"); 247 252 if (!psf) { 248 psError(PS_ERR_UNKNOWN, true, "missing PSF for this analysis metadata");249 psFree (tableName);250 psFree (residName);251 return false;253 psError(PS_ERR_UNKNOWN, true, "missing PSF for this analysis metadata"); 254 psFree (tableName); 255 psFree (residName); 256 return false; 252 257 } 253 258 254 259 // write the PSF model parameters in a FITS table 255 { 256 // we need to write a header for the table,257 psMetadata *header = psMetadataAlloc();258 259 char *modelName = pmModelClassGetName (psf->type);260 psMetadataAddStr (header, PS_LIST_TAIL, "PSF_NAME", 0, "PSF model name", modelName);261 262 psMetadataAddBool (header, PS_LIST_TAIL, "ERR_LMM", 0, "Use Poisson errors in fits?", psf->poissonErrorsPhotLMM);263 psMetadataAddBool (header, PS_LIST_TAIL, "ERR_LIN", 0, "Use Poisson errors in fits?", psf->poissonErrorsPhotLin);264 psMetadataAddBool (header, PS_LIST_TAIL, "ERR_PAR", 0, "Use Poisson errors in fits?", psf->poissonErrorsParams);265 266 int nPar = pmModelClassParameterCount (psf->type) ;267 psMetadataAdd (header, PS_LIST_TAIL, "PSF_NPAR", PS_DATA_S32, "PSF model parameter count", nPar);268 269 psMetadataAddS32 (header, PS_LIST_TAIL, "IMAXIS1", 0, "Image X Size", psf->fieldNx);270 psMetadataAddS32 (header, PS_LIST_TAIL, "IMAXIS2", 0, "Image Y Size", psf->fieldNy);271 psMetadataAddS32 (header, PS_LIST_TAIL, "IMREF1", 0, "Image X Ref", psf->fieldXo);272 psMetadataAddS32 (header, PS_LIST_TAIL, "IMREF2", 0, "Image Y Ref", psf->fieldYo);273 274 // extract PSF Clump info275 pmPSFClump psfClump;260 { 261 // we need to write a header for the table, 262 psMetadata *header = psMetadataAlloc(); 263 264 char *modelName = pmModelClassGetName (psf->type); 265 psMetadataAddStr (header, PS_LIST_TAIL, "PSF_NAME", 0, "PSF model name", modelName); 266 267 psMetadataAddBool (header, PS_LIST_TAIL, "ERR_LMM", 0, "Use Poisson errors in fits?", psf->poissonErrorsPhotLMM); 268 psMetadataAddBool (header, PS_LIST_TAIL, "ERR_LIN", 0, "Use Poisson errors in fits?", psf->poissonErrorsPhotLin); 269 psMetadataAddBool (header, PS_LIST_TAIL, "ERR_PAR", 0, "Use Poisson errors in fits?", psf->poissonErrorsParams); 270 271 int nPar = pmModelClassParameterCount (psf->type) ; 272 psMetadataAdd (header, PS_LIST_TAIL, "PSF_NPAR", PS_DATA_S32, "PSF model parameter count", nPar); 273 274 psMetadataAddS32 (header, PS_LIST_TAIL, "IMAXIS1", 0, "Image X Size", psf->fieldNx); 275 psMetadataAddS32 (header, PS_LIST_TAIL, "IMAXIS2", 0, "Image Y Size", psf->fieldNy); 276 psMetadataAddS32 (header, PS_LIST_TAIL, "IMREF1", 0, "Image X Ref", psf->fieldXo); 277 psMetadataAddS32 (header, PS_LIST_TAIL, "IMREF2", 0, "Image Y Ref", psf->fieldYo); 278 279 // extract PSF Clump info 280 pmPSFClump psfClump; 276 281 277 282 psfClump.X = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.X"); assert (status); … … 280 285 psfClump.dY = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.DY"); assert (status); 281 286 282 psMetadataAddF32 (header, PS_LIST_TAIL, "PSF_CLX", 0, "psf clump center", psfClump.X);283 psMetadataAddF32 (header, PS_LIST_TAIL, "PSF_CLY", 0, "psf clump center", psfClump.Y);284 psMetadataAddF32 (header, PS_LIST_TAIL, "PSF_CLDX", 0, "psf clump size", psfClump.dX);285 psMetadataAddF32 (header, PS_LIST_TAIL, "PSF_CLDY", 0, "psf clump size", psfClump.dY);286 287 // save the dimensions of each parameter288 for (int i = 0; i < nPar; i++) {289 char name[9];290 int nX, nY;291 292 pmTrend2D *trend = psf->params->data[i];293 if (trend == NULL) continue;294 295 if (trend->mode == PM_TREND_MAP) {296 nX = trend->map->map->numCols;297 nY = trend->map->map->numRows;298 } else {299 nX = trend->poly->nX;300 nY = trend->poly->nY;301 }302 snprintf (name, 9, "PAR%02d_NX", i);303 psMetadataAddS32 (header, PS_LIST_TAIL, name, 0, "", nX);304 snprintf (name, 9, "PAR%02d_NY", i);305 psMetadataAddS32 (header, PS_LIST_TAIL, name, 0, "", nY);306 snprintf (name, 9, "PAR%02d_MD", i);307 char *modeName = pmTrend2DModeToString (trend->mode);308 psMetadataAddStr (header, PS_LIST_TAIL, name, 0, "", modeName);309 psFree (modeName);310 }311 312 // other required information describing the PSF313 psMetadataAddF32 (header, PS_LIST_TAIL, "AP_RESID", 0, "aperture residual", psf->ApResid);314 psMetadataAddF32 (header, PS_LIST_TAIL, "AP_ERROR", 0, "aperture residual scatter", psf->dApResid);315 psMetadataAddF32 (header, PS_LIST_TAIL, "CHISQ", 0, "chi-square for fit", psf->chisq);316 psMetadataAddS32 (header, PS_LIST_TAIL, "NSTARS", 0, "number of stars used to measure PSF", psf->nPSFstars);317 318 // XXX can we drop this now?319 psMetadataAddF32 (header, PS_LIST_TAIL, "SKY_BIAS", PS_DATA_F32, "sky bias level", psf->skyBias);320 321 // build a FITS table of the PSF parameters322 psArray *psfTable = psArrayAllocEmpty (100);323 for (int i = 0; i < nPar; i++) {324 pmTrend2D *trend = psf->params->data[i];325 if (trend == NULL) continue; // skip unset parameters (eg, XPOS)326 327 if (trend->mode == PM_TREND_MAP) {328 // write the image components into a table: this is needed because they may each be a different size329 psImageMap *map = trend->map;330 for (int ix = 0; ix < map->map->numCols; ix++) {331 for (int iy = 0; iy < map->map->numRows; iy++) {332 psMetadata *row = psMetadataAlloc ();333 psMetadataAddS32 (row, PS_LIST_TAIL, "MODEL_TERM", 0, "", i);334 psMetadataAddS32 (row, PS_LIST_TAIL, "X_POWER", 0, "", ix);335 psMetadataAddS32 (row, PS_LIST_TAIL, "Y_POWER", 0, "", iy);336 psMetadataAddF32 (row, PS_LIST_TAIL, "VALUE", 0, "", map->map->data.F32[iy][ix]);337 psMetadataAddF32 (row, PS_LIST_TAIL, "ERROR", 0, "", map->error->data.F32[iy][ix]);338 psMetadataAddU8 (row, PS_LIST_TAIL, "MASK", 0, "", 0); // no cells are masked339 340 psArrayAdd (psfTable, 100, row);341 psFree (row);342 }343 }344 } else {345 // write the polynomial components into a table346 psPolynomial2D *poly = trend->poly;347 for (int ix = 0; ix <= poly->nX; ix++) {348 for (int iy = 0; iy <= poly->nY; iy++) {349 psMetadata *row = psMetadataAlloc ();350 psMetadataAddS32 (row, PS_LIST_TAIL, "MODEL_TERM", 0, "", i);351 psMetadataAddS32 (row, PS_LIST_TAIL, "X_POWER", 0, "", ix);352 psMetadataAddS32 (row, PS_LIST_TAIL, "Y_POWER", 0, "", iy);353 psMetadataAddF32 (row, PS_LIST_TAIL, "VALUE", 0, "", poly->coeff[ix][iy]);354 psMetadataAddF32 (row, PS_LIST_TAIL, "ERROR", 0, "", poly->coeffErr[ix][iy]);355 psMetadataAddU8 (row, PS_LIST_TAIL, "MASK", 0, "", poly->mask[ix][iy]);356 357 psArrayAdd (psfTable, 100, row);358 psFree (row);359 }360 }361 }362 }363 364 // write an empty FITS segment if we have no PSF information365 if (psfTable->n == 0) {366 // XXX this is probably an error (if we have a PSF, how do we have no data?)367 psFitsWriteBlank (file->fits, header, tableName);368 } else {369 psTrace ("pmFPAfile", 5, "writing psf data %s\n", tableName);370 if (!psFitsWriteTable (file->fits, header, psfTable, tableName)) {371 psError(PS_ERR_IO, false, "writing psf table data %s\n", tableName);372 psFree (tableName);373 psFree (residName);374 psFree (psfTable);375 psFree (header);376 return false;377 }378 }379 psFree (tableName);380 psFree (psfTable);381 psFree (header);287 psMetadataAddF32 (header, PS_LIST_TAIL, "PSF_CLX", 0, "psf clump center", psfClump.X); 288 psMetadataAddF32 (header, PS_LIST_TAIL, "PSF_CLY", 0, "psf clump center", psfClump.Y); 289 psMetadataAddF32 (header, PS_LIST_TAIL, "PSF_CLDX", 0, "psf clump size", psfClump.dX); 290 psMetadataAddF32 (header, PS_LIST_TAIL, "PSF_CLDY", 0, "psf clump size", psfClump.dY); 291 292 // save the dimensions of each parameter 293 for (int i = 0; i < nPar; i++) { 294 char name[9]; 295 int nX, nY; 296 297 pmTrend2D *trend = psf->params->data[i]; 298 if (trend == NULL) continue; 299 300 if (trend->mode == PM_TREND_MAP) { 301 nX = trend->map->map->numCols; 302 nY = trend->map->map->numRows; 303 } else { 304 nX = trend->poly->nX; 305 nY = trend->poly->nY; 306 } 307 snprintf (name, 9, "PAR%02d_NX", i); 308 psMetadataAddS32 (header, PS_LIST_TAIL, name, 0, "", nX); 309 snprintf (name, 9, "PAR%02d_NY", i); 310 psMetadataAddS32 (header, PS_LIST_TAIL, name, 0, "", nY); 311 snprintf (name, 9, "PAR%02d_MD", i); 312 char *modeName = pmTrend2DModeToString (trend->mode); 313 psMetadataAddStr (header, PS_LIST_TAIL, name, 0, "", modeName); 314 psFree (modeName); 315 } 316 317 // other required information describing the PSF 318 psMetadataAddF32 (header, PS_LIST_TAIL, "AP_RESID", 0, "aperture residual", psf->ApResid); 319 psMetadataAddF32 (header, PS_LIST_TAIL, "AP_ERROR", 0, "aperture residual scatter", psf->dApResid); 320 psMetadataAddF32 (header, PS_LIST_TAIL, "CHISQ", 0, "chi-square for fit", psf->chisq); 321 psMetadataAddS32 (header, PS_LIST_TAIL, "NSTARS", 0, "number of stars used to measure PSF", psf->nPSFstars); 322 323 // XXX can we drop this now? 324 psMetadataAddF32 (header, PS_LIST_TAIL, "SKY_BIAS", PS_DATA_F32, "sky bias level", psf->skyBias); 325 326 // build a FITS table of the PSF parameters 327 psArray *psfTable = psArrayAllocEmpty (100); 328 for (int i = 0; i < nPar; i++) { 329 pmTrend2D *trend = psf->params->data[i]; 330 if (trend == NULL) continue; // skip unset parameters (eg, XPOS) 331 332 if (trend->mode == PM_TREND_MAP) { 333 // write the image components into a table: this is needed because they may each be a different size 334 psImageMap *map = trend->map; 335 for (int ix = 0; ix < map->map->numCols; ix++) { 336 for (int iy = 0; iy < map->map->numRows; iy++) { 337 psMetadata *row = psMetadataAlloc (); 338 psMetadataAddS32 (row, PS_LIST_TAIL, "MODEL_TERM", 0, "", i); 339 psMetadataAddS32 (row, PS_LIST_TAIL, "X_POWER", 0, "", ix); 340 psMetadataAddS32 (row, PS_LIST_TAIL, "Y_POWER", 0, "", iy); 341 psMetadataAddF32 (row, PS_LIST_TAIL, "VALUE", 0, "", map->map->data.F32[iy][ix]); 342 psMetadataAddF32 (row, PS_LIST_TAIL, "ERROR", 0, "", map->error->data.F32[iy][ix]); 343 psMetadataAddU8 (row, PS_LIST_TAIL, "MASK", 0, "", 0); // no cells are masked 344 345 psArrayAdd (psfTable, 100, row); 346 psFree (row); 347 } 348 } 349 } else { 350 // write the polynomial components into a table 351 psPolynomial2D *poly = trend->poly; 352 for (int ix = 0; ix <= poly->nX; ix++) { 353 for (int iy = 0; iy <= poly->nY; iy++) { 354 psMetadata *row = psMetadataAlloc (); 355 psMetadataAddS32 (row, PS_LIST_TAIL, "MODEL_TERM", 0, "", i); 356 psMetadataAddS32 (row, PS_LIST_TAIL, "X_POWER", 0, "", ix); 357 psMetadataAddS32 (row, PS_LIST_TAIL, "Y_POWER", 0, "", iy); 358 psMetadataAddF32 (row, PS_LIST_TAIL, "VALUE", 0, "", poly->coeff[ix][iy]); 359 psMetadataAddF32 (row, PS_LIST_TAIL, "ERROR", 0, "", poly->coeffErr[ix][iy]); 360 psMetadataAddU8 (row, PS_LIST_TAIL, "MASK", 0, "", poly->mask[ix][iy]); 361 362 psArrayAdd (psfTable, 100, row); 363 psFree (row); 364 } 365 } 366 } 367 } 368 369 // write an empty FITS segment if we have no PSF information 370 if (psfTable->n == 0) { 371 // XXX this is probably an error (if we have a PSF, how do we have no data?) 372 psFitsWriteBlank (file->fits, header, tableName); 373 } else { 374 psTrace ("pmFPAfile", 5, "writing psf data %s\n", tableName); 375 if (!psFitsWriteTable (file->fits, header, psfTable, tableName)) { 376 psError(PS_ERR_IO, false, "writing psf table data %s\n", tableName); 377 psFree (tableName); 378 psFree (residName); 379 psFree (psfTable); 380 psFree (header); 381 return false; 382 } 383 } 384 psFree (tableName); 385 psFree (psfTable); 386 psFree (header); 382 387 } 383 388 384 389 // write the residual images (3D) 385 390 { 386 psMetadata *header = psMetadataAlloc ();387 if (psf->residuals == NULL) {388 // set some header keywords to make it clear there are no residuals?389 psFitsWriteBlank (file->fits, header, residName);390 psFree (residName);391 psFree (header);392 return true;393 }394 395 psMetadataAddS32 (header, PS_LIST_TAIL, "XBIN", 0, "", psf->residuals->xBin);396 psMetadataAddS32 (header, PS_LIST_TAIL, "YBIN", 0, "", psf->residuals->yBin);397 psMetadataAddS32 (header, PS_LIST_TAIL, "XCENTER", 0, "", psf->residuals->xCenter);398 psMetadataAddS32 (header, PS_LIST_TAIL, "YCENTER", 0, "", psf->residuals->yCenter);399 400 // write the residuals as three planes of the image401 // this call creates an extension with NAXIS3 = 3402 if (psf->residuals->Rx) {403 // this call creates an extension with NAXIS3 = 3404 psArray *images = psArrayAllocEmpty (3);405 psArrayAdd (images, 1, psf->residuals->Ro);406 psArrayAdd (images, 1, psf->residuals->Rx);407 psArrayAdd (images, 1, psf->residuals->Ry);408 409 psFitsWriteImageCube (file->fits, header, images, residName);410 psFree (images);411 } else {412 // this call creates an extension with NAXIS3 = 1413 psFitsWriteImage(file->fits, header, psf->residuals->Ro, 0, residName);414 }415 psFree (residName);416 psFree (header);391 psMetadata *header = psMetadataAlloc (); 392 if (psf->residuals == NULL) { 393 // set some header keywords to make it clear there are no residuals? 394 psFitsWriteBlank (file->fits, header, residName); 395 psFree (residName); 396 psFree (header); 397 return true; 398 } 399 400 psMetadataAddS32 (header, PS_LIST_TAIL, "XBIN", 0, "", psf->residuals->xBin); 401 psMetadataAddS32 (header, PS_LIST_TAIL, "YBIN", 0, "", psf->residuals->yBin); 402 psMetadataAddS32 (header, PS_LIST_TAIL, "XCENTER", 0, "", psf->residuals->xCenter); 403 psMetadataAddS32 (header, PS_LIST_TAIL, "YCENTER", 0, "", psf->residuals->yCenter); 404 405 // write the residuals as three planes of the image 406 // this call creates an extension with NAXIS3 = 3 407 if (psf->residuals->Rx) { 408 // this call creates an extension with NAXIS3 = 3 409 psArray *images = psArrayAllocEmpty (3); 410 psArrayAdd (images, 1, psf->residuals->Ro); 411 psArrayAdd (images, 1, psf->residuals->Rx); 412 psArrayAdd (images, 1, psf->residuals->Ry); 413 414 psFitsWriteImageCube (file->fits, header, images, residName); 415 psFree (images); 416 } else { 417 // this call creates an extension with NAXIS3 = 1 418 psFitsWriteImage(file->fits, header, psf->residuals->Ro, 0, residName); 419 } 420 psFree (residName); 421 psFree (header); 417 422 } 418 423 … … 465 470 psMetadata *outhead = psMetadataAlloc(); 466 471 if (phu) { 467 psMetadataCopy (outhead, phu->header);472 psMetadataCopy (outhead, phu->header); 468 473 } else { 469 pmConfigConformHeader (outhead, file->format);470 471 psMetadata *fileData = psMetadataLookupMetadata(NULL, file->format, "FILE"); // File information472 const char *fpaNameHdr = psMetadataLookupStr(NULL, fileData, "FPA.NAME");473 if (fpaNameHdr && strlen(fpaNameHdr) > 0) {474 const char *fpaName = psMetadataLookupStr(NULL, file->fpa->concepts, "FPA.NAME");475 psMetadataAddStr(outhead, PS_LIST_TAIL, fpaNameHdr, PS_META_REPLACE, "FPA name", fpaName);476 }474 pmConfigConformHeader (outhead, file->format); 475 476 psMetadata *fileData = psMetadataLookupMetadata(NULL, file->format, "FILE"); // File information 477 const char *fpaNameHdr = psMetadataLookupStr(NULL, fileData, "FPA.NAME"); 478 if (fpaNameHdr && strlen(fpaNameHdr) > 0) { 479 const char *fpaName = psMetadataLookupStr(NULL, file->fpa->concepts, "FPA.NAME"); 480 psMetadataAddStr(outhead, PS_LIST_TAIL, fpaNameHdr, PS_META_REPLACE, "FPA name", fpaName); 481 } 477 482 } 478 483 … … 524 529 { 525 530 if (!pmPSFmodelRead (chip->analysis, view, file, config)) { 526 psError(PS_ERR_IO, false, "Failed to write PSF for chip");527 return false;531 psError(PS_ERR_IO, false, "Failed to write PSF for chip"); 532 return false; 528 533 } 529 534 return true; … … 628 633 snprintf (name, 9, "PAR%02d_NX", i); 629 634 binning->nXruff = psMetadataLookupS32 (&status, header, name); 630 if (!status) continue;// not all parameters are defined635 if (!status) continue; // not all parameters are defined 631 636 632 637 snprintf (name, 9, "PAR%02d_NY", i); 633 638 binning->nYruff = psMetadataLookupS32 (&status, header, name); 634 if (!status) {635 psError(PS_ERR_UNKNOWN, true, "inconsistent PSF header: NX defined for PAR %d, but not NY", i);636 return false;637 }639 if (!status) { 640 psError(PS_ERR_UNKNOWN, true, "inconsistent PSF header: NX defined for PAR %d, but not NY", i); 641 return false; 642 } 638 643 639 644 snprintf (name, 9, "PAR%02d_MD", i); 640 645 char *modeName = psMetadataLookupStr (&status, header, name); 641 if (!status) {642 psError(PS_ERR_UNKNOWN, true, "inconsistent PSF header: NX & NY defined for PAR %d, but not MD", i);643 return false;644 }645 pmTrend2DMode psfTrendMode = pmTrend2DModeFromString (modeName);646 if (psfTrendMode == PM_TREND_NONE) {647 psfTrendMode = PM_TREND_POLY_ORD;648 }649 650 psImageBinningSetScale (binning, PS_IMAGE_BINNING_CENTER);651 psImageBinningSetSkipByOffset (binning, options->psfFieldXo, options->psfFieldYo);652 psf->params->data[i] = pmTrend2DNoImageAlloc (psfTrendMode, binning, NULL);646 if (!status) { 647 psError(PS_ERR_UNKNOWN, true, "inconsistent PSF header: NX & NY defined for PAR %d, but not MD", i); 648 return false; 649 } 650 pmTrend2DMode psfTrendMode = pmTrend2DModeFromString (modeName); 651 if (psfTrendMode == PM_TREND_NONE) { 652 psfTrendMode = PM_TREND_POLY_ORD; 653 } 654 655 psImageBinningSetScale (binning, PS_IMAGE_BINNING_CENTER); 656 psImageBinningSetSkipByOffset (binning, options->psfFieldXo, options->psfFieldYo); 657 psf->params->data[i] = pmTrend2DNoImageAlloc (psfTrendMode, binning, NULL); 653 658 } 654 659 psFree (binning); … … 674 679 675 680 pmTrend2D *trend = psf->params->data[iPar]; 676 if (trend == NULL) {677 psError(PS_ERR_UNKNOWN, true, "parameter %d not available", iPar);678 return false;679 }680 681 if (trend->mode == PM_TREND_MAP) {682 psImageMap *map = trend->map;683 assert (map);684 assert (map->map);685 assert (map->error);686 assert (xPow >= 0);687 assert (yPow >= 0);688 assert (xPow < map->map->numCols);689 assert (yPow < map->map->numRows);690 map->map->data.F32[yPow][xPow] = psMetadataLookupF32 (&status, row, "VALUE");691 map->error->data.F32[yPow][xPow] = psMetadataLookupF32 (&status, row, "ERROR");692 } else {693 psPolynomial2D *poly = trend->poly;694 assert (poly);695 assert (xPow >= 0);696 assert (yPow >= 0);697 assert (xPow <= poly->nX);698 assert (yPow <= poly->nY);699 poly->coeff[xPow][yPow] = psMetadataLookupF32 (&status, row, "VALUE");700 poly->coeffErr[xPow][yPow] = psMetadataLookupF32 (&status, row, "ERROR");701 poly->mask[xPow][yPow] = psMetadataLookupU8 (&status, row, "MASK");702 }681 if (trend == NULL) { 682 psError(PS_ERR_UNKNOWN, true, "parameter %d not available", iPar); 683 return false; 684 } 685 686 if (trend->mode == PM_TREND_MAP) { 687 psImageMap *map = trend->map; 688 assert (map); 689 assert (map->map); 690 assert (map->error); 691 assert (xPow >= 0); 692 assert (yPow >= 0); 693 assert (xPow < map->map->numCols); 694 assert (yPow < map->map->numRows); 695 map->map->data.F32[yPow][xPow] = psMetadataLookupF32 (&status, row, "VALUE"); 696 map->error->data.F32[yPow][xPow] = psMetadataLookupF32 (&status, row, "ERROR"); 697 } else { 698 psPolynomial2D *poly = trend->poly; 699 assert (poly); 700 assert (xPow >= 0); 701 assert (yPow >= 0); 702 assert (xPow <= poly->nX); 703 assert (yPow <= poly->nY); 704 poly->coeff[xPow][yPow] = psMetadataLookupF32 (&status, row, "VALUE"); 705 poly->coeffErr[xPow][yPow] = psMetadataLookupF32 (&status, row, "ERROR"); 706 poly->mask[xPow][yPow] = psMetadataLookupU8 (&status, row, "MASK"); 707 } 703 708 } 704 709 psFree (header);
Note:
See TracChangeset
for help on using the changeset viewer.
