KMOS Pipeline Reference Manual 4.5.10
kmo_fit_profile.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#include <math.h>
30
31#include <cpl.h>
32
33#include "kmo_utils.h"
34#include "kmo_priv_fit_profile.h"
35#include "kmo_priv_functions.h"
36#include "kmo_dfs.h"
37#include "kmo_error.h"
38#include "kmo_constants.h"
39#include "kmo_debug.h"
40
41/*-----------------------------------------------------------------------------
42 * Functions prototypes
43 *----------------------------------------------------------------------------*/
44
45static int kmo_fit_profile_create(cpl_plugin *);
46static int kmo_fit_profile_exec(cpl_plugin *);
47static int kmo_fit_profile_destroy(cpl_plugin *);
48static int kmo_fit_profile(cpl_parameterlist *, cpl_frameset *);
49
50/*-----------------------------------------------------------------------------
51 * Static variables
52 *----------------------------------------------------------------------------*/
53
54static char kmo_fit_profile_description[] =
55"This recipe creates either spectral or spatial profiles of sources using dif-\n"
56"ferent functions to fit. Spectral profiles can be created for F1I frames (if\n"
57"WCS is defined in the input frame, the output parameters are in respect to the\n"
58"defined WCS).\n"
59"Spatial profiles can be created for F2I frames (any WCS information is ignored\n"
60"here).\n"
61"If the frames contain no noise information, constant noise is assumed for the\n"
62"fitting procedure.\n"
63"\n"
64"BASIC PARAMETERS:\n"
65"-----------------\n"
66"--method\n"
67"F1I frames can be fitted using either 'gauss', 'moffat' or 'lorentz' function.\n"
68"F2I frames can be fitted using either 'gauss' or 'moffat' function.\n"
69"\n"
70"ADVANCED PARAMETERS\n"
71"-------------------\n"
72"--range\n"
73"For F1I frames the spectral range can be defined. With available WCS informa-\n"
74"tion the range can be provided in units (e.g. “1.2;1.5”), otherwise in pixels\n"
75"(e.g. “112;224).\n"
76"For F2I frames the spatial range can be defined as follow: “x1,x2;y1,y2”\n"
77"\n"
78"-------------------------------------------------------------------------------\n"
79" Input files:\n"
80"\n"
81" DO KMOS \n"
82" category Type Explanation Required #Frames\n"
83" -------- ----- ----------- -------- -------\n"
84" <none or any> F1I or Frame with or Y 1 \n"
85" F2I without noise \n"
86"\n"
87" Output files:\n"
88"\n"
89" DO KMOS\n"
90" category Type Explanation\n"
91" -------- ----- -----------\n"
92" FIT_PROFILE F1I Fitted profile (without noise frame)\n"
93" or (3 Extensions) \n"
94" F2I \n"
95"-------------------------------------------------------------------------------\n"
96"\n";
97
98/*-----------------------------------------------------------------------------
99 * Functions code
100 *----------------------------------------------------------------------------*/
101
118int cpl_plugin_get_info(cpl_pluginlist *list)
119{
120 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
121 cpl_plugin *plugin = &recipe->interface;
122
123 cpl_plugin_init(plugin,
124 CPL_PLUGIN_API,
125 KMOS_BINARY_VERSION,
126 CPL_PLUGIN_TYPE_RECIPE,
127 "kmo_fit_profile",
128 "Fit spectral line profiles as well as spatial profiles"
129 " with a simple function - for example to measure "
130 "resolution or find the centre of a source",
131 kmo_fit_profile_description,
132 "Alex Agudo Berbel",
133 "https://support.eso.org/",
134 kmos_get_license(),
135 kmo_fit_profile_create,
136 kmo_fit_profile_exec,
137 kmo_fit_profile_destroy);
138
139 cpl_pluginlist_append(list, plugin);
140
141 return 0;
142}
143
151static int kmo_fit_profile_create(cpl_plugin *plugin)
152{
153 cpl_recipe *recipe;
154 cpl_parameter *p;
155
156 /* Check that the plugin is part of a valid recipe */
157 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
158 recipe = (cpl_recipe *)plugin;
159 else
160 return -1;
161
162 /* Create the parameters list in the cpl_recipe object */
163 recipe->parameters = cpl_parameterlist_new();
164
165 /* Fill the parameters list */
166 /* --method */
167 p = cpl_parameter_new_value("kmos.kmo_fit_profile.method",
168 CPL_TYPE_STRING,
169 "Either fit \"gauss\", \"moffat\" or "
170 "\"lorentz\" for 1D data."
171 "Either fit \"gauss\" or \"moffat\" for "
172 "2D data. ",
173 "kmos.kmo_fit_profile",
174 "gauss");
175 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "method");
176 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
177 cpl_parameterlist_append(recipe->parameters, p);
178
179 /* --range */
180 p = cpl_parameter_new_value("kmos.kmo_fit_profile.range",
181 CPL_TYPE_STRING,
182 "The spectral or spatial range to combine. "
183 "Default is the whole range. "
184 "e.g. F1I: \"0.5,2.1\" (microns), "
185 "e.g. F2I: \"1,7;3,10\" (pixels: x1,x2;y1,y2), "
186 "pixels are counted from 1.",
187 "kmos.kmo_fit_profile",
188 "");
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 return 0;
194}
195
201static int kmo_fit_profile_exec(cpl_plugin *plugin)
202{
203 cpl_recipe *recipe;
204
205 /* Get the recipe out of the plugin */
206 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
207 recipe = (cpl_recipe *)plugin;
208 else return -1;
209
210 return kmo_fit_profile(recipe->parameters, recipe->frames);
211}
212
218static int kmo_fit_profile_destroy(cpl_plugin *plugin)
219{
220 cpl_recipe *recipe;
221
222 /* Get the recipe out of the plugin */
223 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
224 recipe = (cpl_recipe *)plugin;
225 else return -1 ;
226
227 cpl_parameterlist_delete(recipe->parameters);
228 return 0 ;
229}
230
245static int kmo_fit_profile(cpl_parameterlist *parlist, cpl_frameset *frameset)
246{
247 cpl_image *data_img_in = NULL,
248 *data_img_in2 = NULL,
249 *data_img_out = NULL,
250 *noise_img_in = NULL,
251 *noise_img_in2 = NULL;
252
253 cpl_vector *data_vec_in = NULL,
254 *data_vec_out = NULL,
255 *noise_vec_in = NULL,
256 *ranges = NULL,
257 *ranges2 = NULL,
258 *fit_par = NULL,
259 *lambda_vec = NULL,
260 *lambda_vec2 = NULL,
261 *data_vec2 = NULL,
262 *noise_vec2 = NULL;
263
264 cpl_frame *frame = NULL;
265 cpl_frame *frame_final = NULL;
266
267 int ret_val = 0,
268 nr_devices = 0,
269 i = 0,
270 j = 0,
271 x1 = 0,
272 x2 = 0,
273 y1 = 0,
274 y2 = 0,
275 valid_ifu = FALSE,
276 devnr = 0,
277 index_data = 0,
278 index_noise = 0;
279
280 double crpix1 = 0.0,
281 crval1 = 0.0,
282 cdelt1 = 0.0,
283 *pranges = NULL;
284
285 const char *ranges_txt = NULL,
286 *method = NULL;
287 const char *input_tag = NULL;
288 const char *ocs_name_header = NULL;
289 const char *ocs_name = NULL;
290
291 cpl_propertylist *sub_header_data = NULL,
292 *sub_header_noise = NULL,
293 *pl = NULL,
294 *new_header = NULL;
295 cpl_propertylist *header = NULL;
296
297 main_fits_desc desc;
298 int nr_stars = 0;
299 cpl_errorstate curr_err;
300
301 KMO_TRY
302 {
303 kmo_init_fits_desc(&desc);
304
305 /* --- check input --- */
306 KMO_TRY_ASSURE((parlist != NULL) &&
307 (frameset != NULL),
308 CPL_ERROR_NULL_INPUT,
309 "Not all input data is provided!");
310
311 KMO_TRY_ASSURE(cpl_frameset_get_size(frameset) == 1,
312 CPL_ERROR_NULL_INPUT,
313 "A fits-file must be provided!");
314
315 /* Input frames are either 0 or MAKE_IMAGE */
316 if (cpl_frameset_count_tags(frameset, "0") > 0)
317 input_tag = "0" ;
318 else if (cpl_frameset_count_tags(frameset, COMMANDLINE) > 0)
319 input_tag = COMMANDLINE ;
320 else if (cpl_frameset_count_tags(frameset, MAKE_IMAGE) > 0)
321 input_tag = MAKE_IMAGE ;
322 else {
323 cpl_msg_error(__func__, "Missing input frames");
324 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
325 return -1 ;
326 }
327
328 KMO_TRY_EXIT_IF_NULL(
329 frame = kmo_dfs_get_frame(frameset, input_tag));
330
331 header = kmo_dfs_load_primary_header(frameset, input_tag);
332
333 cpl_error_code error = CPL_ERROR_NONE;
334 error |= cpl_frame_set_level(frame, CPL_FRAME_LEVEL_TEMPORARY);
335
336 /* load descriptor */
337 desc = kmo_identify_fits_header(
338 cpl_frame_get_filename(frame));
339 char * fit_profile_tmp = cpl_sprintf("%s_tmp.fits", FIT_PROFILE) ;
340
341 KMO_TRY_CHECK_ERROR_STATE();
342
343 KMO_TRY_ASSURE((desc.fits_type == f2i_fits) ||
344 (desc.fits_type == f1i_fits),
345 CPL_ERROR_ILLEGAL_INPUT,
346 "DATA isn't in the correct format (either F2I or F1I)!");
347
348 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset) == 1,
349 CPL_ERROR_ILLEGAL_INPUT,
350 "Cannot identify RAW and CALIB frames!");
351
352 /* --- get parameters --- */
353 cpl_msg_info(cpl_func, "--- Parameter setup for kmo_fit_profile ---");
354
355 KMO_TRY_EXIT_IF_NULL(
356 method = kmo_dfs_get_parameter_string(parlist,
357 "kmos.kmo_fit_profile.method"));
358 KMO_TRY_EXIT_IF_ERROR(
359 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_fit_profile.method"));
360
361 ranges_txt = kmo_dfs_get_parameter_string(parlist,
362 "kmos.kmo_fit_profile.range");
363 KMO_TRY_CHECK_ERROR_STATE();
364 KMO_TRY_EXIT_IF_ERROR(
365 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_fit_profile.range"));
366
367 cpl_msg_info("", "-------------------------------------------");
368
369 if (strcmp(ranges_txt, "") != 0) {
370
371 ranges = kmo_identify_ranges(ranges_txt);
372 KMO_TRY_CHECK_ERROR_STATE();
373
374 KMO_TRY_EXIT_IF_NULL(
375 pranges = cpl_vector_get_data(ranges));
376
377 KMO_TRY_ASSURE((pranges[0] < pranges[1]),
378 CPL_ERROR_ILLEGAL_INPUT,
379 "x1 must be smaller than x2!");
380
381 KMO_TRY_ASSURE((((desc.fits_type == f2i_fits) &&
382 (cpl_vector_get_size(ranges) == 4) ) || (
383 (desc.fits_type == f1i_fits) &&
384 (cpl_vector_get_size(ranges) == 2) )),
385 CPL_ERROR_ILLEGAL_INPUT,
386 "'range' must contain 2 values for F1I and "
387 "4 values for F2I!");
388
389 if (desc.fits_type == f2i_fits) {
390 x1 = pranges[0];
391 x2 = pranges[1];
392 y1 = pranges[2];
393 y2 = pranges[3];
394
395 KMO_TRY_ASSURE((x1 > 0) &&
396 (y1 > 0) &&
397 (x2 < desc.naxis1) &&
398 (y2 < desc.naxis2),
399 CPL_ERROR_ILLEGAL_INPUT,
400 "Provided range is larger than images in F2I!");
401
402 KMO_TRY_ASSURE(y1 < y2,
403 CPL_ERROR_ILLEGAL_INPUT,
404 "y1 must be smaller than y2!");
405
406 } else {
407 // for F1I-files this will be done individually for each
408 // extension.
409 }
410 } else {
411 if (desc.fits_type == f2i_fits) {
412 x1 = 1;
413 x2 = desc.naxis1;
414 y1 = 1;
415 y2 = desc.naxis2;
416 } else {
417 ranges = cpl_vector_new(2);
418 cpl_vector_set(ranges, 0, 1);
419 cpl_vector_set(ranges, 1, desc.naxis1);
420 }
421 }
422
423 /* --- load & save primary header --- */
424 KMO_TRY_EXIT_IF_ERROR(
425 //kmo_dfs_save_main_header(frameset, FIT_PROFILE, "_tmp", frame,
426 // NULL, parlist, cpl_func));
427 cpl_propertylist_save(header, fit_profile_tmp, CPL_IO_CREATE));
428
429 /* --- load data --- */
430 if (desc.ex_noise == TRUE) {
431 nr_devices = desc.nr_ext / 2;
432 } else {
433 nr_devices = desc.nr_ext;
434 }
435
436 for (i = 1; i <= nr_devices; i++) {
437 if (desc.ex_noise == FALSE) {
438 devnr = desc.sub_desc[i - 1].device_nr;
439 } else {
440 devnr = desc.sub_desc[2 * i - 1].device_nr;
441 }
442
443 if (desc.ex_badpix == FALSE) {
444 index_data = kmo_identify_index_desc(desc, devnr, FALSE);
445 } else {
446 index_data = kmo_identify_index_desc(desc, devnr, 2);
447 }
448 KMO_TRY_CHECK_ERROR_STATE();
449
450 if (desc.ex_noise) {
451 index_noise = kmo_identify_index_desc(desc, devnr, TRUE);
452 }
453 KMO_TRY_CHECK_ERROR_STATE();
454
455 /*KMO_TRY_EXIT_IF_NULL(
456 sub_header_data = kmo_dfs_load_sub_header(frameset, "0", devnr,
457 FALSE)); */
458 KMO_TRY_EXIT_IF_NULL(
459 sub_header_data = kmo_dfs_load_sub_header(frameset, input_tag, devnr,
460 FALSE));
461
462 // check if IFU is valid
463 // Fix for PIPE-11013
464 curr_err = cpl_errorstate_get();
465 ocs_name_header = cpl_sprintf("%s%d%s", IFU_NAME_PREFIX, i, IFU_NAME_POSTFIX);
466 ocs_name = cpl_propertylist_get_string(sub_header_data, ocs_name_header);
467
468 valid_ifu = FALSE;
469 if ((desc.sub_desc[index_data-1].valid_data == TRUE) && (strcmp(ocs_name,"Sky")) && (strcmp(ocs_name,""))) {
470 valid_ifu = TRUE;
471 }
472 cpl_errorstate_set(curr_err);
473
474 KMO_TRY_CHECK_ERROR_STATE();
475
476 if (desc.ex_noise) {
477 // load noise anyway since we have to save it in the output
478 /*KMO_TRY_EXIT_IF_NULL(
479 sub_header_noise = kmo_dfs_load_sub_header(frameset, "0",
480 devnr, TRUE)); */
481 KMO_TRY_EXIT_IF_NULL(
482 sub_header_noise = kmo_dfs_load_sub_header(frameset, input_tag,
483 devnr, TRUE));
484 }
485
486 if (valid_ifu) {
487 if (desc.fits_type == f2i_fits) {
488 //
489 // process images
490 //
491
492 // load data
493 /*(KMO_TRY_EXIT_IF_NULL(
494 data_img_in = kmo_dfs_load_image(frameset, "0",
495 devnr, FALSE, FALSE, NULL));*/
496 KMO_TRY_EXIT_IF_NULL(
497 data_img_in = kmo_dfs_load_image(frameset, input_tag,
498 devnr, FALSE, FALSE, NULL));
499
500 KMO_TRY_EXIT_IF_NULL(
501 data_img_in2 = cpl_image_extract(data_img_in,
502 x1, y1, x2, y2));
503
504 // load noise, if existing
505 if (desc.ex_noise && desc.sub_desc[index_noise-1].valid_data) {
506 /*KMO_TRY_EXIT_IF_NULL(
507 noise_img_in = kmo_dfs_load_image(frameset, "0",
508 devnr, TRUE, FALSE, NULL)); */
509 KMO_TRY_EXIT_IF_NULL(
510 noise_img_in = kmo_dfs_load_image(frameset, input_tag,
511 devnr, TRUE, FALSE, NULL));
512
513 KMO_TRY_EXIT_IF_NULL(
514 noise_img_in2 = cpl_image_extract(noise_img_in,
515 x1, y1, x2, y2));
516 }
517
518 // process data
519 KMO_TRY_EXIT_IF_NULL(
520 fit_par = kmo_fit_profile_2D(data_img_in2,
521 noise_img_in2,
522 method,
523 &data_img_out,
524 &pl));
525 cpl_vector_delete(fit_par); fit_par = NULL;
526
527 if (cpl_propertylist_get_double(pl, FIT_INTENSITY) > 5){
528 nr_stars += 1 ;
529 }
530
531 // update subheader with fit parameters
532 KMO_TRY_EXIT_IF_ERROR(
533 cpl_propertylist_append(sub_header_data, pl));
534
535 /* save data (noise is omitted for the fitted data)*/
536 KMO_TRY_EXIT_IF_ERROR(
537 //kmo_dfs_save_image(data_img_out, FIT_PROFILE, "_tmp",
538 // sub_header_data, 0./0.));
539 kmclipm_image_save(data_img_out, fit_profile_tmp,
540 CPL_BPP_IEEE_FLOAT, sub_header_data, CPL_IO_EXTEND, 0./0.));
541
542 /* free memory */
543 cpl_image_delete(data_img_in); data_img_in = NULL;
544 cpl_image_delete(data_img_in2); data_img_in2 = NULL;
545 cpl_image_delete(data_img_out); data_img_out = NULL;
546 cpl_image_delete(noise_img_in); noise_img_in = NULL;
547 cpl_image_delete(noise_img_in2); noise_img_in2 = NULL;
548 } else {
549 //
550 // process vectors
551 //
552
553 // load data
554 kmclipm_vector *ddd = NULL;
555 /*KMO_TRY_EXIT_IF_NULL(
556 ddd = kmo_dfs_load_vector(frameset, "0",
557 devnr, FALSE)); */
558 KMO_TRY_EXIT_IF_NULL(
559 ddd = kmo_dfs_load_vector(frameset, input_tag,
560 devnr, FALSE));
561 data_vec_in = kmclipm_vector_create_non_rejected(ddd);
562 kmclipm_vector_delete(ddd); ddd = NULL;
563
564 // extract CRVAL, CRPIX and CDELT to convert the ranges-
565 // vector from spectral- to pixel-space
566 if (cpl_propertylist_has(sub_header_data, CRPIX1) &&
567 cpl_propertylist_has(sub_header_data, CRVAL1) &&
568 cpl_propertylist_has(sub_header_data, CDELT1))
569 {
570 crpix1 = cpl_propertylist_get_double(sub_header_data,
571 CRPIX1);
572 crval1 = cpl_propertylist_get_double(sub_header_data,
573 CRVAL1);
574 cdelt1 = cpl_propertylist_get_double(sub_header_data,
575 CDELT1);
576
577 if (strcmp(ranges_txt, "") == 0) {
578 cpl_vector_set(ranges, 0,
579 crpix1*crval1 +
580 cdelt1*(cpl_vector_get(ranges,0)-1));
581 cpl_vector_set(ranges, 1,
582 crpix1*crval1 +
583 cdelt1*(cpl_vector_get(ranges,1)-1));
584 }
585 } else {
586 // set crpix1 to 2 because the output position should
587 // be zero-based
588 // (like in the cpl_vector definition)
589// crpix1 = 2;
590 crpix1 = 1;
591 crval1 = 1;
592 cdelt1 = 1;
593 }
594
595 // ranges2 will have the same size as the input spectra
596 // and will contain zeros for positions outside the provided
597 // spectral range and ones for values inside
598 KMO_TRY_EXIT_IF_NULL(
599 ranges2 = kmo_identify_slices(ranges,
600 crpix1,
601 crval1,
602 cdelt1,
603 desc.naxis1));
604 KMO_TRY_EXIT_IF_NULL(
605 pranges = cpl_vector_get_data(ranges2));
606
607 x1 = -1; x2 = -1;
608 for (j = 0; j < cpl_vector_get_size(ranges2); j++) {
609 if ((pranges[j] == 1) && (x1 == -1)) {
610 x1 = j;
611 }
612 if ((pranges[j] == 1) && (x1 != -1)) {
613 x2 = j;
614 }
615 }
616 cpl_vector_delete(ranges2); ranges2 = NULL;
617
618 // create lambda-vector for IFU
619 KMO_TRY_EXIT_IF_NULL(
620 lambda_vec = kmo_create_lambda_vec(desc.naxis1,
621 crpix1,
622 crval1,
623 cdelt1));
624
625 KMO_TRY_EXIT_IF_NULL(
626 lambda_vec2 = cpl_vector_extract(lambda_vec, x1, x2, 1));
627
628 KMO_TRY_EXIT_IF_NULL(
629 data_vec2 = cpl_vector_extract(data_vec_in, x1, x2, 1));
630
631 // load noise, if existing and
632 // extract same range as with data
633 if (desc.ex_noise && desc.sub_desc[index_noise-1].valid_data) {
634 /*KMO_TRY_EXIT_IF_NULL(
635 ddd = kmo_dfs_load_vector(frameset, "0",
636 devnr, TRUE)); */
637 KMO_TRY_EXIT_IF_NULL(
638 ddd = kmo_dfs_load_vector(frameset, input_tag,
639 devnr, TRUE));
640 noise_vec_in = kmclipm_vector_create_non_rejected(ddd);
641 kmclipm_vector_delete(ddd); ddd =NULL;
642
643 KMO_TRY_EXIT_IF_NULL(
644 noise_vec2 = cpl_vector_extract(noise_vec_in,
645 x1, x2, 1));
646 }
647
648 // process data
649 KMO_TRY_EXIT_IF_NULL(
650 fit_par = kmo_fit_profile_1D(lambda_vec2,
651 data_vec2,
652 noise_vec2,
653 method,
654 &data_vec_out,
655 &pl));
656
657 if (cpl_propertylist_get_double(pl, FIT_INTENSITY) > 5){
658 nr_stars += 1 ;
659 }
660
661 cpl_vector_delete(fit_par); fit_par = NULL;
662
663 // update CRPIX if WCS information is available
664 if (cpl_propertylist_has(sub_header_data, CRPIX1) &&
665 cpl_propertylist_has(sub_header_data, CRVAL1) &&
666 cpl_propertylist_has(sub_header_data, CDELT1))
667 {
668 KMO_TRY_EXIT_IF_ERROR(
669 kmclipm_update_property_double(sub_header_data,
670 CRPIX1,
671 crpix1-x1,
672 "[pix] Reference pixel in x"));
673
674 if (desc.ex_noise) {
675 KMO_TRY_EXIT_IF_ERROR(
676 kmclipm_update_property_double(sub_header_noise,
677 CRPIX1,
678 crpix1-x1,
679 "[pix] Reference pixel in x"));
680 }
681 }
682
683 // append fit parameters and errors
684 KMO_TRY_EXIT_IF_ERROR(
685 cpl_propertylist_append(sub_header_data, pl));
686
687 // save data (noise is omitted for the fitted data)
688 ddd = kmclipm_vector_create(cpl_vector_duplicate(data_vec_out));
689 KMO_TRY_EXIT_IF_ERROR(
690 //kmo_dfs_save_vector(ddd, FIT_PROFILE, "_tmp",
691 // sub_header_data, 0./0.));
692 kmclipm_vector_save(ddd, fit_profile_tmp,
693 CPL_BPP_IEEE_FLOAT, sub_header_data, CPL_IO_EXTEND, 0./0.));
694
695 kmclipm_vector_delete(ddd); ddd = NULL;
696
697 // free memory
698 cpl_vector_delete(data_vec_in); data_vec_in = NULL;
699 cpl_vector_delete(data_vec_out); data_vec_out = NULL;
700 cpl_vector_delete(noise_vec_in); noise_vec_in = NULL;
701 cpl_vector_delete(noise_vec2); noise_vec2 = NULL;
702 cpl_vector_delete(lambda_vec); lambda_vec = NULL;
703 cpl_vector_delete(lambda_vec2); lambda_vec2 = NULL;
704 cpl_vector_delete(data_vec2); data_vec2 = NULL;
705 }
706
707 cpl_propertylist_delete(pl); pl = NULL;
708 } else {
709 // invalid IFU, just save sub_headers */
710 KMO_TRY_EXIT_IF_ERROR(
711 //kmo_dfs_save_sub_header(FIT_PROFILE, "_tmp", sub_header_data));
712 cpl_propertylist_save(sub_header_data, fit_profile_tmp, CPL_IO_EXTEND));
713
714 if (desc.ex_noise) {
715 KMO_TRY_EXIT_IF_ERROR(
716 //kmo_dfs_save_sub_header(FIT_PROFILE, "_tmp", sub_header_noise));
717 cpl_propertylist_save(sub_header_data, fit_profile_tmp, CPL_IO_EXTEND));
718 }
719 }
720
721 // free memory
722 cpl_propertylist_delete(sub_header_data); sub_header_data = NULL;
723 cpl_propertylist_delete(sub_header_noise); sub_header_noise = NULL;
724 }
725
726
727 //Update header with QC Param and resave.
728 new_header = kmclipm_propertylist_load(fit_profile_tmp, 0);//kmo_dfs_load_primary_header( frameset, FIT_PROFILE);
729
730 kmclipm_update_property_double(new_header, QC_NR_STARS, nr_stars,
731 "Number of extensions with PRO.FIT.INTENS > 5.");
732
733 frame_final = kmo_dfs_get_frame(frameset, input_tag); // frame_final = kmo_dfs_get_frame(frameset, "0");
734 error |= cpl_frame_set_level(frame_final, CPL_FRAME_LEVEL_FINAL);
735
736 /* load descriptor */
737 KMO_TRY_EXIT_IF_ERROR(
738 kmo_dfs_save_main_header(frameset, FIT_PROFILE, "", frame_final,
739 new_header, parlist, cpl_func));
740 desc = kmo_identify_fits_header(cpl_frame_get_filename(frame_final));
741
742 for (i = 1; i <= nr_devices; i++) {
743
744 if (desc.ex_noise) {
745 devnr = 2*i-1;
746 }
747 else{
748 devnr = i;
749 }
750 valid_ifu = FALSE;
751
752 KMO_TRY_EXIT_IF_NULL(
753 sub_header_data = kmclipm_propertylist_load(fit_profile_tmp, devnr)); // kmo_dfs_load_sub_header(frameset, FIT_PROFILE,
754 //devnr, FALSE));
755 if (desc.ex_noise) {
756 // load noise anyway since we have to save it in the output
757 KMO_TRY_EXIT_IF_NULL(
758 sub_header_noise = kmclipm_propertylist_load(fit_profile_tmp, devnr));//kmo_dfs_load_sub_header(frameset, FIT_PROFILE,
759 // devnr, TRUE));
760 }
761
762 curr_err = cpl_errorstate_get();
763 ocs_name_header = cpl_sprintf("%s%d%s", IFU_NAME_PREFIX, i, IFU_NAME_POSTFIX);
764 ocs_name = cpl_propertylist_get_string(sub_header_data, ocs_name_header);
765 if ((desc.sub_desc[devnr-1].valid_data == TRUE) && (strcmp(ocs_name,"Sky")) && (strcmp(ocs_name,""))) {
766 valid_ifu = TRUE;
767 }
768 cpl_errorstate_set(curr_err);
769
770 if (desc.fits_type == f2i_fits) {
771 data_img_in = NULL;
772 if (valid_ifu) {
773
774 KMO_TRY_EXIT_IF_NULL(
775 data_img_in = kmclipm_image_load(fit_profile_tmp, CPL_TYPE_FLOAT, 0, devnr));//kmo_dfs_load_image(frameset, FIT_PROFILE,
776 // devnr, FALSE, FALSE, NULL));
777 }
778
779 KMO_TRY_EXIT_IF_ERROR(
780 kmo_dfs_save_image(data_img_in, FIT_PROFILE, "",
781 sub_header_data, 0./0.));
782
783
784 }
785 else {
786 kmclipm_vector *ddd = NULL;
787 if (valid_ifu) {
788
789 KMO_TRY_EXIT_IF_NULL(
790 ddd = kmclipm_vector_load(fit_profile_tmp, devnr));//kmo_dfs_load_vector(frameset, FIT_PROFILE,
791 // devnr, FALSE));
792 }
793 KMO_TRY_EXIT_IF_ERROR(
794 kmo_dfs_save_vector(ddd, FIT_PROFILE, "",
795 sub_header_data, 0./0.));
796 kmclipm_vector_delete(ddd); ddd = NULL;
797
798 }
799 if (desc.ex_noise) {
800 KMO_TRY_EXIT_IF_ERROR(
801 kmo_dfs_save_sub_header(FIT_PROFILE, "", sub_header_noise));
802 }
803
804
805 }
806
807
808 //}
809
810
811 }
812 KMO_CATCH
813 {
814 KMO_CATCH_MSG();
815 ret_val = -1;
816 }
817
818 unlink(cpl_sprintf("%s_tmp.fits",FIT_PROFILE));
819
820 kmo_free_fits_desc(&desc);
821 cpl_image_delete(data_img_in); data_img_in = NULL;
822 cpl_image_delete(data_img_in2); data_img_in2 = NULL;
823 cpl_image_delete(data_img_out); data_img_out = NULL;
824 cpl_image_delete(noise_img_in); noise_img_in = NULL;
825 cpl_image_delete(noise_img_in2); noise_img_in2 = NULL;
826 cpl_vector_delete(data_vec_in); data_vec_in = NULL;
827 cpl_vector_delete(data_vec2); data_vec2 = NULL;
828 cpl_vector_delete(data_vec_out); data_vec_out = NULL;
829 cpl_vector_delete(noise_vec_in); noise_vec_in = NULL;
830 cpl_vector_delete(noise_vec2); noise_vec2 = NULL;
831 cpl_vector_delete(lambda_vec); lambda_vec = NULL;
832 cpl_vector_delete(lambda_vec2); lambda_vec2 = NULL;
833 cpl_vector_delete(fit_par); fit_par = NULL;
834 cpl_vector_delete(ranges); ranges = NULL;
835 cpl_vector_delete(ranges2); ranges2 = NULL;
836 cpl_propertylist_delete(sub_header_data); sub_header_data = NULL;
837 cpl_propertylist_delete(sub_header_noise); sub_header_noise = NULL;
838
839 cpl_propertylist_delete(header); header = NULL;
840
841 return ret_val;
842}
843
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.