From 2d610fd680b3e53b38c3af333bead836e724c8d1 Mon Sep 17 00:00:00 2001
From: Guenter Quast <guenter.quast@online.de>
Date: Sat, 1 Jun 2024 15:05:38 +0200
Subject: [PATCH] added output to file in simple numpy format

---
 read_npy.py   | 23 +++++++++++++++++++++++
 redPoscdaq.py | 37 +++++++++++++++++++++++--------------
 2 files changed, 46 insertions(+), 14 deletions(-)
 create mode 100755 read_npy.py

diff --git a/read_npy.py b/read_npy.py
new file mode 100755
index 0000000..74fdc45
--- /dev/null
+++ b/read_npy.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python3
+"""read file from redPoscdaq (in npy format) and display data
+"""
+
+from npy_append_array import NpyAppendArray
+import numpy as np
+import sys
+import matplotlib.pyplot as plt
+
+data = np.load(sys.argv[1], mmap_mode='r')
+print("data read sucessfully, shape = ", data.shape)
+
+n_samples = len(data[0,0])
+xplt = 0.5 + np.linspace(0, n_samples, num=n_samples, endpoint=True)
+fig = plt.figure("Oscillogram", figsize=(8,6))
+
+for d in data:
+    plt.plot(xplt, d[0], '-')
+    plt.plot(xplt, d[1], '-')
+    plt.xlabel("time bin")
+    plt.ylabel("Voltage")    
+    plt.show()
+                  
diff --git a/redPoscdaq.py b/redPoscdaq.py
index 7ece4d0..03b2a7e 100755
--- a/redPoscdaq.py
+++ b/redPoscdaq.py
@@ -46,6 +46,8 @@ import numpy as np
 import matplotlib
 from matplotlib.figure import Figure
 
+from npy_append_array import NpyAppendArray
+
 from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
 from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
 
@@ -140,16 +142,12 @@ class rpControl(QMainWindow, Ui_MCPHA):
 
     def parse_args(self):
         parser =argparse.ArgumentParser(description=__doc__)
-        parser.add_argument('--no-daq', dest='daq_mode', action='store_false',
-                            help='do not start in DAQ mode' )
         parser.add_argument('-c', '--connect_ip', type=str,
             help='connect IP address of RedPitaya')
+        # for oscilloscope display
         parser.add_argument('-i', '--interval', type=int, default=100,
             help='interval for readout (in ms)')
-        parser.add_argument('-s', '--sample_size', type=int, default=4096,
-            help='size of waveform sample')
-        parser.add_argument('-p', '--pretrigger_fraction', type=float, default=0.05,
-            help='pretrigger fraction')
+        # trigger mode
         parser.add_argument('-t', '--trigger_level', type=int, default=500,
             help='trigger level in ADC counts')
         parser.add_argument('--trigger_slope', type=str, choices={'rising','falling'},
@@ -158,6 +156,15 @@ class rpControl(QMainWindow, Ui_MCPHA):
             help='trigger channel')
         parser.add_argument('--trigger_mode', type=str, choices={'norm','auto'}, default='norm', 
             help='trigger mode')
+        parser.add_argument('-s', '--sample_size', type=int, default=4096,
+            help='size of waveform sample')
+        parser.add_argument('-p', '--pretrigger_fraction', type=float, default=0.05,
+            help='pretrigger fraction')
+        # for daq mode
+        parser.add_argument('--no-daq', dest='daq_mode', action='store_false',
+                            help='do not start in DAQ mode' )
+        parser.add_argument('-f', '--file', type=str, default='',
+                            help='file name')
         
         args = parser.parse_args()
         # all relevant parameters are here
@@ -172,7 +179,8 @@ class rpControl(QMainWindow, Ui_MCPHA):
         self.trigger_mode = 0 if args.trigger_mode == 'norm' else 1
         self.trigger_slope = 0 if args.trigger_slope == 'rising' else 1
         # other parameters
-                
+        self.filename = args.file
+      
     def get_physical_units(self):
         """get physical units corresponding to ADC units and channel numbers
         """
@@ -395,6 +403,7 @@ class OscDAQ(QWidget, Ui_OscDisplay):
         self.l_tot = self.rpControl.sample_size
         self.pre = self.rpControl.pretrigger_fraction * self.l_tot
         self.buffer = np.zeros(self.l_tot * 2, np.int16)
+        self.filename = rpControl.filename if self.rpControl.filename != '' else None
         # create figure
         self.figure = Figure()
         if sys.platform != "win32":
@@ -574,15 +583,15 @@ class OscDAQ(QWidget, Ui_OscDisplay):
         self.Tprev = t
         self.dT += dt
         # reshape to an array (2, self.ltot)
-        data = self.buffer.reshape(2,self.l_tot, order='F')
-#        chan1 = self.buffer[0::2]
-#        chan2 = self.buffer[1::2]
+        data = self.buffer.reshape(2, self.l_tot, order='F')
         #
         # do something with data (e.g. pass to sub-process via mpQueue)
-        #
-        # ....
-        #
-        # output status once per second
+        # write to file:
+        if self.filename is not None:
+            with NpyAppendArray(self.filename) as npa:
+                npa.append( np.array([data]) )
+        #        
+        # output status and update scope display once per second
         if self.dT >= 1. :
             dN = self.NTrig - self.Nprev
             r = dN/self.dT
-- 
GitLab