00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #include "crires_recipe.h"
00037
00038 #include "irplib_spectrum.h"
00039
00040 #include "crires_model_refining.h"
00041 #include "crires_model_kernel.h"
00042
00043
00044
00045
00046
00047 #define RECIPE_STRING "crires_model_refine"
00048
00049
00050
00051
00052
00053 static int crires_model_refine_save(cpl_table *, const cpl_parameterlist *,
00054 cpl_frameset *) ;
00055
00056 static char crires_model_refine_description[] =
00057 "crires_model_refine -- Model refining recipe\n"
00058 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00059 "raw-file.fits "CRIRES_MODEL_REFINE_RAW" or\n"
00060 "THAR-file.fits "CRIRES_CALPRO_THAR_CAT" or\n"
00061 "bpm-file.fits "CRIRES_CALPRO_BPM" or\n"
00062 "flat-file.fits "CRIRES_CALPRO_FLAT" or\n"
00063 "detlin-file.fits "CRIRES_CALPRO_COEFFS_CUBE" or\n"
00064 "config-file.fits "CRIRES_CALPRO_MODEL_REFINE_CONF".\n" ;
00065
00066 CRIRES_RECIPE_DEFINE(crires_model_refine,
00067 CRIRES_PARAM_DISPLAY |
00068 CRIRES_PARAM_FWHM |
00069 CRIRES_PARAM_SIGMA |
00070 CRIRES_PARAM_SEARCH_BOX |
00071 CRIRES_PARAM_MIN_MATCH,
00072 "Model Refining recipe",
00073 crires_model_refine_description) ;
00074
00075
00076
00077
00078
00079 static struct {
00080
00081 int display ;
00082 int search_box_sz ;
00083 int min_matches_nb ;
00084 int fwhm ;
00085 double sigma ;
00086
00087 crires_illum_period period ;
00088 double penc_co1 ;
00089 double genc_co1 ;
00090 double sg ;
00091 double fk ;
00092 double cam_dis ;
00093 double slity ;
00094 } crires_model_refine_config ;
00095
00096
00097
00098
00099
00100
00107
00108 static int crires_model_refine(
00109 cpl_frameset * frameset,
00110 const cpl_parameterlist * parlist)
00111 {
00112 cpl_frameset * rawframes ;
00113 const char * config ;
00114 const char * thar ;
00115 const char * bpm ;
00116 const char * flat ;
00117 const char * detlin ;
00118 const char * ref_fname=NULL ;
00119 cpl_frame * ref_frame ;
00120 cpl_vector ** traces ;
00121 double * ptrace ;
00122 double ** cust_lines=NULL;
00123 cpl_imagelist * ilist ;
00124 cpl_vector * extracted[CRIRES_NB_DETECTORS] ;
00125 cpl_vector * bright_lines[CRIRES_NB_DETECTORS] ;
00126 cpl_table * new_conf ;
00127 int nframes;
00128 int i, j, k;
00129
00130 double y_pos_mm=-50;
00131 int coord_cnt=0;
00132 double ** temp_coord;
00133 coord msp_coord[400];
00134 int ph, cust_lines_flag;
00135 int nph=7;
00136 double y_pos_pix=0.0;
00137 FILE* scan_out;
00138
00139
00140 if (crires_model_off()) {
00141 return 0 ;
00142 }
00143
00144
00145 rawframes = NULL ;
00146 crires_model_refine_config.penc_co1 = -1.0 ;
00147 crires_model_refine_config.genc_co1 = -1.0 ;
00148 crires_model_refine_config.sg = -1.0 ;
00149 crires_model_refine_config.fk = -1.0 ;
00150 crires_model_refine_config.cam_dis = -1.0 ;
00151 crires_model_refine_config.slity = -1.0 ;
00152
00153
00154 crires_model_refine_config.display = crires_parameterlist_get_int(parlist,
00155 RECIPE_STRING, CRIRES_PARAM_DISPLAY) ;
00156 crires_model_refine_config.fwhm = crires_parameterlist_get_int(parlist,
00157 RECIPE_STRING, CRIRES_PARAM_FWHM) ;
00158 crires_model_refine_config.sigma = crires_parameterlist_get_double(parlist,
00159 RECIPE_STRING, CRIRES_PARAM_SIGMA) ;
00160 crires_model_refine_config.search_box_sz = crires_parameterlist_get_int(
00161 parlist, RECIPE_STRING, CRIRES_PARAM_SEARCH_BOX) ;
00162 crires_model_refine_config.min_matches_nb = crires_parameterlist_get_int(
00163 parlist, RECIPE_STRING, CRIRES_PARAM_MIN_MATCH) ;
00164
00165
00166 if (crires_dfs_set_groups(frameset, "crires_model_refine")) {
00167 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00168 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00169 return -1 ;
00170 }
00171
00172
00173 config = crires_extract_filename(frameset, CRIRES_CALPRO_MODEL_REFINE_CONF);
00174 if (config == NULL) {
00175 cpl_msg_error(__func__, "Model configuration file is missing") ;
00176 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00177 return -1 ;
00178 }
00179 thar = crires_extract_filename(frameset, CRIRES_CALPRO_THAR_CAT) ;
00180 if (thar == NULL) {
00181 cpl_msg_error(__func__, "Lines catalog file is missing") ;
00182 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00183 return -1 ;
00184 }
00185 bpm = crires_extract_filename(frameset, CRIRES_CALPRO_BPM) ;
00186 flat = crires_extract_filename(frameset, CRIRES_CALPRO_FLAT) ;
00187 detlin = crires_extract_filename(frameset, CRIRES_CALPRO_COEFFS_CUBE) ;
00188
00189
00190 if ((rawframes = crires_extract_frameset(frameset,
00191 CRIRES_MODEL_REFINE_RAW)) == NULL) {
00192 cpl_msg_error(__func__, "No raw frame in input") ;
00193 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00194 return -1 ;
00195 }
00196 nframes = cpl_frameset_get_size(rawframes) ;
00197
00198
00199 crires_model_refine_config.period =
00200 crires_get_detector_illum_period(
00201 cpl_frame_get_filename(cpl_frameset_get_frame(rawframes, 0))) ;
00202 if (crires_model_refine_config.period == CRIRES_ILLUM_UNKNOWN) {
00203 cpl_msg_error(__func__,
00204 "Cannot determine the detector illumination period") ;
00205 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00206 cpl_frameset_delete(rawframes) ;
00207 return -1 ;
00208 } else {
00209 crires_display_detector_illum(crires_model_refine_config.period) ;
00210 }
00211
00212
00213 if (nframes != 1 && nframes != 3) {
00214 cpl_msg_error(__func__, "1 or 3 raw frames expected in input") ;
00215 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00216 return -1 ;
00217 }
00218
00219
00220 for (k=0 ; k<nframes ; k++) {
00221
00222 ref_frame = cpl_frameset_get_frame(rawframes, k) ;
00223 ref_fname = cpl_frame_get_filename(ref_frame) ;
00224
00225 if (crires_model_config_check(config,ref_fname)!=0) {
00226 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00227 cpl_msg_error(__func__,
00228 "Invalid physical model configuration file") ;
00229 cpl_frameset_delete(rawframes) ;
00230 return -1;
00231 }
00232
00233 cust_lines_flag=0;
00234 for (ph=1;ph<=nph;ph++) {
00235 y_pos_pix=-(float)(ph);
00236 cpl_msg_info(__func__,"Raw frame %d, fibre position %d",k+1,ph);
00237
00238 cpl_msg_info(__func__, "Get the shape of the spectra") ;
00239 if ((traces = crires_model_profile(ref_fname,
00240 config,
00241 -1,
00242 y_pos_pix)) != NULL) {
00243
00244 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00245 ptrace = cpl_vector_get_data(traces[i]) ;
00246 for (j=0 ; j<cpl_vector_get_size(traces[i]) ; j++) {
00247 if (ptrace[j] == 0.0)
00248 ptrace[j] = cpl_vector_get_mean(traces[i]) ;
00249 }
00250 }
00251
00252
00253 if (crires_model_refine_config.display>0 &&
00254 crires_model_refine_config.display <= CRIRES_NB_DETECTORS) {
00255 cpl_plot_vector("set grid;set xlabel 'Position (pixels)';set ylabel 'Position (pixels)';",
00256 "t 'Spectrum shape' w lines", "", traces[crires_model_refine_config.display-1]);
00257 }
00258
00259
00260 cpl_msg_info(__func__, "Load the data") ;
00261 ilist = crires_load_file(ref_fname,
00262 crires_model_refine_config.period, CPL_TYPE_FLOAT) ;
00263 if (ilist == NULL) {
00264 cpl_msg_error(__func__, "Cannot load the data") ;
00265 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00266 cpl_frameset_delete(rawframes) ;
00267 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
00268 cpl_vector_delete(traces[i]) ;
00269 cpl_free(traces) ;
00270 return -1 ;
00271 }
00272
00273
00274 if (cust_lines_flag==0) {
00275 cpl_msg_info(__func__, "Customising the line list") ;
00276 cpl_msg_indent_more() ;
00277 if ((cust_lines=crires_model_refining_custom_lines(thar,
00278 crires_model_refine_config.search_box_sz,
00279 ref_fname, config, NULL))==NULL) {
00280 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
00281 cpl_vector_delete(traces[i]) ;
00282 cpl_free(traces) ;
00283 cpl_imagelist_delete(ilist) ;
00284 cpl_frameset_delete(rawframes) ;
00285 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00286 cpl_msg_error(__func__, "Cannot customise the line list");
00287 return -1;
00288 }
00289 else {
00290 cust_lines_flag=1;
00291 }
00292 }
00293 cpl_msg_indent_less() ;
00294
00295
00296
00297 cust_lines=crires_model_refining_fibrefix(cust_lines,ref_fname,config,ph);
00298
00299
00300 cpl_msg_indent_more() ;
00301 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00302 cpl_msg_info(__func__, "Reduce the chip number %d", i+1) ;
00303
00304 cpl_msg_info(__func__, "Extract spectrum") ;
00305 cpl_msg_indent_more() ;
00306 if ((extracted[i]=crires_model_refining_extract(cpl_imagelist_get(ilist, i),
00307 crires_model_refine_config.period,
00308 traces[i], bpm, flat, detlin, i+1)) == NULL) {
00309 cpl_msg_error(__func__, "Cannot extract spectrum");
00310 cpl_frameset_delete(rawframes) ;
00311 for (j=0 ;j<CRIRES_NB_DETECTORS; j++)
00312 cpl_vector_delete(traces[j]) ;
00313 cpl_free(traces) ;
00314 cpl_imagelist_delete(ilist) ;
00315 for (j=0 ; j<i ; j++) cpl_vector_delete(extracted[j]) ;
00316 if ((crires_model_free2Darray(cust_lines,6))!=0) {
00317 cpl_msg_error(__func__, "Cannot free 2D array");
00318 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00319 return -1;
00320 }
00321 cpl_msg_indent_less() ;
00322 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00323 return -1 ;
00324 }
00325 cpl_msg_indent_less() ;
00326
00327
00328 if (crires_model_refine_config.display == i+1) {
00329 cpl_plot_vector("set grid;set xlabel 'Position (pixels)';set ylabel 'Intensity (ADU)';",
00330 "t 'Extracted spectrum' w lines", "", extracted[i]);
00331 }
00332
00333
00334 cpl_msg_info(__func__, "Detect the brightest lines") ;
00335 cpl_msg_indent_more() ;
00336 if ((bright_lines[i] = irplib_spectrum_detect_peaks(extracted[i],
00337 crires_model_refine_config.fwhm,
00338 crires_model_refine_config.sigma,
00339 crires_model_refine_config.display==i+1,
00340 NULL, NULL)) == NULL) {
00341 cpl_msg_warning(__func__, "Cannot detect lines");
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 cpl_msg_indent_less() ;
00365 }
00366 cpl_imagelist_delete(ilist) ;
00367 for (j=0 ; j<CRIRES_NB_DETECTORS; j++)
00368 cpl_vector_delete(extracted[j]) ;
00369
00370
00371 cpl_msg_info(__func__, "Match with the catalog") ;
00372 cpl_msg_indent_more() ;
00373 if ((temp_coord=crires_model_refining_match((const cpl_vector **)bright_lines,
00374 (const cpl_vector **)traces,
00375 cust_lines,
00376 crires_model_refine_config.search_box_sz,
00377 crires_model_refine_config.min_matches_nb,
00378 ref_fname)) == NULL) {
00379 if (nph==1) {
00380 cpl_msg_error(__func__, "Cannot match %s with catalog",
00381 ref_fname);
00382 cpl_frameset_delete(rawframes) ;
00383 for (j=0 ;j<CRIRES_NB_DETECTORS; j++)
00384 cpl_vector_delete(traces[j]) ;
00385 cpl_free(traces) ;
00386 for (j=0 ; j<CRIRES_NB_DETECTORS; j++)
00387 if (bright_lines[j] != NULL)
00388 cpl_vector_delete(bright_lines[j]) ;
00389 if ((crires_model_free2Darray(cust_lines,6))!=0) {
00390 cpl_msg_error(__func__, "Cannot free 2D array");
00391 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00392 return -1;
00393 }
00394 cpl_msg_indent_less() ;
00395 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00396 return -1 ;
00397 } else {
00398 cpl_msg_warning(__func__, "Cannot match lines for fibre %d on raw frame %d", ph, k);
00399 }
00400 }
00401 cpl_msg_indent_less() ;
00402 for (j=0 ; j<CRIRES_NB_DETECTORS; j++)
00403 if (bright_lines[j] != NULL)
00404 cpl_vector_delete(bright_lines[j]) ;
00405 if (temp_coord!=NULL) {
00406 i=0;
00407 while (temp_coord[0][i]!=0.0) {
00408 msp_coord[coord_cnt].wave=temp_coord[0][i];
00409 msp_coord[coord_cnt].x=temp_coord[1][i];
00410 msp_coord[coord_cnt].flux=temp_coord[2][i];
00411 msp_coord[coord_cnt].chip=(int)(temp_coord[3][i]);
00412 msp_coord[coord_cnt].mode=(int)(temp_coord[4][i]);
00413 msp_coord[coord_cnt].y=temp_coord[5][i];
00414 msp_coord[coord_cnt].penc=(int)(temp_coord[6][i]);
00415 msp_coord[coord_cnt].genc=(int)(temp_coord[7][i]);
00416 msp_coord[coord_cnt].slit_pos=ph;
00417 msp_coord[coord_cnt].counter=(int)(temp_coord[9][i]);
00418 msp_coord[coord_cnt].slitw=temp_coord[10][i];
00419 coord_cnt++;
00420 i++;
00421 }
00422 if ((crires_model_free2Darray(temp_coord,11))!=0) {
00423 cpl_msg_error(__func__, "Cannot free 2D array");
00424 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00425 return -1;
00426 }
00427 y_pos_mm=cpl_vector_get(traces[2],1024);
00428 }
00429 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
00430 cpl_vector_delete(traces[i]) ;
00431 cpl_free(traces);
00432 cpl_msg_indent_less() ;
00433 }
00434 else {
00435 cpl_msg_warning(__func__, "Cannot get the spectrum trace") ;
00436 }
00437
00438 }
00439 if ((crires_model_free2Darray(cust_lines,6))!=0) {
00440 cpl_msg_error(__func__, "Cannot free 2D array");
00441 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00442 return -1;
00443 }
00444 }
00445
00446
00447 if (cal_flag==1) {
00448 scan_out=fopen("coord_scan.dat","a+");
00449 for (i=0;i<coord_cnt;i++) {
00450 fprintf(scan_out,"%d %lf %lf %d %lf %d %lf %d %d %d %lf\n",i,
00451 msp_coord[i].y,
00452 msp_coord[i].x,
00453 msp_coord[i].chip,
00454 msp_coord[i].flux,
00455 msp_coord[i].slit_pos,
00456 msp_coord[i].wave*1000000.0,
00457 -msp_coord[i].mode,
00458 msp_coord[i].penc,
00459 msp_coord[i].genc,
00460 msp_coord[i].slitw);
00461 }
00462 fclose(scan_out);
00463 }
00464
00465 cpl_msg_info(__func__, "slit position in mm: %lf",y_pos_mm);
00466
00467 cpl_msg_info(__func__, "Compute the new configuration file") ;
00468 cpl_msg_indent_more() ;
00469 if ((new_conf = crires_model_refining_anneal(msp_coord,
00470 coord_cnt,
00471 y_pos_mm,
00472 ref_fname,
00473 config)) == NULL) {
00474 cpl_msg_error(__func__, "Cannot compute the new configuration file");
00475 cpl_msg_indent_less() ;
00476 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00477 return -1;
00478 }
00479 cpl_msg_indent_less() ;
00480 cpl_frameset_delete(rawframes) ;
00481
00482
00483 cpl_msg_info(__func__, "Save the new configuration file") ;
00484 if (crires_model_refine_save(new_conf, parlist, frameset) == -1) {
00485 cpl_msg_error(__func__, "Cannot save the product");
00486 cpl_table_delete(new_conf) ;
00487 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00488 return -1 ;
00489 }
00490 cpl_table_delete(new_conf) ;
00491
00492
00493 if (cpl_error_get_code()) return -1 ;
00494 else return 0 ;
00495 }
00496
00497
00498
00506
00507 static int crires_model_refine_save(
00508 cpl_table * out_table,
00509 const cpl_parameterlist * parlist,
00510 cpl_frameset * set)
00511 {
00512 cpl_propertylist * plist ;
00513 const char * recipe_name = "crires_model_refine" ;
00514
00515 plist = cpl_propertylist_new();
00516 cpl_propertylist_append_string(plist, "INSTRUME", "CRIRES") ;
00517 cpl_propertylist_append_string(plist, CPL_DFS_PRO_CATG,
00518 CRIRES_CALPRO_MODEL_CONFIG) ;
00519 cpl_propertylist_append_string(plist, CPL_DFS_PRO_TYPE,
00520 CRIRES_PROTYPE_MOD_CONF) ;
00521
00522
00523
00524 if (cpl_dfs_save_table(set, NULL, parlist, set, NULL, out_table,
00525 NULL, recipe_name, plist, NULL, PACKAGE "/" PACKAGE_VERSION,
00526 "crires_model_refine.fits") != CPL_ERROR_NONE) {
00527 cpl_msg_error(__func__, "Cannot save the table") ;
00528 return -1 ;
00529 }
00530
00531
00532 cpl_propertylist_delete(plist) ;
00533 return 0 ;
00534 }
00535