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
00138
00139 if (crires_model_off()) {
00140 return 0 ;
00141 }
00142
00143
00144 rawframes = NULL ;
00145 crires_model_refine_config.penc_co1 = -1.0 ;
00146 crires_model_refine_config.genc_co1 = -1.0 ;
00147 crires_model_refine_config.sg = -1.0 ;
00148 crires_model_refine_config.fk = -1.0 ;
00149 crires_model_refine_config.cam_dis = -1.0 ;
00150 crires_model_refine_config.slity = -1.0 ;
00151
00152
00153 crires_model_refine_config.display = crires_parameterlist_get_int(parlist,
00154 RECIPE_STRING, CRIRES_PARAM_DISPLAY) ;
00155 crires_model_refine_config.fwhm = crires_parameterlist_get_int(parlist,
00156 RECIPE_STRING, CRIRES_PARAM_FWHM) ;
00157 crires_model_refine_config.sigma = crires_parameterlist_get_double(parlist,
00158 RECIPE_STRING, CRIRES_PARAM_SIGMA) ;
00159 crires_model_refine_config.search_box_sz = crires_parameterlist_get_int(
00160 parlist, RECIPE_STRING, CRIRES_PARAM_SEARCH_BOX) ;
00161 crires_model_refine_config.min_matches_nb = crires_parameterlist_get_int(
00162 parlist, RECIPE_STRING, CRIRES_PARAM_MIN_MATCH) ;
00163
00164
00165 if (crires_dfs_set_groups(frameset, "crires_model_refine")) {
00166 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00167 return -1 ;
00168 }
00169
00170
00171 config = crires_extract_filename(frameset, CRIRES_CALPRO_MODEL_REFINE_CONF);
00172 if (config == NULL) {
00173 cpl_msg_error(__func__, "Model configuration file is missing") ;
00174 return -1 ;
00175 }
00176 thar = crires_extract_filename(frameset, CRIRES_CALPRO_THAR_CAT) ;
00177 if (thar == NULL) {
00178 cpl_msg_error(__func__, "Lines catalog file is missing") ;
00179 return -1 ;
00180 }
00181 bpm = crires_extract_filename(frameset, CRIRES_CALPRO_BPM) ;
00182 flat = crires_extract_filename(frameset, CRIRES_CALPRO_FLAT) ;
00183 detlin = crires_extract_filename(frameset, CRIRES_CALPRO_COEFFS_CUBE) ;
00184
00185
00186 if ((rawframes = crires_extract_frameset(frameset,
00187 CRIRES_MODEL_REFINE_RAW)) == NULL) {
00188 cpl_msg_error(__func__, "No raw frame in input") ;
00189 return -1 ;
00190 }
00191 nframes = cpl_frameset_get_size(rawframes) ;
00192
00193
00194 crires_model_refine_config.period =
00195 crires_get_detector_illum_period(
00196 cpl_frame_get_filename(cpl_frameset_get_frame(rawframes, 0))) ;
00197 if (crires_model_refine_config.period == CRIRES_ILLUM_UNKNOWN) {
00198 cpl_msg_error(__func__,
00199 "Cannot determine the detector illumination period") ;
00200 cpl_frameset_delete(rawframes) ;
00201 return -1 ;
00202 } else {
00203 crires_display_detector_illum(crires_model_refine_config.period) ;
00204 }
00205
00206
00207 if (nframes != 1 && nframes != 3) {
00208 cpl_msg_error(__func__, "1 or 3 raw frames expected in input") ;
00209 return -1 ;
00210 }
00211
00212
00213 for (k=0 ; k<nframes ; k++) {
00214
00215 ref_frame = cpl_frameset_get_frame(rawframes, k) ;
00216 ref_fname = cpl_frame_get_filename(ref_frame) ;
00217
00218 if (crires_model_config_check(config,ref_fname)!=0) {
00219 cpl_msg_error(__func__,
00220 "Invalid physical model configuration file") ;
00221 cpl_frameset_delete(rawframes) ;
00222 return -1;
00223 }
00224
00225 cust_lines_flag=0;
00226 for (ph=1;ph<=nph;ph++) {
00227 y_pos_pix=-(float)(ph);
00228 cpl_msg_info(__func__,"Raw frame %d, fibre position %d",k+1,ph);
00229
00230 cpl_msg_info(__func__, "Get the shape of the spectra") ;
00231 if ((traces = crires_model_profile(ref_fname,
00232 config,
00233 -1,
00234 y_pos_pix)) != NULL) {
00235
00236 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00237 ptrace = cpl_vector_get_data(traces[i]) ;
00238 for (j=0 ; j<cpl_vector_get_size(traces[i]) ; j++) {
00239 if (ptrace[j] == 0.0)
00240 ptrace[j] = cpl_vector_get_mean(traces[i]) ;
00241 }
00242 }
00243
00244
00245 if (crires_model_refine_config.display>0 &&
00246 crires_model_refine_config.display <= CRIRES_NB_DETECTORS) {
00247 irplib_vector_plot("set grid;set xlabel 'Position (pixels)';set ylabel 'Position (pixels)';",
00248 "t 'Spectrum shape' w lines", "", traces[crires_model_refine_config.display-1]);
00249 }
00250
00251
00252 cpl_msg_info(__func__, "Load the data") ;
00253 ilist = crires_load_file(ref_fname,
00254 crires_model_refine_config.period, CPL_TYPE_FLOAT) ;
00255 if (ilist == NULL) {
00256 cpl_msg_error(__func__, "Cannot load the data") ;
00257 cpl_frameset_delete(rawframes) ;
00258 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
00259 cpl_vector_delete(traces[i]) ;
00260 cpl_free(traces) ;
00261 return -1 ;
00262 }
00263
00264
00265 if (cust_lines_flag==0) {
00266 cpl_msg_info(__func__, "Customising the line list") ;
00267 cpl_msg_indent_more() ;
00268 if ((cust_lines=crires_model_refining_custom_lines(thar,
00269 crires_model_refine_config.search_box_sz,
00270 ref_fname, config, NULL))==NULL) {
00271 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
00272 cpl_vector_delete(traces[i]) ;
00273 cpl_free(traces) ;
00274 cpl_imagelist_delete(ilist) ;
00275 cpl_frameset_delete(rawframes) ;
00276 cpl_msg_error(__func__, "Cannot customise the line list");
00277 return -1;
00278 }
00279 else {
00280 cust_lines_flag=1;
00281 }
00282 }
00283 cpl_msg_indent_less() ;
00284
00285
00286
00287 cust_lines=crires_model_refining_fibrefix(cust_lines,ref_fname,config,ph);
00288
00289
00290 cpl_msg_indent_more() ;
00291 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00292 cpl_msg_info(__func__, "Reduce the chip number %d", i+1) ;
00293
00294 cpl_msg_info(__func__, "Extract spectrum") ;
00295 cpl_msg_indent_more() ;
00296 if ((extracted[i]=crires_model_refining_extract(cpl_imagelist_get(ilist, i),
00297 crires_model_refine_config.period,
00298 traces[i], bpm, flat, detlin, i+1)) == NULL) {
00299 cpl_msg_error(__func__, "Cannot extract spectrum");
00300 cpl_frameset_delete(rawframes) ;
00301 for (j=0 ;j<CRIRES_NB_DETECTORS; j++)
00302 cpl_vector_delete(traces[j]) ;
00303 cpl_free(traces) ;
00304 cpl_imagelist_delete(ilist) ;
00305 for (j=0 ; j<i ; j++) cpl_vector_delete(extracted[j]) ;
00306 if ((crires_model_free2Darray(cust_lines,6))!=0) {
00307 cpl_msg_error(__func__, "Cannot free 2D array");
00308 return -1;
00309 }
00310 cpl_msg_indent_less() ;
00311 return -1 ;
00312 }
00313 cpl_msg_indent_less() ;
00314
00315
00316 if (crires_model_refine_config.display == i+1) {
00317 irplib_vector_plot("set grid;set xlabel 'Position (pixels)';set ylabel 'Intensity (ADU)';",
00318 "t 'Extracted spectrum' w lines", "", extracted[i]);
00319 }
00320
00321
00322 cpl_msg_info(__func__, "Detect the brightest lines") ;
00323 cpl_msg_indent_more() ;
00324 if ((bright_lines[i] = irplib_spectrum_detect_peaks(extracted[i],
00325 crires_model_refine_config.fwhm,
00326 crires_model_refine_config.sigma,
00327 crires_model_refine_config.display==i+1,
00328 NULL, NULL)) == NULL) {
00329 cpl_msg_warning(__func__, "Cannot detect lines");
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 cpl_msg_indent_less() ;
00353 }
00354 cpl_imagelist_delete(ilist) ;
00355 for (j=0 ; j<CRIRES_NB_DETECTORS; j++)
00356 cpl_vector_delete(extracted[j]) ;
00357
00358
00359 cpl_msg_info(__func__, "Match with the catalog") ;
00360 cpl_msg_indent_more() ;
00361 if ((temp_coord=crires_model_refining_match((const cpl_vector **)bright_lines,
00362 (const cpl_vector **)traces,
00363 cust_lines,
00364 crires_model_refine_config.search_box_sz,
00365 crires_model_refine_config.min_matches_nb,
00366 ref_fname)) == NULL) {
00367 if (nph==1) {
00368 cpl_msg_error(__func__, "Cannot match %s with catalog",
00369 ref_fname);
00370 cpl_frameset_delete(rawframes) ;
00371 for (j=0 ;j<CRIRES_NB_DETECTORS; j++)
00372 cpl_vector_delete(traces[j]) ;
00373 cpl_free(traces) ;
00374 for (j=0 ; j<CRIRES_NB_DETECTORS; j++)
00375 if (bright_lines[j] != NULL)
00376 cpl_vector_delete(bright_lines[j]) ;
00377 if ((crires_model_free2Darray(cust_lines,6))!=0) {
00378 cpl_msg_error(__func__, "Cannot free 2D array");
00379 return -1;
00380 }
00381 cpl_msg_indent_less() ;
00382 return -1 ;
00383 } else {
00384 cpl_msg_warning(__func__, "Cannot match lines for fibre %d on raw frame %d", ph, k);
00385 }
00386 }
00387 cpl_msg_indent_less() ;
00388 for (j=0 ; j<CRIRES_NB_DETECTORS; j++)
00389 if (bright_lines[j] != NULL)
00390 cpl_vector_delete(bright_lines[j]) ;
00391 if (temp_coord!=NULL) {
00392 i=0;
00393 while (temp_coord[0][i]!=0.0) {
00394 msp_coord[coord_cnt].wave=temp_coord[0][i];
00395 msp_coord[coord_cnt].x=temp_coord[1][i];
00396 msp_coord[coord_cnt].flux=temp_coord[2][i];
00397 msp_coord[coord_cnt].chip=(int)(temp_coord[3][i]);
00398 msp_coord[coord_cnt].mode=(int)(temp_coord[4][i]);
00399 msp_coord[coord_cnt].y=temp_coord[5][i];
00400 msp_coord[coord_cnt].penc=(int)(temp_coord[6][i]);
00401 msp_coord[coord_cnt].genc=(int)(temp_coord[7][i]);
00402 msp_coord[coord_cnt].slit_pos=ph;
00403 msp_coord[coord_cnt].counter=(int)(temp_coord[9][i]);
00404 msp_coord[coord_cnt].slitw=temp_coord[10][i];
00405 coord_cnt++;
00406 i++;
00407 }
00408 if ((crires_model_free2Darray(temp_coord,11))!=0) {
00409 cpl_msg_error(__func__, "Cannot free 2D array");
00410 return -1;
00411 }
00412 y_pos_mm=cpl_vector_get(traces[2],1024);
00413 }
00414 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
00415 cpl_vector_delete(traces[i]) ;
00416 cpl_free(traces);
00417 cpl_msg_indent_less() ;
00418 }
00419 else {
00420 cpl_msg_warning(__func__, "Cannot get the spectrum trace") ;
00421 }
00422
00423 }
00424 if ((crires_model_free2Darray(cust_lines,6))!=0) {
00425 cpl_msg_error(__func__, "Cannot free 2D array");
00426 return -1;
00427 }
00428 }
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 cpl_msg_info(__func__, "slit position in mm: %lf",y_pos_mm);
00449
00450 cpl_msg_info(__func__, "Compute the new configuration file") ;
00451 cpl_msg_indent_more() ;
00452 if ((new_conf = crires_model_refining_anneal(msp_coord,
00453 coord_cnt,
00454 y_pos_mm,
00455 ref_fname,
00456 config)) == NULL) {
00457 cpl_msg_error(__func__, "Cannot compute the new configuration file");
00458 cpl_msg_indent_less() ;
00459 return -1;
00460 }
00461 cpl_msg_indent_less() ;
00462 cpl_frameset_delete(rawframes) ;
00463
00464
00465 cpl_msg_info(__func__, "Save the new configuration file") ;
00466 if (crires_model_refine_save(new_conf, parlist, frameset) == -1) {
00467 cpl_msg_error(__func__, "Cannot save the product");
00468 cpl_table_delete(new_conf) ;
00469 return -1 ;
00470 }
00471 cpl_table_delete(new_conf) ;
00472
00473
00474 if (cpl_error_get_code()) return -1 ;
00475 else return 0 ;
00476 }
00477
00478
00479
00487
00488 static int crires_model_refine_save(
00489 cpl_table * out_table,
00490 const cpl_parameterlist * parlist,
00491 cpl_frameset * set)
00492 {
00493 cpl_propertylist * plist ;
00494 const char * recipe_name = "crires_model_refine" ;
00495
00496 plist = cpl_propertylist_new();
00497 cpl_propertylist_append_string(plist, "INSTRUME", "CRIRES") ;
00498 cpl_propertylist_append_string(plist, CPL_DFS_PRO_CATG,
00499 CRIRES_CALPRO_MODEL_CONFIG) ;
00500 cpl_propertylist_append_string(plist, CPL_DFS_PRO_TYPE,
00501 CRIRES_PROTYPE_MOD_CONF) ;
00502
00503
00504
00505 if (cpl_dfs_save_table(set, NULL, parlist, set, NULL, out_table,
00506 NULL, recipe_name, plist, NULL, PACKAGE "/" PACKAGE_VERSION,
00507 "crires_model_refine.fits") != CPL_ERROR_NONE) {
00508 cpl_msg_error(__func__, "Cannot save the table") ;
00509 return -1 ;
00510 }
00511
00512
00513 cpl_propertylist_delete(plist) ;
00514 return 0 ;
00515 }
00516