import random import ch.psi.pshell.device.DummyMotor as DummyMotor import ch.psi.pshell.device.DummyRegister as DummyRegister import ch.psi.pshell.device.DummyPositionable as DummyPositionable import ch.psi.pshell.device.RegisterBase as RegisterBase import ch.psi.pshell.device.MotorGroupBase as MotorGroupBase import ch.psi.pshell.device.MotorGroupDiscretePositioner as MotorGroupDiscretePositioner import ch.psi.pshell.device.ReadonlyRegisterBase as ReadonlyRegisterBase import ch.psi.pshell.device.ReadonlyRegister.ReadonlyRegisterArray as ReadonlyRegisterArray import ch.psi.pshell.device.ReadonlyRegister.ReadonlyRegisterMatrix as ReadonlyRegisterMatrix import ch.psi.pshell.imaging.RegisterMatrixSource as RegisterMatrixSource #################################################################################################### # 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.01) self.val = to_array(self.calc(), 'd') return self.val class Waveform(ReadonlyRegisterBase, ReadonlyRegisterArray): def doRead(self): time.sleep(0.01) 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.01) 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(DummyPositionable("p1"),True) add_device(MotorGroupBase("mg1", m1, m2), True) add_device(MotorGroupDiscretePositioner("dp1", mg1), True) #Initial Configuration p1.config.minValue = 0.0 #Not persisted p1.config.maxValue = 1000.0 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) #Some configuration for so the imaging will work out of the box if not configured: import ch.psi.pshell.imaging.Colormap src1.config.dataPolling = 100 src1.config.colormapAutomatic = True src1.config.colormap = ch.psi.pshell.imaging.Colormap.Temperature src1.config.save() src2.config.dataPolling = 100 src2.config.colormapAutomatic = True src2.config.save()