190 lines
4.9 KiB
Groovy
Executable File
190 lines
4.9 KiB
Groovy
Executable File
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
|
|
|
|
def getSize(self):
|
|
return len(self.take(-1)) #only reads if cache is None
|
|
|
|
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:
|
|
import ch.psi.pshell.imaging.Colormap
|
|
src1.config.colormapAutomatic = True
|
|
src1.config.colormap = ch.psi.pshell.imaging.Colormap.Temperature
|
|
src1.config.save()
|
|
src2.config.colormapAutomatic = True
|
|
src2.config.save()
|
|
|
|
|