Allow v0.3 to read v0.2 instance files

feature/migrate
Alinson S. Xavier 3 years ago
parent 678e6aa2f5
commit 6e30645084

@ -24,7 +24,9 @@ Instances are specified by JSON files containing the following main sections:
* Reserves
* Contingencies
Each section is described in detail below.
Each section is described in detail below. See [case118/2017-01-01.json.gz][example] for a complete example.
[example]: https://axavier.org/UnitCommitment.jl/0.3/instances/matpower/case118/2017-01-01.json.gz
### Parameters
@ -303,3 +305,4 @@ Current limitations
* Only N-1 transmission contingencies are supported. Generator contingencies are not currently supported.
* Time-varying minimum production amounts are not currently compatible with ramp/startup/shutdown limits.
* Flexible ramping products can only be acquired under the `WanHob2016` formulation, which does not support spinning reserves.

@ -9,7 +9,7 @@ suffix: .
Instances
=========
UnitCommitment.jl provides a large collection of benchmark instances collected from the literature and converted to a [common data format](format.md). In some cases, as indicated below, the original instances have been extended, with realistic parameters, using data-driven methods. If you use these instances in your research, we request that you cite UnitCommitment.jl, as well as the original sources, as listed below. Benchmark instances can be loaded with `UnitCommitment.read_benchmark(name)`, as explained in the [usage section](usage.md).
UnitCommitment.jl provides a large collection of benchmark instances collected from the literature and converted to a [common data format](format.md). In some cases, as indicated below, the original instances have been extended, with realistic parameters, using data-driven methods. If you use these instances in your research, we request that you cite UnitCommitment.jl, as well as the original sources, as listed below. Benchmark instances can be loaded with `UnitCommitment.read_benchmark(name)`, as explained in the [usage section](usage.md). Instance files can also be [directly downloaded from our website](https://axavier.org/UnitCommitment.jl/0.3/instances/).
```{warning}
The instances included in UC.jl are still under development and may change in the future. If you use these instances in your research, for reproducibility, you should specify what version of UC.jl they came from.

@ -20,6 +20,7 @@ include("model/formulations/WanHob2016/structs.jl")
include("import/egret.jl")
include("instance/read.jl")
include("instance/migrate.jl")
include("model/build.jl")
include("model/formulations/ArrCon2000/ramp.jl")
include("model/formulations/base/bus.jl")

@ -0,0 +1,38 @@
# UnitCommitment.jl: Optimization Package for Security-Constrained Unit Commitment
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
using DataStructures
using JSON
function _migrate(json)
version = json["Parameters"]["Version"]
if version === nothing
error(
"The provided input file cannot be loaded because it does not " *
"specify what version of UnitCommitment.jl it was written for. " *
"Please modify the \"Parameters\" section of the file and include " *
"a \"Version\" entry. For example: {\"Parameters\":{\"Version\":\"0.3\"}}",
)
end
version = VersionNumber(version)
version >= v"0.3" || _migrate_to_v03(json)
return
end
function _migrate_to_v03(json)
# Migrate reserves
if json["Reserves"] !== nothing &&
json["Reserves"]["Spinning (MW)"] !== nothing
amount = json["Reserves"]["Spinning (MW)"]
json["Reserves"] = DefaultOrderedDict(nothing)
json["Reserves"]["r1"] = DefaultOrderedDict(nothing)
json["Reserves"]["r1"]["Type"] = "spinning"
json["Reserves"]["r1"]["Amount (MW)"] = amount
for (gen_name, gen) in json["Generators"]
if gen["Provides spinning reserves?"] == true
gen["Reserve eligibility"] = ["r1"]
end
end
end
end

@ -80,6 +80,7 @@ function _read_json(path::String)::OrderedDict
end
function _from_json(json; repair = true)
_migrate(json)
units = Unit[]
buses = Bus[]
contingencies = Contingency[]

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -4,12 +4,9 @@
using UnitCommitment
basedir = @__DIR__
@testset "read_egret_solution" begin
solution = UnitCommitment.read_egret_solution(
"$basedir/../fixtures/egret_output.json.gz",
)
solution =
UnitCommitment.read_egret_solution("$FIXTURES/egret_output.json.gz")
for attr in ["Is on", "Production (MW)", "Production cost (\$)"]
@test attr in keys(solution)
@test "115_STEAM_1" in keys(solution[attr])

@ -0,0 +1,18 @@
# UnitCommitment.jl: Optimization Package for Security-Constrained Unit Commitment
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
@testset "read v0.2" begin
instance = UnitCommitment.read("$FIXTURES/ucjl-0.2.json.gz")
@test length(instance.reserves_by_name["r1"].amount) == 4
@test instance.units_by_name["g2"].reserves[1].name == "r1"
end
@testset "read v0.3" begin
instance = UnitCommitment.read("$FIXTURES/ucjl-0.3.json.gz")
@test length(instance.units) == 6
@test length(instance.buses) == 14
@test length(instance.lines) == 20
end

@ -5,7 +5,7 @@
using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
@testset "read_benchmark" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
@test length(instance.lines) == 20
@test length(instance.buses) == 14
@ -112,7 +112,7 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
end
@testset "read_benchmark sub-hourly" begin
instance = UnitCommitment.read_benchmark("test/case14-sub-hourly")
instance = UnitCommitment.read("$FIXTURES/case14-sub-hourly.json.gz")
@test instance.time == 4
unit = instance.units[1]
@test unit.name == "g1"

@ -20,11 +20,11 @@ import UnitCommitment:
function _test(
formulation::Formulation;
instances = ["test/case14"],
instances = ["case14"],
dump::Bool = false,
)::Nothing
for instance_name in instances
instance = UnitCommitment.read_benchmark(instance_name)
instance = UnitCommitment.read("$(FIXTURES)/$(instance_name).json.gz")
model = UnitCommitment.build_model(
instance = instance,
formulation = formulation,
@ -78,7 +78,7 @@ end
@testset "WanHob2016" begin
_test(
Formulation(ramping = WanHob2016.Ramping()),
instances = ["test/case14-flex"],
instances = ["case14-flex"],
)
end
end

@ -8,6 +8,8 @@ using UnitCommitment
push!(Base.LOAD_PATH, @__DIR__)
UnitCommitment._setup_logger(level = Base.CoreLogging.Error)
FIXTURES = "$(@__DIR__)/fixtures"
@testset "UnitCommitment" begin
include("usage.jl")
@testset "import" begin
@ -15,6 +17,7 @@ UnitCommitment._setup_logger(level = Base.CoreLogging.Error)
end
@testset "instance" begin
include("instance/read_test.jl")
include("instance/migrate_test.jl")
end
@testset "model" begin
include("model/formulations_test.jl")

@ -6,7 +6,7 @@ using UnitCommitment, Test, LinearAlgebra
import UnitCommitment: _Violation, _offer, _query
@testset "_ViolationFilter" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
filter = UnitCommitment._ViolationFilter(max_per_line = 1, max_total = 2)
_offer(

@ -6,7 +6,7 @@ using UnitCommitment, Test, LinearAlgebra
import UnitCommitment: _Violation, _offer, _query
@testset "find_violations" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
for line in instance.lines, t in 1:instance.time
line.normal_flow_limit[t] = 1.0
line.emergency_flow_limit[t] = 1.0

@ -5,7 +5,7 @@
using UnitCommitment, Test, LinearAlgebra
@testset "_susceptance_matrix" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
actual = UnitCommitment._susceptance_matrix(instance.lines)
@test size(actual) == (20, 20)
expected = Diagonal([
@ -34,7 +34,7 @@ using UnitCommitment, Test, LinearAlgebra
end
@testset "_reduced_incidence_matrix" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
actual = UnitCommitment._reduced_incidence_matrix(
lines = instance.lines,
buses = instance.buses,
@ -81,7 +81,7 @@ end
end
@testset "_injection_shift_factors" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
actual = UnitCommitment._injection_shift_factors(
lines = instance.lines,
buses = instance.buses,
@ -112,7 +112,7 @@ end
end
@testset "_line_outage_factors" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
isf_before = UnitCommitment._injection_shift_factors(
lines = instance.lines,
buses = instance.buses,

@ -4,12 +4,9 @@
using UnitCommitment, Cbc, JuMP
basedir = @__DIR__
@testset "generate_initial_conditions!" begin
# Load instance
instance =
UnitCommitment.read("$basedir/../fixtures/case118-initcond.json.gz")
instance = UnitCommitment.read("$FIXTURES/case118-initcond.json.gz")
optimizer = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0)
# All units should have unknown initial conditions

@ -5,7 +5,7 @@
using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
@testset "slice" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
modified = UnitCommitment.slice(instance, 1:2)
# Should update all time-dependent fields

@ -5,7 +5,7 @@
using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON
@testset "usage" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
for line in instance.lines, t in 1:4
line.normal_flow_limit[t] = 10.0
end

@ -4,11 +4,9 @@
using UnitCommitment, JSON, GZip, DataStructures
basedir = @__DIR__
function parse_case14()
return JSON.parse(
GZip.gzopen("$basedir/../../instances/test/case14.json.gz"),
GZip.gzopen("$FIXTURES/case14.json.gz"),
dicttype = () -> DefaultOrderedDict(nothing),
)
end

Loading…
Cancel
Save