00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #include <string.h>
00037 #include <strings.h>
00038 #include <sys/types.h>
00039 #include <regex.h>
00040 #include <assert.h>
00041
00042 #include <cpl.h>
00043
00044
00045 #include "irplib_utils.h"
00046 #include "irplib_dfs.h"
00047
00048
00049
00050
00051
00052
00053 #define PAF_KEY_LEN 21
00054
00055 #define PAF_KEY_FORMAT "%-21s "
00056
00057 static const char irplib_pro_did[] = "PRO-1.15";
00058
00059
00060
00061
00062
00063 static FILE * irplib_paf_init(const char *, const char *, const char *)
00064 #if defined __GNUC__ && __GNUC__ >= 4
00065 __attribute__((nonnull))
00066 #endif
00067 ;
00068
00069 static cpl_error_code irplib_paf_dump(const cpl_propertylist *, FILE *)
00070 #if defined __GNUC__ && __GNUC__ >= 4
00071 __attribute__((nonnull))
00072 #endif
00073 ;
00074
00075 static cpl_error_code irplib_paf_dump_string(const char *, const char *,
00076 const char *, FILE *);
00077 static cpl_error_code irplib_paf_dump_double(const char *, double, const char *,
00078 FILE *);
00079 static cpl_error_code irplib_paf_dump_int(const char *, int, const char *,
00080 FILE *);
00081
00082 static cpl_error_code irplib_product_save(cpl_frameset *,
00083 const cpl_parameterlist *,
00084 const cpl_frameset *,
00085 const cpl_image *,
00086 cpl_type_bpp,
00087 const cpl_table *,
00088 const cpl_propertylist *,
00089 const char *,
00090 const char *,
00091 const cpl_propertylist *,
00092 const char *,
00093 const char *,
00094 const char *);
00095
00096
00097
00102
00103
00106
00107
00108
00109
00110
00134
00135 cpl_error_code irplib_image_save(cpl_frameset * allframes,
00136 const cpl_parameterlist * parlist,
00137 const cpl_frameset * usedframes,
00138 const cpl_image * image,
00139 cpl_type_bpp bpp,
00140 const char * recipe,
00141 const char * procat,
00142 const cpl_propertylist * applist,
00143 const char * remregexp,
00144 const char * pipe_id,
00145 const char * filename)
00146 {
00147 const cpl_error_code error =
00148 irplib_product_save(allframes, parlist, usedframes, image, bpp, NULL,
00149 NULL, recipe, procat, applist, remregexp, pipe_id,
00150 filename);
00151
00152 cpl_ensure_code(!error, error);
00153
00154 return CPL_ERROR_NONE;
00155
00156 }
00157
00158
00159
00177
00178 cpl_error_code irplib_table_save(cpl_frameset * allframes,
00179 const cpl_parameterlist * parlist,
00180 const cpl_frameset * usedframes,
00181 const cpl_table * table,
00182 const cpl_propertylist * tablelist,
00183 const char * recipe,
00184 const char * procat,
00185 const cpl_propertylist * applist,
00186 const char * remregexp,
00187 const char * pipe_id,
00188 const char * filename)
00189 {
00190
00191 cpl_error_code error;
00192
00193 cpl_ensure_code(table != NULL, CPL_ERROR_NULL_INPUT);
00194
00195 error = irplib_product_save(allframes, parlist, usedframes, NULL,
00196 CPL_BPP_IEEE_FLOAT, table, tablelist, recipe,
00197 procat, applist, remregexp, pipe_id, filename);
00198
00199 cpl_ensure_code(!error, error);
00200
00201 return CPL_ERROR_NONE;
00202 }
00203
00204
00205
00235
00236 cpl_error_code irplib_paf_save(const char * instrume, const char *recipe,
00237 const cpl_propertylist * paflist,
00238 const char * filename)
00239 {
00240
00241 FILE * paf;
00242 cpl_error_code status;
00243
00244
00245 cpl_ensure_code(instrume != NULL, CPL_ERROR_NULL_INPUT);
00246 cpl_ensure_code(recipe != NULL, CPL_ERROR_NULL_INPUT);
00247 cpl_ensure_code(paflist != NULL, CPL_ERROR_NULL_INPUT);
00248 cpl_ensure_code(filename != NULL, CPL_ERROR_NULL_INPUT);
00249
00250
00251 paf = irplib_paf_init(instrume, recipe, filename);
00252
00253 cpl_ensure_code(paf != NULL, cpl_error_get_code());
00254
00255 status = irplib_paf_dump(paflist, paf);
00256 if (status == CPL_ERROR_NONE && fprintf(paf, "\n") != 1)
00257 status = CPL_ERROR_FILE_IO;
00258
00259 if (status == CPL_ERROR_NONE) {
00260 cpl_ensure_code(fclose(paf) == 0, CPL_ERROR_FILE_IO);
00261 } else {
00262 (void)fclose(paf);
00263 }
00264
00265 return status;
00266
00267 }
00268
00271
00291
00292 static FILE * irplib_paf_init(const char * instrume,
00293 const char * recipe,
00294 const char * filename)
00295 {
00296 FILE * paf = NULL;
00297 char * paf_id = NULL;
00298 const char paf_desc[] = "QC file";
00299 int nlen;
00300 cpl_error_code error;
00301
00302
00303 cpl_ensure(instrume != NULL, CPL_ERROR_NULL_INPUT, NULL);
00304 cpl_ensure(recipe != NULL, CPL_ERROR_NULL_INPUT, NULL);
00305 cpl_ensure(filename != NULL, CPL_ERROR_NULL_INPUT, NULL);
00306
00307
00308 cpl_msg_info(cpl_func, "Writing PAF: %s" , filename);
00309
00310 paf_id = irplib_sprintf("%s/%s", instrume, recipe);
00311 assert( paf_id != NULL);
00312
00313 paf = fopen(filename, "w");
00314
00315 if (paf == NULL) {
00316 cpl_free(paf_id);
00317 cpl_ensure(0, CPL_ERROR_FILE_IO, NULL);
00318 }
00319
00320
00321
00322
00323 error = CPL_ERROR_NONE;
00324
00325 if (!error) {
00326 nlen = fprintf(paf, "PAF.HDR.START ;# start of header\n");
00327 if (nlen <= PAF_KEY_LEN) error = CPL_ERROR_FILE_IO;
00328 }
00329
00330 if (!error) {
00331 nlen = fprintf(paf, "PAF.TYPE \"pipeline product\" ;\n");
00332 if (nlen <= PAF_KEY_LEN) error = CPL_ERROR_FILE_IO;
00333 }
00334
00335 if (!error) {
00336 nlen = fprintf(paf, "PAF.ID \"%s\"\n", paf_id);
00337 if (nlen <= PAF_KEY_LEN) error = CPL_ERROR_FILE_IO;
00338 }
00339
00340 if (!error) {
00341 nlen = fprintf(paf, "PAF.NAME \"%s\"\n", filename);
00342 if (nlen <= PAF_KEY_LEN) error = CPL_ERROR_FILE_IO;
00343 }
00344
00345 if (!error) {
00346 nlen = fprintf(paf, "PAF.DESC \"%s\"\n", paf_desc);
00347 if (nlen <= PAF_KEY_LEN) error = CPL_ERROR_FILE_IO;
00348 }
00349
00350 if (!error) {
00351 nlen = fprintf(paf, "PAF.CHCK.CHECKSUM \"\"\n");
00352 if (nlen <= PAF_KEY_LEN) error = CPL_ERROR_FILE_IO;
00353 }
00354
00355 if (!error) {
00356 nlen = fprintf(paf, "PAF.HDR.END ;# end of header\n");
00357 if (nlen <= PAF_KEY_LEN) error = CPL_ERROR_FILE_IO;
00358 }
00359
00360 if (!error) {
00361 nlen = fprintf(paf, "\n");
00362 if (nlen != 1) error = CPL_ERROR_FILE_IO;
00363 }
00364
00365 cpl_free(paf_id);
00366
00367 if (error) {
00368 (void)fclose(paf);
00369 cpl_msg_error(cpl_func, "Could not write PAF: %s", filename);
00370 cpl_ensure(0, error, NULL);
00371 }
00372
00373 return paf;
00374
00375 }
00376
00377
00406
00407 static cpl_error_code irplib_paf_dump(const cpl_propertylist * self, FILE * paf)
00408 {
00409 int i;
00410
00411
00412 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
00413 cpl_ensure_code(paf, CPL_ERROR_NULL_INPUT);
00414
00415 for (i=0; i < cpl_propertylist_get_size(self); i++) {
00416 const cpl_property * prop = cpl_propertylist_get((cpl_propertylist *)
00417 self, i);
00418 const char * name = cpl_property_get_name(prop);
00419 const char * comment = cpl_property_get_comment(prop);
00420 char * qckey;
00421
00422 cpl_error_code err = CPL_ERROR_UNSUPPORTED_MODE;
00423
00424
00425 if (strstr(name, "ESO ") == name) {
00426
00427 qckey = cpl_malloc(strlen(name) - 3);
00428 memcpy(qckey, name+4, strlen(name) - 3);
00429 } else if (strstr(name, " "))
00430 qckey = cpl_strdup(name);
00431 else
00432 qckey = (char *)name;
00433
00434 if (qckey != name) {
00435
00436 char * p;
00437 for (p = qckey; *p != '\0'; p++)
00438 if (*p == ' ') *p = '.';
00439 }
00440
00441
00442
00443 switch (cpl_property_get_type(prop)) {
00444 case CPL_TYPE_CHAR:
00445 err = irplib_paf_dump_int(qckey, cpl_property_get_char(prop),
00446 comment, paf);
00447 case CPL_TYPE_INT:
00448 err = irplib_paf_dump_int(qckey, cpl_property_get_int(prop),
00449 comment, paf);
00450 break;
00451 case CPL_TYPE_LONG:
00452 if (sizeof(long) == sizeof(int))
00453 err = irplib_paf_dump_int(qckey, cpl_property_get_long(prop),
00454 comment, paf);
00455 break;
00456 case CPL_TYPE_FLOAT:
00457 err = irplib_paf_dump_double(qckey, cpl_property_get_float(prop),
00458 comment, paf);
00459 break;
00460 case CPL_TYPE_DOUBLE:
00461 err = irplib_paf_dump_double(qckey, cpl_property_get_double(prop),
00462 comment, paf);
00463 break;
00464 case CPL_TYPE_STRING:
00465 err = irplib_paf_dump_string(qckey, cpl_property_get_string(prop),
00466 comment, paf);
00467 break;
00468 default:
00469 err = CPL_ERROR_UNSUPPORTED_MODE;
00470 }
00471
00472 if (qckey != name) cpl_free(qckey);
00473
00474 cpl_ensure_code(!err, err);
00475
00476 }
00477
00478 return CPL_ERROR_NONE;
00479 }
00480
00481
00494
00495 static cpl_error_code irplib_paf_dump_string(const char * key,
00496 const char * value,
00497 const char * comment, FILE * paf)
00498 {
00499 cpl_ensure_code(paf, CPL_ERROR_NULL_INPUT);
00500 cpl_ensure_code(key, CPL_ERROR_NULL_INPUT);
00501 cpl_ensure_code(value, CPL_ERROR_NULL_INPUT);
00502
00503 if (comment == NULL)
00504 cpl_ensure_code(fprintf(paf, PAF_KEY_FORMAT "\"%s\"\n",
00505 key, value) > PAF_KEY_LEN,
00506 CPL_ERROR_FILE_IO);
00507 else
00508 cpl_ensure_code(fprintf(paf, PAF_KEY_FORMAT "\"%s\" ; # %s\n",
00509 key, value, comment) > PAF_KEY_LEN,
00510 CPL_ERROR_FILE_IO);
00511
00512 return CPL_ERROR_NONE;
00513 }
00514
00515
00516
00527
00528 static cpl_error_code irplib_paf_dump_double(const char * key,
00529 double value,
00530 const char * comment, FILE * paf)
00531 {
00532 cpl_ensure_code(paf, CPL_ERROR_NULL_INPUT);
00533 cpl_ensure_code(key, CPL_ERROR_NULL_INPUT);
00534
00535 if (comment == NULL)
00536 cpl_ensure_code(fprintf(paf, PAF_KEY_FORMAT "%.10g\n",
00537 key, value) > PAF_KEY_LEN,
00538 CPL_ERROR_FILE_IO);
00539 else
00540 cpl_ensure_code(fprintf(paf, PAF_KEY_FORMAT "%.10g ; # %s\n",
00541 key, value, comment) > PAF_KEY_LEN,
00542 CPL_ERROR_FILE_IO);
00543
00544 return CPL_ERROR_NONE;
00545
00546 }
00547
00548
00559
00560 static cpl_error_code irplib_paf_dump_int(const char * key,
00561 int value,
00562 const char * comment, FILE * paf)
00563 {
00564 cpl_ensure_code(paf, CPL_ERROR_NULL_INPUT);
00565 cpl_ensure_code(key, CPL_ERROR_NULL_INPUT);
00566
00567 if (comment == NULL)
00568 cpl_ensure_code(fprintf(paf, PAF_KEY_FORMAT "%d\n",
00569 key, value) > PAF_KEY_LEN,
00570 CPL_ERROR_FILE_IO);
00571 else
00572 cpl_ensure_code(fprintf(paf, PAF_KEY_FORMAT "%d ; # %s\n",
00573 key, value, comment) > PAF_KEY_LEN,
00574 CPL_ERROR_FILE_IO);
00575
00576 return CPL_ERROR_NONE;
00577
00578 }
00579
00580
00581
00582
00583
00605
00606
00607 static cpl_error_code irplib_product_save(cpl_frameset * allframes,
00608 const cpl_parameterlist * parlist,
00609 const cpl_frameset * usedframes,
00610 const cpl_image * image,
00611 cpl_type_bpp bpp,
00612 const cpl_table * table,
00613 const cpl_propertylist * tablelist,
00614 const char * recipe,
00615 const char * procat,
00616 const cpl_propertylist * applist,
00617 const char * remregexp,
00618 const char * pipe_id,
00619 const char * filename) {
00620
00621 cpl_propertylist * plist;
00622 cpl_frame * product_frame;
00623 const cpl_boolean is_image = table == NULL ? CPL_TRUE : CPL_FALSE;
00624 cpl_error_code error = CPL_ERROR_NONE;
00625
00626
00627 assert(table == NULL || image == NULL);
00628 assert(tablelist == NULL || image == NULL);
00629
00630 cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
00631 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
00632 cpl_ensure_code(usedframes != NULL, CPL_ERROR_NULL_INPUT);
00633 cpl_ensure_code(recipe != NULL, CPL_ERROR_NULL_INPUT);
00634 cpl_ensure_code(procat != NULL, CPL_ERROR_NULL_INPUT);
00635 cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
00636 cpl_ensure_code(filename != NULL, CPL_ERROR_NULL_INPUT);
00637
00638 cpl_msg_info(cpl_func, "Writing FITS %s product(%s): %s",
00639 is_image ? "image" : "table", procat, filename);
00640
00641 product_frame = cpl_frame_new();
00642
00643
00644 error |= cpl_frame_set_filename(product_frame, filename);
00645 error |= cpl_frame_set_tag(product_frame, procat);
00646 error |= cpl_frame_set_type(product_frame,
00647 is_image ? CPL_FRAME_TYPE_IMAGE : CPL_FRAME_TYPE_TABLE);
00648 error |= cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
00649 error |= cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
00650
00651 if (error) {
00652 cpl_frame_delete(product_frame);
00653 return cpl_error_get_code();
00654 }
00655
00656 plist = cpl_propertylist_new();
00657
00658
00659 if (applist != NULL) error = cpl_propertylist_append(plist, applist);
00660
00661
00662 if (!error)
00663 error = cpl_dfs_setup_product_header(plist, product_frame, usedframes,
00664 parlist, recipe, pipe_id,
00665 irplib_pro_did);
00666
00667 if (remregexp != NULL && !error)
00668 error = cpl_propertylist_erase_regexp(plist, remregexp, 0);
00669
00670 if (!error) {
00671 if (is_image) {
00672 error = cpl_image_save(image, filename, bpp, plist,
00673 CPL_IO_DEFAULT);
00674 } else {
00675
00676 error = cpl_table_save(table, plist, tablelist, filename,
00677 CPL_IO_DEFAULT);
00678
00679 }
00680 }
00681
00682 if (!error) {
00683
00684
00685 error = cpl_frameset_insert(allframes, product_frame);
00686
00687 } else {
00688 cpl_frame_delete(product_frame);
00689 }
00690
00691 cpl_propertylist_delete(plist);
00692
00693 return error;
00694
00695 }