CRIRES Pipeline Reference Manual  2.3.15
crires_model_refine.c
1 /* $Id: crires_model_refine.c,v 1.55 2012-01-16 10:09:55 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-01-16 10:09:55 $
24  * $Revision: 1.55 $
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_spectrum.h"
39 
40 #include "crires_model_refining.h"
41 #include "crires_model_kernel.h"
42 
43 /*-----------------------------------------------------------------------------
44  Define
45  -----------------------------------------------------------------------------*/
46 
47 #define RECIPE_STRING "crires_model_refine"
48 
49 /*-----------------------------------------------------------------------------
50  Functions prototypes
51  -----------------------------------------------------------------------------*/
52 
53 static int crires_model_refine_save(cpl_table *, const cpl_parameterlist *,
54  cpl_frameset *) ;
55 
56 static char crires_model_refine_description[] =
57 "crires_model_refine -- Model refining recipe\n"
58 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
59 "raw-file.fits "CRIRES_MODEL_REFINE_RAW" or\n"
60 "THAR-file.fits "CRIRES_CALPRO_THAR_CAT" or\n"
61 "bpm-file.fits "CRIRES_CALPRO_BPM" or\n"
62 "flat-file.fits "CRIRES_CALPRO_FLAT" or\n"
63 "detlin-file.fits "CRIRES_CALPRO_COEFFS_CUBE" or\n"
64 "config-file.fits "CRIRES_CALPRO_MODEL_REFINE_CONF".\n" ;
65 
66 CRIRES_RECIPE_DEFINE(crires_model_refine,
67  CRIRES_PARAM_DISPLAY |
68  CRIRES_PARAM_FWHM |
69  CRIRES_PARAM_SIGMA |
70  CRIRES_PARAM_SEARCH_BOX |
71  CRIRES_PARAM_MIN_MATCH,
72  "Model Refining recipe",
73  crires_model_refine_description) ;
74 
75 /*-----------------------------------------------------------------------------
76  Static variables
77  -----------------------------------------------------------------------------*/
78 
79 static struct {
80  /* Inputs */
81  int display ;
82  int search_box_sz ;
83  int min_matches_nb ;
84  int fwhm ;
85  double sigma ;
86  /* Outputs */
87  crires_illum_period period ;
88  double penc_co1 ;
89  double genc_co1 ;
90  double sg ;
91  double fk ;
92  double cam_dis ;
93  double slity ;
94 } crires_model_refine_config ;
95 
96 /*-----------------------------------------------------------------------------
97  Functions code
98  -----------------------------------------------------------------------------*/
99 
100 /*----------------------------------------------------------------------------*/
107 /*----------------------------------------------------------------------------*/
108 static int crires_model_refine(
109  cpl_frameset * frameset,
110  const cpl_parameterlist * parlist)
111 {
112  cpl_frameset * rawframes ;
113  const char * config ;
114  const char * thar ;
115  const char * bpm ;
116  const char * flat ;
117  const char * detlin ;
118  const char * ref_fname=NULL ;
119  cpl_frame * ref_frame ;
120  cpl_vector ** traces ;
121  double * ptrace ;
122  double ** cust_lines=NULL;
123  cpl_imagelist * ilist ;
124  cpl_vector * extracted[CRIRES_NB_DETECTORS] ;
125  cpl_vector * bright_lines[CRIRES_NB_DETECTORS] ;
126  cpl_table * new_conf ;
127  int nframes;
128  int i, j, k;
129 
130  double y_pos_mm=-50;
131  int coord_cnt=0;
132  double ** temp_coord;
133  coord msp_coord[400];
134  int ph, cust_lines_flag;
135  int nph=7;
136  double y_pos_pix=0.0;
137  FILE* scan_out;
138 
139  /* The Model is switched off */
140  if (crires_model_off()) {
141  return 0 ;
142  }
143 
144  /* Initialise */
145  rawframes = NULL ;
146  crires_model_refine_config.penc_co1 = -1.0 ;
147  crires_model_refine_config.genc_co1 = -1.0 ;
148  crires_model_refine_config.sg = -1.0 ;
149  crires_model_refine_config.fk = -1.0 ;
150  crires_model_refine_config.cam_dis = -1.0 ;
151  crires_model_refine_config.slity = -1.0 ;
152 
153  /* Retrieve input parameters */
154  crires_model_refine_config.display = crires_parameterlist_get_int(parlist,
155  RECIPE_STRING, CRIRES_PARAM_DISPLAY) ;
156  crires_model_refine_config.fwhm = crires_parameterlist_get_int(parlist,
157  RECIPE_STRING, CRIRES_PARAM_FWHM) ;
158  crires_model_refine_config.sigma = crires_parameterlist_get_double(parlist,
159  RECIPE_STRING, CRIRES_PARAM_SIGMA) ;
160  crires_model_refine_config.search_box_sz = crires_parameterlist_get_int(
161  parlist, RECIPE_STRING, CRIRES_PARAM_SEARCH_BOX) ;
162  crires_model_refine_config.min_matches_nb = crires_parameterlist_get_int(
163  parlist, RECIPE_STRING, CRIRES_PARAM_MIN_MATCH) ;
164 
165  /* Identify the RAW and CALIB frames in the input frameset */
166  if (crires_dfs_set_groups(frameset, "crires_model_refine")) {
167  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
168  cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
169  return -1 ;
170  }
171 
172  /* Retrieve calibration data */
173  config = crires_extract_filename(frameset, CRIRES_CALPRO_MODEL_REFINE_CONF);
174  if (config == NULL) {
175  cpl_msg_error(__func__, "Model configuration file is missing") ;
176  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
177  return -1 ;
178  }
179  thar = crires_extract_filename(frameset, CRIRES_CALPRO_THAR_CAT) ;
180  if (thar == NULL) {
181  cpl_msg_error(__func__, "Lines catalog file is missing") ;
182  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
183  return -1 ;
184  }
185  bpm = crires_extract_filename(frameset, CRIRES_CALPRO_BPM) ;
186  flat = crires_extract_filename(frameset, CRIRES_CALPRO_FLAT) ;
187  detlin = crires_extract_filename(frameset, CRIRES_CALPRO_COEFFS_CUBE) ;
188 
189  /* Retrieve raw frames */
190  if ((rawframes = crires_extract_frameset(frameset,
191  CRIRES_MODEL_REFINE_RAW)) == NULL) {
192  cpl_msg_error(__func__, "No raw frame in input") ;
193  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
194  return -1 ;
195  }
196  nframes = cpl_frameset_get_size(rawframes) ;
197 
198  /* Get the detector illumination period */
199  crires_model_refine_config.period =
200  crires_get_detector_illum_period(
201  cpl_frame_get_filename(cpl_frameset_get_position(rawframes, 0))) ;
202  if (crires_model_refine_config.period == CRIRES_ILLUM_UNKNOWN) {
203  cpl_msg_error(__func__,
204  "Cannot determine the detector illumination period") ;
205  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
206  cpl_frameset_delete(rawframes) ;
207  return -1 ;
208  } else {
209  crires_display_detector_illum(crires_model_refine_config.period) ;
210  }
211 
212  /* Check the number of input frames */
213  if (nframes != 1 && nframes != 3) {
214  cpl_msg_error(__func__, "1 or 3 raw frames expected in input") ;
215  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
216  return -1 ;
217  }
218 
219  /* Loop on the input frames */
220  for (k=0 ; k<nframes ; k++) {
221  /* Get the reference frame */
222  ref_frame = cpl_frameset_get_position(rawframes, k) ;
223  ref_fname = cpl_frame_get_filename(ref_frame) ;
224 
225  if (crires_model_config_check(config,ref_fname)!=0) {
226  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
227  cpl_msg_error(__func__,
228  "Invalid physical model configuration file") ;
229  cpl_frameset_delete(rawframes) ;
230  return -1;
231  }
232 
233  cust_lines_flag=0;
234  for (ph=1;ph<=nph;ph++) {
235  y_pos_pix=-(float)(ph);
236  cpl_msg_info(__func__,"Raw frame %d, fibre position %d",k+1,ph);
237  /* Get the shape of the spectrum at the detector y posn specified */
238  cpl_msg_info(__func__, "Get the shape of the spectra") ;
239  if ((traces = crires_model_profile(ref_fname,
240  config,
241  -1,
242  y_pos_pix)) != NULL) {
243  /* Clean the traces */
244  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
245  ptrace = cpl_vector_get_data(traces[i]) ;
246  for (j=0 ; j<cpl_vector_get_size(traces[i]) ; j++) {
247  if (ptrace[j] == 0.0)
248  ptrace[j] = cpl_vector_get_mean(traces[i]) ;
249  }
250  }
251 
252  /* Plot the shapes if requested */
253  if (crires_model_refine_config.display>0 &&
254  crires_model_refine_config.display <= CRIRES_NB_DETECTORS) {
255  cpl_plot_vector("set grid;set xlabel 'Position (pixels)';set ylabel 'Position (pixels)';",
256  "t 'Spectrum shape' w lines", "", traces[crires_model_refine_config.display-1]);
257  }
258 
259  /* Load the input images */
260  cpl_msg_info(__func__, "Load the data") ;
261  ilist = crires_load_file(ref_fname,
262  crires_model_refine_config.period, CPL_TYPE_FLOAT) ;
263  if (ilist == NULL) {
264  cpl_msg_error(__func__, "Cannot load the data") ;
265  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
266  cpl_frameset_delete(rawframes) ;
267  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
268  cpl_vector_delete(traces[i]) ;
269  cpl_free(traces) ;
270  return -1 ;
271  }
272 
273  /* Customise the line list */
274  if (cust_lines_flag==0) {
275  cpl_msg_info(__func__, "Customising the line list") ;
276  cpl_msg_indent_more() ;
277  if ((cust_lines=crires_model_refining_custom_lines(thar,
278  crires_model_refine_config.search_box_sz,
279  ref_fname, config, NULL))==NULL) {
280  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
281  cpl_vector_delete(traces[i]) ;
282  cpl_free(traces) ;
283  cpl_imagelist_delete(ilist) ;
284  cpl_frameset_delete(rawframes) ;
285  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
286  cpl_msg_error(__func__, "Cannot customise the line list");
287  return -1;
288  }
289  else {
290  cust_lines_flag=1;
291  }
292  }
293  cpl_msg_indent_less() ;
294 
295  /* Update the cust_lines list to have the correct predicted
296  detector x,y for the current pinhole*/
297  cust_lines=crires_model_refining_fibrefix(cust_lines,ref_fname,config,ph);
298 
299  /* Loop on detectors */
300  cpl_msg_indent_more() ;
301  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
302  cpl_msg_info(__func__, "Reduce the chip number %d", i+1) ;
303  /* Extract the spectrum using the shape */
304  cpl_msg_info(__func__, "Extract spectrum") ;
305  cpl_msg_indent_more() ;
306  if ((extracted[i]=crires_model_refining_extract(cpl_imagelist_get(ilist, i),
307  crires_model_refine_config.period,
308  traces[i], bpm, flat, detlin, i+1)) == NULL) {
309  cpl_msg_error(__func__, "Cannot extract spectrum");
310  cpl_frameset_delete(rawframes) ;
311  for (j=0 ;j<CRIRES_NB_DETECTORS; j++)
312  cpl_vector_delete(traces[j]) ;
313  cpl_free(traces) ;
314  cpl_imagelist_delete(ilist) ;
315  for (j=0 ; j<i ; j++) cpl_vector_delete(extracted[j]) ;
316  if ((crires_model_free2Darray(cust_lines,6))!=0) {
317  cpl_msg_error(__func__, "Cannot free 2D array");
318  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
319  return -1;
320  }
321  cpl_msg_indent_less() ;
322  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
323  return -1 ;
324  }
325  cpl_msg_indent_less() ;
326 
327  /* Display if requested */
328  if (crires_model_refine_config.display == i+1) {
329  cpl_plot_vector("set grid;set xlabel 'Position (pixels)';set ylabel 'Intensity (ADU)';",
330  "t 'Extracted spectrum' w lines", "", extracted[i]);
331  }
332 
333  /* Detect the brightest lines */
334  cpl_msg_info(__func__, "Detect the brightest lines") ;
335  cpl_msg_indent_more() ;
336  if ((bright_lines[i] = irplib_spectrum_detect_peaks(extracted[i],
337  crires_model_refine_config.fwhm,
338  crires_model_refine_config.sigma,
339  crires_model_refine_config.display==i+1,
340  NULL, NULL)) == NULL) {
341  cpl_msg_warning(__func__, "Cannot detect lines");
342  }
343 /* for (pp=0;pp<cpl_vector_get_size(bright_lines[i]);pp++){ */
344 /* printf("%lf %d %lf %d %lf %d %lf\n", */
345 /* cpl_vector_get(bright_lines[i],pp), */
346 /* (int)(cpl_vector_get(bright_lines[i],pp)-0.5)-1, */
347 /* cpl_vector_get(extracted[i],(int)(cpl_vector_get(bright_lines[i],pp)-0.5)-1), */
348 /* (int)(cpl_vector_get(bright_lines[i],pp)-0.5), */
349 /* cpl_vector_get(extracted[i],(int)(cpl_vector_get(bright_lines[i],pp)-0.5)), */
350 /* (int)(cpl_vector_get(bright_lines[i],pp)-0.5)+1, */
351 /* cpl_vector_get(extracted[i],(int)(cpl_vector_get(bright_lines[i],pp)-0.5)+1)); */
352 /* totflux=0.0; */
353 /* moment=0.0; */
354 /* for (qq=-3;qq<4;qq++) { */
355 /* flux=cpl_vector_get(extracted[i],(int)(cpl_vector_get(bright_lines[i],pp))+qq); */
356 /* if (flux>0.0) { */
357 /* moment+=(float)(qq)*flux; */
358 /* totflux+=flux; */
359 /* } */
360 /* } */
361 /* cpl_vector_set(bright_lines[i],pp,(float)((int)(cpl_vector_get(bright_lines[i],pp)))+(moment/totflux)); */
362 /* printf("%d %lf %lf \n",pp, cpl_vector_get(bright_lines[i],pp),moment/totflux); */
363 /* } */
364  cpl_msg_indent_less() ;
365  }
366  cpl_imagelist_delete(ilist) ;
367  for (j=0 ; j<CRIRES_NB_DETECTORS; j++)
368  cpl_vector_delete(extracted[j]) ;
369 
370  /* Match with the catalog */
371  cpl_msg_info(__func__, "Match with the catalog") ;
372  cpl_msg_indent_more() ;
373  if ((temp_coord=crires_model_refining_match((const cpl_vector **)bright_lines,
374  (const cpl_vector **)traces,
375  cust_lines,
376  crires_model_refine_config.search_box_sz,
377  crires_model_refine_config.min_matches_nb,
378  ref_fname)) == NULL) {
379  if (nph==1) {
380  cpl_msg_error(__func__, "Cannot match %s with catalog",
381  ref_fname);
382  cpl_frameset_delete(rawframes) ;
383  for (j=0 ;j<CRIRES_NB_DETECTORS; j++)
384  cpl_vector_delete(traces[j]) ;
385  cpl_free(traces) ;
386  for (j=0 ; j<CRIRES_NB_DETECTORS; j++)
387  if (bright_lines[j] != NULL)
388  cpl_vector_delete(bright_lines[j]) ;
389  if ((crires_model_free2Darray(cust_lines,6))!=0) {
390  cpl_msg_error(__func__, "Cannot free 2D array");
391  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
392  return -1;
393  }
394  cpl_msg_indent_less() ;
395  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
396  return -1 ;
397  } else {
398  cpl_msg_warning(__func__, "Cannot match lines for fibre %d on raw frame %d", ph, k);
399  }
400  }
401  cpl_msg_indent_less() ;
402  for (j=0 ; j<CRIRES_NB_DETECTORS; j++)
403  if (bright_lines[j] != NULL)
404  cpl_vector_delete(bright_lines[j]) ;
405  if (temp_coord!=NULL) {
406  i=0;
407  while (temp_coord[0][i]!=0.0) {
408  msp_coord[coord_cnt].wave=temp_coord[0][i];
409  msp_coord[coord_cnt].x=temp_coord[1][i];
410  msp_coord[coord_cnt].flux=temp_coord[2][i];
411  msp_coord[coord_cnt].chip=(int)(temp_coord[3][i]);
412  msp_coord[coord_cnt].mode=(int)(temp_coord[4][i]);
413  msp_coord[coord_cnt].y=temp_coord[5][i];
414  msp_coord[coord_cnt].penc=(int)(temp_coord[6][i]);
415  msp_coord[coord_cnt].genc=(int)(temp_coord[7][i]);
416  msp_coord[coord_cnt].slit_pos=ph;
417  msp_coord[coord_cnt].counter=(int)(temp_coord[9][i]);
418  msp_coord[coord_cnt].slitw=temp_coord[10][i];
419  coord_cnt++;
420  i++;
421  }
422  if ((crires_model_free2Darray(temp_coord,11))!=0) {
423  cpl_msg_error(__func__, "Cannot free 2D array");
424  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
425  return -1;
426  }
427  y_pos_mm=cpl_vector_get(traces[2],1024);
428  } /*end of match check*/
429  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
430  cpl_vector_delete(traces[i]) ;
431  cpl_free(traces);
432  cpl_msg_indent_less() ;
433  } /*end of trace check*/
434  else {
435  cpl_msg_warning(__func__, "Cannot get the spectrum trace") ;
436  }
437 
438  } /*end of ph loop*/
439  if ((crires_model_free2Darray(cust_lines,6))!=0) {
440  cpl_msg_error(__func__, "Cannot free 2D array");
441  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
442  return -1;
443  }
444  } /*end of ds loop*/
445 
446  // TEMP SCAN OUTPUT
447  if (cal_flag==1) {
448  scan_out=fopen("coord_scan.dat","a+");
449  for (i=0;i<coord_cnt;i++) {
450  fprintf(scan_out,"%d %lf %lf %d %lf %d %lf %d %d %d %lf\n",i,
451  msp_coord[i].y,
452  msp_coord[i].x,
453  msp_coord[i].chip,
454  msp_coord[i].flux,
455  msp_coord[i].slit_pos,
456  msp_coord[i].wave*1000000.0,
457  -msp_coord[i].mode,
458  msp_coord[i].penc,
459  msp_coord[i].genc,
460  msp_coord[i].slitw);
461  }
462  fclose(scan_out);
463  }
464 
465  cpl_msg_info(__func__, "slit position in mm: %lf",y_pos_mm);
466  /* Compute the new configuration file */
467  cpl_msg_info(__func__, "Compute the new configuration file") ;
468  cpl_msg_indent_more() ;
469  if ((new_conf = crires_model_refining_anneal(msp_coord,
470  coord_cnt,
471  y_pos_mm,
472  ref_fname,
473  config)) == NULL) {
474  cpl_msg_error(__func__, "Cannot compute the new configuration file");
475  cpl_msg_indent_less() ;
476  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
477  return -1;
478  }
479  cpl_msg_indent_less() ;
480  cpl_frameset_delete(rawframes) ;
481 
482  /* Save the new configuration file */
483  cpl_msg_info(__func__, "Save the new configuration file") ;
484  if (crires_model_refine_save(new_conf, parlist, frameset) == -1) {
485  cpl_msg_error(__func__, "Cannot save the product");
486  cpl_table_delete(new_conf) ;
487  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
488  return -1 ;
489  }
490  cpl_table_delete(new_conf) ;
491 
492  /* Return */
493  if (cpl_error_get_code()) return -1 ;
494  else return 0 ;
495 }
496 
497 
498 /*----------------------------------------------------------------------------*/
506 /*----------------------------------------------------------------------------*/
507 static int crires_model_refine_save(
508  cpl_table * out_table,
509  const cpl_parameterlist * parlist,
510  cpl_frameset * set)
511 {
512  cpl_propertylist * plist ;
513  const char * recipe_name = "crires_model_refine" ;
514 
515  plist = cpl_propertylist_new();
516  cpl_propertylist_append_string(plist, "INSTRUME", "CRIRES") ;
517  cpl_propertylist_append_string(plist, CPL_DFS_PRO_CATG,
518  CRIRES_CALPRO_MODEL_CONFIG) ;
519  cpl_propertylist_append_string(plist, CPL_DFS_PRO_TYPE,
520  CRIRES_PROTYPE_MOD_CONF) ;
521 
522 
523  /* Save */
524  if (cpl_dfs_save_table(set, NULL, parlist, set, NULL, out_table,
525  NULL, recipe_name, plist, NULL, PACKAGE "/" PACKAGE_VERSION,
526  "crires_model_refine.fits") != CPL_ERROR_NONE) {
527  cpl_msg_error(__func__, "Cannot save the table") ;
528  return -1 ;
529  }
530 
531  /* Return */
532  cpl_propertylist_delete(plist) ;
533  return 0 ;
534 }
535