From afbbfa9316425db38984c7114424af999b532128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Clau=C3=9F?= Date: Tue, 22 Nov 2022 12:29:05 +0100 Subject: [PATCH] =?UTF-8?q?Auswertung=20SPZ=20Steifigkeit=20nach=20TP=2026?= =?UTF-8?q?=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pytestpavement/functions/citt.py | 6 + src/pytestpavement/labtests/base.py | 16 +- src/pytestpavement/labtests/citt.py | 1456 +++++++++++++++++++++++++- src/pytestpavement/models/citt.py | 64 +- src/pytestpavement/models/data.py | 12 + 5 files changed, 1516 insertions(+), 38 deletions(-) diff --git a/src/pytestpavement/functions/citt.py b/src/pytestpavement/functions/citt.py index af8f6da..84fe0be 100644 --- a/src/pytestpavement/functions/citt.py +++ b/src/pytestpavement/functions/citt.py @@ -8,3 +8,9 @@ def stiffness_tp26(T, f, Emax, Emin, phi, z0, z1, T0=20.0): E = Emin + (Emax - Emin) / (1 + np.exp(z0 * x + z1)) return E + + +def calc_nu(T): + #TODO: Prüfen ob Formel stimmt! + nu = 0.15 + (0.35) / (1 + np.exp(3.1849 - 0.04233 * (9 / 5 * T + 32))) + return nu diff --git a/src/pytestpavement/labtests/base.py b/src/pytestpavement/labtests/base.py index 9c7fc29..095df75 100644 --- a/src/pytestpavement/labtests/base.py +++ b/src/pytestpavement/labtests/base.py @@ -318,14 +318,22 @@ class DataSineLoad(): 'Number of load cycles smaller than selectect values') if not isinstance(self.data, list): - df_sel = [ - sel_df(self.data, num=self.number_of_load_cycles_for_analysis) - ] + if self.number_of_load_cycles_for_analysis > 1: + df_sel = [ + sel_df(self.data, + num=self.number_of_load_cycles_for_analysis) + ] + else: + df_sel = [self.data] else: df_sel = [] for d in self.data: - d_sel = sel_df(d, num=self.number_of_load_cycles_for_analysis) + if self.number_of_load_cycles_for_analysis > 1: + d_sel = sel_df(d, + num=self.number_of_load_cycles_for_analysis) + else: + d_sel = d df_sel.append(d_sel) diff --git a/src/pytestpavement/labtests/citt.py b/src/pytestpavement/labtests/citt.py index 85ca2ec..b00663e 100644 --- a/src/pytestpavement/labtests/citt.py +++ b/src/pytestpavement/labtests/citt.py @@ -1,15 +1,41 @@ import os +from csv import reader -import lmfit as lm import matplotlib.pyplot as plt import numpy as np +import pandas as pd from pytestpavement.analysis.regression import fit_cos, fit_cos_eval -from pytestpavement.helper.exceptions import HashInDb +from pytestpavement.functions.citt import calc_nu +#from pytestpavement.helper.exceptions import HashInDbError from pytestpavement.io.geosys import read_geosys from pytestpavement.labtests.base import DataSineLoad from pytestpavement.models.citt import CyclicIndirectTensileTest +def check_timeindex(t, cycles: int, frequency: float, error: float = 10.0): + """ + check if time length correspondents to freuqncy + + t: time vector + cycles: number of cycles + frequency: frequency of the load + error: differenz in % + + """ + + runtime = cycles * 1 / frequency + abserror = error / 100 * runtime + + td = (t - t[0])[-1] + + if not (runtime - abserror) < td < (runtime + abserror): + print('check_timeindex:', 'runtime', runtime, 'abserror', abserror, + 'td', td) + return False + + return True + + class CittTest(DataSineLoad): """ Base Class of CyclicIndirectTensileTest @@ -18,11 +44,17 @@ class CittTest(DataSineLoad): def __init__(self, fname: str, debug: bool = False, - temperature: float = -999.9): + temperature: float = -999.9, + sigma: float = -999.9, + frequency: float = -999.9, + meta: dict = None): #set parameter self.file = fname self.temperature = temperature + self.frequency = frequency + self.sigma = sigma + self.meta = meta # process file self._run() @@ -37,7 +69,7 @@ class CittTest(DataSineLoad): n = CyclicIndirectTensileTest.objects(filehash=self.filehash).count() - assert n == 0, HashInDb + #assert n == 0, HashInDbError def _set_parameter(self): @@ -57,3 +89,1419 @@ class CittTest(DataSineLoad): ] self.number_of_load_cycles_for_analysis = 5 + + self.encoding = 'latin-1' + + self.roundtemperature = False + + def _fit_data(self): + + self.fit = [] + + for idx_data, data in enumerate(self.data): + + if data is None: continue + if len(data) < 10: continue + + data.index = data.index - data.index[0] + + #overwrite Temperature and Frequency + if self.temperature > -999.9: + temperature = self.temperature + else: + temperature = np.round(data['T'].mean(), 3) + + if self.frequency > -999.9: + frequency = self.frequency + else: + frequency = np.round(data['f'].mean(), 3) + + if self.sigma > -999.9: + sigma = self.sigma + else: + raise 'not Defined' + + x = data.index + + #check time vector + ncycles = len(data['N'].unique()) + if not check_timeindex(x, ncycles, frequency): + print('error in', idx_data) + continue + + # Force + yF = data['F'] + resF = fit_cos(x, yF, freq=frequency, constfreq=False) + + # Displacement + + yS1 = data['s_hor_1'] + resS1 = fit_cos(x, yS1, freq=frequency, constfreq=False) + yS2 = data['s_hor_2'] + resS2 = fit_cos(x, yS2, freq=frequency, constfreq=False) + + yS = data['s_hor_sum'] + resS = fit_cos(x, yS, freq=frequency, constfreq=False) + + ## Stiffness + deltaF = resF['amp'] + nu = calc_nu(temperature) + + h = float(self.meta['speciment_height']) + deltaU = resS['amp'] + + res = {} + res['idx_data'] = idx_data + res['stiffness'] = (deltaF * (0.274 + nu)) / (h * deltaU) + res['nu'] = nu + + res['f_set'] = frequency + res['T_set'] = temperature + res['sigma_set'] = sigma + + res['N_from'] = data['N'].min() + res['N_to'] = data['N'].max() + + for key in resF.keys(): + res[f'F_{key}'] = resF[key] + + for key in resS.keys(): + res[f's_hor_{key}'] = resS[key] + res[f's_hor_1_{key}'] = resS1[key] + res[f's_hor_2_{key}'] = resS2[key] + + res['phase'] = resF['phase'] - resS['phase'] + + #save data + self.fit.append(res) + + self.fit = pd.DataFrame.from_records(self.fit) + + if not self.fit.empty: + self.fit = self.fit.reset_index( + drop=True).set_index('idx_data').sort_index() + + +class CittTestTUDGeosys(CittTest): + + def _set_parameter(self): + + self.split_data_based_on_parameter = ['T', 'f'] + + self.col_as_int = ['N'] + self.col_as_float = ['T', 'F', 'f', 's_vert_sum'] + + self.val_col_names = [ + 'time', 'T', 'f', 'N', 'F', 's_hor_sum', 's_hor_1', 's_hor_2' + ] + # Header names after standardization; check if exists + self.val_header_names = ['speciment_diameter'] + + self.columns_analyse = ['F', 's_hor_sum', 's_hor_1', 's_hor_2'] + + self.number_of_load_cycles_for_analysis = 5 + + self.encoding = 'latin-1' + + self.roundtemperature = False + + def _define_units(self): + + self.unit_s = 1 / 1000. #ym in mm + self.unit_F = 1 #N + self.unit_t = 1. #s + + def _read_data(self, skiprows=14, hasunits=True): + """ + read data + """ + + meta, data = read_geosys(self.file, '039') + + #define in class + self.meta = meta + self.data = data.reset_index() + + return True + + def _standardize_meta(self): + + keys = list(self.meta.keys()) + for key in keys: + if key == 'name': + self.meta['speciment'] = self.meta.pop(key) + elif key == 'h': + self.meta['speciment_height'] = self.meta.pop(key) + elif key == 'd': + self.meta['speciment_diameter'] = self.meta.pop(key) + + return True + + def _standardize_data(self): + + colnames = list(self.data.columns) + + for i, col in enumerate(colnames): + if col == 'Zeit': + colnames[i] = 'time' + + elif col == 'aktuelle Soll-Frequenz': + colnames[i] = 'f' + + elif col == 'Kraft': + colnames[i] = 'F' + + elif col == 'Zyklenzähler': + colnames[i] = 'N' + + elif col == 'Temperatur (Regler) (Soll)': + colnames[i] = 'T' + + elif col == 'Kolbenweg': + colnames[i] = 's_piston' + + elif col == 'Horizontalweg vorn': + colnames[i] = 's_hor_1' + elif col == 'Horizontalweg hinten': + colnames[i] = 's_hor_2' + + elif col == 'Horizontalweg Summe': + colnames[i] = 's_hor_sum' + + self.data.columns = colnames + + +class CittTestTUDTira(CittTest): + + def _set_parameter(self): + + self.split_data_based_on_parameter = ['T', 'f'] + + self.col_as_int = ['N'] + self.col_as_float = ['T', 'F', 'f', 's_vert_sum'] + + self.val_col_names = [ + 'time', 'T', 'f', 'N', 'F', 's_hor_sum', 's_hor_1', 's_hor_2' + ] + # Header names after standardization; check if exists + self.val_header_names = ['speciment_diameter'] + + self.columns_analyse = ['F', 's_hor_sum', 's_hor_1', 's_hor_2'] + + self.number_of_load_cycles_for_analysis = 5 + + self.encoding = 'latin-1' + + self.roundtemperature = False + + def _define_units(self): + + self.unit_s = 1. #ym in mm + self.unit_F = 1 #N + self.unit_t = 1. #s + + def _read_data(self, skiprows=28, hasunits=True): + """ + read data + """ + + meta = {} + + splitsign = ':;' + + with open(self.file, 'r', encoding=self.encoding) as f: + count = 0 + + for line in f: + count += 1 + + #remove whitespace + linesplit = line.strip() + linesplit = linesplit.split(splitsign) + + if len(linesplit) == 2: + + meta[linesplit[0]] = linesplit[1] + + if count >= skiprows: + break + + ## add header to df + with open(self.file, 'r', encoding=self.encoding) as f: + count = 0 + + for line in f: + count += 1 + + if count > skiprows: + break + + head = line.split(';') + head = [h.strip() for h in head] + + # data + data = pd.read_csv(self.file, + encoding=self.encoding, + skiprows=skiprows + 2, + header=None, + skipinitialspace=False, + thousands='.', + decimal=',', + sep=';') + + data = data.iloc[1:] + + data.columns = head + + #clean data + data = data.dropna(axis=1) + + #define in class + self.meta = meta + self.data = data + + if not 'f' in self.data.columns: + if self.frequency > -999.9: + self.data['f'] = self.frequency + + return True + + def _standardize_meta(self): + + keys = list(self.meta.keys()) + for key in keys: + if key == 'name': + self.meta['speciment'] = self.meta.pop(key) + elif key == 'PK-Höhe': + self.meta['speciment_height'] = float( + self.meta.pop(key).split(';')[0].replace(',', '.')) + elif key == 'PK-Durchmesser': + self.meta['speciment_diameter'] = float( + self.meta.pop(key).split(';')[0].replace(',', '.')) + + return True + + def _standardize_data(self): + + colnames = list(self.data.columns) + + for i, col in enumerate(colnames): + if col == 'Zeit': + colnames[i] = 'time' + + elif col == 'aktuelle Soll-Frequenz': + colnames[i] = 'f' + + elif col == 'Kraft': + colnames[i] = 'F' + + elif col == 'Lastwechsel': + colnames[i] = 'N' + + elif col == 'Temp innen': + colnames[i] = 'T' + + elif col == 'Kolbenweg': + colnames[i] = 's_piston' + + elif col == 'IWA A 50 mm': + colnames[i] = 's_hor_1' + elif col == 'IWA B 50 mm': + colnames[i] = 's_hor_2' + + elif col == 'Radialweg': + colnames[i] = 's_hor_sum' + + self.data.columns = colnames + + def _calc_missiong_values(self): + + cols = self.data.columns + + if not 's_hor_sum' in cols: + self.data['s_hor_sum'] = self.data[['s_hor_1', + 's_hor_2']].sum(axis=1) + + +class CittTestBASt(CittTest): + + def _set_parameter(self): + + self.split_data_based_on_parameter = ['T', 'f'] + + self.col_as_int = ['N'] + self.col_as_float = ['T', 'F', 'f', 's_vert_sum'] + + self.val_col_names = [ + 'time', 'T', 'f', 'N', 'F', 's_hor_sum', 's_hor_1', 's_hor_2' + ] + # Header names after standardization; check if exists + self.val_header_names = ['speciment_diameter'] + + self.columns_analyse = ['F', 's_hor_sum', 's_hor_1', 's_hor_2'] + + self.number_of_load_cycles_for_analysis = 5 + + self.encoding = 'latin-1' + + self.roundtemperature = False + + def _define_units(self): + + self.unit_s = 1 / 1000. #ym in mm + self.unit_F = 1 #N + self.unit_t = 1. #s + + def _read_data(self): + """ + read data + """ + + meta, data = read_geosys(self.file, '047') + + #define in class + self.meta = meta + self.data = data.reset_index() + + if not 'f' in self.data.columns: + if self.frequency > -999.9: + self.data['f'] = self.frequency + + return True + + def _standardize_meta(self): + + keys = list(self.meta.keys()) + for key in keys: + if key == 'name': + self.meta['speciment'] = self.meta.pop(key) + elif key == 'h': + self.meta['speciment_height'] = self.meta.pop(key) + elif key == 'd': + self.meta['speciment_diameter'] = self.meta.pop(key) + + return True + + def _standardize_data(self): + + colnames = list(self.data.columns) + + for i, col in enumerate(colnames): + if col == 'Zeit': + colnames[i] = 'time' + + elif col == 'aktuelle Soll-Frequenz': + colnames[i] = 'f' + + elif col == 'Vertikalkraft': + colnames[i] = 'F' + + elif col == 'Zyklenzähler': + colnames[i] = 'N' + + elif col == 'Temperatur Regler (Soll)': + colnames[i] = 'T' + + elif col == 'Kolbenposition': + colnames[i] = 's_piston' + + elif col == 'Horizontalweg IWA vorn': + colnames[i] = 's_hor_1' + elif col == 'Horizontalweg IWA hinten': + colnames[i] = 's_hor_2' + + elif col == 'Horizontalweg IWA Summe': + colnames[i] = 's_hor_sum' + + self.data.columns = colnames + + +class CittTestAachen(CittTest): + + def _set_parameter(self): + + self.split_data_based_on_parameter = ['T', 'f'] + + self.col_as_int = ['N'] + self.col_as_float = ['T', 'F', 'f', 's_vert_sum'] + + self.val_col_names = [ + 'time', 'T', 'f', 'N', 'F', 's_hor_sum', 's_hor_1', 's_hor_2' + ] + # Header names after standardization; check if exists + self.val_header_names = ['speciment_diameter'] + + self.columns_analyse = ['F', 's_hor_sum', 's_hor_1', 's_hor_2'] + + self.number_of_load_cycles_for_analysis = 5 + + self.encoding = 'latin-1' + + self.roundtemperature = False + + def _define_units(self): + + self.unit_s = 1 / 10000. #mm + self.unit_F = 1 / 10.0 #N + self.unit_t = 1 / 1000.0 #s + self.unit_freq = 1 / 10. + + def _read_data(self): + """ + read data + """ + + data = pd.read_csv(self.file, encoding='latin1', sep='\t') + + for col in data.columns: + data[col] = data[col].astype(float) + + sigma = float( + os.path.split( + self.file)[-1].split('MPa')[0].split('_')[-1].replace( + 'x', '.')) + data['sigma'] = sigma + + #define in class + self.data = data.reset_index() + return True + + def _standardize_meta(self): + + keys = list(self.meta.keys()) + for key in keys: + if key == 'name': + self.meta['speciment'] = self.meta.pop(key) + elif key == 'h': + self.meta['speciment_height'] = self.meta.pop(key) + elif key == 'd': + self.meta['speciment_diameter'] = self.meta.pop(key) + + return True + + def _standardize_data(self): + + colnames = list(self.data.columns) + + for i, col in enumerate(colnames): + if col == 'Zyklen': + colnames[i] = 'N' + + elif col == 'FREQUENZ_x10': + colnames[i] = 'f' + + elif col == 'Time_ms': + colnames[i] = 'time' + + elif col == 'AktTemper_°C_x10': + colnames[i] = 'T' + + elif col == 'Load_N_x10': + colnames[i] = 'F' + + elif col == 'POSITION_µm': + colnames[i] = 's_piston' + + elif col == 'SENSOR_EXT_µm_x10': + colnames[i] = 's_hor_1' + elif col == 'SENSOR_S4_µm_x10': + colnames[i] = 's_hor_2' + + elif col == 'Horizontalweg IWA Summe': + colnames[i] = 's_hor_sum' + + self.data.columns = colnames + + def _set_units(self): + + for col in ['s_hor_sum', 's_hor_1', 's_hor_2']: + self.data[col] = self.data[col].mul(self.unit_s) + + for col in ['F']: + self.data[col] = self.data[col].mul(self.unit_F) + + for col in ['time']: + self.data[col] = self.data[col].mul(self.unit_t) + + for col in ['f']: + self.data[col] = self.data[col].mul(self.unit_freq) + + return True + + +class CittTestAhlen(CittTest): + + def _set_parameter(self): + + self.split_data_based_on_parameter = ['T', 'f'] + + self.col_as_int = ['N'] + self.col_as_float = ['T', 'F', 'f', 's_vert_sum'] + + self.val_col_names = [ + 'time', 'T', 'f', 'N', 'F', 's_hor_sum', 's_hor_1', 's_hor_2' + ] + # Header names after standardization; check if exists + self.val_header_names = ['speciment_diameter'] + + self.columns_analyse = ['F', 's_hor_sum', 's_hor_1', 's_hor_2'] + + self.number_of_load_cycles_for_analysis = 5 + + self.encoding = 'latin-1' + + self.roundtemperature = False + + def _define_units(self): + + self.unit_s = 1 / 10000. #mm + self.unit_F = 1 / 10.0 #N + self.unit_t = 1 / 1000.0 #s + self.unit_freq = 1 / 10. + + def _read_data(self): + """ + read data + """ + + data = pd.read_csv(self.file, encoding=self.encoding, sep=';') + + for col in data.columns: + data[col] = data[col].astype(float) + + #define in class + self.data = data.reset_index() + return True + + def _standardize_meta(self): + + keys = list(self.meta.keys()) + for key in keys: + if key == 'name': + self.meta['speciment'] = self.meta.pop(key) + elif key == 'h': + self.meta['speciment_height'] = self.meta.pop(key) + elif key == 'd': + self.meta['speciment_diameter'] = self.meta.pop(key) + + return True + + def _standardize_data(self): + + colnames = list(self.data.columns) + + for i, col in enumerate(colnames): + if col == 'Zyklen': + colnames[i] = 'N' + + elif col == 'FREQUENZ_x10': + colnames[i] = 'f' + + elif col == 'Time_ms': + colnames[i] = 'time' + + elif col == 'AktTemper_°C_x10': + colnames[i] = 'T' + + elif col == 'Load_N_x10': + colnames[i] = 'F' + + elif col == 'POSITION_µm': + colnames[i] = 's_piston' + + elif col == 'SENSOR_EXT_µm_x10': + colnames[i] = 's_hor_1' + elif col == 'SENSOR_S4_µm_x10': + colnames[i] = 's_hor_2' + + elif col == 'Horizontalweg IWA Summe': + colnames[i] = 's_hor_sum' + + self.data.columns = colnames + + def _set_units(self): + + for col in ['s_hor_sum', 's_hor_1', 's_hor_2']: + self.data[col] = self.data[col].mul(self.unit_s) + + for col in ['F']: + self.data[col] = self.data[col].mul(self.unit_F) + + for col in ['time']: + self.data[col] = self.data[col].mul(self.unit_t) + + for col in ['f']: + self.data[col] = self.data[col].mul(self.unit_freq) + + return True + + +class CittTestKITKarlsruhe(CittTest): + + def _set_parameter(self): + + self.split_data_based_on_parameter = ['f', 'T'] + + self.col_as_int = ['N'] + self.col_as_float = ['T', 'F', 'f', 's_vert_sum'] + + self.val_col_names = [ + 'time', 'T', 'f', 'N', 'F', 's_hor_sum', 's_hor_1', 's_hor_2' + ] + # Header names after standardization; check if exists + self.val_header_names = ['speciment_diameter'] + + self.columns_analyse = ['F', 's_hor_sum', 's_hor_1', 's_hor_2'] + + self.number_of_load_cycles_for_analysis = 5 + + self.encoding = 'latin-1' + + self.roundtemperature = False + + def _define_units(self): + + self.unit_s = 1.0 #mm + self.unit_F = -1000.0 #N + self.unit_t = 1.0 #s + + def _read_data(self): + """ + read data + """ + + # open file in read mode + with open(self.file, 'r', encoding='latin1') as read_obj: + csv_reader = reader(read_obj, delimiter=';') + + read = False + + data = [] + temp = [] + + for idx_row, row in enumerate(csv_reader): + if row == ['*****']: + + if read == False: + read = True + else: + read = False + data.append(temp) + + temp = [] + + continue + + if read: + + row = [r.replace(',', '.') for r in row] + + temp.append(row) + + #convert to pandas + + res = [] + + freqs = [10.0, 5.0, 1.0, 0.1, 10.0] + + for idx_data, d in enumerate(data): + + t = pd.DataFrame(d[3:]) + t.columns = d[1] + + freq = freqs[idx_data] + t['f'] = freq + + for col in t.columns: + t[col] = pd.to_numeric(t[col]) + + # add cycle number + dt = 1. / freq + + Nmax = int(np.ceil(t['ZEIT'].max() / dt)) + + N = np.zeros_like(t['ZEIT']) + + for i in range(Nmax): + if i == 0: + tmin = 0 + tmax = dt + else: + tmax = (i + 1) * dt + tmin = (i) * dt + + idx = t[(t['ZEIT'] >= tmin) & (t['ZEIT'] < tmax)].index + N[idx] = i + + t['N'] = N + + res.append(t) + + #remove second 10 Hz + res = pd.concat(res[:-1]) + + res['T'] = self.temperature + #res = res.sort_values(['f', 'ZEIT']) + + #define in class + self.data = res.reset_index() + + return True + + def _standardize_meta(self): + + keys = list(self.meta.keys()) + for key in keys: + if key == 'name': + self.meta['speciment'] = self.meta.pop(key) + elif key == 'h': + self.meta['speciment_height'] = self.meta.pop(key) + elif key == 'd': + self.meta['speciment_diameter'] = self.meta.pop(key) + + return True + + def _standardize_data(self): + + colnames = list(self.data.columns) + + for i, col in enumerate(colnames): + if col == 'ZEIT': + colnames[i] = 'time' + + elif col == 'Kraft25': + colnames[i] = 'F' + + elif col == 'Ext1 ITT': + colnames[i] = 's_hor_1' + elif col == 'Ext2 ITT': + colnames[i] = 's_hor_2' + + elif col == 'Defl ITT': + colnames[i] = 's_hor_sum' + + self.data.columns = colnames + + def _select_data(self): + """ select N load cycles from original data """ + + return + + +class CittTestPTMDortmund(CittTest): + + def _set_parameter(self): + + self.split_data_based_on_parameter = ['sigma', 'T', 'f'] + + self.col_as_int = ['N'] + self.col_as_float = ['T', 'F', 'f', 's_vert_sum'] + + self.val_col_names = [ + 'time', 'T', 'f', 'N', 'F', 's_hor_sum', 's_hor_1', 's_hor_2' + ] + # Header names after standardization; check if exists + self.val_header_names = ['speciment_diameter'] + + self.columns_analyse = ['F', 's_hor_sum', 's_hor_1', 's_hor_2'] + + self.number_of_load_cycles_for_analysis = 1 + + self.encoding = 'latin-1' + + self.roundtemperature = False + + def _define_units(self): + + self.unit_s = 1.0 #mm + self.unit_F = 1000.0 #N + self.unit_t = 1.0 #s + + def _read_data(self): + """ + read data + """ + + res = [] + + for colid in range(1, 6): + temp = pd.read_excel(self.file, f'Seq{colid}_data', skiprows=97) + temp = temp.drop(index=0) + + self.meta = pd.read_excel(self.file, + f'Seq{colid}_data', + skiprows=1, + nrows=90) + + self.meta = self.meta[self.meta.columns[[0, 2]]] + self.meta = self.meta.set_index( + self.meta.columns[0]).to_dict()[self.meta.columns[1]] + + temp['sigma'] = float(self.meta['Max. Spannung']) + temp['T'] = float(self.meta['Versuchstemperatur']) + freq = float(self.meta['Frequenz']) + dt = 1 / freq + temp['f'] = freq + + Nfrom = int(self.meta['Erster Aufzeichnungslastwechsel']) + Nto = int(self.meta['Letzer Aufzeichnungslastwechsel']) + ncycles = int(self.meta['Number of cycles']) + + #BUG + temp['N'] = Nfrom + """ + + N = np.zeros_like(temp['Zeitfolgen']) + + for i in range(Nmax): + if i == 0: + tmin = 0 + tmax = dt + else: + tmax = (i + 1) * dt + tmin = (i) * dt + + idx = temp[(temp['Zeitfolgen'] >= tmin) + & (temp['Zeitfolgen'] < tmax)].index + + N[idx] = i + + temp['N'] = N + + """ + + for col in temp.columns: + temp[col] = pd.to_numeric(temp[col]) + + res.append(temp) + + res = pd.concat(res) + + #define in class + self.data = res.reset_index() + + return True + + def _standardize_meta(self): + + keys = list(self.meta.keys()) + for key in keys: + if key == 'name': + self.meta['Probenbezeichnung'] = self.meta.pop(key) + elif key == 'Länge (mm)': + self.meta['speciment_height'] = self.meta.pop(key) + elif key == 'Durchmesser (mm)': + self.meta['speciment_diameter'] = self.meta.pop(key) + + return True + + def _standardize_data(self): + + colnames = list(self.data.columns) + + for i, col in enumerate(colnames): + if col == 'Zeitfolgen': + colnames[i] = 'time' + + elif col == 'Lastreihe': + colnames[i] = 'F' + + elif col == 'Wegaufnehmer 1 Serie': + #elif col == 'Wegaufnehmer 1 Eingerichtete Serie': + colnames[i] = 's_hor_1' + elif col == 'Wegaufnehmer 2 Serie': + #elif col == 'Wegaufnehmer 2 Eingerichtete Serie': + colnames[i] = 's_hor_2' + + elif col == 'Defl ITT': + colnames[i] = 's_hor_sum' + + self.data.columns = colnames + + +class CittTestPinneberg(CittTest): + + def _set_parameter(self): + + self.split_data_based_on_parameter = ['T', 'f'] + + self.col_as_int = ['N'] + self.col_as_float = ['T', 'F', 'f', 's_vert_sum'] + + self.val_col_names = [ + 'time', 'T', 'f', 'N', 'F', 's_hor_sum', 's_hor_1', 's_hor_2' + ] + # Header names after standardization; check if exists + self.val_header_names = ['speciment_diameter'] + + self.columns_analyse = ['F', 's_hor_sum', 's_hor_1', 's_hor_2'] + + self.number_of_load_cycles_for_analysis = 5 + + self.encoding = 'latin-1' + + self.roundtemperature = False + + def _define_units(self): + self.unit_s = 1 / 10000.0 #mm Daten sind 10fach überhöht gespeichert + self.unit_spiston = 1 / 1000.0 #mm + self.unit_F = 1 / 10.0 #N + self.unit_t = 1 / 1000.0 #s + self.unit_freq = 1 / 10.0 #s + self.unit_T = 1 / 10. #°C + + def _read_data(self, skiprows=0): + """ + read data + """ + + data = pd.read_csv(self.file, + encoding=self.encoding, + skiprows=skiprows, + decimal=',', + sep=';') + + #clean data + data = data.dropna(axis=1) + + # remove second 10 Hz + sel = data[data['FREQUENZ_x10'] == 100] + + diff = sel['Time_ms'].diff() + diff_median = diff.median() + idx_gap = diff[diff > 2 * diff_median].index[0] - 1 + + data = data.loc[0:idx_gap] + + #define in class + self.data = data + return True + + def _standardize_data(self): + + colnames = list(self.data.columns) + + for i, col in enumerate(colnames): + if col == 'Time_ms': + colnames[i] = 'time' + + elif col == 'AktTemper_°C_x10': + colnames[i] = 'T' + + elif col == 'FREQUENZ_x10': + colnames[i] = 'f' + + elif col == 'Zyklen': + colnames[i] = 'N' + + elif col == 'POSITION_µm': + colnames[i] = 's_piston' + + elif col == 'Load_N_x10': + colnames[i] = 'F' + + elif col == 'SENSOR_EXT_µm_x10': + colnames[i] = 's_hor_1' + elif col == 'SENSOR_S4_µm_x10': + colnames[i] = 's_hor_2' + + elif col == 'Defl ITT': + colnames[i] = 's_hor_sum' + + self.data.columns = colnames + + def _set_units(self): + + for col in ['s_hor_sum', 's_hor_1', 's_hor_2']: + self.data[col] = self.data[col].mul(self.unit_s) + + for col in ['s_piston']: + self.data[col] = self.data[col].mul(self.unit_spiston) + + for col in ['F']: + self.data[col] = self.data[col].mul(self.unit_F) + + for col in ['time']: + self.data[col] = self.data[col].mul(self.unit_t) + + for col in ['f']: + self.data[col] = self.data[col].mul(self.unit_freq) + for col in ['T']: + self.data[col] = self.data[col].mul(self.unit_T) + + +class CittTestSiegen(CittTest): + + def _set_parameter(self): + + self.split_data_based_on_parameter = ['T', 'f'] + + self.col_as_int = ['N'] + self.col_as_float = ['T', 'F', 'f', 's_vert_sum'] + + self.val_col_names = [ + 'time', 'T', 'f', 'N', 'F', 's_hor_sum', 's_hor_1', 's_hor_2' + ] + # Header names after standardization; check if exists + self.val_header_names = ['speciment_diameter'] + + self.columns_analyse = ['F', 's_hor_sum', 's_hor_1', 's_hor_2'] + + self.number_of_load_cycles_for_analysis = 5 + + self.encoding = 'latin-1' + + self.roundtemperature = False + + def _define_units(self): + self.unit_s = 1 / 1000. #mm + self.unit_F = 1.0 #N + self.unit_t = 1. #s + + def _read_data(self, skiprows=0): + """ + read data + """ + + meta, data = read_geosys(self.file, '015') + + #BUG: set frequenzy from filename + data['f'] = self.frequency + data['sigma'] = self.sigma + data['T'] = self.temperature + + #define in class + self.meta = meta + self.data = data.reset_index() + return True + + def _standardize_data(self): + + colnames = list(self.data.columns) + + for i, col in enumerate(colnames): + if col == 'Zeit': + colnames[i] = 'time' + + elif col == 'Zyklenzähler': + colnames[i] = 'N' + + elif col == 'Kraft': + colnames[i] = 'F' + + elif col == 'Kolbenweg': + colnames[i] = 's_piston' + + elif col == 'Radialweg vorn': + colnames[i] = 's_hor_1' + elif col == 'Radialweg hinten': + colnames[i] = 's_hor_2' + + elif col == 'Radialweg Summe': + colnames[i] = 's_hor_sum' + + self.data.columns = colnames + + def _standardize_meta(self): + + keys = list(self.meta.keys()) + for key in keys: + if key == 'name': + self.meta['speciment'] = self.meta.pop(key) + elif key == 'h': + self.meta['speciment_height'] = self.meta.pop(key) + elif key == 'd': + self.meta['speciment_diameter'] = self.meta.pop(key) + + +class CittTestSchwerin(CittTest): + + def _set_parameter(self): + + self.split_data_based_on_parameter = ['T', 'f'] + + self.col_as_int = ['N'] + self.col_as_float = ['T', 'F', 'f', 's_vert_sum'] + + self.val_col_names = [ + 'time', 'T', 'f', 'N', 'F', 's_hor_sum', 's_hor_1', 's_hor_2' + ] + # Header names after standardization; check if exists + self.val_header_names = ['speciment_diameter'] + + self.columns_analyse = ['F', 's_hor_sum', 's_hor_1', 's_hor_2'] + + self.number_of_load_cycles_for_analysis = 5 + + self.encoding = 'latin-1' + + self.roundtemperature = False + + def _define_units(self): + self.unit_s = -1.0 #mm + self.unit_F = -1000.0 #N + self.unit_t = 1.0 + + def _read_data(self, skiprows=0): + """ + read data + """ + + data = pd.read_csv(self.file, + encoding=self.encoding, + skiprows=skiprows, + decimal='.', + sep=',') + + data['T'] = -999.0 # nicht in Daten enthalten + + #clean data + data = data.dropna(axis=1) + + data['f'] = self.frequency + data['sigma'] = self.sigma + + self.data = data + return True + + def _standardize_data(self): + + colnames = list(self.data.columns) + + for i, col in enumerate(colnames): + if col == 'Zeit s': + colnames[i] = 'time' + + elif col == 'AktTemper_°C_x10': + colnames[i] = 'T' + + elif col == 'FREQUENZ_x10': + colnames[i] = 'f' + + elif col == 'Zyklus': + colnames[i] = 'N' + + elif col == 'Weg mm': + colnames[i] = 's_piston' + + elif col == 'Kraft kN': + colnames[i] = 'F' + + elif col == 'Verformung1 mm': + colnames[i] = 's_hor_1' + elif col == 'Verformung2 mm': + colnames[i] = 's_hor_2' + + self.data.columns = colnames + + +class CittTestBAGKoeln(CittTest): + + def _set_parameter(self): + + self.split_data_based_on_parameter = ['T', 'f'] + + self.col_as_int = ['N'] + self.col_as_float = ['T', 'F', 'f', 's_vert_sum'] + + self.val_col_names = [ + 'time', 'T', 'f', 'N', 'F', 's_hor_sum', 's_hor_1', 's_hor_2' + ] + # Header names after standardization; check if exists + self.val_header_names = ['speciment_diameter'] + + self.columns_analyse = ['F', 's_hor_sum', 's_hor_1', 's_hor_2'] + + self.number_of_load_cycles_for_analysis = 5 + + self.encoding = 'latin-1' + + self.roundtemperature = False + + def _define_units(self): + self.unit_s = 1 / 10000. #mm + self.unit_F = 1 / 10.0 #N + self.unit_t = 1 / 1000.0 #s + self.unit_freq = 1 / 10. + + def _read_data(self, skiprows=0): + """ + read data + """ + + data = pd.read_csv(self.file, + encoding=self.encoding, + sep=';', + index_col=0) + + for col in data.columns: + data[col] = data[col].astype(float) + + data['sigma'] = self.sigma + + #define in class + self.data = data.reset_index() + return True + + def _standardize_data(self): + + colnames = list(self.data.columns) + + for i, col in enumerate(colnames): + if col == 'Zyklen': + colnames[i] = 'N' + + elif col == 'FREQUENZ_x10': + colnames[i] = 'f' + + elif col == 'Time_ms': + colnames[i] = 'time' + + elif col == 'AktTemper_°C_x10': + colnames[i] = 'T' + + elif col == 'Load_N_x10': + colnames[i] = 'F' + + elif col == 'POSITION_µm': + colnames[i] = 's_piston' + + elif col == 'SENSOR_EXT_µm_x10': + colnames[i] = 's_hor_1' + elif col == 'SENSOR_S4_µm_x10': + colnames[i] = 's_hor_2' + + elif col == 'Horizontalweg IWA Summe': + colnames[i] = 's_hor_sum' + + self.data.columns = colnames + + def _set_units(self): + + for col in ['s_hor_sum', 's_hor_1', 's_hor_2']: + self.data[col] = self.data[col].mul(self.unit_s) + + for col in ['F']: + self.data[col] = self.data[col].mul(self.unit_F) + + for col in ['time']: + self.data[col] = self.data[col].mul(self.unit_t) + + for col in ['f']: + self.data[col] = self.data[col].mul(self.unit_freq) + + return True + + +class CittTestBraunschweig(CittTest): + + def _set_parameter(self): + + self.split_data_based_on_parameter = ['T', 'f'] + + self.col_as_int = ['N'] + self.col_as_float = ['T', 'F', 'f', 's_vert_sum'] + + self.val_col_names = [ + 'time', 'T', 'f', 'N', 'F', 's_hor_sum', 's_hor_1', 's_hor_2' + ] + # Header names after standardization; check if exists + self.val_header_names = ['speciment_diameter'] + + self.columns_analyse = ['F', 's_hor_sum', 's_hor_1', 's_hor_2'] + + self.number_of_load_cycles_for_analysis = 5 + + self.encoding = 'latin-1' + + self.roundtemperature = False + + def _define_units(self): + self.unit_s = 1.0 #mm + self.unit_F = -1000.0 #N + self.unit_t = 1.0 + + def _read_data(self, skiprows=0): + """ + read data + """ + + head = pd.read_csv(self.file, + skiprows=14, + sep=';', + nrows=1, + encoding=self.encoding, + decimal=',', + thousands='.', + skip_blank_lines=True).columns + + head = [h.strip() for h in head] + + data = pd.read_csv(self.file, + skiprows=20, + sep=';', + encoding=self.encoding, + decimal=',', + thousands='.', + header=None, + skip_blank_lines=True) + + data.columns = head + + # add frequency + ## [start, ncycles] + sel = {0.1: [0, 11], 1.0: [11, 20], 5.0: [30, 100], 10: [130, 111]} + + N_f_dict = {} + + Ns = 0 + for freq in sel.keys(): + + par = sel[freq] + + N = par[0] + dN = par[1] + + for i in range(N, N + dN): + + N_f_dict[Ns] = freq + + Ns += 1 + + data['f'] = data['N'].replace(N_f_dict) + data = data[data['f'] <= 10.0] + + #sigma + data['sigma'] = self.sigma + data['T'] = self.temperature + + #clean data + data = data.dropna(axis=0) + data = data.dropna(axis=1) + + self.data = data + return True + + def _standardize_data(self): + + colnames = list(self.data.columns) + + for i, col in enumerate(colnames): + if col == 't [s]': + colnames[i] = 'time' + + elif col == 'FREQUENZ_x10': + colnames[i] = 'f' + + elif col == 's piston [mm]': + colnames[i] = 's_piston' + + elif col == 'F act [kN]': + colnames[i] = 'F' + + elif col == 'r 1A [mm]': + colnames[i] = 's_hor_1' + elif col == 'r 1B [mm]': + colnames[i] = 's_hor_2' + + self.data.columns = colnames diff --git a/src/pytestpavement/models/citt.py b/src/pytestpavement/models/citt.py index 3fd6589..693a018 100644 --- a/src/pytestpavement/models/citt.py +++ b/src/pytestpavement/models/citt.py @@ -2,6 +2,7 @@ import datetime from mongoengine import * +from .data import CITTSiffness from .material import Material @@ -41,40 +42,43 @@ class CITTSiffness(CyclicIndirectTensileTest): sigma_set = FloatField() T_set = FloatField() + N_from = IntField() + N_to = IntField() + + data = LazyReferenceField(CITTSiffness, + required=True, + reverse_delete_rule=CASCADE) + #results stiffness = FloatField() + nu = FloatField() + phase = FloatField() #fit parameter ## F - fit_a_F = FloatField() - fit_b_F = FloatField() - fit_d_F = FloatField() - fit_e_F = FloatField() - fit_f_F = FloatField() - r2_F = FloatField() + F_amp = FloatField() + F_freq = FloatField() + F_phase = FloatField() + F_offset = FloatField() + F_slope = FloatField() + F_r2 = FloatField() ## S1 - fit_a_s_hor_1 = FloatField() - fit_b_s_hor_1 = FloatField() - fit_d_s_hor_1 = FloatField() - fit_e_s_hor_1 = FloatField() - fit_f_s_hor_1 = FloatField() - r2_s_hor_1 = FloatField() + s_hor_1_amp = FloatField() + s_hor_1_freq = FloatField() + s_hor_1_phase = FloatField() + s_hor_1_offset = FloatField() + s_hor_1_slope = FloatField() + s_hor_1_r2 = FloatField() ## S2 - fit_a_s_hor_2 = FloatField() - fit_b_s_hor_2 = FloatField() - fit_d_s_hor_2 = FloatField() - fit_e_s_hor_2 = FloatField() - fit_f_s_hor_2 = FloatField() - r2_s_hor_2 = FloatField() + s_hor_2_amp = FloatField() + s_hor_2_freq = FloatField() + s_hor_2_phase = FloatField() + s_hor_2_offset = FloatField() + s_hor_2_slope = FloatField() + s_hor_2_r2 = FloatField() ## S-Sum - fit_a_s_hor_sum = FloatField() - fit_b_s_hor_sum = FloatField() - fit_d_s_hor_sum = FloatField() - fit_e_s_hor_sum = FloatField() - fit_f_s_hor_sum = FloatField() - r2_s_hor_sum = FloatField() - # data - time = ListField(FloatField()) - F = ListField(FloatField()) - N = ListField(IntField()) - s_hor_1 = ListField(FloatField()) - s_hor_2 = ListField(FloatField()) + s_hor_amp = FloatField() + s_hor_freq = FloatField() + s_hor_phase = FloatField() + s_hor_offset = FloatField() + s_hor_slope = FloatField() + s_hor_r2 = FloatField() diff --git a/src/pytestpavement/models/data.py b/src/pytestpavement/models/data.py index f422ae0..3c42c2a 100644 --- a/src/pytestpavement/models/data.py +++ b/src/pytestpavement/models/data.py @@ -31,3 +31,15 @@ class DataSheartest(RawData): s_vert_2 = ListField(FloatField()) s_vert_sum = ListField(FloatField()) s_piston = ListField(FloatField()) + + +class CITTSiffness(RawData): + + # data + time = ListField(FloatField()) + F = ListField(FloatField()) + N = ListField(IntField()) + s_hor_1 = ListField(FloatField()) + s_hor_2 = ListField(FloatField()) + s_hor_sum = ListField(FloatField()) + s_piston = ListField(FloatField(), required=False)