From d742d8ddd1d820c08ad888a009b0f5f37fa95d40 Mon Sep 17 00:00:00 2001 From: jkl <sagitta1618@gmail.com> Date: Thu, 30 Nov 2023 23:03:12 +0100 Subject: [PATCH] Update to fix UI and install_resipy.py --- .gitlab-ci.yml | 1 + dev/test_inv.py | 3 +- dev/test_mb_2023_4_mux_2023.py | 4 +- index.html | 14 +++---- install_resipy.sh | 9 ++++- ohmpi/config.py | 36 +++++++---------- ohmpi/ohmpi.py | 70 ++++++++++++++++----------------- run_http_interface_on_start.txt | 0 sequences/wenner16.txt | 35 +++++++++++++++++ 9 files changed, 104 insertions(+), 68 deletions(-) mode change 100644 => 100755 install_resipy.sh mode change 100755 => 100644 run_http_interface_on_start.txt create mode 100644 sequences/wenner16.txt diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c5c76ac3..7e58ed7f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,6 +8,7 @@ pages: - apt-get install --assume-yes pandoc - pip install numpy pandas termcolor paho-mqtt zmq # top import of Ohmpi.py - pip install sphinx numpydoc sphinx_rtd_theme pandoc recommonmark + - cp configs/config_dummy.py ohmpi/config.py # only compile doc with dummy if not on rpi with correct config.py - cd doc - make html diff --git a/dev/test_inv.py b/dev/test_inv.py index 2b9d9cef..e3cfc815 100644 --- a/dev/test_inv.py +++ b/dev/test_inv.py @@ -6,6 +6,7 @@ matplotlib.use('TkAgg') import numpy as np from ohmpi.utils import change_config change_config('../configs/config_mb_2023.py', verbose=False) +import os from ohmpi.ohmpi import OhmPi k = OhmPi() @@ -14,7 +15,7 @@ k = OhmPi() # batch inversion xzv = k.run_inversion([ - 'measurement_20231014T133508.csv' + 'measurements_20231130T215031.csv' ], reg_mode=0) # make a contour figure with the output diff --git a/dev/test_mb_2023_4_mux_2023.py b/dev/test_mb_2023_4_mux_2023.py index 72cc18ce..a10319f3 100644 --- a/dev/test_mb_2023_4_mux_2023.py +++ b/dev/test_mb_2023_4_mux_2023.py @@ -88,8 +88,8 @@ if within_ohmpi: k.load_sequence(os.path.join(os.path.dirname(__file__), '../sequences/wenner16.txt')) k.reset_mux() # k.run_multiple_sequences(sequence_delay=20, nb_meas=3) - k.run_sequence(injection_duration=0.2) - # k.rs_check(tx_volt=4) + # k.run_sequence(injection_duration=0.2) + k.rs_check(tx_volt=4) # k.test_mux(mux_id=None, activation_time=0.2) # k._hw.switch_mux([A, B, M, N], state='on') # k._hw.vab_square_wave(12.,1., cycles=2) diff --git a/index.html b/index.html index 5077a266..21caa76d 100755 --- a/index.html +++ b/index.html @@ -93,12 +93,12 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl </div> <div class="modal-body"> <form> - <div class="form-group row"> - <!-- <label for="nb_electrodes" class="col-sm-2 col-form-label">Nb electrodes</label> --> + <!-- <div class="form-group row"> + <label for="nb_electrodes" class="col-sm-2 col-form-label">Nb electrodes</label> <div class="col-sm-10"> <input type="number" class="form-control-number" id="nb_electrodes" value="64"> </div> - </div> + </div> --> <div class="form-group row"> <label for="injection_duration" class="col-sm-2 col-form-label">Injection duration [s]</label> <div class="col-sm-10"> @@ -167,7 +167,7 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> - <button id="removeDataBtn" type="button" class="btn btn-danger">Clear data</button> + <button id="removeDataBtn" type="button" class="btn btn-danger" data-dismiss="modal">Clear data</button> </div> </div> </div> @@ -249,7 +249,7 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl payload = payload.replace(/\bnan\b/g, "null"); // parse to json - let ddic = JSON.parse(payload.split('INFO:')[1]) + let ddic = JSON.parse(payload.split('INFO:')[1].replace(/'/g, '"')) // RS check data if ('rsdata' in ddic) { @@ -274,7 +274,7 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl } else if (message.topic == topic_exec) { // display it in the log - console.log('EXEC LOG:', payload) + //console.log('EXEC LOG:', payload) } // let response = JSON.parse(message.payloadString) @@ -677,7 +677,7 @@ mosquitto_sub -h raspberrypi.local -t ohmpi_0001/ctrl // update list of quadrupoles if any - if (quads.length == 0) { + if ((quads.length == 0) & (surveyNames.length > 0)) { console.log('updating list of quadrupoles') let df = data[surveyNames[0]] let quadSelect = document.getElementById('quadSelect') diff --git a/install_resipy.sh b/install_resipy.sh old mode 100644 new mode 100755 index 4201bde3..e204ca1c --- a/install_resipy.sh +++ b/install_resipy.sh @@ -1 +1,8 @@ -git clone -b rpi https://gitlab.com/hkex/resipy \ No newline at end of file +echo "Installing ResIPy (cloning git, adding python packages)" +source ohmpy/bin/activate +which pip +sudo apt-get install wine --assume-yes +cd .. +git clone -b rpi https://gitlab.com/hkex/resipy +pip install numpy matplotlib scipy pandas requests psutil +cd OhmPi diff --git a/ohmpi/config.py b/ohmpi/config.py index 49e24ecf..f3f566ba 100644 --- a/ohmpi/config.py +++ b/ohmpi/config.py @@ -21,38 +21,32 @@ r_shunt = 2. HARDWARE_CONFIG = { 'ctl': {'model': 'raspberry_pi'}, 'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'}, - 'tx': {'model': 'mb_2024_0_2', + 'tx': {'model': 'mb_2023_0_X', 'voltage_max': 50., # Maximum voltage supported by the TX board [V] 'current_max': 4.80/(50*r_shunt), # Maximum voltage read by the current ADC on the TX board [A] 'r_shunt': r_shunt, # Shunt resistance in Ohms 'interface_name': 'i2c' }, - 'rx': {'model': 'mb_2024_0_2', - 'latency': 0.010, # latency in seconds in continuous mode - 'sampling_rate': 50, # number of samples per second - 'interface_name': 'i2c' + 'rx': {'model': 'mb_2023_0_X', + 'coef_p2': 2.50, # slope for conversion for ADS, measurement in V/V + 'sampling_rate': 50., # number of samples per second + 'interface_name': 'i2c', }, - 'mux': {'boards': - {'mux_00': - {'model': 'mux_2024_0_X', - 'tca_address': None, - 'tca_channel': 0, - 'addr2': 'down', - 'addr1': 'down', - 'roles': {'A': 'X', 'B': 'Y', 'M': 'XX', 'N': 'YY'}, - 'cabling': {(i+0, j): ('mux_00', i) for j in ['A', 'B', 'M', 'N'] for i in range(1, 9)}, - 'voltage_max': 12.} - }, - 'default': {'interface_name': 'i2c_ext', + 'mux': # default properties given in config are system properties that will be + # overwritten by properties defined in each the board dict below. + # if defined in board specs, values out of specs will be bounded to remain in specs + # omitted properties in config will be set to board specs default values if they exist + {'boards': {}, + 'default': {'interface_name': 'i2c', 'voltage_max': 100., 'current_max': 3.} - } - } + } +} # SET THE LOGGING LEVELS, MQTT BROKERS AND MQTT OPTIONS ACCORDING TO YOUR NEEDS # Execution logging configuration EXEC_LOGGING_CONFIG = { - 'logging_level': logging.INFO, + 'logging_level': logging.DEBUG, # TODO: set logging level back to INFO 'log_file_logging_level': logging.DEBUG, 'logging_to_console': True, 'file_name': f'exec{logging_suffix}.log', @@ -76,8 +70,8 @@ DATA_LOGGING_CONFIG = { # State of Health logging configuration (For a future release) SOH_LOGGING_CONFIG = { 'logging_level': logging.INFO, - 'log_file_logging_level': logging.DEBUG, 'logging_to_console': True, + 'log_file_logging_level': logging.DEBUG, 'file_name': f'soh{logging_suffix}.log', 'max_bytes': 16777216, 'backup_count': 1024, diff --git a/ohmpi/ohmpi.py b/ohmpi/ohmpi.py index 7dafe9f7..b11d9ae9 100644 --- a/ohmpi/ohmpi.py +++ b/ohmpi/ohmpi.py @@ -152,8 +152,7 @@ class OhmPi(object): for i in getmembers(deprecated, isfunction): setattr(cls, i[0], i[1]) - @staticmethod - def append_and_save(filename: str, last_measurement: dict, fw_in_csv=None, fw_in_zip=None, cmd_id=None): + def append_and_save(self, filename: str, last_measurement: dict, fw_in_csv=None, fw_in_zip=None, cmd_id=None): """Appends and saves the last measurement dict. Parameters @@ -185,34 +184,35 @@ class OhmPi(object): last_measurement = deepcopy(last_measurement) - # save full waveform data in a long .csv file - if fw_in_zip: - fw_filename = filename.replace('.csv', '_fw.csv') - if not os.path.exists(fw_filename): # new file, write headers first - with open(fw_filename, 'w') as f: - f.write('A,B,M,N,t,current,voltage\n') - # write full data - with open(fw_filename, 'a') as f: - dd = last_measurement['full_waveform'] - aa = np.repeat(last_measurement['A'], dd.shape[0]) - bb = np.repeat(last_measurement['B'], dd.shape[0]) - mm = np.repeat(last_measurement['M'], dd.shape[0]) - nn = np.repeat(last_measurement['N'], dd.shape[0]) - fwdata = np.c_[aa, bb, mm, nn, dd] - np.savetxt(f, fwdata, delimiter=',', fmt=['%d', '%d', '%d', '%d', '%.3f', '%.3f', '%.3f']) - - if fw_in_csv: - d = last_measurement['full_waveform'] - n = d.shape[0] - if n > 1: - idic = dict(zip(['i' + str(i) for i in range(n)], d[:, 0])) - udic = dict(zip(['u' + str(i) for i in range(n)], d[:, 1])) - tdic = dict(zip(['t' + str(i) for i in range(n)], d[:, 2])) - last_measurement.update(idic) - last_measurement.update(udic) - last_measurement.update(tdic) - - last_measurement.pop('full_waveform') + if 'full_waveform' in last_measurement: + # save full waveform data in a long .csv file + if fw_in_zip: + fw_filename = filename.replace('.csv', '_fw.csv') + if not os.path.exists(fw_filename): # new file, write headers first + with open(fw_filename, 'w') as f: + f.write('A,B,M,N,t,current,voltage\n') + # write full data + with open(fw_filename, 'a') as f: + dd = last_measurement['full_waveform'] + aa = np.repeat(last_measurement['A'], dd.shape[0]) + bb = np.repeat(last_measurement['B'], dd.shape[0]) + mm = np.repeat(last_measurement['M'], dd.shape[0]) + nn = np.repeat(last_measurement['N'], dd.shape[0]) + fwdata = np.c_[aa, bb, mm, nn, dd] + np.savetxt(f, fwdata, delimiter=',', fmt=['%d', '%d', '%d', '%d', '%.3f', '%.3f', '%.3f']) + + if fw_in_csv: + d = last_measurement['full_waveform'] + n = d.shape[0] + if n > 1: + idic = dict(zip(['i' + str(i) for i in range(n)], d[:, 0])) + udic = dict(zip(['u' + str(i) for i in range(n)], d[:, 1])) + tdic = dict(zip(['t' + str(i) for i in range(n)], d[:, 2])) + last_measurement.update(idic) + last_measurement.update(udic) + last_measurement.update(tdic) + + last_measurement.pop('full_waveform') if os.path.isfile(filename): # Load data file and append data to it @@ -265,9 +265,8 @@ class OhmPi(object): # get all .csv file in data folder if survey_names is None: survey_names = [] - # ddir = os.path.join(os.path.dirname(__file__), '../data/') - ddir = self.settings['export_dir'] - fnames = [fname for fname in os.listdir(ddir) if fname[-4:] == '.csv'] + ddir = os.path.dirname(self.settings['export_path']) + fnames = [fname for fname in os.listdir(ddir) if fname[-4:] == '.csv' and fname[-7:] != '_fw.csv'] ddic = {} if cmd_id is None: cmd_id = 'unknown' @@ -418,8 +417,7 @@ class OhmPi(object): Unique command identifier. """ self.exec_logger.debug(f'Removing all data following command {cmd_id}') - datadir = os.path.split(self.settings['export_path']) - #datadir = os.path.join(os.path.dirname(__file__), '../data') + datadir = os.path.dirname(self.settings['export_path']) rmtree(datadir) os.mkdir(datadir) @@ -1050,7 +1048,7 @@ class OhmPi(object): # get absolule filename fnames = [] for survey_name in survey_names: - fname = os.path.join(self.settings['export_path'], survey_name) + fname = os.path.join(os.path.dirname(self.settings['export_path']), survey_name) if os.path.exists(fname): fnames.append(fname) else: diff --git a/run_http_interface_on_start.txt b/run_http_interface_on_start.txt old mode 100755 new mode 100644 diff --git a/sequences/wenner16.txt b/sequences/wenner16.txt new file mode 100644 index 00000000..dd4d2abe --- /dev/null +++ b/sequences/wenner16.txt @@ -0,0 +1,35 @@ +16 19 17 18 +17 20 18 19 +18 21 19 20 +19 22 20 21 +20 23 21 22 +21 24 22 23 +22 25 23 24 +23 26 24 25 +24 27 25 26 +25 28 26 27 +26 29 27 28 +27 30 28 29 +28 31 29 30 +16 22 18 20 +17 23 19 21 +18 24 20 22 +19 25 21 23 +20 26 22 24 +21 27 23 25 +22 28 24 26 +23 29 25 27 +24 30 26 28 +25 31 27 29 +16 25 19 22 +17 26 20 23 +18 27 21 24 +19 28 22 25 +20 29 23 26 +21 30 24 27 +22 31 25 28 +16 28 20 24 +17 29 21 25 +18 30 22 26 +19 31 23 27 +16 31 21 26 -- GitLab