uves_response_impl.c

00001 /*                                                                              *
00002  *   This file is part of the ESO UVES Pipeline                                 *
00003  *   Copyright (C) 2004,2005 European Southern Observatory                      *
00004  *                                                                              *
00005  *   This library is free software; you can redistribute it and/or modify       *
00006  *   it under the terms of the GNU General Public License as published by       *
00007  *   the Free Software Foundation; either version 2 of the License, or          *
00008  *   (at your option) any later version.                                        *
00009  *                                                                              *
00010  *   This program is distributed in the hope that it will be useful,            *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of             *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
00013  *   GNU General Public License for more details.                               *
00014  *                                                                              *
00015  *   You should have received a copy of the GNU General Public License          *
00016  *   along with this program; if not, write to the Free Software                *
00017  *   Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA       *
00018  *                                                                              */
00019  
00020 /*
00021  * $Author: amodigli $
00022  * $Date: 2008/03/28 08:54:33 $
00023  * $Revision: 1.72 $
00024  * $Name: uves-3_9_0 $
00025  * $Log: uves_response_impl.c,v $
00026  * Revision 1.72  2008/03/28 08:54:33  amodigli
00027  * IRPLIB_CONCAT2X-->UVES_CONCAT2X
00028  *
00029  * Revision 1.71  2008/02/15 12:43:49  amodigli
00030  * allow lower/upper chip for parameter process_chip
00031  *
00032  * Revision 1.70  2007/12/03 08:02:15  amodigli
00033  * added HIERARCH keys to 'debug' product
00034  *
00035  * Revision 1.69  2007/10/05 16:01:45  amodigli
00036  * using proces_chip parameter to process or not a given RED chip
00037  *
00038  * Revision 1.68  2007/08/21 13:08:26  jmlarsen
00039  * Removed irplib_access module, largely deprecated by CPL-4
00040  *
00041  * Revision 1.67  2007/06/22 09:30:31  jmlarsen
00042  * Changed interface of uves_save_image
00043  *
00044  * Revision 1.66  2007/06/11 13:28:26  jmlarsen
00045  * Changed recipe contact address to cpl at eso.org
00046  *
00047  * Revision 1.65  2007/06/08 13:06:16  jmlarsen
00048  * Send bug reports to Andrea
00049  *
00050  * Revision 1.64  2007/06/06 08:17:33  amodigli
00051  * replace tab with 4 spaces
00052  *
00053  * Revision 1.63  2007/05/25 11:50:32  jmlarsen
00054  * Re-added ORDER_TRACE_TABLE
00055  *
00056  * Revision 1.62  2007/05/22 14:03:29  jmlarsen
00057  * Documented WCALIB_FF_RESPONSE
00058  *
00059  * Revision 1.61  2007/05/22 11:44:47  jmlarsen
00060  * Removed MIDAS flag for good
00061  *
00062  * Revision 1.60  2007/05/14 08:09:48  amodigli
00063  * updated input frames and tag description in recipe man page
00064  *
00065  * Revision 1.59  2007/05/03 15:23:34  jmlarsen
00066  * Fixed const bugs
00067  *
00068  * Revision 1.58  2007/04/24 16:45:17  amodigli
00069  * changed interface of calls to uves_load_ordertable to match new interface
00070  *
00071  * Revision 1.57  2007/04/24 14:09:29  jmlarsen
00072  * Removed obsolete log_slitwidth option to uves_qclog_add_common_wave()
00073  *
00074  * Revision 1.56  2007/04/24 12:50:29  jmlarsen
00075  * Replaced cpl_propertylist -> uves_propertylist which is much faster
00076  *
00077  * Revision 1.55  2007/04/03 06:29:39  amodigli
00078  * changed interface to uves_load_ordertable
00079  *
00080  * Revision 1.54  2007/02/26 10:17:44  jmlarsen
00081  * Update to new interface of uves_qclog_add_common_wave()
00082  *
00083  * Revision 1.53  2007/02/09 13:43:29  jmlarsen
00084  * Use defines for recipe id
00085  *
00086  * Revision 1.52  2007/02/09 08:59:31  jmlarsen
00087  * Use define's rather than hard-coded recipe names
00088  *
00089  * Revision 1.51  2007/01/29 12:13:52  jmlarsen
00090  * Calculate extraction slit length
00091  *
00092  * Revision 1.50  2006/12/11 12:35:25  jmlarsen
00093  * Fixed QC bugs
00094  *
00095  * Revision 1.49  2006/12/11 11:06:44  jmlarsen
00096  * Read QC chip name from input header
00097  *
00098  * Revision 1.48  2006/12/07 08:27:31  jmlarsen
00099  * Factored some common QC parameters
00100  *
00101  * Revision 1.47  2006/12/01 12:30:55  jmlarsen
00102  * Load FLAMES order table oshift/yshift
00103  *
00104  * Revision 1.46  2006/11/22 12:43:16  jmlarsen
00105  * Changed message
00106  *
00107  * Revision 1.45  2006/11/16 14:12:21  jmlarsen
00108  * Changed undefined trace number from 0 to -1, to support zero as an actual trace number
00109  *
00110  * Revision 1.44  2006/11/15 15:02:15  jmlarsen
00111  * Implemented const safe workarounds for CPL functions
00112  *
00113  * Revision 1.42  2006/11/15 14:04:08  jmlarsen
00114  * Removed non-const version of parameterlist_get_first/last/next which is
00115  * already in CPL, added const-safe wrapper, unwrapper and deallocator functions
00116  *
00117  * Revision 1.41  2006/11/06 15:19:42  jmlarsen
00118  * Removed unused include directives
00119  *
00120  * Revision 1.40  2006/11/03 15:01:21  jmlarsen
00121  * Killed UVES 3d table module and use CPL 3d tables
00122  *
00123  * Revision 1.39  2006/10/24 14:07:53  jmlarsen
00124  * Added flames flag when loading frames
00125  *
00126  * Revision 1.38  2006/10/17 12:33:02  jmlarsen
00127  * Added semicolon at UVES_RECIPE_DEFINE invocation
00128  *
00129  * Revision 1.37  2006/10/09 13:01:13  jmlarsen
00130  * Use macro to define recipe interface functions
00131  *
00132  * Revision 1.36  2006/10/05 06:50:23  jmlarsen
00133  * Renamed function format_is_new -> uves_format_is_new
00134  *
00135  * Revision 1.35  2006/10/04 10:59:04  jmlarsen
00136  * Implemented QC.VRAD parameters
00137  *
00138  * Revision 1.34  2006/09/27 15:08:45  jmlarsen
00139  * Fixed doc. bug
00140  *
00141  * Revision 1.33  2006/09/20 12:53:02  jmlarsen
00142  * Changed order of products
00143  *
00144  * Revision 1.32  2006/09/20 10:59:22  jmlarsen
00145  * Produce reduced spectrum, also when no matching reference object is identified (DFS02900)
00146  *
00147  * Revision 1.31  2006/09/20 07:25:49  jmlarsen
00148  * Doc. bug fix
00149  *
00150  * Revision 1.30  2006/09/19 14:38:54  jmlarsen
00151  * Fixed typo
00152  *
00153  * Revision 1.29  2006/09/19 14:30:58  jmlarsen
00154  * uves_insert_frame(): use bitmap to specify which image statistics keywords must be computed
00155  *
00156  * Revision 1.28  2006/09/19 06:55:35  jmlarsen
00157  * Changed interface of uves_frameset to optionally write image statistics kewwords
00158  *
00159  * Revision 1.27  2006/08/28 08:58:42  jmlarsen
00160  * Use default profile measuring method (i.e. select method depending on S/N)
00161  *
00162  * Revision 1.26  2006/08/24 11:36:37  jmlarsen
00163  * Write recipe start/stop time to header
00164  *
00165  * Revision 1.25  2006/08/18 13:35:42  jmlarsen
00166  * Fixed/changed QC parameter formats
00167  *
00168  * Revision 1.24  2006/08/17 13:56:53  jmlarsen
00169  * Reduced max line length
00170  *
00171  * Revision 1.23  2006/08/17 09:20:43  jmlarsen
00172  * Get reference object ID from flux table, not raw header
00173  *
00174  * Revision 1.22  2006/08/11 14:56:05  amodigli
00175  * removed Doxygen warnings
00176  *
00177  * Revision 1.21  2006/08/11 09:00:21  jmlarsen
00178  * Take into account the different meanings of line table 'Y' column
00179  *
00180  * Revision 1.20  2006/08/09 14:23:19  jmlarsen
00181  * Removed unused function argument
00182  *
00183  * Revision 1.19  2006/08/07 14:42:02  jmlarsen
00184  * Implemented on-the-fly correction of a line table when its order numbering 
00185  * is inconsistent with the order table (DFS02694)
00186  *
00187  * Revision 1.18  2006/08/07 11:35:35  jmlarsen
00188  * Disabled parameter environment variable mode
00189  *
00190  * Revision 1.17  2006/07/14 12:19:28  jmlarsen
00191  * Support multiple QC tests per product
00192  *
00193  * Revision 1.16  2006/07/03 13:18:44  jmlarsen
00194  * Changed default optimal extraction method to 'virtual'
00195  *
00196  * Revision 1.15  2006/06/22 12:13:10  amodigli
00197  * removed ESO prefix
00198  *
00199  * Revision 1.14  2006/06/16 08:25:45  jmlarsen
00200  * Manually propagate ESO.DET. keywords from 1st/2nd input header
00201  *
00202  * Revision 1.13  2006/06/13 11:57:02  jmlarsen
00203  * Check that calibration frames are from the same chip ID
00204  *
00205  * Revision 1.12  2006/06/07 13:06:28  jmlarsen
00206  * Changed doxygen tag addtogroup -> defgroup
00207  *
00208  * Revision 1.11  2006/06/07 09:01:28  amodigli
00209  * added some doc
00210  *
00211  * Revision 1.10  2006/06/01 14:43:17  jmlarsen
00212  * Added missing documentation
00213  *
00214  * Revision 1.9  2006/05/31 09:26:40  amodigli
00215  * fixed some problem dumping QC log
00216  *
00217  * Revision 1.8  2006/05/16 12:13:07  amodigli
00218  * added QC log
00219  *
00220  * Revision 1.7  2006/05/09 15:42:00  amodigli
00221  * added QC log
00222  *
00223  * Revision 1.6  2006/04/06 09:48:15  amodigli
00224  * changed uves_frameset_insert interface to have QC log
00225  *
00226  * Revision 1.5  2006/04/06 08:50:22  jmlarsen
00227  * Removed memory leak
00228  *
00229  * Revision 1.4  2006/03/24 13:58:03  jmlarsen
00230  * Changed meaning of VARIANCE_SCIENCE to match MIDAS
00231  *
00232  * Revision 1.3  2006/02/28 09:15:23  jmlarsen
00233  * Minor update
00234  *
00235  * Revision 1.2  2006/02/21 14:26:54  jmlarsen
00236  * Minor changes
00237  *
00238  * Revision 1.1  2006/02/03 07:51:04  jmlarsen
00239  * Moved recipe implementations to ./uves directory
00240  *
00241  * Revision 1.41  2006/01/19 08:47:24  jmlarsen
00242  * Inserted missing doxygen end tag
00243  *
00244  * Revision 1.40  2005/12/20 16:10:32  jmlarsen
00245  * Added some documentation
00246  *
00247  * Revision 1.39  2005/12/19 16:17:55  jmlarsen
00248  * Replaced bool -> int
00249  *
00250  */
00251 #ifdef HAVE_CONFIG_H
00252 #  include <config.h>
00253 #endif
00254 
00255 /*----------------------------------------------------------------------------*/
00263 /*----------------------------------------------------------------------------*/
00264 
00265 /*-----------------------------------------------------------------------------
00266                                 Includes
00267  -----------------------------------------------------------------------------*/
00268 
00269 /* Definitions */
00270 #include <uves.h>
00271 
00272 /* Macro steps */
00273 #include <uves_reduce.h>
00274 #include <uves_reduce_utils.h>
00275 #include <uves_response_efficiency.h>
00276 #include <uves_response_utils.h>
00277 
00278 /* Utility functions */
00279 #include <uves_extract.h>
00280 #include <uves_plot.h>
00281 #include <uves_dfs.h>
00282 #include <uves_pfits.h>
00283 #include <uves_parameters.h>
00284 #include <uves_utils.h>
00285 #include <uves_utils_wrappers.h>
00286 #include <uves_utils_cpl.h>
00287 #include <uves_qclog.h>
00288 #include <uves_recipe.h>
00289 #include <uves_error.h>
00290 #include <uves_msg.h>
00291 
00292 /* Library */
00293 #include <cpl.h>
00294 #include <stdbool.h>
00295 
00296 
00297 /*-----------------------------------------------------------------------------
00298                             Functions prototypes
00299  -----------------------------------------------------------------------------*/
00300 static void uves_efficiency_qclog(cpl_table* table,
00301                   uves_propertylist* raw_header, 
00302                   enum uves_chip chip,
00303                   cpl_table* qclog,
00304                   const char *ref_obj_name);
00305 
00306 static int
00307 uves_response_define_parameters(cpl_parameterlist *parameters);
00308 
00309 /*-----------------------------------------------------------------------------
00310                             Recipe standard code
00311  -----------------------------------------------------------------------------*/
00312 #define cpl_plugin_get_info uves_response_get_info
00313 UVES_RECIPE_DEFINE(
00314     UVES_RESPONSE_ID, UVES_RESPONSE_DOM, uves_response_define_parameters,
00315     "Jonas M. Larsen", "cpl@eso.org",
00316     "Determines response function and quantum efficiency",
00317 "This recipe reduces a standard star frame (STANDARD_xxx or STANDARD_xxx,\n"
00318 "where xxx = BLUE, RED) using a combination (depending on recipe parameters\n"
00319 "and provided input frames) of the steps:\n"
00320 "  - bias subtraction,\n"
00321 "  - dark subtraction,\n"
00322 "  - background subtraction,\n"
00323 "  - extraction/cosmic ray removal,\n"
00324 "  - flat-field correction,\n"
00325 "  - wavelength rebinning,\n"
00326 "  - sky subtraction,\n"
00327 "  - order merging.\n"
00328 "\n"
00329 " Expected input for this recipe is an raw std star frame, STANDARD_xxx or \n"
00330 "order table(s) for each chip, ORDER_TABLE_xxxx (where xxxx=BLUE, REDL, REDU),\n"
00331 "line table(s) for each chip, LINE_TABLE_xxxx, a master bias frame,\n"
00332 "MASTER_BIAS_xxxx, a master flat, MASTER_FLAT_xxxx, a reference standard star\n"
00333 "flux table, FLUX_STD_TABLE, a table describing the atmospheric extintion,\n"
00334 "EXTCOEFF_TABLE. \n"
00335 
00336 "Two reductions are performed, the first using optimal extraction (used to\n"
00337 "compute the instrument response function), the second using linear extraction\n"
00338 "(used to get the Quantum Detection Efficiency)\n"
00339 "\n"
00340 "For each chip (xxxx = BLUE, REDL, REDU) the recipe produces\n"
00341 "  INSTR_RESPONSE_xxxx          Response curve\n"
00342 "  WCALIB_FF_RESPONSE_xxxx      Response curve in (lambda,order) space before\n"
00343 "                               correcting for exposure time, gain, binning and\n"
00344 "                               atmospheric absorption\n"
00345 "  RED_STD_xxxx                 Reduced spectrum\n"
00346 "  EFFICIENCY_TABLE_xxxx        Efficiency table\n"
00347     "  BKG_STD_xxxx                 The subtracted background\n");
00348 
00350 /*----------------------------------------------------------------------------*/
00356 /*----------------------------------------------------------------------------*/
00357 static int
00358 uves_response_define_parameters(cpl_parameterlist *parameters)
00359 {
00360     /*****************
00361      *    General    *
00362      *****************/
00363 
00364     if (uves_define_global_parameters(parameters) != CPL_ERROR_NONE)
00365     {
00366         return -1;
00367     }
00368     
00369     /*******************
00370      *    Reduce       *
00371      ******************/
00372     /* Get reduce parameters for the top level and also for 'efficiency' substep */
00373     if (uves_propagate_parameters_step(
00374         UVES_REDUCE_ID, parameters, make_str(UVES_RESPONSE_ID), NULL) != 0)
00375     {
00376         return -1;
00377     }
00378 
00379     if (uves_propagate_parameters_step(UVES_REDUCE_ID, parameters, 
00380                        make_str(UVES_RESPONSE_ID), "efficiency") != 0)
00381     {
00382         return -1;
00383     }
00384 
00385     /* For the efficiency step: Set default extraction method to 'linear',
00386      * flatfield_method to 'no', blazecorrection to 'false' and merge to
00387      * 'sum' (because optimal merging doesn't make sense without flatfielding)
00388      */
00389     {
00390     const char *param = "linear";
00391     bool bool_param;
00392 
00393     if (uves_set_parameter_default(parameters,
00394                        make_str(UVES_RESPONSE_ID), "efficiency.reduce.extract.method",
00395                        CPL_TYPE_STRING, &param) != CPL_ERROR_NONE)
00396         {
00397         return -1;
00398         }
00399 
00400     param = "no";
00401     if (uves_set_parameter_default(parameters, 
00402                        make_str(UVES_RESPONSE_ID), "efficiency.reduce.ffmethod", 
00403                        CPL_TYPE_STRING, &param) != CPL_ERROR_NONE)
00404         {
00405         return -1;
00406         }
00407 
00408     param = "sum";
00409     if (uves_set_parameter_default(parameters, 
00410                        make_str(UVES_RESPONSE_ID), "efficiency.reduce.merge",
00411                        CPL_TYPE_STRING, &param) != CPL_ERROR_NONE)
00412         {
00413         return -1;
00414         }
00415 
00416     bool_param = false; /* Not best, but fastest. There is no need to
00417                    spend time optimizing the signal-to-noise
00418                    for these frames */
00419     if (uves_set_parameter_default(parameters, 
00420                        make_str(UVES_RESPONSE_ID), "reduce.extract.best",
00421                        CPL_TYPE_BOOL, &bool_param) != CPL_ERROR_NONE)
00422         {
00423         return -1;
00424         }
00425 
00426     }
00427 
00428     /****************
00429      *  Efficiency  *
00430      ****************/
00431 
00432     {
00433     const char *recipe_id = make_str(UVES_RESPONSE_ID);
00434     const char *subcontext = "efficiency";
00435     
00436     /* paccuracy */
00437     uves_par_new_value("paccuracy",
00438                CPL_TYPE_DOUBLE,
00439                "The pointing accuracy (in arcseconds) used to "
00440                "identify the observed star with a "
00441                "catalogue star. If the angular separation is "
00442                "less than this number, the identification is made.",
00443                60.0);
00444     }
00445     
00446     return (cpl_error_get_code() != CPL_ERROR_NONE);
00447 }
00448 
00449 /*----------------------------------------------------------------------------*/
00503 /*----------------------------------------------------------------------------*/
00504 
00505 static cpl_error_code
00506 uves_response_process_chip(const cpl_image *raw_image, 
00507                            const uves_propertylist *raw_header, 
00508                            const uves_propertylist *rotated_header,
00509                const cpl_image *master_bias,
00510                const cpl_image *master_dark, 
00511                            const uves_propertylist *mdark_header, 
00512                const cpl_image *master_flat, 
00513                            const uves_propertylist *mflat_header,
00514                const cpl_table *ordertable, 
00515                            const polynomial *order_locations,
00516                const cpl_table *linetable[3], 
00517                            const uves_propertylist *linetable_header[3], 
00518                            const polynomial *dispersion_relation[3],
00519                const cpl_table *flux_table,
00520                const cpl_table *atm_extinction,
00521                enum uves_chip chip,
00522                /* General */
00523                bool   DEBUG,
00524                /* Backsub */
00525                /* Flat fielding */
00526                /* Extraction */
00527                /* Rebinning  */
00528                const cpl_parameterlist *parameters,
00529                bool calc_response,
00530                /* Identification */
00531                double PACCURACY,
00532                /* Output */
00533                char **ref_obj_id,
00534                cpl_image **reduced_spectrum, 
00535                            uves_propertylist **reduced_header, 
00536                            cpl_image **background,
00537                cpl_image **response_orders, 
00538                            uves_propertylist **response_header_2d,
00539                cpl_image **response_curve,  
00540                            uves_propertylist **response_header,
00541                cpl_table **efficiency, 
00542                            cpl_table** blaze_efficiency,
00543                            cpl_table** info_tbl,
00544                double *extraction_slit)
00545 {
00546     cpl_image        *rebinned_spectrum = NULL;
00547     cpl_image        *rebinned_noise    = NULL;
00548     uves_propertylist *rebinned_header   = NULL;
00549     cpl_image        *reduced_rebinned = NULL;
00550     cpl_image        *reduced_rebinned_noise = NULL;
00551 
00552     cpl_image        *reduced_noise    = NULL;
00553 
00554     cpl_table *cosmic_mask     = NULL;   /* Cosmic ray table  (not a product of this recipe) */
00555     cpl_table *order_trace     = NULL;   /* Order trace table (not a product of this recipe) */
00556     cpl_image *merged_spectrum = NULL;   /* Not sky-subtracted (if simple extraction)        */
00557     cpl_image *merged_sky      = NULL;
00558     cpl_image *merged_noise    = NULL;
00559     cpl_image *reduced_scaled  = NULL;   /* Merged, sky-subtracted and normalized 
00560                         (exposure time, gain...) */
00561 
00562     cpl_table *catalogue_flux = NULL;    /* Std star catalogue flux */
00563  
00564     /* Do the science reduction. Produces wave.cal. spectra. */
00565     uves_msg("Reducing standard star");
00566 
00567     check( uves_reduce(raw_image, 
00568                        raw_header, 
00569                        rotated_header,
00570                master_bias,
00571                master_dark, 
00572                        mdark_header,
00573                master_flat, 
00574                        mflat_header,
00575                ordertable, 
00576                        order_locations,
00577                linetable, 
00578                        linetable_header, 
00579                        dispersion_relation,
00580                chip,
00581                DEBUG, 
00582                parameters, 
00583                        make_str(UVES_RESPONSE_ID),
00584                /* Output */
00585                NULL, 
00586                        NULL, 
00587                        NULL,                   /* 2d products */
00588                &cosmic_mask,
00589                background,
00590                NULL, 
00591                        NULL,                          /* Variance of flat-fielded */
00592                NULL, 
00593                        NULL,                         /* Don't need these 
00594                                   intermediate products */
00595                &merged_sky,
00596                &rebinned_spectrum, 
00597                        &rebinned_noise, 
00598                        &rebinned_header,
00599                &merged_spectrum,   
00600                        &merged_noise, 
00601                        reduced_header,
00602                &reduced_rebinned,  
00603                        &reduced_rebinned_noise,
00604                reduced_spectrum,   
00605                        &reduced_noise,
00606                        info_tbl,
00607                extraction_slit,
00608                        &order_trace),
00609        "Could not reduce frame");
00610 
00611 
00612     check( uves_plot_image_rows(*reduced_spectrum, 1, 1, 1,
00613                 "Wavelength (arbitrary units)", NULL,
00614                 "Reduced spectrum (%s chip)", 
00615                 uves_chip_tostring_upper(chip)),
00616        "Plotting failed");
00617 
00618     if (calc_response)
00619     {
00620         /* Calculate 2d response curve  (but don't scale to unit exposure time, ...) */
00621         uves_msg("Filtering rebinned spectrum");
00622         check( uves_filter_image_median(&reduced_rebinned, 10, 0, false), 
00623            "Could not smooth spectrum");
00624         check( uves_filter_image_average(reduced_rebinned, 10, 0), 
00625            "Could not smooth spectrum");    
00626         
00627         uves_msg("Calculating 2d response curve");
00628         
00629         check( *response_orders = uves_calculate_response(reduced_rebinned, 
00630                                   rebinned_header,
00631                                   flux_table,
00632                                   raw_header, 
00633                                   PACCURACY,
00634                                   true,     
00635                                   /*  std_flux / flux  */
00636                                   ref_obj_id),
00637            "Could not calculate response curve");
00638         
00639         check( *response_header_2d = uves_propertylist_duplicate(rebinned_header),
00640            "Error creating FITS header for 2d response curve");
00641         
00642         check( uves_pfits_set_bunit(*response_header_2d, "FLUX_STD / FLUX"),
00643            "Error writing BUNIT keyword");
00644         
00645         /*
00646          *  Calculate 1d response curve
00647          */
00648         
00649         uves_msg("Normalizing reduced spectrum");
00650         
00651         {
00652         int n_traces = cpl_image_get_size_y(*reduced_spectrum);
00653         assure( n_traces == 1, CPL_ERROR_ILLEGAL_INPUT,
00654             "2d extraction/reduction not supported");
00655         
00656         check( reduced_scaled = uves_normalize_spectrum(*reduced_spectrum, 
00657                                 reduced_noise, 
00658                                 *reduced_header,
00659                                 raw_header,
00660                                 n_traces,
00661                                 chip,
00662                                 atm_extinction,
00663                                 true,  /* Yes, divide by binning */
00664                                 NULL), /* Noise spectrum         */
00665                "Error normalizing reduced spectrum");
00666         }
00667         
00668         uves_msg("Filtering reduced spectrum");
00669         check( uves_filter_image_median(&reduced_scaled, 10, 0, false), 
00670            "Could not smooth spectrum");
00671         check( uves_filter_image_average(reduced_scaled, 10, 0), 
00672            "Could not smooth spectrum");
00673         
00674         uves_msg("Calculating response curve from scaled spectrum");
00675         
00676         cpl_free(*ref_obj_id); *ref_obj_id = NULL;
00677         check( *response_curve = uves_calculate_response(reduced_scaled, 
00678                                  *reduced_header,
00679                                  flux_table,
00680                                  raw_header, 
00681                                  PACCURACY, 
00682                                  true, /*  catalogue_flux / flux  */
00683                                  ref_obj_id),
00684            "Could not calculate response curve");
00685         
00686         check( *response_header = uves_propertylist_duplicate(*reduced_header),
00687            "Error creating FITS header for response curve");
00688         
00689         check( uves_pfits_set_bunit(*response_header, "FLUX_STD / FLUX"),
00690            "Error writing BUNIT keyword");
00691         
00692         if (DEBUG)
00693         {
00694             check( uves_save_image_local("Pre-smoothed response curve", "raw_response", 
00695                          *response_curve, chip, -1, -1, *response_header, true), 
00696                "Error saving image");
00697         }
00698         
00699         check( uves_plot_image_rows(*response_curve, 1, 1, 1, "Wavelength (arbitrary units)", 
00700                     NULL,
00701                     "Raw response (%s chip)", uves_chip_tostring_upper(chip)),
00702            "Plotting failed");
00703         
00704         
00705         /* Rebin the response curve to 50 wlu:
00706            1) smooth it using a radius of    25 wlu,
00707            2) then extract every n'th pixel where n = 50/step */
00708         uves_msg("Rebinning response curve to step size = 50 w.l.u.");
00709         {
00710         double dlambda, lambda_start;
00711         int n, bin, newbin;
00712     
00713         check( lambda_start = uves_pfits_get_crval1(*response_header),
00714                "Error reading start wavelength from header");
00715         check( dlambda = uves_pfits_get_cdelt1(*response_header),
00716                "Error reading wavelength step from header");
00717         
00718         n = uves_round_double(50.0/dlambda);
00719         
00720         assure( n >= 1, CPL_ERROR_ILLEGAL_OUTPUT,
00721             "Cannot rebin to 50 w.l.u. Current step is only %f w.l.u.", dlambda);
00722         
00723         /* Filter radius = 25 wlu, 0    (It's a 1d image) */
00724         check( uves_filter_image_average(*response_curve, n/2, 0),
00725                "Error filtering response curve");
00726         
00727         newbin = 1;
00728         for (bin = 1+n/2; bin <= cpl_image_get_size_x(*response_curve); bin += n)
00729             {
00730             int pis_rejected;
00731             
00732             /* Write to the same image buffer */
00733             cpl_image_set(*response_curve, 
00734                       newbin, 1,
00735                       cpl_image_get(*response_curve, bin, 1, &pis_rejected)
00736                 );
00737             newbin++;
00738             }
00739         
00740         
00741         /* Extract image, update start+step wavelengths */
00742         uves_crop_image(response_curve, 1, 1, newbin-1, 1);
00743         
00744         lambda_start = lambda_start + dlambda * ((1+n/2) - 1);  /* Center of first bin */
00745         dlambda      = n * dlambda;
00746         
00747         check( uves_pfits_set_crval1(*response_header, lambda_start),
00748                "Error updating start wavelength");
00749         check( uves_pfits_set_cdelt1(*response_header, dlambda),
00750                "Error updating wavelength step");
00751         
00752         }
00753         
00754         check( uves_plot_image_rows(*response_curve, 1, 1, 1, "Wavelength (arbitrary units)", 
00755                     NULL,
00756                     "Response curve (%s chip)", 
00757                     uves_chip_tostring_upper(chip)),
00758            "Plotting failed");
00759         
00760         /* Calculate efficiency table */
00761         uves_msg("Calculating efficiency curve");
00762         
00763         check( uves_response_efficiency(raw_image, 
00764                         raw_header, 
00765                         rotated_header,
00766                         master_bias,
00767                         master_dark, 
00768                         mdark_header, 
00769                         ordertable, 
00770                         order_locations,
00771                         linetable, 
00772                         linetable_header, 
00773                         dispersion_relation,
00774                         flux_table,
00775                         atm_extinction,
00776                         chip,
00777                         DEBUG,
00778                         parameters,
00779                         PACCURACY,
00780                         efficiency, 
00781                         blaze_efficiency),
00782            "Efficiency calculation failed");
00783         
00784         check( uves_plot_table(*efficiency, "Wave", "Eff",
00785                    "Detection Quantum Efficiency (%s chip)", 
00786                    uves_chip_tostring_upper(chip)), 
00787            "Plotting failed");
00788         
00789         /* Save blaze function efficiency (efficiency at center of order) */
00790         if (DEBUG) check( uves_save_table_local("Blaze efficiency table",
00791                             "blaze_efficiency", 
00792                             *blaze_efficiency, chip, -1, -1, rotated_header, NULL),
00793                   "Error saving blaze efficiency table");
00794     }
00795     else
00796     {
00797         uves_msg("Skipping response/efficiency computation");
00798     }
00799 
00800   cleanup:
00801     uves_free_propertylist(&rebinned_header);
00802     uves_free_image(&rebinned_noise);
00803     uves_free_image(&rebinned_spectrum);
00804     uves_free_table(&cosmic_mask);
00805     uves_free_table(&order_trace);
00806     uves_free_image(&merged_spectrum);
00807     uves_free_image(&merged_noise);
00808     uves_free_image(&merged_sky);
00809     uves_free_image(&reduced_rebinned);
00810     uves_free_image(&reduced_rebinned_noise);
00811     uves_free_image(&reduced_noise);
00812     uves_free_image(&reduced_scaled);
00813     uves_free_table(&catalogue_flux);
00814 
00815     if (cpl_error_get_code() != CPL_ERROR_NONE)
00816     {
00817         /* Output */
00818         uves_free_image(reduced_spectrum);
00819         uves_free_image(background);
00820         uves_free_image(response_orders);
00821         uves_free_image(response_curve);
00822         uves_free_propertylist(reduced_header);
00823         uves_free_propertylist(response_header);
00824         uves_free_propertylist(response_header_2d);
00825         uves_free_table(efficiency);
00826     }
00827     
00828     return cpl_error_get_code();
00829 }
00830 
00831 /*----------------------------------------------------------------------------*/
00838 /*----------------------------------------------------------------------------*/
00839 static void
00840 UVES_CONCAT2X(UVES_RESPONSE_ID,exe)(cpl_frameset *frames,
00841           const cpl_parameterlist *parameters,
00842           const char *starttime)
00843 {
00844     /*
00845      * Variables containg the values of recipe parameters 
00846      */
00847 
00848     /* General */
00849     bool DEBUG;
00850 
00851     /* Background subtraction */
00852     /* Implicitly passed */
00853 
00854     /* Flat-fielding */
00855 
00856     /* Extraction */
00857     /* Implicitly passed */
00858     
00859     /* Rebinning */
00860     /* Implicitly passed */
00861 
00862     /* Efficiency */
00863     double PACCURACY;
00864 
00865     /* CPL objects */
00866     /* Input, raw */
00867     cpl_image        *raw_image[2]      = {NULL, NULL};
00868     uves_propertylist *raw_header[2]     = {NULL, NULL};
00869     uves_propertylist *rotated_header[2] = {NULL, NULL};
00870 
00871     /* Input, calib */
00872     cpl_image        *master_bias        = NULL;
00873     uves_propertylist *master_bias_header = NULL;
00874 
00875     cpl_image        *master_dark        = NULL;
00876     uves_propertylist *master_dark_header = NULL;
00877 
00878     cpl_image        *master_flat        = NULL;
00879     uves_propertylist *master_flat_header = NULL;
00880 
00881     cpl_table        *ordertable       = NULL;
00882     uves_propertylist *ordertable_header= NULL;
00883     polynomial       *order_locations  = NULL;
00884     cpl_table        *traces           = NULL;
00885 
00886     cpl_table        *flux_table       = NULL;
00887 
00888     cpl_table        *atm_extinction   = NULL;
00889 
00890     /* Line tables for sky, object, sky (UVES specific) */
00891     const cpl_table        *linetable[3]           = {NULL, NULL, NULL};
00892     const uves_propertylist *linetable_header[3]    = {NULL, NULL, NULL};
00893     const polynomial       *dispersion_relation[3] = {NULL, NULL, NULL};
00894 
00895     /* Output */
00896     cpl_image        *background         = NULL;
00897     cpl_image        *reduced_spectrum   = NULL;
00898     uves_propertylist *spectrum_header    = NULL;
00899     cpl_image        *response_orders    = NULL;
00900     uves_propertylist *response_header_2d = NULL;
00901     cpl_image        *response_curve     = NULL;
00902     uves_propertylist *response_header    = NULL;
00903     cpl_table        *efficiency         = NULL;
00904     cpl_table        *blaze_efficiency   = NULL;
00905     uves_propertylist *efficiency_header  = NULL;
00906     cpl_table* info_tbl=NULL;
00907 
00908     /* Local variables */
00909     cpl_table *qclog[2] = {NULL, NULL};
00910     cpl_table *qclog_optext[2] = {NULL, NULL};
00911     cpl_table *catalogue_flux = NULL;
00912     const char *raw_filename = "";        /* Static */
00913     const char *flux_table_filename = ""; /* Static */
00914     const char *atm_ext_filename = "";    /* Static */
00915     char *product_filename = NULL;        /* Dynamically allocated */
00916     char *ref_obj_name = NULL;            /* Reference object id */
00917     bool calc_response = false;           /* Calculate instr response? */
00918     double extraction_slit;
00919 
00920     bool blue  = false;
00921     enum uves_chip chip;
00922     int binx = 0;
00923     int biny = 0;
00924     const char* PROCESS_CHIP=NULL;
00925 
00926     /* Read recipe parameters */
00927     {
00928     /* General */
00929     check( uves_get_parameter(parameters, NULL, "uves", "debug", 
00930                   CPL_TYPE_BOOL  , &DEBUG      ), "Could not read parameter");
00931 
00932     check( uves_get_parameter(parameters, NULL, "uves", "process_chip", CPL_TYPE_STRING, &PROCESS_CHIP),
00933                "Could not read parameter");
00934     uves_string_toupper((char*)PROCESS_CHIP);
00935 
00936     /* Background subtraction, Flat-fielding, Rebinning */
00937     /* The input parameter list is passed */
00938     
00939     /* For both response curve and efficiency step:
00940        Allow only extraction methods average/linear/optimal */
00941     {
00942         extract_method em;
00943 
00944         /* Validate uves_response.reduce.extract.method */
00945         check( em = uves_get_extract_method(
00946                parameters, NULL,
00947                make_str(UVES_RESPONSE_ID) "." UVES_REDUCE_ID "." UVES_EXTRACT_ID),
00948            "Could not read extraction method");
00949         
00950         assure( em == EXTRACT_LINEAR || em == EXTRACT_AVERAGE || em == EXTRACT_OPTIMAL,
00951             CPL_ERROR_UNSUPPORTED_MODE, 
00952             "Use linear/average/optimal extraction method to calculate response curve");
00953         
00954         /* Validate uves_response.efficiency.reduce.extract.method */
00955         check( em = uves_get_extract_method(
00956                parameters, NULL,
00957                make_str(UVES_RESPONSE_ID) ".efficiency." UVES_REDUCE_ID "." UVES_EXTRACT_ID),
00958            "Could not read extraction method");
00959         
00960         assure( em == EXTRACT_LINEAR || em == EXTRACT_AVERAGE || em == EXTRACT_OPTIMAL,
00961             CPL_ERROR_UNSUPPORTED_MODE, 
00962             "Use linear/average/optimal extraction "
00963             "method to calculate quantum efficiency");
00964     }
00965     
00966     /* Identification */
00967     check( uves_get_parameter(parameters, NULL, 
00968                   make_str(UVES_RESPONSE_ID) ".efficiency", "paccuracy", 
00969                   CPL_TYPE_DOUBLE, &PACCURACY), 
00970            "Could not read parameter");
00971     }
00972     
00973     /* Load raw image and header, and identify input frame as red or blue */
00974     check( uves_load_standard(frames,
00975                   &raw_filename, raw_image, raw_header, rotated_header, 
00976                   &blue), 
00977        "Error loading raw frame");
00978 
00979     /* Load flux table */
00980     check( uves_load_flux_table(frames, &flux_table_filename, &flux_table),
00981        "Error loading standard flux table");
00982 
00983     uves_msg_low("Using standard star flux table in '%s'", flux_table_filename);
00984 
00985     /* Before doing the reduction, find out if the standard star is in the table.
00986      * If not, still do the science reduction, but skip the instr.response part
00987      */
00988     catalogue_flux = uves_align(raw_header[0], flux_table, PACCURACY, &ref_obj_name);
00989 
00990     calc_response = true;
00991     if (cpl_error_get_code() == CPL_ERROR_INCOMPATIBLE_INPUT)
00992     {
00993         uves_error_reset();
00994 
00995         uves_msg_warning("No catalogue object found within %.2f arcsecs. "
00996                  "Instrument response curve will not be computed",
00997                  PACCURACY);
00998 
00999         calc_response = false;
01000     }
01001 
01002     /* Load atmospheric extinction table */
01003     check( uves_load_atmo_ext(frames, &atm_ext_filename, &atm_extinction), 
01004        "Error loading extinction coefficients");
01005     
01006     uves_msg_low("Using atmospheric extinction table in '%s'", atm_ext_filename);
01007 
01008     /* Adjust parameters according to binning 
01009      */
01010     check (binx = uves_pfits_get_binx(raw_header[0]), 
01011        "Could not read x binning factor from input header");
01012     check (biny = uves_pfits_get_biny(raw_header[0]),
01013        "Could not read y binning factor from input header");
01014 
01015     /* Loop over one or two chips, over traces and
01016        over extraction windows */
01017     for (chip = uves_chip_get_first(blue);
01018      chip != UVES_CHIP_INVALID;
01019      chip = uves_chip_get_next(chip))
01020     {
01021 
01022 
01023       if(strcmp(PROCESS_CHIP,"REDU") == 0) {
01024     chip = uves_chip_get_next(chip);
01025       }
01026 
01027 
01028         const char *ordertable_filename = "";
01029         const char *linetable_filename = "";
01030         const char *master_bias_filename = "";
01031         const char *master_dark_filename = "";
01032         const char *master_flat_filename = "";
01033         const char *chip_name = "";
01034         /* const char *drs_filename        = "";    not used */
01035         int tracerow;                  /* Index of table row */
01036         
01037         int raw_index = uves_chip_get_index(chip);
01038         uves_msg("Processing %s chip in '%s'",
01039              uves_chip_tostring_upper(chip), raw_filename);
01040         
01041         check_nomsg( chip_name = uves_pfits_get_chipid(raw_header[raw_index], chip));
01042 
01043         uves_msg_debug("Binning = %dx%d", binx, biny);
01044         
01045         /* Load master bias, set pointer to NULL if not present */
01046         uves_free_image(&master_bias);
01047         uves_free_propertylist(&master_bias_header);
01048         if (cpl_frameset_find(frames, UVES_MASTER_BIAS(chip)) != NULL)
01049         {
01050             check( uves_load_mbias(frames, chip_name, 
01051                        &master_bias_filename,
01052                        &master_bias,
01053                        &master_bias_header, chip), 
01054                "Error loading master bias");
01055             
01056             uves_msg_low("Using master bias in '%s'", master_bias_filename);
01057         }
01058         else
01059         {
01060             uves_msg_low("No master bias in SOF. Bias subtraction not done");
01061         }
01062         
01063         
01064         /* Load master dark, set pointer to NULL if not present */
01065         uves_free_image(&master_dark);
01066         uves_free_propertylist(&master_dark_header);
01067         if (cpl_frameset_find(frames, UVES_MASTER_DARK(chip)) != NULL)
01068         {
01069             check( uves_load_mdark(frames, chip_name,
01070                        &master_dark_filename,
01071                        &master_dark,
01072                        &master_dark_header, chip),
01073                "Error loading master dark");
01074             
01075             uves_msg_low("Using master dark in '%s'", master_dark_filename);
01076         }
01077         else
01078         {
01079             uves_msg_low("No master dark in SOF. Dark subtraction not done");
01080         }
01081         
01082         /* Load master flat */
01083         uves_free_image(&master_flat);
01084         uves_free_propertylist(&master_flat_header);
01085         check( uves_load_mflat_const(frames, chip_name, 
01086                      &master_flat_filename,
01087                      &master_flat, 
01088                      &master_flat_header, 
01089                      chip, NULL), "Error loading master flat");
01090         
01091         uves_msg_low("Using master flat in '%s'", master_flat_filename);
01092         
01093         
01094         /* Load the order table for this chip */
01095         uves_free_table       (&ordertable);
01096         uves_free_propertylist(&ordertable_header);
01097         uves_polynomial_delete(&order_locations);
01098         uves_free_table       (&traces);
01099     
01100         check( uves_load_ordertable(frames, 
01101                     false,  /* FLAMES? */
01102                     chip_name,
01103                     &ordertable_filename, 
01104                     &ordertable, 
01105                     &ordertable_header,
01106                                         NULL,
01107                     &order_locations, &traces, 
01108                     NULL, NULL,
01109                                        NULL, NULL, /* fibre_pos,fibre_mask */
01110                     chip, false),
01111            "Could not load order table");
01112         uves_msg_low("Using order table in '%s'", ordertable_filename);
01113         
01114         
01115         /* Loop over all traces (1 trace for UVES) */
01116         for(tracerow = 0; tracerow < cpl_table_get_nrow(traces); tracerow++)
01117         {
01118             double trace_offset;
01119             int trace_number;
01120             int trace_enabled;
01121             
01122             trace_offset  = cpl_table_get_double(traces, "Offset"    , tracerow, NULL);
01123             trace_number  = cpl_table_get_int   (traces, "TraceID"   , tracerow, NULL);
01124             trace_enabled = cpl_table_get_int   (traces, "Tracemask" , tracerow, NULL);
01125             
01126             if (trace_enabled != 0)
01127             {
01128                 int window;          /* window number */
01129                 
01130                             if (cpl_table_get_nrow(traces) > 1) {
01131                                 uves_msg("Processing trace %d", trace_number);
01132                             }
01133                 
01134                 /* This is UVES specific. Load linetable for the 
01135                    two sky windows (number 1, 3) and for the object
01136                    window (number 2) */
01137                 
01138                 for (window = 1; window <= 3; window ++)
01139                 {
01140                     uves_free_table_const ( &(linetable[window-1]) );
01141                     uves_free_propertylist_const( &(linetable_header[window-1]) );
01142                     uves_polynomial_delete_const( &(dispersion_relation[window-1]) );
01143                     check( uves_load_linetable_const(
01144                            frames, 
01145                            false,  /* FLAMES? */
01146                            chip_name,
01147                            order_locations,
01148                            cpl_table_get_column_min(ordertable, "Order"),
01149                            cpl_table_get_column_max(ordertable, "Order"),
01150                            &linetable_filename,
01151                            &(linetable          [window-1]),
01152                            &(linetable_header   [window-1]),
01153                            &(dispersion_relation[window-1]),
01154                            NULL,
01155                            chip,
01156                            trace_number,
01157                            window),
01158                        "Could not load line table, window #%d", window);
01159                 }
01160                 
01161                 uves_msg_low("Using line tables in '%s'", linetable_filename);
01162                 /* end, UVES specific */
01163                 
01164                 /* Do the reduction + response calculation */
01165                 cpl_free(ref_obj_name); ref_obj_name = NULL;
01166                 uves_free_image(&reduced_spectrum);
01167                 uves_free_image(&background);
01168                 uves_free_image(&response_orders);
01169                 uves_free_image(&response_curve);
01170                 uves_free_propertylist(&response_header);
01171                 uves_free_propertylist(&spectrum_header);
01172                 uves_free_propertylist(&response_header_2d);
01173                 uves_free_table(&efficiency);
01174                 uves_free_table(&blaze_efficiency);
01175                 uves_free_table(&info_tbl);
01176                 
01177                 check( uves_response_process_chip(
01178                        raw_image[raw_index],   /* Raw         */
01179                                        raw_header[raw_index],  
01180                        rotated_header[raw_index],
01181                        master_bias,            /* Calibration */
01182                        master_dark, 
01183                                        master_dark_header,
01184                        master_flat, 
01185                                        master_flat_header,
01186                        ordertable, 
01187                                        order_locations,
01188                        linetable, 
01189                                        linetable_header, 
01190                                        dispersion_relation,
01191                        flux_table,
01192                        atm_extinction,
01193                        chip,                  /* Parameters  */
01194                        DEBUG, 
01195                        parameters,
01196                        calc_response,
01197                        PACCURACY,             /* Identification */
01198                        &ref_obj_name,
01199                        &reduced_spectrum, 
01200                                        &spectrum_header, 
01201                                        &background,
01202                        &response_orders, 
01203                                        &response_header_2d,
01204                        &response_curve,  
01205                                        &response_header,
01206                        &efficiency, 
01207                                        &blaze_efficiency,
01208                                        &info_tbl,
01209                        &extraction_slit),
01210                    "Response computation failed");
01211                 
01212                 uves_msg("Saving products...");
01213                 
01214                 /* Calculate QC (two tables) */
01215                 
01216                 if (calc_response)
01217                 {
01218                     uves_qclog_delete(&qclog[0]);
01219                     qclog[0] = uves_qclog_init(raw_header[raw_index], chip);
01220 
01221                     check( uves_efficiency_qclog(blaze_efficiency,
01222                                  raw_header[raw_index],
01223                                  chip,
01224                                  qclog[0],
01225                                  ref_obj_name), 
01226                        "Error generating efficiency QC log");
01227                 }
01228                 
01229                 uves_qclog_delete(&qclog_optext[0]);
01230                         qclog_optext[0] = cpl_table_new(0);
01231                 /* Do not:  
01232                    qclog_optext[0] = uves_qclog_init(raw_header[raw_index], chip);
01233                    because we don't want QC.DID for this
01234                 */
01235                 cpl_table_new_column(qclog_optext[0],"key_name", CPL_TYPE_STRING);
01236                 cpl_table_new_column(qclog_optext[0],"key_type", CPL_TYPE_STRING);
01237                 cpl_table_new_column(qclog_optext[0],"key_value",CPL_TYPE_STRING);
01238                 cpl_table_new_column(qclog_optext[0],"key_help", CPL_TYPE_STRING);
01239                 
01240                 check( uves_qclog_add_sci(qclog_optext[0],
01241                               raw_header[raw_index],
01242                               raw_image[raw_index],
01243                               extraction_slit,
01244                               info_tbl),
01245                    "Error generating extraction QC log");
01246 
01247                 if (calc_response)
01248                 {
01249                     /* Save response curve */
01250                     cpl_free(product_filename);
01251                     check( product_filename = uves_response_curve_filename(chip),
01252                        "Error getting filename");    
01253                     check( uves_frameset_insert(
01254                            frames,
01255                            response_curve,
01256                            CPL_FRAME_GROUP_PRODUCT,
01257                            CPL_FRAME_TYPE_IMAGE,
01258                            CPL_FRAME_LEVEL_INTERMEDIATE,
01259                            product_filename,
01260                            UVES_INSTR_RESPONSE(chip),
01261                            raw_header[raw_index],
01262                            response_header,
01263                            NULL,
01264                            parameters,
01265                            make_str(UVES_RESPONSE_ID),
01266                            PACKAGE "/" PACKAGE_VERSION, 
01267                            qclog_optext,
01268                            starttime, false, 
01269                            UVES_ALL_STATS),
01270                        "Could not add response curve '%s' (%s) to frameset", 
01271                        product_filename, UVES_INSTR_RESPONSE(chip));
01272                     
01273                     uves_msg("Response curve '%s' (%s) added to frameset",
01274                          product_filename, UVES_INSTR_RESPONSE(chip));
01275                     
01276                     /* Save response curve (2d) */
01277                     cpl_free(product_filename);
01278                     check( product_filename = 
01279                        uves_response_curve_2d_filename(chip), 
01280                        "Error getting filename");    
01281                     check( uves_frameset_insert(
01282                            frames,
01283                            response_orders,
01284                            CPL_FRAME_GROUP_PRODUCT,
01285                            CPL_FRAME_TYPE_IMAGE,
01286                            CPL_FRAME_LEVEL_INTERMEDIATE,
01287                            product_filename,
01288                            UVES_WCALIB_FF_RESPONSE(chip),
01289                            raw_header[raw_index],
01290                            response_header_2d,
01291                            NULL,
01292                            parameters,
01293                            make_str(UVES_RESPONSE_ID),
01294                            PACKAGE "/" PACKAGE_VERSION,
01295                            qclog_optext,
01296                            starttime, false, 
01297                            UVES_ALL_STATS),
01298                        "Could not add response curve (2d) "
01299                        "'%s' (%s) to frameset",
01300                        product_filename, UVES_WCALIB_FF_RESPONSE(chip));
01301             
01302                     uves_msg("Response curve (2d) '%s' (%s) added to frameset", 
01303                          product_filename, UVES_WCALIB_FF_RESPONSE(chip));
01304                 }
01305 
01306                 /* Save reduced spectrum */
01307                 cpl_free(product_filename);
01308                 check( product_filename = uves_response_red_standard_filename(chip),
01309                    "Error getting filename");    
01310                 check( uves_frameset_insert(frames,
01311                             reduced_spectrum,
01312                             CPL_FRAME_GROUP_PRODUCT,
01313                             CPL_FRAME_TYPE_IMAGE,
01314                             CPL_FRAME_LEVEL_INTERMEDIATE,
01315                             product_filename,
01316                             UVES_RED_STD(chip),
01317                             raw_header[raw_index],
01318                             spectrum_header,
01319                             NULL,
01320                             parameters,
01321                             make_str(UVES_RESPONSE_ID),
01322                             PACKAGE "/" PACKAGE_VERSION,
01323                             qclog_optext,
01324                             starttime, false, 
01325                             UVES_ALL_STATS),
01326                    "Could not add reduced spectrum '%s' (%s) to frameset",
01327                    product_filename, UVES_RED_STD(chip));
01328                 
01329                 uves_msg("Reduced spectrum '%s' (%s) added to frameset", 
01330                      product_filename, UVES_RED_STD(chip));
01331 
01332                 if (calc_response)
01333                 {
01334                     /* Save efficiency table */
01335                     uves_free_propertylist(&efficiency_header);
01336                     efficiency_header = uves_propertylist_new();
01337                     
01338                     cpl_free(product_filename);
01339                     check( product_filename = 
01340                        uves_response_efficiency_filename(chip),
01341                        "Error getting filename");
01342                     
01343                     check( uves_frameset_insert(
01344                            frames,
01345                            efficiency,
01346                            CPL_FRAME_GROUP_PRODUCT,
01347                            CPL_FRAME_TYPE_TABLE,
01348                            CPL_FRAME_LEVEL_INTERMEDIATE,
01349                            product_filename,
01350                            UVES_EFFICIENCY_TABLE(chip),
01351                            raw_header[raw_index],
01352                            efficiency_header,
01353                            NULL,
01354                            parameters,
01355                            make_str(UVES_RESPONSE_ID),
01356                            PACKAGE "/" PACKAGE_VERSION,
01357                            qclog,
01358                            starttime, true, 0),
01359                        "Could not add background image '%s' (%s) to frameset",
01360                        product_filename, UVES_EFFICIENCY_TABLE(chip));
01361                     
01362                     uves_msg("Efficiency table '%s' (%s) added to frameset", 
01363                          product_filename, UVES_EFFICIENCY_TABLE(chip));
01364                 } /* end if calc_response */
01365                 
01366                 /* Save background image */
01367                 cpl_free(product_filename);
01368                 check( product_filename = 
01369                    uves_response_bkg_standard_filename(chip), 
01370                    "Error getting filename");
01371                 check( uves_frameset_insert(frames,
01372                             background,
01373                             CPL_FRAME_GROUP_PRODUCT,
01374                             CPL_FRAME_TYPE_IMAGE,
01375                             CPL_FRAME_LEVEL_INTERMEDIATE,
01376                             product_filename,
01377                             UVES_BKG_STD(chip),
01378                             raw_header[raw_index],
01379                             rotated_header[raw_index],
01380                             NULL,
01381                             parameters,
01382                             make_str(UVES_RESPONSE_ID),
01383                             PACKAGE "/" PACKAGE_VERSION, NULL,
01384                             starttime, false, 
01385                             CPL_STATS_MIN | CPL_STATS_MAX),
01386                    "Could not add background image '%s' (%s) to frameset",
01387                    product_filename, UVES_BKG_STD(chip));
01388 
01389                 uves_msg("Background image '%s' (%s) added to frameset",
01390                      product_filename, UVES_BKG_STD(chip));
01391                 
01392             }/* ... if trace is enabled */
01393             else
01394             {
01395                 uves_msg_low("Skipping trace number %d", trace_number);
01396             }
01397         
01398         }/* For each trace */
01399     
01400 
01401       if(strcmp(PROCESS_CHIP,"REDL") == 0) {
01402     chip = uves_chip_get_next(chip);
01403       }
01404 
01405 
01406 
01407 
01408     } /* For each chip */
01409     
01410   cleanup:
01411     /* Input */
01412     uves_free_image(&raw_image[0]);
01413     uves_free_image(&raw_image[1]);
01414     uves_free_propertylist(&raw_header[0]);
01415     uves_free_propertylist(&raw_header[1]);
01416     uves_free_propertylist(&rotated_header[0]);
01417     uves_free_propertylist(&rotated_header[1]);
01418     
01419     /* Input, calib */
01420     uves_free_image(&master_bias);
01421     uves_free_propertylist(&master_bias_header);
01422     
01423     uves_free_image(&master_dark);
01424     uves_free_propertylist(&master_dark_header);
01425 
01426     uves_free_image(&master_flat);
01427     uves_free_propertylist(&master_flat_header);
01428     
01429     uves_free_table(&ordertable);
01430     uves_free_propertylist(&ordertable_header);
01431     uves_polynomial_delete(&order_locations);
01432     uves_free_table(&traces);
01433     
01434     uves_free_table_const( &(linetable[0]) );
01435     uves_free_table_const( &(linetable[1]) );
01436     uves_free_table_const( &(linetable[2]) );
01437     uves_free_propertylist_const( &(linetable_header[0]) );
01438     uves_free_propertylist_const( &(linetable_header[1]) );
01439     uves_free_propertylist_const( &(linetable_header[2]) );
01440     uves_polynomial_delete_const( &(dispersion_relation[0]) );
01441     uves_polynomial_delete_const( &(dispersion_relation[1]) );
01442     uves_polynomial_delete_const( &(dispersion_relation[2]) );
01443     uves_free_table( &flux_table );
01444     uves_free_table( &atm_extinction );
01445     
01446     /* Output */
01447     uves_qclog_delete(&qclog[0]);
01448     uves_qclog_delete(&qclog_optext[0]);
01449     uves_free_image(&background);
01450     uves_free_image(&reduced_spectrum);
01451     uves_free_propertylist(&spectrum_header);
01452     uves_free_propertylist(&response_header_2d);
01453     uves_free_propertylist(&response_header);
01454     uves_free_propertylist(&efficiency_header);
01455     uves_free_image(&response_orders);
01456     uves_free_image(&response_curve);
01457     uves_free_table(&efficiency);
01458     uves_free_table(&blaze_efficiency);
01459     uves_free_table(&info_tbl);
01460     
01461     /* Local */
01462     uves_free_table(&catalogue_flux);    
01463     cpl_free(product_filename);
01464     cpl_free(ref_obj_name);
01465     
01466     return;
01467 }
01468 
01478 static void uves_efficiency_qclog(cpl_table* table,
01479                   uves_propertylist* raw_header, 
01480                   enum uves_chip chip,
01481                   cpl_table* qclog,
01482                   const char *ref_obj_name)
01483 {
01484   int i=0;
01485   bool new_format;
01486   
01487   check( new_format = uves_format_is_new(raw_header),
01488      "Error determining FITS header format");
01489 
01490   check_nomsg(uves_qclog_add_string(qclog,
01491                         "QC TEST1 ID",
01492                         "Efficiency-Test-Results",
01493                         "Name of QC test",
01494                     "%s"));
01495 
01496   check_nomsg(uves_qclog_add_string(qclog,
01497                         uves_remove_string_prefix(UVES_INSPATH,"ESO "),
01498                          uves_pfits_get_inspath(raw_header),
01499                         "Optical path used.",
01500                    "%s"));
01501 
01502   check_nomsg(uves_qclog_add_string(qclog,
01503                         uves_remove_string_prefix(UVES_INSMODE,"ESO "),
01504                          uves_pfits_get_insmode(raw_header),
01505                         "Instrument mode used.",
01506                    "%s"));
01507 
01508   check_nomsg(uves_qclog_add_string(qclog,
01509                     uves_remove_string_prefix(UVES_GRATNAME(chip),"ESO "),
01510                     uves_pfits_get_gratname(raw_header,chip),
01511                     "Cross disperser ID",
01512                     "%s"));
01513 
01514   check_nomsg(uves_qclog_add_common_wave(raw_header,
01515                                          chip, qclog));
01516 
01517   check_nomsg(
01518       uves_qclog_add_string(qclog,
01519                 uves_remove_string_prefix(UVES_CHIP_NAME(chip),"ESO "),
01520                 /* UVES_QC_CHIP_VAL(chip), */
01521                 uves_pfits_get_chip_name(raw_header, chip),
01522                 "Detector chip name",
01523                 "%s"));
01524   
01525   check_nomsg(
01526       uves_qclog_add_double(qclog,
01527                 uves_remove_string_prefix(UVES_GRATWLEN(chip),"ESO "),
01528                 uves_pfits_get_gratwlen(raw_header,chip),
01529                 "Grating central wavelength [nm] (hs).",
01530                 "%.1f"));
01531   
01532   check_nomsg(
01533       uves_qclog_add_double(qclog,
01534                 uves_remove_string_prefix(UVES_CONAD(new_format, chip),"ESO "),
01535                 uves_pfits_get_conad(raw_header, chip),
01536                 "Conversion from ADUs to electrons",
01537                 "%8.2f"));
01538   
01539  
01540   check_nomsg(
01541       uves_qclog_add_double(qclog,
01542                 uves_remove_string_prefix(UVES_QC_UIT(new_format, chip), "ESO "),
01543                 uves_pfits_get_uit(raw_header),
01544                 "user defined subintegration time",
01545                 "%8.0f"));
01546   
01547   check_nomsg(
01548       uves_qclog_add_double(qclog,
01549                 "AIRMASS",
01550                 (uves_pfits_get_airmass_start(raw_header) +
01551                  uves_pfits_get_airmass_end(raw_header))/2.0,
01552                 "Averaged airmass",
01553                 "%8.4f"));
01554 
01555   check_nomsg(
01556       uves_qclog_add_string(qclog,
01557                 uves_remove_string_prefix(UVES_TARG_NAME, "ESO "),
01558                 ref_obj_name,
01559                 "OB target name",
01560                 "%s"));
01561   
01562  
01563   for(i = 0; i < cpl_table_get_nrow(table); i++) 
01564       {
01565       char key_name[25];
01566 
01567       int order = cpl_table_get_int(table, "Order", i, NULL);
01568 
01569       sprintf(key_name,"QC BLAZEFF%d", order);
01570 
01571       check_nomsg(uves_qclog_add_double(qclog,
01572                         key_name,
01573                         cpl_table_get_double(table, "Eff", i, NULL),
01574                         "Blaze Efficiency",
01575                         "%13.6f"));
01576       /*
01577         uves_msg("QC-LOG: Wlen =%g Eff=%g", 
01578         cpl_table_get_double(table,"Wave",i,NULL),
01579         cpl_table_get_double(table,"Eff",i,NULL));
01580       */
01581 
01582       sprintf(key_name,"QC BLAZWLEN%d", order);
01583       check_nomsg(uves_qclog_add_double(qclog,
01584                         key_name,
01585                         cpl_table_get_double(table, "Wave", i, NULL)/10.,
01586                         "Blaze wavelength",  /* nm */
01587                         "%13.6f"));
01588       }
01589 
01590   /* Are these QC parameters needed anywhere? */
01591 #if 0
01592   for(i = 0; i < cpl_table_get_nrow(info_tbl); i++) 
01593       {
01594       char key_name[25];
01595 
01596       int order = cpl_table_get_int(info_tbl, "Order", i, NULL);
01597 
01598       sprintf(key_name,"QC ORDER NUM%d", order);
01599       check_nomsg(uves_qclog_add_int(qclog,
01600                      key_name,
01601                      order,
01602                      "Order Number",
01603                      "%d"));
01604       /*
01605         uves_msg("QC-LOG: Order =%d S/N=%g", 
01606         cpl_table_get_int(info_tbl,"Order",i,NULL),
01607         cpl_table_get_double(info_tbl,"S/N",i,NULL));
01608       */
01609 
01610       sprintf(key_name,"QC OBJ SN%d", order);
01611       check_nomsg(uves_qclog_add_double(qclog,
01612                         key_name,
01613                         cpl_table_get_double(info_tbl,"S/N",i,NULL),
01614                         "Order S/N",
01615                         "%f13.6"));
01616       }
01617 #endif
01618 
01619  cleanup:
01620   return;
01621 }
01622 

Generated on Fri Apr 18 14:11:43 2008 for UVES Pipeline Reference Manual by  doxygen 1.5.1