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