esrf

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

"""
#%TITLE% STCHANGES.MAC
#%NAME%
#  STCHANGES.MAC - Changes std. macros for plotting and pseudo macros  
#%DESCRIPTION%
#  The file stchanges.mac should be used to put all the macros which
#  are only slightly modified standard spec macros.
#  Macros in stchanges.mac should be defined in a way to leave the
#  behaviour of standard macros unchanged. Only some hooks to user
#  functions should be included. 
#  
#%EXAMPLE%
#  To use pseudo.mac or plot2.mac you need to load stchanges.mac
#        
#%INTERNALS%
#  As updated moves and counting used the c-function wait directly, these 
#  waits had to be replaced by the new waitcheckcount ,... macros.
#  These changes have been made:
#%DL%  
#   We do not use: PCAII.MAC, QELS.MAC
#   For the moment I define this stuff in move_poll (not very reliable)
#%DT%   IN MOTOR.MAC %DD%
#     move_poll user_finished
#%DT%   Some more changes to have the hooks for the pseudo stuff %DD%
#     waitcount waitmove user_prepcount user_precount user_waitcount
#     user_idledef user_pollcounts user_waitall user_wait2 user_c_cleanup
#     user_m_cleanup user_cr_cleanup user_mr_cleanup user_config1 user_cleanup2
#     user_cleanup cleanup1 user_config user_config1
#%XDL%
#%ATTENTION%
# This version of stchanges.mac is to be used with SPEC version 6.00.07 and later!
# Many ESRF specific macros like mv, ct have been eliminated by improvements
# made to the standard macros in standard.mac. 
# The effort to keep all ESRF functionality was quite big, but we need to be
# vigilant to eliminate errors. All old code has been kept in this file as
# comments, which should allow tracking errors.
#%END%

#There is a series of macros I would like to modify to have a hook when
#you want counting and moving to be finished.

#IN UTIL.MAC

#global USER_MOTORSRUN USER_COUNTERSRUN
#def chk_count '(wait(0x22)||USER_COUNTERSRUN)'
#def chk_move '(wait(0x21)||USER_MOTORSRUN)'

# Sometimes I need to take some actions when a move or a count is really
# finished. For example to switch an airpad off or to redefine the
# cleanup macros. It is clear that if one wants to do that, we can not
# go back to the command line until everything is finished. 
# After looking through all the macros I think it would be the easiest
# thing to modify the source code and call a macro "spec_prompt"
# when you display your prompt. I think that this could be done
# without big trouble, as when you display your prompt you in the
# outer level.
# This modification would be also very useful for the user interface
 

# For the moment I define this stuff in move_poll (not very reliable)
## in MOTOR.MAC:::
### and a lot of other macros if we want to be really strict!
#def umv '_mv $*; _update1 $1 ; move_poll'
#ef umvr '_mvr $*; _update1 $1 ; move_poll'
#def _ord_move 'move_em; move_poll; get_angles; calcHKL'
"""

def move_poll '
  waitall
  user_finished
  '

cdef("user_finished")

def waitcount 'user_waitcount ; wait(2) ;' 
def waitmove 'user_waitmove ; wait(1) ;'  

def user_prepcount ''

def user_precount '
  rdef user_cr_cleanup \'user_c_cleanup\'
  rdef cleanup1 \'user_cleanup\'
  user_prepcount 
'

global COUNTERSPOLLTIME
COUNTERSPOLLTIME=.01

#%IU%
#%MDESC% 
# user_pollcounts will be used to average counts (for pico and adc)
# and allow timers to change their state (from counting to idle)
# and modify USER_COUNTERSRUN to allow the macro to continue.
# The macro will do nothing if user_pollcounts is empty

def user_waitcount '
  if(user_idledef) {
    while (chk_count) {
      user_pollcounts
      sleep (COUNTERSPOLLTIME)
    }
  }
'

#%IU%
#%MDESC% value <> 0 if user_pollcounts is not empty
def user_idledef '((whatis("user_pollcounts")>>16)&0xffff)'

def user_pollcounts ''

def user_waitall '
  user_waitcount
  user_waitmove
  user_wait2 '

def user_wait2 ''
def user_c_cleanup ''
def user_m_cleanup ''
def user_cr_cleanup ''
def user_mr_cleanup ''
def user_config1 ''
def user_cleanup2 ''

def user_cleanup '
	  user_cr_cleanup
          user_mr_cleanup
	  user_cleanup2
'

def cleanup1 'user_cleanup'

def user_config '
	user_config1 
'

def user_finished '
  user_finished1
  rdef user_mr_cleanup \'\'
  rdef user_cr_cleanup \'\'
  '

def user_finished1 ''

"""
# A trivial addition to setplot:
#
#def setplot '
#	if ($# > 1) {
#		print "Usage:  setplot  or  setplot mode"
#		exit
#	}
#	if ($# == 1) {
#		local   t
#		t = substr("$1",1,1)
#		if (t == "+")
#			_1 = PLOT_MODE+substr("$1",2)
#		else if (t ==  "-")
#			_1 = PLOT_MODE+substr("$1",2)
#		else
#			_1 = $1
#		if (_1 < 0 || _1 > (2047+USER_PLOTMODES)) {
#			printf ("Valid modes are from 0 to %d.",2047+USER_PLOTMODES)
#			exit
#		}
#	}
#	if ($# == 0)
#		_setplot
#	if (_1&32)
#		_1 &= ~16
#	if (PLOT_MODE&128 && !(_1&128))
#		plot_cntl("kill")
#	PLOT_MODE=_1
#	rdef _plot _1&1? "rplot":""
#	rdef YMIN _1&16? "0":"\"auto\""
#	BG=_1&64? 1:0
#	if (BG == 1)
#		data_grp(1,4096,COUNTERS+1)
#	plot_cntl(_1&8? "xexact":"-xexact")
#	plot_cntl(_1&32? "ylog":"-ylog")
#	plot_cntl(_1&256? "-dots":"dots")
#	plot_cntl(_1&512? "-lines":"lines")
#	plot_cntl(_1&1024? "-ebars":"ebars")
#        user_setplotadd
#	if (_1 == 0)
#		rdef plot \'_plot0 \$*\'
#	else if (_1 == 2)
#		rdef plot \'_plot2 \$*\'
#	else if (_1 == 4)
#		rdef plot \'_plot4 \$*\'
#	else if (_1 == 6)
#		rdef plot \'_plot6 \$*\'
#'
#
#def _setplot '{
#	 local p; _1=0; p=PLOT_MODE
#	 if (yesno("\n   1) Do real-time screen plots during scans",p&1))
#		 _1 |= 1
#	 if (yesno("   2) Do screen plot after scan",p&2))
#		 _1 |= 2
#	 if (yesno("   4) Do printer plot after scan",p&4))
#		 _1 |= 4
#	 if (yesno("   8) Range x axis with scan min and max",p&8))
#		 _1 |= 8
#	 if (yesno("  16) Force y-axis minimum to zero",p&16))
#		 _1 |= 16
#	 if (yesno("  32) Use logarithmic y-axis",p&32))
#		 _1 |= 32
#	 if (yesno("  64) Do background subtraction for plots",p&64)) {
#		 _1 |= 64
#		 getvar "      How many points at each end to average" bg_pts
#	 }
#	 if (yesno(" 128) Use high resolution plotting device",p&128)) {
#	  getvar "      What kind of high-res graphics terminal" GTERM
#	  _1 |= 128
#	  if (!yesno(" 256) Draw large dots at points",!(p&256)))
#		  _1 |= 256
#	  if (!yesno(" 512) Connect points with lines",!(p&512)))
#		  _1 |= 512
#	  if (!yesno("1024) Draw error bars",!(p&1024)))
#		  _1 |= 1024
#          user_setplotopt
#	 }
#	 printf("      Sum of selections is %d.\n", _1)
#}'
#
#global USER_PLOTMODES
#
#def user_setplotadd ''
#def user_setplotopt ''

## This change is more anoying because it breaks your code
## but I do not understand anyway why you define scan_plot first
## as nothing and then as _plot and never modify it.
##
## A group PL_G2 has to be added and updated every time the user does 
## a config.
## see plot2.mac

#def scan_plot '{
#  local pl_gi pl_g2i x_value _npts
#  _npts = NPTS
#  if (PLOT_MODE&2048 &&  Y_L == cnt_name(DET)) Y_L = cnt_name(PLOT_LIST[0])
#  if (!$#) {
#    x_value = A[_m[0]]*UN
#    }
#  else if ("$1"=="E") {
#    x_value = E
#    }
#  else if ("$1"=="HKL") {
#    x_value = _d3? l_ca:(_d2? k_ca:h_ca)
#    }
#  else if ("$1"=="TIME") {
#    x_value = _time
#    _npts = NPTS - _n1
#    if (_time > _fx) {
#       _fx=2*_time
#       plot_cntl("erase")
#       plot_range(_sx,_fx,YMIN,"auto")
#       plot_move(0,1,T_L)
#       plot_move(0,2,Y_L)
#       plot_move(0,-1,sprintf("%.8s", X_L))
#       }
#    }
#
#  data_put(PL_G, _npts, 0, x_value)
#  if (PL_G2) data_put(PL_G2, _npts, 0, x_value)
#
#  #Save all counter values in group PL_G2 and selected ones in PL_G
#  if (PL_G2) {
#    for (i=0,pl_gi=1,pl_g2i=1;i<COUNTERS;i++) {
#      data_put(PL_G2, _npts,pl_g2i++,S[i])
#      }
#    for (i=0;i<PLOT_NO;i++) {
#      data_put(PL_G, _npts,i+1,S[PLOT_LIST[i]])
#      }
#    }
#
#  _plot
#}'

# These macros just give a parameter to scan_plot
#
#

#def Escan '
#	if ($# != 4 && $# != 5 || $# == 5 && "$5" != "fixQ") {
#		print "Usage: Escan start finish intervals time [fixQ]"
#		print "       (Units are KeV)"
#		print "       (the literal \"fixQ\" means keep HKL constant)"
#		exit
#	} 
#
#	{ _s1 = $1; _f1 = $2; _n1 = int($3); _ctime = $4; }
#
#	if (_n1 <= 0) {
#		print "Number of Intervals <= 0"
#		exit
#	} 
#	if (_s1 <= 0 || _f1 <= 0) {
#		print "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  %s  ",motor_name(Mono))
#	PPRNT=sprintf("%9.9s %9.9s ", "Energy",motor_name(Mono))
#	_stype = 1|(1<<8)
#	_cols=2
#	if (mono_type == 3 || mono_type == 4) {
#		FPRNT=sprintf("%s%s  %s  ",FPRNT,\
#		  motor_name(montrav),motor_name(mond))
#		PPRNT=sprintf("%s%9.9s %9.9s ",PPRNT,\
#		  motor_name(montrav),motor_name(mond))
#		_stype = 1|(3<<8)
#		_cols=4
#	}
#	VPRNT=PPRNT
#
#	scan_head
#	def _scan_on \'
#	 for (; NPTS < _n1; NPTS++) {
#		local   E
#		get_angles
#		E = _s1 + NPTS * _d1
#		calcM E; calcE
#		if ("$5" == "fixQ") { calcA; }
#		scan_move
#		calcE; E = 12.39852 / LAMBDA
#		FPRNT=sprintf("%g %g ",E,A[Mono])
#		PPRNT=sprintf("%9.4f %9.4f ",E,A[Mono])
#		if (mono_type == 3 || mono_type == 4) {
#		    FPRNT=sprintf("%s%9.4f %9.4f ",FPRNT,A[montrav],A[mond])
#		    PPRNT=sprintf("%s%9.4f %9.4f ",PPRNT,A[montrav],A[mond])
#		}
#		VPRNT=PPRNT
#		scan_loop
#		scan_plot "E"
#	 }
#	 scan_tail
#	\'
#	_scan_on
#'

#def hklscan '
#	if ($# != 8) {
#		print \
#"Usage:  hklscan Hstart Hfinish Kstart Kfinish Lstart Lfinish intervals time"
#		exit
#	} 
#	{
#		_s1 = $1; _f1 = $2; _s2 = $3; _f2 = $4; _s3 = $5; _f3 = $6
#		_n1 = int($7); _ctime = $8
#	}
#
#	if (_n1 <= 0) {
#		print "Intervals <= 0"
#		exit
#	} 
#	HEADING = sprintf("hklscan  %g %g  %g %g  %g %g  %g %g", $1,$2,$3,\
#		$4,$5,$6,$7,$8)
#	_d1 = (_f1 - _s1)/_n1
#	_d2 = (_f2 - _s2)/_n1
#	_d3 = (_f3 - _s3)/_n1++
#
#	H=_f1; K=_f2; L=_f3
#	calcA; _bad_lim=0; _hkl_lim
#	if (_bad_lim) {
#		printf("(H K L = %g %g %g)\n",H,K,L)
#		exit
#	}
#	if (_pre_chk) {
#		local i
#		for (i=0;i<_n1;i++) {
#			H = _s1 + i*_d1
#			K = _s2 + i*_d2
#			L = _s3 + i*_d3
#			calcA
#			_bad_lim = 0
#			_hkl_lim
#			if (_bad_lim) {
#				printf("(H K L = %g %g %g)\n",H,K,L)
#				exit
#			}
#		}
#	}
#	_cols=3
#	if (_d3)
#		{ X_L = "L"; _sx = _s3; _fx = _f3 }
#	else if (_d2)
#		{ X_L = "K"; _sx = _s2; _fx = _f2 }
#	else
#		{ X_L = "H"; _sx = _s1; _fx = _f1 }
#	Y_L = cnt_name(DET)
#	_stype = 2
#	FPRNT="H  K  L  "
#	PPRNT=""
#	{
#	 local i
#	 for (i=0;i<_numgeo;i++)
#		PPRNT=sprintf("%s%8.8s ",PPRNT,motor_name(mA[i]))
#	}
#	VPRNT=sprintf("%10s %10s %10s ","H","K","L")
#	scan_head
#	def _scan_on \'
#	 for (; NPTS < _n1; NPTS++) {
#		local i h_ca k_ca l_ca
#		H = h_ca = _s1 + NPTS*_d1
#		K = k_ca = _s2 + NPTS*_d2
#		L = l_ca = _s3 + NPTS*_d3
#		get_angles; calcA
#		scan_move
#		FPRNT=sprintf("%g %g %g ",h_ca,k_ca,l_ca)
#		PPRNT=""
#		for (i=0;i<_numgeo;i++)
#			PPRNT=sprintf("%s%8.4f ",PPRNT,A[mA[i]])
#		VPRNT=sprintf("%10.5g %10.5g %10.5g ",h_ca,k_ca,l_ca)
#		scan_loop
#		data_nput(PL_G, NPTS,_d3? l_ca:(_d2? k_ca:h_ca),S[DET])
#		H=h_ca; K=k_ca; L=l_ca
#		scan_plot "HKL"
#	 }
#	 scan_tail
#	\'
#	_scan_on
#'
"""

#%IMACROS%
#%AUTHOR%
#  STCHANGES.MAC - JK 1.94 
#%TOC%