KMOS Pipeline Reference Manual  1.1.4
kmo_make_image.c
00001 /* $Id: kmo_make_image.c,v 1.14 2013/05/23 10:19:14 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/23 10:19:14 $
00024  * $Revision: 1.14 $
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 "   OH_LIST               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             if (cpl_frameset_count_tags(frameset, OH_LIST) == 1) {
00369                 strcpy(do_mode1, "0");
00370                 strcpy(do_mode2, OH_LIST);
00371             } else {
00372                 strcpy(do_mode1, "0");
00373                 strcpy(do_mode2, "1");
00374             }
00375             KMO_TRY_EXIT_IF_NULL(
00376                 op2_frame = kmo_dfs_get_frame(frameset, do_mode2));
00377 
00378             desc2 = kmo_identify_fits_header(
00379                     cpl_frame_get_filename(op2_frame));
00380             KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem "
00381                                       "to be in KMOS-format! "
00382                                       "(KMOSTYPE must be F1S)!");
00383 
00384             KMO_TRY_ASSURE(desc2.fits_type == f1s_fits,
00385                            CPL_ERROR_ILLEGAL_INPUT,
00386                            "Second input file hasn't correct data type "
00387                            "(KMOSTYPE must be F1S)!");
00388         }
00389         KMO_TRY_EXIT_IF_NULL(
00390             op1_frame = kmo_dfs_get_frame(frameset, do_mode1));
00391 
00392         /* load descriptor of first operand */
00393         desc1 = kmo_identify_fits_header(
00394                     cpl_frame_get_filename(op1_frame));
00395         KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to be "
00396                                       "in KMOS-format!");
00397 
00398         KMO_TRY_ASSURE(desc1.fits_type == f3i_fits,
00399                        CPL_ERROR_ILLEGAL_INPUT,
00400                        "First input file hasn't correct data type "
00401                        "(KMOSTYPE must be F3I)!");
00402 
00403         if (cpl_frameset_get_size(frameset) == 1) {
00404             /* only cube is provided */
00405         } else if (cpl_frameset_get_size(frameset) == 2) {
00406             /* cube and OH line spectrum are provided */
00407             KMO_TRY_EXIT_IF_NULL(
00408                 spec_header = kmo_dfs_load_sub_header(frameset, do_mode2, 1,
00409                                                           FALSE));
00410 
00411             KMO_TRY_ASSURE(cpl_propertylist_get_int(spec_header, NAXIS) == 1,
00412                            CPL_ERROR_ILLEGAL_INPUT,
00413                            "Second input file has to be a vector!");
00414 
00415             /* load header & data of OH-lines*/
00416             spec_crpix = cpl_propertylist_get_int(spec_header, CRPIX1);
00417             KMO_TRY_CHECK_ERROR_STATE();
00418             spec_crval = cpl_propertylist_get_double(spec_header, CRVAL1);
00419             KMO_TRY_CHECK_ERROR_STATE();
00420             spec_cdelt = cpl_propertylist_get_double(spec_header, CDELT1);
00421             KMO_TRY_CHECK_ERROR_STATE();
00422 
00423             kmclipm_vector *tmp_vec = NULL;
00424             KMO_TRY_EXIT_IF_NULL(
00425                 tmp_vec = kmo_dfs_load_vector(frameset, do_mode2,
00426                                                    1, FALSE));
00427             KMO_TRY_EXIT_IF_NULL(
00428                 spec_data_in = kmclipm_vector_create_non_rejected(tmp_vec));
00429             kmclipm_vector_delete(tmp_vec); tmp_vec = NULL;
00430 
00431             /* convert threshold from percentage to absolute value*/
00432             threshold = threshold * cpl_vector_get_max(spec_data_in);
00433 
00434             /* create lambda-vector for OH-lines */
00435             KMO_TRY_EXIT_IF_NULL(
00436                 spec_lambda_in = kmo_create_lambda_vec(
00437                                     cpl_vector_get_size(spec_data_in),
00438                                     spec_crpix,
00439                                     spec_crval,
00440                                     spec_cdelt));
00441 
00442         } else {
00443             KMO_TRY_EXIT_WITH_ERROR(CPL_ERROR_ILLEGAL_INPUT);
00444         }
00445 
00446         // --- load, update & save primary header ---
00447         KMO_TRY_EXIT_IF_ERROR(
00448             kmo_dfs_save_main_header(frameset, MAKE_IMAGE, "", op1_frame,
00449                                      NULL, parlist, cpl_func));
00450 
00451         // --- load data ---
00452         if (desc1.ex_noise == TRUE) {
00453             nr_devices = desc1.nr_ext / 2;
00454         } else {
00455             nr_devices = desc1.nr_ext;
00456         }
00457 
00458         for (i = 1; i <= nr_devices; i++) {
00459             if (desc1.ex_noise == FALSE) {
00460                 devnr = desc1.sub_desc[i - 1].device_nr;
00461             } else {
00462                 devnr = desc1.sub_desc[2 * i - 1].device_nr;
00463             }
00464 
00465             if (desc1.ex_badpix == FALSE) {
00466                 index_data = kmo_identify_index_desc(desc1, devnr, FALSE);
00467             } else {
00468                 index_data = kmo_identify_index_desc(desc1, devnr, 2);
00469             }
00470             KMO_TRY_CHECK_ERROR_STATE();
00471 
00472             if (desc1.ex_noise) {
00473                 index_noise = kmo_identify_index_desc(desc1, devnr, TRUE);
00474             }
00475             KMO_TRY_CHECK_ERROR_STATE();
00476 
00477             KMO_TRY_EXIT_IF_NULL(
00478                 sub_header_data = kmo_dfs_load_sub_header(frameset, do_mode1,
00479                                                           devnr, FALSE));
00480 
00481             // check if IFU is valid
00482             valid_ifu = FALSE;
00483             if (desc1.sub_desc[index_data-1].valid_data == TRUE) {
00484                 valid_ifu = TRUE;
00485             }
00486 
00487             if (desc1.ex_noise) {
00488                 // load noise anyway since we have to save it in the output
00489                 KMO_TRY_EXIT_IF_NULL(
00490                     sub_header_noise = kmo_dfs_load_sub_header(frameset,
00491                                                                do_mode1, devnr,
00492                                                                TRUE));
00493 
00494                 if (cpl_propertylist_has(sub_header_noise, CRPIX3))
00495                     cpl_propertylist_erase(sub_header_noise, CRPIX3);
00496                 if (cpl_propertylist_has(sub_header_noise, CRVAL3))
00497                     cpl_propertylist_erase(sub_header_noise, CRVAL3);
00498                 if (cpl_propertylist_has(sub_header_noise, CDELT3))
00499                     cpl_propertylist_erase(sub_header_noise, CDELT3);
00500                 if (cpl_propertylist_has(sub_header_noise, CTYPE3))
00501                     cpl_propertylist_erase(sub_header_noise, CTYPE3);
00502                 if (cpl_propertylist_has(sub_header_noise, CUNIT3))
00503                     cpl_propertylist_erase(sub_header_noise, CUNIT3);
00504                 if (cpl_propertylist_has(sub_header_noise, CD1_3))
00505                     cpl_propertylist_erase(sub_header_noise, CD1_3);
00506                 if (cpl_propertylist_has(sub_header_noise, CD2_3))
00507                     cpl_propertylist_erase(sub_header_noise, CD2_3);
00508                 if (cpl_propertylist_has(sub_header_noise, CD3_3))
00509                     cpl_propertylist_erase(sub_header_noise, CD3_3);
00510                 if (cpl_propertylist_has(sub_header_noise, CD3_2))
00511                     cpl_propertylist_erase(sub_header_noise, CD3_2);
00512                 if (cpl_propertylist_has(sub_header_noise, CD3_1))
00513                     cpl_propertylist_erase(sub_header_noise, CD3_1);
00514             }
00515 
00516             if (valid_ifu) {
00517                 // load data
00518                 KMO_TRY_EXIT_IF_NULL(
00519                     data_in = kmo_dfs_load_cube(frameset, do_mode1,
00520                                                 devnr, FALSE));
00521 
00522                 // load noise, if existing
00523                 if (desc1.ex_noise && desc1.sub_desc[index_noise-1].valid_data) {
00524                     KMO_TRY_EXIT_IF_NULL(
00525                         noise_in = kmo_dfs_load_cube(frameset, do_mode1, devnr,
00526                                                      TRUE));
00527                 }
00528 
00529                 // interpolate oh-lines to fit input data
00530                 if (spec_data_in != NULL) {
00531                     ifu_crpix = cpl_propertylist_get_int(sub_header_data,
00532                                                          CRPIX3);
00533                     KMO_TRY_CHECK_ERROR_STATE_MSG(
00534                         "CRPIX3 keyword in FITS-header is missing!");
00535 
00536                     ifu_crval = cpl_propertylist_get_double(sub_header_data,
00537                                                             CRVAL3);
00538                     KMO_TRY_CHECK_ERROR_STATE_MSG(
00539                         "CRVAL3 keyword in FITS-header is missing!");
00540 
00541 
00542                     ifu_cdelt = cpl_propertylist_get_double(sub_header_data,
00543                                                             CDELT3);
00544                     KMO_TRY_CHECK_ERROR_STATE_MSG(
00545                         "CDELT3 keyword in FITS-header is missing!");
00546 
00547                     KMO_TRY_EXIT_IF_NULL(
00548                         identified_slices = kmo_identify_slices_with_oh(
00549                                                                 spec_data_in,
00550                                                                 spec_lambda_in,
00551                                                                 ranges,
00552                                                                 threshold,
00553                                                                 ifu_crpix,
00554                                                                 ifu_crval,
00555                                                                 ifu_cdelt,
00556                                                                 desc1.naxis3));
00557                 }
00558 
00559                 if (cpl_propertylist_has(sub_header_data, CRPIX3))
00560                     cpl_propertylist_erase(sub_header_data, CRPIX3);
00561                 if (cpl_propertylist_has(sub_header_data, CRVAL3))
00562                     cpl_propertylist_erase(sub_header_data, CRVAL3);
00563                 if (cpl_propertylist_has(sub_header_data, CDELT3))
00564                     cpl_propertylist_erase(sub_header_data, CDELT3);
00565                 if (cpl_propertylist_has(sub_header_data, CTYPE3))
00566                     cpl_propertylist_erase(sub_header_data, CTYPE3);
00567                 if (cpl_propertylist_has(sub_header_data, CUNIT3))
00568                     cpl_propertylist_erase(sub_header_data, CUNIT3);
00569                 if (cpl_propertylist_has(sub_header_data, CD1_3))
00570                     cpl_propertylist_erase(sub_header_data, CD1_3);
00571                 if (cpl_propertylist_has(sub_header_data, CD2_3))
00572                     cpl_propertylist_erase(sub_header_data, CD2_3);
00573                 if (cpl_propertylist_has(sub_header_data, CD3_3))
00574                     cpl_propertylist_erase(sub_header_data, CD3_3);
00575                 if (cpl_propertylist_has(sub_header_data, CD3_2))
00576                     cpl_propertylist_erase(sub_header_data, CD3_2);
00577                 if (cpl_propertylist_has(sub_header_data, CD3_1))
00578                     cpl_propertylist_erase(sub_header_data, CD3_1);
00579 
00580                 // process & save data
00581                 KMO_TRY_EXIT_IF_ERROR(
00582                     kmclipm_make_image(data_in, noise_in,
00583                                        &data_out, &noise_out,
00584                                        identified_slices,
00585                                        cmethod, cpos_rej, cneg_rej, citer,
00586                                        cmax, cmin));
00587 
00588                 KMO_TRY_EXIT_IF_ERROR(
00589                     kmo_dfs_save_image(data_out, MAKE_IMAGE, "",
00590                                        sub_header_data, 0./0.));
00591 
00592                 // process & save noise, if existing
00593                 if (desc1.ex_noise) {
00594                     KMO_TRY_EXIT_IF_ERROR(
00595                         kmo_dfs_save_image(noise_out, MAKE_IMAGE, "",
00596                                            sub_header_noise, 0./0.));
00597                 }
00598 
00599                 // free memory
00600                 cpl_imagelist_delete(data_in); data_in = NULL;
00601                 cpl_imagelist_delete(noise_in); noise_in = NULL;
00602                 cpl_image_delete(data_out); data_out = NULL;
00603                 cpl_image_delete(noise_out); noise_out = NULL;
00604                 cpl_vector_delete(identified_slices); identified_slices = NULL;
00605             } else {
00606                 if (cpl_propertylist_has(sub_header_data, CRPIX3))
00607                     cpl_propertylist_erase(sub_header_data, CRPIX3);
00608                 if (cpl_propertylist_has(sub_header_data, CRVAL3))
00609                     cpl_propertylist_erase(sub_header_data, CRVAL3);
00610                 if (cpl_propertylist_has(sub_header_data, CDELT3))
00611                     cpl_propertylist_erase(sub_header_data, CDELT3);
00612                 if (cpl_propertylist_has(sub_header_data, CTYPE3))
00613                     cpl_propertylist_erase(sub_header_data, CTYPE3);
00614                 if (cpl_propertylist_has(sub_header_data, CUNIT3))
00615                     cpl_propertylist_erase(sub_header_data, CUNIT3);
00616                 if (cpl_propertylist_has(sub_header_data, CD1_3))
00617                     cpl_propertylist_erase(sub_header_data, CD1_3);
00618                 if (cpl_propertylist_has(sub_header_data, CD2_3))
00619                     cpl_propertylist_erase(sub_header_data, CD2_3);
00620                 if (cpl_propertylist_has(sub_header_data, CD3_3))
00621                     cpl_propertylist_erase(sub_header_data, CD3_3);
00622                 if (cpl_propertylist_has(sub_header_data, CD3_2))
00623                     cpl_propertylist_erase(sub_header_data, CD3_2);
00624                 if (cpl_propertylist_has(sub_header_data, CD3_1))
00625                     cpl_propertylist_erase(sub_header_data, CD3_1);
00626 
00627                 // invalid IFU, just save sub_headers
00628                  KMO_TRY_EXIT_IF_ERROR(
00629                      kmo_dfs_save_sub_header(MAKE_IMAGE, "", sub_header_data));
00630 
00631                  if (desc1.ex_noise) {
00632                      KMO_TRY_EXIT_IF_ERROR(
00633                          kmo_dfs_save_sub_header(MAKE_IMAGE, "", sub_header_noise));
00634                  }
00635             }
00636 
00637             // free memory
00638             cpl_propertylist_delete(sub_header_data); sub_header_data = NULL;
00639             cpl_propertylist_delete(sub_header_noise); sub_header_noise = NULL;
00640         }
00641     }
00642     KMO_CATCH
00643     {
00644         KMO_CATCH_MSG();
00645         ret_val = -1;
00646     }
00647 
00648     kmo_free_fits_desc(&desc1);
00649     kmo_free_fits_desc(&desc2);
00650     cpl_propertylist_delete(sub_header_data); sub_header_data = NULL;
00651     cpl_propertylist_delete(sub_header_noise); sub_header_noise = NULL;
00652     cpl_propertylist_delete(spec_header); spec_header = NULL;
00653     cpl_imagelist_delete(data_in); data_in = NULL;
00654     cpl_imagelist_delete(noise_in); noise_in = NULL;
00655     cpl_image_delete(data_out); data_out = NULL;
00656     cpl_image_delete(noise_out); noise_out = NULL;
00657     cpl_vector_delete(spec_data_in); spec_data_in = NULL;
00658     cpl_vector_delete(spec_lambda_in); spec_lambda_in = NULL;
00659     cpl_vector_delete(ranges); ranges = NULL;
00660 
00661     return ret_val;
00662 }
00663