fors_qc.c

00001 /* $Id: fors_qc.c,v 1.10 2010/09/14 07:49:30 cizzo Exp $
00002  *
00003  * This file is part of the FORS Library
00004  * Copyright (C) 2002-2010 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  02110-1301 USA
00019  */
00020 
00021 /*
00022  * $Author: cizzo $
00023  * $Date: 2010/09/14 07:49:30 $
00024  * $Revision: 1.10 $
00025  * $Name: fors-4_8_6 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <ctype.h>
00035 #include <string.h>
00036 #include <unistd.h>
00037 #include <math.h>
00038 
00039 #include <cpl.h>
00040 #include <fors_utils.h>
00041 #include <fors_paf.h>
00042 #include <fors_dfs.h>
00043 #include <fors_qc.h>
00044 
00045 #define DICT_LINE_LENGTH    (80)
00046 #define MAX_PAF_NAME_LENGTH (80)
00047 #define PAF_ROOT_NAME       "qc"
00048 
00056 const char *const fors_qc_dic_version = "2.0";
00057 
00058 static ForsPAF *pafFile = NULL;
00059 static int     pafIndex = 0;
00060 
00061 
00077 cpl_error_code fors_qc_start_group(cpl_propertylist *header,
00078                                    const char *qcdic_version, 
00079                                    const char *instrument)
00080 {
00081     char pafName[MAX_PAF_NAME_LENGTH];
00082 
00083     if (pafFile)
00084         return cpl_error_set("fors_qc_start_group", CPL_ERROR_FILE_ALREADY_OPEN);
00085 
00086     sprintf(pafName, "%s%.4d.paf", PAF_ROOT_NAME, pafIndex);
00087 
00088     if (!(pafFile = newForsPAF(pafName, "QC1 parameters", NULL, NULL)))
00089         return cpl_error_set("fors_qc_start_group", CPL_ERROR_FILE_NOT_CREATED);
00090     
00091     fors_qc_write_qc_string(header, 
00092                             "QC.DID", qcdic_version, "QC1 dictionary",
00093                             instrument);
00094 
00095     return CPL_ERROR_NONE;
00096 
00097 }
00098 
00099 #undef cleanup
00100 #define cleanup \
00101 do { \
00102     cpl_propertylist_delete(header); \
00103 } while(0)
00104 
00115 void fors_qc_write_group_heading(const cpl_frame *raw_frame,
00116                                  const char *pro_catg,
00117                                  const char *instrument)
00118 {
00119     cpl_propertylist *header = NULL;
00120     assure( raw_frame != NULL, return, NULL );
00121     assure( cpl_frame_get_filename(raw_frame) != NULL, return, NULL );
00122 
00123     header = cpl_propertylist_load(cpl_frame_get_filename(raw_frame), 0);
00124     assure( !cpl_error_get_code(), return, "Could not load %s header",
00125             cpl_frame_get_filename(raw_frame));
00126     
00127     fors_qc_write_string("PRO.CATG", pro_catg,
00128                          "Product category", instrument);
00129     assure( !cpl_error_get_code(), return, "Cannot write product category to "
00130             "QC log file");
00131     
00132     fors_qc_keyword_to_paf(header, "ESO DPR TYPE", NULL, 
00133                            "DPR type", instrument);
00134     assure( !cpl_error_get_code(), return, "Missing keyword DPR TYPE in raw "
00135             "frame header");
00136     
00137     fors_qc_keyword_to_paf(header, "ESO TPL ID", NULL, 
00138                            "Template", instrument);
00139     assure( !cpl_error_get_code(), return, "Missing keyword TPL ID in raw "
00140             "frame header");
00141     
00142     if (cpl_propertylist_has(header, "ESO INS FILT1 NAME")) {
00143         fors_qc_keyword_to_paf(header, "ESO INS FILT1 NAME", NULL,
00144                                "Filter name", instrument);
00145         assure( !cpl_error_get_code(), return, "Failed to write ESO INS FILT1 NAME");
00146     }
00147     
00148     fors_qc_keyword_to_paf(header, "ESO INS COLL NAME", NULL,
00149                            "Collimator name", instrument);
00150     assure( !cpl_error_get_code(), return, "Missing keyword INS COLL NAME in raw "
00151             "frame header");
00152     
00153     fors_qc_keyword_to_paf(header, "ESO DET CHIP1 ID", NULL,
00154                            "Chip identifier", instrument);
00155     assure( !cpl_error_get_code(), return, "Missing keyword DET CHIP1 ID in raw "
00156             "frame header");
00157     
00158     fors_qc_keyword_to_paf(header, "ESO DET WIN1 BINX", NULL,    
00159                            "Binning factor along X", instrument);
00160     assure( !cpl_error_get_code(), return, "Missing keyword ESO DET WIN1 BINX "
00161             "in raw frame header");
00162     
00163     fors_qc_keyword_to_paf(header, "ESO DET WIN1 BINY", NULL,
00164                            "Binning factor along Y", instrument);
00165     assure( !cpl_error_get_code(), return, "Missing keyword ESO DET WIN1 BINY "
00166             "in raw frame header");
00167     
00168     fors_qc_keyword_to_paf(header, "ARCFILE", NULL,
00169                            "Archive name of input data", 
00170                            instrument);
00171     assure( !cpl_error_get_code(), return, "Missing keyword ARCFILE in raw "
00172             "frame header");
00173     
00174     {
00175         char *pipefile = dfs_generate_filename(pro_catg);
00176         fors_qc_write_string("PIPEFILE", pipefile, 
00177                              "Pipeline product name", instrument);
00178         cpl_free(pipefile); pipefile = NULL;
00179         assure( !cpl_error_get_code(), return, "Cannot write PIPEFILE to QC log file");
00180     }
00181 
00182     cleanup;
00183     return;
00184 }
00185 
00186 
00187 
00200 cpl_error_code fors_qc_end_group(void)
00201 {
00202 
00203     if (!pafFile)
00204         return cpl_error_set("fors_qc_end_group", CPL_ERROR_DATA_NOT_FOUND);
00205 
00206     if (!forsPAFIsEmpty(pafFile)) {
00207         forsPAFWrite(pafFile);
00208         pafIndex++;
00209     }
00210 
00211     deleteForsPAF(pafFile);
00212     pafFile = NULL;
00213 
00214     return CPL_ERROR_NONE;
00215 
00216 }
00217 
00218 
00235 cpl_error_code fors_qc_write_string(const char *name, const char *value, 
00236                                 const char *comment, const char *instrument)
00237 {
00238 
00239     int status;
00240     int   length = strlen(instrument) + 3;
00241     char *allComment;
00242 
00243 
00244     if (comment == NULL || name == NULL || instrument == NULL)
00245         return cpl_error_set("fors_qc_write_string", CPL_ERROR_NULL_INPUT);
00246 
00247     length += strlen(comment) + 1;
00248 
00249     allComment = cpl_malloc(length * sizeof(char));
00250 
00251     sprintf(allComment, "%s [%s]", comment, instrument);
00252 
00253     status = forsPAFAppendString(pafFile, name, value, allComment);
00254 
00255     cpl_free(allComment);
00256 
00257     if (status)
00258         cpl_msg_error("fors_qc_write_string", 
00259                       "Cannot write parameter %s to QC1 PAF", name);
00260 
00261     cpl_msg_debug(cpl_func, "%s [%s] = '%s'", comment, name, value);
00262 
00263     return CPL_ERROR_NONE;
00264 
00265 }
00266 
00267 cpl_error_code fors_qc_write_string_chat(const char *name, const char *value,
00268                                 const char *comment, const char *instrument)
00269 {
00270 
00271     int status;
00272     int   length = strlen(instrument) + 3;
00273     char *allComment;
00274 
00275 
00276     if (comment == NULL || name == NULL || instrument == NULL)
00277         return cpl_error_set("fors_qc_write_string_chat", CPL_ERROR_NULL_INPUT);
00278 
00279     length += strlen(comment) + 1;
00280 
00281     allComment = cpl_malloc(length * sizeof(char));
00282 
00283     sprintf(allComment, "%s [%s]", comment, instrument);
00284 
00285     status = forsPAFAppendString(pafFile, name, value, allComment);
00286 
00287     cpl_free(allComment);
00288 
00289     if (status)
00290         cpl_msg_error("fors_qc_write_string_chat",
00291                       "Cannot write parameter %s to QC1 PAF", name);
00292 
00293     cpl_msg_info(cpl_func, "%s [%s] = '%s'", comment, name, value);
00294 
00295     return CPL_ERROR_NONE;
00296 
00297 }
00298 
00299 
00321 cpl_error_code fors_qc_write_double(const char *name, double value, 
00322                                 const char *unit, const char *comment,
00323                                 const char *instrument)
00324 {
00325 
00326     cpl_error_code status;
00327     int   length = strlen(instrument) + 3;
00328     char *allComment;
00329 
00330 
00331     if (comment == NULL || name == NULL || instrument == NULL)
00332         return cpl_error_set("fors_qc_write_double", CPL_ERROR_NULL_INPUT);
00333 
00334     length += strlen(comment) + 1;
00335 
00336     if (unit)
00337       length += strlen(unit) + 3;
00338 
00339     allComment = cpl_malloc(length * sizeof(char));
00340 
00341     if (unit)
00342       sprintf(allComment, "%s (%s) [%s]", comment, unit, instrument);
00343     else
00344       sprintf(allComment, "%s [%s]", comment, instrument);
00345 
00346     status = forsPAFAppendDouble(pafFile, name, value, allComment);
00347 
00348     cpl_free(allComment);
00349 
00350     if (status)
00351         cpl_msg_error("fors_qc_write_double", 
00352                       "Cannot write parameter %s to QC1 PAF", name);
00353 
00354     cpl_msg_info(cpl_func, "%s [%s] = %f %s", 
00355                  comment, name, value, (unit != NULL) ? unit : "");
00356 
00357     return CPL_ERROR_NONE;
00358 
00359 }
00360 
00361 
00362 cpl_error_code fors_qc_write_int(const char *name, int value, const char *unit, 
00363                              const char *comment, const char *instrument)
00364 {
00365 
00366     cpl_error_code status;
00367     int   length = strlen(instrument) + 3;
00368     char *allComment;
00369 
00370 
00371     if (comment == NULL || name == NULL || instrument == NULL)
00372         return cpl_error_set("fors_qc_write_int", CPL_ERROR_NULL_INPUT);
00373 
00374     length += strlen(comment) + 1;
00375 
00376     if (unit)
00377       length += strlen(unit) + 3;
00378 
00379     allComment = cpl_malloc(length * sizeof(char));
00380 
00381     if (unit)
00382       sprintf(allComment, "%s (%s) [%s]", comment, unit, instrument);
00383     else
00384       sprintf(allComment, "%s [%s]", comment, instrument);
00385 
00386     status = forsPAFAppendInt(pafFile, name, value, allComment);
00387 
00388     cpl_free(allComment);
00389 
00390     if (status)
00391         cpl_msg_error("fors_qc_write_int", 
00392                       "Cannot write parameter %s to QC1 PAF", name);
00393 
00394     cpl_msg_info(cpl_func, "%s [%s] = %d %s", 
00395                  comment, name, value, (unit != NULL) ? unit : "");
00396  
00397     return CPL_ERROR_NONE;
00398 
00399 }
00400 
00401 
00425 cpl_error_code fors_qc_keyword_to_paf(cpl_propertylist *header, 
00426                                      const char *name, const char *unit, 
00427                                      const char *comment, 
00428                                      const char *instrument)
00429 {
00430 
00431   const char func[] = "fors_qc_keyword_to_paf";
00432 
00433   char            *keyName;
00434   char            *keep;
00435   char            *pos;
00436   int              ivalue;
00437   float            fvalue;
00438   double           dvalue;
00439   char            *svalue = NULL;
00440   int              status;
00441   int              i;
00442 
00443 
00444   if (header == NULL) {
00445     cpl_msg_error(func, "Empty header");
00446     return cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00447   }
00448 
00449   if (!cpl_propertylist_has(header, name)) {
00450     cpl_msg_error(func, "Keyword %s not found", name);
00451     return cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00452   }
00453 
00454   switch (cpl_propertylist_get_type(header, name)) {
00455   case CPL_TYPE_INT :
00456     ivalue = cpl_propertylist_get_int(header, name);
00457     break;
00458   case CPL_TYPE_FLOAT :
00459     fvalue = cpl_propertylist_get_float(header, name);
00460     break;
00461   case CPL_TYPE_DOUBLE :
00462     dvalue = cpl_propertylist_get_double(header, name);
00463     break;
00464   case CPL_TYPE_STRING :
00465     svalue = (char *)cpl_propertylist_get_string(header, name);
00466     break;
00467   default :
00468     cpl_msg_error(func, "Unsupported keyword type");
00469     return cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00470   }
00471 
00472 
00473   /*
00474    *  Construct entry name for PAF
00475    */
00476 
00477   keep = keyName = cpl_strdup(name);
00478 
00479   pos = strstr(keyName, "ESO ");
00480 
00481   if (pos == keyName)
00482     keyName += 4;
00483 
00484   for (i = 0; keyName[i] != '\0'; i++)
00485     if (keyName[i] == ' ')
00486       keyName[i] = '.';
00487 
00488   /*
00489    *  Now write entry to PAF object.
00490    */
00491 
00492   switch (cpl_propertylist_get_type(header, name)) {
00493   case CPL_TYPE_INT :
00494     status = fors_qc_write_int(keyName, ivalue, unit, comment, instrument);
00495     break;
00496   case CPL_TYPE_FLOAT :
00497     dvalue = fvalue;
00498   case CPL_TYPE_DOUBLE :
00499     status = fors_qc_write_double(keyName, dvalue, unit, comment, instrument);
00500     break;
00501   default :    /* CPL_TYPE_STRING */
00502     status = fors_qc_write_string(keyName, svalue, comment, instrument);
00503   }
00504 
00505   if (status)
00506     cpl_msg_error(func, "Could not copy keyword value to QC1 PAF!");
00507 
00508   cpl_free(keep);
00509 
00510   return status;
00511 
00512 }
00513 
00535 cpl_error_code fors_qc_write_qc_string(cpl_propertylist *header,
00536                                        const char *name, const char *value, 
00537                                        const char *comment, 
00538                                        const char *instrument)
00539 {
00540     const char func[] = "fors_qc_write_qc_string";
00541 
00542     char *header_name;
00543     int   i;
00544 
00545     if (strcmp("QC.DID", name)) {
00546         if (fors_qc_write_string_chat(name, value, comment, instrument)) {
00547             cpl_error_set_where(func);
00548             return cpl_error_get_code();
00549         }
00550     }
00551     else {
00552         if (fors_qc_write_string(name, value, comment, instrument)) {
00553             cpl_error_set_where(func);
00554             return cpl_error_get_code();
00555         }
00556     }
00557 
00558     header_name = cpl_malloc((strlen(name) + 6) * sizeof(char *));
00559 
00560     strcpy(header_name, "ESO ");
00561     strcat(header_name, name);
00562 
00563     for (i = 0; header_name[i] != '\0'; i++)
00564         if (header_name[i] == '.')
00565             header_name[i] = ' ';
00566 
00567     if (cpl_propertylist_update_string(header, header_name, value)) {
00568         cpl_free(header_name);
00569         cpl_error_set_where(func);
00570         return cpl_error_get_code();
00571     }
00572 
00573     cpl_propertylist_set_comment(header, header_name, comment);
00574 
00575     cpl_free(header_name);
00576 
00577     return CPL_ERROR_NONE;
00578 }
00579 
00604 cpl_error_code fors_qc_write_qc_double(cpl_propertylist *header, double value, 
00605                                       const char *name, const char *unit, 
00606                                       const char *comment,
00607                                       const char *instrument)
00608 {
00609 
00610   const char func[] = "fors_qc_write_qc_double";
00611 
00612   char *header_name;
00613   int   i;
00614 
00615 
00616   if (fors_qc_write_double(name, value, unit, comment, instrument)) {
00617       cpl_error_set_where(func);
00618       return cpl_error_get_code();
00619   }
00620 
00621   header_name = cpl_malloc((strlen(name) + 6) * sizeof(char *));
00622 
00623   strcpy(header_name, "ESO ");
00624   strcat(header_name, name);
00625 
00626   for (i = 0; header_name[i] != '\0'; i++)
00627     if (header_name[i] == '.')
00628       header_name[i] = ' ';
00629 
00630   if (cpl_propertylist_update_double(header, header_name, value)) {
00631       cpl_free(header_name);
00632       cpl_error_set_where(func);
00633       return cpl_error_get_code();
00634   }
00635 
00636   cpl_propertylist_set_comment(header, header_name, comment);
00637 
00638   cpl_free(header_name);
00639 
00640   return CPL_ERROR_NONE;
00641 
00642 }
00643 
00644 
00645 cpl_error_code fors_qc_write_qc_int(cpl_propertylist *header, int value,
00646                                    const char *name, const char *unit,
00647                                    const char *comment,
00648                                    const char *instrument)
00649 {
00650 
00651   const char func[] = "fors_qc_write_qc_int";
00652 
00653   char *header_name;
00654   int   i;
00655 
00656 
00657   if (fors_qc_write_int(name, value, unit, comment, instrument)) {
00658       cpl_error_set_where(func);
00659       return cpl_error_get_code();
00660   }
00661 
00662   header_name = cpl_malloc((strlen(name) + 6) * sizeof(char *));
00663 
00664   strcpy(header_name, "ESO ");
00665   strcat(header_name, name);
00666 
00667   for (i = 0; header_name[i] != '\0'; i++)
00668     if (header_name[i] == '.')
00669       header_name[i] = ' ';
00670 
00671   if (cpl_propertylist_update_int(header, header_name, value)) {
00672       cpl_free(header_name);
00673       cpl_error_set_where(func);
00674       return cpl_error_get_code();
00675   }
00676 
00677   cpl_propertylist_set_comment(header, header_name, comment);
00678 
00679   cpl_free(header_name);
00680 
00681   return CPL_ERROR_NONE;
00682 
00683 }
00684 
00685 /*
00686  * @brief
00687  *   Write an integer value to the active QC1 PAF object and to a header.
00688  *
00689  * @return @c CPL_ERROR_NONE on success
00690  *
00691  * @param filnam  Name of existing FITS file.
00692  * @param value   Value to write.
00693  * @param name    QC1 PAF entry name.
00694  * @param unit    Optional unit to be associated to value.
00695  * @param comment Optional comment to be associated to value.
00696  *
00697  * @doc
00698  *   This function writes the header entries directly to the header 
00699  *   of the FITS file written to disk, using the qfits_replace_card() call.
00700  *   An entry with the specified @em name is written to the current QC1 PAF 
00701  *   object. From the entry @em name, the name of the QC keyword that
00702  *   should be written to header is derived prepending the string "ESO "
00703  *   and replacing all '.' with a blank (e.g., "QC.BIAS.MASTER.MEAN"
00704  *   becomes "ESO QC BIAS MASTER MEAN"). Finally, the new keyword
00705  *   is written to the header. Note that before calling this funtion 
00706  *   a QC1 PAF object must be created with a call to fors_qc_start_group().
00707  */
00708 
00709 /*
00710 cpl_error_code fors_qc_write_qc_int(char *filnam, int value, const char *name,
00711                                const char *unit, const char *comment,
00712                                const char *instrument)
00713 {
00714 
00715   const char func[] = "fors_qc_write_qc_int";
00716 
00717   char             line[81];
00718   char             val[81];
00719   char            *descName;
00720   int              i;
00721 
00722 
00723   if (fors_qc_write_int(name, value, unit, comment, instrument)) {
00724     cpl_msg_error(func, "Could not copy value to QC1 PAF!");
00725     cpl_error_set_where(func);
00726     return cpl_error_get_code();
00727   }
00728 
00729   descName = cpl_malloc((strlen(name) + 15) * sizeof(char *));
00730 
00731   strcpy(descName, "HIERARCH ESO ");
00732   strcat(descName, name);
00733 
00734   for (i = 0; descName[i] != '\0'; i++)
00735     if (descName[i] == '.')
00736       descName[i] = ' ';
00737 
00738   sprintf(val, "%d", value);
00739   keytuple2str(line, descName, val, (char *)comment);
00740   qfits_replace_card(filnam, descName, line);
00741 
00742   cpl_free(descName);
00743 
00744   return CPL_ERROR_NONE;
00745 
00746 }
00747 
00748 
00749 cpl_error_code fors_qc_write_qc_double(char *filnam, double value, 
00750                                       const char *name, const char *unit, 
00751                                       const char *comment,
00752                                       const char *instrument)
00753 {
00754 
00755   const char func[] = "fors_qc_write_qc_double";
00756 
00757   char             line[81];
00758   char             val[81];
00759   char            *descName;
00760   int              i;
00761 
00762 
00763   if (fors_qc_write_double(name, value, unit, comment, instrument)) {
00764     cpl_msg_error(func, "Could not copy value to QC1 PAF!");
00765     cpl_error_set_where(func);
00766     return cpl_error_get_code();
00767   }
00768 
00769   descName = cpl_malloc((strlen(name) + 15) * sizeof(char *));
00770 
00771   strcpy(descName, "HIERARCH ESO ");
00772   strcat(descName, name);
00773 
00774   for (i = 0; descName[i] != '\0'; i++)
00775     if (descName[i] == '.')
00776       descName[i] = ' ';
00777 
00778   sprintf(val, "%1.6e", value);
00779   keytuple2str(line, descName, val, (char *)comment);
00780   qfits_replace_card(filnam, descName, line);
00781 
00782   cpl_free(descName);
00783 
00784   return CPL_ERROR_NONE;
00785 
00786 }
00787 
00788 */
00789 

Generated on Fri Mar 4 09:46:00 2011 for FORS Pipeline Reference Manual by  doxygen 1.4.7