KMOS Pipeline Reference Manual  1.1.5
kmo_make_image.c
00001 /* $Id: kmo_make_image.c,v 1.15 2013/05/24 13:35:28 aagudo Exp $
00002  *
00003  * This file is part of the KMOS Pipeline
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: aagudo $
00023  * $Date: 2013/05/24 13:35:28 $
00024  * $Revision: 1.15 $
00025  * $Name: HEAD $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 #include <string.h>
00033 
00034 #include <cpl.h>
00035 
00036 #include "kmo_debug.h"
00037 #include "kmo_utils.h"
00038 #include "kmo_dfs.h"
00039 #include "kmo_error.h"
00040 #include "kmo_priv_make_image.h"
00041 #include "kmo_priv_functions.h"
00042 #include "kmo_constants.h"
00043 
00044 static int kmo_make_image_create(cpl_plugin *);
00045 static int kmo_make_image_exec(cpl_plugin *);
00046 static int kmo_make_image_destroy(cpl_plugin *);
00047 static int kmo_make_image(cpl_parameterlist *, cpl_frameset *);
00048 
00049 static char kmo_make_image_description[] =
00050 "This recipe collapses a cube along the spectral axis using rejection. By \n"
00051 "default all spectral slices are averaged.\n"
00052 "Errors are propagated for the same spectral ranges as for the input data if\n"
00053 "a noise map is provided.\n"
00054 "\n"
00055 "BASIC PARAMETERS:\n"
00056 "-----------------\n"
00057 "--range\n"
00058 "The spectral range can be delimited to one or several sub-ranges like \"1.8,1.9\"\n"
00059 "or \"1.8,1.9; 2.0,2.11\"\n"
00060 "\n"
00061 "--cmethod\n"
00062 "Following methods of frame combination are available:\n"
00063 "   * 'ksigma' (Default)\n"
00064 "   An iterative sigma clipping. For each position all pixels in the spectrum\n"
00065 "   are examined. If they deviate significantly, they will be rejected according\n"
00066 "   to the conditions:\n"
00067 "       val > mean + stdev * cpos_rej\n"
00068 "   and\n"
00069 "       val < mean - stdev * cneg_rej\n"
00070 "   where --cpos_rej, --cneg_rej and --citer are the corresponding configuration\n"
00071 "   parameters. In the first iteration median and percentile level are used.\n"
00072 "\n"
00073 "   * 'median'\n"
00074 "   At each pixel position the median is calculated.\n"
00075 "\n"
00076 "   * 'average'\n"
00077 "   At each pixel position the average is calculated.\n"
00078 "\n"
00079 "   * 'sum'\n"
00080 "   At each pixel position the sum is calculated.\n"
00081 "\n"
00082 "   * 'min_max'\n"
00083 "   The specified number of minimum and maximum pixel values will be rejected.\n"
00084 "   --cmax and --cmin apply to this method.\n"
00085 "\n"
00086 "ADVANCED PARAMETERS\n"
00087 "-------------------\n"
00088 "--threshold\n"
00089 "Optionally an OH spectrum can be provided. In this case a threshold can be\n"
00090 "defined. The wavelengths of values above the threshold level in the OH spectrum\n"
00091 "are omitted in the input frame. This parameter can be combined with the --range\n"
00092 "parameter. Negative threshold values are ignored.\n"
00093 "Own spectra can be converted into the required F1S KMOS FITS format for the OH\n"
00094 "spectrum using kmo_fits_stack.\n"
00095 "\n"
00096 "--cpos_rej\n"
00097 "--cneg_rej\n"
00098 "--citer\n"
00099 "see --cmethod='ksigma'\n"
00100 "\n"
00101 "--cmax\n"
00102 "--cmin\n"
00103 "see --cmethod='min_max'\n"
00104 "\n"
00105 "-------------------------------------------------------------------------------\n"
00106 "  Input files:\n"
00107 "\n"
00108 "   DO                    KMOS                                                  \n"
00109 "   category              Type   Explanation                    Required #Frames\n"
00110 "   --------              -----  -----------                    -------- -------\n"
00111 "   <none or any>         F3I    data frame                         Y       1   \n"
00112 "   <none or any>         F1S    OH line spectrum                   N      0,1  \n"
00113 "\n"
00114 "  Output files:\n"
00115 "\n"
00116 "   DO                    KMOS\n"
00117 "   category              Type   Explanation\n"
00118 "   --------              -----  -----------\n"
00119 "   MAKE_IMAGE            F2I    Collapsed data cubes\n"
00120 "-------------------------------------------------------------------------------\n"
00121 "\n";
00122 
00140 int cpl_plugin_get_info(cpl_pluginlist *list)
00141 {
00142     cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
00143     cpl_plugin *plugin = &recipe->interface;
00144 
00145     cpl_plugin_init(plugin,
00146                         CPL_PLUGIN_API,
00147                         KMOS_BINARY_VERSION,
00148                         CPL_PLUGIN_TYPE_RECIPE,
00149                         "kmo_make_image",
00150                         "Collapse a cube to create a spatial image",
00151                         kmo_make_image_description,
00152                         "Alex Agudo Berbel",
00153                         "kmos-spark@mpe.mpg.de",
00154                         kmos_get_license(),
00155                         kmo_make_image_create,
00156                         kmo_make_image_exec,
00157                         kmo_make_image_destroy);
00158 
00159     cpl_pluginlist_append(list, plugin);
00160 
00161     return 0;
00162 }
00163 
00171 static int kmo_make_image_create(cpl_plugin *plugin)
00172 {
00173     cpl_recipe *recipe;
00174     cpl_parameter *p;
00175 
00176     /* Check that the plugin is part of a valid recipe */
00177     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00178         recipe = (cpl_recipe *)plugin;
00179     else
00180         return -1;
00181 
00182     /* Create the parameters list in the cpl_recipe object */
00183     recipe->parameters = cpl_parameterlist_new();
00184 
00185     /* Fill the parameters list */
00186     /* --range */
00187     p = cpl_parameter_new_value("kmos.kmo_make_image.range",
00188                                 CPL_TYPE_STRING,
00189                                 "The spectral ranges to combine. e.g."
00190                                 "\"x1_start,x1_end;x2_start,x2_end\" (microns)",
00191                                 "kmos.kmo_make_image",
00192                                 "");
00193     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "range");
00194     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00195     cpl_parameterlist_append(recipe->parameters, p);
00196 
00197     /* --threshold (if < 0, no thresholding at all) */
00198     p = cpl_parameter_new_value("kmos.kmo_make_image.threshold",
00199                                 CPL_TYPE_DOUBLE,
00200                                 "The OH threshold level (%)",
00201                                 "kmos.kmo_make_image",
00202                                 0.1);
00203     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "threshold");
00204     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00205     cpl_parameterlist_append(recipe->parameters, p);
00206 
00207     return kmo_combine_pars_create(recipe->parameters,
00208                                    "kmos.kmo_make_image",
00209                                    DEF_REJ_METHOD,
00210                                    FALSE);
00211 }
00212 
00218 static int kmo_make_image_exec(cpl_plugin *plugin)
00219 {
00220     cpl_recipe  *recipe;
00221 
00222     /* Get the recipe out of the plugin */
00223     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00224         recipe = (cpl_recipe *)plugin;
00225     else return -1 ;
00226 
00227     return kmo_make_image(recipe->parameters, recipe->frames);
00228 }
00229 
00235 static int kmo_make_image_destroy(cpl_plugin *plugin)
00236 {
00237     cpl_recipe *recipe;
00238 
00239     /* Get the recipe out of the plugin */
00240     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00241         recipe = (cpl_recipe *)plugin;
00242     else return -1 ;
00243 
00244     cpl_parameterlist_delete(recipe->parameters);
00245     return 0 ;
00246 }
00247 
00262 static int kmo_make_image(cpl_parameterlist *parlist, cpl_frameset *frameset)
00263 {
00264     const char       *cmethod             = NULL;
00265 
00266     double           threshold           = 0.0,
00267                      spec_crval          = 0.0,
00268                      spec_cdelt          = 0.0,
00269                      ifu_crval           = 0.0,
00270                      ifu_cdelt           = 0.0,
00271                      cpos_rej            = 0.0,
00272                      cneg_rej            = 0.0;
00273 
00274     cpl_imagelist    *data_in            = NULL,
00275                      *noise_in           = NULL;
00276 
00277     cpl_image        *data_out           = NULL,
00278                      *noise_out          = NULL;
00279 
00280     const char       *ranges_txt         = NULL;
00281 
00282     cpl_vector       *ranges             = NULL,
00283                      *identified_slices  = NULL,
00284                      *spec_data_in       = NULL,
00285                      *spec_lambda_in     = NULL;
00286 
00287     int              ret_val             = 0,
00288                      nr_devices          = 0,
00289                      i                   = 0,
00290                      valid_ifu           = FALSE,
00291                      citer               = 0,
00292                      cmax                = 0,
00293                      cmin                = 0,
00294                      ifu_crpix           = 0,
00295                      spec_crpix          = 0,
00296                      devnr               = 0,
00297                      index_data          = 0,
00298                      index_noise         = 0;
00299 
00300     cpl_propertylist *sub_header_data    = NULL,
00301                      *sub_header_noise   = NULL,
00302                      *spec_header         = NULL;
00303 
00304     main_fits_desc   desc1,
00305                      desc2;
00306 
00307     cpl_frame        *op1_frame          = NULL,
00308                      *op2_frame          = NULL;
00309 
00310     char             do_mode1[256],
00311                      do_mode2[256];
00312 
00313     KMO_TRY
00314     {
00315         kmo_init_fits_desc(&desc1);
00316         kmo_init_fits_desc(&desc2);
00317 
00318         /* --- check input --- */
00319         KMO_TRY_ASSURE((parlist != NULL) &&
00320                        (frameset != NULL),
00321                        CPL_ERROR_NULL_INPUT,
00322                        "Not all input data is provided!");
00323 
00324         KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_make_image") == 1,
00325                        CPL_ERROR_ILLEGAL_INPUT,
00326                        "Cannot identify RAW and CALIB frames!");
00327 
00328         cpl_msg_info("", "--- Parameter setup for kmo_make_image ----");
00329 
00330         threshold = kmo_dfs_get_parameter_double(parlist,
00331                                           "kmos.kmo_make_image.threshold");
00332         KMO_TRY_CHECK_ERROR_STATE();
00333         KMO_TRY_EXIT_IF_ERROR(
00334             kmo_dfs_print_parameter_help(parlist, "kmos.kmo_make_image.threshold"));
00335 
00336         ranges_txt = kmo_dfs_get_parameter_string(parlist,
00337                                                   "kmos.kmo_make_image.range");
00338         KMO_TRY_CHECK_ERROR_STATE();
00339         KMO_TRY_EXIT_IF_ERROR(
00340             kmo_dfs_print_parameter_help(parlist, "kmos.kmo_make_image.range"));
00341 
00342         ranges = kmo_identify_ranges(ranges_txt);
00343         KMO_TRY_CHECK_ERROR_STATE();
00344 
00345         KMO_TRY_EXIT_IF_ERROR(
00346             kmo_combine_pars_load(parlist,
00347                                   "kmos.kmo_make_image",
00348                                   &cmethod,
00349                                   &cpos_rej,
00350                                   &cneg_rej,
00351                                   &citer,
00352                                   &cmin,
00353                                   &cmax,
00354                                   FALSE));
00355         cpl_msg_info("", "-------------------------------------------");
00356 
00357         KMO_TRY_ASSURE((cpl_frameset_get_size(frameset) == 1) ||
00358                        ((cpl_frameset_get_size(frameset) == 2) &&
00359                        (threshold != 0.0)),
00360                        CPL_ERROR_NULL_INPUT,
00361                        "A cube or a cube and a OH line spectrum "
00362                        "must be provided!");
00363 
00364         if (cpl_frameset_get_size(frameset) == 1) {
00365             strcpy(do_mode1, "0");
00366             strcpy(do_mode2, "");
00367         } else {
00368             strcpy(do_mode1, "0");
00369             strcpy(do_mode2, "1");
00370             KMO_TRY_EXIT_IF_NULL(
00371                 op2_frame = kmo_dfs_get_frame(frameset, do_mode2));
00372 
00373             desc2 = kmo_identify_fits_header(
00374                     cpl_frame_get_filename(op2_frame));
00375             KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem "
00376                                       "to be in KMOS-format! "
00377                                       "(KMOSTYPE must be F1S)!");
00378 
00379             KMO_TRY_ASSURE(desc2.fits_type == f1s_fits,
00380                            CPL_ERROR_ILLEGAL_INPUT,
00381                            "Second input file hasn't correct data type "
00382                            "(KMOSTYPE must be F1S)!");
00383         }
00384         KMO_TRY_EXIT_IF_NULL(
00385             op1_frame = kmo_dfs_get_frame(frameset, do_mode1));
00386 
00387         /* load descriptor of first operand */
00388         desc1 = kmo_identify_fits_header(
00389                     cpl_frame_get_filename(op1_frame));
00390         KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to be "
00391                                       "in KMOS-format!");
00392 
00393         KMO_TRY_ASSURE(desc1.fits_type == f3i_fits,
00394                        CPL_ERROR_ILLEGAL_INPUT,
00395                        "First input file hasn't correct data type "
00396                        "(KMOSTYPE must be F3I)!");
00397 
00398         if (cpl_frameset_get_size(frameset) == 1) {
00399             /* only cube is provided */
00400         } else if (cpl_frameset_get_size(frameset) == 2) {
00401             /* cube and OH line spectrum are provided */
00402             KMO_TRY_EXIT_IF_NULL(
00403                 spec_header = kmo_dfs_load_sub_header(frameset, do_mode2, 1,
00404                                                           FALSE));
00405 
00406             KMO_TRY_ASSURE(cpl_propertylist_get_int(spec_header, NAXIS) == 1,
00407                            CPL_ERROR_ILLEGAL_INPUT,
00408                            "Second input file has to be a vector!");
00409 
00410             /* load header & data of OH-lines*/
00411             spec_crpix = cpl_propertylist_get_int(spec_header, CRPIX1);
00412             KMO_TRY_CHECK_ERROR_STATE();
00413             spec_crval = cpl_propertylist_get_double(spec_header, CRVAL1);
00414             KMO_TRY_CHECK_ERROR_STATE();
00415             spec_cdelt = cpl_propertylist_get_double(spec_header, CDELT1);
00416             KMO_TRY_CHECK_ERROR_STATE();
00417 
00418             kmclipm_vector *tmp_vec = NULL;
00419             KMO_TRY_EXIT_IF_NULL(
00420                 tmp_vec = kmo_dfs_load_vector(frameset, do_mode2,
00421                                                    1, FALSE));
00422             KMO_TRY_EXIT_IF_NULL(
00423                 spec_data_in = kmclipm_vector_create_non_rejected(tmp_vec));
00424             kmclipm_vector_delete(tmp_vec); tmp_vec = NULL;
00425 
00426             /* convert threshold from percentage to absolute value*/
00427             threshold = threshold * cpl_vector_get_max(spec_data_in);
00428 
00429             /* create lambda-vector for OH-lines */
00430             KMO_TRY_EXIT_IF_NULL(
00431                 spec_lambda_in = kmo_create_lambda_vec(
00432                                     cpl_vector_get_size(spec_data_in),
00433                                     spec_crpix,
00434                                     spec_crval,
00435                                     spec_cdelt));
00436 
00437         } else {
00438             KMO_TRY_EXIT_WITH_ERROR(CPL_ERROR_ILLEGAL_INPUT);
00439         }
00440 
00441         // --- load, update & save primary header ---
00442         KMO_TRY_EXIT_IF_ERROR(
00443             kmo_dfs_save_main_header(frameset, MAKE_IMAGE, "", op1_frame,
00444                                      NULL, parlist, cpl_func));
00445 
00446         // --- load data ---
00447         if (desc1.ex_noise == TRUE) {
00448             nr_devices = desc1.nr_ext / 2;
00449         } else {
00450             nr_devices = desc1.nr_ext;
00451         }
00452 
00453         for (i = 1; i <= nr_devices; i++) {
00454             if (desc1.ex_noise == FALSE) {
00455                 devnr = desc1.sub_desc[i - 1].device_nr;
00456             } else {
00457                 devnr = desc1.sub_desc[2 * i - 1].device_nr;
00458             }
00459 
00460             if (desc1.ex_badpix == FALSE) {
00461                 index_data = kmo_identify_index_desc(desc1, devnr, FALSE);
00462             } else {
00463                 index_data = kmo_identify_index_desc(desc1, devnr, 2);
00464             }
00465             KMO_TRY_CHECK_ERROR_STATE();
00466 
00467             if (desc1.ex_noise) {
00468                 index_noise = kmo_identify_index_desc(desc1, devnr, TRUE);
00469             }
00470             KMO_TRY_CHECK_ERROR_STATE();
00471 
00472             KMO_TRY_EXIT_IF_NULL(
00473                 sub_header_data = kmo_dfs_load_sub_header(frameset, do_mode1,
00474                                                           devnr, FALSE));
00475 
00476             // check if IFU is valid
00477             valid_ifu = FALSE;
00478             if (desc1.sub_desc[index_data-1].valid_data == TRUE) {
00479                 valid_ifu = TRUE;
00480             }
00481 
00482             if (desc1.ex_noise) {
00483                 // load noise anyway since we have to save it in the output
00484                 KMO_TRY_EXIT_IF_NULL(
00485                     sub_header_noise = kmo_dfs_load_sub_header(frameset,
00486                                                                do_mode1, devnr,
00487                                                                TRUE));
00488 
00489                 if (cpl_propertylist_has(sub_header_noise, CRPIX3))
00490                     cpl_propertylist_erase(sub_header_noise, CRPIX3);
00491                 if (cpl_propertylist_has(sub_header_noise, CRVAL3))
00492                     cpl_propertylist_erase(sub_header_noise, CRVAL3);
00493                 if (cpl_propertylist_has(sub_header_noise, CDELT3))
00494                     cpl_propertylist_erase(sub_header_noise, CDELT3);
00495                 if (cpl_propertylist_has(sub_header_noise, CTYPE3))
00496                     cpl_propertylist_erase(sub_header_noise, CTYPE3);
00497                 if (cpl_propertylist_has(sub_header_noise, CUNIT3))
00498                     cpl_propertylist_erase(sub_header_noise, CUNIT3);
00499                 if (cpl_propertylist_has(sub_header_noise, CD1_3))
00500                     cpl_propertylist_erase(sub_header_noise, CD1_3);
00501                 if (cpl_propertylist_has(sub_header_noise, CD2_3))
00502                     cpl_propertylist_erase(sub_header_noise, CD2_3);
00503                 if (cpl_propertylist_has(sub_header_noise, CD3_3))
00504                     cpl_propertylist_erase(sub_header_noise, CD3_3);
00505                 if (cpl_propertylist_has(sub_header_noise, CD3_2))
00506                     cpl_propertylist_erase(sub_header_noise, CD3_2);
00507                 if (cpl_propertylist_has(sub_header_noise, CD3_1))
00508                     cpl_propertylist_erase(sub_header_noise, CD3_1);
00509             }
00510 
00511             if (valid_ifu) {
00512                 // load data
00513                 KMO_TRY_EXIT_IF_NULL(
00514                     data_in = kmo_dfs_load_cube(frameset, do_mode1,
00515                                                 devnr, FALSE));
00516 
00517                 // load noise, if existing
00518                 if (desc1.ex_noise && desc1.sub_desc[index_noise-1].valid_data) {
00519                     KMO_TRY_EXIT_IF_NULL(
00520                         noise_in = kmo_dfs_load_cube(frameset, do_mode1, devnr,
00521                                                      TRUE));
00522                 }
00523 
00524                 // interpolate oh-lines to fit input data
00525                 if (spec_data_in != NULL) {
00526                     ifu_crpix = cpl_propertylist_get_int(sub_header_data,
00527                                                          CRPIX3);
00528                     KMO_TRY_CHECK_ERROR_STATE_MSG(
00529                         "CRPIX3 keyword in FITS-header is missing!");
00530 
00531                     ifu_crval = cpl_propertylist_get_double(sub_header_data,
00532                                                             CRVAL3);
00533                     KMO_TRY_CHECK_ERROR_STATE_MSG(
00534                         "CRVAL3 keyword in FITS-header is missing!");
00535 
00536 
00537                     ifu_cdelt = cpl_propertylist_get_double(sub_header_data,
00538                                                             CDELT3);
00539                     KMO_TRY_CHECK_ERROR_STATE_MSG(
00540                         "CDELT3 keyword in FITS-header is missing!");
00541 
00542                     KMO_TRY_EXIT_IF_NULL(
00543                         identified_slices = kmo_identify_slices_with_oh(
00544                                                                 spec_data_in,
00545                                                                 spec_lambda_in,
00546                                                                 ranges,
00547                                                                 threshold,
00548                                                                 ifu_crpix,
00549                                                                 ifu_crval,
00550                                                                 ifu_cdelt,
00551                                                                 desc1.naxis3));
00552                 }
00553 
00554                 if (cpl_propertylist_has(sub_header_data, CRPIX3))
00555                     cpl_propertylist_erase(sub_header_data, CRPIX3);
00556                 if (cpl_propertylist_has(sub_header_data, CRVAL3))
00557                     cpl_propertylist_erase(sub_header_data, CRVAL3);
00558                 if (cpl_propertylist_has(sub_header_data, CDELT3))
00559                     cpl_propertylist_erase(sub_header_data, CDELT3);
00560                 if (cpl_propertylist_has(sub_header_data, CTYPE3))
00561                     cpl_propertylist_erase(sub_header_data, CTYPE3);
00562                 if (cpl_propertylist_has(sub_header_data, CUNIT3))
00563                     cpl_propertylist_erase(sub_header_data, CUNIT3);
00564                 if (cpl_propertylist_has(sub_header_data, CD1_3))
00565                     cpl_propertylist_erase(sub_header_data, CD1_3);
00566                 if (cpl_propertylist_has(sub_header_data, CD2_3))
00567                     cpl_propertylist_erase(sub_header_data, CD2_3);
00568                 if (cpl_propertylist_has(sub_header_data, CD3_3))
00569                     cpl_propertylist_erase(sub_header_data, CD3_3);
00570                 if (cpl_propertylist_has(sub_header_data, CD3_2))
00571                     cpl_propertylist_erase(sub_header_data, CD3_2);
00572                 if (cpl_propertylist_has(sub_header_data, CD3_1))
00573                     cpl_propertylist_erase(sub_header_data, CD3_1);
00574 
00575                 // process & save data
00576                 KMO_TRY_EXIT_IF_ERROR(
00577                     kmclipm_make_image(data_in, noise_in,
00578                                        &data_out, &noise_out,
00579                                        identified_slices,
00580                                        cmethod, cpos_rej, cneg_rej, citer,
00581                                        cmax, cmin));
00582 
00583                 KMO_TRY_EXIT_IF_ERROR(
00584                     kmo_dfs_save_image(data_out, MAKE_IMAGE, "",
00585                                        sub_header_data, 0./0.));
00586 
00587                 // process & save noise, if existing
00588                 if (desc1.ex_noise) {
00589                     KMO_TRY_EXIT_IF_ERROR(
00590                         kmo_dfs_save_image(noise_out, MAKE_IMAGE, "",
00591                                            sub_header_noise, 0./0.));
00592                 }
00593 
00594                 // free memory
00595                 cpl_imagelist_delete(data_in); data_in = NULL;
00596                 cpl_imagelist_delete(noise_in); noise_in = NULL;
00597                 cpl_image_delete(data_out); data_out = NULL;
00598                 cpl_image_delete(noise_out); noise_out = NULL;
00599                 cpl_vector_delete(identified_slices); identified_slices = NULL;
00600             } else {
00601                 if (cpl_propertylist_has(sub_header_data, CRPIX3))
00602                     cpl_propertylist_erase(sub_header_data, CRPIX3);
00603                 if (cpl_propertylist_has(sub_header_data, CRVAL3))
00604                     cpl_propertylist_erase(sub_header_data, CRVAL3);
00605                 if (cpl_propertylist_has(sub_header_data, CDELT3))
00606                     cpl_propertylist_erase(sub_header_data, CDELT3);
00607                 if (cpl_propertylist_has(sub_header_data, CTYPE3))
00608                     cpl_propertylist_erase(sub_header_data, CTYPE3);
00609                 if (cpl_propertylist_has(sub_header_data, CUNIT3))
00610                     cpl_propertylist_erase(sub_header_data, CUNIT3);
00611                 if (cpl_propertylist_has(sub_header_data, CD1_3))
00612                     cpl_propertylist_erase(sub_header_data, CD1_3);
00613                 if (cpl_propertylist_has(sub_header_data, CD2_3))
00614                     cpl_propertylist_erase(sub_header_data, CD2_3);
00615                 if (cpl_propertylist_has(sub_header_data, CD3_3))
00616                     cpl_propertylist_erase(sub_header_data, CD3_3);
00617                 if (cpl_propertylist_has(sub_header_data, CD3_2))
00618                     cpl_propertylist_erase(sub_header_data, CD3_2);
00619                 if (cpl_propertylist_has(sub_header_data, CD3_1))
00620                     cpl_propertylist_erase(sub_header_data, CD3_1);
00621 
00622                 // invalid IFU, just save sub_headers
00623                  KMO_TRY_EXIT_IF_ERROR(
00624                      kmo_dfs_save_sub_header(MAKE_IMAGE, "", sub_header_data));
00625 
00626                  if (desc1.ex_noise) {
00627                      KMO_TRY_EXIT_IF_ERROR(
00628                          kmo_dfs_save_sub_header(MAKE_IMAGE, "", sub_header_noise));
00629                  }
00630             }
00631 
00632             // free memory
00633             cpl_propertylist_delete(sub_header_data); sub_header_data = NULL;
00634             cpl_propertylist_delete(sub_header_noise); sub_header_noise = NULL;
00635         }
00636     }
00637     KMO_CATCH
00638     {
00639         KMO_CATCH_MSG();
00640         ret_val = -1;
00641     }
00642 
00643     kmo_free_fits_desc(&desc1);
00644     kmo_free_fits_desc(&desc2);
00645     cpl_propertylist_delete(sub_header_data); sub_header_data = NULL;
00646     cpl_propertylist_delete(sub_header_noise); sub_header_noise = NULL;
00647     cpl_propertylist_delete(spec_header); spec_header = NULL;
00648     cpl_imagelist_delete(data_in); data_in = NULL;
00649     cpl_imagelist_delete(noise_in); noise_in = NULL;
00650     cpl_image_delete(data_out); data_out = NULL;
00651     cpl_image_delete(noise_out); noise_out = NULL;
00652     cpl_vector_delete(spec_data_in); spec_data_in = NULL;
00653     cpl_vector_delete(spec_lambda_in); spec_lambda_in = NULL;
00654     cpl_vector_delete(ranges); ranges = NULL;
00655 
00656     return ret_val;
00657 }
00658