ERIS Pipeline Reference Manual 1.8.15
eris_ifu_combine.c
1/* $Id: eris_ifu_flat.c,v 0.1 2018-07-22 06:06:06 agudo Exp $
2*
3* This file is part of the ERIS Pipeline
4* Copyright (C) 2002,2003 European Southern Observatory
5*
6* This program is free software; you can redistribute it and/or modify
7* it under the terms of the GNU General Public License as published by
8* the Free Software Foundation; either version 2 of the License, or
9* (at your option) any later version.
10*
11* This program is distributed in the hope that it will be useful,
12* but WITHOUT ANY WARRANTY; without even the implied warranty of
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14* GNU General Public License for more details.
15*
16* You should have received a copy of the GNU General Public License
17* along with this program; if not, write to the Free Software
18* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19*/
20
21#ifdef HAVE_CONFIG_H
22#include <config.h>
23#endif
24
25/*-----------------------------------------------------------------------------
26 Includes
27 -----------------------------------------------------------------------------*/
28#include <string.h>
29
30#include <cpl.h>
31#include <hdrl.h>
32
33#include "eris_ifu_error.h"
34#include "eris_dfs.h"
35#include "eris_utils.h"
36#include "eris_ifu_utils.h"
37#include "eris_pfits.h"
38#include "eris_ifu_combine_static.h"
39
40/*-----------------------------------------------------------------------------
41 Static variables
42 -----------------------------------------------------------------------------*/
43static const char eris_ifu_combine_description[] = "\
44Addapted from sinfo_utl_cube_combine. \n\
45This recipe performs cube combination. The input files are several cubes created \n\
46by eris_ifu_jitter, their associated tags should be OBJECT_CUBE. \n\
47The user must provide offsets in an ASCII file named offset.list located in the \n\
48same dir where the esorex command is given. \n\
49Its content should be two columns with the offsets of the corresponding data \n\
50cubes that can be obtained, for example, with the command: \n\
51 \n\
52 dfits pro/eris_ifu_jitter_obj_cube_00*.fits | fitsort OCS.OFFSET.X OCS.OFFSET.Y > offset.list \n\
53\n\
54The output is a cube COMBINED_CUBE resulting from the input cubes.\n\
55\n\
56\n\
57--compute_mode=MEDIAN should only be used when all data cubes have the same \n\
58exposure time. If these differ MEAN should be used.\n\
59When using MEAN the units of the wavelength axis are ADU/s, when using MEDIAN \n\
60the units of the wavelength axis are ADU. \n\
61\n\
62----------------------------------------------------------------------------- \n\
63Input files:\n\
64 DO CATG Explanation Required #Frames \n\
65 ------- ----------- -------- ------- \n\
66 OBJECT_CUBE Output cube from eris_ifu_jitter Y [1,N] \n\
67 \n\
68Output files:\n\
69 DO CATG Explanation Product Depth \n\
70 ------- ---------------------------------- ------------- \n\
71 COMBINED_CUBE Combined cube.\n\
72 ----------------------------------------------------------------------------\n\
73\n\
74 Information on relevant parameters may be found with\n\
75 esorex --params "REC_NAME_COMBINE"\n\
76 esorex --help "REC_NAME_COMBINE"\n";
77
78/*-----------------------------------------------------------------------------
79 Private function prototypes
80 -----------------------------------------------------------------------------*/
81
82cpl_recipe_define(eris_ifu_combine, ERIS_BINARY_VERSION, "Andrea Modigliani, Y. Cao",
83 PACKAGE_BUGREPORT, "2021",
84 "This recipe combines jittered cubes into a single cube",
85 eris_ifu_combine_description);
86
87cpl_error_code eris_ifu_combine_check_inputs(cpl_frameset *);
88
89/*-----------------------------------------------------------------------------
90 Function code
91 -----------------------------------------------------------------------------*/
99static cpl_error_code eris_ifu_combine_fill_parameterlist(cpl_parameterlist *pl)
100{
101 cpl_parameter *p = NULL;
102 char *recname_full = NULL;
103 cpl_error_code err = CPL_ERROR_NONE;
104
105 cpl_ensure_code(pl, CPL_ERROR_NULL_INPUT);
106
107 TRY {
108 recname_full = cpl_sprintf("eris.%s", REC_NAME_COMBINE);
109
110 /* Fill the parameters list */
111 p = cpl_parameter_new_value("eris.eris_ifu_combine.offset_mode",
112 CPL_TYPE_BOOL,
113 "Offset conventions. If TRUE: applies reference "
114 "offset correction. If FALSE: take user offsets. "
115 "The reference offset is computed as (min_off+max_off)/2",
116 recname_full, CPL_TRUE) ;
117 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "offset_mode") ;
118 cpl_parameterlist_append(pl, p) ;
119
120 p = cpl_parameter_new_enum("eris.eris_ifu_combine.compute_mode",
121 CPL_TYPE_STRING,
122 "Coadding compute mode of the combined cube",
123 recname_full, "MEAN", 2,
124 "MEAN", "MEDIAN");
125 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "compute_mode");
126 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
127 cpl_parameterlist_append(pl, p) ;
128
129 p = cpl_parameter_new_value("eris.eris_ifu_combine.name_i",
130 CPL_TYPE_STRING,
131 "Input filename. This must be provided when offset_mode=FALSE "
132 "Allows the user to set X and Y cumulative offsets in "
133 "a two column format",
134 recname_full, "offset.list");
135 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "name_i") ;
136 cpl_parameterlist_append(pl, p) ;
137
138 p = cpl_parameter_new_value("eris.eris_ifu_combine.name_o",
139 CPL_TYPE_STRING,
140 "Output filename",
141 recname_full, "out_coadd_cube.fits");
142 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "name_o") ;
143 cpl_parameterlist_append(pl, p) ;
144
145 p = cpl_parameter_new_value("eris.eris_ifu_combine.ks_clip",
146 CPL_TYPE_BOOL,
147 "Kappa sigma clipping",
148 recname_full, FALSE);
149 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ks_clip") ;
150 cpl_parameterlist_append(pl, p) ;
151
152 p = cpl_parameter_new_value("eris.eris_ifu_combine.pclip",
153 CPL_TYPE_INT,
154 "Apply an initial percentile clipping based on"
155 "the absolute deviation from the median if "
156 "ks_clip=TRUE",
157 recname_full, 70);
158 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "pclip") ;
159 cpl_parameterlist_append(pl, p) ;
160
161 p = cpl_parameter_new_value("eris.eris_ifu_combine.kappa",
162 CPL_TYPE_DOUBLE,
163 "Kappa value for sigma clip",
164 recname_full, 2.);
165 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "kappa") ;
166 cpl_parameterlist_append(pl, p) ;
167
168 p = cpl_parameter_new_value("eris.eris_ifu_combine.subtract-background",
169 CPL_TYPE_BOOL,
170 "Subtract median of the images chanel-by-chanel",
171 recname_full, FALSE);
172 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "subtract-background") ;
173 cpl_parameterlist_append(pl, p) ;
174
175 p = cpl_parameter_new_value("eris.eris_ifu_combine.edge-trim",
176 CPL_TYPE_INT,
177 "Number or pixels to trim for each plane of the "
178 "input frames",
179 recname_full, 2);
180 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "edge-trim") ;
181 cpl_parameterlist_append(pl, p);
182
183 p = cpl_parameter_new_value("eris.eris_ifu_combine.weights",
184 CPL_TYPE_STRING,
185 "Optional input filename. The user can specify "
186 "his own weighting scheme when compute_mode=MEAN "
187 "A one column format is expected. ",
188 recname_full, "");
189 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "weights") ;
190 cpl_parameterlist_append(pl, p) ;
191 } CATCH {
192 CATCH_MSGS();
193 err = cpl_error_get_code();
194 }
195
196 eris_ifu_free_string(&recname_full);
197
198 return err;
199}
200
207static int eris_ifu_combine(cpl_frameset *frameset,
208 const cpl_parameterlist *parlist)
209{
210 int cnt = 0,
211 edge_trim = 0,
212 pclip = 0,
213 nx_out = 0,
214 ny_out = 0,
215 ks_clip = 0,
216 min_size_x = 9999,
217 min_size_y = 9999,
218 nz = 0,
219 nframes = 0;
220 float ref_offx = 0,
221 ref_offy = 0,
222 tmpoffx = 0,
223 weights = 0,
224 tmpoffy = 0,
225 x0 = 0,
226 y0 = 0,
227 *offsetx = NULL,
228 *offsety = NULL;
229 double kappa = 0.,
230 *exptimes = NULL;
231 bool subtract_background = CPL_FALSE,
232 offset_mode = CPL_FALSE;
233 const char *name_o = NULL,
234 *name_i = NULL,
235 *weights_i = NULL,
236 **files = NULL,
237 *name = NULL,
238 *compute_mode = NULL;
239 FILE *file_list = NULL;
240 const cpl_parameter *param = NULL;
241 cpl_propertylist *plist = NULL;
242 const cpl_frame *frame = NULL;
243 cpl_imagelist *mergedCubeData = NULL,
244 *mergedCubeError = NULL,
245 *mergedCubeDIT = NULL;
246 cpl_image **mergedImageData = NULL,
247 **mergedImageError = NULL,
248 **mergedImageDIT = NULL;
249 cpl_error_code err = CPL_ERROR_NONE;
250
251 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
252 cpl_ensure_code(frameset != NULL, CPL_ERROR_NULL_INPUT);
253 cpl_ensure_code(eris_files_dont_exist(frameset) == CPL_ERROR_NONE, CPL_ERROR_BAD_FILE_FORMAT);
254
255 TRY
256 {
257 /* Get Parameters */
258 param = cpl_parameterlist_find_const(parlist,
259 "eris.eris_ifu_combine.ks_clip");
260 ks_clip = cpl_parameter_get_bool(param);
261
262 param = cpl_parameterlist_find_const(parlist,
263 "eris.eris_ifu_combine.pclip");
264 pclip = cpl_parameter_get_int(param);
265
266 param = cpl_parameterlist_find_const(parlist,
267 "eris.eris_ifu_combine.subtract-background");
268 subtract_background = cpl_parameter_get_bool(param);
269
270 param = cpl_parameterlist_find_const(parlist,
271 "eris.eris_ifu_combine.kappa");
272 kappa = cpl_parameter_get_double(param);
273
274 param = cpl_parameterlist_find_const(parlist,
275 "eris.eris_ifu_combine.name_i");
276 name_i = cpl_parameter_get_string(param);
277
278 param = cpl_parameterlist_find_const(parlist,
279 "eris.eris_ifu_combine.name_o");
280 name_o = cpl_parameter_get_string(param);
281
282 param = cpl_parameterlist_find_const(parlist,
283 "eris.eris_ifu_combine.offset_mode");
284 offset_mode = cpl_parameter_get_bool(param);
285
286 param = cpl_parameterlist_find_const(parlist,
287 "eris.eris_ifu_combine.edge-trim");
288 edge_trim = cpl_parameter_get_int(param);
289
290 param = cpl_parameterlist_find_const(parlist,
291 "eris.eris_ifu_combine.compute_mode");
292 compute_mode = cpl_parameter_get_string(param);
293
294 param = cpl_parameterlist_find_const(parlist,
295 "eris.eris_ifu_combine.weights");
296 weights_i = cpl_parameter_get_string(param);
297
298
299 /* Identify the RAW and CALIB frames in the input frameset */
301 eris_dfs_set_groups(frameset));
302
303 /* Check the inputs frameset consistency */
305 eris_ifu_combine_check_inputs(frameset));
306
307 /* Check the inputs offset list consistency */
308 if (!offset_mode) {
309 if (NULL == (file_list = fopen (name_i, "r" )) ){
311 CPL_ERROR_ILLEGAL_INPUT, "cannot open %s\n", name_i);
312 }
313 cnt = 0 ;
314 while (fscanf(file_list, "%f %f",&tmpoffx, &tmpoffy) != EOF ){
315 cnt++;
316 }
317 fclose(file_list);
318
319 if (cnt != cpl_frameset_get_size(frameset)) {
321 CPL_ERROR_INCOMPATIBLE_INPUT, "Input offlist is not consistent with frameset.");
322 }
323 }
324
325 /* Check the inputs weights list consistency */
326 if (!strcmp(compute_mode, "MEAN") && strcmp(weights_i, "")) {
327 if (NULL == (file_list = fopen (weights_i, "r" )) ){
329 CPL_ERROR_ILLEGAL_INPUT, "cannot open %s\n", weights_i);
330 }
331 cnt = 0 ;
332 while (fscanf(file_list, "%f", &weights) != EOF ){
333 cnt++;
334 }
335 fclose(file_list);
336
337 if (cnt != cpl_frameset_get_size(frameset)) {
339 CPL_ERROR_INCOMPATIBLE_INPUT, "Input list of weights is not consistent with frameset.");
340 }
341 }
342
343 /* Allocate memory */
344 nframes = cpl_frameset_get_size(frameset);
345
347 exptimes = (double*) cpl_calloc(nframes, sizeof(double)));
349 offsetx = (float*) cpl_calloc(nframes, sizeof(float)));
351 offsety = (float*) cpl_calloc(nframes, sizeof(float)));
352
353 /* Read offset list */
354 if (!offset_mode){
355 cpl_msg_info(cpl_func, "Reading user-specified offset list.") ;
356 file_list = fopen (name_i, "r" );
357
358 cnt = 0;
359 while (fscanf( file_list, "%f %f",&tmpoffx,&tmpoffy ) != EOF ) {
360 offsetx[cnt] = tmpoffx;
361 offsety[cnt] = tmpoffy;
362 if (cnt == 0) {
363 x0 = offsetx[0];
364 y0 = offsety[0];
365 }
366 offsetx[cnt] = offsetx[cnt]-x0;
367 offsety[cnt] = offsety[cnt]-y0;
368 cpl_msg_info(cpl_func, " User defined offsets RA, DEC in pixels (relative to the first) %.2f, %.2f",
369 offsetx[cnt], offsety[cnt]) ;
370 cnt++;
371 }
372 fclose(file_list);
373 } else {
374 cpl_msg_info(cpl_func, "Use CUMOFFS from the header.") ;
375
376 double cd1_1 = 0,
377 cd1_2 = 0,
378 cd2_1 = 0,
379 cd2_2 = 0,
380 dra = 0,
381 ddec = 0;
382 const cpl_matrix *cd = NULL;
383
384 for (int n = 0; n < nframes; n++){
385 frame = cpl_frameset_get_position_const(frameset, n);
386 name = cpl_frame_get_filename(frame);
387
388 plist = cpl_propertylist_load(name, 0);
389 dra = cpl_propertylist_get_double(plist, "ESO OCS CUMOFFS RA");
390 ddec = cpl_propertylist_get_double(plist, "ESO OCS CUMOFFS DEC");
392
393 plist = cpl_propertylist_load(name, 1);
394 cpl_wcs *tmp_wcs = cpl_wcs_new_from_propertylist(plist);
396
397 cd = cpl_wcs_get_cd(tmp_wcs);
398 cd1_1 = cpl_matrix_get(cd, 0, 0);
399 cd1_2 = cpl_matrix_get(cd, 1, 0);
400 cd2_1 = cpl_matrix_get(cd, 0, 1);
401 cd2_2 = cpl_matrix_get(cd, 1, 1);
402 cpl_wcs_delete(tmp_wcs);
403
404 dra = -1 * dra /3600.0; //convert to degree
405 ddec = -1 * ddec/3600.0;
406 offsetx[n] = (float) (cd2_2 * dra - cd1_2 * ddec)/(cd1_1*cd2_2 - cd1_2*cd2_1);
407 offsety[n] = (float) (cd1_1 * ddec - cd2_1 * dra)/(cd1_1*cd2_2 - cd1_2*cd2_1);
408
409 if (n == 0) {
410 x0 = offsetx[0];
411 y0 = offsety[0];
412 }
413 offsetx[n] = offsetx[n]-x0;
414 offsety[n] = offsety[n]-y0;
415
416 cpl_msg_info(cpl_func, " CUMOFFS RA, DEC in pixels (relative to the first): %.2f, %.2f",
417 offsetx[n], offsety[n]) ;
418
419 }
420 } // end if: offset mode
422
423 /* Calculate size of new cube*/
425 files = (const char**) cpl_calloc(MAX_NAME_SIZE, sizeof(const char*)));
426
427 for (int n = 0; n < nframes; n++){
428 frame = cpl_frameset_get_position_const(frameset, n);
429 files[n] = cpl_frame_get_filename(frame);
430 exptimes[n] = eris_pfits_get_exptime(files[n]);
431
432 plist = cpl_propertylist_load(files[n], 1);
433 nx_out = eris_pfits_get_naxis1(plist);
434 ny_out = eris_pfits_get_naxis2(plist);
436
437 if (nx_out < min_size_x) {
438 min_size_x = nx_out;
439 }
440 if (ny_out < min_size_y) {
441 min_size_y = ny_out;
442 }
443 }
445
446 /* replace exptime by weights if needed */
447 if (!strcmp(compute_mode, "MEAN") && strcmp(weights_i, "")) {
448 cpl_msg_info(cpl_func, "Reading user-specified weights list.") ;
449 file_list = fopen (weights_i, "r" );
450
451 cnt = 0 ;
452 while (fscanf(file_list, "%f", &weights) != EOF ){
453 exptimes[cnt] = weights;
454 cnt++;
455 }
456 fclose(file_list);
457 }
458
459 cpl_msg_info(cpl_func, "Min. input cube size x = %d, y = %d", min_size_x, min_size_y);
460
462 eris_ifu_combine_auto_size_cube(offsetx, offsety, nframes,
463 &ref_offx, &ref_offy, &nx_out, &ny_out));
464
465 if (edge_trim > 0){
466 cpl_msg_info(cpl_func, "Number of pixels on edges to be trimmed: %d", edge_trim);
467 }
468
469 if(subtract_background) {
470 cpl_msg_info(cpl_func,"Subtract spatial median to each cube plane");
471 }
472
473 if (ks_clip) {
474 cpl_msg_info(cpl_func, "Coadding clipping mode: TRUE");
475 } else {
476 cpl_msg_info(cpl_func, "Coadding clipping mode: FALSE");
477 kappa = -1;
478 pclip = -1;
479 }
480 cpl_msg_info(cpl_func, "Coadding compute mode: %s", compute_mode);
481
482 nz = eris_ifu_combine_min_cube_size(frameset);
484
486 mergedImageData = cpl_calloc(nz, sizeof(cpl_image*)));
488 mergedImageError = cpl_calloc(nz, sizeof(cpl_image*)));
490 mergedImageDIT = cpl_calloc(nz, sizeof(cpl_image*)));
492 mergedCubeData = cpl_imagelist_new());
494 mergedCubeError = cpl_imagelist_new());
496 mergedCubeDIT = cpl_imagelist_new());
497 } CATCH {
498 // catch already here because OPENMP can't handle the error handling macros
499 CATCH_MSGS();
500 return (int)cpl_error_get_code();
501 }
502
503 /* Coadding cubes */
504 cpl_msg_info(cpl_func," Processing %d planes...", nz);
505HDRL_OMP(omp parallel for reduction(max:err))
506 for (int z = 0; z < nz; z++) {
507 cpl_msg_debug(cpl_func," Processing plane [%4.4d] of %d", z, nz);
508 cpl_image **imagesData = cpl_calloc(nframes, sizeof(cpl_image*)),
509 **imagesError = cpl_calloc(nframes, sizeof(cpl_image*));
510
512 imagesData, imagesError,
513 z, edge_trim, subtract_background);
514
515 err = eris_ifu_combine_jittered_images(imagesData,
516 imagesError,
517 nx_out,
518 ny_out,
519 &mergedImageData[z],
520 &mergedImageError[z],
521 &mergedImageDIT[z],
522 nframes,
523 offsetx, offsety,
524 exptimes,
525 kappa,
526 compute_mode,
527 pclip);
528
529 for (int i = 0; i < nframes; i++) {
530 eris_ifu_free_image(&imagesData[i]);
531 eris_ifu_free_image(&imagesError[i]);
532 }
533 cpl_free(imagesData);
534 cpl_free(imagesError);
535
536 eris_ifu_combine_convert_0_to_NaN_img(mergedImageData[z]);
537 eris_ifu_combine_convert_0_to_NaN_img(mergedImageError[z]);
538 eris_ifu_combine_convert_0_to_NaN_img(mergedImageDIT[z]);
539 } // end for(z)
540
541 if (err != CPL_ERROR_NONE) {
542 cpl_msg_error(__func__, "Combining jittered images failed!");
543 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT);
544 return (int)cpl_error_get_code();
545 }
546
547 for (int z = 0; z < nz; z++) {
548 if (!mergedImageData[z]) {
549 mergedImageData[z] = cpl_image_new(nx_out, ny_out, CPL_TYPE_DOUBLE);
550 }
551 cpl_imagelist_set(mergedCubeData, mergedImageData[z], z);
552
553 if (!mergedImageError[z]) {
554 mergedImageError[z] = cpl_image_new(nx_out,ny_out,CPL_TYPE_DOUBLE);
555 }
556 cpl_imagelist_set(mergedCubeError, mergedImageError[z], z);
557
558 if (!mergedImageDIT[z]) {
559 mergedImageDIT[z] = cpl_image_new(nx_out,ny_out,CPL_TYPE_DOUBLE);
560 }
561 cpl_imagelist_set(mergedCubeDIT, mergedImageDIT[z], z);
562 }
563
564 /* Save combined cube */
565 frame = cpl_frameset_get_position_const(frameset, 1);
566 plist = cpl_propertylist_load(files[0], 0);
567 cpl_propertylist_set_string(plist, CPL_DFS_PRO_CATG, ERIS_IFU_PRO_COMBINE);
568 cpl_dfs_save_propertylist(frameset, NULL, parlist, frameset, frame, REC_NAME_COMBINE,
569 plist, NULL, PACKAGE "/" PACKAGE_VERSION, name_o);
571
572 plist = cpl_propertylist_load(files[0], 1);
573
574 double crpix1 = cpl_propertylist_get_double(plist, "CRPIX1"),
575 crpix2 = cpl_propertylist_get_double(plist, "CRPIX2");
576
577 cpl_propertylist_update_double(plist, "CRPIX1", crpix1+ref_offx*2-1);
578 cpl_propertylist_update_double(plist, "CRPIX2", crpix2+ref_offy*2-1);
579 cpl_propertylist_update_string(plist, "EXTNAME", EXTNAME_DATA);
580 cpl_propertylist_set_comment(plist, "EXTNAME", EXTNAME_DATA_COMMENT);
581 cpl_propertylist_update_string(plist, "BUNIT", "adu/s");
582 cpl_imagelist_save(mergedCubeData, name_o, CPL_TYPE_DOUBLE, plist, CPL_IO_EXTEND);
583
584 cpl_propertylist_update_string(plist, "EXTNAME", EXTNAME_ERROR);
585 cpl_propertylist_set_comment(plist, "EXTNAME", EXTNAME_ERROR_COMMENT);
586 cpl_propertylist_update_string(plist, "BUNIT", "adu/s");
587 cpl_imagelist_save(mergedCubeError, name_o, CPL_TYPE_DOUBLE, plist, CPL_IO_EXTEND);
588
589 cpl_propertylist_update_string(plist, "EXTNAME", EXTNAME_DQ);
590 cpl_propertylist_set_comment(plist, "EXTNAME", EXTNAME_DQ_COMMENT);
591 cpl_propertylist_update_string(plist, "BUNIT", "sec");
592 cpl_imagelist_save(mergedCubeDIT, name_o, CPL_TYPE_DOUBLE, plist, CPL_IO_EXTEND);
593
595 for (int i = 0; i < nz; i++) {
596 eris_ifu_free_image(&mergedImageData[i]);
597 eris_ifu_free_image(&mergedImageError[i]);
598 eris_ifu_free_image(&mergedImageDIT[i]);
599 }
600 cpl_free(mergedImageData);
601 cpl_free(mergedImageError);
602 cpl_free(mergedImageDIT);
603 cpl_free(exptimes);
604 cpl_free(offsetx);
605 cpl_free(offsety);
606 cpl_free(files);
607
608 return (int)cpl_error_get_code();
609}
610
616cpl_error_code eris_ifu_combine_check_inputs(cpl_frameset *frameset)
617{
618 const cpl_frame *frame = NULL;
619 const char *tag = NULL;
620 int fs_size = cpl_frameset_get_size(frameset);
621
622 /* Check number of frames */
623 if (fs_size < 2){
624 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
625 cpl_msg_error(cpl_func, "Number of frames in SOF less than 2") ;
626 return cpl_error_get_code();
627 }
628
629 /* Check tags */
630 for (int i = 0; i < fs_size; i++){
631 frame = cpl_frameset_get_position_const(frameset, i);
632 tag = cpl_frame_get_tag(frame);
633 if (strcmp(tag, ERIS_IFU_COMBINE_DOCATG)) {
634 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
635 cpl_msg_error(cpl_func, "Wrong frame tag %s; should be %s",
636 tag, ERIS_IFU_COMBINE_DOCATG) ;
637 return cpl_error_get_code();
638 }
639 }
640 return cpl_error_get_code();
641}
cpl_error_code eris_dfs_set_groups(cpl_frameset *self)
Set the group as RAW or CALIB in a frameset.
Definition: eris_dfs.c:57
void eris_ifu_combine_convert_0_to_NaN_img(cpl_image *img)
eris_ifu_combine_convert_0_to_NaN_img
int eris_ifu_combine_min_cube_size(const cpl_frameset *fs)
eris_ifu_combine_min_cube_size
cpl_error_code eris_ifu_combine_read_image_planes(const cpl_frameset *frameset, cpl_image **imagesData, cpl_image **imagesError, int z, int edge_trim, bool subtract_background)
Read image planes from a frameset.
cpl_error_code eris_ifu_combine_jittered_images(cpl_image **imagesData, cpl_image **imagesError, int nx_out, int ny_out, cpl_image **mergedImageData, cpl_image **mergedImageError, cpl_image **mergedImageDIT, int n_cubes, const float *offsetx, const float *offsety, const double *exptimes, const double kappa, const char *compute_mode, const int pclip)
Combine jittered images into a merged image with optional kappa-sigma clipping.
cpl_error_code eris_ifu_combine_auto_size_cube(const float *offsetx, const float *offsety, const int nframes, float *ref_offx, float *ref_offy, int *size_x, int *size_y)
Computes size of coadded cube.
#define BRK_IF_ERROR(function)
If function is or returns an error != CPL_ERROR_NONE, then the try-block is exited.
#define CHECK_ERROR_STATE(void)
Check the CPL error state, and exit the try-block if not CPL_ERROR_NONE.
#define BRK_WITH_ERROR_MSG(code,...)
Set a new CPL error, and exit the try-block.
#define TRY
Beginning of a TRY-block.
#define CATCH
End of a TRY-block, beginning of a CATCH-block.
#define BRK_IF_NULL(function)
If function is or returns a NULL pointer, then the try-block is exited.
#define CATCH_MSGS()
Displays an error message stack.
cpl_error_code eris_ifu_combine(cubeType obj_type, cpl_frameset *frameset, const cpl_parameterlist *parlist, const char *recipe_name, const char *pipefile_prefix)
Resample and combine multiple IFU cubes into a single cube.
void eris_ifu_free_propertylist(cpl_propertylist **item)
Free memory and set pointer to null.
void eris_ifu_free_string(char **item)
Free memory and set pointer to null.
void eris_ifu_free_image(cpl_image **item)
Free memory and set pointer to null.
double eris_pfits_get_exptime(const char *filename)
find out the character string associated to the EXPTIME keyword
Definition: eris_pfits.c:137
int eris_pfits_get_naxis2(const cpl_propertylist *plist)
find out the character string associated to the NAXIS2 keyword
Definition: eris_pfits.c:168
int eris_pfits_get_naxis1(const cpl_propertylist *plist)
find out the character string associated to the NAXIS1 keyword
Definition: eris_pfits.c:155
cpl_error_code eris_files_dont_exist(cpl_frameset *frameset)
Check if all SOF files exist.
Definition: eris_utils.c:867