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
00049 #include <xsh_error.h>
00050
00051 #include <xsh_utils.h>
00052 #include <xsh_model_utils.h>
00053 #include <xsh_msg.h>
00054
00055 #include <xsh_dfs.h>
00056 #include <xsh_pfits.h>
00057
00058 #include <xsh_drl.h>
00059 #include <xsh_drl_check.h>
00060 #include <xsh_data_instrument.h>
00061 #include <xsh_model_kernel.h>
00062 #include <xsh_model_arm_constants.h>
00063
00064
00065 #include <cpl.h>
00066 #include <math.h>
00067
00068
00069
00070
00071
00072
00073
00074 #define RECIPE_ID "xsh_wavecal"
00075 #define RECIPE_AUTHOR "L.Guglielmi"
00076 #define RECIPE_CONTACT "amodigli@eso.org"
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 static int xsh_wavecal_create(cpl_plugin *);
00087 static int xsh_wavecal_exec(cpl_plugin *);
00088 static int xsh_wavecal_destroy(cpl_plugin *);
00089
00090
00091 static void xsh_wavecal(cpl_parameterlist *, cpl_frameset *);
00092
00093
00094
00095
00096 static char xsh_wavecal_description_short[] =
00097 "Compute arclines tilt and instrument resolution";
00098
00099 static char xsh_wavecal_description[] =
00100 "This recipe detects and follow arc lines in a fully illuminated slit\n\
00101 frame.\n\
00102 Input Frames:\n\
00103 Raw frame (Tag = ARC_SLIT_arm)\n\
00104 Arc Line List (Tag = ARC_LINE_LIST_arm)\n\
00105 Master Bias (Tag = MASTER_BIAS_arm)\n\
00106 [OPTIONAL] Master Dark (Tag = MASTER_DARK_arm)\n\
00107 Order Table (Tag = ORDER_TABLE_EDGES_arm)\n\
00108 [poly mode] Wave Solution (Tag = WAVE_TAB_2D_arm)\n\
00109 [poly mode] Theoretical Map (Tag = THEO_TAB_spec_arm, spec=SING/IFU)\n\
00110 [physical model mode] Model cfg tab (Tag = XSH_MOD_CFG_TAB_arm)\n\
00111 - [OPTIONAL] A non-linear badpixel map (Tag = BP_MAP_NL_arm)\n\
00112 - [OPTIONAL] A reference badpixel map (Tag = BP_MAP_RP_arm)\n\
00113 [OPTIONAL-To compute spectral resolution] Dispersion Table Frame (Tag = DISP_TAB_arm)\n\
00114 Prepare PRE structures.\n\
00115 Subtract the master Dark (UVB, VIS and NIR) (xsh_subtract_dark)\n\
00116 Substract the master Bias (UVB and VIS)(amodigli@pc014007$ vi xsh_wavecal_fail.sofxsh_substract_bias)\n\
00117 Divide by Flat.\n\
00118 Detect and follow arc lines.\n\
00119 Products:\n\
00120 Wavelength solution, PRO.CATG = WAVE_TAB_ARC_SLIT_arm [if poly mode]\n\
00121 Linetilt list, PRO.CATG = TILT_TAB_SLIT_arm\n\
00122 Residuals table, PRO.CATG = RESID_TAB_GOOD_LINES_arm\n\
00123 Wave Map, PRO.CATG = WAVE_MAP_arm [if model-wavemap-compute=TRUE]\n\
00124 In case of IFU mode cdata previous producs repat for each IFU slices\n\
00125 Arc frame, Bias subtracted in PRE format, PRO.CATG = ARC_BIAS_SUBTRACT_arm\n\
00126 If arm=UVB/VIS and PRO.CATG=ARC_NIR_ON if arm=NIR\n\
00127 Arc frame, Bias subtracted, FLAT-FIELDED, PRO.CATG = WAVECAL_FLATFIELDED_arm";
00128
00129
00130
00131
00132
00133
00142
00143
00144 int cpl_plugin_get_info(cpl_pluginlist *list) {
00145 cpl_recipe *recipe = NULL;
00146 cpl_plugin *plugin = NULL;
00147
00148 recipe = cpl_calloc(1, sizeof(*recipe));
00149 if ( recipe == NULL ){
00150 return -1;
00151 }
00152
00153 plugin = &recipe->interface ;
00154
00155 cpl_plugin_init(plugin,
00156 CPL_PLUGIN_API,
00157 XSH_BINARY_VERSION,
00158 CPL_PLUGIN_TYPE_RECIPE,
00159 RECIPE_ID,
00160 xsh_wavecal_description_short,
00161 xsh_wavecal_description,
00162 RECIPE_AUTHOR,
00163 RECIPE_CONTACT,
00164 xsh_get_license(),
00165 xsh_wavecal_create,
00166 xsh_wavecal_exec,
00167 xsh_wavecal_destroy);
00168
00169 cpl_pluginlist_append(list, plugin);
00170
00171 return (cpl_error_get_code() != CPL_ERROR_NONE);
00172 }
00173
00174
00184
00185
00186 static int xsh_wavecal_create(cpl_plugin *plugin)
00187 {
00188 cpl_recipe *recipe = NULL;
00189
00190
00191
00192
00193 xsh_init();
00194
00195
00196 assure( plugin != NULL, CPL_ERROR_NULL_INPUT, "Null plugin");
00197
00198
00199 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
00200 CPL_ERROR_TYPE_MISMATCH,
00201 "Plugin is not a recipe");
00202
00203 recipe = (cpl_recipe *)plugin;
00204
00205
00206 recipe->parameters = cpl_parameterlist_new();
00207 assure( recipe->parameters != NULL,
00208 CPL_ERROR_ILLEGAL_OUTPUT,
00209 "Memory allocation failed!");
00210
00211
00212 check( xsh_parameters_generic( RECIPE_ID, recipe->parameters ) ) ;
00213 xsh_parameters_decode_bp(RECIPE_ID,recipe->parameters,-1);
00214 check( xsh_parameters_pre_overscan( RECIPE_ID, recipe->parameters ) ) ;
00215
00216
00217 check(xsh_parameters_wavecal_range_create( RECIPE_ID,
00218 recipe->parameters));
00219
00220 check(xsh_parameters_wavecal_margin_create( RECIPE_ID,
00221 recipe->parameters));
00222
00223 check( xsh_parameters_wavecal_s_n_create( RECIPE_ID,
00224 recipe->parameters));
00225
00226 check( xsh_parameters_clipping_tilt_create( RECIPE_ID,
00227 recipe->parameters ) ) ;
00228
00229 check( xsh_parameters_clipping_specres_create( RECIPE_ID,
00230 recipe->parameters ) ) ;
00231
00232 cleanup:
00233 if ( cpl_error_get_code() != CPL_ERROR_NONE ){
00234 xsh_error_dump(CPL_MSG_ERROR);
00235 return 1;
00236 }
00237 else {
00238 return 0;
00239 }
00240 }
00241
00242
00248
00249
00250 static int xsh_wavecal_exec(cpl_plugin *plugin)
00251 {
00252 cpl_recipe *recipe = NULL;
00253
00254
00255 assure( plugin != NULL, CPL_ERROR_NULL_INPUT, "Null plugin" );
00256
00257
00258 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
00259 CPL_ERROR_TYPE_MISMATCH, "Plugin is not a recipe");
00260
00261 recipe = (cpl_recipe *)plugin;
00262
00263
00264 xsh_wavecal(recipe->parameters, recipe->frames);
00265
00266 cleanup:
00267 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
00268 xsh_error_dump(CPL_MSG_ERROR);
00269
00270 cpl_error_reset();
00271 return 1;
00272 }
00273 else {
00274 return 0;
00275 }
00276 }
00277
00278
00284
00285 static int xsh_wavecal_destroy(cpl_plugin *plugin)
00286 {
00287 cpl_recipe *recipe = NULL;
00288
00289
00290 assure( plugin != NULL, CPL_ERROR_NULL_INPUT, "Null plugin" );
00291
00292
00293 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
00294 CPL_ERROR_TYPE_MISMATCH, "Plugin is not a recipe");
00295
00296 recipe = (cpl_recipe *)plugin;
00297
00298 xsh_free_parameterlist(&recipe->parameters);
00299
00300 cleanup:
00301 if (cpl_error_get_code() != CPL_ERROR_NONE)
00302 {
00303 return 1;
00304 }
00305 else
00306 {
00307 return 0;
00308 }
00309 }
00310
00311 static void xsh_wavecal_get_parameters( cpl_parameterlist* parameters,
00312 xsh_follow_arclines_param * par )
00313 {
00314 check( par->range = xsh_parameters_wavecal_range_get( RECIPE_ID,
00315 parameters));
00316 check( par->margin = xsh_parameters_wavecal_margin_get( RECIPE_ID,
00317 parameters));
00318 check( par->s_n_min = xsh_parameters_wavecal_s_n_get( RECIPE_ID,
00319 parameters));
00320 check( par->tilt_clipping = xsh_parameters_clipping_tilt_get( RECIPE_ID,
00321 parameters));
00322 check( par->specres_clipping = xsh_parameters_clipping_specres_get( RECIPE_ID,
00323 parameters));
00324 cleanup:
00325 return ;
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335 static cpl_error_code
00336 xsh_params_monitor(xsh_follow_arclines_param follow_param)
00337 {
00338 xsh_msg_dbg_low("follow arclines: range=%d margin=%d",
00339 follow_param.range,follow_param.margin);
00340
00341 return cpl_error_get_code();
00342
00343 }
00344
00345
00346
00347
00348 static cpl_error_code
00349 xsh_params_set_defaults(cpl_parameterlist* pars,
00350 xsh_instrument* inst)
00351 {
00352 cpl_parameter* p=NULL;
00353 check(p=xsh_parameters_find(pars,RECIPE_ID,"followarclines-min-sn"));
00354 if(cpl_parameter_get_double(p) <= 0) {
00355 if (xsh_instrument_get_mode(inst) == XSH_MODE_IFU){
00356 cpl_parameter_set_double(p,6);
00357 } else {
00358 cpl_parameter_set_double(p,15);
00359 }
00360 }
00361
00362
00363 cleanup:
00364
00365 return cpl_error_get_code();
00366
00367 }
00368
00369
00370
00371
00372
00380
00381
00382 static cpl_error_code
00383 xsh_params_bin_scale(cpl_frameset* raws,
00384 xsh_follow_arclines_param follow_param)
00385 {
00386
00387 cpl_frame* frame=NULL;
00388 const char* name=NULL;
00389 cpl_propertylist* plist=NULL;
00390 int binx=0;
00391 int biny=0;
00392
00393 check(frame=cpl_frameset_get_first(raws));
00394 check(name=cpl_frame_get_filename(frame));
00395 check(plist=cpl_propertylist_load(name,0));
00396 check(binx=xsh_pfits_get_binx(plist));
00397 check(biny=xsh_pfits_get_biny(plist));
00398
00399 if(biny>1) {
00400
00401 follow_param.range=follow_param.range/biny;
00402
00403 }
00404
00405
00406 if(binx>1) {
00407
00408 follow_param.margin=follow_param.margin/binx;
00409
00410 }
00411
00412 cleanup:
00413 xsh_free_propertylist(&plist);
00414 return cpl_error_get_code();
00415
00416 }
00417
00418
00426
00427 static void xsh_wavecal(cpl_parameterlist* parameters,
00428 cpl_frameset* frameset)
00429 {
00430 const char* recipe_tags[1] = {XSH_WAVECAL};
00431 int recipe_tags_size = 1;
00432
00433 const char *prefix = "ARC_";
00434
00435 cpl_frameset* raws = NULL;
00436 cpl_frameset* calib = NULL;
00437 cpl_frameset* on = NULL;
00438 cpl_frameset* off = NULL;
00439 cpl_frameset* on_off = NULL;
00440
00441 cpl_frame * raw_frame = NULL ;
00442 cpl_frame * bpmap = NULL;
00443 cpl_frame * order_tab_edges = NULL ;
00444 cpl_frame * arc_line_list = NULL ;
00445 cpl_frame * model_config_frame = NULL;
00446 cpl_frame * spectralformat_frame = NULL;
00447 cpl_frame * wave_tab_2d = NULL ;
00448 cpl_frame * master_bias = NULL ;
00449 cpl_frame * master_dark = NULL ;
00450 cpl_frame * rmbias = NULL ;
00451 cpl_frame * intFrame = NULL ;
00452 cpl_frame * resFrame = NULL ;
00453 cpl_frame *wavemap_frame = NULL;
00454 cpl_frame *disptab_frame = NULL;
00455 cpl_frame *slitmap_frame = NULL;
00456
00457
00458 cpl_frame * shiftFrame = NULL ;
00459 cpl_frame * tilt_list = NULL ;
00460
00461
00462 cpl_frameset * tilt_set = NULL ;
00463
00464
00465 xsh_instrument* instrument = NULL;
00466 xsh_follow_arclines_param follow_param;
00467 int follow_param_init=false;
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 char file_prefix[10];
00481 char tag[40];
00482
00483 int pre_overscan_corr=0;
00484
00485 const char* rec_prefix ="xsh_wavecal";
00486
00487
00488
00489
00490 xsh_begin( frameset, parameters, &instrument, &raws, &calib,
00491 recipe_tags, recipe_tags_size,
00492 RECIPE_ID, XSH_BINARY_VERSION, xsh_wavecal_description_short );
00493
00494
00495 xsh_recipe_params_check(parameters,instrument,RECIPE_ID);
00496
00497
00498
00499 check(bpmap = xsh_check_load_master_bpmap(calib,instrument,RECIPE_ID));
00500 check(order_tab_edges = xsh_find_order_tab_edges(calib,instrument));
00501 spectralformat_frame = xsh_find_spectral_format( calib, instrument);
00502 xsh_error_reset();
00503 if((model_config_frame = xsh_find_frame_with_tag(calib,
00504 XSH_MOD_CFG_OPT_2D,
00505 instrument)) == NULL) {
00506
00507 xsh_error_reset();
00508
00509 if ((model_config_frame = xsh_find_frame_with_tag(calib,XSH_MOD_CFG_TAB,
00510 instrument)) == NULL) {
00511 xsh_error_reset();
00512 }
00513
00514 }
00515
00516 xsh_error_reset();
00517 check(arc_line_list = xsh_find_frame_with_tag(calib,
00518 XSH_ARC_LINE_LIST,
00519 instrument));
00520
00521 check(wave_tab_2d = xsh_find_wave_tab_2d( calib, instrument ));
00522
00523 check( wavemap_frame = xsh_find_wavemap( calib, instrument));
00524 if (wavemap_frame){
00525 wavemap_frame = cpl_frame_duplicate( wavemap_frame);
00526 }
00527 check( slitmap_frame = xsh_find_slitmap( calib, instrument));
00528 if ( slitmap_frame){
00529 slitmap_frame = cpl_frame_duplicate( slitmap_frame);
00530 }
00531
00532 if( NULL==(disptab_frame = xsh_find_disp_tab( calib, instrument))) {
00533 xsh_msg_warning("No input DISP_TAB_ARM provided. Spectral Resolution will not be computed");
00534 }
00535
00536
00537
00538 if ( xsh_instrument_get_arm(instrument) != XSH_ARM_NIR){
00539
00540 XSH_ASSURE_NOT_ILLEGAL_MSG(cpl_frameset_get_size(raws) == 1,
00541 "UVB,VIS arm provide one slit,arc lamp frame");
00542
00543 if((master_bias = xsh_find_frame_with_tag(calib,XSH_MASTER_BIAS,
00544 instrument)) == NULL) {
00545
00546 xsh_msg_warning("Frame %s not provided",XSH_MASTER_BIAS);
00547 xsh_error_reset();
00548 }
00549
00550
00551
00552 if ( (master_dark = xsh_find_master_dark(calib,instrument)) == NULL ) {
00553 xsh_msg_warning("Frame %s not provided",XSH_MASTER_DARK);
00554 xsh_error_reset();
00555 }
00556 else xsh_msg( "Frame %s Found", XSH_MASTER_DARK ) ;
00557 }
00558
00559 else {
00560
00561 check(xsh_dfs_split_nir(raws,&on,&off));
00562 XSH_ASSURE_NOT_ILLEGAL_MSG(cpl_frameset_get_size(on) == 1,
00563 "NIR arm provide one slit,arc lamp on frame");
00564 XSH_ASSURE_NOT_ILLEGAL_MSG(cpl_frameset_get_size(off) == 1,
00565 "NIR arm provide one slit,arc lamp off frame");
00566 }
00567 check( xsh_instrument_update_from_spectralformat( instrument,
00568 spectralformat_frame));
00569
00570
00571
00572
00573
00574 check(xsh_params_set_defaults(parameters,instrument));
00575 check(xsh_wavecal_get_parameters( parameters, &follow_param ));
00576 follow_param_init=true;
00577 xsh_msg_dbg_low( "Parameters: Y range = %d, X Margin = %d", follow_param.range,
00578 follow_param.margin ) ;
00579 xsh_msg_dbg_low( "Clipping Tilt Parameters: sigma = %.2lf, Niter = %d, Frac = %.2lf",
00580 follow_param.tilt_clipping->sigma,
00581 follow_param.tilt_clipping->niter,
00582 follow_param.tilt_clipping->frac ) ;
00583
00584
00585 if ( xsh_instrument_get_arm(instrument) != XSH_ARM_NIR){
00586 check(xsh_params_monitor(follow_param));
00587 check(xsh_params_bin_scale(raws,follow_param));
00588 }
00589 check(xsh_params_monitor(follow_param));
00590
00591
00592
00593
00594
00595
00596
00597 if ( xsh_instrument_get_arm(instrument) != XSH_ARM_NIR){
00598 check(xsh_prepare( raws, bpmap, master_bias, XSH_WAVECAL, instrument,pre_overscan_corr,CPL_TRUE));
00599 check(raw_frame = cpl_frameset_get_first(raws));
00600
00601
00602 if(master_bias != NULL) {
00603 xsh_msg( "Subtract bias" );
00604 sprintf(file_prefix,"ARC_%s_",xsh_instrument_mode_tostring(instrument));
00605 check(rmbias = xsh_subtract_bias( raw_frame, master_bias, instrument,file_prefix,pre_overscan_corr,0));
00606 } else {
00607 rmbias=cpl_frame_duplicate(raw_frame);
00608 }
00609
00610
00611
00612 check( intFrame = xsh_check_subtract_dark( rmbias, master_dark,
00613 instrument, prefix));
00614 }
00615 else{
00616
00617 check(xsh_prepare(on, bpmap, NULL, "ON", instrument,pre_overscan_corr,CPL_TRUE));
00618 check(xsh_prepare(off,bpmap, NULL, "OFF", instrument,pre_overscan_corr,CPL_TRUE));
00619
00620 xsh_msg( "Subtract ON-OFF" ) ;
00621 check( on_off = xsh_subtract_nir_on_off(on, off, instrument));
00622 XSH_ASSURE_NOT_ILLEGAL(cpl_frameset_get_size(on_off) == 1);
00623 check( intFrame = cpl_frame_duplicate( cpl_frameset_get_first( on_off)));
00624 }
00625
00626
00627
00628
00629 if ( model_config_frame != NULL && wavemap_frame == NULL){
00630 char wave_map_tag[256];
00631 char slit_map_tag[256];
00632 int found_temp=true;
00633
00634 xsh_free_frame( &slitmap_frame);
00635 sprintf(wave_map_tag,"%s_%s_%s",rec_prefix,XSH_WAVE_MAP_MODEL,
00636 xsh_instrument_arm_tostring( instrument ));
00637 sprintf(slit_map_tag,"%s_%s_%s",rec_prefix,XSH_SLIT_MAP_MODEL,
00638 xsh_instrument_arm_tostring( instrument ));
00639
00640
00641 check(xsh_model_temperature_update_frame(&model_config_frame,intFrame,
00642 instrument,&found_temp));
00643
00644 check( xsh_create_model_map( model_config_frame, instrument,
00645 wave_map_tag,slit_map_tag,
00646 &wavemap_frame, &slitmap_frame,1));
00647 }
00648
00649
00650
00651
00652
00653
00654
00655
00656 if ( xsh_instrument_get_mode( instrument) == XSH_MODE_SLIT) {
00657 xsh_msg( "Call xsh_follow_arclines, SLIT mode" );
00658 check( xsh_follow_arclines_slit( intFrame, arc_line_list,
00659 wave_tab_2d, order_tab_edges,
00660 spectralformat_frame, model_config_frame,
00661 wavemap_frame, slitmap_frame,
00662 disptab_frame,
00663 &follow_param, instrument,
00664 &tilt_list,
00665 &shiftFrame));
00666
00667
00668
00669
00670 xsh_msg("Saving products, SLIT mode");
00671
00672 XSH_ASSURE_NOT_NULL( tilt_list);
00673 xsh_msg_dbg_low( "Tilt List Product from '%s'",
00674 cpl_frame_get_filename(tilt_list));
00675 check( xsh_add_product_table( tilt_list, frameset, parameters, RECIPE_ID,
00676 instrument,NULL));
00677 }
00678 else {
00679 int i ;
00680
00681 xsh_msg( "Call xsh_follow_arclines, IFU mode" ) ;
00682 check( tilt_set = cpl_frameset_new() ) ;
00683 check( xsh_follow_arclines_ifu( intFrame, arc_line_list,
00684 wave_tab_2d, order_tab_edges,
00685 spectralformat_frame, model_config_frame,
00686 wavemap_frame, slitmap_frame, disptab_frame,
00687 &follow_param, instrument,
00688 tilt_set, &shiftFrame));
00689
00690
00691
00692 xsh_msg("Saving products, IFU mode");
00693
00694 for( i = 0 ; i<3 ; i++ ) {
00695
00696 cpl_frame *tilt_frame = NULL;
00697
00698 check( tilt_frame = cpl_frameset_get_frame( tilt_set, i));
00699 xsh_msg_dbg_low( "Product from '%s'",
00700 cpl_frame_get_filename( tilt_frame));
00701 check( xsh_add_product_table( tilt_frame, frameset, parameters,
00702 RECIPE_ID, instrument,NULL));
00703 }
00704 }
00705
00706
00707
00708
00709 if ( xsh_instrument_get_mode( instrument) == XSH_MODE_SLIT) {
00710 sprintf(tag,"ARC_SLIT_ON");
00711 } else {
00712 sprintf(tag,"ARC_IFU_ON");
00713 }
00714 if ( xsh_instrument_get_arm(instrument) != XSH_ARM_NIR){
00715 xsh_msg_dbg_low( "Product from '%s'",
00716 cpl_frame_get_filename( rmbias));
00717
00718 check(xsh_add_product_image(rmbias,frameset,parameters,
00719 RECIPE_ID,instrument,tag));
00720
00721
00722
00723
00724 } else {
00725 xsh_msg_dbg_low( "Product from '%s'",
00726 cpl_frame_get_filename( intFrame));
00727 check(xsh_add_product_image(intFrame,frameset,parameters,
00728 RECIPE_ID,instrument,tag));
00729
00730
00731
00732
00733 }
00734
00735 xsh_msg_dbg_low( "Product from '%s'",
00736 cpl_frame_get_filename( shiftFrame));
00737 check( xsh_add_product_table( shiftFrame, frameset,parameters, RECIPE_ID,
00738 instrument,NULL));
00739
00740 cleanup:
00741 xsh_end( RECIPE_ID, frameset, parameters);
00742 xsh_instrument_free( &instrument);
00743 xsh_free_frameset( &raws);
00744 xsh_free_frameset( &calib);
00745 xsh_free_frame( &wavemap_frame);
00746 xsh_free_frame( &slitmap_frame);
00747 xsh_free_frame( &rmbias);
00748 xsh_free_frame( &intFrame);
00749 xsh_free_frameset( &on);
00750 xsh_free_frameset( &off);
00751 xsh_free_frameset( &on_off);
00752 xsh_free_frame( &resFrame);
00753 xsh_free_frame( &shiftFrame);
00754 if(follow_param_init) {
00755 XSH_FREE( follow_param.tilt_clipping);
00756 XSH_FREE( follow_param.specres_clipping);
00757 }
00758 xsh_free_frame( &tilt_list);
00759 xsh_free_frameset( &tilt_set);
00760
00761 return;
00762 }