TA Instruments TRIOS Format¶
Purpose
This reference documents the TRIOS file format from TA Instruments rheometers and how RheoJAX reads and processes these files.
Overview¶
TRIOS is the software platform from TA Instruments for their Discovery
and ARES rheometers. RheoJAX reads TRIOS data exported as .txt files using
the “Export to LIMS” functionality.
Supported rheometers include:
Discovery HR series (HR-1, HR-2, HR-3, HR-10, HR-20, HR-30)
Discovery Hybrid Rheometer (DHR)
ARES-G2
RSA-G2 (DMA mode)
File Structure¶
TRIOS .txt files have a hierarchical structure with a header section followed
by one or more [step] data segments.
Example File Structure¶
Filename experiment_name.tri
Instrument serial number 12345
Instrument name Discovery HR-2
operator John Doe
rundate 12/15/2025
Sample name Polymer Sample
Geometry name 40mm Cone
Geometry type Cone
[step]
Step name Frequency sweep (25.0 °C)
Number of points 50
Variables Angular frequency Storage modulus Loss modulus Complex viscosity
rad/s Pa Pa Pa·s
Data point 0.1 1000.5 500.2 11180.3
Data point 0.2 1050.3 520.1 5862.4
Data point 0.5 1120.8 580.5 2520.1
...
[step]
Step name Flow curve (25.0 °C)
Number of points 30
Variables Shear rate Viscosity Shear stress
1/s Pa·s Pa
Data point 0.01 1500.2 15.0
Data point 0.1 1200.5 120.1
...
Header Section¶
The header contains instrument and sample metadata:
Field |
Description |
|---|---|
|
Original TRIOS project filename (.tri) |
|
Rheometer serial number |
|
Rheometer model (e.g., Discovery HR-2) |
|
User who ran the experiment |
|
Date of measurement |
|
User-defined sample identifier |
|
Measurement geometry (e.g., 40mm Cone) |
|
Geometry category (Cone, Plate, Couette, etc.) |
Step Segments¶
Each [step] block contains:
Step name: Test type with optional temperature (e.g., “Frequency sweep (150.0 °C)”)
Number of points: Total data rows in segment
Column headers: Tab-separated variable names
Units row: Tab-separated units for each column
Data rows: Tab-separated values with “Data point” prefix
Supported Test Types¶
RheoJAX automatically detects and handles these TRIOS test types:
Test Type |
X-axis |
Y-axis |
Domain |
|---|---|---|---|
Frequency sweep (SAOS) |
Angular frequency (rad/s) |
\(G'(\omega)\), \(G''(\omega)\) → \(G^*(\omega)\) |
|
Amplitude sweep |
Strain (%) or Stress (Pa) |
\(G'(\gamma)\), \(G''(\gamma)\) |
|
Flow ramp |
Shear rate (1/s) |
Viscosity (Pa·s) |
|
Stress relaxation |
Time (s) |
Stress (Pa) or G(t) |
|
Creep |
Time (s) |
Strain or J(t) |
|
Temperature sweep |
Temperature (°C) |
\(G'(T)\), \(G''(T)\) |
|
Arbitrary wave (LAOS) |
Time (s) |
Stress (Pa), Strain |
|
Loading TRIOS Files¶
Basic Loading¶
from rheojax.io.readers import load_trios
# Load single-segment file
data = load_trios('frequency_sweep.txt')
# Access data
print(f"Points: {len(data.x)}")
print(f"Domain: {data.domain}")
print(f"Test mode: {data.test_mode}")
Multiple Segments¶
For files with multiple test steps:
# Return all segments as a list
segments = load_trios('multi_step_experiment.txt', return_all_segments=True)
for i, seg in enumerate(segments):
print(f"Segment {i}: {seg.test_mode}, {len(seg.x)} points")
if 'temperature' in seg.metadata:
print(f" Temperature: {seg.metadata['temperature']:.1f} K")
Accessing Oscillation Data¶
For SAOS data, RheoJAX automatically constructs the complex modulus:
data = load_trios('frequency_sweep.txt')
# Complex modulus G* = G' + iG''
G_star = data.y # Complex array
# Individual components via properties
G_prime = data.storage_modulus # G' (Pa)
G_double_prime = data.loss_modulus # G'' (Pa)
tan_delta = data.tan_delta # G''/G'
# Frequency
omega = data.x # Angular frequency (rad/s)
# Metadata
print(f"Sample: {data.metadata.get('sample_name', 'Unknown')}")
print(f"Geometry: {data.metadata.get('geometry', 'Unknown')}")
Auto-Chunking for Large Files¶
New in v0.4.0: Files larger than 5 MB are automatically loaded using chunked reading for memory efficiency.
Memory Efficiency¶
Loading Method |
Memory Usage |
Speed |
|---|---|---|
Full loading |
~80 bytes/point |
Faster |
Chunked loading |
~80 bytes × chunk_size |
2-4× slower |
Example: A 150,000 point LAOS file:
Full loading: ~12 MB in memory
Chunked (10k): ~800 KB per chunk (50-87% reduction)
Configuration Options¶
# Auto-chunking is enabled by default for files > 5 MB
data = load_trios('large_file.txt')
# Disable auto-chunking (force full loading)
data = load_trios('large_file.txt', auto_chunk=False)
# Explicit chunk size
data = load_trios('large_file.txt', chunk_size=5000)
# Progress tracking for large files
def progress(current, total):
pct = 100 * current / total
print(f"Loading: {pct:.1f}%")
data = load_trios('large_file.txt', progress_callback=progress)
Chunked Reading Generator¶
For processing large files without aggregation:
from rheojax.io.readers.trios import load_trios_chunked
# Process in chunks (memory-efficient)
for chunk in load_trios_chunked('large_laos_file.txt', chunk_size=10000):
print(f"Processing {len(chunk.x)} points")
# Each chunk is an independent RheoData object
result = process_chunk(chunk)
# Find maximum stress across entire file
max_stress = -float('inf')
for chunk in load_trios_chunked('file.txt'):
max_stress = max(max_stress, chunk.y.max())
# With progress tracking
def progress(current, total):
print(f"Progress: {100*current/total:.0f}%")
for chunk in load_trios_chunked('file.txt', progress_callback=progress):
process(chunk)
Column Detection¶
RheoJAX uses intelligent column detection to identify x and y variables.
Priority-Based Detection¶
X-axis priorities (in order):
Angular frequency
Frequency
Shear rate
Temperature
Step time
Time
Strain
Y-axis priorities (in order):
Storage modulus (\(G'\))
Loss modulus (\(G''\))
Stress
Strain
Viscosity
Complex modulus
Complex viscosity
Torque
Normal stress
Complex Modulus Construction¶
When both Storage modulus (\(G'\)) and Loss modulus (\(G''\)) columns are present, RheoJAX automatically constructs the complex modulus:
This enables direct use with RheoJAX models that expect complex input for oscillation data.
Unit Conversions¶
RheoJAX automatically converts common units to SI base units:
From |
To |
Factor |
|---|---|---|
MPa |
Pa |
× 10⁶ |
kPa |
Pa |
× 10³ |
% |
unitless |
× 0.01 |
Temperature Extraction¶
Temperature is automatically extracted from step names:
Step name Frequency sweep (150.0 °C)
Becomes:
data.metadata['temperature'] # 423.15 K (converted to Kelvin)
This enables use with Time-Temperature Superposition (TTS) for mastercurve construction.
Metadata Access¶
All TRIOS metadata is preserved in the metadata dictionary:
data = load_trios('experiment.txt')
# Instrument metadata
print(data.metadata.get('instrument_name')) # 'Discovery HR-2'
print(data.metadata.get('instrument_serial_number')) # '12345'
print(data.metadata.get('geometry')) # '40mm Cone'
print(data.metadata.get('geometry_type')) # 'Cone'
# Sample metadata
print(data.metadata.get('sample_name')) # 'Polymer Sample'
print(data.metadata.get('operator')) # 'John Doe'
print(data.metadata.get('run_date')) # '12/15/2025'
# Step-specific metadata
print(data.metadata.get('temperature')) # 298.15 (Kelvin)
print(data.metadata.get('test_mode')) # 'oscillation'
print(data.metadata.get('columns')) # ['Angular frequency', ...]
print(data.metadata.get('units')) # ['rad/s', ...]
Complete Example¶
Frequency Sweep Analysis¶
from rheojax.io.readers import load_trios
from rheojax.models import FractionalMaxwellLiquid
import matplotlib.pyplot as plt
# Load TRIOS frequency sweep
data = load_trios('polymer_frequency_sweep.txt')
print(f"Sample: {data.metadata.get('sample_name')}")
print(f"Temperature: {data.metadata.get('temperature', 298.15) - 273.15:.1f} °C")
print(f"Points: {len(data.x)}")
print(f"Frequency range: {data.x.min():.3f} - {data.x.max():.1f} rad/s")
# Fit fractional Maxwell model
model = FractionalMaxwellLiquid()
model.fit(data)
print(f"\nFitted parameters:")
for name, param in model.parameters.items():
print(f" {name}: {param.value:.4g}")
# Plot results
fig, ax = plt.subplots(figsize=(8, 6))
ax.loglog(data.x, data.storage_modulus, 'o', label="G' (data)")
ax.loglog(data.x, data.loss_modulus, 's', label="G'' (data)")
# Model prediction
y_pred = model.predict(data.x)
ax.loglog(data.x, y_pred.real, '-', label="G' (fit)")
ax.loglog(data.x, y_pred.imag, '--', label="G'' (fit)")
ax.set_xlabel('Angular frequency (rad/s)')
ax.set_ylabel('Modulus (Pa)')
ax.legend()
plt.savefig('frequency_sweep_fit.png', dpi=150)
Multi-Temperature Mastercurve¶
from rheojax.io.readers import load_trios
from rheojax.transforms import Mastercurve
# Load multi-temperature frequency sweeps
# Each segment in the file is at a different temperature
segments = load_trios('tts_experiment.txt', return_all_segments=True)
print(f"Loaded {len(segments)} temperature segments:")
for seg in segments:
T = seg.metadata.get('temperature', 298.15)
print(f" {T - 273.15:.1f} °C: {len(seg.x)} points")
# Construct mastercurve
mc = Mastercurve(reference_temp=298.15, method='wlf')
mastercurve, shift_factors = mc.transform(segments)
print(f"\nShift factors (log10 aT):")
for T, aT in shift_factors.items():
print(f" {T - 273.15:.1f} °C: {aT:.3f}")
Large LAOS File Processing¶
from rheojax.io.readers.trios import load_trios_chunked
from rheojax.transforms import SPPDecomposer
# Process large LAOS file in chunks
omega = 1.0 # rad/s (known from experiment)
gamma_0 = 1.0 # strain amplitude
spp = SPPDecomposer(omega=omega, gamma_0=gamma_0)
# Process chunks and aggregate results
all_stress = []
all_time = []
for chunk in load_trios_chunked('laos_150k_points.txt', chunk_size=10000):
all_time.extend(chunk.x.tolist())
all_stress.extend(chunk.y.tolist())
print(f"Total points loaded: {len(all_stress)}")
# Now analyze the complete waveform
import numpy as np
from rheojax.core.data import RheoData
full_data = RheoData(
x=np.array(all_time),
y=np.array(all_stress),
domain='time',
)
result = spp.transform(full_data)
metrics = spp.get_results()
print(f"Cage modulus: {metrics['G_cage']:.0f} Pa")
print(f"Static yield stress: {metrics['sigma_sy']:.1f} Pa")
Troubleshooting¶
File Not Recognized¶
If RheoJAX cannot parse your TRIOS file:
Check export format: Use “Export to LIMS” in TRIOS (not “Export to Excel”)
Verify encoding: File should be UTF-8 or ASCII
Check for ``[step]`` markers: Each data segment must start with
[step]
# Debug: Check file structure
with open('problematic_file.txt', 'r') as f:
for i, line in enumerate(f):
if i < 20 or '[step]' in line.lower():
print(f"{i}: {line.rstrip()}")
Wrong Columns Selected¶
If RheoJAX selects the wrong x/y columns:
# Check detected columns
data = load_trios('file.txt')
print(f"Detected columns: {data.metadata.get('columns')}")
print(f"Detected units: {data.metadata.get('units')}")
# Manually specify columns using CSV reader
from rheojax.io.readers import read_csv
data = read_csv(
'file.txt',
x_column='Angular frequency',
y_column='Storage modulus',
delimiter='\t',
skip_rows=15, # Skip header
)
Memory Issues with Large Files¶
For very large files (> 100 MB):
# Force chunked reading with smaller chunks
from rheojax.io.readers.trios import load_trios_chunked
for chunk in load_trios_chunked('huge_file.txt', chunk_size=5000):
# Process immediately, don't accumulate
result = process_and_save(chunk)
del chunk # Explicit cleanup
Missing Temperature¶
If temperature is not detected:
data = load_trios('file.txt')
# Check if temperature was extracted
if 'temperature' not in data.metadata:
# Manually add temperature (in Kelvin)
data.metadata['temperature'] = 25.0 + 273.15
See Also¶
Data Format Reference — Data format requirements for all analyses
Data I/O Guide — General data I/O guide
Time-Temperature Superposition (TTS) — TTS with TRIOS data
I/O Module (rheojax.io) — Full API reference for I/O functions