Skip to content

Instantly share code, notes, and snippets.

@peisenhower
Last active May 1, 2017 13:50
Show Gist options
  • Save peisenhower/791e2bb7a29950003435c4eaf9abb881 to your computer and use it in GitHub Desktop.
Save peisenhower/791e2bb7a29950003435c4eaf9abb881 to your computer and use it in GitHub Desktop.
Three9 Calibration Code in Python
import matplotlib.pyplot as plt
import numpy as np
import scipy.io as sio
import scipy.signal as ssi
import peakutils
import pprint as pp
import itertools
import argparse
import warnings
# matplotlib uses some deprciated code that causes warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
class DataSet:
def __init__(self, path):
data = sio.loadmat(path)
self.path = path
self.time = data['Time_Sec']
self.well = [None] * 9
self.well[0] = data['Trace_101_C']
self.well[1] = data['Trace_102_C']
self.well[2] = data['Trace_103_C']
self.well[3] = data['Trace_104_C']
self.well[4] = data['Trace_105_C']
self.well[5] = data['Trace_106_C']
self.well[6] = data['Trace_107_C']
self.well[7] = data['Trace_108_C']
self.well[8] = data['Trace_109_C']
class LinearCalibration:
def __init__(self, gain, offset):
self.gain = gain
self.offset = offset
class Index:
def __init__(self, start, end):
self.start = int(start)
self.end = int(end)
def apply(self, step_data):
subset = step_data[self.start:self.end]
self.value = float(sum(subset)/float(len(subset)))
return self.value
def as_array(self):
return [self.start, self.end]
class Well:
def __init__(self, well, value):
self.well = well;
key = range(40, 40 + (len(value) * 10), 10)
self.actual = dict(zip(key, value))
self.error = list(map(float.__sub__, value, key))
def linear_calibration(self, points):
subset = [
self.actual[points[0]],
self.actual[points[1]],
]
gain, offset = np.polyfit(points, subset, 1)
self.calibration = LinearCalibration(gain, offset)
return self.calibration
def plot_error(wells):
plt.figure()
plt.xlabel('Setpoint (C)')
plt.ylabel('Error To Setpoint (C)')
plt.title('Uncalibrated Error')
plt.grid(True)
plt.ylim([-4.0, 1.0])
for w in wells:
setpoint = list(w.actual.keys())
plt.plot(setpoint, w.error, label=str(w.well))
def find_steps(data, plot_it=False):
dy = np.diff(data, axis = 0)
# Make this not some weird dimension array
dy = dy[:,0]
indexes = peakutils.indexes(dy, thres=0.5, min_dist=20)
accumulator = 0
for i in range(len(indexes) - 1):
accumulator = accumulator + (indexes[i + 1] - indexes[i])
peak_distance = accumulator / (len(indexes) - 1)
shift = int(peak_distance * 0.6)
delta = int(peak_distance * 0.15)
shifted = list(map(lambda x: int(x + shift), indexes))
result = list(map(lambda x: Index(x - delta, x + delta), shifted))
if plot_it:
#flatten to a single array
index_simple = list(map(lambda x: x.as_array(), result))
marks = list(itertools.chain(*index_simple))
# Step Plot
plt.figure()
plt.plot(range(0, len(data)), data, '-bD', markevery=marks)
plt.xlabel('time (s)')
plt.ylabel('Temperature (C)')
plt.title('Uncalibrated Step')
plt.grid(True)
# Derivative Plot
plt.figure()
plt.plot(range(0, len(dy)), dy, '-bD', markevery=indexes)
plt.xlabel('time (s)')
plt.ylabel('Derivitive of Temp (C)')
plt.title('1st Derivative')
return result
def build_wells(data_set, indexes):
result = []
for count,w in enumerate(data_set.well):
well_actual = []
for i in indexes:
well_actual.append(i.apply(w))
well = Well(count, well_actual)
result.append(well)
return result
def get_options():
parser = argparse.ArgumentParser(description='Calculate Calbiration Values')
parser.add_argument('files', type=str, nargs='+',
help='mat files to calculation')
parser.add_argument('--plot', '-p',
help='show plotted data', action='store_true', default=False)
return parser.parse_args()
if __name__ == "__main__":
options = get_options()
if options.files is None:
options.files = ['meatwad-b-step.mat']
for file in options.files:
data = DataSet(file)
index = find_steps(data.well[0], plot_it=options.plot)
wells = build_wells(data, index)
plot_error(wells)
print('\r\nFound Values:')
for w in wells:
value_string = ' '.join(map(lambda x: '{:3.3f}'.format(x), w.actual.values()))
print('\tWell:{} Value:{}'.format(w.well, value_string))
error_string = ' '.join(map(lambda x: '{:3.3f}'.format(x), w.error))
print('\tWell:{} Error:{}'.format(w.well, error_string))
print()
print('\r\n\r\nDevice Calibration Values:')
for w in wells:
cal = w.linear_calibration([60,100])
print('\tWell:{} Gain:{:f} Offset:{:f}'.format(w.well, cal.gain, cal.offset))
print('\r\n\r\nCalibration Commands:')
for w in wells:
cal = w.linear_calibration([60,100])
print('\tpersist cal {} {:0.6f} {:0.6f}'.format(w.well, cal.gain, cal.offset))
print('\tpersist store')
if options.plot:
plt.show()
python calibration.py meatwad-b-step.mat -p
Found Values:
Well:0 Value:38.850 48.803 59.142 69.136 78.609 88.141 98.259
Well:0 Error:-1.150 -1.197 -0.858 -0.864 -1.391 -1.859 -1.741
Well:1 Value:39.007 49.009 59.336 69.263 78.774 88.294 98.330
Well:1 Error:-0.993 -0.991 -0.664 -0.737 -1.226 -1.706 -1.670
Well:2 Value:39.041 49.025 59.376 69.307 78.866 88.384 98.378
Well:2 Error:-0.959 -0.975 -0.624 -0.693 -1.134 -1.616 -1.622
Well:3 Value:38.928 48.867 59.204 69.162 78.580 88.085 98.095
Well:3 Error:-1.072 -1.133 -0.796 -0.838 -1.420 -1.915 -1.905
Well:4 Value:38.884 48.934 59.252 69.236 78.705 88.261 98.238
Well:4 Error:-1.116 -1.066 -0.748 -0.764 -1.295 -1.739 -1.762
Well:5 Value:39.091 48.981 59.332 69.290 78.764 88.278 98.365
Well:5 Error:-0.909 -1.019 -0.668 -0.710 -1.236 -1.722 -1.635
Well:6 Value:39.054 49.003 59.343 69.315 78.799 88.311 98.388
Well:6 Error:-0.946 -0.997 -0.657 -0.685 -1.201 -1.689 -1.612
Well:7 Value:39.038 49.068 59.418 69.363 78.891 88.386 98.551
Well:7 Error:-0.962 -0.932 -0.582 -0.637 -1.109 -1.614 -1.449
Well:8 Value:38.787 48.717 59.038 68.910 78.401 87.829 97.966
Well:8 Error:-1.213 -1.283 -0.962 -1.090 -1.599 -2.171 -2.034
Device Calibration Values:
Well:0 Gain:1.022078 Offset:-0.467067
Well:1 Gain:1.025166 Offset:-0.846395
Well:2 Gain:1.024954 Offset:-0.873121
Well:3 Gain:1.027723 Offset:-0.867316
Well:4 Gain:1.025352 Offset:-0.773544
Well:5 Gain:1.024163 Offset:-0.781837
Well:6 Gain:1.023880 Offset:-0.775525
Well:7 Gain:1.021675 Offset:-0.718432
Well:8 Gain:1.026799 Offset:-0.645534
Calibration Commands:
persist cal 0 1.022078 -0.467067
persist cal 1 1.025166 -0.846395
persist cal 2 1.024954 -0.873121
persist cal 3 1.027723 -0.867316
persist cal 4 1.025352 -0.773544
persist cal 5 1.024163 -0.781837
persist cal 6 1.023880 -0.775525
persist cal 7 1.021675 -0.718432
persist cal 8 1.026799 -0.645534
persist store
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment