From e487e4909dfd8566d79ffea313181906f4b64d1c Mon Sep 17 00:00:00 2001 From: gobbo_a Date: Fri, 13 Mar 2026 15:28:30 +0100 Subject: [PATCH] --- config/config.properties | 12 +-- config/devices.properties | 3 + config/jcae.properties | 4 +- config/preferences.json | 4 +- config/tasks.properties | 1 + config/variables.properties | 8 +- devices/CurrentCamera.properties | 19 ++--- devices/Time.properties | 2 +- devices/cam_server.properties | 26 +++++++ devices/dispatcher.properties | 13 ++++ devices/inp.properties | 10 +++ devices/m1.properties | 6 +- devices/m2.properties | 6 +- devices/motor.properties | 2 +- devices/out.properties | 7 ++ devices/p1.properties | 2 +- devices/positioner.properties | 2 +- plugins/TestScript.form | 51 +++++++++++++ plugins/TestScript.java | 121 +++++++++++++++++++++++++++++++ script/TestScript.py | 1 + script/cpython2.py | 116 +++++++++++++++++++++++++++++ script/methood.py | 1 + script/test_camserver.py | 82 +++++++++++++++++++++ script/test_channels.py | 90 +++++++++++++++++++++++ script/test_channels2.py | 22 ++++++ script/test_data_txt.py | 3 +- script/test_list.py | 2 +- script/test_nested.py | 4 +- script/test_plot_type.py | 3 + script/test_sleep.py | 1 + script/test_snapshot.py | 64 ++++++++++++++++ 31 files changed, 653 insertions(+), 35 deletions(-) create mode 100644 config/tasks.properties create mode 100644 devices/cam_server.properties create mode 100644 devices/dispatcher.properties create mode 100644 devices/inp.properties create mode 100644 devices/out.properties create mode 100644 plugins/TestScript.form create mode 100644 plugins/TestScript.java create mode 100644 script/TestScript.py create mode 100644 script/cpython2.py create mode 100644 script/test_camserver.py create mode 100644 script/test_channels.py create mode 100644 script/test_channels2.py create mode 100644 script/test_plot_type.py create mode 100644 script/test_snapshot.py diff --git a/config/config.properties b/config/config.properties index 9d4e353..9e1d7db 100644 --- a/config/config.properties +++ b/config/config.properties @@ -1,4 +1,4 @@ -#Thu Oct 09 08:44:46 CEST 2025 +#Fri Mar 13 14:50:44 CET 2026 autoSaveScanData=true commandBusSize=-1 commandBusTimeToLive=600000 @@ -12,12 +12,13 @@ consoleJournal=false dataDepthDimension=0 dataEmbeddedAttributes=false dataFormat=h5 -dataLayout=table +dataLayout=default dataPath={data}/{year}_{month}/{date}/{date}_{time}_{name} dataServerPort=-1 dataTransferMode=Off dataTransferPath= dataTransferUser= +dataTruncate=true depthDimension=0 disableDataFileLogs=false disableEmbeddedAttributes=false @@ -55,9 +56,10 @@ scanSaveScript=true scanSaveSetpoints=true scanSaveTimestamps=false scanStreamerPort=-1 -serverCommandsHidden=true +serverCommandsHidden=false serverEnabled=true -serverHostName=null +serverHostName= +serverHttps=false serverLight=true serverPort=8080 sessionHandling=Off @@ -67,7 +69,7 @@ terminalPort=3579 userAuthenticator= userManagement=false versionTrackingEnabled=true -versionTrackingLogin=auto +versionTrackingLogin= versionTrackingManual=true versionTrackingRemote=https\://gitea.psi.ch/pshell_config/tst.git xscanAppendSuffix=true diff --git a/config/devices.properties b/config/devices.properties index e831de1..2a009d4 100644 --- a/config/devices.properties +++ b/config/devices.properties @@ -1 +1,4 @@ sin=ch.psi.pshell.epics.ChannelDouble|TESTIOC:TESTSINUS:SinCalc|Read||true +out=ch.psi.pshell.epics.ReadonlyProcessVariable|TESTIOC:TESTCALCOUT2:Output|Read||true +inp=ch.psi.pshell.epics.ProcessVariable|TESTIOC:TESTCALCOUT2:Input|||true +cam_server=ch.psi.pshell.camserver.PipelineSource|localhost:8889|||true diff --git a/config/jcae.properties b/config/jcae.properties index 97245f2..840508c 100644 --- a/config/jcae.properties +++ b/config/jcae.properties @@ -1,5 +1,5 @@ -#Wed Mar 19 11:12:57 CET 2025 -ch.psi.jcae.ContextFactory.addressList=localhost\:54321 sls-cagw.psi.ch\:5062 +#Tue Nov 11 13:47:56 CET 2025 +ch.psi.jcae.ContextFactory.addressList=localhost localhost\:54321 ch.psi.jcae.ContextFactory.serverPort= ch.psi.jcae.ContextFactory.maxArrayBytes=20000000 ch.psi.jcae.ContextFactory.maxSendArrayBytes=20000000 diff --git a/config/preferences.json b/config/preferences.json index ee0520c..d92c2e3 100644 --- a/config/preferences.json +++ b/config/preferences.json @@ -52,7 +52,7 @@ "noVariableEvaluationPropagation" : false, "processingScripts" : [ ], "asyncViewersUpdate" : false, - "asyncHistoryPlotsUpdate" : false, + "asyncHistoryPlotsUpdate" : true, "scanPlotDisabled" : false, "scanTableDisabled" : false, "cachedDataPanel" : false, @@ -81,7 +81,7 @@ "plotBackground" : null, "gridColor" : null, "outlineColor" : null, - "disableOffscreenBuffer" : false, + "directRendering" : false, "defaultPanels" : [ { "deviceClassName" : "ch.psi.pshell.epics.Scaler", "panelClassName" : "ch.psi.pshell.swing.ScalerPanel" diff --git a/config/tasks.properties b/config/tasks.properties new file mode 100644 index 0000000..cbd80e6 --- /dev/null +++ b/config/tasks.properties @@ -0,0 +1 @@ +#test_camserver=5.0;1.0 diff --git a/config/variables.properties b/config/variables.properties index a7f181a..56cf4ea 100644 --- a/config/variables.properties +++ b/config/variables.properties @@ -1,6 +1,6 @@ -#Tue Oct 21 16:12:23 CEST 2025 +#Thu Mar 12 15:49:20 CET 2026 =2 -DaySequentialNumber=1 -FileSequentialNumber=1797 -LastRunDate=251021 +DaySequentialNumber=30 +FileSequentialNumber=2382 +LastRunDate=260312 r=2 diff --git a/devices/CurrentCamera.properties b/devices/CurrentCamera.properties index 31c2ad4..47d9b8a 100644 --- a/devices/CurrentCamera.properties +++ b/devices/CurrentCamera.properties @@ -1,13 +1,14 @@ -#Thu May 08 14:06:17 CEST 2025 -colormap=Grayscale -colormapAutomatic=false +#Thu Dec 11 11:29:17 CET 2025 +colormap=Flame +colormapAutomatic=true colormapLogarithmic=false -colormapMax=NaN -colormapMin=NaN +colormapMax=255.0 +colormapMin=0.0 flipHorizontally=false flipVertically=false grayscale=false invert=false +lse= rescaleFactor=1.0 rescaleOffset=0.0 roiHeight=-1 @@ -17,9 +18,9 @@ roiY=0 rotation=0.0 rotationCrop=false scale=1.0 -spatialCalOffsetX=-637.0000131373355 -spatialCalOffsetY=-483.0000310340799 -spatialCalScaleX=-35.21126791588346 -spatialCalScaleY=-48.38709170854271 +spatialCalOffsetX=-123.99999389793373 +spatialCalOffsetY=-90.99999980402927 +spatialCalScaleX=-2.6978416539937182 +spatialCalScaleY=-2.162849850124783 spatialCalUnits=mm transpose=false diff --git a/devices/Time.properties b/devices/Time.properties index 244cae7..dc85b74 100644 --- a/devices/Time.properties +++ b/devices/Time.properties @@ -4,7 +4,7 @@ maxValue=NaN minValue=NaN offset=0.0 precision=-1 -resolution=NaN +deadband=NaN rotation=false scale=1.0 sign_bit=0 diff --git a/devices/cam_server.properties b/devices/cam_server.properties new file mode 100644 index 0000000..77f1a65 --- /dev/null +++ b/devices/cam_server.properties @@ -0,0 +1,26 @@ +#Fri Mar 06 15:44:07 CET 2026 +colormap=Grayscale +colormapAutomatic=false +colormapLogarithmic=false +colormapMax=NaN +colormapMin=NaN +flipHorizontally=false +flipVertically=false +grayscale=false +invert=false +rescaleFactor=1.0 +rescaleOffset=0.0 +roiHeight=-1 +roiWidth=-1 +roiX=0 +roiY=0 +rotation=0.0 +rotationCrop=false +scale=1.0 +serverURL=localhost\:8889 +spatialCalOffsetX=-123.99999389793373 +spatialCalOffsetY=-90.99999980402927 +spatialCalScaleX=-2.6978416539937182 +spatialCalScaleY=-2.162849850124783 +spatialCalUnits=mm +transpose=false diff --git a/devices/dispatcher.properties b/devices/dispatcher.properties new file mode 100644 index 0000000..47a105e --- /dev/null +++ b/devices/dispatcher.properties @@ -0,0 +1,13 @@ +#Tue Jan 13 17:11:55 CET 2026 +analizeHeader=false +disableCompression=false +headerReservingAllocator=false +keepListeningOnStop=false +mappingIncomplete=fill_null +parallelHandlerProcessing=true +sendAwaitFirstMessage=false +sendBuildChannelConfig=at_startup +sendStrategy=complete_all +sendSyncTimeout=0 +socketType=DEFAULT +validationInconsistency=keep_as_is diff --git a/devices/inp.properties b/devices/inp.properties new file mode 100644 index 0000000..3d8946d --- /dev/null +++ b/devices/inp.properties @@ -0,0 +1,10 @@ +#Thu Mar 12 13:34:04 CET 2026 +deadband=NaN +description=Test Calcout Inopput +maxValue=1000.0 +minValue=-1000.0 +offset=0.0 +precision=5 +scale=1.0 +sign_bit=0 +unit=mm diff --git a/devices/m1.properties b/devices/m1.properties index 7832097..8e41083 100644 --- a/devices/m1.properties +++ b/devices/m1.properties @@ -1,4 +1,5 @@ -#Tue Mar 18 14:13:39 CET 2025 +#Mon Dec 01 16:57:52 CET 2025 +deadband=NaN defaultSpeed=1.0 description=null estbilizationDelay=0 @@ -8,8 +9,7 @@ minSpeed=0.1 minValue=-10.0 monitorByPosition=false offset=0.0 -precision=2 -resolution=NaN +precision=3 rotation=false scale=1.0 sign_bit=0 diff --git a/devices/m2.properties b/devices/m2.properties index 7832097..b58419e 100644 --- a/devices/m2.properties +++ b/devices/m2.properties @@ -1,4 +1,5 @@ -#Tue Mar 18 14:13:39 CET 2025 +#Mon Dec 01 16:58:07 CET 2025 +deadband=NaN defaultSpeed=1.0 description=null estbilizationDelay=0 @@ -8,8 +9,7 @@ minSpeed=0.1 minValue=-10.0 monitorByPosition=false offset=0.0 -precision=2 -resolution=NaN +precision=3 rotation=false scale=1.0 sign_bit=0 diff --git a/devices/motor.properties b/devices/motor.properties index 87c32ab..65e70b9 100644 --- a/devices/motor.properties +++ b/devices/motor.properties @@ -9,7 +9,7 @@ minValue=-10.0 monitorByPosition=false offset=0.0 precision=2 -resolution=NaN +deadband=NaN rotation=false scale=1.0 sign_bit=0 diff --git a/devices/out.properties b/devices/out.properties new file mode 100644 index 0000000..1d08141 --- /dev/null +++ b/devices/out.properties @@ -0,0 +1,7 @@ +#Thu Mar 12 13:34:04 CET 2026 +description=Test Calcout Output +offset=0.0 +precision=5 +scale=1.0 +sign_bit=0 +unit=mm diff --git a/devices/p1.properties b/devices/p1.properties index d4f7619..a22c43a 100644 --- a/devices/p1.properties +++ b/devices/p1.properties @@ -4,7 +4,7 @@ maxValue=1000.0 minValue=0.0 offset=0.0 precision=-1 -resolution=NaN +deadband=NaN rotation=false scale=1.0 sign_bit=0 diff --git a/devices/positioner.properties b/devices/positioner.properties index a7f9256..d27d222 100644 --- a/devices/positioner.properties +++ b/devices/positioner.properties @@ -4,7 +4,7 @@ maxValue=1000.0 minValue=-1000.0 offset=0.0 precision=5 -resolution=Infinity +deadband=Infinity scale=1.0 sign_bit=0 unit=mm diff --git a/plugins/TestScript.form b/plugins/TestScript.form new file mode 100644 index 0000000..94f292e --- /dev/null +++ b/plugins/TestScript.form @@ -0,0 +1,51 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/plugins/TestScript.java b/plugins/TestScript.java new file mode 100644 index 0000000..97e96e7 --- /dev/null +++ b/plugins/TestScript.java @@ -0,0 +1,121 @@ + +import ch.psi.pshell.framework.ScriptProcessor; +import ch.psi.pshell.framework.Task; +import ch.psi.pshell.utils.State; +import java.util.HashMap; +import java.util.Map; + +/** + * + */ +public class TestScript extends ScriptProcessor { + + //TODO: set script name + public static final String SCRIPT_NAME = "TestScript"; + + public TestScript() { + initComponents(); + } + + //Overridable callbacks + @Override + public void onInitialize(int runCount) { + + } + + @Override + public void onStateChange(State state, State former) { + + } + + @Override + public void onExecutedFile(String fileName, Object result) { + } + + @Override + public void onTaskFinished(Task task) { + } + + @Override + protected void onTimer() { + } + + @Override + protected void onLoaded() { + scanPlot.initialize(); + scanPlot.setActive(true); + System.out.println("OK"); + } + + @Override + protected void onUnloaded() { + + } + + + @Override + protected void onStartingExecution(Map args) throws Exception{ + } + + @Override + protected void onFinishedExecution(Map args, Object ret, Throwable t) throws Exception{ + } + + + //Invoked by 'update()' to update components in the event thread + @Override + protected void doUpdate() { + } + + + @Override + public String getScript(){ + return SCRIPT_NAME; + } + + + + @Override + public Map getArgs(){ + //TODO: add script arguments + Map ret = new HashMap<>(); + return ret; + } + + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + scanPlot = new ch.psi.pshell.swing.PlotPanel(); + + javax.swing.GroupLayout scanPlotLayout = new javax.swing.GroupLayout(scanPlot); + scanPlot.setLayout(scanPlotLayout); + scanPlotLayout.setHorizontalGroup( + scanPlotLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 476, Short.MAX_VALUE) + ); + scanPlotLayout.setVerticalGroup( + scanPlotLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 394, Short.MAX_VALUE) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 476, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(scanPlot, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 394, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(scanPlot, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + // Variables declaration - do not modify//GEN-BEGIN:variables + private ch.psi.pshell.swing.PlotPanel scanPlot; + // End of variables declaration//GEN-END:variables +} diff --git a/script/TestScript.py b/script/TestScript.py new file mode 100644 index 0000000..7f54e89 --- /dev/null +++ b/script/TestScript.py @@ -0,0 +1 @@ +tscan(ai1, 10, 1.0) diff --git a/script/cpython2.py b/script/cpython2.py new file mode 100644 index 0000000..1209deb --- /dev/null +++ b/script/cpython2.py @@ -0,0 +1,116 @@ +################################################################################################### +# 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 sys +import os + +#import matplotlib +#matplotlib.use('TkAgg') + +import pandas as pd +import numpy as np +import matplotlib.pyplot as plt + +#try: +# import tkinter as tk +#except: +# import Tkinter as tk + + +def calc(array): + return np.transpose(array + array) + + +def test_pandas(): + s = pd.Series([1,3,5,np.nan,6,8]) + print (s) + dates = pd.date_range('20130101', periods=6) + print (dates) + df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD')) + print (df) + df2 = pd.DataFrame({ 'A' : 1., + 'B' : pd.Timestamp('20130102'), + 'C' : pd.Series(1,index=list(range(4)),dtype='float32'), + 'D' : np.array([3] * 4,dtype='int32'), + 'E' : pd.Categorical(["test","train","test","train"]), + 'F' : 'foo' }) + print (df2) + print (df2.dtypes) + print (df.head()) + print (df.tail(3)) + print (df.values) + print (df.describe()) + print (df.T) + print (df.sort_index(axis=1, ascending=False)) + #print (df.sort_values(by='B')) + print (df['A']) + print (df[0:3]) + print (df.mean()) + return str(df.mean()) + + +def test_tkinter(): + root = tk.Tk() + listb = tk.Listbox(root) + for item in ["Hello", "World"]: + listb.insert(0,item) + listb.pack() + root.mainloop() + + +def test_matplotlib(start,stop,step): + import threading + x = np.arange(start,stop,step) + y = np.exp(-x) + + # example variable error bar values + yerr = 0.1 + 0.2*np.sqrt(x) + xerr = 0.1 + yerr + + # First illustrate basic pyplot interface, using defaults where possible. + plt.figure() + plt.errorbar(x, y, xerr=0.2, yerr=0.4) + plt.title("Simplest errorbars, 0.2 in x, 0.4 in y") + + # Now switch to a more OO interface to exercise more features. + fig, axs = plt.subplots(nrows=2, ncols=2, sharex=True) + ax = axs[0,0] + ax.errorbar(x, y, yerr=yerr, fmt='o') + ax.set_title('Vert. symmetric') + + # With 4 subplots, reduce the number of axis ticks to avoid crowding. + ax.locator_params(nbins=4) + + ax = axs[0,1] + ax.errorbar(x, y, xerr=xerr, fmt='o') + ax.set_title('Hor. symmetric') + + ax = axs[1,0] + ax.errorbar(x, y, yerr=[yerr, 2*yerr], xerr=[xerr, 2*xerr], fmt='--o') + ax.set_title('H, V asymmetric') + + ax = axs[1,1] + ax.set_yscale('log') + # Here we have to be careful to keep all y values positive: + ylower = np.maximum(1e-2, y - yerr) + yerr_lower = y - ylower + + ax.errorbar(x, y, yerr=[yerr_lower, 2*yerr], xerr=xerr, + fmt='o', ecolor='g', capthick=2) + ax.set_title('Mixed sym., log y') + + fig.suptitle('Variable errorbars') + + plt.show() + return [start,stop,step] + + +if __name__ == "__main__": + x = np.arange(0, 5, 0.1) + y = np.sin(x) + plt.plot(x, y) + plt.show() + + diff --git a/script/methood.py b/script/methood.py index 42e40c6..753ef22 100644 --- a/script/methood.py +++ b/script/methood.py @@ -1,3 +1,4 @@ +1/0 def test(): ### pass \ No newline at end of file diff --git a/script/test_camserver.py b/script/test_camserver.py new file mode 100644 index 0000000..2be05d0 --- /dev/null +++ b/script/test_camserver.py @@ -0,0 +1,82 @@ +#START AS: pshell console -dev -v -k -b -g -t test_camserver,1,5 -r false (-cl FINE)(--debug -y) +import ch.psi.pshell.screenpanel.CamServerViewer as CamServerViewer +import traceback + +SHOW_RENDERER=False +CAMERA="simulation" +CHANNEL_IMG = "TEST:FPICTURE" +CHANNEL_WIDTH = "TEST:WIDTH" +CHANNEL_HEIGHT = "TEST:HEIGHT" +INTERVAL = 1.0 +SHOW_PROFILE = False +SHOW_FIT = True +#IMAGE_TYPE = PV.Type.SHORT +IMAGE_TYPE = PV.Type.BYTE +#IMAGE_SIZE = Dimension(500,500) +#IMAGE_SIZE = Dimension(255,255) +IMAGE_SIZE = Dimension(300,218) +MAX_IMAGE_SIZE = 65500 if PV.Type.BYTE else 65500/2 +DEBUG = (not Setup.isServerMode()) or Setup.isDebug() +PLOT = DEBUG + +img = PV.waveform(CHANNEL_IMG, IMAGE_TYPE, MAX_IMAGE_SIZE) +width = PV.scalar(CHANNEL_WIDTH, PV.Type.INT) +height = PV.scalar(CHANNEL_HEIGHT, PV.Type.INT) + +viewer = CamServerViewer() +viewer.applyOptions(); +viewer.initialize(CamServerViewer.SourceSelecionMode.Single); +viewer.setStream(CAMERA) +viewer.camera.config.colormap=Colormap.Flame +viewer.camera.config.colormapAutomatic = True + +viewer.setShowProfile(SHOW_PROFILE) +viewer.setShowFit(SHOW_FIT) +r=viewer.renderer +r.setPenProfile(Pen(Color.GRAY, 0)) +viewer.setPenFit(Pen(Color.WHITE, 0)) +viewer.setPenCross(Pen(Color.WHITE, 0)) + +if SHOW_RENDERER: + f=SwingUtils.showFrame(App.getMainFrame(), "CamServerViewer", Dimension(450,250), r) + f.setAlwaysOnTop(True) +else: + r.device.addListener(r) +p=None + +try: + r.waitImage(10000) + while True: + i=r.getImage(True, IMAGE_SIZE) + i=ImagingUtils.grayscale(i) + d = Data(i) + a = d.array + if IMAGE_TYPE != PV.Type.BYTE: + a=Convert.toUnsigned(a) + img.write(a) + width.write(d.width) + height.write(d.height) + if PLOT: + matrix = Convert.reshape(a, d.height, d.width) + if IMAGE_TYPE == PV.Type.BYTE: + matrix=Convert.toUnsigned(matrix) + #p=plot(matrix)[0] + if p is None or (s.numberOfBinsX!=d.width) []or (s.numberOfBinsY!=d.height): + p=plot(matrix)[0] + p.setColormap(Colormap.Grayscale) + p.getAxis(p.AxisId.Y).inverted=True + s=p.getSeries(0) + else: + s.setData(Convert.toDouble(matrix)) + if INTERVAL: + time.sleep(INTERVAL) + r.waitNext(10000) #If stops receiving, tries restarting +except: + width.write(0) + height.write(0) + if DEBUG: + print "Camera image processing exception:" + print sys.exc_info()[1] + traceback.print_exc() +finally: + viewer.setStream(None) \ No newline at end of file diff --git a/script/test_channels.py b/script/test_channels.py new file mode 100644 index 0000000..9d32ae5 --- /dev/null +++ b/script/test_channels.py @@ -0,0 +1,90 @@ +if not "_pvs" in globals(): + _pvs = {} + +def get_waveform_pv(name, typ='double', size=None): + if name not in _pvs: + class Waveform(RegisterBase, RegisterArray): + def __init__(self, name): + RegisterBase.__init__(self, name) + self.fixed_size = None + self.clear() + + def clear(self): + self.val = None + #if self.fixed_size: + # self.val = [float("nan")] * self.fixed_size + #else: + # self.val = [float("nan")] + + def doRead(self): + return self.val + + def doWrite(self, val): + if val is None or len(val) == 0: + self.clear() + elif self.fixed_size: + self.clear() + del val[self.fixed_size:] + self.val[:len(val)] = val + else: + self.val = val + print self.val + + def getSize(self): + return len(self.val) + + def fixSize(self, size): + self.fixed_size = size + self.clear() + + waveform = Waveform(name) + #waveform.fixSize(size) + waveform.initialize() + cas = CAS(name, waveform, typ) + _pvs[name] = [waveform, cas] + return _pvs[name][0] + + +def get_scalar_pv(name, typ='double', size=None): + if name not in _pvs: + class Scalar(RegisterBase): + def __init__(self, name): + RegisterBase.__init__(self, name) + self.fixed_size = None + self.clear() + + def clear(self): + self.val = float("nan") + + def doRead(self): + return self.val + + def doWrite(self, val): + if val is None: + self.clear() + else: + self.val = val + + scalar = Scalar(name) + scalar.initialize() + cas = CAS(name, scalar, typ) + _pvs[name] = [scalar, cas] + return _pvs[name][0] + + +pv = get_waveform_pv("TEST_CHANNELS:ai1","double") +sc = get_scalar_pv("TEST_CHANNELS:ai2","double") + + +def after_read(record, scan): + #print scan.result[ai1] + [record[ai1],] + pv.write(scan.result[ai1]) + sc.write(record.index) + + +r= tscan((ai1, ai1), 5, 0.1, after_read=after_read, save=False) +pv.write(r[ai1]) +sc.write(len(r)) + +print pv.read() +print sc.read() \ No newline at end of file diff --git a/script/test_channels2.py b/script/test_channels2.py new file mode 100644 index 0000000..e069acc --- /dev/null +++ b/script/test_channels2.py @@ -0,0 +1,22 @@ +wf = PV.waveform("TEST:WAVEFORM", PV.Type.DOUBLE, 5) +sc = PV.scalar("TEST:SCALAR", PV.Type.DOUBLE) +st = PV.scalar("TEST:STATE", PV.Type.STRING) + +if st.read()=="Busy": + print "Ongoing operation" + raise Exception ("Ongoing operation") +st.write("Busy") + +def after_read(record, scan): + #print scan.result[ai1] + [record[ai1],] + wf.write(scan.result[ai1]) + sc.write(record.index) + +try: + r= tscan((ai1, ai1), 5, 1.5, after_read=after_read, save=False) + wf.write(r[ai1]) + sc.write(len(r)) + print wf.read() + print sc.read() +finally: + st.write("Ready") \ No newline at end of file diff --git a/script/test_data_txt.py b/script/test_data_txt.py index 5a4afef..ebe4e2f 100644 --- a/script/test_data_txt.py +++ b/script/test_data_txt.py @@ -2,11 +2,12 @@ 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" +path = "group/data4"+ str(time.time()) create_dataset(path, 'd', False, (0,0)) for row in data2d: append_dataset(path, row) read =load_data(path) print read.tolist() plot(read) +run("test_sleep") set_return(True) \ No newline at end of file diff --git a/script/test_list.py b/script/test_list.py index 2260324..d909784 100644 --- a/script/test_list.py +++ b/script/test_list.py @@ -3,7 +3,7 @@ a = [1,2,3] d = to_array(a) l=to_list(d) -print (a) +print (d) print (l) print (type(a)==type(l)) print (a==l) diff --git a/script/test_nested.py b/script/test_nested.py index ca17f98..6b0d689 100644 --- a/script/test_nested.py +++ b/script/test_nested.py @@ -1,3 +1,4 @@ +print "->START" run("test_data_txt") time.sleep(0.5) run("test_data_txt") @@ -7,4 +8,5 @@ time.sleep(0.5) run("test_data_txt") time.sleep(0.5) run("test_data_txt") -set_return(True) \ No newline at end of file +print "->FINISH" +set_return(True) diff --git a/script/test_plot_type.py b/script/test_plot_type.py new file mode 100644 index 0000000..00a8071 --- /dev/null +++ b/script/test_plot_type.py @@ -0,0 +1,3 @@ +ascan([m1,m2], [ai1], [0.0, 0.0], [1.0, 1.0], [2,4], latency=0.1,zigzag=True, plot_types={"ai1":1}, passes=2) +lscan(m1, wf1, 0.0, 1.0,5, latency=0.2, plot_types={"wf1":1}) + diff --git a/script/test_sleep.py b/script/test_sleep.py index dfc95b4..4b16875 100644 --- a/script/test_sleep.py +++ b/script/test_sleep.py @@ -1,2 +1,3 @@ print "Sleeping" sleep(1.0) +print "Done" \ No newline at end of file diff --git a/script/test_snapshot.py b/script/test_snapshot.py new file mode 100644 index 0000000..c34ec25 --- /dev/null +++ b/script/test_snapshot.py @@ -0,0 +1,64 @@ +################################################################################################### +# Use of Snapshot class to read and restore the state of devices +################################################################################################### + +#Initial state +ao1.write(1.0) +ao2.write(2.0) + +#Snapshot creation: list of read-writable devices and an optional name. +#The name is only needed for saving/loading from files, so multiple different snapshots can be saved at a time. +#If ommited then name is set to "default", and it will overrite other snapshotws when saved. +s=Snapshot([ao1, ao2], "snapshot1") + +#Take snapshot +errors = s.take(Snapshot.Mode.PARALLEL) +if len(errors)>0: #take() returns return errors as a dict device -> exception. If empty then all devices were successfully read. + device, e = errors.keys()[0], errors[device] + raise Exception("Error taking " + device.name + " - " + str(e.message)) +#Do stuff +ao1.write(4.0) +ao2.write(5.0) +time.sleep(2.0) + +#Restore +errors = s.restore(Snapshot.Mode.PARALLEL) +if len(errors)>0: #restore() returns errors as a dict device -> exception. If empty then all devices were successfully restored. + device, e = errors.keys()[0], errors[device] + raise Exception("Error restoring " + device.name + " - " + str(e)) + +#Mode for take and restore can be: +#Snapshot.Mode.PARALLEL: all the devices are accessed in parallel, returning all errors. +#Snapshot.Mode.SERIES: all the devices are accessed sequentially, returning all errors. +#Snapshot.Mode.STOP_ON_ERROR: all the devices are access sequentially, but stops upon the first error. + +#Saving and loading from files +errors = s.take(Snapshot.Mode.PARALLEL) +if len(errors)>0: + raise errors[0] +timestamp = s.save() + +#Do stuff +ao1.write(8.0) +ao2.write(9.0) +time.sleep(2.0) + +#If you had still the reference to s when loading, you could use it to load +s.load(timestamp) #Loads the snapshot from that timestamp, or the most recent if timestamp is ommited +s.restore() +if len(errors)>0: + raise errors.values(0) + +ao1.write(6.0) +ao2.write(4.0) +time.sleep(2.0) + +#If you must load from file in a different script, then you must create a snapshot having the same name and set of devices. + +s2=Snapshot([ao1, ao2], "snapshot1") +s2.load() #Loads the last snapshot sved +s2.restore() +if len(errors)>0: + raise errors.values(0) + +