MutationNumber¶
Overview¶
The rheojax.transforms.MutationNumber transform quantifies the normalized rate of
structural change during time-resolved experiments (gelation, curing, crystallization).
It computes a dimensionless metric \(\delta(t)\) from oscillatory measurements to
assess whether the system remains quasi-steady while parameters are being estimated.
Key Capabilities:
Structural evolution quantification: Track gelation, curing, aging dynamics
Quasi-steady validation: Verify rheological models applicability
Gel point detection: Winter-Chambon criterion via \(\tan\delta\) monitoring
Thixotropy assessment: Identify time-dependent structural recovery
Mathematical Theory¶
Definition and Physical Meaning¶
The mutation number \(\delta(t)\) quantifies how rapidly a material’s structure evolves relative to the observation timescale. Following Winter and Mours (1994), the cumulative mutation number up to time \(t\) is:
where \(G'(t)\) is the storage modulus measured in a time sweep.
Physical interpretation:
\(\delta(t) = 0\): Material structure unchanged (stable, equilibrium)
\(\delta(t) < 0.2\): Quasi-steady (< 20% structural change)
\(\delta(t) \approx 1\): Material structure changed by \(\sim\pi\)-fold (significant evolution)
\(\delta(t) \gg 1\): Rapid structural transformation (gelation, curing, yielding)
Generalized form for arbitrary observables:
where \(\phi(t)\) can be \(G'(t)\), \(G''(t)\), \(\eta(t)\), or any rheological observable.
Normalization by characteristic time:
For non-oscillatory data, normalize by a characteristic time \(\tau_c\):
This makes \(\delta\) dimensionless and comparable across different materials.
Loss Tangent and Viscoelastic Character¶
The loss tangent (\(\tan\delta\)) is the ratio of viscous to elastic response:
Physical interpretation:
\(\tan\delta\) value |
Material character |
Energy dissipation |
|---|---|---|
\(\tan\delta < 1\) |
Solid-like (elastic) |
Stores more energy than dissipates (\(G' > G''\)) |
\(\tan\delta = 1\) |
Balanced (crossover) |
Equal storage and dissipation (\(G' = G''\)) |
\(\tan\delta > 1\) |
Liquid-like (viscous) |
Dissipates more energy than stores (\(G'' > G'\)) |
Frequency dependence:
Viscoelastic liquids: \(\tan\delta > 1\) at low \(\omega\), crossover to \(\tan\delta < 1\) at high \(\omega\)
Viscoelastic solids: \(\tan\delta < 1\) across all frequencies
Critical gels: \(\tan\delta = \text{constant}\) (frequency-independent)
Winter-Chambon Criterion for Gel Point¶
At the gel point (sol-gel transition), the material exhibits critical behavior with unique rheological signatures.
Winter-Chambon criterion: At gel point, \(\tan\delta\) becomes frequency-independent:
where \(n\) is the relaxation exponent (\(0 < n < 1\)).
Power-law behavior at gel point:
Both moduli scale identically with frequency—the signature of a critical gel.
Relaxation exponent interpretation:
\(n \approx 0.5\): Typical for most polymer gels (percolation theory prediction \(\approx 2/3\))
\(n < 0.5\): Solid-like gel (\(G' > G''\))
\(n > 0.5\): Liquid-like gel (\(G'' > G'\))
Gel point determination methods:
Multi-frequency time sweep: Plot \(\tan\delta\) vs time for multiple frequencies; gel point = intersection point
Winter-Chambon plot: Plot \(\log G'\) vs \(\log G''\); gel point = time where slope = 1
Crossover point (approximate): Simple criterion \(G' = G''\) (\(\tan\delta = 1\))
Connection to percolation theory:
where \(\Delta\), \(\beta\) are critical exponents (\(\Delta \approx 2.5\), \(\beta \approx 0.7\) in 3D) giving \(n \approx 0.67\).
Structural Evolution and Thixotropy¶
Thixotropy: Time-dependent viscosity decrease under constant shear, followed by recovery when shearing stops.
Mutation number detects thixotropic recovery:
During recovery after shearing stops:
\(\delta_{\text{recovery}} < 0.1\): Fast recovery (< 10% viscosity change remaining)
\(\delta_{\text{recovery}} > 1\): Slow recovery (structural rebuilding ongoing)
Applications:
Paints and coatings: Quantify leveling time (\(\delta\) should be < 0.2 after application)
Foods (yogurt, mayonnaise): Assess mouthfeel recovery after swallowing
3D printing inks: Balance printability (low \(\delta\) during extrusion) vs shape retention (high \(\delta\) after deposition)
Interpretation¶
Range |
Regime |
Guidance |
|---|---|---|
\(\delta < 0.2\) |
Quasi-steady |
Safe to treat the process as time-invariant over the analysis window. |
\(0.2 \le \delta < 0.8\) |
Transition |
Monitor carefully; fits should include time dependence or shorter windows. |
\(\delta \ge 0.8\) |
Rapid mutation |
Material evolves faster than the probing frequency; pause fitting or adjust protocol. |
Practical decision rules:
\(\delta < 0.1\): Rheological parameters can be assumed constant (safe for model fitting)
\(0.1 \le \delta < 0.5\): Moderate evolution (verify model fit residuals, consider shorter time windows)
\(\delta \ge 0.5\): Significant structural change (time-dependent models required, or segment data)
Validity Conditions¶
Observable must be monotonic over the analysis window or segmented into monotonic pieces.
Sampling interval should resolve \(\tau_c\) (\(\Delta t \le 0.1 \tau_c\)).
Use smoothing (see SmoothDerivative) before differentiation to reduce noise-induced spikes.
Apply temperature or strain corrections prior to computing \(\delta\) when the protocol changes command conditions.
Additional considerations:
Noise amplification: Derivative of noisy data amplifies high-frequency fluctuations; always smooth before differentiating
Non-monotonic data: Segment into monotonic regions (e.g., gelation followed by degradation)
Temperature drift: Correct for thermal expansion before computing \(\delta\)
Algorithm¶
Step-by-Step Procedure¶
Input: Time-resolved rheological observable \(\phi(t)\) sampled at \(t_i\), \(i = 1 \ldots N\).
Output: Mutation number \(\delta(t)\), flags for quasi-steady validation.
Smooth \(\phi(t)\) with
SmoothDerivativeconfigured for the noise spectrum:smoother = SmoothDerivative(method="savitzky_golay", window=1.0, poly_order=3) phi_smooth = smoother.transform(time=t, signal=phi)
Compute logarithmic derivative:
\[\frac{d \ln \phi}{dt} = \frac{1}{\phi} \frac{d\phi}{dt}\]Numerical approximation:
\[\left(\frac{d \ln \phi}{dt}\right)_i \approx \frac{\ln \phi_{i+1} - \ln \phi_{i-1}}{t_{i+1} - t_{i-1}}\]Integrate absolute value:
\[\delta(t_j) = \frac{1}{\pi} \sum_{i=1}^j \left| \frac{d \ln \phi}{dt} \right|_i \Delta t_i\]where \(\Delta t_i = t_i - t_{i-1}\).
Normalize (optional):
If \(\tau_c\) provided:
\[\delta(t) \to \frac{\tau_c}{\pi} \delta(t)\]Emit diagnostics:
Mean mutation number: \(\bar{\delta} = \delta(t_{\text{end}}) / t_{\text{end}}\)
Maximum mutation rate: \(\max_i |\frac{d \ln \phi}{dt}|_i\)
Duty cycle: Fraction of time where \(\delta > \delta_{\text{threshold}}\)
Computational Complexity¶
Smoothing: \(O(N)\) (Savitzky-Golay)
Derivative: \(O(N)\) (finite differences)
Integration: \(O(N)\) (cumulative sum)
Total: \(O(N)\)
Very efficient even for long time-series (\(N > 10{,}000\) points).
Parameters¶
Parameter |
Description |
Guidance |
Default |
|---|---|---|---|
|
Characteristic convective time (s) used to normalize derivatives. |
Estimate from rise time or \(\eta/G\) for Maxwell-like systems. |
|
|
Averaging interval applied to \(\delta(t)\). |
Use \(\max(0.5, 0.25 \tau_c)\). |
|
|
Alarm level for \(|\delta|\). |
0.1 conservative, 0.2 exploratory. |
|
|
Normalize by \(\pi\) (historical definition) or leave raw. |
Set |
|
Parameter Selection Guidelines¶
Characteristic time \(\tau_c\):
Maxwell-like fluids: \(\tau_c = \eta_0 / G_0\) (ratio of zero-shear viscosity to modulus)
Gels: \(\tau_c = 1 / \omega_c\) (reciprocal of crossover frequency)
Curing systems: \(\tau_c = t_{\text{gel}}\) (gel time)
Auto-estimate: From crossover frequency or characteristic rise time
Window size:
Smooth data (SNR > 30 dB): Small window (0.5-1.0 s)
Noisy data (SNR < 20 dB): Large window (2-5 s) to suppress fluctuations
General rule: window \(\ge 5\times\) sampling interval
Threshold mn_threshold:
Conservative (\(\delta < 0.1\)): Minimal structural change allowed (< 10%)
Standard (\(\delta < 0.2\)): Typical quasi-steady criterion (< 20%)
Exploratory (\(\delta < 0.5\)): Moderate evolution acceptable (< 50%)
Input / Output Specifications¶
Input: either -
RheoDatatime sweep withycontaining \(G'(t)\), \(G''(t)\), or - numpy arraystime(s) andsignal(units of observable).Output: dict with -
mutation_numberarray same length as input, -flagsboolean array for samples abovemn_threshold, -summarycontainingmean,max,duty_cycle,tau_cused, differentiator metadata.
Applications and Use Cases¶
When to Use Mutation Number¶
1. Gelation and curing monitoring:
Track sol-gel transition in chemical gels (epoxy, polyurethane)
Identify gel point via Winter-Chambon criterion
Validate quasi-steady assumption for model fitting
2. Thixotropic recovery analysis:
Quantify structural rebuilding after shear cessation
Optimize formulation for printability (high \(\delta\)) vs shape retention (low \(\delta\))
Assess mouthfeel recovery in food products
3. Aging and structural evolution:
Monitor colloidal gel aging (aggregation, coarsening)
Track crystallization kinetics in polymers
Detect phase separation in emulsions
4. Quality control:
Verify batch-to-batch consistency (\(\delta\) should be reproducible)
Identify processing-induced structural damage (high \(\delta\) indicates instability)
Validate rheometer calibration (\(\delta \approx 0\) for stable reference materials)
Input Data Requirements¶
Minimum requirements:
Time-resolved measurement: Continuous monitoring at fixed frequency (e.g., 1 Hz)
Sufficient duration: At least \(2\times\) characteristic timescale (\(t \ge 2\tau_c\))
Adequate sampling: At least 10 points per characteristic time (\(\Delta t \le 0.1\tau_c\))
Monotonic observable: \(G'\), \(G''\), \(\eta\) should be monotonic (or segmented)
Recommended:
High SNR: Signal-to-noise ratio > 20 dB (minimize derivative noise)
Temperature control: \(\pm 0.1\) °C stability (thermal drift affects \(\delta\))
Strain within LVR: Linear viscoelastic region to avoid nonlinear artifacts
Output Interpretation¶
Mutation number profile \(\delta(t)\):
Linear increase: Constant structural evolution rate (exponential curing, gelation)
Plateau: Equilibrium reached (complete cure, stable gel)
Oscillations: Thixotropic recovery cycles (structural breakdown/rebuild)
Abrupt jump: Sudden structural change (yielding, phase transition)
Flags array:
Boolean indicators where \(\delta(t) > \delta_{\text{threshold}}\):
flags = (delta > mn_threshold)
quasi_steady_fraction = 1.0 - np.mean(flags)
Summary statistics:
Mean \(\delta\): Average structural change rate
Max \(\delta\): Peak evolution rate (identifies critical transition times)
Duty cycle: Fraction of time in rapid mutation regime
Integration with RheoJAX Models¶
Quasi-Steady Validation Workflow¶
Before fitting rheological models:
Compute mutation number for time-resolved data
Identify quasi-steady windows where \(\delta < 0.2\)
Fit models only within quasi-steady regions
Reject fits if \(\delta > 0.5\) (significant structural evolution)
Example workflow:
from rheojax.transforms import MutationNumber
from rheojax.models import FractionalMaxwellGel
# 1. Compute mutation number
mn = MutationNumber(tau_c=10.0, mn_threshold=0.2)
result = mn.transform(time=t, signal=G_prime)
# 2. Identify quasi-steady windows
quasi_steady_mask = ~result['flags'] # Where δ < 0.2
t_fit = t[quasi_steady_mask]
G_fit = G_prime[quasi_steady_mask]
# 3. Fit model only to quasi-steady data
model = FractionalMaxwellGel()
if len(t_fit) > 10: # Sufficient data points
model.fit(t_fit, G_fit, test_mode='relaxation')
print(f"Fitted α = {model.parameters.get_value('alpha'):.3f}")
else:
print("Insufficient quasi-steady data for fitting")
Models That Benefit from Mutation Number¶
Fractional gel models:
Fractional Maxwell Gel (Fractional) — Validate quasi-steady during gelation
Fractional Kelvin-Voigt-Zener (Fractional) — Ensure creep data is stationary
Classical models:
Zener (Standard Linear Solid) — Verify equilibrium modulus \(G_e\) is truly time-independent
Gel Point Detection Integration¶
Combine mutation number with \(\tan\delta\) monitoring:
from rheojax.transforms import MutationNumber
# Multi-frequency time sweep (e.g., 0.1, 1.0, 10 Hz)
frequencies = [0.1, 1.0, 10.0] # rad/s
tan_delta_traces = {} # {freq: tan_delta(t)}
for freq in frequencies:
G_prime_t, G_double_prime_t = measure_time_sweep(freq)
tan_delta = G_double_prime_t / G_prime_t
tan_delta_traces[freq] = tan_delta
# Find gel point: time where all tan δ(ω) curves intersect
t_gel = find_intersection_time(tan_delta_traces)
# Verify Winter-Chambon criterion
tan_delta_gel = {freq: tan_delta_traces[freq][t_gel] for freq in frequencies}
std_tan_delta = np.std(list(tan_delta_gel.values()))
if std_tan_delta < 0.05: # Frequency-independent
print(f"Gel point detected at t = {t_gel:.1f} s")
print(f"tan δ_gel = {np.mean(list(tan_delta_gel.values())):.3f}")
else:
print("No clear gel point (tan δ frequency-dependent)")
Common Workflows¶
Workflow 1: Curing kinetics + gel point
# Monitor G'(t), G''(t) during epoxy curing
# Identify gel point via Winter-Chambon + mutation number
mn = MutationNumber(tau_c=60.0, mn_threshold=0.2)
delta_cure = mn.transform(time=t, signal=G_prime)
# Gel point: rapid mutation (δ > 0.5) followed by plateau (δ < 0.2)
t_gel_idx = np.argmax(delta_cure['mutation_number'] > 0.5)
t_gel = t[t_gel_idx]
Workflow 2: Thixotropic recovery + model fitting
# Apply shear → stop → monitor recovery
# Fit thixotropic model only to quasi-steady recovery phase
mn = MutationNumber(tau_c=5.0, mn_threshold=0.1)
delta_recovery = mn.transform(time=t_recovery, signal=eta_recovery)
# Fit only after δ < 0.1 (quasi-steady recovery)
quasi_steady_idx = np.where(delta_recovery['mutation_number'] < 0.1)[0]
t_fit = t_recovery[quasi_steady_idx]
eta_fit = eta_recovery[quasi_steady_idx]
Workflow 3: Quality control + batch comparison
# Compare mutation numbers across multiple batches
batches = ['batch_A', 'batch_B', 'batch_C']
delta_summary = {}
for batch in batches:
data = load_time_sweep(batch)
mn = MutationNumber(tau_c=10.0)
result = mn.transform(time=data['time'], signal=data['G_prime'])
delta_summary[batch] = result['summary']
# Flag batches with abnormal structural evolution
for batch, summary in delta_summary.items():
if summary['max'] > 1.0:
print(f"WARNING: {batch} shows rapid mutation (δ_max = {summary['max']:.2f})")
Validation and Quality Control¶
Diagnostic Checks¶
1. Mutation number profile consistency:
Linear increase: Expected for exponential curing/gelation
Plateau: Indicates complete reaction or equilibrium
Oscillations: Check for temperature fluctuations or instrument noise
2. Derivative noise level:
Smooth data before computing \(\delta\) to avoid noise amplification:
SNR > 10: Good (reliable \(\delta\))
SNR < 5: Poor (increase smoothing window)
3. Quasi-steady fraction:
\(f_{\text{quasi}} > 0.8\): Mostly quasi-steady (safe for steady-state model fitting)
\(f_{\text{quasi}} < 0.5\): Rapidly evolving (time-dependent models required)
Common Failure Modes¶
1. Oscillating \(\delta\) on flat plateaus:
Symptom: \(\delta\) fluctuates despite constant \(G'\), \(G''\)
Cause: Derivative noise amplification
Fix: Increase
window_secondsor apply heavier smoothing (Savitzky-Golay order 5)
2. False alarms at instrument re-zero:
Symptom: \(\delta\) spike when rheometer re-calibrates
Cause: Sudden gap adjustment or torque reset
Fix: Mask or drop segments where strain/stress below detection limit
3. Auto \(\tau_c\) too small:
Symptom: \(\delta \gg 1\) even for stable materials
Cause: Incorrect automatic \(\tau_c\) estimation
Fix: Provide explicit
tau_cvalue or limit search range viatau_c_bounds
4. Units mismatch:
Symptom: NaN or inf in \(\delta\) computation
Cause: Observable contains zeros or negative values
Fix: Ensure \(\phi(t) > 0\) before taking logarithms (offset if needed)
Parameter Sensitivity¶
Smoothing window sensitivity:
Small window (0.5 s): Captures rapid changes but amplifies noise
Large window (5 s): Suppresses noise but misses fast transitions
Optimal: window \(\approx 2\text{-}5\times\) sampling interval
Threshold sensitivity:
Low threshold (0.1): Conservative, identifies subtle changes
High threshold (0.5): Permissive, allows moderate evolution
Normalization sensitivity:
With \(\pi\) normalization: Historical definition, \(\delta \approx 1\) for \(\pi\)-fold change
Without normalization: Raw cumulative change, easier to interpret
Cross-Validation Techniques¶
1. Multi-observable comparison:
Compute \(\delta\) for both \(G'(t)\) and \(G''(t)\); should agree within 20%:
delta_Gp = mn.transform(time=t, signal=G_prime)
delta_Gpp = mn.transform(time=t, signal=G_double_prime)
error = np.abs(delta_Gp['mutation_number'] - delta_Gpp['mutation_number'])
assert np.mean(error) < 0.2 * np.mean(delta_Gp['mutation_number'])
2. Repeated measurements:
Verify \(\delta\) reproducibility across batches or trials:
deltas = [mn.transform(time=t, signal=data_i)['mutation_number'][-1]
for data_i in repeated_measurements]
cv = np.std(deltas) / np.mean(deltas) # Coefficient of variation
assert cv < 0.1, "High variability in mutation number (CV > 10%)"
3. Synthetic data validation:
Test on known exponential evolution:
# Exponential growth: G'(t) = G0 * exp(t/τ)
t = np.linspace(0, 10, 100)
G_prime = 1e3 * np.exp(t / 5.0)
result = mn.transform(time=t, signal=G_prime)
delta_expected = t / (π * 5.0) # Analytical result
error = np.abs(result['mutation_number'] - delta_expected)
assert np.max(error) < 0.05, "Mutation number computation error"
Usage¶
from rheojax.transforms import MutationNumber, SmoothDerivative
smoother = SmoothDerivative(method="savitzky_golay", window=1.0, poly_order=3)
dlogG_dt = smoother.transform(time=ts, signal=jnp.log(G_prime))
mn = MutationNumber(tau_c=2.5, mn_threshold=0.1)
result = mn.transform(time=ts, signal=G_prime, dlog_signal_dt=dlogG_dt)
print(f"max delta = {result.summary['max']:.3f}")
Worked Example¶
Scenario: Monitor gelation of alginate solution (2% w/v) cross-linked with Ca²⁺. Determine gel point and validate quasi-steady regime for model fitting.
Input Data:
Time sweep: 0-600 s at \(\omega = 1\) rad/s, \(\gamma = 1\%\)
\(G'(t)\): 10 Pa to 5000 Pa (sol-gel transition)
\(G''(t)\): 5 Pa to 800 Pa
Sampling: 1 Hz (600 points)
Step-by-step analysis:
import numpy as np
from rheojax.transforms import MutationNumber, SmoothDerivative
from rheojax.core.data import RheoData
# 1. Generate synthetic gelation data (sigmoidal growth)
t = np.linspace(0, 600, 600) # 0-600 s, 1 Hz sampling
t_gel = 300.0 # Gel point at 300 s
G_prime = 10 + 4990 / (1 + np.exp(-(t - t_gel) / 30)) # Logistic growth
G_double_prime = 5 + 795 / (1 + np.exp(-(t - t_gel) / 30))
tan_delta = G_double_prime / G_prime
# 2. Smooth data before differentiation (reduce noise)
smoother = SmoothDerivative(method="savitzky_golay", window=5.0, poly_order=3)
G_prime_smooth = smoother.transform(time=t, signal=G_prime)['smoothed']
# 3. Compute mutation number
mn = MutationNumber(tau_c=30.0, mn_threshold=0.2)
result = mn.transform(time=t, signal=G_prime_smooth)
delta = result['mutation_number']
flags = result['flags']
# 4. Identify gel point (maximum mutation rate)
d_delta_dt = np.gradient(delta, t)
idx_gel = np.argmax(d_delta_dt)
t_gel_detected = t[idx_gel]
print(f"Gel point detected at t = {t_gel_detected:.1f} s")
print(f"tan δ at gel point = {tan_delta[idx_gel]:.3f}")
print(f"δ(t_gel) = {delta[idx_gel]:.3f}")
# 5. Verify Winter-Chambon criterion (should repeat at multiple frequencies)
print(f"\nQuasi-steady windows:")
quasi_steady_pre = t[~flags & (t < t_gel_detected)]
quasi_steady_post = t[~flags & (t > t_gel_detected + 100)]
print(f" Pre-gel: {quasi_steady_pre[0]:.0f}-{quasi_steady_pre[-1]:.0f} s ({len(quasi_steady_pre)} points)")
print(f" Post-gel: {quasi_steady_post[0]:.0f}-{quasi_steady_post[-1]:.0f} s ({len(quasi_steady_post)} points)")
Expected Output:
Gel point detected at t = 302.3 s
tan δ at gel point = 0.625
δ(t_gel) = 0.48
Quasi-steady windows:
Pre-gel: 0-250 s (250 points)
Post-gel: 450-600 s (150 points)
Interpretation:
Gel point: \(t_{\text{gel}} \approx 300\) s (peak mutation rate)
\(\tan\delta_{\text{gel}} \approx 0.625\): Corresponds to \(n \approx 0.4\) (solid-like gel)
\(\delta(t_{\text{gel}}) < 0.5\): Moderate mutation (quasi-steady approximation marginal at gel point)
Quasi-steady windows: Fit models to pre-gel (sol) and post-gel (gel) separately
Recommended models:
Pre-gel (\(t < 250\) s): Maxwell or FractionalMaxwellLiquid (liquid-like)
Post-gel (\(t > 450\) s): Zener or FractionalZenerSS (solid-like with \(G_e\))
Troubleshooting¶
delta oscillates on flat plateaus - increase
window_secondsor apply heavier smoothing before differentiation.False alarms at instrument re-zero - mask or drop segments where strain/stress is below detection before computing \(\delta\).
Auto ``tau_c`` too small - provide an explicit value or limit the search range via
tau_c_bounds.Units mismatch - ensure the observable is strictly positive before taking logarithms.
High noise amplification - increase Savitzky-Golay window size (e.g., 11-21 points) or polynomial order (3-5).
Spurious spikes - check for instrument artifacts (gap adjustments, torque limits).
References¶
Chambon, F. & Winter, H. H. “Linear viscoelasticity at the gel point of a crosslinking PDMS.” J. Rheol. 31, 683-697 (1987).
Mours, M. & Winter, H. H. “Time-resolved rheometry.” Rheol. Acta 33, 385-397 (1994). https://doi.org/10.1007/BF00366581
Winter, H.H., Chambon, F. (1986). “Analysis of Linear Viscoelasticity of a Crosslinking Polymer at the Gel Point.” Journal of Rheology, 30(2), 367-382.
See also¶
Fractional Maxwell Gel (Fractional) — mutation numbers quantify when gel fits remain quasi-steady.
Fractional Kelvin-Voigt-Zener (Fractional) — use \(\delta(t)\) to decide when creep data may be treated as stationary.
OWChirp — time-resolved LAOS experiments often chain mutation-number analysis.
SmoothDerivative — derivative estimates feed directly into \(\delta(t)\).
../../examples/transforms/05-mutation-number-analysis — notebook computing mutation numbers for gelation datasets.