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>
42cpl_error_code eris_ifu_stdstar_fill_common_parameterlist(
43 const char *recipeName,
44 jitterModes jitterMode,
45 cpl_parameterlist *pl)
48 cpl_ensure_code(recipeName, CPL_ERROR_NULL_INPUT);
49 cpl_ensure_code(jitterMode >= M_UNSET && jitterMode <= M_TELLURIC, CPL_ERROR_ILLEGAL_INPUT);
50 cpl_ensure_code(pl, CPL_ERROR_NULL_INPUT);
52 cpl_error_code err = CPL_ERROR_NONE;
53 cpl_parameter *p = NULL;
57 context = cpl_sprintf(
"eris.%s", recipeName);
60 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"compute-efficiency");
61 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
62 "If True try to compute the efficiency from a STD star spectrum",
64 if (jitterMode == M_SCIENCE) {
65 cpl_parameter_set_default_bool(p, CPL_FALSE);
67 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"compute-efficiency");
68 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
69 cpl_parameterlist_append(pl, p);
72 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"compute-response");
73 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
74 "If True try to compute the response from a STD star spectrum",
76 if (jitterMode == M_SCIENCE) {
77 cpl_parameter_set_default_bool(p, CPL_FALSE);
79 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"compute-response");
80 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
81 cpl_parameterlist_append(pl, p);
84 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"compute-strehl");
85 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
86 "If True try to compute the response from a PSF star spectrum",
88 if (jitterMode == M_SCIENCE) {
89 cpl_parameter_set_default_bool(p, CPL_FALSE);
91 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"compute-strehl");
92 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
93 cpl_parameterlist_append(pl, p);
97 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"strehl_flux_radius");
98 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
99 "PSF Flux integration radius [pixels]. If -1 uses 3 times object PSF FWHM.",
102 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"strehl_flux_radius");
103 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
104 cpl_parameterlist_append(pl, p);
106 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"strehl_bkg-radius-low");
107 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
108 "PSF background inner radii [pixels]. If -1 uses 1.5 times strehl_flux_radius.",
111 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"strehl_bkg-radius-low");
112 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
113 cpl_parameterlist_append(pl, p);
115 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"strehl_bkg-radius-high");
116 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
117 "PSF background outer radius [pixels]. If -1 uses 2.0 times strehl_flux_radius.",
120 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"strehl_bkg-radius-high");
121 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
122 cpl_parameterlist_append(pl, p);
125 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"response-polyfit-deg");
126 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
127 "Degree of polynomial fit of response data points.", context,
130 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"response-polyfit-deg");
131 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
132 cpl_parameterlist_append(pl, p);
134 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"response-polyfit-ksigma-kappa");
135 p = cpl_parameter_new_range(pName, CPL_TYPE_DOUBLE,
136 "Kappa value used to clip data points in polynomial fit of response data points.", context,
139 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"response-polyfit-ksigma-kappa");
140 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
141 cpl_parameterlist_append(pl, p);
146 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"response-polyfit-ksigma-niter");
147 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
148 "Degree of polynomial fit of response data points.", context,
151 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"response-polyfit-ksigma-niter");
152 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
153 cpl_parameterlist_append(pl, p);
160static cpl_error_code eris_ifu_jitter_fill_resample_parameterlist(
char* context,
161 cpl_parameterlist *pl)
164 cpl_parameter *p = NULL;
170 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"method");
171 p = cpl_parameter_new_enum(pName, CPL_TYPE_STRING,
172 "Resampling method", context,
"DRIZZLE",6,
173 "NEAREST",
"LINEAR",
"QUADRATIC",
"RENKA",
174 "DRIZZLE",
"LANCZOS");
175 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"method");
176 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
177 cpl_parameterlist_append(pl, p);
180 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"method.loop-distance");
181 p = cpl_parameter_new_value(pName, CPL_TYPE_INT,
182 "Loop distance used by all (but NEAREST) "
183 "methods to control the number of surrounding "
184 "voxels that are taken into account. "
185 "A small value allow faster re-sampling but may not give good quality",
186 context, LOOP_DISTANCE);
187 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"method.loop-distance");
188 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
189 cpl_parameterlist_append(pl, p);
192 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"method.use-errorweights");
193 p = cpl_parameter_new_value(pName,
195 "Use additional weights of 1/err^2", context,
197 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
198 "method.use-errorweights");
199 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
200 cpl_parameterlist_append(pl, p);
203 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"method.renka.critical-radius");
204 p = cpl_parameter_new_value(pName,
205 CPL_TYPE_DOUBLE,
"Critical radius of the Renka "
207 context, RENKA_CRITICAL_RADIUS);
208 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
209 "method.renka.critical-radius");
210 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
211 cpl_parameterlist_append(pl, p);
214 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"method.lanczos.kernel-size");
215 p = cpl_parameter_new_value(pName,
216 CPL_TYPE_INT,
"Kernel size of the Lanczos "
218 context, LANCZOS_KERNEL_SIZE);
219 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
220 "method.lanczos.kernel-size");
221 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
222 cpl_parameterlist_append(pl, p);
225 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"method.drizzle.downscale-x");
226 p = cpl_parameter_new_value(pName,
227 CPL_TYPE_DOUBLE,
"Drizzle down-scaling factor "
229 context, DRIZZLE_DOWN_SCALING_FACTOR_X);
230 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
231 "method.drizzle.downscale-x");
232 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
233 cpl_parameterlist_append(pl, p);
236 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"method.drizzle.downscale-y");
237 p = cpl_parameter_new_value(pName,
238 CPL_TYPE_DOUBLE,
"Drizzle down-scaling factor "
240 context, DRIZZLE_DOWN_SCALING_FACTOR_Y);
241 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
242 "method.drizzle.downscale-y");
243 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
244 cpl_parameterlist_append(pl, p);
247 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"method.drizzle.downscale-z");
248 p = cpl_parameter_new_value(pName,
249 CPL_TYPE_DOUBLE,
"Drizzle down-scaling factor "
250 "in wavelength direction",
251 context, DRIZZLE_DOWN_SCALING_FACTOR_Z);
252 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
253 "method.drizzle.downscale-z");
254 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
255 cpl_parameterlist_append(pl, p);
258 return cpl_error_get_code();
378static cpl_error_code eris_ifu_jitter_fill_dar_parameterlist(
char* context,
379 jitterModes jitterMode,
380 cpl_parameterlist *pl)
382 cpl_parameter *p = NULL;
388 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"dar-corr");
389 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
390 "Correct Differential Atmospheric Refraction (DAR)",
392 if (jitterMode == M_SCIENCE) {
393 cpl_parameter_set_default_bool(p, CPL_FALSE);
395 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"dar-corr");
396 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
397 cpl_parameterlist_append(pl, p);
399 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"dar-shift-method");
400 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
401 "The method to shift images for DAR correction" , context,
403 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"dar-shift-method");
404 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
405 cpl_parameterlist_append(pl, p);
407 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"dar-shift-length");
408 p = cpl_parameter_new_value(pName, CPL_TYPE_INT,
409 "Kernel length for DAR shift image interpolation",
411 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"dar-shift-length");
412 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
413 cpl_parameterlist_append(pl, p);
415 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"dar-shift-radius");
416 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
417 "Kernel radius for DAR shift image interpolation",
419 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"dar-shift-radius");
420 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
421 cpl_parameterlist_append(pl, p);
424 return cpl_error_get_code();;
426cpl_error_code eris_ifu_jitter_fill_extract_parameterlist(
char* context,
427 jitterModes jitterMode,
428 cpl_parameterlist *pl)
431 cpl_ensure_code(context, CPL_ERROR_NULL_INPUT);
432 cpl_ensure_code((jitterMode >= M_UNSET) && (jitterMode <= M_TELLURIC), CPL_ERROR_NULL_INPUT);
433 cpl_ensure_code(pl, CPL_ERROR_NULL_INPUT);
435 cpl_parameter *p = NULL;
440 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"extract-source");
441 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
442 "If True try to extract a point souce",
444 if (jitterMode == M_SCIENCE || jitterMode == M_PUPIL) {
445 cpl_parameter_set_default_bool(p, CPL_FALSE);
447 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract-source");
448 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
449 cpl_parameterlist_append(pl, p);
452 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"mask_method");
453 p = cpl_parameter_new_value(pName, CPL_TYPE_STRING,
454 "Method to specify extraction mask : mask, position, max, fit or optimal",
456 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"mask_method");
457 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
458 cpl_parameterlist_append(pl, p);
461 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"center");
462 p = cpl_parameter_new_value(pName, CPL_TYPE_STRING,
463 "The centre of the circular mask (pixel)",
465 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"center");
466 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
467 cpl_parameterlist_append(pl, p);
471 if(strstr(context,
"stdstar")) {
474 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"radius");
475 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
476 "The radius of the circular mask (pixel)",
478 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"radius");
479 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
480 cpl_parameterlist_append(pl, p);
484 return cpl_error_get_code();;
487cpl_error_code eris_ifu_jitter_fill_common_parameterlist(
488 const char *recipeName,
489 jitterModes jitterMode,
490 cpl_parameterlist *pl)
493 cpl_ensure_code(recipeName, CPL_ERROR_NULL_INPUT);
494 cpl_ensure_code(jitterMode >= M_UNSET && jitterMode <= M_TELLURIC, CPL_ERROR_ILLEGAL_INPUT);
495 cpl_ensure_code(pl, CPL_ERROR_NULL_INPUT);
498 cpl_error_code err = CPL_ERROR_NONE;
499 cpl_parameter *p = NULL;
502 char* context = NULL;
505 context = cpl_sprintf(
"eris.%s", recipeName);
507 eris_ifu_add_std_params(pl, recipeName);
510 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"sky_tweak");
511 p = cpl_parameter_new_value(pName, CPL_TYPE_INT,
512 "Use modified sky cube for sky subtraction."
513 "0: don't apply, 1: Davies' method)",
515 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky_tweak");
516 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
517 cpl_parameterlist_append(pl, p);
520 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"skip_sky_oh_align");
522 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
523 "Skip the OH alignment for the SKY",
525 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skip_sky_oh_align");
526 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
527 cpl_parameterlist_append(pl, p);
530 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"skip_oh_align");
532 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
533 "Skip the OH alignment",
535 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skip_oh_align");
536 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
537 cpl_parameterlist_append(pl, p);
540 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"oh_align_poly_order");
542 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
543 "Order of polynomial fit used in the OH alignment for the SKY: [0,3]."
544 " 0 is recommended to prevent extrapolation problems at band edges and in band K."
545 " A higher value may recover a failed correction in case of large flexures, "
546 " but is less accurate at band edges due to polynomial extrapolation",
547 context, OH_POLY_DEG, 0, 3);
548 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"oh_align_poly_order");
549 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
550 cpl_parameterlist_append(pl, p);
554 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"discard_subband");
555 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
556 "Ignore last sub-band in the sky tweaking",
558 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"discard_subband");
559 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
560 cpl_parameterlist_append(pl, p);
563 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"stretch_sky");
564 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
565 "Stretch sky in the sky tweaking",
566 "kmos.kmos_sci_red", FALSE);
567 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"stretch");
568 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
569 cpl_parameterlist_append(pl, p);
572 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"stretch_degree");
573 p = cpl_parameter_new_value(pName, CPL_TYPE_INT,
574 "Stretch polynomial degree",
576 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"stretch_degree");
577 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
578 cpl_parameterlist_append(pl, p);
581 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"stretch_resampling");
582 p = cpl_parameter_new_value(pName, CPL_TYPE_STRING,
583 "Stretch resampling method (linear/spline)",
585 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"stretch_resampling");
586 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
587 cpl_parameterlist_append(pl, p);
590 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"tbsub");
591 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
592 "Subtract thermal background from input cube."
593 "(TRUE (apply) or FALSE (don't apply)",
595 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"tbsub");
596 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
597 cpl_parameterlist_append(pl, p);
600 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"velocity_offset");
601 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
602 "Specify velocity offset correction in km/s for lambda scale",
604 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"velocity_offset");
605 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
606 cpl_parameterlist_append(pl, p);
609 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"bpm_threshold");
610 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
611 "Specify a theshold for the interpolated BPM values",
613 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"bpm_threshold");
614 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
615 cpl_parameterlist_append(pl, p);
617 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"cube.slitlet-detection");
618 p = cpl_parameter_new_enum(pName, CPL_TYPE_STRING,
619 "Specifies the slitlet detection:"
620 " \"DIST\" slitlet distances as detected by distortion recipe "
621 "or \"EDGE\" slitlet edges as detected be wavecalrecipe",
622 context,
"DIST", 3,
"DIST",
"EDGE",
"GRID");
623 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
624 "cube.slitlet-detection");
625 cpl_parameterlist_append(pl, p);
627 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"cube.first-col");
628 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
629 "Specifies the first column offset in case the"
630 " cube.slitlet-detection parameter is set to \"DIST\"",
632 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
634 cpl_parameterlist_append(pl, p);
636 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"cube.fine-tune");
637 p = cpl_parameter_new_value(pName, CPL_TYPE_INT,
638 "Specifies the row interpolation mode: "
639 "0 -> no interpolation, otherwise see eris_ifu_1d_interpolation"
642 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
644 cpl_parameterlist_append(pl, p);
647 eris_ifu_jitter_fill_resample_parameterlist(context, pl);
652 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"subtract-background");
653 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
654 "Subtract median of the images in 2D only", context,
656 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"subtract-background");
657 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
658 cpl_parameterlist_append(pl, p);
661 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"fieldmargin");
662 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
663 "Ad this margin/border (in percent) to the "
664 "resampled image/cube", context, FIELDMARGIN);
665 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"fieldmargin");
666 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
667 cpl_parameterlist_append(pl, p);
670 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"edge-trim");
671 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
672 "Number or pixels to trim for each plane of the input frames. "
673 "It should be smaller in the range [0,5]", context, EDGETRIM,
675 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"edge-trim");
676 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
677 cpl_parameterlist_append(pl, p);
680 eris_ifu_jitter_fill_extract_parameterlist(context, jitterMode, pl);
683 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"flux-calibrate");
684 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
685 "If True flux calibrate the extracted spectrum and data cube",
687 if (jitterMode == M_SCIENCE) {
688 cpl_parameter_set_default_bool(p, CPL_FALSE);
690 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"flux-calibrate");
691 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
692 cpl_parameterlist_append(pl, p);
696 eris_ifu_jitter_fill_dar_parameterlist(context, jitterMode, pl);
699 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"fwhm-factor");
700 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
701 "Factor to find 2D-Gauss FWHM. The extraction box is: "
702 "halfbox_x=halfbox_y=fwhm_factor*(fwhm_x+fwhm_y)*0.5.",
704 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"fwhm-factor");
705 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
706 cpl_parameterlist_append(pl, p);
709 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"max-cubes-centres-dist");
710 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
711 "Maximum distance between cube centers to build a mosaic. Mosaic creation "
712 "requires a lot of RAM. Users may trim this value to fit RAM resources",
713 context, 240, 20, 10000);
714 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"max-cubes-centres-dist");
715 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
716 cpl_parameterlist_append(pl, p);
719 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"cube.combine");
720 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
721 "With multi-pointing observations combine cubes into a mosaic",
723 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
725 cpl_parameterlist_append(pl, p);
727 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"derot_corr");
728 p = cpl_parameter_new_value(pName, CPL_TYPE_STRING,
729 "The first column offset to be applied on the science data for distortion correction. "
730 "This effect is visible when the spectrum on one side of the cube wraps to the other side. "
731 "Typical value is within +/- 2 pixels. "
732 "A default correction based on altitude and rotation angle will be applied if this parameter "
733 "set to auto; otherwise the user-speficied number of the shift would be used",
735 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"derot_corr");
736 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
737 cpl_parameterlist_append(pl, p);
739 if(strstr(context,
"jitter") != NULL) {
740 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"aj-method");
741 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
742 "Method used to estimate the sky in case of missing sky frames. "
743 "0: no sky subtraction; "
744 "1: sky is taken from the next in MJD-OBS object frame; "
745 "2: sky is taken from the median of all input sky frames; "
746 "3: sky is taken from the mean of all input sky frames; "
747 "4: sky is taken from the median of user spec. rect. box; "
748 "5: sky is taken from the median of 4 regions at FOV edges; "
749 "6: sky is taken from the median of 8 regions at FOV edges; "
750 "7: sky is taken from each cube slice based on ks-clip based mask computed on collapsed cube."
751 "8: sky is taken from each cube slice based on 25% clip based mask computed on collapsed cube.",
753 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"aj-method");
754 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
755 cpl_parameterlist_append(pl, p);
759 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"sky-box-center");
760 p = cpl_parameter_new_value(pName, CPL_TYPE_STRING,
761 "The centre of the rectangular sky region (pixel). "
762 "two integer numbers each in the range [1,64]. ",
764 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky-box-center");
765 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
766 cpl_parameterlist_append(pl, p);
769 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"sky-box-width");
770 p = cpl_parameter_new_value(pName, CPL_TYPE_STRING,
771 "The rectangular (small) sky region x,y half widths [pixel]."
772 "Two numbers each in the range [0,10].",
774 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky-box-width");
775 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
776 cpl_parameterlist_append(pl, p);
780 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"sky-box-edges-margin");
781 p = cpl_parameter_new_value(pName, CPL_TYPE_STRING,
782 "The (small)number of x, y pixels taken as marging to the "
783 "FOV edges so that sky regions (aj-method=5,6) do not "
784 "include pixels at the edges of the re-sampled image [pixel]."
785 "Two numbers each in the range [0,5].",
787 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky-box-edges-margin");
788 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
789 cpl_parameterlist_append(pl, p);
793 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"sky-est-method");
794 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
795 "If the user has no input sky frame and the sky need to be "
796 "estimated from user defined pixels set by aj-method "
797 "this parameter allow to use the median (0) or the mean (1) [0].",
799 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky-est-method");
800 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
801 cpl_parameterlist_append(pl, p);
805 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"sky-est-kappa");
806 p = cpl_parameter_new_range(pName, CPL_TYPE_DOUBLE,
807 "If the user has no input sky frame and the sky need to be "
808 "estimated from user defined pixels set by aj-method "
809 "this parameter allow to use the kappa of the kappa sigma clip iteration [3].",
810 context, 3., 0., 100.);
811 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky-est-kappa");
812 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
813 cpl_parameterlist_append(pl, p);
816 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"sky-est-niter");
817 p = cpl_parameter_new_range(pName, CPL_TYPE_INT,
818 "If the user has no input sky frame and the sky need to be "
819 "estimated from user defined pixels set by aj-method "
820 "this parameter allow to set the number of the kappa sigma clip iterations [5].",
822 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky-est-niter");
823 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
824 cpl_parameterlist_append(pl, p);
826 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"crea-phase3");
827 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
828 "If true crea phase3 compliant data products",
830 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"crea-phase3");
831 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
832 cpl_parameterlist_append(pl, p);
836 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"bpc_iter");
837 p = cpl_parameter_new_value(pName, CPL_TYPE_INT,
838 "No. of iterations for bad pixel correction",
840 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"bpc_iter");
841 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
842 cpl_parameterlist_append(pl, p);
845 snprintf(pName,
sizeof(pName),
"%s.%s", context,
"chop-nan");
846 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
847 "If true chop cube planes with more than 50% NAN pixels",
849 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"chop-nan");
850 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
851 cpl_parameterlist_append(pl, p);
859 err = cpl_error_get_code();
867cpl_error_code eris_ifu_jitter_fetch_params(
869 const char* recipe_name,
870 const cpl_parameterlist * parlist,
871 struct stdParamStruct *stdParams,
872 struct paramStruct *params)
874 char* param_name = NULL;
876 cpl_ensure_code(context, CPL_ERROR_NULL_INPUT);
877 cpl_ensure_code(recipe_name, CPL_ERROR_NULL_INPUT);
878 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
879 cpl_ensure_code(stdParams, CPL_ERROR_NULL_INPUT);
880 cpl_ensure_code(params, CPL_ERROR_NULL_INPUT);
885 eris_ifu_fetch_std_param(parlist, recipe_name, stdParams);
887 param_name = cpl_sprintf(
"%s.sky_tweak", context);
888 params->skyTweak = cpl_parameter_get_int(
889 cpl_parameterlist_find_const(parlist, param_name));
890 cpl_free(param_name);
892 param_name = cpl_sprintf(
"%s.skip_sky_oh_align", context);
893 params->skip_sky_oh_align = cpl_parameter_get_bool(
894 cpl_parameterlist_find_const(parlist, param_name));
895 cpl_free(param_name);
897 param_name = cpl_sprintf(
"%s.skip_oh_align", context);
898 params->skip_oh_align = cpl_parameter_get_bool(
899 cpl_parameterlist_find_const(parlist, param_name));
900 cpl_free(param_name);
902 param_name = cpl_sprintf(
"%s.discard_subband", context);
903 params->discard_subband = cpl_parameter_get_bool(
904 cpl_parameterlist_find_const(parlist, param_name));
905 cpl_free(param_name);
907 param_name = cpl_sprintf(
"%s.stretch_sky", context);
908 params->stretch_sky = cpl_parameter_get_bool(
909 cpl_parameterlist_find_const(parlist, param_name));
910 cpl_free(param_name);
912 param_name = cpl_sprintf(
"%s.stretch_degree", context);
913 params->stretch_degree = cpl_parameter_get_int(
914 cpl_parameterlist_find_const(parlist, param_name));
915 cpl_free(param_name);
917 param_name = cpl_sprintf(
"%s.stretch_resampling", context);
918 const char *resamplingInput = cpl_parameter_get_string(
919 cpl_parameterlist_find_const(parlist, param_name));
920 cpl_free(param_name);
923 if (strncasecmp(resamplingInput,
"linear", strlen(
"linear")) == 0) {
924 params->stretch_resampling = LINEAR;
925 }
else if (strncasecmp(resamplingInput,
"spline", strlen(
"spline")) == 0) {
926 params->stretch_resampling = SPLINE;
929 "Error reading recipe parameter, unknown stretch resampling method %s",
934 param_name = cpl_sprintf(
"%s.tbsub", context);
935 params->tbsub = cpl_parameter_get_bool(
936 cpl_parameterlist_find_const(parlist, param_name));
937 cpl_free(param_name);
939 param_name = cpl_sprintf(
"%s.velocity_offset", context);
940 params->velocityOffset = cpl_parameter_get_double(
941 cpl_parameterlist_find_const(parlist, param_name));
942 cpl_free(param_name);
944 param_name = cpl_sprintf(
"%s.bpm_threshold", context);
945 params->bpmThreshold = cpl_parameter_get_double(
946 cpl_parameterlist_find_const(parlist, param_name));
947 cpl_free(param_name);
949 param_name = cpl_sprintf(
"%s.cube.first-col", context);
950 params->firstCol = cpl_parameter_get_double(
951 cpl_parameterlist_find_const(parlist, param_name));
952 cpl_free(param_name);
954 param_name = cpl_sprintf(
"%s.cube.fine-tune", context);
955 params->fineTuneMode = cpl_parameter_get_int(
956 cpl_parameterlist_find_const(parlist, param_name));
957 cpl_free(param_name);
959 param_name = cpl_sprintf(
"%s.cube.combine", context);
960 params->combine = cpl_parameter_get_bool(
961 cpl_parameterlist_find_const(parlist, param_name));
962 cpl_free(param_name);
964 param_name = cpl_sprintf(
"%s.cube.slitlet-detection", context);
965 const char* slitletMode = cpl_parameter_get_string(
966 cpl_parameterlist_find_const(parlist, param_name));
967 cpl_free(param_name);
969 if (strcmp(slitletMode,
"DIST") == 0) {
970 params->slitletDetectionMode = DISTANCES;
971 }
else if (strcmp(slitletMode,
"EDGE") == 0) {
972 params->slitletDetectionMode = EDGES;
973 }
else if (strcmp(slitletMode,
"GRID") == 0) {
974 params->slitletDetectionMode = GRID;
976 params->slitletDetectionMode = UNSET;
979 param_name = cpl_sprintf(
"%s.cube.first-col", context);
980 params->firstCol = cpl_parameter_get_double(
981 cpl_parameterlist_find_const(parlist, param_name));
982 cpl_free(param_name);
984 param_name = cpl_sprintf(
"%s.extract-source", context);
985 params->extractSource = cpl_parameter_get_bool(
986 cpl_parameterlist_find_const(parlist, param_name));
987 cpl_free(param_name);
989 param_name = cpl_sprintf(
"%s.dar-corr", context);
990 params->darCorrection = cpl_parameter_get_bool(
991 cpl_parameterlist_find_const(parlist, param_name));
992 cpl_free(param_name);
994 param_name = cpl_sprintf(
"%s.dar-shift-method", context);
995 params->darShiftMethod = cpl_parameter_get_int(
996 cpl_parameterlist_find_const(parlist, param_name));
997 cpl_free(param_name);
999 param_name = cpl_sprintf(
"%s.dar-shift-radius", context);
1000 params-> darShiftWidth = cpl_parameter_get_double(
1001 cpl_parameterlist_find_const(parlist, param_name));
1002 cpl_free(param_name);
1004 param_name = cpl_sprintf(
"%s.dar-shift-length", context);
1005 params->darShiftLength = cpl_parameter_get_int(
1006 cpl_parameterlist_find_const(parlist, param_name));
1007 cpl_free(param_name);
1009 param_name = cpl_sprintf(
"%s.derot_corr", context);
1010 const char* derot_opt = cpl_parameter_get_string(
1011 cpl_parameterlist_find_const(parlist, param_name));
1012 cpl_free(param_name);
1013 if (!strcmp(derot_opt,
"auto"))
1014 params->derot_corr = nan(
"");
1016 sscanf(derot_opt,
"%lf", &(params->derot_corr));
1018 param_name = cpl_sprintf(
"%s.bpc_iter", context);
1019 params->bpc_iter = cpl_parameter_get_int(
1020 cpl_parameterlist_find_const(parlist, param_name));
1021 cpl_free(param_name);
1029 return cpl_error_get_code();
1033cpl_error_code eris_ifu_jitter_processSof(
1034 cpl_frameset* frames,
1035 struct stdParamStruct stdParams,
1036 struct paramStruct params,
1037 struct sofStruct *sof)
1039 cpl_image *qualityMask = NULL;
1040 cpl_mask *flatBpm = NULL;
1041 cpl_mask *darkBpm = NULL;
1042 cpl_mask *detlinBpm = NULL;
1043 cpl_mask *masterBpm = NULL;
1044 cpl_vector *lambdaRange = NULL;
1045 cpl_bivector *ref_spectrum = NULL;
1047 cpl_ensure_code(frames != NULL, CPL_ERROR_NULL_INPUT);
1050 cpl_ensure_code(sof != NULL, CPL_ERROR_NULL_INPUT);
1054 const cpl_frame *frame;
1055 deqQualityType qualityType = unspecified;
1056 ifsBand band = UNDEFINED_BAND;
1057 ifsPreopticsScale scale = UNDEFINED_SCALE;
1058 ifsInstrument instrument = UNSET_INSTRUMENT;
1059 cpl_error_code error0 = cpl_error_get_code();
1061 if (frames == NULL) {
1063 "missing frameset");
1065 if (cpl_frameset_is_empty(frames)) {
1067 "SOF file is empty or missing");
1074 eris_ifu_jitter_get_instrument_settings(
1075 frames, &instrument, &band, &scale);
1078 sof->instrument = instrument;
1080 sof->dqi = cpl_image_new(ERIS_IFU_DETECTOR_SIZE_X,
1081 ERIS_IFU_DETECTOR_SIZE_Y, CPL_TYPE_INT);
1084 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_DARK_BP_MAP);
1085 if (frame != NULL) {
1086 darkBpm = cpl_mask_load(cpl_frame_get_filename(frame), 0, 0);
1088 cpl_error_set(cpl_func, error0);
1091 frame = cpl_frameset_find(frames, ERIS_IFU_PRO_FLAT_BPM);
1092 if (frame != NULL) {
1093 flatBpm = cpl_mask_load(cpl_frame_get_filename(frame), 0, 0);
1095 cpl_error_set(cpl_func, error0);
1098 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_DETLIN_BP_MAP);
1099 if (frame != NULL) {
1100 detlinBpm = cpl_mask_load(cpl_frame_get_filename(frame), 0, 0);
1102 cpl_error_set(cpl_func, error0);
1106 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_DARK);
1107 if (frame != NULL) {
1109 qualityType = unspecified;
1110 ifsBand darkBand = UNDEFINED_BAND;
1111 ifsPreopticsScale darkScale = UNDEFINED_SCALE;
1113 darkBand, darkScale, &qualityMask, &qualityType);
1114 if (darkBpm == NULL) {
1116 if (qualityType == flag16bit || qualityType == flag32bit) {
1117 cpl_image_add(sof->dqi, qualityMask);
1121 sof->masterDark = NULL;
1122 cpl_error_set(cpl_func, error0);
1126 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_FLATFIELD);
1127 if (frame != NULL) {
1129 qualityType = unspecified;
1131 band, scale, &qualityMask, &qualityType);
1132 if (flatBpm == NULL) {
1134 if (qualityType == flag16bit || qualityType == flag32bit) {
1135 cpl_image_add(sof->dqi, qualityMask);
1139 sof->masterFlat = NULL;
1140 cpl_error_set(cpl_func, error0);
1144 masterBpm = cpl_mask_new(ERIS_IFU_DETECTOR_SIZE_X,
1145 ERIS_IFU_DETECTOR_SIZE_Y);
1146 if (darkBpm != NULL) {
1147 cpl_mask_or(masterBpm, darkBpm);
1149 if (flatBpm != NULL) {
1150 cpl_mask_or(masterBpm, flatBpm);
1152 if (detlinBpm != NULL) {
1153 cpl_mask_or(masterBpm, detlinBpm);
1155 sof->badPixelMask = cpl_mask_duplicate(masterBpm);
1156 cpl_mask_delete(masterBpm);
1158 cpl_msg_debug(__func__,
"Number of bad pixels in master bad pixel map %lld",
1159 cpl_mask_count(sof->badPixelMask));
1162 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_DISTORTION);
1164 if (frame == NULL) {
1166 "missing \"%s\" tag in the SOF, distortion polynomials",
1167 ERIS_IFU_CALIB_DISTORTION);
1169 if (cpl_fits_count_extensions(cpl_frame_get_filename(frame)) > 2) {
1171 cpl_frame_get_filename(frame),
1172 &sof->distortion, &sof->borders);
1184 sof->distances = NULL;
1185 sof->positions = NULL;
1188 cpl_frame_get_filename(frame), &sof->poly_u, &sof->poly_v);
1191 sof->distortion = NULL;
1192 sof->borders = NULL;
1195 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_DISTANCES);
1197 if (frame == NULL) {
1198 if (params.slitletDetectionMode == DISTANCES) {
1200 "missing \"%s\" tag in the SOF, slitlet distances",
1201 ERIS_IFU_CALIB_DISTANCES);
1204 if (params.slitletDetectionMode != DISTANCES) {
1205 cpl_msg_warning(cpl_func,
1206 "SOF entry with tag %s will be ignored as %s recipe parameter"
1207 " is not set to \"DIST\"", ERIS_IFU_CALIB_DISTANCES,
1208 "cube.slitlet-detection");
1211 cpl_frame_get_filename(frame));
1216 frame = cpl_frameset_find(frames, ERIS_IFU_PRO_DIST_SLIT_POS);
1218 if (frame == NULL) {
1219 if (params.slitletDetectionMode == EDGES) {
1221 "missing \"%s\" tag in the SOF, slitlet positions",
1222 ERIS_IFU_PRO_DIST_SLIT_POS);
1225 if (params.slitletDetectionMode != EDGES) {
1226 cpl_msg_warning(cpl_func,
1227 "SOF entry with tag %s will be ignored as %s recipe parameter"
1228 " is not set to \"EDGE\"", ERIS_IFU_PRO_DIST_SLIT_POS,
1229 "cube.slitlet-detection");
1232 cpl_frame_get_filename(frame));
1233 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1234 cpl_bivector_dump(sof->positions, stdout);
1239 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_WAVE_MAP);
1241 if (frame == NULL) {
1243 "missing \"%s\" tag in the SOF, wavelength map",
1244 ERIS_IFU_CALIB_WAVE_MAP);
1246 sof->waveMap = cpl_image_load(
1247 cpl_frame_get_filename(frame),
1248 CPL_TYPE_UNSPECIFIED, 0, 0);
1250 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_OH_SPEC);
1252 if (frame != NULL) {
1253 const char *ref_filename = NULL;
1256 sof->oh_ref_frame = cpl_frame_duplicate(frame);
1257 lambdaRange = cpl_vector_new(2);
1258 cpl_vector_set(lambdaRange, 0, cpl_image_get_min(sof->waveMap));
1259 cpl_vector_set(lambdaRange, 1, cpl_image_get_max(sof->waveMap));
1261 ref_filename = cpl_frame_get_filename(frame));
1262 ext_cnt = cpl_fits_count_extensions(ref_filename);
1264 const char *ext_name = NULL;
1267 case J_LOW:
case J_SHORT:
case J_MIDDLE:
case J_LONG:
case J_SPIFFI:
1268 ext_name = OH_SPECTRA_J;
1270 case H_LOW:
case H_SHORT:
case H_MIDDLE:
case H_LONG:
case H_SPIFFI:
1271 ext_name = OH_SPECTRA_H;
1273 case K_LOW:
case K_SHORT:
case K_MIDDLE:
case K_LONG:
case K_SPIFFI:
1274 ext_name = OH_SPECTRA_K;
1277 ext_name = OH_SPECTRA_HK;
1281 "unidentified SPIFFIER band selection: %s",
1284 ext_cnt = cpl_fits_find_extension(ref_filename, ext_name);
1288 ref_filename, ext_cnt);
1293 sof->oh_ref_frame = NULL;
1294 sof->oh_ref_peaks = NULL;
1298 eris_ifu_jitter_get_objsky_exposures( frames, stdParams, sof);
1301 eris_ifu_jitter_get_objsky_pairs(sof);
1308 cpl_image_delete(qualityMask);
1309 cpl_mask_delete(flatBpm);
1310 cpl_mask_delete(darkBpm);
1311 cpl_mask_delete(detlinBpm);
1312 cpl_mask_delete(masterBpm);
1313 cpl_vector_delete(lambdaRange);
1314 cpl_bivector_delete(ref_spectrum);
1316 return cpl_error_get_code();
1320cpl_error_code eris_ifu_jitter_get_instrument_settings(
1321 cpl_frameset *frames,
1322 ifsInstrument *instrument,
1324 ifsPreopticsScale *scale)
1328 cpl_ensure_code(frames != NULL, CPL_ERROR_NULL_INPUT);
1331 cpl_error_code retVal = CPL_ERROR_NONE;
1332 cpl_frameset_iterator *iter = NULL;
1333 cpl_propertylist *header = NULL;
1334 cpl_frame *frame = NULL;
1335 cpl_error_code iterError;
1341 iter = cpl_frameset_iterator_new(frames);
1344 frame = cpl_frameset_iterator_get(iter);
1345 if (frame != NULL) {
1346 if (cpl_frame_get_group(frame) == CPL_FRAME_GROUP_RAW) {
1348 header = cpl_propertylist_load(
1349 cpl_frame_get_filename(frame), 0);
1352 cpl_propertylist_delete(header);
1355 iterError = cpl_frameset_iterator_advance(iter, 1);
1356 if (iterError == CPL_ERROR_ACCESS_OUT_OF_RANGE) {
1358 "Found no raw data frames in SOF");
1364 "Found no raw data frames in SOF");
1372 retVal = cpl_error_get_code();
1374 cpl_frameset_iterator_delete(iter);
1380cpl_error_code eris_ifu_jitter_get_objsky_exposures(
1381 cpl_frameset *frames,
1382 struct stdParamStruct params,
1383 struct sofStruct *sof)
1386 cpl_ensure_code(frames != NULL, CPL_ERROR_NULL_INPUT);
1387 cpl_ensure_code(params.crh_detection != NULL, CPL_ERROR_NULL_INPUT);
1388 cpl_ensure_code(sof != NULL, CPL_ERROR_NULL_INPUT);
1391 cpl_error_code retVal = CPL_ERROR_NONE;
1392 cpl_frameset_iterator *iter = NULL;
1393 cpl_frame *frame = NULL;
1394 cpl_error_code iterError;
1395 const char* tag = NULL;
1396 cpl_size frameSetSize;
1397 sofModes mode = NODATA;
1400 frameSetSize = cpl_frameset_get_size(frames);
1401 sof->exposureTableSize = (int) frameSetSize;
1402 sof->exposureTable = cpl_calloc(sof->exposureTableSize,
1403 sizeof(
struct exposureEntry));
1405 sof->exposureTableCnt = 0;
1407 iter = cpl_frameset_iterator_new(frames);
1408 frame = cpl_frameset_iterator_get(iter);
1411 while (frame != NULL) {
1412 bool exposureFound =
false;
1413 int ix = sof->exposureTableCnt;
1414 struct exposureEntry *expEntry = &sof->exposureTable[ix];
1417 tag = cpl_frame_get_tag(frame);
1418 if (strcmp(tag, ERIS_IFU_RAW_OBJ) == 0 ||
1419 strcmp(tag, ERIS_IFU_RAW_STD) == 0 ||
1420 strcmp(tag, ERIS_IFU_RAW_PUPIL_LAMP) == 0 ||
1421 strcmp(tag, ERIS_IFU_RAW_PUPIL_SKY) == 0 ||
1422 strcmp(tag, ERIS_IFU_RAW_STD_FLUX) == 0 ||
1423 strcmp(tag, ERIS_IFU_RAW_PSF) == 0) {
1424 expEntry->isObject =
true;
1426 exposureFound =
true;
1427 if (strcmp(tag, ERIS_IFU_RAW_OBJ) == 0) {
1429 }
else if (strcmp(tag, ERIS_IFU_RAW_STD) == 0) {
1431 }
else if (strcmp(tag, ERIS_IFU_RAW_STD_FLUX) == 0) {
1433 }
else if (strcmp(tag, ERIS_IFU_RAW_PSF) == 0) {
1435 }
else if (strcmp(tag, ERIS_IFU_RAW_PUPIL_LAMP) == 0||
1436 strcmp(tag, ERIS_IFU_RAW_PUPIL_SKY) == 0) {
1440 if (strcmp(tag, ERIS_IFU_RAW_SKY) == 0 ||
1441 strcmp(tag, ERIS_IFU_RAW_OBJ_SKY) == 0 ||
1442 strcmp(tag, ERIS_IFU_RAW_STD_SKY) ==0 ||
1443 strcmp(tag, ERIS_IFU_RAW_STD_FLUX_SKY) ==0 ||
1444 strcmp(tag, ERIS_IFU_RAW_PSF_SKY) == 0) {
1445 expEntry->isObject =
false;
1446 exposureFound =
true;
1447 if (strcmp(tag, ERIS_IFU_RAW_SKY) == 0) {
1448 mode = IGNORE_SOF_MODE;
1449 }
else if (strcmp(tag, ERIS_IFU_RAW_OBJ_SKY) == 0) {
1451 }
else if (strcmp(tag, ERIS_IFU_RAW_STD_SKY) == 0) {
1453 }
else if (strcmp(tag, ERIS_IFU_RAW_STD_FLUX_SKY) == 0) {
1455 }
else if (strcmp(tag, ERIS_IFU_RAW_PSF_SKY) == 0) {
1457 }
else if (strcmp(tag, ERIS_IFU_RAW_PUPIL_SKY) == 0) {
1461 if (exposureFound) {
1462 if (sof->mode == NODATA) {
1463 if (mode != NODATA) {
1464 if (mode != IGNORE_SOF_MODE) {
1469 "Cannot interpret tag %s", tag);
1472 if (mode != IGNORE_SOF_MODE) {
1473 if (mode != sof->mode) {
1475 "Do not mix different input raw data types like"
1476 " SCIENCE, PSF, STD STAR ...");
1480 expEntry->dqiImage = cpl_image_new(ERIS_IFU_DETECTOR_SIZE_X,
1481 ERIS_IFU_DETECTOR_SIZE_Y, CPL_TYPE_INT);
1482 const char *filename = cpl_frame_get_filename(frame);
1483 expEntry->frame = frame;
1485 frame, params.rawImageCorrectionMask, expEntry->dqiImage);
1486 expEntry->hdr = cpl_propertylist_load( filename, 0);
1488 expEntry->obsDate = cpl_propertylist_get_double(
1489 expEntry->hdr, FHDR_MJD_OBS);
1490 expEntry->centeredObsDate =
1491 expEntry->obsDate + (expEntry->dit /2.)/86400.;
1492 if(cpl_propertylist_has(expEntry->hdr,
"ESO TEL ALT")) {
1493 expEntry->alt = cpl_propertylist_get_double(
1494 expEntry->hdr,
"ESO TEL ALT");
1496 if(cpl_propertylist_has(expEntry->hdr,
"ESO ADA ABSROT START")) {
1497 expEntry->rot = cpl_propertylist_get_double(
1498 expEntry->hdr,
"ESO ADA ABSROT START");
1500 expEntry->derot_corr = eris_ifu_auto_derot_corr(expEntry->alt, expEntry->rot);
1501 expEntry->skyIndex = -1;
1502 expEntry->cube = NULL;
1503 expEntry->cubeHdr = NULL;
1504 expEntry->darkSubtrImage = NULL;
1505 expEntry->skySubtrImage = NULL;
1507 cpl_msg_debug(__func__,
"Number of bad pixels in master bad pixel map %lld",
1508 cpl_mask_count(expEntry->badPixelMask));
1509 cpl_mask_or(expEntry->badPixelMask, sof->badPixelMask);
1511 expEntry->badPixelMask);
1512 cpl_image_add(expEntry->dqiImage, sof->dqi);
1514 if (params.productDepth >= PD_DEBUG) {
1515 char *filename2 = NULL;
1516 filename2 = cpl_sprintf(
"%s_%3.3d",
1517 ERIS_IFU_PRO_JITTER_DBG_RAW_FN, ix);
1519 filename2, 1, NULL);
1521 filename2 = cpl_sprintf(
"%s_%3.3d.fits",
1522 ERIS_IFU_PRO_JITTER_DBG_RAW_FN, ix);
1523 cpl_image_save(expEntry->dqiImage, filename2,
1524 CPL_TYPE_INT, NULL, CPL_IO_EXTEND);
1529 sof->exposureTableCnt++;
1532 iterError = cpl_frameset_iterator_advance(iter, 1);
1533 if (iterError == CPL_ERROR_ACCESS_OUT_OF_RANGE) {
1536 frame = cpl_frameset_iterator_get(iter);
1539 if (sof->objectCnt == 0) {
1541 "No object frame tag found in SOF file, either"
1542 " OBJ, STD, STD_FLUX, PSF_CALIBRATOR, PUPIL_LAMP is missing");
1544 cpl_msg_info(cpl_func,
"Number of object frames to be processed: %d", sof->objectCnt);
1549 retVal = cpl_error_get_code();
1551 cpl_frameset_iterator_delete(iter);
1556cpl_error_code eris_ifu_jitter_get_objsky_pairs(
struct sofStruct *sof)
1558 cpl_error_code retVal = CPL_ERROR_NONE;
1561 int *skyIndex = NULL;
1562 double *skyDate = NULL;
1566 cpl_ensure_code(sof, CPL_ERROR_NULL_INPUT);
1567 cpl_ensure_code((sof->objectCnt <= sof->exposureTableCnt),
1568 CPL_ERROR_ILLEGAL_INPUT);
1573 if (sof->objectCnt != sof->exposureTableCnt) {
1575 skyCnt = sof->exposureTableCnt - sof->objectCnt;
1576 skyIndex = cpl_calloc(skyCnt,
sizeof(
int));
1577 skyDate = cpl_calloc(skyCnt,
sizeof(
double));
1581 for (
int ix=0; ix < sof->exposureTableCnt; ix++) {
1582 struct exposureEntry *expEntry = &sof->exposureTable[ix];
1583 if (expEntry->isObject ==
false) {
1584 skyIndex[skyIdx] = ix;
1585 skyDate[skyIdx] = expEntry->centeredObsDate;
1591 for (
int ix=0; ix < sof->exposureTableCnt; ix++) {
1592 struct exposureEntry *expEntry = &sof->exposureTable[ix];
1593 if (expEntry->isObject ==
true) {
1594 obsDate = expEntry->centeredObsDate;
1596 minDiff = fabs(obsDate - skyDate[0]);
1597 for (
int sx = 1; sx<skyCnt; sx++) {
1598 double diff = fabs(obsDate - skyDate[sx]);
1599 if (diff < minDiff) {
1604 expEntry->skyIndex = skyIndex[skyIdx];
1612 retVal = cpl_error_get_code();
1620void eris_free_exposureEntry(
struct exposureEntry* ee) {
1623 if(ee->frame) cpl_frame_delete(ee->frame);
1624 if(ee->hdr) cpl_propertylist_delete(ee->hdr);
1626 if(ee->dqiImage) cpl_image_delete(ee->dqiImage);
1628 if(ee->cubeBpm) cpl_imagelist_delete(ee->cubeBpm);
1629 if(ee->cubeHdr) cpl_propertylist_delete(ee->cubeHdr);
1630 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)
Function to load slitlet positions.
float eris_ifu_get_dit(cpl_propertylist *header)
Determine if a frame is a Sky frame or not.
cpl_error_code eris_ifu_load_distortion_polynomials(const char *filename, cpl_polynomial ***polynomials, cpl_table **borders)
Function to load distortion polynomials.
hdrl_image * eris_ifu_load_cal_image_frame(const cpl_frame *frame, ifsBand band, ifsPreopticsScale scale, cpl_image **qualImage, deqQualityType *qualType)
Function to load a calibration image frame.
cpl_error_code eris_ifu_dfs_set_groups(cpl_frameset *self)
Set the group as RAW or CALIB in a frameset.
cpl_vector * eris_ifu_load_distances(const char *filename)
Function to load slitlet distances.
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)
Function to load distortion polynomials.
#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)
Read a raw detector exposure, perform some correction, add noise data.
ifsInstrument eris_ifu_get_instrument_frame(cpl_frame *frame)
Return value of INSTRUME from a given input frame.
cpl_vector * eris_ifu_lcorr_get_peak_lambdas(const cpl_bivector *spectrum, double min_frac, cpl_vector *range)
Get peaks of position of lines used in wavelength calibration.
cpl_bivector * eris_ifu_lcorr_read_OH_reference_spectrum(const char *filename, cpl_size ext_number)
Creates a spectrum bivector (x: lambda) from an input 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)
eris_ifu_get_bandString
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 imagelist for debugging purposes
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.