MOONS Pipeline Reference Manual 0.13.2
moons_linear.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#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24/*-----------------------------------------------------------------------------
25 Includes
26 -----------------------------------------------------------------------------*/
27
28#include "moo_utils.h"
29#include "moo_badpix.h"
30#include "moo_pfits.h"
31#include "moo_dfs.h"
32#include "moo_raw.h"
33#include "moo_params.h"
34#include "moo_detector.h"
35#include "moo_drl.h"
36#include "moo_products.h"
37#include "moo_compute_linearity.h"
38#include <cpl.h>
39#include <hdrl.h>
40#include <math.h>
41#include <string.h>
42#include <irplib_utils.h>
43#include <irplib_plugin.h>
44
45#define RECIPE_NAME "moons_linear"
46/*-----------------------------------------------------------------------------
47 Plugin registration
48 -----------------------------------------------------------------------------*/
49
50int cpl_plugin_get_info(cpl_pluginlist *list);
51
52/*-----------------------------------------------------------------------------
53 Private function prototypes
54 -----------------------------------------------------------------------------*/
55
56static int _moons_linear_create(cpl_plugin *plugin);
57static int _moons_linear_exec(cpl_plugin *plugin);
58static int _moons_linear_destroy(cpl_plugin *plugin);
59static int
60_moons_linear(cpl_frameset *frameset, const cpl_parameterlist *parlist);
61/*-----------------------------------------------------------------------------
62 Static variables
63 -----------------------------------------------------------------------------*/
64
65static const char *const _moons_linear_description =
66 "INPUT FRAMES\n"
67 "NOTE: m refers to frames with different exposure time with m >= 3\n"
68 "NOTE: n refers to frames with same exposure time with n >= 1\n"
69 " * RawList1 n1 x m1 files (RAW) with tag LINEARITY : "
70 "linearity files at offset 0\n"
71 " * RawList2 n2 x m2 files (RAW) with tag LINEARITY : "
72 "linearity files at offset 1\n"
73 " * [OPTIONAL] trace1 1 file (LOC) with tag "
74 "FF_TRACE_GUESS : "
75 "guess trace for offset 0\n"
76 " * [OPTIONAL] trace2 1 file (LOC) with tag "
77 "FF_TRACE_GUESS : "
78 "guess trace for offset 1\n"
79 " * [OPTIONAL] ReferenceBadPixMask 1 file (QUA) with tag BP_MAP_RP : "
80 "cosmetic bad pixel map\n"
81 "PRODUCTS\n"
82 " * BP_MAP_NL.fits (QUA) with tag BP_MAP_NL : "
83 "the linearity bad pixel mask\n"
84 " * LINEARITY_COEFF_CUBE_OFFSET[offset].fits (3D) with tag "
85 "LINEARITY_COEFF_CUBE\n";
86
87/*-----------------------------------------------------------------------------
88 Function code
89 -----------------------------------------------------------------------------*/
90
91/*----------------------------------------------------------------------------*/
101/*----------------------------------------------------------------------------*/
102
103int
104cpl_plugin_get_info(cpl_pluginlist *list)
105{
106 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
107 cpl_plugin *plugin = &recipe->interface;
108
109 if (cpl_plugin_init(
110 plugin, CPL_PLUGIN_API, MOONS_BINARY_VERSION,
111 CPL_PLUGIN_TYPE_RECIPE, "moons_linear",
112 "Produces a bad pixel mask with a series of linearity exposures",
113 _moons_linear_description, "Regis Haigron", PACKAGE_BUGREPORT,
114 moo_get_license(), _moons_linear_create, _moons_linear_exec,
115 _moons_linear_destroy)) {
116 cpl_msg_error(cpl_func, "Plugin initialization failed");
117 (void)cpl_error_set_where(cpl_func);
118 return 1;
119 }
120
121 if (cpl_pluginlist_append(list, plugin)) {
122 cpl_msg_error(cpl_func, "Error adding plugin to list");
123 (void)cpl_error_set_where(cpl_func);
124 return 1;
125 }
126
127 return 0;
128}
129
130
131/*----------------------------------------------------------------------------*/
139/*----------------------------------------------------------------------------*/
140
141static int
142_moons_linear_create(cpl_plugin *plugin)
143{
144 cpl_recipe *recipe;
145
146 /* Do not create the recipe if an error code is already set */
147 if (cpl_error_get_code() != CPL_ERROR_NONE) {
148 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
149 cpl_func, __LINE__, cpl_error_get_where());
150 return (int)cpl_error_get_code();
151 }
152
153 if (plugin == NULL) {
154 cpl_msg_error(cpl_func, "Null plugin");
155 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
156 }
157
158 /* Verify plugin type */
159 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
160 cpl_msg_error(cpl_func, "Plugin is not a recipe");
161 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
162 }
163
164 /* Get the recipe */
165 recipe = (cpl_recipe *)plugin;
166
167 /* Create the parameters list in the cpl_recipe object */
168 recipe->parameters = cpl_parameterlist_new();
169 if (recipe->parameters == NULL) {
170 cpl_msg_error(cpl_func, "Parameter list allocation failed");
171 cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
172 }
173
174 moo_params *params = moo_params_new("moons", "moons_linear");
175 moo_params_add_keep_temp(params, recipe->parameters);
176 moo_params_add_prepare(params, recipe->parameters);
177 moo_params_add_linear(params, recipe->parameters);
178 moo_params_delete(params);
179
180 return 0;
181}
182
183
184/*----------------------------------------------------------------------------*/
190/*----------------------------------------------------------------------------*/
191
192static int
193_moons_linear_exec(cpl_plugin *plugin)
194{
195 cpl_recipe *recipe;
196 int recipe_status;
197 cpl_errorstate initial_errorstate = cpl_errorstate_get();
198
199 /* Return immediately if an error code is already set */
200 if (cpl_error_get_code() != CPL_ERROR_NONE) {
201 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
202 cpl_func, __LINE__, cpl_error_get_where());
203 return (int)cpl_error_get_code();
204 }
205
206 if (plugin == NULL) {
207 cpl_msg_error(cpl_func, "Null plugin");
208 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
209 }
210
211 /* Verify plugin type */
212 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
213 cpl_msg_error(cpl_func, "Plugin is not a recipe");
214 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
215 }
216
217 /* Get the recipe */
218 recipe = (cpl_recipe *)plugin;
219
220 /* Verify parameter and frame lists */
221 if (recipe->parameters == NULL) {
222 cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
223 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
224 }
225 if (recipe->frames == NULL) {
226 cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
227 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
228 }
229
230 /* Invoke the recipe */
231 recipe_status = _moons_linear(recipe->frames, recipe->parameters);
232
233 /* Ensure DFS-compliance of the products */
234 if (cpl_dfs_update_product_header(recipe->frames)) {
235 if (!recipe_status)
236 recipe_status = (int)cpl_error_get_code();
237 }
238
239 if (!cpl_errorstate_is_equal(initial_errorstate)) {
240 /* Dump the error history since recipe execution start.
241 At this point the recipe cannot recover from the error */
242 cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
243 }
244
245 return recipe_status;
246}
247
248
249/*----------------------------------------------------------------------------*/
255/*----------------------------------------------------------------------------*/
256
257static int
258_moons_linear_destroy(cpl_plugin *plugin)
259{
260 cpl_recipe *recipe;
261
262 if (plugin == NULL) {
263 cpl_msg_error(cpl_func, "Null plugin");
264 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
265 }
266
267 /* Verify plugin type */
268 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
269 cpl_msg_error(cpl_func, "Plugin is not a recipe");
270 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
271 }
272
273 /* Get the recipe */
274 recipe = (cpl_recipe *)plugin;
275
276 cpl_parameterlist_delete(recipe->parameters);
277
278 return 0;
279}
280
281/*----------------------------------------------------------------------------*/
288/*----------------------------------------------------------------------------*/
289static int
290_moons_compare_offset(const cpl_frame *a, const cpl_frame *b)
291{
292 int res = 0;
293 const char *filenameA = cpl_frame_get_filename(a);
294 cpl_propertylist *lista = cpl_propertylist_load(filenameA, 0);
295
296 double oA = moo_pfits_get_slit_offset(lista);
297 const char *filenameB = cpl_frame_get_filename(b);
298 cpl_propertylist *listb = cpl_propertylist_load(filenameB, 0);
299
300 double oB = moo_pfits_get_slit_offset(listb);
301 if (fabs(oA - oB) < 1E-12) {
302 res = 1;
303 }
304
305 cpl_propertylist_delete(lista);
306 cpl_propertylist_delete(listb);
307 return res;
308}
309
310/*----------------------------------------------------------------------------*/
317/*----------------------------------------------------------------------------*/
318static int
319_moons_compare_exptime(const cpl_frame *a, const cpl_frame *b)
320{
321 int res = 0;
322
323 const char *filenameA = cpl_frame_get_filename(a);
324 const char *filenameB = cpl_frame_get_filename(b);
325
326 cpl_propertylist *lista = cpl_propertylist_load(filenameA, 0);
327 if (cpl_propertylist_has(lista, MOO_PFITS_EXPTIME)) {
328 double exptimeA = moo_pfits_get_exptime(lista);
329 cpl_propertylist *listb = cpl_propertylist_load(filenameB, 0);
330 double exptimeB = moo_pfits_get_exptime(listb);
331 if (fabs(exptimeA - exptimeB) < 1E-12) {
332 res = 1;
333 }
334 cpl_propertylist_delete(listb);
335 }
336 cpl_propertylist_delete(lista);
337 return res;
338}
339
340/*----------------------------------------------------------------------------*/
347/*----------------------------------------------------------------------------*/
348static int
349_moons_sort_exptime(const cpl_frame *a, const cpl_frame *b)
350{
351 int res = 0;
352
353 const char *filenameA = cpl_frame_get_filename(a);
354 const char *filenameB = cpl_frame_get_filename(b);
355
356 cpl_propertylist *lista = cpl_propertylist_load(filenameA, 0);
357 if (cpl_propertylist_has(lista, MOO_PFITS_EXPTIME)) {
358 double exptimeA = moo_pfits_get_exptime(lista);
359 cpl_propertylist *listb = cpl_propertylist_load(filenameB, 0);
360 double exptimeB = moo_pfits_get_exptime(listb);
361 res = exptimeA - exptimeB;
362 cpl_propertylist_delete(listb);
363 }
364 cpl_propertylist_delete(lista);
365 return res;
366}
367
368static cpl_error_code
369_moons_compute_linearity(cpl_frameset *exptime_comb_frames,
370 cpl_frameset *trace_frames,
371 cpl_frameset *ref_frames,
372 moo_linear_params *params,
373 moo_products *products)
374{
375 moo_loc **loc_tab = NULL;
376 moo_bpm **bpm_tab = NULL;
377 moo_cube **cube_tab = NULL;
378 moo_saturate_map **saturate_map_tab = NULL;
379 cpl_frame **refframe_tab = NULL;
380 char *cube_name = NULL;
381 char *bpm_name = NULL;
382 int offsets[2];
383
384 cpl_ensure_code(exptime_comb_frames != NULL, CPL_ERROR_NULL_INPUT);
385 cpl_ensure_code(trace_frames != NULL, CPL_ERROR_NULL_INPUT);
386
387 cpl_msg_info(__func__, "Compute linearity coefficients cube");
388 cpl_msg_indent_more();
389 cpl_frameset_join(exptime_comb_frames, trace_frames);
390
391 cpl_size nsel = 0;
392 cpl_size *selection = NULL;
393
394 cube_tab = cpl_calloc(2, sizeof(moo_cube));
395 loc_tab = cpl_calloc(2, sizeof(moo_loc));
396 saturate_map_tab = cpl_calloc(2, sizeof(moo_saturate_map));
397 bpm_tab = cpl_calloc(2, sizeof(moo_bpm));
398 refframe_tab = cpl_calloc(2, sizeof(cpl_frame *));
399
400 moo_try_check(selection =
401 cpl_frameset_labelise(exptime_comb_frames,
402 &_moons_compare_offset, &nsel),
403 " ");
404 int nb_bpm = 0;
405 int nb_cube = 0;
406
407 for (int i = 0; i < nsel; i++) {
408 cpl_frameset *set =
409 cpl_frameset_extract(exptime_comb_frames, selection, i);
410 cpl_frameset *refset = cpl_frameset_extract(ref_frames, selection, i);
411
412 cpl_frame *loc_frame = cpl_frameset_find(set, MOONS_TAG_FF_TRACE_GUESS);
413 if (loc_frame != NULL) {
414 cpl_msg_info("moons_linear", "Use ff_trace: %s",
415 cpl_frame_get_filename(loc_frame));
416 loc_tab[i] = moo_loc_load(loc_frame);
417 cpl_frameset_erase_frame(set, loc_frame);
418 }
419 int size = cpl_frameset_get_size(set);
420
421 if (size > 3) {
422 const cpl_frame *ref_frame =
423 cpl_frameset_get_position_const(refset, 0);
424 refframe_tab[i] = cpl_frame_duplicate(ref_frame);
425 moo_detlist *detlist = moo_detlist_create(set);
426 moo_det *refdet = moo_detlist_get(detlist, 0);
427
428 int offset = moo_pfits_get_slit_offset(refdet->primary_header);
429 offsets[i] = offset;
430 cpl_msg_info(__func__, "Do offset %d", offset);
431 cpl_msg_info(__func__, "Detect saturated pixels");
432
433 saturate_map_tab[i] =
434 moo_compute_saturate_pixels(detlist, loc_tab[i], params);
435 char *saturate_name =
436 cpl_sprintf("%s_OFFSET%d.fits", MOONS_TAG_LINEARITY_SATURATE,
437 offset);
438 moo_products_add_saturate_map(products, saturate_map_tab[i],
439 CPL_FRAME_LEVEL_INTERMEDIATE,
440 MOONS_TAG_LINEARITY_SATURATE,
441 saturate_name, ref_frame);
442 cpl_free(saturate_name);
443 cube_name = cpl_sprintf("%s_OFFSET%d.fits",
444 MOONS_TAG_LINEARITY_COEFF_CUBE, offset);
445 cube_tab[i] = moo_compute_linearity(detlist, loc_tab[i],
446 saturate_map_tab[i], cube_name);
447 nb_cube++;
448 moo_products_add_cube(products, cube_tab[i], CPL_FRAME_LEVEL_FINAL,
449 MOONS_TAG_LINEARITY_COEFF_CUBE, cube_name,
450 ref_frame);
451 cpl_msg_info(__func__, "Producing frame %s", cube_name);
452 cpl_free(cube_name);
453
454 moo_detlist_delete(detlist);
455 }
456
457 cpl_frameset_delete(refset);
458 cpl_frameset_delete(set);
459 }
460
461 if (nb_cube == 2) {
462 cpl_msg_info("moons_linear", "Merging coeffs cube");
463 moo_cube *mcube = moo_cube_merge(cube_tab[0], saturate_map_tab[0],
464 cube_tab[1], saturate_map_tab[1]);
465 cube_name = cpl_sprintf("%s.fits", MOONS_TAG_LINEARITY_COEFF_CUBE);
466 moo_products_add_cube(products, mcube, CPL_FRAME_LEVEL_FINAL,
467 MOONS_TAG_LINEARITY_COEFF_CUBE, cube_name,
468 refframe_tab[0]);
469 cpl_msg_info(__func__, "Producing frame %s", cube_name);
470 cpl_free(cube_name);
471 moo_cube_delete(mcube);
472 }
473
474 for (int i = 0; i < 2; i++) {
475 if (cube_tab[i] != NULL) {
476 int offset = offsets[i];
477 cpl_frame *ref_frame = refframe_tab[i];
478 moo_cube_normalise(cube_tab[i], saturate_map_tab[i]);
479 cube_name =
480 cpl_sprintf("%s_OFFSET%d.fits",
481 MOONS_TAG_LINEARITY_NORM_COEFF_CUBE, offset);
482 moo_products_add_cube(products, cube_tab[i],
483 CPL_FRAME_LEVEL_INTERMEDIATE,
484 MOONS_TAG_LINEARITY_NORM_COEFF_CUBE,
485 cube_name, ref_frame);
486 cpl_msg_info(__func__, "Producing frame %s", cube_name);
487 cpl_free(cube_name);
488
489 cpl_msg_info(__func__, "Compute non linearity bad pixel mask");
490 bpm_name =
491 cpl_sprintf("%s_OFFSET%d.fits", MOONS_TAG_BP_MAP_NL, offset);
492 bpm_tab[i] = moo_compute_bpm_linearity(cube_tab[i], loc_tab[i],
493 saturate_map_tab[i], params,
494 bpm_name);
495 moo_products_add_bpm(products, bpm_tab[i],
496 CPL_FRAME_LEVEL_INTERMEDIATE,
497 MOONS_TAG_BP_MAP_NL, bpm_name, ref_frame);
498 nb_bpm++;
499 cpl_msg_info(__func__, "Producing frame %s", bpm_name);
500 cpl_free(bpm_name);
501 bpm_name = NULL;
502 }
503 }
504 bpm_name = cpl_sprintf("%s.fits", MOONS_TAG_BP_MAP_NL);
505
506 if (nb_bpm == 2) {
507 cpl_msg_info("moons_linear", "Merging bad pixel mask");
508 moo_bpm_merge(bpm_tab[0], bpm_tab[1]);
509 moo_products_add_bpm(products, bpm_tab[0], CPL_FRAME_LEVEL_FINAL,
510 MOONS_TAG_BP_MAP_NL, bpm_name, refframe_tab[0]);
511 cpl_msg_info(__func__, "Producing frame %s", bpm_name);
512 }
513 else {
514 for (int i = 0; i < 2; i++) {
515 if (bpm_tab[i] != NULL) {
516 moo_products_add_bpm(products, bpm_tab[i],
517 CPL_FRAME_LEVEL_FINAL, MOONS_TAG_BP_MAP_NL,
518 bpm_name, refframe_tab[i]);
519 cpl_msg_info(__func__, "Producing frame %s", bpm_name);
520 }
521 }
522 }
523
524 for (int i = 0; i < 2; i++) {
525 if (saturate_map_tab[i] != NULL) {
526 moo_saturate_map_delete(saturate_map_tab[i]);
527 }
528
529 if (loc_tab[i] != NULL) {
530 moo_loc_delete(loc_tab[i]);
531 }
532
533 if (cube_tab[i] != NULL) {
534 moo_cube_delete(cube_tab[i]);
535 }
536
537 if (bpm_tab[i] != NULL) {
538 moo_bpm_delete(bpm_tab[i]);
539 }
540
541 if (refframe_tab[i] != NULL) {
542 cpl_frame_delete(refframe_tab[i]);
543 }
544 }
545
546moo_try_cleanup:
547 cpl_msg_info(__func__, "cleanup");
548 cpl_msg_indent_less();
549 cpl_free(bpm_name);
550 cpl_free(loc_tab);
551 cpl_free(bpm_tab);
552 cpl_free(saturate_map_tab);
553 cpl_free(cube_tab);
554 cpl_free(refframe_tab);
555 cpl_free(selection);
556 return CPL_ERROR_NONE;
557}
558
559/*----------------------------------------------------------------------------*/
571/*----------------------------------------------------------------------------*/
572
573static cpl_frameset *
574_moons_combine_exptime(cpl_frameset *inputset,
575 const char *tag,
576 const cpl_frameset *ref_frameset,
577 moo_products *products,
578 cpl_frameset **ref_comb_frameset)
579{
580 cpl_errorstate prestate = cpl_errorstate_get();
581
582 cpl_ensure(inputset != NULL, CPL_ERROR_NULL_INPUT, NULL);
583 cpl_ensure(products != NULL, CPL_ERROR_NULL_INPUT, NULL);
584 cpl_ensure(tag != NULL, CPL_ERROR_NULL_INPUT, NULL);
585
586 cpl_msg_info(__func__, "Combine frames by offset with same exptime");
587 cpl_msg_indent_more();
588 cpl_frameset *result = cpl_frameset_new();
589
590 cpl_size nsel = 0;
591 cpl_size *selection = NULL;
592 cpl_size *selection2 = NULL;
593 cpl_frameset *raw_expset = NULL;
594 cpl_frameset *expset = NULL;
595 cpl_frameset *raw_timeset = NULL;
596 cpl_frameset *timeset = NULL;
597 moo_crh_params *crh_params = NULL;
598 moo_det *median = NULL;
599 moo_detlist *detlist = NULL;
600 char *resname = NULL;
601 char *restag = NULL;
602 moo_try_check(crh_params = moo_crh_params_new(), " ");
603 crh_params->method = MOO_CRH_METHOD_MEDIAN;
604
605 moo_try_check(selection =
606 cpl_frameset_labelise(inputset, &_moons_compare_offset,
607 &nsel),
608 " ");
609 int i, j;
610 *ref_comb_frameset = cpl_frameset_new();
611 for (i = 0; i < nsel; i++) {
612 expset = cpl_frameset_extract(inputset, selection, i);
613 cpl_frameset_sort(expset, _moons_sort_exptime);
614 raw_expset = cpl_frameset_extract(ref_frameset, selection, i);
615 cpl_frameset_sort(raw_expset, _moons_sort_exptime);
616 cpl_size nsel2 = 0;
617 moo_try_check(selection2 =
618 cpl_frameset_labelise(expset, &_moons_compare_exptime,
619 &nsel2),
620 " ");
621 moo_try_assure(
622 nsel2 >= 3, CPL_ERROR_ILLEGAL_INPUT,
623 "Invalid number of different exptime by offset (%lld) expected >=3",
624 nsel2);
625
626 for (j = 0; j < nsel2; j++) {
627 timeset = cpl_frameset_extract(expset, selection2, j);
628 raw_timeset = cpl_frameset_extract(raw_expset, selection2, j);
629
630 int size = cpl_frameset_get_size(timeset);
631 moo_try_assure(size >= 1, CPL_ERROR_ILLEGAL_INPUT,
632 "Invalid number of frames for a given exptime (%d) "
633 "expected >=1",
634 size);
635 const cpl_frame *ref_frame =
636 cpl_frameset_get_position_const(raw_timeset, 0);
637 moo_try_check(detlist = moo_detlist_create(timeset), " ");
638 moo_try_check(median = moo_remove_CRH(detlist, NULL, crh_params),
639 " ");
640 moo_detlist_delete(detlist);
641 detlist = NULL;
642
643 restag = cpl_sprintf("%s_EXPTIME_COMB", tag);
644 resname = cpl_sprintf("%s_%d_%d.fits", restag, i, j);
645
646 cpl_frame *resframe =
647 moo_products_add(products, median, CPL_FRAME_LEVEL_INTERMEDIATE,
648 restag, resname, ref_frame);
649 cpl_frameset_insert(*ref_comb_frameset,
650 cpl_frame_duplicate(ref_frame));
651 cpl_frameset_insert(result, cpl_frame_duplicate(resframe));
652 cpl_msg_info(__func__, "Producing frame %s", resname);
653 moo_det_delete(median);
654 median = NULL;
655 cpl_free(resname);
656 resname = NULL;
657 cpl_free(restag);
658 restag = NULL;
659 cpl_frameset_delete(raw_timeset);
660 raw_timeset = NULL;
661 cpl_frameset_delete(timeset);
662 timeset = NULL;
663 }
664 cpl_free(selection2);
665 selection2 = NULL;
666 cpl_frameset_delete(expset);
667 expset = NULL;
668 cpl_frameset_delete(raw_expset);
669 raw_expset = NULL;
670 }
671moo_try_cleanup:
672 cpl_msg_indent_less();
673 if (!cpl_errorstate_is_equal(prestate)) {
674 cpl_frameset_delete(result);
675 cpl_frameset_delete(*ref_comb_frameset);
676 cpl_frameset_delete(expset);
677 cpl_frameset_delete(raw_expset);
678 cpl_frameset_delete(timeset);
679 cpl_frameset_delete(raw_timeset);
680 cpl_free(selection2);
681 moo_det_delete(median);
682 moo_detlist_delete(detlist);
683 cpl_free(restag);
684 cpl_free(resname);
685 *ref_comb_frameset = NULL;
686 result = NULL;
687 }
688 moo_crh_params_delete(crh_params);
689 cpl_free(selection);
690 return result;
691}
692
693/*----------------------------------------------------------------------------*/
705/*----------------------------------------------------------------------------*/
706static cpl_error_code
707_moons_linear_check_sof(cpl_frameset *frameset,
708 cpl_frameset **rawlin_frames,
709 const char **bpmap_rp_name,
710 const char **bpmap_nl_name,
711 cpl_frameset **trace_frames)
712{
713 cpl_error_code status = CPL_ERROR_NONE;
714 cpl_errorstate prestate = cpl_errorstate_get();
715 cpl_size *selection = NULL;
716 cpl_size nsel;
717
718 cpl_ensure_code(frameset != NULL, CPL_ERROR_NULL_INPUT);
719 cpl_ensure_code(rawlin_frames != NULL, CPL_ERROR_NULL_INPUT);
720
721 /* SOF file */
722 cpl_ensure_code(moo_dfs_set_groups(frameset) == CPL_ERROR_NONE,
723 cpl_error_get_code());
724
725
726 int nrawlin = 0;
727 int ntrace = 0;
728
729 *rawlin_frames = cpl_frameset_new();
730 *trace_frames = cpl_frameset_new();
731
732 for (int i = 0; i < cpl_frameset_get_size(frameset); ++i) {
733 const cpl_frame *current_frame =
734 cpl_frameset_get_position_const(frameset, i);
735 if (!strcmp(cpl_frame_get_tag(current_frame), MOONS_TAG_LINEARITY)) {
736 cpl_frame *new_frame = cpl_frame_duplicate(current_frame);
737 cpl_frameset_insert(*rawlin_frames, new_frame);
738 ++nrawlin;
739 }
740 else if (!strcmp(cpl_frame_get_tag(current_frame),
741 MOONS_TAG_BP_MAP_RP)) {
742 *bpmap_rp_name = cpl_frame_get_filename(current_frame);
743 }
744 else if (!strcmp(cpl_frame_get_tag(current_frame),
745 MOONS_TAG_BP_MAP_NL)) {
746 *bpmap_nl_name = cpl_frame_get_filename(current_frame);
747 }
748 else if (!strcmp(cpl_frame_get_tag(current_frame),
749 MOONS_TAG_FF_TRACE_GUESS)) {
750 cpl_frame *new_frame = cpl_frame_duplicate(current_frame);
751 cpl_frameset_insert(*trace_frames, new_frame);
752 ntrace++;
753 }
754 }
755
756 moo_try_assure(nrawlin >= 3, CPL_ERROR_DATA_NOT_FOUND,
757 "SOF does not have enough files (%d >= %d) tagged with %s",
758 nrawlin, 3, MOONS_TAG_LINEARITY);
759 moo_try_check(selection =
760 cpl_frameset_labelise(*rawlin_frames,
761 &_moons_compare_offset, &nsel),
762 " ");
763/*moo_try_assure(ntrace>=nsel,CPL_ERROR_DATA_NOT_FOUND,
764 "SOF does not have enough files (%d>=%lld) with tag %s", ntrace,nsel,
765 MOONS_TAG_FF_TRACE_GUESS);
766 */
767moo_try_cleanup:
768 cpl_free(selection);
769
770 if (!cpl_errorstate_is_equal(prestate)) {
771 cpl_frameset_delete(*rawlin_frames);
772 cpl_frameset_delete(*trace_frames);
773 *rawlin_frames = NULL;
774 *trace_frames = NULL;
775 status =
776 cpl_error_get_code(); // Recover from the error(s) (Reset to prestate))
777 }
778 return status;
779}
780
781/*----------------------------------------------------------------------------*/
793/*----------------------------------------------------------------------------*/
794static cpl_frame *
795_moons_prepare(moo_products *products,
796 const cpl_frame *frame,
797 const char *bpmap_rp_name,
798 int i,
799 int j,
800 moo_prepare_params *prepare_params)
801{
802 cpl_frame *result = NULL;
803 cpl_frame *pframe = NULL;
804 char *detname1 = NULL;
805 moo_det *det = NULL;
806 cpl_ensure(frame != NULL, CPL_ERROR_NULL_INPUT, NULL);
807 cpl_errorstate prestate = cpl_errorstate_get();
808
809 moo_try_check(det = moo_prepare_adu(frame, bpmap_rp_name, prepare_params),
810 " ");
811 moo_try_check(detname1 = cpl_sprintf("%s_%d_%d.fits",
812 MOONS_TAG_LINEARITY_PREPAREADU, i, j),
813 " ");
814 moo_try_check(pframe = moo_products_add(products, det,
815 CPL_FRAME_LEVEL_INTERMEDIATE,
816 MOONS_TAG_LINEARITY_PREPAREADU,
817 detname1, frame),
818 " ");
819 moo_try_check(result = cpl_frame_duplicate(pframe), " ");
820
821moo_try_cleanup:
822 if (!cpl_errorstate_is_equal(prestate)) {
823 cpl_frame_delete(result);
824 result = NULL;
825 }
826 moo_det_delete(det);
827 cpl_free(detname1);
828 return result;
829}
830
831/*----------------------------------------------------------------------------*/
843/*----------------------------------------------------------------------------*/
844static cpl_frameset *
845_moons_prepare_set(cpl_frameset *raw_frames,
846 const char *bpmap_rp_name,
847 cpl_frameset **rawout_frames,
848 moo_prepare_params *prepare_params,
849 moo_products *products)
850{
851 cpl_frameset *detframes = NULL;
852 cpl_size nsel = 0;
853 cpl_size *selection = NULL;
854 cpl_frameset *timeset = NULL;
855
856 cpl_ensure(raw_frames, CPL_ERROR_NULL_INPUT, NULL);
857 cpl_ensure(products, CPL_ERROR_NULL_INPUT, NULL);
858
859 cpl_errorstate prestate = cpl_errorstate_get();
860
861 moo_try_check(detframes = cpl_frameset_new(), " ");
862 moo_try_check(*rawout_frames = cpl_frameset_new(), " ");
863 moo_try_check(selection =
864 cpl_frameset_labelise(raw_frames, &_moons_compare_exptime,
865 &nsel),
866 " ");
867
868 for (int i = 0; i < nsel; i++) {
869 timeset = cpl_frameset_extract(raw_frames, selection, i);
870 int size = cpl_frameset_get_size(timeset);
871
872 for (int j = 0; j < size; j++) {
873 cpl_frame *frame = NULL;
874 const cpl_frame *on_frame =
875 cpl_frameset_get_position_const(timeset, j);
876 moo_try_check(frame =
877 _moons_prepare(products, on_frame, bpmap_rp_name,
878 i, j, prepare_params),
879 " ");
880 moo_try_check(cpl_frameset_insert(detframes, frame), " ");
881 moo_try_check(cpl_frameset_insert(*rawout_frames,
882 cpl_frame_duplicate(on_frame)),
883 " ");
884 }
885 cpl_frameset_delete(timeset);
886 timeset = NULL;
887 }
888moo_try_cleanup:
889 cpl_free(selection);
890 if (!cpl_errorstate_is_equal(prestate)) {
891 cpl_frameset_delete(timeset);
892 cpl_frameset_delete(detframes);
893 detframes = NULL;
894 *rawout_frames = NULL;
895 }
896 return detframes;
897}
898
899static int
900_moons_linear(cpl_frameset *frameset, const cpl_parameterlist *parlist)
901{
902 moo_prepare_params *prepare_params = NULL;
903 moo_linear_params *linear_params = NULL;
904 cpl_frameset *rawlin_frames = NULL;
905 cpl_frameset *ref_frames = NULL;
906 cpl_frameset *ref_comb_frames = NULL;
907 cpl_frameset *trace_frames = NULL;
908 const char *bpmap_rp_name = NULL;
909 const char *bpmap_nl_name = NULL;
910 cpl_frameset *detlin_frames = NULL;
911 cpl_frameset *exptimecomb_frames = NULL;
912 cpl_frameset *exptimenorm_frames = NULL;
913 cpl_frameset *snr_frames = NULL;
914
915 moo_products *products = moo_products_new(frameset, parlist, "moons_linear",
916 PACKAGE "/" PACKAGE_VERSION);
917 /* parameters */
918 const moo_params *params = moo_products_get_params(products);
919 moo_try_check(prepare_params = moo_params_get_prepare(params, parlist),
920 " ");
921
922 moo_try_check(linear_params = moo_params_get_linear(params, parlist), " ");
923
924 moo_try_check(_moons_linear_check_sof(frameset, &rawlin_frames,
925 &bpmap_rp_name, &bpmap_nl_name,
926 &trace_frames),
927 " ");
928
929 detlin_frames = _moons_prepare_set(rawlin_frames, bpmap_rp_name,
930 &ref_frames, prepare_params, products);
931
932 exptimecomb_frames =
933 _moons_combine_exptime(detlin_frames, MOONS_TAG_LINEARITY, ref_frames,
934 products, &ref_comb_frames);
935
936 _moons_compute_linearity(exptimecomb_frames, trace_frames, ref_comb_frames,
937 linear_params, products);
938moo_try_cleanup:
939 cpl_frameset_delete(ref_comb_frames);
940 cpl_frameset_delete(ref_frames);
941 cpl_frameset_delete(snr_frames);
942 cpl_frameset_delete(trace_frames);
943 cpl_frameset_delete(exptimecomb_frames);
944 cpl_frameset_delete(exptimenorm_frames);
945 cpl_frameset_delete(detlin_frames);
946 cpl_frameset_delete(rawlin_frames);
947 moo_linear_params_delete(linear_params);
948 moo_prepare_params_delete(prepare_params);
949 moo_products_delete(products);
950 return (int)cpl_error_get_code();
951}
cpl_error_code moo_bpm_merge(moo_bpm *a, moo_bpm *b)
Merge to moo_bpm structure in the first.
Definition: moo_bpm.c:158
void moo_bpm_delete(moo_bpm *self)
Delete a moo_bpm.
Definition: moo_bpm.c:213
void moo_cube_delete(moo_cube *self)
Delete a moo_cube.
Definition: moo_cube.c:343
moo_cube * moo_cube_merge(moo_cube *cubea, moo_saturate_map *saturatea, moo_cube *cubeb, moo_saturate_map *saturateb)
Merging two cubes.
Definition: moo_cube.c:312
cpl_error_code moo_cube_normalise(moo_cube *self, moo_saturate_map *map)
Normalise a moo_cube using saturate map.
Definition: moo_cube.c:238
void moo_det_delete(moo_det *self)
Delete a moo_det.
Definition: moo_det.c:472
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
moo_det * moo_detlist_get(moo_detlist *self, int i)
Get the DET at the position i in the list.
Definition: moo_detlist.c:196
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_linear(moo_params *self, cpl_parameterlist *list)
Add default parameters for linear.
Definition: moo_params.c:764
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_linear_params * moo_params_get_linear(const moo_params *self, const cpl_parameterlist *list)
Get linear parameters from moons parameters list.
Definition: moo_params.c:3186
void moo_params_delete(moo_params *self)
Delete a moo_params.
Definition: moo_params.c:85
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_prepare(moo_params *self, cpl_parameterlist *list)
Add default parameters for prepare.
Definition: moo_params.c:667
moo_params * moo_params_new(const char *pid, const char *recipe_id)
Create a new moo_params.
Definition: moo_params.c:62
void moo_saturate_map_delete(moo_saturate_map *self)
Delete a moo_map_saturate.
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
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_det * moo_prepare_adu(const cpl_frame *rawframe, const char *const badpixmask_rp, moo_prepare_params *params)
This function transforms RAW frames in DET ADU frames attaching the default bad pixel.
Definition: moo_prepare.c:430
int moo_pfits_get_slit_offset(const cpl_propertylist *plist)
find out the INS SLIT OFFSET value
Definition: moo_pfits.c:1110
double moo_pfits_get_exptime(const cpl_propertylist *plist)
find out the EXPTIME value
Definition: moo_pfits.c:1039
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_saturate_map(moo_products *self, moo_saturate_map *saturate, cpl_frame_level level, const char *tag, const char *filename, const cpl_frame *inherit_frame)
create a product from a SATURATE MAP object
Definition: moo_products.c:687
cpl_frame * moo_products_add_cube(moo_products *self, moo_cube *cube, cpl_frame_level level, const char *tag, const char *filename, const cpl_frame *inherit_frame)
create a product from a CUBE object
Definition: moo_products.c:731
cpl_frame * moo_products_add_bpm(moo_products *self, moo_bpm *bpm, cpl_frame_level level, const char *tag, const char *filename, const cpl_frame *inherit_frame)
create a product from a BPM object
Definition: moo_products.c:643
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