epyr.signalprocessing.frequency_analysis

Frequency Analysis for Time-Domain EPR Signals

Comprehensive FFT-based frequency analysis with support for: - 1D time-domain signals (Rabi, DEER, echo decay, etc.) - 2D time-domain data with row-by-row 1D FFT processing - 2D HYSCORE-type measurements with full 2D FFT

Includes DC offset removal and apodization windows for clean spectral analysis.

Functions

analyze_frequencies(time_data, signal_data)

FFT-based frequency analysis of time-domain EPR signals.

analyze_frequencies_2d(time_data, signal_data)

FFT-based frequency analysis of 2D time-domain EPR signals.

demo()

Simple demonstration of EPR FFT analysis.

power_spectrum(time_data, signal_data[, ...])

Calculate power spectral density using Welch or periodogram methods.

spectrogram_analysis(time_data, signal_data)

Time-frequency analysis using spectrogram.

epyr.signalprocessing.frequency_analysis.analyze_frequencies(time_data, signal_data, window='hann', window_alpha=None, zero_padding=2, remove_dc=True, plot=True, freq_range=None, **plot_kwargs)[source]

FFT-based frequency analysis of time-domain EPR signals.

This function performs clean FFT analysis to identify frequency components in time-dependent EPR signals, with proper DC offset removal.

Parameters:

time_datanp.ndarray

Time axis data (in ns, μs, or s)

signal_datanp.ndarray

EPR signal intensity vs time

windowstr or None, optional

Apodization window type (‘hann’, ‘hamming’, ‘blackman’, ‘kaiser’, None) Default: ‘hann’

window_alphafloat, optional

Alpha parameter for Kaiser, Gaussian windows (default: 6 for Kaiser)

zero_paddingint, optional

Zero padding factor (2 = double length, 4 = quadruple, etc.) Default: 2

remove_dcbool, optional

Remove DC offset before analysis (recommended: True)

plotbool, optional

Generate analysis plots. Default: True

freq_rangetuple of float, optional

Frequency range (min, max) to display in plots

Returns:

dict

Analysis results containing: - ‘frequencies’: Frequency axis in appropriate units - ‘power_spectrum’: Power spectral density (normalized) - ‘phase_spectrum’: Phase spectrum - ‘dominant_frequencies’: List of peak frequencies - ‘time_data’: Original time data - ‘processed_signal’: Signal after DC removal and windowing - ‘sampling_rate’: Sampling rate in Hz - ‘time_unit’: Detected time unit - ‘freq_unit’: Frequency unit

Examples:

>>> from epyr import eprload
>>> from epyr.signalprocessing import analyze_frequencies
>>>
>>> # Load Rabi data
>>> time, signal, params, _ = eprload('rabi_data.DTA')
>>> result = analyze_frequencies(time, signal, window='hann', plot=True)
>>> print(f"Dominant frequency: {result['dominant_frequencies'][0]:.3f} MHz")
Parameters:
Return type:

Dict

epyr.signalprocessing.frequency_analysis.power_spectrum(time_data, signal_data, method='welch', window='hann', nperseg=None, overlap=0.5, remove_dc=True, plot=True)[source]

Calculate power spectral density using Welch or periodogram methods.

Parameters:

time_datanp.ndarray

Time axis data

signal_datanp.ndarray

Signal data

methodstr

Method: ‘welch’ or ‘periodogram’

windowstr

Window function for Welch method

npersegint, optional

Length of each segment for Welch method

overlapfloat

Overlap fraction for Welch method (0-1)

remove_dcbool

Remove DC offset before analysis

plotbool

Generate plots

Returns:

dict

Results with frequencies and power spectrum

Parameters:
Return type:

Dict

epyr.signalprocessing.frequency_analysis.spectrogram_analysis(time_data, signal_data, window='hann', nperseg=None, overlap=0.8, remove_dc=True, plot=True)[source]

Time-frequency analysis using spectrogram.

Parameters:

time_datanp.ndarray

Time axis data

signal_datanp.ndarray

Signal data

windowstr

Window function

npersegint, optional

Length of each segment

overlapfloat

Overlap fraction (0-1)

remove_dcbool

Remove DC offset

plotbool

Generate spectrogram plot

Returns:

dict

Results with time axis, frequencies, and spectrogram

Parameters:
Return type:

Dict

epyr.signalprocessing.frequency_analysis.analyze_frequencies_2d(time_data, signal_data, mode='row_by_row', window='hann', window_alpha=None, zero_padding=2, remove_dc=True, axis=1, plot_result=False, freq_range=None, **plot_kwargs)[source]

FFT-based frequency analysis of 2D time-domain EPR signals.

This function handles 2D EPR data with two processing modes: 1. Row-by-row 1D FFT: Process each row/column independently (e.g., 2D Rabi) 2. Full 2D FFT: Process both dimensions together (e.g., HYSCORE)

Parameters:

time_datanp.ndarray or tuple of np.ndarray

Time axis data. Can be: - Single 1D array: time axis for the FFT dimension - Tuple of two 1D arrays: (time_axis1, time_axis2) for 2D FFT

signal_datanp.ndarray

2D EPR signal intensity array (shape: n_traces x n_points)

modestr, optional

Processing mode: - ‘row_by_row’: Apply 1D FFT to each row/column independently - ‘full_2d’: Apply 2D FFT to entire dataset (HYSCORE-type) Default: ‘row_by_row’

windowstr or None, optional

Apodization window type. Default: ‘hann’

window_alphafloat, optional

Alpha parameter for Kaiser, Gaussian windows

zero_paddingint, optional

Zero padding factor. Default: 2

remove_dcbool, optional

Remove DC offset before analysis. Default: True

axisint, optional

Axis to process for row_by_row mode (0=columns, 1=rows). Default: 1

plot_resultbool, optional

Generate analysis plots. Default: False

freq_rangetuple of float, optional

Frequency range (min, max) to display in plots

Returns:

For mode=’row_by_row’:
fqnp.ndarray

Frequency axis (1D array)

axis2np.ndarray

Secondary axis (field, angle, trace index, etc.)

spectrumnp.ndarray

2D FFT spectrum magnitude (n_traces x n_frequencies)

infodict

Analysis information (units, sampling_rate, mode, etc.)

For mode=’full_2d’:
fq1np.ndarray

Frequency axis 1 (1D array)

fq2np.ndarray

Frequency axis 2 (1D array)

spectrumnp.ndarray

2D FFT spectrum magnitude (n_freq1 x n_freq2)

infodict

Analysis information

Examples:

>>> # Row-by-row 1D FFT (2D Rabi oscillations)
>>> x_2d, y_2d, params, _ = eprload('rabi_2d.DTA')
>>> fq, axis2, spectrum, info = analyze_frequencies_2d(
...     x_2d[0], y_2d, mode='row_by_row', plot_result=False)
>>> # Full 2D FFT (HYSCORE)
>>> x_hyscore, y_hyscore, params, _ = eprload('hyscore.DTA')
>>> fq1, fq2, spectrum_2d, info = analyze_frequencies_2d(
...     (x_hyscore[0], x_hyscore[1]), y_hyscore,
...     mode='full_2d', plot_result=True)
Parameters:
Return type:

Tuple

epyr.signalprocessing.frequency_analysis.demo()[source]

Simple demonstration of EPR FFT analysis. Shows clean frequency analysis with DC removal and windowing.