KMOS Pipeline Reference Manual  1.3.0
kmo_fit_profile.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 /*-----------------------------------------------------------------------------
00025  *                              Includes
00026  *----------------------------------------------------------------------------*/
00027 
00028 #include <string.h>
00029 #include <math.h>
00030 
00031 #include <cpl.h>
00032 
00033 #include "kmo_utils.h"
00034 #include "kmo_priv_fit_profile.h"
00035 #include "kmo_priv_functions.h"
00036 #include "kmo_dfs.h"
00037 #include "kmo_error.h"
00038 #include "kmo_constants.h"
00039 #include "kmo_debug.h"
00040 
00041 /*-----------------------------------------------------------------------------
00042  *                          Functions prototypes
00043  *----------------------------------------------------------------------------*/
00044 
00045 static int kmo_fit_profile_create(cpl_plugin *);
00046 static int kmo_fit_profile_exec(cpl_plugin *);
00047 static int kmo_fit_profile_destroy(cpl_plugin *);
00048 static int kmo_fit_profile(cpl_parameterlist *, cpl_frameset *);
00049 
00050 /*-----------------------------------------------------------------------------
00051  *                          Static variables
00052  *----------------------------------------------------------------------------*/
00053 
00054 static char kmo_fit_profile_description[] =
00055 "This recipe creates either spectral or spatial profiles of sources using dif-\n"
00056 "ferent functions to fit. Spectral profiles can be created for F1I frames (if\n"
00057 "WCS is defined in the input frame, the output parameters are in respect to the\n"
00058 "defined WCS).\n"
00059 "Spatial profiles can be created for F2I frames (any WCS information is ignored\n"
00060 "here).\n"
00061 "If the frames contain no noise information, constant noise is assumed for the\n"
00062 "fitting procedure.\n"
00063 "\n"
00064 "BASIC PARAMETERS:\n"
00065 "-----------------\n"
00066 "--method\n"
00067 "F1I frames can be fitted using either 'gauss', 'moffat' or 'lorentz' function.\n"
00068 "F2I frames can be fitted using either 'gauss' or 'moffat' function.\n"
00069 "\n"
00070 "ADVANCED PARAMETERS\n"
00071 "-------------------\n"
00072 "--range\n"
00073 "For F1I frames the spectral range can be defined. With available WCS informa-\n"
00074 "tion the range can be provided in units (e.g. “1.2;1.5”), otherwise in pixels\n"
00075 "(e.g. “112;224).\n"
00076 "For F2I frames the spatial range can be defined as follow: “x1,x2;y1,y2”\n"
00077 "\n"
00078 "-------------------------------------------------------------------------------\n"
00079 "  Input files:\n"
00080 "\n"
00081 "   DO                    KMOS                                                  \n"
00082 "   category              Type   Explanation                    Required #Frames\n"
00083 "   --------              -----  -----------                    -------- -------\n"
00084 "   <none or any>         F1I or Frame with or                     Y       1   \n"
00085 "                         F2I    without noise                                 \n"
00086 "\n"
00087 "  Output files:\n"
00088 "\n"
00089 "   DO                    KMOS\n"
00090 "   category              Type   Explanation\n"
00091 "   --------              -----  -----------\n"
00092 "   FIT_PROFILE           F1I    Fitted profile (without noise frame)\n"
00093 "                         or     (3 Extensions)                      \n"
00094 "                         F2I                                        \n"
00095 "-------------------------------------------------------------------------------\n"
00096 "\n";
00097 
00098 /*-----------------------------------------------------------------------------
00099  *                              Functions code
00100  *----------------------------------------------------------------------------*/
00101 
00118 int cpl_plugin_get_info(cpl_pluginlist *list)
00119 {
00120     cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
00121     cpl_plugin *plugin = &recipe->interface;
00122 
00123     cpl_plugin_init(plugin,
00124                         CPL_PLUGIN_API,
00125                         KMOS_BINARY_VERSION,
00126                         CPL_PLUGIN_TYPE_RECIPE,
00127                         "kmo_fit_profile",
00128                         "Fit spectral line profiles as well as spatial profiles"
00129                         " with a simple function - for example to measure "
00130                         "resolution or find the centre of a source",
00131                         kmo_fit_profile_description,
00132                         "Alex Agudo Berbel",
00133                         "usd-help@eso.org",
00134                         kmos_get_license(),
00135                         kmo_fit_profile_create,
00136                         kmo_fit_profile_exec,
00137                         kmo_fit_profile_destroy);
00138 
00139     cpl_pluginlist_append(list, plugin);
00140 
00141     return 0;
00142 }
00143 
00151 static int kmo_fit_profile_create(cpl_plugin *plugin)
00152 {
00153     cpl_recipe *recipe;
00154     cpl_parameter *p;
00155 
00156     /* Check that the plugin is part of a valid recipe */
00157     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00158         recipe = (cpl_recipe *)plugin;
00159     else
00160         return -1;
00161 
00162     /* Create the parameters list in the cpl_recipe object */
00163     recipe->parameters = cpl_parameterlist_new();
00164 
00165     /* Fill the parameters list */
00166     /* --method */
00167     p = cpl_parameter_new_value("kmos.kmo_fit_profile.method",
00168                                 CPL_TYPE_STRING,
00169                                 "Either fit \"gauss\", \"moffat\" or "
00170                                 "\"lorentz\" for 1D data."
00171                                 "Either fit \"gauss\" or \"moffat\" for "
00172                                 "2D data. ",
00173                                 "kmos.kmo_fit_profile",
00174                                 "gauss");
00175     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "method");
00176     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00177     cpl_parameterlist_append(recipe->parameters, p);
00178 
00179     /* --range */
00180     p = cpl_parameter_new_value("kmos.kmo_fit_profile.range",
00181                                 CPL_TYPE_STRING,
00182                                 "The spectral or spatial range to combine. "
00183                                 "Default is the whole range. "
00184                                 "e.g. F1I: \"0.5,2.1\" (microns), "
00185                                 "e.g. F2I: \"1,7;3,10\" (pixels: x1,x2;y1,y2), "
00186                                 "pixels are counted from 1.",
00187                                 "kmos.kmo_fit_profile",
00188                                 "");
00189     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "range");
00190     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00191     cpl_parameterlist_append(recipe->parameters, p);
00192 
00193     return 0;
00194 }
00195 
00201 static int kmo_fit_profile_exec(cpl_plugin *plugin)
00202 {
00203     cpl_recipe  *recipe;
00204 
00205     /* Get the recipe out of the plugin */
00206     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00207         recipe = (cpl_recipe *)plugin;
00208     else return -1;
00209 
00210     return kmo_fit_profile(recipe->parameters, recipe->frames);
00211 }
00212 
00218 static int kmo_fit_profile_destroy(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     cpl_parameterlist_delete(recipe->parameters);
00228     return 0 ;
00229 }
00230 
00245 static int kmo_fit_profile(cpl_parameterlist *parlist, cpl_frameset *frameset)
00246 {
00247     cpl_image       *data_img_in            = NULL,
00248                     *data_img_in2           = NULL,
00249                     *data_img_out           = NULL,
00250                     *noise_img_in           = NULL,
00251                     *noise_img_in2          = NULL;
00252 
00253     cpl_vector      *data_vec_in            = NULL,
00254                     *data_vec_out           = NULL,
00255                     *noise_vec_in           = NULL,
00256                     *ranges                 = NULL,
00257                     *ranges2                = NULL,
00258                     *fit_par                = NULL,
00259                     *lambda_vec             = NULL,
00260                     *lambda_vec2            = NULL,
00261                     *data_vec2              = NULL,
00262                     *noise_vec2             = NULL;
00263 
00264     cpl_frame        *frame                 = NULL;
00265 
00266     int              ret_val                = 0,
00267                      nr_devices             = 0,
00268                      i                      = 0,
00269                      j                      = 0,
00270                      x1                     = 0,
00271                      x2                     = 0,
00272                      y1                     = 0,
00273                      y2                     = 0,
00274                      valid_ifu              = FALSE,
00275                      devnr                  = 0,
00276                      index_data             = 0,
00277                      index_noise            = 0;
00278 
00279     double           crpix1                 = 0.0,
00280                      crval1                 = 0.0,
00281                      cdelt1                 = 0.0,
00282                      *pranges               = NULL;
00283 
00284     const char       *ranges_txt            = NULL,
00285                      *method                = NULL;
00286 
00287     cpl_propertylist *sub_header_data       = NULL,
00288                      *sub_header_noise      = NULL,
00289                      *pl                    = NULL;
00290 
00291     main_fits_desc   desc;
00292 
00293     KMO_TRY
00294     {
00295         kmo_init_fits_desc(&desc);
00296 
00297         /* --- check input --- */
00298         KMO_TRY_ASSURE((parlist != NULL) &&
00299                        (frameset != NULL),
00300                        CPL_ERROR_NULL_INPUT,
00301                        "Not all input data is provided!");
00302 
00303         KMO_TRY_ASSURE(cpl_frameset_get_size(frameset) == 1,
00304                        CPL_ERROR_NULL_INPUT,
00305                        "A fits-file must be provided!");
00306 
00307         KMO_TRY_EXIT_IF_NULL(
00308             frame = kmo_dfs_get_frame(frameset, "0"));
00309 
00310         /* load descriptor */
00311         desc = kmo_identify_fits_header(
00312                     cpl_frame_get_filename(frame));
00313         KMO_TRY_CHECK_ERROR_STATE();
00314 
00315         KMO_TRY_ASSURE((desc.fits_type == f2i_fits) ||
00316                        (desc.fits_type == f1i_fits),
00317                        CPL_ERROR_ILLEGAL_INPUT,
00318                        "DATA isn't in the correct format (either F2I or F1I)!");
00319 
00320         KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_fit_profile") == 1,
00321                        CPL_ERROR_ILLEGAL_INPUT,
00322                        "Cannot identify RAW and CALIB frames!");
00323 
00324         /* --- get parameters --- */
00325         cpl_msg_info(cpl_func, "--- Parameter setup for kmo_fit_profile ---");
00326 
00327         KMO_TRY_EXIT_IF_NULL(
00328             method = kmo_dfs_get_parameter_string(parlist,
00329                                            "kmos.kmo_fit_profile.method"));
00330         KMO_TRY_EXIT_IF_ERROR(
00331             kmo_dfs_print_parameter_help(parlist, "kmos.kmo_fit_profile.method"));
00332 
00333         ranges_txt = kmo_dfs_get_parameter_string(parlist,
00334                                                   "kmos.kmo_fit_profile.range");
00335         KMO_TRY_CHECK_ERROR_STATE();
00336         KMO_TRY_EXIT_IF_ERROR(
00337             kmo_dfs_print_parameter_help(parlist, "kmos.kmo_fit_profile.range"));
00338 
00339         cpl_msg_info("", "-------------------------------------------");
00340 
00341         if (strcmp(ranges_txt, "") != 0) {
00342 
00343             ranges = kmo_identify_ranges(ranges_txt);
00344             KMO_TRY_CHECK_ERROR_STATE();
00345 
00346             KMO_TRY_EXIT_IF_NULL(
00347                 pranges = cpl_vector_get_data(ranges));
00348 
00349             KMO_TRY_ASSURE((pranges[0] < pranges[1]),
00350                            CPL_ERROR_ILLEGAL_INPUT,
00351                            "x1 must be smaller than x2!");
00352 
00353             KMO_TRY_ASSURE((((desc.fits_type == f2i_fits) &&
00354                              (cpl_vector_get_size(ranges) == 4) ) || (
00355                              (desc.fits_type == f1i_fits) &&
00356                              (cpl_vector_get_size(ranges) == 2) )),
00357                      CPL_ERROR_ILLEGAL_INPUT,
00358                      "'range' must contain 2 values for F1I and "
00359                      "4 values for F2I!");
00360 
00361             if (desc.fits_type == f2i_fits) {
00362                 x1 = pranges[0];
00363                 x2 = pranges[1];
00364                 y1 = pranges[2];
00365                 y2 = pranges[3];
00366 
00367                 KMO_TRY_ASSURE((x1 > 0) &&
00368                                (y1 > 0) &&
00369                                (x2 < desc.naxis1) &&
00370                                (y2 < desc.naxis2),
00371                      CPL_ERROR_ILLEGAL_INPUT,
00372                      "Provided range is larger than images in F2I!");
00373 
00374                 KMO_TRY_ASSURE(y1 < y2,
00375                      CPL_ERROR_ILLEGAL_INPUT,
00376                      "y1 must be smaller than y2!");
00377 
00378             } else {
00379                 // for F1I-files this will be done individually for each
00380                 // extension.
00381             }
00382         } else {
00383             if (desc.fits_type == f2i_fits) {
00384                 x1 = 1;
00385                 x2 = desc.naxis1;
00386                 y1 = 1;
00387                 y2 = desc.naxis2;
00388             } else {
00389                 ranges = cpl_vector_new(2);
00390                 cpl_vector_set(ranges, 0, 1);
00391                 cpl_vector_set(ranges, 1, desc.naxis1);
00392             }
00393         }
00394 
00395         /* --- load & save primary header --- */
00396         KMO_TRY_EXIT_IF_ERROR(
00397             kmo_dfs_save_main_header(frameset, FIT_PROFILE, "", frame,
00398                                      NULL, parlist, cpl_func));
00399 
00400         /* --- load data --- */
00401         if (desc.ex_noise == TRUE) {
00402             nr_devices = desc.nr_ext / 2;
00403         } else {
00404             nr_devices = desc.nr_ext;
00405         }
00406 
00407         for (i = 1; i <= nr_devices; i++) {
00408             if (desc.ex_noise == FALSE) {
00409                 devnr = desc.sub_desc[i - 1].device_nr;
00410             } else {
00411                 devnr = desc.sub_desc[2 * i - 1].device_nr;
00412             }
00413 
00414             if (desc.ex_badpix == FALSE) {
00415                 index_data = kmo_identify_index_desc(desc, devnr, FALSE);
00416             } else {
00417                 index_data = kmo_identify_index_desc(desc, devnr, 2);
00418             }
00419             KMO_TRY_CHECK_ERROR_STATE();
00420 
00421             if (desc.ex_noise) {
00422                 index_noise = kmo_identify_index_desc(desc, devnr, TRUE);
00423             }
00424             KMO_TRY_CHECK_ERROR_STATE();
00425 
00426             KMO_TRY_EXIT_IF_NULL(
00427                 sub_header_data = kmo_dfs_load_sub_header(frameset, "0", devnr,
00428                                                           FALSE));
00429 
00430             // check if IFU is valid
00431             valid_ifu = FALSE;
00432             if (desc.sub_desc[index_data-1].valid_data == TRUE) {
00433                 valid_ifu = TRUE;
00434             }
00435 
00436             if (desc.ex_noise) {
00437                 // load noise anyway since we have to save it in the output
00438                 KMO_TRY_EXIT_IF_NULL(
00439                     sub_header_noise = kmo_dfs_load_sub_header(frameset, "0",
00440                                                                devnr, TRUE));
00441             }
00442 
00443             if (valid_ifu) {
00444                 if (desc.fits_type == f2i_fits) {
00445                     //
00446                     // process images
00447                     //
00448 
00449                     // load data
00450                     KMO_TRY_EXIT_IF_NULL(
00451                         data_img_in = kmo_dfs_load_image(frameset, "0",
00452                                                          devnr, FALSE, FALSE, NULL));
00453 
00454                     KMO_TRY_EXIT_IF_NULL(
00455                         data_img_in2 = cpl_image_extract(data_img_in,
00456                                                          x1, y1, x2, y2));
00457 
00458                     // load noise, if existing
00459                     if (desc.ex_noise && desc.sub_desc[index_noise-1].valid_data) {
00460                         KMO_TRY_EXIT_IF_NULL(
00461                             noise_img_in = kmo_dfs_load_image(frameset, "0",
00462                                                               devnr, TRUE, FALSE, NULL));
00463 
00464                         KMO_TRY_EXIT_IF_NULL(
00465                             noise_img_in2 = cpl_image_extract(noise_img_in,
00466                                                               x1, y1, x2, y2));
00467                     }
00468 
00469                     // process data
00470                     KMO_TRY_EXIT_IF_NULL(
00471                         fit_par = kmo_fit_profile_2D(data_img_in2,
00472                                                      noise_img_in2,
00473                                                      method,
00474                                                      &data_img_out,
00475                                                      &pl));
00476                     cpl_vector_delete(fit_par); fit_par = NULL;
00477 
00478                     // update subheader with fit parameters
00479                     KMO_TRY_EXIT_IF_ERROR(
00480                         cpl_propertylist_append(sub_header_data, pl));
00481 
00482                     /* save data  (noise is omitted for the fitted data)*/
00483                     KMO_TRY_EXIT_IF_ERROR(
00484                         kmo_dfs_save_image(data_img_out, FIT_PROFILE, "",
00485                                            sub_header_data, 0./0.));
00486 
00487                     /* free memory */
00488                     cpl_image_delete(data_img_in); data_img_in = NULL;
00489                     cpl_image_delete(data_img_in2); data_img_in2 = NULL;
00490                     cpl_image_delete(data_img_out); data_img_out = NULL;
00491                     cpl_image_delete(noise_img_in); noise_img_in = NULL;
00492                     cpl_image_delete(noise_img_in2); noise_img_in2 = NULL;
00493                 } else {
00494                     //
00495                     // process vectors
00496                     //
00497 
00498                     // load data
00499 kmclipm_vector *ddd = NULL;
00500                     KMO_TRY_EXIT_IF_NULL(
00501                         ddd = kmo_dfs_load_vector(frameset, "0",
00502                                                   devnr, FALSE));
00503 data_vec_in = kmclipm_vector_create_non_rejected(ddd);
00504 kmclipm_vector_delete(ddd); ddd = NULL;
00505 
00506                     // extract CRVAL, CRPIX and CDELT to convert the ranges-
00507                     // vector from spectral- to pixel-space
00508                     if (cpl_propertylist_has(sub_header_data, CRPIX1) &&
00509                         cpl_propertylist_has(sub_header_data, CRVAL1) &&
00510                         cpl_propertylist_has(sub_header_data, CDELT1))
00511                     {
00512                         crpix1 = cpl_propertylist_get_double(sub_header_data,
00513                                                                 CRPIX1);
00514                         crval1 = cpl_propertylist_get_double(sub_header_data,
00515                                                                 CRVAL1);
00516                         cdelt1 = cpl_propertylist_get_double(sub_header_data,
00517                                                                 CDELT1);
00518 
00519                         if (strcmp(ranges_txt, "") == 0) {
00520                             cpl_vector_set(ranges, 0,
00521                                 crpix1*crval1 +
00522                                     cdelt1*(cpl_vector_get(ranges,0)-1));
00523                             cpl_vector_set(ranges, 1,
00524                                 crpix1*crval1 +
00525                                     cdelt1*(cpl_vector_get(ranges,1)-1));
00526                         }
00527                     } else {
00528                         // set crpix1 to 2 because the output position should
00529                         // be zero-based
00530                         // (like in the cpl_vector definition)
00531 //                        crpix1 = 2;
00532                         crpix1 = 1;
00533                         crval1 = 1;
00534                         cdelt1 = 1;
00535                     }
00536 
00537                     // ranges2 will have the same size as the input spectra
00538                     // and will contain zeros for positions outside the provided
00539                     // spectral range and ones for values inside
00540                     KMO_TRY_EXIT_IF_NULL(
00541                         ranges2 = kmo_identify_slices(ranges,
00542                                                   crpix1,
00543                                                   crval1,
00544                                                   cdelt1,
00545                                                   desc.naxis1));
00546                     KMO_TRY_EXIT_IF_NULL(
00547                         pranges = cpl_vector_get_data(ranges2));
00548 
00549                     x1 = -1; x2 = -1;
00550                     for (j = 0; j < cpl_vector_get_size(ranges2); j++) {
00551                         if ((pranges[j] == 1) && (x1 == -1)) {
00552                             x1 = j;
00553                         }
00554                         if ((pranges[j] == 1) && (x1 != -1)) {
00555                             x2 = j;
00556                         }
00557                     }
00558                     cpl_vector_delete(ranges2); ranges2 = NULL;
00559 
00560                     // create lambda-vector for IFU
00561                     KMO_TRY_EXIT_IF_NULL(
00562                         lambda_vec = kmo_create_lambda_vec(desc.naxis1,
00563                                                            crpix1,
00564                                                            crval1,
00565                                                            cdelt1));
00566 
00567                     KMO_TRY_EXIT_IF_NULL(
00568                         lambda_vec2 = cpl_vector_extract(lambda_vec, x1, x2, 1));
00569 
00570                     KMO_TRY_EXIT_IF_NULL(
00571                         data_vec2 = cpl_vector_extract(data_vec_in, x1, x2, 1));
00572 
00573                     // load noise, if existing and
00574                     // extract same range as with data
00575                     if (desc.ex_noise  && desc.sub_desc[index_noise-1].valid_data) {
00576                         KMO_TRY_EXIT_IF_NULL(
00577                             ddd = kmo_dfs_load_vector(frameset, "0",
00578                                                       devnr, TRUE));
00579 noise_vec_in = kmclipm_vector_create_non_rejected(ddd);
00580 kmclipm_vector_delete(ddd); ddd =NULL;
00581 
00582                         KMO_TRY_EXIT_IF_NULL(
00583                             noise_vec2 = cpl_vector_extract(noise_vec_in,
00584                                                                x1, x2, 1));
00585                     }
00586 
00587                     // process data
00588                     KMO_TRY_EXIT_IF_NULL(
00589                         fit_par = kmo_fit_profile_1D(lambda_vec2,
00590                                                      data_vec2,
00591                                                      noise_vec2,
00592                                                      method,
00593                                                      &data_vec_out,
00594                                                      &pl));
00595 
00596                     cpl_vector_delete(fit_par); fit_par = NULL;
00597 
00598                     // update CRPIX if WCS information is available
00599                     if (cpl_propertylist_has(sub_header_data, CRPIX1) &&
00600                         cpl_propertylist_has(sub_header_data, CRVAL1) &&
00601                         cpl_propertylist_has(sub_header_data, CDELT1))
00602                     {
00603                         KMO_TRY_EXIT_IF_ERROR(
00604                             kmclipm_update_property_double(sub_header_data,
00605                                                            CRPIX1,
00606                                                            crpix1-x1,
00607                                                "[pix] Reference pixel in x"));
00608 
00609                         if (desc.ex_noise) {
00610                             KMO_TRY_EXIT_IF_ERROR(
00611                                 kmclipm_update_property_double(sub_header_noise,
00612                                                                CRPIX1,
00613                                                                crpix1-x1,
00614                                                "[pix] Reference pixel in x"));
00615                         }
00616                     }
00617 
00618                     // append fit parameters and errors
00619                     KMO_TRY_EXIT_IF_ERROR(
00620                         cpl_propertylist_append(sub_header_data, pl));
00621 
00622                     // save data  (noise is omitted for the fitted data)
00623 ddd = kmclipm_vector_create(cpl_vector_duplicate(data_vec_out));
00624                     KMO_TRY_EXIT_IF_ERROR(
00625                         kmo_dfs_save_vector(ddd, FIT_PROFILE, "",
00626                                            sub_header_data, 0./0.));
00627 kmclipm_vector_delete(ddd); ddd = NULL;
00628 
00629                     // free memory
00630                     cpl_vector_delete(data_vec_in); data_vec_in = NULL;
00631                     cpl_vector_delete(data_vec_out); data_vec_out = NULL;
00632                     cpl_vector_delete(noise_vec_in); noise_vec_in = NULL;
00633                     cpl_vector_delete(noise_vec2); noise_vec2 = NULL;
00634                     cpl_vector_delete(lambda_vec); lambda_vec = NULL;
00635                     cpl_vector_delete(lambda_vec2); lambda_vec2 = NULL;
00636                     cpl_vector_delete(data_vec2); data_vec2 = NULL;
00637                 }
00638 
00639                 cpl_propertylist_delete(pl); pl = NULL;
00640             } else {
00641                 // invalid IFU, just save sub_headers */
00642                 KMO_TRY_EXIT_IF_ERROR(
00643                     kmo_dfs_save_sub_header(FIT_PROFILE, "", sub_header_data));
00644 
00645                 if (desc.ex_noise) {
00646                     KMO_TRY_EXIT_IF_ERROR(
00647                         kmo_dfs_save_sub_header(FIT_PROFILE, "", sub_header_noise));
00648                 }
00649             }
00650 
00651             // free memory
00652             cpl_propertylist_delete(sub_header_data); sub_header_data = NULL;
00653             cpl_propertylist_delete(sub_header_noise); sub_header_noise = NULL;
00654         }
00655     }
00656     KMO_CATCH
00657     {
00658         KMO_CATCH_MSG();
00659         ret_val = -1;
00660     }
00661 
00662     kmo_free_fits_desc(&desc);
00663     cpl_image_delete(data_img_in); data_img_in = NULL;
00664     cpl_image_delete(data_img_in2); data_img_in2 = NULL;
00665     cpl_image_delete(data_img_out); data_img_out = NULL;
00666     cpl_image_delete(noise_img_in); noise_img_in = NULL;
00667     cpl_image_delete(noise_img_in2); noise_img_in2 = NULL;
00668     cpl_vector_delete(data_vec_in); data_vec_in = NULL;
00669     cpl_vector_delete(data_vec2); data_vec2 = NULL;
00670     cpl_vector_delete(data_vec_out); data_vec_out = NULL;
00671     cpl_vector_delete(noise_vec_in); noise_vec_in = NULL;
00672     cpl_vector_delete(noise_vec2); noise_vec2 = NULL;
00673     cpl_vector_delete(lambda_vec); lambda_vec = NULL;
00674     cpl_vector_delete(lambda_vec2); lambda_vec2 = NULL;
00675     cpl_vector_delete(fit_par); fit_par = NULL;
00676     cpl_vector_delete(ranges); ranges = NULL;
00677     cpl_vector_delete(ranges2); ranges2 = NULL;
00678     cpl_propertylist_delete(sub_header_data); sub_header_data = NULL;
00679     cpl_propertylist_delete(sub_header_noise); sub_header_noise = NULL;
00680 
00681     return ret_val;
00682 }
00683