Source code for pebm.ebm.fecgyn_tgen

import numpy as np
import scipy

#matlab function by Joachim Bahar, translated to python by Sheina Gendelman

[docs]def fecgyn_tgen(ecg, qrs, fs): #consts n_samples = len(ecg) PI = np.pi start_cycle = 1 n_bins = 250 Th = 0.9 MIN_TRESH = 0.6 nc_relev_mode =0 MIN_nc = 30 n_modes = 1 PACE = 0.1 n_rel = 10 MIN_TLEN = 0.35 template= {} ## calc phase phase = np.zeros([n_samples]) m = np.diff(qrs) L = qrs[0] if m is None: phase[0:(n_samples-1)] = np.linspace(-2*PI, 2*PI, n_samples) else: phase[0:L] = np.linspace(2*PI-L*2*PI/m[0], 2*PI, L) for i in range(0,len(qrs)-1): phase[qrs[i]-1:qrs[i+1]] = np.linspace(0, 2*PI, m[i]+1) L = n_samples - qrs[-1] phase[qrs[-1]-1:] = np.linspace(0, L*2*PI/m[-1], L+1) phase = np.mod(phase, 2*PI) phase[phase > PI] = phase[phase > PI]-2*PI #### phase_change_points = np.asarray(np.where((phase[1:] < 0) & (phase[:-1] > 0))).squeeze() n_cycles = len(phase_change_points) cycle_index = np.arange(phase_change_points[start_cycle]+1, phase_change_points[start_cycle+1]+1) cycle_f = scipy.interpolate.splrep(phase[cycle_index], ecg[cycle_index]) cycle = np.expand_dims(scipy.interpolate.splev(np.linspace(-PI, PI, n_bins), cycle_f), 1) Mode = {'cycles': {1: cycle}, 'mean_cycle': {1: cycle}, 'std_cycle': {1: np.zeros([1,n_bins])}, 'nc': {1: 1}, 'cycle_len': {1: len(cycle_index)}} while (nc_relev_mode < MIN_nc) & (Th> MIN_TRESH): for i in range(start_cycle+1, n_cycles-2): cycle_index = np.arange(phase_change_points[i] + 1, phase_change_points[i + 1] + 1) cycle_f = scipy.interpolate.splrep(phase[cycle_index], ecg[cycle_index]) cycle = np.expand_dims(scipy.interpolate.splev(np.linspace(-PI, PI, n_bins), cycle_f), 1) match = 0 ind_mode = 1 while (not match) & (ind_mode <= n_modes): coeff = np.corrcoef(cycle.squeeze(), Mode['mean_cycle'][ind_mode].squeeze()) coeff_m = np.amax(coeff.flatten())##why?? match = coeff_m > Th ind_mode = ind_mode +1 if not match: n_modes = n_modes +1 Mode['cycles'][n_modes] = cycle Mode['mean_cycle'][n_modes] = cycle Mode['std_cycle'][n_modes] = np.zeros([1, n_bins]) Mode['nc'][n_modes] = 1 Mode['cycle_len'][n_modes] = len(cycle_index) else: Mode['cycles'][ind_mode - 1] = np.concatenate((Mode['cycles'][ind_mode - 1], cycle), axis=1) Mode['mean_cycle'][ind_mode - 1] = np.mean(Mode['cycles'][ind_mode - 1], axis =1) Mode['std_cycle'][ind_mode - 1] = np.std(Mode['cycles'][ind_mode - 1], axis =1) Mode['nc'][ind_mode - 1] = Mode['nc'][ind_mode - 1] + 1 Mode['cycle_len'][ind_mode - 1] = np.hstack((Mode['cycle_len'][ind_mode - 1], len(cycle_index))) rel_mode_ind = [] for i in Mode['nc']: if (Mode['nc'][i] > n_rel) & (np.mean(Mode['cycle_len'][i]) >= MIN_TLEN*fs): rel_mode_ind.append(i) if not len(rel_mode_ind): template['avg'] = None template['std'] = None else: max_ind = max(Mode['nc'], key=Mode['nc'].get) des1 = int(np.round(n_bins/6)) template['avg'] = np.roll(Mode['mean_cycle'][max_ind], -des1) template['std'] = np.roll(Mode['std_cycle'][max_ind], -des1) mean_cycle_len = sum(Mode['cycle_len'][max_ind])/len(Mode['cycle_len'][max_ind]) template['avg'] = scipy.signal.resample(template['avg'], int(np.round(mean_cycle_len))) template['std'] = scipy.signal.resample(template['std'], int(np.round(mean_cycle_len))) Th = Th - PACE return template