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

Generated on Thu Nov 15 14:32:31 2007 for UVES Pipeline Reference Manual by  doxygen 1.5.1