Skip to content

Feature/element data classes+id+dataclasses+data#614

Open
FBumann wants to merge 34 commits intofeature/element-data-classes+idfrom
feature/element-data-classes+id+dataclasses+data
Open

Feature/element data classes+id+dataclasses+data#614
FBumann wants to merge 34 commits intofeature/element-data-classes+idfrom
feature/element-data-classes+id+dataclasses+data

Conversation

@FBumann
Copy link
Member

@FBumann FBumann commented Feb 17, 2026

Description

Brief description of the changes in this PR.

Type of Change

  • Bug fix
  • New feature
  • Documentation update
  • Code refactoring

Related Issues

Closes #(issue number)

Testing

  • I have tested my changes
  • Existing tests still pass

Checklist

  • My code follows the project style
  • I have updated documentation if needed
  • I have added tests for new functionality (if applicable)

FBumann and others added 30 commits February 15, 2026 12:10
  - Piece: 2 init fields (start, end) + 1 internal field (has_time_dim with init=False)
  - Piecewise: 1 field (pieces) + property has_time_dim with propagation setter
  - PiecewiseConversion: 1 field (piecewises) + property has_time_dim with propagation setter
  - PiecewiseEffects: 2 fields (piecewise_origin, piecewise_shares) + property has_time_dim with propagation setter
  - InvestParameters: 9 fields with defaults + __post_init__ for None→{} and None→epsilon normalization
  - StatusParameters: 11 fields with defaults + __post_init__ for None→{} normalization

  All classes:
  - Use @DataClass(eq=False) to avoid issues with numpy/DataArray equality
  - Keep Interface inheritance (serialization still works)
  - Keep transform_data() and link_to_flow_system() (to be removed in later phases when *Data classes handle alignment)

⏺ Task #11 complete. 389 test_math tests pass + 136 IO tests pass. The leaf interface classes (Piece, Piecewise, PiecewiseConversion, PiecewiseEffects,
  InvestParameters, StatusParameters) are now @DataClass with auto-generated __init__ and __repr__, storing raw types in their fields.
StatusData, InvestmentData, and ConvertersData now handle their own
effect alignment via coords/normalize_effects params, removing the need
for transform_data()/link_to_flow_system() calls on StatusParameters,
InvestParameters, and PiecewiseConversion from Element classes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…terfaces

Remove now-unused methods from Piece, Piecewise, PiecewiseConversion,
PiecewiseEffects, InvestParameters, and StatusParameters since alignment
is now handled by *Data classes in batched.py. Also remove the
has_time_dim propagation mechanism that was only used by transform_data.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Flow attributes now stay as raw user data after connect_and_transform().
Alignment to model coordinates happens lazily in FlowsData at model-build
time via a new _align() helper. Also extends align_to_coords to handle
Python lists (for IO roundtrip) and fixes serialization of unnamed DataArrays.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove Interface inheritance from Piece, Piecewise, PiecewiseConversion,
PiecewiseEffects, InvestParameters, StatusParameters. Add dataclass
serialization support in _extract_dataarrays_recursive for plain
dataclasses. Add standalone _has_value function and __repr__ methods.
Convert Piece values to DataArray in __post_init__.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Effect attributes are now aligned lazily in EffectsData via
align_to_coords/align_effects_to_coords instead of eagerly in
Effect.transform_data(). Move validate_config checks to
EffectsData.validate(). Effect.transform_data() is now a no-op.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bus.imbalance_penalty_per_flow_hour is now aligned lazily in BusesData
via align_to_coords. Move validate_config checks to BusesData.validate().
Bus.transform_data() is now a no-op.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rsData

Conversion factors are now aligned lazily in ConvertersData via
align_to_coords. Move validate_config checks to ConvertersData.validate().
LinearConverter.transform_data() now only calls super for status propagation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Storage attributes are now aligned lazily in StoragesData via
align_to_coords. Move validate_config checks to StoragesData.validate().
Storage.transform_data() now only calls super for status propagation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nsData

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the element.transform_data() loop in connect_and_transform()
with explicit _propagate_all_status_parameters(). Remove transform_data()
from all element classes and Interface base. Remove unused _fit_coords
and _fit_effect_coords from Interface. All data alignment now happens
lazily in *Data classes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move all validation checks from element validate_config() methods into
the corresponding *Data.validate() in batched.py. Remove validate_config()
and _plausibility_checks() from Flow, Component, EffectsCollection, and
the abstract _plausibility_checks from Element base class.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…th-based naming

Replace Interface's ~500 lines of IO infrastructure with standalone functions
(create_reference_structure, resolve_reference_structure, etc.) that use
deterministic path-based DataArray keys (e.g., components.Boiler.size).
Interface methods become thin wrappers. FlowSystemDatasetIO uses standalone
functions via lazy imports. This enables future removal of Interface inheritance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move handle_deprecated_kwarg() and validate_kwargs() to module-level
standalone functions. Remove dead wrapper methods (_create_reference_structure,
_resolve_dataarray_reference, _resolve_reference_structure, _has_value) from
Interface. Remove Interface inheritance from Carrier since it only needs
@register_class_for_io. Update FlowSystem to build datasets directly via its
own _create_reference_structure instead of super().to_dataset().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The base method was a one-liner and all 6 overrides were either no-ops
(just calling super) or propagating to flows (which _connect_network
already handles). Replace with direct _flow_system assignment at the
4 call sites and in _connect_network for flows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Merge Interface into Element, remove Interface class (~240 lines)
- Convert Effect, Bus, Component to @DataClass(eq=False, repr=False)
- Convert Flow to @DataClass(eq=False, repr=False, init=False) preserving deprecation bridge
- Convert LinearConverter, Storage, Transmission, Source, Sink, SourceAndSink to @DataClass
- Add _io_exclude class attribute for excluding computed fields from serialization
- Remove dead ContainerMixin, FlowContainer, ElementContainer, ResultsContainer (~244 lines)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove Element.__init__(), validate_kwargs(), and handle_deprecated_kwarg()
as dead code now that all element classes are @DataClass. Simplify Flow's
custom __init__ to use a positional-only param with clean bus/flow_id
resolution, dropping all deprecation bridges (label=, id=, *args form).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract valid_id() and replace_references_with_stats() to module-level functions
- Remove _short_id indirection from all element classes
- Remove unused IO methods from Element (to_dataset, from_dataset, to_netcdf,
  from_netcdf, to_json, get_structure, copy) — only FlowSystem uses these
- Remove Element.id property/setter, __repr__, _valid_id, _valid_label
- Remove nonsensical Flow.id setter (computed property can't round-trip)
- Add Flow.label override returning flow_id with deprecation warning

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ersion

Make create_reference_structure() coords-aware so numpy arrays and pandas
objects are converted to DataArrays during serialization. Remove Piece
__post_init__ that eagerly converted start/end to DataArray. Remove unused
obj_to_dataset/obj_from_dataset standalone serialization functions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rename _is_alignable_numeric to _is_numeric_array, remove unnecessary
bool guard, improve docstrings. Only convert arrays when coords is
available (avoids dim_0 dimension conflicts). Minor formatting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove dead model references (_flows_model, _buses_model, _storages_model)
- Move runtime state (_flow_system, _variable_names, _constraint_names) to FlowSystem registry
- Convert Flow to keyword-only dataclass init (bus= required kwarg)
- Prefer dataclasses.fields() over inspect.signature() for IO serialization
- Remove Element.solution and Element.flow_system properties

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t Storage flows

- Remove unnecessary flow_id= from docs, docstrings, and examples
- Update conversion_factors keys to match bus names where flow_id was removed
- Storage auto-defaults flow_id to 'charging'/'discharging' when not set
- Defer Flow.flow_id defaulting to Component._connect_flows for composability
- Fix effects_per_flow_hour type annotation to Numeric_TPS | dict | None
- Keep meta_data as field(default_factory=dict)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…_init__

Avoids Python dataclass ordering issues (required fields after defaults from
parent) by using explicit __init__ that calls super().__init__() directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tputs to list[Flow]

- Remove fake '' defaults from mandatory fields (Component.id, Flow.bus)
- Serialize IdList as list instead of dict (keys are derivable from objects)
- Remove dict-to-list conversion code from Component.__post_init__ and subclasses
- Simplify type annotations: list[Flow] instead of list[Flow] | dict[str, Flow]

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…n paths

- Serialize scalars as 0-d DataArrays (no broadcasting) alongside arrays
- Use flow ids instead of numeric indices for IdList serialization paths
- Unwrap 0-d DataArrays back to Python scalars on deserialization
- Move flow_id uniqueness check after _connect_flows() to avoid false
  collisions on unresolved None flow_ids
- Simplify FlowSystem restoration with _resolve helper for ::: references

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace FlowsData(flows, flow_system) with explicit params
(coords, effect_ids, timestep_duration, normalize_effects) and
add from_elements() classmethod. FlowsData no longer holds a
reference to the entire FlowSystem, making it a pure data container.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
FBumann and others added 4 commits February 16, 2026 15:46
…lder

Extract build_flows_dataset() into new flixopt/datasets.py that eagerly
builds an xr.Dataset with all flow parameters. FlowsData becomes a thin
wrapper (~500 lines) delegating to the Dataset instead of ~900 lines of
@cached_property getters. Fix generic dim_* dimensions at the IO layer
(_extract_recursive) so they are never stored in netcdf.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
FlowsModel now accesses self.data.ds['var'] directly instead of going
through ~40 cached_property DataArray getters on FlowsData. Absolute
bounds computation inlined into FlowsModel.rate. Subset selection
(.sel/.dropna) moved to point of use in FlowsModel.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…Port, Storage

Replace Component base class with self-contained element classes:
- Converter: replaces LinearConverter, with factory classmethods (boiler, chp, heat_pump, etc.)
- Port: replaces Source/Sink/SourceAndSink with unified imports/exports interface
- Storage: now inherits from Element directly instead of Component
- Split FlowSystem.components into separate containers (converters, ports, storages, transmissions)
  with backward-compatible computed .components property
- Update IO serialization to use separate container keys with legacy format support
- Update all docs and notebooks to use new API
- Deprecate old classes (Source, Sink, SourceAndSink, Boiler, CHP, etc.) with warnings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…_connect_network, updated tests

- Rename add_elements() to add() as primary method (deprecated wrapper kept)
- Make Transmission self-contained (inherit Element, not Component)
- Simplify _connect_network to only handle bus connections (flow ownership set in __init__)
- Update all tests to new API: Port instead of Source/Sink, Converter.boiler() instead of linear_converters.Boiler(), .add() instead of .add_elements()
- Fix IO serialization: preserve empty lists (e.g. outputs=[]) for required init params

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 17, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/element-data-classes+id+dataclasses+data

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments