# macros for virtual theta and two theta motors, including analyser movements # # hp 25.01.2001 # hp 08.05.2001 added support for motor sl3_rot # # contains also macros for analyser movement from hp_energy.mac # which was written for 6ID-B hp 14.12.1999 # # # global definitions # global diffractometer_mode,dist_sample_analyser,ANALYSER_d_spacing,ANALYSER_tta, \ ANALYSER_oma,zero_tt_y,zero_tt_z,pos_tth,pos_th,virtual_motor_status, \ analyser_type,analyser_lat,analyser_ind,UNDULATOR_GAP,UNDULATOR_keV # # diffractometer mode (0 = off (all motors drive separately), 1 = vertical, 2 = horizontal) diffractometer_mode = 0 # # distance between sample and analyser in millimeter dist_sample_analyser = 924.31 # # zero position of tt_y and tt_z zero_tt_y = 5.26 zero_tt_z = 924.31 # # d-spacing of the analyser crystal, zero means analyser will not be moved ANALYSER_d_spacing = 0.0 # # start values for some internally used global variables ANALYSER_tta = 0 ANALYSER_oma = 0 virtual_motor_status = 0 # # # # Examples for possible values of ANALYSER_d_spacing # use setanalyser to calculate values for other analyser # # Si 111 # ANALYSER_d_spacing = 3.13563 # # Ge 111 a0 = 5.65763; d111 = 3.26643 # ANALYSER_d_spacing = 3.26643 # # PG 002 d = 3.355 # ANALYSER_d_spacing = 3.355/3 # # # # # calcM_local was redefined so that analyser will be moved automatically # when the energy is moved, this happens also in a energy scan. This is # already defined in hp_mono_6idd.mac, so do not activate this line # # def calcM_local '{local _x_;_x_=$1;calcM_6idd;_ana_elast _x_}' # # # ################################################################################ # # user_premove # # hp 25.01.2001 # # this macro is normally defined empty in standart.mac and is redefined here # to enable the two virtual motors tth and th # ################################################################################ # def user_premove '{ if (virtual_motor_status != 3) { if (pos_tth != A[tth]) virtual_motor_status = 1 if (pos_th != A[th]) virtual_motor_status = 2 if ((pos_tth != A[tth]) && (pos_th != A[th])) virtual_motor_status = 3 } if (diffractometer_mode == 1) { if ((virtual_motor_status == 1) || (virtual_motor_status == 3)) _6idd_virtual_tt_v if ((virtual_motor_status == 2) || (virtual_motor_status == 3)) _6idd_virtual_om_v } if (diffractometer_mode == 2) { if ((virtual_motor_status == 1) || (virtual_motor_status == 3)) _6idd_virtual_tt_h if ((virtual_motor_status == 2) || (virtual_motor_status == 3)) _6idd_virtual_om_h } virtual_motor_status = 0 }' # # # # ################################################################################ # # user_getangles # # hp 26.01.2001 # # this macro is normally defined empty in standart.mac and is redefined here # to store the values of tth and th in global variables # ################################################################################ # def user_getangles '{ pos_tth = A[tth] pos_th = A[th] }' # # # # ################################################################################ # # _6idd_virtual_tt_v # # hp 25.01.2001 # hp 08.05.2001 added motor sl3_rot # # if you move tth tt_y, tt_z and tta simulate a tth movement # ################################################################################ # def _6idd_virtual_tt_v '{ local pos pos = dial(tth,A[tth]) A[tt_y] = zero_tt_y+dist_sample_analyser*sin(rad(pos)) A[tt_z] = zero_tt_z-dist_sample_analyser*cos(rad(pos)) A[oma] = pos+ANALYSER_oma A[tta] = pos+ANALYSER_tta A[sl3_rot] = -1*ANALYSER_tta }' # # # # ################################################################################ # # _6idd_virtual_tt_h # # hp 25.01.2001 # hp 08.05.2001 added motor sl3_rot # # if you move tth tt_h moves to the same position # ################################################################################ # def _6idd_virtual_tt_h '{ local pos pos = dial(tth,A[tth]) A[tt_h] = pos A[sl3_rot] = ANALYSER_tta }' # # # # ################################################################################ # # _6idd_virtual_om_v # # hp 25.01.2001 # # if you move th om_v moves to the same position # ################################################################################ # def _6idd_virtual_om_v '{ local pos pos = dial(th,A[th]) A[om_v] = pos }' # # # # ################################################################################ # # _6idd_virtual_om_h # # hp 25.01.2001 # # if you move th om_h moves to the same position # ################################################################################ # def _6idd_virtual_om_h '{ local pos pos = dial(th,A[th]) A[om_h] = pos }' # # # # ################################################################################# # # _ana_elast # # hp 06.11.1999 # hp 25.01.2001 adapted to beamline 6ID-D # # calculates the position of the analyser motors corresponding to the actual # energy # ################################################################################ # def _ana_elast '{ local sintet,cur_tet,hp_LAMBDA,an_tta,an_oma an_tta = ANALYSER_tta an_oma = ANALYSER_oma if (ANALYSER_d_spacing!=0) { if ($# == 1) { hp_LAMBDA = hc_over_e/$1 } else { hp_LAMBDA = LAMBDA } sintet = hp_LAMBDA/2/ANALYSER_d_spacing cur_tet = deg(asin(sintet)) ANALYSER_oma = cur_tet ANALYSER_tta = 2*cur_tet } else { ANALYSER_tta = 0 ANALYSER_oma = 0 } if ((ANALYSER_tta != an_tta) || (ANALYSER_oma != an_oma)) { virtual_motor_status = 3 } }' # # # # ################################################################################ # # ana_elast # # hp 06.11.1999 # hp 14.12.1999 # hp 04.02.2000 # hp 25.01.2001 adapted to beamline 6ID-D # # moves theta and tho_theta analyser corresponding to the monochromator energy # if an energy is submitted as arguement values will only be calculated but no # movement will be performed # ################################################################################ # def ana_elast '{ local lambda,pos pos = dial(tth,A[tth]) if (ANALYSER_d_spacing!=0) { if ($# > 0) { lambda = LAMBDA LAMBDA = hc_over_e/$1 _ana_elast LAMBDA = lambda printf("calculated omega analyser %f\n",ANALYSER_oma) printf("calculated two theta analyser %f\n",ANALYSER_tta) if (diffractometer_mode == 1) { printf("that means motor oma will be moved to %f\n",pos+ANALYSER_oma) printf("that means motor tta will be moved to %f\n",pos+ANALYSER_tta) } virtual_motor_status = 0 } if ($# == 0) { waitmove get_angles calcE _ana_elast if (diffractometer_mode == 1) { A[oma] = pos+ANALYSER_oma A[tta] = pos+ANALYSER_tta } if (diffractometer_mode == 2) { A[oma] = ANALYSER_oma A[tta] = ANALYSER_tta } printf("move omega analyser to %f\n",A[oma]) printf("move two theta analyser to %f\n",A[tta]) move_em _update("oma tta") } } else { eprint "Analyser not in use, use setanalyser macro to use it." } }' # # # # ################################################################################ # # setanalyser # # hp 25.01.2001 # hp 11.05.2001 small bugs corrected # # original setmono macro, altered for the use as a analyser macro # ################################################################################ # def setanalyser '{ local direction _1 = ANALYSER_d_spacing if (_1>=0) { direction = 1 } else { direction = 0 } if ($# == 1) { _1 = $1 } else if ($# == 0) { _1 = getval("\nEnter analyser d-spacing ... \n or type 0 to enter crystal type \nor to switch off the analyser",_1) if (_1+0 == 0) { _1 = yesno("\nDo you want to switch off the analyser",_1) if (_1+0 == 0) { miller_analyser direction = yesno("\nAnalyser diffracts in positiv direction",direction) if (direction == 0) _1 = -1*_1 } else { _1 = 0 } } } else { eprint "Usage: setanalyser [d-spacing]" exit } ANALYSER_d_spacing = _1 waitmove; get_angles; calcE _ana_elast virtual_motor_mode = 0 if (diffractometer_mode == 0) { printf("\nThe diffractometer mode is set to off. This means that all\n") printf("motors on the diffractometer drive independently and the analyser\n") printf("will not be positioned automatically. To change this and for\n") printf("explanations execute macro diffractometer_mode_change\n") } }' # # # # ################################################################################ # # miller_analyser # # hp 25.01.2001 # # original miller macro, altered for the use as a analyser macro, uset by setanalyser # ################################################################################ # def miller_analyser '{ local i la m x even s s2 la = analyser_lat x = analyser_type=="S"? "Si":analyser_type=="G"? "Ge":"other" m[0] = analyser_ind[0] m[1] = analyser_ind[1] m[2] = analyser_ind[2] x = substr(getval("Is your crystal Si, Ge or other",x),1,1) if (x == "s") x = "S" if (x == "g") x = "G" if (x == "S" || x == "G") { if (x == "S") la = 5.4307 else if (x == "G") la = 5.65685 } else la=getval("Enter the crystal lattice parameter in Angstroms",la) printf("Enter the Miller indices ...\n") m[0] = getval(" h",m[0]) m[1] = getval(" k",m[1]) m[2] = getval(" l",m[2]) for (i = 0; i < 3; i++) { m[i] = int(m[i]) if (!(m[i]&1)) even++ s += m[i] s2 += m[i] * m[i] } if ((x == "S" || x == "G" || !s) && even \ && (!s || s/4 != int(s/4) || even != 3)) { eprintf("Sorry, that\'s a forbidden reflection.\n") exit } _1 = la / sqrt(s2) printf("That gives a d-spacing of %g Angstroms.\n", _1) analyser_lat = la analyser_type = x analyser_ind[0] = m[0] analyser_ind[1] = m[1] analyser_ind[2] = m[2] }' # # # # ################################################################################ # # diffractometer_mode_change # # hp 25.01.2001 # # changes between the following modes: # 0 - all motors drive independently # 1 - vertical geometry # 2 - horizontal geometry # ################################################################################ # def diffractometer_mode_change '{ local mode mode = diffractometer_mode if ($# == 0) { printf("\ndiffractometer_mode_change (hp) 25.01.2001\n\n") printf("The following modes are defined:\n") printf(" 0 - all motors drive independently\n") printf(" 1 - diffractometer in vertical geometry\n") printf(" 2 - diffractometer in horizontal geometry\n") mode = getval("Your choice",mode) } else { if ($# != 1) { printf("usage: diffractometer_mode_change [value] (0,1,2)\n") exit } else { mode = $1 } } if ((mode == 0) || (mode == 1) || (mode == 2)) { diffractometer_mode = mode printf("\nNew mode: ") if (mode == 0) printf("0 - all motors drive independently\n") if (mode == 1) printf("1 - vertical scattering\n") if (mode == 2) printf("2 - horizontal scattering\n") } else { printf("Only 0, 1 and 2 are valid modes. diffractometer_mode\nwas not changed!\n") exit } }' # # # # ################################################################################# # # undulator_show_position # # hp 31.07.2000 # # shows undulator position on the screen # ################################################################################ # def undulator_show_position ' { _undulator_get_position printf("Actual undulator gap : %g\n",UNDULATOR_GAP) printf("Actual undulator energy : %g\n",UNDULATOR_keV) } ' # # # # ################################################################################# # # _undulator_get_position # # hp 31.07.2000 # # reads undulator position into global variables # ################################################################################ # def _undulator_get_position ' { local un_gap,un_ener un_gap = "ID06:Gap.VAL" un_ener = "ID06:Energy.VAL" UNDULATOR_GAP = epics_get(un_gap) UNDULATOR_keV = epics_get(un_ener) } ' # # # #