esrf

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

#%TITLE% SEARCH.MAC
#%NAME% 
#   Search of a peak with several motors.
#%DESCRIPTION% 
#   The macros in this file helps to search peak with several motors.
#   It will scan the motors you defined with the macro
#   %B%search_seq%B%. To start it just type %B%search%B%
#

#%UU%
#%MDESC%
# search does the input to start a search - checks pairs of inputs
#
def search '{
global SEA_N_ANGS SEA_START SEA_BEG SEA_STOP SEA_WIWAY
local _pp ii
if ($# != 0 && $# != 2 && $# != 4 && $# != 6 && $# != 8 ) {
  printf("usage: search [start-ang1 stop-ang1] [start-angn stop-angn]\n")
  exit
}
if ($#) {
  SEA_N_ANGS = ($#/2) ; SEA_AGAIN = ($#>3) ? 1 : 0 
  SEA_START[0]=$1+0; SEA_STOP[0]=$2+0; SEA_START[1]=$3+0; SEA_STOP[1]=$4+0;
  SEA_START[2]=$5+0; SEA_STOP[2]=$6+0; SEA_START[3]=$7+0; SEA_STOP[3]=$8+0;
  SEA_START[4]=$9+0; SEA_STOP[4]=$10+0; SEA_START[5]=$11+0; SEA_STOP[5]=$12+0;
  if (SEA_N_ANGS > SEAMOTCYC) {
    printf ("Error: you have asked for \
  %1d search angles whilst only %1d have been configured",SEA_N_ANGS,SEAMOTCYC)
    exit
  } 
} else {
  for (ii=0;ii<SEAMOTCYC;ii++) {
    SEA_START[ii]=getval(sprintf("From %s angle",SEA_ANG_NAME[ii]),SEA_START[ii]) 
    SEA_STOP[ii]=getval(sprintf("To %s angle",SEA_ANG_NAME[ii]),SEA_STOP[ii])
  }
  SEA_N_ANGS=SEAMOTCYC
} 
#  for (ii=0;ii<SEA_N_ANGS;ii++) {
#	SEA_ANG_TEMP[ii] = SEA_START[ii] }


printf ("doing %d angles in search: ",SEA_N_ANGS)
for (ii=0;ii<SEA_N_ANGS;ii++) {
  printf (" %s ",SEA_ANG_NAME[ii])
  SEA_BEG[ii]=SEA_START[ii]
}
printf ("\n")
SEA_WIWAY=0
search_do_it
}'

#%UU%
#%MDESC%
#This routine RESTARTS a search sequence
# takes restart positions 
def search_restart '{
local sea_r_angs
#  Check input
if ($#>4) {
  printf ("SEARCH_RESTART takes 1,2,3,4 inputs:\n\
  These are restart angles for previous SEARCH macro\n\
  defaults to current position\n")
  exit
}

if ($# > SEA_N_ANGS) {
  printf ("Too much input - last scan moved SEARCH angle + %d others\n",\
           SEA_N_ANGS)
  exit
}


if ($#) {
  SEA_BEG[0]=$1+0; SEA_BEG[1]=$2+0; SEA_BEG[2]=$3+0; SEA_BEG[3]=$4+0; 
} else {
  for (ii=0;ii<SEAMOTCYC;ii++) {
    SEA_BEG[ii]=A[SEA_ANG[ii]]
  }

}
  
printf ("last search moved %d angles: ",SEA_N_ANGS)
printf ("RE-starting angles are: %7.2f  in %s\n",SEA_BEG[0],SEA_ANG_NAME[0])
for (ii=1;ii<SEA_N_ANGS;ii++) {
  printf ("                and: %7.2f  in %s\n",SEA_BEG[ii],SEA_ANG_NAME[ii])
  }
answ = getval(sprintf("Whichway should I send %s - [U]p or [D]own",\
       SEA_ANG_NAME[0]),"U")
SEA_WIWAY = (answ == "D" || answ == "d") ? -1 : 1
search_do_it
}'

#%UU%
#%MDESC%
# This routine takes care of the outside loops in the search
def search_do_it '{
global SEA_OLD 
local save_ang old_count old_time old_bkgd
waitmove ; get_angles

for (ii=0,printf("Setup : ");ii<SEA_N_ANGS;ii++) 
  printf (" %s angle : %7.2f  ",SEA_ANG_NAME[ii],A[SEA_ANG[ii]]=SEA_BEG[ii])
printf ("\n")

printf ("%s starting velocity %6.2f\n",SEA_ANG_NAME[0],\
               (SEA_OLD= fabs(motor_par (SEA_ANG[0],"velocity")))\
	/motor_par(SEA_ANG[0],"step_size"))

move_em ; waitmove ; get_angles
printf ("set %s search velocity %6.2f\n",SEA_ANG_NAME[0],fabs(SEA_SLEW/motor_par(SEA_ANG[0],"step_size")))

motor_par (SEA_ANG[0], "velocity", fabs(SEA_SLEW))

#H.G. set also base_rate, otherwise it does not work
#motor_par (SEA_ANG[0], "base_rate", fabs(SEA_SLEW))

# Initialise for search graphics
nsamples=0 ; SEA_GRPDATA=6 ; SEA_GRPRES =7
data_grp (SEA_GRPDATA,16000,2)
data_grp (SEA_GRPRES,100,5)

#
# how to set up the direction?
# if weezza coming from search init (whichway=0) we go up
# but if from search_restart - whichway is set for u/d
dir= (SEA_WIWAY<0) ? 1 :0

for (SEA_AGAIN=1;SEA_AGAIN == 1;) {
  dir++;
  began=A[SEA_ANG[0]]
  from = (int(dir/2)==(dir/2)) ? SEA_STOP[0] : SEA_START[0]
  dest = (int(dir/2)==(dir/2)) ? SEA_START[0] : SEA_STOP[0]
  up = (dest > from ) ? 1 : -1 # which way?

  A[SEA_ANG[0]]=dest
  rdef cleanup "sea_abort"
  printf ("%s destination: %7.2f - scanning ",SEA_ANG_NAME[0], A[SEA_ANG[0]])
  if (up==1) { printf ("up\n") } else { printf ("down\n") }
  t0=time()
  move_em
  tcount (2000)
# Search for 2000- and get rid of that after fixing the countdown 
# Ugly fix JK : Count only 1/2 h ( 1Mhz clock 32 bit )
#  tcount (32000)
  old_count=0 
  old_time=0
#H.G & P.S. change = ugly fix
#  old_time=2149
#
# prepare the plot of this slice
  plot_cntl(sprintf("colors=%s",rplot_col))
  plot_cntl("open")
  sea_plot_setup

  for (npt=1;wait(0x21);npt++) {
    sleep (SEA_COUNT)
#
# get new count - take away old count - work out running bkgd
#
    getcounts
# JK change name 
    if ((tdiff = fabs(2000-S[sec] -old_time)) == 0) tdiff=1
# HG & PS change so tdiff is positive
#    if ((tdiff = old_time -S[sec]) == 0) tdiff=1

    C=(S[det]-old_count)/tdiff

    old_count=S[det]
    old_time=2000-S[sec]

    get_angles
# put angle and count into data group
    data_nput(SEA_GRPDATA,npt-1,A[SEA_ANG[0]],C)
    plot_cntl("addpoint")
    data_plot (SEA_GRPDATA,0,npt-1,0,1)
    printf ("%5d t:%7.1f ",C,2000-S[sec])
    for (ii=0;ii<SEA_N_ANGS;ii++) 
      printf ("  %s:%7.2f ",SEA_ANG_NAME[ii],A[SEA_ANG[ii]])    
    printf ("\n")
  }
  t=time()-t0
  stop(2) ; get_counts ; 
  printf ("finished search slice\n")


# Now to the great new slice analysis
  search_analyseslice
 
#
# now look for a next slice 

  SEA_AGAIN=0
  for (ii=1;ii<SEA_N_ANGS;ii++) {
    if ((next=A[SEA_ANG[ii]]+SEA_STEP[ii]) <= SEA_STOP[ii]) {
      printf ("set %s to %7.2f\n",SEA_ANG_NAME[ii],next)
      A[SEA_ANG[ii]]=next 
      move_em ; waitmove ; get_angles
      SEA_AGAIN = 1 
      break
    } else {
      printf ("finished %s range - put it back to %7.2f\n",\
               SEA_ANG_NAME[ii], SEA_START[ii])
      A[SEA_ANG[ii]]=SEA_START[ii]+0   
    }
  }
}
move_em ; waitmove ; get_angles
#stop counter
stop (2)
undef cleanup
printf ("set %s normal velocity %6.2f\n",SEA_ANG_NAME[0],\
	fabs(SEA_OLD/motor_par(SEA_ANG[0],"step_size")))
motor_par (SEA_ANG[0], "velocity",SEA_OLD)
}'

#%IU%
#%MDESC%
def sea_abort '{
global SEA_OLD
stop (1) ;wait (1); stop(2)
get_angles
printf ("\nInterrupt: ")
for (ii=1;ii<SEA_N_ANGS;ii++)  {
  printf ("%s: %9.4f ",SEA_ANG_NAME[ii],A[SEA_ANG[ii]])
  }
printf ("set %s normal velocity %6.2f\n",SEA_ANG_NAME[0],\
		fabs(SEA_OLD/motor_par(SEA_ANG[0],"step_size")))
motor_par (SEA_ANG[0], "velocity", fabs(SEA_OLD))
undef cleanup
}'


#%IU%
#%MDESC%
def sea_plot_setup'{
  plot_cntl("erase")
  plot_move(0,1,sprintf("Searching %s from %7.2f to %7.2f",\
      SEA_ANG_NAME[0],from,dest))
  if (SEA_N_ANGS==1)
    plot_move(0,2,"One slice only")
  else {
    for (ii=1,str =  "angles: ";ii<SEA_N_ANGS;ii++) {
      str = sprintf ("%s %s %7.1f ",str,SEA_ANG_NAME2[ii],SEA_ANG[ii])
    }
    plot_move(0,2,str)
  }
  plot_move(0,-1,sprintf("  %s",SEA_ANG_NAME[0]))
  plot_range(SEA_START[0],SEA_STOP[0],0,"auto")
}'

#%UU%
#%MDESC%
#  Defines parameters for the search
#
def search_seq '{
global SEA_ANG_NAME SEA_ANG WHICH SEA_STEP
global SEA_SLEW SEA_COUNT SEA_THRESH C N_FOUND SEA_N_CEN
global SEA_AGAIN SEA_OLD SEAMOTCYC SEA_FILE
global SEA_NORM SEA_SAV_NUM SEA_SAV_ANG
global SEA_PREWIDTH SEA_PREPTS SEA_PRETIME
global SEA_NOPEAKS
  
local more ii
# JK WHY HERE _centerassign , search must be independent of centering
# _centerassign
# Setting some variables for now
#SEA_SAV_NUM= 4
#SEA_SAV_ANG[0]=0; SEA_SAV_ANG[1]=1; SEA_SAV_ANG[2]=2; SEA_SAV_ANG[3]=3;

SEA_SAV_NUM= 4
SEA_SAV_ANG[0]=tth; SEA_SAV_ANG[1]=th; SEA_SAV_ANG[2]=chi; SEA_SAV_ANG[3]=phi;

SEA_FILE=getval("File name to store results",SEA_FILE)
printf ("Defines the SEARCH sequence. \n")
for (;;) { 
  SEA_ANG_NAME[0]=getval("   Primary ang Name?: ",SEA_ANG_NAME[0])
  if ( (SEA_ANG[0]=motor_num(SEA_ANG_NAME[0])) == -1) {  
    printf ("** %s - no such motor defined\n",SEA_ANG_NAME[0])
  } else break
}
SEA_SLEW = fabs(motor_par(SEA_ANG[0],"step_size"))*getval \
 	("   Angle slew speed (deg/s): ",\
	fabs(SEA_SLEW/motor_par(SEA_ANG[0],"step_size")))
SEA_COUNT = getval ("   Sleep time : ",SEA_COUNT)
SEA_THRESH = getval ("   Peak threshold: (no. times sigma)",SEA_THRESH)
SEA_N_CEN = yesno ("   Initiate CENTERING when peak(s) found",SEA_N_CEN)
#
if (SEA_N_CEN) {
  rdef search_cen_here \'cen_here\'
  SEA_PREWIDTH=getval("    Width of precenter scan",SEA_PREWIDTH); 
  SEA_PREPTS=getval("    No of pts in this scan",SEA_PREPTS)
  SEA_PRETIME=getval("    Count time in this scan",SEA_PRETIME)
} else {
  rdef search_cen_here \'\'
}

printf("Now define other angles to move...\n")
for (SEAMOTCYC=1;;) {
  if ((SEA_ANG_NAME[SEAMOTCYC]=getval(sprintf("   ANGLE(%1d) Name?: [end=0]:",\
	SEAMOTCYC),SEA_ANG_NAME[SEAMOTCYC])) == 0) {
    printf ("%d angles defined for search sequence - ",SEAMOTCYC)
    for (uu=0;uu<SEAMOTCYC;uu++) { 
      printf (" %s ",SEA_ANG_NAME[uu])
    }
    printf ("\n")
    break
  } else {
    if ((SEA_ANG[SEAMOTCYC]= motor_num(SEA_ANG_NAME[SEAMOTCYC])) == -1) {  
      printf ("** %s - no such motor defined\n",SEA_ANG_NAME[SEAMOTCYC])
      continue
    }
    SEA_STEP[SEAMOTCYC]= getval(sprintf("   Give step size for %s: ",\
                         SEA_ANG_NAME[SEAMOTCYC]),SEA_STEP[SEAMOTCYC])
    SEAMOTCYC++
  }
}
}'

#%IU%
def search_prescan '
  _m[0] = SEA_ANG[0]; _s[0] = A[SEA_ANG[0]]-SEA_PREWIDTH/2; 
  _f[0] = A[SEA_ANG[0]]+SEA_PREWIDTH/2; _n1=SEA_PREPTS
  _ctime = SEA_PRETIME ; _nm=1
  printf("Doing a %s prescan: %f - %f %d pts time: %f\n"\
	,motor_mne(_m[0]),_s[0],_f[0],_n1,_ctime)
  _ascan
  waitmove ; get_angles ; A[SEA_ANG[0]]= CEN ; move_em ; waitmove
'

#%IU%
def search_dump '
printf ("%d Peaks found\n",SEA_NOPEAKS)
printf ("%5s %15s %15s %10s %10s\n","No","Index","Position","Intensity","Sigma")
for (ii=0;ii<SEA_NOPEAKS;ii++) {
  g=SEA_GRPRES
  printf("%5d %15f %15.5f %10.1f %10.1f\n",data_get(g,ii,0),data_get(g,ii,1),\
   	data_get(SEA_GRPDATA,data_get(g,ii,1),0),data_get(g,ii,2),\
	data_get(g,ii,3))
  }
'

#%IU%
def search_psearch '
{
local nopts
nopts= data_info(SEA_GRPDATA,"last")+1
SEA_NOPEAKS=data_pipe("search",sprintf("%d %g",nopts,SEA_THRESH),\
		SEA_GRPDATA,SEA_GRPRES)
} '

#%IU%
def search_analyseslice '
  search_psearch
  if (SEA_NOPEAKS) {
    search_dump
    for (pp=0;pp<SEA_NOPEAKS;pp++) {
      waitall 
      oldsim = set_sim(1)
      A[SEA_ANG[0]] = data_get(SEA_GRPDATA,data_get(SEA_GRPRES,pp,1),0)
      move_em ; waitmove ; get_angles
      for (ii=0;ii<SEA_SAV_NUM;ii++) {
	fprintf(SEA_FILE," %9.4f ",A[SEA_SAV_ANG[ii]])
      }
      set_sim(oldsim)
      get_angles;
      fprintf(SEA_FILE," %9.4f\n",data_get(SEA_GRPRES,pp,2))
      fprintf(SEA_FILE," %9.1f\n",data_get(SEA_GRPRES,pp,3))
    }
    close (SEA_FILE)
    if (SEA_N_CEN == 1) {
      local Atmp
      # Store all CURRENT search angles 
      printf ("\nDo a centering..........\n\n")
      waitmove ; get_angles 
      for (ii=0;ii<SEA_N_ANGS;ii++) {
        Atmp[ii] = A[SEA_ANG[ii]] }

      for (pp=0;pp<SEA_NOPEAKS;pp++) {
        # Set all the angles to the "searched" angles
        for (ii=1;ii<SEA_N_ANGS;ii++) {
          A[SEA_ANG[ii]] = Atmp[ii] }
        A[SEA_ANG[0]] = data_get(SEA_GRPDATA,data_get(SEA_GRPRES,pp,1),0)
        move_em ; waitmove ; get_angles
        search_prescan
        search_cen_here
      }

      # Restore and move to all CURRENT search angles
      for (ii=0;ii<SEA_N_ANGS;ii++) {
        A[SEA_ANG[ii]] = Atmp[ii] }
      move_em ; waitmove ; get_angles
    }
  }
'
      
#%IU%
def search_test '
{
  data_read("~blissadm/testing/,testfile.dat",SEA_GRPDATA,0,0)
  data_uop(SEA_GRPDATA,0,SEA_GRPDATA,1,"copy")
  data_uop(SEA_GRPDATA,0,SEA_GRPDATA,0,"fill")
  splot SEA_GRPDATA 0 1
} '

#%MACROS%
#%IMACROS%
#%AUTHOR% BLISS / ESRF 1993-1999
#%TOC%