KMOS Pipeline Reference Manual 4.5.10
kmo_copy.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#define _ISOC99_SOURCE
25#include <math.h>
26#include <string.h>
27
28#include <cpl.h>
29
30#include "kmclipm_constants.h"
31#include "kmclipm_functions.h"
32
33#include "kmo_cpl_extensions.h"
34#include "kmo_utils.h"
35#include "kmo_dfs.h"
36#include "kmo_debug.h"
37#include "kmo_error.h"
38#include "kmo_priv_copy.h"
39
40
41static int kmo_copy_create(cpl_plugin *);
42static int kmo_copy_exec(cpl_plugin *);
43static int kmo_copy_destroy(cpl_plugin *);
44static int kmo_copy(cpl_parameterlist *, cpl_frameset *);
45
46static char kmo_copy_description[] =
47"With this recipe a specified region of an IFU-based cube (F3I), image (F2I) or\n"
48"vector (F1I) can be copied to a new FITS file. One can copy just a plane out\n"
49"of a cube (any orientation) or a vector out of an image etc. By default the\n"
50"operation applies to all IFUs. The input data can contain noise frames which\n"
51"is then copied in the same manner as the input data.\n"
52"It is also possible to extract a specific IFU out of a KMOS FITS structure\n"
53"with 24 IFU extensions or 48 extensions if noise is present.\n"
54"\n"
55"BASIC PARAMETERS:\n"
56"-----------------\n"
57"--ifu\n"
58"Use this parameter to apply the operation to a specific IFU.\n"
59"\n"
60"--x\n"
61"--y\n"
62"--z\n"
63"These are the start values in each dimension. The first pixel is adressed "
64"with 1. \n"
65"\n"
66"--xsize\n"
67"--ysize\n"
68"--zsize\n"
69"These are the extents in each dimension to copy.\n"
70"\n"
71"--autocrop\n"
72"If set to TRUE all borders containing NaN values are cropped. Vectors will be\n"
73"shortened, images and cubes can get smaller. In This special case following\n"
74"parameters can be omitted: --x, --y, --z, --xsize, --ysize and --zsize.\n"
75"\n"
76"Examples:\n"
77"---------\n"
78"extract a cube-section of a cube: \n"
79"esorex kmo_copy --x=3 --y=2 --z=1 --xsize=2 --ysize=3 --zsize=6 copy.sof\n"
80"\n"
81"extract plane:\n"
82"esorex kmo_copy --x=3 --y=2 --z=1 --xsize=2 --ysize=3 copy.sof\n"
83"\n"
84"extract vector just of IFU 4:\n"
85"esorex kmo_copy --x=3 --y=2 --z=1 --ysize=3 --ifu=4 copy.sof\n"
86"\n"
87"extract whole IFU 4:\n"
88"esorex kmo_copy --x=1 --y=1 --z=1 --xsize=<NAXIS1> --ysize=<NAXIS2> \n"
89" --zsize=<NAXIS3> --ifu=4 copy.sof\n"
90"\n"
91"extract scalar:\n"
92"esorex kmo_copy --x=3 --y=2 --z=1 copy.sof\n"
93"\n"
94"with copy.sof:\n"
95"F3I.fits DATA\n"
96"\n"
97"-------------------------------------------------------------------------------\n"
98" Input files:\n"
99"\n"
100" DO KMOS \n"
101" category Type Explanation Required #Frames\n"
102" -------- ----- ----------- -------- -------\n"
103" <none or any> F3I Data cube Y 1 \n"
104" or \n"
105" <none or any> F2I Image \n"
106" or \n"
107" <none or any> F1I Vector \n"
108" (All inputs with or \n"
109" without noise frame) \n"
110"\n"
111" Output files:\n"
112"\n"
113" DO KMOS\n"
114" category Type Explanation\n"
115" -------- ----- -----------\n"
116" COPY F3I or Cropped input data\n"
117" F2I or \n"
118" F1I \n"
119"-------------------------------------------------------------------------------\n"
120"\n";
121
138int cpl_plugin_get_info(cpl_pluginlist *list)
139{
140 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
141 cpl_plugin *plugin = &recipe->interface;
142
143 cpl_plugin_init(plugin,
144 CPL_PLUGIN_API,
145 KMOS_BINARY_VERSION,
146 CPL_PLUGIN_TYPE_RECIPE,
147 "kmo_copy",
148 "Copy a section of a cube to another cube, "
149 "image or spectrum",
150 kmo_copy_description,
151 "Alex Agudo Berbel",
152 "https://support.eso.org/",
153 kmos_get_license(),
154 kmo_copy_create,
155 kmo_copy_exec,
156 kmo_copy_destroy);
157
158 cpl_pluginlist_append(list, plugin);
159
160 return 0;
161}
162
170static int kmo_copy_create(cpl_plugin *plugin)
171{
172 cpl_recipe *recipe;
173 cpl_parameter *p;
174
175 /* Check that the plugin is part of a valid recipe */
176 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
177 recipe = (cpl_recipe *)plugin;
178 else
179 return -1;
180
181 /* Create the parameters list in the cpl_recipe object */
182 recipe->parameters = cpl_parameterlist_new();
183
184 /* Fill the parameters list */
185
186 /* --ifu */
187 p = cpl_parameter_new_value("kmos.kmo_copy.ifu",
188 CPL_TYPE_INT,
189 "Specific IFU to process",
190 "kmos.kmo_copy",
191 -1);
192 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ifu");
193 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
194 cpl_parameterlist_append(recipe->parameters, p);
195
196 /* --autocrop */
197 p = cpl_parameter_new_value("kmos.kmo_copy.autocrop",
198 CPL_TYPE_BOOL,
199 "Crop automatically NaN values at borders",
200 "kmos.kmo_copy",
201 FALSE);
202 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "autocrop");
203 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
204 cpl_parameterlist_append(recipe->parameters, p);
205
206 /* --x, --y, --z */
207 p = cpl_parameter_new_value("kmos.kmo_copy.x",
208 CPL_TYPE_INT,
209 "Start value in first dimension (pixels).",
210 "kmos.kmo_copy",
211 1);
212 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "x");
213 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
214 cpl_parameterlist_append(recipe->parameters, p);
215
216 p = cpl_parameter_new_value("kmos.kmo_copy.y",
217 CPL_TYPE_INT,
218 "Start value in second dimension (pixels).",
219 "kmos.kmo_copy",
220 1);
221 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "y");
222 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
223 cpl_parameterlist_append(recipe->parameters, p);
224
225 p = cpl_parameter_new_value("kmos.kmo_copy.z",
226 CPL_TYPE_INT,
227 "Start value in third dimension (pixels).",
228 "kmos.kmo_copy",
229 1);
230 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "z");
231 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
232 cpl_parameterlist_append(recipe->parameters, p);
233
234 /* --xsize, --ysize, --zsize */
235 p = cpl_parameter_new_value("kmos.kmo_copy.xsize",
236 CPL_TYPE_INT,
237 "Length in first dimension (pixels).",
238 "kmos.kmo_copy",
239 1);
240 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xsize");
241 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
242 cpl_parameterlist_append(recipe->parameters, p);
243
244 p = cpl_parameter_new_value("kmos.kmo_copy.ysize",
245 CPL_TYPE_INT,
246 "Length in second dimension (pixels).",
247 "kmos.kmo_copy",
248 1);
249 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ysize");
250 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
251 cpl_parameterlist_append(recipe->parameters, p);
252
253 p = cpl_parameter_new_value("kmos.kmo_copy.zsize",
254 CPL_TYPE_INT,
255 "Length in third dimension (pixels).",
256 "kmos.kmo_copy",
257 1);
258 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "zsize");
259 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
260 cpl_parameterlist_append(recipe->parameters, p);
261
262 return 0;
263}
264
270static int kmo_copy_exec(cpl_plugin *plugin)
271{
272 cpl_recipe *recipe;
273
274 /* Get the recipe out of the plugin */
275 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
276 recipe = (cpl_recipe *)plugin;
277 else return -1 ;
278
279 return kmo_copy(recipe->parameters, recipe->frames);
280}
281
287static int kmo_copy_destroy(cpl_plugin *plugin)
288{
289 cpl_recipe *recipe;
290
291 /* Get the recipe out of the plugin */
292 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
293 recipe = (cpl_recipe *)plugin;
294 else return -1 ;
295
296 cpl_parameterlist_delete(recipe->parameters);
297 return 0 ;
298}
299
314static int kmo_copy(cpl_parameterlist *parlist, cpl_frameset *frameset)
315{
316 int ret_val = 0,
317 i = 0,
318 x1 = 0,
319 y1 = 0,
320 z1 = 0,
321 x2 = 0,
322 y2 = 0,
323 z2 = 0,
324 xsize = 0,
325 ysize = 0,
326 zsize = 0,
327 ifu = 0,
328 autocrop = 0,
329 nx = 0,
330 ny = 0,
331 nz = 0,
332 allNaN = 0,
333 ix = 0,
334 iy = 0,
335 iz = 0;
336 double crpix1 = 0.,
337 crpix2 = 0.,
338 crpix3 = 0.,
339 crpix1_new = 0.,
340 crpix2_new = 0.,
341 crval1_new = 0.,
342 crval2_new = 0.,
343 crval3 = 0.,
344 cdelt3 = 0.,
345 xshift = 0.,
346 yshift = 0.,
347 crpix3_new = 0.;
348 float *pimg = NULL;
349 cpl_wcs *wcs = NULL;
350 cpl_matrix *phys = NULL,
351 *world = NULL;
352 cpl_array *status = NULL;
353 cpl_propertylist *sub_header = NULL;
354 cpl_imagelist *imglist = NULL,
355 *res_imglist = NULL;
356 cpl_image *img = NULL,
357 *res_img = NULL;
358 kmclipm_vector *vec = NULL,
359 *res_vec = NULL;
360 cpl_frame *frame = NULL;
361 main_fits_desc desc;
362
363 KMO_TRY
364 {
365 kmo_init_fits_desc(&desc);
366
367 /* --- check input --- */
368 KMO_TRY_ASSURE((parlist != NULL) &&
369 (frameset != NULL),
370 CPL_ERROR_NULL_INPUT,
371 "Not all input data is provided!");
372
373 KMO_TRY_ASSURE(cpl_frameset_get_size(frameset) == 1,
374 CPL_ERROR_NULL_INPUT,
375 "A fits-file must be provided!");
376
377 KMO_TRY_EXIT_IF_NULL(
378 frame = kmo_dfs_get_frame(frameset, "0"));
379
380 desc = kmo_identify_fits_header(
381 cpl_frame_get_filename(frame));
382 KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to be "
383 "in KMOS-format!");
384
385 KMO_TRY_ASSURE((desc.fits_type == f1i_fits) ||
386 (desc.fits_type == f2i_fits) ||
387 (desc.fits_type == f3i_fits),
388 CPL_ERROR_ILLEGAL_INPUT,
389 "Input data hasn't correct data type "
390 "(KMOSTYPE must be F1I, F2I or F3I)!");
391
392 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset) == 1,
393 CPL_ERROR_ILLEGAL_INPUT,
394 "Cannot identify RAW and CALIB frames!");
395
396 /* get & check ifu-parameter (optional)*/
397 cpl_msg_info("", "--- Parameter setup for kmo_copy ----------");
398
399 ifu = kmo_dfs_get_parameter_int(parlist, "kmos.kmo_copy.ifu");
400 KMO_TRY_ASSURE((ifu == -1) ||
401 ((ifu >= 0)/* && (ifu <= desc.nr_ext)*/),
402 CPL_ERROR_ILLEGAL_INPUT,
403 "ifu is out of range!");
404 if (ifu != -1) {
405 ix = FALSE;
406 for (i = 0; i < desc.nr_ext; i++) {
407 if (ifu == desc.sub_desc[i].device_nr) {
408 ix = TRUE;
409 }
410 }
411 KMO_TRY_ASSURE(ix == TRUE,
412 CPL_ERROR_ILLEGAL_INPUT,
413 "ifu #%d doesn't exist in this frame!", ifu);
414 }
415
416 KMO_TRY_EXIT_IF_ERROR(
417 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_copy.ifu"));
418
419 autocrop = kmo_dfs_get_parameter_bool(parlist, "kmos.kmo_copy.autocrop");
420 KMO_TRY_ASSURE((autocrop == TRUE) || (autocrop == FALSE),
421 CPL_ERROR_ILLEGAL_INPUT,
422 "autocrop must be TZRUE or FALSE!");
423 KMO_TRY_EXIT_IF_ERROR(
424 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_copy.autocrop"));
425
426 if (!autocrop) {
427 /* get & check x-, y-, z-parameters (mandatory)*/
428 x1 = kmo_dfs_get_parameter_int(parlist, "kmos.kmo_copy.x");
429
430 KMO_TRY_ASSURE(x1 > 0,
431 CPL_ERROR_ILLEGAL_INPUT,
432 "x is smaller than 1!");
433
434 KMO_TRY_ASSURE(x1 <= desc.naxis1,
435 CPL_ERROR_ILLEGAL_INPUT,
436 "x is larger than corresponding dimension of "
437 "input data cube!");
438 KMO_TRY_EXIT_IF_ERROR(
439 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_copy.x"));
440
441 if ((desc.fits_type == f2i_fits) || (desc.fits_type == f3i_fits)) {
442 y1 = kmo_dfs_get_parameter_int(parlist, "kmos.kmo_copy.y");
443
444 KMO_TRY_ASSURE(y1 > 0,
445 CPL_ERROR_ILLEGAL_INPUT,
446 "y is smaller than 1!");
447
448 KMO_TRY_ASSURE(y1 <= desc.naxis2,
449 CPL_ERROR_ILLEGAL_INPUT,
450 "y is larger than corresponding dimension of "
451 "input data cube!");
452 KMO_TRY_EXIT_IF_ERROR(
453 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_copy.y"));
454
455 if (desc.fits_type == f3i_fits) {
456 z1 = kmo_dfs_get_parameter_int(parlist, "kmos.kmo_copy.z");
457
458 KMO_TRY_ASSURE(z1 > 0,
459 CPL_ERROR_ILLEGAL_INPUT,
460 "z is smaller than 1!");
461
462 KMO_TRY_ASSURE(z1 <= desc.naxis3,
463 CPL_ERROR_ILLEGAL_INPUT,
464 "z is larger than corresponding dimension of "
465 "input data cube!");
466 KMO_TRY_EXIT_IF_ERROR(
467 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_copy.z"));
468 }
469 }
470
471 /* get & check x2-, y2-, z2-parameters (optional) */
472 xsize = kmo_dfs_get_parameter_int(parlist, "kmos.kmo_copy.xsize");
473
474 KMO_TRY_ASSURE(xsize > 0,
475 CPL_ERROR_ILLEGAL_INPUT,
476 "xsize is smaller than 1!");
477 KMO_TRY_EXIT_IF_ERROR(
478 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_copy.xsize"));
479
480 x2 = x1 - 1 + xsize;
481
482 KMO_TRY_ASSURE(x2 > 0,
483 CPL_ERROR_ILLEGAL_INPUT,
484 "End value in 1st dimension smaller than 0!");
485
486 KMO_TRY_ASSURE(x2 <= desc.naxis1,
487 CPL_ERROR_ILLEGAL_INPUT,
488 "xsize is too large (xsize <= %d)",
489 desc.naxis1 - x1 + 1);
490
491 if ((desc.fits_type == f2i_fits) || (desc.fits_type == f3i_fits)) {
492 ysize = kmo_dfs_get_parameter_int(parlist, "kmos.kmo_copy.ysize");
493
494 KMO_TRY_ASSURE(ysize > 0,
495 CPL_ERROR_ILLEGAL_INPUT,
496 "ysize is smaller than 1!");
497 KMO_TRY_EXIT_IF_ERROR(
498 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_copy.ysize"));
499
500 y2 = y1 - 1 + ysize;
501
502 KMO_TRY_ASSURE(y2 > 0,
503 CPL_ERROR_ILLEGAL_INPUT,
504 "End value in 2nd dimension smaller than 0!");
505
506 KMO_TRY_ASSURE(y2 <= desc.naxis2,
507 CPL_ERROR_ILLEGAL_INPUT,
508 "ysize is too large (ysize <= %d)",
509 desc.naxis2 - y1 + 1);
510
511 if (desc.fits_type == f3i_fits) {
512 zsize = kmo_dfs_get_parameter_int(parlist,
513 "kmos.kmo_copy.zsize");
514
515 KMO_TRY_ASSURE(zsize > 0,
516 CPL_ERROR_ILLEGAL_INPUT,
517 "zsize is smaller than 1!");
518
519 KMO_TRY_EXIT_IF_ERROR(
520 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_copy.zsize"));
521
522 z2 = z1 - 1 + zsize;
523
524 KMO_TRY_ASSURE(z2 > 0,
525 CPL_ERROR_ILLEGAL_INPUT,
526 "End value in 3rd dimension smaller than 0!");
527
528 KMO_TRY_ASSURE(z2 <= desc.naxis3,
529 CPL_ERROR_ILLEGAL_INPUT,
530 "zsize is too large (zsize <= %d)",
531 desc.naxis3 - z1 + 1);
532 }
533 }
534 KMO_TRY_CHECK_ERROR_STATE();
535 }
536
537 cpl_msg_info("", "-------------------------------------------");
538
539 /* --- load, update & save primary header --- */
540 KMO_TRY_EXIT_IF_ERROR(
541 kmo_dfs_save_main_header(frameset, COPY, "", frame, NULL, parlist, cpl_func));
542
543 //
544 // --- copy data ----
545 //
546 for (i = 0; i < desc.nr_ext; i++) {
547 if ((ifu == desc.sub_desc[i].device_nr) ||
548 (ifu == -1)) {
549
550 KMO_TRY_EXIT_IF_NULL(
551 sub_header = kmo_dfs_load_sub_header(frameset,
552 "0",
553 desc.sub_desc[i].device_nr,
554 desc.sub_desc[i].is_noise));
555
556 //
557 // --- IFU is valid -> copy header and data ---
558 //
559 if (desc.sub_desc[i].valid_data == TRUE) {
560
561 switch (desc.fits_type) {
562 case f1i_fits:
563 KMO_TRY_EXIT_IF_NULL(
564 vec = kmo_dfs_load_vector(frameset,
565 "0",
566 desc.sub_desc[i].device_nr,
567 desc.sub_desc[i].is_noise));
568
569 if (autocrop && !desc.sub_desc[i].is_noise) {
570 x1 = 1;
571 x2 = kmclipm_vector_get_size(vec);
572 while (kmclipm_vector_is_rejected(vec, x1-1)) {
573 x1++;
574 }
575 while (kmclipm_vector_is_rejected(vec, x2-1)) {
576 x2--;
577 }
578
579 if (x1 > x2) {
580 /* invalid IFU, just save sub_header */
581 KMO_TRY_EXIT_IF_ERROR(
582 kmo_dfs_save_sub_header(COPY, "",
583 sub_header));
584 continue; // with next IFU
585 }
586 }
587
588 // extract scalar (F1I)
589 if ((x1 == x2) || (x2 == INT_MIN))
590 {
591 KMO_TRY_EXIT_IF_NULL(
592 res_vec = kmclipm_vector_new(1));
593
594 KMO_TRY_EXIT_IF_ERROR(
595 kmclipm_vector_set(res_vec, 0,
596 kmo_copy_scalar_F1I(vec, x1)));
597 }
598 // extract x-vector (F1I)
599 else if ((x2!= INT_MIN) && (x1 != x2))
600 {
601 KMO_TRY_EXIT_IF_NULL(
602 res_vec = kmo_copy_vector_F1I(vec, x1, x2));
603 }
604
605 kmclipm_vector_delete(vec); vec = NULL;
606
607 break;
608 case f2i_fits:
609 KMO_TRY_EXIT_IF_NULL(
610 img = kmo_dfs_load_image(frameset,
611 "0",
612 desc.sub_desc[i].device_nr,
613 desc.sub_desc[i].is_noise, FALSE, NULL));
614
615 if (autocrop && !desc.sub_desc[i].is_noise) {
616 nx = cpl_image_get_size_x(img);
617 ny = cpl_image_get_size_y(img);
618 x1 = 1;
619 x2 = nx;
620 y1 = 1;
621 y2 = ny;
622
623 KMO_TRY_EXIT_IF_NULL(
624 pimg = cpl_image_get_data_float(img));
625
626 allNaN = TRUE;
627 while (allNaN) {
628 for (iy = 0; iy < ny; iy++) {
629 if(!isnan(pimg[x1-1+iy*nx])) {
630 allNaN = FALSE;
631 break;
632 }
633 }
634 if (allNaN) {
635 x1++;
636 }
637 }
638
639 allNaN = TRUE;
640 while (allNaN) {
641 for (iy = 0; iy < ny; iy++) {
642 if(!isnan(pimg[x2-1+iy*nx])) {
643 allNaN = FALSE;
644 break;
645 }
646 }
647 if (allNaN) {
648 x2--;
649 }
650 }
651
652 allNaN = TRUE;
653 while (allNaN) {
654 for (ix = 0; ix < nx; ix++) {
655 if(!isnan(pimg[ix+(y1-1)*nx])) {
656 allNaN = FALSE;
657 break;
658 }
659 }
660 if (allNaN) {
661 y1++;
662 }
663 }
664
665 allNaN = TRUE;
666 while (allNaN) {
667 for (ix = 0; ix < nx; ix++) {
668 if(!isnan(pimg[ix+(y2-1)*nx])) {
669 allNaN = FALSE;
670 break;
671 }
672 }
673 if (allNaN) {
674 y2--;
675 }
676 }
677
678 if ((x1 > x2) || (y1 > y2)) {
679 /* invalid IFU, just save sub_header */
680 KMO_TRY_EXIT_IF_ERROR(
681 kmo_dfs_save_sub_header(COPY, "",
682 sub_header));
683 continue; // with next IFU
684 }
685 }
686
687 // extract scalar (F2I)
688 if (((x1 == x2) || (x2 == INT_MIN)) &&
689 ((y1 == y2) || (y2 == INT_MIN)))
690 {
691 KMO_TRY_EXIT_IF_NULL(
692 res_vec = kmclipm_vector_new(1));
693
694 KMO_TRY_EXIT_IF_ERROR(
695 kmclipm_vector_set(res_vec, 0,
696 kmo_copy_scalar_F2I(img, x1, y1)));
697 }
698 // extract x-vector (F2I)
699 else if (((y1 == y2) || (y2 == INT_MIN)) &&
700 (x2 != INT_MIN) &&
701 (x1 != x2))
702 {
703 KMO_TRY_EXIT_IF_NULL(
704 res_vec = kmo_copy_vector_F2I_x(img,
705 x1, x2, y1));
706 }
707 // extract y-vector (F2I)
708 else if (((x1 == x2) || (x2 == INT_MIN)) &&
709 (y2 != INT_MIN) &&
710 (y1 != y2))
711 {
712 KMO_TRY_EXIT_IF_NULL(
713 res_vec = kmo_copy_vector_F2I_y(img,
714 x1, y1, y2));
715 }
716 // extract plane (F2I)
717 else if ((x2 != INT_MIN) && (x1 != x2) &&
718 (y2 != INT_MIN) && (y1 != y2))
719 {
720 KMO_TRY_EXIT_IF_NULL(
721 res_img = kmo_copy_image_F2I(img,
722 x1, x2, y1, y2));
723 }
724
725 cpl_image_delete(img); img = NULL;
726
727 break;
728 case f3i_fits:
729 KMO_TRY_EXIT_IF_NULL(
730 imglist = kmo_dfs_load_cube(frameset,
731 "0",
732 desc.sub_desc[i].device_nr,
733 desc.sub_desc[i].is_noise));
734
735 if (autocrop && !desc.sub_desc[i].is_noise) {
736 img = cpl_imagelist_get(imglist, 0);
737 nx = cpl_image_get_size_x(img);
738 ny = cpl_image_get_size_y(img);
739 nz = cpl_imagelist_get_size(imglist);
740 x1 = 1;
741 x2 = nx;
742 y1 = 1;
743 y2 = ny;
744 z1 = 1;
745 z2 = nz;
746
747 while (kmo_image_get_rejected(img) == nx*ny) {
748 z1++;
749 img = cpl_imagelist_get(imglist, z1-1);
750 }
751
752 img = cpl_imagelist_get(imglist, z2-1);
753 while (kmo_image_get_rejected(img) == nx*ny) {
754 z2--;
755 img = cpl_imagelist_get(imglist, z2-1);
756 }
757
758 allNaN = TRUE;
759 while (allNaN) {
760 for (iz = z1-1; iz < z2; iz++) {
761 img = cpl_imagelist_get(imglist, iz);
762 KMO_TRY_EXIT_IF_NULL(
763 pimg = cpl_image_get_data_float(img));
764 if (allNaN == FALSE) {
765 break;
766 }
767 for (iy = 0; iy < ny; iy++) {
768 if(!isnan(pimg[x1-1+iy*nx])) {
769 allNaN = FALSE;
770 break;
771 }
772 }
773 }
774 if (allNaN) {
775 x1++;
776 }
777 }
778
779 allNaN = TRUE;
780 while (allNaN) {
781 for (iz = z1-1; iz < z2; iz++) {
782 img = cpl_imagelist_get(imglist, iz);
783 KMO_TRY_EXIT_IF_NULL(
784 pimg = cpl_image_get_data_float(img));
785 if (allNaN == FALSE) {
786 break;
787 }
788 for (iy = 0; iy < ny; iy++) {
789 if(!isnan(pimg[x2-1+iy*nx])) {
790 allNaN = FALSE;
791 break;
792 }
793 }
794 }
795 if (allNaN) {
796 x2--;
797 }
798 }
799
800 allNaN = TRUE;
801 while (allNaN) {
802 for (iz = z1-1; iz < z2; iz++) {
803 img = cpl_imagelist_get(imglist, iz);
804 KMO_TRY_EXIT_IF_NULL(
805 pimg = cpl_image_get_data_float(img));
806 if (allNaN == FALSE) {
807 break;
808 }
809 for (ix = 0; ix < nx; ix++) {
810 if(!isnan(pimg[ix+(y1-1)*nx])) {
811 allNaN = FALSE;
812 break;
813 }
814 }
815 }
816 if (allNaN) {
817 y1++;
818 }
819 }
820
821 allNaN = TRUE;
822 while (allNaN) {
823 for (iz = z1-1; iz < z2; iz++) {
824 img = cpl_imagelist_get(imglist, iz);
825 KMO_TRY_EXIT_IF_NULL(
826 pimg = cpl_image_get_data_float(img));
827 if (allNaN == FALSE) {
828 break;
829 }
830 for (ix = 0; ix < nx; ix++) {
831 if(!isnan(pimg[ix+(y2-1)*nx])) {
832 allNaN = FALSE;
833 break;
834 }
835 }
836 }
837 if (allNaN) {
838 y2--;
839 }
840 }
841
842 img = NULL;
843
844 if ((x1 > x2) || (y1 > y2) || (z1 > z2)) {
845 /* invalid IFU, just save sub_header */
846 KMO_TRY_EXIT_IF_ERROR(
847 kmo_dfs_save_sub_header(COPY, "",
848 sub_header));
849 continue; // with next IFU
850 }
851 }
852
853 // extract scalar (F3I)
854 if (((x1 == x2) || (x2 == INT_MIN)) &&
855 ((y1 == y2) || (y2 == INT_MIN)) &&
856 ((z1 == z2) || (z2 == INT_MIN)))
857 {
858 KMO_TRY_EXIT_IF_NULL(
859 res_vec = kmclipm_vector_new(1));
860
861 KMO_TRY_EXIT_IF_ERROR(
862 kmclipm_vector_set(res_vec, 0,
863 kmo_copy_scalar_F3I(imglist, x1, y1, z1)));
864 }
865 // extract x-vector (F3I)
866 else if ((x2 != INT_MIN) && (x1 != x2) &&
867 ((y1 == y2) || (y2 == INT_MIN)) &&
868 ((z1 == z2) || (z2 == INT_MIN)))
869 {
870 KMO_TRY_EXIT_IF_NULL(
871 res_vec = kmo_copy_vector_F3I_x(imglist,
872 x1, x2, y1, z1));
873 }
874 // extract y-vector (F3I)
875 else if (((x1 == x2) || (x2 == INT_MIN)) &&
876 (y2!= INT_MIN) && (y1 != y2) &&
877 ((z1 == z2) || (z2 == INT_MIN)))
878 {
879 KMO_TRY_EXIT_IF_NULL(
880 res_vec = kmo_copy_vector_F3I_y(imglist,
881 x1, y1, y2, z1));
882 }
883 // extract z-vector (F3I)
884 else if (((x1 == x2) || (x2 == INT_MIN)) &&
885 ((y1 == y2) || (y2 == INT_MIN)) &&
886 (z2 != INT_MIN) && (z1 != z2))
887 {
888 KMO_TRY_EXIT_IF_NULL(
889 res_vec = kmo_copy_vector_F3I_z(imglist,
890 x1, y1, z1, z2));
891 }
892 // extract x-plane (F3I)
893 else if (((x1 == x2) || (x2 == INT_MIN)) &&
894 (y2 != INT_MIN) && (y1 != y2) &&
895 (z2 != INT_MIN) && (z1 != z2))
896 {
897 KMO_TRY_EXIT_IF_NULL(
898 res_img = kmo_copy_image_F3I_x(imglist,
899 x1, y1, y2, z1, z2));
900 }
901 // extract y-plane (F3I)
902 else if ((x2 != INT_MIN) && (x1 != x2) &&
903 ((y1 == y2) || (y2 == INT_MIN)) &&
904 (z2 != INT_MIN) && (z1 != z2))
905 {
906 KMO_TRY_EXIT_IF_NULL(
907 res_img = kmo_copy_image_F3I_y(imglist,
908 x1, x2, y1, z1, z2));
909 }
910 // extract z-plane (F3I)
911 else if ((x2 != INT_MIN) && (x1 != x2) &&
912 (y2 != INT_MIN) && (y1 != y2) &&
913 ((z1 == z2) || (z2 == INT_MIN)))
914 {
915 KMO_TRY_EXIT_IF_NULL(
916 res_img = kmo_copy_image_F3I_z(imglist,
917 x1, x2, y1, y2, z1));
918 }
919 // extract cube (F3I)
920 else if ((x2!= INT_MIN) && (x1 != x2) &&
921 (y2!= INT_MIN) && (y1 != y2) &&
922 (z2!= INT_MIN) && (z1 != z2))
923 {
924 KMO_TRY_EXIT_IF_NULL(
925 res_imglist = kmo_copy_cube_F3I(imglist,
926 x1, x2, y1, y2, z1, z2));
927 }
928
929 cpl_imagelist_delete(imglist); imglist = NULL;
930
931 break;
932 default:
933 break;
934 }
935
936 //
937 // --- save and delete copied data, delete sub-header ---
938 //
939 if (res_vec != NULL) {
940 KMO_TRY_EXIT_IF_ERROR(
941 kmclipm_update_property_double(sub_header,
942 CRPIX1,
943 1,
944 "[pix] Reference pixel in x"));
945 KMO_TRY_EXIT_IF_ERROR(
946 kmclipm_update_property_double(sub_header,
947 CRVAL1,
948 1,
949 "[um] Wavelength at ref. pixel"));
950 KMO_TRY_EXIT_IF_ERROR(
951 kmclipm_update_property_double(sub_header,
952 CDELT1,
953 1,
954 "[um] Spectral resolution"));
955 if (cpl_propertylist_has(sub_header, CUNIT1)) {
956 KMO_TRY_EXIT_IF_ERROR(
957 kmclipm_update_property_string(
958 sub_header,
959 CUNIT1,
960 "",
961 ""));
962 }
963
964 KMO_TRY_EXIT_IF_ERROR(
965 kmclipm_update_property_string(
966 sub_header,
967 CTYPE1,
968 "",
969 "Coordinate system of x-axis"));
970
971 // going to save vector extracted from cube along lambda-axis
972 // (put dim3 keywords into dim1-keywords)
973 if ((desc.fits_type == f3i_fits) &&
974 (cpl_propertylist_has(sub_header, CRPIX3)) &&
975 (cpl_propertylist_has(sub_header, CRVAL3)) &&
976 ((x1 == x2) && (y1 == y2)))
977 {
978 crpix3 = cpl_propertylist_get_double(sub_header,
979 CRPIX3);
980 crval3 = cpl_propertylist_get_double(sub_header,
981 CRVAL3);
982 cdelt3 = cpl_propertylist_get_double(sub_header,
983 CDELT3);
984 KMO_TRY_CHECK_ERROR_STATE();
985
986 // update WCS in z-direction, because starting point
987 // isn't 1 anymore
988 if (z1 != 1)
989 {
990 crpix3 = crpix3 - z1 + 1;
991 }
992
993 KMO_TRY_EXIT_IF_ERROR(
994 kmclipm_update_property_double(sub_header,
995 CRPIX1,
996 crpix3,
997 "[pix] Reference pixel in x"));
998 KMO_TRY_EXIT_IF_ERROR(
999 kmclipm_update_property_double(sub_header,
1000 CRVAL1,
1001 crval3,
1002 "[um] Wavelength at ref. pixel"));
1003 KMO_TRY_EXIT_IF_ERROR(
1004 kmclipm_update_property_double(sub_header,
1005 CDELT1,
1006 cdelt3,
1007 "[um] Spectral resolution"));
1008 if (cpl_propertylist_has(sub_header, CUNIT3)) {
1009 KMO_TRY_EXIT_IF_ERROR(
1010 kmclipm_update_property_string(
1011 sub_header,
1012 CUNIT1,
1013 cpl_propertylist_get_string(sub_header,
1014 CUNIT3),
1015 cpl_propertylist_get_comment(sub_header,
1016 CUNIT3)));
1017 }
1018
1019 KMO_TRY_EXIT_IF_ERROR(
1020 kmclipm_update_property_string(
1021 sub_header,
1022 CTYPE1,
1023 cpl_propertylist_get_string(
1024 sub_header,
1025 CTYPE3),
1026 "Coordinate system of x-axis"));
1027 }
1028 if (cpl_propertylist_has(sub_header, CRPIX2))
1029 cpl_propertylist_erase(sub_header, CRPIX2);
1030 if (cpl_propertylist_has(sub_header, CRVAL2))
1031 cpl_propertylist_erase(sub_header, CRVAL2);
1032 if (cpl_propertylist_has(sub_header, CDELT2))
1033 cpl_propertylist_erase(sub_header, CDELT2);
1034 if (cpl_propertylist_has(sub_header, CTYPE2))
1035 cpl_propertylist_erase(sub_header, CTYPE2);
1036 if (cpl_propertylist_has(sub_header, CUNIT2))
1037 cpl_propertylist_erase(sub_header, CUNIT2);
1038 if (cpl_propertylist_has(sub_header, CRPIX3))
1039 cpl_propertylist_erase(sub_header, CRPIX3);
1040 if (cpl_propertylist_has(sub_header, CRVAL3))
1041 cpl_propertylist_erase(sub_header, CRVAL3);
1042 if (cpl_propertylist_has(sub_header, CDELT3))
1043 cpl_propertylist_erase(sub_header, CDELT3);
1044 if (cpl_propertylist_has(sub_header, CTYPE3))
1045 cpl_propertylist_erase(sub_header, CTYPE3);
1046 if (cpl_propertylist_has(sub_header, CUNIT3))
1047 cpl_propertylist_erase(sub_header, CUNIT3);
1048 if (cpl_propertylist_has(sub_header, CD1_1))
1049 cpl_propertylist_erase(sub_header, CD1_1);
1050 if (cpl_propertylist_has(sub_header, CD1_2))
1051 cpl_propertylist_erase(sub_header, CD1_2);
1052 if (cpl_propertylist_has(sub_header, CD1_3))
1053 cpl_propertylist_erase(sub_header, CD1_3);
1054 if (cpl_propertylist_has(sub_header, CD2_1))
1055 cpl_propertylist_erase(sub_header, CD2_1);
1056 if (cpl_propertylist_has(sub_header, CD2_2))
1057 cpl_propertylist_erase(sub_header, CD2_2);
1058 if (cpl_propertylist_has(sub_header, CD2_3))
1059 cpl_propertylist_erase(sub_header, CD2_3);
1060 if (cpl_propertylist_has(sub_header, CD3_1))
1061 cpl_propertylist_erase(sub_header, CD3_1);
1062 if (cpl_propertylist_has(sub_header, CD3_2))
1063 cpl_propertylist_erase(sub_header, CD3_2);
1064 if (cpl_propertylist_has(sub_header, CD3_3))
1065 cpl_propertylist_erase(sub_header, CD3_3);
1066 KMO_TRY_EXIT_IF_ERROR(
1067 kmo_dfs_save_vector(res_vec, COPY, "",
1068 sub_header, 0./0.));
1069
1070 kmclipm_vector_delete(res_vec); res_vec = NULL;
1071 } else if (res_img != NULL) {
1072 // going to save image extracted from cube along lambda-axis
1073 // (put dim3 keywords into dim1-keywords)
1074 if ((desc.fits_type == f3i_fits) &&
1075 (cpl_propertylist_has(sub_header, CRPIX3)) &&
1076 (cpl_propertylist_has(sub_header, CRVAL3)) &&
1077 ((x1 == x2) || (y1 == y2)))
1078 {
1079 crpix3 = cpl_propertylist_get_double(sub_header,
1080 CRPIX3);
1081 crval3 = cpl_propertylist_get_double(sub_header,
1082 CRVAL3);
1083 cdelt3 = cpl_propertylist_get_double(sub_header,
1084 CDELT3);
1085 KMO_TRY_CHECK_ERROR_STATE();
1086
1087 // update WCS in z-direction, because starting point
1088 // isn't 1 anymore
1089 if (z1 != 1)
1090 {
1091 crpix3 = crpix3 - z1 + 1;
1092 }
1093
1094 KMO_TRY_EXIT_IF_ERROR(
1095 kmclipm_update_property_double(sub_header,
1096 CRPIX1,
1097 crpix3,
1098 "[pix] Reference pixel in x"));
1099 KMO_TRY_EXIT_IF_ERROR(
1100 kmclipm_update_property_double(sub_header,
1101 CRPIX2,
1102 1,
1103 "[pix] Reference pixel in y"));
1104 KMO_TRY_EXIT_IF_ERROR(
1105 kmclipm_update_property_double(sub_header,
1106 CRVAL1,
1107 crval3,
1108 "[um] Wavelength at ref. pixel"));
1109 KMO_TRY_EXIT_IF_ERROR(
1110 kmclipm_update_property_double(sub_header,
1111 CRVAL2,
1112 1,
1113 "[pix]"));
1114 KMO_TRY_EXIT_IF_ERROR(
1115 kmclipm_update_property_double(sub_header,
1116 CDELT1,
1117 cdelt3,
1118 "[um] Spectral resolution"));
1119 KMO_TRY_EXIT_IF_ERROR(
1120 kmclipm_update_property_double(sub_header,
1121 CDELT2,
1122 1,
1123 "[pix]"));
1124 if (cpl_propertylist_has(sub_header, CUNIT3)) {
1125 KMO_TRY_EXIT_IF_ERROR(
1126 kmclipm_update_property_string(
1127 sub_header,
1128 CUNIT1,
1129 cpl_propertylist_get_string(sub_header,
1130 CUNIT3),
1131 cpl_propertylist_get_comment(sub_header,
1132 CUNIT3)));
1133 }
1134
1135 KMO_TRY_EXIT_IF_ERROR(
1136 kmclipm_update_property_string(
1137 sub_header,
1138 CTYPE1,
1139 cpl_propertylist_get_string(
1140 sub_header,
1141 CTYPE3),
1142 "Coordinate system of x-axis"));
1143
1144 KMO_TRY_EXIT_IF_ERROR(
1145 kmclipm_update_property_string(
1146 sub_header,
1147 CTYPE2,
1148 "",
1149 "Coordinate system of y-axis"));
1150 if (cpl_propertylist_has(sub_header, CD1_1))
1151 cpl_propertylist_erase(sub_header, CD1_1);
1152 if (cpl_propertylist_has(sub_header, CD1_2))
1153 cpl_propertylist_erase(sub_header, CD1_2);
1154 if (cpl_propertylist_has(sub_header, CD2_1))
1155 cpl_propertylist_erase(sub_header, CD2_1);
1156 if (cpl_propertylist_has(sub_header, CD2_2))
1157 cpl_propertylist_erase(sub_header, CD2_2);
1158 }
1159
1160 // erase any still existing 3rd-dimension keywords
1161 if (cpl_propertylist_has(sub_header, CRPIX3))
1162 cpl_propertylist_erase(sub_header, CRPIX3);
1163 if (cpl_propertylist_has(sub_header, CRVAL3))
1164 cpl_propertylist_erase(sub_header, CRVAL3);
1165 if (cpl_propertylist_has(sub_header, CDELT3))
1166 cpl_propertylist_erase(sub_header, CDELT3);
1167 if (cpl_propertylist_has(sub_header, CTYPE3))
1168 cpl_propertylist_erase(sub_header, CTYPE3);
1169 if (cpl_propertylist_has(sub_header, CUNIT3))
1170 cpl_propertylist_erase(sub_header, CUNIT3);
1171 if (cpl_propertylist_has(sub_header, CD1_3))
1172 cpl_propertylist_erase(sub_header, CD1_3);
1173 if (cpl_propertylist_has(sub_header, CD2_3))
1174 cpl_propertylist_erase(sub_header, CD2_3);
1175 if (cpl_propertylist_has(sub_header, CD3_1))
1176 cpl_propertylist_erase(sub_header, CD3_1);
1177 if (cpl_propertylist_has(sub_header, CD3_2))
1178 cpl_propertylist_erase(sub_header, CD3_2);
1179 if (cpl_propertylist_has(sub_header, CD3_3))
1180 cpl_propertylist_erase(sub_header, CD3_3);
1181
1182
1183 // update WCS in x- and y-direction because it got smaller
1184 if ((desc.fits_type == f3i_fits) &&
1185 (desc.fits_type == f2i_fits) &&
1186 (cpl_propertylist_has(sub_header, CRPIX1)) &&
1187 (cpl_propertylist_has(sub_header, CRPIX2)) &&
1188 ((x1 != 1) || (y1 != 1)))
1189 {
1190 KMO_TRY_EXIT_IF_ERROR(
1191 kmclipm_update_property_int(sub_header,
1192 NAXIS,
1193 2,
1194 ""));
1195 cpl_propertylist_erase(sub_header, NAXIS3);
1196
1197 crpix1 = cpl_propertylist_get_double(sub_header,
1198 CRPIX1);
1199 crpix2 = cpl_propertylist_get_double(sub_header,
1200 CRPIX2);
1201 KMO_TRY_CHECK_ERROR_STATE();
1202 crpix3 = 1;
1203 KMO_TRY_CHECK_ERROR_STATE();
1204
1205 xshift = x1 - 1;
1206 yshift = y1 - 1;
1207
1208 crpix1_new = crpix1 - xshift;
1209 crpix2_new = crpix2 - yshift;
1210
1211 phys = cpl_matrix_new (2, 2);
1212 cpl_matrix_set(phys, 0, 0, crpix1);
1213 cpl_matrix_set(phys, 0, 1, crpix2);
1214 cpl_matrix_set(phys, 1, 0, crpix1_new);
1215 cpl_matrix_set(phys, 1, 1, crpix2_new);
1216
1217 KMO_TRY_EXIT_IF_NULL(
1218 wcs = cpl_wcs_new_from_propertylist(sub_header));
1219
1220 KMO_TRY_EXIT_IF_ERROR(
1221 cpl_wcs_convert(wcs, phys, &world, &status,
1222 CPL_WCS_PHYS2WORLD));
1223
1224 crval1_new = cpl_matrix_get(world, 1, 0);
1225 crval2_new = cpl_matrix_get(world, 1, 1);
1226 crpix1_new = crpix1-2*xshift;
1227 crpix2_new = crpix2-2*yshift;
1228
1229 // update WCS
1230 KMO_TRY_EXIT_IF_ERROR(
1231 kmclipm_update_property_double(sub_header,
1232 CRPIX1,
1233 crpix1_new,
1234 "[pix] Reference pixel in x"));
1235 KMO_TRY_EXIT_IF_ERROR(
1236 kmclipm_update_property_double(sub_header,
1237 CRPIX2,
1238 crpix2_new,
1239 "[pix] Reference pixel in y"));
1240 KMO_TRY_EXIT_IF_ERROR(
1241 kmclipm_update_property_double(sub_header,
1242 CRVAL1,
1243 crval1_new,
1244 "[deg] RA at ref. pixel"));
1245 KMO_TRY_EXIT_IF_ERROR(
1246 kmclipm_update_property_double(sub_header,
1247 CRVAL2,
1248 crval2_new,
1249 "[deg] DEC at ref. pixel"));
1250
1251 cpl_matrix_delete(phys); phys = NULL;
1252 cpl_matrix_delete(world); world = NULL;
1253 cpl_array_delete(status); status = NULL;
1254 cpl_wcs_delete(wcs); wcs = NULL;
1255 }
1256
1257 KMO_TRY_EXIT_IF_ERROR(
1258 kmo_dfs_save_image(res_img, COPY, "", sub_header, 0./0.));
1259 cpl_image_delete(res_img); res_img = NULL;
1260 } else if (res_imglist != NULL) {
1261 // update WCS in x- and y-direction because it got smaller
1262 if ((desc.fits_type == f3i_fits) &&
1263 (cpl_propertylist_has(sub_header, CRPIX1)) &&
1264 (cpl_propertylist_has(sub_header, CRPIX2)) &&
1265 ((x1 != 1) || (y1 != 1)))
1266 {
1267 crpix1 = cpl_propertylist_get_double(sub_header,
1268 CRPIX1);
1269 crpix2 = cpl_propertylist_get_double(sub_header,
1270 CRPIX2);
1271 crpix3 = cpl_propertylist_get_double(sub_header,
1272 CRPIX3);
1273 KMO_TRY_CHECK_ERROR_STATE();
1274
1275 xshift = x1 - 1;
1276 yshift = y1 - 1;
1277
1278 crpix1_new = crpix1 - xshift;
1279 crpix2_new = crpix2 - yshift;
1280
1281 phys = cpl_matrix_new (2, 3);
1282 cpl_matrix_set(phys, 0, 0, crpix1);
1283 cpl_matrix_set(phys, 0, 1, crpix2);
1284 cpl_matrix_set(phys, 0, 2, crpix3);
1285 cpl_matrix_set(phys, 1, 0, crpix1_new);
1286 cpl_matrix_set(phys, 1, 1, crpix2_new);
1287 cpl_matrix_set(phys, 1, 2, crpix3);
1288
1289 KMO_TRY_EXIT_IF_NULL(
1290 wcs = cpl_wcs_new_from_propertylist(sub_header));
1291
1292 KMO_TRY_EXIT_IF_ERROR(
1293 cpl_wcs_convert(wcs, phys, &world, &status,
1294 CPL_WCS_PHYS2WORLD));
1295
1296 crval1_new = cpl_matrix_get(world, 1, 0);
1297 crval2_new = cpl_matrix_get(world, 1, 1);
1298 crpix1_new = crpix1-2*xshift;
1299 crpix2_new = crpix2-2*yshift;
1300
1301 // update WCS
1302 KMO_TRY_EXIT_IF_ERROR(
1303 kmclipm_update_property_double(sub_header,
1304 CRPIX1,
1305 crpix1_new,
1306 "[pix] Reference pixel in x"));
1307 KMO_TRY_EXIT_IF_ERROR(
1308 kmclipm_update_property_double(sub_header,
1309 CRPIX2,
1310 crpix2_new,
1311 "[pix] Reference pixel in y"));
1312 KMO_TRY_EXIT_IF_ERROR(
1313 kmclipm_update_property_double(sub_header,
1314 CRVAL1,
1315 crval1_new,
1316 "[deg] RA at ref. pixel"));
1317 KMO_TRY_EXIT_IF_ERROR(
1318 kmclipm_update_property_double(sub_header,
1319 CRVAL2,
1320 crval2_new,
1321 "[deg] DEC at ref. pixel"));
1322
1323 cpl_matrix_delete(phys); phys = NULL;
1324 cpl_matrix_delete(world); world = NULL;
1325 cpl_array_delete(status); status = NULL;
1326 cpl_wcs_delete(wcs); wcs = NULL;
1327 }
1328
1329 // update WCS in z-direction, because starting point
1330 // isn't 1 anymore
1331 if ((cpl_propertylist_has(sub_header, CRPIX3)) &&
1332 (z1 != 1))
1333 {
1334 crpix3 = cpl_propertylist_get_double(sub_header,
1335 CRPIX3);
1336 KMO_TRY_CHECK_ERROR_STATE();
1337
1338 crpix3_new = crpix3 - z1 + 1;
1339 KMO_TRY_EXIT_IF_ERROR(
1340 kmclipm_update_property_double(sub_header,
1341 CRPIX3,
1342 crpix3_new,
1343 "[pix] Reference pixel in z"));
1344 }
1345 KMO_TRY_EXIT_IF_ERROR(
1346 kmo_dfs_save_cube(res_imglist, COPY, "",
1347 sub_header, 0./0.));
1348
1349 cpl_imagelist_delete(res_imglist); res_imglist = NULL;
1350 }
1351 /* --- IFU is invalid --> copy only header --- */
1352 } else {
1353 /* invalid IFU, just save sub_header */
1354 KMO_TRY_EXIT_IF_ERROR(
1355 kmo_dfs_save_sub_header(COPY, "", sub_header));
1356 }
1357
1358 cpl_propertylist_delete(sub_header); sub_header = NULL;
1359 }
1360 }
1361 }
1362 KMO_CATCH
1363 {
1364 KMO_CATCH_MSG();
1365
1366 ret_val = -1;
1367 }
1368
1369 cpl_propertylist_delete(sub_header); sub_header = NULL;
1370 kmo_free_fits_desc(&desc);
1371 kmclipm_vector_delete(vec); vec = NULL;
1372 kmclipm_vector_delete(res_vec); res_vec = NULL;
1373 cpl_image_delete(img); img = NULL;
1374 cpl_image_delete(res_img); res_img = NULL;
1375 cpl_imagelist_delete(imglist); imglist = NULL;
1376 cpl_imagelist_delete(res_imglist); res_imglist = NULL;
1377
1378 return ret_val;
1379}
1380
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.
Definition: kmo_copy.c:138