Source code for soa.analyse

import numpy as np
import matplotlib.pyplot as plt

[docs]class ResponseMeasurements: def __init__(self,signal,t,gradientPoints=8,percentage=5,hopSize=1,SP=None): """ 60 points: gradientPoints=8 240 points: gradientPoints=8 1350 points: gradientPoints=50 """ self.signal = signal self.t = t self.gradientPoints = gradientPoints self.percentage = percentage/100 self.hopSize = hopSize self.dt = abs(self.t[len(self.t)-1] - self.t[len(self.t)-2]) self.SP = SP # (optional) provide SP to compare signal to # num points from end to start measuring high ss (approx 30 for 240 pt signal): self.start_measurement_index = int(0.125 * len(self.signal)) # num points from end to stop measuring high ss (approx 20 for 240 pt signal): self.end_measurement_index = int(0.08333 * len(self.signal)) self.__getMeasurements() def __getMeasurements(self): self.__getInflectionTimeIndex() self.__getSettlingMaxIndex() self.__getSettlingTimeIndex() self.__getSSHighValue() self.__getSSLowValue() self.__getSP() self.__getRiseTime() self.__getOvershoot() def __getSP(self): self.sp = SetPoint(self) def __getInflectionTimeIndex(self): if self.SP is None: grad = [] n = len(self.signal) for i in range(n): if i + self.gradientPoints < n: grad.append(abs(self.signal[i] \ - self.signal[i+self.gradientPoints])) else: break self.inflectionTimeIndex = np.argmax(grad) else: # SP is provided for index in range(0, len(self.SP)): if self.SP[index] > self.SP[0]: self.inflectionTimeIndex = index break def __getSettlingMaxIndex(self): self.settlingMaxIndex = np.argmax(self.signal) def __getSettlingTimeIndex(self): if self.SP is None: # don't have reference SP ss_high = self.signal[self.settlingMaxIndex] n = len(self.signal) signal_end = np.mean(self.signal[len(self.signal)-\ self.start_measurement_index:len(self.signal)-\ self.end_measurement_index]) for i in range(0, len(self.signal)-self.start_measurement_index): if np.max(abs(np.asarray(self.signal[i:len(self.signal)-\ self.end_measurement_index]) - \ signal_end)) <= self.percentage * signal_end: self.settlingTimeIndex = i self.settlingTime = (i-self.inflectionTimeIndex)*abs(self.t[0] -\ self.t[1]) break else: self.settlingTimeIndex = len(self.signal) \ - self.start_measurement_index self.settlingTime = self.t[-1] # signal never settles if self.settlingTime < 0: # signal is unrecognisable/not a step therefore cannot have settled self.settlingTimeIndex = len(self.signal) \ - self.start_measurement_index self.settlingTime = self.t[-1] # signal never settles else: # SP is provided n = len(self.signal) signal_end = self.SP[-1] for i in range(0, len(self.signal)-self.start_measurement_index): if np.max(abs(np.asarray(self.signal[i:len(self.signal)-\ self.end_measurement_index]) \ - signal_end)) <= self.percentage * signal_end: self.settlingTimeIndex = i self.settlingTime = (i-self.inflectionTimeIndex)*abs(self.t[0] \ - self.t[1]) break else: self.settlingTimeIndex = len(self.signal) \ - self.start_measurement_index self.settlingTime = self.t[-1] # signal never settles if self.settlingTime < 0: # signal is unrecognisable/not a step therefore cannot have settled self.settlingTimeIndex = len(self.signal) \ - self.start_measurement_index self.settlingTime = self.t[-1] # signal never settles def __getSSHighValue(self): if self.SP is None: self.SSHighValue = np.mean(self.signal[len(self.signal)\ -self.start_measurement_index:len(self.signal)\ -self.end_measurement_index]) else: self.SSHighValue = self.SP[-1] def __getSSLowValue(self): if self.SP is None: self.SSLowValue = np.mean(self.signal[:self.inflectionTimeIndex]) else: self.SSLowValue = self.SP[0] def __getRiseTime(self): off_set = self.sp.sp[0] # get amount signal is offset from 0 by i=self.inflectionTimeIndex prev_diff = abs((self.signal.copy()[i]-off_set) \ - (((self.SSHighValue-off_set)*0.1))) curr_diff = abs((self.signal.copy()[i+1]-off_set) \ - (((self.SSHighValue-off_set)*0.1))) while curr_diff < prev_diff: prev_diff = abs((self.signal.copy()[i]-off_set) \ - (((self.SSHighValue-off_set)*0.1))) curr_diff = abs((self.signal.copy()[i+1]-off_set) \ - (((self.SSHighValue-off_set)*0.1))) i += 1 if i == len(self.signal)-2: break self.idxTen = i-1 i=self.inflectionTimeIndex prev_diff = abs((self.signal.copy()[i]-off_set) \ - (((self.SSHighValue-off_set)*0.9))) curr_diff = abs((self.signal.copy()[i+1]-off_set) \ - (((self.SSHighValue-off_set)*0.9))) while curr_diff < prev_diff: prev_diff = abs((self.signal.copy()[i]-off_set) \ - (((self.SSHighValue-off_set)*0.9))) curr_diff = abs((self.signal.copy()[i+1]-off_set) \ - (((self.SSHighValue-off_set)*0.9))) i += 1 if i == len(self.signal)-2: break self.idxNinety = i-1 timeTen = self.t[self.idxTen] timeNinety = self.t[self.idxNinety] self.riseTime = (timeNinety - timeTen) if self.idxTen == self.idxNinety: # signal never rose self.riseTime = 1000 def __getOvershoot(self): self.overshoot = abs(float((self.signal[self.settlingMaxIndex] \ - self.SSHighValue)/self.SSHighValue))
[docs]class SetPoint: def __init__(self,response): self.response = response self.__getSetPoint() def __getSetPoint(self): self.sp = np.zeros(len(self.response.signal)) self.inflectionTimeIndex = self.response.inflectionTimeIndex self.sp[:self.inflectionTimeIndex] = self.response.SSLowValue self.sp[self.inflectionTimeIndex:] = self.response.SSHighValue