KMOS Pipeline Reference Manual 4.5.10
kmo_fits_strip.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#include <math.h>
25#include <string.h>
26
27#include <cpl.h>
28
29#include "kmclipm_constants.h"
30#include "kmclipm_functions.h"
31
32#include "kmo_utils.h"
33#include "kmo_dfs.h"
34#include "kmo_error.h"
35#include "kmo_debug.h"
36
37static int kmo_fits_strip_create(cpl_plugin *);
38static int kmo_fits_strip_exec(cpl_plugin *);
39static int kmo_fits_strip_destroy(cpl_plugin *);
40static int kmo_fits_strip(cpl_parameterlist *, cpl_frameset *);
41
42static char kmo_fits_strip_description[] =
43"With this recipe KMOS fits frames can be stripped in following way:\n"
44"\n"
45"--noise\n"
46"All noise extensions will be removed. Only the data extensions remain.\n"
47"\n"
48"--angle\n"
49"Applies only to calibration products from kmo_flat and kmo_wave_cal.\n"
50"All extensions matching provided angle are kept, the others are removed.\n"
51"Supply a single integer value.\n"
52"\n"
53"--empty\n"
54"All empty extensions will be removed.\n"
55"\n"
56"--extension\n"
57"Supply a comma-separated string with integer values indicating the extensions\n"
58"to keep. The other extensions are removed (any data or noise information is\n"
59"disregarded, the values are interpreted absolutely)\n"
60"\n"
61"The parameters --noise, --angle and --empty can be combined.\n"
62"When --extension is specified, all other parameters are ignored.\n"
63"When no parameter is provided, no output will be generated.\n"
64"\n"
65"-------------------------------------------------------------------------------\n"
66" Input files:\n"
67"\n"
68" DO KMOS \n"
69" category Type Explanation Required #Frames\n"
70" -------- ----- ----------- -------- -------\n"
71" <none or any> F2D or frame to strip Y 1 \n"
72" F3I or\n"
73" F2I or\n"
74" F1I or\n"
75"\n"
76" Output files:\n"
77"\n"
78" DO KMOS\n"
79" category Type Explanation\n"
80" -------- ----- -----------\n"
81" STRIP F2D or Stripped frame\n"
82" F3I or \n"
83" F2I or \n"
84" F1I \n"
85"-------------------------------------------------------------------------------\n"
86"\n";
87
104int cpl_plugin_get_info(cpl_pluginlist *list)
105{
106 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
107 cpl_plugin *plugin = &recipe->interface;
108
109 cpl_plugin_init(plugin,
110 CPL_PLUGIN_API,
111 KMOS_BINARY_VERSION,
112 CPL_PLUGIN_TYPE_RECIPE,
113 "kmo_fits_strip",
114 "Strip noise, rotator and/or empty extensions from a "
115 "processed KMOS fits frame",
116 kmo_fits_strip_description,
117 "Alex Agudo Berbel",
118 "https://support.eso.org/",
119 kmos_get_license(),
120 kmo_fits_strip_create,
121 kmo_fits_strip_exec,
122 kmo_fits_strip_destroy);
123
124 cpl_pluginlist_append(list, plugin);
125
126 return 0;
127}
128
136static int kmo_fits_strip_create(cpl_plugin *plugin)
137{
138 cpl_recipe *recipe = NULL;
139 cpl_parameter *p = NULL;
140
141 /* Check that the plugin is part of a valid recipe */
142 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
143 recipe = (cpl_recipe *)plugin;
144 else
145 return -1;
146
147 /* Create the parameters list in the cpl_recipe object */
148 recipe->parameters = cpl_parameterlist_new();
149
150 /* Fill the parameters list */
151 /* --empty */
152 p = cpl_parameter_new_value("kmos.kmo_fits_strip.empty",
153 CPL_TYPE_BOOL,
154 "TRUE: if empty extensions shall be removed,"
155 " FALSE: otherwise",
156 "kmos.kmo_fits_strip",
157 FALSE);
158 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "empty");
159 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
160 cpl_parameterlist_append(recipe->parameters, p);
161
162 /* --noise */
163 p = cpl_parameter_new_value("kmos.kmo_fits_strip.noise",
164 CPL_TYPE_BOOL,
165 "TRUE: if noise extensions shall be removed,"
166 " FALSE: otherwise",
167 "kmos.kmo_fits_strip",
168 FALSE);
169 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "noise");
170 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
171 cpl_parameterlist_append(recipe->parameters, p);
172
173 /* --angle */
174 p = cpl_parameter_new_value("kmos.kmo_fits_strip.angle",
175 CPL_TYPE_INT,
176 "All extensions not matching provided angle "
177 "are stripped.",
178 "kmos.kmo_fits_strip",
179 -1);
180 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "angle");
181 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
182 cpl_parameterlist_append(recipe->parameters, p);
183
184 /* --extension */
185 p = cpl_parameter_new_value("kmos.kmo_fits_strip.extension",
186 CPL_TYPE_STRING,
187 "Comma-separated string with integers. "
188 "All extensions matching these values are stripped.",
189 "kmos.kmo_fits_strip",
190 NULL);
191 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "extension");
192 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
193 cpl_parameterlist_append(recipe->parameters, p);
194
195 return 0;
196}
197
203static int kmo_fits_strip_exec(cpl_plugin *plugin)
204{
205 cpl_recipe *recipe;
206
207 /* Get the recipe out of the plugin */
208 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
209 recipe = (cpl_recipe *)plugin;
210 else return -1 ;
211
212 return kmo_fits_strip(recipe->parameters, recipe->frames);
213}
214
220static int kmo_fits_strip_destroy(cpl_plugin *plugin)
221{
222 cpl_recipe *recipe;
223
224 /* Get the recipe out of the plugin */
225 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
226 recipe = (cpl_recipe *)plugin;
227 else return -1 ;
228
229 cpl_parameterlist_delete(recipe->parameters);
230 return 0 ;
231}
232
233// kmo_dfs_save_main_header() doesn't allow to change ESO OCS ROT NAANGLE
234cpl_error_code kmo_save_header_fits_strip(cpl_propertylist *header,
235 cpl_parameterlist *parlist,
236 cpl_frameset *frameset,
237 const char *filename)
238{
239#define PRO_REC_PARAMi_NAME "ESO PRO REC1 PARAM%d NAME"
240#define PRO_REC_PARAMi_VALUE "ESO PRO REC1 PARAM%d VALUE"
241
242 cpl_error_code err = CPL_ERROR_NONE;
243 char *ggg = NULL,
244 cval[1024];
245 const char *kname = NULL;
246 const cpl_parameter *param = NULL;
247 cpl_frame *product_frame = NULL;
248 int npar = 0;
249
250 KMO_TRY
251 {
252 // setup DFS manually (no MD5 calculated...)
253 KMO_TRY_EXIT_IF_ERROR(
254 cpl_propertylist_update_string(header, "PIPEFILE", "strip.fits"));
255 KMO_TRY_EXIT_IF_ERROR(
256 cpl_propertylist_update_string(header, CPL_DFS_PRO_CATG, STRIP));
257 KMO_TRY_EXIT_IF_ERROR(
258 cpl_propertylist_update_string(header, "ESO PRO REC1 ID", cpl_func));
259 ggg = cpl_sprintf("cpl-%d.%d.%d", cpl_version_get_major(), cpl_version_get_minor(), cpl_version_get_micro());
260 KMO_TRY_EXIT_IF_ERROR(
261 cpl_propertylist_update_string(header, "ESO PRO REC1 DRS ID", ggg));
262 cpl_free(ggg); ggg = NULL;
263 KMO_TRY_EXIT_IF_ERROR(
264 cpl_propertylist_update_string(header, "ESO PRO REC1 PIPE ID", PACKAGE "/" PACKAGE_VERSION));
265 KMO_TRY_EXIT_IF_ERROR(
266 cpl_propertylist_update_string(header, "ESO PRO REC1 CAL1 NAME", kmos_get_base_name(filename)));
267 KMO_TRY_EXIT_IF_ERROR(
268 cpl_propertylist_update_string(header, "ESO PRO REC1 CAL1 CATG", COMMANDLINE));
269 KMO_TRY_EXIT_IF_ERROR(
270 cpl_propertylist_update_string(header, "ESO PRO REC1 CAL1 DATAMD5", cpl_propertylist_get_string(header, "DATAMD5")));
271 KMO_TRY_CHECK_ERROR_STATE();
272
273 while (param != NULL) {
274 char *pval, *dval;
275 ++npar;
276
277 kname = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
278 const char * comment = cpl_parameter_get_help(param);
279 switch (cpl_parameter_get_type(param)) {
280 case CPL_TYPE_BOOL:
281 pval = cpl_strdup(cpl_parameter_get_bool(param) == 1 ? "true" : "false");
282 dval = cpl_sprintf("Default: %s", cpl_parameter_get_default_bool(param) == 1 ? "true" : "false");
283 break;
284 case CPL_TYPE_INT:
285 pval = cpl_sprintf("%d", cpl_parameter_get_int(param));
286 dval = cpl_sprintf("Default: %d", cpl_parameter_get_default_int(param));
287 break;
288 case CPL_TYPE_DOUBLE:
289 pval = cpl_sprintf("%g", cpl_parameter_get_double(param));
290 dval = cpl_sprintf("Default: %g", cpl_parameter_get_default_double(param));
291 break;
292 case CPL_TYPE_STRING:
293 pval = cpl_strdup(cpl_parameter_get_string(param));
294 dval = cpl_sprintf("Default: '%s'", cpl_parameter_get_default_string(param));
295 break;
296 default:
297 /* Theoretically impossible to get here */
298 KMO_TRY_ASSURE(1==0,
299 CPL_ERROR_UNSPECIFIED,
300 "what?");
301 }
302 snprintf(cval, 1024, PRO_REC_PARAMi_NAME, npar);
303 cpl_propertylist_update_string(header, cval, kname);
304 cpl_propertylist_set_comment(header, cval, comment);
305
306 snprintf(cval, 1024, PRO_REC_PARAMi_VALUE, npar);
307 cpl_propertylist_update_string(header, cval, pval);
308 cpl_propertylist_set_comment(header, cval, dval);
309
310 cpl_free((void*)pval);
311 cpl_free((void*)dval);
312
313 param = cpl_parameterlist_get_next_const(parlist);
314 }
315 KMO_TRY_CHECK_ERROR_STATE();
316
317 cpl_msg_info(cpl_func, "Writing FITS %s product(%s): %s", "propertylist", "STRIP", "strip.fits");
318 KMO_TRY_EXIT_IF_NULL(
319 product_frame = cpl_frame_new());
320 KMO_TRY_EXIT_IF_ERROR(
321 cpl_frame_set_filename(product_frame, "strip.fits"));
322 KMO_TRY_EXIT_IF_ERROR(
323 cpl_frame_set_tag(product_frame, "STRIP"));
324 KMO_TRY_EXIT_IF_ERROR(
325 cpl_frame_set_type(product_frame, CPL_FRAME_TYPE_ANY));
326 KMO_TRY_EXIT_IF_ERROR(
327 cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT));
328 KMO_TRY_EXIT_IF_ERROR(
329 cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL));
330 KMO_TRY_EXIT_IF_ERROR(
331 cpl_frameset_insert(frameset, product_frame));
332
333 KMO_TRY_EXIT_IF_ERROR(
334 cpl_propertylist_save(header, "strip.fits", CPL_IO_CREATE));
335 }
336 KMO_CATCH
337 {
338 KMO_CATCH_MSG();
339 err = cpl_error_get_code();
340 }
341
342 return err;
343}
344
363static int kmo_fits_strip(cpl_parameterlist *parlist, cpl_frameset *frameset)
364{
365 int ret_val = 0,
366 nr_devices = 0,
367 remove_noise = FALSE,
368 remove_empty = FALSE,
369 remove_angle = FALSE,
370 found_angle = FALSE,
371 isCalFrame = 0,
372 isMasterFlat = 0,
373 actDetNr = 0,
374 cal_device_nr = 0,
375 dummy = 0,
376 index = 0;
377 double angle = 0.,
378 tmp_angle = 0.,
379 ret_angle = 0.,
380 secClosestAng = 0.,
381 ocsRotAngle = 0.,
382 proRotAngle = 0.,
383 *pextension = NULL;
384 cpl_propertylist *header = NULL,
385 *sub_header = NULL;
386 cpl_imagelist *cube = NULL;
387 cpl_image *img = NULL;
388 cpl_vector *vec = NULL,
389 *extension = NULL;
390 main_fits_desc desc;
391 cpl_frame *frame = NULL;
392 const char *filename = NULL,
393 *extension_txt = NULL;
394 char **split = NULL;
395 kmclipm_vector *kv = NULL;
396
397 KMO_TRY
398 {
399 kmo_init_fits_desc(&desc);
400
401 /* --- check input --- */
402 KMO_TRY_ASSURE((parlist != NULL) &&
403 (frameset != NULL),
404 CPL_ERROR_NULL_INPUT,
405 "Not all input data is provided!");
406
407 KMO_TRY_ASSURE(cpl_frameset_get_size(frameset) == 1,
408 CPL_ERROR_NULL_INPUT,
409 "A fits-file must be provided!");
410
411 KMO_TRY_EXIT_IF_NULL(
412 frame = kmo_dfs_get_frame(frameset, "0"));
413
414 KMO_TRY_EXIT_IF_NULL(
415 filename = cpl_frame_get_filename(frame));
416
417 desc = kmo_identify_fits_header(filename);
418 KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to be "
419 "in KMOS-format!");
420
421 KMO_TRY_ASSURE((desc.fits_type == f2d_fits) ||
422 (desc.fits_type == f3i_fits) ||
423 (desc.fits_type == f2i_fits) ||
424 (desc.fits_type == f1i_fits),
425 CPL_ERROR_ILLEGAL_INPUT,
426 "Input data hasn't correct data type "
427 "(KMOSTYPE must be F2D, F3I, F2I or F1I)!");
428
429 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset) == 1,
430 CPL_ERROR_ILLEGAL_INPUT,
431 "Cannot identify RAW and CALIB frames!");
432
433 cpl_msg_info("", "--- Parameter setup for kmo_fits_strip ----");
434 remove_empty = kmo_dfs_get_parameter_bool(parlist,
435 "kmos.kmo_fits_strip.empty");
436 KMO_TRY_CHECK_ERROR_STATE();
437 KMO_TRY_ASSURE((remove_empty == TRUE) ||
438 (remove_empty == FALSE),
439 CPL_ERROR_ILLEGAL_INPUT,
440 "empty must be TRUE or FALSE!");
441 KMO_TRY_EXIT_IF_ERROR(
442 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_fits_strip.empty"));
443
444 remove_noise = kmo_dfs_get_parameter_bool(parlist,
445 "kmos.kmo_fits_strip.noise");
446 KMO_TRY_CHECK_ERROR_STATE();
447 KMO_TRY_ASSURE((remove_noise == TRUE) ||
448 (remove_noise == FALSE),
449 CPL_ERROR_ILLEGAL_INPUT,
450 "noise must be TRUE or FALSE!");
451 KMO_TRY_EXIT_IF_ERROR(
452 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_fits_strip.noise"));
453
454 angle = kmo_dfs_get_parameter_int(parlist,
455 "kmos.kmo_fits_strip.angle");
456 KMO_TRY_CHECK_ERROR_STATE();
457 KMO_TRY_EXIT_IF_ERROR(
458 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_fits_strip.angle"));
459
460 if (angle >= 0) {
461 remove_angle = TRUE;
462 }
463
464 KMO_TRY_ASSURE(!remove_angle || ((angle >=0) && (angle < 360)),
465 CPL_ERROR_ILLEGAL_INPUT,
466 "angle must be between 0 and 360 degrees!");
467
468 extension_txt = kmo_dfs_get_parameter_string(parlist,
469 "kmos.kmo_fits_strip.extension");
470 KMO_TRY_CHECK_ERROR_STATE();
471 KMO_TRY_EXIT_IF_ERROR(
472 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_fits_strip.extension"));
473
474 if (strcmp(extension_txt, "") != 0) {
475
476 // extract values from string
477 KMO_TRY_EXIT_IF_NULL(
478 split = kmo_strsplit(extension_txt, ",", NULL));
479
480 int i = 0;
481 while (split[i] != NULL) {
482 i++;
483 }
484
485 KMO_TRY_EXIT_IF_NULL(
486 extension = cpl_vector_new(i));
487 KMO_TRY_EXIT_IF_NULL(
488 pextension = cpl_vector_get_data(extension));
489 i = 0;
490 while (split[i] != NULL) {
491 pextension[i] = atof(split[i]);
492 i++;
493 }
494 KMO_TRY_CHECK_ERROR_STATE();
495
496 kmo_strfreev(split); split = NULL;
497
498 // sort vector and remove double entries
499 KMO_TRY_EXIT_IF_ERROR(
500 cpl_vector_sort(extension, CPL_SORT_ASCENDING));
501
502 kv = kmclipm_vector_create(extension);
503
504 for (i = 0; i < kmclipm_vector_get_size(kv)-1; i++) {
505 if (kmclipm_vector_get(kv, i, NULL) == kmclipm_vector_get(kv, i+1, NULL)) {
506 kmclipm_vector_reject(kv, i+1);
507 }
508 }
509 extension = kmclipm_vector_create_non_rejected(kv);
510 kmclipm_vector_delete(kv); kv = NULL;
511
512 KMO_TRY_ASSURE(cpl_vector_get_max(extension) <= desc.nr_ext,
513 CPL_ERROR_ILLEGAL_INPUT,
514 "The input frame has less extensions than specified in 'extensions'-parameter!");
515 KMO_TRY_ASSURE(cpl_vector_get_max(extension) >= 1,
516 CPL_ERROR_ILLEGAL_INPUT,
517 "All values in 'extensions'-parameter must be > 1 !");
518 }
519
520 cpl_msg_info("", "-------------------------------------------");
521
522 if ((!remove_empty) && (!remove_noise) && (!remove_angle) && (extension == NULL)) {
523 // do nothing
524 cpl_msg_info("","No action has been specified (angle-, noise- or empty-parameter),"
525 " therefore no output is generated");
526 } else if (extension != NULL) {
527 //
528 // --- save primary extension ---
529 //
530 // load data and save it away again
531 KMO_TRY_EXIT_IF_NULL(
532 header = kmo_dfs_load_primary_header(frameset, "0"));
533 KMO_TRY_EXIT_IF_ERROR(
534 kmo_save_header_fits_strip(header, parlist, frameset, filename));
535 cpl_propertylist_delete(header); header = NULL;
536
537 //
538 // loop extensions
539 //
540 KMO_TRY_EXIT_IF_NULL(
541 pextension = cpl_vector_get_data(extension));
542 for (int i = 0; i < cpl_vector_get_size(extension); i++) {
543 KMO_TRY_EXIT_IF_NULL(
544 sub_header = cpl_propertylist_load(filename, pextension[i]));
545 if ((desc.fits_type == f2d_fits) ||
546 (desc.fits_type == f2i_fits))
547 {
548 img = cpl_image_load(filename,CPL_TYPE_FLOAT, 0, pextension[i]);
549 if (CPL_ERROR_NONE != cpl_error_get_code()) {
550 cpl_error_reset();
551 }
552 KMO_TRY_EXIT_IF_ERROR(
553 kmo_dfs_save_image(img, STRIP, "", sub_header, 0./0.));
554 cpl_image_delete(img); img = NULL;
555 } else if (desc.fits_type == f3i_fits) {
556 cube = cpl_imagelist_load(filename,CPL_TYPE_FLOAT, pextension[i]);
557 if (CPL_ERROR_NONE != cpl_error_get_code()) {
558 cpl_error_reset();
559 }
560 KMO_TRY_EXIT_IF_ERROR(
561 kmo_dfs_save_cube(cube, STRIP, "", sub_header, 0./0.));
562 cpl_imagelist_delete(cube); cube = NULL;
563 } else if (desc.fits_type == f1i_fits) {
564 vec = cpl_vector_load(filename, pextension[i]);
565 if (CPL_ERROR_NONE != cpl_error_get_code()) {
566 cpl_error_reset();
567 }
568 KMO_TRY_EXIT_IF_NULL(
569 kv = kmclipm_vector_create(vec));
570 KMO_TRY_EXIT_IF_ERROR(
571 kmo_dfs_save_vector(kv, STRIP, "", sub_header, 0./0.));
572 kmclipm_vector_delete(kv); kv = NULL;
573 }
574 cpl_propertylist_delete(sub_header); sub_header = NULL;
575 }
576 } else {
577 // check if it is a multi-angle-calibration file
578 isCalFrame = FALSE;
579 KMO_TRY_EXIT_IF_NULL(
580 sub_header = kmo_dfs_load_sub_header(frameset, "0", 1, FALSE));
581 if (cpl_propertylist_has(sub_header, CAL_ROTANGLE)) {
582 isCalFrame = TRUE;
583 }
584 cpl_propertylist_delete(sub_header); sub_header = NULL;
585
586 //
587 // --- save primary extension ---
588 //
589 // load data and save it away again
590 KMO_TRY_EXIT_IF_NULL(
591 header = kmo_dfs_load_primary_header(frameset, "0"));
592
593 if (strcmp(MASTER_FLAT, cpl_propertylist_get_string(header, CPL_DFS_PRO_CATG))==0) {
594 isMasterFlat = TRUE;
595 }
596
597 if (remove_angle && isCalFrame) {
598 // update OCS.ROT.NAANGLE if it differs
599 ocsRotAngle = cpl_propertylist_get_double(header, ROTANGLE);
600 ocsRotAngle = kmclipm_strip_angle(&ocsRotAngle);
601 proRotAngle = kmclipm_cal_propertylist_find_angle(filename, 1, FALSE, angle,
602 &dummy, &secClosestAng);
603 KMO_TRY_CHECK_ERROR_STATE();
604 if (fabs(ocsRotAngle-proRotAngle) > 0.1) {
605 cpl_msg_warning("", "In the product the original ESO OCS ROT NAANGLE keyword "
606 "has been updated with the chosen "
607 "ESO PRO ROT NAANGLE (was: %g, is: %g)!", ocsRotAngle, proRotAngle);
608 KMO_TRY_EXIT_IF_ERROR(
609 cpl_propertylist_update_double(header, ROTANGLE, proRotAngle));
610 }
611 }
612
613 KMO_TRY_EXIT_IF_ERROR(
614 kmo_save_header_fits_strip(header, parlist, frameset, filename));
615 cpl_propertylist_delete(header); header = NULL;
616
617 if (!isCalFrame) {
618 if (!desc.ex_noise) {
619 nr_devices = desc.nr_ext;
620 } else {
621 nr_devices = desc.nr_ext / 2;
622 }
623 } else {
624 nr_devices = 3;
625 }
626
627 if (isCalFrame) {
628 if (isMasterFlat) {
629 remove_noise = !remove_noise;
630 }
631 } else {
632 if (desc.ex_noise) {
633 remove_noise = !remove_noise;
634 }
635 }
636
637 actDetNr = 1;
638 for (int i = 0; i < nr_devices; i++) {
639
640 // either loop noise or not
641 for (int n = FALSE; n <= remove_noise; n++) {
642
643 if (isCalFrame) {
644 KMO_TRY_EXIT_IF_NULL(
645 header = kmclipm_cal_propertylist_load(filename, i+1, n, angle, &ret_angle));
646 } else {
647 KMO_TRY_EXIT_IF_NULL(
648 header = kmo_dfs_load_sub_header(frameset, "0", i + 1, n));
649 }
650
651 if (remove_angle) {
652 // examine angle
653 if (cpl_propertylist_has(header, CAL_ROTANGLE)) {
654 tmp_angle = cpl_propertylist_get_double(header, CAL_ROTANGLE);
655 KMO_TRY_CHECK_ERROR_STATE();
656
657 if (fabs(angle - tmp_angle) < 0.01) {
658 found_angle = TRUE;
659 isCalFrame = TRUE;
660 } else {
661 found_angle = FALSE;
662 }
663 } else {
664 // frame doesn't seem to have the CAL_ROTANGLE keyword
665 // process all extensions
666 found_angle = TRUE;
667 }
668 } else {
669 found_angle = TRUE;
670 }
671
672 index = kmo_identify_index(filename, i+1, n);
673 if (found_angle) {
674 if ((desc.fits_type == f2d_fits) ||
675 (desc.fits_type == f2i_fits))
676 {
677 if (isCalFrame) {
678 cal_device_nr = cpl_propertylist_get_int(header, CHIPINDEX);
679 KMO_TRY_CHECK_ERROR_STATE();
680 if (cal_device_nr == actDetNr) {
681 KMO_TRY_EXIT_IF_ERROR(
682 kmo_update_sub_keywords(header,
683 n,
684 FALSE,
685 desc.frame_type,
686 actDetNr));
687 print_cal_angle_msg_once = FALSE;
688 print_xcal_angle_msg_once = FALSE;
689 KMO_TRY_EXIT_IF_NULL(
690 img = kmo_dfs_load_cal_image(frameset, "0",
691 i+1, n, angle,
692 FALSE, NULL,
693 &ret_angle, -1, 0, 0));
694
695 if (fabs(angle-ret_angle) > 0.01) {
696 cpl_msg_warning("","Angle provided: %g, angle found: %g", angle, ret_angle);
697 }
698 if (n == remove_noise) {
699 actDetNr++;
700 }
701 }
702 if (img != NULL) {
703 KMO_TRY_EXIT_IF_ERROR(
704 kmo_dfs_save_image(img, STRIP, "", header, 0./0.));
705 }
706 } else {
707 img = cpl_image_load(filename,CPL_TYPE_FLOAT, 0, index);
708 if (CPL_ERROR_NONE != cpl_error_get_code()) {
709 cpl_error_reset();
710 if (!remove_empty) {
711 KMO_TRY_EXIT_IF_ERROR(
712 kmo_dfs_save_image(img, STRIP, "", header, 0./0.));
713 }
714 } else {
715 KMO_TRY_EXIT_IF_ERROR(
716 kmo_dfs_save_image(img, STRIP, "", header, 0./0.));
717 }
718 }
719 cpl_image_delete(img); img = NULL;
720 } else if (desc.fits_type == f3i_fits) {
721 cube = cpl_imagelist_load(filename,CPL_TYPE_FLOAT, index);
722 if (CPL_ERROR_NONE != cpl_error_get_code()) {
723 cpl_error_reset();
724 if (!remove_empty) {
725 KMO_TRY_EXIT_IF_ERROR(
726 kmo_dfs_save_cube(cube, STRIP, "", header, 0./0.));
727 }
728 } else {
729 KMO_TRY_EXIT_IF_ERROR(
730 kmo_dfs_save_cube(cube, STRIP, "", header, 0./0.));
731 }
732 cpl_imagelist_delete(cube); cube = NULL;
733 } else if (desc.fits_type == f1i_fits) {
734 vec = cpl_vector_load(filename, index);
735 if (CPL_ERROR_NONE != cpl_error_get_code()) {
736 cpl_error_reset();
737 if (!remove_empty) {
738 KMO_TRY_EXIT_IF_ERROR(
739 kmo_dfs_save_vector(NULL, STRIP, "", header, 0./0.));
740 }
741 } else {
742 KMO_TRY_EXIT_IF_NULL(
743 kv = kmclipm_vector_create(vec));
744 KMO_TRY_EXIT_IF_ERROR(
745 kmo_dfs_save_vector(kv, STRIP, "", header, 0./0.));
746 }
747 kmclipm_vector_delete(kv); kv = NULL;
748 }
749 } // if (found_angle)
750 cpl_propertylist_delete(header); header = NULL;
751 } // for (n)
752 } // for (i = nr_devices)
753 } // if ((!remove_empty) && (!remove_noise) && (!remove_angle))
754 }
755 KMO_CATCH
756 {
757 KMO_CATCH_MSG();
758
759 ret_val = -1;
760 }
761
762 cpl_propertylist_delete(header); header = NULL;
763 cpl_imagelist_delete(cube); cube = NULL;
764 cpl_image_delete(img); img = NULL;
765 kmclipm_vector_delete(kv); kv = NULL;
766 kmo_free_fits_desc(&desc);
767 cpl_vector_delete(extension); extension = NULL;
768
769 return ret_val;
770}
771
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.