Units
RepTate keeps numerical values internally in canonical units. Unit conversion should happen only at input/output boundaries: when reading files, displaying values, formatting labels, or accepting user-entered values from the GUI.
Numerical theory code should continue to receive plain Python floats and NumPy arrays. Do not pass unit-bearing objects into theory calculations.
Canonical Units
The unit registry is in RepTate.core.units. Current canonical units include:
time:
sdeformation rate:
1/sinverse distance:
1/Anucleation rate:
1/s/m3rate:
m/sunit density:
1/m3angular frequency:
rad/sfrequency:
Hzstress, modulus, pressure:
Pacompliance:
1/Paviscosity:
Pa.sangle:
raddensity:
kg/m3inverse temperature:
1/Ktemperature:
Kmolar mass:
kg/mol
Frequency and angular frequency are intentionally different quantities.
Hz and rad/s must not be treated as generally compatible units. If a
specific importer accepts Hz where an application expects rad/s, that
conversion must be handled explicitly at the file input boundary. This is the
case for rheological data.
Adding a Unit
Add the unit to _UNITS in RepTate.core.units:
"ms": Unit("ms", "time", 1.0e-3)
The factor is relative to the canonical internal unit for that quantity. Keep conversions multiplicative only unless the conversion model is deliberately extended to support offset units.
Column Metadata
Data columns use ColumnSpec metadata:
ColumnSpec(
name="w",
display_unit="Hz",
internal_unit="rad/s",
quantity="angular_frequency",
)
File importers should convert loaded arrays to internal units before storing
them in DataTable.data. Axis-label generation can then use
ColumnSpec.axis_label() or a fallback for legacy data types without unit
metadata.
Theory Parameter Metadata
Theory parameters can carry optional unit metadata:
Parameter(
"tau_e",
2e-6,
"Rouse time of one Entanglement",
ParameterType.real,
quantity="time",
internal_unit="s",
display_unit="μs",
)
The stored Parameter.value remains in internal_unit. GUI display and
editing may use display_unit via display_value() and
value_from_display(). Fitting and theory calculations should continue to
use Parameter.value directly.
Tool Parameter Metadata
Tool parameters use the same Parameter class and unit metadata as theory
parameters. QTool displays Parameter.display_label() and
Parameter.display_value() in the tool parameter table, and converts values
entered by the user through Parameter.value_from_display().
Double-clicking a tool parameter name opens the tool-parameter properties
dialog. If a parameter defines quantity, internal_unit and
display_unit, compatible display units are populated from the unit registry.
When adding a unit-aware tool parameter, follow the same rule used for
theories: numerical tool calculations must use Parameter.value in
internal_unit and conversion must remain at the GUI boundary.
Materials Database
The Materials Database is unit-aware through metadata in
RepTate.tools.polymer_data. Built-in and user material databases are
canonicalized on load with canonicalize_database(). New material database
files should be saved with values already converted to internal units and with
polymer.unit_system set to MATERIAL_DATABASE_UNIT_SYSTEM.
Current unit-aware material fields are:
Field |
Internal unit |
Legacy/display unit |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ToolMaterialsDatabase.get_all_parameters() applies
convert_database_value_to_parameter() before assigning a database value to a
theory parameter. This lets a database field stored in canonical units feed a
legacy theory whose parameter intentionally declares a different internal unit.
Do not bypass this conversion when importing material parameters into a theory. If a theory needs a derived material parameter, obtain the database value in internal database units and explicitly convert it to the target theory parameter’s internal unit before assignment.
Temperature caveat
The canonical registry unit for temperature is K, but WLF-style material
parameters B2 and Te are stored as °C because the existing WLF shift
equations are written in Celsius differences and Celsius offsets. Do not change
those fields to Kelvin unless all WLF formulas that use them are migrated at
the same time.
Legacy theory formulas
Some theories still use historical numerical conventions internally even though
their parameters are unit-aware. Keep conversions local and explicit. For
example, TheoryDSMLinear declares MK and Mc as molar masses stored
in kg/mol but converts them to Da inside the DSM formulas, because the
legacy equations also convert file Mw to Da.
View Axis Metadata
Views can now carry explicit axis metadata through AxisSpec in
RepTate.core.View. This should be preferred over relying only on the
legacy x_units and y_units strings when a view is meant to be
unit-aware.
self.views["G(t)"] = View(
name="G(t)",
description="Relaxation modulus",
x_label="t",
y_label="G",
x_units="s",
y_units="Pa",
log_x=True,
log_y=True,
view_proc=self.viewGt,
n=1,
snames=["G"],
x_axis=AxisSpec(label="t", internal_unit="s"),
y_axis=AxisSpec(label="G", internal_unit="Pa"),
)
AxisSpec stores:
label: axis label textinternal_unit: canonical unit used by calculations and stored view datadisplay_unit: currently selected GUI unitquantity: inferred from the unit registry unless set explicitlytransform: currentlyidentityorlog10unit_choices: optional restricted list of units to offer in the GUI
Two-way conversion helpers are available on both AxisSpec and View:
AxisSpec.convert_from_internal()AxisSpec.convert_to_internal()View.convert_xy_to_display()View.convert_xy_to_internal()
Plotting boundary
view_proc() should continue to return x and y arrays in canonical internal
units. Conversion to the currently selected display units should happen only at
the plotting boundary.
Ordinary data and theory curves are converted in QDataSet.do_plot(). Do not
move display-unit conversion into numerical theory code.
The same rule applies to theory-generated DataTable objects. If a theory
fills self.tables[...] directly, the stored arrays must already be in the
canonical internal units expected by the active application views. Do not store
legacy display-unit values in theory tables and rely on the view layer to
“correct” them later, because that will produce inconsistent scaling between
experimental data and theory curves once view axes become unit-aware.
Theory helper graphics
Theory-side helper artists that live in data coordinates, such as mode markers, LVE envelopes, helper spectra, or editable bin boundaries, must also go through the current view conversion path.
Recommended pattern inside a theory:
view = self.current_view()
x, y, success = view.view_proc(data_table_tmp, file_parameters)
x, y = self.convert_view_data_to_display(x, y, view)
self.helper_artist.set_data(x, y)
If the helper artist is draggable, convert its dragged coordinates back before using them to update theory parameters:
dx, dy = self.convert_view_data_to_internal(dx, dy)
This keeps helper graphics visually aligned with the selected display units while preserving the theory’s canonical internal parameterization.
Logarithmic theory parameters
Parameters such as logwmin or logG00 remain dimensionless and tied to
canonical internal units. RepTate currently does not change their displayed
numeric values when plot-axis units change.
If their interpretation depends on a reference unit, document that in the parameter description or tooltip, for example “decimal logarithm of angular frequency referenced to rad/s”.