#%TITLE% EBPM.MAC
#
#%NAME%
# EBPM.MAC - Macros for reading the machine electron BPM's
#
#%OVERVIEW%
# This macro set allows to read the information provided by the
# electron BPM's installed in the machine.
# %BR%
# All position and angles can be loaded in %B%spec%B% pseudocounters.
# %BR%
# An interactive macro %B%efbpm%B% can be used to read, display and save
# the spectral distribution of the beam position and angle provided by
# the machine eBPM's.
# %BR%
#
#%EXAMPLE%
# %DL%
# %DT%ebpmsetup id3 x=hp x'=hang z=vp
# %DD%Configures three spec counters to be loaded with different values
# from the eBPM's in section 3. Counters \"hp\" and \"hang\" will be
# loaded with the horizontal position and angle respectively from
# the slow BPM's. Counter \"vp\" will take its value from the vertical
# position provide by the eBPMs.
# %DT%efbpm id30
# %DD%Starts an interactive macro to display and save the frequency
# spectrum of the fast electron beam position in the straight section 30.
# %XDL%
#
#%SETUP%
# The %B%ebpmsetup%B% macro must be included in the setup file to declare
# the apropriate pseudocounters.%BR%
# The %B%efbpm%B% macro requires an instance of the %B%SpecfitServer%B%
# module running in the same computer
#%BR% The SpecfitServer device must be define in the setup file using the macro %B%specfit_define%B%
#%BR%ex: specfit_define //gwenn/id24/specfit/bpm.
#%BR%and has to be set at tcp mode
#%BR%ex: taco_io("//gwenn/id24/specfit/bpm","tcp")
#%END%
#%HISTORY%
#$Log: ebpm.mac,v $
#Revision 1.9 2019/10/10 08:04:53 ohlsson
#Disabled version
#Since it use Taco
#
#Revision 1.6 2012/07/04 14:11:01 domingue
#now uses specfit_ebpm.mac
#
#Revision 1.5 2012/07/04 13:05:55 domingue
#remove the need of specfit.mac
#
#Revision 1.4 2012/07/04 12:58:53 domingue
#with tango ebpm server
#
#Revision 1.2 2005/04/28 16:49:39 fajardo
#Correction in the units for the slow ebpm pseudocounters.
#
#Revision 1.1 2004/10/11 11:32:40 fajardo
#Initial revision
#
#
#
#%END%
jtdo("specfit_ebpm")
#%UU% <idname> [<signal>=<mnemonic> ...]
#%MDESC%
# Declares pseudocounters associates to the eBPM's corresponding to idname.
# The available signals are:
# %UL%
# %LI%%B%x%B%- Horizontal position from the eBPM
# %LI%%B%x'%B%- Horizontal angle from the eBPM
# %LI%%B%z%B%- Vertical position from the eBPM
# %LI%%B%z'%B%- Vertical angle from the eBPM
# %XUL%
def ebpmsetup '{
local retval
if ($# == 0 || (retval = _ebpmsetup("$*"))) {
if (SETUP) print "Error in line: $0 $*"
print "Usage: $0 idname [parameter=value ...]"
if (yesno("\nDisplay online help", 0)) eval("help local ebpm")
}
}'
def _ebpmsetup(args) '{
global EBPM[]
local i nparam auxlist0[] auxlist1[] larr
local idname idnumber dev hdev vdev
local chmne[]
nparam = split(args, auxlist0)
for (i = 0; i < nparam; i++) {
if (split(auxlist0[i], larr, "=") > 1){
delete auxlist0[i]
auxlist1[larr[0]] = larr[1]
} else if (i > 1) {
delete auxlist0[i]
auxlist1[larr[0]] = "yes"
}
}
if (!(0 in auxlist0)) {
printf("Bad parameters\n")
return(-1)
}
idname = auxlist0[0]
sscanf(idname, "id%d", idnumber)
if (idnumber <= 0 || idnumber > 32) {
printf("Bad id name.\n")
return(-1)
}
dev = "//orion:10000/sr/d-fbpm/" idname
tango_get(dev, "State")
if (TANGO_ERR != "0") {
print "No eFBPM accessible at " idname
print_tango_err()
return(-1)
}
if (EBPM["setup_n"] != SETUP_N) {
list_init EBPM
EBPM["setup_n"] = SETUP_N
}
if (list_add(EBPM, idname) <= 0) {
printf("Invalid efbpm name: %s\n", idname)
return(-1)
}
EBPM[idname]["dev"] = dev
EBPM[idname]["setup"] = "ebpmsetup " args
if (!(EBPM["fitdev"] = specfit_start(1))) {
printf("No SpecfitServer found running in the system.\n")
return(-1)
}
EBPM["signal"][1] = "x"
EBPM["signal"][2] = "z"
EBPM["signal"][3] = "x\'"
EBPM["signal"][4] = "z\'"
EBPM["color"][1] = 2
EBPM["color"][2] = 7
EBPM["color"][3] = 4
EBPM["color"][4] = 9
# to avoid calling a macro from another file
# anyway, it was hard-coded
#EBPM["npts"] = specfit_par("maxfftpts")
EBPM["npts"] = 8192
float array efbpm_pos[5][EBPM["npts"]]
array_op("fill", efbpm_pos[0][], 1 / 10)
float array efbpm_fft[9][EBPM["npts"] / 2]
array_op("fill", efbpm_fft[0][], 10 * 1000 / EBPM["npts"])
efbpm_fft[0][] += efbpm_fft[0][1]
if (!EBPM[idname]["filter"]) EBPM[idname]["filter"] = 10
EBPM[idname]["plotfilter"] = 1
if (!EBPM[idname]["Fmin"]) EBPM[idname]["Fmin"] = "auto"
if (!EBPM[idname]["Fmax"]) EBPM[idname]["Fmax"] = "auto"
if (!EBPM[idname]["Tmin"]) EBPM[idname]["Tmin"] = "auto"
if (!EBPM[idname]["Tmax"]) EBPM[idname]["Tmax"] = "auto"
if (!EBPM[idname]["plot"]) EBPM[idname]["plot"] = 15
if (!EBPM[idname]["mode"]) EBPM[idname]["mode"] = "freq"
ebpm_addgetcounts(idname, auxlist1)
if ("updateT" in auxlist1)
EBPM[idname]["updateT"] = (auxlist1["updateT"] + 0)
else
EBPM[idname]["updateT"] = 3
delete auxlist1["updateT"]
EBPM[idname]["nextT"] = 0
setup_tail("ebpm", idname)
i = ""
for (i in auxlist1) {
print "Invalid parameter: " i "=" auxlist1[i]
}
if (i != "")
return(-1)
else
return(0)
}'
def ebpm_addgetcounts(idname, auxlist1) '{
local i num mne chname chid
local nchan macrodef key
nchan = 0
macrodef = "\"" idname "\""
for (i = 1; i <= 4; i++) {
chname = EBPM["signal"][i]
num = (chname in auxlist1)? cnt_num(mne = auxlist1[chname]) : -1
delete auxlist1[chname]
if (num >= 0 && counter_par(num, "controller") == "NONE") {
nchan++
} else
mne = ""
macrodef = macrodef ", \"" mne "\""
EBPM[idname][chname] = mne
}
key = "ebpm-" idname
if (nchan) {
macrodef = "ebpm_getcounts(" macrodef ")\n"
cdef("user_getcounts", macrodef, key)
} else {
cdef("user_getcounts", "", key, "delete")
}
}'
def ebpmunsetup '{
local idname key
idname = "$1"
key = "ebpm-" idname
cdef("", "", key, "delete")
list_remove(EBPM, idname)
if (list_n(EBPM) <= 0)
unglobal EBPM
}'
def efbpm_update(idname) '{
local update_flag
update_flag = 0
efbpm_getdata(idname)
if (efbpm_doFFT() < 0) {
local fitdev
print "No SpecfitServer is running now in the system."
if (fitdev = specfit_start(1)) {
EBPM["fitdev"] = fitdev
if (efbpm_doFFT() < 0)
print "The problem persists ..."
else
print "Now it seems ok."
} else {
print "The problem persists ..."
}
update_flag = 1
}
efbpm_filter(idname)
efbpm_plot(idname)
return(update_flag)
}'
def efbpm_getgetbuff(idname, commd, data) '{
tango_get(EBPM[idname]["dev"], commd, data)
if (TANGO_ERR != "0") {
print "Error reading eBPM data at " idname
print_tango_err()
return(-1)
}
}'
def efbpm_getdata(idname) '{
float array datX[10140]
float array datZ[10140]
float array datXp[10140]
float array datZp[10140]
efbpm_pos[1:4][] = 0
if (efbpm_getgetbuff(idname, "XPosBuffer", datX) != 0) return(-1)
if (efbpm_getgetbuff(idname, "ZPosBuffer", datZ) != 0) return(-1)
if (efbpm_getgetbuff(idname, "XAngleBuffer", datXp) != 0) return(-1)
if (efbpm_getgetbuff(idname, "ZAngleBuffer", datZp) != 0) return(-1)
efbpm_pos[1][] = datX
efbpm_pos[2][] = datZ
efbpm_pos[3][] = datXp
efbpm_pos[4][] = datZp
}'
def efbpm_filter(idname) '{
local filt_n
filt_n = EBPM[idname]["filter"]
efbpm_fft[5:8][] *= (1 - 1 / filt_n)
efbpm_fft[5:8][] += efbpm_fft[1:4][] / filt_n
}'
def efbpm_reset_filter '{
efbpm_fft[5:8][] = 0
}'
def efbpm_doFFT() '{
local i error npts
npts = EBPM["npts"]
float array fftdat[2][npts]
error = 0
for (i = 1; i <= 4; i++) {
# TACO_ERR=-1
TACO_ERR_MSG = ""
if (taco_io(EBPM["fitdev"], "SpecfitFFTArray", efbpm_pos[i], fftdat) < 0)
error = -1
efbpm_fft[i][] = sqrt(fftdat[0][1:npts/2] * fftdat[0][1:npts/2] + \
fftdat[1][1:npts/2] * fftdat[1][1:npts/2])
}
return(error)
}'
def efbpm_getcounts(idname, x, z, xp, zp) '{
if (time() < EBPM[idname]["nextT"])
return
efbpm_getdata(idname)
if (x != "") S[cnt_num(x)] = array_op("sum", efbpm_pos[1]) / 1024
if (z != "") S[cnt_num(z)] = array_op("sum", efbpm_pos[2]) / 1024
if (xp != "") S[cnt_num(xp)] = array_op("sum", efbpm_pos[3]) / 1024
if (zp != "") S[cnt_num(zp)] = array_op("sum", efbpm_pos[4]) / 1024
EBPM[idname]["nextT"] = time() + EBPM[idname]["updateT"]
}'
def ebpm_getcounts(idname, x, z, xp, zp) '{
dev = EBPM[idname]["dev"]
if (x != "") S[cnt_num(x)] = tango_get(dev, "XPosition") / 1000
if (xp != "") S[cnt_num(xp)] = tango_get(dev, "XAngle")
if (z != "") S[cnt_num(z)] = tango_get(dev, "ZPosition") / 1000
if (zp != "") S[cnt_num(zp)] = tango_get(dev, "ZAngle")
}'
def efbpm_head '{
local i j z s
printf("\n#S %d %s\n#D %s\n",++SCAN_N,HEADING,DATE)
_head_par G 0
_head_par U 1
_head_par UB 3
_head_par Q 4
printf("#Q %s\n", _hkl_val)
for (i=0; i<MOTORS; i+= 8) {
s = sprintf("#P%d ",i/8)
for (j=i; j<i+8 && j<MOTORS;) {
if (motor_name(mA[j]) != "unused")
s = s sprintf("%.8g", A[mA[j]])
if (j%8 == 7)
break
s = s " "
j++
}
print s
}
Fheader
user_Fheader
}'
def efbpm_tail '{
user_scan_tail
Ftail
}'
def efbpm_save(idname) '{
ond; offt
if (EBPM[idname]["mode"] == "freq") {
HEADING = " eFBPM spectral density - " idname
efbpm_head
printf("#N 9\n")
printf("#L Frequency")
for (i = 1; i <= 8; i++) {
local colname
colname = EBPM["signal"][((i - 1) % 4) + 1]
if (EBPM[idname][colname] != "")
colname = cnt_name(cnt_num(EBPM[idname][colname]))
else {
colname = idname "_" colname
}
if (i > 4)
colname = colname " (filt)"
printf(" %s", colname)
}
printf("\n")
array_dump(efbpm_fft, "%1")
} else {
HEADING = " eFBPM time record - " idname
efbpm_head
printf("#N 5\n")
printf("#L Time")
for (i = 1; i <= 4; i++) {
local colname mne
colname = EBPM["signal"][i]
if ((mne = EBPM[idname][colname]) != "")
colname = cnt_name(cnt_num(mne))
else {
colname = idname "_" colname
}
printf(" %s", colname)
}
printf("\n")
array_dump(efbpm_pos, "%1")
}
efbpm_tail
offd; ont
}'
def efbpm_pcols(idname) '{
local pcol_list[] n i
if (EBPM[idname]["allcases"])
n = split("1 2 4 8 3 12 5 10 15", pcol_list)
else
n = split("5 10 15", pcol_list)
for (i = 0; i < n; i++) {
if (EBPM[idname]["plot"] == pcol_list[i]) {
i = (i + 1) % n
break
}
}
if (i < n)
EBPM[idname]["plot"] = pcol_list[i]
else
EBPM[idname]["plot"] = 15
}'
def efbpm_plot(idname) '{
local i col ncol datacols
local title colors filtered
local min max
plot_cntl("filter5")
colors = "colors=47:49:9:3"
plot_cntl(colors)
plot_cntl("open")
plot_cntl("erase")
filtered = EBPM[idname]["plotfilter"] && (EBPM[idname]["mode"] == "freq")
datacols = ""
for (ncol = 0, i = 1; i <= 4; i++) {
if (EBPM[idname]["plot"] & (1 << (i-1))) {
col = i + (filtered? 4 : 0)
if (!ncol)
datacols = col
else
datacols = datacols "," col
plot_move(ncol * 3, 1, EBPM["signal"][i], EBPM["color"][i])
colors = colors ":" EBPM["color"][i]
ncol++
}
}
plot_cntl(colors)
plot_cntl("-dots,-ebars,xexact")
min = array_op("min", efbpm_fft[datacols][1:])
max = array_op("max", efbpm_fft[datacols][1:])
if (EBPM[idname]["mode"] == "freq") {
title = "title=eFBPM Frequency spectrum - " idname
plot_cntl(title)
plot_cntl("ylog")
if (EBPM[idname]["plotfilter"])
plot_move(24,0, sprintf("Filtered spectra - (filter value = %s)", EBPM[idname]["filter"]))
else
plot_move(-50,0, "Non filtered spectra")
plot_move(0,-1,"f(Hz)")
if (max > 0 && min > 0) {
max = pow(10, int(log10(max)) + 1)
plot_range(EBPM[idname]["Fmin"], EBPM[idname]["Fmax"], min, max)
array_plot(efbpm_fft[0], efbpm_fft[datacols])
} else {
plot_range(EBPM[idname]["Fmin"], EBPM[idname]["Fmax"], "auto", "auto")
array_plot(efbpm_fft[0], efbpm_fft[datacols])
plot_cntl("colors=:2:3")
plot_move(40, 10, "BAD DATA")
}
} else {
title = "title=eFBPM time record - " idname
plot_cntl(title)
plot_cntl("-ylog")
plot_move(-50,0, "Time record")
plot_range(EBPM[idname]["Tmin"], EBPM[idname]["Tmax"], "auto", "auto")
plot_move(0,-1,"t(ms)")
array_plot(efbpm_pos[0], efbpm_pos[datacols])
}
plot_cntl("filter1")
}'
#%UU% [<idname>]
#%MDESC%
# Starts the interactive macro to display and save the time or frequency
# records from the fast eBPM's.
def efbpm '{
local idname options
idname = $#? "$1": ""
if (!$# || list_check(EBPM, idname) > 0){
if (efbpm_setdefault(idname)) {
idname = EBPM["default"]
EBPM[idname]["prompt"] = "(" EBPM["default"] ")"
}
} else
_ebpmsetup(idname)
if (list_check(EBPM, idname) <= 0 ) {
print "Usage: $0 idname"
if (yesno("\nDisplay online help", 0))
eval("help local ebpm")
} else if(EBPM[idname]["dev"] == "") {
print "No eFBPM device found."
} else {
efbpm_main(idname, options)
}
}'
def efbpm_setdefault(idname) '{
if (EBPM[0] <= 0 && idname == "") {
# print "No eFBPM devices configured. Use first \`ebpmsetup\'."
return(0)
}
if (idname != "") {
EBPM["default"] = idname
if (!list_check(EBPM, idname)) {
print "\`" idname "\' is not a valid eFBPM device."
}
}
if (!list_check(EBPM, EBPM["default"])) {
EBPM["default"] = EBPM[1]
print "Setting \`" EBPM["default"] "\' as default eFBPM device."
}
return(1)
}'
def efbpm_main(idname, options) '{
local updateT line
local line time0
local minT maxT
if (minT <= 0) minT = EBPM[idname]["updateT"]
if (maxT <= 0) maxT = EBPM[idname]["updateT"]
updateT = maxT
update_flag = 0
EBPM["ncomm"]++
efbpm_update(idname)
efbpm___process(idname, ".")
while(1){
time0 = time()
line = ""
printf("\n")
efbpm___prompt
while(1) {
sleep(0.05)
c = input(-1)
if (c == "\n") {
printf("\n")
tty_cntl("cd")
break
} else if ((c == "\b" || c == "\177") && line) {
line = substr(line, 0, length(line)-1)
printf("\b \b")
} else if (asc(c) == 27) {
while(input(-1));
} else if (c >= " " && c <= "z") {
line = line c
printf(c)
}
if ((time()-time0) > updateT) {
efbpm_update(idname)
if (efbpm_update(idname)){
printf("\n")
efbpm___prompt
updateT = minT
} else {
updateT *= 2
if (updateT > maxT)
updateT = maxT
}
time0 = time()
}
}
if (efbpm___process(idname, line) == -1)
return(0)
EBPM["ncomm"]++
efbpm_update(idname)
}
}'
def efbpm_shcomm(comm, descr) '{printf("\t%-20s - %s\n", comm, descr)}'
def efbpm___process(idname, line) '{
local comm[] npar i
if ((npar = split(line, comm) - 1) >= 0){
if (substr(comm[0], 1, 1) != ".")
return(eval(line))
if (comm[0] == "." || comm[0] == ".h" || comm[0] == ".help") {
print
print "\tSpecial commands:"
print "\t-----------------"
efbpm_shcomm("., .h, .help", "Display available commands")
efbpm_shcomm(".i, .info", "Display device information")
efbpm_shcomm(".f, .filter", "Set filter value")
efbpm_shcomm(".m, .mode", "Switch plot mode")
efbpm_shcomm(".p, .plot", "Switch plotted spectra")
efbpm_shcomm(".r, .reset", "Reset filter")
efbpm_shcomm(".s, .save", "Save in data file")
efbpm_shcomm(".x, .xrange", "Set X-axis range")
efbpm_shcomm(".q, .quit", "Quit interactive macro")
} else if (comm[0] == ".info" || comm[0] == ".i") {
print
print "\teFBPM info"
print "\t---------"
print "\tName: ", idname
print "\tDevice: ", EBPM[idname]["dev"]
print "\tSetup: ", EBPM[idname]["setup"]
} else if (comm[0] == ".quit" || comm[0] == ".q") {
return(-1)
} else if (comm[0] == ".mode" || comm[0] == ".m") {
if (EBPM[idname]["mode"] == "freq")
EBPM[idname]["mode"] = "time"
else
EBPM[idname]["mode"] = "freq"
print "Switching plot mode to \`" EBPM[idname]["mode"] "\' "
} else if (comm[0] == ".plot" || comm[0] == ".p") {
if (npar)
EBPM[idname]["allcases"] = !EBPM[idname]["allcases"]
efbpm_pcols(idname)
} else if (comm[0] == ".save" || comm[0] == ".s") {
efbpm_save(idname)
print "Saving eFBPM data as scan \#" SCAN_N " in \`" DATAFILE "\'"
} else if (comm[0] == ".filter" || comm[0] == ".f") {
if (npar == 0 || comm[1] < 1) {
EBPM[idname]["plotfilter"] = !EBPM[idname]["plotfilter"]
printf("Plotting %sfiltered values\n", EBPM[idname]["plotfilter"]?"":"non ")
} else {
EBPM[idname]["filter"] = int(comm[1])
EBPM[idname]["plotfilter"] = 1
print "Setting filter value to : ", EBPM[idname]["filter"]
}
} else if (comm[0] == ".xrange" || comm[0] == ".x") {
if (!npar) {
if (EBPM[idname]["mode"] == "freq")
EBPM[idname]["Fmin"] = EBPM[idname]["Fmax"] = "auto"
else
EBPM[idname]["Tmin"] = EBPM[idname]["Tmax"] = "auto"
} else if (npar == 1) {
if (EBPM[idname]["mode"] == "freq")
EBPM[idname]["Fmax"] = comm[1]
else
EBPM[idname]["Tmax"] = comm[1]
} else {
if (EBPM[idname]["mode"] == "freq") {
EBPM[idname]["Fmin"] = comm[1]
EBPM[idname]["Fmax"] = comm[2]
} else {
EBPM[idname]["Tmin"] = comm[1]
EBPM[idname]["Tmax"] = comm[2]
}
}
} else if (comm[0] == ".reset" || comm[0] == ".r") {
efbpm_reset_filter
} else {
printf("Internal command [%s] not valid.\n", comm[0])
}
}
return(0)
}'
def efbpm___prompt '
printf("%d.eFBPM - %s > %s", EBPM["ncomm"], idname, line)
'
#%MACROS%
#%AUTHOR% P.Fajardo, (Original 10/04).
# $Revision: 1.9 $ / $Date: 2019/10/10 08:04:53 $
#%TOC%
|