Commit c869694e authored by Michael Rudolf's avatar Michael Rudolf
Browse files

Added Manual Picking\n - Currently independent from the rest of the scripts\n...

Added Manual Picking\n  - Currently independent from the rest of the scripts\n  - Manual selection of peaks, for cross-checking the automatic picks
parent 4260ec45
# Manual Picking Algorithm
This module allows for a manual picking of ring shear tester data. Currently, it is independent of RSTanalysis and RSTpicking, but is going to be incorporated into the functionality of these scripts.
## How to run:
1. Run `python3 manual_pick.py`.
- This should open a directory selection dialog.
2. Navigate to the folder where the `*.tdms` files are located.
- Be sure that only the needed files are there, e.g. that there is no velocity stepping file in the same folder.
3. The script iterates over all files in the folder and displays them.
4. Manually pick the peaks as advised in the plot.
- It automatically should display the picked value as horizontal line in the plot.
5. When you're done picking, the picks are stored in the same folder as a binary `*.h5`-file and a ascii-type `*.csv`-file.
6. For doing the Mohr-Coulomb analysis run `python3 evaluate_picks.py`.
7. Navigate to the previously generated `picks.h5`.
- This does a linear regression of the picks together with a bootstrap error analysis.
- The figure is displayed and output as a `*.png` to the same folder.
8. Stop the execution of the script by pressing ENTER to exit.
#!/usr/bin/env python3
import h5py
import matplotlib as mpl
import nptdms
import numpy as np
import os
import time
import tkinter as tk
from matplotlib import pyplot as plt
from scipy import optimize
from tkinter import filedialog
import rstmanpick as rmp
root = tk.Tk()
root.withdraw()
f_path = filedialog.askopenfilename(filetypes=[('HDF5-Files', '*.h5')])
# f_path = 'C:/Users/M.Rudolf/ownCloud/DocStelle/GitRepos/rst-evaluation/Data/'
# f_path = '/home/mrudolf/ownCloud/DocStelle/GitRepos/rst-evaluation/Data/'
with h5py.File(f_path, 'r') as f:
dyna = f['dynamic'][()]
norm = f['normal'][()]
peak = f['peak'][()]
stat = f['static'][()]
norm = np.round(norm/500)*500
print('Rounded normal stress to 500 Pa steps!')
print(np.sort(np.unique(norm)))
fit_list = ['peak', 'dynamic', 'static']
fit_var = {'peak': peak, 'dynamic': dyna, 'static': stat}
coloring = mpl.cm.Paired(range(6))
popt = dict()
pcov = dict()
fig, ax = plt.subplots()
k = 0
for fit in fit_list:
popt[fit], pcov[fit] = rmp.fit_bootstrap([0.5, 0],
norm,
fit_var[fit],
rmp.poly1)
ax.plot(norm, fit_var[fit], 's', label=fit, color=coloring[k+1])
ax.plot(norm, rmp.poly1(norm, *popt[fit]),
label='$\mu$=%.2f$\pm$%.2f, C=%.0f$\pm$%.0f Pa'
% tuple([popt[fit][0],
rmp.round_sig_digs(pcov[fit][0], -2),
popt[fit][1],
rmp.round_sig_digs(pcov[fit][1], 0)]),
color=coloring[k])
k += 2
ax.set_ylabel('shear stress (Pa)')
ax.set_xlabel('normal stress (Pa)')
ax.legend()
ax.set_title('Mohr-Coulomb criterion for Picks')
ax.set_xlim(0,)
ax.set_ylim(0,)
ax.text(16000, 100,
'Fit with least squares using a bootstrap method with 100 sets',
horizontalalignment='right',
fontstyle='italic')
fig.canvas.draw()
fig.savefig(f_path.replace('.h5', ''))
plt.show(block=False)
input("Press ENTER to exit")
#!/usr/bin/env python3
import h5py
import matplotlib as mpl
import nptdms
import numpy as np
import os
import time
import tkinter as tk
from matplotlib import pyplot as plt
from scipy import optimize
from tkinter import filedialog
import rstmanpick as rmp
root = tk.Tk()
root.withdraw()
f_path = filedialog.askdirectory()
# f_path = 'C:/Users/M.Rudolf/ownCloud/DocStelle/GitRepos/rst-evaluation/Data/'
# f_path = '/home/mrudolf/ownCloud/DocStelle/GitRepos/rst-evaluation/Data/'
file_list = [f_path+'/'+f for f in os.listdir(f_path) if f.endswith('tdms')]
# preallocation
dyna = np.zeros(len(file_list))
norm = np.zeros(len(file_list))
peak = np.zeros(len(file_list))
stat = np.zeros(len(file_list))
# Loop over list of files
for f in enumerate(file_list):
exp = rmp.tdms_to_dict(f[1])
picks = rmp.picker_plot(exp)
dyna[f[0]] = rmp.force_2_stress(picks['dynamic'])
norm[f[0]] = picks['normal']/0.022619
peak[f[0]] = rmp.force_2_stress(picks['peak'])
stat[f[0]] = rmp.force_2_stress(picks['static'])
# Save into h5file
with h5py.File(f_path+'/'+'picks.h5', 'w') as f:
f.create_dataset('dynamic', data=dyna)
f.create_dataset('normal', data=norm)
f.create_dataset('peak', data=peak)
f.create_dataset('static', data=stat)
# Save to CSV-File
csv_matrix = np.rot90(np.asarray((stat, dyna, peak, norm)), 3)
np.savetxt(f_path+'/'+'picks.csv',
csv_matrix,
fmt='%.2f',
delimiter=';',
header='normal stress; peak; dynamic; static')
#!/usr/bin/env python3
'''
rstmanpick.py
Module containing the functions for manual picking of a ring-shear-tester
dataset.
__AUTHOR__: Michael Rudolf
__DATE__: 20-Feb-2019
'''
import h5py
import matplotlib as mpl
import nptdms
import numpy as np
import os
import time
from matplotlib import pyplot as plt
from scipy import optimize
# Public Functions
def tdms_to_dict(file_in):
''' Reads data from all channels in a TDMS file'''
file = nptdms.TdmsFile(file_in)
data = dict()
data['Time'] = file.group_channels('Untitled')[0].time_track()
for channel in file.group_channels('Untitled'):
channel_name = channel.path.replace('\'', '').split('/')[-1]
data[channel_name] = channel.data
return data
def force_2_stress(force):
'''
Converts force at the sensors to stress using the leverage principle given
for the testing machine in ASTM Standard D6773
'''
rs = 0.125 # m
rm = 0.0776 # m
ad = 0.022619 # m
stress = rs * force / (rm * ad) # Pa
return stress
def picker_plot(exp):
'''
Creates an interactive plot to pick the three important points for the RST
analysis
'''
# Create plot
norm_force = np.mean(exp['Normal Force'])
fig, ax = plt.subplots()
line, = ax.plot(exp['Time'], exp['Shear Force']/exp['Normal Force'])
ax.set_ylim(0, 1)
ax.set_xlim(np.min(exp['Time']), np.max(exp['Time']))
# List of peaks to pick
pick_list = ['peak', 'dynamic', 'static']
pick_string = {
'peak': 'Select Peak',
'dynamic': 'Select dynamic (steady state)',
'static': 'Select static (reactivation)'
}
pick_func = {
'peak': np.max,
'dynamic': np.median,
'static': np.max
}
col_list = ['r', 'y', 'b']
picks = dict()
# Loop which runs over all peak types
for pick, col in zip(pick_list, col_list):
ax.set_title(pick_string[pick])
sel_dat = _select_data(exp)
ax.plot(exp['Time'][sel_dat],
exp['Shear Force'][sel_dat]/norm_force,
color=col)
pdata = pick_func[pick](exp['Shear Force'][sel_dat])
ax.hlines(pdata/norm_force,
np.min(exp['Time']),
np.max(exp['Time']),
color=col)
picks[pick] = pdata
# Draw the figure again and wait 1 second before closing
fig.canvas.draw()
plt.show(block=False)
time.sleep(1)
plt.close()
picks['normal'] = norm_force
return picks
def fit_bootstrap(p0, datax, datay, function, yerr_systematic=0.0):
errfunc = lambda p, x, y: function(x, *p) - y
# Fit first time
pfit, perr = optimize.leastsq(errfunc,
p0,
args=(datax, datay),
full_output=0)
# Get the stdev of the residuals
residuals = errfunc(pfit, datax, datay)
sigma_res = np.std(residuals)
sigma_err_total = np.sqrt(sigma_res**2 + yerr_systematic**2)
# 100 random data sets are generated and fitted
ps = []
for i in range(100):
randomDelta = np.random.normal(0., sigma_err_total, len(datay))
randomdataY = datay + randomDelta
randomfit, randomcov = \
optimize.leastsq(errfunc, p0, args=(datax, randomdataY),
full_output=0)
ps.append(randomfit)
ps = np.array(ps)
mean_pfit = np.mean(ps, 0)
# You can choose the confidence interval that you want for your
# parameter estimates:
Nsigma = 2. # 1sigma gets approximately the same as methods above
# 1sigma corresponds to 68.3% confidence interval
# 2sigma corresponds to 95.44% confidence interval
err_pfit = Nsigma * np.std(ps, 0)
pfit_bootstrap = mean_pfit
perr_bootstrap = err_pfit
return pfit_bootstrap, perr_bootstrap
def round_sig_digs(num, digs, dir='up'):
def _up(num):
return np.ceil(num)
def _down(num):
return np.floor(num)
num = num/(10**digs)
diropts = {'up': _up, 'down': _down}
return diropts[dir](num)*(10**digs)
def poly1(x, a, b):
return a*x + b
# Internal Functions
def _select_data(exp):
selection = plt.ginput(1)
i = np.searchsorted(exp['Time'], selection[0], side='right')
set_slice = slice(i[0]-20, i[0]+20)
return set_slice
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment