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_mbias") == 0) ||
126 (strcmp(recipe_id,
"uves_cal_mkmaster") == 0) ||
127 (strcmp(recipe_id,
"uves_cal_tflat") == 0) ) {
129 uves_parameter_new_value(p, full_name,
131 "Clean detector traps. "
132 "If TRUE detector traps are interpolated."
133 "The bad pixels are replaced by the average of the"
134 "nearest good pixels in the same column, or simply marked "
135 "as bad. The positions of bad pixels are hard-coded "
136 "(as function of UVES chip).",
141 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
142 cpl_parameterlist_append(parameters, p);
146 uves_msg(
"Creation of trap not supported for recipe: '%s'",
151 if (cpl_error_get_code() != CPL_ERROR_NONE)
154 cpl_msg_error(__func__,
155 "Creation of trap column parameters failed: '%s'",
156 cpl_error_get_where());
160 return cpl_error_get_code();
179 uves_master_stack_define_parameters(cpl_parameterlist *parlist,
const char *recipe_id)
182 const char *name =
"";
188 name =
"stack_method";
189 sprintf(full_name,
"%s.%s",recipe_id,name);
190 uves_parameter_new_enum(p, full_name,
192 "Method used to build master frame ",
194 "median",2,
"median",
"mean");
195 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
196 cpl_parameterlist_append(parlist, p);
202 sprintf(full_name,
"%s.%s",recipe_id,name);
203 uves_parameter_new_range(p, full_name,
205 "Kappa used to clip low level values, when method is set to 'mean' ",
208 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
209 cpl_parameterlist_append(parlist, p);
215 sprintf(full_name,
"%s.%s",recipe_id,name);
216 uves_parameter_new_range(p, full_name,
218 "Kappa used to clip high level values, when method is set to 'mean' ",
221 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
222 cpl_parameterlist_append(parlist, p);
230 sprintf(full_name,
"%s.%s",recipe_id,name);
232 uves_parameter_new_range(p, full_name,
234 "Number of kappa sigma iterations, when method is set to 'mean' ",
237 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
238 cpl_parameterlist_append(parlist, p);
242 if (cpl_error_get_code() != CPL_ERROR_NONE)
244 cpl_msg_error(__func__,
"Creation of kappa sigma parameters failed: '%s'",
245 cpl_error_get_where());
248 return cpl_error_get_code();
265 uves_master_flat_define_parameters(cpl_parameterlist *parlist,
const char *recipe_id)
268 const char *name =
"";
274 name =
"norm_method";
275 sprintf(full_name,
"%s.%s",recipe_id,name);
277 uves_parameter_new_enum(p, full_name,
279 "Method used to build master frame ",
281 (strstr(recipe_id,
"flames") !=NULL) ?
"exptime" :
"explevel",
282 2,
"exptime",
"explevel");
284 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
285 cpl_parameterlist_append(parlist, p);
289 if (cpl_error_get_code() != CPL_ERROR_NONE)
291 cpl_msg_error(__func__,
"Creation of master flat parameters failed: '%s'",
292 cpl_error_get_where());
295 return cpl_error_get_code();
311 uves_define_global_parameters(cpl_parameterlist *parlist)
313 const char *context =
"uves";
314 const char *name =
"";
315 char *full_name = NULL;
320 full_name = uves_sprintf(
"%s.%s", context, name);
321 uves_parameter_new_value(p, full_name,
323 "Whether or not to save intermediate "
324 "results to local directory",
327 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
328 cpl_parameterlist_append(parlist, p);
335 full_name = uves_sprintf(
"%s.%s", context, name);
336 uves_parameter_new_value(
339 "Any plots produced by the recipe "
340 "are redirected to the command specified "
341 "by this parameter. The plotting command "
342 "must contain the substring 'gnuplot' and "
343 "must be able to parse gnuplot syntax on its "
345 "Valid examples of such a command may include "
346 "'gnuplot -persist' and 'cat > mygnuplot$$.gp'. "
347 "A finer control of the plotting options can "
348 "be obtained by writing an "
349 "executable script, e.g. my_gnuplot.pl, that "
350 "executes gnuplot after setting the desired gnuplot "
351 "options (e.g. set terminal pslatex color). "
352 "To turn off plotting, set this parameter to 'no'",
356 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
357 cpl_parameterlist_append(parlist, p);
364 name =
"process_chip";
365 full_name = uves_sprintf(
"%s.%s", context, name);
366 uves_parameter_new_enum(p, full_name,
368 "For RED arm data process the "
369 "redl, redu, or both chip(s)",
371 "both",5,
"both",
"redl",
"redu",
"REDL",
"REDU");
372 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
373 cpl_parameterlist_append(parlist, p);
381 name =
"msginfolevel";
382 full_name = uves_sprintf(
"%s.%s", context, name);
383 uves_parameter_new_range(p, full_name,
385 "This parameter controls the subdivision "
386 "of the 'info' message level (set e.g. with "
387 "esorex' --msg-level). The higher the value "
388 "of this parameter, the more messages are "
389 "printed at the info level. For minimum "
390 "output, set to zero. Increase the level "
391 "(to 1, 2, 3, ...) for more output. The "
392 "value -1 is a special value meaning maximum "
397 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
398 cpl_parameterlist_append(parlist, p);
402 if (cpl_error_get_code() != CPL_ERROR_NONE)
404 cpl_msg_error(__func__,
"Creation of global parameters failed: '%s'",
405 cpl_error_get_where());
408 return cpl_error_get_code();
421 uves_define_extract_for_response_chain_parameters(cpl_parameterlist *parameters)
424 const char *name =
"";
425 char *full_name = NULL;
427 cpl_parameter *p = NULL;
432 name =
"uves_cal_response.reduce.extract.method";
433 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
435 uves_parameter_new_enum(p, full_name,
437 "Extraction method. (2d/optimal not supported by uves_cal_wavecal, weighted supported only by uves_cal_wavecal, 2d not supported by uves_cal_response)",
447 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
448 cpl_parameterlist_append(parameters, p);
453 name =
"uves_cal_response.reduce.extract.kappa";
454 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
456 uves_parameter_new_range(p, full_name,
458 "In optimal extraction mode, this is the "
459 "threshold for bad (i.e. hot/cold) "
460 "pixel rejection. If a pixel deviates more than "
461 "kappa*sigma (where sigma is "
462 "the uncertainty of the pixel flux) from "
463 "the inferred spatial profile, its "
464 "weight is set to zero. Range: [-1,100]. If this parameter "
465 "is negative, no rejection is performed.",
469 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
470 cpl_parameterlist_append(parameters, p);
475 name =
"uves_cal_response.reduce.extract.chunk";
476 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
478 uves_parameter_new_range(p, full_name,
480 "In optimal extraction mode, the chunk size (in pixels) "
481 "used for fitting the analytical profile (a fit of the "
482 "analytical profile to single bins would suffer from "
488 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
489 cpl_parameterlist_append(parameters, p);
494 name =
"uves_cal_response.reduce.extract.profile";
495 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
497 uves_parameter_new_enum(p, full_name,
499 "In optimal extraction mode, the kind of profile to use. "
500 "'gauss' gives a Gaussian profile, 'moffat' gives "
501 "a Moffat profile with beta=4 and a possible linear sky "
502 "contribution. 'virtual' uses "
503 "a virtual resampling algorithm (i.e. measures and "
504 "uses the actual object profile). "
505 "'constant' assumes a constant spatial profile and "
506 "allows optimal extraction of wavelength "
507 "calibration frames. 'auto' will automatically "
508 "select the best method based on the estimated S/N of the "
509 "object. For low S/N, 'moffat' or 'gauss' are "
510 "recommended (for robustness). For high S/N, 'virtual' is "
511 "recommended (for accuracy). In the case of virtual resampling, "
512 "a precise determination of the order positions is required; "
513 "therefore the order-definition is repeated "
514 "using the (assumed non-low S/N) science frame",
524 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
525 cpl_parameterlist_append(parameters, p);
530 name =
"uves_cal_response.reduce.extract.skymethod";
531 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
533 uves_parameter_new_enum(p, full_name,
535 "In optimal extraction mode, the sky subtraction method "
536 "to use. 'median' estimates the sky as the median of pixels "
537 "along the slit (ignoring pixels close to the object), whereas "
538 "'optimal' does a chi square minimization along the slit "
539 "to obtain the best combined object and sky levels. The optimal "
540 "method gives the most accurate sky determination but is also "
541 "a bit slower than the median method",
548 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
549 cpl_parameterlist_append(parameters, p);
554 name =
"uves_cal_response.reduce.extract.oversample";
555 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
557 uves_parameter_new_range(p, full_name,
559 "The oversampling factor used for the virtual "
560 "resampling algorithm. If negative, the value 5 is "
561 "used for S/N <=200, and the value 10 is used if the estimated "
567 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
568 cpl_parameterlist_append(parameters, p);
573 name =
"uves_cal_response.reduce.extract.best";
574 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
576 uves_parameter_new_value(p, full_name,
578 "(optimal extraction only) "
579 "If false (fastest), the spectrum is extracted only once. "
580 "If true (best), the spectrum is extracted twice, the "
581 "second time using improved variance estimates "
582 "based on the first iteration. Better variance "
583 "estimates slightly improve the obtained signal to "
584 "noise but at the cost of increased execution time",
588 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
589 cpl_parameterlist_append(parameters, p);
594 if (cpl_error_get_code() != CPL_ERROR_NONE)
596 cpl_msg_error(__func__,
"Creation of extraction parameters failed: '%s'",
597 cpl_error_get_where());
599 return cpl_error_get_code();
614 uves_define_rebin_for_response_chain_parameters(cpl_parameterlist *parameters)
619 const char *name =
"";
620 char *full_name = NULL;
621 cpl_parameter *p = NULL;
625 name =
"uves_cal_response.reduce.rebin.wavestep";
626 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
628 uves_parameter_new_range(p, full_name,
630 "The bin size (in w.l.u.) in wavelength space. "
631 "If negative, a step size of "
632 "2/3 * ( average pixel size ) is used.",
635 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
636 cpl_parameterlist_append(parameters, p);
639 name =
"uves_cal_response.reduce.rebin.scale";
640 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
641 uves_parameter_new_value(p, full_name,
643 "Whether or not to multiply by the factor "
644 "dx/dlambda (pixels per wavelength) "
645 "during the rebinning. This option is disabled "
646 "as default in concordance with the "
647 "method used in the MIDAS pipeline. This "
648 "option should be set to true "
649 "to convert the observed flux (in pixel-space) "
650 "to a flux per wavelength (in "
651 "wavelength-space).",
654 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
655 cpl_parameterlist_append(parameters, p);
659 if (cpl_error_get_code() != CPL_ERROR_NONE)
661 cpl_msg_error(__func__,
"Creation of background parameters failed: '%s'",
662 cpl_error_get_where());
666 return cpl_error_get_code();
682 uves_define_reduce_for_response_chain_parameters(cpl_parameterlist *parameters)
685 const char *name = NULL;
686 char *full_name = NULL;
693 if (cpl_error_get_code() == CPL_ERROR_NONE)
695 name =
"uves_cal_response.reduce.slitlength";
696 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
698 uves_parameter_new_range(p, full_name,
700 "Extraction slit length (in pixels). "
701 "If negative, the value "
702 "inferred from the raw frame header is used",
707 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
708 cpl_parameterlist_append(parameters, p);
712 if (cpl_error_get_code() == CPL_ERROR_NONE)
714 name =
"uves_cal_response.reduce.skysub";
715 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
717 uves_parameter_new_value(p, full_name,
719 "Do sky-subtraction (only applicable to linear "
720 "and average extractions)?",
724 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
725 cpl_parameterlist_append(parameters, p);
729 if (cpl_error_get_code() == CPL_ERROR_NONE)
731 name =
"uves_cal_response.reduce.objoffset";
732 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
734 uves_parameter_new_value(p, full_name,
736 "Offset (in pixels) of extraction slit "
737 "with respect to center of order. "
738 "This parameter applies to linear/average/"
739 "optimal extraction. "
740 "For linear/average extraction, if the related "
741 "parameter objslit is negative, the offset is "
742 "automatically determined by measuring the "
743 "actual object position. ",
747 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
748 cpl_parameterlist_append(parameters, p);
752 if (cpl_error_get_code() == CPL_ERROR_NONE)
754 name =
"uves_cal_response.reduce.objslit";
755 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
757 uves_parameter_new_range(p, full_name,
759 "Object window size (in pixels). This must "
760 "be less than the total slit length. If "
761 "negative, the default value (half of full "
762 "slit length) is used. The upper and lower "
763 "sky windows are defined as the part of the "
764 "full slit (if any) outside the object "
765 "window. The center of the object window "
766 "is determined by the offset parameter. "
767 "This parameter does not apply to optimal "
773 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
774 cpl_parameterlist_append(parameters, p);
778 if (cpl_error_get_code() == CPL_ERROR_NONE)
780 name =
"uves_cal_response.reduce.tiltcorr";
781 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
783 uves_parameter_new_value(p, full_name,
785 "If enabled (recommended), the provided "
786 "dispersion solutions "
787 "obtained at different slit positions are "
788 "interpolated linearly at the actually "
789 "measured position of the object/sky. "
790 "Line tilt correction is currently not supported "
791 "for 2d extraction, in which case the "
792 "dispersion solution obtained at the middle of "
793 "the slit is always used.",
797 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
798 cpl_parameterlist_append(parameters, p);
808 if (cpl_error_get_code() == CPL_ERROR_NONE)
810 name =
"uves_cal_response.reduce.ffmethod";
811 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
813 uves_parameter_new_enum(p, full_name,
815 "Flat-fielding method. If set to 'pixel', "
816 "flat-fielding is done in pixel-pixel space "
817 "(before extraction); if set to 'extract', "
818 "flat-fielding is performed in pixel-order "
819 "space (i.e. after extraction). If set to "
820 "'no', no flat-field correction is done",
825 "pixel",
"extract",
"no");
827 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
828 cpl_parameterlist_append(parameters, p);
836 if (cpl_error_get_code() == CPL_ERROR_NONE)
864 if (cpl_error_get_code() == CPL_ERROR_NONE)
866 name =
"uves_cal_response.reduce.merge";
867 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
869 uves_parameter_new_enum(p, full_name,
871 "Order merging method. If 'optimal', the "
872 "flux in the overlapping region is set "
873 "to the (optimally computed, using the "
874 "uncertainties) average of single order "
875 "spectra. If 'sum', the flux in the "
876 "overlapping region is computed as the "
877 "sum of the single order spectra. If 'noappend' "
878 "the spectrum is simply rebinned but not merged."
879 "If flat-fielding is done, method 'optimal' "
880 "is recommended, otherwise 'sum'.",
884 "optimal",
"sum",
"noappend");
886 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
887 cpl_parameterlist_append(parameters, p);
891 name =
"uves_cal_response.reduce.merge_delt1";
892 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
894 uves_parameter_new_range(p, full_name,
896 "Order merging left hand (short wavelength) "
897 "cut. To reduce the amount of order "
898 "overlapping regions we allow to cut short and "
899 "long wavelength ranges. "
900 "This may reduce the ripple possibly "
901 "introduced by the order merging. "
902 "Suggested values are: "
903 "10 (W<=390), 12 (390<W<=437, 520<W<=564), "
904 "14 (437<W<=520, 564<W) ",
908 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
909 cpl_parameterlist_append(parameters, p);
913 name =
"uves_cal_response.reduce.merge_delt2";
914 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
916 uves_parameter_new_range(p, full_name,
918 "Order merging right hand (long wavelength) "
919 "cut. To reduce the amount of order "
920 "overlapping regions we allow to cut short and "
921 "long wavelength ranges. "
922 "This may reduce the ripple possibly "
923 "introduced by the order merging. "
924 "Suggested values is 4",
928 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
929 cpl_parameterlist_append(parameters, p);
937 if (cpl_error_get_code() != CPL_ERROR_NONE)
939 cpl_msg_error(__func__,
"Creation of background parameters failed: '%s'",
940 cpl_error_get_where());
944 return cpl_error_get_code();
958 uves_define_background_for_response_chain_parameters(cpl_parameterlist *parameters)
963 const char *name = NULL;
964 char *full_name = NULL;
973 name =
"uves_cal_response.reduce.backsub.mmethod";
974 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
976 uves_parameter_new_enum(p, full_name,
978 "Background measuring method. If equal to 'median' "
979 "the background is sampled using the median of a subwindow. "
980 "If 'minimum', the subwindow minimum value is used. "
981 "If 'no', no background subtraction is done.",
985 "median",
"minimum",
"no");
986 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
987 cpl_parameterlist_append(parameters, p);
991 name =
"uves_cal_response.reduce.backsub.npoints";
992 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
993 uves_parameter_new_range(p, full_name,
995 "This is the number of columns in interorder space "
996 "used to sample the background.",
999 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1000 cpl_parameterlist_append(parameters, p);
1001 cpl_free(full_name);
1004 name =
"uves_cal_response.reduce.backsub.radiusy";
1005 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1006 uves_parameter_new_range(p, full_name,
1008 "The height (in pixels) of the background sampling "
1009 "window is (2*radiusy + 1). "
1010 "This parameter is not corrected for binning.",
1013 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1014 cpl_parameterlist_append(parameters, p);
1015 cpl_free(full_name);
1018 name =
"uves_cal_response.reduce.backsub.sdegree";
1019 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1020 uves_parameter_new_range(p, full_name,
1022 "Degree of interpolating splines. Currently "
1023 "only degree = 1 is supported",
1026 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1027 cpl_parameterlist_append(parameters, p);
1028 cpl_free(full_name);
1031 name =
"uves_cal_response.reduce.backsub.smoothx";
1032 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1033 uves_parameter_new_range(p, full_name,
1035 "If spline interpolation is used to measure the background, "
1036 "the x-radius of the post-smoothing window is "
1037 "(smoothx * image_width). Here, 'image_width' is the image "
1038 "width after binning. If negative, the default values are used: "
1039 make_str(BACKSUB_FLAT_SMOOTHX_BLUE)
" for blue flat-field frames, "
1040 make_str(BACKSUB_FLAT_SMOOTHX_RED)
" for red flat-field frames, "
1041 make_str(BACKSUB_SCI_SMOOTHX_BLUE)
" for blue science frames and "
1042 make_str(BACKSUB_SCI_SMOOTHX_RED)
" for red science frames.",
1044 -1.0, -DBL_MAX, DBL_MAX);
1045 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1046 cpl_parameterlist_append(parameters, p);
1047 cpl_free(full_name);
1050 name =
"uves_cal_response.reduce.backsub.smoothy";
1051 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1052 uves_parameter_new_range(p, full_name,
1054 "If spline interpolation is used to measure the "
1055 "background, the y-radius of the post-smoothing "
1056 "window is (smoothy * image_height). Here, "
1057 "'image_height' is the image height after binning. "
1058 "If negative, the default values are used: "
1059 make_str(BACKSUB_FLAT_SMOOTHY_BLUE)
" for blue flat-field frames, "
1060 make_str(BACKSUB_FLAT_SMOOTHY_RED)
" for red flat-field frames, "
1061 make_str(BACKSUB_SCI_SMOOTHY_BLUE)
" for blue science frames and "
1062 make_str(BACKSUB_SCI_SMOOTHY_RED)
" for red science frames.",
1064 -1.0, -DBL_MAX, DBL_MAX);
1065 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1066 cpl_parameterlist_append(parameters, p);
1067 cpl_free(full_name);
1070 if (cpl_error_get_code() != CPL_ERROR_NONE)
1072 cpl_msg_error(__func__,
"Creation of background parameters failed: '%s'",
1073 cpl_error_get_where());
1076 return cpl_error_get_code();
1093 uves_define_efficiency_for_response_chain_parameters(cpl_parameterlist *parlist)
1096 char *full_name = NULL;
1097 cpl_parameter* p=NULL;
1098 const char* name = NULL;
1099 const char* value = NULL;
1114 name =
"uves_cal_response.efficiency.reduce.extract.method";
1117 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1118 uves_parameter_new_value(p, full_name,
1120 "Extraction method."
1121 "<average | linear | weighted | optimal>",
1125 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1126 cpl_parameterlist_append(parlist, p);
1127 cpl_free(full_name);
1129 name =
"uves_cal_response.efficiency.reduce.ffmethod";
1132 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1133 uves_parameter_new_value(p, full_name,
1135 "Flat-fielding method. If set to 'pixel', flat-fielding "
1136 "is done in pixel-pixel space (before extraction); if "
1137 "set to 'extract', flat-fielding is performed in "
1138 "pixel-order space (i.e. after extraction). If set to "
1139 "'no', no flat-field correction is done. <pixel | "
1144 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1145 cpl_parameterlist_append(parlist, p);
1146 cpl_free(full_name);
1148 name =
"uves_cal_response.efficiency.reduce.merge";
1151 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1152 uves_parameter_new_value(p, full_name,
1154 "Order merging method. If 'optimal', the flux in the "
1155 "overlapping region is set to the (optimally computed, "
1156 "using the uncertainties) average of single order "
1157 "spectra. If 'sum', the flux in the overlapping region "
1158 "is computed as the sum of the single order spectra."
1159 "If 'noappend' the spectrum is simply rebinned but not "
1160 "merged.If flat-fielding is done, method 'optimal' is "
1161 "recommended, otherwise 'sum'. <optimal | sum | "
1166 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1167 cpl_parameterlist_append(parlist, p);
1168 cpl_free(full_name);
1172 const char *param =
"linear";
1174 if (uves_set_parameter_default(parlist,
1175 make_str(UVES_REDCHAIN_ID),
"uves_cal_response.efficiency.reduce.extract.method",
1176 CPL_TYPE_STRING, ¶m) != CPL_ERROR_NONE)
1187 name =
"uves_cal_response.efficiency.reduce.best";
1188 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1190 uves_parameter_new_value(p, full_name,
1192 "(optimal extraction only) "
1193 "If false (fastest), the spectrum is extracted only once. "
1194 "If true (best), the spectrum is extracted twice, the "
1195 "second time using improved variance estimates "
1196 "based on the first iteration. Better variance "
1197 "estimates slightly improve the obtained signal to "
1198 "noise but at the cost of increased execution time",
1202 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1203 cpl_parameterlist_append(parlist, p);
1204 cpl_free(full_name);
1215 name =
"uves_cal_response.efficiency.paccuracy";
1216 full_name = uves_sprintf(
"%s.%s%s", make_str(UVES_REDCHAIN_ID),
"", name);
1218 uves_parameter_new_value(p, full_name,
1220 "The pointing accuracy (in arcseconds) used to "
1221 "identify the observed star with a "
1222 "catalogue star. If the angular separation is "
1223 "less than this number, the identification is made.",
1227 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1228 cpl_parameterlist_append(parlist, p);
1229 cpl_free(full_name);
1235 if (cpl_error_get_code() != CPL_ERROR_NONE)
1237 cpl_msg_error(__func__,
"Creation of efficiency parameters failed: '%s'",
1238 cpl_error_get_where());
1241 return cpl_error_get_code();
1255 uves_define_efficiency_parameters(cpl_parameterlist *parlist)
1258 char *full_name = NULL;
1259 cpl_parameter* p=NULL;
1260 const char* name = NULL;
1261 const char* value = NULL;
1277 name =
"efficiency.reduce.extract.method";
1280 full_name = uves_sprintf(
"%s.%s", make_str(UVES_RESPONSE_ID), name);
1281 uves_parameter_new_value(p, full_name,
1283 "Extraction method. "
1284 "<average | linear | weighted | optimal>",
1288 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1289 cpl_parameterlist_append(parlist, p);
1290 cpl_free(full_name);
1293 name =
"efficiency.reduce.ffmethod";
1296 full_name = uves_sprintf(
"%s.%s", make_str(UVES_RESPONSE_ID), name);
1297 uves_parameter_new_value(p, full_name,
1299 "Flat-fielding method. If set to 'pixel', flat-fielding "
1300 "is done in pixel-pixel space (before extraction); if "
1301 "set to 'extract', flat-fielding is performed in "
1302 "pixel-order space (i.e. after extraction). If set to "
1303 "'no', no flat-field correction is done. <pixel | "
1308 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1309 cpl_parameterlist_append(parlist, p);
1310 cpl_free(full_name);
1312 name =
"efficiency.reduce.merge";
1315 full_name = uves_sprintf(
"%s.%s", make_str(UVES_RESPONSE_ID), name);
1316 uves_parameter_new_value(p, full_name,
1318 "Order merging method. If 'optimal', the flux in the "
1319 "overlapping region is set to the (optimally computed, "
1320 "using the uncertainties) average of single order "
1321 "spectra. If 'sum', the flux in the overlapping region "
1322 "is computed as the sum of the single order spectra."
1323 "If 'noappend' the spectrum is simply rebinned but not "
1324 "merged.If flat-fielding is done, method 'optimal' is "
1325 "recommended, otherwise 'sum'. <optimal | sum | "
1330 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1331 cpl_parameterlist_append(parlist, p);
1332 cpl_free(full_name);
1337 const char *param =
"linear";
1339 if (uves_set_parameter_default(parlist,
1340 make_str(UVES_RESPONSE_ID),
"efficiency.reduce.extract.method",
1341 CPL_TYPE_STRING, ¶m) != CPL_ERROR_NONE)
1361 name =
"efficiency.reduce.best";
1362 full_name = uves_sprintf(
"%s.%s", make_str(UVES_RESPONSE_ID), name);
1364 uves_parameter_new_value(p, full_name,
1366 "(optimal extraction only) "
1367 "If false (fastest), the spectrum is extracted only once. "
1368 "If true (best), the spectrum is extracted twice, the "
1369 "second time using improved variance estimates "
1370 "based on the first iteration. Better variance "
1371 "estimates slightly improve the obtained signal to "
1372 "noise but at the cost of increased execution time",
1376 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1377 cpl_parameterlist_append(parlist, p);
1378 cpl_free(full_name);
1389 const char *subcontext =
"efficiency";
1390 const char* name=
"paccuracy";
1391 char *context=uves_sprintf(
"%s.%s",make_str(UVES_RESPONSE_ID),subcontext);
1406 full_name = uves_sprintf(
"%s.%s", context,name);
1407 uves_parameter_new_value(p, full_name,
1409 "The pointing accuracy (in arcseconds) used to "
1410 "identify the observed star with a "
1411 "catalogue star. If the angular separation is "
1412 "less than this number, the identification is made.",
1416 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
1417 cpl_parameterlist_append(parlist, p);
1418 cpl_free(full_name);
1428 if (cpl_error_get_code() != CPL_ERROR_NONE)
1430 cpl_msg_error(__func__,
"Creation of efficiency parameters failed: '%s'",
1431 cpl_error_get_where());
1434 return cpl_error_get_code();
1458 uves_exec_recipe(
int (*get_info)(cpl_pluginlist *),
1459 const char *recipe_domain,
1460 const cpl_parameterlist *parameters,
1461 cpl_frameset *frames,
1462 const char *caller_id,
const char *context)
1464 cpl_pluginlist *list = NULL;
1465 cpl_plugin *plugin = NULL;
1466 cpl_recipe *recipe = NULL;
1468 const char *recipe_id = NULL;
1469 cpl_parameter *p = NULL;
1470 char *parent_name = NULL;
1471 char *sub_domain = NULL;
1474 bool must_destroy_plugin =
false;
1478 assure(recipe_domain != NULL, CPL_ERROR_NULL_INPUT,
"Null recipe message domain");
1479 assure(parameters != NULL, CPL_ERROR_NULL_INPUT,
"Null parameter list");
1480 assure(frames != NULL, CPL_ERROR_NULL_INPUT,
"Null frame set");
1481 assure(caller_id != NULL, CPL_ERROR_NULL_INPUT,
"Null caller recipe name");
1485 check( list = cpl_pluginlist_new(),
1486 "Error allocating plugin list");
1489 status = get_info(list);
1491 assure( status == 0, CPL_ERROR_ILLEGAL_INPUT,
1492 "Could not get info about recipe");
1495 check( plugin = cpl_pluginlist_get_first(list),
"Error getting plugin");
1496 assure( plugin != NULL, CPL_ERROR_ILLEGAL_INPUT,
1497 "Plugin '%s' returned empty plugin list", recipe_id);
1498 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
1499 CPL_ERROR_TYPE_MISMATCH,
"Plugin is not a recipe");
1500 recipe = (cpl_recipe *) plugin;
1502 recipe_id = cpl_strdup(cpl_plugin_get_name(plugin));
1505 must_destroy_plugin =
true;
1506 assure( cpl_plugin_get_init(plugin)(plugin) == 0, CPL_ERROR_ILLEGAL_INPUT,
1507 "Error initializing recipe");
1508 assure( recipe->parameters != NULL, CPL_ERROR_ILLEGAL_INPUT,
1509 "Recipe '%s' returned NULL parameter list", recipe_id);
1516 for (p = cpl_parameterlist_get_first(recipe->parameters);
1518 p = cpl_parameterlist_get_next(recipe->parameters) )
1520 const char *name = cpl_parameter_get_name(p);
1521 const char *subcontext = cpl_parameter_get_context(p);
1522 cpl_type type = cpl_parameter_get_type(p);
1524 const cpl_parameter *parent;
1526 if (strcmp(subcontext,
"uves") == 0)
1528 parent_name = uves_sprintf(
"%s", name);
1532 if (context != NULL)
1534 parent_name = uves_sprintf(
"%s.%s.%s", caller_id, context, name);
1538 parent_name = uves_sprintf(
"%s.%s", caller_id, name);
1543 check( parent = cpl_parameterlist_find_const(parameters, parent_name),
1544 "Could not get parameter '%s' from provided parameter list", parent_name);
1561 double value_double;
1562 const char *value_string;
1565 check( value_bool = cpl_parameter_get_bool(parent),
1566 "Error reading parameter '%s'", parent_name);
1568 check( cpl_parameter_set_bool(p, value_bool),
1569 "Error setting parameter '%s'", name);
1572 name, parent_name, (value_bool) ?
"true" :
"false");
1576 check( value_int = cpl_parameter_get_int(parent),
1577 "Error reading parameter '%s'", parent_name);
1579 check( cpl_parameter_set_int(p, value_int),
1580 "Error setting parameter '%s'", name);
1583 name, parent_name, value_int);
1586 case CPL_TYPE_DOUBLE:
1587 check( value_double = cpl_parameter_get_double(parent),
1588 "Error reading parameter '%s'", parent_name);
1590 check( cpl_parameter_set_double(p, value_double),
1591 "Error setting parameter '%s'", name);
1594 name, parent_name, value_double);
1597 case CPL_TYPE_STRING:
1598 check( value_string = cpl_parameter_get_string(parent),
1599 "Error reading parameter '%s'", parent_name);
1601 check( cpl_parameter_set_string(p, value_string),
1602 "Error setting parameter '%s'", name);
1605 name, parent_name, value_string);
1609 assure(
false, CPL_ERROR_UNSUPPORTED_MODE,
1610 "Parameter '%s' has type %s",
1614 cpl_free(parent_name); parent_name = NULL;
1619 recipe->frames = frames;
1632 sub_domain = uves_sprintf(
"%s.%s", domain, recipe_domain);
1635 status = cpl_plugin_get_exec(plugin)(plugin);
1652 if (cpl_error_get_code() != CPL_ERROR_NONE)
1655 cpl_error_code ec = cpl_error_get_code();
1657 assure(
false, ec,
"Recipe '%s' failed", recipe_id);
1660 assure( status == 0, CPL_ERROR_ILLEGAL_OUTPUT,
1661 "Recipe '%s' failed with exit status %d", recipe_id, status);
1664 must_destroy_plugin =
false;
1665 assure( cpl_plugin_get_deinit(plugin)(plugin) == 0,
1666 CPL_ERROR_ILLEGAL_OUTPUT,
1667 "Error cleaning up recipe");
1669 uves_msg(
"Recipe '%s' succeeded", recipe_id);
1672 uves_free_string_const(&recipe_id);
1673 cpl_free(parent_name); parent_name = NULL;
1674 cpl_free(sub_domain); sub_domain = NULL;
1675 if (must_destroy_plugin)
1677 cpl_plugin_get_deinit(plugin)(plugin);
1680 cpl_pluginlist_delete(list);
1682 return (cpl_error_get_code() != CPL_ERROR_NONE);
1703 uves_invoke_recipe(
const char *recipe_id,
const cpl_parameterlist *parameters,
1704 cpl_frameset *frames,
1705 const char *caller_id,
const char *context)
1707 assure(recipe_id != NULL, CPL_ERROR_NULL_INPUT,
"Null recipe name");
1709 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);
1710 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);
1711 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);
1712 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);
1713 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);
1714 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);
1715 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);
1716 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);
1717 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);
1720 assure(
false, CPL_ERROR_ILLEGAL_INPUT,
"Unknown recipe: '%s'", recipe_id);
1723 return (cpl_error_get_code() != CPL_ERROR_NONE);
1747 uves_prop_par(
int (*get_info)(cpl_pluginlist *),
1748 cpl_parameterlist *parameters,
1749 const char *recipe_id,
const char *context)
1751 cpl_plugin *plugin = NULL;
1752 cpl_pluginlist *list = NULL;
1753 cpl_recipe *subrecipe = NULL;
1758 if (get_info == NULL)
1760 FAIL(-1, CPL_ERROR_NULL_INPUT,
"Null function pointer");
1763 if (parameters == NULL)
1765 FAIL(-1, CPL_ERROR_NULL_INPUT,
"Null parameter list");
1768 if (recipe_id == NULL)
1770 FAIL(-1, CPL_ERROR_NULL_INPUT,
"Null recipe id");
1774 list = cpl_pluginlist_new();
1775 status = get_info(list);
1779 cpl_pluginlist_delete(list);
1780 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
"Could not get info about recipe");
1784 if ((plugin = cpl_pluginlist_get_first(list)) == NULL)
1786 cpl_pluginlist_delete(list);
1787 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
"Error getting plugin");
1789 if (cpl_plugin_get_name(plugin) == NULL) {
1790 cpl_pluginlist_delete(list);
1791 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
"Plugin name is NULL");
1793 sprintf(name,
"%s", cpl_plugin_get_name(plugin));
1795 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE)
1797 cpl_pluginlist_delete(list);
1798 FAIL(-1, CPL_ERROR_TYPE_MISMATCH,
"Plugin is not a recipe");
1800 subrecipe = (cpl_recipe *) plugin;
1803 if( cpl_plugin_get_init(plugin)(plugin) != 0)
1805 cpl_plugin_get_deinit(plugin)(plugin);
1806 cpl_pluginlist_delete(list);
1807 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
"Error getting '%s' parameter list",
1811 if (subrecipe->parameters == NULL)
1813 cpl_plugin_get_deinit(plugin)(plugin);
1814 cpl_pluginlist_delete(list);
1815 FAIL(-1, CPL_ERROR_NULL_INPUT,
"Recipe '%s' returned NULL parameter list",
1819 if (propagate(cpl_plugin_get_name(plugin), subrecipe->parameters, parameters, recipe_id, context) != 0)
1821 cpl_plugin_get_deinit(plugin)(plugin);
1822 cpl_pluginlist_delete(list);
1823 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
"Error propagating parameters from recipe '%s'",
1827 cpl_plugin_get_deinit(plugin)(plugin);
1828 cpl_pluginlist_delete(list);
1841 uves_propagate_parameters(
const char *subrecipe,
1842 cpl_parameterlist *parameters,
1843 const char *recipe_id,
const char *context)
1845 if (subrecipe == NULL) {
1846 FAIL(-1, CPL_ERROR_NULL_INPUT,
"Null subrecipe id");
1849 if (strcmp(subrecipe, make_str(UVES_PHYSMOD_ID) ) == 0)
return uves_prop_par(&uves_physmod_get_info, parameters, recipe_id, context);
1850 else if (strcmp(subrecipe, make_str(UVES_ORDERPOS_ID)) == 0)
return uves_prop_par(&uves_orderpos_get_info, parameters, recipe_id, context);
1851 else if (strcmp(subrecipe, make_str(UVES_MBIAS_ID) ) == 0)
return uves_prop_par(&uves_mbias_get_info, parameters, recipe_id, context);
1852 else if (strcmp(subrecipe, make_str(UVES_MDARK_ID) ) == 0)
return uves_prop_par(&uves_mdark_get_info, parameters, recipe_id, context);
1853 else if (strcmp(subrecipe, make_str(UVES_MFLAT_ID) ) == 0)
return uves_prop_par(&uves_mflat_get_info, parameters, recipe_id, context);
1854 else if (strcmp(subrecipe, make_str(UVES_WAVECAL_ID) ) == 0)
return uves_prop_par(&uves_wavecal_get_info, parameters, recipe_id, context);
1855 else if (strcmp(subrecipe, make_str(UVES_RESPONSE_ID)) == 0)
return uves_prop_par(&uves_response_get_info, parameters, recipe_id, context);
1856 else if (strcmp(subrecipe, make_str(UVES_SCIRED_ID) ) == 0)
return uves_prop_par(&uves_scired_get_info, parameters, recipe_id, context);
1857 else if (strcmp(subrecipe, make_str(UVES_REDCHAIN_ID)) == 0)
return uves_prop_par(&uves_redchain_get_info, parameters, recipe_id, context);
1859 FAIL(-1, CPL_ERROR_DATA_NOT_FOUND,
"Unknown recipe: '%s'", subrecipe);
1911 uves_propagate_parameters_step(
const char *step_id,
1912 cpl_parameterlist *parameters,
1913 const char *recipe_id,
const char *context)
1915 cpl_parameterlist *subparameters = NULL;
1916 cpl_parameterlist *(*get_parameters)(void) = NULL;
1920 if (step_id == NULL)
1922 FAIL(-1, CPL_ERROR_NULL_INPUT,
"Null parameter list");
1925 if (parameters == NULL)
1927 FAIL(-1, CPL_ERROR_NULL_INPUT,
"Null parameter list");
1930 if (recipe_id == NULL)
1932 FAIL(-1, CPL_ERROR_NULL_INPUT,
"Null recipe id");
1937 if (strcmp(step_id, UVES_BACKSUB_ID ) == 0) {
1938 get_parameters = uves_backsub_define_parameters;
1939 }
else if (strcmp(step_id, UVES_QCDARK_ID ) == 0) {
1940 get_parameters = uves_qcdark_define_parameters;
1941 }
else if (strcmp(step_id, UVES_EXTRACT_ID ) == 0) {
1943 }
else if (strcmp(step_id, UVES_REBIN_ID ) == 0) {
1945 }
else if (strcmp(step_id, UVES_REDUCE_ID ) == 0) {
1948 FAIL(-1, CPL_ERROR_DATA_NOT_FOUND,
"Unknown sub-step: '%s'", step_id);
1952 if( (subparameters = get_parameters()) == NULL )
1954 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
"Error getting '%s' parameter list", step_id);
1957 if ( propagate(step_id, subparameters, parameters, recipe_id, context) != 0)
1959 cpl_parameterlist_delete(subparameters);
1960 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
"Error propagating '%s' parameters", step_id);
1963 cpl_parameterlist_delete(subparameters);
1979 static cpl_parameter *
1980 create_parameter_enum_int(
const char *name, cpl_type type,
1981 const char *description,
1982 const char *context,
1983 int default_value,
int size,
1988 cpl_parameter *result = NULL;
1990 if (! (1 <= size && size <= 10))
1992 cpl_msg_error(__func__,
"Unsupported enumeration size: %d (max is 10)", size);
1999 uves_parameter_new_enum(result, name,
2003 default_value, size,
2007 uves_parameter_new_enum(result, name,
2011 default_value, size,
2016 uves_parameter_new_enum(result, name,
2020 default_value, size,
2026 uves_parameter_new_enum(result, name,
2030 default_value, size,
2037 uves_parameter_new_enum(result, name,
2041 default_value, size,
2049 uves_parameter_new_enum(result, name,
2053 default_value, size,
2062 uves_parameter_new_enum(result, name,
2066 default_value, size,
2076 uves_parameter_new_enum(result, name,
2080 default_value, size,
2091 uves_parameter_new_enum(result, name,
2095 default_value, size,
2107 uves_parameter_new_enum(result, name,
2111 default_value, size,
2126 static cpl_parameter *
2127 create_parameter_enum_double(
const char *name, cpl_type type,
2128 const char *description,
2129 const char *context,
double default_value,
2130 int size,
double *values)
2134 cpl_parameter *result = NULL;
2136 if (! (1 <= size && size <= 10))
2138 cpl_msg_error(__func__,
"Unsupported enumeration size: %d (max is 10)", size);
2145 uves_parameter_new_enum(result, name,
2149 default_value, size,
2153 uves_parameter_new_enum(result, name,
2157 default_value, size,
2162 uves_parameter_new_enum(result, name,
2166 default_value, size,
2172 uves_parameter_new_enum(result, name,
2176 default_value, size,
2183 uves_parameter_new_enum(result, name,
2187 default_value, size,
2195 uves_parameter_new_enum(result, name,
2199 default_value, size,
2208 uves_parameter_new_enum(result, name,
2212 default_value, size,
2222 uves_parameter_new_enum(result, name,
2226 default_value, size,
2237 uves_parameter_new_enum(result, name,
2241 default_value, size,
2253 uves_parameter_new_enum(result, name,
2257 default_value, size,
2272 static cpl_parameter *
2273 create_parameter_enum_string(
const char *name, cpl_type type,
2274 const char *description,
2275 const char *context,
2276 const char *default_value,
2277 int size,
const char **values)
2281 cpl_parameter *result = NULL;
2283 if (! (1 <= size && size <= 10))
2285 cpl_msg_error(__func__,
"Unsupported enumeration size: %d (max is 10)", size);
2292 uves_parameter_new_enum(result, name,
2296 default_value, size,
2300 uves_parameter_new_enum(result, name,
2304 default_value, size,
2309 uves_parameter_new_enum(result, name,
2313 default_value, size,
2319 uves_parameter_new_enum(result, name,
2323 default_value, size,
2330 uves_parameter_new_enum(result, name,
2334 default_value, size,
2342 uves_parameter_new_enum(result, name,
2346 default_value, size,
2355 uves_parameter_new_enum(result, name,
2359 default_value, size,
2369 uves_parameter_new_enum(result, name,
2373 default_value, size,
2384 uves_parameter_new_enum(result, name,
2388 default_value, size,
2400 uves_parameter_new_enum(result, name,
2404 default_value, size,
2460 propagate(
const char *substep_id,
const cpl_parameterlist *sub_parameters,
2461 cpl_parameterlist *parent_parameters,
2462 const char *parent_id,
const char *context)
2464 const cpl_parameter *p = NULL;
2471 for (p = cpl_parameterlist_get_first_const(sub_parameters);
2473 p = cpl_parameterlist_get_next_const(sub_parameters) )
2475 const char *name = cpl_parameter_get_name(p);
2476 const char *description = cpl_parameter_get_help(p);
2477 const char *subcontext = cpl_parameter_get_context(p);
2478 const char *alias = cpl_parameter_get_alias(p,
2479 CPL_PARAMETER_MODE_CLI);
2480 cpl_parameter_class
class = cpl_parameter_get_class(p);
2481 cpl_type type = cpl_parameter_get_type(p);
2492 if (strstr(name,
"uves.") == name)
2501 if (strstr(name, S) != name)
2503 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
2504 "Recipe id '%s' is not prefix of parameter name '%s'",
2510 if (strstr(subcontext, S) != subcontext)
2512 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
2513 "Recipe id '%s' is not prefix of parameter context '%s'",
2518 if (strstr(name, subcontext) != name)
2520 FAIL(-1, CPL_ERROR_ILLEGAL_INPUT,
2521 "Parameter context '%s' is not prefix of parameter name '%s'",
2526 if (strcmp(subcontext,
"uves") != 0)
2530 cpl_parameter *new_par = NULL;
2535 if (context == NULL)
2537 new_name = uves_sprintf(
"%s.%s", parent_id, name);
2538 new_context = uves_sprintf(
"%s", parent_id);
2541 new_alias = uves_sprintf(
"%s.%s", substep_id, alias);
2550 new_name = uves_sprintf(
"%s.%s.%s", parent_id, context, name);
2552 new_context = uves_sprintf(
"%s.%s", parent_id, context);
2556 new_alias = uves_sprintf(
"%s.%s.%s",
2557 context, substep_id, alias);
2566 if (new_name == NULL || new_context == NULL)
2568 if (new_name != NULL) cpl_free(new_name);
2569 if (new_context != NULL) cpl_free(new_context);
2570 if (new_alias != NULL) cpl_free(new_alias);
2571 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
"Memory allocation failed");
2576 if (
class != CPL_PARAMETER_CLASS_VALUE &&
2577 class != CPL_PARAMETER_CLASS_RANGE &&
2578 class != CPL_PARAMETER_CLASS_ENUM)
2581 cpl_free(new_context);
2582 if (new_alias != NULL) cpl_free(new_alias);
2583 FAIL(-1, CPL_ERROR_TYPE_MISMATCH,
2584 "Unrecognized class of parameter '%s'", name);
2587 if (type != CPL_TYPE_BOOL &&
2588 type != CPL_TYPE_INT &&
2589 type != CPL_TYPE_DOUBLE &&
2590 type != CPL_TYPE_STRING)
2593 cpl_free(new_context);
2594 if (new_alias != NULL) cpl_free(new_alias);
2595 FAIL(-1, CPL_ERROR_UNSUPPORTED_MODE,
"Unsupported type: %s",
2602 case CPL_PARAMETER_CLASS_VALUE:
2606 uves_parameter_new_value(new_par, new_name,
2610 cpl_parameter_get_default_bool(p));
2614 uves_parameter_new_value(new_par, new_name,
2618 cpl_parameter_get_default_int(p));
2621 case CPL_TYPE_DOUBLE:
2622 uves_parameter_new_value(new_par, new_name,
2626 cpl_parameter_get_default_double(p));
2628 case CPL_TYPE_STRING:
2629 uves_parameter_new_value(new_par, new_name,
2633 cpl_parameter_get_default_string(p));
2641 case CPL_PARAMETER_CLASS_RANGE:
2645 int min_int, max_int;
2646 double min_double, max_double;
2649 min_int = cpl_parameter_get_range_min_int(p);
2650 max_int = cpl_parameter_get_range_max_int(p);
2652 uves_parameter_new_range(new_par, new_name,
2656 cpl_parameter_get_default_int(p),
2660 case CPL_TYPE_DOUBLE:
2661 min_double = cpl_parameter_get_range_min_double(p);
2662 max_double = cpl_parameter_get_range_max_double(p);
2664 uves_parameter_new_range(new_par, new_name,
2668 cpl_parameter_get_default_double(p),
2669 min_double, max_double);
2677 case CPL_PARAMETER_CLASS_ENUM:
2678 enum_size = cpl_parameter_get_enum_size(p);
2684 double *values_double;
2685 const char **values_string;
2689 if ( (values_int = cpl_malloc(
sizeof(
int) * enum_size))
2693 cpl_free(new_context);
2694 if (new_alias != NULL) cpl_free(new_alias);
2695 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
2696 "Memory allocation failed");
2698 for (i = 0; i < enum_size; i++)
2700 values_int[i] = cpl_parameter_get_enum_int(p, i);
2703 new_par = create_parameter_enum_int(
2708 cpl_parameter_get_default_int(p),
2711 cpl_free(values_int);
2714 case CPL_TYPE_DOUBLE:
2715 if ( (values_double =
2716 cpl_malloc(
sizeof(
double) * enum_size)) == NULL)
2719 cpl_free(new_context);
2720 if (new_alias != NULL) cpl_free(new_alias);
2721 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
2722 "Memory allocation failed");
2724 for (i = 0; i < enum_size; i++)
2726 values_double[i] = cpl_parameter_get_enum_double(p, i);
2729 new_par = create_parameter_enum_double(
2734 cpl_parameter_get_default_double(p),
2737 cpl_free(values_double);
2741 case CPL_TYPE_STRING:
2742 if ( (values_string =
2743 cpl_malloc(
sizeof(
char *) * enum_size)) == NULL)
2746 cpl_free(new_context);
2747 if (new_alias != NULL) cpl_free(new_alias);
2748 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
2749 "Memory allocation failed");
2751 for (i = 0; i < enum_size; i++)
2753 values_string[i] = cpl_parameter_get_enum_string(p, i);
2756 new_par = create_parameter_enum_string(
2761 cpl_parameter_get_default_string(p),
2764 cpl_free(values_string);
2780 if (new_par == NULL)
2783 cpl_free(new_context);
2784 if (new_alias != NULL) cpl_free(new_alias);
2785 FAIL(-1, CPL_ERROR_ILLEGAL_OUTPUT,
2786 "Propagation of parameter '%s' failed",
2793 cpl_parameter_set_alias(new_par, CPL_PARAMETER_MODE_CLI, new_alias);
2797 cpl_parameterlist_append(parent_parameters, new_par);
2800 cpl_free(new_context);
2801 if (new_alias != NULL) cpl_free(new_alias);
2807 return (cpl_error_get_code() != CPL_ERROR_NONE);
const char * uves_msg_get_domain(void)
Get current message domain.
int uves_msg_get_warnings(void)
Get number of warnings printed so far.
void uves_msg_add_warnings(int n)
Accumulate warnings.
#define uves_msg(...)
Print a message on 'info' or 'debug' level.
cpl_parameterlist * uves_reduce_define_parameters(void)
Define recipe parameters used for reducing a frame.
const char * uves_tostring_cpl_type(cpl_type t)
Convert a CPL type to a string.
#define uves_error_reset()
#define uves_msg_debug(...)
Print a debug message.
cpl_parameterlist * uves_rebin_define_parameters(void)
Define recipe parameters used for rebinning.
void uves_msg_set_domain(const char *d)
Set message domain.