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

Generated on Tue Jun 19 14:39:17 2007 for UVES Pipeline Reference Manual by  doxygen 1.4.6