30#include "eris_ifu_error.h"
31#include "eris_ifu_utils.h"
32#include "eris_ifu_functions.h"
33#include "eris_ifu_dfs.h"
34#include "eris_ifu_jitter_interface.h"
35#include "eris_ifu_wavecal_static.h"
36#include "eris_ifu_distortion_static.h"
37#include "eris_ifu_lambda_corr.h"
38#include "eris_ifu_sky_tweak.h"
39#include "eris_ifu_efficiency_response.h"
40#include "eris_utils.h"
41#include <eris_ifu_resample.h>
98 const char *recipeName,
99 jitterModes jitterMode,
100 cpl_parameterlist *pl)
103 cpl_ensure_code(recipeName, CPL_ERROR_NULL_INPUT);
104 cpl_ensure_code(jitterMode >= M_UNSET && jitterMode <= M_TELLURIC, CPL_ERROR_ILLEGAL_INPUT);
105 cpl_ensure_code(pl, CPL_ERROR_NULL_INPUT);
107 cpl_error_code err = CPL_ERROR_NONE;
108 cpl_parameter *p = NULL;
110 char *context = NULL;
112 context = cpl_sprintf(
"eris.%s", recipeName);
115 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"compute-efficiency");
116 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
117 "If True try to compute the efficiency from a STD star spectrum",
119 if (jitterMode == M_SCIENCE) {
120 cpl_parameter_set_default_bool(p, CPL_FALSE);
122 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"compute-efficiency");
123 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
124 cpl_parameterlist_append(pl, p);
127 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"compute-response");
128 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
129 "If True try to compute the response from a STD star spectrum",
131 if (jitterMode == M_SCIENCE) {
132 cpl_parameter_set_default_bool(p, CPL_FALSE);
134 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"compute-response");
135 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
136 cpl_parameterlist_append(pl, p);
139 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"compute-strehl");
140 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
141 "If True try to compute the response from a PSF star spectrum",
143 if (jitterMode == M_SCIENCE) {
144 cpl_parameter_set_default_bool(p, CPL_FALSE);
146 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"compute-strehl");
147 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
148 cpl_parameterlist_append(pl, p);
152 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"strehl_flux_radius");
153 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
154 "PSF Flux integration radius [pixels]. If -1 uses 3 times object PSF FWHM.",
157 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"strehl_flux_radius");
158 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
159 cpl_parameterlist_append(pl, p);
161 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"strehl_bkg-radius-low");
162 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
163 "PSF background inner radii [pixels]. If -1 uses 1.5 times strehl_flux_radius.",
166 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"strehl_bkg-radius-low");
167 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
168 cpl_parameterlist_append(pl, p);
170 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"strehl_bkg-radius-high");
171 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
172 "PSF background outer radius [pixels]. If -1 uses 2.0 times strehl_flux_radius.",
175 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"strehl_bkg-radius-high");
176 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
177 cpl_parameterlist_append(pl, p);
180 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"response-polyfit-deg");
181 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
182 "Degree of polynomial fit of response data points.", context,
185 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"response-polyfit-deg");
186 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
187 cpl_parameterlist_append(pl, p);
189 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"response-polyfit-ksigma-kappa");
190 p = cpl_parameter_new_range(pName, CPL_TYPE_DOUBLE,
191 "Kappa value used to clip data points in polynomial fit of response data points.", context,
194 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"response-polyfit-ksigma-kappa");
195 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
196 cpl_parameterlist_append(pl, p);
201 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"response-polyfit-ksigma-niter");
202 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
203 "Degree of polynomial fit of response data points.", context,
206 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"response-polyfit-ksigma-niter");
207 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
208 cpl_parameterlist_append(pl, p);
239static cpl_error_code eris_ifu_jitter_fill_resample_parameterlist(
char* context,
240 cpl_parameterlist *pl)
243 cpl_parameter *p = NULL;
249 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"method");
250 p = cpl_parameter_new_enum(pName, CPL_TYPE_STRING,
251 "Resampling method", context,
"DRIZZLE",6,
252 "NEAREST",
"LINEAR",
"QUADRATIC",
"RENKA",
253 "DRIZZLE",
"LANCZOS");
254 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"method");
255 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
256 cpl_parameterlist_append(pl, p);
259 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"method.loop-distance");
260 p = cpl_parameter_new_value(pName, CPL_TYPE_INT,
261 "Loop distance used by all (but NEAREST) "
262 "methods to control the number of surrounding "
263 "voxels that are taken into account. "
264 "A small value allow faster re-sampling but may not give good quality",
265 context, LOOP_DISTANCE);
266 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"method.loop-distance");
267 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
268 cpl_parameterlist_append(pl, p);
271 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"method.use-errorweights");
272 p = cpl_parameter_new_value(pName,
274 "Use additional weights of 1/err^2", context,
276 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
277 "method.use-errorweights");
278 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
279 cpl_parameterlist_append(pl, p);
282 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"method.renka.critical-radius");
283 p = cpl_parameter_new_value(pName,
284 CPL_TYPE_DOUBLE,
"Critical radius of the Renka "
286 context, RENKA_CRITICAL_RADIUS);
287 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
288 "method.renka.critical-radius");
289 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
290 cpl_parameterlist_append(pl, p);
293 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"method.lanczos.kernel-size");
294 p = cpl_parameter_new_value(pName,
295 CPL_TYPE_INT,
"Kernel size of the Lanczos "
297 context, LANCZOS_KERNEL_SIZE);
298 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
299 "method.lanczos.kernel-size");
300 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
301 cpl_parameterlist_append(pl, p);
304 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"method.drizzle.downscale-x");
305 p = cpl_parameter_new_value(pName,
306 CPL_TYPE_DOUBLE,
"Drizzle down-scaling factor "
308 context, DRIZZLE_DOWN_SCALING_FACTOR_X);
309 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
310 "method.drizzle.downscale-x");
311 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
312 cpl_parameterlist_append(pl, p);
315 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"method.drizzle.downscale-y");
316 p = cpl_parameter_new_value(pName,
317 CPL_TYPE_DOUBLE,
"Drizzle down-scaling factor "
319 context, DRIZZLE_DOWN_SCALING_FACTOR_Y);
320 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
321 "method.drizzle.downscale-y");
322 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
323 cpl_parameterlist_append(pl, p);
326 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"method.drizzle.downscale-z");
327 p = cpl_parameter_new_value(pName,
328 CPL_TYPE_DOUBLE,
"Drizzle down-scaling factor "
329 "in wavelength direction",
330 context, DRIZZLE_DOWN_SCALING_FACTOR_Z);
331 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
332 "method.drizzle.downscale-z");
333 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
334 cpl_parameterlist_append(pl, p);
337 return cpl_error_get_code();
479static cpl_error_code eris_ifu_jitter_fill_dar_parameterlist(
char* context,
480 jitterModes jitterMode,
481 cpl_parameterlist *pl)
483 cpl_parameter *p = NULL;
489 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"dar-corr");
490 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
491 "Correct Differential Atmospheric Refraction (DAR)",
493 if (jitterMode == M_SCIENCE) {
494 cpl_parameter_set_default_bool(p, CPL_FALSE);
496 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"dar-corr");
497 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
498 cpl_parameterlist_append(pl, p);
500 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"dar-shift-method");
501 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
502 "The method to shift images for DAR correction" , context,
504 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"dar-shift-method");
505 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
506 cpl_parameterlist_append(pl, p);
508 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"dar-shift-length");
509 p = cpl_parameter_new_value(pName, CPL_TYPE_INT,
510 "Kernel length for DAR shift image interpolation",
512 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"dar-shift-length");
513 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
514 cpl_parameterlist_append(pl, p);
516 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"dar-shift-radius");
517 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
518 "Kernel radius for DAR shift image interpolation",
520 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"dar-shift-radius");
521 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
522 cpl_parameterlist_append(pl, p);
525 return cpl_error_get_code();;
551 jitterModes jitterMode,
552 cpl_parameterlist *pl)
555 cpl_ensure_code(context, CPL_ERROR_NULL_INPUT);
556 cpl_ensure_code((jitterMode >= M_UNSET) && (jitterMode <= M_TELLURIC), CPL_ERROR_NULL_INPUT);
557 cpl_ensure_code(pl, CPL_ERROR_NULL_INPUT);
559 cpl_parameter *p = NULL;
564 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"extract-source");
565 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
566 "If True try to extract a point souce",
568 if (jitterMode == M_SCIENCE || jitterMode == M_PUPIL) {
569 cpl_parameter_set_default_bool(p, CPL_FALSE);
571 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract-source");
572 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
573 cpl_parameterlist_append(pl, p);
576 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"mask_method");
577 p = cpl_parameter_new_value(pName, CPL_TYPE_STRING,
578 "Method to specify extraction mask : mask, position, max, fit or optimal",
580 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"mask_method");
581 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
582 cpl_parameterlist_append(pl, p);
585 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"center");
586 p = cpl_parameter_new_value(pName, CPL_TYPE_STRING,
587 "The centre of the circular mask (pixel)",
589 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"center");
590 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
591 cpl_parameterlist_append(pl, p);
595 if(strstr(context,
"stdstar")) {
598 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"radius");
599 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
600 "The radius of the circular mask (pixel)",
602 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"radius");
603 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
604 cpl_parameterlist_append(pl, p);
608 return cpl_error_get_code();;
649 const char *recipeName,
650 jitterModes jitterMode,
651 cpl_parameterlist *pl)
654 cpl_ensure_code(recipeName, CPL_ERROR_NULL_INPUT);
655 cpl_ensure_code(jitterMode >= M_UNSET && jitterMode <= M_TELLURIC, CPL_ERROR_ILLEGAL_INPUT);
656 cpl_ensure_code(pl, CPL_ERROR_NULL_INPUT);
659 cpl_error_code err = CPL_ERROR_NONE;
660 cpl_parameter *p = NULL;
663 char* context = NULL;
666 context = cpl_sprintf(
"eris.%s", recipeName);
671 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"sky_tweak");
672 p = cpl_parameter_new_value(pName, CPL_TYPE_INT,
673 "Use modified sky cube for sky subtraction."
674 "0: don't apply, 1: Davies' method)",
676 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky_tweak");
677 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
678 cpl_parameterlist_append(pl, p);
681 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"skip_sky_oh_align");
683 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
684 "Skip the OH alignment for the SKY",
686 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skip_sky_oh_align");
687 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
688 cpl_parameterlist_append(pl, p);
691 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"skip_oh_align");
693 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
694 "Skip the OH alignment",
696 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skip_oh_align");
697 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
698 cpl_parameterlist_append(pl, p);
701 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"oh_align_poly_order");
703 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
704 "Order of polynomial fit used in the OH alignment for the SKY: [0,3]."
705 " 0 is recommended to prevent extrapolation problems at band edges and in band K."
706 " A higher value may recover a failed correction in case of large flexures, "
707 " but is less accurate at band edges due to polynomial extrapolation",
708 context, OH_POLY_DEG, 0, 3);
709 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"oh_align_poly_order");
710 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
711 cpl_parameterlist_append(pl, p);
715 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"discard_subband");
716 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
717 "Ignore last sub-band in the sky tweaking",
719 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"discard_subband");
720 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
721 cpl_parameterlist_append(pl, p);
724 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"stretch_sky");
725 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
726 "Stretch sky in the sky tweaking",
727 "kmos.kmos_sci_red", FALSE);
728 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"stretch");
729 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
730 cpl_parameterlist_append(pl, p);
733 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"stretch_degree");
734 p = cpl_parameter_new_value(pName, CPL_TYPE_INT,
735 "Stretch polynomial degree",
737 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"stretch_degree");
738 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
739 cpl_parameterlist_append(pl, p);
742 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"stretch_resampling");
743 p = cpl_parameter_new_value(pName, CPL_TYPE_STRING,
744 "Stretch resampling method (linear/spline)",
746 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"stretch_resampling");
747 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
748 cpl_parameterlist_append(pl, p);
751 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"tbsub");
752 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
753 "Subtract thermal background from input cube."
754 "(TRUE (apply) or FALSE (don't apply)",
756 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"tbsub");
757 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
758 cpl_parameterlist_append(pl, p);
761 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"velocity_offset");
762 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
763 "Specify velocity offset correction in km/s for lambda scale",
765 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"velocity_offset");
766 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
767 cpl_parameterlist_append(pl, p);
770 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"bpm_threshold");
771 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
772 "Specify a theshold for the interpolated BPM values",
774 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"bpm_threshold");
775 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
776 cpl_parameterlist_append(pl, p);
778 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"cube.slitlet-detection");
779 p = cpl_parameter_new_enum(pName, CPL_TYPE_STRING,
780 "Specifies the slitlet detection:"
781 " \"DIST\" slitlet distances as detected by distortion recipe "
782 "or \"EDGE\" slitlet edges as detected be wavecalrecipe",
783 context,
"DIST", 3,
"DIST",
"EDGE",
"GRID");
784 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
785 "cube.slitlet-detection");
786 cpl_parameterlist_append(pl, p);
788 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"cube.first-col");
789 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
790 "Specifies the first column offset in case the"
791 " cube.slitlet-detection parameter is set to \"DIST\"",
793 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
795 cpl_parameterlist_append(pl, p);
797 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"cube.fine-tune");
798 p = cpl_parameter_new_value(pName, CPL_TYPE_INT,
799 "Specifies the row interpolation mode: "
800 "0 -> no interpolation, otherwise see eris_ifu_1d_interpolation"
803 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
805 cpl_parameterlist_append(pl, p);
808 eris_ifu_jitter_fill_resample_parameterlist(context, pl);
813 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"subtract-background");
814 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
815 "Subtract median of the images in 2D only", context,
817 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"subtract-background");
818 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
819 cpl_parameterlist_append(pl, p);
822 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"fieldmargin");
823 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
824 "Ad this margin/border (in percent) to the "
825 "resampled image/cube", context, FIELDMARGIN);
826 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"fieldmargin");
827 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
828 cpl_parameterlist_append(pl, p);
831 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"edge-trim");
832 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
833 "Number or pixels to trim for each plane of the input frames. "
834 "It should be smaller in the range [0,5]", context, EDGETRIM,
836 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"edge-trim");
837 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
838 cpl_parameterlist_append(pl, p);
844 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"flux-calibrate");
845 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
846 "If True flux calibrate the extracted spectrum and data cube",
848 if (jitterMode == M_SCIENCE) {
849 cpl_parameter_set_default_bool(p, CPL_FALSE);
851 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"flux-calibrate");
852 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
853 cpl_parameterlist_append(pl, p);
857 eris_ifu_jitter_fill_dar_parameterlist(context, jitterMode, pl);
860 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"fwhm-factor");
861 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
862 "Factor to find 2D-Gauss FWHM. The extraction box is: "
863 "halfbox_x=halfbox_y=fwhm_factor*(fwhm_x+fwhm_y)*0.5.",
865 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"fwhm-factor");
866 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
867 cpl_parameterlist_append(pl, p);
870 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"max-cubes-centres-dist");
871 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
872 "Maximum distance between cube centers to build a mosaic. Mosaic creation "
873 "requires a lot of RAM. Users may trim this value to fit RAM resources",
874 context, 240, 20, 10000);
875 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"max-cubes-centres-dist");
876 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
877 cpl_parameterlist_append(pl, p);
880 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"cube.combine");
881 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
882 "With multi-pointing observations combine cubes into a mosaic",
884 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
886 cpl_parameterlist_append(pl, p);
888 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"derot_corr");
889 p = cpl_parameter_new_value(pName, CPL_TYPE_STRING,
890 "The first column offset to be applied on the science data for distortion correction. "
891 "This effect is visible when the spectrum on one side of the cube wraps to the other side. "
892 "Typical value is within +/- 2 pixels. "
893 "A default correction based on altitude and rotation angle will be applied if this parameter "
894 "set to auto; otherwise the user-speficied number of the shift would be used",
896 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"derot_corr");
897 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
898 cpl_parameterlist_append(pl, p);
900 if(strstr(context,
"jitter") != NULL) {
901 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"aj-method");
902 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
903 "Method used to estimate the sky in case of missing sky frames. "
904 "0: no sky subtraction; "
905 "1: sky is taken from the next in MJD-OBS object frame; "
906 "2: sky is taken from the median of all input sky frames; "
907 "3: sky is taken from the mean of all input sky frames; "
908 "4: sky is taken from the median of user spec. rect. box; "
909 "5: sky is taken from the median of 4 regions at FOV edges; "
910 "6: sky is taken from the median of 8 regions at FOV edges; "
911 "7: sky is taken from each cube slice based on ks-clip based mask computed on collapsed cube."
912 "8: sky is taken from each cube slice based on 25% clip based mask computed on collapsed cube.",
914 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"aj-method");
915 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
916 cpl_parameterlist_append(pl, p);
920 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"sky-box-center");
921 p = cpl_parameter_new_value(pName, CPL_TYPE_STRING,
922 "The centre of the rectangular sky region (pixel). "
923 "two integer numbers each in the range [1,64]. ",
925 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky-box-center");
926 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
927 cpl_parameterlist_append(pl, p);
930 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"sky-box-width");
931 p = cpl_parameter_new_value(pName, CPL_TYPE_STRING,
932 "The rectangular (small) sky region x,y half widths [pixel]."
933 "Two numbers each in the range [0,10].",
935 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky-box-width");
936 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
937 cpl_parameterlist_append(pl, p);
941 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"sky-box-edges-margin");
942 p = cpl_parameter_new_value(pName, CPL_TYPE_STRING,
943 "The (small)number of x, y pixels taken as marging to the "
944 "FOV edges so that sky regions (aj-method=5,6) do not "
945 "include pixels at the edges of the re-sampled image [pixel]."
946 "Two numbers each in the range [0,5].",
948 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky-box-edges-margin");
949 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
950 cpl_parameterlist_append(pl, p);
954 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"sky-est-method");
955 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
956 "If the user has no input sky frame and the sky need to be "
957 "estimated from user defined pixels set by aj-method "
958 "this parameter allow to use the median (0) or the mean (1) [0].",
960 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky-est-method");
961 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
962 cpl_parameterlist_append(pl, p);
966 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"sky-est-kappa");
967 p = cpl_parameter_new_range(pName, CPL_TYPE_DOUBLE,
968 "If the user has no input sky frame and the sky need to be "
969 "estimated from user defined pixels set by aj-method "
970 "this parameter allow to use the kappa of the kappa sigma clip iteration [3].",
971 context, 3., 0., 100.);
972 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky-est-kappa");
973 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
974 cpl_parameterlist_append(pl, p);
977 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"sky-est-niter");
978 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
979 "If the user has no input sky frame and the sky need to be "
980 "estimated from user defined pixels set by aj-method "
981 "this parameter allow to set the number of the kappa sigma clip iterations [5].",
983 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky-est-niter");
984 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
985 cpl_parameterlist_append(pl, p);
987 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"crea-phase3");
988 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
989 "If true crea phase3 compliant data products",
991 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"crea-phase3");
992 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
993 cpl_parameterlist_append(pl, p);
997 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"bpc_iter");
998 p = cpl_parameter_new_value(pName, CPL_TYPE_INT,
999 "No. of iterations for bad pixel correction",
1001 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"bpc_iter");
1002 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
1003 cpl_parameterlist_append(pl, p);
1006 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"chop-nan");
1007 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
1008 "If true chop cube planes with more than 50% NAN pixels",
1009 context, CPL_FALSE);
1010 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"chop-nan");
1011 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
1012 cpl_parameterlist_append(pl, p);
1020 err = cpl_error_get_code();
1060 const char* context,
1061 const char* recipe_name,
1062 const cpl_parameterlist * parlist,
1063 struct stdParamStruct *stdParams,
1064 struct paramStruct *params)
1066 char* param_name = NULL;
1068 cpl_ensure_code(context, CPL_ERROR_NULL_INPUT);
1069 cpl_ensure_code(recipe_name, CPL_ERROR_NULL_INPUT);
1070 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
1071 cpl_ensure_code(stdParams, CPL_ERROR_NULL_INPUT);
1072 cpl_ensure_code(params, CPL_ERROR_NULL_INPUT);
1079 param_name = cpl_sprintf(
"%s.sky_tweak", context);
1080 params->skyTweak = cpl_parameter_get_int(
1081 cpl_parameterlist_find_const(parlist, param_name));
1082 cpl_free(param_name);
1084 param_name = cpl_sprintf(
"%s.skip_sky_oh_align", context);
1085 params->skip_sky_oh_align = cpl_parameter_get_bool(
1086 cpl_parameterlist_find_const(parlist, param_name));
1087 cpl_free(param_name);
1089 param_name = cpl_sprintf(
"%s.skip_oh_align", context);
1090 params->skip_oh_align = cpl_parameter_get_bool(
1091 cpl_parameterlist_find_const(parlist, param_name));
1092 cpl_free(param_name);
1094 param_name = cpl_sprintf(
"%s.discard_subband", context);
1095 params->discard_subband = cpl_parameter_get_bool(
1096 cpl_parameterlist_find_const(parlist, param_name));
1097 cpl_free(param_name);
1099 param_name = cpl_sprintf(
"%s.stretch_sky", context);
1100 params->stretch_sky = cpl_parameter_get_bool(
1101 cpl_parameterlist_find_const(parlist, param_name));
1102 cpl_free(param_name);
1104 param_name = cpl_sprintf(
"%s.stretch_degree", context);
1105 params->stretch_degree = cpl_parameter_get_int(
1106 cpl_parameterlist_find_const(parlist, param_name));
1107 cpl_free(param_name);
1109 param_name = cpl_sprintf(
"%s.stretch_resampling", context);
1110 const char *resamplingInput = cpl_parameter_get_string(
1111 cpl_parameterlist_find_const(parlist, param_name));
1112 cpl_free(param_name);
1115 if (strncasecmp(resamplingInput,
"linear", strlen(
"linear")) == 0) {
1116 params->stretch_resampling = LINEAR;
1117 }
else if (strncasecmp(resamplingInput,
"spline", strlen(
"spline")) == 0) {
1118 params->stretch_resampling = SPLINE;
1121 "Error reading recipe parameter, unknown stretch resampling method %s",
1126 param_name = cpl_sprintf(
"%s.tbsub", context);
1127 params->tbsub = cpl_parameter_get_bool(
1128 cpl_parameterlist_find_const(parlist, param_name));
1129 cpl_free(param_name);
1131 param_name = cpl_sprintf(
"%s.velocity_offset", context);
1132 params->velocityOffset = cpl_parameter_get_double(
1133 cpl_parameterlist_find_const(parlist, param_name));
1134 cpl_free(param_name);
1136 param_name = cpl_sprintf(
"%s.bpm_threshold", context);
1137 params->bpmThreshold = cpl_parameter_get_double(
1138 cpl_parameterlist_find_const(parlist, param_name));
1139 cpl_free(param_name);
1141 param_name = cpl_sprintf(
"%s.cube.first-col", context);
1142 params->firstCol = cpl_parameter_get_double(
1143 cpl_parameterlist_find_const(parlist, param_name));
1144 cpl_free(param_name);
1146 param_name = cpl_sprintf(
"%s.cube.fine-tune", context);
1147 params->fineTuneMode = cpl_parameter_get_int(
1148 cpl_parameterlist_find_const(parlist, param_name));
1149 cpl_free(param_name);
1151 param_name = cpl_sprintf(
"%s.cube.combine", context);
1152 params->combine = cpl_parameter_get_bool(
1153 cpl_parameterlist_find_const(parlist, param_name));
1154 cpl_free(param_name);
1156 param_name = cpl_sprintf(
"%s.cube.slitlet-detection", context);
1157 const char* slitletMode = cpl_parameter_get_string(
1158 cpl_parameterlist_find_const(parlist, param_name));
1159 cpl_free(param_name);
1161 if (strcmp(slitletMode,
"DIST") == 0) {
1162 params->slitletDetectionMode = DISTANCES;
1163 }
else if (strcmp(slitletMode,
"EDGE") == 0) {
1164 params->slitletDetectionMode = EDGES;
1165 }
else if (strcmp(slitletMode,
"GRID") == 0) {
1166 params->slitletDetectionMode = GRID;
1168 params->slitletDetectionMode = UNSET;
1171 param_name = cpl_sprintf(
"%s.cube.first-col", context);
1172 params->firstCol = cpl_parameter_get_double(
1173 cpl_parameterlist_find_const(parlist, param_name));
1174 cpl_free(param_name);
1176 param_name = cpl_sprintf(
"%s.extract-source", context);
1177 params->extractSource = cpl_parameter_get_bool(
1178 cpl_parameterlist_find_const(parlist, param_name));
1179 cpl_free(param_name);
1181 param_name = cpl_sprintf(
"%s.dar-corr", context);
1182 params->darCorrection = cpl_parameter_get_bool(
1183 cpl_parameterlist_find_const(parlist, param_name));
1184 cpl_free(param_name);
1186 param_name = cpl_sprintf(
"%s.dar-shift-method", context);
1187 params->darShiftMethod = cpl_parameter_get_int(
1188 cpl_parameterlist_find_const(parlist, param_name));
1189 cpl_free(param_name);
1191 param_name = cpl_sprintf(
"%s.dar-shift-radius", context);
1192 params-> darShiftWidth = cpl_parameter_get_double(
1193 cpl_parameterlist_find_const(parlist, param_name));
1194 cpl_free(param_name);
1196 param_name = cpl_sprintf(
"%s.dar-shift-length", context);
1197 params->darShiftLength = cpl_parameter_get_int(
1198 cpl_parameterlist_find_const(parlist, param_name));
1199 cpl_free(param_name);
1201 param_name = cpl_sprintf(
"%s.derot_corr", context);
1202 const char* derot_opt = cpl_parameter_get_string(
1203 cpl_parameterlist_find_const(parlist, param_name));
1204 cpl_free(param_name);
1205 if (!strcmp(derot_opt,
"auto"))
1206 params->derot_corr = nan(
"");
1208 sscanf(derot_opt,
"%lf", &(params->derot_corr));
1210 param_name = cpl_sprintf(
"%s.bpc_iter", context);
1211 params->bpc_iter = cpl_parameter_get_int(
1212 cpl_parameterlist_find_const(parlist, param_name));
1213 cpl_free(param_name);
1221 return cpl_error_get_code();
1265 cpl_frameset* frames,
1266 struct stdParamStruct stdParams,
1267 struct paramStruct params,
1268 struct sofStruct *sof)
1270 cpl_image *qualityMask = NULL;
1271 cpl_mask *flatBpm = NULL;
1272 cpl_mask *darkBpm = NULL;
1273 cpl_mask *detlinBpm = NULL;
1274 cpl_mask *masterBpm = NULL;
1275 cpl_vector *lambdaRange = NULL;
1276 cpl_bivector *ref_spectrum = NULL;
1278 cpl_ensure_code(frames != NULL, CPL_ERROR_NULL_INPUT);
1281 cpl_ensure_code(sof != NULL, CPL_ERROR_NULL_INPUT);
1285 const cpl_frame *frame;
1286 deqQualityType qualityType = unspecified;
1287 ifsBand band = UNDEFINED_BAND;
1288 ifsPreopticsScale scale = UNDEFINED_SCALE;
1289 ifsInstrument instrument = UNSET_INSTRUMENT;
1290 cpl_error_code error0 = cpl_error_get_code();
1292 if (frames == NULL) {
1294 "missing frameset");
1296 if (cpl_frameset_is_empty(frames)) {
1298 "SOF file is empty or missing");
1306 frames, &instrument, &band, &scale);
1309 sof->instrument = instrument;
1311 sof->dqi = cpl_image_new(ERIS_IFU_DETECTOR_SIZE_X,
1312 ERIS_IFU_DETECTOR_SIZE_Y, CPL_TYPE_INT);
1315 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_DARK_BP_MAP);
1316 if (frame != NULL) {
1317 darkBpm = cpl_mask_load(cpl_frame_get_filename(frame), 0, 0);
1319 cpl_error_set(cpl_func, error0);
1322 frame = cpl_frameset_find(frames, ERIS_IFU_PRO_FLAT_BPM);
1323 if (frame != NULL) {
1324 flatBpm = cpl_mask_load(cpl_frame_get_filename(frame), 0, 0);
1326 cpl_error_set(cpl_func, error0);
1329 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_DETLIN_BP_MAP);
1330 if (frame != NULL) {
1331 detlinBpm = cpl_mask_load(cpl_frame_get_filename(frame), 0, 0);
1333 cpl_error_set(cpl_func, error0);
1337 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_DARK);
1338 if (frame != NULL) {
1340 qualityType = unspecified;
1341 ifsBand darkBand = UNDEFINED_BAND;
1342 ifsPreopticsScale darkScale = UNDEFINED_SCALE;
1344 darkBand, darkScale, &qualityMask, &qualityType);
1345 if (darkBpm == NULL) {
1347 if (qualityType == flag16bit || qualityType == flag32bit) {
1348 cpl_image_add(sof->dqi, qualityMask);
1352 sof->masterDark = NULL;
1353 cpl_error_set(cpl_func, error0);
1357 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_FLATFIELD);
1358 if (frame != NULL) {
1360 qualityType = unspecified;
1362 band, scale, &qualityMask, &qualityType);
1363 if (flatBpm == NULL) {
1365 if (qualityType == flag16bit || qualityType == flag32bit) {
1366 cpl_image_add(sof->dqi, qualityMask);
1370 sof->masterFlat = NULL;
1371 cpl_error_set(cpl_func, error0);
1375 masterBpm = cpl_mask_new(ERIS_IFU_DETECTOR_SIZE_X,
1376 ERIS_IFU_DETECTOR_SIZE_Y);
1377 if (darkBpm != NULL) {
1378 cpl_mask_or(masterBpm, darkBpm);
1380 if (flatBpm != NULL) {
1381 cpl_mask_or(masterBpm, flatBpm);
1383 if (detlinBpm != NULL) {
1384 cpl_mask_or(masterBpm, detlinBpm);
1386 sof->badPixelMask = cpl_mask_duplicate(masterBpm);
1387 cpl_mask_delete(masterBpm);
1389 cpl_msg_debug(__func__,
"Number of bad pixels in master bad pixel map %lld",
1390 cpl_mask_count(sof->badPixelMask));
1393 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_DISTORTION);
1395 if (frame == NULL) {
1397 "missing \"%s\" tag in the SOF, distortion polynomials",
1398 ERIS_IFU_CALIB_DISTORTION);
1400 if (cpl_fits_count_extensions(cpl_frame_get_filename(frame)) > 2) {
1402 cpl_frame_get_filename(frame),
1403 &sof->distortion, &sof->borders);
1415 sof->distances = NULL;
1416 sof->positions = NULL;
1419 cpl_frame_get_filename(frame), &sof->poly_u, &sof->poly_v);
1422 sof->distortion = NULL;
1423 sof->borders = NULL;
1426 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_DISTANCES);
1428 if (frame == NULL) {
1429 if (params.slitletDetectionMode == DISTANCES) {
1431 "missing \"%s\" tag in the SOF, slitlet distances",
1432 ERIS_IFU_CALIB_DISTANCES);
1435 if (params.slitletDetectionMode != DISTANCES) {
1436 cpl_msg_warning(cpl_func,
1437 "SOF entry with tag %s will be ignored as %s recipe parameter"
1438 " is not set to \"DIST\"", ERIS_IFU_CALIB_DISTANCES,
1439 "cube.slitlet-detection");
1442 cpl_frame_get_filename(frame));
1447 frame = cpl_frameset_find(frames, ERIS_IFU_PRO_DIST_SLIT_POS);
1449 if (frame == NULL) {
1450 if (params.slitletDetectionMode == EDGES) {
1452 "missing \"%s\" tag in the SOF, slitlet positions",
1453 ERIS_IFU_PRO_DIST_SLIT_POS);
1456 if (params.slitletDetectionMode != EDGES) {
1457 cpl_msg_warning(cpl_func,
1458 "SOF entry with tag %s will be ignored as %s recipe parameter"
1459 " is not set to \"EDGE\"", ERIS_IFU_PRO_DIST_SLIT_POS,
1460 "cube.slitlet-detection");
1463 cpl_frame_get_filename(frame));
1464 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1465 cpl_bivector_dump(sof->positions, stdout);
1470 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_WAVE_MAP);
1472 if (frame == NULL) {
1474 "missing \"%s\" tag in the SOF, wavelength map",
1475 ERIS_IFU_CALIB_WAVE_MAP);
1477 sof->waveMap = cpl_image_load(
1478 cpl_frame_get_filename(frame),
1479 CPL_TYPE_UNSPECIFIED, 0, 0);
1481 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_OH_SPEC);
1483 if (frame != NULL) {
1484 const char *ref_filename = NULL;
1487 sof->oh_ref_frame = cpl_frame_duplicate(frame);
1488 lambdaRange = cpl_vector_new(2);
1489 cpl_vector_set(lambdaRange, 0, cpl_image_get_min(sof->waveMap));
1490 cpl_vector_set(lambdaRange, 1, cpl_image_get_max(sof->waveMap));
1492 ref_filename = cpl_frame_get_filename(frame));
1493 ext_cnt = cpl_fits_count_extensions(ref_filename);
1495 const char *ext_name = NULL;
1498 case J_LOW:
case J_SHORT:
case J_MIDDLE:
case J_LONG:
case J_SPIFFI:
1499 ext_name = OH_SPECTRA_J;
1501 case H_LOW:
case H_SHORT:
case H_MIDDLE:
case H_LONG:
case H_SPIFFI:
1502 ext_name = OH_SPECTRA_H;
1504 case K_LOW:
case K_SHORT:
case K_MIDDLE:
case K_LONG:
case K_SPIFFI:
1505 ext_name = OH_SPECTRA_K;
1508 ext_name = OH_SPECTRA_HK;
1512 "unidentified SPIFFIER band selection: %s",
1515 ext_cnt = cpl_fits_find_extension(ref_filename, ext_name);
1519 ref_filename, ext_cnt);
1524 sof->oh_ref_frame = NULL;
1525 sof->oh_ref_peaks = NULL;
1532 eris_ifu_jitter_get_objsky_pairs(sof);
1539 cpl_image_delete(qualityMask);
1540 cpl_mask_delete(flatBpm);
1541 cpl_mask_delete(darkBpm);
1542 cpl_mask_delete(detlinBpm);
1543 cpl_mask_delete(masterBpm);
1544 cpl_vector_delete(lambdaRange);
1545 cpl_bivector_delete(ref_spectrum);
1547 return cpl_error_get_code();
1575 cpl_frameset *frames,
1576 ifsInstrument *instrument,
1578 ifsPreopticsScale *scale)
1582 cpl_ensure_code(frames != NULL, CPL_ERROR_NULL_INPUT);
1585 cpl_error_code retVal = CPL_ERROR_NONE;
1586 cpl_frameset_iterator *iter = NULL;
1587 cpl_propertylist *header = NULL;
1588 cpl_frame *frame = NULL;
1589 cpl_error_code iterError;
1595 iter = cpl_frameset_iterator_new(frames);
1598 frame = cpl_frameset_iterator_get(iter);
1599 if (frame != NULL) {
1600 if (cpl_frame_get_group(frame) == CPL_FRAME_GROUP_RAW) {
1602 header = cpl_propertylist_load(
1603 cpl_frame_get_filename(frame), 0);
1606 cpl_propertylist_delete(header);
1609 iterError = cpl_frameset_iterator_advance(iter, 1);
1610 if (iterError == CPL_ERROR_ACCESS_OUT_OF_RANGE) {
1612 "Found no raw data frames in SOF");
1618 "Found no raw data frames in SOF");
1626 retVal = cpl_error_get_code();
1628 cpl_frameset_iterator_delete(iter);
1667 cpl_frameset *frames,
1668 struct stdParamStruct params,
1669 struct sofStruct *sof)
1672 cpl_ensure_code(frames != NULL, CPL_ERROR_NULL_INPUT);
1673 cpl_ensure_code(params.crh_detection != NULL, CPL_ERROR_NULL_INPUT);
1674 cpl_ensure_code(sof != NULL, CPL_ERROR_NULL_INPUT);
1677 cpl_error_code retVal = CPL_ERROR_NONE;
1678 cpl_frameset_iterator *iter = NULL;
1679 cpl_frame *frame = NULL;
1680 cpl_error_code iterError;
1681 const char* tag = NULL;
1682 cpl_size frameSetSize;
1683 sofModes mode = NODATA;
1686 frameSetSize = cpl_frameset_get_size(frames);
1687 sof->exposureTableSize = (int) frameSetSize;
1688 sof->exposureTable = cpl_calloc(sof->exposureTableSize,
1689 sizeof(
struct exposureEntry));
1691 sof->exposureTableCnt = 0;
1693 iter = cpl_frameset_iterator_new(frames);
1694 frame = cpl_frameset_iterator_get(iter);
1697 while (frame != NULL) {
1698 bool exposureFound =
false;
1699 int ix = sof->exposureTableCnt;
1700 struct exposureEntry *expEntry = &sof->exposureTable[ix];
1703 tag = cpl_frame_get_tag(frame);
1704 if (strcmp(tag, ERIS_IFU_RAW_OBJ) == 0 ||
1705 strcmp(tag, ERIS_IFU_RAW_STD) == 0 ||
1706 strcmp(tag, ERIS_IFU_RAW_PUPIL_LAMP) == 0 ||
1707 strcmp(tag, ERIS_IFU_RAW_PUPIL_SKY) == 0 ||
1708 strcmp(tag, ERIS_IFU_RAW_STD_FLUX) == 0 ||
1709 strcmp(tag, ERIS_IFU_RAW_PSF) == 0) {
1710 expEntry->isObject =
true;
1712 exposureFound =
true;
1713 if (strcmp(tag, ERIS_IFU_RAW_OBJ) == 0) {
1715 }
else if (strcmp(tag, ERIS_IFU_RAW_STD) == 0) {
1717 }
else if (strcmp(tag, ERIS_IFU_RAW_STD_FLUX) == 0) {
1719 }
else if (strcmp(tag, ERIS_IFU_RAW_PSF) == 0) {
1721 }
else if (strcmp(tag, ERIS_IFU_RAW_PUPIL_LAMP) == 0||
1722 strcmp(tag, ERIS_IFU_RAW_PUPIL_SKY) == 0) {
1726 if (strcmp(tag, ERIS_IFU_RAW_SKY) == 0 ||
1727 strcmp(tag, ERIS_IFU_RAW_OBJ_SKY) == 0 ||
1728 strcmp(tag, ERIS_IFU_RAW_STD_SKY) ==0 ||
1729 strcmp(tag, ERIS_IFU_RAW_STD_FLUX_SKY) ==0 ||
1730 strcmp(tag, ERIS_IFU_RAW_PSF_SKY) == 0) {
1731 expEntry->isObject =
false;
1732 exposureFound =
true;
1733 if (strcmp(tag, ERIS_IFU_RAW_SKY) == 0) {
1734 mode = IGNORE_SOF_MODE;
1735 }
else if (strcmp(tag, ERIS_IFU_RAW_OBJ_SKY) == 0) {
1737 }
else if (strcmp(tag, ERIS_IFU_RAW_STD_SKY) == 0) {
1739 }
else if (strcmp(tag, ERIS_IFU_RAW_STD_FLUX_SKY) == 0) {
1741 }
else if (strcmp(tag, ERIS_IFU_RAW_PSF_SKY) == 0) {
1743 }
else if (strcmp(tag, ERIS_IFU_RAW_PUPIL_SKY) == 0) {
1747 if (exposureFound) {
1748 if (sof->mode == NODATA) {
1749 if (mode != NODATA) {
1750 if (mode != IGNORE_SOF_MODE) {
1755 "Cannot interpret tag %s", tag);
1758 if (mode != IGNORE_SOF_MODE) {
1759 if (mode != sof->mode) {
1761 "Do not mix different input raw data types like"
1762 " SCIENCE, PSF, STD STAR ...");
1766 expEntry->dqiImage = cpl_image_new(ERIS_IFU_DETECTOR_SIZE_X,
1767 ERIS_IFU_DETECTOR_SIZE_Y, CPL_TYPE_INT);
1768 const char *filename = cpl_frame_get_filename(frame);
1769 expEntry->frame = frame;
1771 frame, params.rawImageCorrectionMask, expEntry->dqiImage);
1772 expEntry->hdr = cpl_propertylist_load( filename, 0);
1774 expEntry->obsDate = cpl_propertylist_get_double(
1775 expEntry->hdr, FHDR_MJD_OBS);
1776 expEntry->centeredObsDate =
1777 expEntry->obsDate + (expEntry->dit /2.)/86400.;
1778 if(cpl_propertylist_has(expEntry->hdr,
"ESO TEL ALT")) {
1779 expEntry->alt = cpl_propertylist_get_double(
1780 expEntry->hdr,
"ESO TEL ALT");
1782 if(cpl_propertylist_has(expEntry->hdr,
"ESO ADA ABSROT START")) {
1783 expEntry->rot = cpl_propertylist_get_double(
1784 expEntry->hdr,
"ESO ADA ABSROT START");
1786 expEntry->derot_corr = eris_ifu_auto_derot_corr(expEntry->alt, expEntry->rot);
1787 expEntry->skyIndex = -1;
1788 expEntry->cube = NULL;
1789 expEntry->cubeHdr = NULL;
1790 expEntry->darkSubtrImage = NULL;
1791 expEntry->skySubtrImage = NULL;
1793 cpl_msg_debug(__func__,
"Number of bad pixels in master bad pixel map %lld",
1794 cpl_mask_count(expEntry->badPixelMask));
1795 cpl_mask_or(expEntry->badPixelMask, sof->badPixelMask);
1797 expEntry->badPixelMask);
1798 cpl_image_add(expEntry->dqiImage, sof->dqi);
1800 if (params.productDepth >= PD_DEBUG) {
1801 char *filename2 = NULL;
1802 filename2 = cpl_sprintf(
"%s_%3.3d",
1803 ERIS_IFU_PRO_JITTER_DBG_RAW_FN, ix);
1805 filename2, 1, NULL);
1807 filename2 = cpl_sprintf(
"%s_%3.3d.fits",
1808 ERIS_IFU_PRO_JITTER_DBG_RAW_FN, ix);
1809 cpl_image_save(expEntry->dqiImage, filename2,
1810 CPL_TYPE_INT, NULL, CPL_IO_EXTEND);
1815 sof->exposureTableCnt++;
1818 iterError = cpl_frameset_iterator_advance(iter, 1);
1819 if (iterError == CPL_ERROR_ACCESS_OUT_OF_RANGE) {
1822 frame = cpl_frameset_iterator_get(iter);
1825 if (sof->objectCnt == 0) {
1827 "No object frame tag found in SOF file, either"
1828 " OBJ, STD, STD_FLUX, PSF_CALIBRATOR, PUPIL_LAMP is missing");
1830 cpl_msg_info(cpl_func,
"Number of object frames to be processed: %d", sof->objectCnt);
1835 retVal = cpl_error_get_code();
1837 cpl_frameset_iterator_delete(iter);
1842cpl_error_code eris_ifu_jitter_get_objsky_pairs(
struct sofStruct *sof)
1844 cpl_error_code retVal = CPL_ERROR_NONE;
1847 int *skyIndex = NULL;
1848 double *skyDate = NULL;
1852 cpl_ensure_code(sof, CPL_ERROR_NULL_INPUT);
1853 cpl_ensure_code((sof->objectCnt <= sof->exposureTableCnt),
1854 CPL_ERROR_ILLEGAL_INPUT);
1859 if (sof->objectCnt != sof->exposureTableCnt) {
1861 skyCnt = sof->exposureTableCnt - sof->objectCnt;
1862 skyIndex = cpl_calloc(skyCnt,
sizeof(
int));
1863 skyDate = cpl_calloc(skyCnt,
sizeof(
double));
1867 for (
int ix=0; ix < sof->exposureTableCnt; ix++) {
1868 struct exposureEntry *expEntry = &sof->exposureTable[ix];
1869 if (expEntry->isObject ==
false) {
1870 skyIndex[skyIdx] = ix;
1871 skyDate[skyIdx] = expEntry->centeredObsDate;
1877 for (
int ix=0; ix < sof->exposureTableCnt; ix++) {
1878 struct exposureEntry *expEntry = &sof->exposureTable[ix];
1879 if (expEntry->isObject ==
true) {
1880 obsDate = expEntry->centeredObsDate;
1882 minDiff = fabs(obsDate - skyDate[0]);
1883 for (
int sx = 1; sx<skyCnt; sx++) {
1884 double diff = fabs(obsDate - skyDate[sx]);
1885 if (diff < minDiff) {
1890 expEntry->skyIndex = skyIndex[skyIdx];
1898 retVal = cpl_error_get_code();
1906void eris_free_exposureEntry(
struct exposureEntry* ee) {
1909 if(ee->frame) cpl_frame_delete(ee->frame);
1910 if(ee->hdr) cpl_propertylist_delete(ee->hdr);
1912 if(ee->dqiImage) cpl_image_delete(ee->dqiImage);
1914 if(ee->cubeBpm) cpl_imagelist_delete(ee->cubeBpm);
1915 if(ee->cubeHdr) cpl_propertylist_delete(ee->cubeHdr);
1916 if(ee->badPixelMask) cpl_mask_delete(ee->badPixelMask);
ifsPreopticsScale eris_ifu_get_preopticsScale(cpl_propertylist *header)
Return the the pre-optics scaling.
cpl_bivector * eris_ifu_load_slit_positions(const char *filename)
Load slitlet position bivector from a table.
float eris_ifu_get_dit(cpl_propertylist *header)
Get the detector integration time (DIT) from FITS header.
cpl_error_code eris_ifu_load_distortion_polynomials(const char *filename, cpl_polynomial ***polynomials, cpl_table **borders)
Load distortion polynomials and slitlet borders from a table.
hdrl_image * eris_ifu_load_cal_image_frame(const cpl_frame *frame, ifsBand band, ifsPreopticsScale scale, cpl_image **qualImage, deqQualityType *qualType)
Load a calibration image from a frame.
cpl_error_code eris_ifu_dfs_set_groups(cpl_frameset *self)
Set the frame group (RAW, CALIB, or PRODUCT) for all frames in a frameset.
cpl_vector * eris_ifu_load_distances(const char *filename)
Load slitlet distance vector from a table.
ifsBand eris_ifu_get_band(const cpl_propertylist *header)
Determine preoptic band.
cpl_error_code eris_ifu_load_distortion_polynomials_old(const char *filename, cpl_polynomial **poly_u, cpl_polynomial **poly_v)
Load old-format distortion polynomials from a table.
#define SET_ERROR_MSG(code, msg)
Set a new error code together with a custom error message.
#define CHECK_ERROR_STATE(void)
Check the CPL error state, and exit the try-block if not CPL_ERROR_NONE.
#define BRK_WITH_ERROR_MSG(code,...)
Set a new CPL error, and exit the try-block.
#define TRY
Beginning of a TRY-block.
#define CATCH
End of a TRY-block, beginning of a CATCH-block.
#define BRK_IF_NULL(function)
If function is or returns a NULL pointer, then the try-block is exited.
hdrl_image * eris_ifu_load_exposure_frame(const cpl_frame *frame, int exposureCorrectionMode, cpl_image *dqi)
Load a raw detector exposure from a frame with optional corrections.
cpl_error_code eris_ifu_fetch_std_param(const cpl_parameterlist *parlist, const char *recipename, struct stdParamStruct *stdParams)
Fetch standard parameters from parameter list into structure.
cpl_error_code eris_ifu_add_std_params(cpl_parameterlist *pl, const char *recipename)
Add standard recipe parameters to a parameter list.
ifsInstrument eris_ifu_get_instrument_frame(cpl_frame *frame)
Get instrument identifier from a CPL frame.
cpl_error_code eris_ifu_jitter_processSof(cpl_frameset *frames, struct stdParamStruct stdParams, struct paramStruct params, struct sofStruct *sof)
Process SOF (Set of Frames) file and load all calibration data.
cpl_error_code eris_ifu_stdstar_fill_common_parameterlist(const char *recipeName, jitterModes jitterMode, cpl_parameterlist *pl)
Fill parameter list with standard star-specific parameters.
cpl_error_code eris_ifu_jitter_get_objsky_exposures(cpl_frameset *frames, struct stdParamStruct params, struct sofStruct *sof)
Load all object and sky exposures from frameset.
cpl_error_code eris_ifu_jitter_fetch_params(const char *context, const char *recipe_name, const cpl_parameterlist *parlist, struct stdParamStruct *stdParams, struct paramStruct *params)
Fetch and parse jitter recipe parameters from parameter list.
cpl_error_code eris_ifu_jitter_fill_extract_parameterlist(char *context, jitterModes jitterMode, cpl_parameterlist *pl)
Fill parameter list with source extraction parameters.
cpl_error_code eris_ifu_jitter_get_instrument_settings(cpl_frameset *frames, ifsInstrument *instrument, ifsBand *band, ifsPreopticsScale *scale)
Extract instrument configuration from frameset.
cpl_error_code eris_ifu_jitter_fill_common_parameterlist(const char *recipeName, jitterModes jitterMode, cpl_parameterlist *pl)
Fill parameter list with common jitter recipe parameters.
cpl_vector * eris_ifu_lcorr_get_peak_lambdas(const cpl_bivector *spectrum, double min_frac, cpl_vector *range)
Detect and refine emission line peak wavelengths using Gaussian fitting.
cpl_bivector * eris_ifu_lcorr_read_OH_reference_spectrum(const char *filename, cpl_size ext_number)
Read OH reference spectrum from FITS file.
void eris_ifu_free_string(char **item)
Free memory and set pointer to null.
void eris_ifu_free_double_array(double **item)
Free memory and set pointer to null.
const char * eris_ifu_get_bandString(ifsBand band)
Convert band enum to string.
void eris_ifu_free_int_array(int **item)
Free memory and set pointer to null.
cpl_mask * eris_ifu_quality2bp_mask(const cpl_image *qualityMask, deqQualityType qualityType)
transform input image (quality mask) to output mask with given bit code
cpl_error_code eris_ifu_save_hdrl_image_dbg(const hdrl_image *hdrl_img, const char *filename, int singlefile, const cpl_propertylist *pl)
Save HDRL image for debugging (data + error + mask)
cpl_error_code eris_check_error_code(const char *func_id)
handle CPL errors
cpl_error_code hdrl_image_reject_from_mask(hdrl_image *self, const cpl_mask *map)
set bpm of hdrl_image
cpl_mask * hdrl_image_get_mask(hdrl_image *himg)
get cpl bad pixel mask from image
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
void hdrl_imagelist_delete(hdrl_imagelist *himlist)
Free all memory used by a hdrl_imagelist object including the images.