Ejemplo n.º 1
0
    def getResults(self):
        global data, results, rpeaks, sample_rate
        if self.results_whole.isChecked():
            filt, rpeaks = ecg(signal=data,
                               sampling_rate=sample_rate,
                               show=False)[1:3]
            self.plotPeaks(data, rpeaks)
            rpeaks = rpeaks / sample_rate
            nni = tools.nn_intervals(rpeaks=rpeaks)
            results = hrv(nni=nni,
                          rpeaks=rpeaks,
                          sampling_rate=sample_rate,
                          interval=[0, int(len(data) / sample_rate)],
                          show=False)
            self.showPlots()

            self.time_domain_txt()
            s = str(folder + '/time_domain.txt')
            text = open(s).read()
            self.time_txt.setPlainText(text)

            self.freq_domain_txt()
            s = str(folder + '/frequency_domain.txt')
            text = open(s).read()
            self.freq_txt.setPlainText(text)

            self.nonlin_domain_txt()
            s = str(folder + '/nonlinear_domain.txt')
            text = open(s).read()
            self.nonlin_txt.setPlainText(text)

        elif self.results_part.isChecked():
            limits = self.lr.getRegion()
            x = int(limits[0] * sample_rate)
            y = int(limits[1] * sample_rate)
            if x < 0:
                signal_t = data[0:y]
            elif y > len(data):
                signal_t = data[x:]
            else:
                signal_t = data[x:y]

            filt, rpeaks = ecg(signal=signal_t,
                               sampling_rate=sample_rate,
                               show=False)[1:3]
            self.plotPeaks(signal_t, rpeaks)
            rpeaks = rpeaks / sample_rate
            nni = tools.nn_intervals(rpeaks=rpeaks)
            results = hrv(nni=nni,
                          rpeaks=rpeaks,
                          sampling_rate=sample_rate,
                          interval=[0, int(len(signal_t) / sample_rate)],
                          show=False)
            self.showPlots()
        else:
            self.showMsg(
                'Please select if you want HRV parameters for whole signal or for selected part'
            )
Ejemplo n.º 2
0
def rri_test_recurrent(filelist=None):
    global shape_tmp
    for i in range(len(filelist)):

        # for i in range(10):
        with open(filelist[i], 'rb') as f:
            plk_tmp = pkl.load(f)
        ecg_re = ecg.ecg(signal=plk_tmp, sampling_rate=Fs, show=False)
        rpeaks_tmp = ecg_re['rpeaks'].tolist()
        nni = tools.nn_intervals(rpeaks=rpeaks_tmp)
        nni_tmp = nni.reshape((-1, int(nni.shape[0])))  # for 2d data type
        rp = RecurrencePlot(threshold='point', percentage=20)
        X_rp = rp.fit_transform(nni_tmp)
        dst = cv2.resize(X_rp[0],
                         dsize=(135, 135),
                         interpolation=cv2.INTER_AREA)
        shape_tmp.append(X_rp.shape)
        recurrence_tmp.append(X_rp)
        recur_resize.append(dst)
        # for pandas
        # shape_tmp = shape_tmp.append(pd.DataFrame(X_rp.shape))
        # plot check
        plt.imshow(X_rp[0], cmap='binary', origin='lower')
        plt.plot(nni)
        plt.title('Recurrence Plot', fontsize=16)
        plt.tight_layout()
        plt.show()
        # np_tmp = np.column_stack([np_tmp, X_rp])
        if i == 0:
            pass
    return shape_tmp, recurrence_tmp, np.asarray(recur_resize)
Ejemplo n.º 3
0
    def extractRR(self, x):

        r = biosppy.signals.ecg.ecg(x, sampling_rate=self.fs, show=False)[2]
        r = r.astype(float)
        # Compute NNI or RR
        nni = tools.nn_intervals(r)

        return nni * 4
Ejemplo n.º 4
0
def heart_rate_variability(sample, lead, rpeak_method = 'string'):
    curdir = 'DATA\TrainData_FeatureExtraction'
    [all_data, header_data, BAD_LABELS] = data_read.data_files_load(curdir)

    data = all_data[sample][lead]

    """INITIALIZE DETECTOR CLASS WITH THE SAMPLING RATE:"""
    detectors = Detectors(500)

    """FIND RPEAK USING ONE OF THE METHODS BELOW--------------------"""

    if rpeak_method == 'hamilton' or rpeak_method == 'string':
        #Hamilton.
        r_peaks = detectors.hamilton_detector(data)

    elif rpeak_method == 'christov':
        #Christov
        r_peaks = detectors.christov_detector(data)

    elif rpeak_method == 'engelse':
        #Engelse and Zeelenberg
        r_peaks = detectors.engzee_detector(data)

    elif rpeak_method == 'pan':
        #Pan and Tompkins
        r_peaks = detectors.pan_tompkins_detector(data)

    elif rpeak_method == 'stationary_wavelet':
        #Stationary Wavelet Transform
        r_peaks = detectors.swt_detector(data)

    elif rpeak_method == 'two_moving_average':
        #Two Moving Average
        r_peaks = detectors.two_average_detector(data)

    #elif rpeak_method == 'matched_filter':
        #Matched Filter
        #go to pyhrv documentation to find the template file
        #r_peaks = detectors.matched_filter_detector(data,template_file)

    """COMPUTE NNI SERIES-------------------------------------------"""
    nn = nn_intervals(r_peaks) #nni seems to be off by a factor of 3
    print("\n\n", nn, "\n\n")

    """PLOT ECG/TACHOGRAM-------------------------------------------"""
    #plot_ecg(data, sampling_rate = 500)
    #tachogram(nn, sampling_rate = 500)

    """COMPUTE HRV--------------------------------------------------"""
    results = hrv(nn, None, None, 500)

    """COMPUTE HR PARAMETERS--(SOMETHING IS WRONG HERE BPM TOO HIGH)"""
    hr = heart_rate(nn)

    """COMPUTE FREQUENCY ANALYSIS-----------------------------------"""
    freq_results = results['fft_bands']

    return results, hr, freq_results
Ejemplo n.º 5
0
    def extractRR(self, x):

        X, r = biosppy.signals.ecg.ecg(x, sampling_rate=self.fs, show=False)[1:3]
        r = biosppy.signals.ecg.correct_rpeaks(signal=X, rpeaks=r, sampling_rate=self.fs)[0]
        r = r.astype(float)
        # Compute NNI or RR
        nni = tools.nn_intervals(r)

        return nni
Ejemplo n.º 6
0
 def get_bvp_metrics(x, metric, sampling_rate=64):
     if metric == 'hr_mean':
         hr = biosppy.signals.bvp.bvp(x,
                                      sampling_rate=sampling_rate,
                                      show=False)['heart_rate']
         return np.mean(hr)
     if metric == 'hrv_mean':
         onsets = biosppy.signals.bvp.bvp(x,
                                          sampling_rate=sampling_rate,
                                          show=False)['onsets']
         hrv = tools.nn_intervals(onsets)
         return np.mean(hrv)
     if metric == 'hr_std':
         hr = biosppy.signals.bvp.bvp(x,
                                      sampling_rate=sampling_rate,
                                      show=False)['heart_rate']
         return np.std(hr)
     if metric == 'hrv_std':
         onsets = biosppy.signals.bvp.bvp(x,
                                          sampling_rate=sampling_rate,
                                          show=False)['onsets']
         hrv = tools.nn_intervals(onsets)
         return np.std(hrv)
     if metric == 'tinn':
         onsets = biosppy.signals.bvp.bvp(x,
                                          sampling_rate=sampling_rate,
                                          show=False)['onsets']
         hrv = tools.nn_intervals(onsets)
         return get_geometrical_features(hrv)['triangular_index']
     if metric == 'rms':
         onsets = biosppy.signals.bvp.bvp(x,
                                          sampling_rate=sampling_rate,
                                          show=False)['onsets']
         hrv = tools.nn_intervals(onsets)
         return np.sqrt((1 / len(hrv)) * sum([i**2 for i in hrv]))
     return ValueError(f"Unsupported Metric {metric}")
Ejemplo n.º 7
0
    def update(self):
        global data, rpeaks, nni, sample_rate
        t = tools.time_vector(signal=data, sampling_rate=sample_rate)

        self.view_signal.clear()
        self.view_signal.plot(t, data, pen=pg.mkPen('r'))
        self.view_signal.setLimits(xMin=0, xMax=t[-1])
        self.view_signal.setMouseEnabled(x=True, y=False)
        self.view_signal.setLabel('bottom', text='Time [s]')

        filt, rpeaks = ecg(signal=data, sampling_rate=sample_rate,
                           show=False)[1:3]
        rpeaks = rpeaks / sample_rate
        nni = tools.nn_intervals(rpeaks=rpeaks)

        t = np.cumsum(nni) / 1000.

        self.tachogram_view.clear()
        self.tachogram_view.plot(t, nni, pen=pg.mkPen('r'))
        self.tachogram_view.setLimits(xMin=0, xMax=t[-1])
        self.tachogram_view.setMouseEnabled(x=True, y=False)
        self.tachogram_view.setLabel('bottom', text='Time [s]')
Ejemplo n.º 8
0
def resp_features(resp_peaks):
    bvp = tools.nn_intervals(resp_peaks.tolist())
    resp_features = {}

    #------時系列解析------#
    L = len(resp_peaks)
    resp_features['bvp_mean'] = np.mean(bvp)
    resp_features['bvp_max'] = np.max(bvp)
    resp_features['bvp_min'] = np.min(bvp)
    resp_features['bvp_sdnn'] = np.std(bvp)
    resp_features['bvp_sdsd'] = np.std(np.diff(bvp))
    resp_features['bvp_rmssd'] = np.sqrt((1 / L) * sum(np.diff(bvp)**2))
    resp_features['bvp_median'] = np.median(bvp)

    #-----ポアンカレプロット-----#
    _, resp_features['bvp_sd1'], resp_features['bvp_sd2'], resp_features[
        'bvp_sd_ratio'], resp_features['bvp_ellipse_area'] = nl.poincare(
            rpeaks=resp_peaks.astype(int).tolist(), show=False)

    #------MultiScaleEntropy-----#
    # 後で追加すること

    return resp_features
Ejemplo n.º 9
0
    def _computeSignal(self, signal):
        obj = {}

        # Best min_dist & thres for sphygmogram signal
        peaks = peak.indexes(signal, min_dist=56, thres=0.16)

        # Ignore un normal signls (with no peaks)
        if (len(peaks) == 0): return obj

        nn = tools.nn_intervals(peaks)

        # Ignore un normal signls (with no NN)
        if (len(nn) == 0): return

        welch = {'welch': self._welch_psd(nn, peaks)}
        lomb = {'lomb': self._lomb_psd(nn, peaks)}
        ar = {'ar': self._ar_psd(nn, peaks)}

        obj['welch'] = self._walk_over(welch, 'welch')
        obj['lomb'] = self._walk_over(lomb, 'lomb')
        obj['ar'] = self._walk_over(ar, 'ar')

        return obj
Ejemplo n.º 10
0
    def _computeSignal(self, signal):
        obj = {}

        # Best min_dist & thres for sphygmogram signal
        peaks = peak.indexes(signal, min_dist=56, thres=0.16)

        # Ignore un normal signls (with no peaks)
        if (len(peaks) == 0): return obj

        nn = tools.nn_intervals(peaks)

        # Ignore un normal signls (with no NN)
        if (len(nn) == 0): return

        # Poincare method
        poincare = {'poincare': self._poincare(nn, peaks)}
        obj['poincare'] = self._walk_over(poincare, 'poincare')

        # ACF
        acf = {'ACF': self._ACF(signal, int(len(signal) / 2))}
        obj['ACF'] = self._walk_over(acf, 'ACF')

        return obj
Ejemplo n.º 11
0
def compute_nni(hrdata,
                sample_rate=64,
                sliding_window=.5,
                prominence=0.1,
                dist_q1=50,
                dist_q2=120,
                std_window=6,
                std_th=130,
                method='remove',
                plot=False):

    hrdata_inv = hrdata * (-1)
    """Calcuamos a media movil"""
    roll_mean = savgol_filter(hrdata_inv, 81, 2)

    #    plt.figure()
    #    plt.plot(hrdata_inv)
    #    plt.plot(roll_mean)
    """Create sliding window to calculate maximum signal over time"""
    windowsize = int(sliding_window * sample_rate)
    add = np.zeros(int(windowsize / 2))
    add[:] = np.nan
    hrdata_ext = np.concatenate((add, hrdata_inv, add))
    """Calculamos la envolvente superior """
    roll_max = []
    for i in range(len(hrdata)):
        roll_max.append(np.nanmax(hrdata_ext[i:i + windowsize]))
    """Suavizamos la envolvente superior """
    sroll_max = savgol_filter(roll_max, 51, 2)
    mn = .3 * np.std(sroll_max)
    sroll_max = sroll_max + mn

    #    plt.plot(sroll_max)
    """Calculamos una representación simplificada del heart rate"""
    simpleHR_1 = (hrdata_inv - roll_mean) * (hrdata_inv > roll_mean)
    envoltorio = minmax(sroll_max - roll_mean)
    simpleHR_2_raw = sigmoid(0, 2, 5, envoltorio) * simpleHR_1
    simpleHR_2 = savgol_filter(simpleHR_2_raw, 31,
                               2) * (hrdata_inv > roll_mean)

    #    plt.plot(simpleHR_2)
    """ Find the centers of the peaks of the signal """
    peaksx = np.where((simpleHR_2 > 0))[0]
    peaksy = simpleHR_2[peaksx]
    peaks, a = find_peaks(peaksy, prominence=prominence)

    #    plt.plot(peaksx[peaks],simpleHR_2[peaksx[peaks]],'*m')
    """ Create an array with the distances between peaks and filter
    the outlayers of missing beats (high or very low distances) """
    nni = tools.nn_intervals((peaksx[peaks] / sample_rate) * 1000)
    hr = tools.heart_rate(nni)
    nni_revised = np.zeros_like(nni)
    nni_revised[:] = np.nan
    index = np.logical_and((hr >= dist_q1), (hr <= dist_q2))
    nni_revised[index] = nni[index]
    nni_revised = nni_revised[~np.isnan(nni_revised)]
    std = std_convoluted(nni_revised, std_window)

    #    plt.figure()
    #    plt.plot(nni_revised)
    #    plt.plot(nni)
    #    plt.plot(std)

    index_std = [i for i in range(len(zscore(std))) if std[i] > std_th]
    groups = np.append(np.diff(index_std), 100)
    if groups[0] > 1:
        groups = groups[1:]

    index_diff = np.where(groups > 1)[0]

    if len(index_diff) > 1:
        start = 0
        end = index_diff[0]
        for i in range(1, len(index_diff) - 1):
            index_hole = index_std[start:end]
            #
            #            plt.figure()
            #            plt.plot(nni_revised[index_hole])
            if method == 'remove':
                aux = np.zeros(nni_revised[index_hole].shape)
                aux[:] = np.nan
                nni_revised[
                    index_hole] = aux  #outliers_iqr_method(nni_revised[index_hole])
            elif method == 'iqr':
                nni_revised[index_hole] = outliers_iqr_method(
                    nni_revised[index_hole])
            elif method == 'modified_z':
                nni_revised[index_hole] = outliers_modified_z(
                    nni_revised[index_hole])

#            plt.plot(nni_revised[index_hole])

            start = index_diff[i - 1]
            end = index_diff[i]

    nni_revised = nni_revised[~np.isnan(nni_revised)]
    """Representamos las graficas necesarias para visualizar los datos"""
    if plot:
        fig, axes = plt.subplots(2, 2)
        axes[0, 0].plot(hrdata_inv)
        axes[0, 0].plot(roll_mean)
        axes[0, 0].plot(roll_max)

        axes[0, 1].plot(simpleHR_1)
        axes[0, 1].plot(simpleHR_2)
        axes[0, 1].plot(peaksx[peaks], peaksy[peaks], 'kx')

        if len(nni_revised) % 2 == 0:
            size = len(nni_revised) - 1
        else:
            size = len(nni_revised)

        axes[1, 0].plot(nni)
        axes[1, 0].plot(nni_revised)
        axes[1, 0].plot(savgol_filter(nni_revised, min([101, size]), 2))
        plt.legend(['original', 'revised', 'fit'])
        #
        axes[1, 1].plot(tools.heart_rate(nni_revised))
        axes[1, 1].plot(
            savgol_filter(tools.heart_rate(nni_revised), min([101, size]), 2))
        axes[1, 1].set_ylim([40, 120])
        plt.legend(['Heart Rate'])


#        axes[1,1].plot((nni-np.nanmean(nni))/np.nanstd(nni))
#        axes[1,1].plot((nni_revised-np.nanmean(nni))/np.nanstd(nni))
#        axes[1,1].plot((std-np.nanmean(std))/np.nanstd(std) )

    return nni_revised
Ejemplo n.º 12
0
import biosignal_plot
path = r"C:\Users\akito\Desktop\test.txt"

arc = OpenSignalsReader(path)

# 心拍データからピークを取り出す
ecg_result = signals.ecg.ecg(signal=arc.signal(['ECG']),
                             sampling_rate=1000.0,
                             show=False)

# 呼吸周波数を取り出す
resp_result = resp_analysis.resp(arc.signal('RESP'), show=False)

# 描画設定
fig, axes = plt.subplots(2, 1, sharex=True, figsize=(16, 9))
axes[0].set_title(path)

# Compute NNI series
nni = tools.nn_intervals(ecg_result['rpeaks'].tolist())
filtered = biosignal_plot.detrend(nni, 500)

# 心拍変動の描画
axes[0].plot(ecg_result['heart_rate_ts'].tolist(), filtered, 'b')
axes[0].set_ylabel("HR[bpm]")

# 呼吸の描画
axes[1].plot(resp_result['ts'], resp_result['filtered'])
for ins, exp in zip(resp_result['inspiration'], resp_result['expiration']):
    axes[0].axvline(ins * 0.001, color='b')
    axes[0].axvline(exp * 0.001, color='r')
plt.show()
Ejemplo n.º 13
0
    def _computeSignal(self, signal):
        obj = {}

        # Best min_dist & thres for sphygmogram signal
        peaks = peak.indexes(signal, min_dist=56, thres=0.16)

        # Ignore un normal signls (with no peaks)
        if (len(peaks) == 0): return obj

        nn = tools.nn_intervals(peaks)

        # Ignore un normal signls (with no NN)
        if (len(nn) == 0): return

        # Standard
        obj = dict(td.nni_parameters(nn, peaks), **obj)
        obj = dict(td.nni_differences_parameters(nn, peaks), **obj)
        obj = dict(td.sdnn(nn, peaks), **obj)
        obj = dict(td.sdnn_index(nn, peaks), **obj)
        obj = dict(td.sdann(nn, peaks), **obj)
        obj = dict(td.rmssd(nn, peaks), **obj)
        obj = dict(td.sdsd(nn, peaks), **obj)
        obj = dict(td.nn50(nn, peaks), **obj)
        obj = dict(td.nn20(nn, peaks), **obj)
        obj = dict(td.geometrical_parameters(nn, peaks, plot=False), **obj)
        del obj['nni_histogram']

        # Additional
        obj = dict({'cv': self._cv(obj['sdnn'], obj['nni_mean'])}, **obj)

        peaks_diff = tools.nni_diff(peaks)
        obj = dict({'MxDMn': max(peaks_diff) - min(peaks_diff)}, **obj)
        obj = dict({'MxRMn': max(peaks_diff) / min(peaks_diff)}, **obj)
        obj = dict({'Mo': stats.mode(peaks_diff)[0][0]}, **obj)

        counter = Counter(peaks_diff)
        idx = list(counter.keys()).index(obj["Mo"])
        obj = dict({'AMo': list(counter.values())[idx]}, **obj)
        obj = dict({'SI': obj['AMo'] / (2 * obj['Mo'] * obj['MxDMn'])}, **obj)

        # Autocorrelation function

        # Frequency stats
        welch = frequency_domain(signal).stats['welch']['params']
        bands = list(welch['fft_bands'].keys())

        obj = dict({'TP': welch['fft_total']}, **obj)

        obj = dict({'HF': welch['fft_rel'][bands.index('hf')]}, **obj)
        obj = dict({'LF': welch['fft_rel'][bands.index('lf')]}, **obj)
        obj = dict({'VLF': welch['fft_rel'][bands.index('vlf')]}, **obj)
        obj = dict({'ULF': welch['fft_rel'][bands.index('ulf')]}, **obj)

        obj = dict({'HFav': welch['fft_abs'][bands.index('hf')]}, **obj)
        obj = dict({'LFav': welch['fft_abs'][bands.index('lf')]}, **obj)
        obj = dict({'VLFav': welch['fft_abs'][bands.index('vlf')]}, **obj)
        obj = dict({'ULFav': welch['fft_abs'][bands.index('ulf')]}, **obj)

        obj = dict({'(LF/HF)av': obj['LFav'] / obj['HFav']}, **obj)
        obj = dict({'IC': obj['LF'] / obj['VLF']}, **obj)

        for k in obj:
            if (math.isnan(obj[k])):
                obj[k] = 0

        return obj
Ejemplo n.º 14
0
    def metrics(self):
        import pyhrv.tools as tools
        intervalosNN = tools.nn_intervals(self.peaks_fpos)
        time_domain_features = get_time_domain_features(
            intervalosNN[intervalosNN != 0])
        frecuency_domain_features = get_frequency_domain_features(intervalosNN)
        geometrical_features = get_geometrical_features(intervalosNN)

        self.ui.scrollAreaFeatures.setStyleSheet('background-color: white')

        layout = QHBoxLayout()
        label = QLabel('<h3>Time Domain Features<h3>')
        label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
        label.setStyleSheet("color: rgb(59,59,59)")
        label.setMaximumWidth(290)
        layout.addWidget(label)
        self.ui.verticalLayout_features.addLayout(layout)

        time_domain_features_to_show = {
            'SDNN': time_domain_features['sdnn'],
            'SDSD': time_domain_features['sdsd'],
            'SDANN': self.sdann,
            'RMSSD': time_domain_features['rmssd']
        }
        time_domain_features_to_show2 = {
            'NN20 Count': time_domain_features['nni_20'],
            'NN50 Count': time_domain_features['nni_50'],
            'PNN50 Count': time_domain_features['pnni_50'],
            'PNN20 Count': time_domain_features['pnni_20']
        }

        for key, value in time_domain_features_to_show.items():
            layout = QVBoxLayout()
            label = QLabel('<h4>' + str(key) + ':</h4>')
            label.setStyleSheet("color: rgb(59,59,59)")
            label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
            label.setMaximumWidth(122)
            layout.addWidget(label)
            label1 = QLabel("{:.4f}".format(value))
            label1.setStyleSheet(
                "padding: 5px; border: 1px solid #cccccc; border-radius: 5px; background-color:#cccccc;"
            )
            label1.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
            label1.setMaximumWidth(122)
            layout.addWidget(label1)
            self.ui.verticalLayout_features1.addLayout(layout)

        for key, value in time_domain_features_to_show2.items():
            layout = QVBoxLayout()
            label = QLabel('<h4>' + str(key) + ':</h4>')
            label.setStyleSheet("color: rgb(59,59,59)")
            label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
            label.setMaximumWidth(122)
            layout.addWidget(label)
            label1 = QLabel("{:.4f}".format(value))
            label1.setStyleSheet(
                "padding: 5px; border: 1px solid #cccccc; border-radius: 5px; background-color:#cccccc;"
            )
            label1.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
            label1.setMaximumWidth(122)
            layout.addWidget(label1)
            self.ui.verticalLayout_features2.addLayout(layout)

        frecuency_domain_features_to_show = {
            'LF': frecuency_domain_features['lf'],
            'HF': frecuency_domain_features['hf'],
            'VLF': frecuency_domain_features['vlf']
        }
        frecuency_domain_features_to_show2 = {
            'LF norm': frecuency_domain_features['vlf'],
            'HF norm': frecuency_domain_features['hfnu'],
            'Total power': frecuency_domain_features['total_power']
        }

        layout = QHBoxLayout()
        label = QLabel('<h3>Frecuency Domain Features</h3>')
        label.setStyleSheet("color: rgb(59,59,59)")
        label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
        label.setMaximumWidth(290)
        layout.addWidget(label)
        self.ui.verticalLayout_features3.addLayout(layout)

        for key, value in frecuency_domain_features_to_show.items():
            layout = QVBoxLayout()
            label = QLabel('<h4>' + str(key) + ':</h4>')
            label.setStyleSheet("color: rgb(59,59,59)")
            label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
            label.setMaximumWidth(122)
            layout.addWidget(label)
            label1 = QLabel("{:.4f}".format(value))
            label1.setStyleSheet(
                "padding: 5px; border: 1px solid #cccccc; border-radius: 5px; background-color:#cccccc;"
            )
            label1.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
            label1.setMaximumWidth(122)
            layout.addWidget(label1)
            self.ui.verticalLayout_features4.addLayout(layout)
        for key, value in frecuency_domain_features_to_show2.items():
            layout = QVBoxLayout()
            label = QLabel('<h4>' + str(key) + ':</h4>')
            label.setStyleSheet("color: rgb(59,59,59)")
            label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
            label.setMaximumWidth(122)
            layout.addWidget(label)
            label1 = QLabel("{:.4f}".format(value))
            label1.setStyleSheet(
                "padding: 5px; border: 1px solid #cccccc; border-radius: 5px; background-color:#cccccc;"
            )
            label1.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
            label1.setMaximumWidth(122)
            layout.addWidget(label1)
            self.ui.verticalLayout_features5.addLayout(layout)

        geometrical_features_to_show = {'TINN': geometrical_features['tinn']}
        geometrical_features_to_show2 = {
            'Triangular Index': geometrical_features['triangular_index']
        }

        layout = QHBoxLayout()
        label = QLabel('<h3>Geometrical Domain Features</h3>')
        label.setStyleSheet("color: rgb(59,59,59)")
        label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
        label.setMaximumWidth(290)
        layout.addWidget(label)
        self.ui.verticalLayout_features6.addLayout(layout)

        for key, value in geometrical_features_to_show2.items():
            layout = QVBoxLayout()
            label = QLabel('<h4>' + str(key) + ':</h4>')
            label.setStyleSheet("color: rgb(59,59,59)")
            label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
            label.setMaximumWidth(122)
            layout.addWidget(label)
            label1 = QLabel("{:.4f}".format(value))
            label1.setStyleSheet(
                "padding: 5px; border: 1px solid #cccccc; border-radius: 5px; background-color:#cccccc;"
            )
            label1.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
            label1.setMaximumWidth(122)
            layout.addWidget(label1)
            self.ui.verticalLayout_features7.addLayout(layout)
        for key, value in geometrical_features_to_show.items():
            layout = QVBoxLayout()
            label = QLabel('<h4>' + str(key) + ':</h4>')
            label.setStyleSheet("color: rgb(59,59,59)")
            label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
            label.setMaximumWidth(122)
            layout.addWidget(label)
            label1 = QLabel(str(value))
            label1.setStyleSheet(
                "padding: 5px; border: 1px solid #cccccc; border-radius: 5px; background-color:#cccccc;"
            )
            label1.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
            label1.setMaximumWidth(122)
            layout.addWidget(label1)
            self.ui.verticalLayout_features8.addLayout(layout)

        from hrvanalysis import plot_psd