KMOS Pipeline Reference Manual 4.5.10
kmo_make_image.c
1/*
2 * This file is part of the KMOS Pipeline
3 * Copyright (C) 2002,2003 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24/*-----------------------------------------------------------------------------
25 * Includes
26 *----------------------------------------------------------------------------*/
27
28#include <string.h>
29
30#include <cpl.h>
31
32#include "kmo_debug.h"
33#include "kmo_utils.h"
34#include "kmo_dfs.h"
35#include "kmo_error.h"
36#include "kmo_priv_make_image.h"
37#include "kmo_priv_functions.h"
38#include "kmo_constants.h"
39
40/*-----------------------------------------------------------------------------
41 * Functions prototypes
42 *----------------------------------------------------------------------------*/
43
44static int kmo_make_image_create(cpl_plugin *);
45static int kmo_make_image_exec(cpl_plugin *);
46static int kmo_make_image_destroy(cpl_plugin *);
47static int kmo_make_image(cpl_parameterlist *, cpl_frameset *);
48
49/*-----------------------------------------------------------------------------
50 * Static variables
51 *----------------------------------------------------------------------------*/
52
53static char kmo_make_image_description[] =
54"This recipe collapses a cube along the spectral axis using rejection. By \n"
55"default all spectral slices are averaged.\n"
56"Errors are propagated for the same spectral ranges as for the input data if\n"
57"a noise map is provided.\n"
58"\n"
59"BASIC PARAMETERS:\n"
60"-----------------\n"
61"--range\n"
62"The spectral range can be delimited to one or several sub-ranges like \n"
63"\"1.8,1.9\" or \"1.8,1.9; 2.0,2.11\"\n"
64"\n"
65"--cmethod\n"
66"Following methods of frame combination are available:\n"
67" * 'ksigma' (Default)\n"
68" An iterative sigma clipping. For each position all pixels in the\n"
69" spectrum are examined. If they deviate significantly, they will be\n"
70" rejected according to the conditions:\n"
71" val > mean + stdev * cpos_rej\n"
72" and\n"
73" val < mean - stdev * cneg_rej\n"
74" where --cpos_rej, --cneg_rej and --citer are the wished parameters\n"
75" In the first iteration median and percentile level are used.\n"
76" * 'median'\n"
77" At each pixel position the median is calculated.\n"
78" * 'average'\n"
79" At each pixel position the average is calculated.\n"
80" * 'sum'\n"
81" At each pixel position the sum is calculated.\n"
82" * 'min_max'\n"
83" The specified number of min and max pixel values will be rejected.\n"
84" --cmax and --cmin apply to this method.\n"
85"\n"
86"ADVANCED PARAMETERS\n"
87"-------------------\n"
88"--threshold\n"
89"Optionally an OH spectrum can be provided. In this case a threshold can be\n"
90"defined. The wavelengths of values above the threshold level in the OH\n"
91"spectrum are omitted in the input frame. This parameter can be combined with\n"
92"the --range parameter. Negative threshold values are ignored.\n"
93"Own spectra can be converted into the required F1S KMOS FITS format for the\n"
94"OH spectrum using kmo_fits_stack.\n"
95"\n"
96"--cpos_rej\n"
97"--cneg_rej\n"
98"--citer\n"
99" see --cmethod='ksigma'\n"
100"--cmax\n"
101"--cmin\n"
102" see --cmethod='min_max'\n"
103"\n"
104"---------------------------------------------------------------------------\n"
105" Input files:\n"
106" DO CATG Type Explanation Required #Frames\n"
107" ------- ----- ----------- -------- -------\n"
108" <none or any> F3I data frame Y 1 \n"
109" <none or any> F1S OH line spectrum N 0,1 \n"
110"\n"
111" Output files:\n"
112" DO CATG Type Explanation\n"
113" ------- ----- -----------\n"
114" MAKE_IMAGE F2I Collapsed data cubes\n"
115"---------------------------------------------------------------------------\n"
116"\n";
117
118/*----------------------------------------------------------------------------*/
122/*----------------------------------------------------------------------------*/
123
126/*----------------------------------------------------------------------------*/
135/*----------------------------------------------------------------------------*/
136int cpl_plugin_get_info(cpl_pluginlist *list)
137{
138 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
139 cpl_plugin *plugin = &recipe->interface;
140
141 cpl_plugin_init(plugin,
142 CPL_PLUGIN_API,
143 KMOS_BINARY_VERSION,
144 CPL_PLUGIN_TYPE_RECIPE,
145 "kmo_make_image",
146 "Collapse a cube to create a spatial image",
147 kmo_make_image_description,
148 "Alex Agudo Berbel",
149 "https://support.eso.org/",
150 kmos_get_license(),
151 kmo_make_image_create,
152 kmo_make_image_exec,
153 kmo_make_image_destroy);
154
155 cpl_pluginlist_append(list, plugin);
156
157 return 0;
158}
159
160/*----------------------------------------------------------------------------*/
168/*----------------------------------------------------------------------------*/
169static int kmo_make_image_create(cpl_plugin *plugin)
170{
171 cpl_recipe *recipe;
172 cpl_parameter *p;
173
174 /* Check that the plugin is part of a valid recipe */
175 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
176 recipe = (cpl_recipe *)plugin;
177 else
178 return -1;
179
180 /* Create the parameters list in the cpl_recipe object */
181 recipe->parameters = cpl_parameterlist_new();
182
183 /* Fill the parameters list */
184 /* --range */
185 p = cpl_parameter_new_value("kmos.kmo_make_image.range", CPL_TYPE_STRING,
186 "The spectral ranges to combine. e.g."
187 "\"x1_start,x1_end;x2_start,x2_end\" (microns)",
188 "kmos.kmo_make_image", "");
189 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "range");
190 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
191 cpl_parameterlist_append(recipe->parameters, p);
192
193 /* --threshold (if < 0, no thresholding at all) */
194 p = cpl_parameter_new_value("kmos.kmo_make_image.threshold",
195 CPL_TYPE_DOUBLE, "The OH threshold level (%)",
196 "kmos.kmo_make_image", 0.1);
197 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "threshold");
198 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
199 cpl_parameterlist_append(recipe->parameters, p);
200
201 return kmos_combine_pars_create(recipe->parameters, "kmos.kmo_make_image",
202 DEF_REJ_METHOD, FALSE);
203}
204
205/*----------------------------------------------------------------------------*/
211/*----------------------------------------------------------------------------*/
212static int kmo_make_image_exec(cpl_plugin *plugin)
213{
214 cpl_recipe *recipe;
215
216 /* Get the recipe out of the plugin */
217 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
218 recipe = (cpl_recipe *)plugin;
219 else return -1 ;
220
221 return kmo_make_image(recipe->parameters, recipe->frames);
222}
223
224/*----------------------------------------------------------------------------*/
230/*----------------------------------------------------------------------------*/
231static int kmo_make_image_destroy(cpl_plugin *plugin)
232{
233 cpl_recipe *recipe;
234
235 /* Get the recipe out of the plugin */
236 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
237 recipe = (cpl_recipe *)plugin;
238 else return -1 ;
239
240 cpl_parameterlist_delete(recipe->parameters);
241 return 0 ;
242}
243
244/*----------------------------------------------------------------------------*/
258/*----------------------------------------------------------------------------*/
259static int kmo_make_image(cpl_parameterlist *parlist, cpl_frameset *frameset)
260{
261 const char *cmethod = NULL;
262
263 double threshold = 0.0,
264 spec_crpix = 0.0,
265 spec_crval = 0.0,
266 spec_cdelt = 0.0,
267 ifu_crpix = 0.0,
268 ifu_crval = 0.0,
269 ifu_cdelt = 0.0,
270 cpos_rej = 0.0,
271 cneg_rej = 0.0;
272
273 cpl_imagelist *data_in = NULL,
274 *noise_in = NULL;
275
276 cpl_image *data_out = NULL,
277 *noise_out = NULL;
278
279 const char *ranges_txt = NULL;
280
281 cpl_vector *ranges = NULL,
282 *identified_slices = NULL,
283 *spec_data_in = NULL,
284 *spec_lambda_in = NULL;
285
286 int ret_val = 0,
287 nr_devices = 0,
288 i = 0,
289 valid_ifu = FALSE,
290 citer = 0,
291 cmax = 0,
292 cmin = 0,
293 devnr = 0,
294 index_data = 0,
295 index_noise = 0;
296
297 cpl_propertylist *sub_header_data = NULL,
298 *sub_header_noise = NULL,
299 *spec_header = NULL;
300
301 main_fits_desc desc1,
302 desc2;
303
304 cpl_frame *op1_frame = NULL,
305 *op2_frame = NULL;
306
307 KMO_TRY
308 {
309 kmo_init_fits_desc(&desc1);
310 kmo_init_fits_desc(&desc2);
311
312 /* --- check input --- */
313 KMO_TRY_ASSURE((parlist != NULL) && (frameset != NULL),
314 CPL_ERROR_NULL_INPUT, "Not all input data is provided");
315
316 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset) == 1,
317 CPL_ERROR_ILLEGAL_INPUT,"Cannot identify RAW and CALIB frames");
318
319 cpl_msg_info("", "--- Parameter setup for kmo_make_image ----");
320 threshold = kmo_dfs_get_parameter_double(parlist,
321 "kmos.kmo_make_image.threshold");
322 KMO_TRY_CHECK_ERROR_STATE();
323 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_print_parameter_help(parlist,
324 "kmos.kmo_make_image.threshold"));
325
326 ranges_txt = kmo_dfs_get_parameter_string(parlist,
327 "kmos.kmo_make_image.range");
328 KMO_TRY_CHECK_ERROR_STATE();
329 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_print_parameter_help(parlist,
330 "kmos.kmo_make_image.range"));
331 ranges = kmo_identify_ranges(ranges_txt);
332 KMO_TRY_CHECK_ERROR_STATE();
333
334 KMO_TRY_EXIT_IF_ERROR(kmos_combine_pars_load(parlist,
335 "kmos.kmo_make_image", &cmethod, &cpos_rej, &cneg_rej,
336 &citer, &cmin, &cmax, FALSE));
337 cpl_msg_info("", "-------------------------------------------");
338
339 KMO_TRY_ASSURE((cpl_frameset_get_size(frameset) == 1) ||
340 ((cpl_frameset_get_size(frameset) == 2) && (threshold != 0.0)),
341 CPL_ERROR_NULL_INPUT,
342 "A cube or a cube and a OH line spectrum must be provided");
343
344 /* Get First Frame and its Descriptor */
345 op1_frame=cpl_frameset_get_position(frameset, 0) ;
346 desc1 = kmo_identify_fits_header(cpl_frame_get_filename(op1_frame));
347 KMO_TRY_CHECK_ERROR_STATE_MSG("Wrong File Format");
348 KMO_TRY_ASSURE(desc1.fits_type == f3i_fits, CPL_ERROR_ILLEGAL_INPUT,
349 "First file has wrong data type (expect F3I)");
350
351 /* Get Second Frame and its decriptor */
352 if (cpl_frameset_get_size(frameset) > 1) {
353 op2_frame=cpl_frameset_get_position(frameset, 1) ;
354 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(op2_frame));
355 KMO_TRY_CHECK_ERROR_STATE_MSG("Wrong File Format");
356 KMO_TRY_ASSURE(desc2.fits_type == f1s_fits, CPL_ERROR_ILLEGAL_INPUT,
357 "Second file has wrong data type (expect F1S)");
358
359 /* Load OH-lines header */
360 spec_header = kmos_dfs_load_sub_header(op2_frame, 1, FALSE);
361 KMO_TRY_EXIT_IF_NULL(spec_header) ;
362 KMO_TRY_ASSURE(cpl_propertylist_get_int(spec_header, NAXIS) == 1,
363 CPL_ERROR_ILLEGAL_INPUT,
364 "Second input file must be a vector");
365 spec_crpix = cpl_propertylist_get_double(spec_header, CRPIX1);
366 KMO_TRY_CHECK_ERROR_STATE_MSG("Cannot get CRPIX1");
367 spec_crval = cpl_propertylist_get_double(spec_header, CRVAL1);
368 KMO_TRY_CHECK_ERROR_STATE_MSG("Cannot get CRVAL1");
369 spec_cdelt = cpl_propertylist_get_double(spec_header, CDELT1);
370 KMO_TRY_CHECK_ERROR_STATE_MSG("Cannot get CDELT1");
371
372 /* Load OH lines data */
373 kmclipm_vector * tmp_vec ;
374 tmp_vec = kmos_dfs_load_vector(op2_frame, 1, FALSE) ;
375 spec_data_in = kmclipm_vector_create_non_rejected(tmp_vec);
376 kmclipm_vector_delete(tmp_vec);
377 KMO_TRY_EXIT_IF_NULL(spec_data_in) ;
378
379 /* Convert threshold from percentage to absolute value */
380 threshold = threshold * cpl_vector_get_max(spec_data_in);
381
382 // create lambda-vector for OH-lines
383 KMO_TRY_EXIT_IF_NULL(
384 spec_lambda_in = kmo_create_lambda_vec(
385 cpl_vector_get_size(spec_data_in),
386 (int)spec_crpix, spec_crval, spec_cdelt));
387 }
388
389 /* --- load, update & save primary header --- */
390 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_save_main_header(frameset, MAKE_IMAGE,
391 "", op1_frame, NULL, parlist, cpl_func));
392
393 /* --- load data --- */
394 if (desc1.ex_noise == TRUE) {
395 nr_devices = desc1.nr_ext / 2;
396 } else {
397 nr_devices = desc1.nr_ext;
398 }
399
400 for (i = 1; i <= nr_devices; i++) {
401
402 /* Get the Device Nb */
403 if (desc1.ex_noise == FALSE) {
404 devnr = desc1.sub_desc[i - 1].device_nr;
405 } else {
406 devnr = desc1.sub_desc[2 * i - 1].device_nr;
407 }
408
409 /* Get the Data index */
410 if (desc1.ex_badpix == FALSE) {
411 index_data = kmo_identify_index_desc(desc1, devnr, FALSE);
412 } else {
413 index_data = kmo_identify_index_desc(desc1, devnr, 2);
414 }
415 KMO_TRY_CHECK_ERROR_STATE();
416
417 /* Get the Noise index */
418 if (desc1.ex_noise) {
419 index_noise = kmo_identify_index_desc(desc1, devnr, TRUE);
420 }
421 KMO_TRY_CHECK_ERROR_STATE();
422
423 /* Load the Extension Header */
424 sub_header_data = kmos_dfs_load_sub_header(op1_frame, devnr, FALSE);
425 KMO_TRY_EXIT_IF_NULL(sub_header_data) ;
426
427 /* Check if IFU is valid */
428 valid_ifu = FALSE;
429 if (desc1.sub_desc[index_data-1].valid_data == TRUE) {
430 valid_ifu = TRUE;
431 }
432
433 /* Load noise anyway since we have to save it in the output */
434 if (desc1.ex_noise) {
435 sub_header_noise = kmos_dfs_load_sub_header(op1_frame, devnr,
436 TRUE);
437 KMO_TRY_EXIT_IF_NULL(sub_header_noise) ;
438 if (cpl_propertylist_has(sub_header_noise, CRPIX3))
439 cpl_propertylist_erase(sub_header_noise, CRPIX3);
440 if (cpl_propertylist_has(sub_header_noise, CRVAL3))
441 cpl_propertylist_erase(sub_header_noise, CRVAL3);
442 if (cpl_propertylist_has(sub_header_noise, CDELT3))
443 cpl_propertylist_erase(sub_header_noise, CDELT3);
444 if (cpl_propertylist_has(sub_header_noise, CTYPE3))
445 cpl_propertylist_erase(sub_header_noise, CTYPE3);
446 if (cpl_propertylist_has(sub_header_noise, CUNIT3))
447 cpl_propertylist_erase(sub_header_noise, CUNIT3);
448 if (cpl_propertylist_has(sub_header_noise, CD1_3))
449 cpl_propertylist_erase(sub_header_noise, CD1_3);
450 if (cpl_propertylist_has(sub_header_noise, CD2_3))
451 cpl_propertylist_erase(sub_header_noise, CD2_3);
452 if (cpl_propertylist_has(sub_header_noise, CD3_3))
453 cpl_propertylist_erase(sub_header_noise, CD3_3);
454 if (cpl_propertylist_has(sub_header_noise, CD3_2))
455 cpl_propertylist_erase(sub_header_noise, CD3_2);
456 if (cpl_propertylist_has(sub_header_noise, CD3_1))
457 cpl_propertylist_erase(sub_header_noise, CD3_1);
458 }
459
460 if (valid_ifu) {
461 /* Load data */
462 data_in = kmos_dfs_load_cube(op1_frame, devnr, FALSE) ;
463 KMO_TRY_EXIT_IF_NULL(data_in) ;
464
465 /* Load noise, if existing */
466 if (desc1.ex_noise && desc1.sub_desc[index_noise-1].valid_data){
467 noise_in = kmos_dfs_load_cube(op1_frame, devnr, TRUE) ;
468 KMO_TRY_EXIT_IF_NULL(noise_in) ;
469 }
470
471 /* Interpolate oh-lines to fit input data */
472 ifu_crpix = cpl_propertylist_get_double(sub_header_data,CRPIX3);
473 KMO_TRY_CHECK_ERROR_STATE_MSG("CRPIX3 is missing");
474 ifu_crval = cpl_propertylist_get_double(sub_header_data,CRVAL3);
475 KMO_TRY_CHECK_ERROR_STATE_MSG("CRVAL3 is missing");
476 ifu_cdelt = cpl_propertylist_get_double(sub_header_data,CDELT3);
477 KMO_TRY_CHECK_ERROR_STATE_MSG("CDELT3 is missing");
478
479 if (spec_data_in == NULL) {
480 identified_slices = kmo_identify_slices(ranges, ifu_crpix,
481 ifu_crval, ifu_cdelt, desc1.naxis3);
482 } else {
483 identified_slices = kmo_identify_slices_with_oh(
484 spec_data_in, spec_lambda_in, ranges, threshold,
485 ifu_crpix, ifu_crval, ifu_cdelt, desc1.naxis3);
486 }
487 KMO_TRY_EXIT_IF_NULL(identified_slices) ;
488
489 if (cpl_propertylist_has(sub_header_data, CRPIX3))
490 cpl_propertylist_erase(sub_header_data, CRPIX3);
491 if (cpl_propertylist_has(sub_header_data, CRVAL3))
492 cpl_propertylist_erase(sub_header_data, CRVAL3);
493 if (cpl_propertylist_has(sub_header_data, CDELT3))
494 cpl_propertylist_erase(sub_header_data, CDELT3);
495 if (cpl_propertylist_has(sub_header_data, CTYPE3))
496 cpl_propertylist_erase(sub_header_data, CTYPE3);
497 if (cpl_propertylist_has(sub_header_data, CUNIT3))
498 cpl_propertylist_erase(sub_header_data, CUNIT3);
499 if (cpl_propertylist_has(sub_header_data, CD1_3))
500 cpl_propertylist_erase(sub_header_data, CD1_3);
501 if (cpl_propertylist_has(sub_header_data, CD2_3))
502 cpl_propertylist_erase(sub_header_data, CD2_3);
503 if (cpl_propertylist_has(sub_header_data, CD3_3))
504 cpl_propertylist_erase(sub_header_data, CD3_3);
505 if (cpl_propertylist_has(sub_header_data, CD3_2))
506 cpl_propertylist_erase(sub_header_data, CD3_2);
507 if (cpl_propertylist_has(sub_header_data, CD3_1))
508 cpl_propertylist_erase(sub_header_data, CD3_1);
509
510 /* Process & save data */
511 KMO_TRY_EXIT_IF_ERROR(kmclipm_make_image(data_in, noise_in,
512 &data_out, &noise_out, identified_slices, cmethod,
513 cpos_rej, cneg_rej, citer, cmax, cmin));
514
515 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_save_image(data_out, MAKE_IMAGE,
516 "", sub_header_data, 0./0.));
517
518 /* Process & save noise, if existing */
519 if (desc1.ex_noise) {
520 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_save_image(noise_out,
521 MAKE_IMAGE, "", sub_header_noise, 0./0.));
522 }
523
524 /* Free memory */
525 cpl_imagelist_delete(data_in); data_in = NULL;
526 cpl_imagelist_delete(noise_in); noise_in = NULL;
527 cpl_image_delete(data_out); data_out = NULL;
528 cpl_image_delete(noise_out); noise_out = NULL;
529 cpl_vector_delete(identified_slices); identified_slices = NULL;
530 } else {
531 if (cpl_propertylist_has(sub_header_data, CRPIX3))
532 cpl_propertylist_erase(sub_header_data, CRPIX3);
533 if (cpl_propertylist_has(sub_header_data, CRVAL3))
534 cpl_propertylist_erase(sub_header_data, CRVAL3);
535 if (cpl_propertylist_has(sub_header_data, CDELT3))
536 cpl_propertylist_erase(sub_header_data, CDELT3);
537 if (cpl_propertylist_has(sub_header_data, CTYPE3))
538 cpl_propertylist_erase(sub_header_data, CTYPE3);
539 if (cpl_propertylist_has(sub_header_data, CUNIT3))
540 cpl_propertylist_erase(sub_header_data, CUNIT3);
541 if (cpl_propertylist_has(sub_header_data, CD1_3))
542 cpl_propertylist_erase(sub_header_data, CD1_3);
543 if (cpl_propertylist_has(sub_header_data, CD2_3))
544 cpl_propertylist_erase(sub_header_data, CD2_3);
545 if (cpl_propertylist_has(sub_header_data, CD3_3))
546 cpl_propertylist_erase(sub_header_data, CD3_3);
547 if (cpl_propertylist_has(sub_header_data, CD3_2))
548 cpl_propertylist_erase(sub_header_data, CD3_2);
549 if (cpl_propertylist_has(sub_header_data, CD3_1))
550 cpl_propertylist_erase(sub_header_data, CD3_1);
551
552 // invalid IFU, just save sub_headers
553 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_save_sub_header(MAKE_IMAGE, "",
554 sub_header_data));
555
556 if (desc1.ex_noise) {
557 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_save_sub_header(MAKE_IMAGE,
558 "", sub_header_noise));
559 }
560 }
561
562 // free memory
563 cpl_propertylist_delete(sub_header_data); sub_header_data = NULL;
564 cpl_propertylist_delete(sub_header_noise); sub_header_noise = NULL;
565 }
566 }
567 KMO_CATCH
568 {
569 KMO_CATCH_MSG();
570 ret_val = -1;
571 }
572
573 kmo_free_fits_desc(&desc1);
574 kmo_free_fits_desc(&desc2);
575 cpl_propertylist_delete(sub_header_data); sub_header_data = NULL;
576 cpl_propertylist_delete(sub_header_noise); sub_header_noise = NULL;
577 cpl_propertylist_delete(spec_header); spec_header = NULL;
578 cpl_imagelist_delete(data_in); data_in = NULL;
579 cpl_imagelist_delete(noise_in); noise_in = NULL;
580 cpl_image_delete(data_out); data_out = NULL;
581 cpl_image_delete(noise_out); noise_out = NULL;
582 cpl_vector_delete(spec_data_in); spec_data_in = NULL;
583 cpl_vector_delete(spec_lambda_in); spec_lambda_in = NULL;
584 cpl_vector_delete(ranges); ranges = NULL;
585
586 return ret_val;
587}
588
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.