KMOS Pipeline Reference Manual  1.2.6
kmo_arithmetic.c
00001 /* $Id: kmo_arithmetic.c,v 1.15 2013-09-05 12:24:58 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-09-05 12:24:58 $
00024  * $Revision: 1.15 $
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_arithmetic.h"
00041 #include "kmo_constants.h"
00042 
00043 static int kmo_arithmetic_create(cpl_plugin *);
00044 static int kmo_arithmetic_exec(cpl_plugin *);
00045 static int kmo_arithmetic_destroy(cpl_plugin *);
00046 static int kmo_arithmetic(cpl_parameterlist *, cpl_frameset *);
00047 
00048 static char kmo_arithmetic_description[] =
00049 "With this recipe simple arithmetic operations, like addition, subtraction,\n"
00050 "multiplication, divison and raising to a power can be performed.\n"
00051 "Since FITS files formatted as F1I, F2I and F3I can contain data (and eventually\n"
00052 "noise) of either just one IFU or of all 24 IFUs, kmo_arithmetic behaves diffe-\n"
00053 "rently in these cases.\n"
00054 "When the number of IFUs is the same for both operands, the first IFU of the\n"
00055 "first operand is processed with the first IFU of the second operand.\n"
00056 "When the second operand has only one IFU while the first operand has more IFUs,\n"
00057 "then the all the IFUs of the first operand are processed individually which the\n"
00058 "IFU of the second operand.\n"
00059 "If an operand contains noise and the other doesn't, the noise will not be\n"
00060 "processed.\n"
00061 "\n"
00062 "Noise is only propagated if both operand contain noise extensions. If the\n"
00063 "second operator is a scalar noise is also propagated, of course.\n"
00064 "\n"
00065 "If two cubes are given as operands, they will be combined according to the \n"
00066 "given operator.If a cube is given as first operand and an image as second,\n"
00067 "then it operates on each slice of the cube; similarly if a spectrum is given\n"
00068 "as the second operand, it operates on each spectrum of the cube; and a number\n"
00069 "as the second operand operates on each pixel of the cube.\n"
00070 "\n"
00071 "BASIC PARAMETERS:\n"
00072 "-----------------\n"
00073 "--operator\n"
00074 "Any of the following operations to perform: '+', '-', '*' or '/' (also '^' \n"
00075 "when the 2nd operand is a scalar\n"
00076 "\n"
00077 "--scalar\n"
00078 "To be provided if a frame should be processed together with a scalar\n"
00079 "\n"
00080 "--file_extension"
00081 "Define a string to append to the product filename ARITHMETIC in order to get\n"
00082 "an unique filename\n"
00083 "\n"
00084 "-------------------------------------------------------------------------------\n"
00085 "  Input files:\n"
00086 "\n"
00087 "   DO                    KMOS                                                  \n"
00088 "   category              Type   Explanation                    Required #Frames\n"
00089 "   --------              -----  -----------                    -------- -------\n"
00090 "   <none or any>         F3I or Data with or                      Y        1   \n"
00091 "                         F2I or without noise frame                            \n"
00092 "                         F1I or                                                \n"
00093 "                         F2D or                                                \n"
00094 "                         RAW                                                   \n"
00095 "   <none or any>         F3I or Data with or                      N       0,1  \n"
00096 "                         F2I or without noise frame                            \n"
00097 "                         F1I or                                                \n"
00098 "                         F2D or                                                \n"
00099 "                         RAW                                                   \n"
00100 "\n"
00101 "  Output files:\n"
00102 "\n"
00103 "   DO                    KMOS\n"
00104 "   category              Type   Explanation\n"
00105 "   --------              -----  -----------\n"
00106 "   ARITHMETIC            F3I or                                                \n"
00107 "                         F2I or                                                \n"
00108 "                         F1I or                                                \n"
00109 "                         F2D                                                   \n"
00110 "-------------------------------------------------------------------------------\n"
00111 "\n";
00112 
00129 int cpl_plugin_get_info(cpl_pluginlist *list)
00130 {
00131     cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
00132     cpl_plugin *plugin = &recipe->interface;
00133 
00134     cpl_plugin_init(plugin,
00135                         CPL_PLUGIN_API,
00136                         KMOS_BINARY_VERSION,
00137                         CPL_PLUGIN_TYPE_RECIPE,
00138                         "kmo_arithmetic",
00139                         "Perform basic arithmetic on cubes",
00140                         kmo_arithmetic_description,
00141                         "Alex Agudo Berbel",
00142                         "kmos-spark@mpe.mpg.de",
00143                         kmos_get_license(),
00144                         kmo_arithmetic_create,
00145                         kmo_arithmetic_exec,
00146                         kmo_arithmetic_destroy);
00147 
00148     cpl_pluginlist_append(list, plugin);
00149 
00150     return 0;
00151 }
00152 
00160 static int kmo_arithmetic_create(cpl_plugin *plugin)
00161 {
00162     cpl_recipe *recipe;
00163     cpl_parameter *p;
00164 
00165     /* Check that the plugin is part of a valid recipe */
00166     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00167         recipe = (cpl_recipe *)plugin;
00168     else
00169         return -1;
00170 
00171     /* Create the parameters list in the cpl_recipe object */
00172     recipe->parameters = cpl_parameterlist_new();
00173 
00174     /* Fill the parameters list */
00175     /* --operator */
00176     p = cpl_parameter_new_value("kmos.kmo_arithmetic.operator",
00177                                 CPL_TYPE_STRING,
00178                                 "The operator ('+', '-', '*', '/' or '^')",
00179                                 "kmos.kmo_arithmetic",
00180                                 "");
00181     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "operator");
00182     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00183     cpl_parameterlist_append(recipe->parameters, p);
00184 
00185     /* --scalar */
00186     p = cpl_parameter_new_value("kmos.kmo_arithmetic.scalar",
00187                                 CPL_TYPE_DOUBLE,
00188                                 "The scalar operand",
00189                                 "kmos.kmo_arithmetic",
00190                                 -DBL_MAX);
00191     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "scalar");
00192     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00193     cpl_parameterlist_append(recipe->parameters, p);
00194 
00195     /* --file_extension */
00196     p = cpl_parameter_new_value("kmos.kmo_arithmetic.file_extension",
00197                                 CPL_TYPE_STRING,
00198                                 "String to add to product filename.",
00199                                 "kmos.kmo_arithmetic",
00200                                 "");
00201     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "file_extension");
00202     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00203     cpl_parameterlist_append(recipe->parameters, p);
00204 
00205     return 0;
00206 }
00207 
00213 static int kmo_arithmetic_exec(cpl_plugin *plugin)
00214 {
00215     cpl_recipe  *recipe;
00216 
00217     /* Get the recipe out of the plugin */
00218     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00219         recipe = (cpl_recipe *)plugin;
00220     else return -1 ;
00221 
00222     return kmo_arithmetic(recipe->parameters, recipe->frames);
00223 }
00224 
00230 static int kmo_arithmetic_destroy(cpl_plugin *plugin)
00231 {
00232     cpl_recipe *recipe;
00233 
00234     /* Get the recipe out of the plugin */
00235     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00236         recipe = (cpl_recipe *)plugin;
00237     else return -1 ;
00238 
00239     cpl_parameterlist_delete(recipe->parameters);
00240     return 0 ;
00241 }
00242 
00257 static int kmo_arithmetic(cpl_parameterlist *parlist, cpl_frameset *frameset)
00258 {
00259     const char       *op                 = NULL,
00260                      *file_extension     = NULL;
00261     char             *fn_out             = NULL;
00262     cpl_imagelist    *op1_3d             = NULL,
00263                      *op2_3d             = NULL,
00264                      *op1_noise_3d       = NULL,
00265                      *op2_noise_3d       = NULL;
00266     cpl_image        *op1_2d             = NULL,
00267                      *op2_2d             = NULL,
00268                      *op1_noise_2d       = NULL,
00269                      *op2_noise_2d       = NULL;
00270     kmclipm_vector   *op1_1d             = NULL,
00271                      *op2_1d             = NULL,
00272                      *op1_noise_1d       = NULL,
00273                      *op2_noise_1d       = NULL;
00274     double           op2_scalar          = -DBL_MAX;
00275     int              ret_val             = 0,
00276                      nr_devices          = 0,
00277                      i                   = 0,
00278                      single_ifu          = FALSE,
00279                      calc_f3i            = FALSE,
00280                      calc_f2i            = FALSE,
00281                      calc_f1i            = FALSE,
00282                      devnr1              = 0,
00283                      devnr2              = 0;
00284     cpl_propertylist *main_header        = NULL,
00285                      *sub_header_data    = NULL,
00286                      *sub_header_noise   = NULL;
00287     main_fits_desc   desc1,
00288                      desc2;
00289     cpl_frame        *op1_frame          = NULL,
00290                      *op2_frame          = NULL;
00291 
00292     KMO_TRY
00293     {
00294         kmo_init_fits_desc(&desc1);
00295         kmo_init_fits_desc(&desc2);
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(kmo_dfs_set_groups(frameset, "kmo_arithmetic") == 1,
00304                        CPL_ERROR_ILLEGAL_INPUT,
00305                        "Cannot identify RAW and CALIB frames!");
00306 
00307         cpl_msg_info("", "--- Parameter setup for kmo_arithmetic ----");
00308 
00309         op2_scalar = kmo_dfs_get_parameter_double(parlist,
00310                                           "kmos.kmo_arithmetic.scalar");
00311         KMO_TRY_CHECK_ERROR_STATE();
00312 
00313         KMO_TRY_ASSURE((cpl_frameset_get_size(frameset) == 2) ||
00314                        ((cpl_frameset_get_size(frameset) == 1) &&
00315                        (op2_scalar != -DBL_MAX)),
00316                        CPL_ERROR_NULL_INPUT,
00317                        "Two fits-files or one fits-file and one "
00318                        "scalar must be provided!");
00319 
00320         if (cpl_frameset_get_size(frameset) == 1) {
00321             KMO_TRY_EXIT_IF_ERROR(
00322                 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_arithmetic.scalar"));
00323         } else {
00324             KMO_TRY_EXIT_IF_NULL(
00325                 op2_frame = kmo_dfs_get_frame(frameset, "1"));
00326         }
00327         KMO_TRY_EXIT_IF_NULL(
00328             op1_frame = kmo_dfs_get_frame(frameset, "0"));
00329 
00330         KMO_TRY_EXIT_IF_NULL(
00331             op = kmo_dfs_get_parameter_string(parlist,
00332                                                "kmos.kmo_arithmetic.operator"));
00333         KMO_TRY_ASSURE((strcmp(op, "+") == 0) ||
00334                        (strcmp(op, "-") == 0) ||
00335                        (strcmp(op, "*") == 0) ||
00336                        (strcmp(op, "/") == 0) ||
00337                        (strcmp(op, "^") == 0),
00338                        CPL_ERROR_ILLEGAL_INPUT,
00339                        "Operator not valid! Has it been provided?");
00340 
00341         KMO_TRY_EXIT_IF_ERROR(
00342             kmo_dfs_print_parameter_help(parlist, "kmos.kmo_arithmetic.operator"));
00343 
00344         file_extension = kmo_dfs_get_parameter_string(parlist,
00345                                                       "kmos.kmo_arithmetic.file_extension");
00346         KMO_TRY_CHECK_ERROR_STATE();
00347 
00348         KMO_TRY_EXIT_IF_ERROR(
00349            kmo_dfs_print_parameter_help(parlist, "kmos.kmo_arithmetic.file_extension"));
00350 
00351         cpl_msg_info("", "-------------------------------------------");
00352 
00353         if (strcmp(file_extension, "") == 0) {
00354             fn_out = cpl_sprintf("%s", ARITHMETIC);
00355         } else {
00356             fn_out = cpl_sprintf("%s_%s", ARITHMETIC, file_extension);
00357         }
00358 
00359         // load descriptor, header and data of first operand
00360         desc1 = kmo_identify_fits_header(
00361                         cpl_frame_get_filename(op1_frame));
00362         KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to be "
00363                                       "in KMOS-format!");
00364 
00365         KMO_TRY_ASSURE((desc1.fits_type == f3i_fits) ||
00366                        (desc1.fits_type == f2i_fits) ||
00367                        (desc1.fits_type == f1i_fits) ||
00368                        (desc1.fits_type == f2d_fits) ||
00369                        (desc1.fits_type == raw_fits),
00370                        CPL_ERROR_ILLEGAL_INPUT,
00371                        "First input file hasn't correct data type "
00372                        "(KMOSTYPE must be F3I, F2I, F1I, F2D or RAW)!");
00373 
00374         // load descriptor, header of second operand
00375         if (op2_scalar == -DBL_MAX) {
00376             desc2 = kmo_identify_fits_header(
00377                             cpl_frame_get_filename(op2_frame));
00378             KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to "
00379                                           "be in KMOS-format!");
00380 
00381             if (desc1.fits_type == f3i_fits) {
00382                 KMO_TRY_ASSURE((desc2.fits_type == f3i_fits) ||
00383                                (desc2.fits_type == f2i_fits)||
00384                                (desc2.fits_type == f1i_fits),
00385                                CPL_ERROR_ILLEGAL_INPUT,
00386                                "For a F3I frame, the 2nd frame must be a "
00387                                "F3I, F2I or a F1I frame!");
00388 
00389                 if (desc2.fits_type == f3i_fits) {
00390                     KMO_TRY_ASSURE((desc1.naxis1 == desc2.naxis1) &&
00391                                    (desc1.naxis2 == desc2.naxis2) &&
00392                                    (desc1.naxis3 == desc2.naxis3),
00393                                    CPL_ERROR_INCOMPATIBLE_INPUT,
00394                                    "The dimensions of the two operands do "
00395                                    "not match!");
00396                 } else if (desc2.fits_type == f2i_fits) {
00397                     KMO_TRY_ASSURE((desc1.naxis1 == desc2.naxis1) &&
00398                                    (desc1.naxis2 == desc2.naxis2),
00399                                    CPL_ERROR_INCOMPATIBLE_INPUT,
00400                                    "The dimensions of the two operands do "
00401                                    "not match!");
00402                 } else if (desc2.fits_type == f1i_fits) {
00403                     KMO_TRY_ASSURE((desc1.naxis3 == desc2.naxis1),
00404                                    CPL_ERROR_INCOMPATIBLE_INPUT,
00405                                    "The dimensions of the two operands do "
00406                                    "not match!");
00407                 }
00408             } else if (desc1.fits_type == f2i_fits) {
00409                 KMO_TRY_ASSURE(desc2.fits_type == f2i_fits,
00410                                CPL_ERROR_ILLEGAL_INPUT,
00411                                "For a F2I frame, the 2nd frame must be a "
00412                                "F2I frame!");
00413                 KMO_TRY_ASSURE((desc1.naxis1 == desc2.naxis1) &&
00414                                (desc1.naxis2 == desc2.naxis2),
00415                                CPL_ERROR_INCOMPATIBLE_INPUT,
00416                                "The dimensions of the two operands do "
00417                                "not match!");
00418             } else if (desc1.fits_type == f1i_fits) {
00419                 KMO_TRY_ASSURE(desc2.fits_type == f1i_fits,
00420                                CPL_ERROR_ILLEGAL_INPUT,
00421                                "For a F1I frame, the 2nd frame must be a "
00422                                "F1I frame!");
00423                 KMO_TRY_ASSURE(desc1.naxis1 == desc2.naxis1,
00424                                CPL_ERROR_INCOMPATIBLE_INPUT,
00425                                "The dimensions of the two operands do "
00426                                "not match!");
00427             } else if (desc1.fits_type == f2d_fits) {
00428                 KMO_TRY_ASSURE((desc2.fits_type == f2d_fits) ||
00429                                ((desc2.fits_type == raw_fits) && (desc1.ex_noise == FALSE)),
00430                                CPL_ERROR_ILLEGAL_INPUT,
00431                                "For a F2D frame, the 2nd frame must be a "
00432                                "F2D frame!");
00433                 KMO_TRY_ASSURE((desc1.naxis1 == desc2.naxis1) &&
00434                                (desc1.naxis2 == desc2.naxis2),
00435                                CPL_ERROR_INCOMPATIBLE_INPUT,
00436                                "The dimensions of the two operands do "
00437                                "not match!");
00438             } else if (desc1.fits_type == raw_fits) {
00439                 KMO_TRY_ASSURE((desc2.fits_type == raw_fits) ||
00440                                ((desc2.fits_type == f2d_fits) && (desc2.ex_noise == FALSE)),
00441                                CPL_ERROR_ILLEGAL_INPUT,
00442                                "For a RAW frame, the 2nd frame must be a "
00443                                "RAW frame!");
00444                 KMO_TRY_ASSURE((desc1.naxis1 == desc2.naxis1) &&
00445                                (desc1.naxis2 == desc2.naxis2),
00446                                CPL_ERROR_INCOMPATIBLE_INPUT,
00447                                "The dimensions of the two operands do "
00448                                "not match!");
00449             }
00450 
00451             if (((desc2.nr_ext == 1) &&
00452                  (desc2.sub_desc[0].valid_data == TRUE))
00453                 ||
00454                 ((desc2.nr_ext == 2) &&
00455                  (desc2.ex_noise == TRUE) &&
00456                  (desc2.sub_desc[0].valid_data == TRUE) &&
00457                  (desc2.sub_desc[1].valid_data == TRUE))) {
00458                 single_ifu = TRUE;
00459             } else {
00460                 if (desc1.ex_noise == desc2.ex_noise) {
00461                     KMO_TRY_ASSURE(desc1.nr_ext == desc2.nr_ext,
00462                                   CPL_ERROR_INCOMPATIBLE_INPUT,
00463                                   "The number of IFUs of the two operands do "
00464                                   "not match!");
00465                 } else {
00466                     KMO_TRY_ASSURE(desc1.nr_ext == desc2.nr_ext * 2,
00467                                    CPL_ERROR_INCOMPATIBLE_INPUT,
00468                                    "The number of IFUs of the two operands do "
00469                                    "not match!");
00470                 }
00471             }
00472         }
00473 
00474         // --- load, update & save primary header ---
00475         KMO_TRY_EXIT_IF_ERROR(
00476             kmo_dfs_save_main_header(frameset, fn_out, "", op1_frame, NULL,
00477                                      parlist, cpl_func));
00478 
00479         //
00480         // load data
00481         //
00482         if (desc1.ex_noise == TRUE) {
00483             nr_devices = desc1.nr_ext / 2;
00484         } else {
00485             nr_devices = desc1.nr_ext;
00486         }
00487 
00488         if ((single_ifu == TRUE) &&
00489             (desc2.sub_desc[0].valid_data == TRUE))
00490         {
00491             switch (desc2.fits_type) {
00492                 case f3i_fits:
00493 
00494                     KMO_TRY_EXIT_IF_NULL(
00495                         op2_3d = kmo_dfs_load_cube(frameset, "1",
00496                                                    desc2.sub_desc[0].device_nr,
00497                                                    FALSE));
00498 
00499                     if ((desc1.ex_noise == TRUE) && (desc2.ex_noise == TRUE)) {
00500                         KMO_TRY_EXIT_IF_NULL(
00501                             op2_noise_3d = kmo_dfs_load_cube(frameset, "1",
00502                                                    desc2.sub_desc[0].device_nr,
00503                                                    TRUE));
00504                     }
00505                     break;
00506                 case f2i_fits:
00507                     KMO_TRY_EXIT_IF_NULL(
00508                         op2_2d = kmo_dfs_load_image(frameset, "1",
00509                                                    desc2.sub_desc[0].device_nr,
00510                                                    FALSE, FALSE, NULL));
00511 
00512                     if ((desc1.ex_noise == TRUE) && (desc2.ex_noise == TRUE)) {
00513                         KMO_TRY_EXIT_IF_NULL(
00514                             op2_noise_2d = kmo_dfs_load_image(frameset,
00515                                                    "1",
00516                                                    desc2.sub_desc[0].device_nr,
00517                                                    TRUE, FALSE, NULL));
00518                     }
00519                     break;
00520                 case f1i_fits:
00521                     KMO_TRY_EXIT_IF_NULL(
00522                         op2_1d = kmo_dfs_load_vector(frameset, "1",
00523                                                    desc2.sub_desc[0].device_nr,
00524                                                    FALSE));
00525 
00526                     if ((desc1.ex_noise == TRUE) && (desc2.ex_noise == TRUE)) {
00527                         KMO_TRY_EXIT_IF_NULL(
00528                             op2_noise_1d = kmo_dfs_load_vector(frameset,
00529                                                    "1",
00530                                                    desc2.sub_desc[0].device_nr,
00531                                                    TRUE));
00532                     }
00533                     break;
00534                 default:
00535                     break;
00536             }
00537         }
00538 
00539         for (i = 1; i <= nr_devices; i++) {
00540             if (desc1.ex_noise == FALSE) {
00541                 devnr1 = desc1.sub_desc[i - 1].device_nr;
00542             } else {
00543                 devnr1 = desc1.sub_desc[2 * i - 1].device_nr;
00544             }
00545 
00546             if (op2_scalar == -DBL_MAX) {
00547                 if (desc2.ex_noise == FALSE) {
00548                     devnr2 = desc2.sub_desc[i - 1].device_nr;
00549                 } else {
00550                     devnr2 = desc2.sub_desc[2 * i - 1].device_nr;
00551                 }
00552             }
00553 
00554             KMO_TRY_EXIT_IF_NULL(
00555                 sub_header_data = kmo_dfs_load_sub_header(frameset, "0",
00556                                                           devnr1,
00557                                                           FALSE));
00558             switch (desc1.fits_type) {
00559                 case raw_fits:
00560                     // load data 1st operand
00561                     KMO_TRY_EXIT_IF_NULL(
00562                         op1_2d = kmo_dfs_load_image(frameset, "0", i,
00563                                                     FALSE, TRUE, NULL));
00564                     //
00565                     // process RAW & RAW
00566                     // process RAW & F2D
00567                     //
00568                     if ((desc2.fits_type == raw_fits) ||
00569                         (desc2.fits_type == f2d_fits))
00570                     {
00571                         /* load data 2nd operand */
00572                         KMO_TRY_EXIT_IF_NULL(
00573                             op2_2d = kmo_dfs_load_image(frameset, "1", i,
00574                                                     FALSE, TRUE, NULL));
00575 
00576                         KMO_TRY_EXIT_IF_ERROR(
00577                             kmo_arithmetic_2D_2D(op1_2d, op2_2d, NULL, NULL, op));
00578                     }
00579 
00580                     //
00581                     // process RAW & scalar
00582                     //
00583                     else if (op2_scalar != -DBL_MAX) {
00584                         KMO_TRY_EXIT_IF_ERROR(
00585                             kmo_arithmetic_2D_scalar(op1_2d, op2_scalar, NULL,
00586                                                      op));
00587                     }
00588 
00589 // keep EXTNAME from op1 (e.g. CHIP1.INT1 instead of creating DET.1.DATA)
00590 //                    KMO_TRY_EXIT_IF_ERROR(
00591 //                        kmo_update_sub_keywords(sub_header_data, FALSE, FALSE,
00592 //                                                detector_frame, i));
00593 
00594                     KMO_TRY_EXIT_IF_ERROR(
00595                         kmo_dfs_save_image(op1_2d, fn_out, "",
00596                                            sub_header_data, 0./0.));
00597                     break;
00598                 case f2d_fits:
00599                     KMO_TRY_EXIT_IF_NULL(
00600                         op1_2d = kmo_dfs_load_image(frameset, "0", i,
00601                                                     FALSE, FALSE, NULL));
00602                     //
00603                     // process F2D & F2D
00604                     // process F2D & RAW
00605                     //
00606                     if ((desc2.fits_type == f2d_fits) ||
00607                         (desc2.fits_type == raw_fits))
00608                     {
00609                         KMO_TRY_EXIT_IF_NULL(
00610                             op2_2d = kmo_dfs_load_image(frameset, "1", i,
00611                                                         FALSE, FALSE, NULL));
00612                         // load noise
00613                         if ((desc1.ex_noise == TRUE) &&
00614                             (desc2.ex_noise == TRUE)) {
00615                             KMO_TRY_EXIT_IF_NULL(
00616                                 op1_noise_2d = kmo_dfs_load_image(frameset,
00617                                                          "0", i, TRUE, FALSE, NULL));
00618 
00619                             KMO_TRY_EXIT_IF_NULL(
00620                                 op2_noise_2d = kmo_dfs_load_image(frameset,
00621                                                          "1", i, TRUE, FALSE, NULL));
00622                         }
00623                         KMO_TRY_EXIT_IF_ERROR(
00624                             kmo_arithmetic_2D_2D(op1_2d, op2_2d,
00625                                                  op1_noise_2d, op2_noise_2d,
00626                                                  op));
00627                     }
00628                     //
00629                     // process F2D & scalar
00630                     //
00631                     else if (op2_scalar != -DBL_MAX) {
00632                         // process data & noise
00633                         if (desc1.ex_noise == TRUE) {
00634                             KMO_TRY_EXIT_IF_NULL(
00635                                 op1_noise_2d = kmo_dfs_load_image(frameset,
00636                                                          "0", i, TRUE, FALSE, NULL));
00637                         }
00638                         KMO_TRY_EXIT_IF_ERROR(
00639                             kmo_arithmetic_2D_scalar(op1_2d,
00640                                                            op2_scalar,
00641                                                            op1_noise_2d,
00642                                                            op));
00643                     }
00644 
00645                     // save data (and noise)
00646                     KMO_TRY_EXIT_IF_ERROR(
00647                         kmo_dfs_save_image(op1_2d, fn_out, "",
00648                                            sub_header_data, 0./0.));
00649 
00650                     if (op1_noise_2d != NULL) {
00651                         KMO_TRY_EXIT_IF_NULL(
00652                             sub_header_noise = kmo_dfs_load_sub_header(frameset,
00653                                                             "0", i, TRUE));
00654                         KMO_TRY_EXIT_IF_ERROR(
00655                             kmo_dfs_save_image(op1_noise_2d, fn_out, "",
00656                                                sub_header_noise, 0./0.));
00657 
00658                         cpl_propertylist_delete(sub_header_noise);
00659                         sub_header_noise = NULL;
00660                     }
00661                     break;
00662                 case f3i_fits:
00663                     calc_f3i = FALSE;
00664 
00665                     // check if IFUs are valid
00666                     if (desc1.ex_noise == FALSE) {
00667                         if (desc1.sub_desc[i - 1].valid_data == TRUE) {
00668                             if (op2_scalar != -DBL_MAX) {
00669                                 calc_f3i = TRUE;
00670                             } else if (((single_ifu == TRUE) &&
00671                                         (desc2.sub_desc[0].valid_data == TRUE))
00672                                        ||
00673                                        (desc2.sub_desc[i - 1].valid_data == TRUE))
00674                             {
00675                                 calc_f3i = TRUE;
00676                             }
00677                         }
00678                     }
00679                     if (desc1.ex_noise == TRUE) {
00680                         if (desc1.sub_desc[2 * i - 1].valid_data == TRUE) {
00681                             calc_f3i = TRUE;
00682                         }
00683                     }
00684                     if ((desc1.ex_noise == TRUE) && (desc2.ex_noise == TRUE)) {
00685                         if (desc1.sub_desc[2 * i - 1].valid_data == TRUE) {
00686                             if (((single_ifu == TRUE) &&
00687                                  (desc2.sub_desc[1].valid_data == TRUE))
00688                                 ||
00689                                 (desc2.sub_desc[2 * i - 1].valid_data == TRUE))
00690                             {
00691                                 calc_f3i = TRUE;
00692                             }
00693                         }
00694                     }
00695                     if ((single_ifu == TRUE) && (desc1.ex_noise == FALSE)) {
00696                         if ((desc1.sub_desc[i - 1].valid_data == TRUE) &&
00697                             (desc2.sub_desc[0].valid_data == TRUE)) {
00698                             calc_f3i = TRUE;
00699                         }
00700                     }
00701 
00702                     if (calc_f3i == TRUE)
00703                     {
00704                         KMO_TRY_EXIT_IF_NULL(
00705                             op1_3d = kmo_dfs_load_cube(frameset, "0",
00706                                                        devnr1, FALSE));
00707                         //
00708                         // process F3I & F3I
00709                         //
00710                         if (desc2.fits_type == f3i_fits) {
00711                             if (single_ifu == FALSE) {
00712                                 KMO_TRY_EXIT_IF_NULL(
00713                                     op2_3d = kmo_dfs_load_cube(frameset,
00714                                                                "1", devnr2,
00715                                                                FALSE));
00716                             }
00717 
00718                             if ((desc1.ex_noise == TRUE) &&
00719                                 (desc2.ex_noise == TRUE))
00720                             {
00721                                 KMO_TRY_EXIT_IF_NULL(
00722                                     op1_noise_3d = kmo_dfs_load_cube(frameset,
00723                                                                "0", devnr1,
00724                                                                TRUE));
00725 
00726                                 if (single_ifu == FALSE) {
00727                                     KMO_TRY_EXIT_IF_NULL(
00728                                         op2_noise_3d = kmo_dfs_load_cube(
00729                                                                frameset,
00730                                                                "1", devnr2,
00731                                                                TRUE));
00732                                 }
00733                             }
00734 
00735                             KMO_TRY_EXIT_IF_ERROR(
00736                                 kmo_arithmetic_3D_3D(op1_3d, op2_3d,
00737                                                      op1_noise_3d, op2_noise_3d,
00738                                                      op));
00739                         }
00740 
00741                         //
00742                         // process F3I & F2I
00743                         //
00744                         else if (desc2.fits_type == f2i_fits) {
00745                             if (single_ifu == FALSE) {
00746                                 KMO_TRY_EXIT_IF_NULL(
00747                                     op2_2d = kmo_dfs_load_image(frameset,
00748                                                                "1", devnr2,
00749                                                                FALSE, FALSE, NULL));
00750                             }
00751 
00752                             if ((desc1.ex_noise == TRUE) &&
00753                                 (desc2.ex_noise == TRUE))
00754                             {
00755                                 KMO_TRY_EXIT_IF_NULL(
00756                                     op1_noise_3d = kmo_dfs_load_cube(frameset,
00757                                                                "0", devnr1,
00758                                                                TRUE));
00759 
00760                                 if (single_ifu == FALSE) {
00761                                     KMO_TRY_EXIT_IF_NULL(
00762                                         op2_noise_2d = kmo_dfs_load_image(
00763                                                                frameset,
00764                                                                "1", devnr2,
00765                                                                TRUE, FALSE, NULL));
00766                                 }
00767                             }
00768 
00769                             KMO_TRY_EXIT_IF_ERROR(
00770                                 kmo_arithmetic_3D_2D(op1_3d, op2_2d,
00771                                                      op1_noise_3d, op2_noise_2d,
00772                                                      op));
00773                         }
00774                         //
00775                         // process F3I & F1I
00776                         //
00777                         else if (desc2.fits_type == f1i_fits) {
00778                             if (single_ifu == FALSE) {
00779                                 KMO_TRY_EXIT_IF_NULL(
00780                                     op2_1d = kmo_dfs_load_vector(frameset,
00781                                                                "1", devnr2,
00782                                                                FALSE));
00783                             }
00784 
00785                             if ((desc1.ex_noise == TRUE) &&
00786                                 (desc2.ex_noise == TRUE))
00787                             {
00788                                 KMO_TRY_EXIT_IF_NULL(
00789                                     op1_noise_3d = kmo_dfs_load_cube(frameset,
00790                                                                "0", devnr1,
00791                                                                TRUE));
00792 
00793                                 if (single_ifu == FALSE) {
00794                                     KMO_TRY_EXIT_IF_NULL(
00795                                         op2_noise_1d = kmo_dfs_load_vector(
00796                                                                frameset,
00797                                                                "1", devnr2,
00798                                                                TRUE));
00799                                 }
00800                             }
00801 
00802                             KMO_TRY_EXIT_IF_ERROR(
00803                                 kmo_arithmetic_3D_1D(op1_3d, op2_1d,
00804                                                      op1_noise_3d, op2_noise_1d,
00805                                                      op));
00806                         }
00807                         //
00808                         // process F3I & scalar
00809                         //
00810                         else if (op2_scalar != -DBL_MAX) {
00811                             if (desc1.ex_noise == TRUE) {
00812                                 KMO_TRY_EXIT_IF_NULL(
00813                                     op1_noise_3d = kmo_dfs_load_cube(frameset,
00814                                                                "0", devnr1,
00815                                                                TRUE));
00816                             }
00817 
00818                             KMO_TRY_EXIT_IF_ERROR(
00819                                 kmo_arithmetic_3D_scalar(op1_3d,
00820                                                          op2_scalar,
00821                                                          op1_noise_3d,
00822                                                          op));
00823                         }
00824 
00825                         // save data (and noise)
00826                         KMO_TRY_EXIT_IF_ERROR(
00827                             kmo_dfs_save_cube(op1_3d, fn_out, "",
00828                                               sub_header_data, 0./0.));
00829 
00830                         if (op1_noise_3d != NULL) {
00831                             KMO_TRY_EXIT_IF_NULL(
00832                                 sub_header_noise = kmo_dfs_load_sub_header(
00833                                                                frameset,
00834                                                                "0", devnr1,
00835                                                                TRUE));
00836 
00837                             KMO_TRY_EXIT_IF_ERROR(
00838                                 kmo_dfs_save_cube(op1_noise_3d, fn_out, "",
00839                                                   sub_header_noise, 0./0.));
00840 
00841                             cpl_propertylist_delete(sub_header_noise);
00842                             sub_header_noise = NULL;
00843                         }
00844                     } else {
00845                         //
00846                         // invalid IFU, just save sub_header
00847                         //
00848                         KMO_TRY_EXIT_IF_ERROR(
00849                             kmo_dfs_save_sub_header(fn_out, "",
00850                                                     sub_header_data));
00851 
00852                         // save noise if it has been calculated
00853                         if ((desc1.ex_noise == TRUE) &&
00854                             ((((desc2.fits_type == f3i_fits) ||
00855                                (desc2.fits_type == f2i_fits) ||
00856                                (desc2.fits_type == f1i_fits)
00857                               ) &&
00858                                 (desc2.ex_noise == TRUE)
00859                              ) ||
00860                                 (op2_scalar != -DBL_MAX)
00861                             )
00862                            )
00863                         {
00864 
00865                             KMO_TRY_EXIT_IF_NULL(
00866                                 sub_header_noise = kmo_dfs_load_sub_header(
00867                                                                frameset,
00868                                                                "0", devnr1,
00869                                                                TRUE));
00870                             KMO_TRY_EXIT_IF_ERROR(
00871                                 kmo_dfs_save_sub_header(fn_out, "",
00872                                                         sub_header_noise));
00873 
00874                             cpl_propertylist_delete(sub_header_noise);
00875                             sub_header_noise = NULL;
00876                         }
00877                     }
00878                     break;
00879                 case f2i_fits:
00880                     calc_f2i = FALSE;
00881 
00882                     // check if IFUs are valid
00883                     if (desc1.ex_noise == FALSE) {
00884                         if (desc1.sub_desc[i - 1].valid_data == TRUE) {
00885                             if (op2_scalar != -DBL_MAX) {
00886                                 calc_f2i = TRUE;
00887                             } else if (((single_ifu == TRUE) &&
00888                                         (desc2.sub_desc[0].valid_data == TRUE))
00889                                        ||
00890                                        (desc2.sub_desc[i - 1].valid_data == TRUE))
00891                             {
00892                                 calc_f2i = TRUE;
00893                             }
00894                         }
00895                     }
00896                     if (desc1.ex_noise == TRUE) {
00897                         if (desc1.sub_desc[2 * i - 1].valid_data == TRUE) {
00898                             calc_f2i = TRUE;
00899                         }
00900                     }
00901                     if ((desc1.ex_noise == TRUE) && (desc2.ex_noise == TRUE)) {
00902                         if (desc1.sub_desc[2 * i - 1].valid_data == TRUE) {
00903                             if (((single_ifu == TRUE) &&
00904                                  (desc2.sub_desc[1].valid_data == TRUE))
00905                                 ||
00906                                 (desc2.sub_desc[2 * i - 1].valid_data == TRUE))
00907                             {
00908                                 calc_f2i = TRUE;
00909                             }
00910                         }
00911                     }
00912                     if ((single_ifu == TRUE) && (desc1.ex_noise == FALSE)) {
00913                         if ((desc1.sub_desc[i - 1].valid_data == TRUE) &&
00914                             (desc2.sub_desc[0].valid_data == TRUE)) {
00915                             calc_f2i = TRUE;
00916                         }
00917                     }
00918 
00919                     if (calc_f2i == TRUE)
00920                     {
00921                         KMO_TRY_EXIT_IF_NULL(
00922                             op1_2d = kmo_dfs_load_image(frameset, "0",
00923                                                         devnr1, FALSE, FALSE, NULL));
00924                         //
00925                         // process F2I & F2I
00926                         //
00927                         if (desc2.fits_type == f2i_fits) {
00928                             if (single_ifu == FALSE) {
00929                                 KMO_TRY_EXIT_IF_NULL(
00930                                     op2_2d = kmo_dfs_load_image(frameset, "1",
00931                                                                 devnr2, FALSE, FALSE, NULL));
00932                             }
00933 
00934                             if ((desc1.ex_noise == TRUE) &&
00935                                 (desc2.ex_noise == TRUE))
00936                             {
00937                                 KMO_TRY_EXIT_IF_NULL(
00938                                     op1_noise_2d = kmo_dfs_load_image(
00939                                                             frameset, "0",
00940                                                             devnr1, TRUE, FALSE, NULL));
00941 
00942                                 if (single_ifu == FALSE) {
00943                                     KMO_TRY_EXIT_IF_NULL(
00944                                         op2_noise_2d = kmo_dfs_load_image(
00945                                                             frameset, "1",
00946                                                             devnr2, TRUE, FALSE, NULL));
00947                                 }
00948                             }
00949 
00950                             KMO_TRY_EXIT_IF_ERROR(
00951                                 kmo_arithmetic_2D_2D(op1_2d, op2_2d,
00952                                                      op1_noise_2d, op2_noise_2d,
00953                                                      op));
00954                         }
00955                         //
00956                         // process F2I & scalar
00957                         //
00958                         else if (op2_scalar != -DBL_MAX) {
00959                             if (desc1.ex_noise == TRUE) {
00960                                 KMO_TRY_EXIT_IF_NULL(
00961                                     op1_noise_2d = kmo_dfs_load_image(
00962                                                                 frameset, "0",
00963                                                                 devnr1, TRUE, FALSE, NULL));
00964                             }
00965 
00966                             KMO_TRY_EXIT_IF_ERROR(
00967                                 kmo_arithmetic_2D_scalar(op1_2d,
00968                                                          op2_scalar,
00969                                                          op1_noise_2d,
00970                                                          op));
00971                         }
00972 
00973                         // save data (and noise)
00974                         KMO_TRY_EXIT_IF_ERROR(
00975                             kmo_dfs_save_image(op1_2d, fn_out, "",
00976                                                sub_header_data, 0./0.));
00977 
00978                         if (op1_noise_2d != NULL) {
00979                             KMO_TRY_EXIT_IF_NULL(
00980                                 sub_header_noise = kmo_dfs_load_sub_header(
00981                                                                 frameset, "0",
00982                                                                 devnr1, TRUE));
00983 
00984                             KMO_TRY_EXIT_IF_ERROR(
00985                                 kmo_dfs_save_image(op1_noise_2d, fn_out, "",
00986                                                    sub_header_noise, 0./0.));
00987 
00988                             cpl_propertylist_delete(sub_header_noise);
00989                             sub_header_noise = NULL;
00990                         }
00991                     } else {
00992                         //
00993                         // invalid IFU, just save sub_header
00994                         //
00995                         KMO_TRY_EXIT_IF_ERROR(
00996                             kmo_dfs_save_sub_header(fn_out, "", sub_header_data));
00997 
00998                         // save noise if it has been calculated
00999                         if ((desc1.ex_noise == TRUE)
01000                             &&
01001                             (((desc2.fits_type == f2i_fits) && (desc2.ex_noise == TRUE)) ||
01002                              (op2_scalar != -DBL_MAX)))
01003                         {
01004 
01005                             KMO_TRY_EXIT_IF_NULL(
01006                                 sub_header_noise = kmo_dfs_load_sub_header(
01007                                                                frameset,
01008                                                                "0", devnr1,
01009                                                                TRUE));
01010                             KMO_TRY_EXIT_IF_ERROR(
01011                                 kmo_dfs_save_sub_header(fn_out, "", sub_header_noise));
01012 
01013                             cpl_propertylist_delete(sub_header_noise);
01014                             sub_header_noise = NULL;
01015                         }
01016                     }
01017                     break;
01018                 case f1i_fits:
01019                     calc_f1i = FALSE;
01020 
01021                     // check if IFUs are valid
01022                     if (desc1.ex_noise == FALSE) {
01023                         if (desc1.sub_desc[i - 1].valid_data == TRUE) {
01024                             if (op2_scalar != -DBL_MAX) {
01025                                 calc_f1i = TRUE;
01026                             } else if (((single_ifu == TRUE) &&
01027                                         (desc2.sub_desc[0].valid_data == TRUE))
01028                                        ||
01029                                        (desc2.sub_desc[i - 1].valid_data == TRUE))
01030                             {
01031                                 calc_f1i = TRUE;
01032                             }
01033                         }
01034                     }
01035                     if (desc1.ex_noise == TRUE) {
01036                         if (desc1.sub_desc[2 * i - 1].valid_data == TRUE) {
01037                             calc_f1i = TRUE;
01038                         }
01039                     }
01040                     if ((desc1.ex_noise == TRUE) && (desc2.ex_noise == TRUE)) {
01041                         if (desc1.sub_desc[2 * i - 1].valid_data == TRUE) {
01042                             if (((single_ifu == TRUE) &&
01043                                  (desc2.sub_desc[1].valid_data == TRUE))
01044                                 ||
01045                                 (desc2.sub_desc[2 * i - 1].valid_data == TRUE))
01046                             {
01047                                 calc_f1i = TRUE;
01048                             }
01049                         }
01050                     }
01051                     if ((single_ifu == TRUE) && (desc1.ex_noise == FALSE)) {
01052                         if ((desc1.sub_desc[i - 1].valid_data == TRUE) &&
01053                             (desc2.sub_desc[0].valid_data == TRUE)) {
01054                             calc_f1i = TRUE;
01055                         }
01056                     }
01057 
01058                     if (calc_f1i == TRUE)
01059                     {
01060                         KMO_TRY_EXIT_IF_NULL(
01061                             op1_1d = kmo_dfs_load_vector(frameset, "0",
01062                                                          devnr1, FALSE));
01063                         //
01064                         // process F1I & F1I
01065                         //
01066                         if (desc2.fits_type == f1i_fits) {
01067                             if (single_ifu == FALSE) {
01068                                 KMO_TRY_EXIT_IF_NULL(
01069                                     op2_1d = kmo_dfs_load_vector(frameset, "1",
01070                                                                  devnr2, FALSE));
01071                             }
01072 
01073                             if ((desc1.ex_noise == TRUE) &&
01074                                 (desc2.ex_noise == TRUE))
01075                             {
01076                                 KMO_TRY_EXIT_IF_NULL(
01077                                     op1_noise_1d = kmo_dfs_load_vector(
01078                                                                 frameset, "0",
01079                                                                 devnr1, TRUE));
01080 
01081                                 if (single_ifu == FALSE) {
01082                                     KMO_TRY_EXIT_IF_NULL(
01083                                         op2_noise_1d = kmo_dfs_load_vector(
01084                                                                 frameset, "1",
01085                                                                 devnr2, TRUE));
01086                                 }
01087                             }
01088 
01089                             KMO_TRY_EXIT_IF_ERROR(
01090                                 kmo_arithmetic_1D_1D(op1_1d, op2_1d,
01091                                                      op1_noise_1d, op2_noise_1d,
01092                                                      op));
01093                         }
01094                         //
01095                         // process F1I & scalar
01096                         //
01097                         else if (op2_scalar != -DBL_MAX) {
01098                             if (desc1.ex_noise == TRUE) {
01099                                 KMO_TRY_EXIT_IF_NULL(
01100                                     op1_noise_1d = kmo_dfs_load_vector(
01101                                                                 frameset, "0",
01102                                                                 devnr1, TRUE));
01103                             }
01104 
01105                             KMO_TRY_EXIT_IF_ERROR(
01106                                 kmo_arithmetic_1D_scalar(op1_1d,
01107                                                          op2_scalar,
01108                                                          op1_noise_1d,
01109                                                          op));
01110                         }
01111 
01112                         // save data (and noise)
01113                         KMO_TRY_EXIT_IF_ERROR(
01114                             kmo_dfs_save_vector(op1_1d, fn_out, "",
01115                                                 sub_header_data, 0./0.));
01116 
01117                         if (op1_noise_1d != NULL) {
01118                             KMO_TRY_EXIT_IF_NULL(
01119                                 sub_header_noise = kmo_dfs_load_sub_header(
01120                                                                 frameset, "0",
01121                                                                 devnr1, TRUE));
01122 
01123                             KMO_TRY_EXIT_IF_ERROR(
01124                                 kmo_dfs_save_vector(op1_noise_1d, fn_out, "",
01125                                                     sub_header_noise, 0./0.));
01126 
01127                             cpl_propertylist_delete(sub_header_noise);
01128                             sub_header_noise = NULL;
01129                         }
01130                     } else {
01131                         //
01132                         // invalid IFU, just save sub_header
01133                         //
01134                         KMO_TRY_EXIT_IF_ERROR(
01135                             kmo_dfs_save_sub_header(fn_out, "", sub_header_data));
01136 
01137                         // save noise if it has been calculated
01138                         if ((desc1.ex_noise == TRUE)
01139                             &&
01140                             (((desc2.fits_type == f2i_fits) && (desc2.ex_noise == TRUE)) ||
01141                              (op2_scalar != -DBL_MAX)))
01142                         {
01143 
01144                             KMO_TRY_EXIT_IF_NULL(
01145                                 sub_header_noise = kmo_dfs_load_sub_header(
01146                                                                frameset,
01147                                                                "0", devnr1,
01148                                                                TRUE));
01149                             KMO_TRY_EXIT_IF_ERROR(
01150                                 kmo_dfs_save_sub_header(fn_out, "",
01151                                                         sub_header_noise));
01152 
01153                             cpl_propertylist_delete(sub_header_noise);
01154                             sub_header_noise = NULL;
01155                         }
01156                     }
01157                     break;
01158                 default:
01159                     break;
01160             }
01161 
01162             cpl_propertylist_delete(sub_header_data); sub_header_data = NULL;
01163 
01164             cpl_image_delete(op1_2d); op1_2d = NULL;
01165             cpl_imagelist_delete(op1_3d); op1_3d = NULL;
01166 
01167             cpl_image_delete(op1_noise_2d); op1_noise_2d = NULL;
01168             cpl_imagelist_delete(op1_noise_3d); op1_noise_3d = NULL;
01169 
01170             if (single_ifu == FALSE) {
01171                 kmclipm_vector_delete(op2_1d); op2_1d = NULL,
01172                 cpl_image_delete(op2_2d); op2_2d = NULL;
01173                 cpl_imagelist_delete(op2_3d); op2_3d = NULL;
01174 
01175                 kmclipm_vector_delete(op2_noise_1d); op2_noise_1d = NULL,
01176                 cpl_image_delete(op2_noise_2d); op2_noise_2d = NULL;
01177                 cpl_imagelist_delete(op2_noise_3d); op2_noise_3d = NULL;
01178             }
01179         }
01180     }
01181     KMO_CATCH
01182     {
01183         KMO_CATCH_MSG();
01184         ret_val = -1;
01185     }
01186 
01187     kmo_free_fits_desc(&desc1);
01188     kmo_free_fits_desc(&desc2);
01189     cpl_free(fn_out); fn_out = NULL;
01190     cpl_propertylist_delete(main_header); main_header = NULL;
01191     cpl_propertylist_delete(sub_header_data); sub_header_data = NULL;
01192     cpl_propertylist_delete(sub_header_noise); sub_header_noise = NULL;
01193     cpl_image_delete(op1_2d); op1_2d = NULL;
01194     cpl_imagelist_delete(op1_3d); op1_3d = NULL;
01195     kmclipm_vector_delete(op2_1d); op2_1d = NULL;
01196     cpl_image_delete(op2_2d); op2_2d = NULL;
01197     cpl_imagelist_delete(op2_3d); op2_3d = NULL;
01198     cpl_image_delete(op1_noise_2d); op1_noise_2d = NULL;
01199     cpl_imagelist_delete(op1_noise_3d); op1_noise_3d = NULL;
01200     kmclipm_vector_delete(op2_noise_1d); op2_noise_1d = NULL;
01201     cpl_image_delete(op2_noise_2d); op2_noise_2d = NULL;
01202     cpl_imagelist_delete(op2_noise_3d); op2_noise_3d = NULL;
01203 
01204     return ret_val;
01205 }
01206