Last active
May 1, 2017 13:50
-
-
Save peisenhower/791e2bb7a29950003435c4eaf9abb881 to your computer and use it in GitHub Desktop.
Three9 Calibration Code in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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