################################################################################# # Package: energy_epics_DCM.mac # Macros to control the 33BM-C DCM and Mirrors. It replaces the stardard # energy.mac. The file is loaded in fourc/conf.mac. # # Author: Xuesong Jiao # Date: May, 30,2006 # # User Macros: moveE en_in_KeV # getE # Escan start finish intervals time # showmono # setmono xtal_mode # mirror_in # mirror_out # cenmono en_in_Kev # xafs_setDCM en_in_KeV mirror_alpha mirror_bender # # Internal Macros/Functions: calcM en_in_KeV # calcE # softlimits(mirror_alpha,xtal_mode) # waitmono # show_mirrors # pa_mono ################################################################################# #-------------------- EPICS PVs of the DCM-Mirrors controls-------------------# global PV_en global PV_monz PV_mony global PV_lambda PV_allstop PV_mono_ALLDONE PV_braggth PV_ydcm PV_xtalmode PV_dhkl global PV_usemirror PV_m1alpha PV_m1y PV_m1b PV_m2alpha PV_m2y PV_m2b PV_en = "hnl:md:energy" PV_mony ="hnl:m58:c0:m2.RBV" PV_monz = "hnl:m58:c1:m1.RBV" PV_lambda = "hnl:md:lambda.RBV" PV_allstop = "hnl:md:allstop" PV_mono_ALLDONE="hnl:md:alldone" PV_braggth = "hnl:md:thetab.RBV" PV_ydcm = "hnl:md:y_dcm" PV_xtalmode = "hnl:md:crystal_mode" PV_dhkl = "hnl:md:d_hkl" PV_usemirror="hnl:md:useMirrors" PV_m1alpha="hnl:md:m1alpha" PV_m1y="hnl:md:m1y" PV_m1b="hnl:m58:c2:m8" PV_m2alpha="hnl:md:m2alpha" PV_m2y="hnl:md:m2y" PV_m2b="hnl:m58:c3:m8" #----------------- global variables for energy soft limits calculation----------# global ZDCM_M1 DCMY1_LLM DCMZ2_HLM DCM_ENLLM DCM_ENHLM ZDCM_M1=2200.0 DCMY1_LLM = epics_get("hnl:m58:c0:m2.LLM") DCMZ2_HLM = epics_get("hnl:m58:c1:m1.HLM") DCM_ENHLM = epics_get(sprintf("%s.HLM",PV_en)) DCM_ENLLM = epics_get(sprintf("%s.LLM",PV_en)) constant hc_over_e 12.39842 #--------------- a wait time for waitmono that ensures the encoder is value is updated--# global epics_delay epics_delay = 0.2 # you can adjust it to 0.5 if the energy step is very small #---------------- User macros ---------------------------------------------------------# #getE - get the current energy def getE ' waitmono;get_angles;calcE printf("E= %g KeV, %g Angstroms\n",epics_get(sprintf("%s.RBV",PV_en)),LAMBDA) ' #moveE - move DCM to get the required energy def moveE ' if ($# !=1) { eprint "Usage: moveE energy_in_KeV" exit } if($1 <=0) { eprint "Can only deal with positive energies." exit } rdef cleanup_once \' epics_put(PV_allstop,1) \' waitmono;waitmove; get_angles;calcM $1 epics_put(sprintf("%s.VAL",PV_en),$1); move_em;waitmove;waitmono;get_angles;calcE ' #setE - re-set the energy, useful for energy calibration def setE ' if ($# !=1) { eprint "Usage: setE energy_in_KeV" exit } else { local oldE if ($1 <=0) { eprint "Can only deal with positive energies." exit } waitmove;waitmono;get_angles;calcM $1 oldE = epics_get(sprintf("%s.RBV),PV_en)) epics_put(sprintf("%s.SET",PV_en),1); epics_put(PV_en,$1); epics_put(sprintf("%s.SET",PV_en),0); get_angles;calcE printf("Monochromator set to % KeV from %g KeV", \ epics_get(sprintf("%s.RBV",PV_en)), oldE ) ; } ' # Escan - scan energy def Escan ' if ($# != 4 && $# != 5 || $# == 5 && "$5" != "fixQ") { eprint "\ Usage: Escan start finish intervals time [fixQ]\n\ (Units are KeV)\n\ (the literal \"fixQ\" means keep HKL constant)" exit } { _s1 = $1; _f1 = $2; _n1 = int($3); _ctime = $4; } if (_n1 <= 0) { eprint "Number of Intervals <= 0" exit } if (_s1 <= 0 || _f1 <= 0) { eprint "Can only deal with positive energies." exit } _bad_lim = 0 _chk_mlim _s1 _chk_mlim _f1 if (_bad_lim) exit HEADING = sprintf("Escan %g %g %g %g%s",$1,$2,$3,$4,$#>4?" $5":"") _d1 = (_f1 - _s1) / _n1++ X_L = "Energy (keV)" Y_L = cnt_name(DET) _sx = _s1; _fx = _f1 FPRNT=sprintf("Energy Braggth ") PPRNT=sprintf("%9.9s %9.9s ", "Energy","Braggth") _stype = 1|(1<<8) _cols=2 mono_mode = epics_get(PV_xtalmode,"short"); if (mono_mode == 0) { #normal FPRNT=sprintf("%s%s %s ",FPRNT,"mony","monz" ) PPRNT=sprintf("%s%9.9s %9.9s ",PPRNT,"mony","monz") _stype = 1|(3<<8) _cols=4 } if (mono_mode == 1) { FPRNT=sprintf("%s%s ",FPRNT,"monz") PPRNT=sprintf("%s%9.9s ",PPRNT,"monz") _stype = 1|(2<<8) _cols=3 } if (mono_mode == 2) { FPRNT=sprintf("%s%s ",FPRNT,"mony") PPRNT=sprintf("%s%9.9s ",PPRNT,"mony") _stype = 1|(2<<8) _cols=3 } VPRNT=PPRNT scan_head def _scan_on \' { local h_ca k_ca l_ca if ("$5" == "fixQ") { h_ca = H k_ca = K l_ca = L } for (; NPTS < _n1; NPTS++) { local E get_angles E = _s1 + NPTS * _d1 calcM E; calcE E if ("$5" == "fixQ") { H = h_ca K = k_ca L = l_ca calcA } moveE E scan_move; calcE; E = epics_get(sprintf("%s.RBV",PV_en)); FPRNT=sprintf("%g %.8g ",E,epics_get(PV_braggth)) PPRNT=sprintf("%9.4f %9.4f ",E,epics_get(PV_braggth)) if (mono_mode == 0) { FPRNT=sprintf("%s%.8g %.8g ",FPRNT,epics_get(PV_mony),epics_get(PV_monz)) PPRNT=sprintf("%s%9.4f %9.4f ",PPRNT,epics_get(PV_mony),epics_get(PV_monz)) } if (mono_mode == 1) { FPRNT=sprintf("%s%.8g ",FPRNT,epics_get(PV_monz)) PPRNT=sprintf("%s%9.4f ",PPRNT,epics_get(PV_monz)) } if (mono_mode == 2) { FPRNT=sprintf("%s%.8g ",FPRNT,epics_get(PV_mony)) PPRNT=sprintf("%s%9.4f ",PPRNT,epics_get(PV_mony)) } VPRNT=PPRNT scan_loop scan_data(NPTS, E) scan_plot } } scan_tail \' _scan_on ' # _chk_mlim - Used by Escan in prescan motor limit checks. def _chk_mlim ' calcM $1 ' # pa_mono - Used by "pa" to display parameters. def pa_mono ' printf(" Monochromator:\n") printf(" d-spacing = %g Angstroms\n", epics_get(PV_dhkl)) printf(" Y_offset = %g mm\n", epics_get(PV_ydcm)) printf(" Operation Mode: %s\n",epics_get(PV_xtalmode)) if(epics_get(PV_usemirror,"short")) { # mirrors in use printf(" Mirrors:\n") showmirrors } else { printf(" Mirrors are not used\n") } ' #showmono - same as pa_mono def showmono ' pa_mono ' #showmirrors - called by showmono, to display mirror status def showmirrors ' printf(" mirror 1: alpha=%9.4f ypos=%9.4f bender=%9.4f\n",\ epics_get(sprintf("%s.RBV",PV_m1alpha)),\ epics_get(sprintf("%s.RBV",PV_m1y)),\ epics_get(sprintf("%s.RBV",PV_m1b))) printf(" mirror 2: alpha=%9.4f ypos=%9.4f bender=%9.4f\n",\ epics_get(sprintf("%s.RBV",PV_m2alpha)),\ epics_get(sprintf("%s.RBV",PV_m2y)),\ epics_get(sprintf("%s.RBV",PV_m2b))) ' #mirror_in - puts mirrors into use; the mono mode stays as normal after this def mirror_in ' #make sure DCM in normal mode rdef cleanup_once \' epics_put(PV_allstop,1) \' setmono 0 epics_put(PV_usemirror,1) printf("\nNow moving mirror in ...") waitmono ' # mirror_out - remove mirrors from beam; the mono mode stays as normal after this def mirror_out ' rdef cleanup_once \' epics_put(PV_allstop,1) \' setmono 0 epics_put(PV_usemirror,0) printf("\nNow moving mirrors out...") waitmono ' # cenmono - after mirror_in or mirror_out, cenmono should be called to align y1 and # z2 for the desired energy def cenmono ' if ($# != 1) { eprint "Usage: cenmono energy." eprint " This puts the y1 and z2 to the optimal position for desired energy" exit } setmono 0 print "\nMoving bragg angle, y1 and z2 for the desired engery..." moveE $1 print "\Done." ' #setmono - set DCM and mirrors def setmono ' if($#!= 1) { eprint "Usage: setmono operation_type." eprint " operation type can be 0 1 2 3 for normal fixy fixz and channel cut." exit } if( $1 == 0 || $1 =="normal") { epics_put(PV_xtalmode,0) } if( $1 == 1 || $1 == "fixy" || $1 =="fixy1") { epics_put(PV_xtalmode,1) } if( $1 == 2 || $1 == "fixz" || $1 =="fixz2") { epics_put(PV_xtalmode,2) } if( $1 ==3 || $1 == "ccut" || $1 == "channel_cut") { epics_put(PV_xtalmode,3) } printf("Monochromator mode set to %s",epics_get(PV_xtalmode)) ' #xafs_setDCM - an example to show how to use the above macros for 33BMC XAFS expeirments def xafs_setDCM ' if($# != 3 ) { eprint "Usage: xafs_setDCM en_in_KeV mirror_alpha_in_mr mirror_bender_in_mm" exit } waitmono; epics_put(PV_m1alpha,$2) epics_put(PV_m1b,$3) waitmono; cenmono $1 setmono 3 showmono ' #-------------------- Internal macros and functions --------------------------------# #calcE - updates the LAMBDA according to the energy value def calcE ' if($# == 0) { LAMBDA = epics_get(PV_lambda) calcE_local } if($#==1) { LAMBDA = hc_over_e/($1) } ' # caclM - checks the energy softlimits to make sure the target energy is valid for the current # mono mode and mirror settings def calcM '{ local mode muse eslm[] alpha if ($# != 1) { eprint "Usage: clacM energy_in_Kev" exit } mode = epics_get(PV_xtalmode,"short") eslm[0]= DCM_ENLLM eslm[1]= DCM_ENHLM if(mode != 3) { local foo[] muse = epics_get(PV_usemirror,"short") alpha = epics_get(sprintf("%s.RBV",PV_m1alpha)) foo = softlimits(alpha,muse) if (mode == 0) {eslm[0]= (foo[0]>DCM_ENLLM)?foo[0]:DCM_ENLLM;eslm[1]=foo[1];} if (mode == 1) eslm[1] = foo[1] if (mode == 2) eslm[0] = (foo[0]>DCM_ENLLM)?foo[0]:DCM_ENLLM } if(($1)==0 || $1>eslm[1] || $1