irplib_dfs.c

00001 /* $Id: irplib_dfs.c,v 1.32 2007/05/14 12:02:25 llundin Exp $
00002  *
00003  * This file is part of the IRPLIB Package
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: llundin $
00023  * $Date: 2007/05/14 12:02:25 $
00024  * $Revision: 1.32 $
00025  * $Name: uves-3_3_1 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                    Includes
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 /* Needed to get irplib_sprintf() */
00045 #include "irplib_utils.h"
00046 #include "irplib_dfs.h"
00047 
00048 /*-----------------------------------------------------------------------------
00049                         Defines and Static variables
00050  -----------------------------------------------------------------------------*/
00051 
00052 /* Use at least this many places when printing the PAF key */
00053 #define PAF_KEY_LEN 21
00054 /* Right justify the PAF key and separate with an extra space */
00055 #define PAF_KEY_FORMAT "%-21s "
00056 
00057 static const char irplib_pro_did[] = "PRO-1.15";
00058 
00059 /*-----------------------------------------------------------------------------
00060                         Private function prototypes
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                               Function codes
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     /* Some ugly, traditional error handling that obscures
00321        the actual functionality (i.e. to fprintf() some strings) */
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         /* Initialization needed in absence of #if for CPL_TYPE_LONG */
00422         cpl_error_code err = CPL_ERROR_UNSUPPORTED_MODE;
00423 
00424 
00425         if (strstr(name, "ESO ") == name) {
00426             /* Drop prefix "ESO " */
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; /* Don't need to modify the key */
00433 
00434         if (qckey != name) {
00435             /* Replace <space> with . */
00436             char * p;
00437             for (p = qckey; *p != '\0'; p++)
00438                 if (*p == ' ') *p = '.';
00439         }
00440 
00441         /* Print the property as PAF */
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)) /* FIXME: Change to #if */
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     /* Create product frame */
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     /* Add any QC parameters here */
00659     if (applist != NULL) error = cpl_propertylist_append(plist, applist);
00660 
00661     /* Add DataFlow keywords */
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         /* Insert the frame of the saved file in the input frameset */
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 }    

Generated on Tue Jun 19 14:39:14 2007 for UVES Pipeline Reference Manual by  doxygen 1.4.6