ERIS Pipeline Reference Manual 1.8.15
eris_nix_lss_stack.c
1/* $Id$
2 *
3 * This file is part of the ERIS Pipeline
4 * Copyright (C) 2017 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21/*
22 * $Author$
23 * $Date$
24 * $Revision$
25 */
26
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30
31/*-----------------------------------------------------------------------------
32 Includes
33 -----------------------------------------------------------------------------*/
34
35#include <libgen.h>
36#include <math.h>
37#include <string.h>
38
39#include "casu_utils.h"
40#include "casu_mods.h"
41
42#include "eris_utils.h"
43#include "eris_nix_utils.h"
44#include "eris_pfits.h"
45#include "eris_dfs.h"
46#include "eris_nix_dfs.h"
47#include "eris_nix_master_bpm.h"
48#include "eris_nix_master_dark.h"
49#include "eris_nix_gain_linearity.h"
50#include "eris_utils.h"
51#include <hdrl.h>
52
53#include <cpl.h>
54
55/*-----------------------------------------------------------------------------
56 Static variables
57 -----------------------------------------------------------------------------*/
58
59static const char eris_nix_lss_stack_description[] =
60"This recipe uses an HDRL collapse operation to stack a set of already \n"
61"registered ERIS/NIX LSS jitter frames.\n"
62"\n"
63"Input files:\n"
64"\n"
65" DO CATG Explanation Req. #Frames\n"
66" ------- ----------- --- -------\n"
67" "ERIS_NIX_CORRECTED_OBJECT_LSS_JITTER_PRO_CATG
68 " calibrated frames Y 1-n\n"
69" to be stacked.\n"
70" or\n"
71" "ERIS_NIX_CORRECTED_STD_LSS_JITTER_PRO_CATG
72 " calibrated standard Y 1-n\n"
73" frames to be stacked.\n"
74"\n"
75"Output files:\n"
76"\n"
77" DO CATG Explanation \n"
78" ------- ----------- \n"
79" "ERIS_NIX_LSS_OBS_COMBINED_PRO_CATG
80 " the stacked 2d-spectrum of the target.\n"
81" or\n"
82" "ERIS_NIX_LSS_STD_COMBINED_PRO_CATG
83 " the stacked 2d-spectrum of the standard.\n"
84"\n"
85" The output image will be in a FITS file named \n"
86" 'stack.<first input filename>', with extensions:\n"
87" - DATA, with the stacked target or standard data.\n"
88" - ERR, with the error plane.\n"
89" - DQ, with the stacked image quality\n"
90" - CONFIDENCE, with the target confidence plane.\n"
91
92"\n"
93"Notes on the method.\n"
94" The stacking uses hdrl_image_collapse to combine all jitter\n"
95" images such that each output pixel is the median of the inputs.\n"
96"\n";
97
98
99#define RECIPE_NAME "eris.eris_nix_lss_stack"
100
101/*-----------------------------------------------------------------------------
102 Private function prototypes
103 -----------------------------------------------------------------------------*/
104
105cpl_recipe_define(eris_nix_lss_stack, ERIS_BINARY_VERSION,
106 "John Lightfoot",
107 PACKAGE_BUGREPORT, "2017",
108 "Stack "ERIS_NIX_CORRECTED_OBJECT_LSS_JITTER_PRO_CATG
109 " frames",
110 eris_nix_lss_stack_description);
111
112/*-----------------------------------------------------------------------------
113 Function code
114 -----------------------------------------------------------------------------*/
115
116/*----------------------------------------------------------------------------*/
124/*----------------------------------------------------------------------------*/
125
126static cpl_error_code eris_nix_lss_stack_fill_parameterlist(
127 cpl_parameterlist * self) {
128
129 if (cpl_error_get_code() != CPL_ERROR_NONE) return cpl_error_get_code();
130
131 cpl_parameter * p = NULL;
132
133 p = cpl_parameter_new_value(RECIPE_NAME".x_probe", CPL_TYPE_INT,
134 "x coord of diagnostic pixel",
135 RECIPE_NAME, -1);
136 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "x-probe");
137 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
138 cpl_parameterlist_append(self, p);
139
140 p = cpl_parameter_new_value(RECIPE_NAME".y_probe", CPL_TYPE_INT,
141 "y coord of diagnostic pixel",
142 RECIPE_NAME, -1);
143 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "y-probe");
144 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
145 cpl_parameterlist_append(self, p);
146
147 return 0;
148}
149
150/*----------------------------------------------------------------------------*/
157/*----------------------------------------------------------------------------*/
158
159static int eris_nix_lss_stack(cpl_frameset * frameset,
160 const cpl_parameterlist * parlist) {
161
162 cpl_image * contrib = NULL;
163 hdrl_imagelist * himlist = NULL;
164 located_imagelist * jitters = NULL;
165 located_imagelist * object_jitters = NULL;
166 const char * out_catg = NULL;
167 located_image * stack = NULL;
168 located_imagelist * std_jitters = NULL;
169 cpl_frameset * used = NULL;
170
171 enu_check_error_code("%s():%d: An error is already set: %s",
172 cpl_func, __LINE__, cpl_error_get_where());
173
174 /* Check input parameters */
175
176 cpl_ensure_code(frameset, CPL_ERROR_NULL_INPUT);
177 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
178
179 /* Set the msg verbosity level from environment variable CPL_MSG_LEVEL */
180
181 cpl_msg_set_level_from_env();
182 cpl_msg_severity severity = cpl_msg_get_level();
183 cpl_msg_info(cpl_func, "level %d", (int) severity);
184
185 /* check for invalid input */
186 if(eris_files_dont_exist(frameset) != CPL_ERROR_NONE) {
187 return CPL_ERROR_BAD_FILE_FORMAT;
188 }
189 /* Retrieve input parameters */
190
191 const cpl_parameter * p = NULL;
192 p = cpl_parameterlist_find_const(parlist, RECIPE_NAME".x_probe");
193 cpl_size x_probe = (cpl_size) cpl_parameter_get_int(p);
194 p = cpl_parameterlist_find_const(parlist, RECIPE_NAME".y_probe");
195 cpl_size y_probe = (cpl_size) cpl_parameter_get_int(p);
196
197 enu_check_error_code("Could not retrieve input parameters");
198
199 /* Identify the RAW and CALIB frames in the input frameset */
200
201 eris_nix_dfs_set_groups(frameset);
202 enu_check_error_code("Could not identify RAW and CALIB frames");
203 used = cpl_frameset_new();
204
205 /* read in the straightened data */
206
207 object_jitters = enu_limlist_load_from_frameset(frameset,
208 ERIS_NIX_CORRECTED_OBJECT_LSS_JITTER_PRO_CATG, used);
209 std_jitters = enu_limlist_load_from_frameset(frameset,
210 ERIS_NIX_CORRECTED_STD_LSS_JITTER_PRO_CATG, used);
211 enu_check_error_code("Error loading frameset");
212
213 if (object_jitters->size > 0) {
214 enu_check(std_jitters->size == 0, CPL_ERROR_ILLEGAL_INPUT,
215 "SoF contains both object and std data");
216 jitters = object_jitters;
217 object_jitters = NULL;
218 out_catg = ERIS_NIX_LSS_OBS_COMBINED_PRO_CATG;
219 cpl_msg_info(cpl_func, "Read in %d "
220 ERIS_NIX_CORRECTED_OBJECT_LSS_JITTER_PRO_CATG" frames",
221 (int)(jitters->size));
222 } else if (std_jitters->size > 0) {
223 jitters = std_jitters;
224 std_jitters = NULL;
225 out_catg = ERIS_NIX_LSS_STD_COMBINED_PRO_CATG;
226 cpl_msg_info(cpl_func, "Read in %d "
227 ERIS_NIX_CORRECTED_STD_LSS_JITTER_PRO_CATG" frames",
228 (int)(jitters->size));
229 }
230
231 /* construct an hdrl_imagelist from the located images */
232
233 himlist = hdrl_imagelist_new();
234 double crval1 = -1.0;
235 double crval3 = -1.0;
236 for (cpl_size j=0; j < jitters->size; j++) {
237 hdrl_imagelist_set(himlist,
238 hdrl_image_duplicate(jitters->limages[j]->himage),
239 j);
240
241 crval1 = cpl_propertylist_get_double(jitters->limages[j]->plist,
242 "CRVAL1");
243 /* LSS data may not have CRVAL3 and other CD matrix keys for 3d axis as they are just images"
244 if(cpl_propertylist_has(jitters->limages[j]->plist,"CRVAL3")) {
245 crval3 = cpl_propertylist_get_double(jitters->limages[j]->plist,
246 "CRVAL3");
247 }
248 */
249 /* output 'probe' pixel if debugging */
250
251 cpl_size nx = hdrl_image_get_size_x(jitters->limages[j]->himage);
252 cpl_size ny = hdrl_image_get_size_y(jitters->limages[j]->himage);
253
254 if (x_probe >= 1 && x_probe <= nx &&
255 y_probe >= 1 && y_probe <= ny) {
256 int reject = 0;
257 hdrl_value val = hdrl_image_get_pixel(jitters->limages[j]->himage,
258 x_probe, y_probe, &reject);
259 int ignore = 0;
260 double confidence = cpl_image_get(jitters->limages[j]->confidence,
261 x_probe, y_probe, &ignore);
262 cpl_msg_info(cpl_func, "j=%d val={%f, %f} reject=%d confidence=%f",
263 (int)j, val.data, val.error, reject, confidence);
264 }
265 }
266
267 /* and stack the data */
268
269 hdrl_image * stack_himage = NULL;
270 hdrl_imagelist_collapse(himlist, HDRL_COLLAPSE_MEDIAN, &stack_himage,
271 &contrib);
272 enu_check_error_code("error set after image stacking");
273
274 /* output 'probe' pixel if debugging */
275
276 cpl_size nx = hdrl_image_get_size_x(stack_himage);
277 cpl_size ny = hdrl_image_get_size_y(stack_himage);
278
279 if (x_probe >= 1 && x_probe <= nx &&
280 y_probe >= 1 && y_probe <= ny) {
281
282 int reject = 0;
283 hdrl_value val = hdrl_image_get_pixel(stack_himage,
284 x_probe, y_probe, &reject);
285 cpl_msg_info(cpl_func, "val={%f, %f} reject=%d",
286 val.data, val.error, reject);
287 }
288
289 /* and stack the background */
290
291 hdrl_imagelist_delete(himlist); himlist = NULL;
292 himlist = hdrl_imagelist_new();
293 for (cpl_size j=0; j < jitters->size; j++) {
294 hdrl_imagelist_set(himlist,
295 hdrl_image_duplicate(jitters->limages[j]->bkg), j);
296 }
297
298 hdrl_image * stack_bkg = NULL;
299 cpl_image_delete(contrib);
300 hdrl_imagelist_collapse(himlist, HDRL_COLLAPSE_MEDIAN,
301 &stack_bkg,
302 &contrib);
303 enu_check_error_code("error set after background stacking");
304
305 /* and stack the confidence.
306 This assumes the stacking elsewhere was done with HDRL_COLLAPSE_MEDIAN,
307 in which case eqn 21 in HDRL Doc section on 'Statistical Esimators'
308 says that the sigma on the median is related to that on the mean
309 by a constant factor (pi/2), which will drop out when the
310 confidence is normalised.
311
312 sigma^2 is 1 / confidence.
313 */
314
315 cpl_image * stack_confidence = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
316 {
317 cpl_image * stack_count = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
318 double * stack_conf_ptr = cpl_image_get_data_double(stack_confidence);
319 double * stack_count_ptr = cpl_image_get_data_double(stack_count);
320 for (cpl_size i=0; i < nx * ny; i++) {
321 stack_conf_ptr[i] = 0.0;
322 stack_count_ptr[i] = 0.0;
323 }
324
325 /* accumulate jitter confidences */
326
327 for (cpl_size j=0; j < jitters->size; j++) {
328 for (cpl_size i=1; i < nx+1; i++){
329 for (cpl_size jj=1; jj< ny+1; jj++) {
330 // confidence images should have no invalid pixels
331 // BUT the images can and, if they do, those pixels
332 // will not contribute to the median. Nor should
333 // those pixel's confidence contribute to the
334 // stacked confidence
335 int rejected = 0;
337 jitters->limages[j]->himage,
338 i, jj, &rejected);
339 if (rejected == 0) {
340 int ignore = 0;
341 double jconf = cpl_image_get(
342 jitters->limages[j]->confidence,
343 i, jj, &ignore);
344 double sconf = cpl_image_get(stack_confidence,
345 i, jj, &ignore);
346 if (jconf > 0.0) {
347 if (sconf != CPL_VALUE_PLUSINF) {
348 // valid numbers, convert confidence to variance
349 jconf = 1.0 / jconf;
350 cpl_image_set(stack_confidence, i, jj,
351 sconf + jconf);
352 double tcount = cpl_image_get(stack_count,
353 i, jj, &ignore);
354 cpl_image_set(stack_count, i, jj, tcount + 1);
355 }
356 } else {
357 // 0 confidence, infinite variance
358 cpl_image_set(stack_confidence, i, jj,
359 CPL_VALUE_PLUSINF);
360 }
361 }
362 }
363 }
364 }
365
366 /* divide by N^2 (mean is sum/N, mean var = sum_var / N^2 */
367
368 for (cpl_size i=1; i < nx+1; i++){
369 for (cpl_size j=1; j< ny+1; j++) {
370 int ignore = 0;
371 double conf = cpl_image_get(stack_confidence,
372 i, j, &ignore);
373 double count = cpl_image_get(stack_count,
374 i, j, &ignore);
375 if (conf != CPL_VALUE_PLUSINF && count > 0.0) {
376 cpl_image_set(stack_confidence,
377 i, j, conf / pow(count, 2));
378 } else {
379 cpl_image_set(stack_confidence,
380 i, j, CPL_VALUE_PLUSINF);
381 }
382 }
383 }
384
385 /* variance -> confidence */
386
387 for (cpl_size i=0; i < nx * ny; i++) {
388 if (stack_conf_ptr[i] == CPL_VALUE_PLUSINF) {
389 stack_conf_ptr[i] = 0.0;
390 } else {
391 stack_conf_ptr[i] = 1.0 / stack_conf_ptr[i];
392 }
393 }
394
395 /* normalise confidence */
396
397 enu_normalise_confidence(stack_confidence);
398
399 cpl_image_delete(stack_count);
400 }
401 enu_check_error_code("error set after confidence stacking");
402
403 /* save the result */
404
405 stack = enu_located_image_new(stack_himage,
406 NULL,
407 stack_confidence,
408 stack_bkg,
409 NULL,
410 cpl_propertylist_new(),
411 NULL,
412 NULL,
413 NULL,
414 NULL,
415 NULL);
416
417 /* Set up the wcs to reflect the corrected spectrum.
418 Borrows from long-slit example in
419 Calabretta and Greisen 2002 A&A 395, 1077 (example on p.
420 1115-16).
421
422 ..This scheme, with its degenerate 3rd axis, my be more 'clever'
423 ..than we need - maybe better to keep 2 dims [lambda, slit offset]?
424
425 In our case the pixel coords are p1,p2 = slit-offset,wavelength
426 NB this is different to the example in the paper.
427
428 The transformation is to RA, Dec, lambda. Using a CD matrix:
429
430 RA CRVAL1 CD1_1 CD1_2 CD1_3 p1 - CRPIX1
431 lambda = CRVAL2 + CD2_1 CD2_2 CD2_3 x p2 - CRPIX2
432 Dec CRVAL3 + CD3_1 CD3_2 CD3_3 p3 - CRPIX3
433
434 The wavelength transformation is 3.045um at 0 to 4.107um at 2047 so:
435
436 CRPIX2 = 0.0
437 CRVAL2 = 3.045
438 CD2_1 = 0
439 CD2_2 = 0
440 cd2_3 = (4.107 - 3.045) / 2047
441
442 The slit offset to RA, Dec transformation combines the RA,Dec of the
443 slit centre with the P.A. of the slit rotation (assumed 0 at N,
444 increasing towrds increasing RA), so:
445
446 CRPIX1 = 1024
447 CRVAL1 = RA centre
448 CD1_1 = sin(PA) * pixscale
449 RA = CRVAL1 + CD1_1 * (p1 - CRPIX1)
450
451 and
452
453 CRVAL3 = Dec centre
454 CD3_1 = cos(PA) * pixscale
455 Dec = CRVAL3 + CD3_1 * (p1 - CRPIX3)
456
457 The p3 axis is degenerate so CD entries for it can have
458 arbitrary values.
459
460 CD1_3 = CD2_3 = CD3_3 = 1
461 */
462
463 cpl_propertylist * olist = stack->plist;
464 cpl_propertylist_update_int(olist, "NAXIS", 3);
465 cpl_propertylist_update_string(olist, "CTYPE1", "RA---TAN");
466 cpl_propertylist_update_string(olist, "CTYPE2", "WAVE");
467 cpl_propertylist_update_string(olist, "CTYPE3", "DEC--TAN");
468 cpl_propertylist_update_double(olist, "CRPIX1", 1024.0);
469 cpl_propertylist_update_double(olist, "CRPIX2", 0.0);
470 cpl_propertylist_update_double(olist, "CRPIX3", 0.0);
471 cpl_propertylist_update_double(olist, "CRVAL1", crval1);
472 cpl_propertylist_update_double(olist, "CRVAL2", 3.045);
473 cpl_propertylist_update_double(olist, "CRVAL3", crval3);
474
475 /* the slit p.a. needs to be sorted out */
476 double slit_pa = 0.0;
477 double pixscale = 0.013;
478 cpl_propertylist_update_double(olist, "CD1_1",
479 sin(slit_pa) * pixscale / (3600.0));
480 cpl_propertylist_update_double(olist, "CD1_2", 0.0);
481 cpl_propertylist_update_double(olist, "CD1_3", 1.0);
482
483 cpl_propertylist_update_double(olist, "CD2_1", 0.0);
484 cpl_propertylist_update_double(olist, "CD2_2",
485 (4.107 - 3.045) / 2047);
486 cpl_propertylist_update_double(olist, "CD2_3", 0.0);
487
488 cpl_propertylist_update_double(olist, "CD3_1",
489 cos(slit_pa) * pixscale / (3600.0));
490 cpl_propertylist_update_double(olist, "CD3_2", 0.0);
491 cpl_propertylist_update_double(olist, "CD3_3", 1.0);
492
493 cpl_propertylist_update_string(olist, "CUNIT1", "DEG");
494 cpl_propertylist_update_string(olist, "CUNIT2", "um");
495 cpl_propertylist_update_string(olist, "CUNIT3", "DEG");
496
497 /* data needs to be converted from dims [nx,ny] to [nx,ny,1] to
498 save in FITS format - FITS required the addition of a degenerate
499 axis */
500
501 hdrl_imagelist * himlist1 = hdrl_imagelist_new();
502 hdrl_imagelist_set(himlist1, stack->himage, 0);
503 stack->himage = NULL;
504 stack->himagelist = himlist1;
505
506 /* generate name of file */
507
508 char * stack_fname = enu_repreface(cpl_frame_get_filename(
509 jitters->limages[0]->frame),
510 "stack");
511
512 /* construct provenance frameset */
513
514 cpl_frameset * provenance = cpl_frameset_new();
515 for (cpl_size j=0; j<jitters->size; j++) {
516 cpl_frameset_insert(provenance, cpl_frame_duplicate(
517 jitters->limages[j]->frame));
518 }
519
520 /* update PRO.CATG and stack info */
521
522 cpl_propertylist * applist = cpl_propertylist_new();
523 cpl_propertylist_update_string(applist, CPL_DFS_PRO_CATG, out_catg);
524 cpl_propertylist_update_string(applist, "PRODCATG",
525 "ANCILLARY.2DSPECTRUM");
526
527 int ncombine = jitters->size;
528
529 double total_exptime = 0.0;
530 double mjd_start = 1000000.0;
531 double mjd_end = 0.0;
532
533 cpl_vector * obsid = cpl_vector_new(jitters->size);
534 for (cpl_size j=0; j < jitters->size; j++) {
535 cpl_vector_set(obsid, j, (double)j);
536
537
538 /* .. total integration time */
539
540 double dit = enu_get_dit(jitters->limages[j]->plist);
541 double exptime = dit * cpl_propertylist_get_int(
542 jitters->limages[j]->plist, "ESO DET NDIT");
543 total_exptime += exptime;
544
545 /* .. MJD of start and end of measurements used */
546
547 double jitter_start = cpl_propertylist_get_double(
548 jitters->limages[j]->plist, "MJD-OBS");
549 if (jitter_start < mjd_start) {
550 mjd_start = jitter_start;
551 }
552 double jitter_end = cpl_propertylist_get_double(
553 jitters->limages[j]->plist, "MJD-END");
554 if (jitter_end > mjd_end) {
555 mjd_end = jitter_end;
556 }
557 cpl_msg_info(cpl_func, "..combined mjd start: %15.8f end: %15.8f",
558 mjd_start, mjd_end);
559
560
561 }
562
563
564 cpl_propertylist_update_int(applist, "NCOMBINE", ncombine);
565 cpl_propertylist_update_double(applist, "EXPTIME", total_exptime);
566 cpl_propertylist_update_double(applist, "TEXPTIME", total_exptime);
567 cpl_propertylist_update_double(applist, "MJD-OBS", mjd_start);
568 cpl_propertylist_update_double(applist, "MJD-END", mjd_end);
569 for (cpl_size j = 0; j < jitters->size; ++j) {
570 char * pname = cpl_sprintf("OBID%.0i", (int)(j+1));
571 cpl_msg_info(cpl_func, "%d %s", (int)j, pname);
572 cpl_propertylist_update_int(applist, pname,
573 (int)cpl_vector_get(obsid, j));
574 cpl_free(pname);
575 }
576
577 cpl_msg_info(cpl_func, "BUNIT fudged for now");
578 cpl_propertylist_update_string(applist, "BUNIT", "adu/s");
579
580 /* and save the result */
581
582 enu_dfs_save_limage(frameset,
583 parlist,
584 provenance,
585 CPL_FALSE,
586 stack,
587 RECIPE_NAME,
588 stack->frame,
589 applist,
590 PACKAGE "/" PACKAGE_VERSION,
591 stack_fname);
592
593 cpl_free(stack_fname);
594 cpl_frameset_delete(provenance);
595 cpl_propertylist_delete(applist);
596
597cleanup:
598 cpl_image_delete(contrib);
599 hdrl_imagelist_delete(himlist);
602 cpl_frameset_delete(used);
603
604 return (int) cpl_error_get_code();
605}
cpl_error_code enu_dfs_save_limage(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *provenance, const cpl_boolean prov_raw, const located_image *limage, const char *recipe, const cpl_frame *inherit, cpl_propertylist *applist, const char *pipe_id, const char *filename)
Save a located image structure to a MEF.
Definition: eris_nix_dfs.c:909
cpl_error_code eris_nix_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: eris_nix_dfs.c:58
void enu_located_imagelist_delete(located_imagelist *limlist)
Delete a located_imagelist and its contents.
located_image * enu_located_image_new(hdrl_image *himage, hdrl_imagelist *himagelist, cpl_image *confidence, hdrl_image *bkg, cpl_image *bkg_confidence, cpl_propertylist *plist, hdrl_catalogue_result *objects, cpl_mask *object_mask, hdrl_catalogue_result *wcs, hdrl_catalogue_result *photom, cpl_frame *frame)
Create a located_image structure and initialise the contents.
located_imagelist * enu_limlist_load_from_frameset(cpl_frameset *frameset, const char *tag, cpl_frameset *used)
Load tagged data from a frameset into a located_imagelist.
void enu_located_image_delete(located_image *limage)
Delete a located_image and its contents.
cpl_error_code enu_normalise_confidence(cpl_image *confidence)
Normalise confidence array so that mean of good pixels is 100.
char * enu_repreface(const char *filename, const char *preface)
Preface a raw filename with a string.
double enu_get_dit(const cpl_propertylist *plist)
Get the DIT of an integration.
cpl_error_code eris_files_dont_exist(cpl_frameset *frameset)
Check if all SOF files exist.
Definition: eris_utils.c:867
hdrl_value hdrl_image_get_pixel(const hdrl_image *self, cpl_size xpos, cpl_size ypos, int *pis_rejected)
get pixel values of hdrl_image
Definition: hdrl_image.c:559
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_image
Definition: hdrl_image.c:391
cpl_size hdrl_image_get_size_y(const hdrl_image *self)
return size of Y dimension of image
Definition: hdrl_image.c:540
cpl_size hdrl_image_get_size_x(const hdrl_image *self)
return size of X dimension of image
Definition: hdrl_image.c:525
cpl_error_code hdrl_imagelist_set(hdrl_imagelist *himlist, hdrl_image *himg, cpl_size pos)
Insert an image into an imagelist.
void hdrl_imagelist_delete(hdrl_imagelist *himlist)
Free all memory used by a hdrl_imagelist object including the images.
cpl_error_code hdrl_imagelist_collapse(const hdrl_imagelist *himlist, const hdrl_parameter *param, hdrl_image **out, cpl_image **contrib)
collapsing of image list
hdrl_imagelist * hdrl_imagelist_new(void)
Create an empty imagelist.