Engee documentation
Notebook

Spectral analysis of cardiac arrhythmias

This example demonstrates the application of spectral analysis to electrocardiographic signals with different types of heart rate. ECG recordings with normal sinus rhythm, extrasystole, and atrial fibrillation obtained from open PhysioNet databases are considered. The functions of the EngeeDSP library are used for frequency analysis.

Function engee.clear() cleans up workspaces:

In [ ]:
engee.clear()

Two graph rendering modes are available to visualize the results.:

  • For static, fast rendering, use gr().

  • For interactive, dynamic visualization with the ability to scale and view values, use plotlyjs().

Select one of the commands by commenting out the second one. Both backends are mutually exclusive, and the last one called will be activated.

In [ ]:
# gr()
plotlyjs()
Out[0]:
Plots.PlotlyJSBackend()

We will connect using the function include the "read" file.jl" for reading files:

In [ ]:
include("$(@__DIR__)/read.jl")
Out[0]:
safe_read_ann (generic function with 1 method)

Spectral analysis of the ECG is normal

An electrocardiographic signal corresponding to the normal sinus rhythm of the heart is used as the initial data for the analysis. This record was obtained from the [MIT-BIH Normal Sinus Rhythm Database (NSRDB)](https://physionet.org/content/nsrdb/1.0.0 /) and reflects the work of the heart of a healthy person without pronounced rhythm disturbances.

Specify the path to the file with the selected ECG recording:

In [ ]:
data = ("$(@__DIR__)/mit-bih-normal-sinus-rhythm/16272")
Out[0]:
"/user/DemoPublic/biomedical/spectral_analysis_arrhythmia/mit-bih-normal-sinus-rhythm/16272"

After setting the file path, the ECG recording header is read. Service information describing the signal parameters is extracted from the header: the name of the recording, the sampling frequency, the number of channels, and the total number of samples. Information about the data format, gain, and text description of the recording is also displayed.

In [ ]:
hdr = read_header(data)

println("Name of the record:   ", hdr.record)
println("Sampling rate: ", hdr.fs, " Hz")
println("Number of signals:   ", hdr.nsig)
println("Number of counts:   ", hdr.nsamp)
println("Data format:         ", hdr.fmt)
println("Gain:              ", hdr.gain)
println("Description:              ", hdr.desc)
Наименование записи:   16272
Частота дискретизации: 128.0 Гц
Количество сигналов:   2
Количество отсчётов:   11520000
Формат данных:         212
Усиление:              0.0
Описание:              ECG1

To demonstrate the temporal representation of the ECG, we will select a 10-second recording fragment.

In [ ]:
t_start = 0.0
t_dur   = 10.0

sampl_start = Int(round(t_start * hdr.fs))
sampl_end   = sampl_start + Int(round(t_dur * hdr.fs))

_, raw, phys = read_dat_212(data; sampfrom=sampl_start, sampto=sampl_end)
y1 = phys === nothing ? float.(raw[:,1])/200 : phys[:,1]

t1 = (0:length(y1)-1)./ hdr.fs.+ t_start

plot(t1, y1,
        xlabel="Time, from", 
        ylabel="The amplitude", 
        title="Recording $(hdr.record) NSRDB",
        legend=false)
Out[0]:

We will also demonstrate a one-minute fragment of the ECG recording. To do this, we will increase the duration of the analyzed interval to 60 seconds, calculate the corresponding section of the signal and construct its time representation.

In [ ]:
t_start = 0.0
t_dur = 60.0

sampl_start = Int(round(t_start * hdr.fs))
sampl_end = sampl_start + Int(round(t_dur * hdr.fs))

_, raw, phys = read_dat_212(data; sampfrom=sampl_start, sampto=sampl_end)
y1 = phys === nothing ? float.(raw[:,1])/200 : phys[:,1]

t1 = (0:length(y1)-1) ./ hdr.fs .+ t_start

plot(t1, y1,
        xlabel="Time, from", 
        ylabel="The amplitude", 
        title="Recording $(hdr.record) NSRDB",
        legend=false)
Out[0]:

To switch to the frequency representation of the signal, we use the functions of the EngeeDSP library. Function EngeeDSP.Functions.fft performs a fast Fourier transform of a time signal, converting it into a set of complex frequency coefficients. Then it is applied EngeeDSP.Functions.fftshift for centering the spectrum.

In [ ]:
nsampl = length(y1)
fs = hdr.fs
df = hdr.fs / nsampl

freq_vec1 = -fs/2 : df : fs/2 - df

fft_y1 = EngeeDSP.Functions.fft(y1)     # FFT

fft_Y1 = EngeeDSP.Functions.fftshift(fft_y1)    # Centered spectrum
Out[0]:
7680-element Vector{ComplexF64}:
   0.4299999999999784 + 0.0im
    1.420074436857042 - 1.259402987504321im
  0.43216868301268896 + 2.18561269828764im
   1.4631953485700109 - 1.264690852185021im
  -0.6108928341574078 + 2.0868506337778356im
   -1.718166119515935 - 0.5277964184678581im
   -1.268020722866865 + 1.0992614404769583im
 -0.11131950936055546 + 0.48566398997173366im
  -1.3889234887099207 + 0.9665944738563965im
   0.8718361075312409 + 3.2228018323602328im
 -0.03253517186771049 + 0.3818156520900047im
  0.31213973318596056 + 1.7696508718261263im
  -0.9692764209245297 - 1.6720509877093566im
                      ⋮
  -0.9692764209245297 + 1.6720509877093566im
  0.31213973318596056 - 1.7696508718261263im
 -0.03253517186771049 - 0.3818156520900047im
   0.8718361075312409 - 3.2228018323602328im
  -1.3889234887099207 - 0.9665944738563965im
 -0.11131950936055546 - 0.48566398997173366im
   -1.268020722866865 - 1.0992614404769583im
   -1.718166119515935 + 0.5277964184678581im
  -0.6108928341574078 - 2.0868506337778356im
   1.4631953485700109 + 1.264690852185021im
  0.43216868301268896 - 2.18561269828764im
    1.420074436857042 + 1.259402987504321im

Let's calculate the amplitude spectrum of the analyzed signal and plot it in the frequency range from 0 to 10 Hz.

In [ ]:
Amp1 = (2*abs.(fft_Y1))/nsampl

 plot(
    freq_vec1, Amp1,
    xlabel="Frequency, Hz",
    ylabel="The amplitude",
    title="Signal amplitude spectrum $(hdr.record) NSRDB",
    grid=true,
    legend=false,
    xlim=(0, 10),
)
Out[0]:

The resulting amplitude spectrum of an ECG signal with a normal sinus rhythm has an ordered structure. The spectrum clearly shows the main frequency component in the region of about 1 Hz, corresponding to the heart rate, and harmonics at multiple frequencies are also observed. The signal energy is concentrated mainly in the low-frequency range up to 10 Hz.

Separately, we can note the presence of a component in the range of about 0.1 Hz, which is not directly related to cardiac activity and is caused by low-frequency interference that occurs when recording the signal.

Spectral analysis of ECG in ventricular extrasystole

Ventricular extrasystole is a type of cardiac arrhythmia in which abnormal contractions occur not from the sinus node, but from additional foci of excitation in the ventricles of the heart. Such premature contractions appear on the ECG as separate, earlier, deformed QRS complexes compared to normal cardiac cycles.

Extrasystoles can be single or repetitive, and depending on the frequency and nature of the occurrence, they are identified as frequent or rare. Ventricular extrasystoles are often not accompanied by pronounced symptoms in the patient, but may feel like interruptions or "missed" heartbeats.

We use ECG recording with ventricular extrasystole from the [CU Ventricular Tachyarrhythmia Database (CU VTADB)](https://physionet.org/content/cudb/1.0.0 /).

In [ ]:
data = ("$(@__DIR__)/cu-ventricular-tachyarrhythmia/cu05")
Out[0]:
"/user/DemoPublic/biomedical/spectral_analysis_arrhythmia/cu-ventricular-tachyarrhythmia/cu05"

We will display the main parameters of the analyzed ECG recording.

In [ ]:
hdr = read_header(data)

println("Name of the record:   ", hdr.record)
println("Sampling rate: ", hdr.fs, " Hz")
println("Number of signals:   ", hdr.nsig)
println("Number of counts:   ", hdr.nsamp)
println("Data format:         ", hdr.fmt)
println("Gain:              ", hdr.gain)
println("Description:              ", hdr.desc)
Наименование записи:   cu05
Частота дискретизации: 250.0 Гц
Количество сигналов:   1
Количество отсчётов:   127232
Формат данных:         212
Усиление:              400.0
Описание:              ECG

Let's demonstrate the ventricular extrasystole. To do this, we will select a two-second fragment on the recording in the range of 126-128 seconds and mark the area corresponding to the extrasystolic complex with a colored area on the graph.

In [ ]:
t_start = 126.0
t_dur = 2.0

sampl_start = Int(round(t_start * hdr.fs))
sampl_end = sampl_start + Int(round(t_dur * hdr.fs))

_, raw, phys = read_dat_212(data; sampfrom=sampl_start, sampto=sampl_end)
y2 = phys === nothing ? float.(raw[:,1]) : phys[:,1]
t2 = (0:length(y2)-1) ./ hdr.fs .+ t_start

p =plot(t2, y2,
        xlabel="Time, from", 
        ylabel="Amlituda", 
        title="Recording $(hdr.record) CU VTADB ",
        legend=false
        )

vline!(p, [127.1, 127.3], color=:red, alpha=0.3)

display(p)

We will demonstrate a minute fragment of an ECG for ventricular extrasystole by selecting a recording section without pronounced artifacts.

In [ ]:
t_start = 115.0
t_dur = 60.0

sampl_start = Int(round(t_start * hdr.fs))
sampl_end = sampl_start + Int(round(t_dur * hdr.fs))

_, raw, phys = read_dat_212(data; sampfrom=sampl_start, sampto=sampl_end)
y2 = phys === nothing ? float.(raw[:,1]) : phys[:,1]
t2 = (0:length(y2)-1) ./ hdr.fs .+ t_start

plot(t2, y2,
        xlabel="Time, from", 
        ylabel="The amplitude", 
        title="Recording $(hdr.record) CU VTADB ",
        legend=false)
Out[0]:

Similarly, we use the functions of the EngeeDSP library for frequency analysis.

In [ ]:
nsampl = length(y2)
fs = hdr.fs
df = hdr.fs / nsampl

freq_vec2 = -fs/2 : df : fs/2 - df

fft_y2 = EngeeDSP.Functions.fft(y2)     # FFT

fft_Y2 = EngeeDSP.Functions.fftshift(fft_y2)    # Centered spectrum
Out[0]:
15000-element Vector{ComplexF64}:
  0.24250000000006366 + 0.0im
   -0.617390662779087 - 0.9645818287347332im
  -0.5170981782064956 + 0.47210546222461947im
   0.3042996579577628 - 0.5017138577633im
  -0.6114165019779407 + 0.17445736541545964im
    0.518487255266888 + 0.8184288482754183im
  0.47517928893948813 + 0.5832875878615109im
   0.2709135407918337 - 0.0490081731987142im
   0.7785997524270325 + 0.8367519488401889im
   -0.621085745416029 - 0.12505334037132454im
 0.006377498767134782 + 0.0835351710709844im
   -0.814160502367459 + 0.584528873438301im
   -0.408193073323317 + 0.24900364154655996im
                      ⋮
   -0.408193073323317 - 0.24900364154655996im
   -0.814160502367459 - 0.584528873438301im
 0.006377498767134782 - 0.0835351710709844im
   -0.621085745416029 + 0.12505334037132454im
   0.7785997524270325 - 0.8367519488401889im
   0.2709135407918337 + 0.0490081731987142im
  0.47517928893948813 - 0.5832875878615109im
    0.518487255266888 - 0.8184288482754183im
  -0.6114165019779407 - 0.17445736541545964im
   0.3042996579577628 + 0.5017138577633im
  -0.5170981782064956 - 0.47210546222461947im
   -0.617390662779087 + 0.9645818287347332im

Let's plot the amplitude spectrum of a minute ECG fragment with ventricular extrasystole in the frequency range up to 10 Hz.

In [ ]:
Amp2 = (2*abs.(fft_Y2))/nsampl

 plot(
    freq_vec2, Amp2,
    xlabel="Frequency, Hz",
    ylabel="The amplitude",
    title="Signal amplitude spectrum $(hdr.record) CU VTADB",
    grid=true,
    legend=false,
    xlim=(0, 10),
)
Out[0]:

The resulting amplitude spectrum of the ECG in ventricular extrasystole has a less ordered structure compared to the normal sinus rhythm. The nature of the spectral energy distribution indicates a violation of the frequency of heart contractions due to the presence of extrasystolic complexes, which is consistent with the features of the ECG in ventricular extrasystole.

Spectral ECG analysis in atrial extrasystole

We use an ECG recording from the [MIT-BIH Arrhythmia Database](https://physionet.org/content/mitdb/1.0.0 /), containing cardiac arrhythmias. Recording 101 is generally characterized by a predominantly normal sinus rhythm, against which single and repeated atrial extrasystoles are periodically present.

Single and repeated atrial extrasystoles are premature cardiac contractions that occur in the atria outside the normal sinus rhythm. With single extrasystoles, such contractions appear sporadically and do not significantly affect the overall rhythm of the heart. Repetitive atrial extrasystoles are characterized by a more frequent occurrence of premature impulses, which leads to periodic disruption of the regularity of cardiac cycles.

In [ ]:
data = ("$(@__DIR__)/mit-bih-arrhythmia/101")
Out[0]:
"/user/DemoPublic/biomedical/spectral_analysis_arrhythmia/mit-bih-arrhythmia/101"

We will display basic information about the selected ECG recording, including sampling parameters, signal structure, and description of the recording.

In [ ]:
hdr = read_header(data)

println("Name of the record:   ", hdr.record)
println("Sampling rate: ", hdr.fs, " Hz")
println("Number of signals:   ", hdr.nsig)
println("Number of counts:   ", hdr.nsamp)
println("Data format:         ", hdr.fmt)
println("Gain:              ", hdr.gain)
println("Description:              ", hdr.desc)
Наименование записи:   101
Частота дискретизации: 360.0 Гц
Количество сигналов:   2
Количество отсчётов:   650000
Формат данных:         212
Усиление:              200.0
Описание:              MLII

Let's demonstrate a single atrial extrasystole. To do this, we will select a six-second fragment in the interval 373-379 seconds on the recording and mark the area corresponding to the extrasystolic complex on the graph with colored vertical lines.

In [ ]:
t_start = 373.0
t_dur = 6.0

sampl_start = Int(round(t_start * hdr.fs))
sampl_end   = sampl_start + Int(round(t_dur * hdr.fs))

_, raw, phys = read_dat_212(data; sampfrom=sampl_start, sampto=sampl_end)
y3 = phys === nothing ? float.(raw[:,1]) : phys[:,1]
t3  = (0:length(y3)-1) ./ hdr.fs .+ t_start

plot(t3, y3,
        xlabel="Time, from", 
        ylabel="Amlituda", 
        title="Recording $(hdr.record) MIT-BIH Arrhythmia Database ",
        legend=false)
vline!([375.6, 376.2], color=:red, alpha=0.3)
Out[0]:

We will demonstrate a one-minute fragment of an ECG recording containing episodes of cardiac arrhythmias.

In [ ]:
t_start = 370.0
t_dur = 60.0

sampl_start = Int(round(t_start * hdr.fs))
sampl_end   = sampl_start + Int(round(t_dur * hdr.fs))

_, raw, phys = read_dat_212(data; sampfrom=sampl_start, sampto=sampl_end)
y3 = phys === nothing ? float.(raw[:,1]) : phys[:,1]
t3  = (0:length(y3)-1) ./ hdr.fs .+ t_start

plot(t3, y3,
        xlabel="Time, from", 
        ylabel="Amlituda", 
        title="Recording $(hdr.record) MIT-BIH Arrhythmia Database ",
        legend=false)
Out[0]:

Similarly to the previous steps, for the minute fragment of the ECG, we will perform a frequency analysis using the functions of the EngeeDSP library, obtaining a centered spectral representation of the signal.

In [ ]:
nsampl = length(y3)
fs = hdr.fs
df = hdr.fs / nsampl

freq_vec3 = -fs/2 : df : fs/2 - df

fft_y3 = EngeeDSP.Functions.fft(y3)     # FFT

fft_Y3 = EngeeDSP.Functions.fftshift(fft_y3)    # Centered spectrum
Out[0]:
21600-element Vector{ComplexF64}:
  -0.3499999999994543 + 0.0im
   -2.234148576509483 - 1.2921799198174142im
  -1.6923286675628049 - 3.0776448272429917im
   0.4223899856295361 + 4.918528645252934im
  0.06853869626723963 + 1.1634092443288893im
  0.07893171630887252 + 1.2391034578455589im
  0.23785772024982066 + 0.35861164346277974im
  0.13804578436253223 - 0.4131028992901946im
   0.9968657203876319 + 0.26269403356537424im
 -0.22749912173740938 + 0.05458454978024285im
 -0.10207517835085866 + 0.39308378482185447im
  -0.7325178393852525 + 0.02981812698969577im
 -0.11654664523090119 + 0.07441184108022014im
                      ⋮
 -0.11654664523090119 - 0.07441184108022014im
  -0.7325178393852525 - 0.02981812698969577im
 -0.10207517835085866 - 0.39308378482185447im
 -0.22749912173740938 - 0.05458454978024285im
   0.9968657203876319 - 0.26269403356537424im
  0.13804578436253223 + 0.4131028992901946im
  0.23785772024982066 - 0.35861164346277974im
  0.07893171630887252 - 1.2391034578455589im
  0.06853869626723963 - 1.1634092443288893im
   0.4223899856295361 - 4.918528645252934im
  -1.6923286675628049 + 3.0776448272429917im
   -2.234148576509483 + 1.2921799198174142im

Let's plot the amplitude spectrum of a minute ECG fragment in the frequency range up to 10 Hz.

In [ ]:
Amp3 = (2*abs.(fft_Y3))/nsampl

 plot(
    freq_vec3, Amp3,
    xlabel="Frequency, Hz",
    ylabel="The amplitude",
    title="Signal amplitude spectrum $(hdr.record) MIT-BIH Arrhythmia Database",
    grid=true,
    legend=false,
    xlim=(0, 10),
    ylim=(0 ,0.08)
)
Out[0]:

The obtained amplitude spectrum of the minute ECG fragment from the MIT-BIH Arrhythmia Database is characterized by pronounced disorder compared to the normal sinus rhythm. The main low-frequency component is present in the spectrum, but the spectral peaks have a noticeable broadening, and the signal energy is distributed over a wider frequency range.

Spectral analysis of ECG in atrial fibrillation

Atrial fibrillation is a form of cardiac arrhythmia in which the electrical activity of the atria becomes chaotic and uncoordinated. Instead of regular sinus node impulses, multiple foci of arousal appear in the atria, which leads to their ineffective contractions.

On an electrocardiogram, atrial fibrillation is characterized by the absence of normal P-waves and the appearance of small irregular baseline fluctuations, as well as irregular intervals between QRS complexes.

We select the s02 entry corresponding to atrial fibrillation from the [Atrial Fibrillation Termination Challenge Database (AFDB)] database.](https://physionet.org/content/afdb/1.0.0/)

In [ ]:
data = ("$(@__DIR__)/af-termination-challenge/s02")
Out[0]:
"/user/DemoPublic/biomedical/spectral_analysis_arrhythmia/af-termination-challenge/s02"
In [ ]:
hdr = read_header(data)

println("Name of the record:   ", hdr.record)
println("Sampling rate: ", hdr.fs, " Hz")
println("Number of signals:   ", hdr.nsig)
println("Number of counts:   ", hdr.nsamp)
println("Data format:         ", hdr.fmt)
println("Gain:              ", hdr.gain)
println("Description:              ", hdr.desc)
Наименование записи:   s02
Частота дискретизации: 128.0 Гц
Количество сигналов:   2
Количество отсчётов:   7680
Формат данных:         16
Усиление:              182.149
Описание:              ECG

Let's demonstrate a 10-second fragment of an ECG recording, which shows an irregular rhythm characteristic of atrial fibrillation.

In [ ]:
t_start = 0.0
t_dur   = 10.0

sampl_start = Int(round(t_start * hdr.fs))
sampl_end   = sampl_start + Int(round(t_dur * hdr.fs))

_, raw, phys = read_dat_16(data; sampfrom=sampl_start, sampto=sampl_end)
y4 = phys === nothing ? float.(raw[:,1]) : phys[:,1]
t4  = (0:length(y4)-1) ./ hdr.fs .+ t_start

plot(t4, y4,
        xlabel="Time, from", 
        ylabel="Amlituda", 
        title="Recording $(hdr.record) AFDB",
        legend=false)
Out[0]:

We will demonstrate a one-minute fragment of an ECG recording for atrial fibrillation, reflecting a pronounced irregular heart rhythm.

In [ ]:
t_start = 0.0
t_dur   = 60.0

sampl_start = Int(round(t_start * hdr.fs))
sampl_end   = sampl_start + Int(round(t_dur * hdr.fs))

_, raw, phys = read_dat_16(data; sampfrom=sampl_start, sampto=sampl_end)
y4 = phys === nothing ? float.(raw[:,1]) : phys[:,1]
t4  = (0:length(y4)-1) ./ hdr.fs .+ t_start

plot(t4, y4,
        xlabel="Time, from", 
        ylabel="The amplitude", 
        title="Recording $(hdr.record) AFDB",
        legend=false)
Out[0]:

Similarly to the previous steps, we will perform a frequency analysis of the minute fragment of the ECG for atrial fibrillation using the functions of the EngeeDSP library and obtain a centered signal spectrum.

In [ ]:
nsampl = length(y4)
fs = hdr.fs
df = hdr.fs / nsampl

freq_vec4 = -fs/2 : df : fs/2 - df

fft_y4 = EngeeDSP.Functions.fft(y4)     # FFT

fft_Y4 = EngeeDSP.Functions.fftshift(fft_y4)    # Centered spectrum
Out[0]:
7680-element Vector{ComplexF64}:
 0.005490010925129241 + 0.0im
  -0.7423632719658406 + 1.9789740826734277im
  0.33492665860237025 - 1.5643893204067822im
  -0.7660751104496875 - 2.9121794152264586im
  -0.5678084664411713 + 0.9427265362270969im
  -0.5230071267951804 - 1.5753561875288806im
    1.182602214953216 - 0.7141930881550123im
  -0.7904291722913852 - 1.9998184339818996im
    1.542071912231664 - 0.48908491965557044im
  -1.9879774432424888 - 0.1390182820275765im
   1.0971526826344933 + 0.7966247851480954im
   -0.723195108699282 - 0.7038636138748355im
  -1.4293774193780902 - 0.9104137771854699im
                      ⋮
  -1.4293774193780902 + 0.9104137771854699im
   -0.723195108699282 + 0.7038636138748355im
   1.0971526826344933 - 0.7966247851480954im
  -1.9879774432424888 + 0.1390182820275765im
    1.542071912231664 + 0.48908491965557044im
  -0.7904291722913852 + 1.9998184339818996im
    1.182602214953216 + 0.7141930881550123im
  -0.5230071267951804 + 1.5753561875288806im
  -0.5678084664411713 - 0.9427265362270969im
  -0.7660751104496875 + 2.9121794152264586im
  0.33492665860237025 + 1.5643893204067822im
  -0.7423632719658406 - 1.9789740826734277im

Let's plot the amplitude spectrum of a minute ECG fragment in atrial fibrillation in the frequency range up to 10 Hz.

In [ ]:
Amp4 = (2*abs.(fft_Y4))/nsampl

 plot(
    freq_vec4, Amp4,
    xlabel="Frequency, Hz",
    ylabel="The amplitude",
    title="Signal amplitude spectrum $(hdr.record) AFDB",
    grid=true,
    legend=false,
    xlim=(0, 10),
)
Out[0]:

The amplitude spectrum of the ECG in atrial fibrillation is characterized by pronounced disorder and the absence of a clearly defined fundamental frequency component. The signal energy is distributed over a wide range of frequencies, with an increased background level of the spectrum and a large number of irregular spectral components.

Materials used

The work used real electrocardiographic recordings from the open source PhysioNet.

  1. MIT-BIH Normal Sinus Rhythm Database (NSRDB) - ECG recordings with normal sinus rhythm - <https://physionet.org/content/nsrdb/1.0.0 />
  2. CU Ventricular Tachyarrhythmia Database (CUDB) - ECG recordings with ventricular arrhythmias - <https://physionet.org/content/cudb/1.0.0 />
  3. MIT-BIH Arrhythmia Database - ECG recordings with various types of arrhythmias - <https://physionet.org/content/mitdb/1.0.0 />
  4. Atrial Fibrillation Database (AFDB) - ECG recordings with atrial fibrillation - <https://physionet.org/content/afdb/1.0.0 />

Conclusion

In the course of the example, a spectral analysis of various cardiac arrhythmias was presented. The work used real electrocardiographic signals obtained from open medical databases. The functions of the EngeeDSP library were used for frequency analysis of signals, in particular the functions EngeeDSP.Functions.fft to calculate the fast Fourier transform and EngeeDSP.Functions.fftshift to form a centered spectral representation. The use of these instruments made it possible to visually demonstrate the features of ECG spectra in various types of cardiac arrhythmias.