Transforms Summary & Workflow Guide

This page provides a comprehensive quick-reference guide for all 11 data transforms in RheoJAX. Use the comparison matrices and workflow examples below to select and chain transforms for your rheological analysis pipelines.

Complete Transforms Comparison Matrix

The table below provides a comprehensive overview of all transforms across key characteristics for rapid transform selection.

Comprehensive Transform Comparison

Transform

Purpose

Input Data Type

Output Data Type

Computational Cost

Real-time Capable

Best For

FFT Analysis

Time → frequency domain conversion, spectral analysis, PSD, peak detection

Time-domain (t, signal)

Frequency-domain (f, spectrum/PSD)

Low

Yes

LAOS analysis, harmonic detection, periodic signals

Mastercurve

Time-Temperature Superposition (TTS), WLF/Arrhenius shifting, build master curves

Multi-T frequency sweeps with metadata

Merged mastercurve + shift factors

Medium

No

Polymer characterization, broaden frequency range, validate WLF

Mutation Number

Quantify relaxation character (solid vs liquid), gel point detection

Relaxation data G(t)

Scalar Δ ∈ [0,1] (0=elastic, 1=viscous)

Low

Yes

Material classification, gel point, compare viscoelastic character

OWChirp

LAOS time-frequency analysis, extract harmonics, nonlinear indicators

Time-domain LAOS (stress/strain vs t)

Frequency spectrum + time-frequency map

High

No

Fast rheometry, curing/gelation monitoring, LAOS harmonics

Smooth Derivative

Noise-robust numerical differentiation (Savitzky-Golay, spline, TV)

Any RheoData (x, y)

Derivative RheoData (dy/dx)

Low-Medium

Yes

Strain rate from strain, noisy data, multi-order derivatives

SRFS

Strain-Rate Frequency Superposition, shear banding detection

Multi-rate frequency sweeps with metadata

Merged master curve + shift factors

Medium

No

Soft glassy materials, thixotropic fluids, shear banding

SPP Decomposer

Sequence of Physical Processes decomposition for LAOS amplitude sweeps

LAOS amplitude sweep (stress, strain, strain rate)

SPP trajectories, yield stress parameters

Medium-High

No

LAOS yield stress extraction, static vs dynamic yield

Prony Conversion

Time ↔ frequency domain conversion via Prony series (generalized Maxwell)

Relaxation G(t) or oscillation G*(ω)

Converted domain + Prony parameters (G_i, τ_i)

Low

Yes

Domain interconversion, parametric representation, LVE envelope input

Spectrum Inversion

Recover continuous relaxation spectrum H(τ) via regularized inversion

Oscillation G*(ω) or relaxation G(t)

Continuous spectrum (τ, H(τ))

Medium

No

Material fingerprinting, relaxation mode identification, blend analysis

LVE Envelope

Linear viscoelastic startup stress envelope from Prony series

Prony parameters (G_i, τ_i) or RheoData with metadata

Stress envelope σ_LVE⁺(t)

Low

Yes

Nonlinearity detection, strain hardening/softening, damping function

Cox-Merz

Cox-Merz rule validation: |η*(ω)| vs η(γ̇) comparison

Two RheoData: oscillation + flow curve

Deviation metric + pass/fail

Low

Yes

Rule validation, yielding detection, material classification

Legend:

  • Computational Cost: Low (<10ms), Medium (10-100ms), High (>100ms) for typical datasets

  • Real-time Capable: Suitable for streaming/online analysis

  • Best For: Primary use cases and applications

Transform Selection Decision Tree

Follow this decision tree to identify the appropriate transform for your analysis workflow.

START: What do you want to achieve?
│
├─ DOMAIN CONVERSION (time ↔ frequency)?
│  │
│  ├─ Time → Frequency (general spectral analysis)?
│  │  └─ FFT Analysis ★★★☆☆
│  │     • Convert time-domain signals to frequency spectra
│  │     • Compute Power Spectral Density (PSD)
│  │     • Detect dominant frequencies and harmonics
│  │     • Window functions: hann, hamming, blackman, tukey
│  │     • Use Cases: LAOS harmonic detection, periodic signal analysis
│  │
│  └─ LAOS-specific time-frequency analysis?
│     └─ OWChirp ★★★★☆
│        • Optimal Windowed Chirp Fourier Transform
│        • Time-resolved frequency content (2D map)
│        • Extract higher harmonics (I₃/I₁, etc.)
│        • Nonlinearity indicators
│        • Use Cases: Curing, gelation, fast time-resolved rheometry
│
├─ TEMPERATURE EFFECTS (build master curves)?
│  └─ Mastercurve ★★★★☆
│     • Time-Temperature Superposition (TTS)
│     • Shift factors: WLF or Arrhenius
│     • Merge multi-temperature frequency sweeps
│     • Optimize WLF parameters (C₁, C₂)
│     • Validate temperature dependence
│     • Use Cases: Polymer characterization, broaden ω range by 3-5 decades
│
├─ MATERIAL CLASSIFICATION (solid vs liquid)?
│  └─ Mutation Number ★★☆☆☆
│     • Quantifies relaxation character: Δ = ∫[dG/d(ln t)] d(ln t)
│     • Δ = 0 → Pure elastic solid
│     • Δ = 1 → Pure viscous liquid
│     • 0 < Δ < 1 → Viscoelastic (closer to 0.5 = balanced)
│     • Use Cases: Gel point detection, material screening, QC
│
├─ NUMERICAL DIFFERENTIATION (need derivatives)?
│  └─ Smooth Derivative ★★★☆☆
│     • Noise-robust differentiation
│     • Methods: Savitzky-Golay, spline, Total Variation (TV)
│     • Multi-order derivatives (1st, 2nd, 3rd)
│     • Automatic unit conversion
│     • Use Cases: Strain rate from strain, acceleration, velocity
│
├─ STRAIN-RATE EFFECTS (soft glassy materials)?
│  └─ SRFS ★★★☆☆
│     • Strain-Rate Frequency Superposition
│     • Master curves from multi-rate oscillatory data
│     • Shear banding detection (non-monotonic flow curve)
│     • Power-law shift factors → estimate SGR x parameter
│     • Use Cases: Soft glasses, emulsions, thixotropic fluids
│
├─ LAOS YIELD STRESS (nonlinear intracycle analysis)?
│  └─ SPP Decomposer ★★★★☆
│     • Sequence of Physical Processes (Rogers framework)
│     • Instantaneous G'(t), G''(t) within each cycle
│     • Cole-Cole trajectories for yielding identification
│     • Static vs dynamic yield stress extraction
│     • Use Cases: Yield stress fluids, LAOS characterization
│
├─ PARAMETRIC DOMAIN CONVERSION (Prony series)?
│  └─ Prony Conversion ★★★☆☆
│     • G(t) → G'(ω), G''(ω) via analytical Prony relations
│     • G'(ω), G''(ω) → G(t) via inverse Prony fitting
│     • NNLS fitting ensures non-negative mode strengths
│     • Auto mode selection or manual n_modes control
│     • Use Cases: Domain interconversion, LVE envelope input, GMM analysis
│
├─ RELAXATION SPECTRUM (continuous H(τ) recovery)?
│  └─ Spectrum Inversion ★★★★☆
│     • Recover H(τ) from G*(ω) or G(t) data
│     • Methods: Tikhonov (GCV auto-λ) or Maximum Entropy
│     • Non-negative spectrum enforcement
│     • Dual-source: oscillation or relaxation input
│     • Use Cases: Material fingerprinting, blend analysis, spectrum comparison
│
├─ STARTUP STRESS PREDICTION (LVE envelope)?
│  └─ LVE Envelope ★★★☆☆
│     • σ_LVE⁺(t) = γ̇₀ [G_e·t + Σ Gᵢτᵢ(1 − exp(−t/τᵢ))]
│     • JIT-compiled for fast multi-rate sweeps
│     • Accepts Prony params directly or from metadata
│     • Use Cases: Nonlinearity detection, strain hardening/softening
│
├─ EMPIRICAL RULE VALIDATION (Cox-Merz)?
│  └─ Cox-Merz ★★☆☆☆
│     • Compare |η*(ω)| with η(γ̇) at ω = γ̇
│     • Log-log interpolation onto common rate grid
│     • Quantitative pass/fail with configurable tolerance
│     • Use Cases: Rule validation, yielding detection, material screening
│
└─ MULTI-STEP ANALYSIS (combine transforms)?
   └─ See "Common Workflow Pipelines" section below

Transform Deep-Dive Guides

FFT Analysis

Purpose: Convert time-domain rheological signals to frequency domain for spectral analysis, harmonic detection, and periodic signal characterization.

Key Capabilities:

  • FFT Transformation: Time → Frequency using Fast Fourier Transform

  • Power Spectral Density (PSD): Energy distribution across frequencies

  • Peak Detection: Identify dominant frequencies and harmonics

  • Windowing: Reduce spectral leakage (Hann, Hamming, Blackman, Tukey, Bartlett)

  • Normalization: Optional amplitude normalization

Input Requirements:

  • Time-domain RheoData with domain='time'

  • Evenly spaced time points (or interpolation applied)

  • Sufficient data length for frequency resolution: Δf = 1/T_total

Output:

  • Frequency-domain RheoData: (frequency, magnitude) or (frequency, PSD)

  • Peak frequencies and amplitudes via .detect_peaks()

Key Parameters:

FFT Analysis Parameters

Parameter

Default

Description

window

'hann'

Window function: ‘hann’, ‘hamming’, ‘blackman’, ‘tukey’, ‘bartlett’, None

detrend

True

Remove linear trend before FFT

return_psd

False

Return Power Spectral Density instead of magnitude

normalize

False

Normalize spectrum by maximum amplitude

n_peaks

5

Number of peaks to detect (in .detect_peaks())

Example Usage:

from rheojax.transforms import FFTAnalysis
import numpy as np

# Time-domain LAOS signal
t = np.linspace(0, 10, 1000)
signal = np.sin(2*np.pi*1.0*t) + 0.3*np.sin(2*np.pi*3.0*t)  # Fundamental + 3rd harmonic

data = RheoData(x=t, y=signal, domain='time')

# FFT with Hann window
fft_transform = FFTAnalysis(window='hann', return_psd=False)
freq_data = fft_transform.transform(data)

# Detect peaks
peaks = fft_transform.detect_peaks(freq_data, n_peaks=3)
print(f"Detected frequencies: {peaks['frequencies']} Hz")

Best For:

  • LAOS harmonic detection (I₃/I₁ ratios)

  • Identifying periodic components in stress/strain signals

  • Quality control of oscillatory tests

  • Frequency content analysis

Mastercurve

Purpose: Apply Time-Temperature Superposition (TTS) to merge multi-temperature frequency sweep data into a single master curve, extending effective frequency range by 3-5 decades.

Key Capabilities:

  • WLF Shifting: Williams-Landel-Ferry equation for polymer melts/elastomers

  • Arrhenius Shifting: Activation energy-based for Newtonian fluids/solutions

  • Shift Factor Optimization: Automatic optimization of C₁, C₂ (WLF) or E_a (Arrhenius)

  • Vertical Shifting: Optional modulus shifting for incompressibility corrections

  • Overlap Error: Quantitative assessment of superposition quality

Input Requirements:

  • List of RheoData objects (frequency sweeps at different temperatures)

  • Each RheoData must have metadata['temperature'] in Kelvin

  • Complex modulus data: G* = [\(G'\), \(G''\)] or equivalent

Output:

  • Merged master curve RheoData at reference temperature

  • Shift factors dictionary: {T: a_T} for horizontal shifts

Shift Models:

  1. WLF (Williams-Landel-Ferry):

    \[\log(a_T) = -\frac{C_1(T - T_{\text{ref}})}{C_2 + (T - T_{\text{ref}})}\]
    • Universal constants: C₁ ≈ 17.44, C₂ ≈ 51.6 K (relative to T_g)

    • Best for: Polymer melts, elastomers, T > T_g

    • Typical range: T_g + 50K to T_g + 150K

  2. Arrhenius:

    \[a_T = \exp\left[\frac{E_a}{R}\left(\frac{1}{T} - \frac{1}{T_{\text{ref}}}\right)\right]\]
    • Best for: Newtonian fluids, polymer solutions, simple liquids

    • E_a: Activation energy (typical: 40-100 kJ/mol)

Key Parameters:

Mastercurve Parameters

Parameter

Default

Description

reference_temp

Required

Reference temperature (K) for master curve

method

'wlf'

Shift method: ‘wlf’ or ‘arrhenius’

C1

17.44

WLF parameter C₁ (only for WLF method)

C2

51.6

WLF parameter C₂ in Kelvin (only for WLF)

E_a

50e3

Activation energy in J/mol (only for Arrhenius)

vertical_shift

False

Apply vertical (modulus) shifting

optimize_shifts

False

Automatically optimize C₁, C₂ or E_a

Example Usage:

from rheojax.transforms import Mastercurve

# Multi-temperature frequency sweep datasets
datasets = [data_25C, data_50C, data_75C, data_100C]

# Create mastercurve at 50°C with WLF shifting
mc = Mastercurve(
    reference_temp=323.15,  # 50°C in Kelvin
    method='wlf',
    C1=17.44,
    C2=51.6,
    optimize_shifts=True  # Auto-optimize C1, C2
)

# Build master curve
mastercurve, shift_factors = mc.transform(datasets)

# Get optimized WLF parameters
C1_opt, C2_opt = mc.get_wlf_parameters()
print(f"Optimized WLF: C1={C1_opt:.2f}, C2={C2_opt:.2f} K")

# Assess superposition quality
overlap_error = mc.compute_overlap_error(datasets)
print(f"Overlap error: {overlap_error:.4f}")

Best For:

  • Polymer rheology (extending ω range from ~3 decades to 6-8 decades)

  • Validating WLF/Arrhenius behavior

  • Characterizing temperature-dependent relaxation

  • Publications requiring master curves

Mutation Number

Purpose: Quantify the viscoelastic character of materials by computing a scalar index Δ ∈ [0, 1] from relaxation data, where Δ=0 is purely elastic and Δ=1 is purely viscous.

Theory:

The mutation number Δ is defined as:

\[\Delta = \frac{1}{G(0)} \int_{-\infty}^{\infty} \frac{dG}{d(\ln t)} d(\ln t)\]

For practical relaxation data:

\[\Delta = \frac{G(t=0) - G(t=\infty)}{G(t=0)}\]

Physical Interpretation:

Mutation Number Interpretation

Δ Value

Material Type

Physical Meaning

Δ = 0

Pure elastic solid

No stress relaxation (G(t) = constant)

0 < Δ < 0.3

Solid-like

Weak relaxation, strong equilibrium modulus

Δ ≈ 0.5

Balanced viscoelastic

Comparable elastic/viscous character

0.7 < Δ < 1

Liquid-like

Strong relaxation, weak/no equilibrium modulus

Δ = 1

Pure viscous liquid

Complete stress relaxation (G(t→∞) = 0)

Key Capabilities:

  • Material Classification: Rapid solid/liquid/gel identification

  • Gel Point Detection: Δ ≈ 0.5-0.7 at sol-gel transition

  • Quality Control: Consistent metric for batch comparison

  • Model Selection Aid: Helps choose solid vs liquid models

Input Requirements:

  • Relaxation data: G(t) vs time

  • RheoData with test_mode='relaxation'

  • Sufficient time range to capture relaxation (ideally 4-5 decades)

Output:

  • Scalar RheoData with Δ value in y attribute

  • domain='scalar' for single-value result

Key Parameters:

Mutation Number Parameters

Parameter

Default

Description

integration_method

'trapz'

Numerical integration: ‘trapz’, ‘simps’, ‘cumulative’

extrapolate

True

Extrapolate to t→0 and t→∞

extrapolation_model

'power_law'

Model for extrapolation: ‘power_law’, ‘exponential’

Example Usage:

from rheojax.transforms import MutationNumber

# Relaxation data
t = np.logspace(-2, 4, 100)
G_t = 1e5 * np.exp(-t / 10.0)  # Exponential relaxation

data = RheoData(x=t, y=G_t, domain='time', initial_test_mode='relaxation')

# Compute mutation number
mutation = MutationNumber(extrapolate=True)
result = mutation.transform(data)

delta = result.y[0]
print(f"Mutation Number Δ = {delta:.3f}")

# Interpret
if delta < 0.3:
    print("Material: Solid-like")
elif delta < 0.7:
    print("Material: Viscoelastic")
else:
    print("Material: Liquid-like")

Best For:

  • Rapid material screening and classification

  • Gel point detection in curing studies

  • Quality control metrics

  • Comparing viscoelastic character across samples

OWChirp

Purpose: Perform time-frequency analysis of Large Amplitude Oscillatory Shear (LAOS) data using Optimal Windowed Chirp transforms, extracting harmonics and nonlinear indicators.

Key Capabilities:

  • Time-Frequency Maps: 2D spectrograms showing frequency content evolution

  • Harmonic Extraction: Separate fundamental, 3rd, 5th, 7th harmonics

  • Nonlinearity Indicators: I₃/I₁, I₅/I₁ ratios (higher harmonics/fundamental)

  • Fast Rheometry: Time-resolved analysis of curing, gelation, structure formation

  • LAOS Analysis: Quantify nonlinear viscoelastic response

Theory:

OWChirp uses a chirp wavelet transform optimized for oscillatory rheological signals:

\[W(t, \omega) = \int_{-\infty}^{\infty} s(\tau) \psi^*(\tau - t, \omega) d\tau\]

where ψ is an optimal wavelet matched to oscillatory strain/stress.

Input Requirements:

  • Time-domain LAOS data: stress(t) or strain(t)

  • Imposed oscillatory strain with known frequency ω₀

  • Sufficient temporal resolution (sample rate >> ω₀)

Output:

  • Frequency spectrum RheoData (1D)

  • Time-frequency map via .get_time_frequency_map() (2D array)

  • Harmonic components via .extract_harmonics()

Key Parameters:

OWChirp Parameters

Parameter

Default

Description

n_frequencies

100

Number of frequency points in analysis

frequency_range

None

(f_min, f_max); auto-detect if None

wavelet_width

6.0

Width of Morlet wavelet (cycles)

extract_harmonics

True

Automatically extract harmonics

max_harmonic

7

Highest harmonic to extract (1, 3, 5, 7, …)

Example Usage:

from rheojax.transforms import OWChirp
import numpy as np

# LAOS stress response (nonlinear)
t = np.linspace(0, 10, 2000)
omega_0 = 2 * np.pi * 1.0  # 1 Hz
stress = (1e3 * np.sin(omega_0 * t) +
          300 * np.sin(3 * omega_0 * t) +  # 3rd harmonic
          50 * np.sin(5 * omega_0 * t))    # 5th harmonic

data = RheoData(x=t, y=stress, domain='time')

# OWChirp analysis
owchirp = OWChirp(n_frequencies=200, extract_harmonics=True, max_harmonic=7)
freq_data = owchirp.transform(data)

# Extract harmonics
harmonics = owchirp.extract_harmonics(freq_data, fundamental_freq=1.0)
I1 = harmonics['I1']  # Fundamental
I3 = harmonics['I3']  # 3rd harmonic
I5 = harmonics['I5']  # 5th harmonic

# Nonlinearity indicators
print(f"I3/I1 = {I3/I1:.3f}")  # Typical: 0.01-0.3 for LAOS
print(f"I5/I1 = {I5/I1:.3f}")

# Time-frequency map
tf_map = owchirp.get_time_frequency_map(data)

Best For:

  • LAOS (Large Amplitude Oscillatory Shear) analysis

  • Curing/gelation monitoring (time-resolved)

  • Fast time-sweep rheometry

  • Nonlinear viscoelastic characterization

Smooth Derivative

Purpose: Compute noise-robust numerical derivatives of rheological data using advanced smoothing techniques (Savitzky-Golay, spline, Total Variation).

Key Capabilities:

  • Noise Suppression: Smoothing before/after differentiation

  • Multiple Methods: Savitzky-Golay, spline, Total Variation (TV) regularization

  • Multi-Order: 1st, 2nd, 3rd derivatives

  • Automatic Units: Updates units for derivative quantity

  • Flexible Smoothing: Pre-smooth, post-smooth, or both

Methods:

  1. Savitzky-Golay (Default):

    • Polynomial fit over moving window

    • Preserves peak shapes

    • Best for: Smooth data with localized features

    • Parameters: window_length, polyorder

  2. Spline:

    • Cubic spline interpolation + differentiation

    • Smooth continuous derivatives

    • Best for: Noisy data requiring aggressive smoothing

    • Parameters: smoothing_factor

  3. Total Variation (TV):

    • L1-norm regularization (edge-preserving)

    • Preserves discontinuities

    • Best for: Data with step changes or plateaus

    • Parameters: regularization_weight

Input Requirements:

  • Any RheoData (x, y) with sufficient data points

  • Minimum points: window_length + 1 for Savitzky-Golay

Output:

  • Derivative RheoData with updated units

  • Same x-axis (or slightly truncated for edge effects)

Key Parameters:

Smooth Derivative Parameters

Parameter

Default

Description

method

'savgol'

Method: ‘savgol’, ‘spline’, ‘tv’

window_length

11

Savitzky-Golay window (must be odd)

polyorder

3

Savitzky-Golay polynomial order (<window_length)

deriv

1

Derivative order (1, 2, 3)

smooth_before

True

Smooth data before differentiation

smooth_after

False

Smooth derivative after computation

smooth_window

5

Window for post-smoothing

Example Usage:

from rheojax.transforms import SmoothDerivative
import numpy as np

# Noisy strain data
t = np.linspace(0, 10, 200)
strain = 0.1 * t**2 + np.random.normal(0, 0.01, size=t.shape)

data = RheoData(x=t, y=strain, domain='time', units_x='s', units_y='dimensionless')

# Compute strain rate (dε/dt) with Savitzky-Golay
derivative_transform = SmoothDerivative(
    method='savgol',
    window_length=15,
    polyorder=3,
    deriv=1,
    smooth_before=True
)

strain_rate = derivative_transform.transform(data)
print(f"Strain rate units: {strain_rate.units_y}")  # '1/s'

# For very noisy data, use spline or TV
derivative_tv = SmoothDerivative(method='tv', deriv=1)
strain_rate_tv = derivative_tv.transform(data)

Best For:

  • Computing strain rate from strain history

  • Velocity/acceleration from position

  • Derivative-based features for model fitting

  • Noisy experimental data

SRFS (Strain-Rate Frequency Superposition)

Purpose: Collapse multi-rate oscillatory data onto a master curve by shifting in the strain-rate domain, analogous to time-temperature superposition (TTS) but for soft glassy materials.

Key Capabilities:

  • Master Curve Construction: Merge \(G'(\omega)\) sweeps at different \(\dot{\gamma}\) onto one reference curve

  • Shift Factor Analysis: Extract power-law exponent to estimate SGR noise temperature \(x\)

  • Shear Banding Detection: Identify non-monotonic constitutive curves from flow data

  • Thixotropy Kinetics: Structural parameter \(\lambda(t)\) evolution under flow

Theory:

For SGR-type soft glasses, moduli at different strain rates superpose via:

\[G'(\omega, \dot{\gamma}) = b(\dot{\gamma}) \, G'_{\text{master}}(a(\dot{\gamma}) \cdot \omega)\]

with \(a(\dot{\gamma}) \sim \dot{\gamma}^{-1/(x-1)}\) and \(b(\dot{\gamma}) \sim \dot{\gamma}^{-1}\) for ideal SGR materials.

Input Requirements:

  • Multi-rate oscillatory frequency sweeps: \(G'(\omega)\) and \(G''(\omega)\) at 3+ strain rates

  • Known strain rate for each sweep

Output:

  • Master curve RheoData at reference strain rate

  • Horizontal and vertical shift factors per rate

  • Estimated \(x\) parameter from shift factor scaling

Key Parameters:

SRFS Parameters

Parameter

Default

Description

reference_rate

1.0

Reference strain rate for the master curve

method

'auto'

Shift factor method: ‘auto’, ‘power_law’, ‘empirical’

vertical_shift

True

Apply vertical (modulus) shifting in addition to horizontal

Example Usage:

from rheojax.transforms import SRFS
import numpy as np

# Multi-rate oscillatory data
rates = [0.01, 0.1, 1.0, 10.0]
omega = np.logspace(-2, 2, 50)
G_star_data = {rate: measure_modulus(omega, rate) for rate in rates}

# Build SRFS master curve
srfs = SRFS(reference_rate=1.0)
master_curve, shift_factors = srfs.transform(omega, G_star_data)

# Extract x from shift factor scaling
# log(a) = -1/(x-1) * log(gamma_dot)
from scipy.stats import linregress
log_rates = np.log10(rates)
log_a = np.log10(shift_factors['a'])
slope, _, r_value, _, _ = linregress(log_rates, log_a)
x_est = 1 - 1/slope
print(f"Estimated x = {x_est:.3f} (R² = {r_value**2:.4f})")

Best For:

  • Soft glassy materials (concentrated emulsions, colloidal gels, pastes)

  • Yield stress fluids with strain-rate-dependent microstructure

  • Thixotropic systems where structure evolves with deformation

  • Validating SGR model predictions

SPP Decomposer

Purpose: Perform intracycle LAOS analysis using the Sequence of Physical Processes (SPP) framework, extracting time-resolved instantaneous moduli and yield stress from nonlinear oscillatory data.

Key Capabilities:

  • Instantaneous Moduli: Time-resolved \(G'(t)\) and \(G''(t)\) within each oscillation cycle

  • Cole-Cole Trajectories: Plot \(G'_t\) vs \(G''_t\) to visualize yielding sequences

  • Yield Stress Extraction: Robust static/dynamic yield stress from LAOS amplitude sweeps

  • Nonlinear Fingerprinting: Classify yielding type (abrupt vs gradual, cage vs flow yield)

Theory:

SPP defines instantaneous moduli from the stress response \(\sigma(t)\) to sinusoidal strain \(\gamma(t) = \gamma_0 \sin(\omega t)\):

\[G'_t = \frac{\dot{\sigma}}{\dot{\gamma}}, \quad G''_t \omega = \frac{d\sigma}{dt}\bigg|_{\gamma=\text{const}}\]

These reduce to the linear viscoelastic \(G', G''\) at small amplitude but reveal rich intracycle structure at large amplitudes.

Input Requirements:

  • Time-domain LAOS data: stress \(\sigma(t)\) and strain \(\gamma(t)\)

  • Known strain amplitude \(\gamma_0\) and angular frequency \(\omega\)

  • Sufficient points per cycle (typically 500-1000)

Output:

  • Instantaneous moduli arrays \(G'(t)\), \(G''(t)\) over one cycle

  • Cole-Cole trajectory array \([G'_t, G''_t]\)

  • Cycle-averaged and maximum moduli, yield indicator

Key Parameters:

SPP Decomposer Parameters

Parameter

Default

Description

gamma_0

Required

Strain amplitude for analysis

omega

Required

Angular frequency (rad/s)

n_points

1000

Points per cycle for analysis

smooth_derivatives

True

Apply Savitzky-Golay smoothing to stress derivatives

window_length

21

Smoothing window size (must be odd)

Example Usage:

from rheojax.transforms import SPPDecomposer
import numpy as np

# LAOS data
gamma_0, omega = 0.5, 1.0
t = np.linspace(0, 2*np.pi/omega, 1000)
gamma = gamma_0 * np.sin(omega * t)
stress = experimental_stress(t)  # Your measured data

spp = SPPDecomposer(gamma_0=gamma_0, omega=omega)
result = spp.transform(t, gamma, stress)

# Cole-Cole trajectory
import matplotlib.pyplot as plt
plt.plot(result.Gp_instantaneous, result.Gpp_instantaneous)
plt.xlabel(r"$G'_t$ (Pa)")
plt.ylabel(r"$G''_t$ (Pa)")
plt.title("SPP Cole-Cole Trajectory")
plt.close("all")

# Yield stress from amplitude sweep
yield_stress = spp.extract_yield_stress(amplitude_sweep_results)
print(f"Yield stress: {yield_stress:.2f} Pa")

Best For:

  • LAOS yield stress determination (more robust than Fourier methods)

  • Identifying yielding mechanisms (Type I abrupt vs Type II gradual)

  • Distinguishing cage yield from flow yield

  • Validating constitutive models against SPP trajectories

Prony Conversion

Purpose: Parametric domain conversion between time and frequency domains using the Prony (generalized Maxwell) series.

Key Capabilities:

  • Time → Frequency: \(G(t) \to G'(\omega), G''(\omega)\) via analytical Prony relations

  • Frequency → Time: \(G'(\omega), G''(\omega) \to G(t)\) via inverse Prony fitting

  • NNLS Fitting: Non-negative least squares ensures thermodynamically consistent mode strengths

  • Auto Mode Selection: Automatic number of modes based on data density

Quick Example:

from rheojax.transforms import PronyConversion

# G(t) → G'(ω), G''(ω)
prony = PronyConversion(n_modes=10, direction="time_to_freq")
freq_data, info = prony.transform(relaxation_data)

# Access Prony parameters
result = info["prony_result"]
print(f"Modes: {result.n_modes}, G_e: {result.G_e:.1f} Pa")

# Reverse: G*(ω) → G(t)
prony_inv = PronyConversion(direction="freq_to_time", n_modes=8)
relax_data, _ = prony_inv.transform(oscillation_data)

Best For:

  • Domain interconversion with compact parametric representation

  • Obtaining Prony parameters for LVE envelope computation

  • Generalized Maxwell model parameter extraction

  • Round-trip validation of data consistency

Spectrum Inversion

Purpose: Recover the continuous relaxation spectrum \(H(\tau)\) from dynamic moduli or relaxation data via regularized inversion.

Key Capabilities:

  • Tikhonov Regularization: GCV-optimized regularization parameter selection

  • Maximum Entropy: Information-theoretic inversion preserving positivity

  • Dual-Source Input: Works from oscillation \(G^*(\omega)\) or relaxation \(G(t)\) data

  • Non-Negative Enforcement: Physical constraint \(H(\tau) \ge 0\)

Quick Example:

from rheojax.transforms import SpectrumInversion

# From oscillatory data
inv = SpectrumInversion(method="tikhonov", n_tau=100)
spectrum_data, info = inv.transform(osc_data)

tau = spectrum_data.x      # Relaxation times
H_tau = spectrum_data.y    # Spectrum H(τ)

# From relaxation data
inv_relax = SpectrumInversion(source="relaxation", method="max_entropy")
spectrum_data, _ = inv_relax.transform(relax_data)

Best For:

  • Material fingerprinting via relaxation time distribution

  • Identifying discrete relaxation modes in blends and composites

  • Comparing spectra across compositions, temperatures, or processing conditions

  • Complementary to discrete Prony representation (continuous vs discrete)

LVE Envelope

Purpose: Compute the linear viscoelastic startup stress envelope from Prony series parameters.

Key Capabilities:

  • Analytical Prediction: \(\sigma_{\text{LVE}}^+(t) = \dot{\gamma}_0 [G_e t + \sum G_i \tau_i (1 - e^{-t/\tau_i})]\)

  • JIT-Compiled: Fast evaluation for multi-rate sweeps

  • Flexible Input: Prony parameters via constructor or from data metadata

Quick Example:

from rheojax.transforms import LVEEnvelope
import numpy as np

G_i = np.array([5e3, 2e3])
tau_i = np.array([0.1, 10.0])

lve = LVEEnvelope(shear_rate=1.0, G_i=G_i, tau_i=tau_i)
envelope_data, info = lve.transform()

# Compare with experimental startup data
import matplotlib.pyplot as plt
plt.loglog(envelope_data.x, envelope_data.y, '--', label='LVE envelope')
plt.loglog(startup_data.x, startup_data.y, 'o', label='Experiment')
plt.legend()
plt.close("all")

Best For:

  • Detecting nonlinear behavior (strain hardening/softening) in startup experiments

  • Damping function extraction: \(h(\gamma) = \sigma_{\text{exp}} / \sigma_{\text{LVE}}\)

  • Multi-rate LVE families for branched polymer characterization

  • Input for constitutive model validation

Cox-Merz

Purpose: Validate the Cox-Merz empirical rule: \(|\eta^*(\omega)| = \eta(\dot{\gamma})\) at \(\omega = \dot{\gamma}\).

Key Capabilities:

  • Rule Validation: Quantitative pass/fail assessment with configurable tolerance

  • Deviation Mapping: Point-by-point relative deviation across the overlap region

  • Log-Log Interpolation: Onto common rate grid preserving power-law structure

  • Flexible Input: Accepts complex \(G^*\) or \([G', G'']\) and stress or viscosity

Quick Example:

from rheojax.transforms import CoxMerz

cm = CoxMerz(tolerance=0.10)
result_data, info = cm.transform([osc_data, flow_data])

result = info["cox_merz_result"]
print(f"Mean deviation: {result.mean_deviation:.1%}")
print(f"Passes (≤10%): {result.passes}")

Best For:

  • Validating oscillatory-to-steady-shear equivalence for flexible polymers

  • Detecting yield stress behavior (Cox-Merz failure = yielding indicator)

  • Material screening and classification

  • Quality control of rheological measurements

Common Workflow Pipelines

Transform workflows combine multiple transforms in sequence to achieve complex analysis goals.

Workflow 1: Stress Relaxation → FFT → Fractional Model Fit

Goal: Convert relaxation data to frequency domain and fit a fractional model.

from rheojax.transforms import FFTAnalysis
from rheojax.models import FractionalZenerSolidSolid

# 1. Time-domain relaxation
G_t_data = RheoData(x=t, y=G_t, domain='time', initial_test_mode='relaxation')

# 2. FFT to frequency domain
fft = FFTAnalysis(window='hann')
G_star_data = fft.transform(G_t_data)

# 3. Fit fractional model
model = FractionalZenerSolidSolid()
model.fit(G_star_data.x, G_star_data.y, test_mode='oscillation')

print(f"Fitted α = {model.parameters.get_value('alpha'):.3f}")

Why this workflow:

  • FFT converts relaxation G(t) to complex modulus G*(ω)

  • Fractional models often fit better in frequency domain

  • Broader frequency range from FFT than experimental oscillation

Workflow 2: Multi-Temperature Sweeps → Mastercurve → Model Fit

Goal: Build master curve from multi-T data, then fit a single model across extended frequency range.

from rheojax.transforms import Mastercurve
from rheojax.models import FractionalMaxwellLiquid

# 1. Multi-temperature datasets
datasets = [data_25C, data_50C, data_75C, data_100C]

# 2. Build mastercurve at 50°C
mc = Mastercurve(reference_temp=323.15, method='wlf', optimize_shifts=True)
mastercurve, shifts = mc.transform(datasets)

# 3. Fit model to extended frequency range
model = FractionalMaxwellLiquid()
model.fit(mastercurve.x, mastercurve.y, test_mode='oscillation')

# 4. Assess quality
C1, C2 = mc.get_wlf_parameters()
error = mc.compute_overlap_error(datasets)
print(f"WLF: C1={C1:.2f}, C2={C2:.2f} K, Error={error:.4f}")

Why this workflow:

  • Extends frequency range by 3-5 decades

  • Single model fit captures temperature-invariant physics

  • Validates WLF behavior

Workflow 3: Oscillation → Mutation Number → Model Selection

Goal: Classify material character, then select appropriate model family.

from rheojax.transforms import MutationNumber
from rheojax.models import FractionalZenerSolidSolid, FractionalMaxwellLiquid

# 1. Relaxation data
G_t_data = RheoData(x=t, y=G_t, domain='time', initial_test_mode='relaxation')

# 2. Compute mutation number
mutation = MutationNumber()
result = mutation.transform(G_t_data)
delta = result.y[0]

# 3. Select model based on Δ
if delta < 0.5:
    print("Solid-like → Using Fractional Zener SS")
    model = FractionalZenerSolidSolid()
else:
    print("Liquid-like → Using Fractional Maxwell Liquid")
    model = FractionalMaxwellLiquid()

# 4. Fit selected model
model.fit(t, G_t, test_mode='relaxation')

Why this workflow:

  • Automated model selection based on physics

  • Mutation number is fast and reliable classifier

  • Improves convergence by using appropriate model

Workflow 4: LAOS Chirp → OWChirp FT → Extract Harmonics → Fit Nonlinear Model

Goal: Analyze LAOS data for nonlinear viscoelastic response.

from rheojax.transforms import OWChirp

# 1. LAOS stress response
stress_data = RheoData(x=t, y=stress, domain='time')

# 2. OWChirp analysis
owchirp = OWChirp(extract_harmonics=True, max_harmonic=7)
freq_data = owchirp.transform(stress_data)

# 3. Extract harmonics
harmonics = owchirp.extract_harmonics(freq_data, fundamental_freq=omega_0/(2*np.pi))
I1, I3, I5 = harmonics['I1'], harmonics['I3'], harmonics['I5']

# 4. Nonlinearity indicators
print(f"Nonlinearity: I3/I1={I3/I1:.3f}, I5/I1={I5/I1:.3f}")

# 5. Time-frequency map for curing monitoring
tf_map = owchirp.get_time_frequency_map(stress_data)

Why this workflow:

  • OWChirp designed for LAOS signals

  • Harmonic extraction quantifies nonlinear response

  • Time-frequency map reveals structural evolution

Workflow 5: Strain History → Smooth Derivative → Strain Rate → Flow Model Fit

Goal: Compute strain rate from noisy strain data, then fit flow curve model.

from rheojax.transforms import SmoothDerivative
from rheojax.models import PowerLaw

# 1. Noisy strain history
strain_data = RheoData(x=t, y=strain, domain='time', units_x='s', units_y='dimensionless')

# 2. Smooth derivative → strain rate
deriv = SmoothDerivative(method='savgol', window_length=15, deriv=1)
strain_rate = deriv.transform(strain_data)

# 3. Combine with stress data
stress_data = RheoData(x=t, y=stress, domain='time')

# 4. Create flow curve (η vs γ̇)
eta = stress_data.y / strain_rate.y
flow_curve = RheoData(x=strain_rate.y, y=eta, domain='rotation')

# 5. Fit Power Law
model = PowerLaw()
model.fit(strain_rate.y, stress_data.y, test_mode='rotation')

K = model.parameters.get_value('K')
n = model.parameters.get_value('n')
print(f"Power Law: K={K:.2e}, n={n:.3f}")

Why this workflow:

  • Smooth derivative essential for noisy strain data

  • Direct computation of flow curve from time-domain data

  • Enables flow model fitting from non-standard tests

Workflow 6: Relaxation → Prony Conversion → LVE Envelope → Nonlinearity

Goal: Fit Prony series to relaxation data, compute LVE startup envelope, compare with experiment.

from rheojax.transforms import PronyConversion, LVEEnvelope
import numpy as np

# Step 1: Fit Prony series to G(t) data
prony = PronyConversion(n_modes=10, direction="time_to_freq")
_, info = prony.transform(relaxation_data)
result = info["prony_result"]

# Step 2: Compute LVE envelope at experimental rate
lve = LVEEnvelope(
    shear_rate=1.0, G_i=result.G_i,
    tau_i=result.tau_i, G_e=result.G_e
)
envelope_data, _ = lve.transform()

# Step 3: Compare with experimental startup data
import matplotlib.pyplot as plt
plt.loglog(envelope_data.x, envelope_data.y, '--', label='LVE')
plt.loglog(startup_data.x, startup_data.y, 'o', label='Experiment')
plt.legend()
plt.close("all")

Why this workflow:

  • Prony series provides compact parametric representation for LVE envelope

  • LVE envelope + experimental data reveals strain hardening/softening onset

  • Multi-rate sweeps identify critical Weissenberg number

Workflow 7: Oscillation → Spectrum Inversion → Material Fingerprint

Goal: Recover continuous relaxation spectrum from frequency sweep for material identification.

from rheojax.transforms import SpectrumInversion
import matplotlib.pyplot as plt

# Recover H(τ) from oscillatory data
inv = SpectrumInversion(method="tikhonov", n_tau=100)
spectrum_data, info = inv.transform(osc_data)

# Plot relaxation spectrum
plt.semilogx(spectrum_data.x, spectrum_data.y)
plt.xlabel(r'$\tau$ (s)')
plt.ylabel(r'$H(\tau)$ (Pa)')
plt.title(f"λ = {info['spectrum_result'].regularization_param:.2e}")
plt.close("all")

Why this workflow:

  • Continuous spectrum reveals distribution of relaxation mechanisms

  • Peaks in \(H(\tau)\) correspond to distinct molecular processes

  • Fingerprint comparison across formulations, temperatures, or aging conditions

Workflow 8: Oscillation + Flow Curve → Cox-Merz Validation

Goal: Validate Cox-Merz rule to assess whether oscillatory and steady-shear data are consistent.

from rheojax.transforms import CoxMerz

cm = CoxMerz(tolerance=0.10, n_points=50)
result_data, info = cm.transform([osc_data, flow_data])

result = info["cox_merz_result"]
if result.passes:
    print(f"Cox-Merz passes: mean deviation {result.mean_deviation:.1%}")
else:
    print(f"Cox-Merz FAILS: deviation {result.mean_deviation:.1%}")
    print("Material may exhibit yielding or associating behavior")

Why this workflow:

  • Quick validation of data consistency between oscillatory and flow measurements

  • Cox-Merz failure flags yield stress behavior or structural breakdown under flow

  • Useful as a quality control step before model fitting

Transform Chaining & Compatibility

Which Transforms Can Be Chained?

Transform Chaining Compatibility Matrix

Transform 1

Transform 2

Compatibility & Notes

FFT

Mastercurve

✓ FFT → frequency domain → merge multi-T → mastercurve

FFT

OWChirp

✗ Both do time→frequency (choose one based on need)

FFT

Mutation Number

✗ Mutation needs time-domain relaxation data

FFT

Smooth Derivative

✓ Smooth first → FFT (reduces spectral noise)

Mastercurve

Smooth Derivative

✓ Smooth individual sweeps before merging

Mutation Number

Smooth Derivative

✓ Smooth G(t) before computing Δ (recommended)

OWChirp

Smooth Derivative

✓ Smooth LAOS signal before OWChirp

Smooth Derivative

Any

✓ Pre-processing step for noisy data (chain first)

Prony Conversion

LVE Envelope

✓ Prony parameters feed directly into LVE envelope computation

Prony Conversion

Spectrum Inversion

✗ Both produce spectral representations (choose one)

FFT

Prony Conversion

✗ Both do time→frequency (choose based on parametric vs non-parametric need)

Prony Conversion

Cox-Merz

✓ Prony → G*(ω) → complex viscosity for Cox-Merz comparison

FFT

Spectrum Inversion

✓ FFT → G*(ω) → H(τ) spectrum recovery

Spectrum Inversion

Any model

✓ Terminal analysis (spectrum is the result); use peaks to initialize model fits

Cox-Merz

Any

✗ Terminal validation step (pass/fail metric is the result)

General Rules:

  1. Smooth Derivative is a pre-processor — Apply first to reduce noise

  2. FFT and OWChirp are alternatives — Both do time→frequency (pick based on use case)

  3. Prony Conversion and FFT are alternatives — Parametric vs non-parametric domain conversion

  4. Prony → LVE Envelope is a natural chain — Prony parameters feed directly into startup prediction

  5. Spectrum Inversion and Cox-Merz are terminal — Their outputs are analysis results, not intermediate data

  6. Mastercurve is a merge operation — Combine multiple datasets, not chainable after FFT/OWChirp

Sequential Processing Pipelines

Pipeline 1: Noise Reduction → FFT → Model Fit

smooth = SmoothDerivative(method='savgol', deriv=0, window_length=11)  # deriv=0 = smoothing only
fft = FFTAnalysis(window='hann')

smoothed_data = smooth.transform(noisy_data)
freq_data = fft.transform(smoothed_data)
model.fit(freq_data.x, freq_data.y)

Pipeline 2: Multi-Temperature → Smooth → Mastercurve → Fit

smooth = SmoothDerivative(method='spline', deriv=0)
mc = Mastercurve(reference_temp=323.15, method='wlf', optimize_shifts=True)

# Smooth each temperature dataset
smoothed_datasets = [smooth.transform(d) for d in datasets]

# Build mastercurve
mastercurve, shifts = mc.transform(smoothed_datasets)

# Fit model
model.fit(mastercurve.x, mastercurve.y)

Quality Checkpoints Between Stages

Checkpoint 1: After Smoothing

# Verify smoothing didn't over-smooth
plt.plot(original_data.x, original_data.y, 'o', label='Original')
plt.plot(smoothed_data.x, smoothed_data.y, '-', label='Smoothed')
plt.legend()

Checkpoint 2: After FFT

# Check for spectral leakage
peaks = fft.detect_peaks(freq_data, n_peaks=5)
print(f"Detected peaks at: {peaks['frequencies']} Hz")

Checkpoint 3: After Mastercurve

# Assess superposition quality
error = mc.compute_overlap_error(datasets)
if error > 0.05:
    print("WARNING: Poor superposition quality")

# Plot shift factors
temps, shifts = mc.get_shift_factors_array()
plt.plot(temps, np.log10(shifts), 'o-')
plt.xlabel('Temperature (K)')
plt.ylabel('log(a_T)')

Parameter Selection Guidelines

FFT Analysis

FFT Parameter Selection Guide

Scenario

Recommended Settings

Rationale

Clean periodic signal

window=None, detrend=True

No window needed; remove DC offset

Noisy signal

window='hann', detrend=True

Hann reduces spectral leakage

Sharp transients

window='blackman'

Blackman has better sidelobe suppression

LAOS harmonics

window='hann', normalize=True

Normalize for I₃/I₁ ratios

Power spectral density

return_psd=True, window='hann'

PSD for energy distribution

Mastercurve

Mastercurve Parameter Selection Guide

Material Type

Recommended Settings

Rationale

Polymer melts

method='wlf', optimize_shifts=True

WLF designed for polymers; optimize for best fit

Elastomers

method='wlf', C1=17.44, C2=51.6

Universal WLF constants (relative to T_g)

Polymer solutions

method='arrhenius', optimize_shifts=True

Arrhenius for simpler temperature dependence

Unknown T_g

optimize_shifts=True

Let optimizer find best C₁, C₂

Known activation energy

method='arrhenius', E_a=<value>

Use literature E_a value

Mutation Number

Mutation Number Parameter Selection

Data Quality

Recommended Settings

Rationale

Clean, wide time range

extrapolate=False

Data sufficient without extrapolation

Limited time range

extrapolate=True, extrapolation_model='power_law'

Power-law extrapolation for fractional materials

Exponential decay

extrapolation_model='exponential'

Match classical Maxwell/Zener behavior

Noisy data

Pre-smooth with SmoothDerivative first

Reduce integration errors

OWChirp

OWChirp Parameter Selection Guide

Application

Recommended Settings

Rationale

LAOS harmonics

extract_harmonics=True, max_harmonic=7

Capture fundamental + odd harmonics

Time-resolved curing

n_frequencies=200, wavelet_width=6.0

High resolution for evolving spectra

Fast screening

n_frequencies=50, extract_harmonics=True

Lower resolution for speed

Known fundamental

Specify fundamental_freq in extract_harmonics()

Direct harmonic extraction

Smooth Derivative

Smooth Derivative Parameter Selection

Data Characteristics

Recommended Settings

Rationale

Low noise, smooth

method='savgol', window_length=7, polyorder=3

Small window preserves features

High noise

method='savgol', window_length=15-21, polyorder=3

Larger window for aggressive smoothing

Very noisy

method='spline' or method='tv'

Advanced methods for heavy noise

Step changes

method='tv'

Total Variation preserves edges

Higher derivatives

polyorder >= deriv + 2

Ensure polynomial order sufficient

SRFS

SRFS Parameter Selection Guide

Material/Scenario

Recommended Settings

Rationale

Concentrated emulsions

method='power_law', vertical_shift=True

SGR power-law scaling expected; modulus softening under flow

Unknown soft glass

method='auto', vertical_shift=True

Let optimizer determine shift model

Thixotropic fluid

method='empirical', vertical_shift=True

Non-ideal SGR; empirical shifts more flexible

Validate SGR x

Fit slope = -1/(x-1) to log(a) vs log(γ̇)

Direct physics extraction from shift factors

SPP Decomposer

SPP Decomposer Parameter Selection Guide

Application

Recommended Settings

Rationale

Yield stress extraction

smooth_derivatives=True, window_length=21

Smoothing essential for clean \(G'_t\) features

High-resolution trajectory

n_points=2000, smooth_derivatives=True

More points capture subtle yielding features

Noisy stress signal

window_length=31-51, poly_order=3

Wider window for aggressive noise removal

Fast screening

n_points=500, smooth_derivatives=True

Fewer points for quick amplitude sweep analysis

Next Steps

  • Detailed transform documentation: Transforms for individual transform pages

  • User guide: /user_guide/transforms for usage patterns and examples

  • API reference: Transforms API for complete API documentation

  • Example notebooks: 8 transform examples in examples/transforms/ directory

  • Pipeline integration: /user_guide/pipeline_api for fluent transform chaining

Need a transform not listed? Transforms are extensible via BaseTransform - see Contributing to RheoJAX.