fors_dfs.c

00001 /* $Id: fors_dfs.c,v 1.26 2008/07/28 15:13:08 cizzo Exp $
00002  *
00003  * This file is part of the FORS library
00004  * Copyright (C) 2002-2006 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: 2008/07/28 15:13:08 $
00024  * $Revision: 1.26 $
00025  * $Name:  $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 #include <fors_dfs.h>
00033 
00034 #include <fors_utils.h>
00035 #include <fors_image.h>
00036 #include <fors_pfits.h>
00037 
00038 #include <cpl.h>
00039 
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <ctype.h>
00043 #include <stdbool.h>
00044 #include <string.h>
00045 #include <unistd.h>
00046 
00056 #define WCS_KEYS "^((CRVAL|CRPIX|CTYPE)[0-9]|RADECSYS|CD[0-9]_[0-9])$"
00057 
00058 static char *strlower(char *s)
00059 {
00060 
00061   char *t = s;
00062 
00063   while (*t) {
00064     *t = tolower(*t);
00065     t++;
00066   }
00067 
00068   return s;
00069 
00070 }
00071 
00072 /*
00073 
00074 static char *strupper(char *s)
00075 {
00076 
00077   char *t = s;
00078 
00079   while (*t) {
00080     *t = toupper(*t);
00081     t++;
00082   }
00083   
00084   return s;
00085 
00086 }
00087 
00088 */
00089 
00090 char *dfs_generate_filename(const char *category)
00091 {
00092     char *filename = cpl_calloc(strlen(category) + 6, sizeof(char));
00093 
00094     strlower(strcpy(filename, category));
00095     strcat(filename, ".fits");
00096 
00097     return filename;
00098 }
00099 
00100 char *dfs_generate_filename_tfits(const char *category)
00101 {
00102     /*
00103     char *filename = cpl_calloc(strlen(category) + 7, sizeof(char));
00104     */
00105     char *filename = cpl_calloc(strlen(category) + 6, sizeof(char));
00106 
00107     strlower(strcpy(filename, category));
00108 
00109     /*
00110     strcat(filename, ".tfits");
00111     */
00112     strcat(filename, ".fits");
00113 
00114     return filename;
00115 }
00116 
00117 
00118 /*----------------------------------------------------------------------------*/
00129 /*----------------------------------------------------------------------------*/
00130 static void
00131 errorstate_dump_one(unsigned self, unsigned first, unsigned last)
00132 {
00133 
00134     const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
00135     const unsigned    newest     = is_reverse ? first : last;
00136     const unsigned    oldest     = is_reverse ? last : first;
00137     const char      * revmsg     = is_reverse ? " in reverse order" : "";
00138 
00139     /* Cannot use internal CPL functions
00140        cx_assert( oldest <= self );
00141        cx_assert( newest >= self ); */
00142 
00143     if (newest == 0) {
00144         cpl_msg_info(cpl_func, "No error(s) to dump");
00145         /* cx_assert( oldest == 0); */
00146     } else {
00147         /*  cx_assert( oldest > 0);
00148             cx_assert( newest >= oldest); */
00149         if (self == first) {
00150             if (oldest == 1) {
00151                 cpl_msg_debug(cpl_func, "Dumping all %u error(s)%s:", newest,
00152                               revmsg);
00153             } else {
00154                 cpl_msg_error(cpl_func, "Dumping the %u most recent error(s) "
00155                               "out of a total of %u errors%s:",
00156                               newest - oldest + 1, newest, revmsg);
00157             }
00158         }
00159 
00160         const char *message_from_cpl = cpl_error_get_message();
00161 
00162         if (message_from_cpl == NULL) {
00163             /* This should never happen */
00164             cpl_msg_error(cpl_func, "Unspecified error");
00165         }
00166 
00167         /* Skip the standard (non-informative) CPL message string, 
00168            which usually terminates with ': '
00169 
00170            If no user-defined error message is given, 
00171            print the CPL standard message
00172         */
00173         while (*message_from_cpl != '\0' && *message_from_cpl != ':') {
00174             message_from_cpl += 1;
00175         }
00176         
00177         if (*message_from_cpl != '\0') {
00178             message_from_cpl += 1;
00179             
00180             if (*message_from_cpl == ' ') message_from_cpl++;
00181             
00182             if (*message_from_cpl != '\0') {
00183                 /* Still something left of the string */
00184                 cpl_msg_error(cpl_func, "%s [%s]", message_from_cpl,
00185                               cpl_error_get_where());
00186             }
00187             else {
00188                 cpl_msg_error(cpl_func, "%s [%s]",
00189                               cpl_error_get_message(), cpl_error_get_where());
00190         }
00191         }
00192         else {
00193             /* Found no ':' is CPL message string */
00194             cpl_msg_error(cpl_func, "%s [%s]",
00195                           cpl_error_get_message(), cpl_error_get_where());
00196         }
00197     }
00198 
00199     return;
00200 }
00201 
00202 
00203 /*----------------------------------------------------------------------------*/
00213 /*----------------------------------------------------------------------------*/
00214 void fors_begin(cpl_frameset *frames,
00215         const char *description_short)
00216 {
00217     cpl_msg_info(cpl_func, "%s", PACKAGE_STRING);   
00218     cpl_msg_info(cpl_func, "%s", description_short);
00219     
00220     fors_dfs_set_groups(frames);
00221     cpl_msg_info(cpl_func, "Input frame%s:", 
00222                  cpl_frameset_get_size(frames) != 1 ? "s" : "");
00223     fors_frameset_print(frames);
00224     
00225     return;
00226 }
00227 
00228 /*----------------------------------------------------------------------------*/
00241 /*----------------------------------------------------------------------------*/
00242 int fors_end(const cpl_frameset *frames, cpl_errorstate before_exec)
00243 {
00244     if (cpl_error_get_code() == CPL_ERROR_NONE) {
00245         
00246         const cpl_frame *f;
00247         
00248         cpl_msg_info(cpl_func, "Product frame%s:", 
00249                      cpl_frameset_get_size(frames) != 1 ? "s" : "");
00250 
00251         for (f = cpl_frameset_get_first_const(frames);
00252              f != NULL;
00253              f = cpl_frameset_get_next_const(frames)) {
00254             if (cpl_frame_get_group(f) == CPL_FRAME_GROUP_PRODUCT) {
00255                 fors_frame_print(f);
00256             }
00257         }
00258         
00259         /* Shut up EsoRex */
00260         //cpl_msg_set_level(CPL_MSG_WARNING);
00261         return 0;
00262     }
00263     else {
00264 
00265         cpl_errorstate_dump(before_exec, CPL_FALSE, errorstate_dump_one);
00266 
00267         return 1;
00268     }
00269 }
00270 
00271 #undef cleanup
00272 #define cleanup
00273 /*----------------------------------------------------------------------------*/
00278 /*----------------------------------------------------------------------------*/
00279 void
00280 fors_dfs_set_groups(cpl_frameset * set)
00281 {
00282     cpl_frame *f;
00283     
00284     assure( set != NULL, return, NULL );
00285     
00286     for (f = cpl_frameset_get_first(set);
00287          f != NULL;
00288          f = cpl_frameset_get_next(set)) {
00289 
00290         const char *tag = cpl_frame_get_tag(f);
00291 
00292         if (tag != NULL) {
00293             if (strcmp(tag, BIAS) == 0 ||
00294                 strcmp(tag, DARK) == 0 ||
00295                 strcmp(tag, SCREEN_FLAT_IMG) == 0 ||
00296                 strcmp(tag, SKY_FLAT_IMG) == 0 ||
00297                 strcmp(tag, STANDARD_IMG) == 0 ||
00298                 strcmp(tag, SCIENCE_IMG) == 0) {
00299                 cpl_frame_set_group(f, CPL_FRAME_GROUP_RAW);
00300             }
00301             else if (strcmp(tag, MASTER_BIAS           ) == 0 ||
00302                      strcmp(tag, MASTER_DARK           ) == 0 ||
00303                      strcmp(tag, MASTER_SCREEN_FLAT_IMG) == 0 ||
00304                      strcmp(tag, MASTER_SKY_FLAT_IMG   ) == 0 ||
00305                      strcmp(tag, ALIGNED_PHOT          ) == 0 ||
00306                      /* static calibration */
00307                      strcmp(tag, FLX_STD_IMG           ) == 0 ||
00308                      strcmp(tag, PHOT_TABLE            ) == 0) {
00309                 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
00310             }
00311             else {
00312                 cpl_msg_warning(cpl_func, "Unrecognized frame tag: '%s'",
00313                                 tag);
00314             }
00315         }
00316     }
00317     
00318     return;
00319 }
00320 
00321 #undef cleanup
00322 #define cleanup
00323 
00331 const char *
00332 fors_dfs_pipeline_version(const cpl_propertylist *header, 
00333                           const char **instrument_version)
00334 {
00335     const char *instrume = NULL;
00336     
00337     instrume = cpl_propertylist_get_string(header, 
00338                                            FORS_PFITS_INSTRUME);
00339     assure( !cpl_error_get_code(), return NULL,
00340             "Missing keyword %s in input header", FORS_PFITS_INSTRUME);
00341     
00342     assure( strlen(instrume) >= 5, return NULL,
00343             "%s keyword must be 'fors1' or 'fors2', not '%s'", 
00344             FORS_PFITS_INSTRUME, instrume);
00345 
00346     assure( instrume[4] == '1' || instrume[4] == '2', return NULL,
00347             "Unrecognized %s: %s", FORS_PFITS_INSTRUME, instrume);
00348 
00349     if (instrument_version != NULL) {
00350         *instrument_version = cpl_sprintf("%s", instrume);
00351     }
00352     
00353     return cpl_sprintf("fors%c/%s", instrume[4], VERSION);
00354 }
00355 
00356 
00379 int dfs_get_parameter_int(cpl_parameterlist *parlist, const char *name,
00380                           const cpl_table *defaults)
00381 {
00382     const char *func = "dfs_get_parameter_int";
00383 
00384     const char    *alias;
00385     cpl_parameter *param;
00386 
00387 
00388     if (parlist == NULL) {
00389         cpl_msg_error(func, "Missing input parameter list");
00390         cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00391         return 0;
00392     }
00393 
00394     if (name == NULL) {
00395         cpl_msg_error(func, "Missing input parameter name");
00396         cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00397         return 0;
00398     }
00399 
00400     param = cpl_parameterlist_find(parlist, name);
00401 
00402     if (param == NULL) {
00403         cpl_msg_error(func, "Wrong parameter name: %s", name);
00404         cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00405         return 0;
00406     }
00407 
00408     if (cpl_parameter_get_type(param) != CPL_TYPE_INT) {
00409         cpl_msg_error(func, "Unexpected type for parameter "
00410                       "\"%s\": it should be integer", name);
00411         cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00412         return 0;
00413     }
00414 
00415     alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00416 
00417     if (defaults && cpl_parameter_get_default_flag(param) == 0) {
00418     
00419         if (cpl_table_has_column(defaults, alias)) {
00420             if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_INT) {
00421                 cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
00422                               "column \"%s\": it should be integer", alias);
00423                 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00424                 return 0;
00425             }
00426             if (cpl_table_is_valid(defaults, alias, 0)) {
00427                 cpl_parameter_set_int(param, cpl_table_get_int(defaults, 
00428                                                                alias, 0, NULL));
00429             }
00430             else {
00431                 cpl_msg_error(func, "Invalid parameter value in table "
00432                               "column \"%s\"", alias);
00433                 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00434                 return 0;
00435             }
00436         }
00437         else {
00438             cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00439                             "- using recipe default", alias);
00440         }
00441     }
00442 
00443     cpl_msg_info(func, "%s:", alias);
00444     cpl_msg_info(func, "%s: %d",
00445                  cpl_parameter_get_help(param), cpl_parameter_get_int(param));
00446 
00447     return cpl_parameter_get_int(param);
00448 
00449 }
00450 
00451 
00474 double dfs_get_parameter_double(cpl_parameterlist *parlist, 
00475                                 const char *name, const cpl_table *defaults)
00476 {
00477     const char *func = "dfs_get_parameter_double";
00478 
00479     const char    *alias;
00480     cpl_parameter *param;
00481 
00482 
00483     if (parlist == NULL) {
00484         cpl_msg_error(func, "Missing input parameter list");
00485         cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00486         return 0;
00487     }
00488 
00489     if (name == NULL) {
00490         cpl_msg_error(func, "Missing input parameter name");
00491         cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00492         return 0;
00493     }
00494 
00495     param = cpl_parameterlist_find(parlist, name);
00496 
00497     if (param == NULL) {
00498         cpl_msg_error(func, "Wrong parameter name: %s", name);
00499         cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00500         return 0;
00501     }
00502 
00503     if (cpl_parameter_get_type(param) != CPL_TYPE_DOUBLE) {
00504         cpl_msg_error(func, "Unexpected type for parameter "
00505                       "\"%s\": it should be double", name);
00506         cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00507         return 0;
00508     }
00509 
00510     alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00511 
00512     if (defaults && cpl_parameter_get_default_flag(param) == 0) {
00513     
00514         if (cpl_table_has_column(defaults, alias)) {
00515             if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_DOUBLE) {
00516                 cpl_msg_error(func, "Unexpected type for GRISM_TABL "
00517                               "column \"%s\": it should be double", alias);
00518                 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00519                 return 0;
00520             }
00521             if (cpl_table_is_valid(defaults, alias, 0)) {
00522                 cpl_parameter_set_double(param, cpl_table_get_double(defaults, 
00523                                                                alias, 0, NULL));
00524             }
00525             else {
00526                 cpl_msg_error(func, "Invalid parameter value in table "
00527                               "column \"%s\"", alias);
00528                 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00529                 return 0;
00530             }
00531         }
00532         else {
00533             cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00534                             "- using recipe default", alias);
00535         }
00536     }
00537 
00538     cpl_msg_info(func, "%s:", alias);
00539     cpl_msg_info(func, "%s: %f",
00540                  cpl_parameter_get_help(param), cpl_parameter_get_double(param));
00541 
00542     return cpl_parameter_get_double(param);
00543 
00544 }
00545 
00546 
00569 const char *dfs_get_parameter_string(cpl_parameterlist *parlist, 
00570                                      const char *name, 
00571                                      const cpl_table *defaults)
00572 {
00573     const char *func = "dfs_get_parameter_string";
00574 
00575     const char    *alias;
00576     cpl_parameter *param;
00577 
00578 
00579     if (parlist == NULL) {
00580         cpl_msg_error(func, "Missing input parameter list");
00581         cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00582         return 0;
00583     }
00584 
00585     if (name == NULL) {
00586         cpl_msg_error(func, "Missing input parameter name");
00587         cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00588         return 0;
00589     }
00590 
00591     param = cpl_parameterlist_find(parlist, name);
00592 
00593     if (param == NULL) {
00594         cpl_msg_error(func, "Wrong parameter name: %s", name);
00595         cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00596         return 0;
00597     }
00598 
00599     if (cpl_parameter_get_type(param) != CPL_TYPE_STRING) {
00600         cpl_msg_error(func, "Unexpected type for parameter "
00601                       "\"%s\": it should be string", name);
00602         cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00603         return 0;
00604     }
00605 
00606     alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00607 
00608     if (defaults && cpl_parameter_get_default_flag(param) == 0) {
00609     
00610         if (cpl_table_has_column(defaults, alias)) {
00611             if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_STRING) {
00612                 cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
00613                               "column \"%s\": it should be string", alias);
00614                 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00615                 return 0;
00616             }
00617             if (cpl_table_is_valid(defaults, alias, 0)) {
00618                 cpl_parameter_set_string(param, cpl_table_get_string(defaults, 
00619                                                              alias, 0));
00620             }
00621             else {
00622                 cpl_msg_error(func, "Invalid parameter value in table "
00623                               "column \"%s\"", alias);
00624                 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00625                 return 0;
00626             }
00627         }
00628         else {
00629             cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00630                             "- using recipe default", alias);
00631         }
00632     }
00633 
00634     cpl_msg_info(func, "%s:", alias);
00635     cpl_msg_info(func, "%s: %s", cpl_parameter_get_help(param), 
00636                  cpl_parameter_get_string(param));
00637 
00638     return cpl_parameter_get_string(param);
00639 
00640 }
00641 
00642 
00665 int dfs_get_parameter_bool(cpl_parameterlist *parlist, const char *name,
00666                            const cpl_table *defaults)
00667 {
00668     const char *func = "dfs_get_parameter_bool";
00669 
00670     const char    *alias;
00671     cpl_parameter *param;
00672     int            value;
00673 
00674 
00675     if (parlist == NULL) {
00676         cpl_msg_error(func, "Missing input parameter list");
00677         cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00678         return 0;
00679     }
00680 
00681     if (name == NULL) {
00682         cpl_msg_error(func, "Missing input parameter name");
00683         cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00684         return 0;
00685     }
00686 
00687     param = cpl_parameterlist_find(parlist, name);
00688 
00689     if (param == NULL) {
00690         cpl_msg_error(func, "Wrong parameter name: %s", name);
00691         cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00692         return 0;
00693     }
00694 
00695     if (cpl_parameter_get_type(param) != CPL_TYPE_BOOL) {
00696         cpl_msg_error(func, "Unexpected type for parameter "
00697                       "\"%s\": it should be boolean", name);
00698         cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00699         return 0;
00700     }
00701 
00702     alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00703 
00704     if (defaults && cpl_parameter_get_default_flag(param) == 0) {
00705     
00706         if (cpl_table_has_column(defaults, alias)) {
00707             if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_INT) {
00708                 cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
00709                               "column \"%s\": it should be integer", alias);
00710                 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00711                 return 0;
00712             }
00713             if (cpl_table_is_valid(defaults, alias, 0)) {
00714                 value = cpl_table_get_int(defaults, alias, 0, NULL);
00715                 if (value < 0 || value > 1) {
00716                     cpl_msg_error(func, "Illegal parameter value in table "
00717                                   "column \"%s\": it should be either 0 or 1", 
00718                                   alias);
00719                     cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00720                     return 0;
00721                 }
00722                 cpl_parameter_set_bool(param, value);
00723             }
00724             else {
00725                 cpl_msg_error(func, "Invalid parameter value in table "
00726                               "column \"%s\"", alias);
00727                 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00728                 return 0;
00729             }
00730         }
00731         else {
00732             cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00733                             "- using recipe default", alias);
00734         }
00735     }
00736 
00737     value = cpl_parameter_get_bool(param);
00738 
00739     if (value) {
00740         cpl_msg_info(func, "%s:", alias);
00741         cpl_msg_info(func, "%s: TRUE", cpl_parameter_get_help(param));
00742     }
00743     else {
00744         cpl_msg_info(func, "%s:", alias);
00745         cpl_msg_info(func, "%s: FALSE", cpl_parameter_get_help(param));
00746     }
00747 
00748     return value;
00749 
00750 }
00751 
00755 int dfs_get_parameter_bool_const(const cpl_parameterlist *parlist, const char *name)
00756 {
00757     return dfs_get_parameter_bool((cpl_parameterlist *)parlist, name, NULL);
00758 }
00759 
00763 int dfs_get_parameter_int_const(const cpl_parameterlist *parlist, const char *name)
00764 {
00765     return dfs_get_parameter_int((cpl_parameterlist *)parlist, name, NULL);
00766 }
00767 
00771 double dfs_get_parameter_double_const(const cpl_parameterlist *parlist, const char *name)
00772 {
00773     return dfs_get_parameter_double((cpl_parameterlist *)parlist, name, NULL);
00774 }
00775 
00779 const char *dfs_get_parameter_string_const(const cpl_parameterlist *parlist, const char *name)
00780 {
00781     return dfs_get_parameter_string((cpl_parameterlist *)parlist, name, NULL);
00782 }
00783 
00784 
00813 cpl_image *dfs_load_image(cpl_frameset *frameset, const char *category, 
00814                           cpl_type type, int ext, int calib)
00815 {
00816     const char *func = "dfs_load_image";
00817 
00818     cpl_frame  *frame = NULL;
00819     cpl_image  *image = NULL;
00820 
00821 
00822     frame = cpl_frameset_find(frameset, category);
00823 
00824     if (frame) {
00825         image = cpl_image_load(cpl_frame_get_filename(frame), type, 0, ext);
00826         if (image == NULL) {
00827             cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
00828             cpl_msg_error(func, "Cannot load image %s",
00829                           cpl_frame_get_filename(frame));
00830         }
00831         else {
00832             if (calib) 
00833                 cpl_frame_set_group(frame, CPL_FRAME_GROUP_CALIB);
00834             else
00835                 cpl_frame_set_group(frame, CPL_FRAME_GROUP_RAW);
00836         }
00837     }
00838 
00839     return image;
00840 }
00841 
00842 
00869 cpl_table *dfs_load_table(cpl_frameset *frameset, const char *category, int ext)
00870 {
00871     const char *func = "dfs_load_table";
00872 
00873     cpl_frame  *frame = NULL;
00874     cpl_table  *table = NULL;
00875 
00876 
00877     frame = cpl_frameset_find(frameset, category);
00878 
00879     if (frame) {
00880         table = cpl_table_load(cpl_frame_get_filename(frame), ext, 1);
00881         if (table == NULL) {
00882             cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
00883             cpl_msg_error(func, "Cannot load table %s",
00884                           cpl_frame_get_filename(frame));
00885         }
00886         else
00887             cpl_frame_set_group(frame, CPL_FRAME_GROUP_CALIB);
00888     }
00889 
00890     return table;
00891 }
00892 
00893 
00919 cpl_propertylist *dfs_load_header(cpl_frameset *frameset, 
00920                                   const char *category, int ext)
00921 {
00922     const char *func = "dfs_load_header";
00923 
00924     cpl_frame         *frame = NULL;
00925     cpl_propertylist  *plist = NULL;
00926 
00927 
00928     frame = cpl_frameset_find(frameset, category);
00929 
00930     if (frame) {
00931         plist = cpl_propertylist_load(cpl_frame_get_filename(frame), ext);
00932         if (plist == NULL) {
00933             cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
00934             cpl_msg_error(func, "Cannot load header from %s",
00935                           cpl_frame_get_filename(frame));
00936         }
00937     }
00938 
00939     return plist;
00940 }
00941 
00942 
00950 static void
00951 dfs_save(cpl_frameset *frameset, const void *object, cpl_frame_type type,
00952          const char *category, cpl_propertylist *header,
00953          const cpl_parameterlist *parlist, const char *recipename,
00954          const cpl_frame *raw_frame)
00955 {
00956     char             *filename;
00957     cpl_frame        *frame;
00958     cpl_propertylist *plist;
00959     const char       *version    = NULL;
00960     cpl_propertylist *raw_header = NULL;
00961 
00962 
00963     if (category == NULL || frameset == NULL || object == NULL || 
00964         raw_frame == NULL) {
00965         cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
00966         cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
00967         return;
00968     }
00969 
00970     if (type == CPL_FRAME_TYPE_IMAGE) {
00971         cpl_msg_debug(cpl_func, "Saving %s image to disk...", category);
00972     }
00973     else {
00974         cpl_msg_debug(cpl_func, "Saving %s table to disk...", category);
00975     }
00976 
00977     /* Read instrument version from raw frame */
00978     {
00979         const char *raw_filename = 
00980             cpl_frame_get_filename(raw_frame);
00981         
00982         raw_header = cpl_propertylist_load(raw_filename, 0);
00983         if (cpl_error_get_code() != CPL_ERROR_NONE) {
00984             cpl_msg_error(cpl_func, "Could not read %s primary header", raw_filename);
00985             return;
00986         }
00987         
00988         version = fors_dfs_pipeline_version(raw_header, NULL);
00989         cpl_propertylist_delete(raw_header);        
00990 
00991         if (cpl_error_get_code() != CPL_ERROR_NONE) {
00992             cpl_msg_error(cpl_func, "Could not identify instrument version from %s header",
00993                           raw_filename);
00994             return;
00995         }       
00996     }
00997 
00998     filename = cpl_calloc(strlen(category) + 6, sizeof(char));
00999 
01000     strlower(strcpy(filename, category));
01001     strcat(filename, ".fits");
01002 
01003     frame = cpl_frame_new();
01004 
01005     cpl_frame_set_filename(frame, filename);
01006     cpl_frame_set_tag(frame, category);
01007     cpl_frame_set_type(frame, type);
01008     cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
01009     cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
01010     if (cpl_error_get_code()) {
01011         cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01012         cpl_msg_error(cpl_func, "Cannot initialise the product frame");
01013         cpl_frame_delete(frame);
01014         cpl_free(filename);
01015         cpl_free((void *)version);
01016         return;
01017     }
01018 
01019 
01020     /*
01021      * Produce DFS compliant FITS header for product
01022      */
01023 
01024     if (header == NULL)
01025         plist = cpl_propertylist_new();
01026     else
01027         plist = header;
01028 
01029     if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01030                                      recipename, version, "PRO-1.15")) {
01031         cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01032         cpl_msg_error(cpl_func, "Problem with product %s FITS header definition",
01033                       category);
01034         if (header == NULL)
01035             cpl_propertylist_delete(plist);
01036         cpl_frame_delete(frame);
01037         cpl_free(filename);
01038         cpl_free((void *)version);
01039         return;
01040     }
01041 
01042     cpl_free((void *)version);
01043 
01044 /* CPL3.0 
01045     cpl_propertylist_erase_regexp(plist, "^ESO DET OUT1 OVSC*", 0);
01046     cpl_propertylist_erase_regexp(plist, "^ESO DET OUT1 PRSC*", 0);
01047 */
01048 /* CPL2.0 */
01049     cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCX");
01050     cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCX");
01051     cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCY");
01052     cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCY");
01053 
01054     /*
01055      * Write to disk
01056      */
01057     
01058     if (type == CPL_FRAME_TYPE_IMAGE) {
01059         fors_image_save((fors_image *)object, plist, filename);
01060     }
01061     else {
01062         cpl_table_save((cpl_table *)object, 
01063                        plist, NULL, filename, CPL_IO_DEFAULT);
01064     }
01065     
01066     if (cpl_error_get_code() != CPL_ERROR_NONE) {
01067         cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01068         cpl_msg_error(cpl_func, "Cannot save product %s to disk", filename);
01069         if (header == NULL)
01070             cpl_propertylist_delete(plist);
01071         cpl_frame_delete(frame);
01072         cpl_free(filename);
01073         return;
01074     }
01075 
01076     if (header == NULL)
01077         cpl_propertylist_delete(plist);
01078 
01079     cpl_free(filename);
01080 
01081     cpl_frameset_insert(frameset, frame);
01082 
01083     return;
01084 }
01085     
01086 
01107 void
01108 fors_dfs_save_image(cpl_frameset *frameset, const fors_image *image,
01109                     const char *category, cpl_propertylist *header,
01110                     const cpl_parameterlist *parlist, const char *recipename,
01111                     const cpl_frame *raw_frame)
01112 {
01113     dfs_save(frameset, image, CPL_FRAME_TYPE_IMAGE, 
01114              category, header, 
01115              parlist, recipename, 
01116              raw_frame);
01117 }
01118 
01119 #undef cleanup
01120 #define cleanup \
01121 do { \
01122     cpl_propertylist_delete(wcs_header); \
01123 } while (0)
01124 
01129 void fors_dfs_add_wcs(cpl_propertylist *header, const cpl_frame *frame,
01130                       const fors_setting *setting)
01131 {
01132     bool invert = false;
01133     int extension = 0;
01134     
01135     cpl_propertylist *wcs_header = 
01136         cpl_propertylist_load_regexp(cpl_frame_get_filename(frame), 
01137                                      extension, WCS_KEYS, invert);
01138   
01139     cpl_propertylist_copy_property_regexp(header, wcs_header, ".*", invert);
01140 
01141     double crpix1 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX1);
01142 
01143     assure( !cpl_error_get_code(), return, 
01144             "Could not read %s from %s", FORS_PFITS_CRPIX1, 
01145             cpl_frame_get_filename(frame));
01146             
01147     double crpix2 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX2);
01148 
01149     assure( !cpl_error_get_code(), return, 
01150             "Could not read %s from %s", FORS_PFITS_CRPIX2,
01151             cpl_frame_get_filename(frame));
01152     
01153     cpl_propertylist_update_double(header, FORS_PFITS_CRPIX1,
01154                                    crpix1 - setting->prescan_x);
01155     
01156     cpl_propertylist_update_double(header, FORS_PFITS_CRPIX2,
01157                                    crpix2 - setting->prescan_y);
01158 
01159     
01160     cleanup;
01161     return;
01162 }
01163 
01164 
01165 #undef cleanup
01166 #define cleanup \
01167 do { \
01168     cpl_propertylist_delete(time_header); \
01169 } while (0)
01170 
01183 void fors_dfs_add_exptime(cpl_propertylist *header, const cpl_frame *frame,
01184                           double exptime)
01185 {
01186     bool invert = false;
01187     int extension = 0;
01188 
01189     cpl_propertylist *time_header = NULL;
01190 
01191     if (frame) {
01192 
01193         time_header =
01194         cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),
01195                                      extension, "EXPTIME", invert);
01196 
01197         if (time_header) {
01198             cpl_propertylist_copy_property_regexp(header, 
01199                                                   time_header, ".*", invert);
01200         }
01201         else {
01202             cpl_error_reset();
01203         }
01204     }
01205     else {
01206         while (cpl_propertylist_erase(header, "EXPTIME"));
01207         cpl_propertylist_update_double(header, "EXPTIME", exptime);
01208     }
01209 
01210     cleanup;
01211     return;
01212 }
01213 
01214 
01222 void
01223 fors_dfs_save_table(cpl_frameset *frameset, const cpl_table *table,
01224                     const char *category, cpl_propertylist *header,
01225                     const cpl_parameterlist *parlist, const char *recipename,
01226                     const cpl_frame *raw_frame)
01227 {
01228     dfs_save(frameset, table, CPL_FRAME_TYPE_TABLE, 
01229              category, header, 
01230              parlist, recipename, 
01231              raw_frame);
01232 }
01233 
01266 int dfs_save_image(cpl_frameset *frameset, const cpl_image *image, 
01267                    const char *category, cpl_propertylist *header,
01268                    const cpl_parameterlist *parlist, const char *recipename, 
01269                    const char *version)
01270 {
01271     const char       *func = "dfs_save_image";
01272 
01273     char             *filename;
01274     cpl_frame        *frame;
01275     cpl_propertylist *plist;
01276 
01277 
01278     if (category == NULL || frameset == NULL || image == NULL) {
01279         cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01280         cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01281         return -1;
01282     }
01283 
01284     cpl_msg_info(func, "Saving %s image to disk...", category);
01285 
01286     filename = cpl_calloc(strlen(category) + 6, sizeof(char));
01287 
01288     strlower(strcpy(filename, category));
01289     strcat(filename, ".fits");
01290 
01291     frame = cpl_frame_new();
01292 
01293     cpl_frame_set_filename(frame, filename);
01294     cpl_frame_set_tag(frame, category);
01295     cpl_frame_set_type(frame, CPL_FRAME_TYPE_IMAGE);
01296     cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
01297     cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
01298     if (cpl_error_get_code()) {
01299         cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01300         cpl_msg_error(func, "Cannot initialise the product frame");
01301         cpl_frame_delete(frame);
01302         cpl_free(filename);
01303         return -1;
01304     }
01305 
01306 
01307     /*
01308      * Produce DFS compliant FITS header for image
01309      */
01310 
01311     if (header == NULL)
01312         plist = cpl_propertylist_new();
01313     else
01314         plist = header;
01315 
01316     if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01317                                      recipename, version, "PRO-1.15")) {
01318         cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01319         cpl_msg_error(func, "Problem with product %s FITS header definition",
01320                       category);
01321         if (header == NULL)
01322             cpl_propertylist_delete(plist);
01323         cpl_frame_delete(frame);
01324         cpl_free(filename);
01325         return -1;
01326     }
01327 
01328 /* CPL3.0 
01329     cpl_propertylist_erase_regexp(plist, "^ESO DET OUT1 OVSC*", 0);
01330     cpl_propertylist_erase_regexp(plist, "^ESO DET OUT1 PRSC*", 0);
01331 */
01332 /* CPL2.0 */
01333     cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCX");
01334     cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCX");
01335     cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCY");
01336     cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCY");
01337 
01338     /*
01339      * Write image to disk
01340      */
01341 
01342     if (cpl_image_save(image, filename, CPL_BPP_IEEE_FLOAT, plist,
01343                        CPL_IO_DEFAULT)) {
01344         cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01345         cpl_msg_error(func, "Cannot save product %s to disk", filename);
01346         if (header == NULL)
01347             cpl_propertylist_delete(plist);
01348         cpl_frame_delete(frame);
01349         cpl_free(filename);
01350         return -1;
01351     }
01352 
01353     if (header == NULL)
01354         cpl_propertylist_delete(plist);
01355 
01356     cpl_free(filename);
01357 
01358     cpl_frameset_insert(frameset, frame);
01359 
01360     return 0;
01361 }
01362 
01363 
01396 int dfs_save_table(cpl_frameset *frameset, const cpl_table *table, 
01397                    const char *category, cpl_propertylist *header,
01398                    const cpl_parameterlist *parlist, const char *recipename, 
01399                    const char *version)
01400 {
01401     const char       *func = "dfs_save_table";
01402 
01403     char             *filename;
01404     cpl_frame        *frame;
01405     cpl_propertylist *plist;
01406 
01407 
01408     if (category == NULL || frameset == NULL || table == NULL) {
01409         cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01410         cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01411         return -1;
01412     }
01413 
01414     cpl_msg_info(func, "Saving %s table to disk...", category);
01415 
01416     /*
01417     filename = cpl_calloc(strlen(category) + 7, sizeof(char));
01418     */
01419     filename = cpl_calloc(strlen(category) + 6, sizeof(char));
01420 
01421     strlower(strcpy(filename, category));
01422 
01423     /*
01424     strcat(filename, ".tfits");
01425     */
01426     strcat(filename, ".fits");
01427 
01428     frame = cpl_frame_new();
01429 
01430     cpl_frame_set_filename(frame, filename);
01431     cpl_frame_set_tag(frame, category);
01432     cpl_frame_set_type(frame, CPL_FRAME_TYPE_TABLE);
01433     cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
01434     cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
01435     if (cpl_error_get_code()) {
01436         cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01437         cpl_msg_error(func, "Cannot initialise the product frame");
01438         cpl_frame_delete(frame);
01439         cpl_free(filename);
01440         return -1;
01441     }
01442 
01443 
01444     /*
01445      * Produce DFS compliant FITS header for table
01446      */
01447 
01448     if (header == NULL)
01449         plist = cpl_propertylist_new();
01450     else
01451         plist = header;
01452 
01453     if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01454                                      recipename, version, "PRO-1.15")) {
01455         cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01456         cpl_msg_error(func, "Problem with product %s FITS header definition",
01457                       category);
01458         if (header == NULL)
01459             cpl_propertylist_delete(plist);
01460         cpl_frame_delete(frame);
01461         cpl_free(filename);
01462         return -1;
01463     }
01464 
01465 /* For CPL3.0
01466     cpl_propertylist_erase_regexp(plist, "^ESO DET OUT1 OVSC*", 0);
01467     cpl_propertylist_erase_regexp(plist, "^ESO DET OUT1 PRSC*", 0);
01468 */
01469 /* For CPL2.0 */
01470     cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCX");
01471     cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCX");
01472     cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCY");
01473     cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCY");
01474 
01475     /*
01476      * Write table to disk
01477      */
01478 
01479     if (cpl_table_save(table, plist, NULL, filename, CPL_IO_DEFAULT)) {
01480         cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01481         cpl_msg_error(func, "Cannot save product %s to disk", filename);
01482         if (header == NULL)
01483             cpl_propertylist_delete(plist);
01484         cpl_frame_delete(frame);
01485         cpl_free(filename);
01486         return -1;
01487     }
01488 
01489     if (header == NULL)
01490         cpl_propertylist_delete(plist);
01491     cpl_free(filename);
01492 
01493     cpl_frameset_insert(frameset, frame);
01494 
01495     return 0;
01496 }
01497 
01498 
01509 int dfs_files_dont_exist(cpl_frameset *frameset)
01510 {
01511     const char *func = "dfs_files_dont_exist";
01512     cpl_frame  *frame;
01513 
01514 
01515     if (frameset == NULL) {
01516         cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01517         return 1;
01518     }
01519 
01520     if (cpl_frameset_is_empty(frameset)) {
01521         return 0;
01522     }
01523 
01524     frame = cpl_frameset_get_first(frameset);
01525 
01526     while (frame) {
01527         if (access(cpl_frame_get_filename(frame), F_OK)) {
01528             cpl_msg_error(func, "File %s (%s) was not found", 
01529                           cpl_frame_get_filename(frame), 
01530                           cpl_frame_get_tag(frame));
01531             cpl_error_set(func, CPL_ERROR_FILE_NOT_FOUND);
01532         }
01533 
01534         frame = cpl_frameset_get_next(frameset);
01535     }
01536 
01537     if (cpl_error_get_code())
01538         return 1;
01539 
01540     return 0;
01541 }
01542 
01560 int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
01561 {
01562     const char       *func = "dfs_equal_keyword";
01563 
01564     cpl_frame        *frame;
01565     cpl_propertylist *reference;
01566     cpl_type          rtype;
01567     cpl_type          type;
01568     const char       *rstring;
01569     const char       *string;
01570     int               rintero;
01571     int               intero;
01572     int               found;
01573 
01574 
01575     if (frameset == NULL || keyword == NULL) {
01576         cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01577         return 0;
01578     }
01579 
01580     if (cpl_frameset_is_empty(frameset)) {
01581         cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
01582         return 0;
01583     }
01584         
01585     frame = cpl_frameset_get_first(frameset);
01586 
01587     found = 0;
01588 
01589     while (frame) {
01590 
01591         reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
01592         if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
01593             cpl_error_reset();
01594             frame = cpl_frameset_get_next(frameset);
01595             continue;
01596         }
01597 
01598         if (cpl_propertylist_has(reference, keyword)) {
01599             rtype = cpl_propertylist_get_type(reference, keyword);
01600 
01601             if (rtype == CPL_TYPE_STRING) {
01602                 found = 1;
01603                 rstring = cpl_strdup(cpl_propertylist_get_string(reference, 
01604                                                                  keyword));
01605                 cpl_propertylist_delete(reference);
01606                 break;
01607             }
01608 
01609             if (rtype == CPL_TYPE_INT) {
01610                 found = 1;
01611                 rintero = cpl_propertylist_get_int(reference, keyword);
01612                 cpl_propertylist_delete(reference);
01613                 break;
01614             }
01615 
01616             cpl_propertylist_delete(reference);
01617             return 0;
01618         }
01619 
01620         cpl_propertylist_delete(reference);
01621 
01622         frame = cpl_frameset_get_next(frameset);
01623     }
01624 
01625 
01626     if (!found)
01627         return 1;
01628 
01629     frame = cpl_frameset_get_first(frameset);
01630 
01631     while (frame) {
01632 
01633         reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
01634         if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
01635             cpl_error_reset();
01636             frame = cpl_frameset_get_next(frameset);
01637             continue;
01638         }
01639 
01640         if (cpl_propertylist_has(reference, keyword)) {
01641 
01642             type = cpl_propertylist_get_type(reference, keyword);
01643 
01644             if (rtype != type) {
01645                 cpl_propertylist_delete(reference);
01646                 return 0;
01647             }
01648 
01649             if (rtype == CPL_TYPE_STRING) {
01650                 string = cpl_propertylist_get_string(reference, 
01651                                                      keyword);
01652                 if (strcmp(rstring, string)) {
01653                     cpl_propertylist_delete(reference);
01654                     return 0;
01655                 }
01656             }
01657 
01658             if (rtype == CPL_TYPE_INT) {
01659                 intero = cpl_propertylist_get_int(reference, keyword);
01660                 if (rintero - intero) {
01661                     cpl_propertylist_delete(reference);
01662                     return 0;
01663                 }
01664             }
01665         }
01666 
01667         cpl_propertylist_delete(reference);
01668 
01669         frame = cpl_frameset_get_next(frameset);
01670     }
01671 
01672     if (rtype == CPL_TYPE_STRING)
01673         cpl_free((void *)rstring);
01674 
01675     return 1;
01676 
01677 }
01678 

Generated on Wed Sep 10 07:31:51 2008 for FORS Pipeline Reference Manual by  doxygen 1.4.6