This commit is contained in:
2025-07-14 17:48:44 +02:00
commit 511f888e98
39 changed files with 1284 additions and 0 deletions
BIN
View File
Binary file not shown.
+47
View File
@@ -0,0 +1,47 @@
"""
Create a device listener to interrupt the scan
"""
import java.lang.InterruptedException
class ListenerAO (ch.psi.pshell.device.DeviceListener):
def onStateChanged(self, device, state, former):
pass
def onValueChanged(self, device, value, former):
pass
def onValueChanging(self, device, value, former):
pass
#Create a listener to the sensor, verifying the readback values.
class ListenerAI (DeviceListener):
def onValueChanged(self, device, value, former):
if value > 1.02:
print "Value over limit-> aborting"
abort()
listenerAI = ListenerAI()
ai1.addListener(listenerAI)
#Create a listener to the positioner checking the setpoint before each command is sent.
class ListenerAO (DeviceListener):
def onStateChanged(self, device, state, former):
pass
def onValueChanged(self, device, value, former):
print "Moved to: " + str(value)
def onValueChanging(self, device, value, former):
if value > 20:
#Vetoing the change will abort the scan
raise Exception("Forbidden move to " + str(value))
print "Moving to: " + str(value) + " ... " ,
listenerAO = ListenerAO()
ao1.addListener(listenerAO)
try:
lscan(ao1, (ai1), 0, 40, 200, 0.01)
except java.lang.InterruptedException:
print "Aborted"
finally:
ai1.removeListener(listenerAI)
ao1.removeListener(listenerAO)
+3
View File
@@ -0,0 +1,3 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
// Deployment specific global definitions - executed after startup.groovy
///////////////////////////////////////////////////////////////////////////////////////////////////
+4
View File
@@ -0,0 +1,4 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
// Deployment specific global definitions - executed after startup.js
///////////////////////////////////////////////////////////////////////////////////////////////////
+190
View File
@@ -0,0 +1,190 @@
###################################################################################################
# Deployment specific global definitions - executed after startup.py
###################################################################################################
import random
####################################################################################################
# Simulated Devices
####################################################################################################
class AnalogOutput(RegisterBase):
def doRead(self):
return self.val if hasattr(self, 'val') else 0.0
def doWrite(self, val):
self.val = val
class AnalogInput(ReadonlyRegisterBase):
def doRead(self):
time.sleep(0.001)
self.val = to_array(self.calc(), 'd')
return self.val
class Waveform(ReadonlyRegisterBase, ReadonlyRegisterArray):
def doRead(self):
time.sleep(0.001)
self.val = to_array(self.calc(), 'd')
return self.val
class Image(ReadonlyRegisterBase, ReadonlyRegisterMatrix):
def doRead(self):
time.sleep(0.001)
self.val = to_array(self.calc(), 'd')
return self.val
def getWidth(self):
return len(self.take(-1)[0])
def getHeight(self):
return len(self.take(-1))
class Random(AnalogInput):
def calc(self):
return random.random()
class SinusoidSample(AnalogInput):
def calc(self):
self.x = self.x + 0.1 if hasattr(self, 'x') else 0.0
noise = (random.random() - 0.5) / 10.0
return math.sin(self.x) + noise
class SinusoidTime(AnalogInput):
def calc(self):
noise = (random.random() - 0.5) / 10.0
return math.sin(time.time()) + noise
class SinusoidWaveform(Waveform):
def calc(self):
ret = []
x = random.random()
for i in range (20):
ret.append(math.sin(x))
x = x + 0.1
return ret
class SinusoidImage(Image):
def calc(self):
(width, height) = (200, 100)
ret = []
x = random.random();
base = []
for i in range (width):
base.append( math.sin(x))
x = x + 0.05
for i in range (height):
noise = (random.random() - 0.5)/5.0
ret.append([x+noise for x in base])
return ret
#Defintion
add_device(DummyMotor("m1"), True)
add_device(DummyMotor("m2"), True)
add_device(DummyRegister("reg1",3), True)
add_device(AnalogOutput("ao1"), True)
add_device(AnalogOutput("ao2"), True)
add_device(SinusoidSample("ai1"), True)
add_device(SinusoidTime("ai2"), True)
add_device(Random("ai3"), True)
add_device(SinusoidWaveform("wf1"), True)
add_device(SinusoidImage("im1"), True)
add_device(DummyPositioner("p1"),True)
add_device(MotorGroupBase("mg1", m1, m2), True)
add_device(MotorGroupDiscretePositioner("dp1", mg1), True)
#Initial Configuration
if p1.config.unit is None:
p1.config.minValue = 0.0 #Not persisted
p1.config.maxValue = 1000.0
p1.config.unit = "mm"
p1.config.save()
p1.initialize()
if dp1.config.positions is None:
dp1.config.positions = ["Park","Ready","Out","Clear"]
dp1.config.motor1 = ["0.0","4.0","8.0" ,"0.0"]
dp1.config.motor2 = ["0.0","5.0","3.0" ,"NaN"]
dp1.config.save()
dp1.initialize()
#Update
m1.setMonitored(True)
m2.setMonitored(True)
####################################################################################################
# Simple Readable / Writable objects can be created and used in scans
####################################################################################################
class WritableScalar(Writable):
def write(self, value):
pass
class ReadableScalar(Readable):
def read(self):
return random.random()
class ReadableWaveform(ReadableArray):
def getSize(self):
return 20
def read(self):
ret = []
for i in range (self.getSize()):
ret.append(random.random())
return ret
class ReadableImage(ReadableMatrix):
def read(self):
ret = []
for i in range (self.getHeight()):
ret.append([random.random()] * self.getWidth())
return to_array(ret, 'd')
def getWidth(self):
return 80
def getHeight(self):
return 40
ws1 = WritableScalar()
rs1 = ReadableScalar()
rw1 = ReadableWaveform()
ri1 = ReadableImage()
####################################################################################################
# Imaging
####################################################################################################
configured = os.path.exists(Device.getConfigFileName("src1"))
add_device(RegisterMatrixSource("src1", im1), True)
add_device(RegisterMatrixSource("src2", ri1), True)
src1.polling = 100
src2.polling = 100
#Some configuration for so the imaging will work out of the box
if not configured:
src1.config.colormapAutomatic = True
src1.config.colormap = Colormap.Temperature
src1.config.save()
src2.config.colormapAutomatic = True
src2.config.save()
+2
View File
@@ -0,0 +1,2 @@
def test():
pass
+14
View File
@@ -0,0 +1,14 @@
###################################################################################################
# Demonstrate the use of Line Scan: one or multiple positioners move together linearly.
###################################################################################################
#Execute the scan: 100 steps, a1 from 0 to 40
r1 = lscan(ao1, (ai1,ai2,wf1), 0, 40, 100, 0.01)
#Steps of size 1.0, a1 from 0 to 40
r2 = lscan(ao1, (ai1,ai2,wf1), 0, 40, 1.0, 0.01)
#2 positioners moving together in 10 steps. Also sampling an image:
r3 = lscan((ao1,ao2), (ai1,ai2,wf1,im1), (0, 0), (40, 100), 4, 0.01)
+29
View File
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration xmlns="http://www.psi.ch/~ebner/models/scan/1.0" numberOfExecution="1" failOnSensorError="true">
<notification>
<recipient>alexandre.gobbo@psi.ch</recipient>
</notification>
<data fileName="test8"/>
<description>My first test</description>
<variable name="var1" value="0.0"/>
<scan>
<dimension>
<positioner xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinearPositioner" name="TESTIOC:TESTCALCOUT:Input" id="id278043">
<start>0.0</start>
<end>31.0</end>
<stepSize>1.0</stepSize>
</positioner>
<action xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ScriptAction">
<script>import time
def process():
time.sleep(0.1)</script>
</action>
<detector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ScalarDetector" name="TESTIOC:TESTCALCOUT:Output" id="id348623"/>
<detector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ScalarDetector" name="TESTIOC:TESTSINUS:SinCalc" id="id367393"/>
<detector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ArrayDetector" arraySize="10" name="TESTIOC:TESTWF2:MyWF" id="id980818"/>
</dimension>
</scan>
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id278043" y="id348623 id367393"/>
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="MatrixPlotArray" y="id278043" z="id980818" type="2D"/>
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlotArray" y="id980818" maxSeries="2" offset="3" size="5"/>
</configuration>
+11
View File
@@ -0,0 +1,11 @@
###################################################################################################
# Demonstrate the use of Line Scan: one or multiple positioners move together linearly.
###################################################################################################
#Execute the scan: 100 steps, a1 from 0 to 40
r1 = lscan(ao1, (ai1,ai2), 0, 40, 100, 0.01)
r2 = lscan(ao1, (ai1,ai2), 0, 40, 100, 0.01)
+27
View File
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration xmlns="http://www.psi.ch/~ebner/models/scan/1.0" numberOfExecution="1" failOnSensorError="true">
<notification>
<recipient>alexandre.gobbo@psi.ch</recipient>
</notification>
<data fileName="test2"/>
<description>My first test</description>
<variable name="var1" value="0.0"/>
<scan>
<dimension>
<positioner xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinearPositioner" name="TESTIOC:TESTCALCOUT:Input" id="id278043">
<start>0.0</start>
<end>31.0</end>
<stepSize>1.0</stepSize>
</positioner>
<action xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ScriptAction">
<script>import time
def process():
time.sleep(0.1)</script>
</action>
<detector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ScalarDetector" name="TESTIOC:TESTCALCOUT:Output" id="id348623"/>
<detector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ScalarDetector" name="TESTIOC:TESTSINUS:SinCalc" id="id367393"/>
<detector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ArrayDetector" arraySize="10" name="TESTIOC:TESTWF2:MyWF" id="id980818"/>
</dimension>
</scan>
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id278043" y="id348623 id367393"/>
</configuration>
+29
View File
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration xmlns="http://www.psi.ch/~ebner/models/scan/1.0" numberOfExecution="1" failOnSensorError="true">
<notification>
<recipient>alexandre.gobbo@psi.ch</recipient>
</notification>
<data fileName="test8"/>
<description>My first test</description>
<variable name="var1" value="0.0"/>
<scan>
<dimension>
<positioner xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinearPositioner" name="TESTIOC:TESTCALCOUT:Input" id="id278043">
<start>0.0</start>
<end>31.0</end>
<stepSize>1.0</stepSize>
</positioner>
<action xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ScriptAction">
<script>import time
def process():
time.sleep(0.1)</script>
</action>
<detector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ScalarDetector" name="TESTIOC:TESTCALCOUT:Output" id="id348623"/>
<detector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ScalarDetector" name="TESTIOC:TESTSINUS:SinCalc" id="id367393"/>
<detector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ArrayDetector" arraySize="10" name="TESTIOC:TESTWF2:MyWF" id="id980818"/>
</dimension>
</scan>
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id278043" y="id348623 id367393"/>
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="MatrixPlotArray" y="id278043" z="id980818" type="2D"/>
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlotArray" y="id980818" maxSeries="2" offset="3" size="5"/>
</configuration>