Core¶
Core helper mixins used across schema classes.
Schemas for core.
- class ionworks.pipeline.core.ConfigMixin[source]¶
Bases:
BaseSchemaMixin that automatically captures __init__ parameters for subclasses.
When a class inherits from this mixin, any subclass that defines its own __init__ method will have its parameters automatically captured and stored in self._init_params. This is useful for serialization/deserialization (e.g., to_config methods for reverse parsing).
Additionally, if the __init__ has an “options” parameter, it captures which option keys were explicitly passed in self._options_keys_passed before calling the original __init__.
The captured parameters exclude self and filter out None values.
This mixin also provides config_schema() classmethod that generates a pydantic schema from the class’s __init__ signature. This is used by ionworksschema generation.
- model_config = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
Containers¶
BaseSchema and the pipeline containers every element is assembled into.
Base classes for ionworks.pipeline.
- ionworks.pipeline.base.reject_runtime_object(value: Any, field_name: str, expected: str) NoReturn[source]¶
Reject a value that is neither a config dict nor a schema instance.
Centralizes the boundary guard shared by the distribution, sampler, prior, and objective resolvers. The schema contract holds only
ionworks.pipelineobjects — a config dict or the matching schema instance — so a live runtime object must be converted (via.to_config()or the matchingionworks.pipelineschema class) before it enters a schema, rather than embedded raw. Callers invoke this on the fall-through branch after they have already accepted the dict and schema-instance forms.- Parameters:
value (Any) – The rejected value, echoed into the error message via
repr.field_name (str) – The schema field being resolved (e.g.
"distribution","sampler","prior","objective"), used to phrase the message.expected (str) – User-facing description of the accepted non-dict form, phrased with its article so it reads in the message (e.g.
"a Distribution instance","an ionworks.pipeline objective instance"). Use the public vocabulary, not an internal implementation class name.
- Raises:
ValueError – Always. The function never returns normally.
- class ionworks.pipeline.base.BaseSchema[source]¶
Bases:
BaseModelShared parent of every schema class in this package.
Construct a concrete subclass (
iw.pipeline.Pipeline,iw.pipeline.DataFit, …) rather than this. It rejects unknown fields, so a typo fails at construction, and provides.to_config(), the only supported serializer:.model_dump()omits thetypediscriminator and uses attribute names (data_input) rather than wire names (data).- model_config = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- to_config() dict[source]¶
Build the dict you submit through
ionworks.api.Nested schemas convert recursively,
Nonefields are dropped, and each component the server must re-identify gains a"type"key.Notes
The only supported serializer.
.model_dump()(even withby_alias=True) omits the"type"discriminator, so it is not a payload:iw.pipeline.stats.Uniform(lb=0.0, ub=1.0).to_config()gives{"distribution": "Uniform", "lb": 0.0, "ub": 1.0}, whereas.model_dump(exclude_none=True)gives{"lb": 0.0, "ub": 1.0}.
- class ionworks.pipeline.base.Pipeline(elements: dict | None = None, output_file: str | None = None, name: str | None = None, description: str | None = None)[source]¶
Bases:
BaseSchemaA sequence of steps that together produce a parameterised cell model.
Each element pulls parameters from a source (
DirectEntry), fits them to data (DataFit), derives quantities (Calculation) or checks them against held-out data (Validation), and passes its parameters to the next, so order matters. Submit.to_config()throughionworks.apito run it server-side.- Parameters:
elements (dict, optional) – Mapping of element name to pipeline element (
DataFit,DirectEntry,Validation,Calculation, …). The name is used to identify the element in the pipeline report.Noneis treated as an empty pipeline byto_config.output_file (str, optional) – Optional file path for persisting the final parameter values produced by the pipeline. If
None, parameters are not written to disk.name (str, optional) – Human-readable name for the pipeline, used in reports and logs.
description (str, optional) – Free-text description of what the pipeline does.
Examples
>>> # known parameters (e.g. ambient temperature) >>> known = iw.pipeline.direct_entries.DirectEntry( ... parameters={"Ambient temperature [K]": 298.15}, ... ) >>> # fit one parameter against an OCP measurement >>> obj = iw.pipeline.objectives.OCPHalfCell( ... electrode="positive", ... data_input="path/to/ocp.csv", ... ) >>> fit = iw.pipeline.DataFit( ... objectives={"ocp": obj}, ... parameters={"Positive electrode capacity [A.h]": iw.pipeline.Parameter( ... "Positive electrode capacity [A.h]", initial_value=3.0, bounds=(2.0, 4.0), ... )}, ... ) >>> # validate the fit against held-out cycling data >>> val_obj = iw.pipeline.objectives.CurrentDriven( ... data_input="path/to/cycle.csv", options={"model": "SPM"} ... ) >>> val = iw.pipeline.Validation(objectives={"cycle": val_obj}) >>> pipeline = iw.pipeline.Pipeline( ... {"known": known, "ocp fit": fit, "validate": val} ... ) >>> config = pipeline.to_config() >>> # then submit `config` via ionworks.api
- to_config() dict[source]¶
Build the pipeline payload you submit through
ionworks.api.Walks every element you added to
elements, serialises it (each element’s ownto_config), and tags it with its kind ("entry","data_fit","validation", …) so the server knows how to dispatch it. Pass the returned dict to the Ionworks API to run the full pipeline.
- model_config = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class ionworks.pipeline.base.SimplePipeline(*args: Any, elements: dict | None = None, output_file: str | None = None, name: str | None = None, description: str | None = None)[source]¶
Bases:
PipelineA pipeline that permits at most one expensive element.
Warning
Deprecated, and removed in a future release. Use
Pipeline, which accepts the same elements.SimplePipelineis identical toPipelineexcept that it rejects configurations containing more than one expensive element (DataFit,ArrayDataFit, orValidation) at construction time, matching the constraint the SimplePipeline API endpoint enforces.- Parameters:
elements (dict, optional) – Mapping of element name to pipeline element (
DataFit,DirectEntry,Validation,Calculation, …). At most one element may be aDataFit,ArrayDataFit, orValidation.output_file (str, optional) – Optional file path for persisting the final parameter values produced by the pipeline. If
None, parameters are not written to disk.name (str, optional) – Human-readable name for the pipeline, used in reports and logs.
description (str, optional) – Free-text description of what the pipeline does.
- Raises:
ValueError – If
elementscontains more than oneDataFit,ArrayDataFit, orValidationelement.
Examples
>>> entry = iw.pipeline.direct_entries.DirectEntry( ... parameters={"Ambient temperature [K]": 298.15}, ... ) >>> obj = iw.pipeline.objectives.OCPHalfCell( ... electrode="positive", ... data_input="path/to/ocp.csv", ... ) >>> fit = iw.pipeline.DataFit( ... objectives={"ocp": obj}, ... parameters={"Positive electrode capacity [A.h]": iw.pipeline.Parameter( ... "Positive electrode capacity [A.h]", ... initial_value=3.0, ... bounds=(2.0, 4.0), ... )}, ... ) >>> pipeline = iw.pipeline.SimplePipeline( ... elements={"known": entry, "ocp fit": fit}, ... name="Single OCP fit", ... ) >>> config = pipeline.to_config()
- model_config = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].