Skip to content

Update current pti parser to handle V35 PSSE files#1419

Merged
jd-lara merged 29 commits into
psy5from
ml/parse_v35_psse_files
Jul 1, 2025
Merged

Update current pti parser to handle V35 PSSE files#1419
jd-lara merged 29 commits into
psy5from
ml/parse_v35_psse_files

Conversation

@mcllerena

Copy link
Copy Markdown
Contributor
  • Current parser is extracting correctly substation location data for parse_pti and parse_psse
  • Handle of multi-line Re/Im of IC data for v35.
  • Add to ext new parameters of version v35.
  • Update Load and Switched Shunt structs to handle old and current file versions.

Comment thread src/descriptors/power_system_structs.json
Comment thread src/descriptors/power_system_structs.json
Comment thread src/descriptors/power_system_structs.json Outdated

@jd-lara jd-lara left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The biggest challenge here is the addition of the interruptible field because we have both interruptible and non-interruptible loads that can be modeled differently and the addition of the flag is not consistent with that pattern. When loads are interruptible we should create the correct type of interruptible because in PCM those require the correct implementation.

@jd-lara jd-lara self-assigned this Jun 16, 2025
@mcllerena mcllerena linked an issue Jun 16, 2025 that may be closed by this pull request
@mcllerena

Copy link
Copy Markdown
Contributor Author

Added these fixes on the last commits, did the tests changing the interruptible flag on the raw file and the load types were created correctly after creating the system.

@mcllerena mcllerena requested a review from jd-lara June 16, 2025 19:57

@jd-lara jd-lara left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Aren't we converting the substation geospatial data into the GeographicInfo attribute?

@mcllerena

Copy link
Copy Markdown
Contributor Author

Aren't we converting the substation geospatial data into the GeographicInfo attribute?

I initial just parse it and store it on parse_pti and parse_psse. I can include them as a GI attribute, I'll do a new commit addressing this.

@mcllerena

Copy link
Copy Markdown
Contributor Author

Just finished adding the GI to the buses 69a0aec

@mcllerena mcllerena requested a review from jd-lara June 18, 2025 05:24

@jd-lara jd-lara left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Add a new structure that combines interruptible power + standard load to support PSSe interruptible flag.

@jd-lara

jd-lara commented Jun 30, 2025

Copy link
Copy Markdown
Member

Add a new structure that combines interruptible power + standard load to support PSSe interruptible flag.

@mcllerena I made a new PR with the additional object we needed.

@kdayday kdayday mentioned this pull request Jun 30, 2025
@jd-lara jd-lara requested review from Copilot and daniel-thom and removed request for SebastianManriqueM, m-bossart and rodrigomha June 30, 2025 20:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 updates the PTI parser to support V35 PSSE files and improves handling of multi‐line Re/Im data and additional V35 parameters. Key changes include:

  • Introducing a new InterruptibleStandardLoad in the tests.
  • Adding geographic information to buses and adjusting load and transformer parsers for V35.
  • Updating data type definitions and PSSE parsing logic to incorporate new V35 fields.

Reviewed Changes

Copilot reviewed 7 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test/test_constructors.jl Adds tests for the new InterruptibleStandardLoad constructor
src/parsers/power_models_data.jl Enhancements for substation geographic info and updated load builders
src/parsers/pm_io/pti.jl Adjustments in PTI parsing to distinguish V35 files and multi‐line data
src/parsers/pm_io/psse.jl Updates to PSSE parsing logic to handle new V35 field names and formats
src/descriptors/power_system_structs.json New fields and updated defaults for V35 load models
src/PowerSystems.jl Exports the new InterruptibleStandardLoad

Comment thread src/parsers/power_models_data.jl Outdated
end
end

@info "Added coordinates to $(buses_with_coords[]) buses, $(buses_without_coords[]) buses without coordinates"

Copilot AI Jun 30, 2025

Copy link

Choose a reason for hiding this comment

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

The use of empty bracket indexing (buses_with_coords[] and buses_without_coords[]) for what appear to be integer counters is unusual. If this is not intended for array access, consider removing the brackets to simply interpolate the integer values.

Suggested change
@info "Added coordinates to $(buses_with_coords[]) buses, $(buses_without_coords[]) buses without coordinates"
@info "Added coordinates to $(buses_with_coords) buses, $(buses_without_coords) buses without coordinates"

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I agree with Copilot.

Comment thread src/parsers/pm_io/pti.jl
if haskey(pti_data, section)
push!(pti_data[section], section_data)
if section == "IMPEDANCE CORRECTION" &&
pti_data["CASE IDENTIFICATION"][1]["REV"] == 35

Copilot AI Jun 30, 2025

Copy link

Choose a reason for hiding this comment

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

[nitpick] The conditional branch for the 'IMPEDANCE CORRECTION' section when REV equals 35 causes the parser to skip adding the parsed section data. Please review this logic to confirm if this behavior is intentional; if so, adding a clarifying comment would improve maintainability.

Suggested change
pti_data["CASE IDENTIFICATION"][1]["REV"] == 35
pti_data["CASE IDENTIFICATION"][1]["REV"] == 35
# Skipping the addition of parsed data for "IMPEDANCE CORRECTION" when REV equals 35.
# This behavior is intentional and based on the specific requirements of PTI v35 files.

Copilot uses AI. Check for mistakes.
Comment thread src/parsers/power_models_data.jl Outdated
lat, lon = substation["latitude"], substation["longitude"]
for node in substation["nodes"]
if haskey(node, "I")
bus_coords_lookup[node["I"]] = (lat, lon)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you create the GeographicInfo object here and share references across components? It could matter a lot if there are many instances of components at the same location.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Agree with this

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed on last commits

Comment thread src/parsers/power_models_data.jl Outdated
end
end

@info "Added coordinates to $(buses_with_coords[]) buses, $(buses_without_coords[]) buses without coordinates"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I agree with Copilot.

Comment thread src/parsers/power_models_data.jl Outdated
load = make_interruptible_standardload(d, bus, sys_mbase; kwargs...)
has_component(InterruptibleStandardLoad, sys, get_name(load)) && throw(
DataFormatError(
"Found duplicate interruptible load names of $(get_name(load)), consider formatting names with `load_name_formatter` kwarg",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Prefer summary(load) over get_name(load) because it includes the struct name.

Comment thread src/parsers/pm_io/pti.jl Outdated

return updated_line_index
catch message
throw(@error("Parsing failed at line $line_index: $(sprint(showerror, message))"))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This doesn't look right. Do you mean to call error()?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, my bad. I just fix it on the last commits.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks like the pattern preceded you. It's odd, but still kinda works.

julia> throw(@error("asdfs"))
┌ Error: asdfs
└ @ Main REPL[15]:1
ERROR: nothing
Stacktrace:
 [1] top-level scope
   @ logging/logging.jl:418

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The ERROR: nothing is confusing though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, better to use the error() or @error

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@mcllerena @error is for logging an error not throwing

@mcllerena mcllerena requested a review from daniel-thom July 1, 2025 00:02
Comment thread src/parsers/pm_io/pti.jl
current_dtypes = is_v35 ? _pti_dtypes_v35 : _pti_dtypes

line_index = 1
while line_index <= length(data_lines)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There is a lot of logic here and I can't say that I've reviewed all of it. I will say that I'm unsure about your change from a for loop (built-in index) to a while loop (managed index). It will be very easy for someone to miss incrementing line_index in some conditional. What is your reasoning here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, I was aware of this risk in using a while loop instead of a for loop. Is just that because I had to keep track of the line index for each components, where there were line/multi-line structures like in the Impedance Correction Data for v35 files, also for the complex parsing of the Substation Data Blocks structure in the file to extract the latitude/longitude fields; I couldn't find a solution to handle this with a for loop when I wrote the code.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ok thanks, I see that now. Can you point me at an example? I'd like to take a look at one of these files before approving.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sure, I'll share it internally since the only one I have with all these characteristics is really heavy.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@mcllerena we can merge once Dan Approves but we still haven't implemented extensive testing. We should add an issue for increasing testing before release.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I’ll be building small tests with ICD and substation data specially, since these were the most annoying ones

@jd-lara jd-lara merged commit e59ff31 into psy5 Jul 1, 2025
1 of 9 checks passed
@jd-lara jd-lara deleted the ml/parse_v35_psse_files branch July 17, 2025 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update/Implement parser to handle V35 PSSE files

4 participants