mirror of
https://github.com/ANL-CEEESA/RELOG.git
synced 2025-12-06 07:48:50 -06:00
Finish implementing parser
This commit is contained in:
@@ -42,8 +42,8 @@ function parse(json)::Instance
|
|||||||
outputs = [products_by_name[p] for p in cdict["outputs"]]
|
outputs = [products_by_name[p] for p in cdict["outputs"]]
|
||||||
operating_cost = timeseries(cdict["operating cost (\$)"])
|
operating_cost = timeseries(cdict["operating cost (\$)"])
|
||||||
prod_dict(key, null_val) = OrderedDict(
|
prod_dict(key, null_val) = OrderedDict(
|
||||||
p => [v === nothing ? null_val : v for v in timeseries(cdict[key][p.name])] for
|
p => [v === nothing ? null_val : v for v in timeseries(cdict[key][p.name])]
|
||||||
p in outputs
|
for p in outputs
|
||||||
)
|
)
|
||||||
fixed_output = prod_dict("fixed output (tonne)", 0.0)
|
fixed_output = prod_dict("fixed output (tonne)", 0.0)
|
||||||
var_output = prod_dict("variable output (tonne/tonne)", 0.0)
|
var_output = prod_dict("variable output (tonne/tonne)", 0.0)
|
||||||
@@ -68,6 +68,54 @@ function parse(json)::Instance
|
|||||||
centers_by_name[cname] = center
|
centers_by_name[cname] = center
|
||||||
end
|
end
|
||||||
|
|
||||||
|
plants = Plant[]
|
||||||
|
plants_by_name = OrderedDict{String,Plant}()
|
||||||
|
for (pname, pdict) in json["plants"]
|
||||||
|
prod_dict(key; scale = 1.0, null_val = Inf) = OrderedDict{Product,Vector{Float64}}(
|
||||||
|
products_by_name[p] => [
|
||||||
|
v === nothing ? null_val : v * scale for v in timeseries(pdict[key][p])
|
||||||
|
] for p in keys(pdict[key])
|
||||||
|
)
|
||||||
|
|
||||||
|
latitude = pdict["latitude (deg)"]
|
||||||
|
longitude = pdict["longitude (deg)"]
|
||||||
|
input_mix = prod_dict("input mix (%)", scale = 0.01)
|
||||||
|
output = prod_dict("output (tonne)")
|
||||||
|
emissions = timeseries(pdict["processing emissions (tonne)"])
|
||||||
|
storage_cost = prod_dict("storage cost (\$/tonne)")
|
||||||
|
storage_limit = prod_dict("storage limit (tonne)")
|
||||||
|
disposal_cost = prod_dict("disposal cost (\$/tonne)")
|
||||||
|
disposal_limit = prod_dict("disposal limit (tonne)")
|
||||||
|
initial_capacity = pdict["initial capacity (tonne)"]
|
||||||
|
capacities = PlantCapacity[]
|
||||||
|
for cdict in pdict["capacities"]
|
||||||
|
size = cdict["size (tonne)"]
|
||||||
|
opening_cost = timeseries(cdict["opening cost (\$)"])
|
||||||
|
fix_operating_cost = timeseries(cdict["fixed operating cost (\$)"])
|
||||||
|
var_operating_cost = timeseries(cdict["variable operating cost (\$/tonne)"])
|
||||||
|
push!(
|
||||||
|
capacities,
|
||||||
|
PlantCapacity(; size, opening_cost, fix_operating_cost, var_operating_cost),
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
plant = Plant(;
|
||||||
|
latitude,
|
||||||
|
longitude,
|
||||||
|
input_mix,
|
||||||
|
output,
|
||||||
|
emissions,
|
||||||
|
storage_cost,
|
||||||
|
storage_limit,
|
||||||
|
disposal_cost,
|
||||||
|
disposal_limit,
|
||||||
|
capacities,
|
||||||
|
initial_capacity,
|
||||||
|
)
|
||||||
|
push!(plants, plant)
|
||||||
|
plants_by_name[pname] = plant
|
||||||
|
end
|
||||||
|
|
||||||
return Instance(;
|
return Instance(;
|
||||||
time_horizon,
|
time_horizon,
|
||||||
building_period,
|
building_period,
|
||||||
@@ -76,5 +124,7 @@ function parse(json)::Instance
|
|||||||
products_by_name,
|
products_by_name,
|
||||||
centers,
|
centers,
|
||||||
centers_by_name,
|
centers_by_name,
|
||||||
|
plants,
|
||||||
|
plants_by_name,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -21,6 +21,27 @@ Base.@kwdef struct Center
|
|||||||
disposal_cost::OrderedDict{Product,Vector{Float64}}
|
disposal_cost::OrderedDict{Product,Vector{Float64}}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Base.@kwdef struct PlantCapacity
|
||||||
|
size::Float64
|
||||||
|
opening_cost::Vector{Float64}
|
||||||
|
fix_operating_cost::Vector{Float64}
|
||||||
|
var_operating_cost::Vector{Float64}
|
||||||
|
end
|
||||||
|
|
||||||
|
Base.@kwdef struct Plant
|
||||||
|
latitude::Float64
|
||||||
|
longitude::Float64
|
||||||
|
input_mix::OrderedDict{Product,Vector{Float64}}
|
||||||
|
output::OrderedDict{Product,Vector{Float64}}
|
||||||
|
emissions::OrderedDict{String,Vector{Float64}}
|
||||||
|
storage_cost::OrderedDict{Product,Vector{Float64}}
|
||||||
|
storage_limit::OrderedDict{Product,Vector{Float64}}
|
||||||
|
disposal_cost::OrderedDict{Product,Vector{Float64}}
|
||||||
|
disposal_limit::OrderedDict{Product,Vector{Float64}}
|
||||||
|
capacities::Vector{PlantCapacity}
|
||||||
|
initial_capacity::Float64
|
||||||
|
end
|
||||||
|
|
||||||
Base.@kwdef struct Instance
|
Base.@kwdef struct Instance
|
||||||
building_period::Vector{Int}
|
building_period::Vector{Int}
|
||||||
centers_by_name::OrderedDict{String,Center}
|
centers_by_name::OrderedDict{String,Center}
|
||||||
@@ -29,4 +50,6 @@ Base.@kwdef struct Instance
|
|||||||
products_by_name::OrderedDict{String,Product}
|
products_by_name::OrderedDict{String,Product}
|
||||||
products::Vector{Product}
|
products::Vector{Product}
|
||||||
time_horizon::Int
|
time_horizon::Int
|
||||||
|
plants::Vector{Plant}
|
||||||
|
plants_by_name::OrderedDict{String,Plant}
|
||||||
end
|
end
|
||||||
|
|||||||
26
test/fixtures/boat_example.ipynb
vendored
26
test/fixtures/boat_example.ipynb
vendored
@@ -2,7 +2,7 @@
|
|||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 18,
|
"execution_count": 12,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
@@ -54,31 +54,31 @@
|
|||||||
"nail_factory = {\n",
|
"nail_factory = {\n",
|
||||||
" \"input\": None,\n",
|
" \"input\": None,\n",
|
||||||
" \"outputs\": [\"Nail\"],\n",
|
" \"outputs\": [\"Nail\"],\n",
|
||||||
" \"fixed output (tonne)\": 1,\n",
|
" \"fixed output (tonne)\": {\"Nail\": 1},\n",
|
||||||
" \"variable output (tonne/tonne)\": {},\n",
|
" \"variable output (tonne/tonne)\": {\"Nail\": 0},\n",
|
||||||
" \"revenue ($/tonne)\": None,\n",
|
" \"revenue ($/tonne)\": None,\n",
|
||||||
" \"collection cost ($/tonne)\": {\"Nail\": 1000},\n",
|
" \"collection cost ($/tonne)\": {\"Nail\": 1000},\n",
|
||||||
" \"operating cost ($)\": 0,\n",
|
" \"operating cost ($)\": 0,\n",
|
||||||
" \"disposal limit (tonne)\": 1e5,\n",
|
" \"disposal limit (tonne)\": {\"Nail\": None},\n",
|
||||||
" \"disposal cost ($/tonne)\": {\"Nail\": 0},\n",
|
" \"disposal cost ($/tonne)\": {\"Nail\": 0},\n",
|
||||||
"}\n",
|
"}\n",
|
||||||
"\n",
|
"\n",
|
||||||
"forest = {\n",
|
"forest = {\n",
|
||||||
" \"input\": None,\n",
|
" \"input\": None,\n",
|
||||||
" \"outputs\": [\"Wood\"],\n",
|
" \"outputs\": [\"Wood\"],\n",
|
||||||
" \"fixed output (tonne)\": 100,\n",
|
" \"fixed output (tonne)\": {\"Wood\": 100},\n",
|
||||||
" \"variable output (tonne/tonne)\": {},\n",
|
" \"variable output (tonne/tonne)\": {\"Wood\": 0},\n",
|
||||||
" \"revenue ($/tonne)\": None,\n",
|
" \"revenue ($/tonne)\": None,\n",
|
||||||
" \"collection cost ($/tonne)\": {\"Wood\": 250},\n",
|
" \"collection cost ($/tonne)\": {\"Wood\": 250},\n",
|
||||||
" \"operating cost ($)\": 0,\n",
|
" \"operating cost ($)\": 0,\n",
|
||||||
" \"disposal limit (tonne)\": 1e5,\n",
|
" \"disposal limit (tonne)\": {\"Wood\": None},\n",
|
||||||
" \"disposal cost ($/tonne)\": {\"Wood\": 0},\n",
|
" \"disposal cost ($/tonne)\": {\"Wood\": 0},\n",
|
||||||
"}\n",
|
"}\n",
|
||||||
"\n",
|
"\n",
|
||||||
"retail = {\n",
|
"retail = {\n",
|
||||||
" \"input\": \"NewBoat\",\n",
|
" \"input\": \"NewBoat\",\n",
|
||||||
" \"outputs\": [\"UsedBoat\"],\n",
|
" \"outputs\": [\"UsedBoat\"],\n",
|
||||||
" \"fixed output (tonne)\": 0,\n",
|
" \"fixed output (tonne)\": {\"UsedBoat\": 0},\n",
|
||||||
" \"variable output (tonne/tonne)\": {\"UsedBoat\": [0.10, 0.25, 0.10]},\n",
|
" \"variable output (tonne/tonne)\": {\"UsedBoat\": [0.10, 0.25, 0.10]},\n",
|
||||||
" \"revenue ($/tonne)\": 3_000,\n",
|
" \"revenue ($/tonne)\": 3_000,\n",
|
||||||
" \"collection cost ($/tonne)\": {\"UsedBoat\": 100},\n",
|
" \"collection cost ($/tonne)\": {\"UsedBoat\": 100},\n",
|
||||||
@@ -115,13 +115,13 @@
|
|||||||
" },\n",
|
" },\n",
|
||||||
" \"capacities\": [\n",
|
" \"capacities\": [\n",
|
||||||
" {\n",
|
" {\n",
|
||||||
" \"size\": 50,\n",
|
" \"size (tonne)\": 50,\n",
|
||||||
" \"opening cost ($)\": 10_000,\n",
|
" \"opening cost ($)\": 10_000,\n",
|
||||||
" \"fixed operating cost ($)\": 1_000,\n",
|
" \"fixed operating cost ($)\": 1_000,\n",
|
||||||
" \"variable operating cost ($/tonne)\": 5,\n",
|
" \"variable operating cost ($/tonne)\": 5,\n",
|
||||||
" },\n",
|
" },\n",
|
||||||
" {\n",
|
" {\n",
|
||||||
" \"size\": 500,\n",
|
" \"size (tonne)\": 500,\n",
|
||||||
" \"opening cost ($)\": 20_000,\n",
|
" \"opening cost ($)\": 20_000,\n",
|
||||||
" \"fixed operating cost ($)\": 2_000,\n",
|
" \"fixed operating cost ($)\": 2_000,\n",
|
||||||
" \"variable operating cost ($/tonne)\": 5,\n",
|
" \"variable operating cost ($/tonne)\": 5,\n",
|
||||||
@@ -147,13 +147,13 @@
|
|||||||
" \"disposal limit (tonne)\": {\"Nail\": None, \"Wood\": None},\n",
|
" \"disposal limit (tonne)\": {\"Nail\": None, \"Wood\": None},\n",
|
||||||
" \"capacities\": [\n",
|
" \"capacities\": [\n",
|
||||||
" {\n",
|
" {\n",
|
||||||
" \"size\": 50,\n",
|
" \"size (tonne)\": 50,\n",
|
||||||
" \"opening cost ($)\": 5_000,\n",
|
" \"opening cost ($)\": 5_000,\n",
|
||||||
" \"fixed operating cost ($)\": 500,\n",
|
" \"fixed operating cost ($)\": 500,\n",
|
||||||
" \"variable operating cost ($/tonne)\": 2.5,\n",
|
" \"variable operating cost ($/tonne)\": 2.5,\n",
|
||||||
" },\n",
|
" },\n",
|
||||||
" {\n",
|
" {\n",
|
||||||
" \"size\": 500,\n",
|
" \"size (tonne)\": 500,\n",
|
||||||
" \"opening cost ($)\": 10_000,\n",
|
" \"opening cost ($)\": 10_000,\n",
|
||||||
" \n",
|
" \n",
|
||||||
" \"fixed operating cost ($)\": 1_000,\n",
|
" \"fixed operating cost ($)\": 1_000,\n",
|
||||||
@@ -166,7 +166,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 17,
|
"execution_count": 13,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
|||||||
444
test/fixtures/boat_example.json
vendored
444
test/fixtures/boat_example.json
vendored
File diff suppressed because it is too large
Load Diff
48
test/fixtures/simple.json
vendored
48
test/fixtures/simple.json
vendored
@@ -103,5 +103,53 @@
|
|||||||
"disposal limit (tonne)": {},
|
"disposal limit (tonne)": {},
|
||||||
"disposal cost ($/tonne)": {}
|
"disposal cost ($/tonne)": {}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"plants": {
|
||||||
|
"L1": {
|
||||||
|
"latitude (deg)": 41.881,
|
||||||
|
"longitude (deg)": -87.623,
|
||||||
|
"input mix (%)": {
|
||||||
|
"P1": 95.3,
|
||||||
|
"P2": 4.7
|
||||||
|
},
|
||||||
|
"output (tonne)": {
|
||||||
|
"P3": 0.25,
|
||||||
|
"P4": 0.12
|
||||||
|
},
|
||||||
|
"processing emissions (tonne)": {
|
||||||
|
"CO2": 0.1
|
||||||
|
},
|
||||||
|
"storage cost ($/tonne)": {
|
||||||
|
"P1": 0.1,
|
||||||
|
"P2": 0.1
|
||||||
|
},
|
||||||
|
"storage limit (tonne)": {
|
||||||
|
"P1": 100,
|
||||||
|
"P2": null
|
||||||
|
},
|
||||||
|
"disposal cost ($/tonne)": {
|
||||||
|
"P3": 0,
|
||||||
|
"P4": 0.86
|
||||||
|
},
|
||||||
|
"disposal limit (tonne)": {
|
||||||
|
"P3": null,
|
||||||
|
"P4": 1000.0
|
||||||
|
},
|
||||||
|
"capacities": [
|
||||||
|
{
|
||||||
|
"size (tonne)": 100,
|
||||||
|
"opening cost ($)": 500,
|
||||||
|
"fixed operating cost ($)": 300,
|
||||||
|
"variable operating cost ($/tonne)": 5.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size (tonne)": 500,
|
||||||
|
"opening cost ($)": 1000.0,
|
||||||
|
"fixed operating cost ($)": 400.0,
|
||||||
|
"variable operating cost ($/tonne)": 5.0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"initial capacity (tonne)": 150
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ end
|
|||||||
|
|
||||||
function runtests()
|
function runtests()
|
||||||
@testset "RELOG" begin
|
@testset "RELOG" begin
|
||||||
instance_parse_test()
|
instance_parse_test_1()
|
||||||
|
instance_parse_test_2()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using RELOG
|
|||||||
using Test
|
using Test
|
||||||
using OrderedCollections
|
using OrderedCollections
|
||||||
|
|
||||||
function instance_parse_test()
|
function instance_parse_test_1()
|
||||||
instance = RELOG.parsefile(fixture("simple.json"))
|
instance = RELOG.parsefile(fixture("simple.json"))
|
||||||
|
|
||||||
# Parameters
|
# Parameters
|
||||||
@@ -21,6 +21,7 @@ function instance_parse_test()
|
|||||||
@test instance.products_by_name["P1"] === p1
|
@test instance.products_by_name["P1"] === p1
|
||||||
p2 = instance.products[2]
|
p2 = instance.products[2]
|
||||||
p3 = instance.products[3]
|
p3 = instance.products[3]
|
||||||
|
p4 = instance.products[4]
|
||||||
|
|
||||||
# Centers
|
# Centers
|
||||||
@test length(instance.centers) == 3
|
@test length(instance.centers) == 3
|
||||||
@@ -41,4 +42,36 @@ function instance_parse_test()
|
|||||||
@test c2.input === nothing
|
@test c2.input === nothing
|
||||||
@test c2.revenue == [0, 0, 0, 0]
|
@test c2.revenue == [0, 0, 0, 0]
|
||||||
|
|
||||||
|
# Plants
|
||||||
|
@test length(instance.plants) == 1
|
||||||
|
l1 = instance.plants[1]
|
||||||
|
@test l1.latitude == 41.881
|
||||||
|
@test l1.longitude == -87.623
|
||||||
|
@test l1.input_mix ==
|
||||||
|
Dict(p1 => [0.953, 0.953, 0.953, 0.953], p2 => [0.047, 0.047, 0.047, 0.047])
|
||||||
|
@test l1.output == Dict(p3 => [0.25, 0.25, 0.25, 0.25], p4 => [0.12, 0.12, 0.12, 0.12])
|
||||||
|
@test l1.emissions == Dict("CO2" => [0.1, 0.1, 0.1, 0.1])
|
||||||
|
@test l1.storage_cost == Dict(p1 => [0.1, 0.1, 0.1, 0.1], p2 => [0.1, 0.1, 0.1, 0.1])
|
||||||
|
@test l1.storage_limit == Dict(p1 => [100, 100, 100, 100], p2 => [Inf, Inf, Inf, Inf])
|
||||||
|
@test l1.disposal_cost == Dict(p3 => [0, 0, 0, 0], p4 => [0.86, 0.86, 0.86, 0.86])
|
||||||
|
@test l1.disposal_limit ==
|
||||||
|
Dict(p3 => [Inf, Inf, Inf, Inf], p4 => [1000.0, 1000.0, 1000.0, 1000.0])
|
||||||
|
@test l1.initial_capacity == 150
|
||||||
|
@test length(l1.capacities) == 2
|
||||||
|
c1 = l1.capacities[1]
|
||||||
|
@test c1.size == 100
|
||||||
|
@test c1.opening_cost == [500, 500, 500, 500]
|
||||||
|
@test c1.fix_operating_cost == [300, 300, 300, 300]
|
||||||
|
@test c1.var_operating_cost == [5, 5, 5, 5]
|
||||||
|
c2 = l1.capacities[2]
|
||||||
|
@test c2.size == 500
|
||||||
|
@test c2.opening_cost == [1000, 1000, 1000, 1000]
|
||||||
|
@test c2.fix_operating_cost == [400, 400, 400, 400]
|
||||||
|
@test c2.var_operating_cost == [5, 5, 5, 5]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function instance_parse_test_2()
|
||||||
|
# Should not crash
|
||||||
|
RELOG.parsefile(fixture("boat_example.json"))
|
||||||
end
|
end
|
||||||
Reference in New Issue
Block a user