Skip to content

Line investment by period #47

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 9 commits into
base: long-to-short-term
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,8 @@ ispypsa_runs/**/*.hdf5

# ignore doit database
.doit*

# repomix for ai coding
.repomixignore
repomix-output.md
.repomix.config.json
41 changes: 41 additions & 0 deletions demo_flow_path_costs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""
Demo script to test the flow path cost templating function.
"""

from pathlib import Path

from ispypsa.data_fetch import read_csvs
from ispypsa.logging import configure_logging
from ispypsa.templater.flow_paths import _template_sub_regional_flow_path_costs

configure_logging()


def main():
"""Run the demo."""
# Define root folder for data
root_folder = Path("ispypsa_runs")
workbook_cache_dir = root_folder / "workbook_table_cache"

print("Loading test data...")
iasr_tables = read_csvs(workbook_cache_dir)
print(f"Loaded {len(iasr_tables)} tables")

# Process each scenario
scenarios = ["Step Change", "Progressive Change", "Green Energy Exports"]

for scenario in scenarios:
results = _template_sub_regional_flow_path_costs(iasr_tables, scenario)
print(f"Found {len(results['flow_path'].unique())} flow paths")
print("\nSample results:")
print(results)

# Save results to CSV
scenario_name = scenario.lower().replace(" ", "_")
output_file = Path(f"flow_path_costs_{scenario_name}.csv")
results.to_csv(output_file, index=False)
print(f"\nResults saved to: {output_file}")


if __name__ == "__main__":
main()
1 change: 0 additions & 1 deletion example_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@
operational_timeseries_location,
)


network.optimize.fix_optimal_capacities()

# Never use network.optimize() as this will remove custom constraints.
Expand Down
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
7 changes: 5 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ authors = [
dependencies = [
"pandas>=2.2.2",
"pypsa>=0.31.1",
"isp-workbook-parser>=2.4.1",
"pyyaml>=6.0.2",
"doit>=0.36.0",
"xmltodict>=0.13.0",
"thefuzz>=0.22.1",
"isp-trace-parser>=1.0.0",
"pyarrow>=18.0.0",
"tables>=3.10.1",
"isp-trace-parser>=1.0.3",
"isp-workbook-parser",
]
readme = "README.md"
requires-python = ">= 3.10"
Expand Down Expand Up @@ -50,6 +50,9 @@ dev-dependencies = [
"sphinx-autobuild>=2024.9.3",
]

[tool.uv.sources]
isp-workbook-parser = { path = "../isp-workbook-parser", editable = true }

[tool.hatch.metadata]
allow-direct-references = true

Expand Down
38 changes: 38 additions & 0 deletions repomix.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"$schema": "https://repomix.com/schemas/latest/schema.json",
"input": {
"maxFileSize": 52428800
},
"output": {
"filePath": "repomix-output.md",
"style": "markdown",
"parsableStyle": false,
"fileSummary": true,
"directoryStructure": true,
"files": true,
"removeComments": false,
"removeEmptyLines": false,
"compress": false,
"topFilesLength": 10,
"showLineNumbers": false,
"copyToClipboard": false,
"instruction-file-path": "instructions.md",
"git": {
"sortByChanges": true,
"sortByChangesMaxCommits": 100,
"includeDiffs": false
}
},
"include": [],
"ignore": {
"useGitignore": true,
"useDefaultPatterns": true,
"customPatterns": []
},
"security": {
"enableSecurityCheck": true
},
"tokenCount": {
"encoding": "o200k_base"
}
}
22 changes: 21 additions & 1 deletion src/ispypsa/iasr_table_caching/local_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@

from isp_workbook_parser import Parser

from ..templater.mappings import _GENERATOR_PROPERTIES
from ..templater.mappings import (
_ACTIONABLE_ISP_PROJECTS_TABLES,
_FLOW_PATH_AGUMENTATION_TABLES,
_FLOW_PATH_AUGMENTATION_COST_TABLES,
_GENERATOR_PROPERTIES,
_PREPATORY_ACTIVITIES_TABLES,
_REZ_AUGMENTATION_COST_TABLES,
_REZ_CONNECTION_AGUMENTATION_TABLES,
_REZ_CONNECTION_PREPATORY_ACTIVITIES_TABLES,
)

_GENERATOR_PROPERTY_TABLES = [
table_name
Expand Down Expand Up @@ -34,6 +43,17 @@
"initial_build_limits",
]

_NETWORK_REQUIRED_TABLES = (
_NETWORK_REQUIRED_TABLES
+ _FLOW_PATH_AGUMENTATION_TABLES
+ _FLOW_PATH_AUGMENTATION_COST_TABLES
+ _PREPATORY_ACTIVITIES_TABLES
+ _ACTIONABLE_ISP_PROJECTS_TABLES
+ _REZ_CONNECTION_AGUMENTATION_TABLES
+ _REZ_AUGMENTATION_COST_TABLES
+ _REZ_CONNECTION_PREPATORY_ACTIVITIES_TABLES
)

_GENERATORS_STORAGE_REQUIRED_SUMMARY_TABLES = [
"existing_generators_summary",
"committed_generators_summary",
Expand Down
23 changes: 12 additions & 11 deletions src/ispypsa/model/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ def build_pypsa_network(
network, pypsa_friendly_tables["buses"], path_to_pypsa_friendly_timeseries_data
)

if not pypsa_friendly_tables["custom_constraints_generators"].empty:
_add_bus_for_custom_constraints(network)

_add_lines_to_network(network, pypsa_friendly_tables["lines"])

_add_custom_constraint_generators_to_network(
network, pypsa_friendly_tables["custom_constraints_generators"]
)
if "custom_constraints_generators" in pypsa_friendly_tables.keys():
_add_bus_for_custom_constraints(network)

_add_custom_constraint_generators_to_network(
network, pypsa_friendly_tables["custom_constraints_generators"]
)

_add_generators_to_network(
network,
Expand All @@ -78,10 +78,11 @@ def build_pypsa_network(
# The underlying linopy model needs to get built so we can add custom constraints.
network.optimize.create_model()

_add_custom_constraints(
network,
pypsa_friendly_tables["custom_constraints_rhs"],
pypsa_friendly_tables["custom_constraints_lhs"],
)
if "custom_constraints_rhs" in pypsa_friendly_tables:
_add_custom_constraints(
network,
pypsa_friendly_tables["custom_constraints_rhs"],
pypsa_friendly_tables["custom_constraints_lhs"],
)

return network
26 changes: 22 additions & 4 deletions src/ispypsa/templater/create_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
)
from ispypsa.templater.flow_paths import (
_template_regional_interconnectors,
_template_rez_transmission_costs,
_template_sub_regional_flow_path_costs,
_template_sub_regional_flow_paths,
)
from ispypsa.templater.nodes import (
Expand Down Expand Up @@ -101,9 +103,7 @@ def create_ispypsa_inputs_template(

template = {}

transmission_expansion_costs = manually_extracted_tables.pop(
"transmission_expansion_costs"
)
# Remove popping transmission_expansion_costs as it's no longer needed
template.update(manually_extracted_tables)

if regional_granularity == "sub_regions":
Expand All @@ -112,7 +112,11 @@ def create_ispypsa_inputs_template(
)

template["flow_paths"] = _template_sub_regional_flow_paths(
iasr_tables["flow_path_transfer_capability"], transmission_expansion_costs
iasr_tables["flow_path_transfer_capability"]
)

template["flow_path_expansion_costs"] = _template_sub_regional_flow_path_costs(
iasr_tables, scenario
)

elif regional_granularity == "nem_regions":
Expand All @@ -137,6 +141,20 @@ def create_ispypsa_inputs_template(
iasr_tables["initial_build_limits"]
)

possible_rez_or_constraint_names = list(
set(
list(template["renewable_energy_zones"]["rez_id"])
+ list(template["rez_group_constraints_rhs"]["constraint_id"])
+ list(template["rez_transmission_limit_constraints_rhs"]["constraint_id"])
)
)

template["rez_transmission_expansion_costs"] = _template_rez_transmission_costs(
iasr_tables,
scenario,
possible_rez_or_constraint_names,
)

template["ecaa_generators"] = _template_ecaa_generators_static_properties(
iasr_tables
)
Expand Down
Loading
Loading