Newer
Older
last_measurement.update(tdic)
last_measurement.pop('fulldata')
Olivier Kaufmann
committed
if os.path.isfile(filename):
Olivier Kaufmann
committed
with open(filename, 'a') as f:
w = csv.DictWriter(f, last_measurement.keys())
w.writerow(last_measurement)
# last_measurement.to_csv(f, header=False)
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, message):
Olivier Kaufmann
committed
"""Processes commands received from the controller(s)
message : str
Olivier Kaufmann
committed
message containing a command and arguments or keywords and arguments
Olivier Kaufmann
committed
decoded_message = json.loads(message)
Olivier Kaufmann
committed
print(f'decoded message: {decoded_message}')
cmd_id = decoded_message.pop('cmd_id', None)
cmd = decoded_message.pop('cmd', None)
args = decoded_message.pop('args', '[]')
Olivier Kaufmann
committed
if len(args) == 0:
Olivier Kaufmann
committed
args = f'["{args}"]'
args = json.loads(args)
kwargs = decoded_message.pop('kwargs', '{}')
Olivier Kaufmann
committed
if len(kwargs) == 0:
kwargs= '{}'
kwargs = json.loads(kwargs)
self.exec_logger.debug(f'Calling method {cmd}({args}, {kwargs})')
Olivier Kaufmann
committed
# e = None # NOTE: Why this?
print(cmd, args, kwargs)
if cmd_id is None:
self.exec_logger.warning('You should use a unique identifier for cmd_id')
if cmd is not None:
try:
output = getattr(self, cmd)(*args, **kwargs)
except Exception as e:
Olivier Kaufmann
committed
self.exec_logger.error(
f"{e}\nUnable to execute {cmd}({args + ', ' if args != '[]' else ''}"
f"{kwargs if kwargs != '{}' else ''})")
status = False
except Exception as e:
self.exec_logger.warning(f'Unable to decode command {message}: {e}')
status = False
finally:
reply = {'cmd_id': cmd_id, 'status': status}
reply = json.dumps(reply)
self.exec_logger.debug(f'Execution report: {reply}')
def set_sequence(self, sequence=sequence):
self.sequence = np.loadtxt(StringIO(sequence)).astype('uint32')
status = True
except Exception as e:
self.exec_logger.warning(f'Unable to set sequence: {e}')
status = False
Olivier Kaufmann
committed
def run_sequence(self, cmd_id=None, **kwargs):
Olivier Kaufmann
committed
"""Runs sequence synchronously (=blocking on main thread).

Guillaume Blanchy
committed
Additional arguments are passed to run_measurement().
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
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
1120
"""
self.status = 'running'
self.exec_logger.debug(f'Status: {self.status}')
self.exec_logger.debug(f'Measuring sequence: {self.sequence}')
t0 = time.time()
# 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
if self.on_pi:
acquired_data = self.run_measurement(quad, **kwargs)
else: # for testing, generate random data
acquired_data = {
'A': [quad[0]], 'B': [quad[1]], 'M': [quad[2]], 'N': [quad[3]],
'R [ohm]': np.abs(np.random.randn(1))
}
# switch mux off
self.switch_mux_off(quad)
# add command_id in dataset
acquired_data.update({'cmd_id': cmd_id})
# log data to the data logger
self.data_logger.info(f'{acquired_data}')
# save data and print in a text file
self.append_and_save(filename, acquired_data)
Olivier Kaufmann
committed
self.exec_logger.debug(f'quadrupole {i+1:d}/{n:d}')
self.status = 'idle'
def run_sequence_async(self, cmd_id=None, **kwargs):
Olivier Kaufmann
committed
"""Runs the sequence in a separate thread. Can be stopped by 'OhmPi.interrupt()'.

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

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)
Olivier Kaufmann
committed
def run_multiple_sequences(self, cmd_id=None, sequence_delay=None, nb_meas=None, **kwargs):
"""Runs multiple sequences in a separate thread for monitoring mode.
Can be stopped by 'OhmPi.interrupt()'.
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.
nb_meas : int, optional
Number of time the sequence must be repeated.
kwargs : dict, optional
See help(k.run_measurement) for more info.
Olivier Kaufmann
committed
# self.run = True
if sequence_delay is None:
sequence_delay = self.settings['sequence_delay']
sequence_delay = int(sequence_delay)
if nb_meas is None:
nb_meas = self.settings['nb_meas']
Olivier Kaufmann
committed
self.exec_logger.debug(f'Status: {self.status}')
self.exec_logger.debug(f'Measuring sequence: {self.sequence}')
Olivier Kaufmann
committed
for g in range(0, nb_meas): # for time-lapse monitoring
if self.status == 'stopping':
Olivier Kaufmann
committed
self.exec_logger.warning('Data acquisition interrupted')
dt = sequence_delay - (time.time() - t0)
if dt < 0:
dt = 0
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):
Olivier Kaufmann
committed
"""Interrupts the acquisition. """
Olivier Kaufmann
committed
self.status = 'stopping'
Olivier Kaufmann
committed
self.exec_logger.debug('Joining tread...')
Olivier Kaufmann
committed
else:
self.exec_logger.debug('No sequence measurement thread to interrupt.')
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('Version:', VERSION)
Olivier Kaufmann
committed
platform, on_pi = OhmPi._get_platform() # noqa
Olivier Kaufmann
committed
print(colored(f'\u2611 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'))
Olivier Kaufmann
committed
print(colored(f'\u26A0 Not running on the Raspberry Pi platform.\nFor simulation purposes only...', 'yellow'))
Olivier Kaufmann
committed
print(f'local date and time : {current_time.strftime("%Y-%m-%d %H:%M:%S")}')
# for testing
if __name__ == "__main__":
ohmpi = OhmPi(settings=OHMPI_CONFIG['settings'])
Olivier Kaufmann
committed
if ohmpi.controller is not None:
ohmpi.controller.loop_forever()