CRIRES Pipeline Reference Manual  2.3.15
crires_util_plot.c
1 /* $Id: crires_util_plot.c,v 1.33 2012-09-19 14:10:27 yjung Exp $
2  *
3  * This file is part of the crires Pipeline
4  * Copyright (C) 2002,2003 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: yjung $
23  * $Date: 2012-09-19 14:10:27 $
24  * $Revision: 1.33 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 
36 #include "crires_recipe.h"
37 
38 #include "irplib_wlxcorr.h"
39 
40 /*-----------------------------------------------------------------------------
41  Define
42  -----------------------------------------------------------------------------*/
43 
44 #define RECIPE_STRING "crires_util_plot"
45 
46 /*-----------------------------------------------------------------------------
47  Functions prototypes
48  -----------------------------------------------------------------------------*/
49 
50 static int crires_util_plot_diff(const cpl_table *,const char *, const char *) ;
51 static int crires_util_plot_spec_pix(cpl_table *, cpl_table *, int) ;
52 static int crires_util_plot_spec_pix_one(cpl_table *, cpl_table *, int,
53  const char *, const char *, const char *) ;
54 static int crires_util_plot_spec_wl(cpl_table *, cpl_table *,
55  const char *, int) ;
56 static int crires_util_plot_convers(cpl_table *, cpl_table *,
57  const char *, int) ;
58 static int crires_util_plot_sensit(cpl_table *, cpl_table *,
59  const char *, int) ;
60 static int crires_util_plot_spec_wl_one(cpl_table *, cpl_table *,
61  const char *, int, const char *, const char *, const char *) ;
62 
63 static char crires_util_plot_description[] = "Plot the CRIRES tables.\n"
64 "For MEF, specify the extension with --display=extension_number.\n"
65 "This recipe accepts possibly 2 parameter:\n"
66 "First parameter: the table to plot.\n"
67 " (PRO TYPE = "CRIRES_PROTYPE_CATALOG") or\n"
68 " (PRO TYPE = "CRIRES_PROTYPE_PHO_FLUX") or\n"
69 " (PRO TYPE = "CRIRES_PROTYPE_SPEC_PIX") or\n"
70 " (PRO TYPE = "CRIRES_PROTYPE_SPEC_WL") or\n"
71 " (PRO TYPE = "CRIRES_PROTYPE_XCORR") or\n"
72 " (PRO TYPE = "CRIRES_PROTYPE_CONVERS") or\n"
73 " (PRO TYPE = "CRIRES_PROTYPE_SENSIT") or\n"
74 " (PRO TYPE = "CRIRES_PROTYPE_FWHM")\n"
75 "Second parameter is optional and must be of the same type and same\n"
76 " table length as the first one. If provided, the two\n"
77 " signals are overplotted. In this case, --adjust can \n"
78 " be used to adjust the second plot average level to \n"
79 " the first one.\n" ;
80 
81 CRIRES_RECIPE_DEFINE(crires_util_plot,
82  CRIRES_PARAM_PMIN |
83  CRIRES_PARAM_PMAX |
84  CRIRES_PARAM_DISPLAY |
85  CRIRES_PARAM_WL_MODEL |
86  CRIRES_PARAM_ADJUST,
87  "Plotting tool for the CRIRES tables",
88  crires_util_plot_description) ;
89 
90 /*-----------------------------------------------------------------------------
91  Static variables
92  -----------------------------------------------------------------------------*/
93 
94 static struct {
95  /* Inputs */
96  int pmin ;
97  int pmax ;
98  int chip ;
99  int use_model ;
100  int adjust_level ;
101 } crires_util_plot_config ;
102 
103 /*-----------------------------------------------------------------------------
104  Functions code
105  -----------------------------------------------------------------------------*/
106 
107 /*----------------------------------------------------------------------------*/
114 /*----------------------------------------------------------------------------*/
115 static int crires_util_plot(
116  cpl_frameset * frameset,
117  const cpl_parameterlist * parlist)
118 {
119  const char * fname ;
120  const char * fname_opt ;
121  const char * title ;
122  const char * sval ;
123  cpl_propertylist * plist ;
124  cpl_table * tab ;
125  cpl_table * tab_opt ;
126  cpl_array * wave ;
127  cpl_array * flux ;
128  cpl_vector * wave_vec ;
129  cpl_vector * flux_vec ;
130  cpl_bivector * flux_biv ;
131  const char * wave_col ;
132  int i ;
133 
134  /* Retrieve input parameters */
135  crires_util_plot_config.pmin = crires_parameterlist_get_int(parlist,
136  RECIPE_STRING, CRIRES_PARAM_PMIN) ;
137  crires_util_plot_config.pmax = crires_parameterlist_get_int(parlist,
138  RECIPE_STRING, CRIRES_PARAM_PMAX) ;
139  crires_util_plot_config.chip = crires_parameterlist_get_int(parlist,
140  RECIPE_STRING, CRIRES_PARAM_DISPLAY) ;
141  crires_util_plot_config.use_model = crires_parameterlist_get_bool(parlist,
142  RECIPE_STRING, CRIRES_PARAM_WL_MODEL) ;
143  crires_util_plot_config.adjust_level=crires_parameterlist_get_bool(parlist,
144  RECIPE_STRING, CRIRES_PARAM_ADJUST) ;
145 
146  /* Initialise */
147  if (crires_util_plot_config.use_model)
148  wave_col = CRIRES_COL_WAVELENGTH_MODEL ;
149  else
150  wave_col = CRIRES_COL_WAVELENGTH ;
151 
152  /* Identify the RAW and CALIB frames in the input frameset */
153  if (crires_dfs_set_groups(frameset, NULL)) {
154  cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
155  return -1 ;
156  }
157 
158  /* Retrieve raw frames */
159  fname = cpl_frame_get_filename(cpl_frameset_get_position(frameset, 0)) ;
160  if (cpl_frameset_get_size(frameset) > 1) {
161  fname_opt = cpl_frame_get_filename(
162  cpl_frameset_get_position(frameset, 1)) ;
163  } else {
164  fname_opt = NULL ;
165  }
166 
167  /* CRIRES_PROTYPE_CATALOG */
168  tab = crires_load_table_check(fname, 1, CRIRES_PROTYPE_CATALOG,
169  crires_util_plot_config.pmin,
170  crires_util_plot_config.pmax,
171  crires_util_plot_config.use_model) ;
172  if (tab != NULL) {
173  plist = cpl_propertylist_load(fname, 0) ;
174  sval = crires_pfits_get_procatg(plist) ;
175  /* CRIRES_CALPRO_THAR_CAT */
176  if (!strcmp(sval, CRIRES_CALPRO_THAR_CAT))
177  title = "t 'Thorium/Argon lines' w lines" ;
178  /* CRIRES_CALPRO_N2O_CAT */
179  else if (!strcmp(sval, CRIRES_CALPRO_N2O_CAT))
180  title = "t 'N2O gas cell lines' w lines" ;
181  /* CRIRES_CALPRO_OH_CAT */
182  else if (!strcmp(sval, CRIRES_CALPRO_OH_CAT))
183  title = "t 'OH lines' w lines" ;
184  /* CRIRES_CALPRO_HITRAN_CAT */
185  else if (!strcmp(sval, CRIRES_CALPRO_HITRAN_CAT))
186  title = "t 'Hitran Spectrum' w lines" ;
187  /* Default */
188  else
189  title = "t 'signal' w lines" ;
190  cpl_propertylist_delete(plist) ;
191 
192  /* Plot */
193  cpl_plot_column(
194  "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Emission';",
195  title, "", tab, CRIRES_COL_WAVELENGTH, CRIRES_COL_EMISSION) ;
196  cpl_table_delete(tab) ;
197  }
198 
199  /* CRIRES_PROTYPE_PHO_FLUX */
200  tab = crires_load_table_check(fname, 1, CRIRES_PROTYPE_PHO_FLUX,
201  crires_util_plot_config.pmin,
202  crires_util_plot_config.pmax,
203  crires_util_plot_config.use_model) ;
204  if (tab != NULL) {
205  for (i=1 ; i<cpl_table_get_nrow(tab) ; i++) {
206  wave=cpl_array_duplicate(
207  cpl_table_get_array(tab, CRIRES_COL_PHOTOFLUX, 0));
208  wave_vec = cpl_vector_wrap(cpl_array_get_size(wave),
209  cpl_array_get_data_double(wave)) ;
210  cpl_array_unwrap(wave) ;
211  flux=cpl_array_duplicate(
212  cpl_table_get_array(tab, CRIRES_COL_PHOTOFLUX, i));
213  flux_vec = cpl_vector_wrap(cpl_array_get_size(flux),
214  cpl_array_get_data_double(flux)) ;
215  cpl_array_unwrap(flux) ;
216  flux_biv=cpl_bivector_wrap_vectors(wave_vec, flux_vec) ;
217 
218  cpl_plot_bivector(
219  "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Flux (Jy)';",
220  "t 'Photspheric flux' w lines", "", flux_biv) ;
221  cpl_bivector_delete(flux_biv) ;
222  }
223  cpl_table_delete(tab) ;
224  }
225  /* CRIRES_PROTYPE_SPEC_PIX */
226  tab = crires_load_table_check(fname, crires_util_plot_config.chip,
227  CRIRES_PROTYPE_SPEC_PIX, crires_util_plot_config.pmin,
228  crires_util_plot_config.pmax, crires_util_plot_config.use_model) ;
229  if (fname_opt != NULL) {
230  tab_opt = crires_load_table_check(fname_opt,
231  crires_util_plot_config.chip, CRIRES_PROTYPE_SPEC_PIX,
232  crires_util_plot_config.pmin, crires_util_plot_config.pmax,
233  crires_util_plot_config.use_model);
234  } else {
235  tab_opt = NULL ;
236  }
237  if (tab != NULL) {
238  crires_util_plot_spec_pix(tab, tab_opt,
239  crires_util_plot_config.adjust_level) ;
240  cpl_table_delete(tab) ;
241  if (tab_opt != NULL) cpl_table_delete(tab_opt) ;
242  }
243 
244  /* CRIRES_PROTYPE_SPEC_WL */
245  tab = crires_load_table_check(fname, crires_util_plot_config.chip,
246  CRIRES_PROTYPE_SPEC_WL, crires_util_plot_config.pmin,
247  crires_util_plot_config.pmax, crires_util_plot_config.use_model) ;
248  if (fname_opt != NULL) {
249  tab_opt = crires_load_table_check(fname_opt,
250  crires_util_plot_config.chip, CRIRES_PROTYPE_SPEC_WL,
251  crires_util_plot_config.pmin, crires_util_plot_config.pmax,
252  crires_util_plot_config.use_model);
253  } else {
254  tab_opt = NULL ;
255  }
256  if (tab != NULL) {
257  crires_util_plot_spec_wl(tab, tab_opt, wave_col,
258  crires_util_plot_config.adjust_level) ;
259  cpl_table_delete(tab) ;
260  if (tab_opt != NULL) cpl_table_delete(tab_opt) ;
261  }
262 
263  /* CRIRES_PROTYPE_XCORR */
264  tab = crires_load_table_check(fname, crires_util_plot_config.chip,
265  CRIRES_PROTYPE_XCORR,
266  crires_util_plot_config.pmin,
267  crires_util_plot_config.pmax,
268  crires_util_plot_config.use_model) ;
269  if (tab != NULL) {
270  irplib_wlxcorr_plot_spc_table(tab, "", 1, 5) ;
271  }
272 
273  /* CRIRES_PROTYPE_CONVERS */
274  tab = crires_load_table_check(fname, crires_util_plot_config.chip,
275  CRIRES_PROTYPE_CONVERS, crires_util_plot_config.pmin,
276  crires_util_plot_config.pmax, crires_util_plot_config.use_model) ;
277  if (fname_opt != NULL) {
278  tab_opt = crires_load_table_check(fname_opt,
279  crires_util_plot_config.chip, CRIRES_PROTYPE_CONVERS,
280  crires_util_plot_config.pmin, crires_util_plot_config.pmax,
281  crires_util_plot_config.use_model);
282  } else {
283  tab_opt = NULL ;
284  }
285  if (tab != NULL) {
286  crires_util_plot_convers(tab, tab_opt, wave_col,
287  crires_util_plot_config.adjust_level) ;
288  cpl_table_delete(tab) ;
289  if (tab_opt != NULL) cpl_table_delete(tab_opt) ;
290  }
291 
292  /* CRIRES_PROTYPE_SENSIT */
293  tab = crires_load_table_check(fname, crires_util_plot_config.chip,
294  CRIRES_PROTYPE_SENSIT, crires_util_plot_config.pmin,
295  crires_util_plot_config.pmax, crires_util_plot_config.use_model) ;
296  if (fname_opt != NULL) {
297  tab_opt = crires_load_table_check(fname_opt,
298  crires_util_plot_config.chip, CRIRES_PROTYPE_SENSIT,
299  crires_util_plot_config.pmin, crires_util_plot_config.pmax,
300  crires_util_plot_config.use_model);
301  } else {
302  tab_opt = NULL ;
303  }
304  if (tab != NULL) {
305  crires_util_plot_sensit(tab, tab_opt, wave_col,
306  crires_util_plot_config.adjust_level) ;
307  cpl_table_delete(tab) ;
308  if (tab_opt != NULL) cpl_table_delete(tab_opt) ;
309  }
310 
311  /* CRIRES_PROTYPE_FWHM */
312  tab = crires_load_table_check(fname, crires_util_plot_config.chip,
313  CRIRES_PROTYPE_FWHM, crires_util_plot_config.pmin,
314  crires_util_plot_config.pmax, crires_util_plot_config.use_model) ;
315  if (tab != NULL) {
316  cpl_plot_column(
317  "set grid;set xlabel 'Position (pixels)';set ylabel 'FWHM (pixels)';",
318  "t 'FWHM' w lines", "", tab,
319  CRIRES_COL_WL_DETPOSX, CRIRES_COL_FWHM) ;
320  cpl_plot_column(
321  "set grid;set xlabel 'Position (pixels)';set ylabel 'Y position (pixels)';",
322  "t 'Y position' w lines", "", tab,
323  CRIRES_COL_WL_DETPOSX, CRIRES_COL_DETPOSY) ;
324  cpl_table_delete(tab) ;
325  }
326 
327  /* Return */
328  if (cpl_error_get_code())
329  return -1 ;
330  else
331  return 0 ;
332 }
333 
334 static int crires_util_plot_diff(
335  const cpl_table * tab,
336  const char * col1,
337  const char * col2)
338 {
339  cpl_bivector * toplot ;
340  cpl_vector * vec_x ;
341  cpl_vector * vec_tmp ;
342  cpl_vector * vec_y ;
343  int nrows ;
344  double val ;
345  int i ;
346 
347  /* Check entries */
348  if (tab == NULL) return -1 ;
349  if (!cpl_table_has_column(tab, col1)) return -1 ;
350  if (!cpl_table_has_column(tab, col2)) return -1 ;
351 
352  /* Initialise */
353  nrows = cpl_table_get_nrow(tab) ;
354 
355  /* Get access */
356  vec_x = cpl_vector_wrap(nrows,
357  cpl_table_get_data_double((cpl_table*)tab, col1)) ;
358  vec_tmp = cpl_vector_wrap(nrows,
359  cpl_table_get_data_double((cpl_table*)tab, col2)) ;
360 
361  /* Compute difference */
362  vec_y = cpl_vector_duplicate(vec_x) ;
363  cpl_vector_subtract(vec_y, vec_tmp) ;
364  cpl_vector_unwrap(vec_tmp) ;
365 
366  /* Handle special case 0s */
367  for (i=0 ; i<cpl_vector_get_size(vec_y) ; i++) {
368  if (fabs(cpl_vector_get(vec_y, i)) > 100) {
369  if (i==0) val = cpl_vector_get(vec_y, 10) ;
370  else val = cpl_vector_get(vec_y, i-1) ;
371  cpl_vector_set(vec_y, i, val) ;
372  }
373  }
374 
375  toplot = cpl_bivector_wrap_vectors(vec_x, vec_y) ;
376 
377  /* Plot */
378  cpl_plot_bivector(
379  "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Wave diff (nm)';",
380  "t 'Wavelength difference XC-model' w lines", "", toplot) ;
381 
382  /* Free and return */
383  cpl_bivector_unwrap_vectors(toplot) ;
384  cpl_vector_unwrap(vec_x) ;
385  cpl_vector_delete(vec_y) ;
386 
387  return 0 ;
388 }
389 
390 static int crires_util_plot_spec_pix(
391  cpl_table * tab,
392  cpl_table * tab_opt,
393  int adjust_level)
394 {
395  /* Protect empty chips in windowing mode */
396  if (cpl_table_get_nrow(tab) == 0) {
397  return 0 ;
398  }
399 
400  /* CRIRES_COL_EXTRACT_INT_OPT */
401  crires_util_plot_spec_pix_one(tab, tab_opt, adjust_level,
402  CRIRES_COL_EXTRACT_INT_OPT,
403 "set grid;set xlabel 'Position (pixels)';set ylabel 'Intensity OPT (ADU/sec)';",
404  "t 'Extracted Spectrum OPT' w lines") ;
405 
406  /* CRIRES_COL_EXTRACT_INT_RECT */
407  crires_util_plot_spec_pix_one(tab, tab_opt, adjust_level,
408  CRIRES_COL_EXTRACT_INT_RECT,
409 "set grid;set xlabel 'Position (pixels)';set ylabel 'Intensity RECT (ADU/sec)';",
410  "t 'Extracted Spectrum RECT' w lines") ;
411 
412  /* CRIRES_COL_EXTRACT_ERR_OPT */
413  crires_util_plot_spec_pix_one(tab, tab_opt, adjust_level,
414  CRIRES_COL_EXTRACT_ERR_OPT,
415 "set grid;set xlabel 'Position (pixels)';set ylabel 'Error OPT (ADU/sec)';",
416  "t 'Error OPT' w lines") ;
417 
418  /* CRIRES_COL_EXTRACT_ERR_RECT */
419  crires_util_plot_spec_pix_one(tab, tab_opt, adjust_level,
420  CRIRES_COL_EXTRACT_ERR_RECT,
421 "set grid;set xlabel 'Position (pixels)';set ylabel 'Error RECT (ADU/sec)';",
422  "t 'Error RECT' w lines") ;
423 
424  /* CRIRES_COL_EXTRACT_WN_OPT */
425  crires_util_plot_spec_pix_one(tab, tab_opt, adjust_level,
426  CRIRES_COL_EXTRACT_WN_OPT,
427 "set grid;set xlabel 'Position (pixels)';set ylabel 'Weight Norm OPT';",
428  "t 'Weight norm OPT' w lines") ;
429 
430  /* CRIRES_COL_EXTRACT_WN_RECT */
431  crires_util_plot_spec_pix_one(tab, tab_opt, adjust_level,
432  CRIRES_COL_EXTRACT_WN_RECT,
433 "set grid;set xlabel 'position (pixels)';set ylabel 'weight norm rect';",
434  "t 'weight norm rect' w lines") ;
435 
436  /* CRIRES_COL_EXTRACT_BG_NOISE */
437  crires_util_plot_spec_pix_one(tab, tab_opt, adjust_level,
438  CRIRES_COL_EXTRACT_BG_NOISE,
439 "set grid;set xlabel 'Position (pixels)';set ylabel 'Background noise';",
440  "t 'Background noise' w lines") ;
441 
442  return 0 ;
443 }
444 
445 static int crires_util_plot_spec_pix_one(
446  cpl_table * tab,
447  cpl_table * tab_opt,
448  int adjust_level,
449  const char * y_col,
450  const char * options,
451  const char * title)
452 {
453  double mean1, mean2 ;
454  int nrows ;
455  cpl_vector ** vectors ;
456 
457  /* Check inputs */
458  if (tab == NULL) return -1 ;
459  nrows = cpl_table_get_nrow(tab) ;
460  if (tab_opt != NULL) {
461  if (cpl_table_get_nrow(tab_opt) != nrows) {
462  cpl_msg_error(__func__,
463  "The two tables must have the same number of rows") ;
464  return -1 ;
465  }
466  }
467 
468  vectors = cpl_malloc(3*sizeof(cpl_vector*)) ;
469  vectors[0] = NULL ;
470  vectors[1] = cpl_vector_wrap(nrows, cpl_table_get_data_double(tab, y_col)) ;
471  if (tab_opt != NULL) {
472  vectors[2] = cpl_vector_wrap(nrows,
473  cpl_table_get_data_double(tab_opt, y_col));
474  if (adjust_level) {
475  mean1 = cpl_vector_get_mean(vectors[1]) ;
476  mean2 = cpl_vector_get_mean(vectors[2]) ;
477  cpl_vector_multiply_scalar(vectors[2], fabs(mean1/mean2)) ;
478  }
479  cpl_plot_vectors(options, title, "", (const cpl_vector **)vectors, 3);
480  cpl_vector_unwrap(vectors[2]) ;
481  } else {
482  cpl_plot_vector(options, title, "", vectors[1]) ;
483  }
484  cpl_vector_unwrap(vectors[1]) ;
485  cpl_free(vectors) ;
486  return 0 ;
487 }
488 
489 static int crires_util_plot_spec_wl(
490  cpl_table * tab,
491  cpl_table * tab_opt,
492  const char * wave_col,
493  int adjust_level)
494 {
495  /* Protect empty chips in windowing mode */
496  if (cpl_table_get_nrow(tab) == 0) {
497  return 0 ;
498  }
499 
500  /* CRIRES_COL_EXTRACT_INT_OPT */
501  crires_util_plot_spec_wl_one(tab, tab_opt, wave_col, adjust_level,
502  CRIRES_COL_EXTRACT_INT_OPT,
503 "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Intensity OPT (ADU/sec)';",
504  "t 'Extracted Spectrum OPT' w lines") ;
505 
506  /* CRIRES_COL_EXTRACT_INT_RECT */
507  crires_util_plot_spec_wl_one(tab, tab_opt, wave_col, adjust_level,
508  CRIRES_COL_EXTRACT_INT_RECT,
509 "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Intensity RECT (ADU/sec)';",
510  "t 'Extracted Spectrum RECT' w lines") ;
511 
512  /* CRIRES_COL_EXTRACT_ERR_OPT */
513  crires_util_plot_spec_wl_one(tab, tab_opt, wave_col, adjust_level,
514  CRIRES_COL_EXTRACT_ERR_OPT,
515 "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Error OPT (ADU/sec)';",
516  "t 'Error OPT' w lines") ;
517 
518  /* CRIRES_COL_EXTRACT_ERR_RECT */
519  crires_util_plot_spec_wl_one(tab, tab_opt, wave_col, adjust_level,
520  CRIRES_COL_EXTRACT_ERR_RECT,
521 "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Error RECT (ADU/sec)';",
522  "t 'Error RECT' w lines") ;
523 
524  /* CRIRES_COL_EXTRACT_WN_OPT */
525  crires_util_plot_spec_wl_one(tab, tab_opt, wave_col, adjust_level,
526  CRIRES_COL_EXTRACT_WN_OPT,
527 "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Weight Norm OPT';",
528  "t 'Weight Norm OPT' w lines") ;
529 
530  /* CRIRES_COL_EXTRACT_WN_RECT */
531  crires_util_plot_spec_wl_one(tab, tab_opt, wave_col, adjust_level,
532  CRIRES_COL_EXTRACT_WN_RECT,
533 "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Weight Norm RECT';",
534  "t 'Weight Norm RECT' w lines") ;
535 
536  /* CRIRES_COL_EXTRACT_BG_NOISE */
537  crires_util_plot_spec_wl_one(tab, tab_opt, wave_col, adjust_level,
538  CRIRES_COL_EXTRACT_BG_NOISE,
539 "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Background noise';",
540  "t 'Background noise' w lines") ;
541 
542  /* Wavelengths difference */
543  crires_util_plot_diff(tab, CRIRES_COL_WAVELENGTH,
544  CRIRES_COL_WAVELENGTH_MODEL) ;
545 
546  return 0 ;
547 }
548 
549 static int crires_util_plot_spec_wl_one(
550  cpl_table * tab,
551  cpl_table * tab_opt,
552  const char * wave_col,
553  int adjust_level,
554  const char * y_col,
555  const char * options,
556  const char * title)
557 {
558  double mean1, mean2 ;
559  int nrows ;
560  cpl_vector ** vectors ;
561 
562  /* Check inputs */
563  if (tab == NULL) return -1 ;
564  nrows = cpl_table_get_nrow(tab) ;
565  if (tab_opt != NULL) {
566  if (cpl_table_get_nrow(tab_opt) != nrows) {
567  cpl_msg_error(__func__,
568  "The two tables must have the same number of rows") ;
569  return -1 ;
570  }
571  }
572 
573  if (tab_opt != NULL) {
574  vectors = cpl_malloc(3*sizeof(cpl_vector*)) ;
575  vectors[0]=cpl_vector_wrap(nrows,cpl_table_get_data_double(tab,
576  wave_col));
577  vectors[1] = cpl_vector_wrap(nrows,
578  cpl_table_get_data_double(tab, y_col)) ;
579  vectors[2] = cpl_vector_wrap(nrows,
580  cpl_table_get_data_double(tab_opt, y_col));
581  if (adjust_level) {
582  mean1 = cpl_vector_get_mean(vectors[1]) ;
583  mean2 = cpl_vector_get_mean(vectors[2]) ;
584  cpl_vector_multiply_scalar(vectors[2], fabs(mean1/mean2)) ;
585  }
586  cpl_plot_vectors(options, title, "", (const cpl_vector **)vectors, 3);
587  cpl_vector_unwrap(vectors[0]) ;
588  cpl_vector_unwrap(vectors[1]) ;
589  cpl_vector_unwrap(vectors[2]) ;
590  cpl_free(vectors) ;
591  } else {
592  cpl_plot_column(options, title, "", tab, wave_col, y_col) ;
593  }
594  return 0 ;
595 }
596 
597 static int crires_util_plot_convers(
598  cpl_table * tab,
599  cpl_table * tab_opt,
600  const char * wave_col,
601  int adjust_level)
602 {
603  /* Protect empty chips in windowing mode */
604  if (cpl_table_get_nrow(tab) == 0) {
605  return 0 ;
606  }
607 
608  /* Start with the same as for CRIRES_PROTYPE_SPEC_WL */
609  if (crires_util_plot_spec_wl(tab, tab_opt, wave_col, adjust_level) == -1)
610  return -1 ;
611 
612  /* CRIRES_COL_CONVERSION_OPT */
613  crires_util_plot_spec_wl_one(tab, tab_opt, wave_col, adjust_level,
614  CRIRES_COL_CONVERSION_OPT,
615 "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Conversion OPT (ADU/sec/Jy)';",
616  "t 'Conversion factor OPT' w lines") ;
617 
618  /* CRIRES_COL_CONVERSION_RECT */
619  crires_util_plot_spec_wl_one(tab, tab_opt, wave_col, adjust_level,
620  CRIRES_COL_CONVERSION_RECT,
621 "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Conversion RECT (ADU/sec/Jy)';",
622  "t 'Conversion factor RECT' w lines") ;
623 
624  /* CRIRES_COL_THROUGHPUT */
625  crires_util_plot_spec_wl_one(tab, tab_opt, wave_col, adjust_level,
626  CRIRES_COL_THROUGHPUT,
627 "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Throughput (e-/phot)';",
628  "t 'Throughput' w lines") ;
629  return 0 ;
630 }
631 
632 static int crires_util_plot_sensit(
633  cpl_table * tab,
634  cpl_table * tab_opt,
635  const char * wave_col,
636  int adjust_level)
637 {
638  /* Protect empty chips in windowing mode */
639  if (cpl_table_get_nrow(tab) == 0) {
640  return 0 ;
641  }
642 
643  /* Start with the same as for CRIRES_PROTYPE_CONVERS */
644  if (crires_util_plot_convers(tab, tab_opt, wave_col, adjust_level) == -1)
645  return -1 ;
646 
647  /* CRIRES_COL_SENSITIVITY */
648  crires_util_plot_spec_wl_one(tab, tab_opt, wave_col, adjust_level,
649  CRIRES_COL_SENSITIVITY,
650 "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Sensitivity (Jy/10sig/hour)';",
651  "t 'Sensitivity' w lines") ;
652  return 0 ;
653 }
654