rencal 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
rencal-0.1.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Low Carbon Contracts Company Ltd
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
rencal-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,193 @@
1
+ Metadata-Version: 2.4
2
+ Name: rencal
3
+ Version: 0.1.1
4
+ Summary: Weather-to-power calibration and Monte Carlo load factor simulation for renewable energy applications
5
+ Keywords: weather,forecasting,renewable energy,wind power,solar power,era5,monte carlo,calibration,climate
6
+ Author: Low Carbon Contracts Company Ltd
7
+ Author-email: Low Carbon Contracts Company Ltd <analytics@lowcarboncontracts.uk>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
16
+ Classifier: Topic :: Utilities
17
+ Requires-Dist: numpy>=1.20.0
18
+ Requires-Dist: pandas>=1.3.0
19
+ Requires-Dist: scipy>=1.7.0
20
+ Requires-Dist: matplotlib>=3.4.0
21
+ Requires-Dist: seaborn>=0.12.0
22
+ Requires-Dist: scikit-learn>=1.0.0
23
+ Requires-Dist: netcdf4>=1.5.0
24
+ Requires-Dist: xarray>=0.19.0
25
+ Requires-Dist: pytz>=2021.1
26
+ Requires-Dist: requests>=2.25.0
27
+ Requires-Dist: polars>=1.8.2
28
+ Requires-Dist: pydantic>=2.10.6
29
+ Requires-Dist: pyodbc>=4.0.0
30
+ Requires-Dist: cdsapi>=0.6.0
31
+ Requires-Dist: python-dotenv>=1.0.0
32
+ Requires-Dist: openpyxl>=3.1.0
33
+ Requires-Dist: zarr>=2.16.1
34
+ Requires-Dist: tqdm>=4.62.0
35
+ Requires-Dist: pyarrow>=22.0.0
36
+ Maintainer: Low Carbon Contracts Company Ltd
37
+ Maintainer-email: Low Carbon Contracts Company Ltd <analytics@lowcarboncontracts.uk>
38
+ Requires-Python: >=3.12, <3.13
39
+ Project-URL: Homepage, https://github.com/LCCC-Tech/rencal
40
+ Project-URL: Repository, https://github.com/LCCC-Tech/rencal.git
41
+ Project-URL: Bug Tracker, https://github.com/LCCC-Tech/rencal/issues
42
+ Project-URL: Changelog, https://github.com/LCCC-Tech/rencal/blob/main/CHANGELOG.md
43
+ Description-Content-Type: text/markdown
44
+
45
+ # RenCal
46
+
47
+ RenCal (Renewable Calibration) is a Python library for calibrating renewable
48
+ energy power curves and generating probabilistic load-factor time series for
49
+ wind and solar plants.
50
+
51
+ It supports Monte Carlo-based forecasting using weather, generation, and plant
52
+ characteristic data. RenCal is intended for energy analysts, researchers, and
53
+ developers working on renewable-energy modelling.
54
+
55
+ ## Status
56
+
57
+ RenCal is an experimental pre-1.0 public package. The API and modelling
58
+ approach may change as the project develops. It is not currently a guarantee of
59
+ production suitability or a substitute for independent validation.
60
+
61
+ ## Installation
62
+
63
+ The first public release will be installed from PyPI with:
64
+
65
+ ```bash
66
+ python -m pip install rencal
67
+ ```
68
+
69
+ Until that release is published, clone the repository and follow the
70
+ [development setup](CONTRIBUTING.md#development-setup) instead.
71
+
72
+ ## Quick start
73
+
74
+ The primary workflow uses data supplied by the user. RenCal does not distribute
75
+ operational ERA5, generation, or plant datasets.
76
+
77
+ ```python
78
+ from pathlib import Path
79
+
80
+ from rencal.core.data_loader import LocalDataLoader
81
+
82
+ loader = LocalDataLoader(data_path=Path("data"))
83
+ plants = loader.load_plant_data()
84
+ generation = loader.load_generation_data()
85
+
86
+ print(f"Loaded {len(plants.data)} plants")
87
+ print(f"Loaded {len(generation.data)} generation records")
88
+ ```
89
+
90
+ For the full wind-calibration workflow, provide the expected input structure:
91
+
92
+ ```text
93
+ data/
94
+ ├── plant/plant_data.csv
95
+ ├── generation/generation_data.parquet
96
+ └── era5/*.nc
97
+ ```
98
+
99
+ The ERA5 loader expects suitable NetCDF weather data. Users are responsible for
100
+ obtaining data, checking its provenance and licence, and preparing it for the
101
+ documented schema.
102
+
103
+ ### Calibrate wind power curves
104
+
105
+ With the plant, generation, and ERA5 inputs in place, run the wind calibration
106
+ workflow and write its outputs to a separate directory:
107
+
108
+ ```python
109
+ from pathlib import Path
110
+
111
+ from rencal.calibration.wind.wind_calibrator import WindCalibrator
112
+
113
+ calibrator = WindCalibrator(
114
+ data_path="data",
115
+ output_path=Path("outputs/wind-calibration"),
116
+ visual_output=True,
117
+ stream_npy_output=True,
118
+ )
119
+ calibrator.calibrate()
120
+ ```
121
+
122
+ The workflow writes the calibration summary, Weibull parameters, extracted wind
123
+ speeds, calibrated wind streams, and optional power-curve plots to the output
124
+ directory. With `stream_npy_output=True`, the generated `Wind Streams.npy` can
125
+ also be used by the weather sampler after its manifest and optional histogram
126
+ artefacts have been prepared.
127
+
128
+ ### Sample calibrated wind streams
129
+
130
+ `WeatherData` samples future hourly paths from calibrated historical streams
131
+ while preserving the configured time-bucket structure. The local loader expects
132
+ the calibrated NPY file and its manifest under `data/calibrated/`.
133
+
134
+ ```python
135
+ import datetime
136
+ import random
137
+
138
+ import numpy as np
139
+
140
+ from rencal.core.data_loader import LocalDataLoader
141
+ from rencal.simulation.weather_data import HistoricalMetadata, WeatherData
142
+
143
+ loader = LocalDataLoader(data_path="data")
144
+ manifest = loader.check_historical_weather()
145
+ metadata = HistoricalMetadata.from_manifest(
146
+ manifest,
147
+ loader.path_resolver_weather_data,
148
+ )
149
+
150
+ wind_sampler = WeatherData(
151
+ metadata=metadata,
152
+ prefix_histograms=loader.get_prefix_histograms(),
153
+ historical_data=loader.get_historical_weather(),
154
+ )
155
+
156
+ sample = wind_sampler.random_sample(
157
+ datetime.datetime(2027, 1, 1),
158
+ datetime.datetime(2027, 1, 7),
159
+ python_rng=random.Random(4),
160
+ numpy_rng=np.random.default_rng(32),
161
+ )
162
+ ```
163
+
164
+ Pass `desired_averages` to `WeatherData` when inverse-distribution resampling is
165
+ required; this also requires historical data or precomputed prefix histograms.
166
+
167
+ ## Main capabilities
168
+
169
+ - Wind and solar power-curve calibration foundations
170
+ - Probabilistic load-factor forecasting
171
+ - Weather and generation data loading and validation
172
+ - Time-bucketed sampling with geographical correlation support
173
+ - Extensible interfaces for local and external data sources
174
+
175
+ ## Documentation
176
+
177
+ - [Wind calibration tutorial](docs/tutorials/wind_calibration_tutorial.ipynb)
178
+ - [Contributing](CONTRIBUTING.md)
179
+ - [Code of Conduct](CODE_OF_CONDUCT.md)
180
+ - [Issue tracker](https://github.com/LCCC-Tech/rencal/issues)
181
+
182
+ Hosted documentation and versioned examples will be linked here once the public
183
+ documentation site is verified.
184
+
185
+ ## Support
186
+
187
+ Use [GitHub Issues](https://github.com/LCCC-Tech/rencal/issues) for public,
188
+ reproducible bugs and feature requests. Please do not include credentials,
189
+ internal data, or confidential information in issues.
190
+
191
+ ## Licence
192
+
193
+ RenCal is released under the [MIT Licence](LICENSE).
rencal-0.1.1/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # RenCal
2
+
3
+ RenCal (Renewable Calibration) is a Python library for calibrating renewable
4
+ energy power curves and generating probabilistic load-factor time series for
5
+ wind and solar plants.
6
+
7
+ It supports Monte Carlo-based forecasting using weather, generation, and plant
8
+ characteristic data. RenCal is intended for energy analysts, researchers, and
9
+ developers working on renewable-energy modelling.
10
+
11
+ ## Status
12
+
13
+ RenCal is an experimental pre-1.0 public package. The API and modelling
14
+ approach may change as the project develops. It is not currently a guarantee of
15
+ production suitability or a substitute for independent validation.
16
+
17
+ ## Installation
18
+
19
+ The first public release will be installed from PyPI with:
20
+
21
+ ```bash
22
+ python -m pip install rencal
23
+ ```
24
+
25
+ Until that release is published, clone the repository and follow the
26
+ [development setup](CONTRIBUTING.md#development-setup) instead.
27
+
28
+ ## Quick start
29
+
30
+ The primary workflow uses data supplied by the user. RenCal does not distribute
31
+ operational ERA5, generation, or plant datasets.
32
+
33
+ ```python
34
+ from pathlib import Path
35
+
36
+ from rencal.core.data_loader import LocalDataLoader
37
+
38
+ loader = LocalDataLoader(data_path=Path("data"))
39
+ plants = loader.load_plant_data()
40
+ generation = loader.load_generation_data()
41
+
42
+ print(f"Loaded {len(plants.data)} plants")
43
+ print(f"Loaded {len(generation.data)} generation records")
44
+ ```
45
+
46
+ For the full wind-calibration workflow, provide the expected input structure:
47
+
48
+ ```text
49
+ data/
50
+ ├── plant/plant_data.csv
51
+ ├── generation/generation_data.parquet
52
+ └── era5/*.nc
53
+ ```
54
+
55
+ The ERA5 loader expects suitable NetCDF weather data. Users are responsible for
56
+ obtaining data, checking its provenance and licence, and preparing it for the
57
+ documented schema.
58
+
59
+ ### Calibrate wind power curves
60
+
61
+ With the plant, generation, and ERA5 inputs in place, run the wind calibration
62
+ workflow and write its outputs to a separate directory:
63
+
64
+ ```python
65
+ from pathlib import Path
66
+
67
+ from rencal.calibration.wind.wind_calibrator import WindCalibrator
68
+
69
+ calibrator = WindCalibrator(
70
+ data_path="data",
71
+ output_path=Path("outputs/wind-calibration"),
72
+ visual_output=True,
73
+ stream_npy_output=True,
74
+ )
75
+ calibrator.calibrate()
76
+ ```
77
+
78
+ The workflow writes the calibration summary, Weibull parameters, extracted wind
79
+ speeds, calibrated wind streams, and optional power-curve plots to the output
80
+ directory. With `stream_npy_output=True`, the generated `Wind Streams.npy` can
81
+ also be used by the weather sampler after its manifest and optional histogram
82
+ artefacts have been prepared.
83
+
84
+ ### Sample calibrated wind streams
85
+
86
+ `WeatherData` samples future hourly paths from calibrated historical streams
87
+ while preserving the configured time-bucket structure. The local loader expects
88
+ the calibrated NPY file and its manifest under `data/calibrated/`.
89
+
90
+ ```python
91
+ import datetime
92
+ import random
93
+
94
+ import numpy as np
95
+
96
+ from rencal.core.data_loader import LocalDataLoader
97
+ from rencal.simulation.weather_data import HistoricalMetadata, WeatherData
98
+
99
+ loader = LocalDataLoader(data_path="data")
100
+ manifest = loader.check_historical_weather()
101
+ metadata = HistoricalMetadata.from_manifest(
102
+ manifest,
103
+ loader.path_resolver_weather_data,
104
+ )
105
+
106
+ wind_sampler = WeatherData(
107
+ metadata=metadata,
108
+ prefix_histograms=loader.get_prefix_histograms(),
109
+ historical_data=loader.get_historical_weather(),
110
+ )
111
+
112
+ sample = wind_sampler.random_sample(
113
+ datetime.datetime(2027, 1, 1),
114
+ datetime.datetime(2027, 1, 7),
115
+ python_rng=random.Random(4),
116
+ numpy_rng=np.random.default_rng(32),
117
+ )
118
+ ```
119
+
120
+ Pass `desired_averages` to `WeatherData` when inverse-distribution resampling is
121
+ required; this also requires historical data or precomputed prefix histograms.
122
+
123
+ ## Main capabilities
124
+
125
+ - Wind and solar power-curve calibration foundations
126
+ - Probabilistic load-factor forecasting
127
+ - Weather and generation data loading and validation
128
+ - Time-bucketed sampling with geographical correlation support
129
+ - Extensible interfaces for local and external data sources
130
+
131
+ ## Documentation
132
+
133
+ - [Wind calibration tutorial](docs/tutorials/wind_calibration_tutorial.ipynb)
134
+ - [Contributing](CONTRIBUTING.md)
135
+ - [Code of Conduct](CODE_OF_CONDUCT.md)
136
+ - [Issue tracker](https://github.com/LCCC-Tech/rencal/issues)
137
+
138
+ Hosted documentation and versioned examples will be linked here once the public
139
+ documentation site is verified.
140
+
141
+ ## Support
142
+
143
+ Use [GitHub Issues](https://github.com/LCCC-Tech/rencal/issues) for public,
144
+ reproducible bugs and feature requests. Please do not include credentials,
145
+ internal data, or confidential information in issues.
146
+
147
+ ## Licence
148
+
149
+ RenCal is released under the [MIT Licence](LICENSE).
@@ -0,0 +1,190 @@
1
+ [build-system]
2
+ requires = ["uv_build>=0.10.8,<0.11.0"]
3
+ build-backend = "uv_build"
4
+
5
+ [project]
6
+ name = "rencal"
7
+ version = "0.1.1"
8
+ description = "Weather-to-power calibration and Monte Carlo load factor simulation for renewable energy applications"
9
+ readme = "README.md"
10
+ requires-python = ">=3.12,<3.13"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [
14
+ {name = "Low Carbon Contracts Company Ltd", email = "analytics@lowcarboncontracts.uk"}
15
+ ]
16
+ maintainers = [
17
+ {name = "Low Carbon Contracts Company Ltd", email = "analytics@lowcarboncontracts.uk"}
18
+ ]
19
+ keywords = [
20
+ "weather",
21
+ "forecasting",
22
+ "renewable energy",
23
+ "wind power",
24
+ "solar power",
25
+ "era5",
26
+ "monte carlo",
27
+ "calibration",
28
+ "climate"
29
+ ]
30
+ classifiers = [
31
+ "Intended Audience :: Science/Research",
32
+ "Intended Audience :: Developers",
33
+ "License :: OSI Approved :: MIT License",
34
+ "Operating System :: OS Independent",
35
+ "Programming Language :: Python :: 3.12",
36
+ "Topic :: Scientific/Engineering :: Atmospheric Science",
37
+ "Topic :: Utilities"
38
+ ]
39
+ dependencies = [
40
+ "numpy>=1.20.0",
41
+ "pandas>=1.3.0",
42
+ "scipy>=1.7.0",
43
+ "matplotlib>=3.4.0",
44
+ "seaborn>=0.12.0",
45
+ "scikit-learn>=1.0.0",
46
+ "netCDF4>=1.5.0",
47
+ "xarray>=0.19.0",
48
+ "pytz>=2021.1",
49
+ "requests>=2.25.0",
50
+ "polars>=1.8.2",
51
+ "pydantic>=2.10.6",
52
+ "pyodbc>=4.0.0",
53
+ "cdsapi>=0.6.0",
54
+ "python-dotenv>=1.0.0",
55
+ "openpyxl>=3.1.0",
56
+ "zarr>=2.16.1",
57
+ "tqdm>=4.62.0",
58
+ "pyarrow>=22.0.0",
59
+ ]
60
+
61
+ [dependency-groups]
62
+ dev = [
63
+ "pytest>=6.0",
64
+ "pytest-cov>=2.0",
65
+ "ruff>=0.8.0",
66
+ "basedpyright>=1.0.0",
67
+ "pre-commit>=2.15.0",
68
+ "build>=1.0.0"
69
+ ]
70
+ docs = [
71
+ "sphinx>=4.0",
72
+ "sphinx-rtd-theme>=1.0",
73
+ "myst-parser>=0.15.0",
74
+ "sphinx-autoapi>=1.8.0"
75
+ ]
76
+ azure = [
77
+ "azure-storage-blob>=12.0.0",
78
+ "azure-identity>=1.7.0"
79
+ ]
80
+ notebook = [
81
+ "jupyter>=1.0.0",
82
+ "ipykernel>=6.0.0",
83
+ "plotly>=5.0.0"
84
+ ]
85
+
86
+ [project.urls]
87
+ Homepage = "https://github.com/LCCC-Tech/rencal"
88
+ Repository = "https://github.com/LCCC-Tech/rencal.git"
89
+ "Bug Tracker" = "https://github.com/LCCC-Tech/rencal/issues"
90
+ Changelog = "https://github.com/LCCC-Tech/rencal/blob/main/CHANGELOG.md"
91
+
92
+ [tool.uv.build-backend]
93
+ module-name = "rencal"
94
+ module-root = ""
95
+
96
+ [tool.basedpyright]
97
+ include = ["rencal"]
98
+ exclude = [".venv", "build", "dist", "rencal/simulation/intermittent_bucketer.py", "rencal/core/bucketed_data.py",]
99
+ venvPath = "."
100
+ venv = ".venv"
101
+ pythonVersion = "3.12"
102
+ typeCheckingMode = "basic" # Changed from strict to basic to reduce false positives
103
+ reportMissingImports = true
104
+ reportMissingTypeStubs = false
105
+ reportUnusedImport = true
106
+ reportUnusedClass = false # Reduce noise for now
107
+ reportUnusedFunction = false # Reduce noise for now
108
+ reportUnusedVariable = true
109
+ # Less strict about third-party library types
110
+ reportUnknownMemberType = false
111
+ reportUnknownVariableType = false
112
+ reportUnknownArgumentType = false
113
+ # Disable overly strict argument type checking for third-party libraries
114
+ reportArgumentType = false
115
+ # Additional settings to help with import resolution
116
+ extraPaths = ["."]
117
+
118
+ [tool.ruff]
119
+ line-length = 100
120
+ indent-width = 4
121
+ target-version = "py312"
122
+
123
+ [tool.ruff.lint]
124
+ select = [
125
+ "E", # pycodestyle errors
126
+ "W", # pycodestyle warnings
127
+ "F", # pyflakes
128
+ "I", # isort
129
+ "B", # flake8-bugbear
130
+ "C4", # flake8-comprehensions
131
+ "UP", # pyupgrade
132
+ ]
133
+ ignore = [
134
+ "E501", # Line too long (handled by formatter)
135
+ "B008", # Do not perform function calls in argument defaults
136
+ ]
137
+
138
+ [tool.ruff.format]
139
+ quote-style = "double"
140
+ indent-style = "space"
141
+ skip-magic-trailing-comma = false
142
+ line-ending = "auto"
143
+ docstring-code-format = true
144
+ docstring-code-line-length = "dynamic"
145
+
146
+ [tool.ruff.lint.isort]
147
+ known-first-party = ["rencal"]
148
+
149
+ # pytest configuration
150
+ [tool.pytest.ini_options]
151
+ minversion = "6.0"
152
+ addopts = "-ra -q --strict-markers --strict-config"
153
+ testpaths = ["tests"]
154
+ python_files = ["test_*.py", "*_test.py"]
155
+ python_classes = ["Test*"]
156
+ python_functions = ["test_*"]
157
+ filterwarnings = [
158
+ "error",
159
+ "ignore::UserWarning",
160
+ "ignore::DeprecationWarning",
161
+ "ignore:numpy.*:RuntimeWarning",
162
+ ]
163
+ markers = [
164
+ "slow: marks tests as slow (deselect with '-m \"not slow\"')",
165
+ "integration: marks tests as integration tests",
166
+ "unit: marks tests as unit tests",
167
+ ]
168
+
169
+ # Coverage configuration
170
+ [tool.coverage.run]
171
+ source = ["rencal"]
172
+ omit = [
173
+ "*/tests/*",
174
+ "*/test_*",
175
+ "setup.py",
176
+ ]
177
+
178
+ [tool.coverage.report]
179
+ exclude_lines = [
180
+ "pragma: no cover",
181
+ "def __repr__",
182
+ "if self.debug:",
183
+ "if settings.DEBUG",
184
+ "raise AssertionError",
185
+ "raise NotImplementedError",
186
+ "if 0:",
187
+ "if __name__ == .__main__.:",
188
+ "class .*\\bProtocol\\):",
189
+ "@(abc\\.)?abstractmethod",
190
+ ]
@@ -0,0 +1,13 @@
1
+ """
2
+ Renewable Calibration (rencal) for renwable energy forecasting.
3
+
4
+ A Python library for calibrating renewable plant power curves using generalised logistic function
5
+ modules for generating probabilistic load factor time series forecasts using resampling from
6
+ historical ERA5 weather data.
7
+ """
8
+
9
+ from importlib.metadata import version
10
+
11
+ __version__ = version("rencal")
12
+ __author__ = "Low Carbon Contracts Company Ltd"
13
+ __email__ = "analytics@lowcarboncontracts.uk"
File without changes
@@ -0,0 +1,99 @@
1
+ """Abstract base class for the calibration of intermittent generator power curves."""
2
+
3
+ from abc import ABC, abstractmethod
4
+
5
+ from ..core.data_loader import DataLoader, LocalDataLoader
6
+
7
+
8
+ class Calibrator(ABC):
9
+ def __init__(
10
+ self,
11
+ data_path: str = None,
12
+ plant_id_col: str = None,
13
+ loader: DataLoader | None = None,
14
+ ):
15
+ """
16
+ Initialise a calibrator instance.
17
+
18
+ The Calibrator is an abstract class that specifies the methods any intermittent
19
+ generator's calibration should include, as well as setting up and loading input
20
+ datasets from the configuration file or user-specified paths.
21
+
22
+ Args:
23
+ data_path (str): Path to the directory containing the input data files.
24
+ plant_id_col (str): Name of the ID column designating a power plant in the input.
25
+ loader (DataLoader | None): Optional pre-configured data loader. When supplied it
26
+ is used as-is (overriding ``data_path``), allowing inputs to be read from
27
+ non-default locations or sources (e.g. a cloud loader reading directly from
28
+ Blob storage) instead of the default ``LocalDataLoader`` layout.
29
+ """
30
+ if loader is not None:
31
+ self.loader = loader
32
+ else:
33
+ self.loader = LocalDataLoader(data_path) if data_path else LocalDataLoader()
34
+ self.plants = (
35
+ self.loader.load_plant_data(plant_id_col)
36
+ if plant_id_col
37
+ else self.loader.load_plant_data()
38
+ )
39
+ self.generation = (
40
+ self.loader.load_generation_data(plant_id_col)
41
+ if plant_id_col
42
+ else self.loader.load_generation_data()
43
+ )
44
+ self.resource = self.loader.load_era5_data()
45
+
46
+ @abstractmethod
47
+ def calibrate(self) -> None:
48
+ """Triggers calibration workflow."""
49
+ pass
50
+
51
+ @abstractmethod
52
+ def extract_resource_timeseries_for_plants(self) -> None:
53
+ """Extracts resource time series for plants."""
54
+ pass
55
+
56
+ @abstractmethod
57
+ def calculate_historical_load_factors(self) -> None:
58
+ """Calculates historical load factors."""
59
+ pass
60
+
61
+ @abstractmethod
62
+ def fit_historical_load_factor_distribution(self) -> None:
63
+ """Fits a distribution to historical load factors."""
64
+ pass
65
+
66
+ @abstractmethod
67
+ def estimate_load_factors_for_resource(self) -> None:
68
+ """Estimates load factors based on historical distribution and full resource availability."""
69
+ pass
70
+
71
+ @abstractmethod
72
+ def generate_resource_streams(self) -> None:
73
+ """Generates load factor streams for available resource time series for each generator."""
74
+ pass
75
+
76
+ @abstractmethod
77
+ def output_historical_load_factor_distribution_parameters(self) -> None:
78
+ """Writes historical load factor parameters to a CSV file."""
79
+ pass
80
+
81
+ @abstractmethod
82
+ def output_resource_per_plant(self) -> None:
83
+ """Writes resource time series for each plant to a CSV file."""
84
+ pass
85
+
86
+ @abstractmethod
87
+ def output_resource_streams(self) -> None:
88
+ """Writes resource streams to a parquet file."""
89
+ pass
90
+
91
+ @abstractmethod
92
+ def output_estimated_load_factors_tabular(self) -> None:
93
+ """Outputs table of estimated load factors."""
94
+ pass
95
+
96
+ @abstractmethod
97
+ def output_estimated_load_factors_visual(self) -> None:
98
+ """Outputs a series of plots of estimated load factors and calibrated curves."""
99
+ pass
File without changes