pyForceDAQ 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. pyforcedaq/__init__.py +43 -0
  2. pyforcedaq/__main__.py +42 -0
  3. pyforcedaq/_lib/__init__.py +1 -0
  4. pyforcedaq/_lib/lsl.py +56 -0
  5. pyforcedaq/_lib/misc.py +126 -0
  6. pyforcedaq/_lib/polling_time_profile.py +52 -0
  7. pyforcedaq/_lib/process_priority_manager.py +148 -0
  8. pyforcedaq/_lib/timer.py +45 -0
  9. pyforcedaq/_lib/types.py +400 -0
  10. pyforcedaq/_lib/udp_connection.py +326 -0
  11. pyforcedaq/daq/__init__.py +19 -0
  12. pyforcedaq/daq/_daq_read_Analog_pydaqmx.py +114 -0
  13. pyforcedaq/daq/_daq_read_analog_nidaqmx.py +84 -0
  14. pyforcedaq/daq/_mock_sensor.py +80 -0
  15. pyforcedaq/daq/_pyATIDAQ.py +306 -0
  16. pyforcedaq/daq/config.py +13 -0
  17. pyforcedaq/extras/__init__.py +0 -0
  18. pyforcedaq/extras/convert.py +275 -0
  19. pyforcedaq/extras/expyriment_daq_control.py +246 -0
  20. pyforcedaq/extras/opensesame_daq_control.py +280 -0
  21. pyforcedaq/extras/read_force_data.py +89 -0
  22. pyforcedaq/extras/remote_control.py +93 -0
  23. pyforcedaq/force/__init__.py +13 -0
  24. pyforcedaq/force/_log.py +18 -0
  25. pyforcedaq/force/data_recorder.py +400 -0
  26. pyforcedaq/force/sensor.py +200 -0
  27. pyforcedaq/force/sensor_process.py +251 -0
  28. pyforcedaq/gui/__init__.py +6 -0
  29. pyforcedaq/gui/_gui_status.py +306 -0
  30. pyforcedaq/gui/_layout.py +104 -0
  31. pyforcedaq/gui/_level_indicator.py +59 -0
  32. pyforcedaq/gui/_pg_surface.py +100 -0
  33. pyforcedaq/gui/_plotter.py +234 -0
  34. pyforcedaq/gui/_run.py +522 -0
  35. pyforcedaq/gui/_scaling.py +71 -0
  36. pyforcedaq/gui/_settings.py +98 -0
  37. pyforcedaq/gui/forceDAQ_logo.png +0 -0
  38. pyforcedaq/gui/launcher.py +249 -0
  39. pyforcedaq-2.0.0.dist-info/METADATA +15 -0
  40. pyforcedaq-2.0.0.dist-info/RECORD +42 -0
  41. pyforcedaq-2.0.0.dist-info/WHEEL +4 -0
  42. pyforcedaq-2.0.0.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,246 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ """
4
+ Expyriment convinient functions for the force DAQ remote control
5
+
6
+ (c) O. Lindemann
7
+
8
+ for two sensor setups
9
+
10
+ """
11
+
12
+ from expyriment import control, io, misc, stimuli
13
+
14
+ from . import remote_control as rc
15
+
16
+ FORCE_SERVER_IP = "192.168.1.2"
17
+ WEAK, FINE, STRONG = [0, 1, 2]
18
+ STR_FULL_FORCE = u"kräftig"
19
+ STR_LESS_FORCE = u"sacht"
20
+
21
+ stopwatch = misc.Clock()
22
+ udp = rc.init_udp_connection()
23
+ print(udp)
24
+
25
+
26
+ def runtimeerror(exp, text):
27
+ stimuli.TextScreen("ERROR", text).present()
28
+ exp.keyboard.wait()
29
+ control.end()
30
+ udp.send(rc.Command.QUIT)
31
+ exit()
32
+
33
+
34
+ def start(exp, time_for_feedback=10):
35
+ """ returns true if feedback is OK
36
+ waits a particular time (in sec) for feedback and
37
+ """
38
+
39
+ udp.send(rc.Command.START)
40
+ stopwatch.reset_stopwatch()
41
+ while True:
42
+ rtn = udp.poll()
43
+ exp.keyboard.check()
44
+ if rtn == rc.Command.FEEDBACK_STARTED:
45
+ break
46
+ if stopwatch.stopwatch_time > time_for_feedback * 1000:
47
+ return False
48
+ return True
49
+
50
+
51
+ def pause(exp, time_for_feedback=60 * 2):
52
+ """returns true if feedback is OK
53
+ waits a particular for feedback and
54
+ """
55
+
56
+ udp.send(rc.Command.PAUSE)
57
+ stopwatch.reset_stopwatch()
58
+ while True:
59
+ rtn = udp.poll()
60
+ exp.keyboard.check()
61
+ if rtn == rc.Command.FEEDBACK_PAUSED:
62
+ break
63
+ if stopwatch.stopwatch_time > time_for_feedback * 1000:
64
+ return False
65
+ return True
66
+
67
+
68
+ # make connection #
69
+ def make_connection(exp, experiment_name="force_daq"):
70
+ """hand shake and filename,
71
+ returns pyforcedaq version
72
+ """
73
+
74
+ stimuli.TextScreen("Prepare force recording", "press key if ready").present()
75
+ exp.keyboard.wait()
76
+ stimuli.BlankScreen().present()
77
+ while not udp.connect_peer(FORCE_SERVER_IP):
78
+ stimuli.TextScreen("ERROR while connecting to server",
79
+ "try again or <ESC> to quit").present()
80
+ exp.keyboard.wait()
81
+ stimuli.BlankScreen().present()
82
+ exp.clock.wait(300)
83
+
84
+ stimuli.TextScreen("Connected", "").present()
85
+ exp.clock.wait(500)
86
+ udp.send(rc.Command.FILENAME.decode('utf-8', 'replace') + "{0}_{1}.csv".format(experiment_name, exp.subject))
87
+ rtn = udp.receive(5) # paused
88
+ if rtn is None:
89
+ runtimeerror(exp, "Force server not responding")
90
+ version = rc.get_data(rc.Command.GET_VERSION)
91
+ stimuli.TextScreen("Connected", "Version " + version).present()
92
+ exp.clock.wait(1000)
93
+ return version
94
+
95
+
96
+ def force_button_box_prepare(n_sensors=1):
97
+ udp.clear_receive_buffer()
98
+ udp.send(rc.Command.SET_LEVEL_CHANGE_DETECTION)
99
+ if n_sensors>1:
100
+ udp.send(rc.Command.SET_LEVEL_CHANGE_DETECTION2)
101
+
102
+
103
+ def force_button_box_check():
104
+ """
105
+ changes to level
106
+ """
107
+ evt, level = rc.poll_multiple_events([rc.Command.CHANGED_LEVEL, rc.Command.CHANGED_LEVEL2])
108
+ if evt is not None:
109
+ if evt == rc.Command.CHANGED_LEVEL:
110
+ sensor = 1
111
+ else:
112
+ sensor = 2
113
+ return (sensor, level)
114
+ return (None, None)
115
+
116
+
117
+ def force_button_box_wait(exp, duration=None, minimum_level=-1):
118
+ """
119
+ returns if one of two sensors changes its level
120
+ """
121
+
122
+ stopwatch.reset_stopwatch()
123
+ last_key = None
124
+ rt = None
125
+ force_button_box_prepare()
126
+ while not(duration is not None and stopwatch.stopwatch_time > duration):
127
+ sensor, level = force_button_box_check()
128
+ if sensor is not None:
129
+ if level>=minimum_level:
130
+ rt = stopwatch.stopwatch_time
131
+ break
132
+ else:
133
+ force_button_box_prepare()
134
+ sensor = None
135
+ last_key = exp.keyboard.check()
136
+ if last_key is not None:
137
+ break
138
+
139
+ return sensor, level, rt, last_key
140
+
141
+
142
+ def wait_no_button_pressed(exp, feedback_stimulus=None, polling_intervall=500):
143
+ """level detection needs to be switch on
144
+ display feedback_stimulus (optional) if one button pressed
145
+ """
146
+ if rc.get_data(rc.Command.GET_THRESHOLD_LEVEL) > 0 or \
147
+ rc.get_data(rc.Command.GET_THRESHOLD_LEVEL) > 0:
148
+ if feedback_stimulus is not None:
149
+ feedback_stimulus.present()
150
+ while rc.get_data(rc.Command.GET_THRESHOLD_LEVEL) > 0 or \
151
+ rc.get_data(rc.Command.GET_THRESHOLD_LEVEL) > 0:
152
+ exp.keyboard.wait(duration=polling_intervall)
153
+
154
+
155
+ ############ further convenient functions
156
+ def hold_check(exp, holding_time, background_stimulus=None,
157
+ n_sensors=2): # FIXME not checked for sensor=1
158
+ if background_stimulus is None:
159
+ background_stimulus = stimuli.BlankScreen()
160
+
161
+ background_stimulus.present()
162
+ background_stimulus.present()
163
+ udp.send("hold:test")
164
+
165
+ fine = stimuli.Circle(radius=20, colour=misc.constants.C_GREY, line_width=0)
166
+ too_low = stimuli.Circle(radius=20, colour=misc.constants.C_GREEN, line_width=0)
167
+ too_strong = stimuli.Circle(radius=20, colour=misc.constants.C_RED, line_width=0)
168
+ bkg = [stimuli.Circle(position=(-200, 0), radius=24, colour=misc.constants.C_BLACK, line_width=0),
169
+ stimuli.Circle(position=(200, 0), radius=24, colour=misc.constants.C_BLACK, line_width=0)]
170
+
171
+ key = None
172
+ stopwatch.reset_stopwatch()
173
+
174
+ while key is None and stopwatch.stopwatch_time < holding_time:
175
+ key = exp.keyboard.check()
176
+ udp.clear_receive_buffer()
177
+ lv = [rc.get_data(rc.Command.GET_THRESHOLD_LEVEL),
178
+ rc.get_data(rc.Command.GET_THRESHOLD_LEVEL2)]
179
+ for i in range(n_sensors):
180
+ bkg[i].clear_surface()
181
+ if lv[i] == WEAK:
182
+ too_low.plot(bkg[i])
183
+ stopwatch.reset_stopwatch()
184
+ elif lv[i] == STRONG:
185
+ too_strong.plot(bkg[i])
186
+ stopwatch.reset_stopwatch()
187
+ elif lv[i] == FINE:
188
+ fine.plot(bkg[i])
189
+ bkg[i].present(clear=False, update=False)
190
+ bkg[i].present(clear=False, update=False)
191
+ exp.screen.update()
192
+
193
+ background_stimulus.present()
194
+
195
+ def _text2number_array(txt):
196
+ """helper function for textinput_thesholds """
197
+ rtn = []
198
+ try:
199
+ for x in txt.split(","):
200
+ rtn.append(float(x))
201
+ return rtn
202
+ except:
203
+ return None
204
+
205
+
206
+ def textinput_thesholds(message="Enter thresholds"):
207
+ thresholds = _text2number_array(io.TextInput(message=message).get())
208
+ stimuli.BlankScreen().present()
209
+ if thresholds is not None:
210
+ if len(thresholds) != 2:
211
+ thresholds = None
212
+ return thresholds
213
+
214
+
215
+ def threshold_menu(exp, thresholds, last_item="Ende"):
216
+ while True:
217
+ select = io.TextMenu(heading=u"Schwellen: " + str(thresholds),
218
+ menu_items=["Schwellen Anpassen ", # 0
219
+ "Halten", # 1
220
+ last_item],
221
+ background_colour=misc.constants.C_GREY,
222
+ text_colour=misc.constants.C_BLACK,
223
+ width=500)
224
+ x = select.get()
225
+ blank = stimuli.BlankScreen()
226
+ blank.present()
227
+
228
+ if x == 0:
229
+ new = textinput_thesholds()
230
+ if new is not None:
231
+ thresholds = new
232
+ elif x == 1:
233
+ if not start(exp):
234
+ stimuli.TextScreen("ERROR: Could not start recording",
235
+ "Press key to quit").present()
236
+ exp.keyboard.wait()
237
+ exit()
238
+ exp.clock.wait(500)
239
+ rc.set_force_thresholds(lower=thresholds[0], upper=thresholds[1])
240
+ hold_check(exp, holding_time=10000)
241
+ blank.present()
242
+ pause(exp)
243
+ else:
244
+ break
245
+
246
+ return thresholds
@@ -0,0 +1,280 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ """
4
+ Openseame Object or the force DAQ remote control
5
+
6
+ (c) O. Lindemann
7
+
8
+ v0.9
9
+
10
+ """
11
+
12
+ from libopensesame.exceptions import osexception
13
+ from libopensesame.experiment import experiment
14
+ from openexp.canvas import canvas
15
+ from openexp.keyboard import keyboard
16
+
17
+ from . import remote_control as rc
18
+
19
+ FORCE_SERVER_IP = "192.168.1.1"
20
+ WEAK, FINE, STRONG = [0, 1, 2]
21
+
22
+ class OpensesameDAQControl():
23
+
24
+ def __init__(self, opensesame_experiment):
25
+ """ OpenSesame clock and var"""
26
+
27
+ if isinstance(opensesame_experiment, experiment):
28
+ self._exp = opensesame_experiment
29
+ else:
30
+ raise osexception("opensesame_experiment needs to be an instance of " +\
31
+ "opensesame.experiment.experiment")
32
+
33
+ self.clock = ExpyClock(self._exp.clock)
34
+ self.subject_number = self._exp.var.get(u'subject_nr')
35
+ self.experiment_name = self._exp.var.get(u'experiment_file').split('.')[0]
36
+ self.udp = rc.init_udp_connection()
37
+ self._exp.cleanup_functions.append(self.quit_recording)
38
+
39
+ def __del__(self):
40
+ self.quit_recording()
41
+
42
+ def start(self, time_for_feedback=10):
43
+ """ returns true if feedback is OK
44
+ waits a particular time (in sec) for feedback and
45
+ """
46
+
47
+ self.udp.send(rc.Command.START)
48
+ self.clock.reset_stopwatch()
49
+ kbd = keyboard(self._exp)
50
+ while True:
51
+ rtn = self.udp.poll()
52
+ kbd.get_key(timeout=0) # just for keyboard processing
53
+ if rtn == rc.Command.FEEDBACK_STARTED:
54
+ break
55
+ if self.clock.stopwatch_time > time_for_feedback*1000:
56
+ msg = "ERROR: Could not start recording <br/> Press key to quit"
57
+ cnv = canvas(self._exp)
58
+ cnv.text(msg)
59
+ cnv.show()
60
+ kbd.get_key()
61
+ self._exp.end()
62
+ exit()
63
+
64
+ return True
65
+
66
+ def stop(self):
67
+ self.udp.send(rc.Command.QUIT)
68
+
69
+ def quit_recording(self):
70
+ if self.udp is not None:
71
+ self.udp.send(rc.Command.QUIT)
72
+ self.udp = None
73
+
74
+ def pause(self, time_for_feedback=60 * 2, text_saving_time ="Please wait..."):
75
+ """returns true if feedback is OK (that means data are saved)
76
+ waits for a particular for feedback
77
+ """
78
+
79
+ self.udp.send(rc.Command.PAUSE)
80
+ self.clock.reset_stopwatch()
81
+ kbd = keyboard(self._exp)
82
+ if text_saving_time != None:
83
+ cnv = canvas(self._exp)
84
+ cnv.text(text_saving_time)
85
+ cnv.show()
86
+ while True:
87
+ rtn = self.udp.poll()
88
+ kbd.get_key(timeout=1)
89
+ if rtn == rc.Command.FEEDBACK_PAUSED:
90
+ break
91
+ if self.clock.stopwatch_time > time_for_feedback * 1000:
92
+ return False
93
+
94
+ if text_saving_time != None:
95
+ canvas(self._exp).show()
96
+
97
+ return True
98
+
99
+ # make connection #
100
+ def make_connection(self, ip=FORCE_SERVER_IP):
101
+ """hand shake and filename,
102
+ returns pyforcedaq version
103
+ """
104
+ kbd = keyboard(self._exp)
105
+ cnv = canvas(self._exp)
106
+
107
+ cnv.text("Prepare force recording <br> press key if ready")
108
+ cnv.show()
109
+ kbd.get_key()
110
+ canvas(self._exp).show()
111
+
112
+ while not self.udp.connect_peer(ip):
113
+ cnv = canvas(self._exp)
114
+ cnv.text("ERROR while connecting to server <br> try again or Q to quit")
115
+ cnv.show()
116
+ key = kbd.get_key()
117
+ if key[0] == u'q':
118
+ msg = "Experiment quitted by user!"
119
+ self.udp.send(rc.Command.QUIT)
120
+ print(msg)
121
+ self._exp.end()
122
+ exit()
123
+ canvas(self._exp).show()
124
+ self.clock.wait(300)
125
+
126
+ cnv = canvas(self._exp)
127
+ cnv.text("Connected")
128
+ cnv.show()
129
+ self.clock.wait(500)
130
+ self.udp.send(rc.Command.FILENAME.decode('utf-8', 'replace') + "{0}_{1}.csv".format(self.experiment_name,
131
+ self.subject_number))
132
+ rtn = self.udp.receive(5) # paused
133
+ if rtn is None:
134
+ msg = "Force server not responding"
135
+ cnv = canvas(self._exp)
136
+ cnv.text(msg)
137
+ cnv.show()
138
+ kbd.get_key()
139
+ self.udp.send(rc.Command.QUIT)
140
+ print(msg)
141
+ self._exp.end()
142
+ exit()
143
+ version = rc.get_data(rc.Command.GET_VERSION)
144
+ if version is None:
145
+ version = "" # FIXME Why is version somethimes None
146
+ cnv = canvas(self._exp)
147
+ cnv.text("Connected <br> Version " + version)
148
+ cnv.show()
149
+ self.clock.wait(1000)
150
+ return version
151
+
152
+ def force_button_box_prepare(self, n_sensors=1):
153
+ self.udp.clear_receive_buffer()
154
+ self.udp.send(rc.Command.SET_LEVEL_CHANGE_DETECTION)
155
+ if n_sensors>1:
156
+ self.udp.send(rc.Command.SET_LEVEL_CHANGE_DETECTION2)
157
+
158
+ def force_button_box_check(self):
159
+ """
160
+ changes to level
161
+ """
162
+ evt, level = rc.poll_multiple_events([rc.Command.CHANGED_LEVEL,
163
+ rc.Command.CHANGED_LEVEL2])
164
+ if evt is not None:
165
+ if evt == rc.Command.CHANGED_LEVEL:
166
+ sensor = 1
167
+ else:
168
+ sensor = 2
169
+ return (sensor, level)
170
+ return (None, None)
171
+
172
+ def force_button_box_wait(self, duration=None, minimum_level=-1):
173
+ """
174
+ returns if one of two sensors changes its level
175
+ """
176
+
177
+ self.clock.reset_stopwatch()
178
+ kbd = keyboard(self._exp)
179
+ last_key = None
180
+ rt = None
181
+ self.force_button_box_prepare()
182
+ while not (duration is not None and self.clock.stopwatch_time > duration):
183
+ sensor, level = self.force_button_box_check()
184
+ if sensor is not None:
185
+ if level >= minimum_level:
186
+ rt = self.clock.stopwatch_time
187
+ break
188
+ else:
189
+ self.force_button_box_prepare()
190
+ sensor = None
191
+ last_key, _ = kbd.get_key(timeout=0)
192
+ if last_key is not None:
193
+ break
194
+
195
+ return sensor, level, rt, last_key
196
+
197
+ def wait_no_button_pressed(self, feedback_stimulus_text=None, polling_intervall=500):
198
+ """level detection needs to be switch on
199
+ display feedback_stimulus (optional) if one button pressed
200
+ """
201
+ if rc.get_data(rc.Command.GET_THRESHOLD_LEVEL) > 0 or \
202
+ rc.get_data(rc.Command.GET_THRESHOLD_LEVEL) > 0:
203
+ if feedback_stimulus_text is not None:
204
+ cnv = canvas(self._exp)
205
+ cnv.text(feedback_stimulus_text)
206
+ cnv.show()
207
+ kbd = keyboard(self._exp)
208
+ while rc.get_data(rc.Command.GET_THRESHOLD_LEVEL) > 0 or \
209
+ rc.get_data(rc.Command.GET_THRESHOLD_LEVEL) > 0:
210
+ kbd.get_key(timeout=polling_intervall)
211
+
212
+ def set_thresholds(self, lower, upper):
213
+ rc.set_force_thresholds(lower=lower, upper=upper)
214
+
215
+ def hold_check(self, holding_time=3000,
216
+ left_pos=-200, right_pos=200, radius=50,
217
+ col_fine='gray',
218
+ col_too_low='green',
219
+ col_too_strong='red',
220
+ n_sensors=2):
221
+ kbd = keyboard(self._exp)
222
+ blank = canvas(self._exp)
223
+ blank.show()
224
+
225
+ self.udp.send("hold:test")
226
+ self.clock.reset_stopwatch()
227
+ prev_lv = None
228
+ while True:
229
+ self.udp.clear_receive_buffer()
230
+ lv = [rc.get_data(rc.Command.GET_THRESHOLD_LEVEL)]
231
+ if n_sensors>1:
232
+ lv.append(rc.get_data(rc.Command.GET_THRESHOLD_LEVEL2))
233
+ else:
234
+ lv.append(lv[0]) # just double, if one sensor
235
+
236
+ if prev_lv != lv:
237
+ # level has changes
238
+ self.clock.reset_stopwatch()
239
+ prev_lv = lv
240
+ cnv = canvas(self._exp)
241
+ for i, pos in enumerate([left_pos, right_pos]):
242
+ if lv[i] == WEAK:
243
+ cnv.circle(x=pos, y=0, r=radius, fill=True,
244
+ color=col_too_low)
245
+ elif lv[i] == STRONG:
246
+ cnv.circle(x=pos, y=0, r=radius, fill=True,
247
+ color=col_too_strong)
248
+ elif lv[i] == FINE:
249
+ cnv.circle(x=pos, y=0, r=radius, fill=True,
250
+ color=col_fine)
251
+ cnv.show()
252
+
253
+ key, _ = kbd.get_key(timeout=0)
254
+ if (lv == [FINE, FINE] and self.clock.stopwatch_time > holding_time) or\
255
+ (key is not None):
256
+ break
257
+
258
+ blank.show()
259
+
260
+
261
+ class ExpyClock():
262
+ """Expyriment-like stopwatch based on Opensesame clock"""
263
+
264
+ def __init__(self, opensesame_clock):
265
+ self._clock = opensesame_clock
266
+ self.reset_stopwatch()
267
+
268
+ @property
269
+ def time(self):
270
+ return self._clock.time()
271
+
272
+ @property
273
+ def stopwatch_time(self):
274
+ return self._clock.time() - self._start
275
+
276
+ def reset_stopwatch(self):
277
+ self._start = self._clock.time()
278
+
279
+ def wait(self, waiting_time):
280
+ return self._clock.sleep(waiting_time)
@@ -0,0 +1,89 @@
1
+ """
2
+ Functions to read your force and event data
3
+ """
4
+
5
+ __author__ = 'Oliver Lindemann'
6
+
7
+ import os
8
+ import sys
9
+ import gzip
10
+ from collections import OrderedDict
11
+ import numpy as np
12
+
13
+ TAG_COMMENTS = "#"
14
+ TAG_UDPDATA = TAG_COMMENTS + "UDP"
15
+ TAG_DAQEVENTS = TAG_COMMENTS + "T"
16
+
17
+ def _csv(line):
18
+ return list(map(lambda x: x.strip(), line.split(",")))
19
+
20
+ def DataFrameDict(data, varnames):
21
+ """data frame: Dict of numpy arrays
22
+
23
+ does not require Pandas, but can be easily converted to pandas dataframe
24
+ via pandas.DataFrame(data_frame_dict)
25
+
26
+ """
27
+
28
+ rtn = OrderedDict()
29
+ for v in varnames:
30
+ rtn[v] = []
31
+
32
+ for row in data:
33
+ for v, d in zip(varnames, row):
34
+ rtn[v].append(d)
35
+
36
+ return rtn
37
+
38
+
39
+ def data_frame_to_text(data_frame):
40
+ rtn = ",".join(data_frame.keys())
41
+ rtn += "\n"
42
+ for x in np.array(list(data_frame.values())).T:
43
+ rtn += ",".join(x) + "\n"
44
+ return rtn
45
+
46
+
47
+ def read_raw_data(path):
48
+ """reading trigger and udp data
49
+
50
+ Returns: data, udp_event, daq_events and comments
51
+
52
+ data, udp_event, daq_events: DataFrameDict
53
+ comments: text string
54
+ """
55
+
56
+ daq_events = []
57
+ udp_events = []
58
+ comments = ""
59
+ data = []
60
+ varnames = None
61
+ app_dir = os.path.split(sys.argv[0])[0]
62
+ path = os.path.abspath(os.path.join(app_dir, path))
63
+
64
+ if path.endswith("gz"):
65
+ fl = gzip.open(path, "rt")
66
+ else:
67
+ fl = open(path, "rt")
68
+
69
+ for ln in fl:
70
+ if ln.startswith(TAG_COMMENTS):
71
+ comments += ln
72
+ if ln.startswith(TAG_UDPDATA + ","):
73
+ udp_events.append(_csv(ln[len(TAG_UDPDATA) + 1:]))
74
+ elif ln.startswith(TAG_DAQEVENTS):
75
+ daq_events.append(_csv(ln[len(TAG_DAQEVENTS) + 1:]))
76
+ else:
77
+ # data
78
+ if varnames is None:
79
+ # first row contains varnames
80
+ varnames = _csv(ln)
81
+ else:
82
+ data.append(_csv(ln))
83
+ fl.close()
84
+
85
+ return (DataFrameDict(data, varnames),
86
+ DataFrameDict(udp_events, ["time", "value"]),
87
+ DataFrameDict(daq_events, ["time", "value"]),
88
+ comments)
89
+
@@ -0,0 +1,93 @@
1
+ """
2
+ import this module to have all relevant classes and function for the remote_control on your remote maschine
3
+ """
4
+
5
+ __author__ = 'Oliver Lindemann'
6
+
7
+ import atexit
8
+ from pickle import dumps, loads
9
+
10
+ from .._lib.types import Thresholds, bytes_startswith
11
+ from .._lib.types import GUIRemoteControlCommands as Command
12
+ from .._lib.udp_connection import UDPConnection
13
+
14
+ udp = None
15
+
16
+ def init_udp_connection():
17
+ """init udp connecting afterwards udp connection is available via
18
+ remote_control.udp
19
+
20
+ REQUIRED BEFORE USING OTHER FUNCTIONS
21
+
22
+ returns udp connection
23
+ """
24
+ global udp
25
+ udp = UDPConnection()
26
+ return udp
27
+
28
+ def quit():
29
+ global udp
30
+ if isinstance(udp, UDPConnection):
31
+ udp.send(Command.QUIT)
32
+ udp = None
33
+
34
+
35
+ atexit.register(quit)
36
+
37
+ def get_data(get_command):
38
+ """Get data from the recording PC
39
+ get_commands e.g.
40
+ Command.GET_FZ or
41
+ Command.GET_VERSION
42
+ ....
43
+ """
44
+
45
+ udp.send(get_command)
46
+ d = udp.receive(1)
47
+ try:
48
+ return loads(d[len(Command.VALUE):])
49
+ except:
50
+ return None
51
+
52
+ def poll_event(event_type):
53
+ """polling response minmax level
54
+ event_tag:
55
+ Command.RESPONSE_MINMAX or
56
+ Command.CHANGED_LEVEL
57
+ ....
58
+ """
59
+ rcv = udp.poll()
60
+ if rcv is not None and bytes_startswith(rcv, event_type):
61
+ x = loads(rcv[len(event_type):])
62
+ return x
63
+ else:
64
+ return None
65
+
66
+
67
+ def poll_multiple_events(event_type_list):
68
+ """polling for multiple events
69
+ e.g.
70
+ [Command.CHANGED_LEVEL, Command.CHANGED_LEVEL2]
71
+
72
+ returns tuple (event_type, event_type_data) or (None, None)
73
+
74
+ """
75
+ rcv = udp.poll()
76
+ if rcv is not None:
77
+ for event_type in event_type_list:
78
+ if bytes_startswith(rcv, event_type):
79
+ x = loads(rcv[len(event_type):])
80
+ return (event_type, x)
81
+ return (None, None)
82
+
83
+
84
+ def set_force_thresholds(lower, upper):
85
+ thr = Thresholds([lower, upper])
86
+ return udp.send(Command.SET_THRESHOLDS + dumps(thr))
87
+
88
+
89
+ def set_level_change_detection(sensor=1):
90
+ if sensor==2:
91
+ return udp.send(Command.SET_LEVEL_CHANGE_DETECTION2)
92
+ else:
93
+ return udp.send(Command.SET_LEVEL_CHANGE_DETECTION)