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: 2007/10/29 08:11:31 $
00023  * $Revision: 1.44 $
00024  * $Name: uves-3_4_5 $
00025  * $Log: uves_parameters.c,v $
00026  * Revision 1.44  2007/10/29 08:11:31  amodigli
00027  * cleaned output
00028  *
00029  * Revision 1.43  2007/10/05 08:27:34  amodigli
00030  * added process_chip parameter
00031  *
00032  * Revision 1.42  2007/08/22 11:17:58  amodigli
00033  * fixed typo
00034  *
00035  * Revision 1.41  2007/08/21 13:08:26  jmlarsen
00036  * Removed irplib_access module, largely deprecated by CPL-4
00037  *
00038  * Revision 1.40  2007/08/17 10:08:12  amodigli
00039  * added case UVES_QCDARK_ID
00040  *
00041  * Revision 1.39  2007/06/26 13:34:55  jmlarsen
00042  * Exported function for FLAMES
00043  *
00044  * Revision 1.38  2007/06/14 11:12:00  jmlarsen
00045  * Expanded description of plotter parameter
00046  *
00047  * Revision 1.37  2007/06/06 08:17:33  amodigli
00048  * replace tab with 4 spaces
00049  *
00050  * Revision 1.36  2007/05/22 11:37:49  jmlarsen
00051  * Removed image plotting functionality
00052  *
00053  * Revision 1.35  2007/03/05 10:17:30  jmlarsen
00054  * Disabled strange msginfolevel parameter
00055  *
00056  * Revision 1.34  2007/02/09 13:39:31  jmlarsen
00057  * Use defines for recipe id
00058  *
00059  * Revision 1.33  2007/02/09 08:58:18  jmlarsen
00060  * Use define's rather than hard-coded recipe names
00061  *
00062  * Revision 1.32  2007/01/15 08:46:45  jmlarsen
00063  * Shortened lines
00064  *
00065  * Revision 1.31  2006/11/15 15:02:14  jmlarsen
00066  * Implemented const safe workarounds for CPL functions
00067  *
00068  * Revision 1.29  2006/11/15 14:04:08  jmlarsen
00069  * Removed non-const version of parameterlist_get_first/last/next which is
00070  * already in CPL, added const-safe wrapper, unwrapper and deallocator functions
00071  *
00072  * Revision 1.28  2006/11/13 14:23:55  jmlarsen
00073  * Removed workarounds for CPL const bugs
00074  *
00075  * Revision 1.27  2006/11/06 15:19:41  jmlarsen
00076  * Removed unused include directives
00077  *
00078  * Revision 1.26  2006/09/27 15:08:45  jmlarsen
00079  * Fixed doc. bug
00080  *
00081  * Revision 1.25  2006/09/20 12:53:57  jmlarsen
00082  * Replaced stringcat functions with uves_sprintf()
00083  *
00084  * Revision 1.24  2006/09/01 13:57:42  jmlarsen
00085  * Fixed bug that causing parameter class to change during propagation
00086  *
00087  * Revision 1.23  2006/08/18 07:07:43  jmlarsen
00088  * Switched order of cpl_calloc arguments
00089  *
00090  * Revision 1.22  2006/08/17 13:56:53  jmlarsen
00091  * Reduced max line length
00092  *
00093  * Revision 1.21  2006/08/14 15:21:08  jmlarsen
00094  * Update to CPL3
00095  *
00096  * Revision 1.20  2006/08/11 11:29:26  jmlarsen
00097  * Added explicit void at function definition
00098  *
00099  * Revision 1.19  2006/08/07 11:35:35  jmlarsen
00100  * Disabled parameter environment variable mode
00101  *
00102  * Revision 1.18  2006/07/03 13:17:12  jmlarsen
00103  * Changed order of global parameters
00104  *
00105  * Revision 1.17  2006/06/06 08:40:10  jmlarsen
00106  * Shortened max line length
00107  *
00108  * Revision 1.16  2006/06/01 14:43:17  jmlarsen
00109  * Added missing documentation
00110  *
00111  * Revision 1.15  2005/12/19 16:17:56  jmlarsen
00112  * Replaced bool -> int
00113  *
00114  */
00115 
00116 #ifdef HAVE_CONFIG_H
00117 #  include <config.h>
00118 #endif
00119 
00120 /*----------------------------------------------------------------------------*/
00128 /*----------------------------------------------------------------------------*/
00129 
00130 /*-----------------------------------------------------------------------------
00131                                 Includes
00132  -----------------------------------------------------------------------------*/
00133 
00134 #include <uves_parameters.h>
00135 #include <uves_dump.h>
00136 #include <uves_backsub.h>
00137 #include <uves_extract.h>
00138 #include <uves_rebin.h>
00139 #include <uves_mdark_impl.h>
00140 #include <uves_reduce.h>
00141 #include <uves_utils_wrappers.h>
00142 #include <uves.h>
00143 #include <uves_error.h>
00144 #include <uves_msg.h>
00145 
00146 #include <cpl.h>
00147 
00148 /*-----------------------------------------------------------------------------
00149                             Functions prototypes
00150  -----------------------------------------------------------------------------*/
00151 static int propagate(const char *substep_id, const cpl_parameterlist *sub_parameters, 
00152              cpl_parameterlist *parent_parameters,
00153              const char *parent_id, const char *context);
00154 static cpl_parameter *
00155 create_parameter_enum_int   (const char *name, cpl_type type,
00156                  const char *description, const char *context, 
00157                  int default_value, int size, int *values);
00158 static cpl_parameter *
00159 create_parameter_enum_double(const char *name, cpl_type type, const char *description,
00160                  const char *context, double default_value, 
00161                  int size, double *values);
00162 static cpl_parameter *
00163 create_parameter_enum_string(const char *name, cpl_type type, const char *description,
00164                  const char *context, const char *default_value, 
00165                  int size, const char **values);
00166 /*-----------------------------------------------------------------------------
00167                             Defines
00168  -----------------------------------------------------------------------------*/
00169 #define FAIL(return_code, error_code, ...) do {       \
00170         cpl_msg_error(__func__, __VA_ARGS__);         \
00171         if (cpl_error_get_code() == CPL_ERROR_NONE) { \
00172           cpl_error_set(__func__, error_code);        \
00173         }                                             \
00174         return return_code;                           \
00175         } while(false)
00176 
00179 /*-----------------------------------------------------------------------------
00180                             Implementation
00181  -----------------------------------------------------------------------------*/
00182 /*----------------------------------------------------------------------------*/
00191 /*----------------------------------------------------------------------------*/
00192 cpl_error_code
00193 uves_define_global_parameters(cpl_parameterlist *parlist)
00194 {
00195     const char *context = "uves";
00196     const char *name = "";
00197     char *full_name = NULL;
00198     cpl_parameter *p;
00199 
00200     {
00201     name = "debug";
00202     full_name = uves_sprintf("%s.%s", context, name);
00203     uves_parameter_new_value(p, full_name,
00204                     CPL_TYPE_BOOL,
00205                     "Whether or not to save intermediate "
00206                     "results to local directory",
00207                     context,
00208                     false);
00209     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00210     cpl_parameterlist_append(parlist, p);
00211     cpl_free(full_name);
00212     }
00213 
00214 
00215     {
00216         name = "plotter";
00217         full_name = uves_sprintf("%s.%s", context, name);
00218         uves_parameter_new_value(
00219             p, full_name,
00220             CPL_TYPE_STRING,
00221             "Any plots produced by the recipe "
00222             "are redirected to the command specified "
00223             "by this parameter. The plotting command "
00224             "must contain the substring 'gnuplot' and "
00225             "must be able to parse gnuplot syntax on its "
00226             "standard input. "
00227             "Valid examples of such a command may include "
00228             "'gnuplot -persist' and 'cat > mygnuplot$$.gp'. "
00229             "A finer control of the plotting options can "
00230             "be obtained by writing an "
00231             "executable script, e.g. my_gnuplot.pl, that "
00232             "executes gnuplot after setting the desired gnuplot "
00233             "options (e.g. set terminal pslatex color). "
00234             "To turn off plotting, set this parameter to 'no'",
00235             context,
00236             "no");
00237 
00238         cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00239         cpl_parameterlist_append(parlist, p);
00240         cpl_free(full_name);
00241     }
00242 
00243 
00244 
00245    {
00246     name = "process_chip";
00247     full_name = uves_sprintf("%s.%s", context, name);
00248     uves_parameter_new_enum(p, full_name,
00249                     CPL_TYPE_STRING,
00250                     "In case of RED arm data allow to proces the "
00251                  "redl, redu, or both chip(s)",
00252                     context,
00253                     "both",3,"both","redl","redu");
00254     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00255     cpl_parameterlist_append(parlist, p);
00256     cpl_free(full_name);
00257     }
00258 
00259     if (0)
00260         /* The meaning of this parameter often escapes the developers,
00261            so let's not expose it to the users */
00262         {
00263         name = "msginfolevel";
00264     full_name = uves_sprintf("%s.%s", context, name);
00265     uves_parameter_new_range(p, full_name,
00266                     CPL_TYPE_INT,
00267                     "This parameter controls the subdivision "
00268                     "of the 'info' message level (set e.g. with "
00269                     "esorex' --msg-level). The higher the value "
00270                     "of this parameter, the more messages are "
00271                     "printed at the info level. For minimum "
00272                     "output, set to zero. Increase the level "
00273                     "(to 1, 2, 3, ...) for more output. The "
00274                     "value -1 is a special value meaning maximum "
00275                     "output",
00276                     context,
00277                     -1,                 /* Default */
00278                     -1, INT_MAX);       /* Range   */
00279     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00280     cpl_parameterlist_append(parlist, p);
00281     cpl_free(full_name);
00282     }
00283 
00284     if (cpl_error_get_code() != CPL_ERROR_NONE)
00285     {
00286         cpl_msg_error(__func__, "Creation of global parameters failed: '%s'",
00287               cpl_error_get_where());
00288     }
00289     
00290     return cpl_error_get_code();
00291 }
00292 
00293 
00294 
00295 /*----------------------------------------------------------------------------*/
00310 /*----------------------------------------------------------------------------*/
00311 
00312 int
00313 uves_exec_recipe(int (*get_info)(cpl_pluginlist *), 
00314                  const char *recipe_domain,
00315                  const cpl_parameterlist *parameters, 
00316                  cpl_frameset *frames,
00317                  const char *caller_id, const char *context)
00318 {
00319     cpl_pluginlist *list  = NULL;
00320     cpl_plugin *plugin    = NULL;
00321     cpl_recipe *recipe    = NULL;
00322 
00323     const char *recipe_id = NULL;
00324     cpl_parameter *p      = NULL;
00325     char *parent_name     = NULL;
00326     char *sub_domain      = NULL;
00327     int status = 0;
00328 
00329     bool must_destroy_plugin = false;   /* Indicates if recipe_create() 
00330                        has been called */
00331 
00332     /* Check input */
00333     assure(recipe_domain != NULL, CPL_ERROR_NULL_INPUT, "Null recipe message domain");
00334     assure(parameters != NULL, CPL_ERROR_NULL_INPUT, "Null parameter list");
00335     assure(frames != NULL, CPL_ERROR_NULL_INPUT, "Null frame set");
00336     assure(caller_id != NULL, CPL_ERROR_NULL_INPUT, "Null caller recipe name");
00337     /* 'context' may be NULL */    
00338 
00339     /* Get the sub-recipe plugin */
00340     check( list = cpl_pluginlist_new(),
00341        "Error allocating plugin list");
00342 
00343     /* Get info about recipe */
00344     status = get_info(list);
00345 
00346     assure( status == 0, CPL_ERROR_ILLEGAL_INPUT, 
00347         "Could not get info about recipe");
00348 
00349     /* Get default parameter list */
00350     check( plugin = cpl_pluginlist_get_first(list), "Error getting plugin");
00351     assure( plugin != NULL, CPL_ERROR_ILLEGAL_INPUT,
00352             "Plugin '%s' returned empty plugin list", recipe_id);
00353     assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE, 
00354             CPL_ERROR_TYPE_MISMATCH, "Plugin is not a recipe");
00355     recipe = (cpl_recipe *) plugin;
00356     
00357     recipe_id = cpl_strdup(cpl_plugin_get_name(plugin));
00358 
00359     /* Call initializer function */
00360     must_destroy_plugin = true;
00361     assure( cpl_plugin_get_init(plugin)(plugin) == 0, CPL_ERROR_ILLEGAL_INPUT,
00362         "Error initializing recipe");
00363     assure( recipe->parameters != NULL, CPL_ERROR_ILLEGAL_INPUT,
00364         "Recipe '%s' returned NULL parameter list", recipe_id);
00365 
00366     /* For each recipe parameter x:
00367        Set to value of C.x (from argument parameter list)
00368 
00369        Parameters in 'uves' context are simply overwritten
00370     */
00371     for (p = cpl_parameterlist_get_first(recipe->parameters); 
00372      p != NULL;
00373      p = cpl_parameterlist_get_next(recipe->parameters) )
00374     {
00375         const char *name          = cpl_parameter_get_name(p);   
00376         const char *subcontext    = cpl_parameter_get_context(p);
00377         cpl_type type             = cpl_parameter_get_type(p);
00378         
00379         const cpl_parameter *parent;
00380         
00381         if (strcmp(subcontext, "uves") == 0)
00382         {
00383             parent_name = uves_sprintf("%s", name);
00384         }
00385         else
00386         {
00387             if (context != NULL)
00388             {
00389                 parent_name = uves_sprintf("%s.%s.%s", caller_id, context, name);
00390             }
00391             else
00392             {
00393                 parent_name = uves_sprintf("%s.%s", caller_id, name);
00394             }
00395         }
00396         
00397         /* Const cast, we don't change the parameter list, parent is declared const */
00398         check( parent = cpl_parameterlist_find_const(parameters, parent_name),
00399            "Could not get parameter '%s' from provided parameter list", parent_name);
00400         
00401         assure( parent != NULL, CPL_ERROR_DATA_NOT_FOUND,
00402             "Missing parameter '%s' needed to define '%s' in context '%s'",
00403             parent_name, name, context);
00404         
00405         assure( cpl_parameter_get_type(parent) == type, CPL_ERROR_TYPE_MISMATCH,
00406             "Parameter '%s' type is %s. Type %s needed for recipe parameter '%s'",
00407             parent_name, 
00408             uves_tostring_cpl_type(cpl_parameter_get_type(parent)),
00409             uves_tostring_cpl_type(type),
00410             name);
00411             
00412         switch (type)
00413         {
00414             int value_int;  
00415             bool value_bool;
00416             double value_double;
00417             const char *value_string;
00418 
00419         case CPL_TYPE_BOOL:
00420             check( value_bool = cpl_parameter_get_bool(parent), 
00421                "Error reading parameter '%s'", parent_name);
00422         
00423             check( cpl_parameter_set_bool(p, value_bool),
00424                "Error setting parameter '%s'", name);
00425             
00426             uves_msg_debug("Setting parameter '%s' <- '%s' = %s",
00427                    name, parent_name, (value_bool) ? "true" : "false");
00428             break;
00429 
00430         case CPL_TYPE_INT:
00431             check( value_int = cpl_parameter_get_int(parent),
00432                "Error reading parameter '%s'", parent_name);
00433         
00434             check( cpl_parameter_set_int(p, value_int),
00435                "Error setting parameter '%s'", name);
00436             
00437             uves_msg_debug("Setting parameter '%s' <- '%s' = %d", 
00438                    name, parent_name, value_int);
00439             break;
00440             
00441         case CPL_TYPE_DOUBLE:
00442             check( value_double = cpl_parameter_get_double(parent),
00443                "Error reading parameter '%s'", parent_name);
00444         
00445             check( cpl_parameter_set_double(p, value_double),
00446                "Error setting parameter '%s'", name);
00447             
00448             uves_msg_debug("Setting parameter '%s' <- '%s' = %e", 
00449                    name, parent_name, value_double);
00450             break;
00451             
00452         case CPL_TYPE_STRING:
00453             check( value_string = cpl_parameter_get_string(parent),
00454                "Error reading parameter '%s'", parent_name);
00455             
00456             check( cpl_parameter_set_string(p, value_string), 
00457                "Error setting parameter '%s'", name);
00458             
00459             uves_msg_debug("Setting parameter '%s' <- '%s' = '%s'", 
00460                    name, parent_name, value_string);
00461             break;
00462             
00463         default:
00464             assure(false, CPL_ERROR_UNSUPPORTED_MODE,
00465                "Parameter '%s' has type %s",
00466                name, uves_tostring_cpl_type(type));
00467         }  /* switch type */
00468         
00469         cpl_free(parent_name); parent_name = NULL;
00470         
00471     } /* Set each recipe parameter */
00472 
00473     /* Pass frame set without touching */
00474     recipe->frames = frames;
00475 
00476     /* 
00477      * Invoke recipe 
00478      *
00479      *  Remember message domain of caller,
00480      *   and number of warnings in caller.
00481      */
00482 
00483     {
00484     const char *domain = uves_msg_get_domain();
00485     int warnings_in_caller = uves_msg_get_warnings();
00486 
00487     sub_domain = uves_sprintf("%s.%s", domain, recipe_domain);
00488     uves_msg_set_domain(sub_domain);
00489 
00490     status = cpl_plugin_get_exec(plugin)(plugin);
00491 
00492     /* Reset state (domain+warnings) */
00493 
00494     uves_msg_set_domain(domain);
00495 
00496     /* Total number of warnings in caller is not
00497      * (previous warnings) + (subrecipe warnings)
00498      */
00499     uves_msg_add_warnings(warnings_in_caller);
00500     }
00501     
00502     /* On recipe failure: The recipe is responsible 
00503      *  for printing any error messages.
00504      *  A failing recipe is an unrecoverable error.
00505      */
00506 
00507     if (cpl_error_get_code() != CPL_ERROR_NONE)
00508     {
00509         /* Reset error stack but keep error code */
00510         cpl_error_code ec = cpl_error_get_code();
00511         uves_error_reset();
00512         assure( false, ec, "Recipe '%s' failed", recipe_id);
00513     }
00514     
00515     assure( status == 0, CPL_ERROR_ILLEGAL_OUTPUT,
00516         "Recipe '%s' failed with exit status %d", recipe_id, status);
00517     
00518     /* Call recipe_destroy */
00519     must_destroy_plugin = false;
00520     assure( cpl_plugin_get_deinit(plugin)(plugin) == 0, 
00521         CPL_ERROR_ILLEGAL_OUTPUT,
00522         "Error cleaning up recipe");
00523     
00524     uves_msg("Recipe '%s' succeeded", recipe_id);
00525 
00526   cleanup:
00527     uves_free_string_const(&recipe_id);
00528     cpl_free(parent_name); parent_name = NULL;
00529     cpl_free(sub_domain); sub_domain = NULL;
00530     if (must_destroy_plugin)
00531     {
00532         cpl_plugin_get_deinit(plugin)(plugin);
00533     }
00534 
00535     cpl_pluginlist_delete(list);
00536     
00537     return (cpl_error_get_code() != CPL_ERROR_NONE);
00538 }
00539 
00540 /*----------------------------------------------------------------------------*/
00555 /*----------------------------------------------------------------------------*/
00556 
00557 int
00558 uves_invoke_recipe(const char *recipe_id, const cpl_parameterlist *parameters, 
00559                    cpl_frameset *frames,
00560                    const char *caller_id, const char *context)
00561 {
00562     assure(recipe_id != NULL, CPL_ERROR_NULL_INPUT, "Null recipe name");
00563 
00564     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);
00565     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);
00566     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);
00567     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);
00568     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);
00569     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);
00570     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);
00571     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);
00572     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);
00573     else
00574         {
00575             assure( false, CPL_ERROR_ILLEGAL_INPUT, "Unknown recipe: '%s'", recipe_id);
00576         }
00577   cleanup:
00578     return (cpl_error_get_code() != CPL_ERROR_NONE);
00579 }
00580 
00581 
00582 /*----------------------------------------------------------------------------*/
00600 /*----------------------------------------------------------------------------*/
00601 int
00602 uves_prop_par(int (*get_info)(cpl_pluginlist *),
00603     cpl_parameterlist *parameters,
00604     const char *recipe_id, const char *context)
00605 {
00606     cpl_plugin *plugin    = NULL;
00607     cpl_pluginlist *list  = NULL;
00608     cpl_recipe *subrecipe = NULL;
00609     const char *name      = NULL;
00610     int status;
00611 
00612     /* Check input */
00613     if (get_info == NULL)
00614     {
00615         FAIL(-1, CPL_ERROR_NULL_INPUT, "Null function pointer");
00616     }
00617     /* context may be NULL */
00618     if (parameters == NULL)
00619     {
00620         FAIL(-1, CPL_ERROR_NULL_INPUT, "Null parameter list");
00621     }
00622     
00623     if (recipe_id == NULL)
00624     {
00625         FAIL(-1, CPL_ERROR_NULL_INPUT, "Null recipe id");
00626     }    
00627 
00628     /* Get the sub-recipe plugin */
00629     list = cpl_pluginlist_new();
00630     status = get_info(list);
00631     
00632     if (status != 0)
00633     {
00634         cpl_pluginlist_delete(list);
00635         FAIL(-1, CPL_ERROR_ILLEGAL_INPUT, "Could not get info about recipe");
00636     }
00637 
00638     /* Get first plugin in plugin list, it must be of type recipe */
00639     if ((plugin = cpl_pluginlist_get_first(list)) == NULL)
00640     {
00641         cpl_pluginlist_delete(list);
00642         FAIL(-1, CPL_ERROR_ILLEGAL_INPUT, "Error getting plugin");
00643     }
00644     if (cpl_plugin_get_name(plugin) == NULL) {
00645         cpl_pluginlist_delete(list);
00646         FAIL(-1, CPL_ERROR_ILLEGAL_INPUT, "Plugin name is NULL");
00647     }
00648     name = cpl_strdup(cpl_plugin_get_name(plugin));
00649     
00650     if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE)
00651         {
00652             cpl_pluginlist_delete(list);
00653             FAIL(-1, CPL_ERROR_TYPE_MISMATCH, "Plugin is not a recipe");
00654         }
00655     subrecipe = (cpl_recipe *) plugin;
00656     
00657     /* Create parameter list by calling subrecipe initializer function */
00658     if( cpl_plugin_get_init(plugin)(plugin) != 0)
00659     {
00660         cpl_plugin_get_deinit(plugin)(plugin);
00661         cpl_pluginlist_delete(list);
00662         FAIL(-1, CPL_ERROR_ILLEGAL_INPUT, "Error getting '%s' parameter list",
00663              name);
00664     }
00665 
00666     if (subrecipe->parameters == NULL)
00667     {
00668         cpl_plugin_get_deinit(plugin)(plugin);
00669         cpl_pluginlist_delete(list);
00670         FAIL(-1, CPL_ERROR_NULL_INPUT, "Recipe '%s' returned NULL parameter list", 
00671              name);
00672     }
00673     
00674     if (propagate(cpl_plugin_get_name(plugin), subrecipe->parameters, parameters, recipe_id, context) != 0)
00675     {
00676         cpl_plugin_get_deinit(plugin)(plugin);
00677         cpl_pluginlist_delete(list);
00678         FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT, "Error propagating parameters from recipe '%s'", 
00679              name);
00680     }
00681     
00682     cpl_plugin_get_deinit(plugin)(plugin);
00683     cpl_pluginlist_delete(list);
00684     
00685     return 0;
00686 }
00687 
00688 /*----------------------------------------------------------------------------*/
00694 /*----------------------------------------------------------------------------*/
00695 int
00696 uves_propagate_parameters(const char *subrecipe,
00697                           cpl_parameterlist *parameters,
00698                           const char *recipe_id, const char *context)
00699 {
00700     if (subrecipe == NULL) {
00701         FAIL(-1, CPL_ERROR_NULL_INPUT, "Null subrecipe id");
00702     }
00703     
00704     if      (strcmp(subrecipe, make_str(UVES_PHYSMOD_ID) ) == 0) return uves_prop_par(&uves_physmod_get_info, parameters, recipe_id, context);
00705     else if (strcmp(subrecipe, make_str(UVES_ORDERPOS_ID)) == 0) return uves_prop_par(&uves_orderpos_get_info, parameters, recipe_id, context);
00706     else if (strcmp(subrecipe, make_str(UVES_MBIAS_ID)   ) == 0) return uves_prop_par(&uves_mbias_get_info, parameters, recipe_id, context);
00707     else if (strcmp(subrecipe, make_str(UVES_MDARK_ID)   ) == 0) return uves_prop_par(&uves_mdark_get_info, parameters, recipe_id, context);
00708     else if (strcmp(subrecipe, make_str(UVES_MFLAT_ID)   ) == 0) return uves_prop_par(&uves_mflat_get_info, parameters, recipe_id, context);
00709     else if (strcmp(subrecipe, make_str(UVES_WAVECAL_ID) ) == 0) return uves_prop_par(&uves_wavecal_get_info, parameters, recipe_id, context);
00710     else if (strcmp(subrecipe, make_str(UVES_RESPONSE_ID)) == 0) return uves_prop_par(&uves_response_get_info, parameters, recipe_id, context);
00711     else if (strcmp(subrecipe, make_str(UVES_SCIRED_ID)  ) == 0) return uves_prop_par(&uves_scired_get_info, parameters, recipe_id, context);
00712     else if (strcmp(subrecipe, make_str(UVES_REDCHAIN_ID)) == 0) return uves_prop_par(&uves_redchain_get_info, parameters, recipe_id, context);
00713     else {
00714         FAIL(-1, CPL_ERROR_DATA_NOT_FOUND, "Unknown recipe: '%s'", subrecipe);
00715     }
00716 }
00717 
00718 /*----------------------------------------------------------------------------*/
00763 /*----------------------------------------------------------------------------*/
00764 
00765 int
00766 uves_propagate_parameters_step(const char *step_id,
00767                    cpl_parameterlist *parameters,
00768                    const char *recipe_id, const char *context)
00769 {
00770     cpl_parameterlist *subparameters = NULL;
00771     cpl_parameterlist *(*get_parameters)(void) = NULL; /* Pointer to function 
00772                               returning parameter list */
00773     
00774     /* Check input */
00775     if (step_id == NULL)
00776     {
00777         FAIL(-1, CPL_ERROR_NULL_INPUT, "Null parameter list");
00778     }
00779     
00780     if (parameters == NULL)
00781     {
00782         FAIL(-1, CPL_ERROR_NULL_INPUT, "Null parameter list");
00783     }
00784     
00785     if (recipe_id == NULL)
00786     {
00787         FAIL(-1, CPL_ERROR_NULL_INPUT, "Null recipe id");
00788     }    
00789     /* context may be NULL */
00790     
00791     /* Define which function to call */
00792     if      (strcmp(step_id, UVES_BACKSUB_ID ) == 0) {
00793       get_parameters = uves_backsub_define_parameters;
00794     } else if      (strcmp(step_id, UVES_QCDARK_ID ) == 0) {
00795       get_parameters = uves_qcdark_define_parameters;
00796     } else if (strcmp(step_id, UVES_EXTRACT_ID ) == 0) {
00797       get_parameters = uves_extract_define_parameters;
00798     } else if (strcmp(step_id, UVES_REBIN_ID   ) == 0) {
00799       get_parameters = uves_rebin_define_parameters;
00800     } else if (strcmp(step_id, UVES_REDUCE_ID  ) == 0) {
00801       get_parameters = uves_reduce_define_parameters;
00802     } else {
00803       FAIL(-1, CPL_ERROR_DATA_NOT_FOUND, "Unknown sub-step: '%s'", step_id);
00804     }
00805 
00806     /* Get sub-step parameters */
00807     if( (subparameters = get_parameters()) == NULL )
00808     {
00809         FAIL(-1, CPL_ERROR_ILLEGAL_INPUT, "Error getting '%s' parameter list", step_id);
00810     }
00811     
00812     if ( propagate(step_id, subparameters, parameters, recipe_id, context) != 0)
00813     {
00814         cpl_parameterlist_delete(subparameters);
00815         FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT, "Error propagating '%s' parameters", step_id);
00816     }
00817     
00818     cpl_parameterlist_delete(subparameters);
00819     return 0;
00820 }
00821 
00822 
00823 /*
00824  * Create an enumeration parameter.
00825  * One function for each of  int, double, string
00826  *    size of values array must match 'size', returns NULL iff error. 
00827  *
00828  * It would be much nicer to use a cpl_parameter_duplicate(), but that
00829  * doesn't exist
00830  *
00831  * (These three functions could be reduced to one function by use
00832  * of void pointers, but that is also ugly)
00833  */
00834 static cpl_parameter *
00835 create_parameter_enum_int(const char *name, cpl_type type,
00836               const char *description, 
00837               const char *context, 
00838               int default_value, int size,
00839               int *values)
00840 {
00841     /*  This is just ugly */
00842 
00843     cpl_parameter *result = NULL;
00844     
00845     if (! (1 <= size && size <= 10))
00846     {
00847         cpl_msg_error(__func__, "Unsupported enumeration size: %d (max is 10)", size);
00848         return NULL;
00849     }
00850     
00851     switch(size)
00852     {
00853     case 1:
00854         uves_parameter_new_enum(result, name,
00855                        type,
00856                        description,
00857                        context,
00858                        default_value, size,
00859                        values[0]);
00860         break;
00861     case 2:
00862         uves_parameter_new_enum(result, name,
00863                           type,
00864                           description,
00865                           context,
00866                           default_value, size,
00867                           values[0],
00868                           values[1]);
00869         break;
00870     case 3:
00871         uves_parameter_new_enum(result, name,
00872                           type,
00873                           description,
00874                           context,
00875                           default_value, size,
00876                           values[0],
00877                           values[1],
00878                           values[2]);
00879         break;
00880     case 4:
00881         uves_parameter_new_enum(result, name,
00882                           type,
00883                           description,
00884                           context,
00885                           default_value, size,
00886                           values[0], 
00887                           values[1], 
00888                           values[2], 
00889                           values[3]);
00890         break;
00891     case 5:
00892         uves_parameter_new_enum(result, name,
00893                           type,
00894                           description,
00895                           context,
00896                           default_value, size,
00897                           values[0], 
00898                           values[1], 
00899                           values[2], 
00900                           values[3], 
00901                           values[4]);
00902         break;
00903     case 6:
00904         uves_parameter_new_enum(result, name,
00905                           type,
00906                           description,
00907                           context,
00908                           default_value, size,
00909                           values[0], 
00910                           values[1], 
00911                           values[2], 
00912                           values[3], 
00913                           values[4], 
00914                           values[5]);
00915         break;
00916     case 7:
00917         uves_parameter_new_enum(result, name,
00918                           type,
00919                           description,
00920                           context,
00921                           default_value, size,
00922                           values[0], 
00923                           values[1], 
00924                           values[2], 
00925                           values[3], 
00926                           values[4], 
00927                           values[5], 
00928                           values[6]);
00929         break;
00930     case 8:
00931         uves_parameter_new_enum(result, name,
00932                           type,
00933                           description,
00934                           context,
00935                           default_value, size,
00936                           values[0], 
00937                           values[1], 
00938                           values[2], 
00939                           values[3], 
00940                           values[4], 
00941                           values[5], 
00942                           values[6], 
00943                           values[7]);
00944         break;
00945     case 9:
00946         uves_parameter_new_enum(result, name,
00947                           type,
00948                           description,
00949                           context,
00950                           default_value, size,
00951                           values[0], 
00952                           values[1], 
00953                           values[2], 
00954                           values[3], 
00955                           values[4], 
00956                           values[5], 
00957                           values[6], 
00958                           values[7], 
00959                           values[8]);
00960         break;
00961     case 10:
00962         uves_parameter_new_enum(result, name,
00963                        type,
00964                        description,
00965                        context,
00966                        default_value, size,
00967                        values[0], 
00968                        values[1], 
00969                        values[2], 
00970                        values[3], 
00971                        values[4], 
00972                        values[5], 
00973                        values[6], 
00974                        values[7], 
00975                        values[8], 
00976                        values[9]);
00977         break;
00978     } /* Switch size */
00979     return result;
00980 }
00981 static cpl_parameter *
00982 create_parameter_enum_double(const char *name, cpl_type type,
00983                  const char *description, 
00984                  const char *context, double default_value,
00985                  int size, double *values)
00986 {
00987     /*  This is very ugly */
00988     
00989     cpl_parameter *result = NULL; 
00990 
00991     if (! (1 <= size && size <= 10))
00992     {
00993         cpl_msg_error(__func__, "Unsupported enumeration size: %d (max is 10)", size);
00994         return NULL;
00995     }
00996     
00997     switch(size)
00998     {
00999     case 1:
01000         uves_parameter_new_enum(result, name,
01001                        type,
01002                        description,
01003                        context,
01004                        default_value, size,
01005                        values[0]);
01006         break;
01007     case 2:
01008         uves_parameter_new_enum(result, name,
01009                           type,
01010                           description,
01011                           context,
01012                           default_value, size,
01013                           values[0],
01014                           values[1]);
01015         break;
01016     case 3:
01017         uves_parameter_new_enum(result, name,
01018                           type,
01019                           description,
01020                           context,
01021                           default_value, size,
01022                           values[0],
01023                           values[1],
01024                           values[2]);
01025         break;
01026     case 4:
01027         uves_parameter_new_enum(result, name,
01028                           type,
01029                           description,
01030                           context,
01031                           default_value, size,
01032                           values[0], 
01033                           values[1], 
01034                           values[2], 
01035                           values[3]);
01036         break;
01037     case 5:
01038         uves_parameter_new_enum(result, name,
01039                           type,
01040                           description,
01041                           context,
01042                           default_value, size,
01043                           values[0], 
01044                           values[1], 
01045                           values[2], 
01046                           values[3], 
01047                           values[4]);
01048         break;
01049     case 6:
01050         uves_parameter_new_enum(result, name,
01051                           type,
01052                           description,
01053                           context,
01054                           default_value, size,
01055                           values[0], 
01056                           values[1], 
01057                           values[2], 
01058                           values[3], 
01059                           values[4], 
01060                           values[5]);
01061         break;
01062     case 7:
01063         uves_parameter_new_enum(result, name,
01064                           type,
01065                           description,
01066                           context,
01067                           default_value, size,
01068                           values[0], 
01069                           values[1], 
01070                           values[2], 
01071                           values[3], 
01072                           values[4], 
01073                           values[5], 
01074                           values[6]);
01075         break;
01076     case 8:
01077         uves_parameter_new_enum(result, name,
01078                           type,
01079                           description,
01080                           context,
01081                           default_value, size,
01082                           values[0], 
01083                           values[1], 
01084                           values[2], 
01085                           values[3], 
01086                           values[4], 
01087                           values[5], 
01088                           values[6], 
01089                           values[7]);
01090         break;
01091     case 9:
01092         uves_parameter_new_enum(result, name,
01093                           type,
01094                           description,
01095                           context,
01096                           default_value, size,
01097                           values[0], 
01098                           values[1], 
01099                           values[2], 
01100                           values[3], 
01101                           values[4], 
01102                           values[5], 
01103                           values[6], 
01104                           values[7], 
01105                           values[8]);
01106         break;
01107     case 10:
01108         uves_parameter_new_enum(result, name,
01109                        type,
01110                        description,
01111                        context,
01112                        default_value, size,
01113                        values[0], 
01114                        values[1], 
01115                        values[2], 
01116                        values[3], 
01117                        values[4], 
01118                        values[5], 
01119                        values[6], 
01120                        values[7], 
01121                        values[8], 
01122                        values[9]);
01123         break;
01124     } /* Switch size */
01125     return result;
01126 }
01127 static cpl_parameter *
01128 create_parameter_enum_string(const char *name, cpl_type type,
01129                  const char *description, 
01130                  const char *context, 
01131                  const char *default_value, 
01132                  int size, const char **values)
01133 {
01134     /*  This is extremely ugly */
01135     
01136     cpl_parameter *result = NULL;
01137 
01138     if (! (1 <= size && size <= 10))
01139     {
01140         cpl_msg_error(__func__, "Unsupported enumeration size: %d (max is 10)", size);
01141         return NULL;
01142     }
01143     
01144     switch(size)
01145     {
01146     case 1:
01147         uves_parameter_new_enum(result, name,
01148                        type,
01149                        description,
01150                        context,
01151                        default_value, size,
01152                        values[0]);
01153         break;
01154     case 2:
01155         uves_parameter_new_enum(result, name,
01156                           type,
01157                           description,
01158                           context,
01159                           default_value, size,
01160                           values[0],
01161                           values[1]);
01162         break;
01163     case 3:
01164         uves_parameter_new_enum(result, name,
01165                           type,
01166                           description,
01167                           context,
01168                           default_value, size,
01169                           values[0],
01170                           values[1],
01171                           values[2]);
01172         break;
01173     case 4:
01174         uves_parameter_new_enum(result, name,
01175                           type,
01176                           description,
01177                           context,
01178                           default_value, size,
01179                           values[0], 
01180                           values[1], 
01181                           values[2], 
01182                           values[3]);
01183         break;
01184     case 5:
01185         uves_parameter_new_enum(result, name,
01186                           type,
01187                           description,
01188                           context,
01189                           default_value, size,
01190                           values[0], 
01191                           values[1], 
01192                           values[2], 
01193                           values[3], 
01194                           values[4]);
01195         break;
01196     case 6:
01197         uves_parameter_new_enum(result, name,
01198                           type,
01199                           description,
01200                           context,
01201                           default_value, size,
01202                           values[0], 
01203                           values[1], 
01204                           values[2], 
01205                           values[3], 
01206                           values[4], 
01207                           values[5]);
01208         break;
01209     case 7:
01210         uves_parameter_new_enum(result, name,
01211                           type,
01212                           description,
01213                           context,
01214                           default_value, size,
01215                           values[0], 
01216                           values[1], 
01217                           values[2], 
01218                           values[3], 
01219                           values[4], 
01220                           values[5], 
01221                           values[6]);
01222         break;
01223     case 8:
01224         uves_parameter_new_enum(result, name,
01225                           type,
01226                           description,
01227                           context,
01228                           default_value, size,
01229                           values[0], 
01230                           values[1], 
01231                           values[2], 
01232                           values[3], 
01233                           values[4], 
01234                           values[5], 
01235                           values[6], 
01236                           values[7]);
01237         break;
01238     case 9:
01239         uves_parameter_new_enum(result, name,
01240                           type,
01241                           description,
01242                           context,
01243                           default_value, size,
01244                           values[0], 
01245                           values[1], 
01246                           values[2], 
01247                           values[3], 
01248                           values[4], 
01249                           values[5], 
01250                           values[6], 
01251                           values[7], 
01252                           values[8]);
01253         break;
01254     case 10:
01255         uves_parameter_new_enum(result, name,
01256                        type,
01257                        description,
01258                        context,
01259                        default_value, size,
01260                        values[0], 
01261                        values[1], 
01262                        values[2], 
01263                        values[3], 
01264                        values[4], 
01265                        values[5], 
01266                        values[6], 
01267                        values[7], 
01268                        values[8], 
01269                        values[9]);
01270         break;
01271     } /* Switch size */
01272     return result;
01273 }
01274 
01275 
01276 /*----------------------------------------------------------------------------*/
01312 /*----------------------------------------------------------------------------*/
01313 
01314 static int
01315 propagate(const char *substep_id, const cpl_parameterlist *sub_parameters, 
01316       cpl_parameterlist *parent_parameters,
01317       const char *parent_id, const char *context)
01318 {
01319     const cpl_parameter *p = NULL;
01320     
01321     /* For each sub-recipe parameter:
01322        prefix with context and insert in parent parameter list
01323 
01324        Set (overwrite) default value as current value
01325     */
01326     for (p = cpl_parameterlist_get_first_const(sub_parameters);
01327          p != NULL;
01328          p = cpl_parameterlist_get_next_const(sub_parameters) )
01329     {
01330         const char *name          = cpl_parameter_get_name(p);   
01331         const char *description   = cpl_parameter_get_help(p);
01332         const char *subcontext    = cpl_parameter_get_context(p);
01333         const char *alias         = cpl_parameter_get_alias(p, 
01334                                                             CPL_PARAMETER_MODE_CLI);
01335         cpl_parameter_class class = cpl_parameter_get_class(p);
01336         cpl_type type             = cpl_parameter_get_type(p);
01337         
01338         /* Check that S <= name
01339          * and S <= c and c <= name,
01340          * where S is either subrecipe id or 'uves', c is the context,
01341          * and "<=" means "is substring of"
01342          */
01343 
01344         {
01345         const char *S;
01346                 
01347         if (strstr(name, "uves.") == name)
01348             {
01349             S = "uves";
01350             }
01351         else
01352             {
01353             S = substep_id;
01354 
01355             /* Check S <= name */
01356             if (strstr(name, S) != name)
01357                 {
01358                 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
01359                      "Recipe id '%s' is not prefix of parameter name '%s'",
01360                      S, name);
01361                 }
01362             }
01363         
01364         /* Check S <= c */
01365         if (strstr(subcontext, S) != subcontext)
01366             {
01367             FAIL(-1, CPL_ERROR_ILLEGAL_INPUT, 
01368                  "Recipe id '%s' is not prefix of parameter context '%s'", 
01369                  S, subcontext);
01370             }
01371         
01372         /* Check c <= name */
01373         if (strstr(name, subcontext) != name)
01374             {
01375             FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
01376                  "Parameter context '%s' is not prefix of parameter name '%s'", 
01377                  subcontext, name);
01378             }
01379         }/* End check parameter format */
01380         
01381         if (strcmp(subcontext, "uves") != 0)
01382         {
01383             int enum_size;
01384             
01385             cpl_parameter *new_par  = NULL;
01386             char *new_name;
01387             char *new_context;
01388             char *new_alias;
01389             
01390             if (context == NULL)
01391             {
01392                 new_name     = uves_sprintf("%s.%s", parent_id, name);     /* R.S.x */
01393                 new_context  = uves_sprintf("%s", parent_id);              /* R     */
01394                 if (alias != NULL)
01395                 {
01396                     new_alias = uves_sprintf("%s.%s", substep_id, alias); /* S.A */
01397                 }
01398                 else
01399                 {
01400                     new_alias = NULL;
01401                 }
01402             }
01403             else
01404             {
01405                 new_name     = uves_sprintf("%s.%s.%s", parent_id, context, name);  
01406                 /* R.c.Sx */
01407                 new_context  = uves_sprintf("%s.%s", parent_id, context); 
01408                 /* R.c    */
01409                 if (alias != NULL)
01410                 {
01411                     new_alias = uves_sprintf("%s.%s.%s", 
01412                                  context, substep_id, alias); 
01413                     /* c.S.A */
01414                 }
01415                 else
01416                 {
01417                     new_alias = NULL;
01418                 }
01419             }
01420             
01421             if (new_name == NULL || new_context == NULL)
01422             {
01423                 if (new_name    != NULL) cpl_free(new_name);
01424                 if (new_context != NULL) cpl_free(new_context);
01425                 if (new_alias   != NULL) cpl_free(new_alias);
01426                 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT, "Memory allocation failed");
01427             }
01428             
01429             
01430             /* Check for legal class/type before switch */
01431             if (class != CPL_PARAMETER_CLASS_VALUE &&
01432             class != CPL_PARAMETER_CLASS_RANGE &&
01433             class != CPL_PARAMETER_CLASS_ENUM)
01434             {
01435                 cpl_free(new_name);
01436                 cpl_free(new_context);
01437                 if (new_alias != NULL) cpl_free(new_alias);
01438                 FAIL(-1, CPL_ERROR_TYPE_MISMATCH,
01439                  "Unrecognized class of parameter '%s'", name);
01440             }
01441             
01442             if (type != CPL_TYPE_BOOL   &&
01443             type != CPL_TYPE_INT    &&
01444             type != CPL_TYPE_DOUBLE &&
01445             type != CPL_TYPE_STRING)
01446             {
01447                 cpl_free(new_name);
01448                 cpl_free(new_context);
01449                 if (new_alias != NULL) cpl_free(new_alias);
01450                 FAIL(-1, CPL_ERROR_UNSUPPORTED_MODE, "Unsupported type: %s",
01451                  uves_tostring_cpl_type(type));
01452             }
01453             
01454             /* Create a new parameter from the sub-parameter */
01455             switch (class)
01456             {
01457             case CPL_PARAMETER_CLASS_VALUE:
01458                 switch (type)
01459                 {
01460                 case CPL_TYPE_BOOL:
01461                     uves_parameter_new_value(new_par, new_name,
01462                                  type,
01463                                  description,
01464                                  new_context,
01465                                  cpl_parameter_get_default_bool(p));
01466                     break;
01467                     
01468                 case CPL_TYPE_INT:
01469                     uves_parameter_new_value(new_par, new_name,
01470                                  type,
01471                                  description,
01472                                  new_context,
01473                                  cpl_parameter_get_default_int(p));
01474                     break;
01475                     
01476                 case CPL_TYPE_DOUBLE:
01477                     uves_parameter_new_value(new_par, new_name,
01478                                  type,
01479                                  description,
01480                                  new_context,
01481                                  cpl_parameter_get_default_double(p));
01482                     break;
01483                 case CPL_TYPE_STRING:
01484                     uves_parameter_new_value(new_par, new_name,
01485                                  type,
01486                                  description,
01487                                  new_context,
01488                                  cpl_parameter_get_default_string(p));
01489                     break;
01490                 default:
01491                     break; 
01492                 }       /* switch type */
01493                 
01494                 break;   /* CLASS_VALUE */
01495                 
01496             case CPL_PARAMETER_CLASS_RANGE:
01497                 /* Range is either int or double */
01498                 switch (type)
01499                 {
01500                     int min_int, max_int;
01501                     double min_double, max_double;
01502                     
01503                 case CPL_TYPE_INT:
01504                     min_int = cpl_parameter_get_range_min_int(p);
01505                     max_int = cpl_parameter_get_range_max_int(p);
01506                     
01507                     uves_parameter_new_range(new_par, new_name,
01508                                  type,
01509                                  description,
01510                                  new_context,
01511                                  cpl_parameter_get_default_int(p),
01512                                  min_int, max_int);
01513                     break;
01514                     
01515                 case CPL_TYPE_DOUBLE:
01516                     min_double = cpl_parameter_get_range_min_double(p);
01517                     max_double = cpl_parameter_get_range_max_double(p);
01518                     
01519                     uves_parameter_new_range(new_par, new_name,
01520                                  type,
01521                                  description,
01522                                  new_context,
01523                                  cpl_parameter_get_default_double(p),
01524                                  min_double, max_double);
01525                     break;
01526                 default:
01527                     break;
01528                 }
01529         
01530                 break;   /* CLASS_RANGE */
01531         
01532             case CPL_PARAMETER_CLASS_ENUM:
01533                 enum_size = cpl_parameter_get_enum_size(p);
01534             
01535                 /* Enum type is either int, double or string */
01536                 switch (type)
01537                 {
01538                     int        *values_int;        /* Arrays to hold enum values */
01539                     double     *values_double;
01540                     const char **values_string;
01541                     int i;
01542                     
01543                 case CPL_TYPE_INT:
01544                     if ( (values_int = cpl_malloc(sizeof(int) * enum_size))
01545                      == NULL)
01546                     {
01547                         cpl_free(new_name);
01548                         cpl_free(new_context);
01549                         if (new_alias != NULL) cpl_free(new_alias);
01550                         FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT, 
01551                          "Memory allocation failed");
01552                     }
01553                     for (i = 0; i < enum_size; i++)
01554                     {
01555                         values_int[i] = cpl_parameter_get_enum_int(p, i);
01556                     }
01557                 
01558                     new_par = create_parameter_enum_int(
01559                     new_name,
01560                     type,
01561                     description,
01562                     new_context,
01563                     cpl_parameter_get_default_int(p),
01564                     enum_size,
01565                     values_int);
01566                     cpl_free(values_int);
01567                     break;  /* Enum type int */
01568                     
01569                 case CPL_TYPE_DOUBLE:
01570                     if ( (values_double = 
01571                       cpl_malloc(sizeof(double) * enum_size)) == NULL)
01572                     {
01573                         cpl_free(new_name);
01574                         cpl_free(new_context);
01575                         if (new_alias != NULL) cpl_free(new_alias);
01576                         FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
01577                          "Memory allocation failed");
01578                     }
01579                     for (i = 0; i < enum_size; i++)
01580                     {
01581                         values_double[i] = cpl_parameter_get_enum_double(p, i);
01582                     }
01583                 
01584                     new_par = create_parameter_enum_double(
01585                     new_name,
01586                     type,
01587                     description,
01588                     new_context,
01589                     cpl_parameter_get_default_double(p),
01590                     enum_size,
01591                     values_double);
01592                     cpl_free(values_double);
01593 
01594                     break;  /* Enum type double */
01595             
01596                 case CPL_TYPE_STRING:
01597                     if ( (values_string = 
01598                       cpl_malloc(sizeof(char *) * enum_size)) == NULL)
01599                     {
01600                         cpl_free(new_name);
01601                         cpl_free(new_context);
01602                         if (new_alias != NULL) cpl_free(new_alias);
01603                         FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT, 
01604                          "Memory allocation failed");
01605                     }
01606                     for (i = 0; i < enum_size; i++)
01607                     {
01608                         values_string[i] = cpl_parameter_get_enum_string(p, i);
01609                     }
01610                 
01611                     new_par = create_parameter_enum_string(
01612                     new_name,
01613                     type,
01614                     description,
01615                     new_context,
01616                     cpl_parameter_get_default_string(p),
01617                     enum_size,
01618                     values_string);
01619                     cpl_free(values_string);
01620                     
01621                     break;  /* Enum type string */
01622                 
01623                 default:
01624                     break;
01625                 
01626                 } /* Switch enum type */
01627             
01628                 break;   /* CLASS_ENUM */
01629 
01630             default:
01631                 break;
01632             
01633             } /* Switch class */
01634 
01635             if (new_par == NULL)
01636             {
01637                 cpl_free(new_name);
01638                 cpl_free(new_context);
01639                 if (new_alias != NULL) cpl_free(new_alias);
01640                 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
01641                  "Propagation of parameter '%s' failed", 
01642                  name);
01643             }
01644         
01645             /* Also propagate alias */
01646             if (alias != NULL)
01647             {
01648                 cpl_parameter_set_alias(new_par, CPL_PARAMETER_MODE_CLI, new_alias);
01649             }
01650 
01651             /* Insert parameter in parent parameter list */
01652             cpl_parameterlist_append(parent_parameters, new_par);
01653             
01654             cpl_free(new_name);
01655             cpl_free(new_context);
01656             if (new_alias != NULL) cpl_free(new_alias);
01657             
01658         }  /* If parameter context was not 'uves' */
01659         
01660     } /* For each sub-recipe parameter */
01661     
01662     return (cpl_error_get_code() != CPL_ERROR_NONE);
01663 }
01664 
01665 

Generated on Thu Nov 15 14:32:29 2007 for UVES Pipeline Reference Manual by  doxygen 1.5.1