KMOS Pipeline Reference Manual  1.2.8
kmo_copy.c
00001 /* $Id: kmo_copy.c,v 1.12 2013-05-21 12:13:58 aagudo Exp $
00002  *
00003  * This file is part of the KMOS Pipeline
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: aagudo $
00023  * $Date: 2013-05-21 12:13:58 $
00024  * $Revision: 1.12 $
00025  * $Name: not supported by cvs2svn $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 #define _ISOC99_SOURCE
00033 #include <math.h>
00034 #include <string.h>
00035 
00036 #include <cpl.h>
00037 
00038 #include "kmclipm_constants.h"
00039 #include "kmclipm_functions.h"
00040 
00041 #include "kmo_cpl_extensions.h"
00042 #include "kmo_utils.h"
00043 #include "kmo_dfs.h"
00044 #include "kmo_debug.h"
00045 #include "kmo_error.h"
00046 #include "kmo_priv_copy.h"
00047 
00048 
00049 static int kmo_copy_create(cpl_plugin *);
00050 static int kmo_copy_exec(cpl_plugin *);
00051 static int kmo_copy_destroy(cpl_plugin *);
00052 static int kmo_copy(cpl_parameterlist *, cpl_frameset *);
00053 
00054 static char kmo_copy_description[] =
00055 "With this recipe a specified region of an IFU-based cube (F3I), image (F2I) or\n"
00056 "vector (F1I) can be copied to a new FITS file. One can copy just a plane out\n"
00057 "of a cube (any orientation) or a vector out of an image etc. By default the\n"
00058 "operation applies to all IFUs. The input data can contain noise frames which\n"
00059 "is then copied in the same manner as the input data.\n"
00060 "It is also possible to extract a specific IFU out of a KMOS FITS structure\n"
00061 "with 24 IFU extensions or 48 extensions if noise is present.\n"
00062 "\n"
00063 "BASIC PARAMETERS:\n"
00064 "-----------------\n"
00065 "--ifu\n"
00066 "Use this parameter to apply the operation to a specific IFU.\n"
00067 "\n"
00068 "--x\n"
00069 "--y\n"
00070 "--z\n"
00071 "These are the start values in each dimension. The first pixel is adressed "
00072 "with 1. \n"
00073 "\n"
00074 "--xsize\n"
00075 "--ysize\n"
00076 "--zsize\n"
00077 "These are the extents in each dimension to copy.\n"
00078 "\n"
00079 "--autocrop\n"
00080 "If set to TRUE all borders containing NaN values are cropped. Vectors will be\n"
00081 "shortened, images and cubes can get smaller. In This special case following\n"
00082 "parameters can be omitted: --x, --y, --z, --xsize, --ysize and --zsize.\n"
00083 "\n"
00084 "Examples:\n"
00085 "---------\n"
00086 "extract a cube-section of a cube: \n"
00087 "esorex kmo_copy --x=3 --y=2 --z=1 --xsize=2 --ysize=3 --zsize=6 copy.sof\n"
00088 "\n"
00089 "extract plane:\n"
00090 "esorex kmo_copy --x=3 --y=2 --z=1 --xsize=2 --ysize=3 copy.sof\n"
00091 "\n"
00092 "extract vector just of IFU 4:\n"
00093 "esorex kmo_copy --x=3 --y=2 --z=1 --ysize=3 --ifu=4 copy.sof\n"
00094 "\n"
00095 "extract whole IFU 4:\n"
00096 "esorex kmo_copy --x=1 --y=1 --z=1 --xsize=<NAXIS1> --ysize=<NAXIS2> \n"
00097 "                                           --zsize=<NAXIS3> --ifu=4 copy.sof\n"
00098 "\n"
00099 "extract scalar:\n"
00100 "esorex kmo_copy --x=3 --y=2 --z=1 copy.sof\n"
00101 "\n"
00102 "with copy.sof:\n"
00103 "F3I.fits    DATA\n"
00104 "\n"
00105 "-------------------------------------------------------------------------------\n"
00106 "  Input files:\n"
00107 "\n"
00108 "   DO                    KMOS                                                  \n"
00109 "   category              Type   Explanation                    Required #Frames\n"
00110 "   --------              -----  -----------                    -------- -------\n"
00111 "   <none or any>         F3I    Data cube                         Y        1   \n"
00112 "   or                                                                          \n"
00113 "   <none or any>         F2I    Image                                          \n"
00114 "   or                                                                          \n"
00115 "   <none or any>         F1I    Vector                                         \n"
00116 "                                (All inputs with or                            \n"
00117 "                                without noise frame)                           \n"
00118 "\n"
00119 "  Output files:\n"
00120 "\n"
00121 "   DO                    KMOS\n"
00122 "   category              Type   Explanation\n"
00123 "   --------              -----  -----------\n"
00124 "   COPY                  F3I or Cropped input data\n"
00125 "                         F2I or                   \n"
00126 "                         F1I                      \n"
00127 "-------------------------------------------------------------------------------\n"
00128 "\n";
00129 
00146 int cpl_plugin_get_info(cpl_pluginlist *list)
00147 {
00148     cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
00149     cpl_plugin *plugin = &recipe->interface;
00150 
00151     cpl_plugin_init(plugin,
00152                         CPL_PLUGIN_API,
00153                         KMOS_BINARY_VERSION,
00154                         CPL_PLUGIN_TYPE_RECIPE,
00155                         "kmo_copy",
00156                         "Copy a section of a cube to another cube, "
00157                             "image or spectrum",
00158                         kmo_copy_description,
00159                         "Alex Agudo Berbel",
00160                         "kmos-spark@mpe.mpg.de",
00161                         kmos_get_license(),
00162                         kmo_copy_create,
00163                         kmo_copy_exec,
00164                         kmo_copy_destroy);
00165 
00166     cpl_pluginlist_append(list, plugin);
00167 
00168     return 0;
00169 }
00170 
00178 static int kmo_copy_create(cpl_plugin *plugin)
00179 {
00180     cpl_recipe *recipe;
00181     cpl_parameter *p;
00182 
00183     /* Check that the plugin is part of a valid recipe */
00184     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00185         recipe = (cpl_recipe *)plugin;
00186     else
00187         return -1;
00188 
00189     /* Create the parameters list in the cpl_recipe object */
00190     recipe->parameters = cpl_parameterlist_new();
00191 
00192     /* Fill the parameters list */
00193 
00194     /* --ifu */
00195     p = cpl_parameter_new_value("kmos.kmo_copy.ifu",
00196                                 CPL_TYPE_INT,
00197                                 "Specific IFU to process",
00198                                 "kmos.kmo_copy",
00199                                 -1);
00200     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ifu");
00201     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00202     cpl_parameterlist_append(recipe->parameters, p);
00203 
00204     /* --autocrop */
00205     p = cpl_parameter_new_value("kmos.kmo_copy.autocrop",
00206                                 CPL_TYPE_BOOL,
00207                                 "Crop automatically NaN values at borders",
00208                                 "kmos.kmo_copy",
00209                                 FALSE);
00210     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "autocrop");
00211     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00212     cpl_parameterlist_append(recipe->parameters, p);
00213 
00214     /* --x, --y, --z */
00215     p = cpl_parameter_new_value("kmos.kmo_copy.x",
00216                                 CPL_TYPE_INT,
00217                                 "Start value in first dimension (pixels).",
00218                                 "kmos.kmo_copy",
00219                                 1);
00220     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "x");
00221     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00222     cpl_parameterlist_append(recipe->parameters, p);
00223 
00224     p = cpl_parameter_new_value("kmos.kmo_copy.y",
00225                                 CPL_TYPE_INT,
00226                                 "Start value in second dimension (pixels).",
00227                                 "kmos.kmo_copy",
00228                                 1);
00229     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "y");
00230     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00231     cpl_parameterlist_append(recipe->parameters, p);
00232 
00233     p = cpl_parameter_new_value("kmos.kmo_copy.z",
00234                                 CPL_TYPE_INT,
00235                                 "Start value in third dimension (pixels).",
00236                                 "kmos.kmo_copy",
00237                                 1);
00238     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "z");
00239     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00240     cpl_parameterlist_append(recipe->parameters, p);
00241 
00242     /* --xsize, --ysize, --zsize */
00243     p = cpl_parameter_new_value("kmos.kmo_copy.xsize",
00244                                 CPL_TYPE_INT,
00245                                 "Length in first dimension (pixels).",
00246                                 "kmos.kmo_copy",
00247                                 1);
00248     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xsize");
00249     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00250     cpl_parameterlist_append(recipe->parameters, p);
00251 
00252     p = cpl_parameter_new_value("kmos.kmo_copy.ysize",
00253                                 CPL_TYPE_INT,
00254                                 "Length in second dimension (pixels).",
00255                                 "kmos.kmo_copy",
00256                                 1);
00257     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ysize");
00258     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00259     cpl_parameterlist_append(recipe->parameters, p);
00260 
00261     p = cpl_parameter_new_value("kmos.kmo_copy.zsize",
00262                                 CPL_TYPE_INT,
00263                                 "Length in third dimension (pixels).",
00264                                 "kmos.kmo_copy",
00265                                 1);
00266     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "zsize");
00267     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00268     cpl_parameterlist_append(recipe->parameters, p);
00269 
00270     return 0;
00271 }
00272 
00278 static int kmo_copy_exec(cpl_plugin *plugin)
00279 {
00280     cpl_recipe  *recipe;
00281 
00282     /* Get the recipe out of the plugin */
00283     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00284         recipe = (cpl_recipe *)plugin;
00285     else return -1 ;
00286 
00287     return kmo_copy(recipe->parameters, recipe->frames);
00288 }
00289 
00295 static int kmo_copy_destroy(cpl_plugin *plugin)
00296 {
00297     cpl_recipe *recipe;
00298 
00299     /* Get the recipe out of the plugin */
00300     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00301         recipe = (cpl_recipe *)plugin;
00302     else return -1 ;
00303 
00304     cpl_parameterlist_delete(recipe->parameters);
00305     return 0 ;
00306 }
00307 
00322 static int kmo_copy(cpl_parameterlist *parlist, cpl_frameset *frameset)
00323 {
00324     int                 ret_val         = 0,
00325                         i               = 0,
00326                         x1              = 0,
00327                         y1              = 0,
00328                         z1              = 0,
00329                         x2              = 0,
00330                         y2              = 0,
00331                         z2              = 0,
00332                         xsize           = 0,
00333                         ysize           = 0,
00334                         zsize           = 0,
00335                         ifu             = 0,
00336                         autocrop        = 0,
00337                         nx              = 0,
00338                         ny              = 0,
00339                         nz              = 0,
00340                         allNaN          = 0,
00341                         ix              = 0,
00342                         iy              = 0,
00343                         iz              = 0;
00344     double              crpix1          = 0.,
00345                         crpix2          = 0.,
00346                         crpix3          = 0.,
00347                         crpix1_new      = 0.,
00348                         crpix2_new      = 0.,
00349                         crval1_new      = 0.,
00350                         crval2_new      = 0.,
00351                         crval3          = 0.,
00352                         cdelt3          = 0.,
00353                         xshift          = 0.,
00354                         yshift          = 0.,
00355                         crpix3_new      = 0.;
00356     float               *pimg           = NULL;
00357     cpl_wcs             *wcs            = NULL;
00358     cpl_matrix          *phys           = NULL,
00359                         *world          = NULL;
00360     cpl_array           *status         = NULL;
00361     cpl_propertylist    *sub_header     = NULL;
00362     cpl_imagelist       *imglist        = NULL,
00363                         *res_imglist    = NULL;
00364     cpl_image           *img            = NULL,
00365                         *res_img        = NULL;
00366     kmclipm_vector      *vec            = NULL,
00367                         *res_vec        = NULL;
00368     cpl_frame           *frame          = NULL;
00369     main_fits_desc      desc;
00370 
00371     KMO_TRY
00372     {
00373         kmo_init_fits_desc(&desc);
00374 
00375         /* --- check input --- */
00376         KMO_TRY_ASSURE((parlist != NULL) &&
00377                        (frameset != NULL),
00378                        CPL_ERROR_NULL_INPUT,
00379                        "Not all input data is provided!");
00380 
00381         KMO_TRY_ASSURE(cpl_frameset_get_size(frameset) == 1,
00382                        CPL_ERROR_NULL_INPUT,
00383                        "A fits-file must be provided!");
00384 
00385         KMO_TRY_EXIT_IF_NULL(
00386                     frame = kmo_dfs_get_frame(frameset, "0"));
00387 
00388         desc = kmo_identify_fits_header(
00389                     cpl_frame_get_filename(frame));
00390         KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to be "
00391                                       "in KMOS-format!");
00392 
00393         KMO_TRY_ASSURE((desc.fits_type == f1i_fits) ||
00394                        (desc.fits_type == f2i_fits) ||
00395                        (desc.fits_type == f3i_fits),
00396                        CPL_ERROR_ILLEGAL_INPUT,
00397                        "Input data hasn't correct data type "
00398                        "(KMOSTYPE must be F1I, F2I or F3I)!");
00399 
00400         KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_copy") == 1,
00401                        CPL_ERROR_ILLEGAL_INPUT,
00402                        "Cannot identify RAW and CALIB frames!");
00403 
00404         /* get & check ifu-parameter (optional)*/
00405         cpl_msg_info("", "--- Parameter setup for kmo_copy ----------");
00406 
00407         ifu = kmo_dfs_get_parameter_int(parlist, "kmos.kmo_copy.ifu");
00408         KMO_TRY_ASSURE((ifu == -1) ||
00409                        ((ifu >= 0)/* && (ifu <= desc.nr_ext)*/),
00410                        CPL_ERROR_ILLEGAL_INPUT,
00411                        "ifu is out of range!");
00412         if (ifu != -1) {
00413             ix = FALSE;
00414             for (i = 0; i < desc.nr_ext; i++) {
00415                 if (ifu == desc.sub_desc[i].device_nr) {
00416                     ix = TRUE;
00417                 }
00418             }
00419             KMO_TRY_ASSURE(ix == TRUE,
00420                            CPL_ERROR_ILLEGAL_INPUT,
00421                            "ifu #%d doesn't exist in this frame!", ifu);
00422         }
00423 
00424         KMO_TRY_EXIT_IF_ERROR(
00425             kmo_dfs_print_parameter_help(parlist, "kmos.kmo_copy.ifu"));
00426 
00427         autocrop = kmo_dfs_get_parameter_bool(parlist, "kmos.kmo_copy.autocrop");
00428         KMO_TRY_ASSURE((autocrop == TRUE) || (autocrop == FALSE),
00429                        CPL_ERROR_ILLEGAL_INPUT,
00430                        "autocrop must be TZRUE or FALSE!");
00431         KMO_TRY_EXIT_IF_ERROR(
00432             kmo_dfs_print_parameter_help(parlist, "kmos.kmo_copy.autocrop"));
00433 
00434         if (!autocrop) {
00435             /* get & check x-, y-, z-parameters (mandatory)*/
00436             x1 = kmo_dfs_get_parameter_int(parlist, "kmos.kmo_copy.x");
00437 
00438             KMO_TRY_ASSURE(x1 > 0,
00439                            CPL_ERROR_ILLEGAL_INPUT,
00440                            "x is smaller than 1!");
00441 
00442             KMO_TRY_ASSURE(x1 <= desc.naxis1,
00443                            CPL_ERROR_ILLEGAL_INPUT,
00444                            "x is larger than corresponding dimension of "
00445                            "input data cube!");
00446             KMO_TRY_EXIT_IF_ERROR(
00447                 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_copy.x"));
00448 
00449             if ((desc.fits_type == f2i_fits) || (desc.fits_type == f3i_fits)) {
00450                 y1 = kmo_dfs_get_parameter_int(parlist, "kmos.kmo_copy.y");
00451 
00452                 KMO_TRY_ASSURE(y1 > 0,
00453                                CPL_ERROR_ILLEGAL_INPUT,
00454                                "y is smaller than 1!");
00455 
00456                 KMO_TRY_ASSURE(y1 <= desc.naxis2,
00457                                CPL_ERROR_ILLEGAL_INPUT,
00458                                "y is larger than corresponding dimension of "
00459                                "input data cube!");
00460                 KMO_TRY_EXIT_IF_ERROR(
00461                     kmo_dfs_print_parameter_help(parlist, "kmos.kmo_copy.y"));
00462 
00463                 if (desc.fits_type == f3i_fits) {
00464                     z1 = kmo_dfs_get_parameter_int(parlist, "kmos.kmo_copy.z");
00465 
00466                     KMO_TRY_ASSURE(z1 > 0,
00467                            CPL_ERROR_ILLEGAL_INPUT,
00468                            "z is smaller than 1!");
00469 
00470                     KMO_TRY_ASSURE(z1 <= desc.naxis3,
00471                                    CPL_ERROR_ILLEGAL_INPUT,
00472                                    "z is larger than corresponding dimension of "
00473                                    "input data cube!");
00474                     KMO_TRY_EXIT_IF_ERROR(
00475                         kmo_dfs_print_parameter_help(parlist, "kmos.kmo_copy.z"));
00476                 }
00477             }
00478 
00479             /* get & check x2-, y2-, z2-parameters (optional) */
00480             xsize = kmo_dfs_get_parameter_int(parlist, "kmos.kmo_copy.xsize");
00481 
00482             KMO_TRY_ASSURE(xsize > 0,
00483                            CPL_ERROR_ILLEGAL_INPUT,
00484                            "xsize is smaller than 1!");
00485             KMO_TRY_EXIT_IF_ERROR(
00486                 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_copy.xsize"));
00487 
00488             x2 = x1 - 1 + xsize;
00489 
00490             KMO_TRY_ASSURE(x2 > 0,
00491                            CPL_ERROR_ILLEGAL_INPUT,
00492                            "End value in 1st dimension smaller than 0!");
00493 
00494             KMO_TRY_ASSURE(x2 <= desc.naxis1,
00495                            CPL_ERROR_ILLEGAL_INPUT,
00496                            "xsize is too large (xsize <= %d)",
00497                            desc.naxis1 - x1 + 1);
00498 
00499             if ((desc.fits_type == f2i_fits) || (desc.fits_type == f3i_fits)) {
00500                 ysize = kmo_dfs_get_parameter_int(parlist, "kmos.kmo_copy.ysize");
00501 
00502                 KMO_TRY_ASSURE(ysize > 0,
00503                                CPL_ERROR_ILLEGAL_INPUT,
00504                                "ysize is smaller than 1!");
00505                 KMO_TRY_EXIT_IF_ERROR(
00506                     kmo_dfs_print_parameter_help(parlist, "kmos.kmo_copy.ysize"));
00507 
00508                 y2 = y1 - 1 + ysize;
00509 
00510                 KMO_TRY_ASSURE(y2 > 0,
00511                                CPL_ERROR_ILLEGAL_INPUT,
00512                                "End value in 2nd dimension smaller than 0!");
00513 
00514                 KMO_TRY_ASSURE(y2 <= desc.naxis2,
00515                                CPL_ERROR_ILLEGAL_INPUT,
00516                                "ysize is too large (ysize <= %d)",
00517                                desc.naxis2 - y1 + 1);
00518 
00519                 if (desc.fits_type == f3i_fits) {
00520                     zsize = kmo_dfs_get_parameter_int(parlist,
00521                                                       "kmos.kmo_copy.zsize");
00522 
00523                     KMO_TRY_ASSURE(zsize > 0,
00524                                    CPL_ERROR_ILLEGAL_INPUT,
00525                                    "zsize is smaller than 1!");
00526 
00527                     KMO_TRY_EXIT_IF_ERROR(
00528                         kmo_dfs_print_parameter_help(parlist, "kmos.kmo_copy.zsize"));
00529 
00530                     z2 = z1 - 1 + zsize;
00531 
00532                     KMO_TRY_ASSURE(z2 > 0,
00533                                    CPL_ERROR_ILLEGAL_INPUT,
00534                                    "End value in 3rd dimension smaller than 0!");
00535 
00536                     KMO_TRY_ASSURE(z2 <= desc.naxis3,
00537                                    CPL_ERROR_ILLEGAL_INPUT,
00538                                    "zsize is too large (zsize <= %d)",
00539                                    desc.naxis3 - z1 + 1);
00540                 }
00541             }
00542             KMO_TRY_CHECK_ERROR_STATE();
00543         }
00544 
00545         cpl_msg_info("", "-------------------------------------------");
00546 
00547         /* --- load, update & save primary header --- */
00548         KMO_TRY_EXIT_IF_ERROR(
00549             kmo_dfs_save_main_header(frameset, COPY, "", frame, NULL, parlist, cpl_func));
00550 
00551         //
00552         // --- copy data ----
00553         //
00554         for (i = 0; i < desc.nr_ext; i++) {
00555             if ((ifu == desc.sub_desc[i].device_nr) ||
00556                 (ifu == -1)) {
00557 
00558                 KMO_TRY_EXIT_IF_NULL(
00559                     sub_header = kmo_dfs_load_sub_header(frameset,
00560                                                     "0",
00561                                                     desc.sub_desc[i].device_nr,
00562                                                     desc.sub_desc[i].is_noise));
00563 
00564                 //
00565                 // --- IFU is valid -> copy header and data ---
00566                 //
00567                 if (desc.sub_desc[i].valid_data == TRUE) {
00568 
00569                     switch (desc.fits_type) {
00570                         case f1i_fits:
00571                             KMO_TRY_EXIT_IF_NULL(
00572                                 vec = kmo_dfs_load_vector(frameset,
00573                                                 "0",
00574                                                 desc.sub_desc[i].device_nr,
00575                                                 desc.sub_desc[i].is_noise));
00576 
00577                             if (autocrop && !desc.sub_desc[i].is_noise) {
00578                                 x1 = 1;
00579                                 x2 = kmclipm_vector_get_size(vec);
00580                                 while (kmclipm_vector_is_rejected(vec, x1-1)) {
00581                                     x1++;
00582                                 }
00583                                 while (kmclipm_vector_is_rejected(vec, x2-1)) {
00584                                     x2--;
00585                                 }
00586 
00587                                 if (x1 > x2) {
00588                                     /* invalid IFU, just save sub_header */
00589                                     KMO_TRY_EXIT_IF_ERROR(
00590                                         kmo_dfs_save_sub_header(COPY, "",
00591                                                                 sub_header));
00592                                     continue; // with next IFU
00593                                 }
00594                             }
00595 
00596                             // extract scalar (F1I)
00597                             if ((x1 == x2) || (x2 == INT_MIN))
00598                             {
00599                                 KMO_TRY_EXIT_IF_NULL(
00600                                     res_vec = kmclipm_vector_new(1));
00601 
00602                                 KMO_TRY_EXIT_IF_ERROR(
00603                                     kmclipm_vector_set(res_vec, 0,
00604                                                  kmo_copy_scalar_F1I(vec, x1)));
00605                             }
00606                             // extract x-vector (F1I)
00607                             else if ((x2!= INT_MIN) && (x1 != x2))
00608                             {
00609                                 KMO_TRY_EXIT_IF_NULL(
00610                                     res_vec = kmo_copy_vector_F1I(vec, x1, x2));
00611                             }
00612 
00613                             kmclipm_vector_delete(vec); vec = NULL;
00614 
00615                             break;
00616                         case f2i_fits:
00617                             KMO_TRY_EXIT_IF_NULL(
00618                                 img = kmo_dfs_load_image(frameset,
00619                                                 "0",
00620                                                 desc.sub_desc[i].device_nr,
00621                                                 desc.sub_desc[i].is_noise, FALSE, NULL));
00622 
00623                             if (autocrop && !desc.sub_desc[i].is_noise) {
00624                                 nx = cpl_image_get_size_x(img);
00625                                 ny = cpl_image_get_size_y(img);
00626                                 x1 = 1;
00627                                 x2 = nx;
00628                                 y1 = 1;
00629                                 y2 = ny;
00630 
00631                                 KMO_TRY_EXIT_IF_NULL(
00632                                     pimg = cpl_image_get_data_float(img));
00633 
00634                                 allNaN = TRUE;
00635                                 while (allNaN) {
00636                                     for (iy = 0; iy < ny; iy++) {
00637                                         if(!isnan(pimg[x1-1+iy*nx])) {
00638                                             allNaN = FALSE;
00639                                             break;
00640                                         }
00641                                     }
00642                                     if (allNaN) {
00643                                         x1++;
00644                                     }
00645                                 }
00646 
00647                                 allNaN = TRUE;
00648                                 while (allNaN) {
00649                                     for (iy = 0; iy < ny; iy++) {
00650                                         if(!isnan(pimg[x2-1+iy*nx])) {
00651                                             allNaN = FALSE;
00652                                             break;
00653                                         }
00654                                     }
00655                                     if (allNaN) {
00656                                         x2--;
00657                                     }
00658                                 }
00659 
00660                                 allNaN = TRUE;
00661                                 while (allNaN) {
00662                                     for (ix = 0; ix < nx; ix++) {
00663                                         if(!isnan(pimg[ix+(y1-1)*nx])) {
00664                                             allNaN = FALSE;
00665                                             break;
00666                                         }
00667                                     }
00668                                     if (allNaN) {
00669                                         y1++;
00670                                     }
00671                                 }
00672 
00673                                 allNaN = TRUE;
00674                                 while (allNaN) {
00675                                     for (ix = 0; ix < nx; ix++) {
00676                                         if(!isnan(pimg[ix+(y2-1)*nx])) {
00677                                             allNaN = FALSE;
00678                                             break;
00679                                         }
00680                                     }
00681                                     if (allNaN) {
00682                                         y2--;
00683                                     }
00684                                 }
00685 
00686                                 if ((x1 > x2) || (y1 > y2)) {
00687                                     /* invalid IFU, just save sub_header */
00688                                     KMO_TRY_EXIT_IF_ERROR(
00689                                         kmo_dfs_save_sub_header(COPY, "",
00690                                                                 sub_header));
00691                                     continue; // with next IFU
00692                                 }
00693                             }
00694 
00695                             // extract scalar (F2I)
00696                             if (((x1 == x2) || (x2 == INT_MIN)) &&
00697                                 ((y1 == y2) || (y2 == INT_MIN)))
00698                             {
00699                                 KMO_TRY_EXIT_IF_NULL(
00700                                     res_vec = kmclipm_vector_new(1));
00701 
00702                                 KMO_TRY_EXIT_IF_ERROR(
00703                                     kmclipm_vector_set(res_vec, 0,
00704                                              kmo_copy_scalar_F2I(img, x1, y1)));
00705                             }
00706                             // extract x-vector (F2I)
00707                             else if (((y1 == y2) || (y2 == INT_MIN)) &&
00708                                        (x2 != INT_MIN) &&
00709                                        (x1 != x2))
00710                             {
00711                                 KMO_TRY_EXIT_IF_NULL(
00712                                     res_vec = kmo_copy_vector_F2I_x(img,
00713                                                                    x1, x2, y1));
00714                             }
00715                             // extract y-vector (F2I)
00716                             else if (((x1 == x2) || (x2 == INT_MIN)) &&
00717                                        (y2 != INT_MIN) &&
00718                                        (y1 != y2))
00719                             {
00720                                 KMO_TRY_EXIT_IF_NULL(
00721                                     res_vec = kmo_copy_vector_F2I_y(img,
00722                                                                    x1, y1, y2));
00723                             }
00724                             // extract plane (F2I)
00725                             else if ((x2 != INT_MIN) && (x1 != x2) &&
00726                                        (y2 != INT_MIN) && (y1 != y2))
00727                             {
00728                                 KMO_TRY_EXIT_IF_NULL(
00729                                     res_img = kmo_copy_image_F2I(img,
00730                                                                x1, x2, y1, y2));
00731                             }
00732 
00733                             cpl_image_delete(img); img = NULL;
00734 
00735                             break;
00736                         case f3i_fits:
00737                             KMO_TRY_EXIT_IF_NULL(
00738                                 imglist = kmo_dfs_load_cube(frameset,
00739                                                 "0",
00740                                                 desc.sub_desc[i].device_nr,
00741                                                 desc.sub_desc[i].is_noise));
00742 
00743                             if (autocrop && !desc.sub_desc[i].is_noise) {
00744                                 img = cpl_imagelist_get(imglist, 0);
00745                                 nx = cpl_image_get_size_x(img);
00746                                 ny = cpl_image_get_size_y(img);
00747                                 nz = cpl_imagelist_get_size(imglist);
00748                                 x1 = 1;
00749                                 x2 = nx;
00750                                 y1 = 1;
00751                                 y2 = ny;
00752                                 z1 = 1;
00753                                 z2 = nz;
00754 
00755                                 while (kmo_image_get_rejected(img) == nx*ny) {
00756                                     z1++;
00757                                     img = cpl_imagelist_get(imglist, z1-1);
00758                                 }
00759 
00760                                 img = cpl_imagelist_get(imglist, z2-1);
00761                                 while (kmo_image_get_rejected(img) == nx*ny) {
00762                                     z2--;
00763                                     img = cpl_imagelist_get(imglist, z2-1);
00764                                 }
00765 
00766                                 allNaN = TRUE;
00767                                 while (allNaN) {
00768                                     for (iz = z1-1; iz < z2; iz++) {
00769                                         img = cpl_imagelist_get(imglist, iz);
00770                                         KMO_TRY_EXIT_IF_NULL(
00771                                             pimg = cpl_image_get_data_float(img));
00772                                         if (allNaN == FALSE) {
00773                                             break;
00774                                         }
00775                                         for (iy = 0; iy < ny; iy++) {
00776                                             if(!isnan(pimg[x1-1+iy*nx])) {
00777                                                 allNaN = FALSE;
00778                                                 break;
00779                                             }
00780                                         }
00781                                     }
00782                                     if (allNaN) {
00783                                         x1++;
00784                                     }
00785                                 }
00786 
00787                                 allNaN = TRUE;
00788                                 while (allNaN) {
00789                                     for (iz = z1-1; iz < z2; iz++) {
00790                                         img = cpl_imagelist_get(imglist, iz);
00791                                         KMO_TRY_EXIT_IF_NULL(
00792                                             pimg = cpl_image_get_data_float(img));
00793                                         if (allNaN == FALSE) {
00794                                             break;
00795                                         }
00796                                         for (iy = 0; iy < ny; iy++) {
00797                                             if(!isnan(pimg[x2-1+iy*nx])) {
00798                                                 allNaN = FALSE;
00799                                                 break;
00800                                             }
00801                                         }
00802                                     }
00803                                     if (allNaN) {
00804                                         x2--;
00805                                     }
00806                                 }
00807 
00808                                 allNaN = TRUE;
00809                                 while (allNaN) {
00810                                     for (iz = z1-1; iz < z2; iz++) {
00811                                         img = cpl_imagelist_get(imglist, iz);
00812                                         KMO_TRY_EXIT_IF_NULL(
00813                                             pimg = cpl_image_get_data_float(img));
00814                                         if (allNaN == FALSE) {
00815                                             break;
00816                                         }
00817                                         for (ix = 0; ix < nx; ix++) {
00818                                             if(!isnan(pimg[ix+(y1-1)*nx])) {
00819                                                 allNaN = FALSE;
00820                                                 break;
00821                                             }
00822                                         }
00823                                     }
00824                                     if (allNaN) {
00825                                         y1++;
00826                                     }
00827                                 }
00828 
00829                                 allNaN = TRUE;
00830                                 while (allNaN) {
00831                                     for (iz = z1-1; iz < z2; iz++) {
00832                                         img = cpl_imagelist_get(imglist, iz);
00833                                         KMO_TRY_EXIT_IF_NULL(
00834                                             pimg = cpl_image_get_data_float(img));
00835                                         if (allNaN == FALSE) {
00836                                             break;
00837                                         }
00838                                         for (ix = 0; ix < nx; ix++) {
00839                                             if(!isnan(pimg[ix+(y2-1)*nx])) {
00840                                                 allNaN = FALSE;
00841                                                 break;
00842                                             }
00843                                         }
00844                                     }
00845                                     if (allNaN) {
00846                                         y2--;
00847                                     }
00848                                 }
00849 
00850                                 img = NULL;
00851 
00852                                 if ((x1 > x2) || (y1 > y2) || (z1 > z2)) {
00853                                     /* invalid IFU, just save sub_header */
00854                                     KMO_TRY_EXIT_IF_ERROR(
00855                                         kmo_dfs_save_sub_header(COPY, "",
00856                                                             sub_header));
00857                                     continue; // with next IFU
00858                                 }
00859                             }
00860 
00861                             // extract scalar (F3I)
00862                             if (((x1 == x2) || (x2 == INT_MIN)) &&
00863                                 ((y1 == y2) || (y2 == INT_MIN)) &&
00864                                 ((z1 == z2) || (z2 == INT_MIN)))
00865                             {
00866                                 KMO_TRY_EXIT_IF_NULL(
00867                                     res_vec = kmclipm_vector_new(1));
00868 
00869                                 KMO_TRY_EXIT_IF_ERROR(
00870                                     kmclipm_vector_set(res_vec, 0,
00871                                      kmo_copy_scalar_F3I(imglist, x1, y1, z1)));
00872                             }
00873                             // extract x-vector (F3I)
00874                             else if ((x2 != INT_MIN) && (x1 != x2) &&
00875                                        ((y1 == y2) || (y2 == INT_MIN)) &&
00876                                        ((z1 == z2) || (z2 == INT_MIN)))
00877                             {
00878                                 KMO_TRY_EXIT_IF_NULL(
00879                                     res_vec = kmo_copy_vector_F3I_x(imglist,
00880                                                                x1, x2, y1, z1));
00881                             }
00882                             // extract y-vector (F3I)
00883                             else if (((x1 == x2) || (x2 == INT_MIN)) &&
00884                                        (y2!= INT_MIN) && (y1 != y2) &&
00885                                        ((z1 == z2) || (z2 == INT_MIN)))
00886                             {
00887                                 KMO_TRY_EXIT_IF_NULL(
00888                                     res_vec = kmo_copy_vector_F3I_y(imglist,
00889                                                                x1, y1, y2, z1));
00890                             }
00891                             // extract z-vector (F3I)
00892                             else if (((x1 == x2) || (x2 == INT_MIN)) &&
00893                                        ((y1 == y2) || (y2 == INT_MIN)) &&
00894                                        (z2 != INT_MIN) && (z1 != z2))
00895                             {
00896                                 KMO_TRY_EXIT_IF_NULL(
00897                                     res_vec = kmo_copy_vector_F3I_z(imglist,
00898                                                                x1, y1, z1, z2));
00899                             }
00900                             // extract x-plane (F3I)
00901                             else if (((x1 == x2) || (x2 == INT_MIN)) &&
00902                                        (y2 != INT_MIN) && (y1 != y2) &&
00903                                        (z2 != INT_MIN) && (z1 != z2))
00904                             {
00905                                 KMO_TRY_EXIT_IF_NULL(
00906                                     res_img = kmo_copy_image_F3I_x(imglist,
00907                                                            x1, y1, y2, z1, z2));
00908                             }
00909                             // extract y-plane (F3I)
00910                             else if ((x2 != INT_MIN) && (x1 != x2) &&
00911                                        ((y1 == y2) || (y2 == INT_MIN)) &&
00912                                        (z2 != INT_MIN) && (z1 != z2))
00913                             {
00914                                 KMO_TRY_EXIT_IF_NULL(
00915                                     res_img = kmo_copy_image_F3I_y(imglist,
00916                                                            x1, x2, y1, z1, z2));
00917                             }
00918                             // extract z-plane (F3I)
00919                             else if ((x2 != INT_MIN) && (x1 != x2) &&
00920                                        (y2 != INT_MIN) && (y1 != y2) &&
00921                                        ((z1 == z2) || (z2 == INT_MIN)))
00922                             {
00923                                 KMO_TRY_EXIT_IF_NULL(
00924                                     res_img = kmo_copy_image_F3I_z(imglist,
00925                                                            x1, x2, y1, y2, z1));
00926                             }
00927                             // extract cube (F3I)
00928                             else if ((x2!= INT_MIN) && (x1 != x2) &&
00929                                        (y2!= INT_MIN) && (y1 != y2) &&
00930                                        (z2!= INT_MIN) && (z1 != z2))
00931                             {
00932                                 KMO_TRY_EXIT_IF_NULL(
00933                                     res_imglist = kmo_copy_cube_F3I(imglist,
00934                                                        x1, x2, y1, y2, z1, z2));
00935                             }
00936 
00937                             cpl_imagelist_delete(imglist); imglist = NULL;
00938 
00939                             break;
00940                         default:
00941                             break;
00942                     }
00943 
00944                     //
00945                     // --- save and delete copied data, delete sub-header ---
00946                     //
00947                     if (res_vec != NULL) {
00948                         KMO_TRY_EXIT_IF_ERROR(
00949                             kmclipm_update_property_double(sub_header,
00950                                                            CRPIX1,
00951                                                            1,
00952                                              "[pix] Reference pixel in x"));
00953                         KMO_TRY_EXIT_IF_ERROR(
00954                             kmclipm_update_property_double(sub_header,
00955                                                            CRVAL1,
00956                                                            1,
00957                                           "[um] Wavelength at ref. pixel"));
00958                         KMO_TRY_EXIT_IF_ERROR(
00959                             kmclipm_update_property_double(sub_header,
00960                                                            CDELT1,
00961                                                            1,
00962                                                "[um] Spectral resolution"));
00963                         if (cpl_propertylist_has(sub_header, CUNIT1)) {
00964                             KMO_TRY_EXIT_IF_ERROR(
00965                                 kmclipm_update_property_string(
00966                                         sub_header,
00967                                         CUNIT1,
00968                                         "",
00969                                         ""));
00970                         }
00971 
00972                         KMO_TRY_EXIT_IF_ERROR(
00973                             kmclipm_update_property_string(
00974                                     sub_header,
00975                                     CTYPE1,
00976                                     "",
00977                                     "Coordinate system of x-axis"));
00978 
00979                         // going to save vector extracted from cube along lambda-axis
00980                         // (put dim3 keywords into dim1-keywords)
00981                         if ((desc.fits_type == f3i_fits) &&
00982                             (cpl_propertylist_has(sub_header, CRPIX3)) &&
00983                             (cpl_propertylist_has(sub_header, CRVAL3)) &&
00984                             ((x1 == x2) && (y1 == y2)))
00985                         {
00986                             crpix3 = cpl_propertylist_get_double(sub_header,
00987                                                                  CRPIX3);
00988                             crval3 = cpl_propertylist_get_double(sub_header,
00989                                                                  CRVAL3);
00990                             cdelt3 = cpl_propertylist_get_double(sub_header,
00991                                                                  CDELT3);
00992                             KMO_TRY_CHECK_ERROR_STATE();
00993 
00994                             // update WCS in z-direction, because starting point
00995                             // isn't 1 anymore
00996                             if (z1 != 1)
00997                             {
00998                                 crpix3 = crpix3 - z1 + 1;
00999                             }
01000 
01001                             KMO_TRY_EXIT_IF_ERROR(
01002                                 kmclipm_update_property_double(sub_header,
01003                                                                CRPIX1,
01004                                                                crpix3,
01005                                                  "[pix] Reference pixel in x"));
01006                             KMO_TRY_EXIT_IF_ERROR(
01007                                 kmclipm_update_property_double(sub_header,
01008                                                                CRVAL1,
01009                                                                crval3,
01010                                               "[um] Wavelength at ref. pixel"));
01011                             KMO_TRY_EXIT_IF_ERROR(
01012                                 kmclipm_update_property_double(sub_header,
01013                                                                CDELT1,
01014                                                                cdelt3,
01015                                                    "[um] Spectral resolution"));
01016                             if (cpl_propertylist_has(sub_header, CUNIT3)) {
01017                                 KMO_TRY_EXIT_IF_ERROR(
01018                                     kmclipm_update_property_string(
01019                                             sub_header,
01020                                             CUNIT1,
01021                                             cpl_propertylist_get_string(sub_header,
01022                                                                         CUNIT3),
01023                                             cpl_propertylist_get_comment(sub_header,
01024                                                                          CUNIT3)));
01025                             }
01026 
01027                             KMO_TRY_EXIT_IF_ERROR(
01028                                 kmclipm_update_property_string(
01029                                         sub_header,
01030                                         CTYPE1,
01031                                         cpl_propertylist_get_string(
01032                                                                 sub_header,
01033                                                                 CTYPE3),
01034                                         "Coordinate system of x-axis"));
01035                         }
01036                         if (cpl_propertylist_has(sub_header, CRPIX2))
01037                             cpl_propertylist_erase(sub_header, CRPIX2);
01038                         if (cpl_propertylist_has(sub_header, CRVAL2))
01039                             cpl_propertylist_erase(sub_header, CRVAL2);
01040                         if (cpl_propertylist_has(sub_header, CDELT2))
01041                             cpl_propertylist_erase(sub_header, CDELT2);
01042                         if (cpl_propertylist_has(sub_header, CTYPE2))
01043                             cpl_propertylist_erase(sub_header, CTYPE2);
01044                         if (cpl_propertylist_has(sub_header, CUNIT2))
01045                             cpl_propertylist_erase(sub_header, CUNIT2);
01046                         if (cpl_propertylist_has(sub_header, CRPIX3))
01047                             cpl_propertylist_erase(sub_header, CRPIX3);
01048                         if (cpl_propertylist_has(sub_header, CRVAL3))
01049                             cpl_propertylist_erase(sub_header, CRVAL3);
01050                         if (cpl_propertylist_has(sub_header, CDELT3))
01051                             cpl_propertylist_erase(sub_header, CDELT3);
01052                         if (cpl_propertylist_has(sub_header, CTYPE3))
01053                             cpl_propertylist_erase(sub_header, CTYPE3);
01054                         if (cpl_propertylist_has(sub_header, CUNIT3))
01055                             cpl_propertylist_erase(sub_header, CUNIT3);
01056                         if (cpl_propertylist_has(sub_header, CD1_1))
01057                             cpl_propertylist_erase(sub_header, CD1_1);
01058                         if (cpl_propertylist_has(sub_header, CD1_2))
01059                             cpl_propertylist_erase(sub_header, CD1_2);
01060                         if (cpl_propertylist_has(sub_header, CD1_3))
01061                             cpl_propertylist_erase(sub_header, CD1_3);
01062                         if (cpl_propertylist_has(sub_header, CD2_1))
01063                             cpl_propertylist_erase(sub_header, CD2_1);
01064                         if (cpl_propertylist_has(sub_header, CD2_2))
01065                             cpl_propertylist_erase(sub_header, CD2_2);
01066                         if (cpl_propertylist_has(sub_header, CD2_3))
01067                             cpl_propertylist_erase(sub_header, CD2_3);
01068                         if (cpl_propertylist_has(sub_header, CD3_1))
01069                             cpl_propertylist_erase(sub_header, CD3_1);
01070                         if (cpl_propertylist_has(sub_header, CD3_2))
01071                             cpl_propertylist_erase(sub_header, CD3_2);
01072                         if (cpl_propertylist_has(sub_header, CD3_3))
01073                             cpl_propertylist_erase(sub_header, CD3_3);
01074                         KMO_TRY_EXIT_IF_ERROR(
01075                             kmo_dfs_save_vector(res_vec, COPY, "",
01076                                                 sub_header, 0./0.));
01077 
01078                         kmclipm_vector_delete(res_vec); res_vec = NULL;
01079                     } else if (res_img != NULL) {
01080                         // going to save image extracted from cube along lambda-axis
01081                         // (put dim3 keywords into dim1-keywords)
01082                         if ((desc.fits_type == f3i_fits) &&
01083                             (cpl_propertylist_has(sub_header, CRPIX3)) &&
01084                             (cpl_propertylist_has(sub_header, CRVAL3)) &&
01085                             ((x1 == x2) || (y1 == y2)))
01086                         {
01087                             crpix3 = cpl_propertylist_get_double(sub_header,
01088                                                                  CRPIX3);
01089                             crval3 = cpl_propertylist_get_double(sub_header,
01090                                                                  CRVAL3);
01091                             cdelt3 = cpl_propertylist_get_double(sub_header,
01092                                                                  CDELT3);
01093                             KMO_TRY_CHECK_ERROR_STATE();
01094 
01095                             // update WCS in z-direction, because starting point
01096                             // isn't 1 anymore
01097                             if (z1 != 1)
01098                             {
01099                                 crpix3 = crpix3 - z1 + 1;
01100                             }
01101 
01102                             KMO_TRY_EXIT_IF_ERROR(
01103                                 kmclipm_update_property_double(sub_header,
01104                                                                CRPIX1,
01105                                                                crpix3,
01106                                                  "[pix] Reference pixel in x"));
01107                             KMO_TRY_EXIT_IF_ERROR(
01108                                 kmclipm_update_property_double(sub_header,
01109                                                                CRPIX2,
01110                                                                1,
01111                                                  "[pix] Reference pixel in y"));
01112                             KMO_TRY_EXIT_IF_ERROR(
01113                                 kmclipm_update_property_double(sub_header,
01114                                                                CRVAL1,
01115                                                                crval3,
01116                                               "[um] Wavelength at ref. pixel"));
01117                             KMO_TRY_EXIT_IF_ERROR(
01118                                 kmclipm_update_property_double(sub_header,
01119                                                                CRVAL2,
01120                                                                1,
01121                                                                "[pix]"));
01122                             KMO_TRY_EXIT_IF_ERROR(
01123                                 kmclipm_update_property_double(sub_header,
01124                                                                CDELT1,
01125                                                                cdelt3,
01126                                                    "[um] Spectral resolution"));
01127                             KMO_TRY_EXIT_IF_ERROR(
01128                                 kmclipm_update_property_double(sub_header,
01129                                                                CDELT2,
01130                                                                1,
01131                                                                "[pix]"));
01132                             if (cpl_propertylist_has(sub_header, CUNIT3)) {
01133                                 KMO_TRY_EXIT_IF_ERROR(
01134                                     kmclipm_update_property_string(
01135                                             sub_header,
01136                                             CUNIT1,
01137                                             cpl_propertylist_get_string(sub_header,
01138                                                                         CUNIT3),
01139                                             cpl_propertylist_get_comment(sub_header,
01140                                                                          CUNIT3)));
01141                             }
01142 
01143                             KMO_TRY_EXIT_IF_ERROR(
01144                                 kmclipm_update_property_string(
01145                                         sub_header,
01146                                         CTYPE1,
01147                                         cpl_propertylist_get_string(
01148                                                                 sub_header,
01149                                                                 CTYPE3),
01150                                         "Coordinate system of x-axis"));
01151 
01152                             KMO_TRY_EXIT_IF_ERROR(
01153                                 kmclipm_update_property_string(
01154                                             sub_header,
01155                                             CTYPE2,
01156                                             "",
01157                                             "Coordinate system of y-axis"));
01158                             if (cpl_propertylist_has(sub_header, CD1_1))
01159                                 cpl_propertylist_erase(sub_header, CD1_1);
01160                             if (cpl_propertylist_has(sub_header, CD1_2))
01161                                 cpl_propertylist_erase(sub_header, CD1_2);
01162                             if (cpl_propertylist_has(sub_header, CD2_1))
01163                                 cpl_propertylist_erase(sub_header, CD2_1);
01164                             if (cpl_propertylist_has(sub_header, CD2_2))
01165                                 cpl_propertylist_erase(sub_header, CD2_2);
01166                         }
01167 
01168                         // erase any still existing 3rd-dimension keywords
01169                         if (cpl_propertylist_has(sub_header, CRPIX3))
01170                             cpl_propertylist_erase(sub_header, CRPIX3);
01171                         if (cpl_propertylist_has(sub_header, CRVAL3))
01172                             cpl_propertylist_erase(sub_header, CRVAL3);
01173                         if (cpl_propertylist_has(sub_header, CDELT3))
01174                             cpl_propertylist_erase(sub_header, CDELT3);
01175                         if (cpl_propertylist_has(sub_header, CTYPE3))
01176                             cpl_propertylist_erase(sub_header, CTYPE3);
01177                         if (cpl_propertylist_has(sub_header, CUNIT3))
01178                             cpl_propertylist_erase(sub_header, CUNIT3);
01179                         if (cpl_propertylist_has(sub_header, CD1_3))
01180                             cpl_propertylist_erase(sub_header, CD1_3);
01181                         if (cpl_propertylist_has(sub_header, CD2_3))
01182                             cpl_propertylist_erase(sub_header, CD2_3);
01183                         if (cpl_propertylist_has(sub_header, CD3_1))
01184                             cpl_propertylist_erase(sub_header, CD3_1);
01185                         if (cpl_propertylist_has(sub_header, CD3_2))
01186                             cpl_propertylist_erase(sub_header, CD3_2);
01187                         if (cpl_propertylist_has(sub_header, CD3_3))
01188                             cpl_propertylist_erase(sub_header, CD3_3);
01189 
01190 
01191                         // update WCS in x- and y-direction because it got smaller
01192                         if ((desc.fits_type == f3i_fits) &&
01193                             (desc.fits_type == f2i_fits) &&
01194                             (cpl_propertylist_has(sub_header, CRPIX1)) &&
01195                             (cpl_propertylist_has(sub_header, CRPIX2)) &&
01196                             ((x1 != 1) || (y1 != 1)))
01197                         {
01198                             KMO_TRY_EXIT_IF_ERROR(
01199                                 kmclipm_update_property_int(sub_header,
01200                                                                NAXIS,
01201                                                                2,
01202                                                                ""));
01203                             cpl_propertylist_erase(sub_header, NAXIS3);
01204 
01205                             crpix1 = cpl_propertylist_get_double(sub_header,
01206                                                                  CRPIX1);
01207                             crpix2 = cpl_propertylist_get_double(sub_header,
01208                                                                  CRPIX2);
01209                             KMO_TRY_CHECK_ERROR_STATE();
01210                             crpix3 = 1;
01211                             KMO_TRY_CHECK_ERROR_STATE();
01212 
01213                             xshift = x1 - 1;
01214                             yshift = y1 - 1;
01215 
01216                             crpix1_new = crpix1 - xshift;
01217                             crpix2_new = crpix2 - yshift;
01218 
01219                             phys = cpl_matrix_new (2, 2);
01220                             cpl_matrix_set(phys, 0, 0, crpix1);
01221                             cpl_matrix_set(phys, 0, 1, crpix2);
01222                             cpl_matrix_set(phys, 1, 0, crpix1_new);
01223                             cpl_matrix_set(phys, 1, 1, crpix2_new);
01224 
01225                             KMO_TRY_EXIT_IF_NULL(
01226                                 wcs = cpl_wcs_new_from_propertylist(sub_header));
01227 
01228                             KMO_TRY_EXIT_IF_ERROR(
01229                                 cpl_wcs_convert(wcs, phys, &world, &status,
01230                                                 CPL_WCS_PHYS2WORLD));
01231 
01232                             crval1_new = cpl_matrix_get(world, 1, 0);
01233                             crval2_new = cpl_matrix_get(world, 1, 1);
01234                             crpix1_new = crpix1-2*xshift;
01235                             crpix2_new = crpix2-2*yshift;
01236 
01237                             // update WCS
01238                             KMO_TRY_EXIT_IF_ERROR(
01239                                 kmclipm_update_property_double(sub_header,
01240                                                                CRPIX1,
01241                                                                crpix1_new,
01242                                                  "[pix] Reference pixel in x"));
01243                             KMO_TRY_EXIT_IF_ERROR(
01244                                 kmclipm_update_property_double(sub_header,
01245                                                                CRPIX2,
01246                                                                crpix2_new,
01247                                                  "[pix] Reference pixel in y"));
01248                             KMO_TRY_EXIT_IF_ERROR(
01249                                 kmclipm_update_property_double(sub_header,
01250                                                                CRVAL1,
01251                                                                crval1_new,
01252                                                      "[deg] RA at ref. pixel"));
01253                             KMO_TRY_EXIT_IF_ERROR(
01254                                 kmclipm_update_property_double(sub_header,
01255                                                                CRVAL2,
01256                                                                crval2_new,
01257                                                     "[deg] DEC at ref. pixel"));
01258 
01259                             cpl_matrix_delete(phys); phys = NULL;
01260                             cpl_matrix_delete(world); world = NULL;
01261                             cpl_array_delete(status); status = NULL;
01262                             cpl_wcs_delete(wcs); wcs = NULL;
01263                         }
01264 
01265                         KMO_TRY_EXIT_IF_ERROR(
01266                             kmo_dfs_save_image(res_img, COPY, "", sub_header, 0./0.));
01267                         cpl_image_delete(res_img); res_img = NULL;
01268                     } else if (res_imglist != NULL) {
01269                         // update WCS in x- and y-direction because it got smaller
01270                         if ((desc.fits_type == f3i_fits) &&
01271                             (cpl_propertylist_has(sub_header, CRPIX1)) &&
01272                             (cpl_propertylist_has(sub_header, CRPIX2)) &&
01273                             ((x1 != 1) || (y1 != 1)))
01274                         {
01275                             crpix1 = cpl_propertylist_get_double(sub_header,
01276                                                                  CRPIX1);
01277                             crpix2 = cpl_propertylist_get_double(sub_header,
01278                                                                  CRPIX2);
01279                             crpix3 = cpl_propertylist_get_double(sub_header,
01280                                                                  CRPIX3);
01281                             KMO_TRY_CHECK_ERROR_STATE();
01282 
01283                             xshift = x1 - 1;
01284                             yshift = y1 - 1;
01285 
01286                             crpix1_new = crpix1 - xshift;
01287                             crpix2_new = crpix2 - yshift;
01288 
01289                             phys = cpl_matrix_new (2, 3);
01290                             cpl_matrix_set(phys, 0, 0, crpix1);
01291                             cpl_matrix_set(phys, 0, 1, crpix2);
01292                             cpl_matrix_set(phys, 0, 2, crpix3);
01293                             cpl_matrix_set(phys, 1, 0, crpix1_new);
01294                             cpl_matrix_set(phys, 1, 1, crpix2_new);
01295                             cpl_matrix_set(phys, 1, 2, crpix3);
01296 
01297                             KMO_TRY_EXIT_IF_NULL(
01298                                 wcs = cpl_wcs_new_from_propertylist(sub_header));
01299 
01300                             KMO_TRY_EXIT_IF_ERROR(
01301                                 cpl_wcs_convert(wcs, phys, &world, &status,
01302                                                 CPL_WCS_PHYS2WORLD));
01303 
01304                             crval1_new = cpl_matrix_get(world, 1, 0);
01305                             crval2_new = cpl_matrix_get(world, 1, 1);
01306                             crpix1_new = crpix1-2*xshift;
01307                             crpix2_new = crpix2-2*yshift;
01308 
01309                             // update WCS
01310                             KMO_TRY_EXIT_IF_ERROR(
01311                                 kmclipm_update_property_double(sub_header,
01312                                                                CRPIX1,
01313                                                                crpix1_new,
01314                                                  "[pix] Reference pixel in x"));
01315                             KMO_TRY_EXIT_IF_ERROR(
01316                                 kmclipm_update_property_double(sub_header,
01317                                                                CRPIX2,
01318                                                                crpix2_new,
01319                                                  "[pix] Reference pixel in y"));
01320                             KMO_TRY_EXIT_IF_ERROR(
01321                                 kmclipm_update_property_double(sub_header,
01322                                                                CRVAL1,
01323                                                                crval1_new,
01324                                                      "[deg] RA at ref. pixel"));
01325                             KMO_TRY_EXIT_IF_ERROR(
01326                                 kmclipm_update_property_double(sub_header,
01327                                                                CRVAL2,
01328                                                                crval2_new,
01329                                                     "[deg] DEC at ref. pixel"));
01330 
01331                             cpl_matrix_delete(phys); phys = NULL;
01332                             cpl_matrix_delete(world); world = NULL;
01333                             cpl_array_delete(status); status = NULL;
01334                             cpl_wcs_delete(wcs); wcs = NULL;
01335                         }
01336 
01337                         // update WCS in z-direction, because starting point
01338                         // isn't 1 anymore
01339                         if ((cpl_propertylist_has(sub_header, CRPIX3)) &&
01340                             (z1 != 1))
01341                         {
01342                             crpix3 = cpl_propertylist_get_double(sub_header,
01343                                                                  CRPIX3);
01344                             KMO_TRY_CHECK_ERROR_STATE();
01345 
01346                             crpix3_new = crpix3 - z1 + 1;
01347                             KMO_TRY_EXIT_IF_ERROR(
01348                                 kmclipm_update_property_double(sub_header,
01349                                                                CRPIX3,
01350                                                                crpix3_new,
01351                                                  "[pix] Reference pixel in z"));
01352                         }
01353                         KMO_TRY_EXIT_IF_ERROR(
01354                             kmo_dfs_save_cube(res_imglist, COPY, "",
01355                                               sub_header, 0./0.));
01356 
01357                         cpl_imagelist_delete(res_imglist); res_imglist = NULL;
01358                     }
01359                 /* --- IFU is invalid --> copy only header --- */
01360                 } else {
01361                     /* invalid IFU, just save sub_header */
01362                     KMO_TRY_EXIT_IF_ERROR(
01363                         kmo_dfs_save_sub_header(COPY, "", sub_header));
01364                 }
01365 
01366                 cpl_propertylist_delete(sub_header); sub_header = NULL;
01367             }
01368         }
01369     }
01370     KMO_CATCH
01371     {
01372         KMO_CATCH_MSG();
01373 
01374         ret_val = -1;
01375     }
01376 
01377     cpl_propertylist_delete(sub_header); sub_header = NULL;
01378     kmo_free_fits_desc(&desc);
01379     kmclipm_vector_delete(vec); vec = NULL;
01380     kmclipm_vector_delete(res_vec); res_vec = NULL;
01381     cpl_image_delete(img); img = NULL;
01382     cpl_image_delete(res_img); res_img = NULL;
01383     cpl_imagelist_delete(imglist); imglist = NULL;
01384     cpl_imagelist_delete(res_imglist); res_imglist = NULL;
01385 
01386     return ret_val;
01387 }
01388