#%TITLE% cen.mac
#%NAME%
# Centering macros. OBSOLETE.
#
#%CATEGORY% Scans, obsolete
#
#%DESCRIPTION%
# This macro set is OBSOLETE. Kept here as example
#
# This set of macros will try to find the center of a reflection in the
# angle sequence specified by the user.
# It will do a scan in the first angle, go to the center of the peak found,
# do a scan in the next angle, and so on.
# Initially it takes a user supplied scan width, but after the first cycle,
# it adjusts the scan width depending on FWHM found.
# The sequence is repeated until either convergence or a max
# number of cycles is found. %BR%
# This routine can be used in conjunction with the SEARCH routine, either
# directly inside, or from the search results file.
#
#%EXAMPLE%
# %PRE%
# %B%cen_seq%B%
# Defines the centering sequence - Angle names and convergence criteria
# Angle number 1
# Name?: [ 0 to end]: (0)? th
# Give data for: th
# Initial scan width: (1)? 1.5
# Initial scan step size: (0)? .1
# Minimum step size: (0)? 0.05
# Max shift to define convergence: (0)? 0.02
# Recenter if already converged (NO)? YES
# Angle number 2
# Name?: [ 0 to end]: (0)? chi
# Give data for: chi
# Initial scan width: (3)? 6
# Initial scan step size: (0)? .25
# Minimum step size: (0)? .2
# Max shift to define convergence: (0)? .05
# Recenter if already converged (NO)? YES
# Angle number 3
# Name?: [ 0 to end]: (0)? 0
# 2 angles in sequence - th chi
# %B%cen_here%B%
# The centering will start from the current angles.
# %PRE%
#
#%LOG%
#
# $Revision: 3.1 $
#
# $Log: cen.mac,v $
# Revision 3.1 2008/02/27 13:19:36 rey
# documentation changes
#
#%END%
##############################################################################
#This routine does the centering cycles
#%IU%
#%MDESC%
# This routine does the real centering
def cen_do_it '{
global CENANAME CENMOTCYC CENSSEQ CEN_START_ANG BESTANG I_CYC FOUND
global CONV CENWIDTH COUNTTIME CENSHIFT THIS TRY1 TRY2 BEST_CPS
global START STOP STEP COUNT NPT
local cen_ok done
#set up initial parameters for first cycle
COUNT = CENITIME ; BEST_CPS=0
for (THIS=0;THIS<CENMOTCYC;THIS++) {
CENWIDTH[THIS]=CENIWIDTH[THIS]
BESTANG[THIS]=CEN_START_ANG[THIS]
CONV[THIS]=0 # set converged false
cen_ok[THIS]=0 # set skip false.
}
#make sure starting angles are setup
cen_mv
#
for (I_CYC=0,n=0;I_CYC<CENNCYC;I_CYC++) { # MAX NUMBER OF CENTERING CYCLES
for (THIS=0;THIS<CENMOTCYC;THIS++) { # NUMBER OF ANGLES IN EACH CYCLE
n++
if (cen_ok[THIS]==0) { # IF WE SHOULD DO THIS ONE
if (I_CYC == 0) # SCAN WIDTH/STEP WHETHER 1ST OR SUBS
STEP=CENISTEP[THIS]
else {
STEP = CENWIDTH[THIS]/(CENNPTS-1)
if (STEP < CENSTEP[THIS]) STEP=CENSTEP[THIS]
}
START = BESTANG[THIS] - CENWIDTH[THIS]/2
STOP = BESTANG[THIS] + CENWIDTH[THIS]/2
TRY1=0;TRY2=0
for (FOUND=0;FOUND == 0;) {
cen_scan THIS
cen_what_next
cen_mv
}
if (FOUND != -1) {
printf (\
"New: %8.4f shift: %8.4f width: %7.4f maxcps: %5d count: %7.1f\n",\
BESTANG[THIS],CENSHIFT,pl_FWHM,C_maxc/COUNT,COUNT)
CEN_FWHM[THIS]=pl_FWHM
if (CONV[THIS]) {
printf("shift less than %7.4f - so converged\n",CENMSHIFT[THIS])
if (!CENMCYC[THIS]) {
printf("Converged at cycle %d - enough said\n",I_CYC+1)
cen_ok[THIS]=1
}
} else {
printf("shift more than %7.4f - NOT converged\n",CENMSHIFT[THIS])
cen_ok[THIS]=0
}
# at end of second cycle, look at all angles to see if all converged
done=0
printf ("look for convergence:- ")
for (conv=1,ii=0;ii<CENMOTCYC;ii++) {
printf ("%d ",CONV[ii])
if (CONV[ii] == 0) conv=0
}
if (conv == 1) {
printf ("CONVERGED\n")
done=1
break
} else {
printf ("not yet\n")
}
} else # if FOUND != -1
break
} # if cen_ok[THIS]=0 IF IT DID THE SCAN
if (FOUND == -1 || done == 1) break
} # ONE ANGLE SCAN
if (FOUND == -1 || done == 1) break
} # FULL CYCLE
# decide whether converged:
if (FOUND == -1)
printf ("\n**Abandon ship**!!\n")
else {
if (done == 0)
printf("This is getting boring - Had enuf\n")
else
printf("done sufficient for a big happiness\n")
if (conv == 1)
printf ("**CONVERGED: ")
else
printf ("UNconverged: ")
}
# write the results to the terminal
printf ("best angles: ")
for (ii=0;ii<CENMOTCYC;ii++) {
printf("%s:%9.4f ",motor_mne(CENMINDX[ii]),A[CENMINDX[ii]])
}
printf (" with cps: %8d\n",BEST_CPS)
# move to best angles
printf (" I move to this angles\n")
cen_mv
# and append to the file
cen_savetofile
}'
###########################################################################
# THIS ROUTINE LOOKS AT THE SCAN AND DECIDES WHAT TO DO
#%IU%
#%MDESC%
# decides whether to give up (maxc < CENMINC), scan further,
# or prepares the next angles.
def cen_what_next '{
global C_maxc
FOUND=1
C_maxc=data_anal(0,0,0,1,1,"max") ;C_maxa=data_anal(0,0,0,0,0,"max")
C_minc=data_anal(0,0,0,1,1,"min")
C_fwhm=data_anal(0,0,0,1,1,"fwhm")
C_c1 = data_get (0,0,1) ; C_c2 = data_get (0,NPT-1,1)
C_c=CEN
#
#H.G. check on max. counts per seconds i.s.o. maximum counts.
if (C_maxc/COUNT < CENMINC) {
printf ("Max count only: %d - give up\n\n",C_maxc/COUNT)
FOUND=-1
}
#
if (C_maxc/COUNT > BEST_CPS) BEST_CPS=C_maxc/COUNT
if ( FOUND != -1 && C_c1 > C_maxc/2) {
printf ("not found lhs ")
TRY1=TRY1+1
if (TRY1==2) {
printf("give up\n")
FOUND=-1
} else {
printf ("Add a scan width to LHS\n")
START = START - CENWIDTH[THIS]
FOUND=0
}
}
if ( FOUND !=-1 && C_c2 > C_maxc/2) {
printf ("not found rhs ")
TRY2=TRY2+1
if (TRY2==2) {
printf("give up\n")
FOUND=-1
} else {
printf ("Add a scan width to RHS\n")
STOP = STOP + CENWIDTH[THIS]
FOUND=0
}
}
if (FOUND == 1) {
C_central=C_c
CENSHIFT=fabs(BESTANG[THIS]-C_central)
if (fabs(CENSHIFT) <= CENMSHIFT[THIS]) CONV[THIS]=1
CENWIDTH[THIS]=pl_FWHM*CENFWHMFAC
BESTANG[THIS]=C_central
}
}'
###############################################################################
#%IU% <center-angle-index>
#%MDESC%
def cen_scan '{
_m[0] = CENMINDX[$1] # scan angle number
if (START != STOP) {
_s[0] = START # scan starting position
_f[0] = STOP # scan end
_n1 = int (fabs(STOP-START)/STEP)
if (_n1 < CENNPTS) _n1 = CENNPTS
NPT = _n1 +1 ; _ctime = COUNT ; _nm = 1
printf ("\n\nCycle %d - Scan %s Best %8.3f Width: %7.2f pts: %d\n",\
I_CYC+1,motor_mne(_m[0]),BESTANG[THIS],CENWIDTH[THIS],NPT)
_ascan
} else {
printf ("Zero width demanded for %s\n",motor_mne(_m[0]))
}
}'
###############################################################################
#setup parameters for centering times etc
#%IU%
#%MDESC%
#%PRE%
# Number of points in the scan : 15
# Maximum number of cycles allowed :5
# Initial counting time in secs :1
# Max permitted counting time :10 (not implemented yet)
# Minimum counts to define a peak :200 (better will be a peak/bkgd ratio)
#%PRE%
def cen_par '
{
global CENNPTS CENNCYC CENITIME CENMTIME CENMINC
CENNPTS=getval("Number of points in the scan ",CENNPTS)
CENNCYC=getval("Maximum number of cycles allowed ",CENNCYC)
CENITIME=getval("Initial counting time in secs ",CENITIME)
CENMTIME=getval("Max permitted counting time ",CENMTIME)
CENMINC=getval("Minimum counts to define a peak ",CENMINC)
}'
#%IU%
#%MDESC%
# Sets defaults for angles to write, output format ,...
# This is done in this way to allow other macros to use the centering
# for more general scans (like beamline alignment)
def cen_defaults '
{
global CEN_SAV_NUM CEN_SAV_ANG CEN_FWHM CEN_SAVFWHM CEN_FORMAT CENFWHMFAC
global CEN_SAVHKL
CEN_SAV_NUM=4
#CEN_SAV_ANG[0]=mot_num(tth) ; CEN_SAV_ANG[1]=mot_num(th)
#CEN_SAV_ANG[2]=mot_num(chi) ; CEN_SAV_ANG[3]=mot_num(phi)
#h.g. ugly fix
CEN_SAV_ANG[0]=0 ; CEN_SAV_ANG[1]=4
CEN_SAV_ANG[2]=5 ; CEN_SAV_ANG[3]=6
if ((CEN_SAV_ANG[0]<0)||(CEN_SAV_ANG[1]<0)||(CEN_SAV_ANG[2]<0)||\
(CEN_SAV_ANG[3]<0)) {
printf ("Can not work - at least one motor missing (tth th chi phi)\n")
exit
}
CEN_SAVFWHM=0
CEN_SAVHKL=1
CEN_FORMAT=" %9.4f "
CENFWHMFAC=3
}'
###############################################################################
#setup parameters for the centering sequence
#%UU%
#%MDESC%
# You will be ask the filename for results and other general paramters
# (see %B% cen_par %B%). For every angle you like to center you have
# to answer the following questions:
#%UL%
#%LI% Name?: [ 0 to end] : Enter the motor mnemonic
#%LI% Initial scan width :
#%LI% Initial scan step size : Just give enough to be sure not
#to miss your peak. The step width will be adjusted for the
#consecutive scans.
#%LI% Minimum step size : A scan will not be made with smaller
#step size even if you ask for more points in the scan (see general setup)
#%LI% Max shift to define convergence
#%LI% Recenter if already converged : NO will stop doing scans
#with this motor if it is converged. YES will recenter this angle even
#if it is converged. (ex: the angles dependent on each other).
#%XUL%
def cen_seq '{
global CENIWIDTH CENMSHIFT CENMCYC
global CENANAME CENMOTCYC CENISTEP CENSTEP
global CENFILE CENMINDX CEN_NUM CENOLDF
global CEN_SAV_NUM CEN_SAV_ANG CEN_FWHM CEN_SAVFWHM
global CEN_FORMAT
local uu line
# Some global settings
CENOLDF = CENFILE
if ((CENFILE = getval("File name to write results",CENFILE))!=CENOFILE) {
if (!unix(sprintf("test -r %s",CENFILE))) {
getline(CENFILE,"open")
for (CEN_NUM=0,line=getline(CENFILE);line!="-1";line=getline(CENFILE)){
sscanf (line,"%d",CEN_NUM)
}
} else {
CEN_NUM = 0
}
}
cen_par
if (CEN_SAV_NUM == 0) {
cen_defaults
}
printf ("Defines the centering sequence - Angles and convergence criteria\n")
for (CENMOTCYC=0;;) {
printf ("Angle number %d\n",CENMOTCYC+1)
if ((CENANAME[CENMOTCYC]=getval(" Name?: [ 0 to end]: ",\
CENANAME[CENMOTCYC])) ==0) {
printf ("%d angles in sequence - ",CENMOTCYC)
for (uu=0;uu<CENMOTCYC;uu++) printf (" %s ",CENANAME[uu])
printf ("\n")
break
} else {
if ((CENMINDX[CENMOTCYC]=motor_num(CENANAME[CENMOTCYC])) == -1) {
printf ("%s is not a recognised motor name!\n",CENANAME[uu])
continue
}
printf (" Give data for: %s\n",CENANAME[CENMOTCYC])
CENIWIDTH[CENMOTCYC] =getval(" Initial scan width:",\
CENIWIDTH[CENMOTCYC])
CENISTEP[CENMOTCYC] =getval(" Initial step size: ",\
CENISTEP[CENMOTCYC])
CENSTEP[CENMOTCYC] =getval(" Minimum step size:",\
CENSTEP[CENMOTCYC])
CENMSHIFT[CENMOTCYC] =getval(" Max shift to define convergence: ",\
CENMSHIFT[CENMOTCYC])
CENMCYC[CENMOTCYC] =yesno(" Recenter if already converged ",\
CENMCYC[CENMOTCYC])
CENMOTCYC++
}
}
}'
##############################################################################
# set up CEN_START_ANG from current positions
#%UU%
#%MDESC%
# This initiates the centering algorithm from current angles\n")
def cen_here'{
local uu ok mini_more
if (!CENMOTCYC) {
printf("No angles to center\n")
exit
}
printf ("\nThis initiates the centering algorithm from current angles\n")
waitmove
get_angles
printf ("\n")
printf ("Centering sequence: %d angles: ",CENMOTCYC)
for (ii=0;ii<CENMOTCYC;ii++)
printf (" %s (%9.4f) ",CENANAME[ii],A[CENMINDX[ii]])
printf ("\n")
for (uu=0;uu<CENMOTCYC;uu++) {
CEN_START_ANG[uu]=A[CENMINDX[uu]]
}
cen_do_it
}'
#############################################################
#%IU%
#%MDESC%
# does the moving in the centering - uses the BESTANG array
def cen_mv '
{
local uu tonk
waitmove
get_angles
for (uu=0;uu<CENMOTCYC;uu++) {
A[CENMINDX[uu]] = BESTANG[uu]+0
}
move_em
waitmove
}
'
#%IU%
#%MDESC%
# This macro saves the results to a file. This has been separated
# to allow other macro sets to redefine it.
def cen_savetofile '
{
local ii
if (open(CENFILE)== 0) {
fprintf(CENFILE,"%5d ",++CEN_NUM)
if (CEN_SAVHKL) {
calcHKL
fprintf (CENFILE,"%6.2f %6.2f %6.2f ",H,K,L)
}
#h.g. fix get the real angles
sync; get_angles
for (ii=0;ii<CEN_SAV_NUM;ii++) {
if ((mn =CEN_SAV_ANG[ii]) == -1) {
if (ii >= CENMOTCYC) {
continue
} else {
mn = CENMINDX[ii]
}
}
fprintf(CENFILE,CEN_FORMAT,A[mn])
}
if (CEN_SAVFWHM)
for (ii=0;ii<CENMOTCYC;ii++) {
fprintf(CENFILE,CEN_FORMAT,CEN_FWHM[ii])
}
# fprintf(CENFILE,"%2d %8d\n",conv, BEST_CPS)
fprintf(CENFILE,"%8d %s\n",BEST_CPS,conv?"*C****AC":"*C****A*")
close (CENFILE)
} else
printf ("CANNOT WRITE TO %s\n",CENFILE)
} '
#%MACROS%
#%IMACROS%
#%ATTENTION%
#
#%DEPENDENCIES%
# - The file cen.mac has to be read in (qdo'd) !done by: startup script
#%AUTHOR%
# JA 1st trimestre .94 , modified by JK (6.94)
#%TOC%
|