#%TITLE% MSCAN.MAC
#%NAME%
# Macro for special mirror scans to determine its shape
#
#%CATEGORY% Scans
#
#%DESCRIPTION%
# The incoming beam will be scanned in height and at each point the
# outgoing reflection will be searched with another scan.
# You will need a motor which can scan the beam up and down ( a
# pinhole for example) and a motor which scans a one dimensional
# detector up and down (like a wire monitor or a slit).
# The resulting data can be treated with a special program (contact us)
#
#%UU%
#%MDESC%
# Sets the scan up. the following questions will be asked:
# %DL%
# %DT% Factor to multiply FWHM to get new scan width %DD%
# After the first wire scan, the new scan will be done around the
# the point where the beam should be for a plane mirror.
# %DT% Minimum FWHM to accept a peak as a peak %DD%
# %DT% Minimum max_counts to accept peak %DD%
# Both questions are to define the beam on the wire monitor
# %DT% Distance Mirror-zero to wire monitor [m] %DD%
# %DT% Mirror Angle (for Slope Error) [mrad] %DD%
# Questions about the geometrical setup of your experiment
# %DT% Do you want to do a regular check scan %DD%
# A regular checkscan with the beam going back to 0 and a wire scan
# can be done to be sure not to loose steps. All the following
# questions are for these checkscans
#
# %DT% Interval between check scans (1,2,..) %DD%
# %DT% From Position %DD%
# %DT% To Position %DD%
# %DT% No of points %DD%
# %DT% Count time %DD%
# %XDL%
def mscansetup '
global MSC_FACTOR MSC_MINCOUNTS MSC_MINFWHM MSC_Q MSC_TH
global MSC_GRPRES MSC_GRPMEA MSC_RESNO MSC_MEANO
global MSC_CHECK MSC_CSTART MSC_CEND MSC_NOPTS MSC_CTIME
global MSC_INPUT
MSC_GRPRES = 46
MSC_GRPMEA = 47
data_grp(MSC_GRPRES,4096,3)
data_grp(MSC_GRPMEA,4096,4)
MSC_FACTOR=getval("Factor to multiply FWHM to get new scan width",MSC_FACTOR)
MSC_MINFWHM = getval ("Minimum FWHM to accept a peak as a peak",MSC_MINFWHM)
MSC_MINCOUNTS = getval("Minimum max_counts to accept peak",MSC_MINCOUNTS)
MSC_Q = getval("Distance Mirror-zero to wire monitor [m]",MSC_Q)
MSC_TH = getval("Mirror Angle (for Slope Error) [mrad]",MSC_TH)
if (MSC_CHECK = yesno("Do you want to do a regular check scan",MSC_CHECK)){
MSC_FRQ = getval("Interval between check scans (1,2,..) ",MSC_FRQ)
MSC_CSTART = getval("From Position",MSC_CSTART)
MSC_CEND = getval("To Position",MSC_CEND)
MSC_NOPTS = getval("No of points",MSC_NOPTS)
MSC_CTIME = getval("Count time",MSC_CTIME)
}
'
#%UU% <mot1 s1 f1 intervals1 mot2 s2 f2 intervals2 time>
#%MDESC%
# Derived from a standard spec mesh scan. The mot1 will be the wire
# (or beam monitor) and mot2 the pinhole (beam scan motor)
#
#
def mscan '
global MSC_FSTART MSC_SSTART
global MSC_FSTART2 MSC_SSTART2
if ($# != 9) {
print \
"Usage: mscan mot1 s1 f1 intervals1 mot2 s2 f2 intervals2 time"
exit
}
MSC_INPUT="$0"
_check0 "$1"; _check0 "$5"
{
_m[0] = $1; _s1 = $2; _f1 = $3; _n1 = int($4)
_m[1] = $5; _s2 = $6; _f2 = $7; _n2 = int($8)
_ctime = $9
}
if (_n1 <= 0 || _n2 <= 0) {
print "Intervals <= 0"
exit
}
_bad_lim = 0
_chk_lim _m[0] _s1
_chk_lim _m[0] _f1
_chk_lim _m[1] _s2
_chk_lim _m[1] _f2
if (_bad_lim) exit
MSC_FSTART = _f1 ; MSC_SSTART = _s1 ;
MSC_FSTART2 = _f2 ; MSC_SSTART2 = _s2 ;
MSC_RESNO = 0 ; MSC_MEANO = 0
HEADING = sprintf("mscan $1 %g%s %g%s %g $5 %g%s %g%s %g %g",\
($2)*UN,UL, ($3)*UN,UL, $4, ($6)*UN,UL, ($7)*UN,UL, $8, $9)
_d1 = (_f1 - _s1) / _n1++; _d2 = (_f2 - _s2) / _n2++
_nm=2
_cols=2+_hkl_col
X_L = "$1"; _sx = _s1*UN; _fx = _f1*UN
Y_L = cnt_name(DET)
_stype = 1|8|(2<<8)
FPRNT=sprintf("%s %s ",motor_name(_m[0]),motor_name(_m[1]))
PPRNT=sprintf("%8.8s %8.8s ",motor_name(_m[0]),motor_name(_m[1]))
VPRNT=sprintf("%9.9s %9.9s ",motor_name(_m[0]),motor_name(_m[1]))
FPRNT=sprintf("%s%s ",FPRNT,_hkl_sym1)
scan_head
PFMT=sprintf("%%8.%df %%8.%df ",UP,UP)
VFMT=sprintf("%%9.%df %%9.%df ",UP,UP)
_g2 = 0
_g1 = _n1
def _scan_on \'
for (; _g2 < _n2; _g2++){
msc_checksteps
A[_m[1]] = _s2 + _g2 * _d2
if (_g1 == _n1) {
_g1 = 0;
NPTS=0
}
for (; _g1 < _n1; _g1++, NPTS++) {
A[_m[0]] = _s1 + _g1 * _d1
scan_move
FPRNT=sprintf("%g %g ",A[_m[0]]*UN,A[_m[1]]*UN)
PPRNT=sprintf(PFMT,A[_m[0]]*UN,A[_m[1]]*UN)
VPRNT=sprintf(VFMT,A[_m[0]]*UN,A[_m[1]]*UN)
FPRNT=sprintf("%s%s ",FPRNT,_hkl_val)
scan_loop
data_nput(PL_G,_g1,A[_m[0]]*UN, S[DET])
scan_plot
}
msc_calcpars
}
scan_tail
msc_calcres
mscslope
\'
_scan_on
'
def msc_calcpars '
{
mfwhm = msc_FWHM ; cfwhm = msc_CFWHM ; mmax = msc_MAX
data_nput(MSC_GRPMEA,MSC_MEANO++,_s2+_g2*_d2,cfwhm,mfwhm,MSC_CHECKPOS)
mfwhm = (mfwhm < MSC_MINFWHM) ? MSC_MINFWHM : mfwhm
if (mmax < MSC_MINCOUNTS) {
_s1 = MSC_SSTART
_f1 = MSC_FSTART
} else {
_s1 = cfwhm - MSC_FACTOR/2*mfwhm- _d2
_f1 = cfwhm + MSC_FACTOR/2*mfwhm- _d2
_s1 = (_s1< MSC_SSTART) ? MSC_SSTART : _s1
_f1 = (_f1> MSC_FSTART) ? MSC_FSTART : _f1
msc_res
}
_n1 = int((_f1-_s1)/_d1+1)
_g1 = _n1
} '
def msc_res '
#Calc profile and deviat.
offset = (_s2+_d2*_g2)
xideal = MSC_Q*1000*sin(2*MSC_TH/1000) - offset
xshift = cfwhm - xideal
slope = xshift / (MSC_Q-offset/sin(2*MSC_TH/1000)) * 1000
mpos = offset / sin(MSC_TH/1000)
data_nput(MSC_GRPRES,MSC_RESNO++,mpos,slope)
'
def msc_calcres '
# Calc integral
{
data_put(MSC_GRPRES,0,2,0)
for (uu=1,integral = 0;uu<MSC_RESNO;uu++) {
integral += (data_get(MSC_GRPRES,uu-1,1)+data_get(MSC_GRPRES,uu,1))/2
data_put(MSC_GRPRES,uu,2,integral)
}
}
'
def mscslope '
Y_L = "slope"; X_L = "Mirror position [mm]"
plot_cntl("filter2")
plot_cntl("-ylog")
plot_cntl("dots")
plot_cntl("lines")
plot_cntl("-ebars")
splot MSC_GRPRES 0 1
plot_cntl("filter1")
'
def mscpos '
Y_L = "Position [um]"; X_L = "Mirror position [mm]"
plot_cntl("-ylog")
plot_cntl("dots")
plot_cntl("lines")
plot_cntl("-ebars")
splot MSC_GRPRES 0 2
'
def msc_checksteps '
{
if (MSC_CHECK && (MSC_TURN == 0)) {
local uu _dd
A[_m[1]] = s2+0;
_dd = (MSC_CSTART - MSC_CEND) / MSC_NOPTS;
for (uu=0;uu<MSC_NOPTS+1;uu++) {
A[_m[0]] = MSC_CSTART + uu * _dd
scan_move
scan_count (MSC_CTIME)
data_nput(PL_G,uu,A[_m[0]]*UN, S[DET])
}
MSC_CHECKPOS= msc_CFWHM
} else {
MSC_CHECKPOS=0
}
if (++MSC_TURN >= MSC_FRQ) MSC_TURN=0
}'
#%UU%
#%MDESC%
# Print the results from the last scan on the screen
#
def mscshow '
{
local i
printf("#C Date: %s User: %s Version: %s\n",date(),USER,SPEC)
printf("#C Command: mscan %s\n",MSC_INPUT)
printf("#C Factor: %f Min FWHM: %f Min Counts: %f Distance %f [m] Theta %f [mrad]\n",MSC_FACTOR ,MSC_MINFWHM,MSC_MINCOUNTS,MSC_Q,MSC_TH)
if (MSC_CHECK) {
printf ("#C Check Scan: Freq. %d Start: %f End: %f Pts: %f Time:%f\n",\
MSC_FRQ,MSC_CSTART,MSC_CEND,MSC_NOPTS,MSC_CTIME)
}
printf("#C Measured Values:\n")
printf("%3s %10s %10s %10s %10s \n","No","Slit","Wire-Center","FWHM","Check Pos")
for (i=0;i<MSC_MEANO;i++) {
printf("%3d %10f %10f %10f %10f\n",i+1,data_get(MSC_GRPMEA,i,0),data_get(MSC_GRPMEA,i,1), data_get(MSC_GRPMEA,i,2),data_get(MSC_GRPMEA,i,3))
}
printf("#C Calulated Mirror Position (Approximation)\n")
printf("%3s %10s %10s %10s\n","No","M-Pos","Slope","Integral")
for (i=0;i<MSC_RESNO;i++) {
printf("%3d %10f %10f %10f \n",i+1,data_get(MSC_GRPRES,i,0),data_get(MSC_GRPRES,i,1), data_get(MSC_GRPRES,i,2))
}
}'
def msc_MAX 'data_anal(PL_G,0,0, 0,PL_Y,"max")'
def msc_FWHM 'data_anal(PL_G,0,0, 0,PL_Y,"fwhm")'
def msc_CFWHM 'data_anal(PL_G,0,0, 0,PL_Y,"cfwhm")'
#%MACROS%
#%IMACROS%
#%AUTHOR% JK
#%TOC%
|