Mixins¶
Composable base classes that provide validation, serialization, plotting, coordinate geometry, datetime handling, change propagation, and more.
Colors
¶
Classes¶
ColorMixin
¶
A class to manage colors, including conversion between hex and RGB formats, and generating color gradients.
Methods:¶
rgb_tuple_to_hex
staticmethod
¶
Convert an (R, G, B) tuple to a hex colour string.
get_colorway
staticmethod
¶
Generate a list of n hex colors interpolated between two HTML hex colors.
| PARAMETER | DESCRIPTION |
|---|---|
color1
|
The first color in HTML hex format (e.g., '#ff0000').
TYPE:
|
color2
|
The second color in HTML hex format (e.g., '#0000ff').
TYPE:
|
n
|
The number of colors to generate in the gradient.
TYPE:
|
adjust_fill_opacity
staticmethod
¶
Adjust the fill opacity of any color format while preserving line opacity.
| PARAMETER | DESCRIPTION |
|---|---|
color_str
|
Color in any format (hex, rgb, rgba, named).
TYPE:
|
opacity
|
Target opacity (0.0 to 1.0).
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
Color string with adjusted opacity in rgba format. |
get_color_format
staticmethod
¶
Detect the format of a color string.
| PARAMETER | DESCRIPTION |
|---|---|
color_str
|
Color string in any format.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
Color format: 'hex', 'rgb', 'rgba', 'hsl', 'hsla', 'named', or 'unknown'. |
validate_opacity
staticmethod
¶
Validate that opacity is within valid range.
| PARAMETER | DESCRIPTION |
|---|---|
opacity
|
Opacity value to validate.
TYPE:
|
param_name
|
Parameter name for error messages.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If opacity is not between 0.0 and 1.0. |
adjust_trace_opacity
staticmethod
¶
Adjust opacity of a plotly trace in-place.
| PARAMETER | DESCRIPTION |
|---|---|
trace
|
The plotly trace to modify.
|
opacity
|
Target opacity (0.0 to 1.0).
TYPE:
|
Coordinates
¶
Classes¶
CoordinateMixin
¶
A class to manage and manipulate 3D coordinates. Provides methods for rotation, area calculation, and coordinate ordering.
Methods:¶
get_radius_of_points
staticmethod
¶
Calculate the radius of a spiral given its coordinates.
| PARAMETER | DESCRIPTION |
|---|---|
coords
|
Array of shape (N, 2) with columns [x, z].
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tuple[float, Tuple[float, float]]
|
(radius, (center_x, center_z)) where radius is in meters. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If input coordinates are invalid or insufficient valid points. |
get_xz_center_line
staticmethod
¶
Generate center line(s) for coordinate data, handling both single and multi-segment polygons.
| PARAMETER | DESCRIPTION |
|---|---|
coordinates
|
Array of 3D coordinates with shape (N, 3) where columns are [x, y, z]. NaN values in x or z coordinates indicate breaks between polygon segments.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ndarray
|
For single polygon: Array with shape (2, 2) containing start and end points. |
ndarray
|
For multiple segments: Array with center lines for each segment separated by [NaN, NaN]. |
ndarray
|
For empty coordinates: Empty array with shape (0, 2). |
rotate_coordinates
staticmethod
¶
Rotate a NumPy array of coordinates around the specified axis. Can handle 2D coordinates (N, 2) for x, y or 3D coordinates (N, 3) for x, y, z. Can handle coordinates with None values (preserves None positions).
:param coords: NumPy array of shape (N, 2) for 2D or (N, 3) for 3D coordinates :param axis: Axis to rotate around ('x', 'y', or 'z'). For 2D arrays, only 'z' is valid. :param angle: Angle in degrees :param center: Point to rotate around. For 2D: (x, y) tuple. For 3D: (x, y, z) tuple. If None, rotates around origin. :return: Rotated NumPy array with same shape as input
build_square_array
staticmethod
¶
Build a NumPy array representing a square or rectangle defined by its bottom-left corner (x, y) and its width and height.
| PARAMETER | DESCRIPTION |
|---|---|
x
|
The x-coordinate of the bottom-left corner of the square.
TYPE:
|
y
|
The y-coordinate of the bottom-left corner of the square.
TYPE:
|
x_width
|
The width of the square.
TYPE:
|
y_width
|
The height of the square.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tuple[ndarray, ndarray]
|
Tuple containing x and y coordinate arrays defining the square/rectangle. |
build_circle_array
staticmethod
¶
build_circle_array(center_x: float, center_y: float, radius: float, num_points: int = 64, anticlockwise: bool = True) -> Tuple[ndarray, ndarray]
Build a NumPy array representing a circle defined by its center and radius.
| PARAMETER | DESCRIPTION |
|---|---|
center_x
|
The x-coordinate of the circle center.
TYPE:
|
center_y
|
The y-coordinate of the circle center.
TYPE:
|
radius
|
The radius of the circle.
TYPE:
|
num_points
|
Number of points to use for the circle approximation. Defaults to 64.
TYPE:
|
anticlockwise
|
If True, points are ordered anticlockwise; if False, clockwise. Defaults to True.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tuple[ndarray, ndarray]
|
Tuple containing x and y coordinate arrays defining the circle. |
order_coordinates_clockwise_numpy
staticmethod
¶
Order 3D coordinates in clockwise direction based on a specified plane. Handles multiple coordinate blocks separated by NaN rows.
| PARAMETER | DESCRIPTION |
|---|---|
coords
|
Array of 3D coordinates with shape (N, 3) where columns are [x, y, z]. NaN rows indicate separations between coordinate blocks.
TYPE:
|
plane
|
Plane to use for ordering ('xy', 'xz', 'yz'). Defaults to 'xy'.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ndarray
|
Sorted coordinates array with same shape as input, with each block |
ndarray
|
sorted clockwise and separated by NaN rows. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If coords array doesn't have shape (N, 3) or plane is invalid. |
concat_with_nan_separators
staticmethod
¶
Efficiently concatenate numpy arrays with NaN separators.
| PARAMETER | DESCRIPTION |
|---|---|
arrays
|
List of numpy arrays to concatenate.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ndarray
|
Concatenated array with NaN separators. |
get_area_from_points
staticmethod
¶
Calculate the area of a closed shape defined by the coordinates in x and y using the shoelace formula. Can handle multiple shapes separated by None values.
extrude_footprint
staticmethod
¶
extrude_footprint(x: ndarray, y: ndarray, datum: ndarray, thickness: float) -> Tuple[ndarray, ndarray, ndarray, ndarray]
Extrude a 2D footprint to 3D, handling both single and multi-segment polygons.
| PARAMETER | DESCRIPTION |
|---|---|
x
|
Array of x coordinates. NaN values indicate segment separators.
TYPE:
|
y
|
Array of y coordinates. NaN values indicate segment separators.
TYPE:
|
datum
|
Datum point for extrusion (shape (3,)).
TYPE:
|
thickness
|
Thickness of the extrusion.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tuple[ndarray, ndarray, ndarray, ndarray]
|
Arrays of x, y, z coordinates and side labels, with NaN separators between segments. |
get_coordinate_intersection
staticmethod
¶
Calculate the intersection area between two sets of coordinates.
| PARAMETER | DESCRIPTION |
|---|---|
coords1
|
First set of coordinates (N, 2) with columns [x, y].
TYPE:
|
coords2
|
Second set of coordinates (M, 2) with columns [x, y].
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
float
|
Intersection area between the two polygons. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If either coordinate set has insufficient valid points for polygon creation. |
insert_gaps_with_nans
staticmethod
¶
insert_gaps_with_nans(data: ndarray, column_index: int, tolerance_multiplier: float = 2.0) -> ndarray
Insert rows of NaNs when gaps in a specified column exceed a tolerance threshold.
| PARAMETER | DESCRIPTION |
|---|---|
data
|
Input array with shape (N, M) where N is number of rows and M is number of columns.
TYPE:
|
column_index
|
Index of the column to analyze for gaps (0-based indexing).
TYPE:
|
tolerance_multiplier
|
Multiplier for average gap to determine tolerance threshold. Defaults to 2.0.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ndarray
|
Array with NaN rows inserted where gaps exceed the tolerance. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If column_index is out of bounds for the array. |
IndexError
|
If data array is empty or has insufficient dimensions. |
Examples:
remove_skip_coat_area
staticmethod
¶
remove_skip_coat_area(x_coords: ndarray, y_coords: ndarray, weld_tab_positions: ndarray, skip_coat_width: float) -> Tuple[ndarray, ndarray]
Remove skip coat areas around weld tab positions from coordinates.
| PARAMETER | DESCRIPTION |
|---|---|
x_coords
|
Array of x coordinates defining the boundary.
TYPE:
|
y_coords
|
Array of y coordinates defining the boundary.
TYPE:
|
weld_tab_positions
|
Array of x positions where weld tabs are located.
TYPE:
|
skip_coat_width
|
Width of the skip coat area around each weld tab.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tuple[ndarray, ndarray]
|
Modified x and y coordinate arrays with np.nan separators between segments. |
Data
¶
Classes¶
DataMixin
¶
A mixin class providing data processing and validation utilities. Provides methods for monotonicity enforcement and nested breakdown aggregation.
Methods:¶
enforce_monotonicity
staticmethod
¶
Enforces a monotonic version of the input array. If the array is not monotonic, it is smoothed using cumulative max/min.
sum_breakdowns
staticmethod
¶
Aggregate breakdown dictionaries across multiple components. If a component doesn't have the specified breakdown, use its fallback attribute instead.
| PARAMETER | DESCRIPTION |
|---|---|
components
|
List of component objects.
|
breakdown_type
|
Type of breakdown to aggregate ('mass', 'cost', etc.).
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
|
Aggregated breakdown dictionary with summed values maintaining structure, |
|
|
or simple float sum if no components have the specified breakdown. |
DateTime
¶
steer_core/Mixins/DateTime.py
Lightweight, dependency-free datetime parsing and validation helpers.
Goal:
- Provide shared utilities across STEER repos for parsing user-friendly datetime strings
into canonical datetime objects with enforced alignment (hour/day).
Classes¶
DateTimeMixin
¶
A mixin class to handle datetime parsing, validation, and alignment operations. Provides utilities for converting strings to datetime objects with enforced temporal alignment.
Methods:¶
str_to_datetime
staticmethod
¶
Parse a datetime string using a provided strptime format.
If no format is specified, automatically detects and parses using either the hour format ('%Y-%m-%d-%H') or day format ('%Y-%m-%d').
| PARAMETER | DESCRIPTION |
|---|---|
value
|
The datetime string to parse.
TYPE:
|
fmt
|
The strptime format string (e.g., '%Y-%m-%d-%H'). If None, automatically tries both DEFAULT_HOUR_FMT and DEFAULT_DAY_FMT.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
datetime
|
The parsed datetime object. |
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If value is not a string. |
ValueError
|
If value cannot be parsed with the provided or detected format(s). |
Examples:
datetime_to_str
staticmethod
¶
Format a datetime object into a user-friendly string.
If no format is specified, uses the hour format ('%Y-%m-%d-%H').
| PARAMETER | DESCRIPTION |
|---|---|
dt
|
The datetime object to format.
TYPE:
|
fmt
|
The strftime format string (e.g., '%Y-%m-%d-%H', '%Y-%m-%d'). If None, defaults to DEFAULT_HOUR_FMT.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The formatted datetime string. |
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If dt is not a datetime object. |
Examples:
shift_years
staticmethod
¶
Shift a datetime by a specified number of years (forward or backward).
Handles the edge case of February 29 (leap day): if the original date is Feb 29 and the target year is not a leap year, the result will be Feb 28.
| PARAMETER | DESCRIPTION |
|---|---|
dt
|
The datetime object to shift.
TYPE:
|
years
|
The number of years to shift (positive to add, negative to subtract).
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
datetime
|
A new datetime object with the years shifted. |
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If dt is not a datetime object or years is not an integer. |
Examples:
shift_months
staticmethod
¶
Shift a datetime by a specified number of months (forward or backward).
Handles month boundaries intelligently: if the original day doesn't exist in the target month (e.g., Jan 31 + 1 month), the result will be the last valid day of that month (e.g., Feb 28 or Feb 29).
| PARAMETER | DESCRIPTION |
|---|---|
dt
|
The datetime object to shift.
TYPE:
|
months
|
The number of months to shift (positive to add, negative to subtract).
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
datetime
|
A new datetime object with the months shifted. |
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If dt is not a datetime object or months is not an integer. |
Examples:
validate_end_after_start
staticmethod
¶
Validate that end datetime comes after start datetime.
| PARAMETER | DESCRIPTION |
|---|---|
start
|
The start datetime.
TYPE:
|
end
|
The end datetime.
TYPE:
|
strictly
|
If True, end must be strictly after start (end > start). If False, end can equal start (end >= start). Default is True.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If start or end is not a datetime object. |
ValueError
|
If end is not after start. |
Examples:
Datum
¶
Mixin providing standard datum property interface with mm/m unit conversion.
Classes¶
DatumMixin
¶
Mixin providing uniform datum coordinate properties.
Expects:
- _datum: Tuple[float, float, float] instance attribute (stored in meters)
- validate_datum(value) method available (from ValidationMixin)
Provides:
- datum property (getter/setter) in millimeters
- datum_x, datum_y, datum_z properties (getter/setter)
Setter Customization:
- Override with @DatumMixin.datum.setter and add decorators like
@calculate_coordinates or @calculate_all_properties as needed
- For translation-based updates (e.g., assemblies with computed geometry),
use _compute_datum_translation() helper before updating _datum
Examples:
Recalculation pattern (most common)::
@DatumMixin.datum.setter @calculate_coordinates def datum(self, value): self.validate_datum(value) self._datum = tuple(float(v) * MM_TO_M for v in value)
Translation pattern (for complex assemblies):
@DatumMixin.datum.setter
def datum(self, value):
self.validate_datum(value)
translation = self._compute_datum_translation(value)
if translation:
self._translate_all_components(translation)
self._datum = tuple(float(v) * MM_TO_M for v in value)
Attributes¶
Plotter
¶
Classes¶
PlotterMixin
¶
Methods:¶
hex_to_rgb
staticmethod
¶
Convert a hex colour string (e.g. '#4C78A8') to an (R, G, B) tuple.
rgb_to_hex
staticmethod
¶
Convert an (R, G, B) tuple to a hex colour string.
lighten_color
staticmethod
¶
Lighten hex_color by blending towards white.
| PARAMETER | DESCRIPTION |
|---|---|
hex_color
|
Hex colour string, e.g.
TYPE:
|
factor
|
Blend factor —
TYPE:
|
hex_to_rgba
staticmethod
¶
Convert a hex colour string to an rgba() CSS string.
create_component_trace
staticmethod
¶
create_component_trace(components: list | object, coord_attr: str, name: str, line_width: float, color_func: Callable, unit_conversion_factor: float, order_clockwise: str | None = None, gl: bool = False) -> Scatter | Scattergl | None
Create a single trace for a component or group of components with NaN separators.
| PARAMETER | DESCRIPTION |
|---|---|
components
|
Single component or list of components to process.
TYPE:
|
coord_attr
|
Attribute path for coordinates (e.g., '_a_side_coating_coordinates').
TYPE:
|
name
|
Name for the trace.
TYPE:
|
line_width
|
Width of the trace line.
TYPE:
|
color_func
|
Function to get color from component.
TYPE:
|
unit_conversion_factor
|
Factor to convert coordinates to desired units.
TYPE:
|
order_clockwise
|
Plane for clockwise ordering ('xy', 'xz', 'yz') or None to disable, by default None.
TYPE:
|
gl
|
Whether to use WebGL rendering.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Scatter | Scattergl | None
|
Plotly scatter trace or None if no valid coordinates. |
plot_breakdown_sunburst
staticmethod
¶
plot_breakdown_sunburst(breakdown_dict: dict[str, Any], title: str = 'Breakdown', root_label: str = 'Total', unit: str = '', colorway: list[str] = None, sort_siblings: bool = True, textinfo: str = 'label', branch_color_map: dict[str, str] | None = None, label_wrap_width: int = 14, **kwargs) -> Figure
Create a sunburst plot for any generic nested breakdown dictionary.
| PARAMETER | DESCRIPTION |
|---|---|
breakdown_dict
|
Nested dictionary where values can be either numbers or nested dictionaries. Each nesting level becomes a ring in the sunburst plot.
TYPE:
|
title
|
Title for the plot. Defaults to "Breakdown".
TYPE:
|
root_label
|
Label for the root node. Defaults to "Total".
TYPE:
|
unit
|
Unit string to display in hover text (e.g., "g", "kg", "%"). Defaults to "".
TYPE:
|
colorway
|
List of colors to use for the inner ring. If None, uses Plotly's default colorway. Defaults to None.
TYPE:
|
sort_siblings
|
Sort sibling nodes by descending contribution. Defaults to True.
TYPE:
|
textinfo
|
Text displayed on sunburst segments. Defaults to label only, keeping longer labels readable.
TYPE:
|
branch_color_map
|
Optional mapping from label text to a base color. Matching labels and their descendants use the mapped color.
TYPE:
|
label_wrap_width
|
Wrap labels longer than this many characters onto multiple lines. Set to 0 or None to disable wrapping. Defaults to 14.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
Plotly sunburst figure. |
plot_scatter
staticmethod
¶
plot_scatter(df: DataFrame, x: str, y: str, hover_name: str = None, custom_data: list[str] | None = None, color: str | None = None, size: str | None = None, size_max: int = 30, template: str = 'presentation', layout_defaults: dict[str, Any] | None = None, **kwargs) -> Figure
Create a styled 2-D scatter plot.
| PARAMETER | DESCRIPTION |
|---|---|
df
|
DataFrame containing the columns referenced by x, y, etc.
TYPE:
|
x
|
Column name for the X axis.
TYPE:
|
y
|
Column name for the Y axis.
TYPE:
|
hover_name
|
Column whose values appear as the main hover label.
TYPE:
|
custom_data
|
Column names to include in
TYPE:
|
color
|
Column name for colour grouping.
TYPE:
|
size
|
Column name for marker-size mapping.
TYPE:
|
size_max
|
Maximum marker size when size is set.
TYPE:
|
template
|
Plotly template name.
TYPE:
|
layout_defaults
|
Additional
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
Plotly figure. |
plot_grouped_scatter
staticmethod
¶
plot_grouped_scatter(groups, x_values, y_values, x_label: str = 'X', y_label: str = 'Y', group_label: str = 'Group', palette: list[str] | None = None, template: str = 'presentation', layout_defaults: dict[str, Any] | None = None) -> Figure
Create a scatter plot of group means with std dev error bars.
| PARAMETER | DESCRIPTION |
|---|---|
groups
|
Parallel list of group labels (one per observation).
|
x_values
|
Parallel list of numeric X values.
|
y_values
|
Parallel list of numeric Y values.
|
x_label
|
Human-readable X-axis label.
TYPE:
|
y_label
|
Human-readable Y-axis label.
TYPE:
|
group_label
|
Human-readable label for the grouping variable.
TYPE:
|
palette
|
Hex colour palette. Falls back to
TYPE:
|
template
|
Plotly template name.
TYPE:
|
layout_defaults
|
Additional
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
Plotly figure. |
plot_scatter_3d
staticmethod
¶
plot_scatter_3d(df: DataFrame, x: str, y: str, z: str, hover_name: str = None, custom_data: list[str] | None = None, color: str | None = None, size: str | None = None, size_max: int = 30, template: str = 'presentation', layout_defaults: dict[str, Any] | None = None, **kwargs) -> Figure
Create a styled 3-D scatter plot.
| PARAMETER | DESCRIPTION |
|---|---|
df
|
DataFrame containing the columns referenced by x, y, z, etc.
TYPE:
|
x
|
Column name for the X axis.
TYPE:
|
y
|
Column name for the Y axis.
TYPE:
|
z
|
Column name for the Z axis.
TYPE:
|
hover_name
|
Column whose values appear as the main hover label.
TYPE:
|
custom_data
|
Column names to include in
TYPE:
|
color
|
Column name for colour grouping.
TYPE:
|
size
|
Column name for marker-size mapping.
TYPE:
|
size_max
|
Maximum marker size when size is set.
TYPE:
|
template
|
Plotly template name.
TYPE:
|
layout_defaults
|
Additional
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
Plotly figure. |
plot_grouped_scatter_3d
staticmethod
¶
plot_grouped_scatter_3d(groups, x_values, y_values, z_values, x_label: str = 'X', y_label: str = 'Y', z_label: str = 'Z', group_label: str = 'Group', palette: list[str] | None = None, template: str = 'presentation', layout_defaults: dict[str, Any] | None = None) -> Figure
Create a 3-D scatter plot of group means with std dev error bars.
| PARAMETER | DESCRIPTION |
|---|---|
groups
|
Parallel list of group labels.
|
x_values
|
Parallel list of numeric X values.
|
y_values
|
Parallel list of numeric Y values.
|
z_values
|
Parallel list of numeric Z values.
|
x_label
|
Human-readable X-axis label.
TYPE:
|
y_label
|
Human-readable Y-axis label.
TYPE:
|
z_label
|
Human-readable Z-axis label.
TYPE:
|
group_label
|
Human-readable label for the grouping variable.
TYPE:
|
palette
|
Hex colour palette. Falls back to
TYPE:
|
template
|
Plotly template name.
TYPE:
|
layout_defaults
|
Additional
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
Plotly figure. |
plot_bar
staticmethod
¶
plot_bar(x, y, custom_data=None, x_label: str = 'X', y_label: str = 'Y', template: str = 'presentation', layout_defaults: dict[str, Any] | None = None, **kwargs) -> Figure
Create a styled bar chart.
| PARAMETER | DESCRIPTION |
|---|---|
x
|
Values for the X axis.
|
y
|
Values for the Y axis.
|
custom_data
|
Custom data attached to each bar (for click handlers).
DEFAULT:
|
x_label
|
Human-readable X-axis label.
TYPE:
|
y_label
|
Human-readable Y-axis label.
TYPE:
|
template
|
Plotly template name.
TYPE:
|
layout_defaults
|
Additional
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
Plotly figure. |
plot_grouped_bar
staticmethod
¶
plot_grouped_bar(groups, values, y_label: str = 'Y', group_label: str = 'Group', palette: list[str] | None = None, template: str = 'presentation', layout_defaults: dict[str, Any] | None = None) -> Figure
Create a bar chart showing mean +/- std dev per group.
| PARAMETER | DESCRIPTION |
|---|---|
groups
|
Parallel list of group labels (one per observation).
|
values
|
Parallel list of numeric values (one per observation).
|
y_label
|
Human-readable Y-axis label.
TYPE:
|
group_label
|
Human-readable X-axis (group axis) label.
TYPE:
|
palette
|
Hex colour palette. Falls back to
TYPE:
|
template
|
Plotly template name.
TYPE:
|
layout_defaults
|
Additional
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
Plotly figure. |
plot_histogram
staticmethod
¶
plot_histogram(x, x_label: str = 'Value', template: str = 'presentation', layout_defaults: dict[str, Any] | None = None, **kwargs) -> Figure
Create a styled histogram.
| PARAMETER | DESCRIPTION |
|---|---|
x
|
Values to bin.
|
x_label
|
Human-readable axis label.
TYPE:
|
template
|
Plotly template name.
TYPE:
|
layout_defaults
|
Additional
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
Plotly figure. |
plot_grouped_histogram
staticmethod
¶
plot_grouped_histogram(groups, values, x_label: str = 'Value', palette: list[str] | None = None, template: str = 'presentation', layout_defaults: dict[str, Any] | None = None) -> Figure
Create overlaid histograms, one per group.
| PARAMETER | DESCRIPTION |
|---|---|
groups
|
Parallel list of group labels.
|
values
|
Parallel list of numeric values.
|
x_label
|
Human-readable axis label.
TYPE:
|
palette
|
Hex colour palette. Falls back to
TYPE:
|
template
|
Plotly template name.
TYPE:
|
layout_defaults
|
Additional
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
Plotly figure. |
plot_pdf
staticmethod
¶
plot_pdf(values, label: str = 'Value', color_groups: dict[str, list[float]] | None = None, template: str = 'presentation', layout_defaults: dict[str, Any] | None = None) -> Figure
Create a probability-density histogram (one trace per colour group).
| PARAMETER | DESCRIPTION |
|---|---|
values
|
Values to bin (used when color_groups is
|
label
|
Human-readable axis label.
TYPE:
|
color_groups
|
Mapping
TYPE:
|
template
|
Plotly template name.
TYPE:
|
layout_defaults
|
Additional
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
Plotly figure. |
plot_grouped_pdf
staticmethod
¶
plot_grouped_pdf(groups, values, label: str = 'Value', palette: list[str] | None = None, template: str = 'presentation', layout_defaults: dict[str, Any] | None = None) -> Figure
Create overlaid probability-density histograms, one per group.
| PARAMETER | DESCRIPTION |
|---|---|
groups
|
Parallel list of group labels.
|
values
|
Parallel list of numeric values.
|
label
|
Human-readable axis label.
TYPE:
|
palette
|
Hex colour palette. Falls back to
TYPE:
|
template
|
Plotly template name.
TYPE:
|
layout_defaults
|
Additional
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
Plotly figure. |
plot_box
staticmethod
¶
plot_box(y, x=None, custom_data=None, y_label: str = 'Y', points: str = 'all', template: str = 'presentation', layout_defaults: dict[str, Any] | None = None, **kwargs) -> Figure
Create a styled box plot.
| PARAMETER | DESCRIPTION |
|---|---|
y
|
Values for the Y axis.
|
x
|
Category values for grouping along the X axis.
DEFAULT:
|
custom_data
|
Custom data attached to each point (for click handlers).
DEFAULT:
|
y_label
|
Human-readable Y-axis label.
TYPE:
|
points
|
One of
TYPE:
|
template
|
Plotly template name.
TYPE:
|
layout_defaults
|
Additional
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
Plotly figure. |
plot_violin
staticmethod
¶
plot_violin(y, x=None, custom_data=None, y_label: str = 'Y', points: str = 'all', box: bool = True, template: str = 'presentation', layout_defaults: dict[str, Any] | None = None, **kwargs) -> Figure
Create a styled violin plot.
| PARAMETER | DESCRIPTION |
|---|---|
y
|
Values for the Y axis.
|
x
|
Category values for grouping along the X axis.
DEFAULT:
|
custom_data
|
Custom data attached to each point.
DEFAULT:
|
y_label
|
Human-readable Y-axis label.
TYPE:
|
points
|
One of
TYPE:
|
box
|
Whether to overlay an inner box-plot.
TYPE:
|
template
|
Plotly template name.
TYPE:
|
layout_defaults
|
Additional
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
Plotly figure. |
plot_strip
staticmethod
¶
plot_strip(y, x=None, hover_name=None, custom_data=None, y_label: str = 'Y', template: str = 'presentation', layout_defaults: dict[str, Any] | None = None, **kwargs) -> Figure
Create a styled strip (jitter) plot.
| PARAMETER | DESCRIPTION |
|---|---|
y
|
Values for the Y axis.
|
x
|
Category values for grouping along the X axis.
DEFAULT:
|
hover_name
|
Values to display as the main hover label.
DEFAULT:
|
custom_data
|
Custom data attached to each point.
DEFAULT:
|
y_label
|
Human-readable Y-axis label.
TYPE:
|
template
|
Plotly template name.
TYPE:
|
layout_defaults
|
Additional
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
Plotly figure. |
plot_radar
staticmethod
¶
plot_radar(df: DataFrame, axis_labels: list[str], inverted: dict[str, bool] | None = None, color_column: str | None = None, name_column: str = 'name', palette: list[str] | None = None, template: str = 'presentation', layout_defaults: dict[str, Any] | None = None) -> Figure
Create a normalised radar (spider) chart.
Each row in df becomes a Scatterpolar trace. Values are
normalised to 0–1 per axis so properties with very different scales
are comparable. Per-spoke tick annotations show the original values.
| PARAMETER | DESCRIPTION |
|---|---|
df
|
Must contain columns named in axis_labels (raw values) and name_column. Optionally contains color_column.
TYPE:
|
axis_labels
|
Column names in df for the radar axes.
TYPE:
|
inverted
|
TYPE:
|
color_column
|
Column name for categorical colour grouping.
TYPE:
|
name_column
|
Column name used as the trace name / hover label.
TYPE:
|
palette
|
Hex colour palette. Falls back to
TYPE:
|
template
|
Plotly template name.
TYPE:
|
layout_defaults
|
Additional
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
Plotly figure. |
plot_grouped_radar
staticmethod
¶
plot_grouped_radar(df: DataFrame, axis_labels: list[str], group_column: str, inverted: dict[str, bool] | None = None, palette: list[str] | None = None, template: str = 'presentation', layout_defaults: dict[str, Any] | None = None) -> Figure
Create a normalised radar chart showing group means with std dev bands.
Rows are grouped by group_column; each group becomes a trace showing the per-axis mean. A lighter shaded band shows +/- 1 std dev.
| PARAMETER | DESCRIPTION |
|---|---|
df
|
Must contain columns named in axis_labels and group_column.
TYPE:
|
axis_labels
|
Column names in df for the radar axes.
TYPE:
|
group_column
|
Column name used for grouping.
TYPE:
|
inverted
|
TYPE:
|
palette
|
Hex colour palette. Falls back to
TYPE:
|
template
|
Plotly template name.
TYPE:
|
layout_defaults
|
Additional
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
Plotly figure. |
plot_correlation_heatmap
staticmethod
¶
plot_correlation_heatmap(df: DataFrame, axis_labels: list[str], template: str = 'presentation', layout_defaults: dict[str, Any] | None = None) -> Figure
Create an annotated Pearson correlation heatmap.
| PARAMETER | DESCRIPTION |
|---|---|
df
|
DataFrame containing at least axis_labels as numeric columns.
TYPE:
|
axis_labels
|
Column names to include in the correlation matrix.
TYPE:
|
template
|
Plotly template name.
TYPE:
|
layout_defaults
|
Additional
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
Plotly figure. |
Propagation
¶
Mixin for update propagation through hierarchical object trees.
Classes¶
PropagationMixin
¶
Mixin providing update propagation through a hierarchical object tree.
This mixin adds two methods:
- update(): Triggers the parent's setter for this object (one level up)
- propagate_changes(): Triggers parent setters all the way up to root
Each object can have a parent reference. When a child is assigned to a parent,
the parent should call child._set_parent(self, 'attribute_name') to establish
the link. The attribute name is used during propagation to re-assign the child
to the parent via its setter.
Python's cyclic garbage collector handles any circular references.
Serialization Note
The _parent reference is skipped during serialization to avoid circular
serialization. Parent references are re-established when objects are
reassembled after deserialization (via setters that call _set_parent).
Example Usage:
Change property at any depth:¶
root.assembly.layout.child.sub_component.thickness = new_value
Option 1: Update current level by triggering parent's setter¶
root.assembly.layout.child.sub_component.update()
Equivalent to: a.b.c.sub_component = a.b.c.sub_component¶
Option 2: Propagate changes all the way to root (triggers all parent setters)¶
root.assembly.layout.child.sub_component.propagate_changes()
Equivalent to re-assigning at each level up to root¶
Methods:¶
update
¶
Trigger the parent's setter for this object.
This is equivalent to parent.attr = self, ensuring that all setter
logic (validation, coordinate calculation, etc.) is executed.
If this object has no parent, falls back to calling
_calculate_all_properties() directly.
Use propagate_changes() to bubble updates all the way to the root.
batch_updates
¶
Context manager for efficient batch property updates.
Temporarily disables automatic recalculation during property changes, then performs a single recalculation when exiting the context.
Use this when setting multiple properties at once to avoid redundant recalculations that would otherwise occur after each property change.
Examples:
>>> with obj.batch_updates():
... obj.property_a = value_a
... obj.property_b = value_b
# Single recalculation happens here
| YIELDS | DESCRIPTION |
|---|---|
None
|
None |
propagate_changes
¶
Propagate changes up to root by triggering parent setters.
This method triggers the parent's setter by re-assigning this object to its parent attribute. This ensures any parent setter logic (validation, name modification, coordinate calculation, etc.) is executed during propagation.
The propagation continues recursively until reaching the root.
Note: This does NOT call update() on the current object - that should already have happened via the property setter's @calculate_all_properties decorator when the property was modified.
Use this when you want changes to bubble up automatically. Use
update() instead when you need to manually trigger recalculation.
Functions:¶
propagating_setter
¶
Decorator for setters that manage parent-child relationships.
This decorator: 1. Clears the old child's parent reference (if replacing with different object) 2. Optionally creates a deep copy of the value (for storing copies) 3. Sets the new child's parent reference with the attribute name
| PARAMETER | DESCRIPTION |
|---|---|
attr_name
|
The attribute name to use for propagation. If not provided, the decorator will derive it from the setter's name.
TYPE:
|
deepcopy
|
If True, creates a deep copy of the value before passing to the setter. Useful when you want to store a copy rather than the original. During propagation (re-assignment of the same stored object), no copy is made to avoid unnecessary duplication.
TYPE:
|
Example Usage:
Standard usage (no copy):¶
@component.setter @calculate_all_properties @propagating_setter() def component(self, component: _Component): self.validate_type(component, _Component, "component") self._component = component
With deepcopy (stores a copy):¶
@material.setter @calculate_bulk_properties @propagating_setter(deepcopy=True) def material(self, material: Material | None): self.validate_type(material, Material, "material") self._material = material # This is already a copy
Serializer
¶
Classes¶
SerializerMixin
¶
Methods:¶
serialize
¶
Serialize object using MessagePack with numpy support.
| PARAMETER | DESCRIPTION |
|---|---|
compress
|
Whether to compress the serialized data (default: True).
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bytes
|
The serialized byte representation of the object. |
deserialize
classmethod
¶
Deserialize byte data into an object. Automatically detects and decompresses if needed. Supports both LZ4 (new) and zlib (legacy) compression.
| PARAMETER | DESCRIPTION |
|---|---|
data
|
The byte data to deserialize.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
T
|
Instance of the class. |
from_database
classmethod
¶
Pull object from the database by name.
Subclasses must define a '_table_name' class variable (str or list of str) unless table_name is explicitly provided.
The backend is selected by the OPENCELL_ENV environment variable:
development(default) — uses the local SQLite database viasteer_opencell_data.DataManager. No network calls, works offline. Requiressteer-opencell-datato be installed withdatabase.db.production— uses the REST API viasteer_core.Data.DataManager. Requires theAPI_URLenv var pointing to the deployed Lambda endpoint.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Name of the object to retrieve.
TYPE:
|
table_name
|
Specific table to search. If provided, '_table_name' is not required. If None, uses class's _table_name.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
T
|
Instance of the class. |
| RAISES | DESCRIPTION |
|---|---|
NotImplementedError
|
If the subclass doesn't define '_table_name' and table_name is not provided. |
ValueError
|
If the object name is not found in any of the tables. |
Thermodynamics
¶
Thermodynamics mixin providing generic phase equilibrium calculations.
This mixin provides reusable thermodynamic functions that can be composed with material classes.
Classes¶
ThermodynamicsMixin
¶
Mixin providing generic thermodynamic calculation methods.
Methods:¶
calculate_antoine_pressure
staticmethod
¶
Calculate vapor pressure using Antoine equation.
Equation: log10(P) = A - B / (T + C)
| PARAMETER | DESCRIPTION |
|---|---|
T
|
Temperature (units depend on Antoine coefficients, typically °C or K)
TYPE:
|
A, B, C
|
Antoine coefficients for the substance
|
| RETURNS | DESCRIPTION |
|---|---|
float
|
Vapor pressure (units depend on Antoine coefficients, typically mmHg or bar) |
calculate_antoine_temperature
staticmethod
¶
Calculate temperature from vapor pressure using inverse Antoine equation.
| PARAMETER | DESCRIPTION |
|---|---|
P
|
Vapor pressure (same units as Antoine coefficients)
TYPE:
|
A, B, C
|
Antoine coefficients for the substance
|
| RETURNS | DESCRIPTION |
|---|---|
float
|
Temperature (same units as Antoine coefficients) |
calculate_ideal_gas_density
staticmethod
¶
Calculate ideal gas density using ideal gas law.
| PARAMETER | DESCRIPTION |
|---|---|
P_Pa
|
Pressure in Pascals
TYPE:
|
T_K
|
Temperature in Kelvin
TYPE:
|
MW_kg_mol
|
Molecular weight in kg/mol
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
float
|
Density in kg/m³ |
TypeChecker
¶
Classes¶
ValidationMixin
¶
Methods:¶
validate_plotly_trace
staticmethod
¶
Check whether value is a Plotly trace object.
| PARAMETER | DESCRIPTION |
|---|---|
value
|
The value to validate.
TYPE:
|
name
|
The name of the parameter (unused, kept for API compatibility).
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
|
validate_type
staticmethod
¶
Validate that a value is of the expected type or one of multiple allowed types.
| PARAMETER | DESCRIPTION |
|---|---|
value
|
The value to validate.
|
expected_type
|
A single expected type or an iterable (list/tuple/set) of acceptable types.
|
name
|
The name of the parameter for error messages.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If the value is not an instance of any of the expected types. |
Examples:
>>> ValidationMixin.validate_type(5, int, 'count') # OK
>>> ValidationMixin.validate_type(5, (int, float), 'count') # OK
>>> ValidationMixin.validate_type('x', (int, float), 'count') # TypeError
>>> ValidationMixin.validate_type([1,2,3], list, 'items') # OK
>>> ValidationMixin.validate_type([1,2,3], [list, tuple], 'items') # OK
validate_percentage
staticmethod
¶
Validate that a value is a percentage (between 0 and 100).
| PARAMETER | DESCRIPTION |
|---|---|
value
|
The value to validate.
TYPE:
|
name
|
The name of the parameter for error messages.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If the value is not a percentage. |
validate_fraction
staticmethod
¶
Validate that a value is a fraction (between 0 and 1).
| PARAMETER | DESCRIPTION |
|---|---|
value
|
The value to validate.
TYPE:
|
name
|
The name of the parameter for error messages.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If the value is not a fraction. |
validate_pandas_dataframe
staticmethod
¶
Validate that the input is a pandas DataFrame.
| PARAMETER | DESCRIPTION |
|---|---|
df
|
The DataFrame to validate.
TYPE:
|
name
|
The name of the DataFrame for error messages.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If the input is not a pandas DataFrame. |
validate_datum
staticmethod
¶
Validate the datum point for extrusion.
| PARAMETER | DESCRIPTION |
|---|---|
datum
|
Datum point for extrusion (shape (3,)).
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If the datum does not have exactly 3 coordinates. |
validate_positive_float
staticmethod
¶
Validate that a value is a positive float.
| PARAMETER | DESCRIPTION |
|---|---|
value
|
The value to validate.
TYPE:
|
name
|
The name of the parameter for error messages.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If the value is not a positive float. |
validate_positive_int
staticmethod
¶
Validate that a value is a positive integer.
| PARAMETER | DESCRIPTION |
|---|---|
value
|
The value to validate.
TYPE:
|
name
|
The name of the parameter for error messages.
TYPE:
|
strictly
|
If True (default), value must be strictly positive (> 0). If False, value must be non-negative (>= 0).
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If the value is not an integer (bool is rejected even though it is a subclass of int). |
ValueError
|
If the integer does not meet the positivity requirement. |
Examples:
>>> ValidationMixin.validate_positive_int(5, 'count') # OK
>>> ValidationMixin.validate_positive_int(0, 'count') # ValueError (strict mode)
>>> ValidationMixin.validate_positive_int(0, 'count', strictly=False) # OK (non-strict mode)
>>> ValidationMixin.validate_positive_int(-3, 'count') # ValueError
>>> ValidationMixin.validate_positive_int(True, 'flag') # TypeError (bool rejected)
>>> ValidationMixin.validate_positive_int(12_000, 'cycles') # OK
validate_string
staticmethod
¶
Validate that a value is a string.
| PARAMETER | DESCRIPTION |
|---|---|
value
|
The value to validate.
TYPE:
|
name
|
The name of the parameter for error messages.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If the value is not a string. |
validate_two_iterable_of_floats
staticmethod
¶
Validate that a value is a tuple of two iterables.
| PARAMETER | DESCRIPTION |
|---|---|
value
|
The value to validate.
TYPE:
|
name
|
The name of the parameter for error messages.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If the value is not a tuple of two floats. |
validate_positive_float_list
staticmethod
¶
Validate that a value is a list of positive floats.
| PARAMETER | DESCRIPTION |
|---|---|
value
|
The value to validate.
TYPE:
|
name
|
The name of the parameter for error messages.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If the value is not a list of positive floats. |
validate_enum_string
staticmethod
¶
Validate that a string value belongs to an enum class.
| PARAMETER | DESCRIPTION |
|---|---|
value
|
The string value to validate.
|
enum_class
|
The enum class to validate against.
TYPE:
|
name
|
The name of the parameter for error messages.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If the value is not a string. |
ValueError
|
If the string value is not a valid member of the enum class. |
Examples:
validate_datetime_string
staticmethod
¶
Validate that a string is in a valid datetime format.
Accepts either 'YYYY-MM-DD-HH' (hourly) or 'YYYY-MM-DD' (daily) formats.
| PARAMETER | DESCRIPTION |
|---|---|
value
|
The datetime string to validate.
TYPE:
|
name
|
The name of the parameter for error messages.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If the value is not a string. |
ValueError
|
If the string is not in a valid datetime format. |
Examples:
validate_number
staticmethod
¶
Validate that a value is a numeric amount (int or float, but not bool).
| PARAMETER | DESCRIPTION |
|---|---|
value
|
The numeric value to validate.
|
name
|
The name of the parameter for error messages.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If the value is a bool or not a numeric type (int or float). |
Examples:
validate_base_binning_frequency
staticmethod
¶
validate_display_frequency
staticmethod
¶
Validate that display_freq is equal to or coarser than base_freq.
Parameters¶
display_freq : Frequency enum The display frequency to validate. base_freq : Frequency enum The base binning frequency. name : str Parameter name used in the error message.
Raises¶
ValueError If display_freq is finer than base_freq.
validate_base_binning_frequency_not_increased
staticmethod
¶
validate_base_binning_frequency_not_increased(current_freq, new_freq, name: str = 'base_binning_frequency') -> None
Validate that new_freq is not finer than current_freq.
Prevents increasing the resolution of an already-set base binning frequency (e.g., daily → hourly), which would fabricate precision that was never there. Going coarser (hourly → daily) is always allowed.
Parameters¶
current_freq : Frequency enum The currently set base binning frequency. new_freq : Frequency enum The proposed new base binning frequency. name : str Parameter name used in the error message.
Raises¶
ValueError If new_freq is finer than current_freq.
validate_compounding_frequency
staticmethod
¶
validate_compounding_frequency(base_freq, compounding_freq, name: str = 'compounding_frequency') -> None
Validate that base_freq is equal to or finer than compounding_freq.
Parameters¶
base_freq : Frequency enum The base binning frequency. compounding_freq : Frequency enum The compounding frequency. name : str Parameter name used in the error message.
Raises¶
ValueError If base_freq is coarser than compounding_freq.