Source code for slippy.surface.read_tst_file

import struct

__all__ = ['read_tst_file']


[docs]def read_tst_file(filename): """Reads a .tst file from a bruker UMT machine Parameters ---------- filename : str The full path to the .tst file including extension Returns ------- data : dict The full data including all metadata from the .tst file Notes ----- The structure of data can be a little confusing at the top level it is a dict with two keys: one for the metadata that applies to the entire file and one for the data from each run of the script. The metadata is stored in another dict while the data for each run are in a list with the same order as they were run in. This structure is kept all the way though every time something is ordered a list is used other wise a dictionary is used. To access data from the first run: >>>first_run=data['runs'][0] To access data from the second step in that run: >>>second_step=first_run['steps'][1] To get the numerical data from that step: >>>num_data=second_step['data'] This doesn't need to be split: >>>num_data=data['runs'][0]['steps'][1]['data'] Gives the same result. num_data is a dict of lists with keys of the results recorded: >>>num_data['Fx'] Gives the force results in the x direction """ data = dict() with open(filename, 'rb') as file: metadata = dict() while True: number, name, value = split_line(file) if name is None: break metadata[name] = value if name == 'channelsarray': channels = [] for i in range(value): channels.append(read_channel(file)) metadata['channels'] = channels # no other names can have # in # meta data for the whole file has been read data['metadata'] = metadata # next the data for each run is read n_runs = metadata['runs'] run_data = [] for run in range(n_runs): run_data.append(read_run(file, metadata)) data['runs'] = run_data return data
def read_run(file, file_metadata): """ Reads a 'run' of a script """ # first read the run meta data run_data = dict() number, name, value = split_line(file) metadata = dict() if name != 'run': raise ValueError("This is not a run") metadata[name] = value file.readline() # one empty line before run starts while True: number, name, value = split_line(file) if name is None: break metadata[name] = value # all the metadata for the run has been read in run_data['metadata'] = metadata # then read each step n_steps = file_metadata['steps'] steps = [] for i in range(n_steps): steps.append(read_step(file, file_metadata, metadata)) run_data['steps'] = steps return run_data def read_step(file, file_metadata, run_metadata): """ reads a step of the test""" number, name, value = split_line(file) metadata = dict() if name is None: # for steps other than the first there is 2 lines of stars number, name, value = split_line(file) if name != 'test': raise ValueError("This is not a run") metadata[name] = value while True: number, name, value = split_line(file) if name is None: break metadata[name] = value while True: number, name, value = split_line(file) if name is None: break metadata[name] = value if metadata['samples']: step_data = read_data(file, file_metadata, run_metadata, metadata) else: step_data = None return {'metadata': metadata, 'data': step_data} def read_data(file, file_metadata, run_metadata, step_metadata): """ reads the data from the file """ channels = file_metadata['channels'] samples = step_metadata['samples'] chan_lens = [c['lengthinbytes'] for c in channels] chan_names = [c['name'] for c in channels] data = {cn: [] for cn in chan_names} for sample in range(int(samples)): for name, chan_len in zip(chan_names, chan_lens): data[name].append(struct.unpack('d', file.read(chan_len))[0]) file.read(1) return data def read_channel(file): channel_data = dict() name = '' while name != 'type': number, name, value = split_line(file) channel_data[name] = value return channel_data def split_line(file): try: line = file.readline() line_str = line.decode() except UnicodeDecodeError: print(line) raise ValueError("could not decode above") number, *rest = line_str.split('#')[1:] rest = ''.join(rest) number = number.strip(' ') name, value = rest.split('$')[0:2] name = name.strip(' ') value = value.strip(' ') if name.strip('*') == '': name = None else: name = name.lower() if value == '': value = None elif number in ['28', '31']: value = int(value) elif number in ['33', '37', '38']: value = float(value) number = int(number) return number, name, value if __name__ == '__main__': import numpy as np filename_1 = r"I:\UMT\Mike\17May2019\running in-1.tst" data_1 = read_tst_file(filename_1) mean_mu = np.mean(np.abs(data_1['runs'][0]['steps'][1]['data']['Fx'])) / 10