KMOS Pipeline Reference Manual  1.2.8
kmo_make_image.c
00001 /* $Id: kmo_make_image.c,v 1.16 2013-06-07 13:37:26 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-06-07 13:37:26 $
00024  * $Revision: 1.16 $
00025  * $Name: not supported by cvs2svn $
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(cpl_frame_get_filename(op2_frame));
00374             KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem "
00375                                           "to be in KMOS-format! "
00376                                           "(KMOSTYPE must be F1S)!");
00377 
00378             KMO_TRY_ASSURE(desc2.fits_type == f1s_fits,
00379                            CPL_ERROR_ILLEGAL_INPUT,
00380                            "Second input file hasn't correct data type "
00381                            "(KMOSTYPE must be F1S)!");
00382         }
00383         KMO_TRY_EXIT_IF_NULL(
00384             op1_frame = kmo_dfs_get_frame(frameset, do_mode1));
00385 
00386         // load descriptor of first operand
00387         desc1 = kmo_identify_fits_header( cpl_frame_get_filename(op1_frame));
00388         KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to be "
00389                                       "in KMOS-format!");
00390 
00391         KMO_TRY_ASSURE(desc1.fits_type == f3i_fits,
00392                        CPL_ERROR_ILLEGAL_INPUT,
00393                        "First input file hasn't correct data type "
00394                        "(KMOSTYPE must be F3I)!");
00395 
00396         if (cpl_frameset_get_size(frameset) == 1) {
00397             // only cube is provided
00398         } else if (cpl_frameset_get_size(frameset) == 2) {
00399             // cube and OH line spectrum are provided
00400             KMO_TRY_EXIT_IF_NULL(
00401                 spec_header = kmo_dfs_load_sub_header(frameset, do_mode2, 1, FALSE));
00402 
00403             KMO_TRY_ASSURE(cpl_propertylist_get_int(spec_header, NAXIS) == 1,
00404                            CPL_ERROR_ILLEGAL_INPUT,
00405                            "Second input file has to be a vector!");
00406 
00407             // load header & data of OH-lines
00408             switch (cpl_propertylist_get_type(spec_header, CRPIX1)) {
00409             case CPL_TYPE_INT:
00410                 spec_crpix = cpl_propertylist_get_int(spec_header, CRPIX1);
00411                 break;
00412             case CPL_TYPE_DOUBLE:
00413                 spec_crpix = cpl_propertylist_get_double(spec_header, CRPIX1);
00414                 break;
00415             case CPL_TYPE_FLOAT:
00416                 spec_crpix = cpl_propertylist_get_float(spec_header, CRPIX1);
00417                 break;
00418             default:
00419                 KMO_TRY_ASSURE(1 == 0,
00420                                CPL_ERROR_ILLEGAL_INPUT,
00421                                "CRPIX1 is of wrong type!");
00422             }
00423             KMO_TRY_CHECK_ERROR_STATE();
00424             spec_crval = cpl_propertylist_get_double(spec_header, CRVAL1);
00425             KMO_TRY_CHECK_ERROR_STATE();
00426             spec_cdelt = cpl_propertylist_get_double(spec_header, CDELT1);
00427             KMO_TRY_CHECK_ERROR_STATE();
00428 
00429             kmclipm_vector *tmp_vec = NULL;
00430             KMO_TRY_EXIT_IF_NULL(
00431                 tmp_vec = kmo_dfs_load_vector(frameset, do_mode2, 1, FALSE));
00432             KMO_TRY_EXIT_IF_NULL(
00433                 spec_data_in = kmclipm_vector_create_non_rejected(tmp_vec));
00434             kmclipm_vector_delete(tmp_vec); tmp_vec = NULL;
00435 
00436             // convert threshold from percentage to absolute value
00437             threshold = threshold * cpl_vector_get_max(spec_data_in);
00438 
00439             // create lambda-vector for OH-lines
00440             KMO_TRY_EXIT_IF_NULL(
00441                 spec_lambda_in = kmo_create_lambda_vec(
00442                                     cpl_vector_get_size(spec_data_in),
00443                                     spec_crpix,
00444                                     spec_crval,
00445                                     spec_cdelt));
00446 
00447         } else {
00448             KMO_TRY_EXIT_WITH_ERROR(CPL_ERROR_ILLEGAL_INPUT);
00449         }
00450 
00451         // --- load, update & save primary header ---
00452         KMO_TRY_EXIT_IF_ERROR(
00453             kmo_dfs_save_main_header(frameset, MAKE_IMAGE, "", op1_frame,
00454                                      NULL, parlist, cpl_func));
00455 
00456         // --- load data ---
00457         if (desc1.ex_noise == TRUE) {
00458             nr_devices = desc1.nr_ext / 2;
00459         } else {
00460             nr_devices = desc1.nr_ext;
00461         }
00462 
00463         for (i = 1; i <= nr_devices; i++) {
00464             if (desc1.ex_noise == FALSE) {
00465                 devnr = desc1.sub_desc[i - 1].device_nr;
00466             } else {
00467                 devnr = desc1.sub_desc[2 * i - 1].device_nr;
00468             }
00469 
00470             if (desc1.ex_badpix == FALSE) {
00471                 index_data = kmo_identify_index_desc(desc1, devnr, FALSE);
00472             } else {
00473                 index_data = kmo_identify_index_desc(desc1, devnr, 2);
00474             }
00475             KMO_TRY_CHECK_ERROR_STATE();
00476 
00477             if (desc1.ex_noise) {
00478                 index_noise = kmo_identify_index_desc(desc1, devnr, TRUE);
00479             }
00480             KMO_TRY_CHECK_ERROR_STATE();
00481 
00482             KMO_TRY_EXIT_IF_NULL(
00483                 sub_header_data = kmo_dfs_load_sub_header(frameset, do_mode1,
00484                                                           devnr, FALSE));
00485 
00486             // check if IFU is valid
00487             valid_ifu = FALSE;
00488             if (desc1.sub_desc[index_data-1].valid_data == TRUE) {
00489                 valid_ifu = TRUE;
00490             }
00491 
00492             if (desc1.ex_noise) {
00493                 // load noise anyway since we have to save it in the output
00494                 KMO_TRY_EXIT_IF_NULL(
00495                     sub_header_noise = kmo_dfs_load_sub_header(frameset, do_mode1,
00496                                                                devnr, TRUE));
00497 
00498                 if (cpl_propertylist_has(sub_header_noise, CRPIX3))
00499                     cpl_propertylist_erase(sub_header_noise, CRPIX3);
00500                 if (cpl_propertylist_has(sub_header_noise, CRVAL3))
00501                     cpl_propertylist_erase(sub_header_noise, CRVAL3);
00502                 if (cpl_propertylist_has(sub_header_noise, CDELT3))
00503                     cpl_propertylist_erase(sub_header_noise, CDELT3);
00504                 if (cpl_propertylist_has(sub_header_noise, CTYPE3))
00505                     cpl_propertylist_erase(sub_header_noise, CTYPE3);
00506                 if (cpl_propertylist_has(sub_header_noise, CUNIT3))
00507                     cpl_propertylist_erase(sub_header_noise, CUNIT3);
00508                 if (cpl_propertylist_has(sub_header_noise, CD1_3))
00509                     cpl_propertylist_erase(sub_header_noise, CD1_3);
00510                 if (cpl_propertylist_has(sub_header_noise, CD2_3))
00511                     cpl_propertylist_erase(sub_header_noise, CD2_3);
00512                 if (cpl_propertylist_has(sub_header_noise, CD3_3))
00513                     cpl_propertylist_erase(sub_header_noise, CD3_3);
00514                 if (cpl_propertylist_has(sub_header_noise, CD3_2))
00515                     cpl_propertylist_erase(sub_header_noise, CD3_2);
00516                 if (cpl_propertylist_has(sub_header_noise, CD3_1))
00517                     cpl_propertylist_erase(sub_header_noise, CD3_1);
00518             }
00519 
00520             if (valid_ifu) {
00521                 // load data
00522                 KMO_TRY_EXIT_IF_NULL(
00523                     data_in = kmo_dfs_load_cube(frameset, do_mode1,
00524                                                 devnr, FALSE));
00525 
00526                 // load noise, if existing
00527                 if (desc1.ex_noise && desc1.sub_desc[index_noise-1].valid_data) {
00528                     KMO_TRY_EXIT_IF_NULL(
00529                         noise_in = kmo_dfs_load_cube(frameset, do_mode1, devnr,
00530                                                      TRUE));
00531                 }
00532 
00533                 // interpolate oh-lines to fit input data
00534                 if (spec_data_in != NULL) {
00535                     ifu_crpix = cpl_propertylist_get_double(sub_header_data, CRPIX3);
00536                     KMO_TRY_CHECK_ERROR_STATE_MSG(
00537                         "CRPIX3 keyword in FITS-header is missing!");
00538 
00539                     ifu_crval = cpl_propertylist_get_double(sub_header_data, CRVAL3);
00540                     KMO_TRY_CHECK_ERROR_STATE_MSG(
00541                         "CRVAL3 keyword in FITS-header is missing!");
00542 
00543 
00544                     ifu_cdelt = cpl_propertylist_get_double(sub_header_data, CDELT3);
00545                     KMO_TRY_CHECK_ERROR_STATE_MSG(
00546                         "CDELT3 keyword in FITS-header is missing!");
00547 
00548                     KMO_TRY_EXIT_IF_NULL(
00549                         identified_slices = kmo_identify_slices_with_oh(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