Skip to content

← spectral package

CrossSpectralDensity

Compute the complex multichannel cross-spectral density (CSD) matrix via the multi-taper method.

For each signal stream with space and time axes, emits an S[f, target, source] CSD tensor in which each frequency-slice is a Hermitian positive-definite matrix capturing the pairwise complex spectral relationships between channels. Unit-L2 discrete prolate spheroidal (Slepian) tapers are used, which implies the useful normalization that the zero-lag inverse FFT of the CSD recovers the data auto-covariance matrix. The output is compatible with the Wilson MVAR node, which converts the CSD into a fitted multivariate autoregressive model for downstream dynamical-measure nodes (DTF, dDTF, PDC, ...). Segmented data (input with an instance axis) is handled by computing one CSD per instance; the instance axis is preserved in the output. Non-segmented data produces a single CSD covering the entire time window. More Info... Version 1.0.1

Ports/Properties

data

Data to process.

verbose name
Data
default value
None
port type
DataPort
value type
Packet (can be None)
data direction
INOUT

half_bandwidth_hz

Spectral half-bandwidth (W, in Hz) of each multi-taper estimate. This is the classical Thomson-multitaper parameter expressed in physical units: each taper concentrates energy within +/- W Hz of its center frequency, so the effective spectral smoothing bandwidth is roughly 2 * W Hz. Internally, the time-halfbandwidth product NW = W * segment_length is computed per-segment and governs both the number of usable tapers (~ 2 NW - 1) and the smoothing bandwidth. Typical values are 0.5-3 Hz for EEG; larger values give smoother estimates at the cost of spectral resolution.

verbose name
Half-Bandwidth (Hz)
default value
2.0
port type
FloatPort
value type
float (can be None)

num_tapers

Override the number of tapers. Default is 2 * NW - 1 (where NW = half_bandwidth_hz * segment_length), which retains the tapers that are most concentrated within the chosen bandwidth. Smaller values reduce bias but increase variance; larger values have the opposite effect. Going much above 2*NW-1 picks up poorly-concentrated tapers and is usually not worthwhile.

verbose name
Number Of Tapers
default value
None
port type
IntPort
value type
int (can be None)

nfft

FFT length. If omitted (the default), uses the length of the time axis so that IFFT(S) gives the unbiased lag-0 covariance. Larger values give finer frequency resolution at the cost of computation.

verbose name
Nfft
default value
None
port type
IntPort
value type
int (can be None)

onesided

Return a one-sided spectrum. Most spectral nodes in NeuroPype default to one-sided output for real-valued data; this node defaults to two-sided because that is what the Wilson MVAR factorization (and most spectral-factorization algorithms) require. Enable if you want the one-sided CSD for visualization or if chaining into nodes that expect one-sided input.

verbose name
One-Sided Spectrum
default value
False
port type
BoolPort
value type
bool (can be None)

detrend

Per-segment detrending applied before tapering. 'mean' subtracts the sample mean (removes any DC offset that would otherwise dominate low-frequency bins and leak upward); 'linear' additionally removes a best-fit straight line (removes slow baseline drift). 'none' skips detrending and uses the raw samples. 'mean' is a safe default for most EEG work and catches the most common failure mode where an un-removed baseline offset corrupts the spectrum near DC.

verbose name
Per-Segment Detrending
default value
mean
port type
EnumPort
value type
str (can be None)

segment_length_sec

Welch-style sub-segment length, in seconds. When set, each input time window is split into (possibly overlapping) sub-segments of this length, a multitaper CSD is computed per sub-segment, and the per-segment CSDs are averaged. This gives dramatically better conditioning on long continuous data (tens of independent spectral observations per frequency bin versus ~ 2NW-1 from a single-segment multitaper) at the cost of frequency resolution (= 1 / segment_length). Leave unset (None, the default) to treat the entire input time window as a single segment. When the input already has an instance axis (trial-segmented data), sub-segmenting is applied within* each trial independently. A good rule of thumb is to pick segment_length_sec so that each sub-segment comfortably covers your lowest frequency of interest (e.g. 2-4 s for EEG analyses down to ~1 Hz), then let the averaging across sub-segments do its variance-reduction work.

verbose name
Segment Length (S)
default value
None
port type
FloatPort
value type
float (can be None)

segment_overlap

Fractional overlap between adjacent Welch sub-segments, in [0, 1). Only has an effect when segment_length_sec is set. 0.5 (the default) is the common textbook recommendation: it nearly doubles the number of averaged observations relative to non-overlapping segments without materially increasing estimator variance, thanks to the Hann-like concentration of the DPSS tapers.

verbose name
Segment Overlap
default value
0.5
port type
FloatPort
value type
float (can be None)

shrinkage_target

Per-frequency shrinkage target. With 'none' (the default) the raw multi-taper estimate is returned. With 'diagonal', each S(f) is shrunk toward its own diagonal (keeping per-channel power, removing off-diagonal/cross-channel information); with 'scaled_identity', toward tr(S(f)) / n * I (isotropic power, zero cross-terms). Both targets make S(f) full rank and well-conditioned, which helps Wilson-style spectral factorization on short or noisy windows, but note that shrinkage toward any diagonal-structured target is literally shrinking away from the off-diagonal connectivity signal - keep the intensity small or rely on the automatic Ledoit-Wolf estimate.

verbose name
Shrinkage Target
default value
none
port type
EnumPort
value type
str (can be None)

shrinkage_intensity

Per-frequency shrinkage intensity, in [0, 1]. 0 is no shrinkage, 1 replaces S(f) entirely with the target. If left unspecified (None, the default), a Ledoit-Wolf-style estimate of the asymptotically- optimal intensity is computed independently for each frequency bin from the per-taper spectral estimates. Only has an effect when shrinkage_target is not 'none'.

verbose name
Shrinkage Intensity
default value
None
port type
FloatPort
value type
float (can be None)

freq_smoothing_hz

Width (in Hz, full width of a Hann window) of an optional frequency-domain post-smoothing applied to S(f). 0.0 (the default) disables smoothing. Internally this is converted to an odd integer number of bins from the FFT length and sampling rate, so the actual smoothing bandwidth is quantized to the frequency resolution of the estimate. Multi-taper estimation already smooths the spectrum with an effective bandwidth of roughly 2 * half_bandwidth / T_window Hz, so post-smoothing is a secondary tool that decouples smoothing bandwidth from taper count. It is most useful when (a) the time window is too short to increase half_bandwidth further without running out of usable tapers, or (b) a downstream spectral factorization (e.g. WilsonMVAR) is sensitive to sharp spectral peaks and benefits from gentler estimates. Reasonable starting values are in the 0.3-2 Hz range for typical EEG work. If you find yourself needing wide smoothing (a large fraction of your band of interest), prefer increasing half_bandwidth instead - multi-taper smoothing is more statistically efficient per Hz of bandwidth than post-smoothing.

verbose name
Frequency Smoothing (Hz)
default value
0.0
port type
FloatPort
value type
float (can be None)

set_breakpoint

Set a breakpoint on this node. If this is enabled, your debugger (if one is attached) will trigger a breakpoint.

verbose name
Set Breakpoint (Debug Only)
default value
False
port type
BoolPort
value type
bool (can be None)

metadata

User-definable meta-data associated with the node. Usually reserved for technical purposes.

verbose name
Metadata
default value
{}
port type
DictPort
value type
dict (can be None)