47 #include <uves_parameters.h>
48 #include <uves_dump.h>
49 #include <uves_backsub.h>
50 #include <uves_extract.h>
51 #include <uves_rebin.h>
52 #include <uves_mdark_impl.h>
53 #include <uves_corrbadpix.h>
54 #include <uves_reduce.h>
55 #include <uves_utils_wrappers.h>
56 #include <uves_error.h>
64 static int propagate(
const char *substep_id,
const cpl_parameterlist *sub_parameters,
65 cpl_parameterlist *parent_parameters,
66 const char *parent_id,
const char *context);
67 static cpl_parameter *
68 create_parameter_enum_int (
const char *name, cpl_type type,
69 const char *description,
const char *context,
70 int default_value,
int size,
int *values);
71 static cpl_parameter *
72 create_parameter_enum_double(
const char *name, cpl_type type,
const char *description,
73 const char *context,
double default_value,
74 int size,
double *values);
75 static cpl_parameter *
76 create_parameter_enum_string(
const char *name, cpl_type type,
const char *description,
77 const char *context,
const char *default_value,
78 int size,
const char **values);
82 #define FAIL(return_code, error_code, ...) do { \
83 cpl_msg_error(__func__, __VA_ARGS__); \
84 if (cpl_error_get_code() == CPL_ERROR_NONE) { \
85 cpl_error_set(__func__, error_code); \
109 uves_corr_traps_define_parameters(cpl_parameterlist * parameters,
110 const char *recipe_id)
114 const char *name =
"";
120 name =
"clean_traps";
121 sprintf(full_name,
"%s.%s",recipe_id,name);
123 if((strcmp(recipe_id,
"uves_obs_scired") == 0) ||
124 (strcmp(recipe_id,
"uves_obs_spatred") == 0) ||
125 (strcmp(recipe_id,
"uves_cal_tflat") == 0) ) {
127 uves_parameter_new_value(p, full_name,
129 "Clean detector traps. "
130 "If TRUE detector traps are interpolated."
131 "The bad pixels are replaced by the average of the"
132 "nearest good pixels in the same column, or simply marked "
133 "as bad. The positions of bad pixels are hard-coded "
134 "(as function of UVES chip).",
139 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
140 cpl_parameterlist_append(parameters, p);
141 }
else if((strcmp(recipe_id,
"uves_cal_mbias") == 0) ||
142 (strcmp(recipe_id,
"uves_cal_mkmaster") == 0) ) {
144 uves_parameter_new_value(p, full_name,
146 "Clean detector traps. "
147 "If TRUE detector traps are interpolated."
148 "The bad pixels are replaced by the average of "
149 "nearest good pixels in the same column, or simply marked "
150 "as bad. The positions of bad pixels are hard-coded "
151 "(as function of UVES chip).",
156 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
157 cpl_parameterlist_append(parameters, p);
161 uves_msg(
"Creation of trap not supported for recipe: '%s'",
166 if (cpl_error_get_code() != CPL_ERROR_NONE)
169 cpl_msg_error(__func__,
170 "Creation of trap column parameters failed: '%s'",
171 cpl_error_get_where());
175 return cpl_error_get_code();
194 uves_master_stack_define_parameters(cpl_parameterlist *parlist,
const char *recipe_id)
197 const char *name =
"";
203 name =
"stack_method";
204 sprintf(full_name,
"%s.%s",recipe_id,name);
205 uves_parameter_new_enum(p, full_name,
207 "Method used to build master frame ",
209 "median",2,
"median",
"mean");
210 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
211 cpl_parameterlist_append(parlist, p);
217 sprintf(full_name,
"%s.%s",recipe_id,name);
218 uves_parameter_new_range(p, full_name,
220 "Kappa used to clip low level values, when method is set to 'mean' ",
223 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
224 cpl_parameterlist_append(parlist, p);
230 sprintf(full_name,
"%s.%s",recipe_id,name);
231 uves_parameter_new_range(p, full_name,
233 "Kappa used to clip high level values, when method is set to 'mean' ",
236 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
237 cpl_parameterlist_append(parlist, p);
245 sprintf(full_name,
"%s.%s",recipe_id,name);
247 uves_parameter_new_range(p, full_name,
249 "Number of kappa sigma iterations, when method is set to 'mean' ",
252 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
253 cpl_parameterlist_append(parlist, p);
257 if (cpl_error_get_code() != CPL_ERROR_NONE)
259 cpl_msg_error(__func__,
"Creation of kappa sigma parameters failed: '%s'",
260 cpl_error_get_where());
263 return cpl_error_get_code();
280 uves_master_flat_define_parameters(cpl_parameterlist *parlist,
const char *recipe_id)
283 const char *name =
"";
289 name =
"norm_method";
290 sprintf(full_name,
"%s.%s",recipe_id,name);
292 uves_parameter_new_enum(p, full_name,
294 "Method used to build master frame ",
296 (strstr(recipe_id,
"flames") !=NULL) ?
"exptime" :
"explevel",
297 2,
"exptime",
"explevel");
299 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
300 cpl_parameterlist_append(parlist, p);
304 if (cpl_error_get_code() != CPL_ERROR_NONE)
306 cpl_msg_error(__func__,
"Creation of master flat parameters failed: '%s'",
307 cpl_error_get_where());
310 return cpl_error_get_code();
326 uves_define_global_parameters(cpl_parameterlist *parlist)
328 const char *context =
"uves";
329 const char *name =
"";
330 char *full_name = NULL;
335 full_name = uves_sprintf(
"%s.%s", context, name);
336 uves_parameter_new_value(p, full_name,
338 "Whether or not to save intermediate "
339 "results to local directory",
342 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
343 cpl_parameterlist_append(parlist, p);
350 full_name = uves_sprintf(
"%s.%s", context, name);
351 uves_parameter_new_value(
354 "Any plots produced by the recipe "
355 "are redirected to the command specified "
356 "by this parameter. The plotting command "
357 "must contain the substring 'gnuplot' and "
358 "must be able to parse gnuplot syntax on its "
360 "Valid examples of such a command may include "
361 "'gnuplot -persist' and 'cat > mygnuplot$$.gp'. "
362 "A finer control of the plotting options can "
363 "be obtained by writing an "
364 "executable script, e.g. my_gnuplot.pl, that "
365 "executes gnuplot after setting the desired gnuplot "
366 "options (e.g. set terminal pslatex color). "
367 "To turn off plotting, set this parameter to 'no'",
371 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
372 cpl_parameterlist_append(parlist, p);
379 name =
"process_chip";
380 full_name = uves_sprintf(
"%s.%s", context, name);
381 uves_parameter_new_enum(p, full_name,
383 "For RED arm data process the "
384 "redl, redu, or both chip(s)",
386 "both",5,
"both",
"redl",
"redu",
"REDL",
"REDU");
387 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
388 cpl_parameterlist_append(parlist, p);
396 name =
"msginfolevel";
397 full_name = uves_sprintf(
"%s.%s", context, name);
398 uves_parameter_new_range(p, full_name,
400 "This parameter controls the subdivision "
401 "of the 'info' message level (set e.g. with "
402 "esorex' --msg-level). The higher the value "
403 "of this parameter, the more messages are "
404 "printed at the info level. For minimum "
405 "output, set to zero. Increase the level "
406 "(to 1, 2, 3, ...) for more output. The "
407 "value -1 is a special value meaning maximum "
412 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
413 cpl_parameterlist_append(parlist, p);
417 if (cpl_error_get_code() != CPL_ERROR_NONE)
419 cpl_msg_error(__func__,
"Creation of global parameters failed: '%s'",
420 cpl_error_get_where());
423 return cpl_error_get_code();
436 uves_define_extract_for_response_chain_parameters(cpl_parameterlist *parameters)
439 const char *name =
"";
440 char *full_name = NULL;
442 cpl_parameter *p = NULL;
447 name =
"uves_cal_response.reduce.extract.method";
448 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
450 uves_parameter_new_enum(p, full_name,
452 "Extraction method. (2d/optimal not supported by uves_cal_wavecal, weighted supported only by uves_cal_wavecal, 2d not supported by uves_cal_response)",
462 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
463 cpl_parameterlist_append(parameters, p);
468 name =
"uves_cal_response.reduce.extract.kappa";
469 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
471 uves_parameter_new_range(p, full_name,
473 "In optimal extraction mode, this is the "
474 "threshold for bad (i.e. hot/cold) "
475 "pixel rejection. If a pixel deviates more than "
476 "kappa*sigma (where sigma is "
477 "the uncertainty of the pixel flux) from "
478 "the inferred spatial profile, its "
479 "weight is set to zero. Range: [-1,100]. If this parameter "
480 "is negative, no rejection is performed.",
484 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
485 cpl_parameterlist_append(parameters, p);
490 name =
"uves_cal_response.reduce.extract.chunk";
491 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
493 uves_parameter_new_range(p, full_name,
495 "In optimal extraction mode, the chunk size (in pixels) "
496 "used for fitting the analytical profile (a fit of the "
497 "analytical profile to single bins would suffer from "
503 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
504 cpl_parameterlist_append(parameters, p);
509 name =
"uves_cal_response.reduce.extract.profile";
510 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
512 uves_parameter_new_enum(p, full_name,
514 "In optimal extraction mode, the kind of profile to use. "
515 "'gauss' gives a Gaussian profile, 'moffat' gives "
516 "a Moffat profile with beta=4 and a possible linear sky "
517 "contribution. 'virtual' uses "
518 "a virtual resampling algorithm (i.e. measures and "
519 "uses the actual object profile). "
520 "'constant' assumes a constant spatial profile and "
521 "allows optimal extraction of wavelength "
522 "calibration frames. 'auto' will automatically "
523 "select the best method based on the estimated S/N of the "
524 "object. For low S/N, 'moffat' or 'gauss' are "
525 "recommended (for robustness). For high S/N, 'virtual' is "
526 "recommended (for accuracy). In the case of virtual resampling, "
527 "a precise determination of the order positions is required; "
528 "therefore the order-definition is repeated "
529 "using the (assumed non-low S/N) science frame",
539 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
540 cpl_parameterlist_append(parameters, p);
545 name =
"uves_cal_response.reduce.extract.skymethod";
546 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
548 uves_parameter_new_enum(p, full_name,
550 "In optimal extraction mode, the sky subtraction method "
551 "to use. 'median' estimates the sky as the median of pixels "
552 "along the slit (ignoring pixels close to the object), whereas "
553 "'optimal' does a chi square minimization along the slit "
554 "to obtain the best combined object and sky levels. The optimal "
555 "method gives the most accurate sky determination but is also "
556 "a bit slower than the median method",
563 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
564 cpl_parameterlist_append(parameters, p);
569 name =
"uves_cal_response.reduce.extract.oversample";
570 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
572 uves_parameter_new_range(p, full_name,
574 "The oversampling factor used for the virtual "
575 "resampling algorithm. If negative, the value 5 is "
576 "used for S/N <=200, and the value 10 is used if the estimated "
582 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
583 cpl_parameterlist_append(parameters, p);
588 name =
"uves_cal_response.reduce.extract.best";
589 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
591 uves_parameter_new_value(p, full_name,
593 "(optimal extraction only) "
594 "If false (fastest), the spectrum is extracted only once. "
595 "If true (best), the spectrum is extracted twice, the "
596 "second time using improved variance estimates "
597 "based on the first iteration. Better variance "
598 "estimates slightly improve the obtained signal to "
599 "noise but at the cost of increased execution time",
603 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
604 cpl_parameterlist_append(parameters, p);
609 if (cpl_error_get_code() != CPL_ERROR_NONE)
611 cpl_msg_error(__func__,
"Creation of extraction parameters failed: '%s'",
612 cpl_error_get_where());
614 return cpl_error_get_code();
629 uves_define_rebin_for_response_chain_parameters(cpl_parameterlist *parameters)
634 const char *name =
"";
635 char *full_name = NULL;
636 cpl_parameter *p = NULL;
640 name =
"uves_cal_response.reduce.rebin.wavestep";
641 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
643 uves_parameter_new_range(p, full_name,
645 "The bin size (in w.l.u.) in wavelength space. "
646 "If negative, a step size of "
647 "2/3 * ( average pixel size ) is used.",
650 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
651 cpl_parameterlist_append(parameters, p);
654 name =
"uves_cal_response.reduce.rebin.scale";
655 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
656 uves_parameter_new_value(p, full_name,
658 "Whether or not to multiply by the factor "
659 "dx/dlambda (pixels per wavelength) "
660 "during the rebinning. This option is disabled "
661 "as default in concordance with the "
662 "method used in the MIDAS pipeline. This "
663 "option should be set to true "
664 "to convert the observed flux (in pixel-space) "
665 "to a flux per wavelength (in "
666 "wavelength-space).",
669 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
670 cpl_parameterlist_append(parameters, p);
674 if (cpl_error_get_code() != CPL_ERROR_NONE)
676 cpl_msg_error(__func__,
"Creation of background parameters failed: '%s'",
677 cpl_error_get_where());
681 return cpl_error_get_code();
697 uves_define_reduce_for_response_chain_parameters(cpl_parameterlist *parameters)
700 const char *name = NULL;
701 char *full_name = NULL;
708 if (cpl_error_get_code() == CPL_ERROR_NONE)
710 name =
"uves_cal_response.reduce.slitlength";
711 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
713 uves_parameter_new_range(p, full_name,
715 "Extraction slit length (in pixels). "
716 "If negative, the value "
717 "inferred from the raw frame header is used",
722 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
723 cpl_parameterlist_append(parameters, p);
727 if (cpl_error_get_code() == CPL_ERROR_NONE)
729 name =
"uves_cal_response.reduce.skysub";
730 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
732 uves_parameter_new_value(p, full_name,
734 "Do sky-subtraction (only applicable to linear "
735 "and average extractions)?",
739 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
740 cpl_parameterlist_append(parameters, p);
744 if (cpl_error_get_code() == CPL_ERROR_NONE)
746 name =
"uves_cal_response.reduce.objoffset";
747 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
749 uves_parameter_new_value(p, full_name,
751 "Offset (in pixels) of extraction slit "
752 "with respect to center of order. "
753 "This parameter applies to linear/average/"
754 "optimal extraction. "
755 "For linear/average extraction, if the related "
756 "parameter objslit is negative, the offset is "
757 "automatically determined by measuring the "
758 "actual object position. ",
762 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
763 cpl_parameterlist_append(parameters, p);
767 if (cpl_error_get_code() == CPL_ERROR_NONE)
769 name =
"uves_cal_response.reduce.objslit";
770 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
772 uves_parameter_new_range(p, full_name,
774 "Object window size (in pixels). This must "
775 "be less than the total slit length. If "
776 "negative, the default value (half of full "
777 "slit length) is used. The upper and lower "
778 "sky windows are defined as the part of the "
779 "full slit (if any) outside the object "
780 "window. The center of the object window "
781 "is determined by the offset parameter. "
782 "This parameter does not apply to optimal "
788 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
789 cpl_parameterlist_append(parameters, p);
793 if (cpl_error_get_code() == CPL_ERROR_NONE)
795 name =
"uves_cal_response.reduce.tiltcorr";
796 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
798 uves_parameter_new_value(p, full_name,
800 "If enabled (recommended), the provided "
801 "dispersion solutions "
802 "obtained at different slit positions are "
803 "interpolated linearly at the actually "
804 "measured position of the object/sky. "
805 "Line tilt correction is currently not supported "
806 "for 2d extraction, in which case the "
807 "dispersion solution obtained at the middle of "
808 "the slit is always used.",
812 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
813 cpl_parameterlist_append(parameters, p);
823 if (cpl_error_get_code() == CPL_ERROR_NONE)
825 name =
"uves_cal_response.reduce.ffmethod";
826 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
828 uves_parameter_new_enum(p, full_name,
830 "Flat-fielding method. If set to 'pixel', "
831 "flat-fielding is done in pixel-pixel space "
832 "(before extraction); if set to 'extract', "
833 "flat-fielding is performed in pixel-order "
834 "space (i.e. after extraction). If set to "
835 "'no', no flat-field correction is done",
840 "pixel",
"extract",
"no");
842 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
843 cpl_parameterlist_append(parameters, p);
851 if (cpl_error_get_code() == CPL_ERROR_NONE)
879 if (cpl_error_get_code() == CPL_ERROR_NONE)
881 name =
"uves_cal_response.reduce.merge";
882 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
884 uves_parameter_new_enum(p, full_name,
886 "Order merging method. If 'optimal', the "
887 "flux in the overlapping region is set "
888 "to the (optimally computed, using the "
889 "uncertainties) average of single order "
890 "spectra. If 'sum', the flux in the "
891 "overlapping region is computed as the "
892 "sum of the single order spectra. If 'noappend' "
893 "the spectrum is simply rebinned but not merged."
894 "If flat-fielding is done, method 'optimal' "
895 "is recommended, otherwise 'sum'.",
899 "optimal",
"sum",
"noappend");
901 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
902 cpl_parameterlist_append(parameters, p);
906 name =
"uves_cal_response.reduce.merge_delt1";
907 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
909 uves_parameter_new_range(p, full_name,
911 "Order merging left hand (short wavelength) "
912 "cut. To reduce the amount of order "
913 "overlapping regions we allow to cut short and "
914 "long wavelength ranges. "
915 "This may reduce the ripple possibly "
916 "introduced by the order merging. "
917 "Suggested values are: "
918 "10 (W<=390), 12 (390<W<=437, 520<W<=564), "
919 "14 (437<W<=520, 564<W) ",
923 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
924 cpl_parameterlist_append(parameters, p);
928 name =
"uves_cal_response.reduce.merge_delt2";
929 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
931 uves_parameter_new_range(p, full_name,
933 "Order merging right hand (long wavelength) "
934 "cut. To reduce the amount of order "
935 "overlapping regions we allow to cut short and "
936 "long wavelength ranges. "
937 "This may reduce the ripple possibly "
938 "introduced by the order merging. "
939 "Suggested values is 4",
943 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
944 cpl_parameterlist_append(parameters, p);
952 if (cpl_error_get_code() != CPL_ERROR_NONE)
954 cpl_msg_error(__func__,
"Creation of background parameters failed: '%s'",
955 cpl_error_get_where());
959 return cpl_error_get_code();
973 uves_define_background_for_response_chain_parameters(cpl_parameterlist *parameters)
978 const char *name = NULL;
979 char *full_name = NULL;
988 name =
"uves_cal_response.reduce.backsub.mmethod";
989 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
991 uves_parameter_new_enum(p, full_name,
993 "Background measuring method. If equal to 'median' "
994 "the background is sampled using the median of a subwindow. "
995 "If 'minimum', the subwindow minimum value is used. "
996 "If 'no', no background subtraction is done.",
1000 "median",
"minimum",
"no");
1001 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1002 cpl_parameterlist_append(parameters, p);
1003 cpl_free(full_name);
1006 name =
"uves_cal_response.reduce.backsub.npoints";
1007 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1008 uves_parameter_new_range(p, full_name,
1010 "This is the number of columns in interorder space "
1011 "used to sample the background.",
1014 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1015 cpl_parameterlist_append(parameters, p);
1016 cpl_free(full_name);
1019 name =
"uves_cal_response.reduce.backsub.radiusy";
1020 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1021 uves_parameter_new_range(p, full_name,
1023 "The height (in pixels) of the background sampling "
1024 "window is (2*radiusy + 1). "
1025 "This parameter is not corrected for binning.",
1028 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1029 cpl_parameterlist_append(parameters, p);
1030 cpl_free(full_name);
1033 name =
"uves_cal_response.reduce.backsub.sdegree";
1034 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1035 uves_parameter_new_range(p, full_name,
1037 "Degree of interpolating splines. Currently "
1038 "only degree = 1 is supported",
1041 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1042 cpl_parameterlist_append(parameters, p);
1043 cpl_free(full_name);
1046 name =
"uves_cal_response.reduce.backsub.smoothx";
1047 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1048 uves_parameter_new_range(p, full_name,
1050 "If spline interpolation is used to measure the background, "
1051 "the x-radius of the post-smoothing window is "
1052 "(smoothx * image_width). Here, 'image_width' is the image "
1053 "width after binning. If negative, the default values are used: "
1054 make_str(BACKSUB_FLAT_SMOOTHX_BLUE)
" for blue flat-field frames, "
1055 make_str(BACKSUB_FLAT_SMOOTHX_RED)
" for red flat-field frames, "
1056 make_str(BACKSUB_SCI_SMOOTHX_BLUE)
" for blue science frames and "
1057 make_str(BACKSUB_SCI_SMOOTHX_RED)
" for red science frames.",
1059 -1.0, -DBL_MAX, DBL_MAX);
1060 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1061 cpl_parameterlist_append(parameters, p);
1062 cpl_free(full_name);
1065 name =
"uves_cal_response.reduce.backsub.smoothy";
1066 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1067 uves_parameter_new_range(p, full_name,
1069 "If spline interpolation is used to measure the "
1070 "background, the y-radius of the post-smoothing "
1071 "window is (smoothy * image_height). Here, "
1072 "'image_height' is the image height after binning. "
1073 "If negative, the default values are used: "
1074 make_str(BACKSUB_FLAT_SMOOTHY_BLUE)
" for blue flat-field frames, "
1075 make_str(BACKSUB_FLAT_SMOOTHY_RED)
" for red flat-field frames, "
1076 make_str(BACKSUB_SCI_SMOOTHY_BLUE)
" for blue science frames and "
1077 make_str(BACKSUB_SCI_SMOOTHY_RED)
" for red science frames.",
1079 -1.0, -DBL_MAX, DBL_MAX);
1080 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1081 cpl_parameterlist_append(parameters, p);
1082 cpl_free(full_name);
1085 if (cpl_error_get_code() != CPL_ERROR_NONE)
1087 cpl_msg_error(__func__,
"Creation of background parameters failed: '%s'",
1088 cpl_error_get_where());
1091 return cpl_error_get_code();
1108 uves_define_efficiency_for_response_chain_parameters(cpl_parameterlist *parlist)
1111 char *full_name = NULL;
1112 cpl_parameter* p=NULL;
1113 const char* name = NULL;
1114 const char* value = NULL;
1129 name =
"uves_cal_response.efficiency.reduce.extract.method";
1132 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1133 uves_parameter_new_value(p, full_name,
1135 "Extraction method."
1136 "<average | linear | weighted | optimal>",
1140 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1141 cpl_parameterlist_append(parlist, p);
1142 cpl_free(full_name);
1144 name =
"uves_cal_response.efficiency.reduce.ffmethod";
1147 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1148 uves_parameter_new_value(p, full_name,
1150 "Flat-fielding method. If set to 'pixel', flat-fielding "
1151 "is done in pixel-pixel space (before extraction); if "
1152 "set to 'extract', flat-fielding is performed in "
1153 "pixel-order space (i.e. after extraction). If set to "
1154 "'no', no flat-field correction is done. <pixel | "
1159 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1160 cpl_parameterlist_append(parlist, p);
1161 cpl_free(full_name);
1163 name =
"uves_cal_response.efficiency.reduce.merge";
1166 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1167 uves_parameter_new_value(p, full_name,
1169 "Order merging method. If 'optimal', the flux in the "
1170 "overlapping region is set to the (optimally computed, "
1171 "using the uncertainties) average of single order "
1172 "spectra. If 'sum', the flux in the overlapping region "
1173 "is computed as the sum of the single order spectra."
1174 "If 'noappend' the spectrum is simply rebinned but not "
1175 "merged.If flat-fielding is done, method 'optimal' is "
1176 "recommended, otherwise 'sum'. <optimal | sum | "
1181 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1182 cpl_parameterlist_append(parlist, p);
1183 cpl_free(full_name);
1187 const char *param =
"linear";
1189 if (uves_set_parameter_default(parlist,
1190 make_str(UVES_REDCHAIN_ID),
"uves_cal_response.efficiency.reduce.extract.method",
1191 CPL_TYPE_STRING, ¶m) != CPL_ERROR_NONE)
1202 name =
"uves_cal_response.efficiency.reduce.best";
1203 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1205 uves_parameter_new_value(p, full_name,
1207 "(optimal extraction only) "
1208 "If false (fastest), the spectrum is extracted only once. "
1209 "If true (best), the spectrum is extracted twice, the "
1210 "second time using improved variance estimates "
1211 "based on the first iteration. Better variance "
1212 "estimates slightly improve the obtained signal to "
1213 "noise but at the cost of increased execution time",
1217 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1218 cpl_parameterlist_append(parlist, p);
1219 cpl_free(full_name);
1230 name =
"uves_cal_response.efficiency.paccuracy";
1231 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1233 uves_parameter_new_value(p, full_name,
1235 "The pointing accuracy (in arcseconds) used to "
1236 "identify the observed star with a "
1237 "catalogue star. If the angular separation is "
1238 "less than this number, the identification is made.",
1242 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1243 cpl_parameterlist_append(parlist, p);
1244 cpl_free(full_name);
1250 if (cpl_error_get_code() != CPL_ERROR_NONE)
1252 cpl_msg_error(__func__,
"Creation of efficiency parameters failed: '%s'",
1253 cpl_error_get_where());
1256 return cpl_error_get_code();
1270 uves_define_efficiency_parameters(cpl_parameterlist *parlist)
1273 char *full_name = NULL;
1274 cpl_parameter* p=NULL;
1275 const char* name = NULL;
1276 const char* value = NULL;
1292 name =
"efficiency.reduce.extract.method";
1295 full_name = uves_sprintf(
"%s.%s", make_str(UVES_RESPONSE_ID), name);
1296 uves_parameter_new_value(p, full_name,
1298 "Extraction method. "
1299 "<average | linear | weighted | optimal>",
1303 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1304 cpl_parameterlist_append(parlist, p);
1305 cpl_free(full_name);
1308 name =
"efficiency.reduce.ffmethod";
1311 full_name = uves_sprintf(
"%s.%s", make_str(UVES_RESPONSE_ID), name);
1312 uves_parameter_new_value(p, full_name,
1314 "Flat-fielding method. If set to 'pixel', flat-fielding "
1315 "is done in pixel-pixel space (before extraction); if "
1316 "set to 'extract', flat-fielding is performed in "
1317 "pixel-order space (i.e. after extraction). If set to "
1318 "'no', no flat-field correction is done. <pixel | "
1323 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1324 cpl_parameterlist_append(parlist, p);
1325 cpl_free(full_name);
1327 name =
"efficiency.reduce.merge";
1330 full_name = uves_sprintf(
"%s.%s", make_str(UVES_RESPONSE_ID), name);
1331 uves_parameter_new_value(p, full_name,
1333 "Order merging method. If 'optimal', the flux in the "
1334 "overlapping region is set to the (optimally computed, "
1335 "using the uncertainties) average of single order "
1336 "spectra. If 'sum', the flux in the overlapping region "
1337 "is computed as the sum of the single order spectra."
1338 "If 'noappend' the spectrum is simply rebinned but not "
1339 "merged.If flat-fielding is done, method 'optimal' is "
1340 "recommended, otherwise 'sum'. <optimal | sum | "
1345 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1346 cpl_parameterlist_append(parlist, p);
1347 cpl_free(full_name);
1352 const char *param =
"linear";
1354 if (uves_set_parameter_default(parlist,
1355 make_str(UVES_RESPONSE_ID),
"efficiency.reduce.extract.method",
1356 CPL_TYPE_STRING, ¶m) != CPL_ERROR_NONE)
1376 name =
"efficiency.reduce.best";
1377 full_name = uves_sprintf(
"%s.%s", make_str(UVES_RESPONSE_ID), name);
1379 uves_parameter_new_value(p, full_name,
1381 "(optimal extraction only) "
1382 "If false (fastest), the spectrum is extracted only once. "
1383 "If true (best), the spectrum is extracted twice, the "
1384 "second time using improved variance estimates "
1385 "based on the first iteration. Better variance "
1386 "estimates slightly improve the obtained signal to "
1387 "noise but at the cost of increased execution time",
1391 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1392 cpl_parameterlist_append(parlist, p);
1393 cpl_free(full_name);
1404 const char *subcontext =
"efficiency";
1405 const char* name=
"paccuracy";
1406 char *context=uves_sprintf(
"%s.%s",make_str(UVES_RESPONSE_ID),subcontext);
1421 full_name = uves_sprintf(
"%s.%s", context,name);
1422 uves_parameter_new_value(p, full_name,
1424 "The pointing accuracy (in arcseconds) used to "
1425 "identify the observed star with a "
1426 "catalogue star. If the angular separation is "
1427 "less than this number, the identification is made.",
1431 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1432 cpl_parameterlist_append(parlist, p);
1433 cpl_free(full_name);
1443 if (cpl_error_get_code() != CPL_ERROR_NONE)
1445 cpl_msg_error(__func__,
"Creation of efficiency parameters failed: '%s'",
1446 cpl_error_get_where());
1449 return cpl_error_get_code();
1473 uves_exec_recipe(
int (*get_info)(cpl_pluginlist *),
1474 const char *recipe_domain,
1475 const cpl_parameterlist *parameters,
1476 cpl_frameset *frames,
1477 const char *caller_id,
const char *context)
1479 cpl_pluginlist *list = NULL;
1480 cpl_plugin *plugin = NULL;
1481 cpl_recipe *recipe = NULL;
1483 const char *recipe_id = NULL;
1484 cpl_parameter *p = NULL;
1485 char *parent_name = NULL;
1486 char *sub_domain = NULL;
1489 bool must_destroy_plugin =
false;
1493 assure(recipe_domain != NULL, CPL_ERROR_NULL_INPUT,
"Null recipe message domain");
1494 assure(parameters != NULL, CPL_ERROR_NULL_INPUT,
"Null parameter list");
1495 assure(frames != NULL, CPL_ERROR_NULL_INPUT,
"Null frame set");
1496 assure(caller_id != NULL, CPL_ERROR_NULL_INPUT,
"Null caller recipe name");
1500 check( list = cpl_pluginlist_new(),
1501 "Error allocating plugin list");
1504 status = get_info(list);
1506 assure( status == 0, CPL_ERROR_ILLEGAL_INPUT,
1507 "Could not get info about recipe");
1510 check( plugin = cpl_pluginlist_get_first(list),
"Error getting plugin");
1511 assure( plugin != NULL, CPL_ERROR_ILLEGAL_INPUT,
1512 "Plugin '%s' returned empty plugin list", recipe_id);
1513 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
1514 CPL_ERROR_TYPE_MISMATCH,
"Plugin is not a recipe");
1515 recipe = (cpl_recipe *) plugin;
1517 recipe_id = cpl_strdup(cpl_plugin_get_name(plugin));
1520 must_destroy_plugin =
true;
1521 assure( cpl_plugin_get_init(plugin)(plugin) == 0, CPL_ERROR_ILLEGAL_INPUT,
1522 "Error initializing recipe");
1523 assure( recipe->parameters != NULL, CPL_ERROR_ILLEGAL_INPUT,
1524 "Recipe '%s' returned NULL parameter list", recipe_id);
1531 for (p = cpl_parameterlist_get_first(recipe->parameters);
1533 p = cpl_parameterlist_get_next(recipe->parameters) )
1535 const char *name = cpl_parameter_get_name(p);
1536 const char *subcontext = cpl_parameter_get_context(p);
1537 cpl_type type = cpl_parameter_get_type(p);
1539 const cpl_parameter *parent;
1541 if (strcmp(subcontext,
"uves") == 0)
1543 parent_name = uves_sprintf(
"%s", name);
1547 if (context != NULL)
1549 parent_name = uves_sprintf(
"%s.%s.%s", caller_id, context, name);
1553 parent_name = uves_sprintf(
"%s.%s", caller_id, name);
1558 check( parent = cpl_parameterlist_find_const(parameters, parent_name),
1559 "Could not get parameter '%s' from provided parameter list", parent_name);
1576 double value_double;
1577 const char *value_string;
1580 check( value_bool = cpl_parameter_get_bool(parent),
1581 "Error reading parameter '%s'", parent_name);
1583 check( cpl_parameter_set_bool(p, value_bool),
1584 "Error setting parameter '%s'", name);
1587 name, parent_name, (value_bool) ?
"true" :
"false");
1591 check( value_int = cpl_parameter_get_int(parent),
1592 "Error reading parameter '%s'", parent_name);
1594 check( cpl_parameter_set_int(p, value_int),
1595 "Error setting parameter '%s'", name);
1598 name, parent_name, value_int);
1601 case CPL_TYPE_DOUBLE:
1602 check( value_double = cpl_parameter_get_double(parent),
1603 "Error reading parameter '%s'", parent_name);
1605 check( cpl_parameter_set_double(p, value_double),
1606 "Error setting parameter '%s'", name);
1609 name, parent_name, value_double);
1612 case CPL_TYPE_STRING:
1613 check( value_string = cpl_parameter_get_string(parent),
1614 "Error reading parameter '%s'", parent_name);
1616 check( cpl_parameter_set_string(p, value_string),
1617 "Error setting parameter '%s'", name);
1620 name, parent_name, value_string);
1624 assure(
false, CPL_ERROR_UNSUPPORTED_MODE,
1625 "Parameter '%s' has type %s",
1629 cpl_free(parent_name); parent_name = NULL;
1634 recipe->frames = frames;
1647 sub_domain = uves_sprintf(
"%s.%s", domain, recipe_domain);
1650 status = cpl_plugin_get_exec(plugin)(plugin);
1667 if (cpl_error_get_code() != CPL_ERROR_NONE)
1670 cpl_error_code ec = cpl_error_get_code();
1672 assure(
false, ec,
"Recipe '%s' failed", recipe_id);
1675 assure( status == 0, CPL_ERROR_ILLEGAL_OUTPUT,
1676 "Recipe '%s' failed with exit status %d", recipe_id, status);
1679 must_destroy_plugin =
false;
1680 assure( cpl_plugin_get_deinit(plugin)(plugin) == 0,
1681 CPL_ERROR_ILLEGAL_OUTPUT,
1682 "Error cleaning up recipe");
1684 uves_msg(
"Recipe '%s' succeeded", recipe_id);
1687 uves_free_string_const(&recipe_id);
1688 cpl_free(parent_name); parent_name = NULL;
1689 cpl_free(sub_domain); sub_domain = NULL;
1690 if (must_destroy_plugin)
1692 cpl_plugin_get_deinit(plugin)(plugin);
1695 cpl_pluginlist_delete(list);
1697 return (cpl_error_get_code() != CPL_ERROR_NONE);
1718 uves_invoke_recipe(
const char *recipe_id,
const cpl_parameterlist *parameters,
1719 cpl_frameset *frames,
1720 const char *caller_id,
const char *context)
1722 assure(recipe_id != NULL, CPL_ERROR_NULL_INPUT,
"Null recipe name");
1724 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);
1725 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);
1726 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);
1727 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);
1728 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);
1729 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);
1730 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);
1731 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);
1732 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);
1735 assure(
false, CPL_ERROR_ILLEGAL_INPUT,
"Unknown recipe: '%s'", recipe_id);
1738 return (cpl_error_get_code() != CPL_ERROR_NONE);
1762 uves_prop_par(
int (*get_info)(cpl_pluginlist *),
1763 cpl_parameterlist *parameters,
1764 const char *recipe_id,
const char *context)
1766 cpl_plugin *plugin = NULL;
1767 cpl_pluginlist *list = NULL;
1768 cpl_recipe *subrecipe = NULL;
1773 if (get_info == NULL)
1775 FAIL(-1, CPL_ERROR_NULL_INPUT,
"Null function pointer");
1778 if (parameters == NULL)
1780 FAIL(-1, CPL_ERROR_NULL_INPUT,
"Null parameter list");
1783 if (recipe_id == NULL)
1785 FAIL(-1, CPL_ERROR_NULL_INPUT,
"Null recipe id");
1789 list = cpl_pluginlist_new();
1790 status = get_info(list);
1794 cpl_pluginlist_delete(list);
1795 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
"Could not get info about recipe");
1799 if ((plugin = cpl_pluginlist_get_first(list)) == NULL)
1801 cpl_pluginlist_delete(list);
1802 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
"Error getting plugin");
1804 if (cpl_plugin_get_name(plugin) == NULL) {
1805 cpl_pluginlist_delete(list);
1806 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
"Plugin name is NULL");
1808 sprintf(name,
"%s", cpl_plugin_get_name(plugin));
1810 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE)
1812 cpl_pluginlist_delete(list);
1813 FAIL(-1, CPL_ERROR_TYPE_MISMATCH,
"Plugin is not a recipe");
1815 subrecipe = (cpl_recipe *) plugin;
1818 if( cpl_plugin_get_init(plugin)(plugin) != 0)
1820 cpl_plugin_get_deinit(plugin)(plugin);
1821 cpl_pluginlist_delete(list);
1822 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
"Error getting '%s' parameter list",
1826 if (subrecipe->parameters == NULL)
1828 cpl_plugin_get_deinit(plugin)(plugin);
1829 cpl_pluginlist_delete(list);
1830 FAIL(-1, CPL_ERROR_NULL_INPUT,
"Recipe '%s' returned NULL parameter list",
1834 if (propagate(cpl_plugin_get_name(plugin), subrecipe->parameters, parameters, recipe_id, context) != 0)
1836 cpl_plugin_get_deinit(plugin)(plugin);
1837 cpl_pluginlist_delete(list);
1838 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
"Error propagating parameters from recipe '%s'",
1842 cpl_plugin_get_deinit(plugin)(plugin);
1843 cpl_pluginlist_delete(list);
1856 uves_propagate_parameters(
const char *subrecipe,
1857 cpl_parameterlist *parameters,
1858 const char *recipe_id,
const char *context)
1860 if (subrecipe == NULL) {
1861 FAIL(-1, CPL_ERROR_NULL_INPUT,
"Null subrecipe id");
1864 if (strcmp(subrecipe, make_str(UVES_PHYSMOD_ID) ) == 0)
return uves_prop_par(&uves_physmod_get_info, parameters, recipe_id, context);
1865 else if (strcmp(subrecipe, make_str(UVES_ORDERPOS_ID)) == 0)
return uves_prop_par(&uves_orderpos_get_info, parameters, recipe_id, context);
1866 else if (strcmp(subrecipe, make_str(UVES_MBIAS_ID) ) == 0)
return uves_prop_par(&uves_mbias_get_info, parameters, recipe_id, context);
1867 else if (strcmp(subrecipe, make_str(UVES_MDARK_ID) ) == 0)
return uves_prop_par(&uves_mdark_get_info, parameters, recipe_id, context);
1868 else if (strcmp(subrecipe, make_str(UVES_MFLAT_ID) ) == 0)
return uves_prop_par(&uves_mflat_get_info, parameters, recipe_id, context);
1869 else if (strcmp(subrecipe, make_str(UVES_WAVECAL_ID) ) == 0)
return uves_prop_par(&uves_wavecal_get_info, parameters, recipe_id, context);
1870 else if (strcmp(subrecipe, make_str(UVES_RESPONSE_ID)) == 0)
return uves_prop_par(&uves_response_get_info, parameters, recipe_id, context);
1871 else if (strcmp(subrecipe, make_str(UVES_SCIRED_ID) ) == 0)
return uves_prop_par(&uves_scired_get_info, parameters, recipe_id, context);
1872 else if (strcmp(subrecipe, make_str(UVES_REDCHAIN_ID)) == 0)
return uves_prop_par(&uves_redchain_get_info, parameters, recipe_id, context);
1874 FAIL(-1, CPL_ERROR_DATA_NOT_FOUND,
"Unknown recipe: '%s'", subrecipe);
1926 uves_propagate_parameters_step(
const char *step_id,
1927 cpl_parameterlist *parameters,
1928 const char *recipe_id,
const char *context)
1930 cpl_parameterlist *subparameters = NULL;
1931 cpl_parameterlist *(*get_parameters)(void) = NULL;
1935 if (step_id == NULL)
1937 FAIL(-1, CPL_ERROR_NULL_INPUT,
"Null parameter list");
1940 if (parameters == NULL)
1942 FAIL(-1, CPL_ERROR_NULL_INPUT,
"Null parameter list");
1945 if (recipe_id == NULL)
1947 FAIL(-1, CPL_ERROR_NULL_INPUT,
"Null recipe id");
1952 if (strcmp(step_id, UVES_BACKSUB_ID ) == 0) {
1953 get_parameters = uves_backsub_define_parameters;
1954 }
else if (strcmp(step_id, UVES_QCDARK_ID ) == 0) {
1955 get_parameters = uves_qcdark_define_parameters;
1956 }
else if (strcmp(step_id, UVES_EXTRACT_ID ) == 0) {
1958 }
else if (strcmp(step_id, UVES_REBIN_ID ) == 0) {
1960 }
else if (strcmp(step_id, UVES_REDUCE_ID ) == 0) {
1963 FAIL(-1, CPL_ERROR_DATA_NOT_FOUND,
"Unknown sub-step: '%s'", step_id);
1967 if( (subparameters = get_parameters()) == NULL )
1969 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
"Error getting '%s' parameter list", step_id);
1972 if ( propagate(step_id, subparameters, parameters, recipe_id, context) != 0)
1974 cpl_parameterlist_delete(subparameters);
1975 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
"Error propagating '%s' parameters", step_id);
1978 cpl_parameterlist_delete(subparameters);
1994 static cpl_parameter *
1995 create_parameter_enum_int(
const char *name, cpl_type type,
1996 const char *description,
1997 const char *context,
1998 int default_value,
int size,
2003 cpl_parameter *result = NULL;
2005 if (! (1 <= size && size <= 10))
2007 cpl_msg_error(__func__,
"Unsupported enumeration size: %d (max is 10)", size);
2014 uves_parameter_new_enum(result, name,
2018 default_value, size,
2022 uves_parameter_new_enum(result, name,
2026 default_value, size,
2031 uves_parameter_new_enum(result, name,
2035 default_value, size,
2041 uves_parameter_new_enum(result, name,
2045 default_value, size,
2052 uves_parameter_new_enum(result, name,
2056 default_value, size,
2064 uves_parameter_new_enum(result, name,
2068 default_value, size,
2077 uves_parameter_new_enum(result, name,
2081 default_value, size,
2091 uves_parameter_new_enum(result, name,
2095 default_value, size,
2106 uves_parameter_new_enum(result, name,
2110 default_value, size,
2122 uves_parameter_new_enum(result, name,
2126 default_value, size,
2141 static cpl_parameter *
2142 create_parameter_enum_double(
const char *name, cpl_type type,
2143 const char *description,
2144 const char *context,
double default_value,
2145 int size,
double *values)
2149 cpl_parameter *result = NULL;
2151 if (! (1 <= size && size <= 10))
2153 cpl_msg_error(__func__,
"Unsupported enumeration size: %d (max is 10)", size);
2160 uves_parameter_new_enum(result, name,
2164 default_value, size,
2168 uves_parameter_new_enum(result, name,
2172 default_value, size,
2177 uves_parameter_new_enum(result, name,
2181 default_value, size,
2187 uves_parameter_new_enum(result, name,
2191 default_value, size,
2198 uves_parameter_new_enum(result, name,
2202 default_value, size,
2210 uves_parameter_new_enum(result, name,
2214 default_value, size,
2223 uves_parameter_new_enum(result, name,
2227 default_value, size,
2237 uves_parameter_new_enum(result, name,
2241 default_value, size,
2252 uves_parameter_new_enum(result, name,
2256 default_value, size,
2268 uves_parameter_new_enum(result, name,
2272 default_value, size,
2287 static cpl_parameter *
2288 create_parameter_enum_string(
const char *name, cpl_type type,
2289 const char *description,
2290 const char *context,
2291 const char *default_value,
2292 int size,
const char **values)
2296 cpl_parameter *result = NULL;
2298 if (! (1 <= size && size <= 10))
2300 cpl_msg_error(__func__,
"Unsupported enumeration size: %d (max is 10)", size);
2307 uves_parameter_new_enum(result, name,
2311 default_value, size,
2315 uves_parameter_new_enum(result, name,
2319 default_value, size,
2324 uves_parameter_new_enum(result, name,
2328 default_value, size,
2334 uves_parameter_new_enum(result, name,
2338 default_value, size,
2345 uves_parameter_new_enum(result, name,
2349 default_value, size,
2357 uves_parameter_new_enum(result, name,
2361 default_value, size,
2370 uves_parameter_new_enum(result, name,
2374 default_value, size,
2384 uves_parameter_new_enum(result, name,
2388 default_value, size,
2399 uves_parameter_new_enum(result, name,
2403 default_value, size,
2415 uves_parameter_new_enum(result, name,
2419 default_value, size,
2475 propagate(
const char *substep_id,
const cpl_parameterlist *sub_parameters,
2476 cpl_parameterlist *parent_parameters,
2477 const char *parent_id,
const char *context)
2479 const cpl_parameter *p = NULL;
2486 for (p = cpl_parameterlist_get_first_const(sub_parameters);
2488 p = cpl_parameterlist_get_next_const(sub_parameters) )
2490 const char *name = cpl_parameter_get_name(p);
2491 const char *description = cpl_parameter_get_help(p);
2492 const char *subcontext = cpl_parameter_get_context(p);
2493 const char *alias = cpl_parameter_get_alias(p,
2494 CPL_PARAMETER_MODE_CLI);
2495 cpl_parameter_class
class = cpl_parameter_get_class(p);
2496 cpl_type type = cpl_parameter_get_type(p);
2507 if (strstr(name,
"uves.") == name)
2516 if (strstr(name, S) != name)
2518 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
2519 "Recipe id '%s' is not prefix of parameter name '%s'",
2525 if (strstr(subcontext, S) != subcontext)
2527 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
2528 "Recipe id '%s' is not prefix of parameter context '%s'",
2533 if (strstr(name, subcontext) != name)
2535 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
2536 "Parameter context '%s' is not prefix of parameter name '%s'",
2541 if (strcmp(subcontext,
"uves") != 0)
2545 cpl_parameter *new_par = NULL;
2550 if (context == NULL)
2552 new_name = uves_sprintf(
"%s.%s", parent_id, name);
2553 new_context = uves_sprintf(
"%s", parent_id);
2556 new_alias = uves_sprintf(
"%s.%s", substep_id, alias);
2565 new_name = uves_sprintf(
"%s.%s.%s", parent_id, context, name);
2567 new_context = uves_sprintf(
"%s.%s", parent_id, context);
2571 new_alias = uves_sprintf(
"%s.%s.%s",
2572 context, substep_id, alias);
2581 if (new_name == NULL || new_context == NULL)
2583 if (new_name != NULL) cpl_free(new_name);
2584 if (new_context != NULL) cpl_free(new_context);
2585 if (new_alias != NULL) cpl_free(new_alias);
2586 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
"Memory allocation failed");
2591 if (
class != CPL_PARAMETER_CLASS_VALUE &&
2592 class != CPL_PARAMETER_CLASS_RANGE &&
2593 class != CPL_PARAMETER_CLASS_ENUM)
2596 cpl_free(new_context);
2597 if (new_alias != NULL) cpl_free(new_alias);
2598 FAIL(-1, CPL_ERROR_TYPE_MISMATCH,
2599 "Unrecognized class of parameter '%s'", name);
2602 if (type != CPL_TYPE_BOOL &&
2603 type != CPL_TYPE_INT &&
2604 type != CPL_TYPE_DOUBLE &&
2605 type != CPL_TYPE_STRING)
2608 cpl_free(new_context);
2609 if (new_alias != NULL) cpl_free(new_alias);
2610 FAIL(-1, CPL_ERROR_UNSUPPORTED_MODE,
"Unsupported type: %s",
2617 case CPL_PARAMETER_CLASS_VALUE:
2621 uves_parameter_new_value(new_par, new_name,
2625 cpl_parameter_get_default_bool(p));
2629 uves_parameter_new_value(new_par, new_name,
2633 cpl_parameter_get_default_int(p));
2636 case CPL_TYPE_DOUBLE:
2637 uves_parameter_new_value(new_par, new_name,
2641 cpl_parameter_get_default_double(p));
2643 case CPL_TYPE_STRING:
2644 uves_parameter_new_value(new_par, new_name,
2648 cpl_parameter_get_default_string(p));
2656 case CPL_PARAMETER_CLASS_RANGE:
2660 int min_int, max_int;
2661 double min_double, max_double;
2664 min_int = cpl_parameter_get_range_min_int(p);
2665 max_int = cpl_parameter_get_range_max_int(p);
2667 uves_parameter_new_range(new_par, new_name,
2671 cpl_parameter_get_default_int(p),
2675 case CPL_TYPE_DOUBLE:
2676 min_double = cpl_parameter_get_range_min_double(p);
2677 max_double = cpl_parameter_get_range_max_double(p);
2679 uves_parameter_new_range(new_par, new_name,
2683 cpl_parameter_get_default_double(p),
2684 min_double, max_double);
2692 case CPL_PARAMETER_CLASS_ENUM:
2693 enum_size = cpl_parameter_get_enum_size(p);
2699 double *values_double;
2700 const char **values_string;
2704 if ( (values_int = cpl_malloc(
sizeof(
int) * enum_size))
2708 cpl_free(new_context);
2709 if (new_alias != NULL) cpl_free(new_alias);
2710 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
2711 "Memory allocation failed");
2713 for (i = 0; i < enum_size; i++)
2715 values_int[i] = cpl_parameter_get_enum_int(p, i);
2718 new_par = create_parameter_enum_int(
2723 cpl_parameter_get_default_int(p),
2726 cpl_free(values_int);
2729 case CPL_TYPE_DOUBLE:
2730 if ( (values_double =
2731 cpl_malloc(
sizeof(
double) * enum_size)) == NULL)
2734 cpl_free(new_context);
2735 if (new_alias != NULL) cpl_free(new_alias);
2736 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
2737 "Memory allocation failed");
2739 for (i = 0; i < enum_size; i++)
2741 values_double[i] = cpl_parameter_get_enum_double(p, i);
2744 new_par = create_parameter_enum_double(
2749 cpl_parameter_get_default_double(p),
2752 cpl_free(values_double);
2756 case CPL_TYPE_STRING:
2757 if ( (values_string =
2758 cpl_malloc(
sizeof(
char *) * enum_size)) == NULL)
2761 cpl_free(new_context);
2762 if (new_alias != NULL) cpl_free(new_alias);
2763 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
2764 "Memory allocation failed");
2766 for (i = 0; i < enum_size; i++)
2768 values_string[i] = cpl_parameter_get_enum_string(p, i);
2771 new_par = create_parameter_enum_string(
2776 cpl_parameter_get_default_string(p),
2779 cpl_free(values_string);
2795 if (new_par == NULL)
2798 cpl_free(new_context);
2799 if (new_alias != NULL) cpl_free(new_alias);
2800 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
2801 "Propagation of parameter '%s' failed",
2808 cpl_parameter_set_alias(new_par, CPL_PARAMETER_MODE_CLI, new_alias);
2812 cpl_parameterlist_append(parent_parameters, new_par);
2815 cpl_free(new_context);
2816 if (new_alias != NULL) cpl_free(new_alias);
2822 return (cpl_error_get_code() != CPL_ERROR_NONE);