KMOS Pipeline Reference Manual  1.1.3
kmo_fits_strip.c
00001 /* $Id: kmo_fits_strip.c,v 1.7 2013/03/01 12:45:29 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/03/01 12:45:29 $
00024  * $Revision: 1.7 $
00025  * $Name: HEAD $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 #include <math.h>
00033 #include <string.h>
00034 
00035 #include <cpl.h>
00036 
00037 #include "kmclipm_constants.h"
00038 #include "kmclipm_functions.h"
00039 
00040 #include "kmo_dfs.h"
00041 #include "kmo_error.h"
00042 #include "kmo_debug.h"
00043 
00044 static int kmo_fits_strip_create(cpl_plugin *);
00045 static int kmo_fits_strip_exec(cpl_plugin *);
00046 static int kmo_fits_strip_destroy(cpl_plugin *);
00047 static int kmo_fits_strip(cpl_parameterlist *, cpl_frameset *);
00048 
00049 static char kmo_fits_strip_description[] =
00050 "With this recipe KMOS fits frames can be stripped in following way:\n"
00051 "\n"
00052 "--noise\n"
00053 "All noise extensions will be removed. Only the data extensions remain.\n"
00054 "\n"
00055 "--angle\n"
00056 "Applies only to calibration products from kmo_flat and kmo_wave_cal.\n"
00057 "All extensions matching provided angle are kept, the others are removed.\n"
00058 "\n"
00059 "--empty\n"
00060 "All empty extensions will be removed.\n"
00061 "\n"
00062 "All parameters can be combined. When no parameter is provided, no output\n"
00063 "will be generated.\n"
00064 "\n"
00065 "-------------------------------------------------------------------------------\n"
00066 "  Input files:\n"
00067 "\n"
00068 "   DO                    KMOS                                                  \n"
00069 "   category              Type   Explanation                    Required #Frames\n"
00070 "   --------              -----  -----------                    -------- -------\n"
00071 "   <none or any>         F2D or frame to strip                     Y       1   \n"
00072 "                         F3I or\n"
00073 "                         F2I or\n"
00074 "                         F1I or\n"
00075 "\n"
00076 "  Output files:\n"
00077 "\n"
00078 "   DO                    KMOS\n"
00079 "   category              Type   Explanation\n"
00080 "   --------              -----  -----------\n"
00081 "   STRIP                 F2D    Stripped frame\n"
00082 "-------------------------------------------------------------------------------\n"
00083 "\n";
00084 
00101 int cpl_plugin_get_info(cpl_pluginlist *list)
00102 {
00103     cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
00104     cpl_plugin *plugin = &recipe->interface;
00105 
00106     cpl_plugin_init(plugin,
00107                         CPL_PLUGIN_API,
00108                         KMOS_BINARY_VERSION,
00109                         CPL_PLUGIN_TYPE_RECIPE,
00110                         "kmo_fits_strip",
00111                         "Strip noise, rotator and/or empty extensions from a "
00112                         "processed KMOS fits frame",
00113                         kmo_fits_strip_description,
00114                         "Alex Agudo Berbel",
00115                         "agudo@mpe.mpg.de",
00116                         kmos_get_license(),
00117                         kmo_fits_strip_create,
00118                         kmo_fits_strip_exec,
00119                         kmo_fits_strip_destroy);
00120 
00121     cpl_pluginlist_append(list, plugin);
00122 
00123     return 0;
00124 }
00125 
00133 static int kmo_fits_strip_create(cpl_plugin *plugin)
00134 {
00135     cpl_recipe *recipe = NULL;
00136     cpl_parameter *p = NULL;
00137 
00138     /* Check that the plugin is part of a valid recipe */
00139     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00140         recipe = (cpl_recipe *)plugin;
00141     else
00142         return -1;
00143 
00144     /* Create the parameters list in the cpl_recipe object */
00145     recipe->parameters = cpl_parameterlist_new();
00146 
00147     /* Fill the parameters list */
00148     /* --empty */
00149     p = cpl_parameter_new_value("kmos.kmo_fits_strip.empty",
00150                                 CPL_TYPE_BOOL,
00151                                 "TRUE: if empty extensions shall be removed,"
00152                                 " FALSE: otherwise",
00153                                 "kmos.kmo_fits_strip",
00154                                 FALSE);
00155     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "empty");
00156     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00157     cpl_parameterlist_append(recipe->parameters, p);
00158 
00159     /* --noise */
00160     p = cpl_parameter_new_value("kmos.kmo_fits_strip.noise",
00161                                 CPL_TYPE_BOOL,
00162                                 "TRUE: if noise extensions shall be removed,"
00163                                 " FALSE: otherwise",
00164                                 "kmos.kmo_fits_strip",
00165                                 FALSE);
00166     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "noise");
00167     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00168     cpl_parameterlist_append(recipe->parameters, p);
00169 
00170     /* --angle */
00171     p = cpl_parameter_new_value("kmos.kmo_fits_strip.angle",
00172                                 CPL_TYPE_INT,
00173                                 "All extensions not matching provided angle "
00174                                 "are stripped.",
00175                                 "kmos.kmo_fits_strip",
00176                                 -1);
00177     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "angle");
00178     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00179     cpl_parameterlist_append(recipe->parameters, p);
00180 
00181     return 0;
00182 }
00183 
00189 static int kmo_fits_strip_exec(cpl_plugin *plugin)
00190 {
00191     cpl_recipe  *recipe;
00192 
00193     /* Get the recipe out of the plugin */
00194     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00195         recipe = (cpl_recipe *)plugin;
00196     else return -1 ;
00197 
00198     return kmo_fits_strip(recipe->parameters, recipe->frames);
00199 }
00200 
00206 static int kmo_fits_strip_destroy(cpl_plugin *plugin)
00207 {
00208     cpl_recipe *recipe;
00209 
00210     /* Get the recipe out of the plugin */
00211     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00212         recipe = (cpl_recipe *)plugin;
00213     else return -1 ;
00214 
00215     cpl_parameterlist_delete(recipe->parameters);
00216     return 0 ;
00217 }
00218 
00219 static const char * kmos_get_base_name(const char * self)
00220 {
00221     const char * p = self ? strrchr(self, '/') : NULL;
00222 
00223     return p ? p + 1 : self;
00224 }
00225 
00244 static int kmo_fits_strip(cpl_parameterlist *parlist, cpl_frameset *frameset)
00245 {
00246 #define PRO_REC_PARAMi_NAME         "ESO PRO REC1 PARAM%d NAME"
00247 #define PRO_REC_PARAMi_VALUE        "ESO PRO REC1 PARAM%d VALUE"
00248 
00249     int                 ret_val             = 0,
00250                         nr_devices          = 0,
00251                         remove_noise        = FALSE,
00252                         remove_empty        = FALSE,
00253                         remove_angle        = FALSE,
00254                         found_angle         = FALSE,
00255                         isCalFrame          = 0,
00256                         isMasterFlat        = 0,
00257                         actDetNr            = 0,
00258                         cal_device_nr       = 0,
00259                         dummy               = 0,
00260                         npar                = 0,
00261                         index               = 0;
00262     double              angle               = 0.,
00263                         tmp_angle           = 0.,
00264                         ret_angle           = 0.,
00265                         ocsRotAngle         = 0.,
00266                         proRotAngle         = 0.;
00267     cpl_propertylist    *header             = NULL,
00268                         *sub_header         = NULL;
00269     cpl_imagelist       *cube               = NULL;
00270     cpl_image           *img                = NULL;
00271     cpl_vector          *vec                = NULL;
00272     main_fits_desc      desc;
00273     cpl_frame           *frame              = NULL;
00274     const char          *kname              = NULL,
00275                         *filename           = NULL;
00276     char                *ggg                = NULL,
00277                         cval[1024];
00278     const cpl_parameter *param              = NULL;
00279     cpl_frame           *product_frame      = NULL;
00280     kmclipm_vector      *kv                 = NULL;
00281 
00282     KMO_TRY
00283     {
00284         kmo_init_fits_desc(&desc);
00285 
00286         /* --- check input --- */
00287         KMO_TRY_ASSURE((parlist != NULL) &&
00288                        (frameset != NULL),
00289                        CPL_ERROR_NULL_INPUT,
00290                        "Not all input data is provided!");
00291 
00292         KMO_TRY_ASSURE(cpl_frameset_get_size(frameset) == 1,
00293                        CPL_ERROR_NULL_INPUT,
00294                        "A fits-file must be provided!");
00295 
00296         KMO_TRY_EXIT_IF_NULL(
00297             frame = kmo_dfs_get_frame(frameset, "0"));
00298 
00299         KMO_TRY_EXIT_IF_NULL(
00300             filename = cpl_frame_get_filename(frame));
00301 
00302         desc = kmo_identify_fits_header(filename);
00303         KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to be "
00304                                       "in KMOS-format!");
00305 
00306         KMO_TRY_ASSURE((desc.fits_type == f2d_fits) ||
00307                        (desc.fits_type == f3i_fits) ||
00308                        (desc.fits_type == f2i_fits) ||
00309                        (desc.fits_type == f1i_fits),
00310                        CPL_ERROR_ILLEGAL_INPUT,
00311                        "Input data hasn't correct data type "
00312                        "(KMOSTYPE must be F2D, F3I, F2I or F1I)!");
00313 
00314         KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_fits_strip") == 1,
00315                        CPL_ERROR_ILLEGAL_INPUT,
00316                        "Cannot identify RAW and CALIB frames!");
00317 
00318         cpl_msg_info("", "--- Parameter setup for kmo_fits_strip ----");
00319         remove_empty = kmo_dfs_get_parameter_bool(parlist,
00320                                                   "kmos.kmo_fits_strip.empty");
00321         KMO_TRY_CHECK_ERROR_STATE();
00322         KMO_TRY_ASSURE((remove_empty == TRUE) ||
00323                        (remove_empty == FALSE),
00324                        CPL_ERROR_ILLEGAL_INPUT,
00325                        "empty must be TRUE or FALSE!");
00326         KMO_TRY_EXIT_IF_ERROR(
00327             kmo_dfs_print_parameter_help(parlist, "kmos.kmo_fits_strip.empty"));
00328 
00329         remove_noise = kmo_dfs_get_parameter_bool(parlist,
00330                                                   "kmos.kmo_fits_strip.noise");
00331         KMO_TRY_CHECK_ERROR_STATE();
00332         KMO_TRY_ASSURE((remove_noise == TRUE) ||
00333                        (remove_noise == FALSE),
00334                        CPL_ERROR_ILLEGAL_INPUT,
00335                        "noise must be TRUE or FALSE!");
00336         KMO_TRY_EXIT_IF_ERROR(
00337             kmo_dfs_print_parameter_help(parlist, "kmos.kmo_fits_strip.noise"));
00338 
00339         angle = kmo_dfs_get_parameter_int(parlist,
00340                                           "kmos.kmo_fits_strip.angle");
00341         KMO_TRY_CHECK_ERROR_STATE();
00342         KMO_TRY_EXIT_IF_ERROR(
00343             kmo_dfs_print_parameter_help(parlist, "kmos.kmo_fits_strip.angle"));
00344 
00345         if (angle >= 0) {
00346             remove_angle = TRUE;
00347         }
00348 
00349         KMO_TRY_ASSURE(!remove_angle || ((angle >=0) && (angle < 360)),
00350                        CPL_ERROR_ILLEGAL_INPUT,
00351                        "angle must be between 0 and 360 degrees!");
00352 
00353         cpl_msg_info("", "-------------------------------------------");
00354 
00355         if ((!remove_empty) && (!remove_noise) && (!remove_angle)) {
00356             // do nothing
00357             cpl_msg_info("","No action has been specified (angle-, noise- or empty-parameter),"
00358                             " therefore no output is generated");
00359         } else {
00360             // check if it is a multi-angle-calibration file
00361             isCalFrame = FALSE;
00362             KMO_TRY_EXIT_IF_NULL(
00363                 sub_header = kmo_dfs_load_sub_header(frameset, "0", 1, FALSE));
00364             if (cpl_propertylist_has(sub_header, CAL_ROTANGLE)) {
00365                 isCalFrame = TRUE;
00366             }
00367             cpl_propertylist_delete(sub_header); sub_header = NULL;
00368 
00369             //
00370             // --- save primary extension ---
00371             //
00372             // load data and save it away again
00373             KMO_TRY_EXIT_IF_NULL(
00374                 header = kmo_dfs_load_primary_header(frameset, "0"));
00375 
00376             if (strcmp(MASTER_FLAT, cpl_propertylist_get_string(header, CPL_DFS_PRO_CATG))==0) {
00377                 isMasterFlat = TRUE;
00378             }
00379 
00380             if (remove_angle && isCalFrame) {
00381                 // update OCS.ROT.NAANGLE if it differs
00382                 ocsRotAngle = cpl_propertylist_get_double(header, ROTANGLE);
00383                 ocsRotAngle = kmclipm_strip_angle(&ocsRotAngle);
00384                 proRotAngle = kmclipm_cal_propertylist_find_angle(filename, 1, FALSE, angle, &dummy);
00385                 KMO_TRY_CHECK_ERROR_STATE();
00386                 if (fabs(ocsRotAngle-proRotAngle) > 0.1) {
00387                     cpl_msg_warning("", "In the product the original ESO OCS ROT NAANGLE keyword "
00388                                         "has been updated with the chosen "
00389                                         "ESO PRO ROT NAANGLE (was: %g, is: %g)!", ocsRotAngle, proRotAngle);
00390                     KMO_TRY_EXIT_IF_ERROR(
00391                         cpl_propertylist_update_double(header, ROTANGLE, proRotAngle));
00392                 }
00393             }
00394 //            // kmo_dfs_save_main_header() doesn't allow to change ESO OCS ROT NAANGLE
00395 //            KMO_TRY_EXIT_IF_ERROR(
00396 //                kmo_dfs_save_main_header(frameset, STRIP, "", frame,
00397 //                                         header, parlist, cpl_func));
00398             {
00399                 // setup DFS manually (no MD5 calculated...)
00400                 KMO_TRY_EXIT_IF_ERROR(
00401                     cpl_propertylist_update_string(header, "PIPEFILE", "strip.fits"));
00402                 KMO_TRY_EXIT_IF_ERROR(
00403                     cpl_propertylist_update_string(header, CPL_DFS_PRO_CATG, STRIP));
00404                 KMO_TRY_EXIT_IF_ERROR(
00405                     cpl_propertylist_update_string(header, "ESO PRO REC1 ID", cpl_func));
00406                 ggg = cpl_sprintf("cpl-%d.%d.%d", cpl_version_get_major(), cpl_version_get_minor(), cpl_version_get_micro());
00407                 KMO_TRY_EXIT_IF_ERROR(
00408                     cpl_propertylist_update_string(header, "ESO PRO REC1 DRS ID", ggg));
00409                 cpl_free(ggg); ggg = NULL;
00410                 KMO_TRY_EXIT_IF_ERROR(
00411                     cpl_propertylist_update_string(header, "ESO PRO REC1 PIPE ID", VERSION));
00412                 KMO_TRY_EXIT_IF_ERROR(
00413                     cpl_propertylist_update_string(header, "ESO PRO REC1 CAL1 NAME", kmos_get_base_name(filename)));
00414                 KMO_TRY_EXIT_IF_ERROR(
00415                     cpl_propertylist_update_string(header, "ESO PRO REC1 CAL1 CATG", COMMANDLINE));
00416                 KMO_TRY_EXIT_IF_ERROR(
00417                     cpl_propertylist_update_string(header, "ESO PRO REC1 CAL1 DATAMD5", cpl_propertylist_get_string(header, "DATAMD5")));
00418                 KMO_TRY_CHECK_ERROR_STATE();
00419 
00420                 while (param != NULL) {
00421                     char *pval, *dval;
00422                     ++npar;
00423 
00424                     kname = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00425                     const char * comment = cpl_parameter_get_help(param);
00426                     switch (cpl_parameter_get_type(param)) {
00427                     case CPL_TYPE_BOOL:
00428                         pval = cpl_strdup(cpl_parameter_get_bool(param) == 1 ? "true" : "false");
00429                         dval = cpl_sprintf("Default: %s", cpl_parameter_get_default_bool(param) == 1 ? "true" : "false");
00430                         break;
00431                     case CPL_TYPE_INT:
00432                         pval = cpl_sprintf("%d", cpl_parameter_get_int(param));
00433                         dval = cpl_sprintf("Default: %d", cpl_parameter_get_default_int(param));
00434                         break;
00435                     case CPL_TYPE_DOUBLE:
00436                         pval = cpl_sprintf("%g", cpl_parameter_get_double(param));
00437                         dval = cpl_sprintf("Default: %g", cpl_parameter_get_default_double(param));
00438                         break;
00439                     case CPL_TYPE_STRING:
00440                         pval = cpl_strdup(cpl_parameter_get_string(param));
00441                         dval = cpl_sprintf("Default: '%s'", cpl_parameter_get_default_string(param));
00442                         break;
00443                     default:
00444                         /* Theoretically impossible to get here */
00445                         KMO_TRY_ASSURE(1==0,
00446                                        CPL_ERROR_UNSPECIFIED,
00447                                        "what?");
00448                     }
00449                     snprintf(cval, 1024, PRO_REC_PARAMi_NAME, npar);
00450                     cpl_propertylist_update_string(header, cval, kname);
00451                     cpl_propertylist_set_comment(header, cval, comment);
00452 
00453                     snprintf(cval, 1024, PRO_REC_PARAMi_VALUE, npar);
00454                     cpl_propertylist_update_string(header, cval, pval);
00455                     cpl_propertylist_set_comment(header, cval, dval);
00456 
00457                     cpl_free((void*)pval);
00458                     cpl_free((void*)dval);
00459 
00460                     param = cpl_parameterlist_get_next_const(parlist);
00461                 }
00462             }
00463             KMO_TRY_CHECK_ERROR_STATE();
00464 
00465             cpl_msg_info(cpl_func, "Writing FITS %s product(%s): %s", "propertylist", "STRIP", "strip.fits");
00466             KMO_TRY_EXIT_IF_NULL(
00467                 product_frame = cpl_frame_new());
00468             KMO_TRY_EXIT_IF_ERROR(
00469                 cpl_frame_set_filename(product_frame, "strip.fits"));
00470             KMO_TRY_EXIT_IF_ERROR(
00471                 cpl_frame_set_tag(product_frame, "STRIP"));
00472             KMO_TRY_EXIT_IF_ERROR(
00473                 cpl_frame_set_type(product_frame, CPL_FRAME_TYPE_ANY));
00474             KMO_TRY_EXIT_IF_ERROR(
00475                 cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT));
00476             KMO_TRY_EXIT_IF_ERROR(
00477                 cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL));
00478             KMO_TRY_EXIT_IF_ERROR(
00479                 cpl_frameset_insert(frameset, product_frame));
00480 
00481             KMO_TRY_EXIT_IF_ERROR(
00482                 cpl_propertylist_save(header, "strip.fits", CPL_IO_CREATE));
00483             cpl_propertylist_delete(header); header = NULL;
00484 
00485             if (!isCalFrame) {
00486                 if (!desc.ex_noise) {
00487                     nr_devices = desc.nr_ext;
00488                 } else {
00489                     nr_devices = desc.nr_ext / 2;
00490                 }
00491             } else {
00492                 nr_devices = 3;
00493             }
00494 
00495             if (isCalFrame) {
00496                 if (isMasterFlat) {
00497                     remove_noise = !remove_noise;
00498                 }
00499             } else {
00500                 if (desc.ex_noise) {
00501                     remove_noise = !remove_noise;
00502                 }
00503             }
00504 
00505             actDetNr = 1;
00506             for (int i = 0; i < nr_devices; i++)
00507             {
00508                 // either loop noise or not
00509                 for (int n = FALSE; n <= remove_noise; n++) {
00510                     if (isCalFrame) {
00511                         KMO_TRY_EXIT_IF_NULL(
00512                             header = kmclipm_cal_propertylist_load(filename, i+1, n, angle, &ret_angle));
00513                     } else {
00514                         KMO_TRY_EXIT_IF_NULL(
00515                             header = kmo_dfs_load_sub_header(frameset, "0", i + 1, n));
00516                     }
00517 
00518                     if (remove_angle) {
00519                         // examine angle
00520                         if (cpl_propertylist_has(header, CAL_ROTANGLE)) {
00521                             tmp_angle = cpl_propertylist_get_double(header, CAL_ROTANGLE);
00522                             KMO_TRY_CHECK_ERROR_STATE();
00523 
00524                             if (fabs(angle - tmp_angle) < 0.01) {
00525                                 found_angle = TRUE;
00526                                 isCalFrame = TRUE;
00527                             } else {
00528                                 found_angle = FALSE;
00529                             }
00530                         } else {
00531                             // frame doesn't seem to have the CAL_ROTANGLE keyword
00532                             // process all extensions
00533                             found_angle = TRUE;
00534                         }
00535                     } else {
00536                         found_angle = TRUE;
00537                     }
00538 
00539                     index = kmo_identify_index(filename, i+1, n);
00540                     if (found_angle) {
00541                         if ((desc.fits_type == f2d_fits) ||
00542                             (desc.fits_type == f2i_fits))
00543                         {
00544                             if (isCalFrame) {
00545                                 cal_device_nr = cpl_propertylist_get_int(header, CHIPINDEX);
00546                                 KMO_TRY_CHECK_ERROR_STATE();
00547                                 if (cal_device_nr == actDetNr) {
00548                                     KMO_TRY_EXIT_IF_ERROR(
00549                                         kmo_update_sub_keywords(header,
00550                                                                 n,
00551                                                                 FALSE,
00552                                                                 desc.frame_type,
00553                                                                 actDetNr));
00554                                     KMO_TRY_EXIT_IF_NULL(
00555                                         img = kmo_dfs_load_cal_image(frameset, "0",
00556                                                                      i+1, n, angle,
00557                                                                      FALSE, NULL,
00558                                                                      &ret_angle));
00559 
00560                                     if (fabs(angle-ret_angle) > 0.01) {
00561                                         cpl_msg_warning("","Angle provided: %g, angle found: %g", angle, ret_angle);
00562                                     }
00563                                     if (n == remove_noise) {
00564                                         actDetNr++;
00565                                     }
00566                                 }
00567                                 if (img != NULL) {
00568                                     KMO_TRY_EXIT_IF_ERROR(
00569                                         kmo_dfs_save_image(img, STRIP, "", header, 0./0.));
00570                                 }
00571                             } else {
00572                                 img = cpl_image_load(filename,CPL_TYPE_FLOAT, 0, index);
00573                                 if (CPL_ERROR_NONE != cpl_error_get_code()) {
00574                                     cpl_error_reset();
00575                                     if (!remove_empty) {
00576                                         KMO_TRY_EXIT_IF_ERROR(
00577                                             kmo_dfs_save_image(img, STRIP, "", header, 0./0.));
00578                                     }
00579                                 } else {
00580                                     KMO_TRY_EXIT_IF_ERROR(
00581                                         kmo_dfs_save_image(img, STRIP, "", header, 0./0.));
00582                                 }
00583                             }
00584                             cpl_image_delete(img); img = NULL;
00585                         } else if (desc.fits_type == f3i_fits) {
00586                             cube = cpl_imagelist_load(filename,CPL_TYPE_FLOAT, index);
00587                             if (CPL_ERROR_NONE != cpl_error_get_code()) {
00588                                 cpl_error_reset();
00589                                 if (!remove_empty) {
00590                                     KMO_TRY_EXIT_IF_ERROR(
00591                                         kmo_dfs_save_cube(cube, STRIP, "", header, 0./0.));
00592                                 }
00593                             } else {
00594                                 KMO_TRY_EXIT_IF_ERROR(
00595                                     kmo_dfs_save_cube(cube, STRIP, "", header, 0./0.));
00596                             }
00597                             cpl_imagelist_delete(cube); cube = NULL;
00598                         } else if (desc.fits_type == f1i_fits) {
00599                             vec = cpl_vector_load(filename, index);
00600                             if (CPL_ERROR_NONE != cpl_error_get_code()) {
00601                                 cpl_error_reset();
00602                                 if (!remove_empty) {
00603                                     KMO_TRY_EXIT_IF_ERROR(
00604                                         kmo_dfs_save_vector(NULL, STRIP, "", header, 0./0.));
00605                                 }
00606                             } else {
00607                                 KMO_TRY_EXIT_IF_NULL(
00608                                     kv = kmclipm_vector_create(vec));
00609                                 KMO_TRY_EXIT_IF_ERROR(
00610                                     kmo_dfs_save_vector(kv, STRIP, "", header, 0./0.));
00611                             }
00612                             kmclipm_vector_delete(kv); kv = NULL;
00613                         }
00614                     } // if (found_angle)
00615                     cpl_propertylist_delete(header); header = NULL;
00616                 } // for (n)
00617             } // for (i = nr_devices)
00618         } // if ((!remove_empty) && (!remove_noise) && (!remove_angle))
00619     }
00620     KMO_CATCH
00621     {
00622         KMO_CATCH_MSG();
00623 
00624         ret_val = -1;
00625     }
00626 
00627     cpl_propertylist_delete(header); header = NULL;
00628     cpl_imagelist_delete(cube); cube = NULL;
00629     cpl_image_delete(img); img = NULL;
00630     kmclipm_vector_delete(kv); kv = NULL;
00631     kmo_free_fits_desc(&desc);
00632 
00633     return ret_val;
00634 }
00635