UVES Pipeline Reference Manual  5.4.6
uves_physmod_body.c
1 /* *
2  * This file is part of the ESO UVES Pipeline *
3  * Copyright (C) 2004,2005 European Southern Observatory *
4  * *
5  * This library is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the Free Software *
17  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA *
18  * */
19 
20 /*
21  * $Author: amodigli $
22  * $Date: 2013-08-08 13:36:46 $
23  * $Revision: 1.60 $
24  * $Name: not supported by cvs2svn $
25  * $Log: not supported by cvs2svn $
26  * Revision 1.59 2013/07/29 12:38:25 amodigli
27  * set med_dx, med_dy to proper values to have at least a model iteration on both chips (PIPE-4666)
28  *
29  * Revision 1.58 2013/07/01 15:37:10 amodigli
30  * Rename DEBUG to debug_mode to remove compiler error on some platforms (that name is reserved to special compiler options)
31  *
32  * Revision 1.57 2010/09/27 08:00:41 amodigli
33  * removed x_axis_scale and y_axis_scal params from interface as always kept constant
34  *
35  * Revision 1.56 2010/09/24 09:32:06 amodigli
36  * put back QFITS dependency to fix problem spot by NRI on FIBER mode (with MIDAS calibs) data
37  *
38  * Revision 1.54 2010/08/30 14:17:20 amodigli
39  * moved declaration product_filename variable up to eventually used to dump an extra QC product
40  *
41  * Revision 1.53 2010/06/15 15:46:26 amodigli
42  * removed useless second call to uves_save_table_local of the same temporary product already saved
43  *
44  * Revision 1.52 2010/05/06 14:21:06 amodigli
45  * increase mbox_x/y min to 10 to improve recipe robustness
46  *
47  * Revision 1.51 2010/05/01 16:01:27 amodigli
48  * clearer error message
49  *
50  * Revision 1.50 2010/03/09 15:27:49 amodigli
51  * removed generation of tmp product 'pippo4.fits'
52  *
53  * Revision 1.49 2010/03/01 18:17:22 amodigli
54  * now model_prediction prediction table is generated only in debug mode
55  *
56  * Revision 1.48 2009/08/03 12:48:10 amodigli
57  * some messaging to monitor physmodel shifts
58  *
59  * Revision 1.47 2009/07/13 07:56:21 amodigli
60  * insert proper offsets for new CCD echelle standard modes
61  *
62  * Revision 1.46 2009/07/13 06:38:41 amodigli
63  * moved functions to get new CCD shifts in uves_physmod_create_table.c
64  *
65  * Revision 1.45 2009/04/27 08:32:59 amodigli
66  * fixed trans_x/y setting in FIBER mode
67  *
68  * Revision 1.44 2009/04/14 07:02:07 amodigli
69  * set explicit filename to distingush if physmod is executed on a normal formatcheck or on a reference one
70  *
71  * Revision 1.43 2008/09/29 06:58:03 amodigli
72  * add #include <string.h>
73  *
74  * Revision 1.42 2008/05/01 09:57:03 amodigli
75  * fixed compiler warnings
76  *
77  * Revision 1.41 2008/05/01 09:46:06 amodigli
78  * modify x-y shift (if flames) if trans_x/y are set
79  *
80  * Revision 1.40 2008/02/15 12:43:49 amodigli
81  * allow lower/upper chip for parameter process_chip
82  *
83  * Revision 1.39 2007/12/05 14:12:43 amodigli
84  * if stability_cnt=0 does not do certain steps as in MIDAS
85  *
86  * Revision 1.38 2007/12/03 17:00:14 amodigli
87  * removed dependency from flames and fixed a warning
88  *
89  * Revision 1.37 2007/12/03 10:43:00 amodigli
90  * added flames_get_physmod_shift and set itermax to 1 to fix problems on flames-uves
91  *
92  * Revision 1.36 2007/10/23 07:37:43 amodigli
93  * if provided subtract MASTER_BIAS from input raw and reference formatchecks
94  *
95  * Revision 1.35 2007/10/05 16:01:45 amodigli
96  * using proces_chip parameter to process or not a given RED chip
97  *
98  * Revision 1.34 2007/08/21 13:08:26 jmlarsen
99  * Removed irplib_access module, largely deprecated by CPL-4
100  *
101  * Revision 1.33 2007/08/10 15:24:11 amodigli
102  * fixed seg fault with flames-uves
103  *
104  * Revision 1.32 2007/06/26 15:08:17 amodigli
105  * changes to make work flames and uves physmod in simple way
106  *
107  * Revision 1.31 2007/06/22 09:30:22 jmlarsen
108  * Changed interface of uves_save_image
109  *
110  * Revision 1.30 2007/06/13 15:13:48 amodigli
111  * fixed mem leaks in case of fiber mode data
112  *
113  * Revision 1.29 2007/06/06 08:17:33 amodigli
114  * replace tab with 4 spaces
115  *
116  * Revision 1.28 2007/05/22 14:34:32 jmlarsen
117  * Removed unnecessary includes
118  *
119  * Revision 1.27 2007/05/14 09:38:38 amodigli
120  * removed call to irplib_error_dump
121  *
122  * Revision 1.26 2007/04/25 08:38:40 amodigli
123  * chnaged interface uves_physmod_plotmod
124  *
125  * Revision 1.25 2007/04/24 14:08:53 jmlarsen
126  * Log more QC parameters (DFS03805)
127  *
128  * Revision 1.24 2007/04/24 12:50:29 jmlarsen
129  * Replaced cpl_propertylist -> uves_propertylist which is much faster
130  *
131  * Revision 1.23 2007/04/14 05:55:19 amodigli
132  * warning of flames,iter demoted to debug message
133  *
134  * Revision 1.22 2007/04/12 12:03:10 jmlarsen
135  * Fixed doc. typo
136  *
137  * Revision 1.21 2007/03/05 10:18:55 jmlarsen
138  * Do QC-log INS.SLITi.WID
139  *
140  * Revision 1.20 2007/02/26 10:16:22 jmlarsen
141  * Do not QC log slit width
142  *
143  * Revision 1.19 2007/01/15 14:28:44 jmlarsen
144  * Write default stability QC-parameters, only when master frame is provided
145  *
146  * Revision 1.18 2007/01/15 08:43:15 jmlarsen
147  * Fixed missing plots
148  *
149  * Revision 1.17 2007/01/13 09:52:22 amodigli
150  * fixed some problems on flames QC log
151  *
152  * Revision 1.16 2007/01/09 17:46:03 amodigli
153  * fixed a problem in echelle mode
154  *
155  * Revision 1.15 2007/01/08 16:59:18 amodigli
156  * changes to make flames-uves iterations to recover physical model
157  *
158  * Revision 1.14 2006/12/07 08:26:04 jmlarsen
159  * Added uves_pfits_get_readspeed
160  *
161  * Revision 1.13 2006/12/01 12:29:21 jmlarsen
162  * Factored out FLAMES plate-id code
163  *
164  * Revision 1.12 2006/11/22 08:42:20 jmlarsen
165  * Set traceid = 1, not 0 for UVES
166  *
167  * Revision 1.10 2006/11/22 08:22:29 jmlarsen
168  * Set message level according to preprocessor symbol
169  *
170  * Revision 1.9 2006/11/16 14:12:21 jmlarsen
171  * Changed undefined trace number from 0 to -1, to support zero as an actual trace number
172  *
173  * Revision 1.8 2006/11/16 09:49:25 jmlarsen
174  * Fixed doxygen bug
175  *
176  * Revision 1.7 2006/11/15 15:02:14 jmlarsen
177  * Implemented const safe workarounds for CPL functions
178  *
179  * Revision 1.5 2006/11/15 14:04:08 jmlarsen
180  * Removed non-const version of parameterlist_get_first/last/next which is already
181  * in CPL, added const-safe wrapper, unwrapper and deallocator functions
182  *
183  * Revision 1.4 2006/11/06 15:19:41 jmlarsen
184  * Removed unused include directives
185  *
186  * Revision 1.3 2006/10/26 14:03:48 jmlarsen
187  * Fixed position of const modifier
188  *
189  * Revision 1.2 2006/10/25 11:43:32 amodigli
190  * fixed problem running physmod in debug mode
191  *
192  * Revision 1.1 2006/10/24 14:09:56 jmlarsen
193  * Factored out common UVES/FLAMES code
194  *
195  * Revision 1.30 2006/10/19 13:53:25 jmlarsen
196  * Changed guess line table tag to LINE_GUESS_TAB
197  *
198  * Revision 1.29 2006/10/17 12:33:02 jmlarsen
199  * Added semicolon at UVES_RECIPE_DEFINE invocation
200  *
201  * Revision 1.28 2006/10/11 12:22:36 amodigli
202  * now the stability check consist only i the msrawxy and the table comparison, as in MIDAS
203  *
204  * Revision 1.27 2006/10/09 13:01:13 jmlarsen
205  * Use macro to define recipe interface functions
206  *
207  * Revision 1.26 2006/09/19 14:31:38 jmlarsen
208  * uves_insert_frame(): use bitmap to specify which image statistics keywords must be computed
209  *
210  * Revision 1.25 2006/09/19 06:55:39 jmlarsen
211  * Changed interface of uves_frameset to optionally write image statistics kewwords
212  *
213  * Revision 1.24 2006/08/24 11:36:37 jmlarsen
214  * Write recipe start/stop time to header
215  *
216  * Revision 1.23 2006/08/18 13:35:42 jmlarsen
217  * Fixed/changed QC parameter formats
218  *
219  * Revision 1.22 2006/08/17 13:56:53 jmlarsen
220  * Reduced max line length
221  *
222  * Revision 1.21 2006/08/11 14:56:05 amodigli
223  * removed Doxygen warnings
224  *
225  * Revision 1.20 2006/08/07 11:35:35 jmlarsen
226  * Disabled parameter environment variable mode
227  *
228  * Revision 1.19 2006/08/01 14:42:34 amodigli
229  * fixed bugs getting raw header from master formatcheck
230  *
231  * Revision 1.18 2006/07/31 06:29:26 amodigli
232  * added QC on stability test
233  *
234  * Revision 1.17 2006/07/28 14:51:26 amodigli
235  * fixed some bugs on improper table selection
236  *
237  * Revision 1.16 2006/07/14 12:19:28 jmlarsen
238  * Support multiple QC tests per product
239  *
240  * Revision 1.15 2006/07/03 12:46:34 amodigli
241  * updated description
242  *
243  * Revision 1.14 2006/06/28 13:28:29 amodigli
244  * improved output
245  *
246  * Revision 1.13 2006/06/20 09:06:39 amodigli
247  * correct input tag info in man page
248  *
249  * Revision 1.12 2006/06/16 08:25:45 jmlarsen
250  * Manually propagate ESO.DET. keywords from 1st/2nd input header
251  *
252  * Revision 1.11 2006/06/13 11:57:02 jmlarsen
253  * Check that calibration frames are from the same chip ID
254  *
255  * Revision 1.10 2006/06/07 13:06:28 jmlarsen
256  * Changed doxygen tag addtogroup -> defgroup
257  *
258  * Revision 1.9 2006/06/07 09:01:28 amodigli
259  * added some doc
260  *
261  * Revision 1.8 2006/05/08 15:42:16 amodigli
262  * allow to specify order column label
263  *
264  * Revision 1.7 2006/04/20 10:47:39 amodigli
265  * added qclog
266  *
267  * Revision 1.6 2006/04/07 07:11:12 jmlarsen
268  * Minor doc. fix
269  *
270  * Revision 1.5 2006/04/06 09:48:15 amodigli
271  * changed uves_frameset_insert interface to have QC log
272  *
273  * Revision 1.4 2006/04/06 08:42:19 jmlarsen
274  * Changed indentation
275  *
276  * Revision 1.3 2006/03/03 13:54:11 jmlarsen
277  * Changed syntax of check macro
278  *
279  * Revision 1.2 2006/02/28 09:15:22 jmlarsen
280  * Minor update
281  *
282  * Revision 1.1 2006/02/03 07:46:30 jmlarsen
283  * Moved recipe implementations to ./uves directory
284  *
285  * Revision 1.66 2006/01/25 10:09:18 jmlarsen
286  * Added doxygen end marker
287  *
288  * Revision 1.65 2006/01/20 10:36:25 amodigli
289  *
290  * Fixed warings from doxigen
291  *
292  * Revision 1.64 2006/01/19 10:03:06 amodigli
293  * Fixed leaks
294  *
295  * Revision 1.62 2006/01/16 13:52:58 jmlarsen
296  * Removed memory leak
297  *
298  * Revision 1.61 2006/01/16 08:01:57 amodigli
299  *
300  * Added stability check
301  *
302  * Revision 1.60 2006/01/13 13:43:15 jmlarsen
303  * Removed memory leak
304  *
305  * Revision 1.59 2006/01/13 09:54:42 amodigli
306  * Fixed some bugs: improved agreement with MIDAS version
307  *
308  * Revision 1.58 2006/01/09 15:23:06 jmlarsen
309  * Removed some warnings
310  *
311  * Revision 1.57 2006/01/09 14:05:42 amodigli
312  * Fixed doxigen warnings
313  *
314  * Revision 1.56 2006/01/03 16:57:13 amodigli
315  * Fixed bug
316  *
317  * Revision 1.55 2006/01/03 14:47:53 amodigli
318  *
319  * Added uves_physmod_chop_otab.h .c to match MIDAS
320  *
321  * Revision 1.54 2005/12/19 16:17:55 jmlarsen
322  * Replaced bool -> int
323  *
324  */
325 #ifdef HAVE_CONFIG_H
326 # include <config.h>
327 #endif
328 
329 /*----------------------------------------------------------------------------*/
333 /*----------------------------------------------------------------------------*/
334 
335 /*-----------------------------------------------------------------------------
336  Includes
337  -----------------------------------------------------------------------------*/
338 
339 /* Self */
340 #include <uves_physmod_body.h>
341 
342 /* called related functions */
343 #include <uves_physmod_plotmod.h>
344 #include <uves_physmod_create_table.h>
345 
346 #include <uves_physmod_qc1pmtbl.h>
347 #include <uves_physmod_calmap.h>
348 #include <uves_physmod_msrawxy.h>
349 #include <uves_physmod_chop_otab.h>
350 #include <uves_physmod_stability_check.h>
351 
352 /* Utility functions */
353 #include <uves_utils.h>
354 #include <uves_utils_polynomial.h>
355 #include <uves_utils_wrappers.h>
356 #include <uves_pfits.h>
357 #include <uves_dfs.h>
358 #include <uves_parameters.h>
359 #include <uves_qclog.h>
360 #include <uves_recipe.h>
361 #include <uves_error.h>
362 #include <uves_msg.h>
363 /* Library */
364 #include <cpl.h>
365 #include <math.h>
366 #include <stdbool.h>
367 #include <string.h>
368 /*-----------------------------------------------------------------------------
369  Defines
370  -----------------------------------------------------------------------------*/
371 
372 #define UVES_PHYSMOD_ITER_MAX 5
373 /*-----------------------------------------------------------------------------
374  Functions prototypes
375  ----------------------------------------------------------------------------*/
376 
377 static int
378 uves_physmod_qclog(cpl_table* line_table,
379  cpl_table* order_table,
380  cpl_table* qclog,
381  const uves_propertylist *raw_header,
382  enum uves_chip chip,
383  bool flames,
384  const int iter,
385  const int plate_no);
386 
387 static int
388 uves_physmod_qclog_sc(const double med_dx,
389  const double med_dy,
390  const double avg_dx,
391  const double avg_dy,
392  const uves_propertylist *raw_header,
393  const uves_propertylist *ref_header,
394  enum uves_chip chip,
395  bool flames,
396  const int iter,
397  cpl_table* qclog);
398 
399 
400 
401 static int
402 flames_get_physmod_shift(const int plate_no,
403  const int wavec,
404  enum uves_chip chip,
405  double* physmod_shift_x,
406  double* physmod_shift_y,
407  double* rot_1,
408  double* rot_2,
409  double* rot_3);
410 
411 
412 /*-----------------------------------------------------------------------------
413  Recipe standard code
414  -----------------------------------------------------------------------------*/
415 
416 const char * const uves_physmod_desc_short = "Implements the UVES physical model";
417 const char * const uves_physmod_desc =
418 "This recipe implements the UVES physical model\n"
419 "Input files are BLUE or RED arm formatcheck frames identified by the tag\n"
420 "ARC_LAMP_FORM_xxxx, xxxx=BLUE or RED and a ThAr line reference table\n"
421 "identified by the tag LINE_REFER_TABLE\n"
422 "The recipe extracts from the input files FITS header data indicating the\n"
423 "instrument setting and ambiental atmospheric conditions, then using the\n"
424 "model predicts X,Y position of the lines listed in the LINE_REFER_TABLE\n"
425 "table which are imaging on the detector and stores this information in an\n"
426 "guess order and a guess line table.\n"
427 "Output are a guess order table and a guess line table per chip.\n"
428 "If the user provides in input also master format checks having tag\n"
429 "MASTER_FORM_xxxx, xxxx=BLUE or REDL and REDU the recipe performs also a\n"
430 "stability check\n";
431 
433 /*-----------------------------------------------------------------------------
434  Functions code
435  -----------------------------------------------------------------------------*/
436 
437 /*----------------------------------------------------------------------------*/
443 /*----------------------------------------------------------------------------*/
444 int
445 uves_physmod_define_parameters_body(cpl_parameterlist *parameters,
446  const char *recipe_id)
447 {
448  const char *subcontext = NULL;
449 
450  /*****************
451  * General *
452  *****************/
453 
454  if (uves_define_global_parameters(parameters) != CPL_ERROR_NONE)
455  {
456  return -1;
457  }
458 
459  uves_par_new_range("mbox_x",
460  CPL_TYPE_INT,
461  "Match box X size",
462  40,10,100);
463 
464  uves_par_new_range("mbox_y",
465  CPL_TYPE_INT,
466  "Match box Y size",
467  40,10,100);
468 
469  uves_par_new_value("trans_x",
470  CPL_TYPE_DOUBLE,
471  "Detector translation along X",
472  0.);
473 
474  uves_par_new_value("trans_y",
475  CPL_TYPE_DOUBLE,
476  "Detector translation along Y",
477  0.);
478 
479  uves_par_new_value("ech_angle_off",
480  CPL_TYPE_DOUBLE,
481  "Offset on echelle angle",
482  0.);
483 
484  uves_par_new_value("cd_angle_off",
485  CPL_TYPE_DOUBLE,
486  "Offset on cross disperser angle",
487  0.);
488 
489  uves_par_new_value("ccd_rot_angle_off",
490  CPL_TYPE_DOUBLE,
491  "Offset on CCD rotation angle",
492  0.);
493 
494  uves_par_new_value("compute_regression_sw",
495  CPL_TYPE_BOOL,
496  "Compute regression?",
497  true);
498 
499 /* we decided to remove those params as we always have them set to 0
500  uves_par_new_value("x_axis_scale",
501  CPL_TYPE_DOUBLE,
502  "Scale X axis",
503  0.);
504 
505  uves_par_new_value("y_axis_scale",
506  CPL_TYPE_DOUBLE,
507  "Scale Y axis",
508  0.);
509 */
510  uves_par_new_value("def_pol1",
511  CPL_TYPE_INT,
512  "Polynomial X deg",
513  4);
514 
515  uves_par_new_value("def_pol2",
516  CPL_TYPE_INT,
517  "Polynomial Y deg",
518  5);
519 
520  uves_par_new_value("kappa",
521  CPL_TYPE_DOUBLE,
522  "Kappa value in kappa sigma clipping "
523  "on RESIDUAL between YFIT and Y columns",
524  4.5);
525 
526  uves_par_new_value("tol",
527  CPL_TYPE_DOUBLE,
528  "Tolerance in kappa sigma clipping "
529  "on RESIDUAL between YFIT and Y columns",
530  2.0);
531 
532  return (int) cpl_error_get_code();
533 }
534 /*----------------------------------------------------------------------------*/
562 /*----------------------------------------------------------------------------*/
563 
564 static cpl_table *
565 uves_physmod_process_chip(const cpl_image *raw_image,
566  const uves_propertylist *raw_header,
567  const char *raw_filename,
568  enum uves_chip chip,
569  bool flames,
570  const char *recipe_id,
571  const int debug_mode,
572  const cpl_parameterlist* parameters,
573  cpl_table* line_refer,
574  const double physmod_shift_x,
575  const double physmod_shift_y,
576  cpl_table** tmp_mod_tbl,
577  cpl_table** lin_tbl,
578  cpl_table** ord_tbl,
579  cpl_table** mline_tbl,
580  int* abs_ord_min,
581  int* abs_ord_max,
582  polynomial** absolute_order_poly2d,
583  const int stability_cnt)
584 {
585 
586  cpl_table *tmp_fsr_tbl = NULL;
587  cpl_table *tmp_m_tbl = NULL;
588  cpl_table *tmp_p_tbl = NULL;
589  cpl_table *tmp_w_tbl = NULL;
590  cpl_table *tmp_s_tbl = NULL;
591  cpl_table *tmp_rline_tbl = NULL;
592  cpl_table *tmp_npline_tbl = NULL;
593 
594 
595  cpl_table * result=NULL;
596  const char *product_filename = NULL;
597 
598  /* Start processing this chip */
599  uves_msg("stability counter=%d",stability_cnt);
600  if(stability_cnt == 0) {
601  uves_msg("offsetx=%f offsety=%f",physmod_shift_x,physmod_shift_y);
602  check( uves_physmod_create_table(raw_header,
603  chip,
604  flames,
605  recipe_id,
606  parameters,
607  line_refer,
608  physmod_shift_x,
609  physmod_shift_y,
610  tmp_mod_tbl,
611  &tmp_fsr_tbl),
612  "Could not run UVES physical model on the raw image %s",
613  raw_filename);
614 
615  if (debug_mode) {
616 
617  const char *product_filename = NULL;
618  product_filename = "model_prediction";
619  check( uves_save_table_local("Physical model table",
620  product_filename, *tmp_mod_tbl, chip, -1, -1, raw_header, NULL),
621  "Error saving physical model table");
622 
623 
624  }
625  }
626 
627 
628 
629 
630  uves_free_table(&tmp_rline_tbl);
631  check( uves_physmod_msrawxy(raw_image,
632  raw_header,
633  recipe_id,
634  parameters,
635  *tmp_mod_tbl,
636  lin_tbl,
637  &tmp_m_tbl,
638  &tmp_p_tbl,
639  &tmp_rline_tbl,
640  mline_tbl,
641  &tmp_npline_tbl),
642  "Could not run uves_msrawxy to measure arc line position on raw image %s",
643  raw_filename);
644 
645 /*
646  product_filename = "tmp_mod_tbl";
647  check( uves_save_table_local("tmp_mod_tbl table",
648  product_filename, *tmp_mod_tbl, chip, -1, -1, raw_header, NULL),
649  "Error saving tmp_mod_tbl table");
650 */
651 
652  check(uves_physmod_plotmod(tmp_rline_tbl,raw_header,recipe_id,
653  parameters,chip),
654  "Could not run uves_physmod_plotmod");
655 
656  if(stability_cnt == 0) {
657  uves_free_table(&tmp_w_tbl);
658  uves_free_table(&tmp_s_tbl);
659  check(uves_physmod_calmap(raw_header,
660  chip,
661  recipe_id,
662  parameters,
663  tmp_npline_tbl,
664  ord_tbl,
665  lin_tbl,
666  &tmp_w_tbl,
667  &tmp_s_tbl,
668  abs_ord_min,
669  abs_ord_max,
670  absolute_order_poly2d),
671  "Could not run uves_calmap on raw image %s", raw_filename);
672 
673  //cpl_table_save(*lin_tbl, NULL, NULL, "pippo4.fits", CPL_IO_DEFAULT);
674 
675 
676  check(uves_physmod_chop_otab(raw_header,chip,lin_tbl,"Order",
677  abs_ord_min,abs_ord_max),
678  "Could not run uves_physmod_chop_otab on raw image %s",
679  raw_filename);
680 
681 
682  check(uves_physmod_qc1pmtbl(&tmp_rline_tbl,lin_tbl),
683  "Could not run uves_qc1pmtbl on raw image %s", raw_filename);
684 
685 
686  check(uves_physmod_chop_otab(raw_header,chip,ord_tbl,"ORDER",
687  abs_ord_min,abs_ord_max),
688  "Could not run uves_physmod_chop_otab on raw image %s",
689  raw_filename);
690  }
691 
692  if (debug_mode) {
693  /* Temporary products (to debug_mode) */
694 
695  /* Basic info about orders */
696  if(stability_cnt==0) {
697  product_filename = "arclampform";
698  } else {
699  product_filename = "ref_arclampform";
700  }
701  check( uves_save_image_local("Physical model table",
702  product_filename, raw_image, chip, -1, -1, raw_header, true),
703  "Error saving arc lamp form image");
704 
705  product_filename = "pline";
706  check( uves_save_table_local("Physical model table",
707  product_filename, *tmp_mod_tbl, chip, -1, -1, raw_header, NULL),
708  "Error saving physical model table");
709 
710 
711  if(stability_cnt == 0) {
712  product_filename = "free_spectral_range";
713  check( uves_save_table_local("FSR table",
714  product_filename, tmp_fsr_tbl,
715  chip, -1, -1, raw_header, NULL),
716  "Error saving free spectral range table");
717 
718  }
719 
720  product_filename = "midduml";
721  check( uves_save_table_local("midduml table",
722  product_filename, *lin_tbl, chip, -1, -1, raw_header, NULL),
723  "Error saving midduml table");
724 
725 
726 
727  product_filename = "middumm";
728  check( uves_save_table_local("middumm table",
729  product_filename, tmp_m_tbl, chip, -1, -1, raw_header, NULL),
730  "Error saving middumm table");
731 
732 
733 
734  product_filename = "middumrline";
735  check( uves_save_table_local("middumrline table",
736  product_filename, tmp_rline_tbl, chip, -1, -1, raw_header, NULL),
737  "Error saving middumrline table");
738 
739 
740  product_filename = "middummline";
741  check( uves_save_table_local("middummline table",
742  product_filename, *mline_tbl, chip, -1, -1, raw_header, NULL),
743  "Error saving middummline table");
744 
745 
746  product_filename = "middump";
747  check( uves_save_table_local("middump table",
748  product_filename, tmp_p_tbl, chip, -1, -1, raw_header, NULL),
749  "Error saving middump table");
750 
751 
752  product_filename = "middumnpline";
753  check( uves_save_table_local("middumnpline table",
754  product_filename, tmp_npline_tbl, chip, -1, -1, raw_header, NULL),
755  "Error saving middumnpline table");
756 
757 
758  /* Calmap */
759  if(stability_cnt== 0) {
760  product_filename = "middumw";
761  check( uves_save_table_local("middumw table",
762  product_filename, tmp_w_tbl,
763  chip, -1, -1, raw_header, NULL),
764  "Error saving middumw table");
765 
766  product_filename = "middums";
767  check( uves_save_table_local("middums table",
768  product_filename, tmp_s_tbl,
769  chip, -1, -1, raw_header, NULL),
770  "Error saving middums table");
771 
772 
773  product_filename = "order";
774  check( uves_save_table_local("order table",
775  product_filename, *ord_tbl,
776  chip, -1, -1, raw_header, NULL),
777  "Error saving order table");
778  uves_msg("Order table saved to file %s",
779  product_filename);
780 
781  }
782  product_filename = "line";
783  check( uves_save_table_local("line table",
784  product_filename, *lin_tbl, chip, -1, -1, raw_header, NULL),
785  "Error saving uves_line table");
786  uves_msg("Line table saved to file %s",
787  product_filename);
788 
789 
790 
791  }
792 
793  cleanup:
794  uves_free_table(&tmp_fsr_tbl);
795  uves_free_table(&tmp_m_tbl);
796  uves_free_table(&tmp_p_tbl);
797  uves_free_table(&tmp_w_tbl);
798  uves_free_table(&tmp_s_tbl);
799  uves_free_table(&tmp_rline_tbl);
800  uves_free_table(&tmp_npline_tbl);
801 
802  uves_msg_debug("end %s",__func__);
803  return result;
804 }
805 
806 
807 
808 /*---------------------------------------------------------------------------*/
817 /*---------------------------------------------------------------------------*/
818 void
819 uves_physmod_exe_body(cpl_frameset *frames,
820  bool flames,
821  const char *recipe_id,
822  const cpl_parameterlist *parameters,
823  const char *starttime)
824 {
825  /* Input image */
826  cpl_image *raw_image[2] = {NULL, NULL};
827  uves_propertylist *raw_header[2] = {NULL, NULL};
828  uves_propertylist *rotated_header[2] = {NULL, NULL};
829  uves_propertylist *master_formatcheck_header[2] = {NULL, NULL};
830 
831  /* Physical Model guess table products */
832  cpl_table *line_table = NULL;
833  cpl_table *order_table = NULL;
834  cpl_table *mline_table = NULL;
835  cpl_table *m_mline_table = NULL;
836  cpl_table *model_table = NULL;
837 
838  cpl_table *r_mline_table = NULL;
839  cpl_table *mst_line_table = NULL;
840  cpl_table *mst_mline_table = NULL;
841  cpl_table *mst_order_table = NULL;
842 
843 
844  uves_propertylist *product_header = NULL;
845  uves_propertylist *table_header = NULL;
846  cpl_table *line_refer = NULL;
847  polynomial *absolute_order_poly2d=NULL;
848  polynomial *mst_absolute_order_poly2d=NULL;
849 
850 
851  /* Local variables */
852  int debug_mode=0;
853  int abs_ord_min=0;
854  int abs_ord_max=0;
855  int mst_abs_ord_min=0;
856  int mst_abs_ord_max=0;
857  double avg_dx=0;
858  double avg_dy=0;
859 
860  const char *raw_filename = "";
861  char *product_filename = NULL;
862 
863  bool blue = false;
864  enum uves_chip chip;
865  const char *line_refer_filename = "";
866  const char *master_formatcheck_filename = "";
867  cpl_image *master_formatcheck = NULL;
868  int nordpred=0;
869  int plate_no=0;
870  int iter=1;
871  int it=0;
872 
873  int iter_max=UVES_PHYSMOD_ITER_MAX;
874  /* QC tables for iter_max*(TEST1+TEST2) and a NULL pointer */
875  cpl_table* qclog[iter_max*2+1];
876 
877 
878  double physmod_shift_x=0;
879  double physmod_shift_y=0;
880  double ref_frame_physmod_shift_x=0;
881  double ref_frame_physmod_shift_y=0;
882  const double max_shift_x=0.4;
883  const double max_shift_y=0.2;
884  double med_dx=2*max_shift_x;
885  double med_dy=2*max_shift_y;
886  const char* PROCESS_CHIP=NULL;
887  /* Master bias */
888  cpl_image *master_bias = NULL;
889  uves_propertylist *master_bias_header = NULL;
890 
891  double rot_1=0;
892  double rot_2=0;
893  double rot_3=0;
894  double wlen=0;
895  int wavec=0;
896  int stab_check=0;
897  int stability_cnt=1;
898  const char *chip_name = "";
899  int raw_index = 0;
900  const char *master_bias_filename = "";
901 
902  double trans_x=0;
903  double trans_y=0;
904  char extname[80];
905  for( iter=0 ; iter < 2*iter_max+1 ; iter++) {
906  qclog[iter]=NULL;
907  }
908 
909  if(flames) {
910  iter_max=1; //Temporally changed to 1
911  } else {
912  iter_max=1;
913  }
914  check( uves_get_parameter(parameters, NULL, "uves", "debug",
915  CPL_TYPE_BOOL, &debug_mode),
916  "Could not read parameter");
917  check( uves_get_parameter(parameters, NULL, "uves", "process_chip",
918  CPL_TYPE_STRING, &PROCESS_CHIP),
919  "Could not read parameter");
920  uves_string_toupper((char*)PROCESS_CHIP);
921  /* Load raw image and header, and identify input frame as red or blue */
922  check( uves_load_formatcheck(frames, flames, &raw_filename, raw_image,
923  raw_header, rotated_header, &blue),
924  "Error loading raw frame");
925 
926  /* Load reference line table */
927  check( uves_load_linerefertable(frames, &line_refer_filename,
928  &line_refer, NULL),
929  "Could not load line reference table");
930  uves_msg("Using line reference table in '%s'", line_refer_filename);
931 
932  check( uves_get_parameter(parameters, NULL, recipe_id,
933  "trans_x", CPL_TYPE_DOUBLE, &trans_x ) ,
934  "Could not read parameter");
935 
936  check( uves_get_parameter(parameters, NULL, recipe_id,
937  "trans_y", CPL_TYPE_DOUBLE, &trans_y ) ,
938  "Could not read parameter");
939 
940 
941 
942  /* Loop over one or two chips */
943  for (chip = uves_chip_get_first(blue);
944  chip != UVES_CHIP_INVALID;
945  chip = uves_chip_get_next(chip))
946  {
947  /* following init to have at least one model iteration on both chips */
948  med_dx=2*max_shift_x;
949  med_dy=2*max_shift_y;
950  if(strcmp(PROCESS_CHIP,"REDU") == 0) {
951  chip = uves_chip_get_next(chip);
952  }
953 
954  stab_check=0;
955  stability_cnt=1;
956  raw_index = uves_chip_get_index(chip);
957 
958 
959  uves_msg("Processing %s chip in '%s'",
960  uves_chip_tostring_upper(chip), raw_filename);
961 
962  check_nomsg( chip_name = uves_pfits_get_chipid(raw_header[raw_index], chip));
963 
964 
965  physmod_shift_x=0;
966  physmod_shift_y=0;
967  if(flames) {
968  check(plate_no = uves_flames_pfits_get_plateid(raw_header[raw_index]),
969  "Error reading plate id");
970  check_nomsg(wlen=uves_pfits_get_gratwlen(raw_header[raw_index],chip));
971  wavec=(int)wlen;
972 
973 
974  ck0_nomsg(flames_get_physmod_shift(plate_no,wavec,chip,
975  &physmod_shift_x,&physmod_shift_y,
976  &rot_1,&rot_2,&rot_3));
977 
978  ref_frame_physmod_shift_x=physmod_shift_x;
979  ref_frame_physmod_shift_y=physmod_shift_y;
980 
981 
982 
983  uves_msg("shift_x=%f shift_y=%f",physmod_shift_x,physmod_shift_y);
984  if( trans_x != 0 ) {
985  physmod_shift_x+=trans_x;
986  }
987 
988  if( trans_y != 0 ) {
989  physmod_shift_y+=trans_y;
990  }
991  uves_msg("shift_x=%f shift_y=%f",physmod_shift_x,physmod_shift_y);
992 
993  } else {
994 
995  if( trans_x != 0 ) {
996  physmod_shift_x=trans_x;
997  }
998 
999  if( trans_y != 0 ) {
1000  physmod_shift_y=trans_y;
1001  }
1002 
1003  }
1004  uves_msg("Using physmod shifts: %g %g",physmod_shift_x,physmod_shift_y);
1005  /* Check if a stability check can be done */
1006  if (cpl_frameset_find(frames, UVES_MASTER_ARC_FORM(chip)) != NULL) {
1007 
1008  uves_free_image (&master_formatcheck);
1009  uves_free_propertylist(&master_formatcheck_header[raw_index]);
1010  check( uves_load_master_formatcheck(frames,
1011  chip_name,
1012  &master_formatcheck_filename,
1013  &master_formatcheck,
1014  &master_formatcheck_header[raw_index],
1015  chip),
1016  "Could not load master formatcheck frm");
1017 
1018 
1019  stab_check=1;
1020 
1021  } else {
1022  uves_msg_low("No master format check frm in SOF.");
1023  uves_msg_low("Stability check not done");
1024  }
1025 
1026  /* Load master bias, set pointer to NULL if not present */
1027  uves_free_image(&master_bias);
1028  uves_free_propertylist(&master_bias_header);
1029  if (cpl_frameset_find(frames, UVES_MASTER_BIAS(chip)) != NULL)
1030  {
1031  uves_free_image(&master_bias);
1032  uves_free_propertylist(&master_bias_header);
1033  check( uves_load_mbias(frames,
1034  chip_name,
1035  &master_bias_filename, &master_bias,
1036  &master_bias_header, chip),
1037  "Error loading master bias");
1038 
1039  uves_msg_low("Using master bias in '%s' and '%s'",
1040  master_bias_filename,master_formatcheck_filename);
1041  check_nomsg(cpl_image_subtract(raw_image[raw_index],master_bias));
1042  if(stab_check==1) {
1043  check_nomsg(cpl_image_subtract(master_formatcheck,master_bias));
1044  }
1045 
1046  }
1047  else
1048  {
1049  uves_msg_low("No master bias in SOF. Bias subtraction not done");
1050  }
1051 
1052  /* Init QC-Log: before starting the stability check as in
1053  FLAMES-UVES one may have several iterations to be dumped
1054  on the different tables
1055  */
1056 
1057  for(iter=1,it=0;
1058  iter<=iter_max &&
1059  (fabs(med_dx) > max_shift_x ||
1060  fabs(med_dy) > max_shift_y ) ;
1061  iter++,it+=2) {
1062  uves_msg("iter=%d it=%d",iter,it);
1063 
1064  uves_qclog_delete(&qclog[it]);
1065  uves_qclog_delete(&qclog[it+1]);
1066  qclog[it] = uves_qclog_init(raw_header[raw_index], chip);
1067  qclog[it+1] = uves_qclog_init(raw_header[raw_index], chip);
1068 
1069 
1070  //Run the physical model on the raw frame
1071  uves_free_table(&model_table);
1072  uves_free_table(&line_table);
1073  uves_free_table(&order_table);
1074  uves_free_table(&mline_table);
1075 
1076  uves_polynomial_delete(&absolute_order_poly2d);
1077  uves_msg("Run the physical model on the raw frame");
1078  uves_msg("physmod shift x %f y %f",physmod_shift_x,physmod_shift_y);
1079  check( uves_physmod_process_chip(raw_image[raw_index],
1080  raw_header[raw_index],
1081  raw_filename,
1082  chip,
1083  flames,
1084  recipe_id,
1085  debug_mode,
1086  parameters,
1087  line_refer,
1088  physmod_shift_x,
1089  physmod_shift_y,
1090  &model_table,
1091  &line_table,
1092  &order_table,
1093  &mline_table,
1094  &abs_ord_min,
1095  &abs_ord_max,
1096  &absolute_order_poly2d,0),
1097  "Error processing chip");
1098 
1099  nordpred=abs_ord_max-abs_ord_min+1;
1100  uves_msg("No of predicted orders %d",nordpred);
1101 
1102 
1103  /* add QC log */
1104  uves_msg("add QC log on raw frame");
1105  ck0(uves_physmod_qclog(line_table,order_table,qclog[it],
1106  raw_header[raw_index], chip,
1107  flames,iter,plate_no),"qc-log dump");
1108 
1109 
1110 
1111  uves_msg("iter_max=%d",iter_max);
1112  if(stab_check) {
1113  uves_free_table(&mst_line_table);
1114  uves_free_table(&mst_order_table);
1115  uves_free_table(&mst_mline_table);
1116  uves_polynomial_delete(&mst_absolute_order_poly2d);
1117 
1118  uves_msg("Run the physical model on the Master formatcheck frame");
1119  uves_msg("ref physmod shift x %f y %f",
1120  ref_frame_physmod_shift_x,ref_frame_physmod_shift_y);
1121 
1122  uves_msg("Stability counter=%d",stability_cnt);
1123  check(uves_physmod_process_chip(master_formatcheck,
1124  master_formatcheck_header[raw_index],
1125  master_formatcheck_filename,
1126  chip,
1127  flames,
1128  recipe_id,
1129  debug_mode,
1130  parameters,
1131  line_refer,
1132  ref_frame_physmod_shift_x,
1133  ref_frame_physmod_shift_y,
1134  &model_table,
1135  &mst_line_table,
1136  &mst_order_table,
1137  &mst_mline_table,
1138  &mst_abs_ord_min,
1139  &mst_abs_ord_max,
1140  &mst_absolute_order_poly2d,
1141  stability_cnt),
1142  "Error processing chip");
1143  stability_cnt+=1;
1144  uves_msg("Stability check");
1145  uves_msg("Using master format check frm '%s'",
1146  master_formatcheck_filename);
1148  mline_table,
1149  mst_mline_table,
1150  &med_dx,
1151  &med_dy,
1152  &avg_dx,
1153  &avg_dy) );
1154 
1155 
1156 
1157  uves_physmod_qclog_sc(med_dx,med_dy,avg_dx,avg_dy,
1158  raw_header[raw_index],
1159  master_formatcheck_header[raw_index],
1160  chip,flames,iter,
1161  qclog[it+1]);
1162  uves_msg("iter=%d med_dx=%g med_dy=%g",
1163  iter,fabs(med_dx),fabs(med_dy));
1164  uves_msg("iter=%d max_shift_x=%g max_shift_y=%g",
1165  iter,max_shift_x,max_shift_y);
1166 
1167 
1168  nordpred=abs_ord_max-abs_ord_min+1;
1169  physmod_shift_x-=med_dx;
1170  physmod_shift_y-=med_dy;
1171 
1172  } // end of stability check
1173 
1174  } // end of iterations
1175 
1176 
1177  /* Finished. Now save the products */
1178  uves_msg("Saving products...");
1179 
1180 
1181  /* QC parameters should go here.
1182  Other mandatory keywords (FITS + dfs) are
1183  automatically added. */
1184 
1185  uves_free_propertylist(&product_header);
1186  uves_free_propertylist(&table_header);
1187  product_header = uves_propertylist_new();
1188  table_header = uves_propertylist_new();
1189  check( uves_pfits_set_traceid ( table_header, 0),
1190  "Error writing trace ID to product header");
1191  check( uves_pfits_set_windownumber( table_header, 2),
1192  "Error window number to product header");
1193 
1194  check( uves_pfits_set_firstabsorder(table_header, abs_ord_min),
1195  "Error window number to product header");
1196 
1197  check( uves_pfits_set_lastabsorder(table_header, abs_ord_max),
1198  "Error window number to product header");
1199 
1200  check_nomsg(uves_pfits_set_ordpred(product_header,nordpred));
1201 
1202 
1203  if (flames) {
1204 
1206  plate_no));
1207  }
1208 
1209  cpl_free(product_filename);
1210  uves_pfits_set_extname(product_header,"Guess line table");
1211  sprintf(extname,"LINE_GUESS_TAB");
1212  uves_pfits_set_extname(table_header,extname);
1213  check(( product_filename = uves_guess_line_table_filename(chip),
1214  uves_frameset_insert(frames,
1215  line_table,
1216  CPL_FRAME_GROUP_PRODUCT,
1217  CPL_FRAME_TYPE_TABLE,
1218  CPL_FRAME_LEVEL_INTERMEDIATE,
1219  product_filename,
1220  UVES_GUESS_LINE_TABLE(flames, chip),
1221  raw_header[raw_index],
1222  product_header,
1223  table_header,
1224  parameters,
1225  recipe_id,
1226  PACKAGE "/" PACKAGE_VERSION,
1227  qclog,
1228  starttime,
1229  true,
1230  0)),
1231  "Could not add line guess table %s to frameset",
1232  product_filename);
1233 
1234  /* Save in next extension */
1235 
1236  sprintf(extname,"LINE_GUESS_POL1");
1237  uves_pfits_set_extname(table_header,extname);
1238  check( uves_save_polynomial(absolute_order_poly2d,
1239  product_filename, table_header),
1240  "Could not write polynomial to file '%s'", product_filename);
1241 
1242  sprintf(extname,"LINE_GUESS_POL2");
1243  uves_pfits_set_extname(table_header,extname);
1244  check( uves_save_polynomial(absolute_order_poly2d,
1245  product_filename, table_header),
1246  "Could not write polynomial to file '%s'", product_filename);
1247 
1248 
1249 
1250  uves_msg("Line table %s added to frameset", product_filename);
1251 
1252  /* Save guess order table, re-use product header */
1253 
1254  cpl_free(product_filename);
1255  uves_pfits_set_extname(product_header,"Guess order table");
1256  sprintf(extname,"ORD_GUESS_TAB");
1257  uves_pfits_set_extname(table_header,extname);
1258  check(( product_filename = uves_guess_order_table_filename(chip),
1259  uves_frameset_insert(frames,
1260  order_table,
1261  CPL_FRAME_GROUP_PRODUCT,
1262  CPL_FRAME_TYPE_TABLE,
1263  CPL_FRAME_LEVEL_INTERMEDIATE,
1264  product_filename,
1265  UVES_GUESS_ORDER_TABLE(flames, chip),
1266  raw_header[raw_index],
1267  product_header,
1268  table_header,
1269  parameters,
1270  recipe_id,
1271  PACKAGE "/" PACKAGE_VERSION,
1272  NULL,
1273  starttime,
1274  false,
1275  0)),
1276  "Could not add order guess table %s to frameset",
1277  product_filename);
1278 
1279  uves_msg("Order guess table %s added to frameset",
1280  product_filename);
1281 
1282  for(it=0;it<2*iter_max+1;it++) {
1283  uves_qclog_delete(&qclog[it]);
1284  }
1285 
1286  if(strcmp(PROCESS_CHIP,"REDL") == 0) {
1287  chip = uves_chip_get_next(chip);
1288  }
1289 
1290  }/* For each chip */
1291 
1292  cleanup:
1293  for(it=0;it<2*iter_max+1;it++) {
1294  uves_qclog_delete(&qclog[it]);
1295  }
1296 
1297  /* Master bias */
1298  uves_free_image(&master_bias);
1299  uves_free_propertylist(&master_bias_header);
1300 
1301  uves_free_image (&raw_image[0]);
1302  uves_free_image (&raw_image[1]);
1303  uves_free_propertylist(&raw_header[0]);
1304  uves_free_propertylist(&raw_header[1]);
1305  uves_free_propertylist(&rotated_header[0]);
1306  uves_free_propertylist(&rotated_header[1]);
1307 
1308  uves_free_image (&master_formatcheck);
1309  uves_free_propertylist(&master_formatcheck_header[0]);
1310  uves_free_propertylist(&master_formatcheck_header[1]);
1311 
1312  uves_free_table(&model_table);
1313  uves_free_table(&line_table);
1314  uves_free_table(&mst_line_table);
1315  uves_free_table(&order_table);
1316  uves_free_table(&mst_order_table);
1317  uves_free_table(&line_refer);
1318 
1319  uves_free_table(&mline_table);
1320  uves_free_table(&m_mline_table);
1321  uves_free_table(&r_mline_table);
1322  uves_free_table(&mst_mline_table);
1323 
1324  uves_free_propertylist(&product_header);
1325  uves_free_propertylist(&table_header);
1326  uves_polynomial_delete(&absolute_order_poly2d);
1327  uves_polynomial_delete(&mst_absolute_order_poly2d);
1328  cpl_free(product_filename);
1329 
1330  uves_msg_debug("end %s",__func__);
1331  return;
1332 }
1333 
1334 
1344 static int
1345 uves_physmod_qclog(cpl_table* line_table,
1346  cpl_table* order_table,
1347  cpl_table* qclog,
1348  const uves_propertylist *raw_header,
1349  enum uves_chip chip,
1350  bool flames,
1351  const int iter,
1352  const int plate_no)
1353 {
1354  int nlinsel=0;
1355  cpl_table *xline_table=NULL;
1356  char key_value[25];
1357 
1358 
1360  chip, qclog) );
1361 
1362 
1363  if(flames) {
1364  ck0_nomsg(uves_qclog_add_string(qclog,
1365  "QC TEST1 ID",
1366  "Fibre-Physical-Model-Prediction-Results",
1367  "Name of QC test",
1368  "%s"));
1369  } else {
1370  ck0_nomsg(uves_qclog_add_string(qclog,
1371  "QC TEST1 ID",
1372  "Physical-Model-Prediction-Results",
1373  "Name of QC test",
1374  "%s"));
1375  }
1376  ck0_nomsg(uves_qclog_add_string(qclog,
1377  "QC MODEL ID",
1378  "UVES_phys_mod/1.1.0",
1379  "Physmod Model Id",
1380  "%s"));
1381 
1382  ck0_nomsg(uves_qclog_add_string(qclog,
1383  "QC MODEL DATE",
1384  "2000:03:18T00:00:00.000",
1385  "Physmod Model Parameters Last Change",
1386  "%s"));
1387 
1388  if(flames) {
1389 
1390  sprintf(key_value,"%s%d","QC MODEL ITER",iter);
1391  ck0_nomsg(uves_qclog_add_int(qclog,
1392  key_value,
1393  iter,
1394  "Model iteration",
1395  "%d"));
1396 
1397  ck0_nomsg(uves_qclog_add_int(qclog,
1398  "QC MODEL ORDMIN",
1399  cpl_table_get_column_min(line_table,"Order"),
1400  "minimum predicted order value",
1401  "%d"));
1402 
1403  ck0_nomsg(uves_qclog_add_int(qclog,
1404  "QC MODEL ORDMAX",
1405  cpl_table_get_column_max(line_table,"Order"),
1406  "maximum predicted order value",
1407  "%d"));
1408 
1409 
1410  ck0_nomsg(uves_qclog_add_double(qclog,
1411  "QC MODEL WLENMIN",
1412  cpl_table_get_column_min(line_table,"WAVEC")/10.,
1413  "minimum predicted order value",
1414  "%f"));
1415 
1416  ck0_nomsg(uves_qclog_add_double(qclog,
1417  "QC MODEL WLENMAX",
1418  cpl_table_get_column_max(line_table,"WAVEC")/10.,
1419  "maximum predicted order value",
1420  "%f"));
1421 
1422 
1423  } /* in case of flames-uves */
1424 
1425  ck0_nomsg(uves_qclog_add_int(qclog,
1426  "QC MODEL NLINALL",
1427  cpl_table_get_nrow(line_table),
1428  "Number of predicted lines",
1429  "%d"));
1430 
1431  check_nomsg(nlinsel=cpl_table_and_selected_int(line_table,"SELPLOT",
1432  CPL_EQUAL_TO,1));
1433  check_nomsg(xline_table=cpl_table_extract_selected(line_table));
1434 
1435  ck0_nomsg(uves_qclog_add_int(qclog,
1436  "QC MODEL NLINSEL",
1437  nlinsel,
1438  "Number of lines selected",
1439  "%d"));
1440 
1441  if(iter == 1) {
1442  ck0_nomsg(uves_qclog_add_double(qclog,
1443  "QC MODEL DIFFXRMS",
1444  cpl_table_get_column_stdev(xline_table,"XDIF"),
1445  "Std dev of X difference to physical model",
1446  "%8.4f"));
1447 
1448  ck0_nomsg(uves_qclog_add_double(qclog,
1449  "QC MODEL DIFFXAVG",
1450  cpl_table_get_column_mean(xline_table,"XDIF"),
1451  "Average of X difference to physical model",
1452  "%8.4f"));
1453 
1454  ck0_nomsg(uves_qclog_add_double(qclog,"QC MODEL DIFFXMED",
1455  cpl_table_get_column_median(xline_table,"XDIF"),
1456  "Median of X difference to physical model",
1457  "%8.4f"));
1458 
1459  ck0_nomsg(uves_qclog_add_double(qclog,
1460  "QC MODEL DIFFYRMS",
1461  cpl_table_get_column_stdev(xline_table,"YDIF"),
1462  "Std dev of Y difference to physical model",
1463  "%8.4f"));
1464 
1465  ck0_nomsg(uves_qclog_add_double(qclog,
1466  "QC MODEL DIFFYAVG",
1467  cpl_table_get_column_mean(xline_table,"YDIF"),
1468  "Average of Y difference to physical model",
1469  "%8.4f"));
1470 
1471  ck0_nomsg(uves_qclog_add_double(qclog,"QC MODEL DIFFYMED",
1472  cpl_table_get_column_median(xline_table,"YDIF"),
1473  "Median of Y difference to physical model",
1474  "%8.4f"));
1475  }
1476 
1477  if ( flames == 1 ) {
1478 
1479 
1480  sprintf(key_value,"%s%d","QC MODEL RESXRMS",iter);
1481  ck0_nomsg(uves_qclog_add_double(qclog,
1482  key_value,
1483  cpl_table_get_column_stdev(xline_table,"XDIF"),
1484  "Std dev of X difference to physical model",
1485  "%8.4f"));
1486 
1487 
1488  sprintf(key_value,"%s%d","QC MODEL RESXAVG",iter);
1489  ck0_nomsg(uves_qclog_add_double(qclog,
1490  key_value,
1491  cpl_table_get_column_mean(xline_table,"XDIF"),
1492  "Average of X difference to physical model",
1493  "%8.4f"));
1494 
1495  sprintf(key_value,"%s%d","QC MODEL RESXMED",iter);
1496  ck0_nomsg(uves_qclog_add_double(qclog,
1497  key_value,
1498  cpl_table_get_column_median(xline_table,"XDIF"),
1499  "Median of X difference to physical model",
1500  "%8.4f"));
1501 
1502 
1503 
1504  sprintf(key_value,"%s%d","QC MODEL RESYRMS",iter);
1505  ck0_nomsg(uves_qclog_add_double(qclog,
1506  key_value,
1507  cpl_table_get_column_stdev(xline_table,"YDIF"),
1508  "Std dev of Y difference to physical model",
1509  "%8.4f"));
1510 
1511 
1512  sprintf(key_value,"%s%d","QC MODEL RESYAVG",iter);
1513  ck0_nomsg(uves_qclog_add_double(qclog,
1514  key_value,
1515  cpl_table_get_column_mean(xline_table,"YDIF"),
1516  "Average of Y difference to physical model",
1517  "%8.4f"));
1518 
1519  sprintf(key_value,"%s%d","QC MODEL RESYMED",iter);
1520  ck0_nomsg(uves_qclog_add_double(qclog,
1521  key_value,
1522  cpl_table_get_column_median(xline_table,"YDIF"),
1523  "Median of Y difference to physical model",
1524  "%8.4f"));
1525 
1526 
1527  }
1528 
1529 
1530  cpl_table_unselect_all(line_table);
1531 
1532  /* we divide by 10 as line_table contains values in Angstrom and we want
1533  nanometers */
1534  ck0_nomsg(uves_qclog_add_double(qclog,
1535  "QC MODEL WLENMIN",
1536  cpl_table_get_column_min(xline_table,"WAVEC")/10.,
1537  "minimum predicted wavelength value",
1538  "%8.4f"));
1539 
1540  ck0_nomsg(uves_qclog_add_double(qclog,
1541  "QC MODEL WLENMAX",
1542  cpl_table_get_column_max(xline_table,"WAVEC")/10.,
1543  "maximum predicted wavelength value",
1544  "%8.4f"));
1545 
1546 
1547  ck0_nomsg(uves_qclog_add_int(qclog,
1548  "QC MODEL ORDMIN",
1549  (int)cpl_table_get_column_min(xline_table,"Order"),
1550  "minimum predicted order value",
1551  "%d"));
1552 
1553  ck0_nomsg(uves_qclog_add_int(qclog,
1554  "QC MODEL ORDMAX",
1555  (int)cpl_table_get_column_max(xline_table,"Order"),
1556  "maximum predicted order value",
1557  "%d"));
1558 
1559 
1560 
1561  /* we divide by 10 as line_table contains values in Angstrom and we want
1562  nanometers */
1563  ck0_nomsg(uves_qclog_add_double(qclog,
1564  "QC WLENMIN",
1565  cpl_table_get_column_min(line_table,"WAVEC")/10.,
1566  "minimum wavelength",
1567  "%8.4f"));
1568 
1569  ck0_nomsg(uves_qclog_add_double(qclog,
1570  "QC WLENMAX",
1571  cpl_table_get_column_max(line_table,"WAVEC")/10.,
1572  "maximum wavelength",
1573  "%8.4f"));
1574 
1575  ck0_nomsg(uves_qclog_add_int(qclog,
1576  "QC ORDMIN",
1577  cpl_table_get_column_min(order_table,"ORDER"),
1578  "minimum order number",
1579  "%d"));
1580 
1581  ck0_nomsg(uves_qclog_add_int(qclog,
1582  "QC ORDMAX",
1583  cpl_table_get_column_max(order_table,"ORDER"),
1584  "maximum order number",
1585  "%d"));
1586 
1587 
1588  if (flames) {
1589  /*
1590 stat/ima {wlc} {SESSOUTV}
1591 tot_int = outputr(7)
1592 exp_time = {{wlc},{h_dit1}}
1593 rel_int = tot_int / exp_time
1594  */
1595 
1596  ck0_nomsg(uves_qclog_add_double(qclog,
1597  "QC FIB1 ABSTRANS",
1598  cpl_table_get_column_max(order_table,"ORDER"),
1599  "abs. trans. countrate",
1600  "%f"));
1601  /*
1602 @p flames_check_sat_lev {wlc} {DRS_PTHRE_MIN} {DRS_PTHRE_MAX}
1603 sat_lev = {q1}
1604 n_hpix = {q2}
1605  */
1606 
1607  ck0_nomsg(uves_qclog_add_int(qclog,
1608  "QC NHOTPIX",
1609  cpl_table_get_column_max(order_table,"ORDER"),
1610  "no. of hot pixels",
1611  "%d"));
1612 
1613 
1614  ck0_nomsg(uves_qclog_add_int(qclog,
1615  "QC PLATENO",
1616  plate_no,
1617  "Plate Id.",
1618  "%d"));
1619  }
1620 
1621  /* The number of orders predicted is already written to another
1622  keyword, and this is not need for QC logging, so it is commented out
1623  uves_qclog_add_int(qclog,"QC NORDGUE",???,"No of predicted orders","%d");
1624  */
1625 
1626  cleanup:
1627  uves_free_table(&xline_table);
1628 
1629  if (cpl_error_get_code() != CPL_ERROR_NONE) {
1630  return -1;
1631 
1632  } else {
1633 
1634  return 0;
1635  }
1636 
1637 
1638 
1639 }
1640 
1641 
1642 
1643 
1653 static int
1654 uves_physmod_qclog_sc(const double med_dx,
1655  const double med_dy,
1656  const double avg_dx,
1657  const double avg_dy,
1658  const uves_propertylist *raw_header,
1659  const uves_propertylist *ref_header,
1660  enum uves_chip chip,
1661  bool flames,
1662  const int iter,
1663  cpl_table* qclog)
1664 {
1665 
1666  char key_value[25];
1667 
1668  if(flames) {
1669  ck0_nomsg(uves_qclog_add_string(qclog,
1670  "QC TEST2 ID",
1671  "Fibre-Stability-Check-Results",
1672  "Name of QC test",
1673  "%s"));
1674  } else {
1675  ck0_nomsg(uves_qclog_add_string(qclog,
1676  "QC TEST2 ID",
1677  "Stability-Check-Results",
1678  "Name of QC test",
1679  "%s"));
1680  }
1681 
1682  ck0_nomsg(uves_qclog_add_string(qclog,
1683  "QC MODEL ID",
1684  "UVES_phys_mod/1.1.0",
1685  "Physmod Model Id",
1686  "%s"));
1687 
1688  ck0_nomsg(uves_qclog_add_string(qclog,
1689  "QC MODEL DATE",
1690  "2000:03:18T00:00:00.000",
1691  "Physmod Model Parameters Last Change",
1692  "%s"));
1693 
1695  chip, qclog) );
1696 
1697 
1698  ck0_nomsg(uves_qclog_add_string(qclog,
1699  "QC REF PNAME",
1700  uves_pfits_get_arcfile(ref_header),
1701  "Reference file name",
1702  "%s"));
1703 
1704  ck0_nomsg(uves_qclog_add_double(qclog,
1705  "QC AMBI PRES",
1706  uves_pfits_get_ambipress(raw_header),
1707  "Ambient pressure [mm] Hg.",
1708  "%8.4f"));
1709 
1710 
1711  if(flames) {
1712 
1713  sprintf(key_value,"%s%d","QC MODEL ITER",iter);
1714  ck0_nomsg(uves_qclog_add_int(qclog,
1715  key_value,
1716  iter,
1717  "Model iteration",
1718  "%d"));
1719 
1720 
1721  }
1722 
1723  if(iter == 1) {
1724  ck0_nomsg(uves_qclog_add_double(qclog,
1725  "QC SHFTXAVG",
1726  avg_dx,
1727  "mean shift in x",
1728  "%8.4f"));
1729 
1730  ck0_nomsg(uves_qclog_add_double(qclog,
1731  "QC SHFTXMED",
1732  med_dx,
1733  "median shift in x",
1734  "%8.4f"));
1735 
1736  ck0_nomsg(uves_qclog_add_double(qclog,
1737  "QC SHFTYAVG",
1738  avg_dy,
1739  "mean shift in y",
1740  "%8.4f"));
1741 
1742  ck0_nomsg(uves_qclog_add_double(qclog,
1743  "QC SHFTYMED",
1744  med_dy,
1745  "median shift in y",
1746  "%8.4f"));
1747 
1748  }
1749  cleanup:
1750 
1751  if (cpl_error_get_code() != CPL_ERROR_NONE) {
1752  return -1;
1753  } else {
1754  return 0;
1755  }
1756 }
1757 
1758 
1759 /*---------------------------------------------------------------------------*/
1771 /*---------------------------------------------------------------------------*/
1772 
1773 
1774 static int
1775 flames_get_physmod_shift(const int plate_no,
1776  const int wavec,
1777  enum uves_chip chip,
1778  double* trans_x,
1779  double* trans_y,
1780  double* rot_1,
1781  double* rot_2,
1782  double* rot_3)
1783 {
1784 
1785  //For the moment rot angle default is assumed always 0,0,0
1786  *rot_1=0;
1787  *rot_2=0;
1788  *rot_3=0;
1789 
1790  uves_msg("plate_no=%d,wavec=%d,chip=%d",plate_no,wavec,chip);
1791  switch(plate_no){
1792 
1793  case 1:
1794  if(chip==UVES_CHIP_REDL) {
1795  switch(wavec){
1796 
1797  case 520:
1798  *trans_x=-15.330;
1799  *trans_y=-40.461;
1800  uves_msg("case 520 REDL pt1");
1801  break;
1802 
1803  case 580:
1804  *trans_x=-17.972;
1805  *trans_y=-39.200;
1806  uves_msg("case 580 REDL pt1");
1807  break;
1808 
1809  case 860:
1810  *trans_x=-12.212;
1811  *trans_y=-49.370;
1812  uves_msg("case 860 REDL pt1");
1813  break;
1814 
1815  }
1816  } else {
1817 
1818  switch(wavec){
1819 
1820  case 520:
1821  *trans_x=-14.237;
1822  *trans_y=-40.337;
1823  uves_msg("case 520 REDU pt1");
1824  break;
1825 
1826  case 580:
1827  *trans_x=-14.738;
1828  *trans_y=-38.831;
1829  uves_msg("case 580 REDU pt1");
1830  break;
1831 
1832  case 860:
1833  *trans_x=-08.253;
1834  *trans_y=-45.385;
1835  uves_msg("case 860 REDU pt1");
1836  break;
1837 
1838  }
1839  break;
1840 
1841  }
1842  break;
1843 
1844 
1845  case 2:
1846  if(chip==UVES_CHIP_REDL) {
1847 
1848  case UVES_CHIP_REDL:
1849  switch(wavec){
1850 
1851  case 520:
1852  *trans_x=+10.136;
1853  *trans_y=-41.420;
1854  uves_msg("case 520 REDL pt2");
1855  break;
1856 
1857  case 580:
1858  *trans_x=+09.000;
1859  *trans_y=-38.289;
1860  uves_msg("case 580 REDL pt2");
1861  break;
1862 
1863  case 860:
1864  *trans_x=+16.386;
1865  *trans_y=-47.519;
1866  uves_msg("case 860 REDL pt2");
1867  break;
1868 
1869  }
1870  break;
1871 
1872  } else {
1873 
1874  switch(wavec){
1875 
1876  case 520:
1877  *trans_x=+12.244;
1878  *trans_y=-41.970;
1879  uves_msg("case 520 REDU pt2");
1880  break;
1881 
1882  case 580:
1883  *trans_x=+12.023;
1884  *trans_y=-38.165;
1885  uves_msg("case 580 REDU pt2");
1886  break;
1887 
1888  case 860:
1889  *trans_x=+18.241;
1890  *trans_y=-43.889;
1891  uves_msg("case 860 REDU pt2");
1892  break;
1893 
1894  }
1895  break;
1896 
1897  }
1898  break;
1899 
1900 
1901  default:
1902  *trans_x=0;
1903  *trans_y=0;
1904 
1905 
1906 
1907  }
1908 
1909 
1910  uves_msg("Physical Model shifts trans=%f,%f rot=%f,%f,%f",
1911  *trans_x,*trans_y,*rot_1,*rot_2,*rot_3);
1912  return 0;
1913 }
1914 
1915 
1916 
int uves_physmod_stability_check(cpl_table *m_tbl, cpl_table *r_tbl, double *med_dx, double *med_dy, double *avg_dx, double *avg_dy)
This procedure run a stability check.
void uves_polynomial_delete(polynomial **p)
Delete a polynomial.
int uves_physmod_qc1pmtbl(cpl_table **rline_tbl, cpl_table **lin_tbl)
To be written.
int uves_flames_pfits_get_plateid(const uves_propertylist *raw_header)
read the plate id
Definition: uves_pfits.c:3201
void uves_pfits_set_windownumber(uves_propertylist *plist, int window_number)
Write the window number.
Definition: uves_pfits.c:1944
const char * uves_pfits_get_arcfile(const uves_propertylist *plist)
find out the arcfile
Definition: uves_pfits.c:272
int uves_qclog_add_string(cpl_table *table, const char *key_name, const char *value, const char *key_help, const char *format)
Add string key to QC-LOG table.
Definition: uves_qclog.c:683
#define check_nomsg(CMD)
Definition: uves_error.h:204
int uves_physmod_create_table(const uves_propertylist *raw_header, enum uves_chip chip, bool flames, const char *recipe_id, const cpl_parameterlist *parameters, cpl_table *line_refer, const double physmod_shift_x, const double physmod_shift_y, cpl_table **mod_tbl, cpl_table **fsr_tbl)
Generates two tables with results of the UVES physical model.
int uves_qclog_delete(cpl_table **table)
delete QC-LOG table
Definition: uves_qclog.c:716
double uves_pfits_get_gratwlen(const uves_propertylist *plist, enum uves_chip chip)
find out the central wavelength
Definition: uves_pfits.c:1371
int uves_qclog_add_double(cpl_table *table, const char *key_name, const double value, const char *key_help, const char *format)
Add double key to QC-LOG table.
Definition: uves_qclog.c:641
double uves_pfits_get_ambipress(const uves_propertylist *plist)
find out the arcfile
Definition: uves_pfits.c:251
void uves_flames_pfits_set_newplateid(uves_propertylist *plist, int plate_no)
Write the plate number.
Definition: uves_pfits.c:3273
int uves_qclog_add_int(cpl_table *table, const char *key_name, const int value, const char *key_help, const char *format)
Add integer key to QC-LOG table.
Definition: uves_qclog.c:521
uves_propertylist * uves_propertylist_new(void)
Create an empty property list.
#define uves_msg(...)
Print a message on 'info' or 'debug' level.
Definition: uves_msg.h:119
void uves_pfits_set_traceid(uves_propertylist *plist, int trace_id)
Write the trace ID.
Definition: uves_pfits.c:1888
int uves_physmod_chop_otab(const uves_propertylist *raw_header, enum uves_chip chip, cpl_table **ord_tbl, const char *col_name, int *ord_min, int *ord_max)
Chop off orders which are not fully in the detector chip.
int uves_chip_get_index(enum uves_chip chip)
Convert to integer.
Definition: uves_chip.c:124
enum uves_chip uves_chip_get_first(bool blue)
Get first chip for blue or red arm.
Definition: uves_chip.c:92
cpl_error_code uves_pfits_set_extname(uves_propertylist *plist, const char *extname)
Write the EXTNAME keyword.
Definition: uves_pfits.c:2736
#define uves_msg_low(...)
Print a message on a lower message level.
Definition: uves_msg.h:105
void uves_pfits_set_lastabsorder(uves_propertylist *plist, int last_abs_order)
Write the last absolute order number.
Definition: uves_pfits.c:1750
enum uves_chip uves_chip_get_next(enum uves_chip chip)
Get next chip.
Definition: uves_chip.c:108
#define uves_msg_debug(...)
Print a debug message.
Definition: uves_msg.h:97
const char * uves_chip_tostring_upper(enum uves_chip chip)
Convert to string.
Definition: uves_chip.c:156
int uves_physmod_msrawxy(const cpl_image *raw_image, const uves_propertylist *raw_header, const char *recipe_id, const cpl_parameterlist *parameters, cpl_table *mod_tbl, cpl_table **l_tbl, cpl_table **m_tbl, cpl_table **p_tbl, cpl_table **rline_tbl, cpl_table **mline_tbl, cpl_table **npline_tbl)
This procedure measures the raw XY positions and widths of Th-Ar lines on an ThAr arc echelle exposur...
int uves_physmod_plotmod(const cpl_table *tbl, const uves_propertylist *head, const char *rec_id, const cpl_parameterlist *params, enum uves_chip chip)
This procedure plots results from the uves_physmod recipe.
const char * uves_string_toupper(char *s)
Convert all lowercase characters in a string into uppercase characters.
Definition: uves_utils.c:1493
cpl_error_code uves_pfits_set_ordpred(uves_propertylist *plist, int nord)
Write the predicted number of order.
Definition: uves_pfits.c:1000
void uves_qclog_add_common_wave(const uves_propertylist *raw_header, enum uves_chip chip, cpl_table *qclog)
Write common QC parameters.
Definition: uves_qclog.c:942
#define check(CMD,...)
Definition: uves_error.h:198
cpl_table * uves_qclog_init(const uves_propertylist *raw_header, enum uves_chip chip)
Init QC-LOG table.
Definition: uves_qclog.c:410
const char * uves_pfits_get_chipid(const uves_propertylist *plist, enum uves_chip chip)
Find out the chip ID.
Definition: uves_pfits.c:619
void uves_pfits_set_firstabsorder(uves_propertylist *plist, int first_abs_order)
Write the first absolute order number.
Definition: uves_pfits.c:1717
int uves_physmod_calmap(const uves_propertylist *raw_header, enum uves_chip chip, const char *recipe_id, const cpl_parameterlist *parameters, cpl_table *npline_tbl, cpl_table **ord_tbl, cpl_table **lin_tbl, cpl_table **w_tbl, cpl_table **s_tbl, int *abs_ord_min, int *abs_ord_max, polynomial **poly2d)
This procedure makes the order definitions and wavelength calibration from the wavelength projection ...