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 #ifdef HAVE_CONFIG_H
00027 #include <config.h>
00028 #endif
00029
00030
00038
00041
00042
00043
00044
00045
00046
00047
00048 #include <xsh_error.h>
00049
00050 #include <xsh_pfits_qc.h>
00051 #include <xsh_utils.h>
00052 #include <xsh_msg.h>
00053
00054 #include <xsh_dfs.h>
00055
00056 #include <xsh_drl.h>
00057 #include <xsh_data_instrument.h>
00058
00059
00060 #include <cpl.h>
00061
00062
00063
00064
00065
00066 #define RECIPE_ID "xsh_orderpos"
00067 #define RECIPE_AUTHOR "L.Guglielmi,R.Haigron,P.Goldoni,F.Royer"
00068 #define RECIPE_CONTACT "amodigli@eso.org"
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 static int xsh_orderpos_create(cpl_plugin *);
00079 static int xsh_orderpos_exec(cpl_plugin *);
00080 static int xsh_orderpos_destroy(cpl_plugin *);
00081
00082
00083 static void xsh_orderpos(cpl_parameterlist *, cpl_frameset *);
00084
00085
00086
00087
00088 static char xsh_orderpos_description_short[] =
00089 "Create the orders centre traces table file";
00090
00091 static char xsh_orderpos_description[] =
00092 "This recipe creates the orders centre traces table.\n\
00093 Input Frames for UVB and VIS:\n\
00094 Raw file (Tag = ORDERDEF_arm_D2)\n\
00095 Master Dark (Tag = MASTER_DARK_arm)\n\
00096 Master Bias (Tag = MASTER_BIAS_arm)\n\
00097 Input Frames for NIR:\n\
00098 Raw file ON(Tag = ORDERDEF_NIR_ON)\n\
00099 Raw file OFF(Tag = ORDERDEF_NIR_OFF)\n\
00100 Input Frames for all arms\n\
00101 Guess order table (Tag = ORDER_TAB_GUESS_arm)\n\
00102 Spectral format table (Tag = SPECTRAL_FORMAT_TAB_arm)\n\
00103 [OPTIONAL] Bad Pixel Map (Tag = BADPIXEL_MAP_arm)\n\
00104 Prepare PRE structures.\n\
00105 For NIR, subtract NIR-OFF from NIR-ON.\n\
00106 For UVB and NIR, Substract the master Bias and master dark.\n\
00107 Detect Orders and calculate the order table.\n\
00108 The final products are:\n\
00109 An updated Order Table, PRO.CATG=ORDER_TABLE_CENTR_arm.\n\
00110 A order trace residuals Table, PRO.CATG=ORDERPOS_RESID_TAB_arm.\n\
00111 The order pos frame bias subtracted, PRO.CATG=ORDERDEF_BIAS_SUBTRACTED_arm.\n";
00112
00113
00114
00115
00116
00117
00126
00127
00128 int cpl_plugin_get_info(cpl_pluginlist *list) {
00129 cpl_recipe *recipe = NULL;
00130 cpl_plugin *plugin = NULL;
00131
00132 recipe = cpl_calloc(1, sizeof(*recipe));
00133 if ( recipe == NULL ){
00134 return -1;
00135 }
00136
00137 plugin = &recipe->interface ;
00138
00139 cpl_plugin_init(plugin,
00140 CPL_PLUGIN_API,
00141 XSH_BINARY_VERSION,
00142 CPL_PLUGIN_TYPE_RECIPE,
00143 RECIPE_ID,
00144 xsh_orderpos_description_short,
00145 xsh_orderpos_description,
00146 RECIPE_AUTHOR,
00147 RECIPE_CONTACT,
00148 xsh_get_license(),
00149 xsh_orderpos_create,
00150 xsh_orderpos_exec,
00151 xsh_orderpos_destroy);
00152
00153 cpl_pluginlist_append(list, plugin);
00154
00155 return (cpl_error_get_code() != CPL_ERROR_NONE);
00156 }
00157
00158
00168
00169
00170 static int xsh_orderpos_create(cpl_plugin *plugin){
00171 cpl_recipe *recipe = NULL;
00172 xsh_detect_continuum_param param = { 10, 2, 5,
00173 DETECT_CONTINUUM_POLYNOMIAL_DEGREE,
00174 1, 0.,
00175 20, 50, 140., 2., 0 } ;
00176
00177
00178 xsh_init();
00179
00180
00181 assure( plugin != NULL, CPL_ERROR_NULL_INPUT, "Null plugin");
00182
00183
00184 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
00185 CPL_ERROR_TYPE_MISMATCH,
00186 "Plugin is not a recipe");
00187
00188 recipe = (cpl_recipe *)plugin;
00189
00190
00191 recipe->parameters = cpl_parameterlist_new();
00192 assure( recipe->parameters != NULL,
00193 CPL_ERROR_ILLEGAL_OUTPUT,
00194 "Memory allocation failed!");
00195
00196
00197 check( xsh_parameters_generic( RECIPE_ID, recipe->parameters ) ) ;
00198 check( xsh_parameters_pre_overscan( RECIPE_ID, recipe->parameters ) ) ;
00199
00200 check(xsh_parameters_detect_continuum_create(RECIPE_ID,
00201 recipe->parameters,
00202 param));
00203 check( xsh_parameters_clipping_dcn_create( RECIPE_ID,
00204 recipe->parameters ) ) ;
00205 cleanup:
00206 if ( cpl_error_get_code() != CPL_ERROR_NONE ){
00207 xsh_error_dump(CPL_MSG_ERROR);
00208 return 1;
00209 }
00210 else {
00211 return 0;
00212 }
00213 }
00214
00215
00221
00222
00223 static int xsh_orderpos_exec(cpl_plugin *plugin) {
00224 cpl_recipe *recipe = NULL;
00225
00226
00227 assure( plugin != NULL, CPL_ERROR_NULL_INPUT, "Null plugin" );
00228
00229
00230 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
00231 CPL_ERROR_TYPE_MISMATCH, "Plugin is not a recipe");
00232
00233 recipe = (cpl_recipe *)plugin;
00234
00235
00236 xsh_orderpos(recipe->parameters, recipe->frames);
00237
00238
00239 cleanup:
00240 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
00241 xsh_error_dump(CPL_MSG_ERROR);
00242
00243 cpl_error_reset();
00244 return 1;
00245 }
00246 else {
00247 return 0;
00248 }
00249 }
00250
00251
00257
00258 static int xsh_orderpos_destroy(cpl_plugin *plugin)
00259 {
00260 cpl_recipe *recipe = NULL;
00261
00262
00263 assure( plugin != NULL, CPL_ERROR_NULL_INPUT, "Null plugin" );
00264
00265
00266 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
00267 CPL_ERROR_TYPE_MISMATCH, "Plugin is not a recipe");
00268
00269 recipe = (cpl_recipe *)plugin;
00270
00271 xsh_free_parameterlist(&recipe->parameters);
00272
00273 cleanup:
00274 if (cpl_error_get_code() != CPL_ERROR_NONE)
00275 {
00276 return 1;
00277 }
00278 else
00279 {
00280 return 0;
00281 }
00282 }
00283
00284 static cpl_error_code
00285 xsh_params_set_defaults(cpl_parameterlist* pars,
00286 xsh_instrument* inst,
00287 xsh_detect_continuum_param* det_order,
00288 xsh_clipping_param* clip)
00289 {
00290
00291 cpl_parameter* p=NULL;
00292
00293 if (xsh_instrument_get_arm(inst) == XSH_ARM_NIR){
00294 check(p=xsh_parameters_find(pars,RECIPE_ID,
00295 "detectcontinuum-search-window-half-size"));
00296 if(xsh_parameter_get_default_flag(p) == 0) {
00297
00298 det_order->search_window=2;
00299 }
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 check(p=xsh_parameters_find(pars,RECIPE_ID,
00312 "detectcontinuum-clip-res-max"));
00313
00314 if(xsh_parameter_get_default_flag(p) == 0) {
00315
00316 check(clip->res_max=0.4);
00317 }
00318 }
00319
00320
00321 cleanup:
00322
00323 return cpl_error_get_code();
00324
00325 }
00326
00327
00328
00336
00337 static void xsh_orderpos(cpl_parameterlist* parameters,
00338 cpl_frameset* frameset)
00339 {
00340 const char* recipe_tags[1] = {XSH_ORDERDEF};
00341 int recipe_tags_size = 1;
00342
00343
00344 cpl_frameset* raws = NULL;
00345 cpl_frameset* calib = NULL;
00346 cpl_frame* bpmap = NULL;
00347 cpl_frame* master_bias = NULL;
00348 cpl_frame* master_dark = NULL;
00349 cpl_frame * order_tab_guess = NULL ;
00350 cpl_frame * orderframe = NULL ;
00351 cpl_frame * spectralformat_frame = NULL ;
00352 cpl_frame * rmbias = NULL ;
00353 cpl_frame * intFrame = NULL ;
00354 cpl_frame * nir_on = NULL ;
00355 cpl_frame * nir_off = NULL ;
00357
00358 cpl_frame * resFrame = NULL ;
00359
00360
00361 xsh_detect_continuum_param * detect_param = NULL ;
00362 xsh_instrument* instrument = NULL;
00363 xsh_clipping_param * dcn_clipping_param = NULL;
00364 cpl_frame* resid_tab=NULL;
00365 int pre_overscan_corr=0;
00366
00367
00368
00369
00370 check( xsh_begin( frameset, parameters, &instrument, &raws, &calib,
00371 recipe_tags, recipe_tags_size,
00372 RECIPE_ID, XSH_BINARY_VERSION,
00373 xsh_orderpos_description_short ) ) ;
00374 check( xsh_instrument_update_lamp( instrument, XSH_LAMP_UNDEFINED));
00375 check( spectralformat_frame = xsh_find_frame_with_tag( calib,
00376 XSH_SPECTRAL_FORMAT, instrument));
00377
00378
00379
00380 bpmap = xsh_find_master_bpmap(calib) ;
00381
00382 order_tab_guess = xsh_find_frame_with_tag(calib,XSH_ORDER_TAB_GUESS,
00383 instrument) ;
00384 cpl_error_reset() ;
00385
00386 if ( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR ) {
00387 check( nir_on = xsh_find_raw_orderdef_nir ( raws ) ) ;
00388 check( nir_off = xsh_find_raw_orderdef_nir_off ( raws ) ) ;
00389 }
00390 else {
00391 check( orderframe = xsh_find_raw_orderdef_vis_uvb( raws ) ) ;
00392 if((master_bias = xsh_find_frame_with_tag(calib,XSH_MASTER_BIAS,
00393 instrument)) == NULL) {
00394
00395 xsh_msg_warning("Frame %s not provided",XSH_MASTER_BIAS);
00396 xsh_error_reset();
00397 }
00398
00399
00400 if((master_dark = xsh_find_frame_with_tag(calib,XSH_MASTER_DARK,
00401 instrument)) == NULL){
00402 xsh_msg_warning("Frame %s not provided",XSH_MASTER_DARK);
00403 xsh_error_reset();
00404 }
00405 }
00406 check( xsh_instrument_update_from_spectralformat( instrument,
00407 spectralformat_frame));
00408
00409
00410
00411
00412 check( pre_overscan_corr = xsh_parameters_get_int( parameters, RECIPE_ID,
00413 "pre-overscan-corr"));
00414
00415 check(detect_param=xsh_parameters_detect_continuum_get( RECIPE_ID,
00416 parameters)) ;
00417
00418
00419 xsh_msg_dbg_low("Search Window: %d, Running Window: %d, Fit Window: %d",
00420 detect_param->search_window, detect_param->running_window,
00421 detect_param->fit_window ) ;
00422 xsh_msg_dbg_low( "Polynomial degree: %d, Step: %d", detect_param->poly_degree,
00423 detect_param->poly_step ) ;
00424
00425 check( dcn_clipping_param = xsh_parameters_clipping_dcn_get( RECIPE_ID,
00426 parameters ));
00427
00428
00429 check(xsh_params_set_defaults(parameters,instrument,detect_param,
00430 dcn_clipping_param));
00431
00432
00433
00434
00435
00436 xsh_msg( "Working on Arm %s", xsh_instrument_arm_tostring(instrument ) ) ;
00437
00438 check(xsh_prepare(raws, bpmap, master_bias, XSH_ORDERDEF, instrument,pre_overscan_corr));
00439
00440
00441
00442
00443
00444 if ( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR ) {
00445
00446
00447 check( intFrame = xsh_pre_frame_subtract( nir_on, nir_off,
00448 "ON-OFF_NIR.fits",
00449 instrument ) ) ;
00450 }
00451 else {
00452
00453 if(master_bias!= NULL) {
00454
00455 xsh_msg( "Substract bias" ) ;
00456 check(rmbias = xsh_subtract_bias( orderframe, master_bias, instrument,"ORDERDEF_",pre_overscan_corr));
00457 } else {
00458 rmbias=cpl_frame_duplicate(orderframe);
00459 }
00460
00461 if(master_dark!= NULL) {
00462 char fname[128] ;
00463 xsh_msg( "Substract dark" ) ;
00464 sprintf( fname, "ORDERPOS_%s_DARK.fits",
00465 xsh_instrument_arm_tostring(instrument ) ) ;
00466 check(intFrame = xsh_subtract_dark(rmbias, master_dark,
00467 fname, instrument));
00468 } else {
00469 intFrame=cpl_frame_duplicate(rmbias);
00470 }
00471 }
00472
00473 if ( xsh_instrument_get_arm(instrument) != XSH_ARM_NIR){
00474 check(xsh_check_input_is_unbinned(intFrame));
00475 }
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 xsh_msg("Calling detect continuum" ) ;
00486
00487 check_msg( resFrame = xsh_detect_continuum( intFrame, order_tab_guess,
00488 spectralformat_frame,
00489 detect_param,
00490 dcn_clipping_param,
00491 instrument, &resid_tab ),
00492 "Error in xsh_detect_continuum" ) ;
00493
00494 check(xsh_monitor_flux( intFrame, resFrame, instrument));
00495
00496
00497
00498 xsh_msg( "Save Order Table product" ) ;
00499 check(xsh_add_product_table_multi( resFrame, frameset, parameters, RECIPE_ID,
00500 instrument));
00501
00502 check(xsh_add_product_table_multi(resid_tab, frameset, parameters, RECIPE_ID,
00503 instrument));
00504
00505 if ( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR ) {
00506 check(xsh_add_product_pre(intFrame,frameset,parameters,RECIPE_ID,instrument));
00507 } else {
00508 check(xsh_add_product_pre(rmbias,frameset,parameters,RECIPE_ID,instrument));
00509 }
00510 cleanup:
00511 xsh_end( RECIPE_ID, frameset, parameters );
00512 XSH_FREE( dcn_clipping_param );
00513 XSH_FREE( detect_param );
00514 xsh_instrument_free(&instrument );
00515 xsh_free_frameset(&raws);
00516 xsh_free_frameset(&calib);
00517 xsh_free_frame( &resFrame) ;
00518 xsh_free_frame( &resid_tab) ;
00519 xsh_free_frame(&rmbias);
00520 xsh_free_frame(&intFrame);
00521 return;
00522 }
00523