API Reference¶
Data loading is handled by the mojito
package (mojito.reader.MojitoL1File). This package focuses exclusively on
the signal processing steps applied to that data.
Signal Processing¶
- class MojitoProcessor.SigProcessing.SignalProcessor(data, fs, t0=None)[source]¶
Bases:
objectSignal processor for multi-channel time series data.
Handles filtering, downsampling, trimming, and windowing while automatically tracking sampling parameters (fs, N, T, dt).
- Parameters:
data (dict) – Dictionary of channel data, e.g., {‘X’: array, ‘Y’: array, ‘Z’: array}
fs (float) – Sampling frequency in Hz
- data¶
Current processed data (updated after each operation). Includes a
't'key giving the time array[t0, t0+dt, ..., t0+(N-1)*dt]in seconds (or[0, dt, ..., (N-1)*dt]whent0isNone).- Type:
dict
- fs¶
Current sampling frequency in Hz
- Type:
float
- N¶
Current number of samples per channel
- Type:
int
- T¶
Current duration in seconds
- Type:
float
- dt¶
Current sampling period in seconds
- Type:
float
- t¶
Time array
[t0, t0+dt, ..., t0+(N-1)*dt]in seconds.- Type:
ndarray
- channels¶
List of channel names
- Type:
list
Example
>>> sp = SignalProcessor({'X': x_data, 'Y': y_data}, fs=4.0) >>> filtered = sp.filter(low=1e-4, high=1.0, order=6) >>> trimmed = sp.trim(fraction=0.02) # Trim 2% total (1% each end) >>> windowed = sp.apply_window(window='tukey', alpha=0.05) >>> t = sp.data['t'] # time array [t0, t0+dt, ..., t0+(N-1)*dt]
- apply_window(window='tukey', **window_params)[source]¶
Apply window function to all channels.
- Parameters:
window (str, optional) – Window type: ‘tukey’, ‘blackmanharris’, ‘hann’, ‘hamming’, ‘blackman’, ‘planck’ (default: ‘tukey’)
**window_params – Additional parameters for window function. For ‘tukey’: alpha (default: 0.05) For ‘planck’: alpha (default: 0.05) Other windows typically don’t need parameters.
- Returns:
windowed_data – Dictionary of windowed channel data
- Return type:
dict
Examples
>>> sp.apply_window('tukey', alpha=0.05) >>> sp.apply_window('blackmanharris') >>> sp.apply_window('hann')
- property data: dict¶
Channel data as a dict, including a
't'key for the time array.The time array is
t0 + np.arange(N) * dt(seconds). Whent0isNone, the array starts from 0.- Returns:
All channel arrays plus
't'.- Return type:
dict
- downsample(target_fs, window=('kaiser', 31.0), padtype='line')[source]¶
Resample all channels to a target sampling rate using polyphase filtering.
Uses
scipy.signal.resample_polywhich applies a zero-phase FIR anti-aliasing filter via polyphase decomposition. Accepts arbitrary rational target rates (e.g., 4 Hz -> 0.4 Hz), unlikedecimatewhich requires an integer factor.- Parameters:
target_fs (float) – Desired output sampling frequency in Hz. Must be positive and less than or equal to the current sampling frequency (this method is a downsampler).
window (tuple or array_like, optional) – Window specification passed to
scipy.signal.resample_polyfor FIR anti-aliasing filter design. Default('kaiser', 5.0)is scipy’s own default and gives good stopband attenuation.padtype (str, optional) – Edge-padding strategy. Options:
'line'(default),'constant','mean','median','maximum','minimum'.'line'extends the signal linearly from each end, reducing edge transients for slowly-varying data such as LISA TDI channels.
- Return type:
Tuple[Dict[str,ndarray],float]- Returns:
resampled_data (dict) – Dictionary mapping channel names to resampled 1D arrays.
new_fs (float) – Actual output sampling frequency in Hz (exact rational result
self.fs * up / down).
- Raises:
ValueError – If
target_fsis not positive.ValueError – If
target_fsexceeds the current sampling frequency.ValueError – If the rational approximation of
target_fs / self.fsproducesup == 0.
Notes
The up/down integers are computed via:
ratio = Fraction(target_fs / self.fs).limit_denominator(10000) up, down = ratio.numerator, ratio.denominator
Common use cases from 4 Hz source data:
4 Hz -> 1 Hz: up=1, down=4
4 Hz -> 0.4 Hz: up=1, down=10
4 Hz -> 2 Hz: up=1, down=2
4 Hz -> 3 Hz: up=3, down=4
Examples
>>> sp = SignalProcessor({'X': x_data, 'Y': y_data}, fs=4.0) >>> sp.filter(low=5e-6, order=2) >>> sp.trim(fraction=0.022) # Trim 2.2% total >>> resampled, new_fs = sp.downsample(target_fs=1.0) >>> print(new_fs) # 1.0
- fft()[source]¶
Compute the one-sided complex FFT spectrum for each channel.
The data is assumed to have already been windowed (e.g. by
apply_window()), so no additional window is applied here. Returns raw complex amplitudes fromnumpy.fft.rfft.- Return type:
Tuple[ndarray,Dict[str,ndarray]]- Returns:
freqs (ndarray) – Frequency array in Hz, shape
(N//2 + 1,).ffts (dict) – Dictionary mapping channel names to complex FFT arrays, each with shape
(N//2 + 1,).
Examples
>>> freqs, ffts = sp.fft() >>> plt.loglog(freqs[1:], np.abs(ffts['X'][1:]))
- filter(*, low=None, high=None, order=2, filter_type='butterworth', zero_phase=True)[source]¶
Apply filter to all channels (auto-detects highpass/lowpass/bandpass).
Automatically determines filter type based on provided cutoff frequencies: - Only low set: highpass filter - Only high set: lowpass filter - Both low and high set: bandpass filter
- Parameters:
low (float, optional) – Lower cutoff frequency in Hz (highpass)
high (float, optional) – Upper cutoff frequency in Hz (lowpass)
order (int, optional) – Filter order (default: 6)
filter_type (str, optional) – Filter type: ‘butterworth’, ‘chebyshev1’, ‘chebyshev2’, ‘bessel’ (default: ‘butterworth’)
zero_phase (bool, optional) – Use zero-phase filtering (filtfilt) if True, else single-pass (default: True)
- Returns:
filtered_data – Dictionary of filtered channel data
- Return type:
dict
- Raises:
ValueError – If neither low nor high is provided
Examples
>>> # Highpass only >>> sp.filter(low=5e-6, order=2) >>> # Lowpass only >>> sp.filter(high=0.1, order=2) >>> # Bandpass >>> sp.filter(low=1e-4, high=0.1, order=6)
- get_params()[source]¶
Get current signal parameters.
- Returns:
params – Dictionary containing fs, N, T, dt, and channels
- Return type:
dict
- periodogram()[source]¶
Compute the one-sided power spectral density for each channel.
The data is assumed to have already been windowed (e.g. by
apply_window()), so no additional window is applied here.Normalisation follows Parseval’s theorem: the integral of the one-sided PSD over positive frequencies equals the mean square of the signal.
- Return type:
Tuple[ndarray,Dict[str,ndarray]]- Returns:
freqs (ndarray) – Frequency array in Hz, shape
(N//2 + 1,).psds (dict) – Dictionary mapping channel names to one-sided PSD arrays (units²/Hz), each with the same shape as
freqs.
Examples
>>> freqs, psds = sp.periodogram() >>> plt.loglog(freqs[1:], psds['X'][1:])
- property t: ndarray¶
Time array
[t0, t0+dt, ..., t0+(N-1)*dt]in seconds.
- to_aet()[source]¶
Transform XYZ Michelson channels to noise-orthogonal AET channels.
Uses the standard equal-arm combination:
A = (Z - X) / sqrt(2) E = (X - 2Y + Z) / sqrt(6) T = (X + Y + Z) / sqrt(3)
Returns a new
SignalProcessorwith channels['A', 'E', 'T'], inheritingfs,t0, and all derived parameters from the original.- Returns:
New processor with AET channel data.
- Return type:
- Raises:
ValueError – If any of the channels
'X','Y','Z'are missing.
Examples
>>> sp_xyz = processed_segments['segment0'] >>> sp_aet = sp_xyz.to_aet() >>> freqs, psds = sp_aet.periodogram()
- trim(fraction)[source]¶
Trim data by removing a fraction of the dataset.
- Parameters:
fraction (float) – Total fraction of data to remove (e.g., 0.01 = 1%).
- Returns:
trimmed_data – Dictionary of trimmed channel data
- Return type:
dict
- Raises:
ValueError – If fraction is not in range [0, 1] or would remove all data
Examples
>>> # Trim 2% total (1% from each end) >>> sp.trim(fraction=0.02) >>> # Trim 5% from start only >>> sp.trim(fraction=0.05)
- MojitoProcessor.SigProcessing.process_pipeline(data, channels=None, *, filter_kwargs=None, downsample_kwargs=None, trim_kwargs=None, truncate_kwargs=None, window_kwargs=None)[source]¶
Run the full TDI data processing pipeline on a MojitoData object.
Applies the following steps in order:
Filter — band-pass (if
lowpass_cutoffgiven) or high-pass onlyDownsample — polyphase resampling to
target_fs(optional)Trim — removes edge artefacts introduced by the filter from both ends
Truncate — selects the first
truncate_daysof the processed dataWindow — tapers edges to reduce spectral leakage
Pipeline progress is emitted at
logging.INFOlevel via theMojitoUtils.SigProcessinglogger.- Parameters:
data (MojitoData) – Loaded LISA L1 data object (from
load_mojito_l1). Must havedata.tdis(dict of channel arrays) anddata.fs(sampling rate).channels (list of str, optional) – TDI channels to process. Default
['X', 'Y', 'Z'].filter_kwargs (dict, optional) – Filter parameters. Keys: -
highpass_cutoff(float): High-pass cutoff in Hz (default: 5e-6) -lowpass_cutoff(float, optional): Low-pass cutoff for band-pass -order(int): Filter order (default: 2) -filter_type(str): Filter type (default: ‘butterworth’)downsample_kwargs (dict, optional) – Downsampling parameters. Keys: -
target_fs(float): Target sampling rate in Hz -kaiser_window(float): Kaiser window beta parameter (default: 31.0)trim_kwargs (dict, optional) – Trimming parameters. Omit (or pass
None) to skip trimming. Keys: -fraction(float): Fraction to trim from each end (default: 0.0)truncate_kwargs (dict, optional) – Segmentation parameters. Keys: -
days(float): Segment length in days (default: 4.0) Dataset is split into non-overlapping segments of this length. Each segment is independently windowed. Set toNoneto disable segmentation (returns single segment with full dataset). Note: Remainder samples shorter than a full segment are discarded.window_kwargs (dict, optional) – Windowing parameters. Omit (or pass
None) to skip windowing. Keys: -window(str): Window type - ‘tukey’, ‘hann’, etc. (default: ‘tukey’) -alpha(float): Taper fraction for Tukey window (default: 0.025)
- Returns:
segments – Dictionary mapping segment names (‘segment0’, ‘segment1’, …) to SignalProcessor objects. Each segment contains windowed data ready for FFT analysis. Access via
segments['segment0'].data,segments['segment0'].fs, etc.- Return type:
dict of SignalProcessor