This commit is contained in:
2025-10-23 16:33:17 +02:00
parent d97084323e
commit 0b8ceb6cf0
34 changed files with 729 additions and 33 deletions

51
script/cpython.py Normal file
View File

@@ -0,0 +1,51 @@
###################################################################################################
# This moddule is called by demo scripts to execute and embed CPython.
# Must be put in the scripts folder, or else in the python path.
###################################################################################################
import numpy as np
def linfit(x, y):
"""
Return linear fit
"""
print(1, type(x), type(y), x, y)
p = np.polyfit(x, y, 1)
f = np.poly1d(p)
x_fit = np.linspace(min(x), max(x), 100)
y_fit = f(x_fit)
yhat = f(x)
ybar = np.sum(y)/len(y)
ssreg = np.sum((yhat - ybar)**2)
sstot = np.sum((y - ybar)**2)
R2 = ssreg / sstot
return (p, x_fit, y_fit, R2)
def test():
return np.ones(5)
def test2(name, x=None, y=None, **kwargs):
print (name,x,y)
ret = y*x
print (ret)
print(kwargs.get("z", 0.0))
return ret
def add(x,y,z):
return x+y+z
def read_dev(dev):
return dev.read()
def print_dict(d):
for k in d.keys():
print (k, d[k])
ret = {}
ret.update(d)
return ret
def get_tuple():
return (1,2,3)

View File

@@ -166,6 +166,10 @@ rw1 = ReadableWaveform()
ri1 = ReadableImage()
av = create_averager(ai2, 5, 0.05, name="av1")
av.setMonitored(True)
add_device(av, True)
####################################################################################################
# Imaging
####################################################################################################
@@ -188,3 +192,19 @@ if not configured:
test_bg_scan_state = State.Ready
test_bg_scan_result = None
if get_context().isServerEnabled():
#CAS.setServerPort(5062)
add_device(EpicsServerUrl("epics_server_url_old", "PSHELL_OP:SERVER_URL"), True) #TODO: Change dependencies to "SF-PSHELL_OP:SERVER_URL and remove
add_device(EpicsServerUrl("epics_server_url", "SF-PSHELL_OP:SERVER_URL"), True)
add_device(EpicsServerState("epics_server_state", "SF-PSHELL_OP:STATE"), True)
add_device(EpicsCmdAPI("epics_cmd", "SF-PSHELL_OP:CMD", as_string=False), True)
add_device(EpicsCmdAPI("epics_cmd_bg", "SF-PSHELL_OP:CMD_BG", as_string=False, background=True), True)
add_device(EpicsCmdAPI("epics_cmd_str", "SF-PSHELL_OP:CMD_STR", as_string=True), True)
add_device(EpicsCmdAPI("epics_cmd_str_bg", "SF-PSHELL_OP:CMD_STR_BG", as_string=True, background=True), True)

139
script/startup_c.py Normal file
View File

@@ -0,0 +1,139 @@
###################################################################################################
#Utilities
###################################################################################################
def get_setting(name=None):
"""Get a persisted script setting value.
Args:
name (str): name of the setting.
Returns:
String with setting value or None if setting is undefined.
If name is None then returns map with all settings.
"""
return Context.getSettings() if (name is None) else Context.getSetting(name)
def set_setting(name, value):
"""Set a persisted script setting value.
Args:
name (str): name of the setting.
value (obj): value for the setting, converted to string (if None then remove the setting).
Returns:
None.
"""
Context.setSetting(name, value)
def exec_cmd(cmd, stderr_raise_ex = True):
"""Executes a shell command. If errors happens raises an exception.
Args:
cmd (str or list of str): command process input and parameters. If stderr_raise_ex is set then raise exception if stderr is not null.
Returns:
Output of command process.
"""
import subprocess
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE if stderr_raise_ex else subprocess.STDOUT)
ret=result.stdout.decode('utf-8')
err=result.stderr.decode('utf-8')
if stderr_raise_ex and (err is not None) and err!="":
raise Exception(err)
return ret
def bsget(channel, modulo=1, offset=0, timeout = 5.0):
"""Reads an values a bsread stream, using the default provider.
Args:
channel(str or list of str): channel name(s)
module(int, optional): stream modulo
offset(int, optional): stream offset
timeout(float, optional): stream timeout in secs
Returns:
BS value or list of values
"""
channels = to_list(channel)
ret = Stream.readChannels(channels, modulo, offset, int(timeout * 1000))
if is_string(channel):
return ret[0]
return ret
def flatten(data):
"""Flattens multi-dimentional or nested data.
Args:
data (tuple, array, List or Array): input data
Returns:
Iterator on the flattened data.
"""
if is_array(data):
if not data.typecode.startswith('['):
return data
import itertools
return itertools.chain(*data)
def frange_gen(start, finish, step):
while ((step >= 0.0) and (start <= finish)) or ((step < 0.0) and (start >= finish)):
yield start
start += step
def frange(start, finish, step, enforce_finish = False, inclusive_finish = False):
"""Create a list with a range of float values (a float equivalent to "range").
Args:
start(float): start of range.
finish(float): end of range.
step(float): step size.
enforce_finish(boolean, optional): adds the final element even if range was not exact.
inclusive_finish(boolean, optional): if false finish is exclusive (like in "range").
Returns:
list
"""
step = float(step)
ret = list(frange_gen(start, finish, step))
if len(ret) > 0:
if inclusive_finish == False:
if ret[-1]==finish:
del ret[-1]
if enforce_finish and ret[-1]!=finish:
ret.append(finish)
return ret
def notify(subject, text, attachments = None, to=None):
"""Send email message.
Args:
subject(str): Message subject.
text(str): Message body.
attachments(list of str, optional): list of files to be attached (expansion tokens are allowed).
to (list ofd str, optional): recipients. If None uses the recipients defined in mail.properties.
Returns:
None
"""
Context.notify(subject, text, to_list(attachments), to_list(to))
def expand_path(path, timestamp=-1):
"""Expand path containing tokens.
Args:
path(str): path name.
timestamp(int): If not defined(-1), uses now.
Returns:
Expanded path name.
"""
return Setup.expandPath(path, timestamp)
def send_event(name, value=True):
"""Send an interpreter event, which is propagated as a SSE.
Args:
name(str): event name.
value(Object): event value.
"""
get_interpreter().sendEvent(name, value)

12
script/test_async_scan.py Normal file
View File

@@ -0,0 +1,12 @@
test_async_scan_state.assertReady()
test_async_scan_state = State.Busy
test_async_scan_result = None
try:
r1 = lscan(ao1, (ai1,av1,wf1), 0, 40, 100, 0.05)
test_async_scan_result = "Ok"
except Exception as ex:
test_async_scan_result = str(ex)
finally:
test_async_scan_state = State.Ready

11
script/test_bg_scan.py Normal file
View File

@@ -0,0 +1,11 @@
test_bg_scan_state.assertReady()
test_bg_scan_state = State.Busy
test_bg_scan_result = None
try:
r1 = lscan(ao1, (ai1,av1,wf1), 0, 40, 100, 0.05)
test_bg_scan_result = "Ok"
except:
test_bg_scan_result = str(sys.exc_info()[1])
finally:
test_bg_scan_state = State.Ready

16
script/test_cpy.py Normal file
View File

@@ -0,0 +1,16 @@
from jeputils import import_py
import_py("cpython", "test")
import_py("cpython", "add")
import_py("cpython", "linfit")
print (test())
print (add(1,2,3))
x=to_array([0,1,2,3,4,5,6,7,8,9], 'd')
y=to_array([1,2,3,6,9,6,3,2,1,0], 'd')
(p, x_fit, y_fit, R2) = linfit(x,y)
#print "Fit: ", (p, x_fit, y_fit, R2)
plot((y,y_fit), name=("data", "fit"),xdata=(x,x_fit))

12
script/test_cpy2.py Normal file
View File

@@ -0,0 +1,12 @@
from jeputils import *
import ch.psi.pshell.utils.Convert as Convert
a = call_jep("numpy", "ones", [[400,200],'d'])
while(True):
b = call_jep("numpy", "ones", [[400,200],'d'])
a = call_jep("cpython", "add", [a,b])
s = call_jep("cpython", "sum", [a,])
print a.getData()[0], s
sleep(0.01)

79
script/test_data.py Normal file
View File

@@ -0,0 +1,79 @@
###################################################################################################
#Data Manipulation: Using the data access API to generate and retrieve data
###################################################################################################
FormatTIFF.setParallelWriting(False)
#Creating a 1D dataset from an array
print "---- 1 -------"
path="group/data1"
data1d = [1.0, 2.0, 3.0, 4.0, 5.0]
save_dataset(path, data1d)
flush_data()
#Reading ii back
read =load_data(path)
print read.tolist()
assert data1d==read.tolist()
plot(read)
set_attribute(path, "AttrString", "Value")
set_attribute(path, "AttrInteger", 1)
set_attribute(path, "AttrDouble", 2.0)
set_attribute(path, "AttrBoolean", True)
#Creating a 2D dataset from an array with some attributes
print "---- 2 -------"
data2d = [ [1.0, 2.0, 3.0, 4.0, 5.0], [2.0, 3.0, 4.0, 5.0, 6.0, ], [3.0, 4.0, 5.0, 6.0, 7.0]]
path="group/data2"
save_dataset(path, data2d)
set_attribute(path, "AttrString", "Value")
set_attribute(path, "AttrInteger", 1)
set_attribute(path, "AttrDouble", 2.0)
set_attribute(path, "AttrBoolean", True)
#Reading it back
read =load_data(path)
print read.tolist()
plot(read)
#Creating a 3D dataset from an array
print "---- 3 -------"
data3d = [ [ [1,2,3,4,5], [2,3,4,5,6], [3,4,5,6,7]], [ [3,2,3,4,5], [4,3,4,5,6], [5,4,5,6,7]]]
path="group/data3"
save_dataset(path, data3d)
#Reading it back
read =load_data(path,0)
print read.tolist()
read =load_data(path,1)
print read.tolist()
set_attribute(path, "AttrString", "Value")
set_attribute(path, "AttrInteger", 1)
set_attribute(path, "AttrDouble", 2.0)
set_attribute(path, "AttrBoolean", True)
#Creating a 2D dataset adding lines one by one
print "---- 4 -------"
path = "group/data4"
create_dataset(path, 'd', False, (0,0))
for row in data2d:
append_dataset(path, row)
read =load_data(path)
print read.tolist()
plot(read)
set_attribute(path, "AttrString", "Value")
set_attribute(path, "AttrInteger", 1)
set_attribute(path, "AttrDouble", 2.0)
set_attribute(path, "AttrBoolean", True)
#Creating a 3D dataset adding images one by one
print "---- 5 -------"
path = "group/data5"
create_dataset(path, 'd', False, (0,0,0))
for i in range(len(data3d)):
append_dataset(path,data3d[i])
read =load_data(path,0)
print read.tolist()
read =load_data(path,1)
print read.tolist()
set_attribute(path, "AttrString", "Value")
set_attribute(path, "AttrInteger", 1)
set_attribute(path, "AttrDouble", 2.0)
set_attribute(path, "AttrBoolean", True)

12
script/test_data_txt.py Normal file
View File

@@ -0,0 +1,12 @@
#set_exec_pars(format="txt")
data2d = [ [1.0, 2.0, 3.0, 4.0, 5.0], [2.0, 3.0, 4.0, 5.0, 6.0, ], [3.0, 4.0, 5.0, 6.0, 7.0]]
path = "group/data4"
create_dataset(path, 'd', False, (0,0))
for row in data2d:
append_dataset(path, row)
read =load_data(path)
print read.tolist()
plot(read)
set_return(True)

32
script/test_invalidate.py Normal file
View File

@@ -0,0 +1,32 @@
mot=DummyMotor("motor")
reg= DummyRegister("register")
mot.initialize()
reg.initialize()
beam_ok = True
def is_beam_ok():
return beam_ok
def wait_beam():
if not is_beam_ok():
print "Waiting for beam..."
while not is_beam_ok():
time.sleep(0.1)
print "Beam ok"
def before_read(pos, scan):
wait_beam()
#...
def after_read(rec, scan):
if not is_beam_ok():
print "Beam is down invalidating record ", rec.index, " at position ", rec.setpoints
rec.invalidate()
return
#...
a= lscan(mot, reg, 0.0, 10.0, 0.1, latency=0.1, before_read=before_read, after_read=after_read)

88
script/test_jep.py Normal file
View File

@@ -0,0 +1,88 @@
###################################################################################################
# Embedding CPython with JEP: USe of numpy, pandas and matpplotlib in the same process.
# Requires cpython.py to be put in the scripts folder, or else in the python path.
###################################################################################################
#Requirements to the use of JEP:
# 1- PYTHONHOME is set to the python interpreter home folder.
# 2- jep*.so is in LD_LIBRARY_PATH (e.g. in extensions folder )
# 3- jep*.jar is in the CLASS_PATH (e.g. in extensions folder )
#JEP works with python 2 and 3.
from jeputils import *
#In order to use matplotlib we must set Tk backend before importing plt
eval_jep("import matplotlib")
eval_jep("matplotlib.use('TkAgg')")
#Evaluating statements
eval_jep("import sys")
eval_jep("import numpy as np")
eval_jep("a = np.array((100, 100), )")
eval_jep("print (a)")
eval_jep("""
def stderr(str):
if sys.version_info < (3,0) :
exec("print >> sys.stderr, '" + str + "'")
else:
exec("print ('" + str + "', file=sys.stderr)")
""")
eval_jep("stderr('Testing stderr')")
#Accessing a numpy array
a=get_jep("a")
print a.getData()
print a.getDimensions()
#Setting numpy array with scan data
steps = (3,4)
dims = (steps[0]+1,steps[1]+1)
r = ascan((m1,m2), (ai1), (0.0,0.0), (0.2,0.2), steps)
data = r[ai1]
a = to_npa(data, dims,'d')
print a.getDimensions()
print a.getData()
plot( Convert.reshape(a.getData(),a.getDimensions()),title="Scan Data")
#Calling a module function
b = call_jep("numpy", "transpose", [a,])
print b.getDimensions()
print b.getData()
plot( Convert.reshape(b.getData(),b.getDimensions()),title="Transposed")
#More calculations calling numpy
a = call_jep("numpy", "ones", [to_array([400,200]),'d'])
for i in range (100):
b = call_jep("numpy", "ones", [to_array([400,200]),'d'])
a = call_jep("numpy", "add", [a,b])
s = call_jep("numpy", "sum", [a,])
print a.getData()[0], s
sleep(0.001)
#Calling a local function
data, dims = [1,2,3,4,5,6,7,8,9,0], [2,5]
array = to_npa(data, dims,'d') #Auxiliary function to create numpy arrays from lists or java arrays.
ret = call_jep("cpython", "calc", [array,])
print ret.getDimensions(),ret.getData()
#Testing pandas
ret = call_jep("cpython", "test_pandas")
#Testing tkinter
ret = call_jep("cpython", "test_tkinter")
#Testing matplotlib
ret = call_jep("cpython", "test_matplotlib", [0.1, 4, 0.4])
#Running a modole
run_jep("cpython")

9
script/test_list.py Normal file
View File

@@ -0,0 +1,9 @@
a = [1,2,3]
d = to_array(a)
l=to_list(d)
print (a)
print (l)
print (type(a)==type(l))
print (a==l)

10
script/test_nested.py Normal file
View File

@@ -0,0 +1,10 @@
run("test_data_txt")
time.sleep(0.5)
run("test_data_txt")
time.sleep(0.5)
run("test_data_txt")
time.sleep(0.5)
run("test_data_txt")
time.sleep(0.5)
run("test_data_txt")
set_return(True)

3
script/test_next.py Normal file
View File

@@ -0,0 +1,3 @@
import java.io.File
App.getInstance().evalFileNext(java.io.File("test_next"))

10
script/test_scan.py Normal file
View File

@@ -0,0 +1,10 @@
set_exec_pars(layout="table", open=True)
print "Scan 1"
r1 = lscan(ao1, (ai1,av1,wf1), 0, 40, 100, 0.01)
print "Scan 2"
r2 = lscan(m1, (m1.setpoint, ai1,ai2, av1), 0, 0.1, 10, relative=True)
print "Scan 3"
r3 = lscan(m1, (m1.setpoint, ai1, av1), 0, 0.1, 10, relative=True, diags = (ao1, ao2), snaps = (wf1,), monitors=(ai2,))
if get_data_manager().getFormat().id == "tiff":
print "Scan 4"
r4 = lscan((ao1,ao2), (ai1,av1,wf1,im1), (0, 0), (40, 100), 4, 0.01)

15
script/test_scan2.py Normal file
View File

@@ -0,0 +1,15 @@
run("test_data_txt")
#set_exec_pars(layout="default", open=True , meta = {"a":1}, then="run('test_sleep')")
print "Scan 1"
set_exec_pars(layout="default", open=True , meta = {"a":1})
r1 = lscan(ao1, (ai1,av1,wf1), 0, 40, 100, 0.01, meta=False)
#print "Scan 2"
#r2 = lscan(m1, (m1.setpoint, ai1,ai2, av1), 0, 0.1, 10, relative=True, meta = {"a":2})
#print "Scan 3"
#r4 = lscan(m1, (m1.setpoint, ai1, av1), 0, 0.1, 10, relative=True, diags = (reg1, p1), snaps = (wf1,), monitors=(ai2,), meta = {"b":2})
#print "Scan 4"
#r3 = lscan((ao1,ao2), (ai1,av1,wf1,im1), (0, 0), (40, 100), 4, 0.01)
#lscan((ao1,ao2), (ai1,av1,wf1,im1), (0, 0), (40, 100), 4, 0.01, depth_dim=2)
set_return(r1)

4
script/test_scan3.py Normal file
View File

@@ -0,0 +1,4 @@
set_exec_pars(layout="table")
r1 = lscan(m1, (ai1,ai2,wf1), 0, 0.1, 10, relative=True)
r1 = lscan(m1, (m1.readback, ai1,ai2,wf1), 0, 0.1, 10, relative=True)

4
script/test_scan4.py Normal file
View File

@@ -0,0 +1,4 @@
set_exec_pars(layout="default")
r1 = lscan(m1, (ai1,ai2,wf1), 0, 0.1, 10, relative=True)
r1 = lscan(m1, (m1.readback, ai1,ai2,wf1), 0, 0.1, 10, relative=True)

2
script/test_sleep.py Normal file
View File

@@ -0,0 +1,2 @@
print "Sleeping"
sleep(1.0)

3
script/test_stack.py Normal file
View File

@@ -0,0 +1,3 @@
set_exec_pars(layout="table")
#tscan((ai1, src1.dataMatrix), 5, 0.1)
tscan((ai1, src1.dataMatrix), 5, 0.1, stack=True)