-
Notifications
You must be signed in to change notification settings - Fork 0
Add CSV Readers for PowerLASCOPF System Creation (Part 1) #56
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
base: sams_branch
Are you sure you want to change the base?
Add CSV Readers for PowerLASCOPF System Creation (Part 1) #56
Conversation
…keep existing compat)
… existing compat)
…keep existing compat)
…ersion 0.12, (keep existing compat)
…keep existing compat)
…ep existing compat)
…ion 1, (keep existing compat)
…keep existing compat)
… (keep existing compat)
… (keep existing compat)
… existing compat)
…on 0.11, (keep existing compat)
…, (keep existing compat)
…ep existing compat)
…30, (keep existing compat)
… (keep existing compat)
…2-17-00-08-49-128-01411173499 CompatHelper: add new compat entry for PowerModels at version 0.21, (keep existing compat)
…02-17-00-08-50-572-00206183664 CompatHelper: add new compat entry for Statistics at version 1, (keep existing compat)
…02-17-00-08-52-103-03075536309 CompatHelper: add new compat entry for BenchmarkTools at version 1, (keep existing compat)
…02-17-00-08-53-518-00796215751 CompatHelper: add new compat entry for StorageSystemsSimulations at version 0.12, (keep existing compat)
…02-17-00-09-07-537-00951528936 CompatHelper: add new compat entry for Ipopt at version 1, (keep existing compat)
…02-17-00-09-09-031-04086465610 CompatHelper: add new compat entry for PowerGraphics at version 0.19, (keep existing compat)
…02-17-00-09-10-577-01515313495 CompatHelper: add new compat entry for DataFrames at version 1, (keep existing compat)
…02-17-00-09-12-269-02969035087 CompatHelper: add new compat entry for HydroPowerSimulations at version 0.11, (keep existing compat)
…02-17-00-09-13-829-02394655932 CompatHelper: add new compat entry for GLPK at version 1, (keep existing compat)
…02-17-00-09-15-412-02292681967 CompatHelper: add new compat entry for DataStructures at version 0.18, (keep existing compat)
…02-17-00-09-16-912-00310535970 CompatHelper: add new compat entry for PowerSystems at version 4, (keep existing compat)
…02-17-00-09-18-526-03575892309 CompatHelper: add new compat entry for PowerSimulations at version 0.30, (keep existing compat)
…02-17-00-09-20-189-00079707099 CompatHelper: add new compat entry for JuMP at version 1, (keep existing compat)
…03-27-00-08-37-804-00475756877 CompatHelper: add new compat entry for PowerGraphics at version 0.20, (keep existing compat)
Update ExtendedThermalGenerationCost.jl
This commit adds comprehensive CSV reading functionality to convert various CSV-based power system data formats into PowerSystems.jl compatible objects for use with PowerLASCOPF. Features: - Automatic format detection (RTS-GMLC and csv_118 formats) - Configurable reader with sensible defaults for missing fields - Support for buses, branches, generators, and loads - Comprehensive documentation and examples Files added: - src/io/readers/csv_reader.jl: Core CSV reading functionality - src/io/readers/PowerLASCOPFReaders.jl: Module definition - src/io/readers/README.md: Comprehensive documentation - examples/read_csv_example.jl: Usage examples Supported formats: 1. RTS-GMLC format (PowerSystems standard) - bus.csv, gen.csv, branch.csv - Example: example_cases/RTS_GMLC/ 2. csv_118 custom format - Buses.csv, Generators.csv, Lines.csv - Example: example_cases/csv_118/ The readers handle missing fields intelligently by: - Using configurable defaults - Computing values from other fields - Inferring values from naming conventions - Warning users of missing critical data Future work: - MATPOWER format reader - PSSE format reader - JSON format reader - Time series data integration
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a comprehensive CSV reader module for PowerLASCOPF that enables loading power system data from various CSV formats into PowerSystems.jl-compatible objects.
Key Changes:
- Implements CSV reader with support for RTS-GMLC and csv_118 formats with automatic format detection
- Provides configurable defaults for missing data fields through CSVReaderConfig struct
- Includes comprehensive documentation and examples for the new CSV reader functionality
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 10 comments.
| File | Description |
|---|---|
| src/io/readers/csv_reader.jl | Core CSV reader implementation with format-specific parsers for buses, branches, generators, and loads |
| src/io/readers/PowerLASCOPFReaders.jl | Module wrapper that exports the CSV reader functionality |
| src/io/readers/README.md | Comprehensive documentation for CSV readers including usage examples and format specifications |
| examples/read_csv_example.jl | Example script demonstrating usage of CSV readers with both supported formats |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| system = PSY.System(config.base_power) | ||
| system.name = "System_$(basename(data_dir))" |
Copilot
AI
Nov 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Direct assignment to system.name may not be supported by PowerSystems.jl API. PowerSystems typically requires setting the name during construction via PSY.System(base_power; name=...) or using a setter method if available. This could fail at runtime.
| system = PSY.System(config.base_power) | |
| system.name = "System_$(basename(data_dir))" | |
| system = PSY.System(config.base_power; name="System_$(basename(data_dir))") |
|
|
||
| for row in eachrow(df) | ||
| line_name = string(row[Symbol("Line Name")]) | ||
| from_bus_name = string(row[Symbol("Bus from ")]) # Note the space |
Copilot
AI
Nov 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment 'Note the space' highlights a fragile dependency on CSV column naming with trailing whitespace. Consider using strip() on column names during CSV reading or implementing a more robust column name matching that ignores leading/trailing whitespace to prevent silent failures.
| system = PSY.System(config.base_power) | ||
| system.name = "System_$(basename(data_dir))" |
Copilot
AI
Nov 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The system name should be set during system construction rather than after. Modify line 682 to: system = PSY.System(config.base_power; name=\"System_$(basename(data_dir))\") and remove line 683.
| system = PSY.System(config.base_power) | |
| system.name = "System_$(basename(data_dir))" | |
| system = PSY.System(config.base_power; name="System_$(basename(data_dir))") |
examples/read_csv_example.jl
Outdated
| # Add the PowerLASCOPF source to the load path | ||
| push!(LOAD_PATH, joinpath(@__DIR__, "..", "src")) | ||
|
|
Copilot
AI
Nov 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Modifying LOAD_PATH at runtime is not recommended. For package development, users should activate the package environment instead. Consider removing this line and documenting proper package activation in comments or README.
| # Add the PowerLASCOPF source to the load path | |
| push!(LOAD_PATH, joinpath(@__DIR__, "..", "src")) | |
| # To run this example, activate the package environment by starting Julia with: | |
| # julia --project=.. | |
| # This ensures all dependencies are available without modifying LOAD_PATH. |
|
|
||
| # Calculate load based on participation factor | ||
| p = total_system_load_pu * load_participation | ||
| q = p * 0.33 # Assume power factor of 0.95 (tan(acos(0.95)) ≈ 0.33) |
Copilot
AI
Nov 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment explains the power factor calculation but the magic number 0.33 reduces maintainability. Consider defining this as a named constant (e.g., const DEFAULT_POWER_FACTOR_TAN = 0.33) with a more detailed comment explaining the power factor assumption.
| bus_dict = Dict(b.name => b for b in buses) | ||
|
|
||
| # Assume total system load of 1000 MW for scaling | ||
| total_system_load_mw = 1000.0 |
Copilot
AI
Nov 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hardcoded total system load of 1000.0 MW is an arbitrary assumption that may not be appropriate for all systems. This should either be configurable through CSVReaderConfig or calculated from generator capacities with a warning about the assumption.
|
|
||
| # Create operation cost (simplified) | ||
| # In a real implementation, you'd parse the heat rate curve | ||
| variable_cost = 30.0 # Default $/MWh |
Copilot
AI
Nov 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default variable cost of 30.0 $/MWh is a magic number that should be made configurable through CSVReaderConfig. Different fuel types and regions have significantly different costs, making this hardcoded value potentially misleading.
src/io/readers/README.md
Outdated
| ### Basic Usage | ||
|
|
||
| ```julia | ||
| using PowerSystems |
Copilot
AI
Nov 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The README shows importing PowerLASCOPFReaders as a separate module, but this module is defined in src/io/readers/ which is not the standard location for a Julia module. Users would need to manually add src/io/readers to LOAD_PATH or the module needs to be included in the main PowerLASCOPF module. This creates a discrepancy between documentation and actual usage.
| using PowerSystems | |
| using PowerSystems | |
| # NOTE: PowerLASCOPFReaders is located in src/io/readers/, which is not a standard Julia module location. | |
| # To use it directly, add the directory to LOAD_PATH before importing: | |
| push!(LOAD_PATH, joinpath(@__DIR__, "src/io/readers")) |
| angle_limits = if hasproperty(df, Symbol("Min Angle Diff")) && hasproperty(df, Symbol("Max Angle Diff")) | ||
| (min = row[Symbol("Min Angle Diff")], max = row[Symbol("Max Angle Diff")]) | ||
| else | ||
| (min = -π/6, max = π/6) |
Copilot
AI
Nov 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default angle limits of ±π/6 radians (±30 degrees) are magic numbers that should be defined as named constants (e.g., const DEFAULT_ANGLE_LIMIT = π/6) or made configurable through CSVReaderConfig for better maintainability and clarity.
Changes:
- Include csv_reader.jl in main PowerLASCOPF module
- Export CSV reader functions from PowerLASCOPF module
- Remove standalone PowerLASCOPFReaders module wrapper
- Update README to show usage as part of PowerLASCOPF
- Update examples to use PowerLASCOPF instead of separate module
This resolves the module structure issue where PowerLASCOPFReaders
was presented as a standalone module but was located in src/io/readers/.
Now all CSV reader functions are properly integrated into and exported
from the main PowerLASCOPF module.
Usage is now:
using PowerLASCOPF
system = read_csv_system("path/to/data")
Instead of the previous (incorrect):
using PowerLASCOPFReaders
system = read_csv_system("path/to/data")
Co-authored-by: Copilot <[email protected]>
This commit adds comprehensive CSV reading functionality to convert various CSV-based power system data formats into PowerSystems.jl compatible objects for use with PowerLASCOPF.
Features:
Files added:
Supported formats:
RTS-GMLC format (PowerSystems standard)
csv_118 custom format
The readers handle missing fields intelligently by:
Future work:
Summary
This PR adds comprehensive CSV reading functionality to convert various CSV-based power system data formats into PowerSystems.jl compatible objects for use with PowerLASCOPF.
This is Part 1 of a multi-part implementation to address the full request.
Features
Supported CSV Formats
RTS-GMLC format (PowerSystems standard)
bus.csv,gen.csv,branch.csvexample_cases/RTS_GMLC/csv_118 custom format
Buses.csv,Generators.csv,Lines.csvexample_cases/csv_118/Key Capabilities
Files Added
src/io/readers/csv_reader.jl: Core CSV reading (~800 lines)src/io/readers/PowerLASCOPFReaders.jl: Module definitionsrc/io/readers/README.md: Documentation with usage examplesexamples/read_csv_example.jl: Practical examplesUsage Example