def __init__(self, signal, freq, file=False, filename=None, show_plot=False): self._y = signal self._freq = freq self._derivative = self._get_derivative(signal) if file: self.data = nk.eda_process(signal, sampling_rate=freq) if show_plot: nk.plot_events_in_signal(nk.z_score(self.data["df"]), self.data["EDA"]["SCR_Peaks_Indexes"]) print(self.data["EDA"]["SCR_Peaks_Indexes"]) plt.show() self.save_to_file(filename, self.data) else: self.data = self.read_from_file(filename)
def test_z_score(): raw_scores = [1, 1, 5, 2, 1] z = nk.z_score(raw_scores) assert int(z.values[3]) == 0
) # Plot it df.plot() plt.title('All the data ploted') plt.savefig('graphs/alldata') # Process the signals bio = nk.bio_process(ecg=df["ECG"], rsp=df["RSP"], eda=df["EDA"], add=df["Photosensor"], sampling_rate=100) # Plot the processed dataframe, normalizing all variables for viewing purpose nk.z_score(bio["df"]).plot() plt.title('Signals plotted') plt.savefig('graphs/signalsplot') # Get average quality print("AVG quality:") print(bio["ECG"]["Average_Signal_Quality"]) # Plot all the heart beats pd.DataFrame(bio["ECG"]["Cardiac_Cycles"]).plot(legend=False) plt.title('Heart beats') plt.savefig('graphs/hbeats') # A large number of HRV indices can be found print("HRV indices: ") print(bio["ECG"]["HRV"])
# ## Extracting Features # To understand the ECG and RESP signals, we must extract some features out of them. I am using a package called NeuroKit that does exactly that. It extracts information from the ECG and respiration signals to obtain simple values like heart rate, and heart beat positions. It also extracts some more complex values like Respiratory Sinus Arrhythmia, which is a naturally occurring variation in heart rate that occurs during a breathing cycle (inhalation and exhalation). This variation is directly affected by the autonomic nervous system, and thus, by measuring this variation of the heart rate during stress and non-stress conditions, we can capture useful information in classifying the two states. # # To see which data is most useful, I have plotted it for all the subjects and analyzed all the features, as well as gotten their standard deviations and other metrics for analysis. For brevity, I have kept some findings for one subject and have only kept a few example plots that make it easy to visualize the type of things I was looking for in the features. # In[353]: # Process Example ECG Signals for Visual Analysis i = 1 bio = nk.bio_process(ecg=df_respiban[i][:]['ECG'],rsp=df_respiban[i][:]['RESP'], ecg_quality_model=None, ecg_filter_frequency=[1,35], sampling_rate=100) # Plot the processed dataframe, normalizing all variables for viewing purpose nk.z_score(bio["df"][1000:-1000]).plot() plt.show() # In[551]: nk.z_score(bio["df"][["ECG_Filtered", "RSP_Filtered", "RSA"]])[1000:2500].plot() plt.show() # In[552]: rsa_values = [0,0] for i in range(1,2):
def eda_ERP(epoch, event_length, sampling_rate=1000, window_post=4): """ Extract event-related EDA and Skin Conductance Response (SCR). Parameters ---------- epoch : pandas.DataFrame An epoch contains in the epochs dict returned by :function:`nk.create_epochs()` on dataframe returned by :function:`nk.bio_process()`. Index must range from -4s to +4s (relatively to event onset and end). event_length : int In seconds. sampling_rate : int Sampling rate (samples/second). window_post : float Post-stimulus window size (in seconds) to include eventual responses (usually 3 or 4). Returns ---------- SCR : dict Event-locked SCR response features. Example ---------- >>> import neurokit as nk >>> bio = nk.bio_process(eda=df["EDA"], add=df["Photosensor"]) >>> df = bio["df"] >>> events = nk.find_events(df["Photosensor"], cut="lower") >>> epochs = nk.create_epochs(df, events["onsets"], duration=events["durations"]+8000, onset=-4000) >>> for epoch in epochs: >>> SCR = nk.eda_eventlocked_response(epoch, event_length=4000) Notes ---------- *Details* - **Looking for help**: *Experimental*: respiration artifacts correction needs to be implemented. - **EDA_Peak**: Max of EDA (in a window starting 1s after the stim onset) minus baseline. - **SCR_Amplitude**: Peak of SCR. If no SCR, returns NA. - **SCR_Magnitude**: Peak of SCR. If no SCR, returns 0. - **SCR_Amplitude_Log**: log of 1+amplitude. - **SCR_Magnitude_Log**: log of 1+magnitude. - **SCR_PeakTime**: Time of peak. - **SCR_Latency**: Time between stim onset and SCR onset. - **SCR_RiseTime**: Time between SCR onset and peak. - **SCR_Strength**: *Experimental*: peak divided by latency. *Authors* - Dominique Makowski (https://github.com/DominiqueMakowski) *Dependencies* - numpy - pandas *See Also* - https://www.biopac.com/wp-content/uploads/EDA-SCR-Analysis.pdf References ----------- - Schneider, R., Schmidt, S., Binder, M., Schäfer, F., & Walach, H. (2003). Respiration-related artifacts in EDA recordings: introducing a standardized method to overcome multiple interpretations. Psychological reports, 93(3), 907-920. """ # Initialization event_length = event_length/sampling_rate*1000 SCR = {} # Sanity check if epoch.index[-1]/sampling_rate*1000-event_length < 1000: print("NeuroKit Warning: eda_eventlocked_response(): your epoch only lasts for about %.2f s post stimulus. You might lose some SCRs." %((epoch.index[-1]/sampling_rate*1000-event_length)/1000)) if epoch.index[0]/sampling_rate*1000 > -3000: print("NeuroKit Warning: eda_eventlocked_response(): your epoch only starts %.2f s before the stimulus. Might induce some errors in artifacts correction." %((epoch.index[0]/sampling_rate*1000)/1000)) # EDA Based # ================= baseline = epoch["EDA_Filtered"].ix[0] eda_peak = epoch["EDA_Filtered"].ix[sampling_rate:event_length+window_post*sampling_rate].max() SCR["EDA_Peak"] = eda_peak - baseline # SCR Based # ================= # Very Basic Model # SCR["SCR_Amplitude_Basic"] = epoch["SCR_Peaks"].ix[100:event_length+4*sampling_rate].max() # if np.isnan(SCR["SCR_Amplitude_Basic"]): # SCR["SCR_Magnitude_Basic"] = 0 # else: # SCR["SCR_Magnitude_Basic"] = SCR["SCR_Amplitude_Basic"] # Model peak_onset = epoch["SCR_Onsets"].ix[0:event_length].idxmax() if pd.isnull(peak_onset) is False: SCR["SCR_Amplitude"] = epoch["SCR_Peaks"].ix[peak_onset:event_length+window_post*sampling_rate].max() peak_loc = epoch["SCR_Peaks"].ix[peak_onset:event_length+window_post*sampling_rate].idxmax() SCR["SCR_Magnitude"] = SCR["SCR_Amplitude"] if pd.isnull(SCR["SCR_Amplitude"]): SCR["SCR_Magnitude"] = 0 else: SCR["SCR_Amplitude"] = np.nan SCR["SCR_Magnitude"] = 0 # Log SCR["SCR_Amplitude_Log"] = np.log(1+SCR["SCR_Amplitude"]) SCR["SCR_Magnitude_Log"] = np.log(1+SCR["SCR_Magnitude"]) # Latency and Rise time if np.isfinite(SCR["SCR_Amplitude"]): peak_onset = epoch["SCR_Onsets"].ix[0:peak_loc].idxmax() SCR["SCR_PeakTime"] = peak_loc/sampling_rate*1000 SCR["SCR_Latency"] = peak_onset/sampling_rate*1000 SCR["SCR_RiseTime"] = (peak_loc - peak_onset)/sampling_rate*1000 else: SCR["SCR_PeakTime"] = np.nan SCR["SCR_Latency"] = np.nan SCR["SCR_RiseTime"] = np.nan SCR["SCR_Strength"] = SCR["SCR_Magnitude"]/(SCR["SCR_Latency"]/1000) # RSP Corrected # This needs to be done!! if "RSP_Filtered" in epoch.columns: # granger = statsmodels.tsa.stattools.grangercausalitytests(epoch[["EDA_Filtered", "RSP_Filtered"]], 10) RSP_z = nk.z_score(epoch["RSP_Filtered"]) RSP_peak = RSP_z.ix[:0].max() if np.isnan(RSP_peak[0]) and RSP_peak[0] > 1.96: SCR["SCR_Amplitude_RSP_Corrected"] = SCR["SCR_Amplitude"]/(RSP_peak-0.96) SCR["SCR_Magnitude_RSP_Corrected"] = SCR["SCR_Magnitude"]/(RSP_peak-0.96) else: SCR["SCR_Amplitude_RSP_Corrected"] = SCR["SCR_Amplitude"] SCR["SCR_Magnitude_RSP_Corrected"] = SCR["SCR_Magnitude"] return(SCR)
# #df = pd.concat(All, axis=0, ignore_index=True) #df.to_csv("cardiac_cycles.csv", index=False) df = pd.DataFrame.from_csv("cardiac_cycles.csv") #============================================================================== # Preprocessing #============================================================================== # Remove lines with NA df = df.dropna(axis=1) # Z score y = df.pop("Lead") df = nk.z_score(df.T).T X = np.array(df) X_train, X_test, y_train, y_test = sklearn.model_selection.train_test_split(X, y, test_size=0.33, random_state=666) ##============================================================================== ## Fit model ##============================================================================== model = sklearn.neural_network.MLPClassifier() # model.fit(X_train, y_train)
def test_z_score(self): raw_scores = [1, 1, 5, 2, 1] z = nk.z_score(raw_scores) self.assertEqual(int(z.values[3]), 0)
rri_new = scipy.interpolate.splev(x=np.arange(0, beat_time[-1], 1/sampling_rate), tck=spline, der=0) # plotting plt.figure(figsize=(20, 3), dpi=100) plt.scatter(np.arange(rri_new.shape[0]), rri_new,s=1) plt.grid(True) plt.title('RRI indexed per beat') plt.ylabel('RR interval duration (sec)') plt.xlabel('#beat') plt.tight_layout() plt.show() plt.figure(figsize=(20, 3), dpi=100) plt.plot(rri,'b-',linewidth=0.5) plt.grid(True) plt.title('Resampled RRI indexed per time') plt.ylabel('RR interval duration (sec)') plt.xlabel('Time (sec)') plt.tight_layout() plt.show() df=df["df"][["ECG_Filtered", "Heart_Rate"]] df["ECG_HRV"] = np.nan df["ECG_HRV"].ix[rpeaks[0]+1:rpeaks[0]+len(rri_new)] = rri_new nk.z_score(df).plot()