KMOS Pipeline Reference Manual  1.0.7
kmo_fits_strip.c
00001 /* $Id: kmo_fits_strip.c,v 1.3 2013/02/01 10:05: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/02/01 10:05:29 $
00024  * $Revision: 1.3 $
00025  * $Name: HEAD $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 #include <math.h>
00033 
00034 #include <cpl.h>
00035 
00036 #include "kmclipm_constants.h"
00037 #include "kmclipm_functions.h"
00038 
00039 #include "kmo_dfs.h"
00040 #include "kmo_error.h"
00041 
00042 static int kmo_fits_strip_create(cpl_plugin *);
00043 static int kmo_fits_strip_exec(cpl_plugin *);
00044 static int kmo_fits_strip_destroy(cpl_plugin *);
00045 static int kmo_fits_strip(cpl_parameterlist *, cpl_frameset *);
00046 
00047 static char kmo_fits_strip_description[] =
00048 "With this recipe KMOS fits frames can be stripped in following way:\n"
00049 "\n"
00050 "--noise\n"
00051 "All noise extensions will be removed. Only the data extensions remain.\n"
00052 "\n"
00053 "--angle\n"
00054 "Applies only to calibration products from kmo_flat and kmo_wave_cal.\n"
00055 "All extensions matching provided angle are kept, the others are removed.\n"
00056 "\n"
00057 "--empty\n"
00058 "All empty extensions will be removed.\n"
00059 "\n"
00060 "All parameters can be combined. When no parameter is provided, no output\n"
00061 "will be generated.\n"
00062 "\n"
00063 "-------------------------------------------------------------------------------\n"
00064 "  Input files:\n"
00065 "\n"
00066 "   DO                    KMOS                                                  \n"
00067 "   category              Type   Explanation                    Required #Frames\n"
00068 "   --------              -----  -----------                    -------- -------\n"
00069 "   <none or any>         F2D or frame to strip                     Y       1   \n"
00070 "                         F3I or\n"
00071 "                         F2I or\n"
00072 "                         F1I or\n"
00073 "\n"
00074 "  Output files:\n"
00075 "\n"
00076 "   DO                    KMOS\n"
00077 "   category              Type   Explanation\n"
00078 "   --------              -----  -----------\n"
00079 "   STRIP                 F2D    Stripped frame\n"
00080 "-------------------------------------------------------------------------------\n"
00081 "\n";
00082 
00099 int cpl_plugin_get_info(cpl_pluginlist *list)
00100 {
00101     cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
00102     cpl_plugin *plugin = &recipe->interface;
00103 
00104     cpl_plugin_init(plugin,
00105                         CPL_PLUGIN_API,
00106                         KMOS_BINARY_VERSION,
00107                         CPL_PLUGIN_TYPE_RECIPE,
00108                         "kmo_fits_strip",
00109                         "Strip noise, rotator and/or empty extensions from a "
00110                         "processed KMOS fits frame",
00111                         kmo_fits_strip_description,
00112                         "Alex Agudo Berbel",
00113                         "agudo@mpe.mpg.de",
00114                         kmos_get_license(),
00115                         kmo_fits_strip_create,
00116                         kmo_fits_strip_exec,
00117                         kmo_fits_strip_destroy);
00118 
00119     cpl_pluginlist_append(list, plugin);
00120 
00121     return 0;
00122 }
00123 
00131 static int kmo_fits_strip_create(cpl_plugin *plugin)
00132 {
00133     cpl_recipe *recipe = NULL;
00134     cpl_parameter *p = NULL;
00135 
00136     /* Check that the plugin is part of a valid recipe */
00137     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00138         recipe = (cpl_recipe *)plugin;
00139     else
00140         return -1;
00141 
00142     /* Create the parameters list in the cpl_recipe object */
00143     recipe->parameters = cpl_parameterlist_new();
00144 
00145     /* Fill the parameters list */
00146     /* --empty */
00147     p = cpl_parameter_new_value("kmos.kmo_fits_strip.empty",
00148                                 CPL_TYPE_BOOL,
00149                                 "TRUE: if empty extensions shall be removed,"
00150                                 " FALSE: otherwise",
00151                                 "kmos.kmo_fits_strip",
00152                                 FALSE);
00153     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "empty");
00154     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00155     cpl_parameterlist_append(recipe->parameters, p);
00156 
00157     /* --noise */
00158     p = cpl_parameter_new_value("kmos.kmo_fits_strip.noise",
00159                                 CPL_TYPE_BOOL,
00160                                 "TRUE: if noise extensions shall be removed,"
00161                                 " FALSE: otherwise",
00162                                 "kmos.kmo_fits_strip",
00163                                 FALSE);
00164     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "noise");
00165     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00166     cpl_parameterlist_append(recipe->parameters, p);
00167 
00168     /* --angle */
00169     p = cpl_parameter_new_value("kmos.kmo_fits_strip.angle",
00170                                 CPL_TYPE_INT,
00171                                 "The angle the extensions with shall be removed",
00172                                 "kmos.kmo_fits_strip",
00173                                 -1);
00174     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "angle");
00175     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00176     cpl_parameterlist_append(recipe->parameters, p);
00177 
00178     return 0;
00179 }
00180 
00186 static int kmo_fits_strip_exec(cpl_plugin *plugin)
00187 {
00188     cpl_recipe  *recipe;
00189 
00190     /* Get the recipe out of the plugin */
00191     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00192         recipe = (cpl_recipe *)plugin;
00193     else return -1 ;
00194 
00195     return kmo_fits_strip(recipe->parameters, recipe->frames);
00196 }
00197 
00203 static int kmo_fits_strip_destroy(cpl_plugin *plugin)
00204 {
00205     cpl_recipe *recipe;
00206 
00207     /* Get the recipe out of the plugin */
00208     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00209         recipe = (cpl_recipe *)plugin;
00210     else return -1 ;
00211 
00212     cpl_parameterlist_delete(recipe->parameters);
00213     return 0 ;
00214 }
00215 
00234 static int kmo_fits_strip(cpl_parameterlist *parlist, cpl_frameset *frameset)
00235 {
00236     int                 ret_val             = 0,
00237                         nr_devices          = 0,
00238                         remove_noise        = FALSE,
00239                         remove_empty        = FALSE,
00240                         remove_angle        = FALSE,
00241                         found_angle         = FALSE,
00242                         isCalFrame          = 0,
00243                         actDetNr            = 0,
00244                         cal_device_nr       = 0;
00245     double              angle               = 0.,
00246                         tmp_angle           = 0.,
00247                         ret_angle           = 0.;
00248     cpl_propertylist    *header             = NULL;
00249     cpl_imagelist       *cube               = NULL;
00250     cpl_image           *img                = NULL;
00251     kmclipm_vector      *vec                = NULL;
00252     main_fits_desc      desc;
00253     cpl_frame           *frame              = NULL;
00254 
00255     KMO_TRY
00256     {
00257         kmo_init_fits_desc(&desc);
00258 
00259         /* --- check input --- */
00260         KMO_TRY_ASSURE((parlist != NULL) &&
00261                        (frameset != NULL),
00262                        CPL_ERROR_NULL_INPUT,
00263                        "Not all input data is provided!");
00264 
00265         KMO_TRY_ASSURE(cpl_frameset_get_size(frameset) == 1,
00266                        CPL_ERROR_NULL_INPUT,
00267                        "A fits-file must be provided!");
00268 
00269         KMO_TRY_EXIT_IF_NULL(
00270             frame = kmo_dfs_get_frame(frameset, "0"));
00271 
00272         desc = kmo_identify_fits_header(
00273                         cpl_frame_get_filename(frame));
00274         KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to be "
00275                                       "in KMOS-format!");
00276 
00277         KMO_TRY_ASSURE((desc.fits_type == f2d_fits) ||
00278                        (desc.fits_type == f3i_fits) ||
00279                        (desc.fits_type == f2i_fits) ||
00280                        (desc.fits_type == f1i_fits),
00281                        CPL_ERROR_ILLEGAL_INPUT,
00282                        "Input data hasn't correct data type "
00283                        "(KMOSTYPE must be F2D, F3I, F2I or F1I)!");
00284 
00285         KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_fits_strip") == 1,
00286                        CPL_ERROR_ILLEGAL_INPUT,
00287                        "Cannot identify RAW and CALIB frames!");
00288 
00289         cpl_msg_info("", "--- Parameter setup for kmo_fits_strip ----");
00290         remove_empty = kmo_dfs_get_parameter_bool(parlist,
00291                                                   "kmos.kmo_fits_strip.empty");
00292         KMO_TRY_CHECK_ERROR_STATE();
00293         KMO_TRY_ASSURE((remove_empty == TRUE) ||
00294                        (remove_empty == FALSE),
00295                        CPL_ERROR_ILLEGAL_INPUT,
00296                        "empty must be TRUE or FALSE!");
00297         KMO_TRY_EXIT_IF_ERROR(
00298             kmo_dfs_print_parameter_help(parlist, "kmos.kmo_fits_strip.empty"));
00299 
00300         remove_noise = kmo_dfs_get_parameter_bool(parlist,
00301                                                   "kmos.kmo_fits_strip.noise");
00302         KMO_TRY_CHECK_ERROR_STATE();
00303         KMO_TRY_ASSURE((remove_noise == TRUE) ||
00304                        (remove_noise == FALSE),
00305                        CPL_ERROR_ILLEGAL_INPUT,
00306                        "noise must be TRUE or FALSE!");
00307         KMO_TRY_EXIT_IF_ERROR(
00308             kmo_dfs_print_parameter_help(parlist, "kmos.kmo_fits_strip.noise"));
00309 
00310         angle = kmo_dfs_get_parameter_int(parlist,
00311                                           "kmos.kmo_fits_strip.angle");
00312         KMO_TRY_CHECK_ERROR_STATE();
00313         KMO_TRY_EXIT_IF_ERROR(
00314             kmo_dfs_print_parameter_help(parlist, "kmos.kmo_fits_strip.angle"));
00315 
00316         if (angle > 0) {
00317             remove_angle = TRUE;
00318         }
00319 
00320         KMO_TRY_ASSURE(!remove_angle || ((angle >=0) && (angle < 360)),
00321                        CPL_ERROR_ILLEGAL_INPUT,
00322                        "angle must be between 0 and 360 degrees!");
00323 
00324         cpl_msg_info("", "-------------------------------------------");
00325 
00326         if ((!remove_empty) && (!remove_noise) && (!remove_angle)) {
00327             // do nothing
00328             cpl_msg_info("","No action has been specified (angle-, noise- or empty-parameter),"
00329                             " therefore no output is generated");
00330         } else {
00331             //
00332             // --- save primary extension ---
00333             //
00334             // load data and save it away again
00335             KMO_TRY_EXIT_IF_NULL(
00336                 header = kmo_dfs_load_primary_header(frameset, "0"));
00337             KMO_TRY_EXIT_IF_ERROR(
00338                 kmo_dfs_save_main_header(frameset, STRIP, "", frame,
00339                                          header, parlist, cpl_func));
00340             cpl_propertylist_delete(header); header = NULL;
00341 
00342             isCalFrame = FALSE;
00343             KMO_TRY_EXIT_IF_NULL(
00344                 header = kmo_dfs_load_sub_header(frameset, "0", 1, FALSE));
00345             if (cpl_propertylist_has(header, CAL_ROTANGLE)) {
00346                 isCalFrame = TRUE;
00347             }
00348 
00349             if (!isCalFrame) {
00350                 if (!desc.ex_noise) {
00351                     nr_devices = desc.nr_ext;
00352                 } else {
00353                     nr_devices = desc.nr_ext / 2;
00354                 }
00355             } else {
00356                 nr_devices = 3;
00357             }
00358 
00359             remove_noise = !remove_noise;
00360             actDetNr = 1;
00361             for (int i = 0; i < nr_devices; i++)
00362             {
00363                 // either loop noise or not
00364                 for (int n = FALSE; n <= remove_noise; n++) {
00365                     if (isCalFrame) {
00366                         KMO_TRY_EXIT_IF_NULL(
00367                             header = kmclipm_cal_propertylist_load(cpl_frame_get_filename(frame),
00368                                                           i+1, n, angle, &ret_angle));
00369                     } else {
00370                         KMO_TRY_EXIT_IF_NULL(
00371                             header = kmo_dfs_load_sub_header(frameset, "0", i + 1, FALSE));
00372                     }
00373 
00374                     if (remove_angle) {
00375                         // examine angle
00376                         if (cpl_propertylist_has(header, CAL_ROTANGLE)) {
00377                             tmp_angle = cpl_propertylist_get_double(header, CAL_ROTANGLE);
00378                             KMO_TRY_CHECK_ERROR_STATE();
00379                             if (fabs(angle - tmp_angle) < 0.01) {
00380                                 found_angle = TRUE;
00381                                 isCalFrame = TRUE;
00382                             } else {
00383                                 found_angle = FALSE;
00384                             }
00385                         } else {
00386                             // frame doesn't seem to have the CAL_ROTANGLE keyword
00387                             // process all extensions
00388                             found_angle = TRUE;
00389                         }
00390                     } else {
00391                         found_angle = TRUE;
00392                     }
00393 
00394                     if (found_angle) {
00395                         if ((desc.fits_type == f2d_fits) ||
00396                             (desc.fits_type == f2i_fits))
00397                         {
00398                             if (isCalFrame) {
00399                                 cal_device_nr = cpl_propertylist_get_int(header, CHIPINDEX);
00400                                 if (cal_device_nr == actDetNr) {
00401                                     KMO_TRY_EXIT_IF_ERROR(
00402                                         kmo_update_sub_keywords(header,
00403                                                                 n,
00404                                                                 FALSE,
00405                                                                 desc.frame_type,
00406                                                                 actDetNr));
00407 
00408                                     KMO_TRY_EXIT_IF_NULL(
00409                                         img = kmo_dfs_load_cal_image(frameset, "0",
00410                                                                      i+1, n, angle,
00411                                                                      FALSE, NULL,
00412                                                                      &ret_angle));
00413                                     if (fabs(angle-ret_angle) > 0.01) {
00414                                         cpl_msg_warning("","Angle provided: %g, angle found: %g", angle, ret_angle);
00415                                     }
00416                                     actDetNr++;
00417                                 }
00418                             } else {
00419                                 KMO_TRY_EXIT_IF_NULL(
00420                                     img = kmo_dfs_load_image(frameset, "0", i + 1, n, FALSE, NULL));
00421                             }
00422 
00423                             if (img != NULL) {
00424                                 KMO_TRY_EXIT_IF_ERROR(
00425                                     kmo_dfs_save_image(img, STRIP, "", header, 0./0.));
00426                             }
00427                             cpl_image_delete(img); img = NULL;
00428                         } else if (desc.fits_type == f3i_fits) {
00429                             KMO_TRY_EXIT_IF_NULL(
00430                                 cube = kmo_dfs_load_cube(frameset, "0", i + 1, n));
00431 
00432                             KMO_TRY_EXIT_IF_ERROR(
00433                                 kmo_dfs_save_cube(cube, STRIP, "", header, 0./0.));
00434                             cpl_imagelist_delete(cube); cube = NULL;
00435                         } else if (desc.fits_type == f3i_fits) {
00436                             KMO_TRY_EXIT_IF_NULL(
00437                                 vec = kmo_dfs_load_vector(frameset, "0", i + 1, n));
00438 
00439                             KMO_TRY_EXIT_IF_ERROR(
00440                                 kmo_dfs_save_vector(vec, STRIP, "", header, 0./0.));
00441                             kmclipm_vector_delete(vec); vec = NULL;
00442                         }
00443 
00444                     } // if (found_angle)
00445 
00446                     cpl_propertylist_delete(header); header = NULL;
00447                 } // for (n)
00448             } // for (i = nr_devices)
00449         } // if ((!remove_empty) && (!remove_noise) && (!remove_angle))
00450     }
00451     KMO_CATCH
00452     {
00453         KMO_CATCH_MSG();
00454 
00455         ret_val = -1;
00456     }
00457 
00458     cpl_propertylist_delete(header); header = NULL;
00459     cpl_imagelist_delete(cube); cube = NULL;
00460     cpl_image_delete(img); img = NULL;
00461     kmclipm_vector_delete(vec); vec = NULL;
00462     kmo_free_fits_desc(&desc);
00463 
00464     return ret_val;
00465 }
00466