def write_diff(path): with open(os.path.join(path, "code.diff"), "w") as f: subprocess.run( ["git", "-C", bne_config.get('code_path'), "diff", "HEAD"], stdout=f, universal_newlines=True) with open(os.path.join(path, "data.diff"), "w") as f: subprocess.run( ["hg", "-R", bne_config.get('project_path'), "diff"], stdout=f, universal_newlines=True)
def get_dict_of_lists(self): data = super().get_dict_of_lists() n_exp = len(next(iter(data.values()))) self.data['origin'] = ['Fabian' for _ in range(n_exp)] self.data['bead_radius'] = [ bne_config.get('bead_radius') for _ in range(n_exp) ] self.data['frequency'] = 1 / np.array(self.data['tap_duration'], dtype='float') # Amplitude derived from data for excitation acceleration See the calculation from 1st Oct. 2018 # for a rectangular acceleration profile (full tap) self.data['amplitude'] = [ a / (4 * f * f) for a, f in zip(self.data['acc_excitation'], self.data['frequency']) ] self.data['rel_excitation'] = [ a / (bne_config.get('g') * gamb) for a, gamb in zip( self.data['acc_excitation'], self.data['ambient_g']) ] return self.data
def get_rel_excitation(e): """ Calculate the relative excitation, if it hasn't been defined so far """ assert (e is not None) gamma = e.get('rel_excitation') if gamma is None: try: amp = e.get('amplitude') f = e.get('frequency') g = e.get('ambient_g') * bne_config.get('g') gamma = amp + (2 * pi * f)**2 / g except: gamma = np.NaN return gamma
def get_shaking(e): """ Calculate the shaking S = (v_vib / v_grav)^2 = gamma * amp / bead_diameter """ assert (e is not None) try: amp = e.get('amplitude') f = e.get('frequency') g = e.get('ambient_g') * bne_config.get('g') d = e.get('bead_radius') * 2 S = (2 * pi * amp * f)**2 / (g * d) except: S = np.NaN # DEBUG # print("{}-{}: A={}, f={}, g={}, r={} --> S={}".format(e.get('exp_id'),e.get('origin'), amp, f, g, r, S)) return S
def get_vstar(e): """ Calculate the maximum dimensionless velocity vstar = vmax / sqrt (ambient_g * bead_diameter) """ assert (e is not None) vmax = e.get('vmax') if vmax is None: vmax = e.get('v1') try: g = e.get('ambient_g') * bne_config.get('g') d = e.get('bead_radius') * 2 vstar = vmax / sqrt(g * d) except: vstar = np.NaN return vstar
def main(): # rawdata_ingo = bne_read_ods_ingo() # rawdata_fabian = bne_read_ods_fabian() # rawdata_yamada = bne_read_ods_yamada() # # exps_ingo = rawdata_ingo.get_list_of_dicts() # exps_fabian = rawdata_fabian.get_list_of_dicts() # exps_yamada = rawdata_yamada.get_list_of_dicts() # # print("Number of experiments by Ingo: {}".format(len(exps_ingo))) # print("Number of experiments by Fabian: {}".format(len(exps_fabian))) # print("Number of experiments by Yamada et al: {}".format(len(exps_yamada))) # return exps_ingo + exps_fabian + exps_yamada # ###################################################################### #### Get the stage programmes######################################### ###################################################################### stage_programme_names_ingo = stage_programme_names() stage_programme_names_ingo.read_file() programmes_ingo = stage_programme_names_ingo.get_programme_info() programme_info = [] for i, name in enumerate(programmes_ingo['name']): filename_pattern = programmes_ingo['filenames'][i] duration_str = programmes_ingo['duration'][i] if type(duration_str == str): try: duration = float( duration_str.replace(",", ".").replace("?", "")) except: duration = None else: duration = float(duration_str) try: acc_rise_times_str = programmes_ingo.get('acc_rise_times')[i] try: acc_rise_times = [int(t) for t in acc_rise_times_str] except (ValueError, TypeError) as error: acc_rise_times = None except KeyError: acc_rise_times = None filenames = glob.glob( bne_config.get('project_path') + bne_config.get('sensor_path') + filename_pattern) success = {} if len(filenames) == 0: print("No files found for {}, matching {}".format( name, filename_pattern)) continue try: prg_info = single_stage_programme(name, filenames[0], "") success['init'] = True except: success['init'] = False try: prg_info.read_by_filename() success['reading'] = True except: success['reading'] = False try: prg_info.extract_data(None, duration, acc_rise_times) success['extraction'] = True except: success['extraction'] = False prg_info.ambient_g = programmes_ingo['ambient_g'][i] prg_info.relative_excitation = programmes_ingo['relative_excitation'][ i] prg_info.acc_rise_times = acc_rise_times prg_info.duration = duration prg_info.amplitude = bne_config.get('amplitude_ingo') if prg_info.frequency is None and duration is not None and acc_rise_times is not None: prg_info.frequency = 5000 * duration / (acc_rise_times[1] - acc_rise_times[0]) # print("{:80s}: Init: {:3}, Reading: {:3}, Data extraction: {:3} ({}s)".format(filenames[0],success['init'], success['reading'], success['extraction'], duration)) programme_info.append(prg_info) print(prg_info) rawdata_ingo = bne_read_ods_ingo() rawdata_fabian = bne_read_ods_fabian() rawdata_yamada = bne_read_ods_yamada() exps_ingo = rawdata_ingo.get_list_of_dicts() exps_fabian = rawdata_fabian.get_list_of_dicts() exps_yamada = rawdata_yamada.get_list_of_dicts() exps = exps_ingo + exps_fabian + exps_yamada # Get all possible origins origins = set([e.get('origin') for e in exps]) n_origins = len(origins) symbols = ['+', 'x', '*', 's', 'D', '3', '4'] # Get the number, sorted by origin for o in origins: print("Number of experiments by {}: {}".format( o, len([e for e in exps if e.get('origin') == o]))) # Add those parameters which we need for all in a uniform way for e in exps: gamma = get_rel_excitation(e) e['rel_excitation'] = gamma vstar = get_vstar(e) e['vstar'] = vstar S = get_shaking(e) e['S'] = S L = get_L(e) e['L'] = L # Create directory for saved plots codeversion, code_modified = get_git_version() dataversion, data_modified = get_hg_version(bne_config.get('project_path')) figure_path = bne_config.get('project_path') + bne_config.get( 'plot_path') + codeversion + '/' if not os.path.exists(figure_path): os.makedirs(figure_path) write_diff(figure_path) png_metadata = { 'Author': 'TU Braunschweig, Ingo von Borstel', 'Code version': codeversion, 'Data version': dataversion, 'Software': "Brazil nut experiments analysis", } # Show coverage of parameter range in relative excitation and ambient gravity fig, ax = plt.subplots(1, 1, num='rel. excitation over ambient g') filename = figure_path + 'bne_ambientg_relExcitation.png' ax.plot([e.get('ambient_g') for e in exps], [e.get('rel_excitation') for e in exps], '.', color='white') plt.xlabel('ambient gravity [g]') plt.ylabel('relative excitation $\Gamma$') for o, s in zip(origins, symbols): es = [e for e in exps if e.get('origin') == o] ax.plot([e.get('ambient_g') for e in es], [e.get('rel_excitation') for e in es], s, label=o) legend = ax.legend(loc='upper right') plt.show() plt.savefig(filename) add_image_metadata(filename, metadata=png_metadata) # Show coverage of parameter range in relative excitation and frequency fig, ax = plt.subplots(1, 1, num='rel. excitation over frequency') filename = figure_path + 'bne_frequency_relExcitation.png' ax.plot([e.get('frequency') for e in exps], [e.get('rel_excitation') for e in exps], '.', color='white') plt.xlabel('frequency [Hz]') plt.ylabel('relative excitation $\Gamma$') for o, s in zip(origins, symbols): es = [e for e in exps if e.get('origin') == o] ax.plot([e.get('frequency') for e in es], [e.get('rel_excitation') for e in es], s, label=o) legend = ax.legend(loc='lower right') plt.show() plt.savefig(filename) add_image_metadata(filename, metadata=png_metadata) fig, ax = plt.subplots(1, 1, num='rise velocity over gamma') filename = figure_path + 'bne_relExcitation_vstar.png' ax.loglog([e.get('rel_excitation') for e in exps], [e.get('vstar') for e in exps], '.', color='white') plt.xlabel('relative excitation $\Gamma$ [1]') plt.ylabel('rise velocity v* [1]') for o, s in zip(origins, symbols): es = [e for e in exps if e.get('origin') == o] ax.loglog([e.get('rel_excitation') for e in es], [e.get('vstar') for e in es], s, label=o) legend = ax.legend(loc='lower right') plt.show() plt.savefig(filename) add_image_metadata(filename, metadata=png_metadata) fig, ax = plt.subplots(1, 1, num='rise velocity over relative shaking energy') filename = figure_path + 'bne_S_vstar.png' ax.loglog([e.get('S') for e in exps], [e.get('vstar') for e in exps], '.', color='white') plt.xlabel('rel. shaking energy S [1]') plt.ylabel('rise velocity v* [1]') for o, s in zip(origins, symbols): es = [e for e in exps if e.get('origin') == o] ax.loglog([e.get('S') for e in es], [e.get('vstar') for e in es], s, label=o) legend = ax.legend(loc='lower right') plt.show() plt.savefig(filename) add_image_metadata(filename, metadata=png_metadata) exi = exps fig, ax = plt.subplots(1, 1, num='rise velocity over excitation') filename = figure_path + 'bne_relExcitation_vmax.png' ax.loglog([e.get('rel_excitation') - 1 for e in exi], [e.get('v1') for e in exi], '.', color='white') plt.xlabel('rel. excitation -1 [g]') plt.ylabel('rise velocity mm/s') glevels = set([e.get('ambient_g') for e in exi]) for g, s in zip(glevels, symbols): es = [e for e in exi if e.get('ambient_g') == g] ax.loglog([e.get('rel_excitation') - 1 for e in es], [e.get('v1') for e in es], s, label=g) print("g={}: ({:3} exps, {:3}x v1 defined)".format( g, len(es), len(es) - [e.get('v1') for e in es].count(np.NaN))) legend = ax.legend(loc='lower right') plt.show() plt.savefig(filename, metadata=png_metadata) # add_image_metadata(filename, metadata=png_metadata) return exps
def __init__(self): translate_dict = { 'Zeile': { 'new_header': 'exp_id', 'type': 'str', 'prefix': 'fabian-', }, 'Zeit/ s': { 'new_header': 'tap_duration', 'type': 'float', 'conversion': 1.0, }, 'Schüttelung/ m/s^2': { 'new_header': 'acc_excitation', 'type': 'float', 'conversion': 1.0, }, 'Geschwindigkeit1/ m/s': { 'new_header': 'v1', 'type': 'float', }, 'Geschwindigkeit2': { 'new_header': 'v2', 'type': 'float', }, 'Geschwindigkeit3': { 'new_header': 'v3', 'type': 'float', }, 'Geschwindigkeit4': { 'new_header': 'v4', 'type': 'float', }, 'Geschwindigkeit5': { 'new_header': 'v5', 'type': 'float', }, 'Geschwindigkeit6': { 'new_header': 'v6', 'type': 'float', }, 'Geschwindigkeit7': { 'new_header': 'v7', 'type': 'float', }, 'g': { 'new_header': 'ambient_g', 'type': 'float', 'conversion': 1.0, }, 'Bildzahl1': { # These are counted twice for experimental reasons 'new_header': 'taps1', 'type': 'int', 'conversion': 0.5, }, 'Bildzahl2': { # These are counted twice for experimental reasons 'new_header': 'taps2', 'type': 'int', 'conversion': 0.5, }, 'Bildzahl3': { # These are counted twice for experimental reasons 'new_header': 'taps3', 'type': 'int', 'conversion': 0.5, }, 'Bildzahl4': { # These are counted twice for experimental reasons 'new_header': 'taps4', 'type': 'int', 'conversion': 0.5, }, 'Bildzahl5': { # These are counted twice for experimental reasons 'new_header': 'taps5', 'type': 'int', 'conversion': 0.5, }, 'Bildzahl6': { # These are counted twice for experimental reasons 'new_header': 'taps6', 'type': 'int', 'conversion': 0.5, }, 'Bildzahl7': { # These are counted twice for experimental reasons 'new_header': 'taps7', 'type': 'int', 'conversion': 0.5, }, 'Frequenz/ Hz': { 'new_header': 'unused_frequency', 'type': 'float', 'conversion': 1.0 / (2*pi), }, 'Amplitude/ m': { 'new_header': 'unused_amplitude', 'type': 'float', 'conversion': 1.0, }, 'gamma': { 'new_header': 'unused_gamma', 'type': 'float', 'conversion': 1.0, }, 'S': {'new_header': 'unused_S'}, 'L': {'new_header': 'unused_L'}, 'v1*': {'new_header': 'unused_v1*'}, 'v2*': {'new_header': 'unused_v2*'}, 'v3*': {'new_header': 'unused_v3*'}, 'v4*': {'new_header': 'unused_v4*'}, 'v5*': {'new_header': 'unused_v5*'}, 'v6*': {'new_header': 'unused_v6*'}, 'v7*': {'new_header': 'unused_v7*'}, 'Spannung Hoch/ V': {'new_header': 'unused'}, 'Fehler Spannung Hoch': {'new_header': 'unused'}, 'Spannung Runter/ V': {'new_header': 'unused'}, 'Fehler Spannung Runter': {'new_header': 'unused'}, 'Intervallänge': {'new_header': 'unused_intervall'}, 'Zeitfehler': {'new_header': 'unused'}, 'Fehler Frequenz': {'new_header': 'unused'}, 'Beschleunigung Hoch/ m/s^2': {'new_header': 'unused'}, 'Fehler Beschleunigung Hoch': {'new_header': 'unused'}, 'Beschleunigung Runter/ m/s^2': {'new_header': 'unused'}, 'Fehler Schüttelung': {'new_header': 'unused'}, 'Null Schüttelung/ m/s^2': {'new_header': 'unused'}, 'Fehler Null Schüttelung': {'new_header': 'unused'}, 'Fehler Amplitude': {'new_header': 'unused'}, 'Fehler Gamma': {'new_header': 'unused'}, 'Fehler S': {'new_header': 'unused'}, 'S^0,45*L^0,82': {'new_header': 'unused'}, 'Fehler Z5050': {'new_header': 'unused'}, 's^-0.0391': {'new_header': 'unused'}, 'Fehler Z5052': {'new_header': 'unused'}, 'S^0,1275': {'new_header': 'unused'}, 'Fehler Z5054': {'new_header': 'unused'}, 'Fehler v1*': {'new_header': 'unused'}, 'Fehler v2*': {'new_header': 'unused'}, 'Fehler v3*': {'new_header': 'unused'}, 'Fehler v4*': {'new_header': 'unused'}, 'Fehler v5*': {'new_header': 'unused'}, 'Fehler v6*': {'new_header': 'unused'}, 'Fehler v7*': {'new_header': 'unused'}, 'Fehler Geschwindigkeit1': {'new_header': 'unused'}, 'Fehler Geschwindigkeit2': {'new_header': 'unused'}, 'Fehler Geschwindigkeit3': {'new_header': 'unused'}, 'Fehler Geschwindigkeit4': {'new_header': 'unused'}, 'Fehler Geschwindigkeit5': {'new_header': 'unused'}, 'Fehler Geschwindigkeit6': {'new_header': 'unused'}, 'Fehler Geschwindigkeit7': {'new_header': 'unused'}, } # filename = PROJECT_PATH + "TestImport.ods" filename = bne_config.get('project_path') + bne_config.get( 'filename_data_fabian') sheet = bne_config.get('sheetname_data_fabian') super().__init__(filename, sheet, translate_dict, experiments_in_columns=False) self.decimal_sep = ','
def read_file(self): assert (self.filename is not None), "No filename to read specified" doc = ODSReader(self.filename, clonespannedcolumns = True) self.programmes = doc.getSheet(bne_config.get('sheetname_stage_programmes'))
import pandas as pd from scipy.signal import savgol_filter from scipy.ndimage.interpolation import shift import matplotlib.pyplot as plt from BNE.bne_config import bne_config from tools.cast_lists import cast_to_float, list_to_int default_calibration = { 'level0g': 2.4655959, 'level1g': 2.4412975, 'trigger_offset': 0.00851714, } programme_table_filename = bne_config.get('project_path') + bne_config.get('filename_stage_programmes') sensor_file_path = bne_config.get('project_path') + bne_config.get('sensor_path') calibration_keys = ['level0g', 'level1g', 'trigger_offset'] def find_nearest(array,value): """Find the nearest list entry for a given value @param array The array to search in @param value The value to find the nearest list entry for """ idx = (np.abs(array-value)).argmin() return array[idx] def get_key(dictionary, key, default = None):
def __init__(self): translate_dict = { 'Amplitude': { 'new_header': 'amplitude', 'type': 'float', 'conversion': 0.001, }, 'Frequency': { 'new_header': 'frequency', 'type': 'float', }, 'Grain_diameter': { 'new_header': 'bead_radius', 'type': 'float', 'conversion': 0.0005, }, 'Vessel_radius': { 'new_header': 'container_radius', 'type': 'float', 'conversion': 0.001, }, 'Granular_bed_Height': { 'new_header': 'fill_height', 'type': 'float', 'conversion': 0.001, }, 'v_zmax': { 'new_header': 'vmax', 'type': 'float', 'conversion': 0.001, }, 'g': { 'new_header': 'ambient_g', 'type': 'float', 'conversion': 0.001 / 9.81, }, 'Gamma': { 'new_header': 'rel_excitation', 'type': 'float', 'conversion': 1.0, }, 'S': { 'new_header': 'unused_S' }, 'L': { 'new_header': 'unused_L' }, 'v_zmax_SD': { 'new_header': 'unused_v_zmax_SD' }, 'v1*': { 'new_header': 'unused_v1*' }, 'v1*_SD': { 'new_header': 'unused_v1*_SD' } } filename = bne_config.get('project_path') + bne_config.get( 'filename_data_yamada') sheet = bne_config.get('sheetname_data_yamada') super().__init__(filename, sheet, translate_dict, True) self.data_row_start = 2 self.decimal_sep = ','
def get_dict_of_lists(self): data = super().get_dict_of_lists() n_exp = len(next(iter(data.values()))) self.data['origin'] = ['Ingo' for _ in range(n_exp)] self.data['bead_radius'] = [ bne_config.get('bead_radius') for _ in range(n_exp) ] self.data['amplitude'] = [ bne_config.get('amplitude_ingo') for _ in range(n_exp) ] self.data['fill_height'] = [ bne_config.get('fill_height_ingo') for _ in range(n_exp) ] # read the info about the programmes stage_programmes = stage_programme_names( bne_config.get('project_path') + bne_config.get('filename_stage_programmes')) stage_programmes.read_file() stage_programmes.get_programme_info() prg_name_dict = stage_programmes.get_programmes_as_dict() # obtain the acceleration data for each programme and analyse them for prg, val in prg_name_dict.items(): pattern = val.get('filename_pattern') filenames = glob.glob( bne_config.get('project_path') + bne_config.get('sensor_path') + pattern) # print("{}: ".format(prg)," ",filenames) # print(val) if len(filenames) == 0: continue acc_prg = single_stage_programme(prg, filenames[0]) acc_prg.read_by_filename() acc_prg.extract_data(None, val.get('duration'), val.get('acc_rise_times')) # DEBUG # acc_prg.show_data() prg_name_dict[prg]['frequency'] = acc_prg.get_frequency() self.data['frequency'] = [np.NaN for _ in range(n_exp)] for i, pname in enumerate(self.data['stage_programme']): try: self.data['frequency'][i] = prg_name_dict.get(pname).get( 'frequency') except: pass for v, f, tap in zip( ['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7'], ['frequency' for _ in range(7)], ['taps1', 'taps2', 'taps3', 'taps4', 'taps5', 'taps6', 'taps7']): self.data[v] = [ v_from_taps(fill_height, f, t) for t, f, fill_height in zip( self.data[tap], self.data['frequency'], self.data['fill_height']) ] self.data['vmax'] = [ max(v1, v2, v3, v4, v5, v6, v7) for v1, v2, v3, v4, v5, v6, v7 in zip(self.data.get('v1'), self.data.get('v2'), self.data.get('v3'), self.data.get('v4'), self.data.get('v5'), self.data.get('v6'), self.data.get('v7')) ] return self.data
def __init__(self): translate_dict = { 'exp.no.': { 'new_header': 'exp_id', }, 'ambient[Earth G]': { 'new_header': 'ambient_g', 'type': 'float', 'conversion': 1.0 }, 'excitation[amb. G]': { 'new_header': 'rel_excitation', 'type': 'float', 'conversion': 1.0 }, 'Nut Dia. [mm]': { 'new_header': 'nut_radius', 'type': 'float', 'conversion': 0.001, }, 'duration1 [taps]': { 'new_header': 'taps1', 'type': 'int', }, 'duration2 [taps]': { 'new_header': 'taps2', 'type': 'int', }, 'duration3 [taps]': { 'new_header': 'taps3', 'type': 'int', }, 'duration4 [taps]': { 'new_header': 'taps4', 'type': 'int', }, 'duration5 [taps]': { 'new_header': 'taps5', 'type': 'int', }, 'duration6 [taps]': { 'new_header': 'taps6', 'type': 'int', }, 'duration7 [taps]': { 'new_header': 'taps7', 'type': 'int', }, 'Programme': { 'new_header': 'stage_programme', }, 'containerdia. [cm]': { 'new_header': 'container_radius', 'type': 'float', 'conversion': 0.01 } } filename = bne_config.get('project_path') + bne_config.get( 'filename_data_ingo') sheet = bne_config.get('sheetname_data_ingo') super().__init__(filename, sheet, translate_dict, True) self.data_row_start = 1 self.decimal_sep = '.'