Newer
Older
Olivier Kaufmann
committed
with open(filename, 'a') as f:
w = csv.DictWriter(f, last_measurement.keys())
w.writeheader()
w.writerow(last_measurement)
def _process_commands(self, command):
""" TODO
Parameters
----------
command
Returns
-------
"""
try:
cmd_id = None
decoded_message = json.loads(command)
cmd_id = decoded_message.pop('cmd_id', None)
cmd = decoded_message.pop('cmd', None)
args = decoded_message.pop('args', None)
status = False
e = None
if cmd is not None and cmd_id is not None:
if cmd == 'update_settings' and args is not None:
status = True
elif cmd == 'set_sequence' and args is not None:
try:
self.sequence = np.loadtxt(StringIO(args)).astype('uint32')
status = True
except Exception as e:
self.exec_logger.warning(f'Unable to set sequence: {e}')
status = False
elif cmd == 'run_sequence':
self.run_sequence(cmd_id=cmd_id)
elif cmd == 'run_sequence_async':
self.run_sequence_async(cmd_id=cmd_id)
#while not self.status == 'idle': # idem for async, we need to return immediately otherwise
# the interrupt command cannot be processed
# time.sleep(0.1)
elif cmd == 'run_multiple_sequences':
self.run_multiple_sequences(cmd_id=cmd_id)
#while not self.status == 'idle': # we cannot do that as it's supposed to be an asynchrone command
# time.sleep(0.1)
elif cmd == 'interrupt':
self.interrupt()
elif cmd == 'load_sequence':
self.load_sequence(args)
status = True
except Exception as e:
self.exec_logger.warning(f'Unable to load sequence: {e}')
status = False
elif cmd == 'rs_check':
try:
self.rs_check()
status = True
except Exception as e:
print('error====', e)
self.exec_logger.warning(f'Unable to run rs-check: {e}')
self.exec_logger.warning(f'Unknown command {cmd} - cmd_id: {cmd_id}')
except Exception as e:
self.exec_logger.warning(f'Unable to decode command {command}: {e}')
status = False
finally:
reply = {'cmd_id': cmd_id, 'status':status, 'ohmpi_status': self.status}
reply = json.dumps(reply)
self.exec_logger.debug(f'Execution report: {reply}')
def set_sequence(self, args):
try:
self.sequence = np.loadtxt(StringIO(args)).astype('uint32')
status = True
except Exception as e:
self.exec_logger.warning(f'Unable to set sequence: {e}')
status = False

Guillaume Blanchy
committed
"""Run sequence synchronously (=blocking on main thread).
Additional arguments are passed to run_measurement().
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
"""
self.status = 'running'
self.exec_logger.debug(f'Status: {self.status}')
self.exec_logger.debug(f'Measuring sequence: {self.sequence}')
# create filename with timestamp
filename = self.settings["export_path"].replace('.csv',
f'_{datetime.now().strftime("%Y%m%dT%H%M%S")}.csv')
self.exec_logger.debug(f'Saving to {filename}')
# make sure all multiplexer are off
self.reset_mux()
# measure all quadrupole of the sequence
if self.sequence is None:
n = 1
else:
n = self.sequence.shape[0]
for i in range(0, n):
if self.sequence is None:
quad = np.array([0, 0, 0, 0])
else:
quad = self.sequence[i, :] # quadrupole
if self.status == 'stopping':
break
# call the switch_mux function to switch to the right electrodes
self.switch_mux_on(quad)
# run a measurement
acquired_data = self.run_measurement(quad, **kwargs)
# switch mux off
self.switch_mux_off(quad)
# save data and print in a text file
self.append_and_save(filename, acquired_data)
self.exec_logger.debug(f'{i+1:d}/{n:d}')
self.status = 'idle'
def run_sequence_async(self, **kwargs):
""" Run the sequence in a separate thread. Can be stopped by 'OhmPi.interrupt()'.

Guillaume Blanchy
committed
Additional arguments are passed to run_measurement().
"""
def func():
self.thread = threading.Thread(target=func)
self.thread.start()

Guillaume Blanchy
committed
def measure(self, *args, **kwargs):
warnings.warn('This function is deprecated. Use run_multiple_sequences() instead.', DeprecationWarning)
self.run_multiple_sequences(self, *args, **kwargs)

Guillaume Blanchy
committed
def run_multiple_sequences(self, sequence_delay=None, **kwargs):
""" Run multiple sequences in a separate thread for monitoring mode.
Can be stopped by 'OhmPi.interrupt()'.

Guillaume Blanchy
committed
Additional arguments are passed to run_measurement().
Parameters
----------
sequence_delay : int, optional
Number of seconds at which the sequence must be started from each others.
kwargs : dict, optional
See help(k.run_measurement) for more info.
Olivier Kaufmann
committed
# self.run = True
if sequence_delay == None:
sequence_delay = self.settings['sequence_delay']
sequence_delay = int(sequence_delay)
self.status = 'running'
def func():
for g in range(0, self.settings["nb_meas"]): # for time-lapse monitoring
Olivier Kaufmann
committed
if self.status != 'running':
Olivier Kaufmann
committed
self.exec_logger.warning('Data acquisition interrupted')
dt = sequence_delay - (time.time() - t0)
if dt < 0:
dt = 0
rpi2.0
committed
if self.settings["nb_meas"] > 1:
time.sleep(dt) # waiting for next measurement (time-lapse)
self.thread = threading.Thread(target=func)
self.thread.start()
warnings.warn('This function is deprecated. Use interrupt instead.', DeprecationWarning)
self.interrupt()
def interrupt(self):
""" Interrupt the acquisition. """
Olivier Kaufmann
committed
self.status = 'stopping'
print('joining thread')
Olivier Kaufmann
committed
self.exec_logger.debug(f'Status: {self.status}')
def quit(self):
"""Quit OhmPi.
"""
self.cmd_listen = False
if self.cmd_thread is not None:
self.cmd_thread.join()
self.exec_logger.debug(f'Stopped listening to control topic.')
exit()
Olivier Kaufmann
committed
def restart(self):
self.exec_logger.info('Restarting pi...')
os.system('reboot')
Olivier Kaufmann
committed
print(colored(r' ________________________________' + '\n' +
r'| _ | | | || \/ || ___ \_ _|' + '\n' +
r'| | | | |_| || . . || |_/ / | |' + '\n' +
r'| | | | _ || |\/| || __/ | |' + '\n' +
r'\ \_/ / | | || | | || | _| |_' + '\n' +
r' \___/\_| |_/\_| |_/\_| \___/ ', 'red'))
print('OhmPi start')
print('Version:', VERSION)
platform, on_pi = OhmPi._get_platform()
if on_pi:
print(colored(f'Running on {platform} platform', 'green'))
Olivier Kaufmann
committed
# TODO: check model for compatible platforms (exclude Raspberry Pi versions that are not supported...)
# and emit a warning otherwise
if not arm64_imports:
print(colored(f'Warning: Required packages are missing.\n'
f'Please run ./env.sh at command prompt to update your virtual environment\n', 'yellow'))
else:
print(colored(f'Not running on the Raspberry Pi platform.\nFor simulation purposes only...', 'yellow'))
current_time = datetime.now()
print(current_time.strftime("%Y-%m-%d %H:%M:%S"))
# for testing
if __name__ == "__main__":
ohmpi = OhmPi(settings=OHMPI_CONFIG['settings'])
def func():
ohmpi.controller.loop_forever()
t = threading.Thread(target=func)
t.start()