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