CRIRES Pipeline Reference Manual 2.3.19
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
53static int crires_model_refine_save(cpl_table *, const cpl_parameterlist *,
54 cpl_frameset *) ;
55
56static 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
66CRIRES_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
79static 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/*----------------------------------------------------------------------------*/
108static 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/*----------------------------------------------------------------------------*/
507static 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