Skip to content

Conversation

@FBumann
Copy link
Member

@FBumann FBumann commented Sep 27, 2025

Renamed Effect domains:

investnontemporal
operationtemporal

Further, rename Effect parameters to:

  • minimum_investmentminimum_nontemporal
  • maximum_investmentmaximum_nontemporal
  • minimum_operationminimum_temporal
  • maximum_operationmaximum_temporal
  • minimum_operation_per_hourminimum_per_hour
  • maximum_operation_per_hourmaximum_per_hour

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)

Summary by CodeRabbit

  • New Features

    • Added validation to reject unexpected keyword arguments, helping catch typos early.
  • Refactor

    • Renamed effect parameters and results from operation/invest to temporal/nontemporal.
    • Simplified result keys: costs|total → costs; total_per_timestep → per_timestep.
    • Backward-compatible aliases provided with deprecation warnings.
  • Documentation

    • Changelog updated to reflect parameter and naming changes.
  • Tests

    • Updated test suite and examples to use new temporal/nontemporal and simplified result keys.

@FBumann FBumann linked an issue Sep 27, 2025 that may be closed by this pull request
2 tasks
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 27, 2025

Walkthrough

Renamed Effect domains and parameters from operation/invest to temporal/nontemporal across core models, features, elements, results, examples, and tests. Introduced per_timestep naming, updated result keys (e.g., costs|total → costs), added kwargs validation, and provided backward-compatible deprecated properties and warnings.

Changes

Cohort / File(s) Summary
Terminology and results renaming
flixopt/effects.py, flixopt/features.py, flixopt/elements.py, flixopt/calculation.py
Switched model components and result keys from operation/invest to temporal/nontemporal; renamed total and per-timestep outputs; aligned constraints and variable names; updated share routing.
Backward-compatibility and validation
flixopt/effects.py, flixopt/components.py, flixopt/structure.py
Added deprecated getters/setters and warnings for old params; ensured mutual exclusivity of old/new names; introduced Interface._validate_kwargs and invoked kwargs validation in component init paths.
Examples
examples/03_Calculation_types/example_calculation_types.py
Updated plotting data sources to new keys: costs(temporal)
Tests alignment
tests/test_effect.py, tests/test_flow.py, tests/test_functional.py, tests/test_integration.py, tests/test_io.py, tests/test_linear_converter.py, tests/conftest.py
Rewrote expectations and lookups to temporal/nontemporal and new total/per_timestep names; adjusted bounds and share targets; updated fixture parameter names.
Changelog
CHANGELOG.md
Documented parameter renames under Deprecated.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Developer
  participant Eff as Effect (API)
  participant EM as EffectModel
  participant SAM as ShareAllocationModel
  participant Sol as Solver
  participant Res as CalculationResults

  Dev->>Eff: Create Effect(minimum_temporal, maximum_nontemporal, ...)\n(or deprecated names via **kwargs)
  note over Eff: Deprecated names mapped with warnings

  Eff->>EM: Build model components\nnontemporal, temporal, per_timestep
  EM->>SAM: Add shares targeting\n[temporal | nontemporal]
  EM->>Sol: Define variables/constraints\n- Effect\n- Effect(temporal)|per_timestep\n- Effect(nontemporal)

  Sol-->>EM: Solutions for variables
  EM-->>Res: Populate results keys\n- costs\n- costs(temporal)|per_timestep\n- costs(nontemporal)

  Dev->>Res: Access results by new keys
  note over Res: Old keys not used in tests
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • baumbude
  • PStange

Poem

I thump my paws: new times are here,
From operation’s fade to temporal clear.
Nontemporal burrows count their share,
Per-timestep carrots everywhere.
Keys renamed, results aligned—
A tidy warren, well-designed. 🥕🐇

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The pull request description deviates from the repository’s template by replacing the required “## Description” heading with a custom one and leaving the “Closes #(issue number)” placeholder unfilled. The template’s section headings must match exactly for consistency and automation. Please update the description to use the exact “## Description” heading, move the renaming details under that section, provide the actual issue number in “Closes #”, and verify the testing checkboxes to reflect the test status.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly identifies the primary change of renaming effect domains from invest/operation to nontemporal/temporal, making it closely related to the main change. Although it includes the branch/issue tag “Feature/308”, it still concisely conveys the key action.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/308-rename-effect-domains

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 02b8859 and 06f20e6.

📒 Files selected for processing (1)
  • flixopt/effects.py (8 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
flixopt/effects.py (3)
flixopt/structure.py (4)
  • _validate_kwargs (205-233)
  • label_full (312-313)
  • label_full (419-425)
  • add (365-389)
flixopt/flow_system.py (1)
  • create_time_series (349-373)
flixopt/features.py (2)
  • ShareAllocationModel (923-1024)
  • add_share (989-1024)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.13)
  • GitHub Check: test (3.11)
  • GitHub Check: test (3.10)
🔇 Additional comments (12)
flixopt/effects.py (12)

55-73: LGTM! Comprehensive API parameter migration with clear documentation.

The parameter renamings from operation/invest to temporal/nontemporal and operation_per_hour to per_hour are well-documented. The docstring provides clear explanations of both the new and deprecated parameters.


122-123: LGTM! Updated example demonstrates the new parameter names.

The example correctly uses minimum_per_hour and maximum_per_hour instead of the deprecated minimum_operation_per_hour and maximum_operation_per_hour.


143-162: LGTM! Updated function signature with backward compatibility.

The parameter names are correctly updated to use the new temporal/nontemporal/per_hour naming scheme, and the **kwargs parameter allows for proper backward compatibility handling.


174-255: Excellent backward compatibility implementation.

This is a comprehensive backward compatibility layer that:

  • Properly extracts deprecated parameters from kwargs
  • Issues appropriate deprecation warnings with stacklevel=2
  • Prevents simultaneous specification of old and new parameters
  • Validates remaining kwargs to prevent typos

The implementation follows Python deprecation best practices.


256-264: LGTM! Clean attribute assignment.

Attributes are directly assigned using the resolved values after backward compatibility processing.


266-386: Well-implemented deprecated property wrappers.

All deprecated properties correctly:

  • Issue deprecation warnings with stacklevel=2
  • Map to the corresponding new attributes
  • Include both getters and setters for full compatibility

The pattern is consistently applied across all deprecated properties.


387-394: LGTM! Updated method uses new parameter names.

The transform_data method correctly references minimum_per_hour and maximum_per_hour instead of the deprecated parameter names.


415-425: LGTM! EffectModel updated to use new naming scheme.

The nontemporal ShareAllocationModel is properly configured with the new parameter names and label structure.


427-443: LGTM! Temporal model correctly configured.

The temporal ShareAllocationModel is properly set up with:

  • New parameter names (minimum_temporal, maximum_temporal)
  • Correct per-hour limits from the new attributes
  • Updated label structure

449-464: LGTM! Updated total calculation uses new component references.

The total effect calculation correctly references self.temporal.total and self.nontemporal.total instead of the old operation/invest naming.


641-649: LGTM! Method signature updated to use new target types.

The add_share_to_effects method correctly uses Literal['temporal', 'nontemporal'] and properly routes to the corresponding model components.


669-682: LGTM! Cross-effect relationships updated to new naming.

The _add_share_between_effects method correctly:

  • References temporal and nontemporal models instead of operation and invest
  • Updates comments to reflect the new terminology
  • Maintains the same logic flow with updated component names

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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
flixopt/effects.py (1)

567-589: Circular-share check can silently fail with string keys (labels)

create_effect_values_dict promotes keys to labels; then comparing Effect objects against string keys will never match, weakening loop detection.

-        for effect in self.effects.values():
-            # Effekt darf nicht selber als Share in seinen ShareEffekten auftauchen:
-            # operation:
-            for target_effect in effect.specific_share_to_other_effects_operation.keys():
-                assert effect not in self[target_effect].specific_share_to_other_effects_operation.keys(), (
-                    f'Error: circular operation-shares \n{error_str(effect.label, self[target_effect].label)}'
-                )
-            # invest:
-            for target_effect in effect.specific_share_to_other_effects_invest.keys():
-                assert effect not in self[target_effect].specific_share_to_other_effects_invest.keys(), (
-                    f'Error: circular invest-shares \n{error_str(effect.label, self[target_effect].label)}'
-                )
+        def key_label(k):  # supports both Effect and str keys
+            return k.label if isinstance(k, Effect) else k
+
+        for effect in self.effects.values():
+            # temporal (formerly operation)
+            for target_label in effect.specific_share_to_other_effects_operation.keys():
+                peer = self[target_label]
+                peer_keys = {key_label(k) for k in peer.specific_share_to_other_effects_operation.keys()}
+                assert effect.label not in peer_keys, (
+                    f'Error: circular temporal-shares \n{error_str(effect.label, peer.label)}'
+                )
+            # nontemporal (formerly invest)
+            for target_label in effect.specific_share_to_other_effects_invest.keys():
+                peer = self[target_label]
+                peer_keys = {key_label(k) for k in peer.specific_share_to_other_effects_invest.keys()}
+                assert effect.label not in peer_keys, (
+                    f'Error: circular nontemporal-shares \n{error_str(effect.label, peer.label)}'
+                )
🧹 Nitpick comments (6)
flixopt/structure.py (1)

225-233: Generalize var-keyword detection in _validate_kwargs.

Right now we special-case the literal name "kwargs" when building known_params. Any __init__ that uses a different var-keyword name (e.g., **options) would still allow arbitrary keywords, but this helper would flag them as unexpected. That makes _validate_kwargs brittle for future classes that adopt the helper with differently named ** parameters. Please derive known_params using inspect.Parameter.kind != VAR_KEYWORD so all var-keyword names are excluded automatically.

-        sig = inspect.signature(self.__init__)
-        known_params = set(sig.parameters.keys()) - {'self', 'kwargs'}
+        sig = inspect.signature(self.__init__)
+        known_params = {
+            name
+            for name, param in sig.parameters.items()
+            if name != 'self' and param.kind != inspect.Parameter.VAR_KEYWORD
+        }
flixopt/results.py (1)

7-7: Remove unused import.

warnings is imported but not used in this file.

flixopt/features.py (1)

956-965: Variable/constraint name collision (same label) is intentional—please confirm uniqueness assumptions.

self.total and its constraint both named self.label_full. Linopy keeps variables and constraints separate, but double-check any consumers that treat names as unique across both sets.

If needed, consider a distinct constraint short name (e.g., '|total_eq') to ease debugging while preserving public variable naming.

tests/test_effect.py (1)

114-116: Legacy share parameter names: confirm deprecation path.

specific_share_to_other_effects_operation / _invest still appear. If renamed to temporal/nontemporal, update tests; otherwise ensure deprecation support is active.

Would you like me to update tests to the new names (e.g., specific_share_to_other_effects_temporal / _nontemporal) if available?

flixopt/effects.py (2)

153-161: Deprecation compatibility layer is solid; minor cleanup suggested

Logic correctly maps old kwargs to new ones and prevents double-specification. Two small improvements:

  • Drop repeated local imports of warnings and rely on the module-level import.
  • Optionally use class_name in _validate_kwargs for clearer error messages.
-        import warnings
+        # use module-level warnings import

-        import warnings
+        # use module-level warnings import

If desired:

-        self._validate_kwargs(kwargs)
+        self._validate_kwargs(kwargs, class_name=self.__class__.__name__)

Also applies to: 174-265


414-420: Align TimeSeries labels with 'temporal' terminology

Labels still use 'operation' in prefixes/suffixes; update to 'temporal' for consistency. This affects metadata/IO names, not model math.

-        self.specific_share_to_other_effects_operation = flow_system.create_effect_time_series(
-            f'{self.label_full}|operation->', self.specific_share_to_other_effects_operation, 'operation'
-        )
+        self.specific_share_to_other_effects_operation = flow_system.create_effect_time_series(
+            f'{self.label_full}|temporal->', self.specific_share_to_other_effects_operation, 'temporal'
+        )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6452f28 and 02b8859.

📒 Files selected for processing (16)
  • CHANGELOG.md (1 hunks)
  • examples/03_Calculation_types/example_calculation_types.py (1 hunks)
  • flixopt/calculation.py (1 hunks)
  • flixopt/components.py (5 hunks)
  • flixopt/effects.py (8 hunks)
  • flixopt/elements.py (1 hunks)
  • flixopt/features.py (7 hunks)
  • flixopt/results.py (5 hunks)
  • flixopt/structure.py (1 hunks)
  • tests/conftest.py (1 hunks)
  • tests/test_effect.py (3 hunks)
  • tests/test_flow.py (5 hunks)
  • tests/test_functional.py (2 hunks)
  • tests/test_integration.py (4 hunks)
  • tests/test_io.py (1 hunks)
  • tests/test_linear_converter.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (12)
tests/test_linear_converter.py (3)
flixopt/results.py (4)
  • constraints (235-239)
  • constraints (385-393)
  • variables (228-232)
  • variables (374-382)
flixopt/structure.py (2)
  • constraints (462-463)
  • variables (458-459)
tests/conftest.py (1)
  • assert_conequal (455-471)
flixopt/components.py (1)
flixopt/structure.py (1)
  • _validate_kwargs (205-233)
tests/test_flow.py (3)
flixopt/results.py (4)
  • constraints (235-239)
  • constraints (385-393)
  • variables (228-232)
  • variables (374-382)
flixopt/structure.py (2)
  • constraints (462-463)
  • variables (458-459)
tests/conftest.py (1)
  • assert_conequal (455-471)
tests/test_effect.py (2)
flixopt/structure.py (4)
  • constraints (462-463)
  • variables (458-459)
  • coords (105-106)
  • hours_per_step (97-98)
tests/conftest.py (3)
  • assert_var_equal (474-508)
  • assert_conequal (455-471)
  • create_linopy_model (424-427)
flixopt/results.py (2)
flixopt/structure.py (2)
  • label (415-416)
  • solution (76-94)
flixopt/io.py (1)
  • save_dataset_to_netcdf (207-243)
flixopt/features.py (3)
flixopt/effects.py (2)
  • effects (625-626)
  • add_share_to_effects (663-675)
flixopt/structure.py (4)
  • coords (105-106)
  • label_full (312-313)
  • label_full (419-425)
  • add (365-389)
flixopt/elements.py (1)
  • label_full (481-482)
flixopt/effects.py (3)
flixopt/structure.py (4)
  • _validate_kwargs (205-233)
  • label_full (312-313)
  • label_full (419-425)
  • add (365-389)
flixopt/flow_system.py (1)
  • create_time_series (349-373)
flixopt/features.py (2)
  • ShareAllocationModel (923-1024)
  • add_share (989-1024)
examples/03_Calculation_types/example_calculation_types.py (2)
flixopt/core.py (1)
  • to_dataframe (738-767)
flixopt/plotting.py (1)
  • with_plotly (328-463)
flixopt/calculation.py (1)
flixopt/structure.py (1)
  • solution (76-94)
tests/test_io.py (1)
flixopt/structure.py (1)
  • solution (76-94)
tests/test_functional.py (1)
flixopt/results.py (2)
  • variables (228-232)
  • variables (374-382)
tests/test_integration.py (2)
flixopt/structure.py (1)
  • solution (76-94)
flixopt/results.py (1)
  • solution_without_overlap (865-878)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: test (3.13)
  • GitHub Check: test (3.11)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.10)
🔇 Additional comments (22)
tests/test_flow.py (5)

102-115: Terminology rename looks correct for temporal effects on flow hours.

Assertions align with ShareAllocationModel naming and dimensions.


405-419: Non‑temporal investment effects wiring is correct.

Variables/constraints names and expression semantics match the new nontemporal domain.


440-446: Divest effect constraint matches intended formulation.

Constraint enforces var == (1 - is_invested) * 500.


543-556: Temporal running-hour effects wiring is correct.

Time-series constraint uses on * hours_per_step * factor as expected.


889-895: Startup cost mapped to temporal domain is correct.

Constraint equals per-switch_on cost; naming is consistent.

flixopt/features.py (7)

89-90: Use of nontemporal for fix effects is correct.

Matches the new domain naming.


100-101: Divest effects correctly target nontemporal.

Semantics preserved.


107-108: Specific effects mapped to nontemporal look good.

Consistent with investment sizing.


739-740: Running-hour effects correctly target temporal.

Time-based contributions go to the temporal domain.


749-750: Per‑switch effects to temporal is appropriate.

Discrete switch events are time-indexed.


967-984: per_timestep renaming and bounds are correct.

Bounds correctly scale per-hour limits by hours_per_step; naming matches tests.


1079-1080: Piecewise effect shares routed to nontemporal are correct.

Aggregation logic consistent with non-temporal totals.

tests/test_effect.py (5)

18-34: Effect variable/constraint renames (temporal/nontemporal) look correct.

Names and dimensions align with ShareAllocationModel changes.


57-65: Bounds rename coverage is correct.

minimum_temporal, maximum_temporal, minimum_nontemporal, maximum_nontemporal, and per-hour limits are used as intended.


83-106: Constraint wiring for totals and per_timestep is consistent.

Totals sum temporal+nontemporal; temporal equals sum of per_timestep.


123-137: Cross‑effect variable naming is correct.

Effect1(nontemporal)->Effect2(nontemporal) and ... (temporal) match new scheme.


139-160: Cross‑effect share constraints are correctly formulated.

Nontemporal maps scalar‑to‑scalar; temporal maps per_timestep to per_timestep.

tests/test_integration.py (2)

66-70: Result key renames look consistent with the new temporal/nontemporal API

The updated accessors (costs, CO2, costs(temporal)|per_timestep, CO2(temporal), CO2(nontemporal), and the component->effect paths) align with ShareAllocationModel naming and EffectModel totals. Good coverage across scalar totals and per_timestep arrays.

Also applies to: 182-201, 204-233, 235-255


410-419: No residual old ‘operation’ keys detected: scan found only CHANGELOG mappings and the intended deprecation handlers in effects.py.

flixopt/effects.py (3)

55-73: Docstring rename is clear and complete for bounds

Parameters reflect temporal/nontemporal and per-hour terminology with deprecation notes. Looks good.


441-468: Model split into temporal/nontemporal is correct

Naming (…(temporal), …(nontemporal), …|per_timestep) and bounds wiring (total, per-hour) are consistent with ShareAllocationModel and tests.

Also applies to: 480-488


697-709: Cross-effect share routing is correct under new domains

Temporal uses total_per_timestep * TS; nontemporal uses scalar total * factor. Naming yields CO2(temporal)->costs(temporal) as expected.

@FBumann FBumann mentioned this pull request Sep 27, 2025
9 tasks
@FBumann FBumann changed the base branch from main to v2.2/main September 27, 2025 10:41
@FBumann FBumann merged commit 67a5ca6 into v2.2/main Sep 27, 2025
12 checks passed
@FBumann FBumann deleted the feature/308-rename-effect-domains branch October 13, 2025 21:37
This was referenced Nov 15, 2025
@coderabbitai coderabbitai bot mentioned this pull request Nov 23, 2025
9 tasks
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.

[FEATURE] Rename Effect domains

2 participants