00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 #ifdef HAVE_CONFIG_H
00186 # include <config.h>
00187 #endif
00188
00189
00197
00198
00199
00200
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
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
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
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
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
00551
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,
00568 -1, INT_MAX);
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
00599 cpl_parameter *p = NULL;
00600
00601
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
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
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",
00995
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
01006
01007
01008 if (cpl_error_get_code() == CPL_ERROR_NONE)
01009 {
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029 }
01030
01031
01032
01033
01034
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
01135 const char *name = NULL;
01136 char *full_name = NULL;
01137 cpl_parameter *p;
01138
01139
01140
01141
01142
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",
01156 3,
01157 "median", "minimum", "no");
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
01276
01277
01278
01279
01280
01281
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, ¶m) != 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
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
01438
01439
01440
01441
01442
01443
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, ¶m) != CPL_ERROR_NONE)
01514 {
01515 return -1;
01516 }
01517
01518
01519
01520
01521
01522
01523
01524
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
01557
01558
01559 {
01560
01561 const char *subcontext = "efficiency";
01562 const char* name="paccuracy";
01563 char *context=uves_sprintf("%s.%s",make_str(UVES_RESPONSE_ID),subcontext);
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
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;
01647
01648
01649
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
01655
01656
01657 check( list = cpl_pluginlist_new(),
01658 "Error allocating plugin list");
01659
01660
01661 status = get_info(list);
01662
01663 assure( status == 0, CPL_ERROR_ILLEGAL_INPUT,
01664 "Could not get info about recipe");
01665
01666
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
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
01684
01685
01686
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
01715 check( parent = cpl_parameterlist_find_const(parameters, parent_name),
01716 "Could not get parameter '%s' from provided parameter list", parent_name);
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
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 }
01785
01786 cpl_free(parent_name); parent_name = NULL;
01787
01788 }
01789
01790
01791 recipe->frames = frames;
01792
01793
01794
01795
01796
01797
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
01810
01811 uves_msg_set_domain(domain);
01812
01813
01814
01815
01816 uves_msg_add_warnings(warnings_in_caller);
01817 }
01818
01819
01820
01821
01822
01823
01824 if (cpl_error_get_code() != CPL_ERROR_NONE)
01825 {
01826
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
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
01930 if (get_info == NULL)
01931 {
01932 FAIL(-1, CPL_ERROR_NULL_INPUT, "Null function pointer");
01933 }
01934
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
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
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
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;
02089
02090
02091
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
02107
02108
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
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
02142
02143
02144
02145
02146
02147
02148
02149
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
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 }
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
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 }
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
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 }
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
02639
02640
02641
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
02656
02657
02658
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
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
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
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 }
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);
02710 new_context = uves_sprintf("%s", parent_id);
02711 if (alias != NULL)
02712 {
02713 new_alias = uves_sprintf("%s.%s", substep_id, alias);
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
02724 new_context = uves_sprintf("%s.%s", parent_id, context);
02725
02726 if (alias != NULL)
02727 {
02728 new_alias = uves_sprintf("%s.%s.%s",
02729 context, substep_id, alias);
02730
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
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
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 }
02810
02811 break;
02812
02813 case CPL_PARAMETER_CLASS_RANGE:
02814
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;
02848
02849 case CPL_PARAMETER_CLASS_ENUM:
02850 enum_size = cpl_parameter_get_enum_size(p);
02851
02852
02853 switch (type)
02854 {
02855 int *values_int;
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;
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;
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;
02939
02940 default:
02941 break;
02942
02943 }
02944
02945 break;
02946
02947 default:
02948 break;
02949
02950 }
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
02963 if (alias != NULL)
02964 {
02965 cpl_parameter_set_alias(new_par, CPL_PARAMETER_MODE_CLI, new_alias);
02966 }
02967
02968
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 }
02976
02977 }
02978
02979 return (cpl_error_get_code() != CPL_ERROR_NONE);
02980 }
02981
02982