KMOS Pipeline Reference Manual  1.2.3
kmo_stats.c
00001 /* $Id: kmo_stats.c,v 1.16 2013/05/24 13:35:28 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/05/24 13:35:28 $
00024  * $Revision: 1.16 $
00025  * $Name: HEAD $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033  *                              Includes
00034  *----------------------------------------------------------------------------*/
00035 
00036 #include <string.h>
00037 
00038 #include <cpl.h>
00039 
00040 #include "kmo_utils.h"
00041 #include "kmo_dfs.h"
00042 #include "kmo_priv_stats.h"
00043 #include "kmo_priv_functions.h"
00044 #include "kmo_error.h"
00045 #include "kmo_debug.h"
00046 #include "kmo_constants.h"
00047 
00048 /*-----------------------------------------------------------------------------
00049  *                          Functions prototypes
00050  *----------------------------------------------------------------------------*/
00051 
00052 static int kmo_stats_create(cpl_plugin *);
00053 static int kmo_stats_exec(cpl_plugin *);
00054 static int kmo_stats_destroy(cpl_plugin *);
00055 static int kmo_stats(cpl_parameterlist *, cpl_frameset *);
00056 
00057 /*-----------------------------------------------------------------------------
00058  *                          Static variables
00059  *----------------------------------------------------------------------------*/
00060 
00061 static char kmo_stats_description[] =
00062 "This recipe performs basic statistics on KMOS-conform data-frames of type F2D,\n"
00063 "F1I, F2I and F3I either with or without noise and RAW. Optionally a 2D mask\n"
00064 "can be provided to define a region on which the statistics should be calculated\n"
00065 "on (mask 0: exclude pixel, mask 1: include pixel). A mask can’t be provided for\n"
00066 "statistics on F1I frames.\n"
00067 "The output is stored in a vector of length 11. The vector represents following\n"
00068 "values:\n"
00069 "   1.  Number of pixels\n"
00070 "   2.  Number of finite pixels\n"
00071 "   3.  Mean\n"
00072 "   4.  Standard Deviation\n"
00073 "   5.  Mean with iterative rejection (i.e. mean & sigma are calculated iterati-\n"
00074 "       vely, each time rejecting pixels more than +/-N sigma from the mean)\n"
00075 "   6.  Standard Deviation with iterative rejection\n"
00076 "   7.  Median\n"
00077 "   8.  Mode (i.e. the peak in a histogram of pixel values)\n"
00078 "   9.  Noise (a robust estimate given by the standard deviation from the nega-\n"
00079 "       tive side of the histogram of pixel values)\n"
00080 "   10. Minimum\n"
00081 "   11. Maximum\n"
00082 "\n"
00083 "The same numerical operations are applied to the noise as with the data itself.\n"
00084 "\n"
00085 "BASIC PARAMETERS:\n"
00086 "-----------------\n"
00087 "--ext\n"
00088 "These parameters specify with extensions to process. The value 0, which is\n"
00089 "default, calulates all extensions.\n"
00090 "\n"
00091 "ADVANCED PARAMETERS\n"
00092 "-------------------\n"
00093 "--cpos_rej\n"
00094 "--cneg_rej\n"
00095 "--citer\n"
00096 "An iterative sigma clipping is applied in order to calculate the mode (using\n"
00097 "kmo_stats). For each position all pixels in the spectrum are examined. If they\n"
00098 "deviate significantly, they will be rejected according to the conditions:\n"
00099 "       val > mean + stdev * cpos_rej\n"
00100 "   and\n"
00101 "       val < mean - stdev * cneg_rej\n"
00102 "In the first iteration median and percentile level are used.\n"
00103 "\n"
00104 "-------------------------------------------------------------------------------\n"
00105 "  Input files:\n"
00106 "\n"
00107 "   DO            DO      KMOS                                                  \n"
00108 "   category      group   Type   Explanation                    Required #Frames\n"
00109 "   --------      -----   -----  -----------                    -------- -------\n"
00110 "   <none or any>   -     F3I or The datacubes                      Y       1   \n"
00111 "                         F2I or                                                \n"
00112 "                         F1I or                                                \n"
00113 "                         F2D or                                                \n"
00114 "                         B2D or                                                \n"
00115 "                         RAW                                                   \n"
00116 "   <none or any>   -     F2I or The mask                           N      0,1  \n"
00117 "                         F2D or                                                \n"
00118 "                         B2D or                                                \n"
00119 "                         RAW                                                   \n"
00120 "\n"
00121 "  Output files:\n"
00122 "\n"
00123 "   DO                    KMOS\n"
00124 "   category              Type   Explanation\n"
00125 "   --------              -----  -----------\n"
00126 "   STATS                 F1I    Calculated statistics parameters \n"
00127 "-------------------------------------------------------------------------------\n"
00128 "\n";
00129 
00130 /*-----------------------------------------------------------------------------
00131  *                              Functions code
00132  *----------------------------------------------------------------------------*/
00133 
00150 int cpl_plugin_get_info(cpl_pluginlist *list)
00151 {
00152     cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
00153     cpl_plugin *plugin = &recipe->interface;
00154 
00155     cpl_plugin_init(plugin,
00156                         CPL_PLUGIN_API,
00157                         KMOS_BINARY_VERSION,
00158                         CPL_PLUGIN_TYPE_RECIPE,
00159                         "kmo_stats",
00160                         "Perform basic statistics on a KMOS-conform fits-file",
00161                         kmo_stats_description,
00162                         "Alex Agudo Berbel",
00163                         "kmos-spark@mpe.mpg.de",
00164                         kmos_get_license(),
00165                         kmo_stats_create,
00166                         kmo_stats_exec,
00167                         kmo_stats_destroy);
00168 
00169     cpl_pluginlist_append(list, plugin);
00170 
00171     return 0;
00172 }
00173 
00181 static int kmo_stats_create(cpl_plugin *plugin)
00182 {
00183     cpl_recipe *recipe;
00184     cpl_parameter *p;
00185 
00186     /* Check that the plugin is part of a valid recipe */
00187     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00188         recipe = (cpl_recipe *)plugin;
00189     else
00190         return -1;
00191 
00192     /* Create the parameters list in the cpl_recipe object */
00193     recipe->parameters = cpl_parameterlist_new();
00194 
00195     /* --ext */
00196     p = cpl_parameter_new_value("kmos.kmo_stats.ext",
00197                                 CPL_TYPE_INT,
00198                                 "The extension the stats should be calculated "
00199                                 "of. Zero is default and calculates the stats "
00200                                 "of all extensions",
00201                                 "kmos.kmo_stats",
00202                                 0);
00203     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ext");
00204     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00205     cpl_parameterlist_append(recipe->parameters, p);
00206 
00207     /* Fill the parameters list */
00208     return kmo_combine_pars_create(recipe->parameters,
00209                                    "kmos.kmo_stats",
00210                                    DEF_REJ_METHOD,
00211                                    TRUE);
00212 }
00213 
00219 static int kmo_stats_exec(cpl_plugin *plugin)
00220 {
00221     cpl_recipe  *recipe;
00222 
00223     /* Get the recipe out of the plugin */
00224     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00225         recipe = (cpl_recipe *)plugin;
00226     else return -1 ;
00227 
00228     return kmo_stats(recipe->parameters, recipe->frames);
00229 }
00230 
00236 static int kmo_stats_destroy(cpl_plugin *plugin)
00237 {
00238     cpl_recipe *recipe;
00239 
00240     /* Get the recipe out of the plugin */
00241     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00242         recipe = (cpl_recipe *)plugin;
00243     else return -1 ;
00244 
00245     cpl_parameterlist_delete(recipe->parameters);
00246     return 0 ;
00247 }
00248 
00263 static int kmo_stats(cpl_parameterlist *parlist, cpl_frameset *frameset)
00264 {
00265     double           cpos_rej            = 0.0,
00266                      cneg_rej            = 0.0;
00267 
00268     cpl_imagelist    *data_in            = NULL;
00269 
00270     cpl_image        *mask               = NULL,
00271                      *img_in             = NULL;
00272 
00273     kmclipm_vector   *vec_in             = NULL,
00274                      *mask_vec           = NULL,
00275                      *data_out           = NULL;
00276 
00277     int              ret_val             = 0,
00278                      nr_devices          = 0,
00279                      i                   = 0,
00280                      j                   = 0,
00281                      tmpi                = 0,
00282                      valid_ifu           = FALSE,
00283                      citer               = 0,
00284                      mask_available      = FALSE,
00285                      ifu                 = 0,
00286                      stats_size          = 0,
00287                      extnr               = 0,
00288                      devnr               = 0,
00289                      index_data          = 0,
00290                      index_noise         = 0;
00291 
00292     cpl_propertylist *sub_header         = NULL;
00293 
00294     main_fits_desc   desc1,
00295                      desc2;
00296 
00297     cpl_frame        *data_frame         = NULL,
00298                      *mask_frame         = NULL;
00299 
00300     char             do_mode1[256],
00301                      do_mode2[256];
00302 
00303     const char       *cmethod            = "ksigma";
00304 
00305     char             *tmp_str            = NULL,
00306                      **strarr            = NULL;
00307 
00308     KMO_TRY
00309     {
00310         kmo_init_fits_desc(&desc1);
00311 
00312         // --- check inputs ---
00313         KMO_TRY_ASSURE((parlist != NULL) &&
00314                        (frameset != NULL),
00315                        CPL_ERROR_NULL_INPUT,
00316                        "Not all input data is provided!");
00317 
00318         KMO_TRY_ASSURE((cpl_frameset_get_size(frameset) == 1) ||
00319                        ((cpl_frameset_get_size(frameset) == 2)),
00320                        CPL_ERROR_NULL_INPUT,
00321                        "Either a cube (F3I) or a cube and a mask (F2I) "
00322                        "must be provided!");
00323 
00324         KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_stats") == 1,
00325                        CPL_ERROR_ILLEGAL_INPUT,
00326                        "Cannot identify RAW and CALIB frames!");
00327 
00328         if (cpl_frameset_get_size(frameset) == 1) {
00329             strcpy(do_mode1, "0");
00330             strcpy(do_mode2, "");
00331         } else {
00332             strcpy(do_mode1, "0");
00333             strcpy(do_mode2, "1");
00334             KMO_TRY_EXIT_IF_NULL(
00335                 mask_frame = kmo_dfs_get_frame(frameset, do_mode2));
00336         }
00337         KMO_TRY_EXIT_IF_NULL(
00338             data_frame = kmo_dfs_get_frame(frameset, do_mode1));
00339 
00340         cpl_msg_info("", "--- Parameter setup for kmo_stats ---------");
00341 
00342         // load descriptor of first operand
00343         desc1 = kmo_identify_fits_header(
00344                     cpl_frame_get_filename(data_frame));
00345         KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to be "
00346                                       "in KMOS-format!");
00347 
00348         KMO_TRY_ASSURE((desc1.fits_type == f3i_fits) ||
00349                        (desc1.fits_type == f1i_fits) ||
00350                        (desc1.fits_type == f2i_fits) ||
00351                        (desc1.fits_type == f2d_fits) ||
00352                        (desc1.fits_type == b2d_fits) ||
00353                        (desc1.fits_type == raw_fits),
00354                        CPL_ERROR_ILLEGAL_INPUT,
00355                        "First input file hasn't correct data type "
00356                        "(KMOSTYPE must be F1I, F2I, F3I, F2D, B2D or RAW)!");
00357 
00358         ifu = kmo_dfs_get_parameter_int(parlist,
00359                                             "kmos.kmo_stats.ext");
00360          KMO_TRY_EXIT_IF_ERROR(
00361              kmo_dfs_print_parameter_help(parlist, "kmos.kmo_stats.ext"));
00362 
00363          KMO_TRY_ASSURE((desc1.nr_ext >= ifu) ||
00364                         (ifu == 0),
00365                         CPL_ERROR_ILLEGAL_INPUT,
00366                         "ext must be smaller or equal to the number of "
00367                         "extensions!");
00368 
00369         KMO_TRY_EXIT_IF_ERROR(
00370             kmo_combine_pars_load(parlist,
00371                                   "kmos.kmo_stats",
00372                                   &cmethod,
00373                                   &cpos_rej,
00374                                   &cneg_rej,
00375                                   &citer,
00376                                   NULL,
00377                                   NULL,
00378                                   TRUE));
00379 
00380 
00381         cpl_msg_info("", "-------------------------------------------");
00382 
00383         // check the (optional) mask
00384         if (cpl_frameset_get_size(frameset) == 2) {
00385             kmo_init_fits_desc(&desc2);
00386 
00387             // load descriptor of second operand
00388             desc2 = kmo_identify_fits_header(
00389                         cpl_frame_get_filename(mask_frame));
00390             KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem "
00391                                           "to be in KMOS-format!");
00392 
00393             mask_available = TRUE;
00394             if ((desc1.fits_type == f3i_fits) ||
00395                 (desc1.fits_type == f2i_fits))
00396             {
00397                 KMO_TRY_ASSURE(desc2.fits_type == f2i_fits,
00398                             CPL_ERROR_ILLEGAL_INPUT,
00399                             "Mask hasn't correct data type "
00400                             "(KMOSTYPE must be F2I)!");
00401                 KMO_TRY_ASSURE((desc1.naxis1 == desc2.naxis1) &&
00402                                (desc1.naxis2 == desc2.naxis2),
00403                                CPL_ERROR_ILLEGAL_INPUT,
00404                                "STAT_DATA and STAT_MASK don't have the same "
00405                                "dimensions!");
00406             } else if ((desc1.fits_type == f2d_fits) ||
00407                        (desc1.fits_type == b2d_fits) ||
00408                        (desc1.fits_type == raw_fits))
00409             {
00410                 KMO_TRY_ASSURE((desc2.fits_type == f2d_fits) ||
00411                                (desc2.fits_type == b2d_fits),
00412                             CPL_ERROR_ILLEGAL_INPUT,
00413                             "Mask file hasn't correct data type "
00414                             "(KMOSTYPE must be F2D or B2D)!");
00415                 KMO_TRY_ASSURE((desc1.naxis1 == desc2.naxis1) &&
00416                                (desc1.naxis2 == desc2.naxis2),
00417                                CPL_ERROR_ILLEGAL_INPUT,
00418                                "STAT_DATA and STAT_MASK don't have the same "
00419                                "dimensions!");
00420             } else if (desc1.fits_type == f1i_fits)
00421             {
00422                 KMO_TRY_ASSURE(1==0,
00423                             CPL_ERROR_ILLEGAL_INPUT,
00424                             "Mask can't be provided for F1I frames!");
00425             } else {
00426                 mask_available = FALSE;
00427             }
00428 
00429             KMO_TRY_ASSURE((desc1.nr_ext == desc2.nr_ext) ||
00430                            (desc1.nr_ext/2 == desc2.nr_ext) ||
00431                            ((desc2.nr_ext == 1) && (ifu > 0) &&
00432                                                          (ifu <= desc1.nr_ext)),
00433                         CPL_ERROR_ILLEGAL_INPUT,
00434                         "Mask hasn't same number of extensions as data!");
00435         }
00436 
00437         if (desc1.ex_noise == TRUE) {
00438             nr_devices = desc1.nr_ext / 2;
00439         } else {
00440             nr_devices = desc1.nr_ext;
00441         }
00442 
00443         if (ifu != 0) {
00444             if (((desc1.ex_noise == FALSE) &&
00445                  (desc1.sub_desc[ifu-1].valid_data == FALSE)) ||
00446                 ((desc1.ex_noise == TRUE) &&
00447                  (desc1.sub_desc[2 * (ifu-1) - 1].valid_data == FALSE)))
00448             {
00449                 cpl_msg_info(cpl_func, "No valid IFU or detector has been "
00450                                        "selected!");
00451                 kmo_free_fits_desc(&desc1);
00452                 kmo_free_fits_desc(&desc2);
00453                 return 0;
00454             }
00455         }
00456 
00457         // --- load, update & save primary header ---
00458         KMO_TRY_EXIT_IF_ERROR(
00459             kmo_dfs_save_main_header(frameset, STATS, "", data_frame,
00460                                      NULL, parlist, cpl_func));
00461         //
00462         // load & process data
00463         //
00464         for (i = 1; i <= nr_devices; i++) {
00465             if (desc1.ex_noise == FALSE) {
00466                 devnr = desc1.sub_desc[i - 1].device_nr;
00467             } else {
00468                 devnr = desc1.sub_desc[2 * i - 1].device_nr;
00469             }
00470 
00471             if (desc1.ex_badpix == FALSE) {
00472                 index_data = kmo_identify_index_desc(desc1, devnr, FALSE);
00473             } else {
00474                 index_data = kmo_identify_index_desc(desc1, devnr, 2);
00475             }
00476             KMO_TRY_CHECK_ERROR_STATE();
00477 
00478             if (desc1.ex_noise) {
00479                 index_noise = kmo_identify_index_desc(desc1, devnr, TRUE);
00480             }
00481             KMO_TRY_CHECK_ERROR_STATE();
00482 
00483             if (i > 1) {
00484                 kmclipm_omit_warning_one_slice = TRUE;
00485             }
00486             if ((ifu == 0) || (ifu == i)) {
00487                 // check if IFU is valid
00488                 valid_ifu = FALSE;
00489                 if (desc1.sub_desc[index_data-1].valid_data == TRUE) {
00490                     valid_ifu = TRUE;
00491                 }
00492 
00493                 if (valid_ifu) {
00494                     // load data
00495 //                    if ((desc1.fits_type == f3i_fits) ||
00496 //                        (desc1.fits_type == f2i_fits) ||
00497 //                        (desc1.fits_type == f2d_fits) ||
00498 //                        (desc1.fits_type == raw_fits)) {
00499                     // load mask, if available
00500                     if (mask_available == TRUE) {
00501                         tmpi = i;
00502                         if (desc2.nr_ext == 1) {
00503                             tmpi = 1;
00504                         }
00505                         if (desc2.naxis == 1) {
00506                             KMO_TRY_EXIT_IF_NULL(
00507                                 mask_vec = kmo_dfs_load_vector(frameset,
00508                                                                do_mode2,
00509                                                                tmpi,
00510                                                                FALSE));
00511                         } else if (desc2.naxis == 2) {
00512                             if (desc2.fits_type == b2d_fits) {
00513                                 KMO_TRY_EXIT_IF_NULL(
00514                                     mask = kmo_dfs_load_image(frameset,
00515                                                               do_mode2,
00516                                                               tmpi,
00517                                                               2, FALSE, NULL));
00518                             } else {
00519                                 KMO_TRY_EXIT_IF_NULL(
00520                                     mask = kmo_dfs_load_image(frameset,
00521                                                               do_mode2,
00522                                                               tmpi,
00523                                                               FALSE, FALSE, NULL));
00524                             }
00525                         } else {
00526                             KMO_TRY_ASSURE(1 == 0,
00527                                            CPL_ERROR_ILLEGAL_INPUT,
00528                                            "STAT_MASK must either be a "
00529                                            "vector or an image!");
00530                         }
00531                     }
00532 //                    }
00533 
00534                     if (desc1.fits_type == f3i_fits) {
00535                         KMO_TRY_EXIT_IF_NULL(
00536                             data_in = kmo_dfs_load_cube(frameset, do_mode1,
00537                                                         devnr, FALSE));
00538                         KMO_TRY_EXIT_IF_NULL(
00539                             data_out = kmo_calc_stats_cube(data_in,
00540                                                            mask,
00541                                                            cpos_rej,
00542                                                            cneg_rej,
00543                                                            citer));
00544                         cpl_imagelist_delete(data_in); data_in = NULL;
00545                     } else if (desc1.fits_type == f1i_fits) {
00546                         KMO_TRY_EXIT_IF_NULL(
00547                             vec_in = kmo_dfs_load_vector(frameset, do_mode1,
00548                                                          devnr, FALSE));
00549                         KMO_TRY_EXIT_IF_NULL(
00550                             data_out = kmo_calc_stats_vec(vec_in,
00551                                                           mask_vec,
00552                                                           cpos_rej,
00553                                                           cneg_rej,
00554                                                           citer));
00555                         kmclipm_vector_delete(vec_in); vec_in = NULL;
00556                     } else if ((desc1.fits_type == f2i_fits) ||
00557                                (desc1.fits_type == f2d_fits) ||
00558                                (desc1.fits_type == b2d_fits) ||
00559                                (desc1.fits_type == raw_fits))
00560                     {
00561                         int sat_mode = FALSE;
00562                         if (desc1.fits_type == raw_fits) {
00563                             sat_mode = TRUE;
00564                         }
00565 
00566                         if (desc1.fits_type == b2d_fits) {
00567                             KMO_TRY_EXIT_IF_NULL(
00568                                 img_in = kmo_dfs_load_image(frameset, do_mode1,
00569                                                             devnr, 2, sat_mode, NULL));
00570                         } else {
00571                             KMO_TRY_EXIT_IF_NULL(
00572                                 img_in = kmo_dfs_load_image(frameset, do_mode1,
00573                                                             devnr,
00574                                                             FALSE, sat_mode, NULL));
00575                         }
00576                         KMO_TRY_EXIT_IF_NULL(
00577                             data_out = kmo_calc_stats_img(img_in,
00578                                                           mask,
00579                                                           cpos_rej,
00580                                                           cneg_rej,
00581                                                           citer));
00582                         cpl_image_delete(img_in); img_in = NULL;
00583                     } else {
00584                         KMO_TRY_ASSURE(1==0,
00585                                        CPL_ERROR_ILLEGAL_INPUT,
00586                                        "Unsupported fits_type!");
00587                     }
00588 
00589                     stats_size = kmclipm_vector_get_size(data_out);
00590 
00591                     if ((desc1.fits_type == f3i_fits) ||
00592                         (desc1.fits_type == f2i_fits) ||
00593                         (desc1.fits_type == f2d_fits) ||
00594                         (desc1.fits_type == b2d_fits) ||
00595                         (desc1.fits_type == raw_fits))
00596                     {
00597                         if (mask_available == TRUE) {
00598                             cpl_image_delete(mask); mask = NULL;
00599                         }
00600                     }
00601 
00602                     // save data
00603                     if (desc1.fits_type == b2d_fits) {
00604                         KMO_TRY_EXIT_IF_NULL(
00605                             sub_header = kmo_dfs_load_sub_header(frameset, do_mode1, devnr,
00606                                                                  2));
00607                     } else {
00608                         KMO_TRY_EXIT_IF_NULL(
00609                             sub_header = kmo_dfs_load_sub_header(frameset, do_mode1, devnr,
00610                                                                  FALSE));
00611                     }
00612 
00613                     if ((desc1.fits_type == raw_fits) ||
00614                         (desc1.fits_type == b2d_fits))
00615                     {
00616                         KMO_TRY_EXIT_IF_NULL(
00617                             tmp_str = cpl_sprintf("%s%d%s", "DET.",
00618                                                   devnr,
00619                                                   ".DATA"));
00620                         KMO_TRY_EXIT_IF_ERROR(
00621                             kmclipm_update_property_string(sub_header,
00622                                                     EXTNAME,
00623                                                     tmp_str,
00624                                                     "FITS extension name"));
00625                         cpl_free(tmp_str); tmp_str = NULL;
00626                     }
00627 
00628                     KMO_TRY_EXIT_IF_ERROR(
00629                         kmo_dfs_save_vector(data_out, STATS, "", sub_header, 0./0.));
00630 
00631                     cpl_propertylist_delete(sub_header); sub_header = NULL;
00632                     kmclipm_vector_delete(data_out); data_out = NULL;
00633 
00634                     //
00635                     // do exactly the same thing for noise, if existing
00636                     //
00637                     if (desc1.ex_noise) {
00638                         if (desc1.sub_desc[index_noise-1].valid_data) {
00639                             if (desc1.fits_type == f3i_fits) {
00640                                 KMO_TRY_EXIT_IF_NULL(
00641                                     data_in = kmo_dfs_load_cube(frameset, do_mode1,
00642                                                                 devnr, TRUE));
00643 
00644                                 KMO_TRY_EXIT_IF_NULL(
00645                                     data_out = kmo_calc_stats_cube(data_in,
00646                                                                    mask,
00647                                                                    cpos_rej,
00648                                                                    cneg_rej,
00649                                                                    citer));
00650                                 cpl_imagelist_delete(data_in); data_in = NULL;
00651                             } else if (desc1.fits_type == f1i_fits) {
00652                                 KMO_TRY_EXIT_IF_NULL(
00653                                     vec_in = kmo_dfs_load_vector(frameset, do_mode1,
00654                                                                  devnr, TRUE));
00655                                 KMO_TRY_EXIT_IF_NULL(
00656                                     data_out = kmo_calc_stats_vec(vec_in,
00657                                                                   mask_vec,
00658                                                                   cpos_rej,
00659                                                                   cneg_rej,
00660                                                                   citer));
00661                                 kmclipm_vector_delete(vec_in); vec_in = NULL;
00662                             } else if ((desc1.fits_type == f2i_fits) ||
00663                                        (desc1.fits_type == f2d_fits) ||
00664                                        (desc1.fits_type == raw_fits))
00665                             {
00666                                 KMO_TRY_EXIT_IF_NULL(
00667                                     img_in = kmo_dfs_load_image(frameset, do_mode1,
00668                                                                 devnr, TRUE, FALSE, NULL));
00669 
00670                                 KMO_TRY_EXIT_IF_NULL(
00671                                     data_out = kmo_calc_stats_img(img_in,
00672                                                                   mask,
00673                                                                   cpos_rej,
00674                                                                   cneg_rej,
00675                                                                   citer));
00676                                 cpl_image_delete(img_in); img_in = NULL;
00677                             }
00678 
00679                             if ((desc1.fits_type == f3i_fits) ||
00680                                 (desc1.fits_type == f2i_fits) ||
00681                                 (desc1.fits_type == f2d_fits) ||
00682                                 (desc1.fits_type == raw_fits))
00683                             {
00684                                 if (mask_available == TRUE) {
00685                                     cpl_image_delete(mask); mask = NULL;
00686                                     kmclipm_vector_delete(mask_vec); mask_vec = NULL;
00687                                 }
00688                             }
00689 
00690                             // save noise
00691                             KMO_TRY_EXIT_IF_NULL(
00692                                 sub_header = kmo_dfs_load_sub_header(frameset,
00693                                                                      do_mode1,
00694                                                                      devnr, TRUE));
00695 
00696                             if ((desc1.fits_type == raw_fits) ||
00697                                 (desc1.fits_type == b2d_fits))
00698                             {
00699                                 KMO_TRY_EXIT_IF_NULL(
00700                                     tmp_str = cpl_sprintf("%s%d%s", "DET.",
00701                                                           devnr,
00702                                                           ".NOISE"));
00703                                 KMO_TRY_EXIT_IF_ERROR(
00704                                     kmclipm_update_property_string(sub_header,
00705                                                             EXTNAME,
00706                                                             tmp_str,
00707                                                             "FITS extension name"));
00708                                 cpl_free(tmp_str); tmp_str = NULL;
00709                             }
00710 
00711                             KMO_TRY_EXIT_IF_ERROR(
00712                                 kmo_dfs_save_vector(data_out, STATS, "",
00713                                                     sub_header, 0./0.));
00714 
00715                             cpl_propertylist_delete(sub_header);sub_header = NULL;
00716                             kmclipm_vector_delete(data_out); data_out = NULL;
00717                         }
00718                     }
00719                 } else {
00720                     // invalid IFU, just save sub_headers
00721                     KMO_TRY_EXIT_IF_NULL(
00722                         sub_header = kmo_dfs_load_sub_header(frameset,
00723                                                              do_mode1,
00724                                                              devnr, FALSE));
00725 
00726                     if ((desc1.fits_type == raw_fits) ||
00727                         (desc1.fits_type == b2d_fits))
00728                     {
00729                         KMO_TRY_EXIT_IF_NULL(
00730                             tmp_str = cpl_sprintf("%s%d%s", "DET.",
00731                                                   devnr,
00732                                                   ".DATA"));
00733                         KMO_TRY_EXIT_IF_ERROR(
00734                             kmclipm_update_property_string(sub_header,
00735                                                     EXTNAME,
00736                                                     tmp_str,
00737                                                     "FITS extension name"));
00738                         cpl_free(tmp_str); tmp_str = NULL;
00739                     }
00740 
00741                      KMO_TRY_EXIT_IF_ERROR(
00742                          kmo_dfs_save_sub_header(STATS, "", sub_header));
00743                      cpl_propertylist_delete(sub_header); sub_header = NULL;
00744 
00745                     if (desc1.ex_noise) {
00746                         cpl_propertylist_delete(sub_header); sub_header = NULL;
00747 
00748                         KMO_TRY_EXIT_IF_NULL(
00749                             sub_header = kmo_dfs_load_sub_header(frameset,
00750                                                                  do_mode1,
00751                                                                  i, TRUE));
00752 
00753                         if ((desc1.fits_type == raw_fits) ||
00754                             (desc1.fits_type == b2d_fits))
00755                         {
00756                             KMO_TRY_EXIT_IF_NULL(
00757                                 tmp_str = cpl_sprintf("%s%d%s", "DET.",
00758                                                       devnr,
00759                                                       ".NOISE"));
00760                             KMO_TRY_EXIT_IF_ERROR(
00761                                 kmclipm_update_property_string(sub_header,
00762                                                         EXTNAME,
00763                                                         tmp_str,
00764                                                         "FITS extension name"));
00765                             cpl_free(tmp_str); tmp_str = NULL;
00766                         }
00767 
00768                         KMO_TRY_EXIT_IF_ERROR(
00769                             kmo_dfs_save_sub_header(STATS, "", sub_header));
00770                         cpl_propertylist_delete(sub_header); sub_header = NULL;
00771                     }
00772                 }
00773             }
00774         }
00775 
00776         // print stats info to console
00777         kmo_free_fits_desc(&desc1);
00778         kmo_init_fits_desc(&desc1);
00779 
00780         KMO_TRY_EXIT_IF_NULL(
00781             data_frame = kmo_dfs_get_frame(frameset, STATS));
00782 
00783         desc1 = kmo_identify_fits_header(
00784                     cpl_frame_get_filename(data_frame));
00785 
00786         KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to be "
00787                                       "in KMOS-format!");
00788 
00789         cpl_msg_info("", "-------------------------------------------");
00790         cpl_msg_info("", "--- kmo_stats info                      ---");
00791         cpl_msg_info("", "-------------------------------------------");
00792 
00793         KMO_TRY_EXIT_IF_NULL(
00794             strarr = (char**)cpl_malloc((stats_size+1) * sizeof(char*)));
00795 
00796         for (i = 0; i < stats_size+1; i++) {
00797             KMO_TRY_EXIT_IF_NULL(
00798                 strarr[i] = (char*)cpl_malloc(1024 * sizeof(char)));
00799             switch (i) {
00800             case 0: strcpy(strarr[i], "                  |"); break;
00801             case 1: strcpy(strarr[i], "1.  #pixels:      | "); break;
00802             case 2: strcpy(strarr[i], "2.  #finite pix.: | "); break;
00803             case 3: strcpy(strarr[i], "3.  mean:         | "); break;
00804             case 4: strcpy(strarr[i], "4.  stdev:        | "); break;
00805             case 5: strcpy(strarr[i], "5.  mean w. rej.: | "); break;
00806             case 6: strcpy(strarr[i], "6.  stdev w. rej.:| "); break;
00807             case 7: strcpy(strarr[i], "7.  median:       | "); break;
00808             case 8: strcpy(strarr[i], "8.  mode:         | "); break;
00809             case 9: strcpy(strarr[i], "9.  noise est.:   | "); break;
00810             case 10: strcpy(strarr[i], "10. min. value:   | "); break;
00811             case 11: strcpy(strarr[i], "11. max. value:   | "); break;
00812             default: cpl_msg_error(cpl_func, "To much values in output "
00813                                              "statistic vector!"); break;
00814             }
00815         }
00816 
00817         if (desc1.ex_noise == TRUE) {
00818             nr_devices = desc1.nr_ext / 2;
00819         } else {
00820             nr_devices = desc1.nr_ext;
00821         }
00822 
00823         for (j = 1; j <= nr_devices; j++) {
00824             if (desc1.ex_noise == FALSE) {
00825                 devnr = desc1.sub_desc[j - 1].device_nr;
00826             } else {
00827                 devnr = desc1.sub_desc[2 * j - 1].device_nr;
00828             }
00829 
00830             if (desc1.ex_badpix == FALSE) {
00831                 index_data = kmo_identify_index_desc(desc1, devnr, FALSE);
00832             } else {
00833                 index_data = kmo_identify_index_desc(desc1, devnr, 2);
00834             }
00835             KMO_TRY_CHECK_ERROR_STATE();
00836 
00837             if (desc1.ex_noise) {
00838                 index_noise = kmo_identify_index_desc(desc1, devnr, TRUE);
00839             }
00840             KMO_TRY_CHECK_ERROR_STATE();
00841 
00842             // check if IFU is valid
00843             valid_ifu = FALSE;
00844             if (desc1.sub_desc[index_data-1].valid_data == TRUE) {
00845                 valid_ifu = TRUE;
00846             }
00847 
00848             if (valid_ifu) {
00849                 if (ifu != 0) {
00850                     extnr = ifu;
00851                 } else {
00852                     extnr = devnr;
00853                 }
00854 
00855                 KMO_TRY_EXIT_IF_NULL(
00856                     sub_header = kmo_dfs_load_sub_header(frameset, STATS, extnr,
00857                                                          FALSE));
00858 
00859                 strcat(strarr[0],
00860                        cpl_propertylist_get_string(sub_header, EXTNAME));
00861                 strcat(strarr[0], "|");
00862                 cpl_propertylist_delete(sub_header); sub_header = NULL;
00863 
00864                 KMO_TRY_EXIT_IF_NULL(
00865                     data_out = kmo_dfs_load_vector(frameset, STATS, extnr, FALSE));
00866 
00867                 for (i = 1; i < stats_size+1; i++) {
00868                     double val = 0.;
00869                     int rejected = 0;
00870                     val = kmclipm_vector_get(data_out, i-1, &rejected);
00871                     if (!rejected) {
00872                         KMO_TRY_EXIT_IF_NULL(
00873                             tmp_str = cpl_sprintf("%8.7g |", val));
00874                     } else {
00875                         KMO_TRY_EXIT_IF_NULL(
00876                             tmp_str = cpl_sprintf("    -     |"));
00877                     }
00878 
00879                     strcat(strarr[i], tmp_str);
00880                     cpl_free(tmp_str); tmp_str = NULL;
00881                 }
00882                 kmclipm_vector_delete(data_out); data_out = NULL;
00883 
00884                 if (desc1.ex_noise == TRUE) {
00885                     KMO_TRY_EXIT_IF_NULL(
00886                         sub_header = kmo_dfs_load_sub_header(frameset, STATS,
00887                                                              extnr, TRUE));
00888                     strcat(strarr[0],
00889                            cpl_propertylist_get_string(sub_header, EXTNAME));
00890                     strcat(strarr[0], "|");
00891                     cpl_propertylist_delete(sub_header); sub_header = NULL;
00892 
00893                     KMO_TRY_EXIT_IF_NULL(
00894                         data_out = kmo_dfs_load_vector(frameset, STATS, extnr,
00895                                                        TRUE));
00896 
00897                     for (i = 1; i < stats_size+1; i++) {
00898                         double val = 0.;
00899                         int rejected = 0;
00900                         val = kmclipm_vector_get(data_out, i-1, &rejected);
00901                         if (!rejected) {
00902                             KMO_TRY_EXIT_IF_NULL(
00903                                 tmp_str = cpl_sprintf("%9.7g | ", val));
00904                         } else {
00905                             KMO_TRY_EXIT_IF_NULL(
00906                                 tmp_str = cpl_sprintf("    -     |"));
00907                         }
00908 
00909                         strcat(strarr[i], tmp_str);
00910                         cpl_free(tmp_str); tmp_str = NULL;
00911                     }
00912                     kmclipm_vector_delete(data_out); data_out = NULL;
00913                 }
00914             }
00915         }
00916 
00917         for (i = 0; i < stats_size+1; i++) {
00918             cpl_msg_info("", "%s", strarr[i]);
00919             cpl_free(strarr[i]); strarr[i] = NULL;
00920         }
00921         cpl_free(strarr); strarr = NULL;
00922         cpl_msg_info("", "-------------------------------------------");
00923     }
00924     KMO_CATCH
00925     {
00926         KMO_CATCH_MSG();
00927 
00928         ret_val = -1;
00929     }
00930 
00931     kmo_free_fits_desc(&desc1);
00932     if (mask_available == TRUE) {
00933         kmo_free_fits_desc(&desc2);
00934     }
00935     cpl_propertylist_delete(sub_header); sub_header = NULL;
00936     cpl_imagelist_delete(data_in); data_in = NULL;
00937     kmclipm_vector_delete(data_out); data_out = NULL;
00938     cpl_image_delete(mask); mask = NULL;
00939     kmclipm_vector_delete(mask_vec); mask_vec = NULL;
00940 
00941     return ret_val;
00942 }
00943