36 #include "crires_recipe.h"
38 #include "irplib_spectrum.h"
40 #include "crires_model_refining.h"
41 #include "crires_model_kernel.h"
47 #define RECIPE_STRING "crires_model_refine"
53 static int crires_model_refine_save(cpl_table *,
const cpl_parameterlist *,
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" ;
66 CRIRES_RECIPE_DEFINE(crires_model_refine,
67 CRIRES_PARAM_DISPLAY |
70 CRIRES_PARAM_SEARCH_BOX |
71 CRIRES_PARAM_MIN_MATCH,
72 "Model Refining recipe",
73 crires_model_refine_description) ;
87 crires_illum_period period ;
94 } crires_model_refine_config ;
108 static int crires_model_refine(
109 cpl_frameset * frameset,
110 const cpl_parameterlist * parlist)
112 cpl_frameset * rawframes ;
113 const char * config ;
117 const char * detlin ;
118 const char * ref_fname=NULL ;
119 cpl_frame * ref_frame ;
120 cpl_vector ** traces ;
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 ;
132 double ** temp_coord;
133 coord msp_coord[400];
134 int ph, cust_lines_flag;
136 double y_pos_pix=0.0;
140 if (crires_model_off()) {
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 ;
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) ;
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") ;
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) ;
179 thar = crires_extract_filename(frameset, CRIRES_CALPRO_THAR_CAT) ;
181 cpl_msg_error(__func__,
"Lines catalog file is missing") ;
182 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
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) ;
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) ;
196 nframes = cpl_frameset_get_size(rawframes) ;
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) ;
209 crires_display_detector_illum(crires_model_refine_config.period) ;
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) ;
220 for (k=0 ; k<nframes ; k++) {
222 ref_frame = cpl_frameset_get_position(rawframes, k) ;
223 ref_fname = cpl_frame_get_filename(ref_frame) ;
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) ;
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);
238 cpl_msg_info(__func__,
"Get the shape of the spectra") ;
239 if ((traces = crires_model_profile(ref_fname,
242 y_pos_pix)) != NULL) {
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]) ;
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]);
260 cpl_msg_info(__func__,
"Load the data") ;
261 ilist = crires_load_file(ref_fname,
262 crires_model_refine_config.period, CPL_TYPE_FLOAT) ;
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]) ;
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]) ;
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");
293 cpl_msg_indent_less() ;
297 cust_lines=crires_model_refining_fibrefix(cust_lines,ref_fname,config,ph);
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) ;
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]) ;
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) ;
321 cpl_msg_indent_less() ;
322 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
325 cpl_msg_indent_less() ;
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]);
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");
364 cpl_msg_indent_less() ;
366 cpl_imagelist_delete(ilist) ;
367 for (j=0 ; j<CRIRES_NB_DETECTORS; j++)
368 cpl_vector_delete(extracted[j]) ;
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,
376 crires_model_refine_config.search_box_sz,
377 crires_model_refine_config.min_matches_nb,
378 ref_fname)) == NULL) {
380 cpl_msg_error(__func__,
"Cannot match %s with catalog",
382 cpl_frameset_delete(rawframes) ;
383 for (j=0 ;j<CRIRES_NB_DETECTORS; j++)
384 cpl_vector_delete(traces[j]) ;
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) ;
394 cpl_msg_indent_less() ;
395 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
398 cpl_msg_warning(__func__,
"Cannot match lines for fibre %d on raw frame %d", ph, k);
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) {
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];
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) ;
427 y_pos_mm=cpl_vector_get(traces[2],1024);
429 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
430 cpl_vector_delete(traces[i]) ;
432 cpl_msg_indent_less() ;
435 cpl_msg_warning(__func__,
"Cannot get the spectrum trace") ;
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) ;
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,
455 msp_coord[i].slit_pos,
456 msp_coord[i].wave*1000000.0,
465 cpl_msg_info(__func__,
"slit position in mm: %lf",y_pos_mm);
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,
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) ;
479 cpl_msg_indent_less() ;
480 cpl_frameset_delete(rawframes) ;
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) ;
490 cpl_table_delete(new_conf) ;
493 if (cpl_error_get_code())
return -1 ;
507 static int crires_model_refine_save(
508 cpl_table * out_table,
509 const cpl_parameterlist * parlist,
512 cpl_propertylist * plist ;
513 const char * recipe_name =
"crires_model_refine" ;
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) ;
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") ;
532 cpl_propertylist_delete(plist) ;