- Timestamp:
- Oct 2, 2007, 5:01:45 PM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/pap_branch_070920/psLib/src/fits/psFitsHeader.c
r15154 r15168 7 7 * @author Robert DeSonia, MHPCC 8 8 * 9 * @version $Revision: 1.34.4. 4$ $Name: not supported by cvs2svn $10 * @date $Date: 2007-10-0 1 21:51:42$9 * @version $Revision: 1.34.4.5 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2007-10-03 03:01:45 $ 11 11 * 12 12 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 68 68 69 69 70 bool psFitsEmptyPHU(const psFits *fits, const psMetadata *header) 71 { 72 PS_ASSERT_PTR_NON_NULL(fits, false); 73 PS_ASSERT_METADATA_NON_NULL(header, false); 70 bool psFitsCheckSingleCompressedImagePHU(const psFits *fits, psMetadata *header) 71 { 72 PS_ASSERT_FITS_NON_NULL(fits, false); 73 74 if (!fits->compression) { 75 // User has turned off compression conventions; doesn't want any nasty surprises 76 return false; 77 } 74 78 75 79 if (psFitsGetExtNum(fits) != 0) { 76 // It's not the PHU, so it can't be an empty PHU! 77 return false; 78 } 79 80 if (header->list->n == 0) { 81 // There's nothing in the list 80 // It's not the PHU, so it can't be the PHU for a single compressed image! 81 return false; 82 } 83 84 if (psFitsGetSize(fits) != 2) { 85 // No second extension, or multiple extensions 86 return false; 87 } 88 89 int numKeys; // Number of keywords in the header 90 int status = 0; // CFITSIO status 91 fits_get_hdrspace(fits->fd, &numKeys, 0, &status); 92 if (numKeys >= NUM_EMPTY_KEYS) { 93 return false; 94 } 95 96 int bitpix, naxis; // Bits per pixel and number of axes 97 long naxes[MAX_COMPRESS_DIM]; // Dimensions 98 fits_get_img_param(fits->fd, MAX_COMPRESS_DIM, &bitpix, &naxis, naxes, &status); 99 if (naxis != 0) { 100 return false; 101 } 102 103 if (!header) { 104 for (int i = 1; i <= numKeys; i++) { 105 // Just want to read the keyword names, without parsing the values and stuffing into a metadata 106 char keyName[MAX_STRING_LENGTH];// Keyword name 107 char keyValue[MAX_STRING_LENGTH]; // Corresponding value 108 char keyComment[MAX_STRING_LENGTH]; // Corresponding comment 109 fits_read_keyn(fits->fd, i, keyName, keyValue, keyComment, &status); 110 if (!keywordInList(keyName, emptyKeys)) { 111 return false; 112 } 113 } 114 } else { 115 psMetadataIterator *iter = psMetadataIteratorAlloc(header, PS_LIST_HEAD, NULL); // Iterator 116 psMetadataItem *item; // Item from iteration 117 while ((item = psMetadataGetAndIncrement(iter))) { 118 if (!keywordInList(item->name, emptyKeys)) { 119 psFree(iter); 120 return false; 121 } 122 } 123 psFree(iter); 124 } 125 126 if (!psFitsMoveExtNum(fits, 1, false)) { 127 psWarning("Unable to examine first extension as suspect compressed image."); 128 return false; 129 } 130 131 if (fits_is_compressed_image(fits->fd, &status)) { 82 132 return true; 83 133 } 84 134 85 // Check if it's got any keywords of potential interest 86 psMetadataIterator *iter = psMetadataIteratorAlloc(header, PS_LIST_HEAD, NULL); // Iterator 87 psMetadataItem *item; // Item from iteration 88 while ((item = psMetadataGetAndIncrement(iter))) { 89 if (!keywordInList(item->name, emptyKeys)) { 90 psFree(iter); 91 return false; 92 } 93 } 94 psFree(iter); 95 96 return true; 97 } 98 99 100 psMetadata* psFitsReadHeader(psMetadata* out, 101 const psFits* fits) 102 { 103 if (fits == NULL) { 104 psError(PS_ERR_BAD_PARAMETER_NULL, true, 105 _("The input psFits object can not NULL.")); 106 return NULL; 107 } 108 109 if (out == NULL) { 110 out = psMetadataAlloc(); 111 } 135 // It's not a single compressed image PHU --- move back to the PHU for the user 136 if (!psFitsMoveExtNum(fits, 0, false)) { 137 psWarning("Unable to examine first extension as suspect compressed image."); 138 return false; 139 } 140 141 return false; 142 } 143 144 // Read the header 145 static psMetadata *readHeader(const psFits *fits // FITS file from which to read header 146 ) 147 { 148 assert(fits); 149 150 psMetadata *header = psMetadataAlloc(); // Header, to return 112 151 113 152 // Get number of key names … … 150 189 case 'X': // bit 151 190 case 'B': // byte 152 success = psMetadataAddS8( out, PS_LIST_TAIL, keyName, dupFlag, keyComment, atoi(keyValue));191 success = psMetadataAddS8(header, PS_LIST_TAIL, keyName, dupFlag, keyComment, atoi(keyValue)); 153 192 break; 154 193 case 'I': // short int. … … 156 195 // Trap NAN, INF and -INF, which cfitsio doesn't handle. 157 196 if (strncasecmp(keyValue, "NAN", 3) == 0) { 158 success = psMetadataAddF32( out, PS_LIST_TAIL, keyName, dupFlag, keyComment, NAN);197 success = psMetadataAddF32(header, PS_LIST_TAIL, keyName, dupFlag, keyComment, NAN); 159 198 } else if (strncasecmp(keyValue, "INF", 3) == 0) { 160 success = psMetadataAddF32( out, PS_LIST_TAIL, keyName, dupFlag, keyComment, INFINITY);199 success = psMetadataAddF32(header, PS_LIST_TAIL, keyName, dupFlag, keyComment, INFINITY); 161 200 } else if (strncasecmp(keyValue, "-INF", 4) == 0) { 162 success = psMetadataAddF32( out, PS_LIST_TAIL, keyName, dupFlag, keyComment, -INFINITY);201 success = psMetadataAddF32(header, PS_LIST_TAIL, keyName, dupFlag, keyComment, -INFINITY); 163 202 } else { 164 success = psMetadataAddS32(out, PS_LIST_TAIL, keyName, dupFlag, keyComment, atoi(keyValue)); 203 success = psMetadataAddS32(header, PS_LIST_TAIL, keyName, dupFlag, keyComment, 204 atoi(keyValue)); 165 205 } 166 206 break; 167 207 case 'J': // int. 168 success = psMetadataAddS32( out, PS_LIST_TAIL, keyName, dupFlag, keyComment, atoi(keyValue));208 success = psMetadataAddS32(header, PS_LIST_TAIL, keyName, dupFlag, keyComment, atoi(keyValue)); 169 209 break; 170 210 case 'U': // unsigned int. 171 success = psMetadataAddU32( out, PS_LIST_TAIL, keyName, dupFlag, keyComment, atol(keyValue));211 success = psMetadataAddU32(header, PS_LIST_TAIL, keyName, dupFlag, keyComment, atol(keyValue)); 172 212 break; 173 213 174 214 case 'K': // long int. can't all fit in a psS32, put in psF64 175 215 case 'F': 176 success = psMetadataAddF64( out, PS_LIST_TAIL, keyName, dupFlag, keyComment, atof(keyValue));216 success = psMetadataAddF64(header, PS_LIST_TAIL, keyName, dupFlag, keyComment, atof(keyValue)); 177 217 break; 178 218 case 'C': { … … 195 235 // cfitsio won't write these, so we write them as strings, and then have to trap them on read. 196 236 if (strcasecmp(keyValueFixed, "NAN") == 0) { 197 success = psMetadataAddF32( out, PS_LIST_TAIL, keyName, dupFlag, keyComment, NAN);237 success = psMetadataAddF32(header, PS_LIST_TAIL, keyName, dupFlag, keyComment, NAN); 198 238 } else if (strcasecmp(keyValueFixed, "INF") == 0) { 199 success = psMetadataAddF32( out, PS_LIST_TAIL, keyName, dupFlag, keyComment, INFINITY);239 success = psMetadataAddF32(header, PS_LIST_TAIL, keyName, dupFlag, keyComment, INFINITY); 200 240 } else if (strcasecmp(keyValueFixed, "-INF") == 0) { 201 success = psMetadataAddF32( out, PS_LIST_TAIL, keyName, dupFlag, keyComment, -INFINITY);241 success = psMetadataAddF32(header, PS_LIST_TAIL, keyName, dupFlag, keyComment, -INFINITY); 202 242 } else { 203 success = psMetadataAddStr( out, PS_LIST_TAIL, keyName, dupFlag, keyComment,243 success = psMetadataAddStr(header, PS_LIST_TAIL, keyName, dupFlag, keyComment, 204 244 keyValueFixed); 205 245 } … … 208 248 case 'L': { 209 249 bool temp = (keyValue[0] == 'T') ? 1 : 0; 210 success = psMetadataAddBool( out, PS_LIST_TAIL, keyName, dupFlag, keyComment, temp);250 success = psMetadataAddBool(header, PS_LIST_TAIL, keyName, dupFlag, keyComment, temp); 211 251 break; 212 252 } 213 253 default: 214 254 psError(PS_ERR_IO, true, _("Specified FITS metadata type, %c, is not supported."), keyType); 215 return out; 255 psFree(header); 256 return NULL; 216 257 } 217 258 218 259 if (!success) { 219 260 psError(PS_ERR_UNKNOWN, false, _("Failed to add metadata item, %s."), keyName); 220 return out; 261 psFree(header); 262 return NULL; 221 263 } 222 264 … … 227 269 (void)fits_get_errstatus(status, fitsErr); 228 270 psError(PS_ERR_IO, true, _("Failed to add metadata item, %s."), fitsErr); 229 return false; 230 } 231 271 psFree(header); 272 return false; 273 } 274 275 return header; 276 } 277 278 279 psMetadata* psFitsReadHeader(psMetadata* out, 280 const psFits* fits) 281 { 282 PS_ASSERT_FITS_NON_NULL(fits, NULL); 283 284 psMetadata *header = readHeader(fits); // Header 285 if (!header) { 286 return NULL; 287 } 288 289 // Explore the potential case that this is an empty PHU, and the first extension contains the sole image, 290 // which is compressed. 291 if (psFitsCheckSingleCompressedImagePHU(fits, header)) { 292 // This is really what we want, not the empty PHU 293 psTrace("psLib.fits", 1, 294 "This PHU should really be a compressed image --- getting that header instead."); 295 psFree(header); 296 header = readHeader(fits); 297 if (!header) { 298 return NULL; 299 } 300 } 301 302 if (!out) { 303 return header; 304 } 305 306 // Need to move header onto the nominated metadata 307 psMetadataIterator *iter = psMetadataIteratorAlloc(header, PS_LIST_HEAD, NULL); // Iterator 308 psMetadataItem *item; // Item from iteration 309 while ((item = psMetadataGetAndIncrement(iter))) { 310 // Need to look for MULTI, which won't be picked up using the iterator. 311 psMetadataItem *multiCheckItem = psMetadataLookup(header, item->name); 312 assert(multiCheckItem); 313 unsigned int flag = 0; // Flag to indicate MULTI; otherwise default action 314 if (multiCheckItem->type == PS_DATA_METADATA_MULTI) { 315 flag = PS_META_DUPLICATE_OK; 316 } 317 if (!psMetadataAddItem(out, item, PS_LIST_TAIL, flag)) { 318 psError(PS_ERR_UNKNOWN, false, "Unable to add header item %s to extant metadata.", 319 item->name); 320 psFree(iter); 321 psFree(header); 322 return NULL; 323 } 324 } 325 psFree(iter); 326 psFree(header); 232 327 return out; 233 328 } … … 235 330 psMetadata* psFitsReadHeaderSet(psMetadata* out, const psFits* fits) 236 331 { 237 if (fits == NULL) { 238 psError(PS_ERR_BAD_PARAMETER_NULL, true, _("The input psFits object can not NULL.")); 239 psFree(out); 240 return NULL; 241 } 242 243 if (out == NULL) { 332 PS_ASSERT_FITS_NON_NULL(fits, NULL); 333 334 if (!out) { 244 335 out = psMetadataAlloc(); 245 336 } … … 378 469 } 379 470 } else { 380 fits_update_key(fits->fd, TFLOAT, item->name, &item->data.F32, item->comment, &status); 471 fits_update_key(fits->fd, TFLOAT, item->name, &item->data.F32, item->comment, 472 &status); 381 473 } 382 474 break; … … 393 485 } 394 486 } else { 395 fits_update_key(fits->fd, TDOUBLE, item->name, &item->data.F64, item->comment, &status); 487 fits_update_key(fits->fd, TDOUBLE, item->name, &item->data.F64, item->comment, 488 &status); 396 489 } 397 490 break; … … 424 517 ) 425 518 { 426 if (!fits) { 427 psError(PS_ERR_BAD_PARAMETER_NULL, true, _("The input psFits object can not NULL.")); 428 return false; 429 } 430 431 if (!output) { 432 psError(PS_ERR_BAD_PARAMETER_NULL, true, _("The input psMetadata was NULL. Need a non-NULL psMetadata for operation to be performed.")); 433 return false; 434 } 519 PS_ASSERT_FITS_NON_NULL(fits, false); 520 PS_ASSERT_METADATA_NON_NULL(output, false); 435 521 436 522 return fitsWriteHeader(fits, output, true); … … 442 528 ) 443 529 { 444 if (!fits) { 445 psError(PS_ERR_BAD_PARAMETER_NULL, true, _("The input psFits object can not NULL.")); 446 return false; 447 } 530 PS_ASSERT_FITS_NON_NULL(fits, false); 448 531 449 532 // We allow output == NULL in order to write a minimal header. … … 487 570 bool psFitsHeaderValidate(psMetadata *header) 488 571 { 489 if (header == NULL) { 490 psError(PS_ERR_BAD_PARAMETER_NULL, true, _("The input psMetadata was NULL. Need a non-NULL psMetadata for operation to be performed.")); 491 return false; 492 } 572 PS_ASSERT_METADATA_NON_NULL(header, false); 493 573 494 574 // Traverse the metadata list and inspect at each key
Note:
See TracChangeset
for help on using the changeset viewer.
