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