diff --git a/CHANGELOG.md b/CHANGELOG.md index d400877..5bb5085 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file. ## [Unreleased] ## Added - Allow user to specify locations as unique identifiers, instead of latitude and longitude (e.g. `us-state:IL` or `2018-us-county:17043`) +- Add products report. ## [0.5.0] -- 2021-01-06 ## Added diff --git a/src/RELOG.jl b/src/RELOG.jl index 46df1c3..d202938 100644 --- a/src/RELOG.jl +++ b/src/RELOG.jl @@ -20,6 +20,7 @@ include("model/solve.jl") include("reports/plant_emissions.jl") include("reports/plant_outputs.jl") include("reports/plants.jl") +include("reports/products.jl") include("reports/tr_emissions.jl") include("reports/tr.jl") include("reports/write.jl") diff --git a/src/docs/reports.md b/src/docs/reports.md index 11f4774..8f7090d 100644 --- a/src/docs/reports.md +++ b/src/docs/reports.md @@ -6,15 +6,13 @@ In this page, we also illustrate what types of charts and visualizations can be ## Plants report -Report showing plant costs, capacities, energy expenditure and utilization factors. - -Generated by `RELOG.write_plants_report(solution, filename)`. For a concrete example, see [nimh_plants.csv](https://github.com/ANL-CEEESA/RELOG/blob/master/test/fixtures/nimh_plants.csv). +Report showing plant costs, capacities, energy expenditure and utilization factors. Generated by `RELOG.write_plants_report(solution, filename)`. | Column | Description |:--------------------------------------|---------------| | `plant type` | Plant type. | `location name` | Location name. -| `year` | What year this row corresponds to. This reports includes one row for each year in the simulation. +| `year` | What year this row corresponds to. This reports includes one row for each year. | `latitude (deg)` | Latitude of the plant. | `longitude (deg)` | Longitude of the plant. | `capacity (tonne)` | Capacity of the plant at this point in time. @@ -72,16 +70,14 @@ gp.GeoDataFrame(data, geometry=points).plot(ax=ax); ## Plant outputs report -Report showing amount of products produced, sent and disposed of by each plant, as well as disposal costs. - -Generated by `RELOG.write_plant_outputs_report(solution, filename)`. For a concrete example, see [nimh_plant_outputs.csv](https://github.com/ANL-CEEESA/RELOG/blob/master/test/fixtures/nimh_plant_outputs.csv). +Report showing amount of products produced, sent and disposed of by each plant, as well as disposal costs. Generated by `RELOG.write_plant_outputs_report(solution, filename)`. | Column | Description |:--------------------------------------|---------------| | `plant type` | Plant type. | `location name` | Location name. -| `year` | What year this row corresponds to. This reports includes one row for each year in the simulation. +| `year` | What year this row corresponds to. This reports includes one row for each year. | `product name` | Product being produced. | `amount produced (tonne)` | Amount of product produced this year. | `amount sent (tonne)` | Amount of product produced by this plant and sent to another plant for further processing this year. @@ -110,9 +106,7 @@ sns.barplot(x="amount produced (tonne)", ## Plant emissions report -Report showing amount of emissions produced by each plant. - -Generated by `RELOG.write_plant_emissions_report(solution, filename)`. For a concrete example, see [nimh_plant_emissions.csv](https://github.com/ANL-CEEESA/RELOG/blob/master/test/fixtures/nimh_plant_emissions.csv). +Report showing amount of emissions produced by each plant. Generated by `RELOG.write_plant_emissions_report(solution, filename)`. | Column | Description |:--------------------------------------|---------------| @@ -141,11 +135,24 @@ sns.barplot(x="plant type", -## Transportation report +## Products report -Report showing amount of product sent from initial locations to plants, and from one plant to another. Includes the distance between each pair of locations, amount-distance shipped, transportation costs and energy expenditure. +Report showing primary product amounts, locations and marginal costs. Generated by `RELOG.write_products_report(solution, filename)`. -Generated by `RELOG.write_transportation_report(solution, filename)`. For a concrete example, see [nimh_transportation.csv](https://github.com/ANL-CEEESA/RELOG/blob/master/test/fixtures/nimh_transportation.csv). +| Column | Description +|:--------------------------------------|---------------| +| `product name` | Product name. +| `location name` | Name of the collection center. +| `latitude (deg)` | Latitude of the collection center. +| `longitude (deg)` | Longitude of the collection center. +| `year` | What year this row corresponds to. This reports includes one row for each year. +| `amount (tonne)` | Amount of product available at this collection center. +| `marginal cost ($/tonne)` | Cost to process one additional tonne of this product coming from this collection center. + + +## Transportation report + +Report showing amount of product sent from initial locations to plants, and from one plant to another. Includes the distance between each pair of locations, amount-distance shipped, transportation costs and energy expenditure. Generated by `RELOG.write_transportation_report(solution, filename)`. | Column | Description @@ -231,9 +238,7 @@ gp.GeoDataFrame(data, geometry=points).plot(ax=ax, ## Transportation emissions report -Report showing emissions for each trip between initial locations and plants, and between pairs of plants. - -Generated by `RELOG.write_transportation_emissions_report(solution, filename)`. For a concrete example, see [nimh_transportation_emissions.csv](https://github.com/ANL-CEEESA/RELOG/blob/master/test/fixtures/nimh_transportation_emissions.csv). +Report showing emissions for each trip between initial locations and plants, and between pairs of plants. Generated by `RELOG.write_transportation_emissions_report(solution, filename)`. | Column | Description |:--------------------------------------|---------------| diff --git a/src/model/getsol.jl b/src/model/getsol.jl index 92c2e16..a368c47 100644 --- a/src/model/getsol.jl +++ b/src/model/getsol.jl @@ -45,6 +45,9 @@ function get_solution(model::JuMP.Model; marginal_costs = true) "Marginal cost (\$/tonne)" => [ round(abs(JuMP.shadow_price(model[:eq_balance][n, t])), digits = 2) for t = 1:T ], + "Latitude (deg)" => n.location.latitude, + "Longitude (deg)" => n.location.longitude, + "Amount (tonne)" => n.location.amount, ) if n.product.name ∉ keys(output["Products"]) output["Products"][n.product.name] = OrderedDict() diff --git a/src/reports/products.jl b/src/reports/products.jl new file mode 100644 index 0000000..0c5f322 --- /dev/null +++ b/src/reports/products.jl @@ -0,0 +1,43 @@ +# RELOG: Reverse Logistics Optimization +# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved. +# Released under the modified BSD license. See COPYING.md for more details. + +using DataFrames +using CSV + +function products_report(solution; marginal_costs = true)::DataFrame + df = DataFrame() + df."product name" = String[] + df."location name" = String[] + df."latitude (deg)" = Float64[] + df."longitude (deg)" = Float64[] + df."year" = Int[] + df."amount (tonne)" = Float64[] + df."marginal cost (\$/tonne)" = Float64[] + T = length(solution["Energy"]["Plants (GJ)"]) + for (prod_name, prod_dict) in solution["Products"] + for (location_name, location_dict) in prod_dict + for year = 1:T + marginal_cost = location_dict["Marginal cost (\$/tonne)"][year] + latitude = round(location_dict["Latitude (deg)"], digits = 6) + longitude = round(location_dict["Longitude (deg)"], digits = 6) + amount = location_dict["Amount (tonne)"][year] + push!( + df, + [ + prod_name, + location_name, + latitude, + longitude, + year, + amount, + marginal_cost, + ], + ) + end + end + end + return df +end + +write_products_report(solution, filename) = CSV.write(filename, products_report(solution)) diff --git a/test/reports_test.jl b/test/reports_test.jl index 28031d5..684a4cf 100644 --- a/test/reports_test.jl +++ b/test/reports_test.jl @@ -9,10 +9,11 @@ using RELOG, JSON, GZip solution = RELOG.solve("$(pwd())/../instances/s1.json") tmp_filename = tempname() # The following should not crash - RELOG.write_plants_report(solution, tmp_filename) - RELOG.write_plant_outputs_report(solution, tmp_filename) RELOG.write_plant_emissions_report(solution, tmp_filename) - RELOG.write_transportation_report(solution, tmp_filename) + RELOG.write_plant_outputs_report(solution, tmp_filename) + RELOG.write_plants_report(solution, tmp_filename) + RELOG.write_products_report(solution, tmp_filename) RELOG.write_transportation_emissions_report(solution, tmp_filename) + RELOG.write_transportation_report(solution, tmp_filename) end end