# hp_mono_6idd.mac macros for operating the 6ID-D monochromator # # hp 01.05.2000 # hp 10.11.2000 # hp 10.05.2001 added automatic storage of monochromator values and detection which crystals are used # # # # calcM_local was redefined so that analyser will be moved automatically # when the energy is moved, this happens also in a energy scan. Also a special # macro for this specific monochromator is called. This requires that also # hp_motor_6idd.mac is loaded # def calcM_local '{local _x_;_x_=$1;calcM_6idd;_ana_elast _x_}' # # # # # global definitions # global mon_val,montrav_offset,mon_name,mon_num,mon_anz,mon_low_ener,mon_high_ener, \ mon_peak_points,mon_count_time,mon_scan_range_scale,mon_crystal_width, \ mon_file_name # # File name and Path where monochromator positions are stored (use filename without "." and extension (like .mac)) mon_file_name = sprintf("%s/monochromator/mono_values",SPECD) # # number of monochromator crystal pairs built into the sidestation mon_anz = 3 mon_anz -= 1 # start values for a fresh start (no working monochromator, setmono must be invoked first!) mon_num = -1 g_mod_d = 0 g_mod_s = 0 # options for mono_align_crystal mon_peak_points = 10 # Number of scan points in the peak mon_count_time = 0.5 # Counting time during mono_align_crystal mon_scan_range_scale = 4 # scan_range (mon_san_range_scale*mon_val[?][12]) # montrav offset montrav_offset = -7921.1375 # name mon_name[0] = "111 annealed crystal" mon_name[1] = "311 annealed crystal" mon_name[2] = "331 annealed crystal" # d-spacing (g_mo_d) mon_val[0][1] = 3.13542 mon_val[1][1] = 1.63742 mon_val[2][1] = 1.24589 # offset (g_mo_s) mon_val[0][2] = 600 mon_val[1][2] = 600 mon_val[2][2] = 600 # offset 1st monochromator omega mon_val[0][3] = -0.66080 mon_val[1][3] = -0.01475 mon_val[2][3] = -0.2699 # position crystal changer (m1_xtal) 1st monochromator mon_val[0][4] = 102.55 mon_val[1][4] = 150.65 mon_val[2][4] = 55.6 # chi 1st monochromator mon_val[0][5] = 1.220 mon_val[1][5] = -0.450 mon_val[2][5] = 2.3750 # phi 1st monochromator mon_val[0][6] = 0.0 mon_val[1][6] = 0.0 mon_val[2][6] = 0.0 # offset 2dn monochromator omega mon_val[0][7] = 0.14700 mon_val[1][7] = 0.05340 mon_val[2][7] = 0.00390 # position crystal changer (m2_xtal) 2nd monochromator mon_val[0][8] = 98.80 mon_val[1][8] = 128.95 mon_val[2][8] = 69.00 # chi 2nd monochromator mon_val[0][9] = 0.2225 mon_val[1][9] = 0.6526 mon_val[2][9] = 0.4100 # phi 2nd monochromator mon_val[0][10] = -0.11 mon_val[1][10] = -0.11 mon_val[2][10] = -0.11 # length 2nd monochromator in mm mon_val[0][11] = 80 mon_val[1][11] = 80 mon_val[2][11] = 80 # crystal width (rocking curve) in degree mon_val[0][12] = 0.01 mon_val[1][12] = 0.01 mon_val[2][12] = 0.01 # # # read last known monochromator positions qdofile(sprintf("%s.mac",mon_file_name)) # # # ################################################################################ # # setmono # # hp 29.11.2000 # # choose monochromator to work with, adjust all positions and settings # ################################################################################ # def setmono ' { local num,mode,i printf("\nsetmono (hp) 01.12.2000\n\n") mode = 1 if (mon_num>=0) { printf("actual used monochromator:\n") _mono_show_settings mon_num } if ($# == 0) { printf("\nChoose one of the following monochromator crystals:\n\n") for(i=0;i<=mon_anz;i++) { _mono_calc_energy_range mon_val[i][1] mon_val[i][2] printf(" %u - %s (%.1f - %.1f keV)\n",i,mon_name[i],mon_low_ener,mon_high_ener) } num = int(getval("\nYour choice",mon_num)) } else if ($# == 1) { num = int($1) mode = 0 } else { printf("usage: setmono [n]\n") exit } if (num<0 || num>mon_anz) { printf("Only 0, 1 and 2 are valid monochromator crystal pairs\n") exit } if (num == mon_num) { printf("\nMonochromator %s already in use, no action necessary.\n",mon_name[num]) } else { if (mode==1) { printf("\nstep 1: assign new lattice and distance parameters\n") printf(" g_mo_d = %f\n",mon_val[num][1]) printf(" g_mo_s = %f\n",mon_val[num][2]) printf("\nstep 2: move motors to new Position\n") printf("old positions:\n") wm m1_xtal m1_chi m1_phi m2_xtal m2_chi m2_phi printf("new positions:\n") printf(" %10.4f %10.4f %10.4f %10.4f %10.4f %10.4f\n", \ mon_val[num][4],mon_val[num][5],mon_val[num][6], \ mon_val[num][8],mon_val[num][9],mon_val[num][10]) printf("\nstep 3: change offset off monu and mond (omega mono 1 + 2)\n") printf(" monu mond\n") printf(" old offset: %f %f\n",A[monu]-dial(monu,A[monu]), \ A[mond]-dial(mond,A[mond])) printf(" new offset: %f %f\n",mon_val[num][3],mon_val[num][7]) if (yesno("\nDo you want this changes to de done",0)) { mon_num = num _mono_change_settings printf("\n\nmonochromator crystals were changed successfully.\n") printf("\nnew settings:\n") _mono_show_settings mon_num } else { printf("\n\nmonochromator settings have not been changed!\n") } } else { mon_num = num _mono_change_settings printf("\n\nmonochromator crystals were changed successfully.\n") printf("\nnew settings:\n") _mono_show_settings mon_num } } }' # # # # ################################################################################ # # mono_accept_position # # hp 29.01.2000 # # actual position is used as new alignement for monochromator # ################################################################################ # def mono_accept_position ' { local i,energy,num printf("\nmono_accept_position (hp) 29.01.2001\n\n") if ($#>1) { printf("\nusage: mono_accept_position energy (in keV)\n") exit } if ($# == 1) { energy = $1 } else { waitmove get_angles calcE energy = hc_over_e/LAMBDA energy = getval("Enter theoretical energy for this mono position",energy) } if ((mon_num<0) || (mon_num>mon_anz)) { printf("\nThe monochromator was not used since the last fresh start.\n") printf("\nChoose one of the following monochromator crystals:\n\n") for(i=0;i<=mon_anz;i++) { _mono_calc_energy_range mon_val[i][1] mon_val[i][2] printf(" %u - %s (%.1f - %.1f keV)\n",i,mon_name[i],mon_low_ener,mon_high_ener) } num = int(getval("\nYour choice",mon_num)) if ((int(num)<0) || (int(num)>mon_anz)) { eprint "Number out of range" exit } mon_num = num _setmono mon_val[mon_num][1] mon_val[mon_num][2] } _mono_accept_position energy }' # # # # ################################################################################ # # _mono_accept_position # # hp 29.01.2000 # # actual position is used as new alignement for monochromator # ################################################################################ # def _mono_accept_position ' { local mnum,en if ($# != 1) { printf("\nusage: _mono_accept_position energy (in keV)\n") exit } mnum = mon_num en = $1 if ((mnum<0) && (mnum>mon_anz)) { eprint "_mono_accept_position: wrong monochromator number!" exit } _mono_calc_energy_range mon_val[mnum][1] mon_val[mnum][2] if ((enmon_high_ener)) { eprint "_mono_accept_position: energy out of range" exit } waitmove get_angles _mono_calc_position en set monu theo_monu set mond theo_mond waitmove get_angles mon_val[mnum][3] = A[monu]-dial(monu,A[monu]) mon_val[mnum][4] = A[m1_xtal] mon_val[mnum][5] = A[m1_chi] mon_val[mnum][6] = A[m1_phi] mon_val[mnum][7] = A[mond]-dial(mond,A[mond]) mon_val[mnum][8] = A[m2_xtal] mon_val[mnum][9] = A[m2_chi] mon_val[mnum][10] = A[m2_phi] _mono_save_values_automatic }' # # # # ################################################################################ # # mono_calc_position # # hp 29.01.2000 # # calculates the theoretical monochromator position for a given energy # ################################################################################ # def mono_calc_position ' { local en printf("\nmono_calc_position (hp) 29.01.2001\n") if ($# > 1) { printf("\nusage: _mono_calc_position [energy] (in keV)\n") exit } if ($# == 1) { en = $1 } else { en = hc_over_e/LAMBDA en = getval("\nEnergy",en) } _mono_calc_position en printf("\nTheoretical monochromator positions for %f keV:\n",en) printf("monu : %f\n",theo_monu) printf("mond : %f\n",theo_mond) printf("montrav : %f\n",theo_montrav) }' # # # # ################################################################################ # # _mono_calc_position # # hp 26.01.2000 # # calculates the theoretical monochromator position for a given energy # ################################################################################ # def _mono_calc_position ' { local ener if ($# != 1) { printf("\nusage: _mono_calc_position energy (in keV)\n") exit } ener = $1 if ((ener<20) || (ener>200)) { eprint "_mono_calc_position: energy out of range" exit } calcM ener theo_monu = A[monu] theo_mond = A[mond] theo_montrav = A[montrav] }' # # # # ################################################################################ # # _mono_change_settings # # hp 04.12.2000 # # normally called by setmono, changes all necessary monochromator parameters quitly # ################################################################################ # def _mono_change_settings ' { printf("\nexecuting monochromator change ...\n") printf("\nstep 1: assigning new values to g_mo_d and g_mo_s\n") _setmono mon_val[mon_num][1] mon_val[mon_num][2] printf("\nstep 2: moving monochromator motors\n\n") # ugmv m1_xtal mon_val[mon_num][4] m1_chi mon_val[mon_num][5] m1_phi mon_val[mon_num][6] \ # m2_xtal mon_val[mon_num][8] m2_chi mon_val[mon_num][9] m2_phi mon_val[mon_num][10] # above command is disabled because m1_phi is not allowed to drive, limit switch in wrong place # ugmv m1_xtal mon_val[mon_num][4] m1_chi mon_val[mon_num][5] \ # m2_xtal mon_val[mon_num][8] m2_chi mon_val[mon_num][9] m2_phi mon_val[mon_num][10] umv m1_xtal mon_val[mon_num][4] umv m1_chi mon_val[mon_num][5] umv m2_xtal mon_val[mon_num][8] umv m2_chi mon_val[mon_num][9] umv m2_phi mon_val[mon_num][10] printf("\nstep 3: assigning new offset values for monu and mond\n\n") printf("monu: ");set monu dial(monu,A[monu])+mon_val[mon_num][3] printf("mond: ");set mond dial(mond,A[mond])+mon_val[mon_num][7] }' # # # # ################################################################################ # # mono_calc_energy_range # # hp 05.12.2000 # # calculates energy range for the monochromator, calls _mono_calc_energy_range # ################################################################################ # def mono_calc_energy_range ' { printf("\nmono_calc_energy_range (hp) 05.12.2000\n\n") _mono_calc_energy_range g_mo_d g_mo_s printf("%.1f - %.1f keV\n\n",mon_low_ener,mon_high_ener) }' # # # # ################################################################################ # # _mono_calc_energy_range # # hp 05.12.2000 # # calculates energy range for the monochromator # ################################################################################ # def _mono_calc_energy_range ' { local x,d,s,low,high if ($# == 0) { d = g_mo_d s = g_mo_s } else if ($# == 2) { d = $1 s = $2 } else { printf("usage: mono_calc_energy_range g_mo_d g_mo_s\n") exit } d = $1 s = $2 low = get_lim(montrav,-1)-montrav_offset high = get_lim(montrav,+1)-montrav_offset x = 0.5*atan(s/low) mon_low_ener = hc_over_e/(2*d*sin(x)) x = 0.5*atan(s/high) mon_high_ener = hc_over_e/(2*d*sin(x)) }' # # # # ################################################################################ # # mono_show_all # # hp 05.12.2000 # # displays settings for all employed monochromators # ################################################################################ # def mono_show_all ' { local i printf("\nmono_show_all (hp) 05.12.2000\n\n") printf("actual used monochromator : %g (%s)\n\n",mon_num,mon_name[mon_num]) for (i=0;i<=mon_anz;i++) { printf("\n\n") _mono_show_settings i } }' # # # # ################################################################################ # # mono_show_settings # # hp 01.12.2000 # # displays settings for the different monochromator crystal pairs # ################################################################################ # def mono_show_settings ' { local num printf("\nmono_show_settings (hp) 01.12.2000\n\n") printf("actual used monochromator : %g (%s)\n\n",mon_num,mon_name[mon_num]) if ($# == 0) { num = mon_num } else if ($# == 1) { num = $1 if (num != mon_num) printf("settings shown for monochromator: %g (%s)\n",num,mon_name[num]) } else { printf("usage: mono_show_settings [n]\n") exit } if (num<0 || num>mon_anz) { printf("Only 0 to %u are valid monochromator crystal pairs\n",mon_anz) } else { _mono_show_settings num } }' # # # # ################################################################################ # # _mono_show_settings # # hp 01.12.2000 # # called by mono_show_settings and setmono # ################################################################################ # def _mono_show_settings ' { local nn if ($# != 1) { printf("usage: _mono_show_settings n\n") exit } nn = $1 if (nn<0 || nn>mon_anz) { printf("Only numbers between 0 and %u are valid monochromator crystal pairs\n",mon_anz) } else { printf("monochromator no. %u : %s\n",nn,mon_name[nn]) _mono_calc_energy_range mon_val[nn][1] mon_val[nn][2] printf("Energy range : %.1f - %.1f keV\n",mon_low_ener,mon_high_ener) printf("montrav (m2_z) offset : %.4f mm\n",montrav_offset) printf("d-spacing : %f Angstroem\n",mon_val[nn][1]) printf("fixed exit distance : %.1f mm\n",mon_val[nn][2]) printf(" crystal 1 crystal 2\n") printf("offset omega : %8.4f degree %8.4f degree\n",mon_val[nn][3],mon_val[nn][7]) printf("crystal pos.(m?_xtal) : %8.4f mm %8.4f mm\n",mon_val[nn][4],mon_val[nn][8]) printf("chi : %8.4f degree %8.4f degree\n",mon_val[nn][5],mon_val[nn][9]) printf("phi : %8.4f degree %8.4f degree\n",mon_val[nn][6],mon_val[nn][10]) } }' # # # # ################################################################################ # # calcM_6idd # # hp 10.11.2000 # # correct offset in montrav caused by homeposition. # ################################################################################ # def calcM_6idd ' { A[montrav] = A[montrav]+montrav_offset }' # # # # ################################################################################ # # mono_align_crystals # # hp 05.12.2000 # # align monochromator to specific energy # ################################################################################ # def mono_align_crystals ' { local pos_monu,pos_mond,pos_montrav printf("\nmono_align_crystals (hp) 05.12.2000\n\n") waitmove get_angles pos_monu = A[monu] pos_mond = A[mond] pos_montrav = A[montrav] printf("Original Monochomator position:\nmonu = %f\nmond = %f\nmontrav = %f\n",pos_monu,pos_mond,pos_montrav) printf("Step 1: Prealign monochromator crystal 1 (monu)\n") lup monu -0.05 0.05 100 mon_count_time umv monu CEN waitmove get_angles printf("monu prealigned to %f\n\n",A[monu]) printf("Step 2: Determine beam position on crystal 2\n") _mono_calc_crystal_width _mono_align_crystals 0.5*mon_crystal_width 0.5*2*mon_crystal_width/30 printf("Original Monochomator position:\nmonu = %f\nmond = %f\nmontrav = %f\n",pos_monu,pos_mond,pos_montrav) }' # # # # ################################################################################ # # _mono_align_crystals # # hp 05.12.2000 # # scans mond for several monu positions. Called by mono_align_crystals # ################################################################################ # def _mono_align_crystals ' { local i,pos,dist,step,anz,ii if ($# != 2) { printf("usage: _mono_align_crystals distance stepwidth n\n") exit } dist = $1 step = $2 if (dist<=0) { printf("distance must be a positive value!\n") exit } if (step<=0) { printf("stepwidth must be a positive value!\n") exit } waitmove get_angles anz = int(2*dist/step) pos = A[monu]+dist ugmvr monu -dist mond -dist i = A[monu] printf("%u scans will be executed during this macro\n",anz) printf("Distance: %f\n",dist) printf("stepwidth: %f\n",step) ii = 1 printf("\nStarting scan %u, monu = %f, mond = %f\n",ii,A[monu],A[mond]) lup monu -0.5*mon_val[mon_num][12]*mon_scan_range_scale 0.5*mon_val[mon_num][12]*mon_scan_range_scale mon_peak_points*mon_scan_range_scale mon_count_time while (imon_anz)) { eprint "_mono_calc_crystal_width: no mono defined (mon_num = ",mon_num,")" exit } a = A[montrav]-montrav_offset b = mon_val[mon_num][2] c = mon_val[mon_num][11] mon_crystal_width = deg(atan(b/(a-0.5*c))-atan(b/(a+0.5*c))) p a,b,c,mon_crystal_width }' # # # # ################################################################################ # # _mono_save_values_automatic # # hp 10.05.2001 # # automatically make backups of monochromator settings # ################################################################################ # def _mono_save_values_automatic '{ local uc1,ar1,ar2 split(date(),ar1) split(ar1[3],ar2,":") uc1 = sprintf("cp -p %s.mac %s_%s_%s_%s_%s.%s.%s.mac",mon_file_name, \ mon_file_name,ar1[4],ar1[1],ar1[2],ar2[0],ar2[1],ar2[2]) # print uc1 _mono_save_values unix(uc1) }' # # # # ################################################################################ # # mono_save_values # # hp 29.01.2001 # # saves all global variables to a file. # ################################################################################ # def mono_save_values '{ local filename printf("\nmono_save_values (hp) 29.01.2001\n\n") if ($# != 1) { printf("usage: mono_save_values filename\n") exit } _mono_save_values "$*" }' # # # # ################################################################################ # # _mono_save_values # # hp 29.01.2001 # # saves all global variables to a file. # ################################################################################ # def _mono_save_values '{ local i,j,u1,filename if ($# > 1) { printf("usage: _mono_save_values [filename]\n") exit } if ($# == 1) { filename = "$1" } else { filename = sprintf("%s%s",mon_file_name,".mac") # filename = "mono_settings.mac" } u1 = sprintf("rm %s\n",filename) unix(u1) open(filename) fprintf(filename,"# written by _mono_save_values (hp) 29.01.2001\n") fprintf(filename,"# Created at: %s\n",date()) for(i=0;i<=mon_anz;i++) { fprintf(filename,"mon_name[%g] = %c%s%c\n",i,34,mon_name[i],34) for(j=0;j<13;j++) { fprintf(filename,"mon_val[%g][%g] = %f\n",i,j,mon_val[i][j]) } } close(filename) }' # # # # ################################################################################ # # _mono_determine_crystal # # hp 10.05.2001 # # determines used monochromator crystal from motor position # ################################################################################ # def _mono_determine_crystal ' { local i,pos,abw,mabw waitmove get_angles pos = A[m1_xtal] abw = 1.0 mabw = 4 for(i=0;i<=mon_anz;i++) { if ((mon_val[i][mabw]pos-abw)) { mon_num = i } } if (mon_num<0) { printf("\n\nNo automatic determination which monochromator is in use\n") printf("was possible!\n\n") } else { printf("\nMonochromator pair %u (%s) is in use.\n",mon_num,mon_name[mon_num]) } } ' # # # ################################################################################ # # _setmono # # hp 04.12.2000 # # original setmono macro, replaced by special macro for 6ID-D beamline. Use # _setmono if for any reason you want to use the original macro. # ################################################################################ # # setmono - Sets d-spacing and offset, if applicable. def _setmono '{ local f, has_off, use_file _1 = g_mo_d _2 = g_mo_s has_off = mono_type == 2 || mono_type == 3 f = mono_settings() if (!file_info(f)) { # file does not exist if (unix(sprintf("cp /dev/null %s 2>/dev/null", f))) { # file cannot be created eprintf("\n\ According to the mono_settings() macro, monochromator parameters\n\ are kept in \"%s\".\n\n\ That file doesn\'t exist, and you don\'t have permission to\n\ create the file. Have the system administrator address the\n\ permission issues. In the meantime, the parameters will be\n\ kept in your state file as with other global variables.\n", f); use_file = 0 } else use_file = 1 } else { # file exists if (!file_info(f, "-w")) { # file cannot be updated eprintf("\n\ Monochromator parameters are kept in\n\ \"%s\".\n\n\ You don\'t have permission to change that file.\n\ Have the system administrator make the file writable\n\ by you if that is appropriate. In the meantime,\n\ the current parameters will be read from the file.\n", f); if (file_info(f, "-r")) { printf("\n") read_mono(f) } else eprintf("Yikes! %s is unreadable.\n", f) use_file = -1 } else use_file = 1 } if (use_file >= 0) { if ($# == 1) _1 = $1 else if ($# == 2 && has_off) { _1 = $1; _2 = $2; } else if ($# == 0) { _1 = getval("\n\ Enter monochromator d-spacing ... \n or type 0 to enter crystal type",_1) if (_1+0 == 0) miller if (has_off) _2 = getval("\ Enter monochromator separation in millimeters", _2) } else { if (has_off) eprint "Usage: setmono or setmono d [s]" else eprint "Usage: setmono or setmono d" exit } if (_1 != g_mo_d || (has_off && _2 != g_mo_s)) { if (use_file) { unix(sprintf("cp /dev/null %s", f)) fprintf(f,"\ # Mono parameters last changed on %s by %s\n\n\ if (g_mo_d != %g) {\n\ print \"Monochromator d-spacing is %g Angstroms.\" qcomment \"g_mo_d reset from %%g to %%g\" \"g_mo_d,%g\"\n\ }\n\ constant g_mo_d %g\n\n", date(),USER,_1,_1,_1,_1) if (has_off) fprintf(f, "\ if (g_mo_s != %g) {\n\ print \"Monochromator offset is %g mm.\" qcomment \"g_mo_s reset from %%g to %%g\" \"g_mo_s,%g\"\n\ }\n\ constant g_mo_s %g\n", _2,_2,_2,_2) close(f) printf("\n") read_mono(f) } else { printf("\nMonochromator d-spacing is %g Angstroms.\n",_1) qcomment "g_mo_d reset from %g to %g" "g_mo_d,_1" constant g_mo_d _1 if (has_off) { printf("Monochromator offset is %g mm.\n",_2) qcomment "g_mo_s reset from %g to %g" "g_mo_s,_2" constant g_mo_s _2 } } } } }' # # # # ################################################################################ # # setE # # hp 02.08.2000 # hp 17.05.2001 # # setE is only a link to mono_accept_position # ################################################################################ # def setE ' { mono_accept_position $* } ' # # # # ################################################################################ # # calcM_6idd_korr # # hp 01.05.2000 # # Korrigiert Abweichungen bei Bewegung des 2. Monochromatorkristalls # Suche nach Korrekturwerten startet beim letzten benutzten Wert und ist folglich # für kleine Monochromatorbewegungen schneller # ################################################################################ # global definitions # # global mon_cor_array,mon_cor_array_max,mon_cor_array_act # array mon_cor_array[100][2] # # mon_cor_array: array to correct theta value of second analyser # mon_cor_array_max: number of last array value # # #def calcM_6idd_korr ' { # local pos,v,uv,lv,i,val,anteil,min,max # pos = A[montrav] # i = mon_cor_array_act # v = mon_cor_array[i][0] # uv = v # lv = v # min = mon_cor_array[0][0] # max = mon_cor_array[mon_cor_array_max][0] # # p pos # if (pos>=min && pos<=max) { # if (pos>v) { # while(pos>uv) { # i = i+1 # uv = mon_cor_array[i][0] # p i,uv # } # i = i-1 # } # if (pos