MOONS Pipeline Reference Manual 0.13.2
moons_mflat2.c
1/*
2 * This file is part of the MOONS Pipeline
3 * Copyright (C) 2002-2016 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#include "cpl_error.h"
21#include "cpl_frameset.h"
22#define ALTERNATIVE_DRIVER
23
24/*-----------------------------------------------------------------------------
25 Includes
26 -----------------------------------------------------------------------------*/
27
28#include <string.h>
29
30#include <cpl.h>
31
32#include "moo_utils.h"
33#include "moo_pfits.h"
34#include "moo_dfs.h"
35#include "moo_params.h"
36#include "moo_drl.h"
37#include "moo_products.h"
38#include "moo_flat_shift_compute.h"
39#include "moo_compute_slitoffset.h"
40
41/*-----------------------------------------------------------------------------
42 Plugin registration
43 -----------------------------------------------------------------------------*/
44
45int cpl_plugin_get_info(cpl_pluginlist *list);
46
47/*-----------------------------------------------------------------------------
48 Private function prototypes
49 -----------------------------------------------------------------------------*/
50
51static int _moons_mflat_create(cpl_plugin *plugin);
52static int _moons_mflat_exec(cpl_plugin *plugin);
53static int _moons_mflat_destroy(cpl_plugin *plugin);
54
55static int
56_moons_mflat(cpl_frameset *frameset, const cpl_parameterlist *parlist);
57
58/*-----------------------------------------------------------------------------
59 Static variables
60 -----------------------------------------------------------------------------*/
61
62static const char *const _moons_mflat_description[2] = {
63 "This recipe aims at creating the products necessary to locate and extract "
64 "1D"
65 " spectra and correct from flat-field signatures. It can be used in three"
66 " different flows\n\n"
67 "Workflow 1: Localises the spectra from scratch and creates the guess"
68 " localisation traces and widths\n"
69 "INPUT FRAMES\n"
70 " * RawList n1>=3 files (RAW) with tag FLAT : "
71 "flat files\n"
72 " * RawOffList n2==n1 files (RAW) with tag FLAT_OFF : "
73 "flat off files\n"
74 " * [OPTIONAL] ReferenceBadPixMask 1 file (QUA) with tag BP_MAP_RP : "
75 "cosmetic bad pixel map\n"
76 " * MasterBias 1 file (DET) with tag MASTER_BIAS : "
77 "master bias file\n"
78 " * [OPTIONAL] MasterDarkVis 1 file (DET) with tag "
79 "MASTER_DARK_VIS : "
80 "master dark vis file\n"
81 " * [OPTIONAL] MasterDarkNir 1 file (DET) with tag "
82 "MASTER_DARK_NIR : "
83 "master dark nir file\n"
84 "PRODUCTS\n"
85 " * FF_TRACE_GUESS_OFFSET[offset]_[insmode].fits (LOC) with tag "
86 "FF_TRACE_GUESS : "
87 "the localisation trace stores the Y centroid values of the spectra traces"
88 " and the width of the spectra in Y direction at each centroid position "
89 "\n\n"
90 "Workflow 2: Localises the spectra and creates the localisation traces"
91 " and widths. Creates the master and extracted flat-fields, and "
92 "the fibre-to-fibre relative response. Updates the bad-pixel mask.\n"
93 "INPUT FRAMES\n"
94 " * RawList n1>=3 files (RAW) with tag FLAT : "
95 "flat files\n"
96 " * RawOffList n2==n1 files (RAW) with tag FLAT_OFF : "
97 "flat off files\n"
98 " * [OPTIONAL] ReferenceBadPixMask 1 file (QUA) with tag BP_MAP_RP : "
99 "cosmetic bad pixel map\n"
100 " * [OPTIONAL] NonLinearityBadPixMask 1 file (QUA) with tag BP_MAP_NL : "
101 "non linearity bad pixel map coming from linearity recipe\n"
102 " * MasterBias 1 file (DET) with tag MASTER_BIAS : "
103 "master bias file\n"
104 " * [OPTIONAL] MasterDarkVis 1 file (DET) with tag "
105 "MASTER_DARK_VIS : "
106 "master dark vis file\n"
107 " * [OPTIONAL] MasterDarkNir 1 file (DET) with tag "
108 "MASTER_DARK_NIR : "
109 "master dark nir file\n"
110 " * [OPTIONAL] LinCoeffsCube 1 file (3D) with tag "
111 "LINEARITY_COEFF_CUBE : "
112 "linearity coefficients coming from linearity recipe\n"
113 " * [OPTIONAL] P2pMap 1 file (DET) with tag P2P_MAP : "
114 "the pixel to pixel variation map \n"
115 " * FfTraceGuess 1 file (LOC) with tag "
116 "FF_TRACE_GUESS : "
117 "localisation trace produced in workflow 1\n"
118 "PRODUCTS\n"
119 " * FF_TRACE_OFFSET[offset]_[insmode].fits (LOC) with tag FF_TRACE : "
120 "the localisation trace stores the Y centroid values of the spectra traces"
121 " and the width of the spectra in Y direction at each centroid position\n"
122 " * FF_EXTSPECTRA_OFFSET[offset]_[insmode].fits (EXT) with tag "
123 "FF_FF_EXTSPECTRA : "
124 "extracted flat-fields\n"
125 " * F2F_OFFSET[offset]_[insmode].fits (F2F) with tag F2F_TABLE "
126 ": "
127 "the fibre-to-fibre relative response\n"
128 "[if --extract-method==OPTIMAL]\n"
129 " * MASTER_FLAT_OFFSET[offset]_[insmode].fits (PSF) with tag "
130 "MASTER_FLAT : "
131 "the master normalized flat product for given position\n"
132 "[endif]\n\n",
133 "Workflow 3: Localises the spectra and creates the localisation traces"
134 " and widths. Creates the master and extracted flat-fields,"
135 " the pixel-to-pixel variation map and the fibre-to-fibre relative "
136 "response."
137 " Updates the bad-pixel mask\n"
138 "INPUT FRAMES\n"
139 " * RawList n1>=3 files (RAW) with tag FLAT : "
140 "flat files at offset 0\n"
141 " * RawList n2>=3 files (RAW) with tag FLAT : "
142 "flat files at offset 1\n"
143 " * RawOffList n2+n1 files (RAW) with tag FLAT_OFF : "
144 "flat off files\n"
145 " * [OPTIONAL] ReferenceBadPixMask 1 file (QUA) with tag BP_MAP_RP : "
146 "cosmetic bad pixel map\n"
147 " * [OPTIONAL] NonLinearityBadPixMask 1 file (QUA) with tag BP_MAP_NL : "
148 "non linearity bad pixel map coming from linearity recipe\n"
149 " * MasterBias 1 file (DET) with tag MASTER_BIAS : "
150 "master bias file\n"
151 " * [OPTIONAL] MasterDarkVis 1 file (DET) with tag "
152 "MASTER_DARK_VIS : "
153 "master dark vis file\n"
154 " * [OPTIONAL] MasterDarkNir 1 file (DET) with tag "
155 "MASTER_DARK_NIR : "
156 "master dark nir file\n"
157 " * [OPTIONAL] LinCoeffsCube1 1 file (3D) with tag "
158 "LINEARITY_COEFF_CUBE : "
159 "linearity coefficients coming from linearity recipe at offset 0\n"
160 " * [OPTIONAL] LinCoeffsCube2 1 file (3D) with tag "
161 "LINEARITY_COEFF_CUBE : "
162 "linearity coefficients coming from linearity recipe at offset 1\n"
163 " * FfTraceGuess1 1 file (LOC) with tag "
164 "FF_TRACE_GUESS : "
165 "localisation trace produced in workflow 1 at offset 0\n"
166 " * FfTraceGuess2 1 file (LOC) with tag "
167 "FF_TRACE_GUESS : "
168 "localisation trace produced in workflow 1 at offset 1\n"
169 "PRODUCTS\n"
170 " * P2P_[insmode].fits (DET) with tag P2P_MAP : "
171 "the pixel to pixel variation map \n\n"
172 "Workflow 4: Compute shift in fibre-to-fibre relative response."
173 "INPUT FRAMES\n"
174 " * FlatAttached (RAW) with tag FLAT_ATTACHED "
175 ": "
176 "flat file\n"
177 " * RawOff (RAW) with tag FLAT_OFF : "
178 "flat off files\n"
179 " * [OPTIONAL] ReferenceBadPixMask 1 file (QUA) with tag BP_MAP_RP : "
180 "cosmetic bad pixel map\n"
181 " * [OPTIONAL] NonLinearityBadPixMask 1 file (QUA) with tag BP_MAP_NL : "
182 "non linearity bad pixel map coming from linearity recipe\n"
183 " * MasterBias 1 file (DET) with tag MASTER_BIAS : "
184 "master bias file\n"
185 " * [OPTIONAL] MasterDarkVis 1 file (DET) with tag "
186 "MASTER_DARK_VIS : "
187 "master dark vis file\n"
188 " * [OPTIONAL] MasterDarkNir 1 file (DET) with tag "
189 "MASTER_DARK_NIR : "
190 "master dark nir file\n"
191 " * [OPTIONAL] LinCoeffsCube 1 file (3D) with tag "
192 "LINEARITY_COEFF_CUBE : "
193 "linearity coefficients coming from linearity recipe\n"
194 " * FfTrace 1 file (LOC): "
195 "localisation trace produced in workflow 2\n"
196 "PRODUCTS\n"
197 " * F2F_OFFSET[offset]_[insmode].fits (F2F) with tag F2F_TABLE "
198 ": "
199 "the fibre-to-fibre relative response\n"};
200
201/*-----------------------------------------------------------------------------
202 Function code
203 -----------------------------------------------------------------------------*/
204
205/*----------------------------------------------------------------------------*/
215/*----------------------------------------------------------------------------*/
216
217int
218cpl_plugin_get_info(cpl_pluginlist *list)
219{
220 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
221 cpl_plugin *plugin = &recipe->interface;
222
223 cpl_size sz[2] = {strlen(_moons_mflat_description[0]),
224 strlen(_moons_mflat_description[1])};
225 char *description = cpl_calloc(sizeof(char), sz[0] + sz[1] + 1);
226
227 cpl_size idx;
228 cpl_size offset = 0;
229 for (idx = 0; idx < 2; ++idx) {
230 strncpy(&description[offset], _moons_mflat_description[idx], sz[idx]);
231 offset += sz[idx];
232 }
233
234#ifdef ALTERNATIVE_DRIVER
235 if (cpl_plugin_init(plugin, CPL_PLUGIN_API, MOONS_BINARY_VERSION,
236 CPL_PLUGIN_TYPE_RECIPE, "moons_mflat2",
237 "Create a master flat product", description,
238 "Regis Haigron", PACKAGE_BUGREPORT, moo_get_license(),
239 _moons_mflat_create, _moons_mflat_exec,
240 _moons_mflat_destroy)) {
241 cpl_free(description);
242 cpl_msg_error(cpl_func, "Plugin initialization failed");
243 (void)cpl_error_set_where(cpl_func);
244 return 1;
245 }
246#else
247 if (cpl_plugin_init(plugin, CPL_PLUGIN_API, MOONS_BINARY_VERSION,
248 CPL_PLUGIN_TYPE_RECIPE, "moons_mflat",
249 "Create a master flat product", description,
250 "Regis Haigron", PACKAGE_BUGREPORT, moo_get_license(),
251 _moons_mflat_create, _moons_mflat_exec,
252 _moons_mflat_destroy)) {
253 cpl_free(description);
254 cpl_msg_error(cpl_func, "Plugin initialization failed");
255 (void)cpl_error_set_where(cpl_func);
256 return 1;
257 }
258#endif
259 cpl_free(description);
260
261 if (cpl_pluginlist_append(list, plugin)) {
262 cpl_msg_error(cpl_func, "Error adding plugin to list");
263 (void)cpl_error_set_where(cpl_func);
264 return 1;
265 }
266
267 return 0;
268}
269
270
271/*----------------------------------------------------------------------------*/
279/*----------------------------------------------------------------------------*/
280
281static int
282_moons_mflat_create(cpl_plugin *plugin)
283{
284 cpl_recipe *recipe;
285
286 /* Do not create the recipe if an error code is already set */
287 if (cpl_error_get_code() != CPL_ERROR_NONE) {
288 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
289 cpl_func, __LINE__, cpl_error_get_where());
290 return (int)cpl_error_get_code();
291 }
292
293 if (plugin == NULL) {
294 cpl_msg_error(cpl_func, "Null plugin");
295 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
296 }
297
298 /* Verify plugin type */
299 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
300 cpl_msg_error(cpl_func, "Plugin is not a recipe");
301 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
302 }
303
304 /* Get the recipe */
305 recipe = (cpl_recipe *)plugin;
306
307 /* Create the parameters list in the cpl_recipe object */
308 recipe->parameters = cpl_parameterlist_new();
309 if (recipe->parameters == NULL) {
310 cpl_msg_error(cpl_func, "Parameter list allocation failed");
311 cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
312 }
313
314 moo_params *params = moo_params_new("moons", "moons_mflat");
315
316 /* Fill the parameters list */
317 moo_params_add_keep_temp(params, recipe->parameters);
318 moo_params_add_prepare(params, recipe->parameters);
319 moo_params_add_correct_bias(params, recipe->parameters,
320 MOO_CORRECT_BIAS_METHOD_MASTER);
321 moo_params_add_crh(params, recipe->parameters, MOO_CRH_METHOD_SIGCLIP);
322 moo_params_add_localise(params, recipe->parameters);
323 moo_params_add_compute_slitoffset(params, recipe->parameters);
324 moo_params_add_extract(params, recipe->parameters);
325 moo_params_add_model_flat(params, recipe->parameters);
326 moo_params_add_compute_fibtrans(params, recipe->parameters);
327 moo_params_delete(params);
328
329 return 0;
330}
331
332
333/*----------------------------------------------------------------------------*/
339/*----------------------------------------------------------------------------*/
340
341static int
342_moons_mflat_exec(cpl_plugin *plugin)
343{
344 cpl_recipe *recipe;
345 int recipe_status;
346 cpl_errorstate initial_errorstate = cpl_errorstate_get();
347
348 /* Return immediately if an error code is already set */
349 if (cpl_error_get_code() != CPL_ERROR_NONE) {
350 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
351 cpl_func, __LINE__, cpl_error_get_where());
352 return (int)cpl_error_get_code();
353 }
354
355 if (plugin == NULL) {
356 cpl_msg_error(cpl_func, "Null plugin");
357 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
358 }
359
360 /* Verify plugin type */
361 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
362 cpl_msg_error(cpl_func, "Plugin is not a recipe");
363 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
364 }
365
366 /* Get the recipe */
367 recipe = (cpl_recipe *)plugin;
368
369 /* Verify parameter and frame lists */
370 if (recipe->parameters == NULL) {
371 cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
372 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
373 }
374 if (recipe->frames == NULL) {
375 cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
376 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
377 }
378
379 /* Invoke the recipe */
380 recipe_status = _moons_mflat(recipe->frames, recipe->parameters);
381
382 /* Ensure DFS-compliance of the products */
383 if (cpl_dfs_update_product_header(recipe->frames)) {
384 if (!recipe_status)
385 recipe_status = (int)cpl_error_get_code();
386 }
387
388 if (!cpl_errorstate_is_equal(initial_errorstate)) {
389 /* Dump the error history since recipe execution start.
390 At this point the recipe cannot recover from the error */
391 cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
392 }
393
394 return recipe_status;
395}
396
397
398/*----------------------------------------------------------------------------*/
404/*----------------------------------------------------------------------------*/
405
406static int
407_moons_mflat_destroy(cpl_plugin *plugin)
408{
409 cpl_recipe *recipe;
410
411 if (plugin == NULL) {
412 cpl_msg_error(cpl_func, "Null plugin");
413 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
414 }
415
416 /* Verify plugin type */
417 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
418 cpl_msg_error(cpl_func, "Plugin is not a recipe");
419 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
420 }
421
422 /* Get the recipe */
423 recipe = (cpl_recipe *)plugin;
424
425 cpl_parameterlist_delete(recipe->parameters);
426
427 return 0;
428}
429
430/*----------------------------------------------------------------------------*/
448/*----------------------------------------------------------------------------*/
449static cpl_frame *
450_moons_prepare(moo_products *products,
451 const cpl_frame *frame,
452 const cpl_frame *frame_off,
453 const char *bpmap_rp_name,
454 const char *bpmap_nl_name,
455 const cpl_frame *masterbias,
456 const cpl_frame *masterdark_vis,
457 const cpl_frame *masterdark_nir,
458 const cpl_frame *coeffs_cube,
459 moo_prepare_params *prepare_params,
460 moo_correct_bias_params *params,
461 int i,
462 int offset,
463 moo_mode_type mode)
464{
465 cpl_frame *result = NULL;
466 cpl_frame *pframe = NULL;
467 char *detname1 = NULL;
468 char *detname2 = NULL;
469 char *detname3 = NULL;
470 moo_det *det = NULL;
471 moo_det *detoff = NULL;
472
473 cpl_ensure(frame != NULL, CPL_ERROR_NULL_INPUT, NULL);
474 cpl_ensure(frame_off != NULL, CPL_ERROR_NULL_INPUT, NULL);
475 cpl_errorstate prestate = cpl_errorstate_get();
476
477 moo_try_check(det = moo_prepare(frame, bpmap_rp_name, bpmap_nl_name,
478 masterbias, coeffs_cube, prepare_params),
479 " ");
480
481 moo_try_check(moo_correct_bias(det, masterbias, params), " ");
482
483 moo_try_check(detname1 = cpl_sprintf("%s_OFFSET%d_%s_%d.fits",
484 MOONS_TAG_FLAT_CORRECTBIAS, offset,
485 moo_mode_get_name(mode), i),
486 " ");
487 moo_try_check(moo_products_add(products, det, CPL_FRAME_LEVEL_INTERMEDIATE,
488 MOONS_TAG_FLAT_CORRECTBIAS, detname1, frame),
489 " ");
490
491 moo_try_check(detname2 = cpl_sprintf("%s_OFFSET%d_%s_%d.fits",
492 MOONS_TAG_FLATOFF_PREPARE, offset,
493 moo_mode_get_name(mode), i),
494 " ");
495
496 moo_try_check(detoff = moo_prepare(frame_off, bpmap_rp_name, bpmap_nl_name,
497 masterbias, coeffs_cube, prepare_params),
498 " ");
499
500 moo_try_check(pframe = moo_products_add(products, detoff,
501 CPL_FRAME_LEVEL_INTERMEDIATE,
502 MOONS_TAG_FLATOFF_PREPARE, detname2,
503 frame_off),
504 " ");
505
506 moo_try_check(moo_correct_dark(det, detoff, masterdark_vis, masterdark_nir),
507 " ");
508 moo_try_check(detname3 = cpl_sprintf("%s_OFFSET%d_%s_%d.fits",
509 MOONS_TAG_FLAT_CORRECTDARK, offset,
510 moo_mode_get_name(mode), i),
511 " ");
512 moo_try_check(pframe = moo_products_add(products, det,
513 CPL_FRAME_LEVEL_INTERMEDIATE,
514 MOONS_TAG_FLAT_CORRECTDARK,
515 detname3, frame),
516 " ");
517
518 moo_try_check(result = cpl_frame_duplicate(pframe), " ");
519
520moo_try_cleanup:
521 if (!cpl_errorstate_is_equal(prestate)) {
522 cpl_frame_delete(result);
523 result = NULL;
524 }
525 moo_det_delete(det);
526 moo_det_delete(detoff);
527 cpl_free(detname1);
528 cpl_free(detname2);
529 cpl_free(detname3);
530 return result;
531}
532
533/*----------------------------------------------------------------------------*/
549/*----------------------------------------------------------------------------*/
550static cpl_frameset *
551_moons_prepare_set(cpl_frameset *raw_frames,
552 cpl_frameset *rawoff_frames,
553 const char *bpmap_rp_name,
554 const char *bpmap_nl_name,
555 const cpl_frame *masterbias,
556 const cpl_frame *masterdark_vis,
557 const cpl_frame *masterdark_nir,
558 const cpl_frame *coeffs_cube,
559 moo_prepare_params *prepare_params,
560 moo_correct_bias_params *params,
561 moo_products *products,
562 int offset,
563 moo_mode_type mode)
564{
565 cpl_frameset *detframes = NULL;
566 moo_det *det = NULL;
567 moo_det *detoff = NULL;
568
569 cpl_ensure(raw_frames, CPL_ERROR_NULL_INPUT, NULL);
570 cpl_ensure(rawoff_frames, CPL_ERROR_NULL_INPUT, NULL);
571 cpl_ensure(products, CPL_ERROR_NULL_INPUT, NULL);
572
573 cpl_errorstate prestate = cpl_errorstate_get();
574
575 moo_try_check(detframes = cpl_frameset_new(), " ");
576
577 int i;
578
579 for (i = 0; i < cpl_frameset_get_size(raw_frames); ++i) {
580 const cpl_frame *current_frame = NULL;
581 const cpl_frame *raw_off = NULL;
582 cpl_frame *pframe = NULL;
583
584 moo_try_check(current_frame =
585 cpl_frameset_get_position_const(raw_frames, i),
586 " ");
587 moo_try_check(raw_off =
588 cpl_frameset_get_position_const(rawoff_frames, i),
589 " ");
590
591 moo_try_check(pframe = _moons_prepare(products, current_frame, raw_off,
592 bpmap_rp_name, bpmap_nl_name,
593 masterbias, masterdark_vis,
594 masterdark_nir, coeffs_cube,
595 prepare_params, params, i, mode,
596 offset),
597 " ");
598 moo_try_check(cpl_frameset_insert(detframes, pframe), " ");
599 }
600
601moo_try_cleanup:
602 if (!cpl_errorstate_is_equal(prestate)) {
603 moo_det_delete(det);
604 moo_det_delete(detoff);
605 cpl_frameset_delete(detframes);
606 detframes = NULL;
607 }
608 return detframes;
609}
610
611/*----------------------------------------------------------------------------*/
621/*----------------------------------------------------------------------------*/
622static cpl_error_code
623_moons_flat_check_header(const cpl_frame *raw, const cpl_frame *ff_trace)
624{
625 cpl_ensure_code(raw != NULL, CPL_ERROR_NULL_INPUT);
626 cpl_ensure_code(ff_trace != NULL, CPL_ERROR_NULL_INPUT);
627 cpl_error_code status = CPL_ERROR_NONE;
628 const char *filename = NULL;
629 const char *trace_filename = NULL;
630 cpl_propertylist *raw_pheader = NULL;
631 cpl_propertylist *trace_pheader = NULL;
632 int raw_offset, trace_offset;
633
634 cpl_errorstate prestate = cpl_errorstate_get();
635 moo_try_check(filename = cpl_frame_get_filename(raw), " ");
636 moo_try_check(trace_filename = cpl_frame_get_filename(ff_trace), " ");
637
638 moo_try_check(raw_pheader = cpl_propertylist_load(filename, 0), " ");
639 moo_try_check(trace_pheader = cpl_propertylist_load(trace_filename, 0),
640 " ");
641
642 moo_try_check(raw_offset = moo_pfits_get_slit_offset(raw_pheader), " ");
643 moo_try_check(trace_offset = moo_pfits_get_slit_offset(trace_pheader), " ");
644
645 if (raw_offset != trace_offset) {
646 cpl_msg_error("check_header",
647 "OFFSET keyword mismatch between FLAT file %s value %d "
648 "and FF_TRACE file %s value %d",
649 filename, raw_offset, trace_filename, trace_offset);
650 status = CPL_ERROR_ILLEGAL_INPUT;
651 cpl_error_set("check_header", status);
652 }
653
654moo_try_cleanup:
655 if (!cpl_errorstate_is_equal(prestate)) {
656 status = cpl_error_get_code();
657 }
658 cpl_propertylist_delete(raw_pheader);
659 cpl_propertylist_delete(trace_pheader);
660 return status;
661}
662
663/*----------------------------------------------------------------------------*/
680/*----------------------------------------------------------------------------*/
681static moo_loc *
682_moons_mflat_localise(cpl_frameset *raw_frames,
683 cpl_frameset *rawoff_frames,
684 const char *bpmap_rp_name,
685 const char *bpmap_nl_name,
686 const cpl_frame *masterbias,
687 const cpl_frame *masterdark_vis,
688 const cpl_frame *masterdark_nir,
689 const cpl_frame *coeffs_cube,
690 const cpl_frame *p2pmap,
691 const cpl_frame *ff_trace_guess,
692 moo_prepare_params *prepare_params,
693 moo_crh_params *crh_params,
694 moo_compute_slitoffset_params *compute_slitoffset_params,
695 moo_localise_params *localise_params,
696 moo_model_flat_params *modelflat_params,
697 moo_correct_bias_params *cbias_params,
698 int domodel,
699 const char *loctag,
700 moo_products *products,
701 moo_det **medflat,
702 moo_psf **psf,
703 const cpl_frame **ref_frame,
704 double *offset,
705 moo_mode_type *mode,
706 cpl_frame_level level)
707{
708 moo_loc *loc = NULL;
709 cpl_frameset *detframes = NULL;
710 moo_detlist *detList = NULL;
711 char *locname = NULL;
712 char *flatname = NULL;
713 char *flatp2p_name = NULL;
714 moo_det *p2p = NULL;
715
716 cpl_ensure(loctag != NULL, CPL_ERROR_NULL_INPUT, NULL);
717 cpl_ensure(raw_frames != NULL, CPL_ERROR_NULL_INPUT, NULL);
718 cpl_ensure(rawoff_frames != NULL, CPL_ERROR_NULL_INPUT, NULL);
719
720 cpl_errorstate prestate = cpl_errorstate_get();
721
722 int nraw, nraw_off;
723
724 moo_try_check(nraw = cpl_frameset_get_size(raw_frames), " ");
725 moo_try_check(nraw_off = cpl_frameset_get_size(rawoff_frames), " ");
726
727 if (nraw == 0) {
728 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
729 "SOF does not have any file tagged "
730 "with %s",
731 MOONS_TAG_FLAT);
732 return NULL;
733 }
734
735 if (nraw < 3) {
736 cpl_msg_warning(cpl_func,
737 "SOF does not have enough files (%d<3) tagged "
738 "with %s",
739 nraw, MOONS_TAG_FLAT);
740 }
741
742 if (nraw_off != nraw) {
743 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
744 "SOF does not have %d files tagged "
745 "with %s",
746 nraw, MOONS_TAG_FLAT_OFF);
747 return NULL;
748 }
749
750 if (masterbias == NULL) {
751 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
752 "SOF does not have any file tagged "
753 "with %s",
754 MOONS_TAG_MASTER_BIAS);
755 return NULL;
756 }
757
758 if (ff_trace_guess != NULL) {
759 moo_try_check(_moons_flat_check_header(
760 cpl_frameset_get_position_const(raw_frames, 0),
761 ff_trace_guess),
762 " Mismatch header");
763 }
764
765 moo_try_check(*ref_frame = cpl_frameset_get_position_const(raw_frames, 0),
766 " ");
767 moo_try_check(*mode = moo_mode_get(*ref_frame), " ");
768 moo_try_check(*offset = moo_offset_get(*ref_frame), " ");
769
770
771 moo_try_check(detframes = _moons_prepare_set(raw_frames, rawoff_frames,
772 bpmap_rp_name, bpmap_nl_name,
773 masterbias, masterdark_vis,
774 masterdark_nir, coeffs_cube,
775 prepare_params, cbias_params,
776 products, *mode, *offset),
777 " ");
778
779 moo_try_check(detList = moo_detlist_create(detframes), " ");
780 moo_try_check(*medflat = moo_remove_CRH(detList, NULL, crh_params), " ");
781 moo_try_check(flatname = cpl_sprintf("%s_OFFSET%d_%s.fits",
782 MOONS_TAG_FLAT_REMOVECRH, (int)*offset,
783 moo_mode_get_name(*mode)),
784 " ");
785
786 moo_try_check(moo_products_add(products, *medflat,
787 CPL_FRAME_LEVEL_INTERMEDIATE,
788 MOONS_TAG_FLAT_REMOVECRH, flatname,
789 *ref_frame),
790 " ");
791
792 if (p2pmap != NULL) {
793 moo_try_check(p2p = moo_det_create(p2pmap), " ");
794 moo_try_check(moo_apply_p2p(*medflat, p2p), " ");
795 flatp2p_name =
796 cpl_sprintf("%s_OFFSET%d_%s.fits", MOONS_TAG_FLAT_APPLYP2P,
797 (int)*offset, moo_mode_get_name(*mode));
798 moo_products_add(products, *medflat, CPL_FRAME_LEVEL_INTERMEDIATE,
799 MOONS_TAG_FLAT_APPLYP2P, flatp2p_name, *ref_frame);
800 moo_det_delete(p2p);
801 p2p = NULL;
802 }
803 if (ff_trace_guess != NULL) {
804 moo_loc *gloc = moo_loc_load(ff_trace_guess);
805 float *offsets =
806 moo_compute_slitoffset(*medflat, gloc, compute_slitoffset_params);
807 for (int i = 0; i < 6; i++) {
808 cpl_msg_info("test", "Offsets[%d]=%f", i, offsets[i]);
809 }
810 moo_loc_delete(gloc);
811 cpl_free(offsets);
812 }
813 moo_try_check(locname = cpl_sprintf("%s_OFFSET%d_%s.fits", loctag,
814 (int)*offset, moo_mode_get_name(*mode)),
815 " ");
816 moo_try_check(loc = moo_localise(*medflat, ff_trace_guess, localise_params,
817 locname),
818 " ");
819
820 moo_try_check(moo_products_add_loc(products, loc,
821 localise_params->keep_points, level,
822 loctag, locname, *ref_frame),
823 " ");
824
825 if (domodel) {
826 char *psfname =
827 cpl_sprintf("%s_OFFSET%d_%s.fits", MOONS_TAG_MASTER_FLAT,
828 (int)*offset, moo_mode_get_name(*mode));
829 *psf = moo_model_flat(*medflat, loc, modelflat_params, psfname);
830 moo_products_add_psf(products, *psf, level, MOONS_TAG_MASTER_FLAT,
831 psfname, *ref_frame);
832 cpl_free(psfname);
833 }
834
835moo_try_cleanup:
836 cpl_frameset_delete(detframes);
837 moo_detlist_delete(detList);
838 cpl_free(flatname);
839 cpl_free(flatp2p_name);
840 cpl_free(locname);
841 if (!cpl_errorstate_is_equal(prestate)) {
842 moo_loc_delete(loc);
843 loc = NULL;
844 moo_det_delete(p2p);
845 p2p = NULL;
846 }
847 return loc;
848}
849
850static cpl_error_code
851_moons_mflat_fibtrans(moo_det *medflat,
852 moo_loc *ff_trace,
853 moo_psf *psf,
854 moo_extract_params *extract_params,
855 moo_compute_fibtrans_params *fibtrans_params,
856 moo_products *products,
857 const cpl_frame *ref_frame,
858 double offset,
859 moo_mode_type mode)
860{
861 moo_f2f *f2f = NULL;
862 moo_ext *ext = NULL;
863 char *flatname = NULL;
864 char *extname = NULL;
865 char *ffname = NULL;
866 char *f2fname = NULL;
867
868 cpl_ensure_code(medflat != NULL, CPL_ERROR_NULL_INPUT);
869 cpl_msg_info("moons_mflat", "Work on offset %d mode %s", (int)offset,
870 moo_mode_get_name(mode));
871
872 extname = cpl_sprintf("%s_OFFSET%d_%s.fits", MOONS_TAG_FLAT_EXTSPECTRA,
873 (int)offset, moo_mode_get_name(mode));
874
875 moo_try_check(ext = moo_extract(medflat, ff_trace, psf, extract_params,
876 extname),
877 " ");
878 moo_products_add_ext(products, ext, CPL_FRAME_LEVEL_INTERMEDIATE,
879 MOONS_TAG_FLAT_EXTSPECTRA, extname, ref_frame);
880
881
882 ffname = cpl_sprintf("%s_OFFSET%d_%s.fits", MOONS_TAG_FF_EXTSPECTRA,
883 (int)offset, moo_mode_get_name(mode));
884 f2fname = cpl_sprintf("%s_OFFSET%d_%s.fits", MOONS_TAG_F2F_TABLE,
885 (int)offset, moo_mode_get_name(mode));
886
887 moo_try_check(f2f = moo_compute_fibtrans(ext, fibtrans_params, f2fname),
888 " ");
889 moo_products_add_ext(products, ext, CPL_FRAME_LEVEL_FINAL,
890 MOONS_TAG_FF_EXTSPECTRA, ffname, ref_frame);
891 moo_products_add_f2f(products, f2f, CPL_FRAME_LEVEL_FINAL,
892 MOONS_TAG_F2F_TABLE, f2fname, ref_frame);
893
894moo_try_cleanup:
895 cpl_free(flatname);
896 cpl_free(extname);
897 cpl_free(f2fname);
898 cpl_free(ffname);
899
900 moo_ext_delete(ext);
901 moo_f2f_delete(f2f);
902
903 return CPL_ERROR_NONE;
904}
905
906/*----------------------------------------------------------------------------*/
926/*----------------------------------------------------------------------------*/
927#ifdef ALTERNATIVE_DRIVER
928static int
929_moons_mflat_wf1(cpl_frameset *raw_frames,
930 cpl_frameset *rawoff_frames,
931 const char *bpmap_rp_name,
932 const char *bpmap_nl_name,
933 const cpl_frame *masterbias,
934 const cpl_frame *masterdark_vis,
935 const cpl_frame *masterdark_nir,
936 const cpl_frame *coeffs_cube,
937 moo_prepare_params *prepare_params,
938 moo_crh_params *crh_params,
939 moo_localise_params *localise_params,
940 moo_correct_bias_params *cbias_params,
941 moo_products *products)
942#else
943static int
944_moons_mflat_wf1(cpl_frameset **raw_byoffset_set,
945 cpl_frameset *rawoff_frames,
946 const char *bpmap_rp_name,
947 const char *bpmap_nl_name,
948 const cpl_frame *masterbias,
949 const cpl_frame *masterdark_vis,
950 const cpl_frame *masterdark_nir,
951 const cpl_frame *coeffs_cube,
952 moo_prepare_params *prepare_params,
953 moo_crh_params *crh_params,
954 moo_localise_params *localise_params,
955 moo_correct_bias_params *cbias_params,
956 moo_products *products)
957#endif
958{
959#ifdef ALTERNATIVE_DRIVER
960 cpl_ensure_code(raw_frames != NULL, CPL_ERROR_NULL_INPUT);
961#else
962 cpl_ensure_code(raw_byoffset_set != NULL, CPL_ERROR_NULL_INPUT);
963 cpl_ensure_code(raw_byoffset_set[0] != NULL, CPL_ERROR_NULL_INPUT);
964 cpl_ensure_code(raw_byoffset_set[1] != NULL, CPL_ERROR_NULL_INPUT);
965
966 int size1 = 0;
967 int size2 = 0;
968 cpl_frameset *raw_frames = NULL;
969#endif
970 const cpl_frame *ref_frame = NULL;
971 moo_det *medflat = NULL;
972 moo_loc *guess_loc = NULL;
973 double offset;
974 moo_mode_type mode;
975
976#ifndef ALTERNATIVE_DRIVER
977 moo_try_check(size1 = cpl_frameset_get_size(raw_byoffset_set[0]), " ");
978 moo_try_check(size2 = cpl_frameset_get_size(raw_byoffset_set[1]), " ");
979
980
981 if (size1 > 0) {
982 if (size2 > 0) {
983 return (int)
984 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
985 "SOF have two different offset in input");
986 }
987 raw_frames = raw_byoffset_set[0];
988 }
989 else {
990 raw_frames = raw_byoffset_set[1];
991 }
992#endif
993 moo_try_assure(cpl_frameset_get_size(raw_frames) > 0,
994 CPL_ERROR_ILLEGAL_INPUT, "No FLAT frames in input");
995 moo_try_check(guess_loc = _moons_mflat_localise(
996 raw_frames, rawoff_frames, bpmap_rp_name, bpmap_nl_name,
997 masterbias, masterdark_vis, masterdark_nir, coeffs_cube,
998 NULL, NULL, prepare_params, crh_params, NULL,
999 localise_params, NULL, cbias_params, 0,
1000 MOONS_TAG_FF_TRACE_GUESS, products, &medflat, NULL,
1001 &ref_frame, &offset, &mode, CPL_FRAME_LEVEL_FINAL),
1002 " ");
1003
1004moo_try_cleanup:
1005 moo_loc_delete(guess_loc);
1006 moo_det_delete(medflat);
1007 return CPL_ERROR_NONE;
1008}
1009/*----------------------------------------------------------------------------*/
1030/*----------------------------------------------------------------------------*/
1031static int
1032_moons_mflat_wf4(const cpl_frame *flat_attached_frame,
1033 const cpl_frame *flat_off_frame,
1034 const char *bpmap_rp_name,
1035 const char *bpmap_nl_name,
1036 const cpl_frame *masterbias,
1037 const cpl_frame *masterdark_vis,
1038 const cpl_frame *masterdark_nir,
1039 const cpl_frame *coeffs_cube,
1040 const cpl_frame *ff_trace_frame,
1041 const cpl_frame *p2pmap,
1042 const cpl_frame *master_flat,
1043 moo_prepare_params *prepare_params,
1044 moo_extract_params *extract_params,
1045 moo_compute_fibtrans_params *fibtrans_params,
1046 moo_correct_bias_params *cbias_params,
1047 moo_products *products)
1048{
1049 cpl_ensure_code(flat_attached_frame != NULL, CPL_ERROR_NULL_INPUT);
1050 cpl_ensure_code(flat_off_frame != NULL, CPL_ERROR_NULL_INPUT);
1051 cpl_ensure_code(ff_trace_frame != NULL, CPL_ERROR_NULL_INPUT);
1052
1053 moo_loc *ff_trace = NULL;
1054 int offset;
1055 moo_mode_type mode;
1056 char *detname1 = NULL;
1057 char *detname2 = NULL;
1058 char *detname3 = NULL;
1059 moo_det *det = NULL;
1060 moo_det *detoff = NULL;
1061 moo_f2f *f2f = NULL;
1062 moo_ext *ext = NULL;
1063 char *flatname = NULL;
1064 char *extname = NULL;
1065 char *f2fname = NULL;
1066 moo_det *p2p = NULL;
1067 moo_psf *psf = NULL;
1068
1069 cpl_errorstate prestate = cpl_errorstate_get();
1070
1071 if (masterbias == NULL) {
1072 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1073 "SOF does not have any file tagged "
1074 "with %s",
1075 MOONS_TAG_MASTER_BIAS);
1076 return CPL_ERROR_NONE;
1077 }
1078
1079 if (ff_trace_frame != NULL) {
1080 moo_try_check(_moons_flat_check_header(flat_attached_frame,
1081 ff_trace_frame),
1082 " Mismatch header");
1083 }
1084
1085 moo_try_check(mode = moo_mode_get(flat_attached_frame), " ");
1086 moo_try_check(offset = moo_offset_get(flat_attached_frame), " ");
1087 moo_try_check(det = moo_prepare(flat_attached_frame, bpmap_rp_name,
1088 bpmap_nl_name, masterbias, coeffs_cube,
1089 prepare_params),
1090 " ");
1091
1092 moo_try_check(detoff =
1093 moo_prepare(flat_off_frame, bpmap_rp_name, bpmap_nl_name,
1094 masterbias, coeffs_cube, prepare_params),
1095 " ");
1096 moo_try_check(moo_correct_bias(det, masterbias, cbias_params), " ");
1097
1098 moo_try_check(detname1 = cpl_sprintf("%s_OFFSET%d_%s.fits",
1099 MOONS_TAG_FLAT_CORRECTBIAS, offset,
1100 moo_mode_get_name(mode)),
1101 " ");
1102 moo_try_check(moo_products_add(products, det, CPL_FRAME_LEVEL_INTERMEDIATE,
1103 MOONS_TAG_FLAT_CORRECTBIAS, detname1,
1104 flat_attached_frame),
1105 " ");
1106
1107 moo_try_check(detname2 = cpl_sprintf("%s_OFFSET%d_%s.fits",
1108 MOONS_TAG_FLATOFF_PREPARE, offset,
1109 moo_mode_get_name(mode)),
1110 " ");
1111
1112 moo_try_check(moo_products_add(products, detoff,
1113 CPL_FRAME_LEVEL_INTERMEDIATE,
1114 MOONS_TAG_FLATOFF_PREPARE, detname2,
1115 flat_off_frame),
1116 " ");
1117
1118 moo_try_check(moo_correct_dark(det, detoff, masterdark_vis, masterdark_nir),
1119 " ");
1120 moo_try_check(detname3 = cpl_sprintf("%s_OFFSET%d_%s.fits",
1121 MOONS_TAG_FLAT_CORRECTDARK, offset,
1122 moo_mode_get_name(mode)),
1123 " ");
1124 moo_try_check(moo_products_add(products, det, CPL_FRAME_LEVEL_INTERMEDIATE,
1125 MOONS_TAG_FLAT_CORRECTDARK, detname3,
1126 flat_attached_frame),
1127 " ");
1128
1129 if (p2pmap != NULL) {
1130 moo_try_check(p2p = moo_det_create(p2pmap), " ");
1131 moo_try_check(moo_apply_p2p(det, p2p), " ");
1132 flatname = cpl_sprintf("%s_OFFSET%d_%s.fits", MOONS_TAG_FLAT_APPLYP2P,
1133 offset, moo_mode_get_name(mode));
1134 moo_products_add(products, det, CPL_FRAME_LEVEL_INTERMEDIATE,
1135 MOONS_TAG_FLAT_APPLYP2P, flatname,
1136 flat_attached_frame);
1137
1138 moo_det_delete(p2p);
1139 p2p = NULL;
1140 }
1141
1142 extname =
1143 cpl_sprintf("EXT_OFFSET%d_%s.fits", offset, moo_mode_get_name(mode));
1144
1145 moo_try_check(ff_trace = moo_loc_load(ff_trace_frame), " ");
1146
1147 if (master_flat != NULL) {
1148 psf = moo_psf_load(master_flat);
1149 }
1150 moo_try_check(ext =
1151 moo_extract(det, ff_trace, psf, extract_params, extname),
1152 " ");
1153
1154 moo_products_add_ext(products, ext, CPL_FRAME_LEVEL_INTERMEDIATE, "EXT",
1155 extname, flat_attached_frame);
1156
1157
1158 f2fname =
1159 cpl_sprintf("F2F_OFFSET%d_%s.fits", offset, moo_mode_get_name(mode));
1160 f2f = moo_compute_fibtrans(ext, fibtrans_params, f2fname);
1161 moo_flat_shift_compute(det, ff_trace);
1162
1163 moo_products_add_f2f(products, f2f, CPL_FRAME_LEVEL_FINAL,
1164 MOONS_TAG_F2F_TABLE, f2fname, flat_attached_frame);
1165
1166moo_try_cleanup:
1167 cpl_free(flatname);
1168 cpl_free(extname);
1169 cpl_free(f2fname);
1170
1171 moo_ext_delete(ext);
1172 moo_f2f_delete(f2f);
1173 if (!cpl_errorstate_is_equal(prestate)) {
1174 moo_det_delete(p2p);
1175 }
1176 moo_det_delete(det);
1177 moo_det_delete(detoff);
1178 cpl_free(detname1);
1179 cpl_free(detname2);
1180 cpl_free(detname3);
1181 moo_loc_delete(ff_trace);
1182 moo_psf_delete(psf);
1183
1184 return CPL_ERROR_NONE;
1185}
1186
1187/*----------------------------------------------------------------------------*/
1211/*----------------------------------------------------------------------------*/
1212#ifdef ALTERNATIVE_DRIVER
1213static int
1214_moons_mflat_wf2(cpl_frameset *raw_frames,
1215 cpl_frameset *rawoff_frames,
1216 const char *bpmap_rp_name,
1217 const char *bpmap_nl_name,
1218 const cpl_frame *masterbias,
1219 const cpl_frame *masterdark_vis,
1220 const cpl_frame *masterdark_nir,
1221 const cpl_frame *coeffs_cube,
1222 const cpl_frame *ff_trace_guess,
1223 const cpl_frame *p2pmap,
1224 moo_prepare_params *prepare_params,
1225 moo_crh_params *crh_params,
1226 moo_localise_params *localise_params,
1227 moo_compute_slitoffset_params *compute_slitoffset_params,
1228 moo_extract_params *extract_params,
1229 moo_model_flat_params *modelflat_params,
1230 moo_compute_fibtrans_params *fibtrans_params,
1231 moo_correct_bias_params *cbias_params,
1232 moo_products *products)
1233#else
1234static int
1235_moons_mflat_wf2(cpl_frameset **raw_byoffset_set,
1236 cpl_frameset *rawoff_frames,
1237 const char *bpmap_rp_name,
1238 const char *bpmap_nl_name,
1239 const cpl_frame *masterbias,
1240 const cpl_frame *masterdark_vis,
1241 const cpl_frame *masterdark_nir,
1242 const cpl_frame *coeffs_cube,
1243 const cpl_frame *ff_trace_guess,
1244 const cpl_frame *p2pmap,
1245 moo_prepare_params *prepare_params,
1246 moo_crh_params *crh_params,
1247 moo_localise_params *localise_params,
1248 moo_compute_slitoffset_params *compute_slitoffset_params,
1249 moo_extract_params *extract_params,
1250 moo_model_flat_params *modelflat_params,
1251 moo_compute_fibtrans_params *fibtrans_params,
1252 moo_correct_bias_params *cbias_params,
1253 moo_products *products)
1254#endif
1255{
1256#ifdef ALTERNATIVE_DRIVER
1257 cpl_ensure_code(raw_frames != NULL, CPL_ERROR_NULL_INPUT);
1258#else
1259 cpl_ensure_code(raw_byoffset_set != NULL, CPL_ERROR_NULL_INPUT);
1260 cpl_ensure_code(raw_byoffset_set[0] != NULL, CPL_ERROR_NULL_INPUT);
1261 cpl_ensure_code(raw_byoffset_set[1] != NULL, CPL_ERROR_NULL_INPUT);
1262#endif
1263 int domodel =
1264 (strcmp(extract_params->method, MOO_EXTRACT_METHOD_OPTIMAL) == 0);
1265
1266 const cpl_frame *ref_frame = NULL;
1267 moo_det *medflat = NULL;
1268 moo_loc *ff_trace = NULL;
1269 moo_psf *psf = NULL;
1270 double offset;
1271 moo_mode_type mode;
1272#ifndef ALTERNATIVE_DRIVER
1273 cpl_frameset *raw_frames = NULL;
1274
1275 int size1 = 0;
1276 int size2 = 0;
1277
1278 moo_try_check(size1 = cpl_frameset_get_size(raw_byoffset_set[0]), " ");
1279 moo_try_check(size2 = cpl_frameset_get_size(raw_byoffset_set[1]), " ");
1280
1281 if (size1 > 0) {
1282 if (size2 > 0) {
1283 return (int)cpl_error_set_message(
1284 cpl_func, CPL_ERROR_ILLEGAL_INPUT,
1285 "SOF have two different offset in input ");
1286 }
1287 raw_frames = raw_byoffset_set[0];
1288 }
1289 else {
1290 raw_frames = raw_byoffset_set[1];
1291 }
1292#endif
1293
1294 moo_try_assure(cpl_frameset_get_size(raw_frames) > 0,
1295 CPL_ERROR_ILLEGAL_INPUT, "No FLAT frames in input");
1296
1297
1298 moo_try_check(ff_trace = _moons_mflat_localise(
1299 raw_frames, rawoff_frames, bpmap_rp_name, bpmap_nl_name,
1300 masterbias, masterdark_vis, masterdark_nir, coeffs_cube,
1301 p2pmap, ff_trace_guess, prepare_params, crh_params,
1302 compute_slitoffset_params, localise_params,
1303 modelflat_params, cbias_params, domodel,
1304 MOONS_TAG_FF_TRACE, products, &medflat, &psf, &ref_frame,
1305 &offset, &mode, CPL_FRAME_LEVEL_FINAL),
1306 " ");
1307
1308 moo_try_check(_moons_mflat_fibtrans(medflat, ff_trace, psf, extract_params,
1309 fibtrans_params, products, ref_frame,
1310 offset, mode),
1311 " ");
1312
1313moo_try_cleanup:
1314 moo_loc_delete(ff_trace);
1315 moo_det_delete(medflat);
1316 moo_psf_delete(psf);
1317
1318 return CPL_ERROR_NONE;
1319}
1320
1321#ifdef ALTERNATIVE_DRIVER
1322static int
1323_moons_mflat_wf3(cpl_frameset *frames_offset1,
1324 cpl_frameset *frames_offset2,
1325 cpl_frameset *frames_other,
1326 moo_prepare_params *prepare_params,
1327 moo_crh_params *crh_params,
1328 moo_compute_slitoffset_params *compute_slitoffset_params,
1329 moo_localise_params *localise_params,
1330 moo_model_flat_params *modelflat_params,
1331 moo_correct_bias_params *cbias_params,
1332 moo_products *products)
1333#else
1334static int
1335_moons_mflat_wf3(cpl_frameset **raw_byoffset_set,
1336 cpl_frameset *rawoff_frames,
1337 const char *bpmap_rp_name,
1338 const char *bpmap_nl_name,
1339 const cpl_frame *masterbias,
1340 const cpl_frame *masterdark_vis,
1341 const cpl_frame *masterdark_nir,
1342 cpl_frameset **cube_set,
1343 cpl_frameset **ff_trace_set,
1344 moo_prepare_params *prepare_params,
1345 moo_crh_params *crh_params,
1346 moo_compute_slitoffset_params *compute_slitoffset_params,
1347 moo_localise_params *localise_params,
1348 moo_model_flat_params *modelflat_params,
1349 moo_correct_bias_params *cbias_params,
1350 moo_products *products)
1351#endif
1352{
1353 const cpl_frame *coeffs_cube1 = NULL;
1354 const cpl_frame *coeffs_cube2 = NULL;
1355 const cpl_frame *ref_frame1 = NULL;
1356 const cpl_frame *ref_frame2 = NULL;
1357
1358 moo_det *medflat1 = NULL;
1359 moo_loc *ff_trace1 = NULL;
1360 double offset1;
1361 moo_psf *psf1 = NULL;
1362
1363 moo_det *medflat2 = NULL;
1364 moo_loc *ff_trace2 = NULL;
1365 double offset2;
1366 moo_psf *psf2 = NULL;
1367
1368 moo_mode_type mode;
1369 moo_det *p2p = NULL;
1370 char *p2pname = NULL;
1371
1372#ifdef ALTERNATIVE_DRIVER
1373 const int min_nflats_on = 3;
1374
1375 cpl_frameset *raw_frames1 =
1376 moo_dfs_extract_tag(frames_offset1, MOONS_TAG_FLAT);
1377 cpl_frameset *raw_frames2 =
1378 moo_dfs_extract_tag(frames_offset2, MOONS_TAG_FLAT);
1379
1380 if ((raw_frames1 == NULL) &&
1381 (cpl_frameset_get_size(raw_frames1) < min_nflats_on)) {
1382 cpl_error_code ecode = CPL_ERROR_DATA_NOT_FOUND;
1383 cpl_frameset_delete(raw_frames2);
1384 cpl_frameset_delete(raw_frames1);
1385 cpl_error_set_message(cpl_func, ecode,
1386 "Too few input `%s' frames are available for "
1387 "slit offset position `%d'. Minimum required "
1388 "input frames is `%d'!",
1389 MOONS_TAG_FLAT, 1, min_nflats_on);
1390 return ecode;
1391 }
1392 if ((raw_frames2 == NULL) &&
1393 (cpl_frameset_get_size(raw_frames2) < min_nflats_on)) {
1394 cpl_error_code ecode = CPL_ERROR_DATA_NOT_FOUND;
1395 cpl_frameset_delete(raw_frames2);
1396 cpl_frameset_delete(raw_frames1);
1397 cpl_error_set_message(cpl_func, ecode,
1398 "Too few input `%s' frames are available for "
1399 "slit offset position `%d'. Minimum required "
1400 "input frames is `%d'!",
1401 MOONS_TAG_FLAT, 2, min_nflats_on);
1402 return ecode;
1403 }
1404 if (cpl_frameset_get_size(raw_frames1) !=
1405 cpl_frameset_get_size(raw_frames2)) {
1406 cpl_error_code ecode = CPL_ERROR_INCOMPATIBLE_INPUT;
1407 cpl_frameset_delete(raw_frames2);
1408 cpl_frameset_delete(raw_frames1);
1409 cpl_error_set_message(
1410 cpl_func, ecode,
1411 "The number of provided `%s' frames for slit "
1412 "offset position `%d' does not match "
1413 "the number of provided `%s' frames for slit offset position `%d'!",
1414 MOONS_TAG_FLAT, 1, MOONS_TAG_FLAT, 2);
1415 return ecode;
1416 }
1417
1418 cpl_frameset *rawoff_frames1 =
1419 moo_dfs_extract_tag(frames_offset1, MOONS_TAG_FLAT_OFF);
1420 cpl_frameset *rawoff_frames2 =
1421 moo_dfs_extract_tag(frames_offset2, MOONS_TAG_FLAT_OFF);
1422
1423 if (cpl_frameset_get_size(rawoff_frames1) !=
1424 cpl_frameset_get_size(raw_frames1)) {
1425 cpl_error_code ecode = CPL_ERROR_INCOMPATIBLE_INPUT;
1426 cpl_frameset_delete(rawoff_frames2);
1427 cpl_frameset_delete(rawoff_frames1);
1428 cpl_frameset_delete(raw_frames2);
1429 cpl_frameset_delete(raw_frames1);
1430 cpl_error_set_message(cpl_func, ecode,
1431 "The number of provided `%s' frames for slit "
1432 "offset position `%d' does not match "
1433 "the number of provided `%s' frames!",
1434 MOONS_TAG_FLAT_OFF, 1, MOONS_TAG_FLAT);
1435 return ecode;
1436 }
1437 if (cpl_frameset_get_size(rawoff_frames2) !=
1438 cpl_frameset_get_size(raw_frames2)) {
1439 cpl_error_code ecode = CPL_ERROR_INCOMPATIBLE_INPUT;
1440 cpl_frameset_delete(rawoff_frames2);
1441 cpl_frameset_delete(rawoff_frames1);
1442 cpl_frameset_delete(raw_frames2);
1443 cpl_frameset_delete(raw_frames1);
1444 cpl_error_set_message(cpl_func, ecode,
1445 "The number of provided `%s' frames for slit "
1446 "offset position `%d' does not match "
1447 "the number of provided `%s'frames!",
1448 MOONS_TAG_FLAT_OFF, 2, MOONS_TAG_FLAT);
1449 return ecode;
1450 }
1451
1452 const cpl_frame *bp_map_nl[] = {
1453 cpl_frameset_find_const(frames_offset1, MOONS_TAG_BP_MAP_NL),
1454 cpl_frameset_find_const(frames_offset2, MOONS_TAG_BP_MAP_NL)};
1455 if (((bp_map_nl[0] == NULL) && (bp_map_nl[1] != NULL)) ||
1456 ((bp_map_nl[1] == NULL) && (bp_map_nl[0] != NULL))) {
1457 cpl_error_code ecode = CPL_ERROR_INCOMPATIBLE_INPUT;
1458 cpl_frameset_delete(rawoff_frames2);
1459 cpl_frameset_delete(rawoff_frames1);
1460 cpl_frameset_delete(raw_frames2);
1461 cpl_frameset_delete(raw_frames1);
1462 cpl_error_set_message(
1463 cpl_func, ecode,
1464 "Inconsistent number of optional `%s' frames! The number of "
1465 "provided input frames must be the same for both slit offset "
1466 "positions!",
1467 MOONS_TAG_BP_MAP_NL);
1468 return ecode;
1469 }
1470
1471 const cpl_frame *coeffs_cube[] = {
1472 cpl_frameset_find_const(frames_offset1, MOONS_TAG_LINEARITY_COEFF_CUBE),
1473 cpl_frameset_find_const(frames_offset2,
1474 MOONS_TAG_LINEARITY_COEFF_CUBE)};
1475 if (((coeffs_cube[0] == NULL) && (coeffs_cube[1] != NULL)) ||
1476 ((coeffs_cube[1] == NULL) && (coeffs_cube[0] != NULL))) {
1477 cpl_error_code ecode = CPL_ERROR_INCOMPATIBLE_INPUT;
1478 cpl_frameset_delete(rawoff_frames2);
1479 cpl_frameset_delete(rawoff_frames1);
1480 cpl_frameset_delete(raw_frames2);
1481 cpl_frameset_delete(raw_frames1);
1482 cpl_error_set_message(
1483 cpl_func, ecode,
1484 "Inconsistent number of optional `%s' frames! The number of "
1485 "provided input frames must be the same for both slit offset "
1486 "positions!",
1487 MOONS_TAG_BP_MAP_NL);
1488 return ecode;
1489 }
1490
1491 // FIXME: If the guess fftrace frame is not found this results in a different error code
1492 // compared to the original code. This may have to be adjusted for compatibility
1493 // reasons, but the returned error codes are anyway inconsistent in the original
1494 // code when comparing the same error condition across the 4 workflows. So for
1495 // now stick to the error code model used in the other functions of the new code.
1496 const cpl_frame *fftrace_guess[] = {
1497 cpl_frameset_find_const(frames_offset1, MOONS_TAG_FF_TRACE_GUESS),
1498 cpl_frameset_find_const(frames_offset2, MOONS_TAG_FF_TRACE_GUESS)};
1499 if (((fftrace_guess[0] == NULL) || (fftrace_guess[1] == NULL))) {
1500 cpl_error_code ecode = CPL_ERROR_DATA_NOT_FOUND;
1501 cpl_frameset_delete(rawoff_frames2);
1502 cpl_frameset_delete(rawoff_frames1);
1503 cpl_frameset_delete(raw_frames2);
1504 cpl_frameset_delete(raw_frames1);
1505 cpl_error_set_message(cpl_func, ecode,
1506 "Required input frame `%s' is missing for at "
1507 "least one slit offset position!",
1508 MOONS_TAG_FF_TRACE_GUESS);
1509 return ecode;
1510 }
1511
1512 const cpl_frame *bp_map_rp =
1513 cpl_frameset_find_const(frames_other, MOONS_TAG_BP_MAP_RP);
1514 const cpl_frame *masterbias =
1515 cpl_frameset_find_const(frames_other, MOONS_TAG_MASTER_BIAS);
1516 cpl_msg_info(cpl_func, "masterbias: %p", masterbias);
1517 cpl_frameset_dump(frames_other, NULL);
1518 cpl_msg_info(cpl_func, "master bias frame:");
1519 cpl_frame_dump(masterbias, NULL);
1520
1521 const cpl_frame *masterdark_vis =
1522 cpl_frameset_find_const(frames_other, MOONS_TAG_MASTER_DARK_VIS);
1523 const cpl_frame *masterdark_nir =
1524 cpl_frameset_find_const(frames_other, MOONS_TAG_MASTER_DARK_NIR);
1525
1526 if (masterbias == NULL) {
1527 cpl_error_code ecode = CPL_ERROR_DATA_NOT_FOUND;
1528 cpl_frameset_delete(rawoff_frames2);
1529 cpl_frameset_delete(rawoff_frames1);
1530 cpl_frameset_delete(raw_frames2);
1531 cpl_frameset_delete(raw_frames1);
1532 cpl_error_set_message(cpl_func, ecode,
1533 "Required `%s' input frame is missing!",
1534 MOONS_TAG_MASTER_BIAS);
1535 return ecode;
1536 }
1537
1538 const char *bpmap_rp_name =
1539 (bp_map_rp != NULL) ? cpl_frame_get_filename(bp_map_rp) : NULL;
1540
1541 // FIXME: Adapt to original function interface. Remove if new driver code
1542 // is accepted!
1543 const cpl_frame *ff_trace_guess1 = fftrace_guess[0];
1544 const cpl_frame *ff_trace_guess2 = fftrace_guess[1];
1545
1546 const char *bpmap_nl_name1 =
1547 (bp_map_nl[0] != NULL) ? cpl_frame_get_filename(bp_map_nl[0]) : NULL;
1548 const char *bpmap_nl_name2 =
1549 (bp_map_nl[1] != NULL) ? cpl_frame_get_filename(bp_map_nl[1]) : NULL;
1550#else
1551 int sff_trace1 = cpl_frameset_get_size(ff_trace_set[0]);
1552 int sff_trace2 = cpl_frameset_get_size(ff_trace_set[1]);
1553
1554 cpl_ensure_code(sff_trace1 == 1, CPL_ERROR_ILLEGAL_INPUT);
1555 cpl_ensure_code(sff_trace2 == 1, CPL_ERROR_ILLEGAL_INPUT);
1556
1557 cpl_frameset *raw_frames1 = raw_byoffset_set[0];
1558 cpl_frameset *raw_frames2 = raw_byoffset_set[1];
1559 cpl_frameset *rawoff_frames1 = rawoff_frames;
1560 cpl_frameset *rawoff_frames2 = rawoff_frames;
1561
1562 const cpl_frame *ff_trace_guess1 =
1563 cpl_frameset_get_position_const(ff_trace_set[0], 0);
1564 const cpl_frame *ff_trace_guess2 =
1565 cpl_frameset_get_position_const(ff_trace_set[1], 0);
1566
1567 int csize1 = cpl_frameset_get_size(cube_set[0]);
1568 int csize2 = cpl_frameset_get_size(cube_set[1]);
1569 if (csize1 > 0) {
1570 coeffs_cube1 = cpl_frameset_get_position_const(cube_set[0], 0);
1571 }
1572 if (csize2 > 0) {
1573 coeffs_cube2 = cpl_frameset_get_position_const(cube_set[1], 0);
1574 }
1575
1576 const char *bpmap_nl_name1 = bpmap_nl_name;
1577 const char *bpmap_nl_name2 = bpmap_nl_name;
1578#endif
1579
1580 moo_try_check(ff_trace1 = _moons_mflat_localise(
1581 raw_frames1, rawoff_frames1, bpmap_rp_name,
1582 bpmap_nl_name1, masterbias, masterdark_vis,
1583 masterdark_nir, coeffs_cube1, NULL, ff_trace_guess1,
1584 prepare_params, crh_params, compute_slitoffset_params,
1585 localise_params, modelflat_params, cbias_params, 1,
1586 MOONS_TAG_FF_TRACE, products, &medflat1, &psf1,
1587 &ref_frame1, &offset1, &mode,
1588 CPL_FRAME_LEVEL_INTERMEDIATE),
1589 "Fibre localisation failed for slit offset position 1!");
1590
1591 moo_try_check(ff_trace2 = _moons_mflat_localise(
1592 raw_frames2, rawoff_frames2, bpmap_rp_name,
1593 bpmap_nl_name2, masterbias, masterdark_vis,
1594 masterdark_nir, coeffs_cube2, NULL, ff_trace_guess2,
1595 prepare_params, crh_params, compute_slitoffset_params,
1596 localise_params, modelflat_params, cbias_params, 1,
1597 MOONS_TAG_FF_TRACE, products, &medflat2, &psf2,
1598 &ref_frame2, &offset2, &mode,
1599 CPL_FRAME_LEVEL_INTERMEDIATE),
1600 "Fibre localisation failed for slit offset position 2!");
1601
1602 moo_try_check(p2p = moo_compute_p2p(medflat1, ff_trace1, psf1, medflat2,
1603 ff_trace2, psf2),
1604 "Pixel-to=pixel variation map computation failed!");
1605
1606 moo_try_check(p2pname = cpl_sprintf("%s_%s.fits", MOONS_TAG_P2P_MAP,
1607 moo_mode_get_name(mode)),
1608 " ");
1609
1610 moo_products_add_det(products, p2p, CPL_FRAME_LEVEL_FINAL,
1611 MOONS_TAG_P2P_MAP, p2pname, ref_frame1,
1612 "ESO INS SLIT .*");
1613
1614moo_try_cleanup:
1615 moo_det_delete(medflat1);
1616 moo_loc_delete(ff_trace1);
1617 moo_det_delete(medflat2);
1618 moo_loc_delete(ff_trace2);
1619 moo_psf_delete(psf1);
1620 moo_psf_delete(psf2);
1621 moo_det_delete(p2p);
1622 cpl_free(p2pname);
1623
1624 return CPL_ERROR_NONE;
1625}
1626
1627#ifndef ALTERNATIVE_DRIVER
1628/*----------------------------------------------------------------------------*/
1645/*----------------------------------------------------------------------------*/
1646static cpl_error_code
1647_moons_mflat_check_sof(cpl_frameset *frameset,
1648 cpl_frameset **ff_trace_guess_frames,
1649 cpl_frameset **raw_frames,
1650 const cpl_frame **flat_attached,
1651 const cpl_frame **ff_trace,
1652 const cpl_frame **master_flat,
1653 cpl_frameset **rawoff_frames,
1654 const char **bpmap_rp_name,
1655 const char **bpmap_nl_name,
1656 const cpl_frame **master_bias,
1657 const cpl_frame **master_dark_vis,
1658 const cpl_frame **master_dark_nir,
1659 cpl_frameset **coeffs_cube_frames,
1660 const cpl_frame **p2pmap)
1661{
1662 cpl_errorstate prestate = cpl_errorstate_get();
1663
1664 cpl_ensure_code(frameset != NULL, CPL_ERROR_NULL_INPUT);
1665 cpl_ensure_code(ff_trace_guess_frames != NULL, CPL_ERROR_NULL_INPUT);
1666 cpl_ensure_code(raw_frames != NULL, CPL_ERROR_NULL_INPUT);
1667 cpl_ensure_code(rawoff_frames != NULL, CPL_ERROR_NULL_INPUT);
1668 cpl_ensure_code(moo_dfs_set_groups(frameset) == CPL_ERROR_NONE,
1669 cpl_error_get_code());
1670
1671 moo_try_check(*ff_trace_guess_frames = cpl_frameset_new(), " ");
1672 moo_try_check(*coeffs_cube_frames = cpl_frameset_new(), " ");
1673 moo_try_check(*raw_frames = cpl_frameset_new(), " ");
1674 moo_try_check(*rawoff_frames = cpl_frameset_new(), " ");
1675
1676 int size = 0;
1677 moo_try_check(size = cpl_frameset_get_size(frameset), " ");
1678
1679 for (int i = 0; i < size; ++i) {
1680 const cpl_frame *current_frame = NULL;
1681
1682 moo_try_check(current_frame =
1683 cpl_frameset_get_position_const(frameset, i),
1684 " ");
1685
1686 if (!strcmp(cpl_frame_get_tag(current_frame), MOONS_TAG_FLAT)) {
1687 moo_try_check(cpl_frameset_insert(*raw_frames, cpl_frame_duplicate(
1688 current_frame)),
1689 " ");
1690 }
1691 else if (!strcmp(cpl_frame_get_tag(current_frame),
1692 MOONS_TAG_FLAT_ATTACHED)) {
1693 *flat_attached = current_frame;
1694 }
1695 else if (!strcmp(cpl_frame_get_tag(current_frame),
1696 MOONS_TAG_FLAT_OFF)) {
1697 moo_try_check(cpl_frameset_insert(*rawoff_frames,
1698 cpl_frame_duplicate(
1699 current_frame)),
1700 " ");
1701 }
1702 else if (!strcmp(cpl_frame_get_tag(current_frame),
1703 MOONS_TAG_BP_MAP_RP)) {
1704 moo_try_check(*bpmap_rp_name =
1705 cpl_frame_get_filename(current_frame),
1706 " ");
1707 }
1708 else if (!strcmp(cpl_frame_get_tag(current_frame),
1709 MOONS_TAG_BP_MAP_NL)) {
1710 moo_try_check(*bpmap_nl_name =
1711 cpl_frame_get_filename(current_frame),
1712 " ");
1713 }
1714 else if (!strcmp(cpl_frame_get_tag(current_frame),
1715 MOONS_TAG_MASTER_BIAS)) {
1716 *master_bias = current_frame;
1717 }
1718 else if (!strcmp(cpl_frame_get_tag(current_frame),
1719 MOONS_TAG_MASTER_DARK_VIS)) {
1720 *master_dark_vis = current_frame;
1721 }
1722 else if (!strcmp(cpl_frame_get_tag(current_frame),
1723 MOONS_TAG_MASTER_DARK_NIR)) {
1724 *master_dark_nir = current_frame;
1725 }
1726 else if (!strcmp(cpl_frame_get_tag(current_frame), MOONS_TAG_P2P_MAP)) {
1727 *p2pmap = current_frame;
1728 }
1729 else if (!strcmp(cpl_frame_get_tag(current_frame),
1730 MOONS_TAG_FF_TRACE_GUESS)) {
1731 moo_try_check(cpl_frameset_insert(*ff_trace_guess_frames,
1732 cpl_frame_duplicate(
1733 current_frame)),
1734 " ");
1735 }
1736 else if (!strcmp(cpl_frame_get_tag(current_frame),
1737 MOONS_TAG_FF_TRACE)) {
1738 *ff_trace = current_frame;
1739 }
1740 else if (!strcmp(cpl_frame_get_tag(current_frame),
1741 MOONS_TAG_MASTER_FLAT)) {
1742 *master_flat = current_frame;
1743 }
1744 else if (!strcmp(cpl_frame_get_tag(current_frame),
1745 MOONS_TAG_LINEARITY_COEFF_CUBE)) {
1746 moo_try_check(cpl_frameset_insert(*coeffs_cube_frames,
1747 cpl_frame_duplicate(
1748 current_frame)),
1749 " ");
1750 }
1751 }
1752
1753moo_try_cleanup:
1754 if (!cpl_errorstate_is_equal(prestate)) {
1755 cpl_frameset_delete(*ff_trace_guess_frames);
1756 cpl_frameset_delete(*raw_frames);
1757 cpl_frameset_delete(*rawoff_frames);
1758 *ff_trace_guess_frames = NULL;
1759 *raw_frames = NULL;
1760 *rawoff_frames = NULL;
1761 }
1762 return cpl_error_get_code();
1763}
1764#endif
1765
1766/*----------------------------------------------------------------------------*/
1773/*----------------------------------------------------------------------------*/
1774static int
1775_moons_mflat(cpl_frameset *frameset, const cpl_parameterlist *parlist)
1776{
1777#ifdef ALTERNATIVE_DRIVER
1778 const char *const msg_id = "moons_mflat";
1779
1780 // moons_mflat is essentially four recipes, with related but different
1781 // purposes and thus 4 different "workflows" with different input data
1782 // requirements. Three of the 4 supported workflows work on a single
1783 // slit offset position, but "workflow 3" works on both slit offset
1784 // positions simultaneously. To keep the workflow interfaces simple
1785 // with respect to the input data, the incoming frameset is first
1786 // split by slit offset position, each of these framesets is then
1787 // checked for completeness depending on the requested workflow.
1788
1789 // Tag input frames with their respective DFS 'RAW' and 'CALIB' group labels
1790 cpl_error_code ecode = moo_dfs_set_groups(frameset);
1791 cpl_ensure((ecode == CPL_ERROR_NONE), ecode, ecode);
1792
1793 // Split the input set-of-frames. The input frames are sorted into groups according to
1794 // their slit offset position
1795
1796 cpl_frameset *frames_offset1 = cpl_frameset_new();
1797 cpl_frameset *frames_offset2 = cpl_frameset_new();
1798 cpl_frameset *frames_other = cpl_frameset_new();
1799
1800 ecode = moo_dfs_group_offsets(frameset, frames_offset1, frames_offset2,
1801 frames_other);
1802 if (ecode != CPL_ERROR_NONE) {
1803 cpl_frameset_delete(frames_other);
1804 cpl_frameset_delete(frames_offset2);
1805 cpl_frameset_delete(frames_offset1);
1806 cpl_error_set_message(cpl_func, ecode,
1807 "Cannot group input frames according to their "
1808 "slit offset position property");
1809 return ecode;
1810 }
1811
1812 typedef enum
1813 {
1814 UNDEFINED = -1,
1815 UNKNOWN = 0,
1816 GUESS = 1,
1817 TRACE,
1818 P2P,
1819 ATTACHED
1820 } mflat_mode;
1821
1822 // Determine the operating mode of moons_mflat. Check the grouped framesets for
1823 // the input data required for each mode.
1824
1825 mflat_mode mode = UNDEFINED;
1826 cpl_frameset *frames = NULL;
1827 if ((!cpl_frameset_is_empty(frames_offset1) &&
1828 (cpl_frameset_count_tags(frames_offset1, MOONS_TAG_FLAT) > 0)) &&
1829 (!cpl_frameset_is_empty(frames_offset2) &&
1830 (cpl_frameset_count_tags(frames_offset2, MOONS_TAG_FLAT) > 0))) {
1831 mode = P2P;
1832 cpl_msg_debug(msg_id,
1833 "Input data set contains `%s' for 2 slit offset "
1834 "positions, running in mode `%d'",
1835 MOONS_TAG_FLAT, (int)mode);
1836 }
1837 else {
1838 frames = (!cpl_frameset_is_empty(frames_offset1))
1839 ? cpl_frameset_duplicate(frames_offset1)
1840 : cpl_frameset_duplicate(frames_offset2);
1841 cpl_frameset_join(frames, frames_other);
1842
1843 if (cpl_frameset_count_tags(frames, MOONS_TAG_FLAT_ATTACHED) > 0) {
1844 mode = ATTACHED;
1845 cpl_msg_debug(
1846 msg_id,
1847 "Found frame with tag `%s` in input, running in mode `%d'",
1848 MOONS_TAG_FLAT_ATTACHED, (int)mode);
1849 }
1850 else if ((cpl_frameset_count_tags(frames_offset1, MOONS_TAG_FLAT) >
1851 0) &&
1852 (cpl_frameset_count_tags(frames, MOONS_TAG_FF_TRACE_GUESS) >
1853 0)) {
1854 mode = TRACE;
1855 cpl_msg_debug(
1856 msg_id,
1857 "Found frame with tag `%s` in input, running in mode `%d'",
1858 MOONS_TAG_FF_TRACE_GUESS, (int)mode);
1859 }
1860 else if (cpl_frameset_count_tags(frames_offset1, MOONS_TAG_FLAT) > 0) {
1861 mode = GUESS;
1862 cpl_msg_debug(
1863 msg_id,
1864 "Got data without fibre tracing solution, running in mode `%d'",
1865 (int)mode);
1866 }
1867 else {
1868 mode = UNKNOWN;
1869 }
1870 }
1871 if ((mode == UNDEFINED) || (mode == UNKNOWN)) {
1872 cpl_frameset_delete(frames);
1873 cpl_frameset_delete(frames_other);
1874 cpl_frameset_delete(frames_offset2);
1875 cpl_frameset_delete(frames_offset1);
1876 ecode = CPL_ERROR_ILLEGAL_INPUT;
1877 cpl_error_set_message(
1878 cpl_func, ecode,
1879 "Unable to determine the `%s' operating mode! Received input data "
1880 "does not contain a valid set of frames to run any `%s' workflow!",
1881 msg_id, msg_id);
1882 return ecode;
1883 }
1884
1885 moo_products *products = moo_products_new(frameset, parlist, "moons_mflat",
1886 PACKAGE "/" PACKAGE_VERSION);
1887
1888 // Setup parameter configuration
1889 const moo_params *params = moo_products_get_params(products);
1890
1891 // Declare parameter variables prior to the first call to moo_try_check
1892 // otherwise they will be used uninitialized on cleanup!
1893 moo_prepare_params *prepare_params = NULL;
1894 moo_correct_bias_params *correct_bias_params = NULL;
1895 moo_localise_params *localise_params = NULL;
1896 moo_crh_params *crh_params = NULL;
1897 moo_compute_slitoffset_params *compute_slitoffset_params = NULL;
1898 moo_extract_params *extract_params = NULL;
1899 moo_model_flat_params *model_flat_params = NULL;
1900 moo_compute_fibtrans_params *fibtrans_params = NULL;
1901
1902 moo_try_check(prepare_params = moo_params_get_prepare(params, parlist),
1903 " ");
1904 moo_try_check(correct_bias_params =
1905 moo_params_get_correct_bias(params, parlist),
1906 " ");
1907 moo_try_check(localise_params = moo_params_get_localise(params, parlist),
1908 " ");
1909 moo_try_check(crh_params = moo_params_get_crh(params, parlist), " ");
1910 moo_try_check(compute_slitoffset_params =
1911 moo_params_get_compute_slitoffset(params, parlist),
1912 " ");
1913 moo_try_check(extract_params = moo_params_get_extract(params, parlist),
1914 " ");
1915 moo_try_check(model_flat_params =
1916 moo_params_get_model_flat(params, parlist),
1917 " ");
1918 moo_try_check(fibtrans_params =
1919 moo_params_get_compute_fibtrans(params, parlist),
1920 " ");
1921
1922
1923 // FIXME: All checks preceding the actual workflow function call should be moved
1924 // into that function. Benefits are a unified interface just passing
1925 // framesets and it simplifies the error handling. For now we keep
1926 // the workflow function interface as much as possible and try to
1927 // stick to the original error handling scheme using work-arounds
1928 // when necessary!
1929 switch (mode) {
1930 case GUESS: {
1931 cpl_msg_info(msg_id,
1932 "Workflow 1 : create a guess fibre "
1933 "tracing solution `%s' (single slit offset)",
1934 MOONS_TAG_FF_TRACE_GUESS);
1935
1936 const int min_nflats_on = 3;
1937
1938 cpl_frameset *flats_on =
1939 moo_dfs_extract_tag(frames, MOONS_TAG_FLAT);
1940 cpl_frameset *flats_off =
1941 moo_dfs_extract_tag(frames, MOONS_TAG_FLAT_OFF);
1942 const cpl_frame *bp_map_rp =
1943 cpl_frameset_find_const(frames, MOONS_TAG_BP_MAP_RP);
1944 const cpl_frame *bp_map_nl =
1945 cpl_frameset_find_const(frames, MOONS_TAG_BP_MAP_NL);
1946 const cpl_frame *masterbias =
1947 cpl_frameset_find_const(frames, MOONS_TAG_MASTER_BIAS);
1948 const cpl_frame *masterdark_vis =
1949 cpl_frameset_find_const(frames, MOONS_TAG_MASTER_DARK_VIS);
1950 const cpl_frame *masterdark_nir =
1951 cpl_frameset_find_const(frames, MOONS_TAG_MASTER_DARK_NIR);
1952
1953 // Check for required input frames
1954 if ((flats_on == NULL) ||
1955 (cpl_frameset_get_size(flats_on) < min_nflats_on)) {
1956 cpl_frameset_delete(flats_off);
1957 ecode = CPL_ERROR_DATA_NOT_FOUND;
1958 cpl_error_set_message(
1959 cpl_func, ecode,
1960 "Too few input `%s' frames are available. Minimum required "
1961 "input frames is `%d'!",
1962 MOONS_TAG_FLAT, min_nflats_on);
1963 break;
1964 }
1965 if (cpl_frameset_get_size(flats_on) !=
1966 cpl_frameset_get_size(flats_off)) {
1967 cpl_frameset_delete(flats_off);
1968 cpl_frameset_delete(flats_on);
1969 ecode = CPL_ERROR_INCOMPATIBLE_INPUT;
1970 cpl_error_set_message(
1971 cpl_func, ecode,
1972 "The number of provided `%s' frames does not match "
1973 "the number of provided `%s'frames!",
1974 MOONS_TAG_FLAT_OFF, MOONS_TAG_FLAT);
1975 break;
1976 }
1977 if (masterbias == NULL) {
1978 cpl_frameset_delete(flats_off);
1979 cpl_frameset_delete(flats_on);
1980 ecode = CPL_ERROR_DATA_NOT_FOUND;
1981 cpl_error_set_message(cpl_func, ecode,
1982 "Required `%s' input frame is missing!",
1983 MOONS_TAG_MASTER_BIAS);
1984 break;
1985 }
1986
1987 const char *bpmap_rp_name =
1988 (bp_map_rp != NULL) ? cpl_frame_get_filename(bp_map_rp) : NULL;
1989 const char *bpmap_nl_name =
1990 (bp_map_nl != NULL) ? cpl_frame_get_filename(bp_map_nl) : NULL;
1991
1992 _moons_mflat_wf1(flats_on, flats_off, bpmap_rp_name, bpmap_nl_name,
1993 masterbias, masterdark_vis, masterdark_nir, NULL,
1994 prepare_params, crh_params, localise_params,
1995 correct_bias_params, products);
1996 break;
1997 }
1998 case TRACE: {
1999 cpl_msg_info(msg_id,
2000 "Workflow 2 : create a fibre "
2001 "tracing solution `%s' (single slit offset)",
2002 MOONS_TAG_FF_TRACE);
2003
2004 const int min_nflats_on = 3;
2005
2006 cpl_frameset *flats_on =
2007 moo_dfs_extract_tag(frames, MOONS_TAG_FLAT);
2008 cpl_frameset *flats_off =
2009 moo_dfs_extract_tag(frames, MOONS_TAG_FLAT_OFF);
2010 const cpl_frame *bp_map_rp =
2011 cpl_frameset_find_const(frames, MOONS_TAG_BP_MAP_RP);
2012 const cpl_frame *bp_map_nl =
2013 cpl_frameset_find_const(frames, MOONS_TAG_BP_MAP_NL);
2014 const cpl_frame *masterbias =
2015 cpl_frameset_find_const(frames, MOONS_TAG_MASTER_BIAS);
2016 const cpl_frame *masterdark_vis =
2017 cpl_frameset_find_const(frames, MOONS_TAG_MASTER_DARK_VIS);
2018 const cpl_frame *masterdark_nir =
2019 cpl_frameset_find_const(frames, MOONS_TAG_MASTER_DARK_NIR);
2020 const cpl_frame *fftrace_guess =
2021 cpl_frameset_find_const(frames, MOONS_TAG_FF_TRACE_GUESS);
2022 const cpl_frame *p2pmap =
2023 cpl_frameset_find_const(frames, MOONS_TAG_P2P_MAP);
2024 const cpl_frame *coeffs_cube =
2025 cpl_frameset_find_const(frames, MOONS_TAG_LINEARITY_COEFF_CUBE);
2026
2027
2028 // Check for required input frames
2029 if ((flats_on == NULL) ||
2030 (cpl_frameset_get_size(flats_on) < min_nflats_on)) {
2031 cpl_frameset_delete(flats_off);
2032 ecode = CPL_ERROR_DATA_NOT_FOUND;
2033 cpl_error_set_message(
2034 cpl_func, ecode,
2035 "Too few input `%s' frames are available. Minimum required "
2036 "input frames is `%d'!",
2037 MOONS_TAG_FLAT, min_nflats_on);
2038 break;
2039 }
2040 if (cpl_frameset_get_size(flats_on) !=
2041 cpl_frameset_get_size(flats_off)) {
2042 cpl_frameset_delete(flats_off);
2043 cpl_frameset_delete(flats_on);
2044 ecode = CPL_ERROR_INCOMPATIBLE_INPUT;
2045 cpl_error_set_message(
2046 cpl_func, ecode,
2047 "The number of provided `%s' frames does not match "
2048 "the number of provided `%s'frames!",
2049 MOONS_TAG_FLAT_OFF, MOONS_TAG_FLAT);
2050 break;
2051 }
2052 if (masterbias == NULL) {
2053 cpl_frameset_delete(flats_off);
2054 cpl_frameset_delete(flats_on);
2055 ecode = CPL_ERROR_DATA_NOT_FOUND;
2056 cpl_error_set_message(cpl_func, ecode,
2057 "Required `%s' input frame is missing!",
2058 MOONS_TAG_MASTER_BIAS);
2059 break;
2060 }
2061 if (fftrace_guess == NULL) {
2062 cpl_frameset_delete(flats_off);
2063 cpl_frameset_delete(flats_on);
2064 ecode = CPL_ERROR_DATA_NOT_FOUND;
2065 cpl_error_set_message(cpl_func, ecode,
2066 "Required `%s' input frame is missing!",
2067 MOONS_TAG_FF_TRACE_GUESS);
2068 break;
2069 }
2070
2071 const char *bpmap_rp_name =
2072 (bp_map_rp != NULL) ? cpl_frame_get_filename(bp_map_rp) : NULL;
2073 const char *bpmap_nl_name =
2074 (bp_map_nl != NULL) ? cpl_frame_get_filename(bp_map_nl) : NULL;
2075
2076 _moons_mflat_wf2(flats_on, flats_off, bpmap_rp_name, bpmap_nl_name,
2077 masterbias, masterdark_vis, masterdark_nir,
2078 coeffs_cube, fftrace_guess, p2pmap, prepare_params,
2079 crh_params, localise_params,
2080 compute_slitoffset_params, extract_params,
2081 model_flat_params, fibtrans_params,
2082 correct_bias_params, products);
2083 break;
2084 }
2085 case P2P: {
2086 cpl_msg_info(msg_id,
2087 "Workflow 3 : create a pixel-to-pixel variation map "
2088 "`%s' (dual slit offset)",
2089 MOONS_TAG_P2P_MAP);
2090
2091 _moons_mflat_wf3(frames_offset1, frames_offset2, frames_other,
2092 prepare_params, crh_params,
2093 compute_slitoffset_params, localise_params,
2094 model_flat_params, correct_bias_params, products);
2095
2096 break;
2097 }
2098 case ATTACHED: {
2099 cpl_msg_info(msg_id,
2100 "Workflow 4 : create a fibre-to-fibre relative "
2101 "response `%s' (single slit offset)",
2102 MOONS_TAG_F2F_TABLE);
2103
2104 const cpl_frame *flat_attached =
2105 cpl_frameset_find_const(frames, MOONS_TAG_FLAT_ATTACHED);
2106 const cpl_frame *flat_off =
2107 cpl_frameset_find_const(frames, MOONS_TAG_FLAT_OFF);
2108 const cpl_frame *bp_map_rp =
2109 cpl_frameset_find_const(frames, MOONS_TAG_BP_MAP_RP);
2110 const cpl_frame *bp_map_nl =
2111 cpl_frameset_find_const(frames, MOONS_TAG_BP_MAP_NL);
2112 const cpl_frame *masterbias =
2113 cpl_frameset_find_const(frames, MOONS_TAG_MASTER_BIAS);
2114 const cpl_frame *masterdark_vis =
2115 cpl_frameset_find_const(frames, MOONS_TAG_MASTER_DARK_VIS);
2116 const cpl_frame *masterdark_nir =
2117 cpl_frameset_find_const(frames, MOONS_TAG_MASTER_DARK_NIR);
2118 const cpl_frame *masterflat =
2119 cpl_frameset_find_const(frames, MOONS_TAG_MASTER_FLAT);
2120 const cpl_frame *fftrace =
2121 cpl_frameset_find_const(frames, MOONS_TAG_FF_TRACE);
2122 const cpl_frame *p2pmap =
2123 cpl_frameset_find_const(frames, MOONS_TAG_P2P_MAP);
2124 const cpl_frame *coeffs_cube =
2125 cpl_frameset_find_const(frames, MOONS_TAG_LINEARITY_COEFF_CUBE);
2126
2127 // Check for required input frames
2128 moo_try_assure((flat_attached != NULL), CPL_ERROR_DATA_NOT_FOUND,
2129 "Required `%s' input frame is missing!",
2130 MOONS_TAG_FLAT_ATTACHED);
2131 moo_try_assure((flat_off != NULL), CPL_ERROR_DATA_NOT_FOUND,
2132 "Required `%s' input frame is missing!",
2133 MOONS_TAG_FLAT_OFF);
2134 moo_try_assure((fftrace != NULL), CPL_ERROR_DATA_NOT_FOUND,
2135 "Required `%s' input frame is missing!",
2136 MOONS_TAG_FF_TRACE);
2137
2138 const char *bpmap_rp_name =
2139 (bp_map_rp != NULL) ? cpl_frame_get_filename(bp_map_rp) : NULL;
2140 const char *bpmap_nl_name =
2141 (bp_map_nl != NULL) ? cpl_frame_get_filename(bp_map_nl) : NULL;
2142
2143 _moons_mflat_wf4(flat_attached, flat_off, bpmap_rp_name,
2144 bpmap_nl_name, masterbias, masterdark_vis,
2145 masterdark_nir, coeffs_cube, fftrace, p2pmap,
2146 masterflat, prepare_params, extract_params,
2147 fibtrans_params, correct_bias_params, products);
2148 break;
2149 }
2150 default: {
2151 // This point should never be reached!
2152 cpl_error_set_message(
2153 cpl_func, CPL_ERROR_UNSUPPORTED_MODE,
2154 "Got unsupported mflat operating mode '%d'! Aborting!", mode);
2155 break;
2156 }
2157 }
2158
2159moo_try_cleanup:
2160 moo_compute_fibtrans_params_delete(fibtrans_params);
2161 moo_model_flat_params_delete(model_flat_params);
2162 moo_extract_params_delete(extract_params);
2163 moo_compute_slitoffset_params_delete(compute_slitoffset_params);
2164 moo_crh_params_delete(crh_params);
2165 moo_localise_params_delete(localise_params);
2166 moo_correct_bias_params_delete(correct_bias_params);
2167 moo_prepare_params_delete(prepare_params);
2168 moo_products_delete(products);
2169 cpl_frameset_delete(frames);
2170 cpl_frameset_delete(frames_other);
2171 cpl_frameset_delete(frames_offset2);
2172 cpl_frameset_delete(frames_offset1);
2173
2174#else
2175
2176 /* parameters */
2177 moo_prepare_params *prepare_params = NULL;
2178 moo_correct_bias_params *correct_bias_params = NULL;
2179 moo_localise_params *localise_params = NULL;
2180 moo_crh_params *crh_params = NULL;
2181 moo_compute_slitoffset_params *compute_slitoffset_params = NULL;
2182 moo_extract_params *extract_params = NULL;
2183 moo_model_flat_params *model_flat_params = NULL;
2184 moo_compute_fibtrans_params *fibtrans_params = NULL;
2185
2186 /* input files */
2187 const char *bpmap_rp_name = NULL;
2188 const char *bpmap_nl_name = NULL;
2189 const cpl_frame *masterbias = NULL;
2190 const cpl_frame *masterdark_vis = NULL;
2191 const cpl_frame *masterdark_nir = NULL;
2192 const cpl_frame *p2pmap = NULL;
2193 cpl_frameset *coeffs_cube_frames = NULL;
2194 cpl_frameset *ff_trace_guess_frames = NULL;
2195 cpl_frameset *raw_frames = NULL;
2196 const cpl_frame *flat_attached = NULL;
2197 const cpl_frame *ff_trace = NULL;
2198 const cpl_frame *master_flat = NULL;
2199 cpl_frameset *rawoff_frames = NULL;
2200 cpl_frameset **raw_byoffset_set = NULL;
2201
2202 moo_products *products = moo_products_new(frameset, parlist, "moons_mflat",
2203 PACKAGE "/" PACKAGE_VERSION);
2204
2205 /* parameters */
2206 const moo_params *params = moo_products_get_params(products);
2207 moo_try_check(prepare_params = moo_params_get_prepare(params, parlist),
2208 " ");
2209
2210 moo_try_check(correct_bias_params =
2211 moo_params_get_correct_bias(params, parlist),
2212 " ");
2213 moo_try_check(localise_params = moo_params_get_localise(params, parlist),
2214 " ");
2215 moo_try_check(crh_params = moo_params_get_crh(params, parlist), " ");
2216
2217 moo_try_check(compute_slitoffset_params =
2218 moo_params_get_compute_slitoffset(params, parlist),
2219 " ");
2220
2221 moo_try_check(extract_params = moo_params_get_extract(params, parlist),
2222 " ");
2223
2224 moo_try_check(model_flat_params =
2225 moo_params_get_model_flat(params, parlist),
2226 " ");
2227
2228 moo_try_check(fibtrans_params =
2229 moo_params_get_compute_fibtrans(params, parlist),
2230 " ");
2231
2232 /* SOF file */
2233 moo_try_check(_moons_mflat_check_sof(frameset, &ff_trace_guess_frames,
2234 &raw_frames, &flat_attached, &ff_trace,
2235 &master_flat, &rawoff_frames,
2236 &bpmap_rp_name, &bpmap_nl_name,
2237 &masterbias, &masterdark_vis,
2238 &masterdark_nir, &coeffs_cube_frames,
2239 &p2pmap),
2240 " ");
2241
2242 int size = 0;
2243 int csize = 0;
2244
2245 moo_try_check(csize = cpl_frameset_get_size(coeffs_cube_frames), " ");
2246 moo_try_check(size = cpl_frameset_get_size(ff_trace_guess_frames), " ");
2247 moo_try_check(raw_byoffset_set = moo_dfs_split_by_offset(raw_frames), " ");
2248
2249 if (flat_attached != NULL) {
2250 cpl_msg_info("moons_mflat", "Workflow 4 : create a F2F_TABLE");
2251 const cpl_frame *coeffs_cube = NULL;
2252 const cpl_frame *flat_off = NULL;
2253 int off_size = 0;
2254 moo_try_check(off_size = cpl_frameset_get_size(rawoff_frames), " ");
2255 if (off_size > 0) {
2256 flat_off = cpl_frameset_get_position_const(rawoff_frames, 0);
2257 }
2258 if (csize > 0) {
2259 coeffs_cube =
2260 cpl_frameset_get_position_const(coeffs_cube_frames, 0);
2261 }
2262
2263 _moons_mflat_wf4(flat_attached, flat_off, bpmap_rp_name, bpmap_nl_name,
2264 masterbias, masterdark_vis, masterdark_nir,
2265 coeffs_cube, ff_trace, p2pmap, master_flat,
2266 prepare_params, extract_params, fibtrans_params,
2267 correct_bias_params, products);
2268 }
2269 else if (size == 0) {
2270 cpl_msg_info("moons_mflat", "Workflow 1 : create a FF_TRACE_GUESS");
2271 _moons_mflat_wf1(raw_byoffset_set, rawoff_frames, bpmap_rp_name,
2272 bpmap_nl_name, masterbias, masterdark_vis,
2273 masterdark_nir, NULL, prepare_params, crh_params,
2274 localise_params, correct_bias_params, products);
2275 }
2276 else if (size == 1) {
2277 const cpl_frame *coeffs_cube = NULL;
2278
2279 if (csize > 0) {
2280 coeffs_cube =
2281 cpl_frameset_get_position_const(coeffs_cube_frames, 0);
2282 }
2283 cpl_msg_info("moons_mflat", "Workflow 2 : one offset reduction");
2284 const cpl_frame *ff_trace_guess =
2285 cpl_frameset_get_position_const(ff_trace_guess_frames, 0);
2286 _moons_mflat_wf2(raw_byoffset_set, rawoff_frames, bpmap_rp_name,
2287 bpmap_nl_name, masterbias, masterdark_vis,
2288 masterdark_nir, coeffs_cube, ff_trace_guess, p2pmap,
2289 prepare_params, crh_params, localise_params,
2290 compute_slitoffset_params, extract_params,
2291 model_flat_params, fibtrans_params,
2292 correct_bias_params, products);
2293 }
2294 else {
2295 cpl_msg_info("moons_mflat", "Workflow 3 : two offsets reduction");
2296 cpl_frameset **fftrace_byoffset_set =
2297 moo_dfs_split_by_offset(ff_trace_guess_frames);
2298 cpl_frameset **cube_byoffset_set =
2299 moo_dfs_split_by_offset(coeffs_cube_frames);
2300
2301 _moons_mflat_wf3(raw_byoffset_set, rawoff_frames, bpmap_rp_name,
2302 bpmap_nl_name, masterbias, masterdark_vis,
2303 masterdark_nir, cube_byoffset_set,
2304 fftrace_byoffset_set, prepare_params, crh_params,
2305 compute_slitoffset_params, localise_params,
2306 model_flat_params, correct_bias_params, products);
2307 for (int i = 0; i < 2; i++) {
2308 cpl_frameset_delete(fftrace_byoffset_set[i]);
2309 }
2310 cpl_free(fftrace_byoffset_set);
2311
2312 for (int i = 0; i < 2; i++) {
2313 cpl_frameset_delete(cube_byoffset_set[i]);
2314 }
2315 cpl_free(cube_byoffset_set);
2316 }
2317
2318moo_try_cleanup:
2319 if (raw_byoffset_set != NULL) {
2320 for (int i = 0; i < 2; i++) {
2321 cpl_frameset_delete(raw_byoffset_set[i]);
2322 }
2323 cpl_free(raw_byoffset_set);
2324 }
2325 cpl_frameset_delete(raw_frames);
2326 cpl_frameset_delete(rawoff_frames);
2327 cpl_frameset_delete(coeffs_cube_frames);
2328 cpl_frameset_delete(ff_trace_guess_frames);
2329 moo_crh_params_delete(crh_params);
2330 moo_localise_params_delete(localise_params);
2331 moo_compute_slitoffset_params_delete(compute_slitoffset_params);
2332 moo_extract_params_delete(extract_params);
2333 moo_model_flat_params_delete(model_flat_params);
2334 moo_compute_fibtrans_params_delete(fibtrans_params);
2335 moo_prepare_params_delete(prepare_params);
2336 moo_correct_bias_params_delete(correct_bias_params);
2337 moo_products_delete(products);
2338#endif
2339
2340 return (int)cpl_error_get_code();
2341}
moo_det * moo_det_create(const cpl_frame *frame)
Create a new moo_det from the given DET frame.
Definition: moo_det.c:91
void moo_det_delete(moo_det *self)
Delete a moo_det.
Definition: moo_det.c:472
moo_mode_type moo_mode_get(const cpl_frame *frame)
Get the name of a mode from a frame.
Definition: moo_detector.c:224
int moo_offset_get(const cpl_frame *refframe)
Get the offset from a frame.
Definition: moo_detector.c:254
const char * moo_mode_get_name(moo_mode_type type)
Get the name of a mode.
Definition: moo_detector.c:204
moo_detlist * moo_detlist_create(cpl_frameset *frameset)
Create a new moo_detlist from the given DET frameset.
Definition: moo_detlist.c:71
void moo_detlist_delete(moo_detlist *self)
Free all memory used by a moo_detlist object including the DET.
Definition: moo_detlist.c:559
void moo_ext_delete(moo_ext *self)
Delete a moo_ext.
Definition: moo_ext.c:370
void moo_f2f_delete(moo_f2f *self)
Delete a moo_f2f.
Definition: moo_f2f.c:413
moo_loc * moo_loc_load(const cpl_frame *locframe)
Load a LOC frame and create a moo_loc.
Definition: moo_loc.c:109
void moo_loc_delete(moo_loc *self)
Delete a moo_loc.
Definition: moo_loc.c:332
cpl_error_code moo_params_add_compute_fibtrans(moo_params *self, cpl_parameterlist *list)
Add default parameters for compute_fibtrans.
Definition: moo_params.c:1866
cpl_error_code moo_params_add_extract(moo_params *self, cpl_parameterlist *list)
Add default parameters for extraction.
Definition: moo_params.c:902
moo_prepare_params * moo_params_get_prepare(const moo_params *self, const cpl_parameterlist *list)
Get remove prepare parameters from moons parameters list.
Definition: moo_params.c:1073
moo_localise_params * moo_params_get_localise(const moo_params *self, const cpl_parameterlist *list)
Get localisation parameters from moons parameters list.
Definition: moo_params.c:1233
cpl_error_code moo_params_add_compute_slitoffset(moo_params *self, cpl_parameterlist *list)
Add default parameters for moo_sci_compute_slitoffset.
Definition: moo_params.c:2663
moo_compute_slitoffset_params * moo_params_get_compute_slitoffset(const moo_params *self, const cpl_parameterlist *list)
Get compute_slitoffset parameters from moons parameters list.
Definition: moo_params.c:3119
moo_model_flat_params * moo_params_get_model_flat(const moo_params *self, const cpl_parameterlist *list)
Get model flat parameters from moons parameters list.
Definition: moo_params.c:1640
moo_compute_fibtrans_params * moo_params_get_compute_fibtrans(const moo_params *self, const cpl_parameterlist *list)
Get compute fibtrans parameters from moons parameters list.
Definition: moo_params.c:1927
moo_correct_bias_params * moo_params_get_correct_bias(const moo_params *self, const cpl_parameterlist *list)
Get correct_bias parameters from moons parameters list.
Definition: moo_params.c:1167
cpl_error_code moo_params_add_crh(moo_params *self, cpl_parameterlist *list, const char *method)
Add default parameters for remove crh.
Definition: moo_params.c:694
moo_extract_params * moo_params_get_extract(const moo_params *self, const cpl_parameterlist *list)
Get extraction parameters from moons parameters list.
Definition: moo_params.c:1197
void moo_params_delete(moo_params *self)
Delete a moo_params.
Definition: moo_params.c:85
moo_crh_params * moo_params_get_crh(const moo_params *self, const cpl_parameterlist *list)
Get remove crh parameters from moons parameters list.
Definition: moo_params.c:1099
cpl_error_code moo_params_add_correct_bias(moo_params *self, cpl_parameterlist *list, const char *method)
Add default parameters for correct_bias.
Definition: moo_params.c:860
cpl_error_code moo_params_add_keep_temp(moo_params *self, cpl_parameterlist *list)
Add default parameters for keep-temp.
Definition: moo_params.c:932
cpl_error_code moo_params_add_localise(moo_params *self, cpl_parameterlist *list)
Add default parameters for localisation.
Definition: moo_params.c:1410
cpl_error_code moo_params_add_prepare(moo_params *self, cpl_parameterlist *list)
Add default parameters for prepare.
Definition: moo_params.c:667
cpl_error_code moo_params_add_model_flat(moo_params *self, cpl_parameterlist *list)
Add default parameters for model flat.
Definition: moo_params.c:1524
moo_params * moo_params_new(const char *pid, const char *recipe_id)
Create a new moo_params.
Definition: moo_params.c:62
void moo_psf_delete(moo_psf *self)
Delete a moo_psf.
Definition: moo_psf.c:264
moo_psf * moo_psf_load(const cpl_frame *psfframe)
Load a PSF frame and create a moo_psf.
Definition: moo_psf.c:109
cpl_error_code moo_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: moo_dfs.c:206
cpl_frameset ** moo_dfs_split_by_offset(cpl_frameset *set)
Get the EXPTIME from the frameset.
Definition: moo_dfs.c:66
moo_det * moo_compute_p2p(moo_det *flat1, moo_loc *loc1, moo_psf *model_flat1, moo_det *flat2, moo_loc *loc2, moo_psf *model_flat2)
To compute pixel-to-pixel variation map.
moo_det * moo_remove_CRH(moo_detlist *detlist, moo_masklist *cosmiclist, moo_crh_params *params)
Remove CRH in single frames or in a combination of multiple frames.
moo_ext * moo_extract(moo_det *det, moo_loc *loc, moo_psf *master_flat, moo_extract_params *params, const char *filename)
extract the 1D spectrum of fibres
Definition: moo_extract.c:523
moo_psf * moo_model_flat(moo_det *det, moo_loc *loc, moo_model_flat_params *params, const char *filename)
To extract 2D FF and model it, resulting MASTER_FLAT.
float * moo_compute_slitoffset(moo_det *det, moo_loc *loc, moo_compute_slitoffset_params *params)
Compute slit offset in LOC.
cpl_error_code moo_apply_p2p(moo_det *flat, moo_det *p2pmap)
Divide DET by the pixel-to-pixel variation map.
moo_det * moo_prepare(const cpl_frame *rawframe, const char *const badpixmask_rp, const char *const badpixmask_nl, const cpl_frame *masterbias, const cpl_frame *cube_frame, moo_prepare_params *params)
This function transforms RAW frames in DET frames attaching the default bad pixel map and an error im...
Definition: moo_prepare.c:324
cpl_error_code moo_flat_shift_compute(moo_det *det, moo_loc *ff_trace)
Compute the shift between FF_TRACE and FLAT.
cpl_error_code moo_correct_bias(moo_det *det, const cpl_frame *masterbias_frame, moo_correct_bias_params *params)
Subtracts the Master Bias frame from a DET frame.
Definition: moo_drl.c:86
moo_f2f * moo_compute_fibtrans(moo_ext *ext, moo_compute_fibtrans_params *params, const char *filename)
Computes fibre-to-fibre relative transmission table.
moo_loc * moo_localise(moo_det *det, const cpl_frame *guess_loc, moo_localise_params *params, const char *locname)
To localise the centroid of fibre spectrum on frames.
cpl_error_code moo_correct_dark(moo_det *det, moo_det *detoff, const cpl_frame *masterDarkVis, const cpl_frame *masterDarkNir)
Subtracts the master dark frame from a frame after scaling for exposure time (RI)....
Definition: moo_drl.c:250
int moo_pfits_get_slit_offset(const cpl_propertylist *plist)
find out the INS SLIT OFFSET value
Definition: moo_pfits.c:1110
moo_products * moo_products_new(cpl_frameset *framelist, const cpl_parameterlist *parlist, const char *recid, const char *pipeline_id)
create a moo_product object for a recipe
Definition: moo_products.c:53
cpl_frame * moo_products_add_loc(moo_products *self, moo_loc *loc, int keep_points, cpl_frame_level level, const char *tag, const char *filename, const cpl_frame *inherit_frame)
This function creates a product from a LOC structure.
Definition: moo_products.c:277
cpl_frame * moo_products_add_ext(moo_products *self, moo_ext *ext, cpl_frame_level level, const char *tag, const char *filename, const cpl_frame *inherit_frame)
create a product from a EXT object
Definition: moo_products.c:333
cpl_frame * moo_products_add(moo_products *self, moo_det *det, cpl_frame_level level, const char *tag, const char *filename, const cpl_frame *inherit_frame)
create a product from a DET object
Definition: moo_products.c:203
const moo_params * moo_products_get_params(const moo_products *self)
get the moo_params object
Definition: moo_products.c:87
const char * moo_get_license(void)
Get the pipeline copyright and license.
Definition: moo_utils.c:81