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