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