66import pyqtgraph as pg
77from PySide6 .QtCore import QTimer
88from PySide6 .QtGui import QAction , QIcon , QPixmap
9- from PySide6 .QtWidgets import QMainWindow , QStatusBar , QMenu , QToolButton , QMessageBox
9+ from PySide6 .QtWidgets import QMainWindow , QStatusBar , QMenu , QToolButton , QMessageBox , QFileDialog
1010from WidgetCollection .Dialogs import AboutDialog
1111
1212from pyqtgraph .dockarea import DockArea , Dock
2525# get the version of the current module, given in the pyproject.toml
2626
2727
28+ def downsample_data (data , num_points ):
29+ """
30+ Downsample the data by selecting points at equal intervals.
2831
32+ Args:
33+ data (list): The original data list.
34+ num_points (int): The desired number of data points.
35+
36+ Returns:
37+ list: The downsampled data list.
38+ """
39+ if num_points >= len (data ):
40+ return data
41+
42+ interval = len (data ) // num_points
43+ downsampled_data = [data [i * interval ] for i in range (num_points )]
44+
45+ # If the length of the data is not exactly divisible by the interval,
46+ # append the last point to the downsampled data.
47+ if len (data ) % num_points != 0 :
48+ downsampled_data .append (data [- 1 ])
49+
50+ return downsampled_data
51+
52+ previewDataPoints = 10000
2953
3054class ControlWindow (QMainWindow ):
3155
@@ -78,11 +102,11 @@ def __init__(self, model: AD2ScopeModel, controller: BaseADScopeController):
78102
79103 # Timer for periodically updating the plot
80104 self .capture_update_timer = QTimer ()
81- self .capture_update_timer .setInterval (10 )
105+ self .capture_update_timer .setInterval (50 )
82106 self .capture_update_timer .timeout .connect (self ._on_capture_update_plot )
83107
84108 self .stream_update_timer = QTimer ()
85- self .stream_update_timer .setInterval (40 )
109+ self .stream_update_timer .setInterval (50 )
86110 self .stream_update_timer .timeout .connect (self ._on_stream_update_timer_timeout )
87111
88112 self .autostop_capture = QTimer ()
@@ -112,6 +136,11 @@ def _init_menu_bar(self):
112136
113137 self .file_menu .addSeparator ()
114138
139+ self .act_save_data = QAction ('Save Data' , self )
140+ self .act_save_data .triggered .connect (self .save_data )
141+ self .act_save_data .setShortcut ('Ctrl+S' )
142+ self .file_menu .addAction (self .act_save_data )
143+
115144 self .act_view_data = QAction ('View Data' , self )
116145 self .act_view_data .triggered .connect (self .view_data )
117146 self .act_view_data .setShortcut ('Ctrl+Alt+S' )
@@ -130,6 +159,15 @@ def _init_menu_bar(self):
130159 self ._ui .menu_file .setMenu (self .file_menu )
131160 self ._ui .menu_file .setPopupMode (QToolButton .ToolButtonPopupMode .InstantPopup )
132161
162+ def save_data (self ):
163+ self .controller .create_dataframe ()
164+
165+ # Create a file dialog to save the dataframe
166+ file_path , _ = QFileDialog .getSaveFileName (self , "Save Data" , "" , "CSV Files (*.csv)" )
167+ if file_path :
168+ self .model .capturing_information .recorded_samples_df .to_csv (file_path )
169+ self .status_bar .showMessage (f"Data saved to { file_path } " )
170+
133171 def view_data (self ):
134172 self .controller .create_dataframe ()
135173 pdview (self .model .capturing_information .recorded_samples_df )
@@ -146,7 +184,7 @@ def _init_UI_live_plot(self):
146184 self .scope_original = pg .PlotWidget (title = "AD2 Acquisition" )
147185 self .scope_original .plotItem .showGrid (x = True , y = True , alpha = 1 )
148186 d1 .addWidget (self .scope_original )
149- self .scope_original .setYRange (- 1.5 , 1.5 , padding = 0 )
187+ # self.scope_original.setYRange(-1.5, 1.5, padding=0)
150188
151189 self .scope_captured = pg .PlotWidget (title = "Captured Data" )
152190 self .scope_captured .plotItem .showGrid (x = True , y = True , alpha = 1 )
@@ -211,36 +249,17 @@ def _connect_signals(self):
211249 # Supervision Information
212250 self .model .supervisor_information .signals .supervisor_name_changed .connect (self ._on_supervisor_name_changed )
213251 self .model .supervisor_information .signals .supervised_changed .connect (self ._on_supervised_changed )
214- self .model .supervisor_information .signals .supervisor_model_changed .connect (self ._on_supervised_model_changed )
215-
216-
217252
218253 # ==================================================================================================================
219254 # Slots
220255 # ==================================================================================================================
221- def _on_supervisor_sweep_start_wavelength_changed (self , sweep_start_wavelength ):
222- print (f"Sweep Start Wavelength: { sweep_start_wavelength } " )
223-
224- def _on_supervisor_sweep_end_wavelength_changed (self , sweep_end_wavelength ):
225- print (f"Sweep End Wavelength: { sweep_end_wavelength } " )
226-
227256
228257 def _on_supervisor_name_changed (self , supervisor_name ):
229258 self .supervisor_info .supervisor_name = supervisor_name
230259
231260 def _on_supervised_changed (self , supervised ):
232261 self .supervisor_info .supervised = supervised
233262
234- def _on_supervised_model_changed (self ):
235- self .model .supervisor_information .supervisor_model .signals .sweep_start_wavelength_changed .connect (
236- self ._on_supervisor_sweep_start_wavelength_changed
237- )
238-
239- self .model .supervisor_information .supervisor_model .signals .sweep_stop_wavelength_changed .connect (
240- self ._on_supervisor_sweep_end_wavelength_changed
241-
242- )
243-
244263 def _on_dwf_version_changed (self , dwf_version ):
245264 """
246265 Gets called if the DWF version changes. Updates the UI.
@@ -432,9 +451,16 @@ def _on_capture_update_plot(self):
432451 if len (self .model .capturing_information .recorded_samples ) > 0 :
433452 self .scope_captured .clear ()
434453 # print(self.ad2device.recorded_samples)
435- d = self .model .capturing_information .recorded_samples_preview
436454
437- self .scope_captured .plot (d , pen = pg .mkPen (width = 1 ))
455+ # Downsample the data
456+ downsampled_data = downsample_data (
457+ self .model .capturing_information .recorded_samples ,
458+ previewDataPoints
459+ )
460+
461+ # Plot the downsampled data
462+ self .scope_captured .plot (downsampled_data , pen = pg .mkPen (width = 1 ))
463+
438464 # print(f"Length: {len(self.controller.recorded_sample_stream)}")
439465
440466 #if len(self.controller.status_dqueue) > 0:
@@ -449,8 +475,12 @@ def _on_stream_update_timer_timeout(self):
449475 # print(self.ad2device.recorded_samples)
450476
451477 self .scope_original .plot (
452- np .array (self .controller .streaming_dqueue ), # [::100],
453- pen = pg .mkPen (width = 1 ))
478+ downsample_data (
479+ np .array (self .controller .streaming_dqueue ),
480+ previewDataPoints
481+ ),
482+ pen = pg .mkPen (width = 1 )
483+ )
454484 # self._ui.lcd_unconsumed_stream.display(self.model.capturing_information.unconsumed_stream_samples)
455485
456486 # ============== Connected Device Information
0 commit comments