uves_parameters.c

00001 /*                                                                              *
00002  *   This file is part of the ESO UVES Pipeline                                 *
00003  *   Copyright (C) 2004,2005 European Southern Observatory                      *
00004  *                                                                              *
00005  *   This library is free software; you can redistribute it and/or modify       *
00006  *   it under the terms of the GNU General Public License as published by       *
00007  *   the Free Software Foundation; either version 2 of the License, or          *
00008  *   (at your option) any later version.                                        *
00009  *                                                                              *
00010  *   This program is distributed in the hope that it will be useful,            *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of             *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
00013  *   GNU General Public License for more details.                               *
00014  *                                                                              *
00015  *   You should have received a copy of the GNU General Public License          *
00016  *   along with this program; if not, write to the Free Software                *
00017  *   Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA       *
00018  *                                                                              */
00019 
00020 /*
00021  * $Author: amodigli $
00022  * $Date: 2010/12/16 16:57:40 $
00023  * $Revision: 1.68 $
00024  * $Name: uves-4_9_1 $
00025  * $Log: uves_parameters.c,v $
00026  * Revision 1.68  2010/12/16 16:57:40  amodigli
00027  * fixed compiler warnings
00028  *
00029  * Revision 1.67  2010/10/07 12:54:40  amodigli
00030  * in case of flames recipe norm_method default is still 'exptimes' (not to have recipe crash)
00031  *
00032  * Revision 1.66  2010/10/06 16:49:52  amodigli
00033  * changed default option for master flat combination to 'explevel'
00034  *
00035  * Revision 1.65  2010/09/27 15:23:12  amodigli
00036  * removed blazecorr param
00037  *
00038  * Revision 1.64  2010/09/24 09:32:05  amodigli
00039  * put back QFITS dependency to fix problem spot by NRI on FIBER mode (with MIDAS calibs) data
00040  *
00041  * Revision 1.62  2010/06/15 14:52:31  amodigli
00042  * Lim,ited scope of extract method parameter: 2d is not allowed in uves_cal_response
00043  *
00044  * Revision 1.61  2010/06/11 11:40:25  amodigli
00045  * rename method to stack_method
00046  *
00047  * Revision 1.60  2010/06/09 07:17:14  amodigli
00048  * renamed parameter definition function used by response step in redchain recipe to make them more explicit
00049  *
00050  * Revision 1.59  2010/06/08 16:29:09  amodigli
00051  * Fixed problems in parameter definition for reduction chain recipe
00052  *
00053  * Revision 1.58  2010/06/04 14:44:31  amodigli
00054  * changed extract.best from false to true also in uves_cal_response
00055  *
00056  * Revision 1.57  2010/05/18 11:35:18  amodigli
00057  * added uves_master_flat_define_parameters
00058  *
00059  * Revision 1.56  2010/05/11 05:49:20  amodigli
00060  * clarified recipe help
00061  *
00062  * Revision 1.55  2010/05/06 15:55:36  amodigli
00063  * added min/max to khigh/klow/niter parameters of kappa-sigma-clip, removed compiler warnings
00064  *
00065  * Revision 1.54  2010/05/04 17:20:04  amodigli
00066  * cleaned output
00067  *
00068  * Revision 1.53  2010/04/28 08:46:17  amodigli
00069  * add uves_define_efficiency_parameters()
00070  *
00071  * Revision 1.52  2010/03/22 15:55:53  amodigli
00072  * added uves_master_stack_define_parameters
00073  *
00074  * Revision 1.51  2008/11/27 12:06:05  amodigli
00075  * clarified parameter description
00076  *
00077  * Revision 1.50  2008/09/29 06:58:19  amodigli
00078  * add #include <string.h>
00079  *
00080  * Revision 1.49  2008/09/04 12:07:05  amodigli
00081  * fixed mem leaks
00082  *
00083  * Revision 1.48  2008/04/02 14:03:51  amodigli
00084  * fixed compilation warnings
00085  *
00086  * Revision 1.47  2008/03/04 15:21:23  amodigli
00087  * fixed redchain problem with clean_traps parameter
00088  *
00089  * Revision 1.46  2008/03/03 16:34:52  amodigli
00090  * added parameter to control trap column correction
00091  *
00092  * Revision 1.45  2008/02/15 12:43:49  amodigli
00093  * allow lower/upper chip for parameter process_chip
00094  *
00095  * Revision 1.44  2007/10/29 08:11:31  amodigli
00096  * cleaned output
00097  *
00098  * Revision 1.43  2007/10/05 08:27:34  amodigli
00099  * added process_chip parameter
00100  *
00101  * Revision 1.42  2007/08/22 11:17:58  amodigli
00102  * fixed typo
00103  *
00104  * Revision 1.41  2007/08/21 13:08:26  jmlarsen
00105  * Removed irplib_access module, largely deprecated by CPL-4
00106  *
00107  * Revision 1.40  2007/08/17 10:08:12  amodigli
00108  * added case UVES_QCDARK_ID
00109  *
00110  * Revision 1.39  2007/06/26 13:34:55  jmlarsen
00111  * Exported function for FLAMES
00112  *
00113  * Revision 1.38  2007/06/14 11:12:00  jmlarsen
00114  * Expanded description of plotter parameter
00115  *
00116  * Revision 1.37  2007/06/06 08:17:33  amodigli
00117  * replace tab with 4 spaces
00118  *
00119  * Revision 1.36  2007/05/22 11:37:49  jmlarsen
00120  * Removed image plotting functionality
00121  *
00122  * Revision 1.35  2007/03/05 10:17:30  jmlarsen
00123  * Disabled strange msginfolevel parameter
00124  *
00125  * Revision 1.34  2007/02/09 13:39:31  jmlarsen
00126  * Use defines for recipe id
00127  *
00128  * Revision 1.33  2007/02/09 08:58:18  jmlarsen
00129  * Use define's rather than hard-coded recipe names
00130  *
00131  * Revision 1.32  2007/01/15 08:46:45  jmlarsen
00132  * Shortened lines
00133  *
00134  * Revision 1.31  2006/11/15 15:02:14  jmlarsen
00135  * Implemented const safe workarounds for CPL functions
00136  *
00137  * Revision 1.29  2006/11/15 14:04:08  jmlarsen
00138  * Removed non-const version of parameterlist_get_first/last/next which is
00139  * already in CPL, added const-safe wrapper, unwrapper and deallocator functions
00140  *
00141  * Revision 1.28  2006/11/13 14:23:55  jmlarsen
00142  * Removed workarounds for CPL const bugs
00143  *
00144  * Revision 1.27  2006/11/06 15:19:41  jmlarsen
00145  * Removed unused include directives
00146  *
00147  * Revision 1.26  2006/09/27 15:08:45  jmlarsen
00148  * Fixed doc. bug
00149  *
00150  * Revision 1.25  2006/09/20 12:53:57  jmlarsen
00151  * Replaced stringcat functions with uves_sprintf()
00152  *
00153  * Revision 1.24  2006/09/01 13:57:42  jmlarsen
00154  * Fixed bug that causing parameter class to change during propagation
00155  *
00156  * Revision 1.23  2006/08/18 07:07:43  jmlarsen
00157  * Switched order of cpl_calloc arguments
00158  *
00159  * Revision 1.22  2006/08/17 13:56:53  jmlarsen
00160  * Reduced max line length
00161  *
00162  * Revision 1.21  2006/08/14 15:21:08  jmlarsen
00163  * Update to CPL3
00164  *
00165  * Revision 1.20  2006/08/11 11:29:26  jmlarsen
00166  * Added explicit void at function definition
00167  *
00168  * Revision 1.19  2006/08/07 11:35:35  jmlarsen
00169  * Disabled parameter environment variable mode
00170  *
00171  * Revision 1.18  2006/07/03 13:17:12  jmlarsen
00172  * Changed order of global parameters
00173  *
00174  * Revision 1.17  2006/06/06 08:40:10  jmlarsen
00175  * Shortened max line length
00176  *
00177  * Revision 1.16  2006/06/01 14:43:17  jmlarsen
00178  * Added missing documentation
00179  *
00180  * Revision 1.15  2005/12/19 16:17:56  jmlarsen
00181  * Replaced bool -> int
00182  *
00183  */
00184 
00185 #ifdef HAVE_CONFIG_H
00186 #  include <config.h>
00187 #endif
00188 
00189 /*----------------------------------------------------------------------------*/
00197 /*----------------------------------------------------------------------------*/
00198 
00199 /*-----------------------------------------------------------------------------
00200                                 Includes
00201  -----------------------------------------------------------------------------*/
00202 
00203 #include <uves.h>
00204 #include <uves_parameters.h>
00205 #include <uves_dump.h>
00206 #include <uves_backsub.h>
00207 #include <uves_extract.h>
00208 #include <uves_rebin.h>
00209 #include <uves_mdark_impl.h>
00210 #include <uves_corrbadpix.h>
00211 #include <uves_reduce.h>
00212 #include <uves_utils_wrappers.h>
00213 #include <uves_error.h>
00214 #include <uves_msg.h>
00215 
00216 #include <cpl.h>
00217 #include <string.h>
00218 /*-----------------------------------------------------------------------------
00219                             Functions prototypes
00220  -----------------------------------------------------------------------------*/
00221 static int propagate(const char *substep_id, const cpl_parameterlist *sub_parameters, 
00222              cpl_parameterlist *parent_parameters,
00223              const char *parent_id, const char *context);
00224 static cpl_parameter *
00225 create_parameter_enum_int   (const char *name, cpl_type type,
00226                  const char *description, const char *context, 
00227                  int default_value, int size, int *values);
00228 static cpl_parameter *
00229 create_parameter_enum_double(const char *name, cpl_type type, const char *description,
00230                  const char *context, double default_value, 
00231                  int size, double *values);
00232 static cpl_parameter *
00233 create_parameter_enum_string(const char *name, cpl_type type, const char *description,
00234                  const char *context, const char *default_value, 
00235                  int size, const char **values);
00236 /*-----------------------------------------------------------------------------
00237                             Defines
00238  -----------------------------------------------------------------------------*/
00239 #define FAIL(return_code, error_code, ...) do {       \
00240         cpl_msg_error(__func__, __VA_ARGS__);         \
00241         if (cpl_error_get_code() == CPL_ERROR_NONE) { \
00242           cpl_error_set(__func__, error_code);        \
00243         }                                             \
00244         return return_code;                           \
00245         } while(false)
00246 
00249 /*-----------------------------------------------------------------------------
00250                             Implementation
00251  -----------------------------------------------------------------------------*/
00252 
00253 /*---------------------------------------------------------------------------*/
00263 /*---------------------------------------------------------------------------*/
00264 
00265 cpl_error_code
00266 uves_corr_traps_define_parameters(cpl_parameterlist * parameters,
00267                                   const char *recipe_id)
00268 {
00269 
00270    //const char *context = "clean";
00271    const char *name = "";
00272    char full_name[256];
00273    cpl_parameter *p;
00274 
00275     
00276    //
00277    name = "clean_traps";
00278    sprintf(full_name,"%s.%s",recipe_id,name);
00279 
00280    if((strcmp(recipe_id,"uves_obs_scired") == 0) ||
00281       (strcmp(recipe_id,"uves_obs_spatred") == 0) ||
00282       (strcmp(recipe_id,"uves_cal_tflat") == 0) ) {
00283 
00284       uves_parameter_new_value(p, full_name,
00285                                CPL_TYPE_BOOL,
00286                                "Clean detector traps. "
00287                                "If TRUE detector traps are interpolated."
00288                                "The bad pixels are replaced by the average of the"
00289                                "nearest good pixels in the same column, or simply marked "
00290                                "as bad. The positions of bad pixels are hard-coded "
00291                                "(as function of UVES chip).",
00292                                recipe_id,
00293                                CPL_FALSE);
00294  
00295 
00296       cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00297       cpl_parameterlist_append(parameters, p);
00298    } else if((strcmp(recipe_id,"uves_cal_mbias") == 0) ||
00299              (strcmp(recipe_id,"uves_cal_mkmaster") == 0) ) {
00300 
00301       uves_parameter_new_value(p, full_name,
00302                                CPL_TYPE_BOOL,
00303                                "Clean detector traps. "
00304                                "If TRUE detector traps are interpolated."
00305                                "The bad pixels are replaced by the average of "
00306                                "nearest good pixels in the same column, or simply marked "
00307                                "as bad. The positions of bad pixels are hard-coded "
00308                                "(as function of UVES chip).",
00309                                recipe_id,
00310                                CPL_TRUE);
00311 
00312  
00313       cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00314       cpl_parameterlist_append(parameters, p);
00315 
00316    } else {
00317 
00318       uves_msg("Creation of trap not supported for recipe: '%s'",
00319                recipe_id);
00320 
00321    }
00322 
00323    if (cpl_error_get_code() != CPL_ERROR_NONE)
00324    {
00325  
00326       cpl_msg_error(__func__, 
00327                     "Creation of trap column parameters failed: '%s'",
00328                     cpl_error_get_where());
00329    }
00330  
00331     
00332    return cpl_error_get_code();
00333 
00334 
00335 }
00336 
00337 
00338 
00339 /*----------------------------------------------------------------------------*/
00348 /*----------------------------------------------------------------------------*/
00349 
00350 cpl_error_code
00351 uves_master_stack_define_parameters(cpl_parameterlist *parlist, const char *recipe_id)
00352 {
00353  
00354     const char *name = "";
00355     char full_name[256];
00356  
00357     cpl_parameter *p;
00358 
00359     {
00360     name = "stack_method";
00361     sprintf(full_name,"%s.%s",recipe_id,name);
00362     uves_parameter_new_enum(p, full_name,
00363                     CPL_TYPE_STRING,
00364                     "Method used to build master frame ",
00365                     recipe_id,
00366                             "median",2,"median","mean");
00367     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00368     cpl_parameterlist_append(parlist, p);
00369 
00370     }
00371 
00372     {
00373     name = "klow";
00374     sprintf(full_name,"%s.%s",recipe_id,name);
00375     uves_parameter_new_range(p, full_name,
00376                     CPL_TYPE_DOUBLE,
00377                     "Kappa used to clip low level values, when method is set to 'mean' ",
00378                     recipe_id,
00379                              5.,0.,100.);
00380     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00381     cpl_parameterlist_append(parlist, p);
00382 
00383     }
00384 
00385     {
00386     name = "khigh";
00387     sprintf(full_name,"%s.%s",recipe_id,name);
00388     uves_parameter_new_range(p, full_name,
00389                     CPL_TYPE_DOUBLE,
00390                     "Kappa used to clip high level values, when method is set to 'mean' ",
00391                     recipe_id,
00392                              5.,0.,100.);
00393     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00394     cpl_parameterlist_append(parlist, p);
00395 
00396     }
00397 
00398 
00399 
00400     {
00401     name = "niter";
00402     sprintf(full_name,"%s.%s",recipe_id,name);
00403  
00404     uves_parameter_new_range(p, full_name,
00405                     CPL_TYPE_INT,
00406                     "Number of kappa sigma iterations, when method is set to 'mean' ",
00407                     recipe_id,
00408                              5,0,100);
00409     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00410     cpl_parameterlist_append(parlist, p);
00411 
00412     }
00413 
00414     if (cpl_error_get_code() != CPL_ERROR_NONE)
00415     {
00416         cpl_msg_error(__func__, "Creation of kappa sigma parameters failed: '%s'",
00417               cpl_error_get_where());
00418     }
00419     
00420     return cpl_error_get_code();
00421 }
00422 
00423 
00424 
00425 /*----------------------------------------------------------------------------*/
00434 /*----------------------------------------------------------------------------*/
00435 
00436 cpl_error_code
00437 uves_master_flat_define_parameters(cpl_parameterlist *parlist, const char *recipe_id)
00438 {
00439  
00440     const char *name = "";
00441     char full_name[256];
00442  
00443     cpl_parameter *p;
00444 
00445     {
00446     name = "norm_method";
00447     sprintf(full_name,"%s.%s",recipe_id,name);
00448     uves_msg("recipe id %s",recipe_id);
00449     uves_parameter_new_enum(p, full_name,
00450                             CPL_TYPE_STRING,
00451                             "Method used to build master frame ",
00452                             recipe_id,
00453                             (strstr(recipe_id,"flames") !=NULL) ? "exptime" : "explevel",
00454                             2,"exptime","explevel");
00455     }
00456     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00457     cpl_parameterlist_append(parlist, p);
00458 
00459 
00460 
00461     if (cpl_error_get_code() != CPL_ERROR_NONE)
00462     {
00463         cpl_msg_error(__func__, "Creation of master flat parameters failed: '%s'",
00464               cpl_error_get_where());
00465     }
00466     
00467     return cpl_error_get_code();
00468 }
00469 
00470 
00471 
00472 /*----------------------------------------------------------------------------*/
00481 /*----------------------------------------------------------------------------*/
00482 cpl_error_code
00483 uves_define_global_parameters(cpl_parameterlist *parlist)
00484 {
00485     const char *context = "uves";
00486     const char *name = "";
00487     char *full_name = NULL;
00488     cpl_parameter *p;
00489 
00490     {
00491     name = "debug";
00492     full_name = uves_sprintf("%s.%s", context, name);
00493     uves_parameter_new_value(p, full_name,
00494                     CPL_TYPE_BOOL,
00495                     "Whether or not to save intermediate "
00496                     "results to local directory",
00497                     context,
00498                     false);
00499     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00500     cpl_parameterlist_append(parlist, p);
00501     cpl_free(full_name);
00502     }
00503 
00504 
00505     {
00506         name = "plotter";
00507         full_name = uves_sprintf("%s.%s", context, name);
00508         uves_parameter_new_value(
00509             p, full_name,
00510             CPL_TYPE_STRING,
00511             "Any plots produced by the recipe "
00512             "are redirected to the command specified "
00513             "by this parameter. The plotting command "
00514             "must contain the substring 'gnuplot' and "
00515             "must be able to parse gnuplot syntax on its "
00516             "standard input. "
00517             "Valid examples of such a command may include "
00518             "'gnuplot -persist' and 'cat > mygnuplot$$.gp'. "
00519             "A finer control of the plotting options can "
00520             "be obtained by writing an "
00521             "executable script, e.g. my_gnuplot.pl, that "
00522             "executes gnuplot after setting the desired gnuplot "
00523             "options (e.g. set terminal pslatex color). "
00524             "To turn off plotting, set this parameter to 'no'",
00525             context,
00526             "no");
00527 
00528         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00529         cpl_parameterlist_append(parlist, p);
00530         cpl_free(full_name);
00531     }
00532 
00533 
00534 
00535    {
00536     name = "process_chip";
00537     full_name = uves_sprintf("%s.%s", context, name);
00538     uves_parameter_new_enum(p, full_name,
00539                     CPL_TYPE_STRING,
00540                     "For RED arm data proces the "
00541                  "redl, redu, or both chip(s)",
00542                     context,
00543                             "both",5,"both","redl","redu","REDL","REDU");
00544     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00545     cpl_parameterlist_append(parlist, p);
00546     cpl_free(full_name);
00547     }
00548 
00549     if (0)
00550         /* The meaning of this parameter often escapes the developers,
00551            so let's not expose it to the users */
00552         {
00553         name = "msginfolevel";
00554     full_name = uves_sprintf("%s.%s", context, name);
00555     uves_parameter_new_range(p, full_name,
00556                     CPL_TYPE_INT,
00557                     "This parameter controls the subdivision "
00558                     "of the 'info' message level (set e.g. with "
00559                     "esorex' --msg-level). The higher the value "
00560                     "of this parameter, the more messages are "
00561                     "printed at the info level. For minimum "
00562                     "output, set to zero. Increase the level "
00563                     "(to 1, 2, 3, ...) for more output. The "
00564                     "value -1 is a special value meaning maximum "
00565                     "output",
00566                     context,
00567                     -1,                 /* Default */
00568                     -1, INT_MAX);       /* Range   */
00569     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00570     cpl_parameterlist_append(parlist, p);
00571     cpl_free(full_name);
00572     }
00573 
00574     if (cpl_error_get_code() != CPL_ERROR_NONE)
00575     {
00576         cpl_msg_error(__func__, "Creation of global parameters failed: '%s'",
00577               cpl_error_get_where());
00578     }
00579     
00580     return cpl_error_get_code();
00581 }
00582 /*----------------------------------------------------------------------------*/
00591 /*----------------------------------------------------------------------------*/
00592 cpl_error_code
00593 uves_define_extract_for_response_chain_parameters(cpl_parameterlist *parameters)
00594 {
00595 
00596     const char *name = "";
00597     char *full_name = NULL;
00598     //char *context = NULL;
00599     cpl_parameter *p = NULL;
00600 /*
00601     context = uves_sprintf("%s.%s.%s", make_str(UVES_REDCHAIN_ID), make_str(UVES_RESPONSE_ID), name);
00602 */  
00603     {
00604         name = "uves_cal_response.reduce.extract.method";
00605         full_name = uves_sprintf("%s.%s%s", make_str(UVES_REDCHAIN_ID), "", name);
00606 
00607         uves_parameter_new_enum(p, full_name,
00608                                 CPL_TYPE_STRING,
00609                                 "Extraction method. (2d/optimal not supported by uves_cal_wavecal, weighted supported only by uves_cal_wavecal, 2d not supported by uves_cal_response)",
00610                                 UVES_EXTRACT_ID,
00611                                 "optimal",
00612                                 5,
00613                                 "average",
00614                                 "linear",
00615                                 "2d",
00616                                 "weighted",
00617                                 "optimal");
00618         
00619         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00620         cpl_parameterlist_append(parameters, p);
00621         cpl_free(full_name);
00622     }
00623 
00624     {
00625         name = "uves_cal_response.reduce.extract.kappa";
00626         full_name = uves_sprintf("%s.%s%s", make_str(UVES_REDCHAIN_ID), "", name);
00627         
00628         uves_parameter_new_range(p, full_name,
00629                                  CPL_TYPE_DOUBLE,
00630                                  "In optimal extraction mode, this is the "
00631                                  "threshold for bad (i.e. hot/cold) "
00632                                  "pixel rejection. If a pixel deviates more than "
00633                                  "kappa*sigma (where sigma is "
00634                                  "the uncertainty of the pixel flux) from "
00635                                  "the inferred spatial profile, its "
00636                                  "weight is set to zero. Range: [-1,100]. If this parameter "
00637                                  "is negative, no rejection is performed.",
00638                                  UVES_EXTRACT_ID,
00639                                  10.0,-1.,100.);
00640         
00641         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00642         cpl_parameterlist_append(parameters, p);
00643         cpl_free(full_name);
00644     }
00645 
00646     {
00647         name = "uves_cal_response.reduce.extract.chunk";
00648         full_name = uves_sprintf("%s.%s%s", make_str(UVES_REDCHAIN_ID), "", name);
00649         
00650         uves_parameter_new_range(p, full_name,
00651                                  CPL_TYPE_INT,
00652                                  "In optimal extraction mode, the chunk size (in pixels) "
00653                                  "used for fitting the analytical profile (a fit of the "
00654                                  "analytical profile to single bins would suffer from "
00655                                  "low statistics).",
00656                                  UVES_EXTRACT_ID,
00657                                  32,
00658                                  1, INT_MAX);
00659         
00660         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00661         cpl_parameterlist_append(parameters, p);
00662         cpl_free(full_name);
00663     }
00664     
00665     {
00666         name = "uves_cal_response.reduce.extract.profile";
00667         full_name = uves_sprintf("%s.%s%s", make_str(UVES_REDCHAIN_ID), "", name);
00668         
00669         uves_parameter_new_enum(p, full_name,
00670                                 CPL_TYPE_STRING,
00671                                 "In optimal extraction mode, the kind of profile to use. "
00672                                 "'gauss' gives a Gaussian profile, 'moffat' gives "
00673                                 "a Moffat profile with beta=4 and a possible linear sky "
00674                                 "contribution. 'virtual' uses "
00675                                 "a virtual resampling algorithm (i.e. measures and "
00676                                 "uses the actual object profile). "
00677                                 "'constant' assumes a constant spatial profile and "
00678                                 "allows optimal extraction of wavelength "
00679                                 "calibration frames. 'auto' will automatically "
00680                                 "select the best method based on the estimated S/N of the "
00681                                 "object. For low S/N, 'moffat' or 'gauss' are "
00682                                 "recommended (for robustness). For high S/N, 'virtual' is "
00683                                 "recommended (for accuracy). In the case of virtual resampling, "
00684                                 "a precise determination of the order positions is required; "
00685                                 "therefore the order-definition is repeated "
00686                                 "using the (assumed non-low S/N) science frame",
00687                                 UVES_EXTRACT_ID,
00688                 "auto",
00689                                 5,
00690                                 "constant",
00691                                 "gauss",
00692                                 "moffat",
00693                                 "virtual",
00694                                 "auto");
00695         
00696         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00697         cpl_parameterlist_append(parameters, p);
00698         cpl_free(full_name);
00699     }
00700 
00701     {
00702         name = "uves_cal_response.reduce.extract.skymethod";
00703         full_name = uves_sprintf("%s.%s%s", make_str(UVES_REDCHAIN_ID), "", name);
00704         
00705         uves_parameter_new_enum(p, full_name,
00706                                 CPL_TYPE_STRING,
00707                                 "In optimal extraction mode, the sky subtraction method "
00708                 "to use. 'median' estimates the sky as the median of pixels "
00709                 "along the slit (ignoring pixels close to the object), whereas "
00710                 "'optimal' does a chi square minimization along the slit "
00711                 "to obtain the best combined object and sky levels. The optimal "
00712                 "method gives the most accurate sky determination but is also "
00713                 "a bit slower than the median method",
00714                                 UVES_EXTRACT_ID,
00715                 "optimal",
00716                                 2,
00717                                 "median",
00718                                 "optimal");
00719         
00720         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00721         cpl_parameterlist_append(parameters, p);
00722         cpl_free(full_name);
00723     }
00724 
00725     {
00726         name = "uves_cal_response.reduce.extract.oversample";
00727         full_name = uves_sprintf("%s.%s%s", make_str(UVES_REDCHAIN_ID), "", name);
00728         
00729         uves_parameter_new_range(p, full_name,
00730                                  CPL_TYPE_INT,
00731                                  "The oversampling factor used for the virtual "
00732                                  "resampling algorithm. If negative, the value 5 is "
00733                                  "used for S/N <=200, and the value 10 is used if the estimated "
00734                                  "S/N is > 200",
00735                                  UVES_EXTRACT_ID,
00736                                  -1,
00737                                  -2, INT_MAX);
00738         
00739         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00740         cpl_parameterlist_append(parameters, p);
00741         cpl_free(full_name);
00742     }
00743 
00744     {
00745         name = "uves_cal_response.reduce.extract.best";
00746         full_name = uves_sprintf("%s.%s%s", make_str(UVES_REDCHAIN_ID), "", name);
00747     
00748     uves_parameter_new_value(p, full_name,
00749                  CPL_TYPE_BOOL,
00750                  "(optimal extraction only) "
00751                  "If false (fastest), the spectrum is extracted only once. "
00752                  "If true (best), the spectrum is extracted twice, the "
00753                  "second time using improved variance estimates "
00754                  "based on the first iteration. Better variance "
00755                  "estimates slightly improve the obtained signal to "
00756                  "noise but at the cost of increased execution time",
00757                  UVES_EXTRACT_ID,
00758                  true);
00759     
00760     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00761     cpl_parameterlist_append(parameters, p);
00762     cpl_free(full_name);
00763     }
00764 
00765 
00766     if (cpl_error_get_code() != CPL_ERROR_NONE)
00767     {
00768         cpl_msg_error(__func__, "Creation of extraction parameters failed: '%s'",
00769               cpl_error_get_where());
00770     }
00771     return cpl_error_get_code();
00772 
00773 }
00774 
00775 /*----------------------------------------------------------------------------*/
00784 /*----------------------------------------------------------------------------*/
00785 cpl_error_code
00786 uves_define_rebin_for_response_chain_parameters(cpl_parameterlist *parameters)
00787 {
00788 
00789 
00790 
00791     const char *name = "";
00792     char *full_name = NULL;
00793     cpl_parameter *p = NULL;
00794 
00795     
00796     {
00797     name = "uves_cal_response.reduce.rebin.wavestep";
00798     full_name = uves_sprintf("%s.%s%s",  make_str(UVES_REDCHAIN_ID),"", name);
00799 
00800     uves_parameter_new_range(p, full_name,
00801                  CPL_TYPE_DOUBLE,
00802                  "The bin size (in w.l.u.) in wavelength space. "
00803                  "If negative, a step size of "
00804                  "2/3 * ( average pixel size ) is used.",
00805                  UVES_REBIN_ID,
00806                              -1.0,-1.0,DBL_MAX);
00807     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00808     cpl_parameterlist_append(parameters, p);
00809     cpl_free(full_name);
00810 
00811     name = "uves_cal_response.reduce.rebin.scale";
00812     full_name = uves_sprintf("%s.%s%s",  make_str(UVES_REDCHAIN_ID),"", name);
00813     uves_parameter_new_value(p, full_name,
00814                  CPL_TYPE_BOOL,
00815                  "Whether or not to multiply by the factor "
00816                  "dx/dlambda (pixels per wavelength) "
00817                  "during the rebinning. This option is disabled "
00818                  "as default in concordance with the "
00819                  "method used in the MIDAS pipeline. This "
00820                  "option should be set to true "
00821                  "to convert the observed flux (in pixel-space) "
00822                  "to a flux per wavelength (in "
00823                  "wavelength-space).",
00824                  UVES_REBIN_ID,
00825                  false);
00826     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00827     cpl_parameterlist_append(parameters, p);
00828     cpl_free(full_name);
00829     }
00830     
00831   if (cpl_error_get_code() != CPL_ERROR_NONE)
00832     {
00833         cpl_msg_error(__func__, "Creation of background parameters failed: '%s'",
00834               cpl_error_get_where());
00835     }
00836     
00837 
00838     return cpl_error_get_code();
00839 
00840 }
00841 
00842 
00843 /*----------------------------------------------------------------------------*/
00852 /*----------------------------------------------------------------------------*/
00853 cpl_error_code
00854 uves_define_reduce_for_response_chain_parameters(cpl_parameterlist *parameters)
00855 {
00856 
00857    const char *name = NULL;
00858    char *full_name = NULL;
00859    cpl_parameter *p;
00860 
00861   
00862     /******************
00863      *  Slit geometry *
00864      ******************/
00865     if (cpl_error_get_code() == CPL_ERROR_NONE)
00866     {
00867         name = "uves_cal_response.reduce.slitlength";
00868         full_name = uves_sprintf("%s.%s%s",  make_str(UVES_REDCHAIN_ID),"", name);
00869         
00870         uves_parameter_new_range(p, full_name,
00871                     CPL_TYPE_DOUBLE,
00872                     "Extraction slit length (in pixels). "
00873                     "If negative, the value "
00874                     "inferred from the raw frame header is used",
00875                     UVES_REDUCE_ID,
00876                     -1.0,
00877                     -2.0, DBL_MAX);
00878         
00879         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00880         cpl_parameterlist_append(parameters, p);
00881         cpl_free(full_name);
00882     }
00883 
00884     if (cpl_error_get_code() == CPL_ERROR_NONE)
00885     {
00886         name = "uves_cal_response.reduce.skysub";
00887          full_name = uves_sprintf("%s.%s%s",  make_str(UVES_REDCHAIN_ID),"", name);
00888         
00889         uves_parameter_new_value(p, full_name,
00890                      CPL_TYPE_BOOL,
00891                      "Do sky-subtraction (only applicable to linear "
00892                      "and average extractions)?",
00893                      UVES_REDUCE_ID,
00894                      true);
00895         
00896         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00897         cpl_parameterlist_append(parameters, p);
00898         cpl_free(full_name);
00899     }
00900 
00901     if (cpl_error_get_code() == CPL_ERROR_NONE)
00902     {
00903         name = "uves_cal_response.reduce.objoffset";
00904          full_name = uves_sprintf("%s.%s%s",  make_str(UVES_REDCHAIN_ID),"", name);
00905         
00906         uves_parameter_new_value(p, full_name,
00907                      CPL_TYPE_DOUBLE,
00908                      "Offset (in pixels) of extraction slit "
00909                                      "with respect to center of order. "
00910                                      "This parameter applies to linear/average/"
00911                                      "optimal extraction. "
00912                                      "For linear/average extraction, if the related "
00913                                      "parameter objslit is negative, the offset is "
00914                      "automatically determined by measuring the "
00915                      "actual object position. ",
00916                      UVES_REDUCE_ID,
00917                      0.0);
00918         
00919         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00920         cpl_parameterlist_append(parameters, p);
00921         cpl_free(full_name);
00922     }
00923 
00924     if (cpl_error_get_code() == CPL_ERROR_NONE)
00925         {
00926             name = "uves_cal_response.reduce.objslit";
00927          full_name = uves_sprintf("%s.%s%s",  make_str(UVES_REDCHAIN_ID),"", name);
00928             
00929             uves_parameter_new_range(p, full_name,
00930                                      CPL_TYPE_DOUBLE,
00931                                      "Object window size (in pixels). This must "
00932                                      "be less than the total slit length. If "
00933                                      "negative, the default value (half of full "
00934                                      "slit length) is used. The upper and lower "
00935                                      "sky windows are defined as the part of the "
00936                                      "full slit (if any) outside the object "
00937                                      "window. The center of the object window "
00938                                      "is determined by the offset parameter. "
00939                                      "This parameter does not apply to optimal "
00940                                      "extraction.",
00941                                      UVES_REDUCE_ID,
00942                                      -1.0,
00943                                      -2.0, DBL_MAX);
00944         
00945         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00946         cpl_parameterlist_append(parameters, p);
00947         cpl_free(full_name);
00948     }
00949 
00950     if (cpl_error_get_code() == CPL_ERROR_NONE)
00951     {
00952         name = "uves_cal_response.reduce.tiltcorr";
00953          full_name = uves_sprintf("%s.%s%s",  make_str(UVES_REDCHAIN_ID),"", name);
00954         
00955         uves_parameter_new_value(p, full_name,
00956                      CPL_TYPE_BOOL,
00957                      "If enabled (recommended), the provided "
00958                                      "dispersion solutions "
00959                                      "obtained at different slit positions are "
00960                                      "interpolated linearly at the actually "
00961                                      "measured position of the object/sky. "
00962                                      "Line tilt correction is currently not supported "
00963                                      "for 2d extraction, in which case the "
00964                                      "dispersion solution obtained at the middle of "
00965                                      "the slit is always used.",
00966                      UVES_REDUCE_ID,
00967                      true);
00968         
00969         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00970         cpl_parameterlist_append(parameters, p);
00971         cpl_free(full_name);
00972     }
00973 
00974 
00975 
00976     /*****************
00977      *  Flatfielding *
00978      *****************/
00979 
00980     if (cpl_error_get_code() == CPL_ERROR_NONE)
00981     {
00982         name = "uves_cal_response.reduce.ffmethod";
00983          full_name = uves_sprintf("%s.%s%s",  make_str(UVES_REDCHAIN_ID),"", name);
00984         
00985         uves_parameter_new_enum(p, full_name,
00986                     CPL_TYPE_STRING,
00987                     "Flat-fielding method. If set to 'pixel', "
00988                     "flat-fielding is done in pixel-pixel space "
00989                     "(before extraction); if set to 'extract', "
00990                     "flat-fielding is performed in pixel-order "
00991                     "space (i.e. after extraction). If set to "
00992                     "'no', no flat-field correction is done",
00993                     UVES_REDUCE_ID,
00994                     "extract",    /* 'Pixel' method is usually preferred,
00995                              but do like UVES/MIDAS */
00996                     3, 
00997                     "pixel", "extract", "no");
00998         
00999         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01000         cpl_parameterlist_append(parameters, p);
01001         cpl_free(full_name);
01002     }
01003 
01004     /*****************
01005      *  Blaze corr.  *
01006      *****************/
01007 
01008     if (cpl_error_get_code() == CPL_ERROR_NONE)
01009     {
01010 
01011 /*
01012         name = "uves_cal_response.reduce.blazecorr";
01013          full_name = uves_sprintf("%s.%s%s",  make_str(UVES_REDCHAIN_ID),"", name);
01014         
01015         uves_parameter_new_value(p, full_name,
01016                     CPL_TYPE_BOOL,
01017                     "(highly experimental, recommended=false) "
01018                     "Apply a correction for the different shapes "
01019                     "of flat-field and science blaze functions? "
01020                     "For this to be possible, flat-fielding method "
01021                     "must be different from 'no'.",
01022                     UVES_REDUCE_ID,
01023                     false);
01024         
01025         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01026         cpl_parameterlist_append(parameters, p);
01027         cpl_free(full_name);
01028 */
01029     }
01030 
01031  
01032 
01033     /*****************
01034      *   Merging     *
01035      *****************/
01036     if (cpl_error_get_code() == CPL_ERROR_NONE)
01037     {
01038       name = "uves_cal_response.reduce.merge";
01039        full_name = uves_sprintf("%s.%s%s",  make_str(UVES_REDCHAIN_ID),"", name);
01040         
01041       uves_parameter_new_enum(p, full_name,
01042                   CPL_TYPE_STRING,
01043                               "Order merging method. If 'optimal', the "
01044                               "flux in the overlapping region is set "
01045                               "to the (optimally computed, using the "
01046                               "uncertainties) average of single order "
01047                               "spectra. If 'sum', the flux in the "
01048                               "overlapping region is computed as the "
01049                               "sum of the single order spectra. If 'noappend' "
01050                               "the spectrum is simply rebinned but not merged."
01051                               "If flat-fielding is done, method 'optimal' "
01052                               "is recommended, otherwise 'sum'.",
01053                               UVES_REDUCE_ID,
01054                               "optimal",
01055                               3, 
01056                   "optimal", "sum", "noappend");
01057         
01058       cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01059       cpl_parameterlist_append(parameters, p);
01060       cpl_free(full_name);
01061 
01062 
01063       name = "uves_cal_response.reduce.merge_delt1";
01064        full_name = uves_sprintf("%s.%s%s",  make_str(UVES_REDCHAIN_ID),"", name);
01065         
01066       uves_parameter_new_range(p, full_name,
01067                    CPL_TYPE_DOUBLE,
01068                                "Order merging left hand (short wavelength) "
01069                                "cut. To reduce the amount of order "
01070                                "overlapping regions we allow to cut short and "
01071                                "long wavelength ranges. "
01072                                "This may reduce the ripple possibly "
01073                                "introduced by the order merging. "
01074                                "Suggested values are: "
01075                                "10 (W<=390), 12 (390<W<=437, 520<W<=564), "
01076                    "14 (437<W<=520, 564<W) ",
01077                                UVES_REDUCE_ID,
01078                                0.,0.,20.);
01079         
01080       cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01081       cpl_parameterlist_append(parameters, p);
01082       cpl_free(full_name);
01083 
01084 
01085       name = "uves_cal_response.reduce.merge_delt2";
01086        full_name = uves_sprintf("%s.%s%s",  make_str(UVES_REDCHAIN_ID),"", name);
01087        
01088       uves_parameter_new_range(p, full_name,
01089                    CPL_TYPE_DOUBLE,
01090                                "Order merging right hand (long wavelength) "
01091                                "cut. To reduce the amount of order "
01092                                "overlapping regions we allow to cut short and "
01093                                "long wavelength ranges. "
01094                                "This may reduce the ripple possibly "
01095                                "introduced by the order merging. "
01096                                "Suggested values is 4",
01097                                UVES_REDUCE_ID,
01098                                0.,0.,20.);
01099         
01100       cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01101       cpl_parameterlist_append(parameters, p);
01102       cpl_free(full_name);
01103 
01104 
01105 
01106     }
01107 
01108 
01109   if (cpl_error_get_code() != CPL_ERROR_NONE)
01110     {
01111         cpl_msg_error(__func__, "Creation of background parameters failed: '%s'",
01112               cpl_error_get_where());
01113     }
01114     
01115 
01116     return cpl_error_get_code();
01117 
01118 }
01119 /*----------------------------------------------------------------------------*/
01128 /*----------------------------------------------------------------------------*/
01129 cpl_error_code
01130 uves_define_background_for_response_chain_parameters(cpl_parameterlist *parameters)
01131 {
01132 
01133 
01134    //const char *context = "uves"; 
01135    const char *name = NULL;
01136    char *full_name = NULL;
01137    cpl_parameter *p;
01138 
01139  
01140 
01141     /**************************
01142      * Inter-order-background *
01143      **************************/
01144 
01145     name = "uves_cal_response.reduce.backsub.mmethod";
01146     full_name = uves_sprintf("%s.%s%s",  make_str(UVES_REDCHAIN_ID),"", name);
01147     
01148     uves_parameter_new_enum(p, full_name,
01149                    CPL_TYPE_STRING,
01150                    "Background measuring method. If equal to 'median' "
01151                    "the background is sampled using the median of a subwindow. "
01152                    "If 'minimum', the subwindow minimum value is used. "
01153                    "If 'no', no background subtraction is done.",
01154                    UVES_BACKSUB_ID,
01155                    "median",                        /* Default */
01156                    3,                               /* Number of options */
01157                    "median", "minimum", "no");      /* List of options */
01158     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01159     cpl_parameterlist_append(parameters, p);
01160     cpl_free(full_name);
01161 
01162     //
01163     name = "uves_cal_response.reduce.backsub.npoints";
01164     full_name = uves_sprintf("%s.%s%s", make_str(UVES_REDCHAIN_ID), "", name);
01165     uves_parameter_new_range(p, full_name,
01166                  CPL_TYPE_INT,
01167                  "This is the number of columns in interorder space "
01168                  "used to sample the background.",
01169                  UVES_BACKSUB_ID,
01170                  82, 0, INT_MAX);
01171     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01172     cpl_parameterlist_append(parameters, p);
01173     cpl_free(full_name);
01174     
01175     //
01176     name = "uves_cal_response.reduce.backsub.radiusy";
01177     full_name = uves_sprintf("%s.%s%s", make_str(UVES_REDCHAIN_ID), "", name);
01178     uves_parameter_new_range(p, full_name,
01179                 CPL_TYPE_INT,
01180                 "The height (in pixels) of the background sampling "
01181                 "window is (2*radiusy + 1). "
01182                 "This parameter is not corrected for binning.",
01183                 UVES_BACKSUB_ID,
01184                 2, 0, INT_MAX);
01185     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01186     cpl_parameterlist_append(parameters, p);
01187     cpl_free(full_name);
01188     
01189     //
01190     name = "uves_cal_response.reduce.backsub.sdegree";
01191     full_name = uves_sprintf("%s.%s%s", make_str(UVES_REDCHAIN_ID), "", name);
01192     uves_parameter_new_range(p, full_name,
01193                  CPL_TYPE_INT,
01194                  "Degree of interpolating splines. Currently "
01195                  "only degree = 1 is supported",
01196                  UVES_BACKSUB_ID,
01197                  1, 0, INT_MAX);
01198     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01199     cpl_parameterlist_append(parameters, p);
01200     cpl_free(full_name);
01201 
01202     //
01203     name = "uves_cal_response.reduce.backsub.smoothx";
01204     full_name = uves_sprintf("%s.%s%s", make_str(UVES_REDCHAIN_ID), "", name);
01205     uves_parameter_new_range(p, full_name,
01206                  CPL_TYPE_DOUBLE,
01207                  "If spline interpolation is used to measure the background, "
01208                  "the x-radius of the post-smoothing window is "
01209                  "(smoothx * image_width). Here, 'image_width' is the image "
01210                  "width after binning. If negative, the default values are used: "
01211                  make_str(BACKSUB_FLAT_SMOOTHX_BLUE) " for blue flat-field frames, "
01212                  make_str(BACKSUB_FLAT_SMOOTHX_RED) " for red flat-field frames, "
01213                  make_str(BACKSUB_SCI_SMOOTHX_BLUE) " for blue science frames and "
01214                  make_str(BACKSUB_SCI_SMOOTHX_RED) " for red science frames.",
01215                  UVES_BACKSUB_ID,
01216                  -1.0, -DBL_MAX, DBL_MAX);
01217     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01218     cpl_parameterlist_append(parameters, p);
01219     cpl_free(full_name);
01220     
01221     //
01222     name = "uves_cal_response.reduce.backsub.smoothy";
01223     full_name = uves_sprintf("%s.%s%s", make_str(UVES_REDCHAIN_ID), "", name);
01224     uves_parameter_new_range(p, full_name,
01225                  CPL_TYPE_DOUBLE,
01226                  "If spline interpolation is used to measure the "
01227                  "background, the y-radius of the post-smoothing "
01228                  "window is (smoothy * image_height). Here, "
01229                  "'image_height' is the image height after binning. "
01230                  "If negative, the default values are used: "
01231                  make_str(BACKSUB_FLAT_SMOOTHY_BLUE) " for blue flat-field frames, "
01232                  make_str(BACKSUB_FLAT_SMOOTHY_RED) " for red flat-field frames, "
01233                  make_str(BACKSUB_SCI_SMOOTHY_BLUE) " for blue science frames and "
01234                  make_str(BACKSUB_SCI_SMOOTHY_RED) " for red science frames.",
01235                  UVES_BACKSUB_ID,
01236                  -1.0, -DBL_MAX, DBL_MAX);
01237     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01238     cpl_parameterlist_append(parameters, p);
01239     cpl_free(full_name);
01240 
01241 
01242     if (cpl_error_get_code() != CPL_ERROR_NONE)
01243     {
01244         cpl_msg_error(__func__, "Creation of background parameters failed: '%s'",
01245               cpl_error_get_where());
01246     }
01247     
01248     return cpl_error_get_code();
01249 
01250 }
01251 
01252 
01253 
01254 /*----------------------------------------------------------------------------*/
01263 /*----------------------------------------------------------------------------*/
01264 cpl_error_code
01265 uves_define_efficiency_for_response_chain_parameters(cpl_parameterlist *parlist)
01266 {
01267 
01268     char *full_name = NULL;
01269     cpl_parameter* p=NULL;
01270       const char* name = NULL;
01271       const char* value = NULL;
01272 
01273 
01274     /**********************
01275      *  Extraction-Merge  *
01276      **********************/
01277 
01278 
01279     /* For the efficiency step: Set default extraction method to 'linear',
01280      * flatfield_method to 'no', blazecorrection to 'false' and merge to
01281      * 'sum' (because optimal merging doesn't make sense without flatfielding)
01282      */
01283     
01284     {
01285 
01286       name = "uves_cal_response.efficiency.reduce.extract.method";
01287       value = "linear";
01288 
01289       full_name = uves_sprintf("%s.%s%s", make_str(UVES_REDCHAIN_ID), "", name);
01290        uves_parameter_new_value(p, full_name,
01291                      CPL_TYPE_STRING,
01292                      "Extraction method."
01293                      "<average | linear | weighted | optimal>",
01294                      UVES_REDUCE_ID,
01295                      value);
01296         
01297         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01298         cpl_parameterlist_append(parlist, p);
01299         cpl_free(full_name);
01300     
01301       name = "uves_cal_response.efficiency.reduce.ffmethod";
01302       value = "no";
01303 
01304      full_name = uves_sprintf("%s.%s%s", make_str(UVES_REDCHAIN_ID), "", name);
01305        uves_parameter_new_value(p, full_name,
01306                      CPL_TYPE_STRING,
01307                       "Flat-fielding method. If set to 'pixel', flat-fielding "
01308                       "is done in pixel-pixel space (before extraction); if "
01309                        "set to 'extract', flat-fielding is performed in "
01310                        "pixel-order space (i.e. after extraction). If set to "
01311                        "'no', no flat-field correction is done. <pixel | "
01312                 "extract | no>",
01313                      UVES_REDUCE_ID,
01314                      value);
01315         
01316         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01317         cpl_parameterlist_append(parlist, p);
01318         cpl_free(full_name);
01319 
01320       name = "uves_cal_response.efficiency.reduce.merge";
01321       value = "sum";
01322 
01323       full_name = uves_sprintf("%s.%s%s", make_str(UVES_REDCHAIN_ID), "", name);
01324        uves_parameter_new_value(p, full_name,
01325                      CPL_TYPE_STRING,
01326                      "Order merging method. If 'optimal', the flux in the "
01327                      "overlapping region is set to the (optimally computed, "
01328                      "using the uncertainties) average of single order "
01329                      "spectra. If 'sum', the flux in the overlapping region "
01330                      "is computed as the sum of the single order spectra."
01331                      "If 'noappend' the spectrum is simply rebinned but not "
01332                      "merged.If flat-fielding is done, method 'optimal' is "
01333                      "recommended, otherwise 'sum'. <optimal | sum | "
01334                      "noappend>",
01335                      UVES_REDUCE_ID,
01336                      value);
01337         
01338         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01339         cpl_parameterlist_append(parlist, p);
01340         cpl_free(full_name);
01341 
01342 
01343 
01344     const char *param = "linear";
01345 
01346     if (uves_set_parameter_default(parlist,
01347                        make_str(UVES_REDCHAIN_ID), "uves_cal_response.efficiency.reduce.extract.method",
01348                        CPL_TYPE_STRING, &param) != CPL_ERROR_NONE)
01349         {
01350         return -1;
01351         }
01352 
01353 
01354     }
01355 
01356 
01357    {
01358 
01359       name = "uves_cal_response.efficiency.reduce.best";
01360      full_name = uves_sprintf("%s.%s%s", make_str(UVES_REDCHAIN_ID), "", name);
01361      
01362     uves_parameter_new_value(p, full_name,
01363                  CPL_TYPE_BOOL,
01364                  "(optimal extraction only) "
01365                  "If false (fastest), the spectrum is extracted only once. "
01366                  "If true (best), the spectrum is extracted twice, the "
01367                  "second time using improved variance estimates "
01368                  "based on the first iteration. Better variance "
01369                  "estimates slightly improve the obtained signal to "
01370                  "noise but at the cost of increased execution time",
01371                  UVES_EXTRACT_ID,
01372                  true);
01373     
01374     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01375     cpl_parameterlist_append(parlist, p);
01376     cpl_free(full_name);
01377     }
01378 
01379 
01380 
01381     /****************
01382      *  Efficiency  *
01383      ****************/
01384 
01385     {
01386 
01387     name = "uves_cal_response.efficiency.paccuracy";
01388     full_name = uves_sprintf("%s.%s%s", make_str(UVES_REDCHAIN_ID), "", name);
01389 
01390        uves_parameter_new_value(p, full_name,
01391                      CPL_TYPE_DOUBLE,
01392               "The pointing accuracy (in arcseconds) used to "
01393                "identify the observed star with a "
01394                "catalogue star. If the angular separation is "
01395                "less than this number, the identification is made.",
01396                      UVES_REDUCE_ID,
01397                      60.0);
01398         
01399         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01400         cpl_parameterlist_append(parlist, p);
01401         cpl_free(full_name);
01402 
01403     }
01404     
01405 
01406 
01407     if (cpl_error_get_code() != CPL_ERROR_NONE)
01408     {
01409         cpl_msg_error(__func__, "Creation of efficiency parameters failed: '%s'",
01410               cpl_error_get_where());
01411     }
01412 
01413     return cpl_error_get_code();
01414 }
01415 
01416 /*----------------------------------------------------------------------------*/
01425 /*----------------------------------------------------------------------------*/
01426 cpl_error_code
01427 uves_define_efficiency_parameters(cpl_parameterlist *parlist)
01428 {
01429 
01430     char *full_name = NULL;
01431     cpl_parameter* p=NULL;
01432       const char* name = NULL;
01433       const char* value = NULL;
01434 
01435 
01436     /**********************
01437      *  Extraction-Merge  *
01438      **********************/
01439 
01440 
01441     /* For the efficiency step: Set default extraction method to 'linear',
01442      * flatfield_method to 'no', blazecorrection to 'false' and merge to
01443      * 'sum' (because optimal merging doesn't make sense without flatfielding)
01444      */
01445     
01446     {
01447 
01448 
01449       name = "efficiency.reduce.extract.method";
01450       value = "linear";
01451 
01452       full_name = uves_sprintf("%s.%s",  make_str(UVES_RESPONSE_ID), name);
01453        uves_parameter_new_value(p, full_name,
01454                      CPL_TYPE_STRING,
01455                      "Extraction method. "
01456                      "<average | linear | weighted | optimal>",
01457                      UVES_REDUCE_ID,
01458                      value);
01459         
01460         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01461         cpl_parameterlist_append(parlist, p);
01462         cpl_free(full_name);
01463 
01464     
01465       name = "efficiency.reduce.ffmethod";
01466       value = "no";
01467 
01468       full_name = uves_sprintf("%s.%s",  make_str(UVES_RESPONSE_ID), name);
01469        uves_parameter_new_value(p, full_name,
01470                      CPL_TYPE_STRING,
01471                       "Flat-fielding method. If set to 'pixel', flat-fielding "
01472                       "is done in pixel-pixel space (before extraction); if "
01473                        "set to 'extract', flat-fielding is performed in "
01474                        "pixel-order space (i.e. after extraction). If set to "
01475                        "'no', no flat-field correction is done. <pixel | "
01476                 "extract | no>",
01477                      UVES_REDUCE_ID,
01478                      value);
01479         
01480         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01481         cpl_parameterlist_append(parlist, p);
01482         cpl_free(full_name);
01483 
01484       name = "efficiency.reduce.merge";
01485       value = "sum";
01486 
01487       full_name = uves_sprintf("%s.%s",  make_str(UVES_RESPONSE_ID), name);
01488        uves_parameter_new_value(p, full_name,
01489                      CPL_TYPE_STRING,
01490                      "Order merging method. If 'optimal', the flux in the "
01491                      "overlapping region is set to the (optimally computed, "
01492                      "using the uncertainties) average of single order "
01493                      "spectra. If 'sum', the flux in the overlapping region "
01494                      "is computed as the sum of the single order spectra."
01495                      "If 'noappend' the spectrum is simply rebinned but not "
01496                      "merged.If flat-fielding is done, method 'optimal' is "
01497                      "recommended, otherwise 'sum'. <optimal | sum | "
01498                      "noappend>",
01499                      UVES_REDUCE_ID,
01500                      value);
01501         
01502         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01503         cpl_parameterlist_append(parlist, p);
01504         cpl_free(full_name);
01505 
01506 
01507 
01508 
01509     const char *param = "linear";
01510 
01511     if (uves_set_parameter_default(parlist,
01512                        make_str(UVES_RESPONSE_ID), "efficiency.reduce.extract.method",
01513                        CPL_TYPE_STRING, &param) != CPL_ERROR_NONE)
01514         {
01515         return -1;
01516         }
01517 
01518 
01519 /* 
01520     if (uves_set_parameter_default(parlist, 
01521                        make_str(UVES_RESPONSE_ID), "efficiency.reduce.extract.best",
01522                        CPL_TYPE_BOOL, &bool_param) != CPL_ERROR_NONE)
01523         {
01524         return -1;
01525         }
01526 */  
01527 
01528     }
01529 
01530 
01531    {
01532 
01533       name = "efficiency.reduce.best";
01534       full_name = uves_sprintf("%s.%s",  make_str(UVES_RESPONSE_ID), name);
01535      
01536     uves_parameter_new_value(p, full_name,
01537                  CPL_TYPE_BOOL,
01538                  "(optimal extraction only) "
01539                  "If false (fastest), the spectrum is extracted only once. "
01540                  "If true (best), the spectrum is extracted twice, the "
01541                  "second time using improved variance estimates "
01542                  "based on the first iteration. Better variance "
01543                  "estimates slightly improve the obtained signal to "
01544                  "noise but at the cost of increased execution time",
01545                  UVES_EXTRACT_ID,
01546                  true);
01547     
01548     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01549     cpl_parameterlist_append(parlist, p);
01550     cpl_free(full_name);
01551     }
01552 
01553 
01554 
01555     /****************
01556      *  Efficiency  *
01557      ****************/
01558 
01559     {
01560        /* const char *recipe_id = make_str(UVES_RESPONSE_ID); */
01561     const char *subcontext = "efficiency";
01562     const char* name="paccuracy";
01563     char *context=uves_sprintf("%s.%s",make_str(UVES_RESPONSE_ID),subcontext);
01564     // paccuracy 
01565 
01566 
01567 /*
01568     uves_par_new_value("paccuracy",
01569                CPL_TYPE_DOUBLE,
01570                "The pointing accuracy (in arcseconds) used to "
01571                "identify the observed star with a "
01572                "catalogue star. If the angular separation is "
01573                "less than this number, the identification is made.",
01574                60.0);
01575 */
01576 
01577 
01578     full_name = uves_sprintf("%s.%s", context,name);
01579        uves_parameter_new_value(p, full_name,
01580                      CPL_TYPE_DOUBLE,
01581               "The pointing accuracy (in arcseconds) used to "
01582                "identify the observed star with a "
01583                "catalogue star. If the angular separation is "
01584                "less than this number, the identification is made.",
01585                      context,
01586                      60.0);
01587         
01588         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
01589         cpl_parameterlist_append(parlist, p);
01590         cpl_free(full_name);
01591         cpl_free(context);
01592 
01593 
01594 
01595 
01596     }
01597     
01598 
01599 
01600     if (cpl_error_get_code() != CPL_ERROR_NONE)
01601     {
01602         cpl_msg_error(__func__, "Creation of efficiency parameters failed: '%s'",
01603               cpl_error_get_where());
01604     }
01605 
01606     return cpl_error_get_code();
01607 }
01608 
01609 
01610 
01611 
01612 /*----------------------------------------------------------------------------*/
01627 /*----------------------------------------------------------------------------*/
01628 
01629 int
01630 uves_exec_recipe(int (*get_info)(cpl_pluginlist *), 
01631                  const char *recipe_domain,
01632                  const cpl_parameterlist *parameters, 
01633                  cpl_frameset *frames,
01634                  const char *caller_id, const char *context)
01635 {
01636     cpl_pluginlist *list  = NULL;
01637     cpl_plugin *plugin    = NULL;
01638     cpl_recipe *recipe    = NULL;
01639 
01640     const char *recipe_id = NULL;
01641     cpl_parameter *p      = NULL;
01642     char *parent_name     = NULL;
01643     char *sub_domain      = NULL;
01644     int status = 0;
01645 
01646     bool must_destroy_plugin = false;   /* Indicates if recipe_create() 
01647                        has been called */
01648 
01649     /* Check input */
01650     assure(recipe_domain != NULL, CPL_ERROR_NULL_INPUT, "Null recipe message domain");
01651     assure(parameters != NULL, CPL_ERROR_NULL_INPUT, "Null parameter list");
01652     assure(frames != NULL, CPL_ERROR_NULL_INPUT, "Null frame set");
01653     assure(caller_id != NULL, CPL_ERROR_NULL_INPUT, "Null caller recipe name");
01654     /* 'context' may be NULL */    
01655 
01656     /* Get the sub-recipe plugin */
01657     check( list = cpl_pluginlist_new(),
01658        "Error allocating plugin list");
01659 
01660     /* Get info about recipe */
01661     status = get_info(list);
01662 
01663     assure( status == 0, CPL_ERROR_ILLEGAL_INPUT, 
01664         "Could not get info about recipe");
01665 
01666     /* Get default parameter list */
01667     check( plugin = cpl_pluginlist_get_first(list), "Error getting plugin");
01668     assure( plugin != NULL, CPL_ERROR_ILLEGAL_INPUT,
01669             "Plugin '%s' returned empty plugin list", recipe_id);
01670     assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE, 
01671             CPL_ERROR_TYPE_MISMATCH, "Plugin is not a recipe");
01672     recipe = (cpl_recipe *) plugin;
01673     
01674     recipe_id = cpl_strdup(cpl_plugin_get_name(plugin));
01675 
01676     /* Call initializer function */
01677     must_destroy_plugin = true;
01678     assure( cpl_plugin_get_init(plugin)(plugin) == 0, CPL_ERROR_ILLEGAL_INPUT,
01679         "Error initializing recipe");
01680     assure( recipe->parameters != NULL, CPL_ERROR_ILLEGAL_INPUT,
01681         "Recipe '%s' returned NULL parameter list", recipe_id);
01682 
01683     /* For each recipe parameter x:
01684        Set to value of C.x (from argument parameter list)
01685 
01686        Parameters in 'uves' context are simply overwritten
01687     */
01688     for (p = cpl_parameterlist_get_first(recipe->parameters); 
01689      p != NULL;
01690      p = cpl_parameterlist_get_next(recipe->parameters) )
01691     {
01692         const char *name          = cpl_parameter_get_name(p);   
01693         const char *subcontext    = cpl_parameter_get_context(p);
01694         cpl_type type             = cpl_parameter_get_type(p);
01695         
01696         const cpl_parameter *parent;
01697         
01698         if (strcmp(subcontext, "uves") == 0)
01699         {
01700             parent_name = uves_sprintf("%s", name);
01701         }
01702         else
01703         {
01704             if (context != NULL)
01705             {
01706                 parent_name = uves_sprintf("%s.%s.%s", caller_id, context, name);
01707             }
01708             else
01709             {
01710                 parent_name = uves_sprintf("%s.%s", caller_id, name);
01711             }
01712         }
01713         
01714         /* Const cast, we don't change the parameter list, parent is declared const */
01715         check( parent = cpl_parameterlist_find_const(parameters, parent_name),
01716            "Could not get parameter '%s' from provided parameter list", parent_name);
01717         /* PIPPO
01718         assure( parent != NULL, CPL_ERROR_DATA_NOT_FOUND,
01719             "Missing parameter '%s' needed to define '%s' in context '%s'",
01720             parent_name, name, context);
01721         
01722         assure( cpl_parameter_get_type(parent) == type, CPL_ERROR_TYPE_MISMATCH,
01723             "Parameter '%s' type is %s. Type %s needed for recipe parameter '%s'",
01724             parent_name, 
01725             uves_tostring_cpl_type(cpl_parameter_get_type(parent)),
01726             uves_tostring_cpl_type(type),
01727             name);
01728         */  
01729         switch (type)
01730         {
01731             int value_int;  
01732             bool value_bool;
01733             double value_double;
01734             const char *value_string;
01735 
01736         case CPL_TYPE_BOOL:
01737             check( value_bool = cpl_parameter_get_bool(parent), 
01738                "Error reading parameter '%s'", parent_name);
01739         
01740             check( cpl_parameter_set_bool(p, value_bool),
01741                "Error setting parameter '%s'", name);
01742             
01743             uves_msg_debug("Setting parameter '%s' <- '%s' = %s",
01744                    name, parent_name, (value_bool) ? "true" : "false");
01745             break;
01746 
01747         case CPL_TYPE_INT:
01748             check( value_int = cpl_parameter_get_int(parent),
01749                "Error reading parameter '%s'", parent_name);
01750         
01751             check( cpl_parameter_set_int(p, value_int),
01752                "Error setting parameter '%s'", name);
01753             
01754             uves_msg_debug("Setting parameter '%s' <- '%s' = %d", 
01755                    name, parent_name, value_int);
01756             break;
01757             
01758         case CPL_TYPE_DOUBLE:
01759             check( value_double = cpl_parameter_get_double(parent),
01760                "Error reading parameter '%s'", parent_name);
01761         
01762             check( cpl_parameter_set_double(p, value_double),
01763                "Error setting parameter '%s'", name);
01764             
01765             uves_msg_debug("Setting parameter '%s' <- '%s' = %e", 
01766                    name, parent_name, value_double);
01767             break;
01768             
01769         case CPL_TYPE_STRING:
01770             check( value_string = cpl_parameter_get_string(parent),
01771                "Error reading parameter '%s'", parent_name);
01772             
01773             check( cpl_parameter_set_string(p, value_string), 
01774                "Error setting parameter '%s'", name);
01775             
01776             uves_msg_debug("Setting parameter '%s' <- '%s' = '%s'", 
01777                    name, parent_name, value_string);
01778             break;
01779             
01780         default:
01781             assure(false, CPL_ERROR_UNSUPPORTED_MODE,
01782                "Parameter '%s' has type %s",
01783                name, uves_tostring_cpl_type(type));
01784         }  /* switch type */
01785         
01786         cpl_free(parent_name); parent_name = NULL;
01787         
01788     } /* Set each recipe parameter */
01789 
01790     /* Pass frame set without touching */
01791     recipe->frames = frames;
01792 
01793     /* 
01794      * Invoke recipe 
01795      *
01796      *  Remember message domain of caller,
01797      *   and number of warnings in caller.
01798      */
01799 
01800     {
01801     const char *domain = uves_msg_get_domain();
01802     int warnings_in_caller = uves_msg_get_warnings();
01803 
01804     sub_domain = uves_sprintf("%s.%s", domain, recipe_domain);
01805     uves_msg_set_domain(sub_domain);
01806 
01807     status = cpl_plugin_get_exec(plugin)(plugin);
01808 
01809     /* Reset state (domain+warnings) */
01810 
01811     uves_msg_set_domain(domain);
01812 
01813     /* Total number of warnings in caller is not
01814      * (previous warnings) + (subrecipe warnings)
01815      */
01816     uves_msg_add_warnings(warnings_in_caller);
01817     }
01818     
01819     /* On recipe failure: The recipe is responsible 
01820      *  for printing any error messages.
01821      *  A failing recipe is an unrecoverable error.
01822      */
01823 
01824     if (cpl_error_get_code() != CPL_ERROR_NONE)
01825     {
01826         /* Reset error stack but keep error code */
01827         cpl_error_code ec = cpl_error_get_code();
01828         uves_error_reset();
01829         assure( false, ec, "Recipe '%s' failed", recipe_id);
01830     }
01831     
01832     assure( status == 0, CPL_ERROR_ILLEGAL_OUTPUT,
01833         "Recipe '%s' failed with exit status %d", recipe_id, status);
01834     
01835     /* Call recipe_destroy */
01836     must_destroy_plugin = false;
01837     assure( cpl_plugin_get_deinit(plugin)(plugin) == 0, 
01838         CPL_ERROR_ILLEGAL_OUTPUT,
01839         "Error cleaning up recipe");
01840     
01841     uves_msg("Recipe '%s' succeeded", recipe_id);
01842 
01843   cleanup:
01844     uves_free_string_const(&recipe_id);
01845     cpl_free(parent_name); parent_name = NULL;
01846     cpl_free(sub_domain); sub_domain = NULL;
01847     if (must_destroy_plugin)
01848     {
01849         cpl_plugin_get_deinit(plugin)(plugin);
01850     }
01851 
01852     cpl_pluginlist_delete(list);
01853     
01854     return (cpl_error_get_code() != CPL_ERROR_NONE);
01855 }
01856 
01857 /*----------------------------------------------------------------------------*/
01872 /*----------------------------------------------------------------------------*/
01873 
01874 int
01875 uves_invoke_recipe(const char *recipe_id, const cpl_parameterlist *parameters, 
01876                    cpl_frameset *frames,
01877                    const char *caller_id, const char *context)
01878 {
01879     assure(recipe_id != NULL, CPL_ERROR_NULL_INPUT, "Null recipe name");
01880 
01881     if      (strcmp(recipe_id, make_str(UVES_PHYSMOD_ID) ) == 0) return uves_exec_recipe(&uves_physmod_get_info, UVES_PHYSMOD_DOM, parameters, frames, caller_id, context);
01882     else if (strcmp(recipe_id, make_str(UVES_ORDERPOS_ID)) == 0) return uves_exec_recipe(&uves_orderpos_get_info, UVES_ORDERPOS_DOM, parameters, frames, caller_id, context);
01883     else if (strcmp(recipe_id, make_str(UVES_MBIAS_ID)   ) == 0) return uves_exec_recipe(&uves_mbias_get_info, UVES_MBIAS_DOM, parameters, frames, caller_id, context);
01884     else if (strcmp(recipe_id, make_str(UVES_MDARK_ID)   ) == 0) return uves_exec_recipe(&uves_mdark_get_info, UVES_MDARK_DOM, parameters, frames, caller_id, context);
01885     else if (strcmp(recipe_id, make_str(UVES_MFLAT_ID)   ) == 0) return uves_exec_recipe(&uves_mflat_get_info,  UVES_MFLAT_DOM, parameters, frames, caller_id, context);
01886     else if (strcmp(recipe_id, make_str(UVES_WAVECAL_ID) ) == 0) return uves_exec_recipe(&uves_wavecal_get_info,  UVES_WAVECAL_DOM, parameters, frames, caller_id, context);
01887     else if (strcmp(recipe_id, make_str(UVES_RESPONSE_ID)) == 0) return uves_exec_recipe(&uves_response_get_info, UVES_RESPONSE_DOM, parameters, frames, caller_id, context);
01888     else if (strcmp(recipe_id, make_str(UVES_SCIRED_ID)  ) == 0) return uves_exec_recipe(&uves_scired_get_info, UVES_SCIRED_DOM, parameters, frames, caller_id, context);
01889     else if (strcmp(recipe_id, make_str(UVES_REDCHAIN_ID)) == 0) return uves_exec_recipe(&uves_redchain_get_info, UVES_REDCHAIN_DOM, parameters, frames, caller_id, context);
01890     else
01891         {
01892             assure( false, CPL_ERROR_ILLEGAL_INPUT, "Unknown recipe: '%s'", recipe_id);
01893         }
01894   cleanup:
01895     return (cpl_error_get_code() != CPL_ERROR_NONE);
01896 }
01897 
01898 
01899 /*----------------------------------------------------------------------------*/
01917 /*----------------------------------------------------------------------------*/
01918 int
01919 uves_prop_par(int (*get_info)(cpl_pluginlist *),
01920     cpl_parameterlist *parameters,
01921     const char *recipe_id, const char *context)
01922 {
01923     cpl_plugin *plugin    = NULL;
01924     cpl_pluginlist *list  = NULL;
01925     cpl_recipe *subrecipe = NULL;
01926     char name[256];
01927     int status;
01928 
01929     /* Check input */
01930     if (get_info == NULL)
01931     {
01932         FAIL(-1, CPL_ERROR_NULL_INPUT, "Null function pointer");
01933     }
01934     /* context may be NULL */
01935     if (parameters == NULL)
01936     {
01937         FAIL(-1, CPL_ERROR_NULL_INPUT, "Null parameter list");
01938     }
01939     
01940     if (recipe_id == NULL)
01941     {
01942         FAIL(-1, CPL_ERROR_NULL_INPUT, "Null recipe id");
01943     }    
01944 
01945     /* Get the sub-recipe plugin */
01946     list = cpl_pluginlist_new();
01947     status = get_info(list);
01948     
01949     if (status != 0)
01950     {
01951         cpl_pluginlist_delete(list);
01952         FAIL(-1, CPL_ERROR_ILLEGAL_INPUT, "Could not get info about recipe");
01953     }
01954 
01955     /* Get first plugin in plugin list, it must be of type recipe */
01956     if ((plugin = cpl_pluginlist_get_first(list)) == NULL)
01957     {
01958         cpl_pluginlist_delete(list);
01959         FAIL(-1, CPL_ERROR_ILLEGAL_INPUT, "Error getting plugin");
01960     }
01961     if (cpl_plugin_get_name(plugin) == NULL) {
01962         cpl_pluginlist_delete(list);
01963         FAIL(-1, CPL_ERROR_ILLEGAL_INPUT, "Plugin name is NULL");
01964     }
01965     sprintf(name,cpl_plugin_get_name(plugin));
01966     
01967     if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE)
01968         {
01969             cpl_pluginlist_delete(list);
01970             FAIL(-1, CPL_ERROR_TYPE_MISMATCH, "Plugin is not a recipe");
01971         }
01972     subrecipe = (cpl_recipe *) plugin;
01973     
01974     /* Create parameter list by calling subrecipe initializer function */
01975     if( cpl_plugin_get_init(plugin)(plugin) != 0)
01976     {
01977         cpl_plugin_get_deinit(plugin)(plugin);
01978         cpl_pluginlist_delete(list);
01979         FAIL(-1, CPL_ERROR_ILLEGAL_INPUT, "Error getting '%s' parameter list",
01980              name);
01981     }
01982 
01983     if (subrecipe->parameters == NULL)
01984     {
01985         cpl_plugin_get_deinit(plugin)(plugin);
01986         cpl_pluginlist_delete(list);
01987         FAIL(-1, CPL_ERROR_NULL_INPUT, "Recipe '%s' returned NULL parameter list", 
01988              name);
01989     }
01990     
01991     if (propagate(cpl_plugin_get_name(plugin), subrecipe->parameters, parameters, recipe_id, context) != 0)
01992     {
01993         cpl_plugin_get_deinit(plugin)(plugin);
01994         cpl_pluginlist_delete(list);
01995         FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT, "Error propagating parameters from recipe '%s'", 
01996              name);
01997     }
01998     
01999     cpl_plugin_get_deinit(plugin)(plugin);
02000     cpl_pluginlist_delete(list);
02001    
02002     return 0;
02003 }
02004 
02005 /*----------------------------------------------------------------------------*/
02011 /*----------------------------------------------------------------------------*/
02012 int
02013 uves_propagate_parameters(const char *subrecipe,
02014                           cpl_parameterlist *parameters,
02015                           const char *recipe_id, const char *context)
02016 {
02017     if (subrecipe == NULL) {
02018         FAIL(-1, CPL_ERROR_NULL_INPUT, "Null subrecipe id");
02019     }
02020     
02021     if      (strcmp(subrecipe, make_str(UVES_PHYSMOD_ID) ) == 0) return uves_prop_par(&uves_physmod_get_info, parameters, recipe_id, context);
02022     else if (strcmp(subrecipe, make_str(UVES_ORDERPOS_ID)) == 0) return uves_prop_par(&uves_orderpos_get_info, parameters, recipe_id, context);
02023     else if (strcmp(subrecipe, make_str(UVES_MBIAS_ID)   ) == 0) return uves_prop_par(&uves_mbias_get_info, parameters, recipe_id, context);
02024     else if (strcmp(subrecipe, make_str(UVES_MDARK_ID)   ) == 0) return uves_prop_par(&uves_mdark_get_info, parameters, recipe_id, context);
02025     else if (strcmp(subrecipe, make_str(UVES_MFLAT_ID)   ) == 0) return uves_prop_par(&uves_mflat_get_info, parameters, recipe_id, context);
02026     else if (strcmp(subrecipe, make_str(UVES_WAVECAL_ID) ) == 0) return uves_prop_par(&uves_wavecal_get_info, parameters, recipe_id, context);
02027     else if (strcmp(subrecipe, make_str(UVES_RESPONSE_ID)) == 0) return uves_prop_par(&uves_response_get_info, parameters, recipe_id, context);
02028     else if (strcmp(subrecipe, make_str(UVES_SCIRED_ID)  ) == 0) return uves_prop_par(&uves_scired_get_info, parameters, recipe_id, context);
02029     else if (strcmp(subrecipe, make_str(UVES_REDCHAIN_ID)) == 0) return uves_prop_par(&uves_redchain_get_info, parameters, recipe_id, context);
02030     else {
02031         FAIL(-1, CPL_ERROR_DATA_NOT_FOUND, "Unknown recipe: '%s'", subrecipe);
02032     }
02033 }
02034 
02035 /*----------------------------------------------------------------------------*/
02080 /*----------------------------------------------------------------------------*/
02081 
02082 int
02083 uves_propagate_parameters_step(const char *step_id,
02084                    cpl_parameterlist *parameters,
02085                    const char *recipe_id, const char *context)
02086 {
02087     cpl_parameterlist *subparameters = NULL;
02088     cpl_parameterlist *(*get_parameters)(void) = NULL; /* Pointer to function 
02089                               returning parameter list */
02090     
02091     /* Check input */
02092     if (step_id == NULL)
02093     {
02094         FAIL(-1, CPL_ERROR_NULL_INPUT, "Null parameter list");
02095     }
02096     
02097     if (parameters == NULL)
02098     {
02099         FAIL(-1, CPL_ERROR_NULL_INPUT, "Null parameter list");
02100     }
02101     
02102     if (recipe_id == NULL)
02103     {
02104         FAIL(-1, CPL_ERROR_NULL_INPUT, "Null recipe id");
02105     }    
02106     /* context may be NULL */
02107     
02108     /* Define which function to call */
02109            if (strcmp(step_id, UVES_BACKSUB_ID ) == 0) {
02110       get_parameters = uves_backsub_define_parameters;
02111     } else if (strcmp(step_id, UVES_QCDARK_ID ) == 0) {
02112       get_parameters = uves_qcdark_define_parameters;
02113     } else if (strcmp(step_id, UVES_EXTRACT_ID ) == 0) {
02114       get_parameters = uves_extract_define_parameters;
02115     } else if (strcmp(step_id, UVES_REBIN_ID   ) == 0) {
02116       get_parameters = uves_rebin_define_parameters;
02117     } else if (strcmp(step_id, UVES_REDUCE_ID  ) == 0) {
02118       get_parameters = uves_reduce_define_parameters;
02119     } else {
02120       FAIL(-1, CPL_ERROR_DATA_NOT_FOUND, "Unknown sub-step: '%s'", step_id);
02121     }
02122 
02123     /* Get sub-step parameters */
02124     if( (subparameters = get_parameters()) == NULL )
02125     {
02126         FAIL(-1, CPL_ERROR_ILLEGAL_INPUT, "Error getting '%s' parameter list", step_id);
02127     }
02128     
02129     if ( propagate(step_id, subparameters, parameters, recipe_id, context) != 0)
02130     {
02131         cpl_parameterlist_delete(subparameters);
02132         FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT, "Error propagating '%s' parameters", step_id);
02133     }
02134     
02135     cpl_parameterlist_delete(subparameters);
02136     return 0;
02137 }
02138 
02139 
02140 /*
02141  * Create an enumeration parameter.
02142  * One function for each of  int, double, string
02143  *    size of values array must match 'size', returns NULL iff error. 
02144  *
02145  * It would be much nicer to use a cpl_parameter_duplicate(), but that
02146  * doesn't exist
02147  *
02148  * (These three functions could be reduced to one function by use
02149  * of void pointers, but that is also ugly)
02150  */
02151 static cpl_parameter *
02152 create_parameter_enum_int(const char *name, cpl_type type,
02153               const char *description, 
02154               const char *context, 
02155               int default_value, int size,
02156               int *values)
02157 {
02158     /*  This is just ugly */
02159 
02160     cpl_parameter *result = NULL;
02161     
02162     if (! (1 <= size && size <= 10))
02163     {
02164         cpl_msg_error(__func__, "Unsupported enumeration size: %d (max is 10)", size);
02165         return NULL;
02166     }
02167     
02168     switch(size)
02169     {
02170     case 1:
02171         uves_parameter_new_enum(result, name,
02172                        type,
02173                        description,
02174                        context,
02175                        default_value, size,
02176                        values[0]);
02177         break;
02178     case 2:
02179         uves_parameter_new_enum(result, name,
02180                           type,
02181                           description,
02182                           context,
02183                           default_value, size,
02184                           values[0],
02185                           values[1]);
02186         break;
02187     case 3:
02188         uves_parameter_new_enum(result, name,
02189                           type,
02190                           description,
02191                           context,
02192                           default_value, size,
02193                           values[0],
02194                           values[1],
02195                           values[2]);
02196         break;
02197     case 4:
02198         uves_parameter_new_enum(result, name,
02199                           type,
02200                           description,
02201                           context,
02202                           default_value, size,
02203                           values[0], 
02204                           values[1], 
02205                           values[2], 
02206                           values[3]);
02207         break;
02208     case 5:
02209         uves_parameter_new_enum(result, name,
02210                           type,
02211                           description,
02212                           context,
02213                           default_value, size,
02214                           values[0], 
02215                           values[1], 
02216                           values[2], 
02217                           values[3], 
02218                           values[4]);
02219         break;
02220     case 6:
02221         uves_parameter_new_enum(result, name,
02222                           type,
02223                           description,
02224                           context,
02225                           default_value, size,
02226                           values[0], 
02227                           values[1], 
02228                           values[2], 
02229                           values[3], 
02230                           values[4], 
02231                           values[5]);
02232         break;
02233     case 7:
02234         uves_parameter_new_enum(result, name,
02235                           type,
02236                           description,
02237                           context,
02238                           default_value, size,
02239                           values[0], 
02240                           values[1], 
02241                           values[2], 
02242                           values[3], 
02243                           values[4], 
02244                           values[5], 
02245                           values[6]);
02246         break;
02247     case 8:
02248         uves_parameter_new_enum(result, name,
02249                           type,
02250                           description,
02251                           context,
02252                           default_value, size,
02253                           values[0], 
02254                           values[1], 
02255                           values[2], 
02256                           values[3], 
02257                           values[4], 
02258                           values[5], 
02259                           values[6], 
02260                           values[7]);
02261         break;
02262     case 9:
02263         uves_parameter_new_enum(result, name,
02264                           type,
02265                           description,
02266                           context,
02267                           default_value, size,
02268                           values[0], 
02269                           values[1], 
02270                           values[2], 
02271                           values[3], 
02272                           values[4], 
02273                           values[5], 
02274                           values[6], 
02275                           values[7], 
02276                           values[8]);
02277         break;
02278     case 10:
02279         uves_parameter_new_enum(result, name,
02280                        type,
02281                        description,
02282                        context,
02283                        default_value, size,
02284                        values[0], 
02285                        values[1], 
02286                        values[2], 
02287                        values[3], 
02288                        values[4], 
02289                        values[5], 
02290                        values[6], 
02291                        values[7], 
02292                        values[8], 
02293                        values[9]);
02294         break;
02295     } /* Switch size */
02296     return result;
02297 }
02298 static cpl_parameter *
02299 create_parameter_enum_double(const char *name, cpl_type type,
02300                  const char *description, 
02301                  const char *context, double default_value,
02302                  int size, double *values)
02303 {
02304     /*  This is very ugly */
02305     
02306     cpl_parameter *result = NULL; 
02307 
02308     if (! (1 <= size && size <= 10))
02309     {
02310         cpl_msg_error(__func__, "Unsupported enumeration size: %d (max is 10)", size);
02311         return NULL;
02312     }
02313     
02314     switch(size)
02315     {
02316     case 1:
02317         uves_parameter_new_enum(result, name,
02318                        type,
02319                        description,
02320                        context,
02321                        default_value, size,
02322                        values[0]);
02323         break;
02324     case 2:
02325         uves_parameter_new_enum(result, name,
02326                           type,
02327                           description,
02328                           context,
02329                           default_value, size,
02330                           values[0],
02331                           values[1]);
02332         break;
02333     case 3:
02334         uves_parameter_new_enum(result, name,
02335                           type,
02336                           description,
02337                           context,
02338                           default_value, size,
02339                           values[0],
02340                           values[1],
02341                           values[2]);
02342         break;
02343     case 4:
02344         uves_parameter_new_enum(result, name,
02345                           type,
02346                           description,
02347                           context,
02348                           default_value, size,
02349                           values[0], 
02350                           values[1], 
02351                           values[2], 
02352                           values[3]);
02353         break;
02354     case 5:
02355         uves_parameter_new_enum(result, name,
02356                           type,
02357                           description,
02358                           context,
02359                           default_value, size,
02360                           values[0], 
02361                           values[1], 
02362                           values[2], 
02363                           values[3], 
02364                           values[4]);
02365         break;
02366     case 6:
02367         uves_parameter_new_enum(result, name,
02368                           type,
02369                           description,
02370                           context,
02371                           default_value, size,
02372                           values[0], 
02373                           values[1], 
02374                           values[2], 
02375                           values[3], 
02376                           values[4], 
02377                           values[5]);
02378         break;
02379     case 7:
02380         uves_parameter_new_enum(result, name,
02381                           type,
02382                           description,
02383                           context,
02384                           default_value, size,
02385                           values[0], 
02386                           values[1], 
02387                           values[2], 
02388                           values[3], 
02389                           values[4], 
02390                           values[5], 
02391                           values[6]);
02392         break;
02393     case 8:
02394         uves_parameter_new_enum(result, name,
02395                           type,
02396                           description,
02397                           context,
02398                           default_value, size,
02399                           values[0], 
02400                           values[1], 
02401                           values[2], 
02402                           values[3], 
02403                           values[4], 
02404                           values[5], 
02405                           values[6], 
02406                           values[7]);
02407         break;
02408     case 9:
02409         uves_parameter_new_enum(result, name,
02410                           type,
02411                           description,
02412                           context,
02413                           default_value, size,
02414                           values[0], 
02415                           values[1], 
02416                           values[2], 
02417                           values[3], 
02418                           values[4], 
02419                           values[5], 
02420                           values[6], 
02421                           values[7], 
02422                           values[8]);
02423         break;
02424     case 10:
02425         uves_parameter_new_enum(result, name,
02426                        type,
02427                        description,
02428                        context,
02429                        default_value, size,
02430                        values[0], 
02431                        values[1], 
02432                        values[2], 
02433                        values[3], 
02434                        values[4], 
02435                        values[5], 
02436                        values[6], 
02437                        values[7], 
02438                        values[8], 
02439                        values[9]);
02440         break;
02441     } /* Switch size */
02442     return result;
02443 }
02444 static cpl_parameter *
02445 create_parameter_enum_string(const char *name, cpl_type type,
02446                  const char *description, 
02447                  const char *context, 
02448                  const char *default_value, 
02449                  int size, const char **values)
02450 {
02451     /*  This is extremely ugly */
02452     
02453     cpl_parameter *result = NULL;
02454 
02455     if (! (1 <= size && size <= 10))
02456     {
02457         cpl_msg_error(__func__, "Unsupported enumeration size: %d (max is 10)", size);
02458         return NULL;
02459     }
02460     
02461     switch(size)
02462     {
02463     case 1:
02464         uves_parameter_new_enum(result, name,
02465                        type,
02466                        description,
02467                        context,
02468                        default_value, size,
02469                        values[0]);
02470         break;
02471     case 2:
02472         uves_parameter_new_enum(result, name,
02473                           type,
02474                           description,
02475                           context,
02476                           default_value, size,
02477                           values[0],
02478                           values[1]);
02479         break;
02480     case 3:
02481         uves_parameter_new_enum(result, name,
02482                           type,
02483                           description,
02484                           context,
02485                           default_value, size,
02486                           values[0],
02487                           values[1],
02488                           values[2]);
02489         break;
02490     case 4:
02491         uves_parameter_new_enum(result, name,
02492                           type,
02493                           description,
02494                           context,
02495                           default_value, size,
02496                           values[0], 
02497                           values[1], 
02498                           values[2], 
02499                           values[3]);
02500         break;
02501     case 5:
02502         uves_parameter_new_enum(result, name,
02503                           type,
02504                           description,
02505                           context,
02506                           default_value, size,
02507                           values[0], 
02508                           values[1], 
02509                           values[2], 
02510                           values[3], 
02511                           values[4]);
02512         break;
02513     case 6:
02514         uves_parameter_new_enum(result, name,
02515                           type,
02516                           description,
02517                           context,
02518                           default_value, size,
02519                           values[0], 
02520                           values[1], 
02521                           values[2], 
02522                           values[3], 
02523                           values[4], 
02524                           values[5]);
02525         break;
02526     case 7:
02527         uves_parameter_new_enum(result, name,
02528                           type,
02529                           description,
02530                           context,
02531                           default_value, size,
02532                           values[0], 
02533                           values[1], 
02534                           values[2], 
02535                           values[3], 
02536                           values[4], 
02537                           values[5], 
02538                           values[6]);
02539         break;
02540     case 8:
02541         uves_parameter_new_enum(result, name,
02542                           type,
02543                           description,
02544                           context,
02545                           default_value, size,
02546                           values[0], 
02547                           values[1], 
02548                           values[2], 
02549                           values[3], 
02550                           values[4], 
02551                           values[5], 
02552                           values[6], 
02553                           values[7]);
02554         break;
02555     case 9:
02556         uves_parameter_new_enum(result, name,
02557                           type,
02558                           description,
02559                           context,
02560                           default_value, size,
02561                           values[0], 
02562                           values[1], 
02563                           values[2], 
02564                           values[3], 
02565                           values[4], 
02566                           values[5], 
02567                           values[6], 
02568                           values[7], 
02569                           values[8]);
02570         break;
02571     case 10:
02572         uves_parameter_new_enum(result, name,
02573                        type,
02574                        description,
02575                        context,
02576                        default_value, size,
02577                        values[0], 
02578                        values[1], 
02579                        values[2], 
02580                        values[3], 
02581                        values[4], 
02582                        values[5], 
02583                        values[6], 
02584                        values[7], 
02585                        values[8], 
02586                        values[9]);
02587         break;
02588     } /* Switch size */
02589     return result;
02590 }
02591 
02592 
02593 /*----------------------------------------------------------------------------*/
02629 /*----------------------------------------------------------------------------*/
02630 
02631 static int
02632 propagate(const char *substep_id, const cpl_parameterlist *sub_parameters, 
02633       cpl_parameterlist *parent_parameters,
02634       const char *parent_id, const char *context)
02635 {
02636     const cpl_parameter *p = NULL;
02637     
02638     /* For each sub-recipe parameter:
02639        prefix with context and insert in parent parameter list
02640 
02641        Set (overwrite) default value as current value
02642     */
02643     for (p = cpl_parameterlist_get_first_const(sub_parameters);
02644          p != NULL;
02645          p = cpl_parameterlist_get_next_const(sub_parameters) )
02646     {
02647         const char *name          = cpl_parameter_get_name(p);   
02648         const char *description   = cpl_parameter_get_help(p);
02649         const char *subcontext    = cpl_parameter_get_context(p);
02650         const char *alias         = cpl_parameter_get_alias(p, 
02651                                                             CPL_PARAMETER_MODE_CLI);
02652         cpl_parameter_class class = cpl_parameter_get_class(p);
02653         cpl_type type             = cpl_parameter_get_type(p);
02654 
02655         /* Check that S <= name
02656          * and S <= c and c <= name,
02657          * where S is either subrecipe id or 'uves', c is the context,
02658          * and "<=" means "is substring of"
02659          */
02660 
02661         {
02662         const char *S;
02663 
02664         if (strstr(name, "uves.") == name)
02665             {
02666             S = "uves";
02667             }
02668         else
02669             {
02670             S = substep_id;
02671 
02672             /* Check S <= name */
02673             if (strstr(name, S) != name)
02674                 {
02675                 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
02676                      "Recipe id '%s' is not prefix of parameter name '%s'",
02677                      S, name);
02678                 }
02679             }
02680         
02681         /* Check S <= c */
02682         if (strstr(subcontext, S) != subcontext)
02683             {
02684             FAIL(-1, CPL_ERROR_ILLEGAL_INPUT, 
02685                  "Recipe id '%s' is not prefix of parameter context '%s'", 
02686                  S, subcontext);
02687             }
02688         
02689         /* Check c <= name */
02690         if (strstr(name, subcontext) != name)
02691             {
02692             FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
02693                  "Parameter context '%s' is not prefix of parameter name '%s'", 
02694                  subcontext, name);
02695             }
02696         }/* End check parameter format */
02697         
02698         if (strcmp(subcontext, "uves") != 0)
02699         {
02700             int enum_size;
02701             
02702             cpl_parameter *new_par  = NULL;
02703             char *new_name;
02704             char *new_context;
02705             char *new_alias;
02706             
02707             if (context == NULL)
02708             {
02709                 new_name     = uves_sprintf("%s.%s", parent_id, name);     /* R.S.x */
02710                 new_context  = uves_sprintf("%s", parent_id);              /* R     */
02711                 if (alias != NULL)
02712                 {
02713                     new_alias = uves_sprintf("%s.%s", substep_id, alias); /* S.A */
02714                 }
02715                 else
02716                 {
02717                     new_alias = NULL;
02718                 }
02719             }
02720             else
02721             {
02722                 new_name     = uves_sprintf("%s.%s.%s", parent_id, context, name);  
02723                 /* R.c.Sx */
02724                 new_context  = uves_sprintf("%s.%s", parent_id, context); 
02725                 /* R.c    */
02726                 if (alias != NULL)
02727                 {
02728                     new_alias = uves_sprintf("%s.%s.%s", 
02729                                  context, substep_id, alias); 
02730                     /* c.S.A */
02731                 }
02732                 else
02733                 {
02734                     new_alias = NULL;
02735                 }
02736             }
02737             
02738             if (new_name == NULL || new_context == NULL)
02739             {
02740                 if (new_name    != NULL) cpl_free(new_name);
02741                 if (new_context != NULL) cpl_free(new_context);
02742                 if (new_alias   != NULL) cpl_free(new_alias);
02743                 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT, "Memory allocation failed");
02744             }
02745             
02746             
02747             /* Check for legal class/type before switch */
02748             if (class != CPL_PARAMETER_CLASS_VALUE &&
02749             class != CPL_PARAMETER_CLASS_RANGE &&
02750             class != CPL_PARAMETER_CLASS_ENUM)
02751             {
02752                 cpl_free(new_name);
02753                 cpl_free(new_context);
02754                 if (new_alias != NULL) cpl_free(new_alias);
02755                 FAIL(-1, CPL_ERROR_TYPE_MISMATCH,
02756                  "Unrecognized class of parameter '%s'", name);
02757             }
02758             
02759             if (type != CPL_TYPE_BOOL   &&
02760             type != CPL_TYPE_INT    &&
02761             type != CPL_TYPE_DOUBLE &&
02762             type != CPL_TYPE_STRING)
02763             {
02764                 cpl_free(new_name);
02765                 cpl_free(new_context);
02766                 if (new_alias != NULL) cpl_free(new_alias);
02767                 FAIL(-1, CPL_ERROR_UNSUPPORTED_MODE, "Unsupported type: %s",
02768                  uves_tostring_cpl_type(type));
02769             }
02770             
02771             /* Create a new parameter from the sub-parameter */
02772             switch (class)
02773             {
02774             case CPL_PARAMETER_CLASS_VALUE:
02775                 switch (type)
02776                 {
02777                 case CPL_TYPE_BOOL:
02778                     uves_parameter_new_value(new_par, new_name,
02779                                  type,
02780                                  description,
02781                                  new_context,
02782                                  cpl_parameter_get_default_bool(p));
02783                     break;
02784                     
02785                 case CPL_TYPE_INT:
02786                     uves_parameter_new_value(new_par, new_name,
02787                                  type,
02788                                  description,
02789                                  new_context,
02790                                  cpl_parameter_get_default_int(p));
02791                     break;
02792                     
02793                 case CPL_TYPE_DOUBLE:
02794                     uves_parameter_new_value(new_par, new_name,
02795                                  type,
02796                                  description,
02797                                  new_context,
02798                                  cpl_parameter_get_default_double(p));
02799                     break;
02800                 case CPL_TYPE_STRING:
02801                     uves_parameter_new_value(new_par, new_name,
02802                                  type,
02803                                  description,
02804                                  new_context,
02805                                  cpl_parameter_get_default_string(p));
02806                     break;
02807                 default:
02808                     break; 
02809                 }       /* switch type */
02810                 
02811                 break;   /* CLASS_VALUE */
02812                 
02813             case CPL_PARAMETER_CLASS_RANGE:
02814                 /* Range is either int or double */
02815                 switch (type)
02816                 {
02817                     int min_int, max_int;
02818                     double min_double, max_double;
02819                     
02820                 case CPL_TYPE_INT:
02821                     min_int = cpl_parameter_get_range_min_int(p);
02822                     max_int = cpl_parameter_get_range_max_int(p);
02823                     
02824                     uves_parameter_new_range(new_par, new_name,
02825                                  type,
02826                                  description,
02827                                  new_context,
02828                                  cpl_parameter_get_default_int(p),
02829                                  min_int, max_int);
02830                     break;
02831                     
02832                 case CPL_TYPE_DOUBLE:
02833                     min_double = cpl_parameter_get_range_min_double(p);
02834                     max_double = cpl_parameter_get_range_max_double(p);
02835                     
02836                     uves_parameter_new_range(new_par, new_name,
02837                                  type,
02838                                  description,
02839                                  new_context,
02840                                  cpl_parameter_get_default_double(p),
02841                                  min_double, max_double);
02842                     break;
02843                 default:
02844                     break;
02845                 }
02846         
02847                 break;   /* CLASS_RANGE */
02848         
02849             case CPL_PARAMETER_CLASS_ENUM:
02850                 enum_size = cpl_parameter_get_enum_size(p);
02851             
02852                 /* Enum type is either int, double or string */
02853                 switch (type)
02854                 {
02855                     int        *values_int;        /* Arrays to hold enum values */
02856                     double     *values_double;
02857                     const char **values_string;
02858                     int i;
02859                     
02860                 case CPL_TYPE_INT:
02861                     if ( (values_int = cpl_malloc(sizeof(int) * enum_size))
02862                      == NULL)
02863                     {
02864                         cpl_free(new_name);
02865                         cpl_free(new_context);
02866                         if (new_alias != NULL) cpl_free(new_alias);
02867                         FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT, 
02868                          "Memory allocation failed");
02869                     }
02870                     for (i = 0; i < enum_size; i++)
02871                     {
02872                         values_int[i] = cpl_parameter_get_enum_int(p, i);
02873                     }
02874                 
02875                     new_par = create_parameter_enum_int(
02876                     new_name,
02877                     type,
02878                     description,
02879                     new_context,
02880                     cpl_parameter_get_default_int(p),
02881                     enum_size,
02882                     values_int);
02883                     cpl_free(values_int);
02884                     break;  /* Enum type int */
02885                     
02886                 case CPL_TYPE_DOUBLE:
02887                     if ( (values_double = 
02888                       cpl_malloc(sizeof(double) * enum_size)) == NULL)
02889                     {
02890                         cpl_free(new_name);
02891                         cpl_free(new_context);
02892                         if (new_alias != NULL) cpl_free(new_alias);
02893                         FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
02894                          "Memory allocation failed");
02895                     }
02896                     for (i = 0; i < enum_size; i++)
02897                     {
02898                         values_double[i] = cpl_parameter_get_enum_double(p, i);
02899                     }
02900                 
02901                     new_par = create_parameter_enum_double(
02902                     new_name,
02903                     type,
02904                     description,
02905                     new_context,
02906                     cpl_parameter_get_default_double(p),
02907                     enum_size,
02908                     values_double);
02909                     cpl_free(values_double);
02910 
02911                     break;  /* Enum type double */
02912             
02913                 case CPL_TYPE_STRING:
02914                     if ( (values_string = 
02915                       cpl_malloc(sizeof(char *) * enum_size)) == NULL)
02916                     {
02917                         cpl_free(new_name);
02918                         cpl_free(new_context);
02919                         if (new_alias != NULL) cpl_free(new_alias);
02920                         FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT, 
02921                          "Memory allocation failed");
02922                     }
02923                     for (i = 0; i < enum_size; i++)
02924                     {
02925                         values_string[i] = cpl_parameter_get_enum_string(p, i);
02926                     }
02927                 
02928                     new_par = create_parameter_enum_string(
02929                     new_name,
02930                     type,
02931                     description,
02932                     new_context,
02933                     cpl_parameter_get_default_string(p),
02934                     enum_size,
02935                     values_string);
02936                     cpl_free(values_string);
02937                     
02938                     break;  /* Enum type string */
02939                 
02940                 default:
02941                     break;
02942                 
02943                 } /* Switch enum type */
02944             
02945                 break;   /* CLASS_ENUM */
02946 
02947             default:
02948                 break;
02949             
02950             } /* Switch class */
02951 
02952             if (new_par == NULL)
02953             {
02954                 cpl_free(new_name);
02955                 cpl_free(new_context);
02956                 if (new_alias != NULL) cpl_free(new_alias);
02957                 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
02958                  "Propagation of parameter '%s' failed", 
02959                  name);
02960             }
02961         
02962             /* Also propagate alias */
02963             if (alias != NULL)
02964             {
02965                 cpl_parameter_set_alias(new_par, CPL_PARAMETER_MODE_CLI, new_alias);
02966             }
02967 
02968             /* Insert parameter in parent parameter list */
02969             cpl_parameterlist_append(parent_parameters, new_par);
02970             
02971             cpl_free(new_name);
02972             cpl_free(new_context);
02973             if (new_alias != NULL) cpl_free(new_alias);
02974             
02975         }  /* If parameter context was not 'uves' */
02976         
02977     } /* For each sub-recipe parameter */
02978     
02979     return (cpl_error_get_code() != CPL_ERROR_NONE);
02980 }
02981 
02982 

Generated on 8 Mar 2011 for UVES Pipeline Reference Manual by  doxygen 1.6.1