esrf

Beamline Instrument Software Support
SPEC Macro documentation: [ Macro Index | BCU Home ]

#%TITLE% KSCAN.MAC 
#%NAME%
#   Macros to perform scans on K.
#%CATEGORY% Scans
#%DESCRIPTION%
#   This macro set allows to make scans in energy with several
#   regions around an edge. 
#   Each region can have different spacing between points as
#   well as to have different collection time per region.
#%SETUP%
#   A pseudo motor energy has to be available.
#   By default a set of parameters is given. This set of parameters
#   can be implemented by a call to the macro kscan_defaults.
#   Otherways the parameters can be changed by calling to kscan_setup.
#%EXAMPLE%
#   kscan energy_motor 7.111 2
#   Performs a kscan of the motor energy_motor whith 7.111 taken as
#   the edge energy (all parameters in kscan are referred to the edge
#   position in order to allow a single profile to be used at different
#   edges). 
#%END%

#%UU%(k)
#%MDESC%
# Given a value of k, returns the corresponding value in energy above
# the edge in eV.
#
def kscan_calcE(k) '{
	return((k/0.51242415)*(k/0.51242415))
}'

#%UU%(energy_in_eV)
#%MDESC%
# Given a value of the energy (in eV above the edge) as input, returns
# the corresponding value in k.
#
def kscan_calcK(delta_e_in_eV)'{
	return(0.51242415*sqrt(delta_e_in_eV))
}'

#%UU%
#%MDESC%
# Interactive definition of the kscan
#
def kscan_setup '{
local i
global KSCAN_N_PRE KSCAN_N_POST
global KSCAN_PRE KSCAN_POST
global KSCAN_EDGE_1 KSCAN_EDGE_2 KSCAN_EDGE_INC KSCAN_EDGE_T KSCAN_EDGE_K
global KSCAN_E0
global KSCAN_NPTS KSCAN_TIME
array KSCAN_E [4000] KSCAN_T [4000]

KSCAN_N_PRE=getval("Enter number of  pre-edge regions ",KSCAN_N_PRE)
KSCAN_PRE [0] [0] = KSCAN_PRE [0] [0]
for (i=0;i<KSCAN_N_PRE;i++){
printf("Defining pre-edge region %i\n",i+1) 
KSCAN_PRE [i] [0] = getval("Enter energy relative to edge (in eV)",KSCAN_PRE [i] [0]) 
KSCAN_PRE [i] [1] = getval("Enter energy increment (in eV)",KSCAN_PRE [i] [1]) 
KSCAN_PRE [i] [2] = getval("Enter collection time in seconds",KSCAN_PRE [i] [2]) 
}

KSCAN_EDGE_1=getval("Enter starting edge region energy (in eV relative to edge):",KSCAN_EDGE_1)
KSCAN_EDGE_2=getval("Enter final  edge  region  energy (in eV relative to edge):",KSCAN_EDGE_2)
KSCAN_EDGE_INC=getval("Enter energy increment in edge region:",KSCAN_EDGE_INC)
KSCAN_EDGE_T=getval("Enter collection time in seconds:",KSCAN_EDGE_T)
KSCAN_EDGE_K=kscan_calcK(KSCAN_EDGE_2)

KSCAN_POST [0] [0] = KSCAN_POST [0] [0]
KSCAN_N_POST=getval("Enter number of  post-edge regions ",KSCAN_N_POST)
printf("Your edge region ends at k = %f\n",KSCAN_EDGE_K)
for (i=0;i<KSCAN_N_POST;i++){
printf("Defining post-edge region %i\n",i+1) 
KSCAN_POST [i] [0] = getval("Enter k end",KSCAN_POST [i] [0]) 
KSCAN_POST [i] [1] = getval("Enter k increment",KSCAN_POST [i] [1]) 
KSCAN_POST [i] [2] = getval("Enter collection time in seconds",KSCAN_POST [i] [2]) 
}

}'

#%UU% energy_motor edge_energy time
#%MDESC%
# Executes the scan defined with kscan_setup or kscan_defaults.
# The time is a multiplicative factor to apply to the time defined
# in kscan_setup.
#
def kscan '
if ($# != 3) {
	p "Usage: kscan energy_motor edge_energy time"
	exit
}
if ((_m[0] = motor_num($1))<0) {
    print "Invalid motor name: " _m[0]
    exit
}
_nm=1
HEADING = sprintf("$0 $*")
KSCAN_E0 = $2
# Make sure we work in eV
if(KSCAN_E0 < 100) {KSCAN_E0 = KSCAN_E0 * 1000.}
KSCAN_TIME  = $3
_kscan_profile
p _ctime=KSCAN_T [0] * KSCAN_TIME
_kscan
'

def _kscan_profile '{
# This macro calculates a grid in energy and time for the spectrum
local i j e_work k_work
KSCAN_E [0] = KSCAN_E0 + KSCAN_PRE [0] [0]
KSCAN_T [0] = KSCAN_PRE [0] [2]
# pre-edge profile
i=0
for (j=0;j<KSCAN_N_PRE;j++) {
	if(j == KSCAN_N_PRE -1) {
		e_work = KSCAN_E0+KSCAN_EDGE_1	
	} else {
		e_work = KSCAN_E0+KSCAN_PRE [j+1] [0]
	}
	while (KSCAN_E [i] < e_work) { 
		i++
		KSCAN_E [i] =  KSCAN_E [i-1] + KSCAN_PRE [j] [1]
		KSCAN_T [i] =  KSCAN_PRE [j] [2] 
	}
}

# edge profile
KSCAN_E [i] = e_work
KSCAN_T [i] = KSCAN_EDGE_T
e_work=KSCAN_E0+KSCAN_EDGE_2
while (KSCAN_E [i] < e_work) {
	i++
	KSCAN_E [i] =  KSCAN_E [i-1] + KSCAN_EDGE_INC
	KSCAN_T [i] =  KSCAN_EDGE_T
}
KSCAN_E [i] = e_work
KSCAN_T [i] = KSCAN_EDGE_T

# K profile
for (j=0;j<KSCAN_N_POST;j++) {
	k_work = kscan_calcK(e_work - KSCAN_E0)
	while (k_work < KSCAN_POST [j] [0]) { 
		i++
		k_work += KSCAN_POST [j] [1]
		KSCAN_E [i] = KSCAN_E0+kscan_calcE (k_work)
		KSCAN_T [i] =  KSCAN_POST [j] [2] 
	}
}
KSCAN_NPTS=i+1
if ((substr(PSEUDOE_UNITS,0,2)=="EV") | (substr(PSEUDOE_UNITS,0,2)=="ev") | \
    (substr(PSEUDOE_UNITS,0,2)=="Ev") | (substr(PSEUDOE_UNITS,0,2)=="eV")) {
} else {
	 for(i=0;i<KSCAN_NPTS;i++){
	 	KSCAN_E [i] = KSCAN_E [i]/1000.0
	 }
}

}'


def _kscan '{
         local i
         for (i=0;i<_nm;i++) {
                 _bad_lim = 0
                 _chk_lim _m[i] KSCAN_E[0]
                 _chk_lim _m[i] KSCAN_E[KSCAN_NPTS-1]
                 if (_bad_lim) exit;
         }
}
	
#	_n1++
	_n1=KSCAN_NPTS
	_cols=_nm+_hkl_col
	X_L = motor_name(_m[0])
	Y_L = cnt_name(DET)
	_s[0] = KSCAN_E [0]
	_f[0] = KSCAN_E [KSCAN_NPTS-1]
	_sx = _s[0]
	_fx = _f[0]
	FPRNT=PPRNT=VPRNT=""
{
         local i
         for (i=0;i<_nm;i++) {
             FPRNT=sprintf("%s%s  ",FPRNT,motor_name(_m[i]))
             PPRNT=sprintf("%s%8.8s ",PPRNT,motor_name(_m[i]))
             VPRNT=sprintf("%s%9.9s ",VPRNT,motor_name(_m[i]))
         }
}
FPRNT=sprintf("%s%s  ",FPRNT,_hkl_sym1)
scan_head
PFMT=sprintf("%%s%%8.%df ",UP)
VFMT=sprintf("%%s%%9.%df ",UP)
def _scan_on \'
	for(;NPTS < KSCAN_NPTS;NPTS++) {
		local i
		A[_m[0]] = KSCAN_E [NPTS]
		scan_move
                FPRNT=PPRNT=VPRNT=""
                for (i=0;i<_nm;i++) {
                     FPRNT=sprintf("%s%.8g ",FPRNT,A[_m[i]])
                     PPRNT=sprintf(PFMT,PPRNT,A[_m[i]])
                     VPRNT=sprintf(VFMT,VPRNT,A[_m[i]])

                }
                FPRNT=sprintf("%s%s ",FPRNT,_hkl_val)
		_ctime=KSCAN_T [NPTS] * KSCAN_TIME
                scan_loop
#                data_nput(PL_G, NPTS, A[_m[0]]*UN, S[DET])
 		scan_data(NPTS,A[_m[0]])
                scan_plot
         }
         scan_tail
\'
_scan_on
'

#%UU%
#%MDESC%
# This macro sets a profile as default. This profile should be
# good for most of the applications. The profile can always be
# visualized and/or changed with kscan_defaults.
#
def kscan_defaults '
global KSCAN_N_PRE KSCAN_N_POST
global KSCAN_PRE KSCAN_POST
global KSCAN_EDGE_1 KSCAN_EDGE_2 KSCAN_EDGE_INC KSCAN_EDGE_T KSCAN_EDGE_K
global KSCAN_E0
global KSCAN_NPTS KSCAN_TIME
array KSCAN_E [4000] KSCAN_T [4000]
KSCAN_N_PRE = 2
KSCAN_N_POST = 1
KSCAN_PRE [0] [0] = -100.0
KSCAN_PRE [0] [1] =    5.0
KSCAN_PRE [0] [2] =    1.0
KSCAN_PRE [1] [0] =  -50.0
KSCAN_PRE [1] [1] =    2.0
KSCAN_PRE [1] [2] =    1.0
KSCAN_EDGE_1 = -20
KSCAN_EDGE_2 = +20
KSCAN_EDGE_INC = 0.5
KSCAN_EDGE_T = 1
KSCAN_POST [0] [0] =  16.0
KSCAN_POST [0] [1] =  0.03
KSCAN_POST [0] [2] =  1
'
#%MACROS%
#%IMACROS%
#%AUTHOR% V.A.Sole - ID26 - ESRF - Copyright 1999
#%TOC%