KMOS Pipeline Reference Manual  1.2.4
kmo_arithmetic.c
00001 /* $Id: kmo_arithmetic.c,v 1.14 2013/06/07 15:41:19 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 15:41:19 $
00024  * $Revision: 1.14 $
00025  * $Name: kmosp_v1_2_4__20130807 $
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                     KMO_TRY_EXIT_IF_ERROR(
00590                         kmo_update_sub_keywords(sub_header_data, FALSE, FALSE,
00591                                                 detector_frame, i));
00592 
00593                     KMO_TRY_EXIT_IF_ERROR(
00594                         kmo_dfs_save_image(op1_2d, fn_out, "",
00595                                            sub_header_data, 0./0.));
00596                     break;
00597                 case f2d_fits:
00598                     KMO_TRY_EXIT_IF_NULL(
00599                         op1_2d = kmo_dfs_load_image(frameset, "0", i,
00600                                                     FALSE, FALSE, NULL));
00601                     //
00602                     // process F2D & F2D
00603                     // process F2D & RAW
00604                     //
00605                     if ((desc2.fits_type == f2d_fits) ||
00606                         (desc2.fits_type == raw_fits))
00607                     {
00608                         KMO_TRY_EXIT_IF_NULL(
00609                             op2_2d = kmo_dfs_load_image(frameset, "1", i,
00610                                                         FALSE, FALSE, NULL));
00611                         // load noise
00612                         if ((desc1.ex_noise == TRUE) &&
00613                             (desc2.ex_noise == TRUE)) {
00614                             KMO_TRY_EXIT_IF_NULL(
00615                                 op1_noise_2d = kmo_dfs_load_image(frameset,
00616                                                          "0", i, TRUE, FALSE, NULL));
00617 
00618                             KMO_TRY_EXIT_IF_NULL(
00619                                 op2_noise_2d = kmo_dfs_load_image(frameset,
00620                                                          "1", i, TRUE, FALSE, NULL));
00621                         }
00622                         KMO_TRY_EXIT_IF_ERROR(
00623                             kmo_arithmetic_2D_2D(op1_2d, op2_2d,
00624                                                  op1_noise_2d, op2_noise_2d,
00625                                                  op));
00626                     }
00627                     //
00628                     // process F2D & scalar
00629                     //
00630                     else if (op2_scalar != -DBL_MAX) {
00631                         // process data & noise
00632                         if (desc1.ex_noise == TRUE) {
00633                             KMO_TRY_EXIT_IF_NULL(
00634                                 op1_noise_2d = kmo_dfs_load_image(frameset,
00635                                                          "0", i, TRUE, FALSE, NULL));
00636                         }
00637                         KMO_TRY_EXIT_IF_ERROR(
00638                             kmo_arithmetic_2D_scalar(op1_2d,
00639                                                            op2_scalar,
00640                                                            op1_noise_2d,
00641                                                            op));
00642                     }
00643 
00644                     // save data (and noise)
00645                     KMO_TRY_EXIT_IF_ERROR(
00646                         kmo_dfs_save_image(op1_2d, fn_out, "",
00647                                            sub_header_data, 0./0.));
00648 
00649                     if (op1_noise_2d != NULL) {
00650                         KMO_TRY_EXIT_IF_NULL(
00651                             sub_header_noise = kmo_dfs_load_sub_header(frameset,
00652                                                             "0", i, TRUE));
00653                         KMO_TRY_EXIT_IF_ERROR(
00654                             kmo_dfs_save_image(op1_noise_2d, fn_out, "",
00655                                                sub_header_noise, 0./0.));
00656 
00657                         cpl_propertylist_delete(sub_header_noise);
00658                         sub_header_noise = NULL;
00659                     }
00660                     break;
00661                 case f3i_fits:
00662                     calc_f3i = FALSE;
00663 
00664                     // check if IFUs are valid
00665                     if (desc1.ex_noise == FALSE) {
00666                         if (desc1.sub_desc[i - 1].valid_data == TRUE) {
00667                             if (op2_scalar != -DBL_MAX) {
00668                                 calc_f3i = TRUE;
00669                             } else if (((single_ifu == TRUE) &&
00670                                         (desc2.sub_desc[0].valid_data == TRUE))
00671                                        ||
00672                                        (desc2.sub_desc[i - 1].valid_data == TRUE))
00673                             {
00674                                 calc_f3i = TRUE;
00675                             }
00676                         }
00677                     }
00678                     if (desc1.ex_noise == TRUE) {
00679                         if (desc1.sub_desc[2 * i - 1].valid_data == TRUE) {
00680                             calc_f3i = TRUE;
00681                         }
00682                     }
00683                     if ((desc1.ex_noise == TRUE) && (desc2.ex_noise == TRUE)) {
00684                         if (desc1.sub_desc[2 * i - 1].valid_data == TRUE) {
00685                             if (((single_ifu == TRUE) &&
00686                                  (desc2.sub_desc[1].valid_data == TRUE))
00687                                 ||
00688                                 (desc2.sub_desc[2 * i - 1].valid_data == TRUE))
00689                             {
00690                                 calc_f3i = TRUE;
00691                             }
00692                         }
00693                     }
00694                     if ((single_ifu == TRUE) && (desc1.ex_noise == FALSE)) {
00695                         if ((desc1.sub_desc[i - 1].valid_data == TRUE) &&
00696                             (desc2.sub_desc[0].valid_data == TRUE)) {
00697                             calc_f3i = TRUE;
00698                         }
00699                     }
00700 
00701                     if (calc_f3i == TRUE)
00702                     {
00703                         KMO_TRY_EXIT_IF_NULL(
00704                             op1_3d = kmo_dfs_load_cube(frameset, "0",
00705                                                        devnr1, FALSE));
00706                         //
00707                         // process F3I & F3I
00708                         //
00709                         if (desc2.fits_type == f3i_fits) {
00710                             if (single_ifu == FALSE) {
00711                                 KMO_TRY_EXIT_IF_NULL(
00712                                     op2_3d = kmo_dfs_load_cube(frameset,
00713                                                                "1", devnr2,
00714                                                                FALSE));
00715                             }
00716 
00717                             if ((desc1.ex_noise == TRUE) &&
00718                                 (desc2.ex_noise == TRUE))
00719                             {
00720                                 KMO_TRY_EXIT_IF_NULL(
00721                                     op1_noise_3d = kmo_dfs_load_cube(frameset,
00722                                                                "0", devnr1,
00723                                                                TRUE));
00724 
00725                                 if (single_ifu == FALSE) {
00726                                     KMO_TRY_EXIT_IF_NULL(
00727                                         op2_noise_3d = kmo_dfs_load_cube(
00728                                                                frameset,
00729                                                                "1", devnr2,
00730                                                                TRUE));
00731                                 }
00732                             }
00733 
00734                             KMO_TRY_EXIT_IF_ERROR(
00735                                 kmo_arithmetic_3D_3D(op1_3d, op2_3d,
00736                                                      op1_noise_3d, op2_noise_3d,
00737                                                      op));
00738                         }
00739 
00740                         //
00741                         // process F3I & F2I
00742                         //
00743                         else if (desc2.fits_type == f2i_fits) {
00744                             if (single_ifu == FALSE) {
00745                                 KMO_TRY_EXIT_IF_NULL(
00746                                     op2_2d = kmo_dfs_load_image(frameset,
00747                                                                "1", devnr2,
00748                                                                FALSE, FALSE, NULL));
00749                             }
00750 
00751                             if ((desc1.ex_noise == TRUE) &&
00752                                 (desc2.ex_noise == TRUE))
00753                             {
00754                                 KMO_TRY_EXIT_IF_NULL(
00755                                     op1_noise_3d = kmo_dfs_load_cube(frameset,
00756                                                                "0", devnr1,
00757                                                                TRUE));
00758 
00759                                 if (single_ifu == FALSE) {
00760                                     KMO_TRY_EXIT_IF_NULL(
00761                                         op2_noise_2d = kmo_dfs_load_image(
00762                                                                frameset,
00763                                                                "1", devnr2,
00764                                                                TRUE, FALSE, NULL));
00765                                 }
00766                             }
00767 
00768                             KMO_TRY_EXIT_IF_ERROR(
00769                                 kmo_arithmetic_3D_2D(op1_3d, op2_2d,
00770                                                      op1_noise_3d, op2_noise_2d,
00771                                                      op));
00772                         }
00773                         //
00774                         // process F3I & F1I
00775                         //
00776                         else if (desc2.fits_type == f1i_fits) {
00777                             if (single_ifu == FALSE) {
00778                                 KMO_TRY_EXIT_IF_NULL(
00779                                     op2_1d = kmo_dfs_load_vector(frameset,
00780                                                                "1", devnr2,
00781                                                                FALSE));
00782                             }
00783 
00784                             if ((desc1.ex_noise == TRUE) &&
00785                                 (desc2.ex_noise == TRUE))
00786                             {
00787                                 KMO_TRY_EXIT_IF_NULL(
00788                                     op1_noise_3d = kmo_dfs_load_cube(frameset,
00789                                                                "0", devnr1,
00790                                                                TRUE));
00791 
00792                                 if (single_ifu == FALSE) {
00793                                     KMO_TRY_EXIT_IF_NULL(
00794                                         op2_noise_1d = kmo_dfs_load_vector(
00795                                                                frameset,
00796                                                                "1", devnr2,
00797                                                                TRUE));
00798                                 }
00799                             }
00800 
00801                             KMO_TRY_EXIT_IF_ERROR(
00802                                 kmo_arithmetic_3D_1D(op1_3d, op2_1d,
00803                                                      op1_noise_3d, op2_noise_1d,
00804                                                      op));
00805                         }
00806                         //
00807                         // process F3I & scalar
00808                         //
00809                         else if (op2_scalar != -DBL_MAX) {
00810                             if (desc1.ex_noise == TRUE) {
00811                                 KMO_TRY_EXIT_IF_NULL(
00812                                     op1_noise_3d = kmo_dfs_load_cube(frameset,
00813                                                                "0", devnr1,
00814                                                                TRUE));
00815                             }
00816 
00817                             KMO_TRY_EXIT_IF_ERROR(
00818                                 kmo_arithmetic_3D_scalar(op1_3d,
00819                                                          op2_scalar,
00820                                                          op1_noise_3d,
00821                                                          op));
00822                         }
00823 
00824                         // save data (and noise)
00825                         KMO_TRY_EXIT_IF_ERROR(
00826                             kmo_dfs_save_cube(op1_3d, fn_out, "",
00827                                               sub_header_data, 0./0.));
00828 
00829                         if (op1_noise_3d != NULL) {
00830                             KMO_TRY_EXIT_IF_NULL(
00831                                 sub_header_noise = kmo_dfs_load_sub_header(
00832                                                                frameset,
00833                                                                "0", devnr1,
00834                                                                TRUE));
00835 
00836                             KMO_TRY_EXIT_IF_ERROR(
00837                                 kmo_dfs_save_cube(op1_noise_3d, fn_out, "",
00838                                                   sub_header_noise, 0./0.));
00839 
00840                             cpl_propertylist_delete(sub_header_noise);
00841                             sub_header_noise = NULL;
00842                         }
00843                     } else {
00844                         //
00845                         // invalid IFU, just save sub_header
00846                         //
00847                         KMO_TRY_EXIT_IF_ERROR(
00848                             kmo_dfs_save_sub_header(fn_out, "",
00849                                                     sub_header_data));
00850 
00851                         // save noise if it has been calculated
00852                         if ((desc1.ex_noise == TRUE) &&
00853                             ((((desc2.fits_type == f3i_fits) ||
00854                                (desc2.fits_type == f2i_fits) ||
00855                                (desc2.fits_type == f1i_fits)
00856                               ) &&
00857                                 (desc2.ex_noise == TRUE)
00858                              ) ||
00859                                 (op2_scalar != -DBL_MAX)
00860                             )
00861                            )
00862                         {
00863 
00864                             KMO_TRY_EXIT_IF_NULL(
00865                                 sub_header_noise = kmo_dfs_load_sub_header(
00866                                                                frameset,
00867                                                                "0", devnr1,
00868                                                                TRUE));
00869                             KMO_TRY_EXIT_IF_ERROR(
00870                                 kmo_dfs_save_sub_header(fn_out, "",
00871                                                         sub_header_noise));
00872 
00873                             cpl_propertylist_delete(sub_header_noise);
00874                             sub_header_noise = NULL;
00875                         }
00876                     }
00877                     break;
00878                 case f2i_fits:
00879                     calc_f2i = FALSE;
00880 
00881                     // check if IFUs are valid
00882                     if (desc1.ex_noise == FALSE) {
00883                         if (desc1.sub_desc[i - 1].valid_data == TRUE) {
00884                             if (op2_scalar != -DBL_MAX) {
00885                                 calc_f2i = TRUE;
00886                             } else if (((single_ifu == TRUE) &&
00887                                         (desc2.sub_desc[0].valid_data == TRUE))
00888                                        ||
00889                                        (desc2.sub_desc[i - 1].valid_data == TRUE))
00890                             {
00891                                 calc_f2i = TRUE;
00892                             }
00893                         }
00894                     }
00895                     if (desc1.ex_noise == TRUE) {
00896                         if (desc1.sub_desc[2 * i - 1].valid_data == TRUE) {
00897                             calc_f2i = TRUE;
00898                         }
00899                     }
00900                     if ((desc1.ex_noise == TRUE) && (desc2.ex_noise == TRUE)) {
00901                         if (desc1.sub_desc[2 * i - 1].valid_data == TRUE) {
00902                             if (((single_ifu == TRUE) &&
00903                                  (desc2.sub_desc[1].valid_data == TRUE))
00904                                 ||
00905                                 (desc2.sub_desc[2 * i - 1].valid_data == TRUE))
00906                             {
00907                                 calc_f2i = TRUE;
00908                             }
00909                         }
00910                     }
00911                     if ((single_ifu == TRUE) && (desc1.ex_noise == FALSE)) {
00912                         if ((desc1.sub_desc[i - 1].valid_data == TRUE) &&
00913                             (desc2.sub_desc[0].valid_data == TRUE)) {
00914                             calc_f2i = TRUE;
00915                         }
00916                     }
00917 
00918                     if (calc_f2i == TRUE)
00919                     {
00920                         KMO_TRY_EXIT_IF_NULL(
00921                             op1_2d = kmo_dfs_load_image(frameset, "0",
00922                                                         devnr1, FALSE, FALSE, NULL));
00923                         //
00924                         // process F2I & F2I
00925                         //
00926                         if (desc2.fits_type == f2i_fits) {
00927                             if (single_ifu == FALSE) {
00928                                 KMO_TRY_EXIT_IF_NULL(
00929                                     op2_2d = kmo_dfs_load_image(frameset, "1",
00930                                                                 devnr2, FALSE, FALSE, NULL));
00931                             }
00932 
00933                             if ((desc1.ex_noise == TRUE) &&
00934                                 (desc2.ex_noise == TRUE))
00935                             {
00936                                 KMO_TRY_EXIT_IF_NULL(
00937                                     op1_noise_2d = kmo_dfs_load_image(
00938                                                             frameset, "0",
00939                                                             devnr1, TRUE, FALSE, NULL));
00940 
00941                                 if (single_ifu == FALSE) {
00942                                     KMO_TRY_EXIT_IF_NULL(
00943                                         op2_noise_2d = kmo_dfs_load_image(
00944                                                             frameset, "1",
00945                                                             devnr2, TRUE, FALSE, NULL));
00946                                 }
00947                             }
00948 
00949                             KMO_TRY_EXIT_IF_ERROR(
00950                                 kmo_arithmetic_2D_2D(op1_2d, op2_2d,
00951                                                      op1_noise_2d, op2_noise_2d,
00952                                                      op));
00953                         }
00954                         //
00955                         // process F2I & scalar
00956                         //
00957                         else if (op2_scalar != -DBL_MAX) {
00958                             if (desc1.ex_noise == TRUE) {
00959                                 KMO_TRY_EXIT_IF_NULL(
00960                                     op1_noise_2d = kmo_dfs_load_image(
00961                                                                 frameset, "0",
00962                                                                 devnr1, TRUE, FALSE, NULL));
00963                             }
00964 
00965                             KMO_TRY_EXIT_IF_ERROR(
00966                                 kmo_arithmetic_2D_scalar(op1_2d,
00967                                                          op2_scalar,
00968                                                          op1_noise_2d,
00969                                                          op));
00970                         }
00971 
00972                         // save data (and noise)
00973                         KMO_TRY_EXIT_IF_ERROR(
00974                             kmo_dfs_save_image(op1_2d, fn_out, "",
00975                                                sub_header_data, 0./0.));
00976 
00977                         if (op1_noise_2d != NULL) {
00978                             KMO_TRY_EXIT_IF_NULL(
00979                                 sub_header_noise = kmo_dfs_load_sub_header(
00980                                                                 frameset, "0",
00981                                                                 devnr1, TRUE));
00982 
00983                             KMO_TRY_EXIT_IF_ERROR(
00984                                 kmo_dfs_save_image(op1_noise_2d, fn_out, "",
00985                                                    sub_header_noise, 0./0.));
00986 
00987                             cpl_propertylist_delete(sub_header_noise);
00988                             sub_header_noise = NULL;
00989                         }
00990                     } else {
00991                         //
00992                         // invalid IFU, just save sub_header
00993                         //
00994                         KMO_TRY_EXIT_IF_ERROR(
00995                             kmo_dfs_save_sub_header(fn_out, "", sub_header_data));
00996 
00997                         // save noise if it has been calculated
00998                         if ((desc1.ex_noise == TRUE)
00999                             &&
01000                             (((desc2.fits_type == f2i_fits) && (desc2.ex_noise == TRUE)) ||
01001                              (op2_scalar != -DBL_MAX)))
01002                         {
01003 
01004                             KMO_TRY_EXIT_IF_NULL(
01005                                 sub_header_noise = kmo_dfs_load_sub_header(
01006                                                                frameset,
01007                                                                "0", devnr1,
01008                                                                TRUE));
01009                             KMO_TRY_EXIT_IF_ERROR(
01010                                 kmo_dfs_save_sub_header(fn_out, "", sub_header_noise));
01011 
01012                             cpl_propertylist_delete(sub_header_noise);
01013                             sub_header_noise = NULL;
01014                         }
01015                     }
01016                     break;
01017                 case f1i_fits:
01018                     calc_f1i = FALSE;
01019 
01020                     // check if IFUs are valid
01021                     if (desc1.ex_noise == FALSE) {
01022                         if (desc1.sub_desc[i - 1].valid_data == TRUE) {
01023                             if (op2_scalar != -DBL_MAX) {
01024                                 calc_f1i = TRUE;
01025                             } else if (((single_ifu == TRUE) &&
01026                                         (desc2.sub_desc[0].valid_data == TRUE))
01027                                        ||
01028                                        (desc2.sub_desc[i - 1].valid_data == TRUE))
01029                             {
01030                                 calc_f1i = TRUE;
01031                             }
01032                         }
01033                     }
01034                     if (desc1.ex_noise == TRUE) {
01035                         if (desc1.sub_desc[2 * i - 1].valid_data == TRUE) {
01036                             calc_f1i = TRUE;
01037                         }
01038                     }
01039                     if ((desc1.ex_noise == TRUE) && (desc2.ex_noise == TRUE)) {
01040                         if (desc1.sub_desc[2 * i - 1].valid_data == TRUE) {
01041                             if (((single_ifu == TRUE) &&
01042                                  (desc2.sub_desc[1].valid_data == TRUE))
01043                                 ||
01044                                 (desc2.sub_desc[2 * i - 1].valid_data == TRUE))
01045                             {
01046                                 calc_f1i = TRUE;
01047                             }
01048                         }
01049                     }
01050                     if ((single_ifu == TRUE) && (desc1.ex_noise == FALSE)) {
01051                         if ((desc1.sub_desc[i - 1].valid_data == TRUE) &&
01052                             (desc2.sub_desc[0].valid_data == TRUE)) {
01053                             calc_f1i = TRUE;
01054                         }
01055                     }
01056 
01057                     if (calc_f1i == TRUE)
01058                     {
01059                         KMO_TRY_EXIT_IF_NULL(
01060                             op1_1d = kmo_dfs_load_vector(frameset, "0",
01061                                                          devnr1, FALSE));
01062                         //
01063                         // process F1I & F1I
01064                         //
01065                         if (desc2.fits_type == f1i_fits) {
01066                             if (single_ifu == FALSE) {
01067                                 KMO_TRY_EXIT_IF_NULL(
01068                                     op2_1d = kmo_dfs_load_vector(frameset, "1",
01069                                                                  devnr2, FALSE));
01070                             }
01071 
01072                             if ((desc1.ex_noise == TRUE) &&
01073                                 (desc2.ex_noise == TRUE))
01074                             {
01075                                 KMO_TRY_EXIT_IF_NULL(
01076                                     op1_noise_1d = kmo_dfs_load_vector(
01077                                                                 frameset, "0",
01078                                                                 devnr1, TRUE));
01079 
01080                                 if (single_ifu == FALSE) {
01081                                     KMO_TRY_EXIT_IF_NULL(
01082                                         op2_noise_1d = kmo_dfs_load_vector(
01083                                                                 frameset, "1",
01084                                                                 devnr2, TRUE));
01085                                 }
01086                             }
01087 
01088                             KMO_TRY_EXIT_IF_ERROR(
01089                                 kmo_arithmetic_1D_1D(op1_1d, op2_1d,
01090                                                      op1_noise_1d, op2_noise_1d,
01091                                                      op));
01092                         }
01093                         //
01094                         // process F1I & scalar
01095                         //
01096                         else if (op2_scalar != -DBL_MAX) {
01097                             if (desc1.ex_noise == TRUE) {
01098                                 KMO_TRY_EXIT_IF_NULL(
01099                                     op1_noise_1d = kmo_dfs_load_vector(
01100                                                                 frameset, "0",
01101                                                                 devnr1, TRUE));
01102                             }
01103 
01104                             KMO_TRY_EXIT_IF_ERROR(
01105                                 kmo_arithmetic_1D_scalar(op1_1d,
01106                                                          op2_scalar,
01107                                                          op1_noise_1d,
01108                                                          op));
01109                         }
01110 
01111                         // save data (and noise)
01112                         KMO_TRY_EXIT_IF_ERROR(
01113                             kmo_dfs_save_vector(op1_1d, fn_out, "",
01114                                                 sub_header_data, 0./0.));
01115 
01116                         if (op1_noise_1d != NULL) {
01117                             KMO_TRY_EXIT_IF_NULL(
01118                                 sub_header_noise = kmo_dfs_load_sub_header(
01119                                                                 frameset, "0",
01120                                                                 devnr1, TRUE));
01121 
01122                             KMO_TRY_EXIT_IF_ERROR(
01123                                 kmo_dfs_save_vector(op1_noise_1d, fn_out, "",
01124                                                     sub_header_noise, 0./0.));
01125 
01126                             cpl_propertylist_delete(sub_header_noise);
01127                             sub_header_noise = NULL;
01128                         }
01129                     } else {
01130                         //
01131                         // invalid IFU, just save sub_header
01132                         //
01133                         KMO_TRY_EXIT_IF_ERROR(
01134                             kmo_dfs_save_sub_header(fn_out, "", sub_header_data));
01135 
01136                         // save noise if it has been calculated
01137                         if ((desc1.ex_noise == TRUE)
01138                             &&
01139                             (((desc2.fits_type == f2i_fits) && (desc2.ex_noise == TRUE)) ||
01140                              (op2_scalar != -DBL_MAX)))
01141                         {
01142 
01143                             KMO_TRY_EXIT_IF_NULL(
01144                                 sub_header_noise = kmo_dfs_load_sub_header(
01145                                                                frameset,
01146                                                                "0", devnr1,
01147                                                                TRUE));
01148                             KMO_TRY_EXIT_IF_ERROR(
01149                                 kmo_dfs_save_sub_header(fn_out, "",
01150                                                         sub_header_noise));
01151 
01152                             cpl_propertylist_delete(sub_header_noise);
01153                             sub_header_noise = NULL;
01154                         }
01155                     }
01156                     break;
01157                 default:
01158                     break;
01159             }
01160 
01161             cpl_propertylist_delete(sub_header_data); sub_header_data = NULL;
01162 
01163             cpl_image_delete(op1_2d); op1_2d = NULL;
01164             cpl_imagelist_delete(op1_3d); op1_3d = NULL;
01165 
01166             cpl_image_delete(op1_noise_2d); op1_noise_2d = NULL;
01167             cpl_imagelist_delete(op1_noise_3d); op1_noise_3d = NULL;
01168 
01169             if (single_ifu == FALSE) {
01170                 kmclipm_vector_delete(op2_1d); op2_1d = NULL,
01171                 cpl_image_delete(op2_2d); op2_2d = NULL;
01172                 cpl_imagelist_delete(op2_3d); op2_3d = NULL;
01173 
01174                 kmclipm_vector_delete(op2_noise_1d); op2_noise_1d = NULL,
01175                 cpl_image_delete(op2_noise_2d); op2_noise_2d = NULL;
01176                 cpl_imagelist_delete(op2_noise_3d); op2_noise_3d = NULL;
01177             }
01178         }
01179     }
01180     KMO_CATCH
01181     {
01182         KMO_CATCH_MSG();
01183         ret_val = -1;
01184     }
01185 
01186     kmo_free_fits_desc(&desc1);
01187     kmo_free_fits_desc(&desc2);
01188     cpl_free(fn_out); fn_out = NULL;
01189     cpl_propertylist_delete(main_header); main_header = NULL;
01190     cpl_propertylist_delete(sub_header_data); sub_header_data = NULL;
01191     cpl_propertylist_delete(sub_header_noise); sub_header_noise = NULL;
01192     cpl_image_delete(op1_2d); op1_2d = NULL;
01193     cpl_imagelist_delete(op1_3d); op1_3d = NULL;
01194     kmclipm_vector_delete(op2_1d); op2_1d = NULL;
01195     cpl_image_delete(op2_2d); op2_2d = NULL;
01196     cpl_imagelist_delete(op2_3d); op2_3d = NULL;
01197     cpl_image_delete(op1_noise_2d); op1_noise_2d = NULL;
01198     cpl_imagelist_delete(op1_noise_3d); op1_noise_3d = NULL;
01199     kmclipm_vector_delete(op2_noise_1d); op2_noise_1d = NULL;
01200     cpl_image_delete(op2_noise_2d); op2_noise_2d = NULL;
01201     cpl_imagelist_delete(op2_noise_3d); op2_noise_3d = NULL;
01202 
01203     return ret_val;
01204 }
01205