4. Engineer Frequency-Domain Features for Crash Severity and Deployment Prediction

Why Frequency-Domain Features Matter for Crash Pulses

Time-domain features (peak acceleration, delta-v, rise time, impulse) summarize a crash pulse by its amplitude and gross timing. They are necessary but not sufficient: two pulses can share nearly identical peak and delta-v while differing sharply in how energy is distributed across frequencies. A short, stiff barrier impact concentrates energy in a high-frequency band; a softer, longer crush event spreads energy into lower frequencies. Airbag deployment logic and occupant injury response both depend on this spectral content, because the sensing channel, the vehicle structure, and the occupant's body each respond differently across frequency. This case engineers frequency-domain features from crash pulses and measures how much they add to deployment prediction relative to time-domain features.

Signal Model and Preprocessing

Work with a single longitudinal accelerometer channel sampled at fs = 1000 Hz over a 200 ms window (200 samples). Before any transform, apply the standard preprocessing chain so spectral features are comparable across records:

  • Bias removal: subtract the pre-trigger mean (first 20 samples) to remove sensor offset.
  • Detrending: remove any linear drift over the window.
  • Windowing: apply a Hann window to reduce spectral leakage before the FFT.
  • Unit consistency: keep acceleration in g; all energies are therefore in g².

These steps are not cosmetic. A DC offset left in the signal dumps energy into the 0 Hz bin and corrupts band-energy ratios; a rectangular window smears a tonal component across neighboring bins and inflates the centroid.

Feature Definitions

Given the windowed signal x[n], compute the one-sided amplitude spectrum X[k] for k = 0 … N/2 with N = 200, so the frequency resolution is Δf = fs/N = 5 Hz. The features below are the deliverable of this case.

FeatureDefinitionPhysical meaning
Band energy E0–20Σ |X[k]|² for f in [0,20) HzRigid-body / low-frequency crush content
Band energy E20–50Σ |X[k]|² for f in [20,50) HzStructural bending and early occupant coupling
Band energy E50–100Σ |X[k]|² for f in [50,100) HzStiff local impacts, sensor mount ringing
Band energy E100–200Σ |X[k]|² for f in [100,200) HzHigh-frequency transients, noise floor
Spectral centroidΣ f·|X[k]|² / Σ |X[k]|²Center of mass of the spectrum (Hz)
Spectral spread√(Σ (f−centroid)²·|X[k]|² / Σ|X[k]|²)Bandwidth around the centroid
High/low energy ratio(E50–100+E100–200) / (E0–20+E20–50)Relative stiffness of the pulse
Wavelet detail energiesdb4 DWT, levels 1–4Time-localized energy per octave band

The discrete wavelet transform (db4, 4 levels) complements the FFT: it preserves when energy appears, which matters because a high-frequency burst at 30 ms and one at 120 ms imply very different occupant loading even with identical band energies.

Reference Implementation

The following Python snippet is self-contained and runnable with numpy and PyWavelets. It defines the feature extractor and demonstrates it on two synthetic pulses that share peak and delta-v but differ in spectral content.

import numpy as np
import pywt

FS = 1000.0
N = 200
BANDS = [(0, 20), (20, 50), (50, 100), (100, 200)]

def preprocess(x):
    x = np.asarray(x, dtype=float)
    x = x - x[:20].mean()                 # bias removal
    t = np.arange(len(x))
    x = x - np.polyval(np.polyfit(t, x, 1), t)  # detrend
    return x * np.hanning(len(x))         # Hann window

def spectral_features(x):
    xw = preprocess(x)
    X = np.fft.rfft(xw)
    P = np.abs(X) ** 2
    f = np.fft.rfftfreq(len(xw), d=1.0 / FS)
    feats = {}
    for lo, hi in BANDS:
        m = (f >= lo) & (f < hi)
        feats[f"E_{lo}_{hi}"] = float(P[m].sum())
    total = P.sum() + 1e-12
    centroid = float((f * P).sum() / total)
    spread = float(np.sqrt(((f - centroid) ** 2 * P).sum() / total))
    feats["centroid"] = centroid
    feats["spread"] = spread
    lo_e = feats["E_0_20"] + feats["E_20_50"]
    hi_e = feats["E_50_100"] + feats["E_100_200"]
    feats["hl_ratio"] = hi_e / (lo_e + 1e-12)
    coeffs = pywt.wavedec(xw, "db4", level=4)
    for i, c in enumerate(coeffs[1:], start=1):
        feats[f"dwt_d{i}"] = float(np.sum(c ** 2))
    return feats

# Two synthetic pulses: same peak (~30 g) and delta-v (~8 m/s)
t = np.arange(N) / FS
soft = 30 * np.exp(-((t - 0.06) / 0.030) ** 2)          # low-frequency
stiff = 30 * np.exp(-((t - 0.06) / 0.008) ** 2)         # high-frequency
for name, sig in [("soft", soft), ("stiff", stiff)]:
    f = spectral_features(sig)
    print(name, {k: round(v, 3) for k, v in f.items()})

Expected qualitative output (illustrative, from the synthetic pulses above): the stiff pulse shows a much larger E_50_100 and E_100_200, a higher centroid, and a hl_ratio well above 1, while the soft pulse concentrates energy in E_0_20 and yields a hl_ratio below 1. The dwt_d1 coefficient is correspondingly larger for the stiff pulse. These are properties of the constructed signals, not measured crash data.

Comparing Frequency vs. Time-Domain Contribution

To answer the case goal — how much spectral features add to deployment prediction — build two feature sets on the same labeled dataset (labels from the deployment decision rules established earlier in the course):

  1. TD set: peak acceleration, delta-v, rise time, impulse, jerk, time-domain energy.
  2. FD set: the eight spectral features above.
  3. Combined set: TD ∪ FD.

Train the same classifier (a regularized logistic regression is sufficient for this comparison) with identical cross-validation folds on each set, and report precision, recall, and PR-AUC at a fixed decision threshold. The incremental value of frequency-domain features is the difference between the combined and TD-only scores. A useful diagnostic is permutation importance restricted to the FD block: if shuffling the spectral features barely changes PR-AUC, they are redundant with time-domain information for this dataset; if it drops materially, they carry independent signal.

Keep the FFT window length fixed across all records. Changing N changes Δf and therefore the band boundaries' bin alignment, which silently shifts band energies and makes cross-record comparison invalid.
Do not interpret a high hl_ratio as "more severe." High-frequency content often reflects sensor mounting resonance or a stiff local contact rather than occupant-relevant loading. Always validate spectral features against the injury-response target, not against intuition about stiffness.

Feature Contribution Map

The diagram below shows how a raw crash pulse is split into the two feature families and how each feeds the deployment classifier, with the incremental contribution of the spectral block highlighted.

Raw crash pulse a(t), fs = 1000 Hz N = 200 samples Preprocess bias · detrend Hann window Time-domain features peak · delta-v · rise time impulse · jerk · energy TD set Frequency-domain features FFT band energies (4 bands) centroid · spread · hl_ratio db4 DWT detail energies FD set Deployment classifier regularized logistic regression precision · recall · PR-AUC Incremental value ΔPR-AUC = combined − TD-only permutation check on FD Time-domain block Frequency-domain block Contribution metric

Verification and Failure Symptoms

Confirm the pipeline before trusting any comparison:

  • Parseval check: total spectral energy should match the windowed time-domain energy within numerical tolerance. A large mismatch indicates a windowing or scaling error.
  • Band boundary alignment: with Δf = 5 Hz, band edges fall exactly on bins; verify no band is empty and that the four bands sum to the total energy.
  • DWT length: db4 level-4 detail coefficients should have lengths consistent with the input length; a mismatch signals a boundary-mode or level error.

Typical failure symptoms: a spectral centroid pinned near 0 Hz means the DC offset was not removed; a centroid near Nyquist means the signal is dominated by noise or the window was applied twice; identical band energies across all records suggest the FFT was taken on the raw (unwindowed, un-detrended) signal or on a constant-length zero-padded buffer that masks real differences.

Deliverable: Feature Comparison Record

For each dataset split, record the following so the comparison is auditable and reproducible:

FieldExample entry
Feature setTD / FD / Combined
Classifier & regularizationLogistic regression, C = 1.0
CV scheme5-fold stratified, fixed seed
Decision threshold0.5 (and the tuned operating point)
Precision / Recall / PR-AUCreport all three per set
ΔPR-AUC (combined − TD)the headline contribution number
FD permutation dropPR-AUC loss when FD block is shuffled

Report the incremental PR-AUC and the permutation drop together. A positive incremental value with a near-zero permutation drop is a warning that the spectral features are correlated proxies for time-domain information rather than independent predictors — a distinction that matters when deciding whether to invest in FFT/DWT computation in a production deployment pipeline.