def getMinuteVentilation(peak_datastream: DataStream, valley_datastream: DataStream, window_size: float, window_offset: float): """ :param peak_datastream: DataStream :param valley_datastream: DataStream :return: respiration minute ventilation datastream """ peak_window_data = window_sliding(peak_datastream.data, window_size, window_offset) valley_window_data = window_sliding(valley_datastream.data, window_size, window_offset) minuteVentilation = [] for valley_key, valley_value in valley_window_data.items(): starttime, endtime = valley_key for peak_key, peak_value in peak_window_data.items(): if peak_key == valley_key: minuteVentilation.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=calculateMinuteVentilation( valley_value, peak_value))) datastream_minuteVentilation = DataStream.from_datastream( [valley_datastream]) datastream_minuteVentilation.data = minuteVentilation return datastream_minuteVentilation
def rsa_feature_computation(valleys_datastream: DataStream, rr_datastream: DataStream, window_size: float, window_offset: float ): """ :param rr_datastream: :param valleys_datastream: :param window_size: :param window_offset: :return: rsa_features computed over the given window """ if (valleys_datastream or rr_datastream) is None: return None if (len(valleys_datastream.data) or len(rr_datastream)) == 0: return None rsa_datastream = compute_datastream_rsa(valleys_datastream, rr_datastream) # perform windowing of rsa_datastream window_data = window_sliding(rsa_datastream.data, window_size, window_offset) # initialize each RSA feature RSA_Quartile_Deviation = [] RSA_Mean = [] RSA_Median = [] RSA_80thPercentile = [] # iterate over each window and calculate features for key, value in window_data.items(): starttime, endtime = key rsa = np.array([i.sample for i in value]) RSA_Quartile_Deviation.append(DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=(0.5 * ( np.percentile(rsa, 75) - np.percentile( rsa, 25))))) RSA_80thPercentile.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=np.percentile(rsa, 80))) RSA_Mean.append(DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=np.mean(rsa))) RSA_Median.append(DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=np.median(rsa))) rsa_mean = DataStream.from_datastream([valleys_datastream]) rsa_mean.data = RSA_Mean rsa_median = DataStream.from_datastream([valleys_datastream]) rsa_median.data = RSA_Median rsa_quartile = DataStream.from_datastream([valleys_datastream]) rsa_quartile.data = RSA_Quartile_Deviation rsa_80 = DataStream.from_datastream([valleys_datastream]) rsa_80.data = RSA_80thPercentile return rsa_mean, rsa_median, rsa_quartile, rsa_80
def test_heart_rate_power(self): window_data = window_sliding(self.rr_intervals.data, window_size=120, window_offset=60) test_window = list(window_data.items())[0] power, frequency_range = lomb(test_window[1], low_frequency=0.01, high_frequency=0.7) hr_hf = heart_rate_power(power, frequency_range, 0.15, 0.4) self.assertAlmostEqual(hr_hf, 14.143026468160871, delta=0.01)
def test_lomb(self): window_data = window_sliding(self.rr_intervals.data, window_size=120, window_offset=60) test_window = list(window_data.items())[0] result, frequency_range = lomb(test_window[1], low_frequency=0.01, high_frequency=0.7) self.assertAlmostEqual(result[0], 37.093948304468618, delta=0.01) self.assertEqual(frequency_range[-1], 0.7)
def test_Window_Valid(self): data = [] for i in range(0, 100): data.append( DataPoint.from_tuple(datetime.now(tz=self.timezone), None, random())) sleep(0.01) self.assertEqual(100, len(data)) result = window_sliding(data, window_size=0.25, window_offset=0.05) # TODO: check results of function output self.assertIsInstance(result, OrderedDict)
def getBasicStatistics(datastream: DataStream, window_size: float, window_offset: float): """ Computes mean, median, 80th percentile, and quartile deviation of datastream :param datastream: DataStream :return: mean, median, 80th percentile, and quartile deviation DataStreams of datastream """ # perform windowing of datastream window_data = window_sliding(datastream.data, window_size, window_offset) datastream_mean_data = [] datastream_median_data = [] datastream_80percentile_data = [] datastream_quartile_deviation_data = [] for key, value in window_data.items(): starttime, endtime = key reference_data = np.array([i.sample for i in value]) datastream_mean_data.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=np.mean(reference_data))) datastream_median_data.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=np.median(reference_data))) datastream_quartile_deviation_data.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=(0.5 * (np.percentile(reference_data, 75) - np.percentile(reference_data, 25))))) datastream_80percentile_data.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=np.percentile(reference_data, 80))) datastream_mean = DataStream.from_datastream([datastream]) datastream_mean.data = datastream_mean_data datastream_median = DataStream.from_datastream([datastream]) datastream_median.data = datastream_median_data datastream_quartile = DataStream.from_datastream([datastream]) datastream_quartile.data = datastream_quartile_deviation_data datastream_80 = DataStream.from_datastream([datastream]) datastream_80.data = datastream_80percentile_data return datastream_mean, datastream_median, datastream_quartile, datastream_80
def getBreathRate(datastream: DataStream, window_size: float, window_offset: float): """ Computes breath rate :param datastream: DataStream :return: breathing rate per minute datastream """ window_data = window_sliding(datastream.data, window_size, window_offset) breath_rates = [] for key, value in window_data.items(): starttime, endtime = key totalCycle = len(value) breath_rates.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=totalCycle)) datastream_breath_rates = DataStream.from_datastream([datastream]) datastream_breath_rates.data = breath_rates return datastream_breath_rates
def ecg_feature_computation(datastream: DataStream, window_size: float, window_offset: float, low_frequency: float = 0.01, high_frequency: float = 0.7, low_rate_vlf: float = 0.0009, high_rate_vlf: float = 0.04, low_rate_hf: float = 0.15, high_rate_hf: float = 0.4, low_rate_lf: float = 0.04, high_rate_lf: float = 0.15): """ ECG Feature Implementation. The frequency ranges for High, Low and Very low heart rate variability values are derived from the following paper: 'Heart rate variability: standards of measurement, physiological interpretation and clinical use' :param high_rate_lf: float :param low_rate_lf: float :param high_rate_hf: float :param low_rate_hf: float :param high_rate_vlf: float :param low_rate_vlf: float :param high_frequency: float :param low_frequency: float :param datastream: DataStream :param window_size: float :param window_offset: float :return: ECG Feature DataStreams """ if datastream is None: return None if len(datastream.data) == 0: return None # perform windowing of datastream window_data = window_sliding(datastream.data, window_size, window_offset) # initialize each ecg feature array rr_variance_data = [] rr_mean_data = [] rr_median_data = [] rr_80percentile_data = [] rr_20percentile_data = [] rr_quartile_deviation_data = [] rr_HF_data = [] rr_LF_data = [] rr_VLF_data = [] rr_LF_HF_data = [] rr_heart_rate_data = [] # iterate over each window and calculate features for key, value in window_data.items(): starttime, endtime = key reference_data = np.array([i.sample for i in value]) rr_variance_data.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=np.var(reference_data))) power, frequency = lomb(data=value, low_frequency=low_frequency, high_frequency=high_frequency) rr_VLF_data.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=heart_rate_power( power, frequency, low_rate_vlf, high_rate_vlf))) rr_HF_data.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=heart_rate_power( power, frequency, low_rate_hf, high_rate_hf))) rr_LF_data.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=heart_rate_power( power, frequency, low_rate_lf, high_rate_lf))) if heart_rate_power(power, frequency, low_rate_hf, high_rate_hf) != 0: lf_hf = float( heart_rate_power(power, frequency, low_rate_lf, high_rate_lf) / heart_rate_power(power, frequency, low_rate_hf, high_rate_hf)) rr_LF_HF_data.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=lf_hf)) else: rr_LF_HF_data.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=0)) rr_mean_data.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=np.mean(reference_data))) rr_median_data.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=np.median(reference_data))) rr_quartile_deviation_data.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=(0.5 * (np.percentile(reference_data, 75) - np.percentile(reference_data, 25))))) rr_80percentile_data.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=np.percentile(reference_data, 80))) rr_20percentile_data.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=np.percentile(reference_data, 20))) rr_heart_rate_data.append( DataPoint.from_tuple(start_time=starttime, end_time=endtime, sample=np.median(60 / reference_data))) rr_variance = DataStream.from_datastream([datastream]) rr_variance.data = rr_variance_data rr_vlf = DataStream.from_datastream([datastream]) rr_vlf.data = rr_VLF_data rr_hf = DataStream.from_datastream([datastream]) rr_hf.data = rr_HF_data rr_lf = DataStream.from_datastream([datastream]) rr_lf.data = rr_LF_data rr_lf_hf = DataStream.from_datastream([datastream]) rr_lf_hf.data = rr_LF_HF_data rr_mean = DataStream.from_datastream([datastream]) rr_mean.data = rr_mean_data rr_median = DataStream.from_datastream([datastream]) rr_median.data = rr_median_data rr_quartile = DataStream.from_datastream([datastream]) rr_quartile.data = rr_quartile_deviation_data rr_80 = DataStream.from_datastream([datastream]) rr_80.data = rr_80percentile_data rr_20 = DataStream.from_datastream([datastream]) rr_20.data = rr_20percentile_data rr_heart_rate = DataStream.from_datastream([datastream]) rr_heart_rate.data = rr_heart_rate_data return rr_variance, rr_vlf, rr_hf, rr_lf, rr_lf_hf, rr_mean, rr_median, rr_quartile, rr_80, rr_20, rr_heart_rate