Skip to content

Commit 457c28e

Browse files
committed
Formatted code using the Black formatter - https://black.readthedocs.io
Resolves issue 82: #82
1 parent 398c7d2 commit 457c28e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+3000
-2543
lines changed

com/data_logger.py

+75-72
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
from datetime import datetime
44
from shutil import copyfile
55

6-
class Data_logger():
7-
'''Class for logging data from a pyControl setup to disk'''
6+
7+
class Data_logger:
8+
"""Class for logging data from a pyControl setup to disk"""
89

910
def __init__(self, sm_info=None, print_func=None, data_consumers=[]):
1011
self.data_file = None
@@ -16,55 +17,58 @@ def __init__(self, sm_info=None, print_func=None, data_consumers=[]):
1617

1718
def set_state_machine(self, sm_info):
1819
self.sm_info = sm_info
19-
self.ID2name_fw = self.sm_info['ID2name'] # Dict mapping framework IDs to names.
20-
20+
self.ID2name_fw = self.sm_info["ID2name"] # Dict mapping framework IDs to names.
21+
2122
def open_data_file(self, data_dir, experiment_name, setup_ID, subject_ID, datetime_now=None):
22-
'''Open file tsv/txt file for event data and write header information.
23-
If state machine uses analog inputs instantiate analog data writers.'''
23+
"""Open file tsv/txt file for event data and write header information.
24+
If state machine uses analog inputs instantiate analog data writers."""
2425
self.data_dir = data_dir
2526
self.experiment_name = experiment_name
2627
self.subject_ID = subject_ID
2728
self.setup_ID = setup_ID
28-
if datetime_now is None: datetime_now = datetime.now()
29+
if datetime_now is None:
30+
datetime_now = datetime.now()
2931
self.end_timestamp = -1
30-
file_name = self.subject_ID + datetime_now.strftime('-%Y-%m-%d-%H%M%S') + '.tsv'
32+
file_name = self.subject_ID + datetime_now.strftime("-%Y-%m-%d-%H%M%S") + ".tsv"
3133
self.file_path = os.path.join(self.data_dir, file_name)
32-
self.data_file = open(self.file_path, 'w', newline = '\n')
33-
self.data_file.write(self.tsv_row_str( # Write header with row names.
34-
rtype='type', time='time', name='name', value='value'))
35-
self.write_info_line('experiment_name', self.experiment_name)
36-
self.write_info_line('task_name', self.sm_info['name'])
37-
self.write_info_line('task_file_hash', self.sm_info['task_hash'])
38-
self.write_info_line('setup_id', self.setup_ID)
39-
self.write_info_line('framework_version', self.sm_info['framework_version'])
40-
self.write_info_line('micropython_version', self.sm_info['micropython_version'])
41-
self.write_info_line('subject_id', self.subject_ID)
42-
self.write_info_line('start_time', datetime.utcnow().isoformat(timespec='milliseconds'))
43-
self.analog_writers = {ID:
44-
Analog_writer(ai['name'], ai['fs'], ai['dtype'], self.file_path)
45-
for ID, ai in self.sm_info['analog_inputs'].items()}
34+
self.data_file = open(self.file_path, "w", newline="\n")
35+
self.data_file.write(
36+
self.tsv_row_str(rtype="type", time="time", name="name", value="value") # Write header with row names.
37+
)
38+
self.write_info_line("experiment_name", self.experiment_name)
39+
self.write_info_line("task_name", self.sm_info["name"])
40+
self.write_info_line("task_file_hash", self.sm_info["task_hash"])
41+
self.write_info_line("setup_id", self.setup_ID)
42+
self.write_info_line("framework_version", self.sm_info["framework_version"])
43+
self.write_info_line("micropython_version", self.sm_info["micropython_version"])
44+
self.write_info_line("subject_id", self.subject_ID)
45+
self.write_info_line("start_time", datetime.utcnow().isoformat(timespec="milliseconds"))
46+
self.analog_writers = {
47+
ID: Analog_writer(ai["name"], ai["fs"], ai["dtype"], self.file_path)
48+
for ID, ai in self.sm_info["analog_inputs"].items()
49+
}
4650

4751
def write_info_line(self, name, value, time=0):
48-
self.data_file.write(self.tsv_row_str('info', time=time, name=name, value=value))
52+
self.data_file.write(self.tsv_row_str("info", time=time, name=name, value=value))
4953

50-
def tsv_row_str(self, rtype, time='', name='', value=''):
51-
time_str = f'{time/1000:.3f}' if type(time) == int else time
52-
return f'{time_str}\t{rtype}\t{name}\t{value}\n'
54+
def tsv_row_str(self, rtype, time="", name="", value=""):
55+
time_str = f"{time/1000:.3f}" if type(time) == int else time
56+
return f"{time_str}\t{rtype}\t{name}\t{value}\n"
5357

54-
def copy_task_file(self, data_dir, tasks_dir, dir_name='task_files'):
55-
'''If not already present, copy task file to data_dir/dir_name
56-
appending the files djb2 hash to the file name.'''
58+
def copy_task_file(self, data_dir, tasks_dir, dir_name="task_files"):
59+
"""If not already present, copy task file to data_dir/dir_name
60+
appending the files djb2 hash to the file name."""
5761
exp_tasks_dir = os.path.join(data_dir, dir_name)
5862
if not os.path.exists(exp_tasks_dir):
5963
os.mkdir(exp_tasks_dir)
60-
task_file_path = os.path.join(tasks_dir, self.sm_info['name']+'.py')
61-
task_save_name = os.path.split(self.sm_info['name'])[1] +'_{}.py'.format(self.sm_info['task_hash'])
64+
task_file_path = os.path.join(tasks_dir, self.sm_info["name"] + ".py")
65+
task_save_name = os.path.split(self.sm_info["name"])[1] + "_{}.py".format(self.sm_info["task_hash"])
6266
if not task_save_name in os.listdir(exp_tasks_dir):
6367
copyfile(task_file_path, os.path.join(exp_tasks_dir, task_save_name))
64-
68+
6569
def close_files(self):
6670
if self.data_file:
67-
self.write_info_line('end_time', self.end_datetime.isoformat(timespec='milliseconds'), self.end_timestamp)
71+
self.write_info_line("end_time", self.end_datetime.isoformat(timespec="milliseconds"), self.end_timestamp)
6872
self.data_file.close()
6973
self.data_file = None
7074
self.file_path = None
@@ -73,12 +77,12 @@ def close_files(self):
7377
self.analog_writers = {}
7478

7579
def process_data(self, new_data):
76-
'''If data _file is open new data is written to file. If print_func is specified
77-
human readable data strings are passed to it.'''
80+
"""If data _file is open new data is written to file. If print_func is specified
81+
human readable data strings are passed to it."""
7882
if self.data_file:
7983
self.write_to_file(new_data)
8084
if self.print_func:
81-
self.print_func(self.data_to_string(new_data).replace('\t\t', '\t'), end='')
85+
self.print_func(self.data_to_string(new_data).replace("\t\t", "\t"), end="")
8286
if self.data_consumers:
8387
for data_consumer in self.data_consumers:
8488
data_consumer.process_data(new_data)
@@ -89,35 +93,35 @@ def write_to_file(self, new_data):
8993
self.data_file.write(data_string)
9094
self.data_file.flush()
9195
for nd in new_data:
92-
if nd.type == 'A':
96+
if nd.type == "A":
9397
self.analog_writers[nd.ID].save_analog_chunk(timestamp=nd.time, data_array=nd.data)
9498

9599
def data_to_string(self, new_data):
96-
'''Convert list of data tuples into a string. If verbose=True state and event names are used,
97-
if verbose=False state and event IDs are used.'''
98-
data_string = ''
100+
"""Convert list of data tuples into a string. If verbose=True state and event names are used,
101+
if verbose=False state and event IDs are used."""
102+
data_string = ""
99103
for nd in new_data:
100-
if nd.type == 'D': # State entry or event.
101-
if nd.ID in self.sm_info['states'].values():
102-
data_string += self.tsv_row_str('state', time=nd.time, name=self.ID2name_fw[nd.ID])
104+
if nd.type == "D": # State entry or event.
105+
if nd.ID in self.sm_info["states"].values():
106+
data_string += self.tsv_row_str("state", time=nd.time, name=self.ID2name_fw[nd.ID])
103107
else:
104-
data_string += self.tsv_row_str('event', time=nd.time, name=self.ID2name_fw[nd.ID])
105-
elif nd.type == 'P': # User print output.
106-
data_string += self.tsv_row_str('print', time=nd.time, value=nd.data)
107-
elif nd.type == 'V': # Variable.
108-
data_string += self.tsv_row_str('variable', time=nd.time, name=nd.ID, value=nd.data)
109-
elif nd.type == '!': # Warning
110-
data_string += self.tsv_row_str('warning', value=nd.data)
111-
elif nd.type == '!!': # Error
112-
data_string += self.tsv_row_str('error', value=nd.data.replace('\n','|').replace('\r','|'))
113-
elif nd.type == 'S': # Framework stop.
108+
data_string += self.tsv_row_str("event", time=nd.time, name=self.ID2name_fw[nd.ID])
109+
elif nd.type == "P": # User print output.
110+
data_string += self.tsv_row_str("print", time=nd.time, value=nd.data)
111+
elif nd.type == "V": # Variable.
112+
data_string += self.tsv_row_str("variable", time=nd.time, name=nd.ID, value=nd.data)
113+
elif nd.type == "!": # Warning
114+
data_string += self.tsv_row_str("warning", value=nd.data)
115+
elif nd.type == "!!": # Error
116+
data_string += self.tsv_row_str("error", value=nd.data.replace("\n", "|").replace("\r", "|"))
117+
elif nd.type == "S": # Framework stop.
114118
self.end_datetime = datetime.utcnow()
115119
self.end_timestamp = nd.time
116120
return data_string
117121

118122

119-
class Analog_writer():
120-
'''Class for writing data from one analog input to disk.'''
123+
class Analog_writer:
124+
"""Class for writing data from one analog input to disk."""
121125

122126
def __init__(self, name, sampling_rate, data_type, session_filepath):
123127
self.name = name
@@ -127,36 +131,35 @@ def __init__(self, name, sampling_rate, data_type, session_filepath):
127131

128132
def open_data_files(self, session_filepath):
129133
ses_path_stem, file_ext = os.path.splitext(session_filepath)
130-
self.path_stem = ses_path_stem + f'_{self.name}'
131-
self.t_tempfile_path = self.path_stem + '.time.temp'
132-
self.d_tempfile_path = self.path_stem + f'.data-1{self.data_type}.temp'
133-
self.time_tempfile = open(self.t_tempfile_path, 'wb')
134-
self.data_tempfile = open(self.d_tempfile_path, 'wb')
134+
self.path_stem = ses_path_stem + f"_{self.name}"
135+
self.t_tempfile_path = self.path_stem + ".time.temp"
136+
self.d_tempfile_path = self.path_stem + f".data-1{self.data_type}.temp"
137+
self.time_tempfile = open(self.t_tempfile_path, "wb")
138+
self.data_tempfile = open(self.d_tempfile_path, "wb")
135139
self.next_chunk_start_time = 0
136140

137141
def close_files(self):
138-
'''Close data files. Convert temp files to numpy.'''
142+
"""Close data files. Convert temp files to numpy."""
139143
self.time_tempfile.close()
140144
self.data_tempfile.close()
141-
with open(self.t_tempfile_path, 'rb') as f:
142-
times = np.frombuffer(f.read(), dtype='float64')
143-
np.save(self.path_stem + '.time.npy', times)
144-
with open(self.d_tempfile_path, 'rb') as f:
145+
with open(self.t_tempfile_path, "rb") as f:
146+
times = np.frombuffer(f.read(), dtype="float64")
147+
np.save(self.path_stem + ".time.npy", times)
148+
with open(self.d_tempfile_path, "rb") as f:
145149
data = np.frombuffer(f.read(), dtype=self.data_type)
146-
np.save(self.path_stem + '.data.npy', data)
150+
np.save(self.path_stem + ".data.npy", data)
147151
os.remove(self.t_tempfile_path)
148152
os.remove(self.d_tempfile_path)
149153

150154
def save_analog_chunk(self, timestamp, data_array):
151-
'''Save a chunk of analog data to .pca data file.'''
152-
if np.abs(self.next_chunk_start_time - timestamp/1000)<0.001:
155+
"""Save a chunk of analog data to .pca data file."""
156+
if np.abs(self.next_chunk_start_time - timestamp / 1000) < 0.001:
153157
chunk_start_time = self.next_chunk_start_time
154158
else:
155-
chunk_start_time = timestamp/1000
156-
times = (np.arange(len(data_array), dtype='float64')
157-
/ self.sampling_rate) + chunk_start_time # Seconds
159+
chunk_start_time = timestamp / 1000
160+
times = (np.arange(len(data_array), dtype="float64") / self.sampling_rate) + chunk_start_time # Seconds
158161
self.time_tempfile.write(times.tobytes())
159162
self.data_tempfile.write(data_array.tobytes())
160163
self.time_tempfile.flush()
161164
self.data_tempfile.flush()
162-
self.next_chunk_start_time = chunk_start_time+len(data_array)/self.sampling_rate
165+
self.next_chunk_start_time = chunk_start_time + len(data_array) / self.sampling_rate

com/pyboard.py

+32-28
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,16 @@
2323
import time
2424
import serial
2525

26+
2627
def stdout_write_bytes(b):
2728
sys.stdout.buffer.write(b)
2829
sys.stdout.buffer.flush()
2930

31+
3032
class PyboardError(BaseException):
3133
pass
3234

35+
3336
class Pyboard:
3437
def __init__(self, serial_device, baudrate=115200):
3538
self.serial = serial.Serial(serial_device, baudrate=baudrate, interCharTimeout=1)
@@ -59,37 +62,37 @@ def read_until(self, min_num_bytes, ending, timeout=10, data_consumer=None):
5962
return data
6063

6164
def enter_raw_repl(self):
62-
self.serial.write(b'\r\x03\x03') # ctrl-C twice: interrupt any running program
65+
self.serial.write(b"\r\x03\x03") # ctrl-C twice: interrupt any running program
6366
# flush input (without relying on serial.flushInput())
6467
n = self.serial.in_waiting
6568
while n > 0:
6669
self.serial.read(n)
6770
n = self.serial.in_waiting
68-
self.serial.write(b'\r\x01') # ctrl-A: enter raw REPL
69-
data = self.read_until(1, b'to exit\r\n>')
70-
if not data.endswith(b'raw REPL; CTRL-B to exit\r\n>'):
71+
self.serial.write(b"\r\x01") # ctrl-A: enter raw REPL
72+
data = self.read_until(1, b"to exit\r\n>")
73+
if not data.endswith(b"raw REPL; CTRL-B to exit\r\n>"):
7174
print(data)
72-
raise PyboardError('could not enter raw repl')
73-
self.serial.write(b'\x04') # ctrl-D: soft reset
74-
data = self.read_until(1, b'to exit\r\n>')
75-
if not data.endswith(b'raw REPL; CTRL-B to exit\r\n>'):
75+
raise PyboardError("could not enter raw repl")
76+
self.serial.write(b"\x04") # ctrl-D: soft reset
77+
data = self.read_until(1, b"to exit\r\n>")
78+
if not data.endswith(b"raw REPL; CTRL-B to exit\r\n>"):
7679
print(data)
77-
raise PyboardError('could not enter raw repl')
80+
raise PyboardError("could not enter raw repl")
7881

7982
def exit_raw_repl(self):
80-
self.serial.write(b'\r\x02') # ctrl-B: enter friendly REPL
83+
self.serial.write(b"\r\x02") # ctrl-B: enter friendly REPL
8184

8285
def follow(self, timeout, data_consumer=None):
8386
# wait for normal output
84-
data = self.read_until(1, b'\x04', timeout=timeout, data_consumer=data_consumer)
85-
if not data.endswith(b'\x04'):
86-
raise PyboardError('timeout waiting for first EOF reception')
87+
data = self.read_until(1, b"\x04", timeout=timeout, data_consumer=data_consumer)
88+
if not data.endswith(b"\x04"):
89+
raise PyboardError("timeout waiting for first EOF reception")
8790
data = data[:-1]
8891

8992
# wait for error output
90-
data_err = self.read_until(2, b'\x04>', timeout=timeout)
91-
if not data_err.endswith(b'\x04>'):
92-
raise PyboardError('timeout waiting for second EOF reception')
93+
data_err = self.read_until(2, b"\x04>", timeout=timeout)
94+
if not data_err.endswith(b"\x04>"):
95+
raise PyboardError("timeout waiting for second EOF reception")
9396
data_err = data_err[:-2]
9497

9598
# return normal and error output
@@ -99,47 +102,48 @@ def exec_raw_no_follow(self, command):
99102
if isinstance(command, bytes):
100103
command_bytes = command
101104
else:
102-
command_bytes = bytes(command, encoding='utf8')
105+
command_bytes = bytes(command, encoding="utf8")
103106

104107
# write command
105108
for i in range(0, len(command_bytes), 256):
106-
self.serial.write(command_bytes[i:min(i + 256, len(command_bytes))])
109+
self.serial.write(command_bytes[i : min(i + 256, len(command_bytes))])
107110
time.sleep(0.01)
108-
self.serial.write(b'\x04')
111+
self.serial.write(b"\x04")
109112

110113
# check if we could exec command
111114
data = self.serial.read(2)
112-
if data != b'OK':
113-
raise PyboardError('could not exec command')
115+
if data != b"OK":
116+
raise PyboardError("could not exec command")
114117

115118
def exec_raw(self, command, timeout=10, data_consumer=None):
116-
self.exec_raw_no_follow(command);
119+
self.exec_raw_no_follow(command)
117120
return self.follow(timeout, data_consumer)
118121

119122
def eval(self, expression):
120-
ret = self.exec('print({})'.format(expression))
123+
ret = self.exec("print({})".format(expression))
121124
ret = ret.strip()
122125
return ret
123126

124127
def exec(self, command):
125128
ret, ret_err = self.exec_raw(command)
126129
if ret_err:
127-
raise PyboardError('exception', ret, ret_err)
130+
raise PyboardError("exception", ret, ret_err)
128131
return ret
129132

130133
def execfile(self, filename):
131-
with open(filename, 'rb') as f:
134+
with open(filename, "rb") as f:
132135
pyfile = f.read()
133136
return self.exec(pyfile)
134137

135138
def get_time(self):
136-
t = str(self.eval('pyb.RTC().datetime()'), encoding='utf8')[1:-1].split(', ')
139+
t = str(self.eval("pyb.RTC().datetime()"), encoding="utf8")[1:-1].split(", ")
137140
return int(t[4]) * 3600 + int(t[5]) * 60 + int(t[6])
138141

139-
def execfile(filename, device='/dev/ttyACM0'):
142+
143+
def execfile(filename, device="/dev/ttyACM0"):
140144
pyb = Pyboard(device)
141145
pyb.enter_raw_repl()
142146
output = pyb.execfile(filename)
143147
stdout_write_bytes(output)
144148
pyb.exit_raw_repl()
145-
pyb.close()
149+
pyb.close()

0 commit comments

Comments
 (0)