⚠️ CAUTION: This project is a work in progress. Blood pressure analysis is not yet implemented. Breathing signal extraction and visualisation are functional but should be treated as experimental.
- What is spectHR?
- Theoretical background
- Getting started
- The interface at a glance
- Step 1, Check and clean the ECG
- Step 2, Inspect the heart rate series
- Step 3, Define your analysis segments
- Step 4, Explore autonomic dynamics (Poincaré tab)
- Step 5, Examine frequency-domain HRV (PSD tab)
- Step 6, Export your results
- Configuring the analysis
- Data Formats
- IBI Classification
- Breathing Signal Extraction
- Poincaré Metrics
- Power Spectral Density, method details
- Installation
- Contributing
- License
spectHR is a free, open-source desktop application for Heart Rate Variability (HRV) analysis. It is built for researchers and students who want to move from a raw ECG recording to interpretable HRV metrics without writing any code, and without trusting a black box.
Heart rate variability reflects the beat-to-beat fluctuations in the time between heartbeats. These fluctuations are regulated by the autonomic nervous system: higher HRV generally indicates flexible, healthy regulation; lower HRV is associated with stress, disease, or fatigue. By analysing the power in different frequency bands of the IBI series, spectHR lets you separate the parasympathetic (HF) and sympathetic/parasympathetic (LF) contributions to heart rate control in each named epoch of your recording.
The key principle behind spectHR is that you remain in control of data quality. Every step that could go wrong, R-peak detection, noisy intervals, epoch boundaries, is shown to you visually and can be corrected before any metrics are computed.
The heart does not beat at a perfectly regular rate. Even in a healthy person sitting quietly, the interval between consecutive heartbeats varies continuously, typically over a range of tens to hundreds of milliseconds. This variation, heart rate variability, is not noise. It is the result of a continuous, dynamic interplay between two branches of the autonomic nervous system (ANS): the sympathetic branch, which tends to increase heart rate and mobilise energy, and the parasympathetic branch, which tends to slow the heart and promote recovery.
The primary pathway for parasympathetic control of the heart runs through the vagus nerve. Vagal activity produces rapid, moment-to-moment fluctuations in heart rate, particularly those linked to breathing, the heart speeds up slightly during inhalation and slows during exhalation. This coupling between respiration and heart rate is called respiratory sinus arrhythmia (RSA). Sympathetic influences are slower, taking several seconds to propagate through the circulatory system, and are more closely linked to vasomotor tone and blood pressure regulation.
Because the two branches operate at different speeds, spectral analysis of the heartbeat interval series separates them by frequency: fast (e.g., respiratory-induced) fluctuations appear in the high-frequency band; slower vasomotor fluctuations appear in the low and mid frequency bands. This is the fundamental justification for frequency-domain HRV analysis, it is not merely a signal-processing choice but a reflection of the underlying physiology (Mulder, 1989; Task Force of the European Society of Cardiology, 1996).
The use of HRV in psychophysiological research has a long history. Mulder (1980) demonstrated that mental task performance reduces heart rate variability compared to rest, and that this reduction is particularly pronounced in the mid-frequency band (0.06–0.14 Hz), which reflects baroreceptor-mediated blood pressure regulation. Subsequent work by Mulder & Mulder (1981) formalised the theoretical framework: when a person invests mental effort in a task, sympathetic activation increases and parasympathetic withdrawal follows, leading to a rise in heart rate and a fall in HRV power, especially in the LF band. The relationship is not between task difficulty and HRV per se, but between invested effort and HRV. A person who disengages from a hard task may show little HRV change; a person heavil engaged in an easy task may show a marked decrease (Mulder, 1992).
This framework has been extensively replicated. HRV is consistently lowered by mental effort and mental workload, probably due to sympathetic activation and parasympathetic withdrawal. The pattern generalises across task types and populations: driving (de Waard, 1996; Mulder et al., 2004), aviation (De Rivecourt et al., 2008), air traffic control, and clinical work (Peabody et al., 2023). De Waard's (1996) systematic evaluation of seven driving studies found that the 0.10 Hz HRV component was sensitive to fine-grained changes in task complexity, and notably that it was more sensitive to task-related effort than to changes in driver state such as fatigue or monotony, further supporting the view that LF HRV indexes invested effort rather than arousal level per se. A recent large-scale driving simulation study with 892 participants (Arutyunova, 2024) re-established the finding that increased cognitive load was accompanied by higher heart rate and lower HRV as measured by RMSSD.
Importantly, the overall cardiovascular pattern under mental effort is coherent: heart rate increases, HRV decreases, blood pressure rises, and baroreflex sensitivity falls (Mulder, 1992). This consistency across multiple physiological channels, not just HRV alone, gives the framework its strength. HRV is most informative when interpreted alongside mean heart rate and, where available, blood pressure and respiratory signals.
The word stress appears constantly in the HRV literature, but it is used in at least two very different senses that are easily conflated. This distinction is not merely semantic, it has real consequences for how HRV data should be interpreted.
Stress as a physiological state is the body's response to demand. Selye's original definition, the non-specific response of the body to any demand for change, refers to a biological process: activation of the hypothalamic–pituitary–adrenal axis, release of cortisol and catecholamines, and the corresponding autonomic shifts that HRV reflects. In this sense, HRV is a legitimate biomarker of stress load on the system.
Stress as a perceived social construct is something different. When people say they "feel stressed", they are reporting an appraisal, a subjective evaluation that the demands placed on them exceed their resources. This appraisal depends on personality, context, social support, prior experience, and a host of factors that have nothing to do with the objective difficulty of the task or the physiological state of the ANS. Two people performing the same task under the same conditions can have very different stress experiences while showing similar HRV changes, or vice versa.
HRV does not measure perceived stress. It measures a physiological state, specifically, the balance of autonomic nervous system activity, that may or may not correspond to what a person calls "stress". An environmental demand translates both into psychological responses (self-appraisal or perception) and biological responses in the body, and these are mediated by a complex interplay of nervous, endocrine, and immune mechanisms. The psychological response and the biological response are related but not identical, and the gap between them is where individual differences, coping strategies, and social context operate.
Several reviews have documented this gap empirically. The utility of HRV for characterising psychological stress is primarily impacted by methodological considerations such as study populations, the nature of experienced versus induced stress, and the method of stress assessment. Across 15 studies meeting rigorous methodological criteria, RMSSD was the most consistently associated metric, but effect sizes and directions varied substantially between populations and stressor types. At present, there is no universally recognised standard for stress evaluation, and the search for stress biomarkers remains a challenging task because of the lack of consensus on the definition of stress.
The practical implication for HRV researchers is this: HRV changes reflect the physiological cost of effort and demand, not the experience of stress. A participant who reports high stress on a questionnaire while showing normal HRV may be coping effectively; a participant who reports low stress while showing suppressed HRV may be under-reporting or physiologically reactive. Neither pattern is wrong, they are simply measuring different things. Treating HRV as a direct readout of "how stressed someone is" conflates these levels and can lead to circular or misleading conclusions.
The CARSPAN tradition, which spectHR inherits, has always been careful about this. Mulder's framework uses the term mental effort or mental workload, defined as invested resources in response to task demands, rather than stress. The physiological changes HRV captures are understood as the cost of that investment, not as an emotion or an appraisal. This framing is more tractable for experimental research because effort can be manipulated (via task difficulty and incentives) independently of the subjective experience of stress.
The spectral content of HRV is distributed across three bands that reflect different regulatory processes (Mulder, 1989; Mulder, 1988):
Very low frequency (VLF, 0.02–0.06 Hz) reflects slow regulatory processes including thermoregulation, hormonal rhythms, and gradual adaptation to sustained task demands. Reliable estimation of VLF power requires recordings of at least 5 minutes and preferably longer. Some authors caution against interpreting VLF from short recordings.
Low / mid frequency (LF, 0.06–0.14 Hz) reflects oscillatory fluctuations in blood pressure arising from baroreceptor regulation of vasomotor tone. This band is the most consistently sensitive to mental workload in the Mulder tradition: Mulder and Mulder (1981) found that spectral power between 0.06 and 0.14 Hz was related to the dynamic control of mean arterial blood pressure, and that under mental load this band was particularly affected, contributing about 80% to the total decrease in spectral energy. Baroreflex sensitivity, the gain of the closed-loop blood pressure control system, also decreases under mental load, which helps explain why LF power drops.
High frequency (HF, 0.14–0.40 Hz) reflects respiratory sinus arrhythmia and is primarily parasympathetically mediated. It is sensitive to both breathing rate (which must remain within the HF band for it to be correctly measured) and parasympathetic tone. HF power decreases under mental effort, but the effect is less specific than the LF effect because any change in breathing pattern, rate, depth, regularity, will alter HF power independently of ANS state.
The LF/HF ratio is sometimes used as a sympatho-vagal balance index. Its interpretation is contested (Billman, 2013), and Mulder's tradition generally prefers absolute band power normalised by mean heart rate (the mMI² metric), which removes the confound of mean heart rate level.
A simple measure like mean heart rate or RMSSD captures something real about autonomic state, but it collapses all the frequency-specific information into a single number. Spectral analysis preserves that frequency structure, allowing the researcher to ask: how much of the variability is coming from the LF band (baroreceptor regulation, sensitive to effort) versus the HF band (respiratory coupling, sensitive to breathing and vagal tone)?
The CARSPAN approach, which spectHR implements, represents the heart rate signal as a series of unit impulses at R-peak times, the Integral Pulse Frequency Modulation (IPFM) model. This model, developed by Rompelman (1985) and formalised for spectral analysis by Mulder (1988), has the advantage that the DFT can be computed directly on the event times without resampling to a uniform grid. This matters because resampling introduces artefacts that are especially problematic in short segments and at the boundaries of frequency bands.
Spectral analysis of HRV is most informative when the following conditions hold: the recording is long enough relative to the frequency of interest (at least 10 cycles per band), the IBI series is free of artefacts, the participant is not talking or moving heavily (both of which corrupt the signal), and the analysis epochs correspond to clearly defined task conditions.
A few things are worth bearing in mind when interpreting spectHR output:
Recording length matters. The frequency resolution of the spectrum is
Artefacts are critical. A single missed or spurious R-peak can produce an IBI value two or three times the normal range, introducing broadband spectral energy that swamps the genuine HRV signal (Mulder, 1988). This is why spectHR shows every detected peak and requires the user to verify the IBI series before computing any metrics. The variance added by one prolonged IBI can equal the variance of the entire remaining series, a point made explicitly in the CARSPAN manual and the reason artefact correction is treated as a first-class step rather than an afterthought.
Normalise by mean heart rate. Absolute spectral power in ms² is proportional to mean IBI squared, so it increases at lower heart rates. The CARSPAN mMI² normalisation divides by the squared mean heart rate, making values comparable across sessions, participants, and conditions with different resting heart rates. spectHR applies this normalisation automatically when the CARSPAN PSD method is selected.
HRV is one signal among many. The most reliable conclusions come from a convergent pattern across heart rate, HRV, and when available, blood pressure and respiration. A decrease in LF HRV that is accompanied by an increase in heart rate and a decrease in baroreflex sensitivity is a much stronger indicator of increased effort than an isolated HRV change. Stuiver and Mulder (2014) demonstrated exactly this: across an ambulance dispatch simulation and a driving simulator study, the cardiovascular response was consistently a combination of an initial defence reaction followed by compensatory blood pressure control via the baroreflex, and this full pattern was more diagnostically useful than any single measure in isolation. Interpreting heart rate alone, for example, can be misleading because the initial sympathetic increase in HR is often reversed by baroreflex compensation during sustained load, producing a decrease in HR even as mental effort remains high.
- Launch the application. On first run it creates a default workspace pointing to your Documents folder.
- Open WorkSpace → Edit Workspace to point spectHR at the folder where your data files live.
- Your files appear in the tree on the left. Click one to load it.
- Work through the tabs from left to right: clean the ECG, define your epochs, then read the results.
The window is divided into two areas. On the left is a narrow file tree listing all datasets in your configured data folder. On the right is the main analysis area, organised into six tabs:
| Tab | What you do there |
|---|---|
| Preprocessing | Verify and correct R-peak detection |
| IBI Series | Review the heart rate time course |
| Poincaré | Explore beat-to-beat dynamics visually |
| Epochs | Draw and adjust your analysis segments |
| PSD | Read the frequency-domain power spectrum per epoch |
| Parameters | See all HRV metrics in a table and export to CSV |
This is the most important step. The quality of every metric downstream depends entirely on whether the R-peaks have been detected correctly.
When you select a file, spectHR loads the ECG, finds R-peaks automatically, and displays everything in the Preprocessing tab. The main plot shows the raw ECG signal in red. Every detected R-peak is marked with a vertical coloured line, and the IBI (in milliseconds) is printed as an arrow between consecutive peaks. A colour code immediately tells you which beats look suspicious, see IBI Classification for the full scheme.
If a breathing signal is available from the device's accelerometer, it appears as a green curve overlaid on the ECG. Light-blue shading marks inhalation phases.
Below the main ECG is a thumbnail strip showing the entire recording. The navigation bar at the bottom lets you jump to the next or previous abnormal beat, pan, and zoom.
When you spot a problem, use the mode selector:
- Drag, shift a peak line to its correct position.
- Add, click anywhere on the ECG to insert a missing peak.
- Remove, click a peak line to delete a spurious detection.
All changes are saved automatically to the cache file when you leave the tab.
Tip: Right-clicking a file gives you Reload Raw, Invert ECG Polarity, and Retrigger ECG.
Once the peaks look correct, switch to the IBI Series tab to see heart rate over time in beats per minute. If a breathing signal is available it is shown as a faint green overlay.
HRV metrics are always computed within named segments. The Epochs tab shows a Gantt-style chart. If your recording contains marker events, epochs are built automatically. You can also add epochs manually via Actions → Add Epoch and trim them by dragging their edges.
Any change here immediately updates the Poincaré plot, the PSD plots, and the metrics table.
The Poincaré tab shows a scatter plot where each point represents one heartbeat: its IBI on the x-axis and the following IBI on the y-axis. A healthy autonomic system produces a characteristic elliptical cloud elongated along the diagonal.
The short axis (SD1) reflects rapid, beat-to-beat variability; the long axis (SD2) reflects slower variability. Each active epoch is drawn in a different colour with its own ellipse overlaid.
A note on SD1 and SD2: SD1 and SD2 carry no statistical information beyond RMSSD and SDNN respectively. Van Roon et al. (2025) demonstrate this rigorously: SD1
$= \text{RMSSD}/\sqrt{2}$ by definition, and SD2 follows algebraically from SDNN and RMSSD. spectHR reports them because they are widely expected in the literature and because the Poincaré plot is a useful visual summary, but users should not treat SD1 and SD2 as independent metrics alongside RMSSD and SDNN in statistical analyses.van Roon, A.M., Span, M.M., Lefrandt, J.D., & Riese, H. (2025). Overview of mathematical relations between Poincaré plot measures and time and frequency domain measures of heart rate variability. Entropy, 27(8), 861. https://doi.org/10.3390/e27080861
The PSD tab shows one power spectrum per active epoch, stacked vertically. Three frequency bands are shaded:
- VLF (0.02–0.06 Hz), slow regulatory processes; requires long recordings.
- LF (0.06–0.14 Hz), baroreflex, mixed sympathetic/parasympathetic.
- HF (0.14–0.40 Hz), respiratory sinus arrhythmia, parasympathetic tone.
The shaded grey band is the confidence interval (see Confidence intervals).
Three PSD methods are available, selected in WorkSpace → Edit Parameters. The method takes effect immediately without restarting.
The Parameters tab shows a table with one row per epoch:
- Time-domain: count, mean, median, min, max, std, RMSSD, SDNN, SDSD
- Poincaré: SD1, SD2, SD2/SD1, ellipse area
- Frequency-domain: VLF, LF, HF power and LF/HF ratio
- ms² when using Welch or Lomb-Scargle
- mMI² when using the CARSPAN method
Click Save to export to CSV.
All parameters are stored in a JSON workspace file, editable through the application menus.
WorkSpace → Edit Workspace changes the three folder paths (data, cache, export).
WorkSpace → Edit Parameters covers:
- Frequency Analysis, PSD method, band edges and colours, method-specific parameters, CI level.
- IBI Classification, window length, threshold multiplier, TL ceiling.
- ECG Preprocessing, high-pass filter settings.
Changes take effect immediately and are saved to disk.
spectHR reads .xdf files from LabStreamingLayer, designed for use with the Polar H10 via PolarBLE. Streams are identified automatically. Epoch markers follow start <label> / stop <label> or end <label> conventions.
The plain-text RR-interval export format from the Polar app. See ExampleData/.
CARSPAN event files. If an .nff file with the same base name is present, spectHR loads the ECG channel from it.
After R-peak detection, each inter-beat interval is classified before any metrics are computed. The beat colour in the ECG plot reflects its label:
| Label | Meaning | Colour |
|---|---|---|
| N | Normal, within the expected range | Blue |
| S | Short, below the lower threshold | Magenta |
| L | Long, above the upper threshold | Cyan |
| TL | Too Long, exceeds the absolute ceiling; excluded from all metrics | Orange |
| SL | Short followed immediately by Long | Turquoise |
| SNS | Short-Normal-Short triplet | Light sea green |
| T | Degenerate (NaN or zero duration); excluded from all metrics | , |
Note
Terminology: The CARSPAN documentation occasionally uses the term Energy where Power is the correct term. spectHR uses Power consistently throughout.
Note
Let
| Condition | Label |
|---|---|
| TL (excluded from all statistics) | |
|
|
T (excluded from all statistics) |
| L | |
| S | |
| beat |
SL |
| beat |
SNS |
| otherwise | N |
Default parameters (all configurable in Edit Parameters):
| Parameter | Default | JSON key |
|---|---|---|
| Window length |
51 beats | window_length |
| Threshold |
4.0 std | n_std |
| TL ceiling |
2.0 s | max_ibi_sec |
Users familiar with CARSPAN will notice several differences in the classification approach. Each is a deliberate design choice.
CARSPAN enforces a hardware refractory period min_peak_distance_ms parameter passed to scipy.signal.find_peaks. Any two candidate peaks closer than 300 ms simply cannot both be detected.
This approach prevents the false detection from entering the data in the first place. The effect on the classified IBI series is identical.
CARSPAN computes its running statistics over a causal (backward-looking) window of
A centred window produces more stable thresholds at condition boundaries, precisely where accurate classification is most important in psychophysiological research. A causal window adapts its threshold only after a heart rate change has occurred, which can flag the first beats of a new condition incorrectly.
CARSPAN's window is defined in seconds; spectHR's in beats. For a resting heart rate of ~70 bpm, 51 beats ≈ 44 seconds, close to CARSPAN's default of 60 seconds. A beat-based window always contains the same number of statistical observations regardless of heart rate.
CARSPAN also flags a beat if the difference between consecutive intervals (
CARSPAN clips the standard deviation used for thresholding to a minimum of 5 % and a maximum of 15 % of the local mean IBI. spectHR relies instead on the user's choice of n_std and max_ibi_sec. The absolute ceiling guards the upper extreme; the 300 ms minimum peak distance guards the lower extreme.
CARSPAN automatically corrects detected artefacts by linear interpolation, inserting estimated beats and adding normally-distributed noise to prevent variance reduction. spectHR does not perform automatic correction. Every flagged beat is shown in the Preprocessing tab and can be corrected manually. Intervals left uncorrected and labelled TL or T are excluded from all metric calculations. This reflects spectHR's core principle: you, not the algorithm, decide what to do with each artefact.
When a Polar H10 accelerometer stream is present, spectHR derives a respiration surrogate from the 3-axis chest-belt movement data by removing the gravity component, bandpassing to 0.10–0.70 Hz, and applying PCA to extract the dominant axis of motion as a single 1-D signal. The result is z-score normalised and overlaid in green on the ECG and heart rate plots. Inhalation phases are shaded in light blue.
SD1, beat-to-beat variability, equal to
SD2, longer-term variability, algebraically related to SDNN and RMSSD:
SD2/SD1, autonomic balance index.
Ellipse area
Important: SD1 and SD2 are fully determined by RMSSD and SDNN and therefore carry no additional statistical information (van Roon et al., 2025). Including all four in a statistical model introduces redundancy.
The IBI series (in ms) is resampled onto a uniform grid using linear interpolation, divided into overlapping segments, windowed, Fourier-transformed, and averaged. Averaging over segments reduces variance at the cost of frequency resolution. Output units: ms²/Hz; band power in ms².
Note
Let scipy.signal.welch is called with scaling='density', returning the one-sided PSD in ms²/Hz.
Band power
For
Default parameters (configurable in Edit Parameters):
| Parameter | Default | JSON key |
|---|---|---|
| Resampling frequency | 4 Hz | fs |
| Segment length | 256 samples | nperseg |
| Overlap | 128 samples | noverlap |
| FFT length | same as nperseg |
nfft |
| Window | Hamming | window |
Note on resampling: The 4 Hz resampling rate gives a frequency resolution of nperseg, the segment length is reduced to the number of available samples and overlap is halved automatically.
The Lomb-Scargle method evaluates the spectrum directly at the original, irregularly-spaced beat timestamps, no resampling required. The mean IBI is subtracted before estimation to suppress the DC component. Output units: ms²/Hz; band power in ms².
Note
Let nfreqs equally spaced points. The periodogram scipy.signal.lombscargle with normalize=False and scaled to a power density:
where
Confidence intervals use the Scargle (1982) effective degrees of freedom:
This accounts for the adaptive frequency resolution of Lomb-Scargle compared to the regular DFT grid.
Default parameters (configurable in Edit Parameters):
| Parameter | Default | JSON key |
|---|---|---|
| Number of frequency points | 1000 | nfreqs |
| Lower frequency floor | 0.0001 Hz | fmin_floor |
The CARSPAN method implements the direct Discrete Fourier Transform on R-peak event times, following the algorithm described by Mulder (1988) and used in the CARSPAN software package. No resampling is performed. The spectrum is computed on the native frequency grid
Note
Following Rompelman (1985) and Mulder (1988), the heart rate signal is represented as a series of unit impulses at the R-peak occurrence times
This is the Integral Pulse Frequency Modulation (IPFM) model representation. The spectrum of this series reflects heart rate variability, not IBI variability directly. CARSPAN normalises out the mean heart rate afterwards (formula 3.20) to make the two equivalent.
Assuming periodicity outside the analysis segment
where
Deviation from CARSPAN: In CARSPAN, formula 3.19 uses
The native grid runs from
The native spectrum is interpolated onto a fixed display grid with step freq_resolution (default 0.01 Hz). A finer value produces a smoother curve; a coarser value shows the raw native lines more directly. Band power values are never affected by freq_resolution.
Following the CARSPAN manual (§3.3, pre-algorithm choices):
"a moving average window over three frequency points (0.03 Hz bandwidth) is applied before plotting the spectral functions"
When smooth_for_display = True (the default), a 3-point unweighted moving average is applied to the interpolated display spectrum before it is shown. The same passage also states:
"No smoothing of the spectra is carried out on the spectra before computing the spectral band values"
Accordingly, smoothing is applied only in the display path; band power is always computed from the unsmoothed native grid.
Band power in
This is a rectangular (Riemann) summation, matching CARSPAN exactly. spectHR uses trapezoidal integration for Welch and Lomb-Scargle band power; only the CARSPAN back-end uses rectangular summation to match formula 3.28.
Important: Because freq_resolution, band power values are completely independent of the display resolution setting.
The raw spectrum is in units of events²/Hz. To make it dimensionless and independent of mean heart rate, it is normalised by the squared mean of the R-peak event series. For the unit-impulse representation, the mean equals the mean heart rate
Multiplication by
Implementation note on units: The normalisation formula divides by mean_ibi_sec = mean(ibi_ms) / 1000 and then applies power_raw * mean_ibi_sec² * 1e6. A common error is to use mean_ibi_ms² instead, which would make the result
Default parameters (configurable in Edit Parameters):
| Parameter | Default | JSON key | Effect |
|---|---|---|---|
| Display grid resolution | 0.01 Hz | freq_resolution |
Smoothness of displayed curve; does not affect band power |
| Tapering window | hann |
window |
Any scipy.signal.get_window name |
| 3-point display smoothing | true |
smooth_for_display |
Matches CARSPAN plot convention |
spectHR adds confidence intervals to all three PSD methods. CARSPAN itself does not compute CIs, this is a spectHR extension. The CI reflects how much the spectral estimate would vary if the measurement were repeated under identical conditions.
All three methods use a chi-square CI of the form:
The difference lies in how the degrees of freedom
Note
Welch:
Lomb-Scargle:
CARSPAN: Each native DFT line
so freq_resolution) is supported by approximately
For a 5-minute recording with the default 0.01 Hz resolution:
A useful consequence: the CI width is directly controlled by freq_resolution. A coarser grid (larger step) averages more native lines per display point, narrowing the CI. A finer grid (smaller step) places each display point between native lines, widening the CI. The CARSPAN manual itself notes (§3.3) that this integration over the fixed output grid is the only factor that increases the reliability of each spectral point.
CARSPAN does not display CIs. The manual states explicitly: "No statistical analyses are performed by CARSPAN." The CI shown in spectHR is an addition, intended to make the uncertainty of the direct DFT estimate visible.
All three methods share the same configurable band definitions:
| Band | Default range | Reflects |
|---|---|---|
| VLF | 0.02–0.06 Hz | Slow regulatory processes; requires long recordings |
| LF | 0.06–0.14 Hz | Baroreceptor reflex, mixed sympathetic/parasympathetic |
| HF | 0.14–0.40 Hz | Respiratory sinus arrhythmia, parasympathetic tone |
Band edges are configurable in Edit Parameters. If your participants breathe slowly, you may need to extend the HF band to lower frequencies.
| Method | PSD unit | Band power unit | Normalised by mean HR? |
|---|---|---|---|
| Welch | ms²/Hz | ms² | No |
| Lomb-Scargle | ms²/Hz | ms² | No |
| CARSPAN | mMI²/Hz | mMI² | Yes, |
Welch and Lomb-Scargle ms² values scale with mean IBI and should be treated with caution when comparing groups or conditions that differ in resting heart rate. CARSPAN mMI² values are dimensionless and largely heart-rate independent.
Download spectHR-Windows-vX.Y.Z.zip from the Releases page, extract, and run spectHR.exe. No Python installation is required.
Download spectHR-macOS-vX.Y.Z.zip from the Releases page and extract spectHR.app. Drag it to /Applications. Because the app is not signed by Apple, macOS will block it the first time. Right-click spectHR.app in Finder, choose Open, and click Open in the dialog. Alternatively run xattr -dr com.apple.quarantine /Applications/spectHR.app in a Terminal.
spectHR is written in pure Python. The analysis library (src/spectHR/) and the GUI (src/spectUI/) are kept separate so the library can be used independently in scripts.
New HRV metrics can be added by decorating a method with @hrv_metric in CardioSeries, it will appear in the Parameters table and CSV automatically.
New file formats can be added by registering a loader function with @register_loader(".ext") in src/spectHR/DataSet/loaders/.
Fork the repository and open a pull request with a clear description of the change.
spectHR is released under the GNU LGPL-2.1 license. See the LICENSE file for details.
Billman, G.E. (2013). The LF/HF ratio does not accurately measure cardiac sympatho-vagal balance. Frontiers in Physiology, 4, 26. https://doi.org/10.3389/fphys.2013.00026
De Rivecourt, M., Kuperus, M.N., Post, W.J., & Mulder, L.J.M. (2008). Cardiovascular and eye activity measures as indices for momentary changes in mental effort during simulated flight. Ergonomics, 51, 1295–1319. https://doi.org/10.1080/00140130802120267
de Waard, D. (1996). The measurement of drivers' mental workload. Ph.D. Thesis, University of Groningen.
Grossman P, Ackland GL, Allen AM, Berntson GGB, Booth LC, Burghardt GM, Buron J, Dinets V, Doody JS, Dutschmann M, Farmer DGS, Fisher JP, Gourine AV, Joyner MJ, Karemaker JM, Khalsa SS, Lakatta EG, Leite CAC, Macefield VG, Machado BH, Machado RM, Menuet C, Mendelowitz D, Moraes DJA, Neuhuber W, Ottaviani MM, Paterson DJ, Paton JFP, Pellegrino PR, Ramchandra R, Shanks J, Schwaber JS, Shivkumar K, Spyer KM, Taylor EW, Taylor JA, Wang T, Yao ST, Zucker IH. Why The Polyvagal Theory Is Untenable: An international expert evaluation of the polyvagal theory and commentary upon Porges, S.W. (2025). Polyvagal theory: current status, clinical applications, and future directions. Clin. Neuropsychiatry, 22(3), 169-184. Clin Neuropsychiatry. 2026 Feb;23(1):100-112. doi: 10.36131/cnfioritieditore20260110. PMID: 41768017; PMCID: PMC12937499.
Mulder, G. (1980). The heart of mental effort. Ph.D. Thesis, University of Groningen.
Mulder, L.J.M. (1988). Assessment of cardiovascular reactivity by means of spectral analysis. Ph.D. Thesis, University of Groningen.
Mulder, L.J.M. (1992). Measurement and analysis methods of heart rate and respiration for use in applied environments. Biological Psychology, 34, 205–236. https://doi.org/10.1016/0301-0511(92)90016-N
Mulder, L.J.M. (1989). Cardiovascular reactivity and mental workload. International Journal of Psychophysiology, 7, 321.
Mulder, L.J.M., de Waard, D., & Brookhuis, K.A. (2004). Estimating mental effort using heart rate and heart rate variability. In N.A. Stanton, A. Hedge, K. Brookhuis, E. Salas, & H. Hendrick (Eds.), Handbook of Human Factors and Ergonomics Methods (pp. 20.1–20.8). Boca Raton: CRC Press.
Peabody, J.E., Ryznar, R., Ziesmann, M.T., & Gillman, L. (2023). A systematic review of heart rate variability as a measure of stress in medical professionals. Cureus, 15(1), e34345. https://doi.org/10.7759/cureus.34345
Rompelman O. (1985) Spectral analysis of heart-rate variability, In: J.F. Orlebeke, G. Mulder and L.J.P. van Doornen (eds.) Psychophysiology of cardiovascular control (pp. 315-331). New York: Plenum Press.
Stuiver, A., & Mulder, B. (2014). Cardiovascular state changes in simulated work environments. Frontiers in Neuroscience, 8, 399. https://doi.org/10.3389/fnins.2014.00399
Task Force of the European Society of Cardiology and the North American Society of Pacing and Electrophysiology (1996). Heart rate variability: standards of measurement, physiological interpretation and clinical use. Circulation, 93(5), 1043–1065. https://doi.org/10.1161/01.CIR.93.5.1043
Tegegne, B., Man, T., van Roon, A., Riese, H., & Snieder, H. (2019). To the Editor: 10-second ECG-based RMSSD as valid measure of HRV. Heart Rhythm, 16(3), e35. https://doi.org/10.1016/j.hrthm.2018.10.038
van Roon, A.M., Span, M.M., Lefrandt, J.D., & Riese, H. (2025). Overview of mathematical relations between Poincaré plot measures and time and frequency domain measures of heart rate variability. Entropy, 27(8), 861. https://doi.org/10.3390/e27080861
Arutyunova, K.R., Bakhchina, A.V., Konovalov, D.I., Margaryan, M., Filimonov, A.V., & Shishalov, I.S. (2024). Heart rate dynamics for cognitive load estimation in a driving simulation task. Scientific Reports, 14, 31656. https://doi.org/10.1038/s41598-024-79728-x