diff --git a/DESCRIPTION b/DESCRIPTION index 462c7ed..a6f6ee4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: mrprom Type: Package Title: Functions for generating input data for OPEN-PROM -Version: 1.27.4 +Version: 1.27.5 Author: Anastasis Giannousakis, Fotis Sioutas, Giannis Tolios, Michael Madianos, Alexandros Tsimpoukis, Songmin Yu Maintainer: Fotis Sioutas Description: mrprom can be run standalone or (preferably) in diff --git a/R/fullOPEN-PROM.R b/R/fullOPEN-PROM.R index a5ea316..7c1e28f 100644 --- a/R/fullOPEN-PROM.R +++ b/R/fullOPEN-PROM.R @@ -209,8 +209,11 @@ fullOPEN_PROM <- function() { x <- calcOutput("IFuelPrice", aggregate = FALSE) # POP is weights for aggregation, perform aggregation x <- toolAggregate(x, weight = POP, rel = map, from = "ISO3.Code", to = "Region.Code") + # Replace existing BMSWAS keys with annual regional MAgPIE prices. + # The source is kUSD2015/toe; toolReplaceBMSWASPrice converts it back to + # IFuelPrice's USD2015/toe before this file is written. + xq <- toolReplaceBMSWASPrice(x) # write input data file that GAMS can read - xq <- as.quitte(x) xq <- xq[!is.na(xq[["value"]]), ] %>% select(c("period", "value", "region", "variable", "new")) %>% # nolint pivot_wider(names_from = "period") # nolint diff --git a/R/readMAgPIE_BMSWAS_Price.R b/R/readMAgPIE_BMSWAS_Price.R new file mode 100644 index 0000000..f93c51b --- /dev/null +++ b/R/readMAgPIE_BMSWAS_Price.R @@ -0,0 +1,82 @@ +#' readMAgPIE_BMSWAS_Price +#' +#' Read annual regional bioenergy prices prepared from a MAgPIE report for use +#' as OPEN-PROM's historical BMSWAS fuel price. The source file is already in +#' OPEN-PROM region and subsector space and uses kUSD2015/toe. +#' +#' @return The MAgPIE BMSWAS price data as a magpie object. +#' +#' @author Songmin Yu +#' +#' @examples +#' \dontrun{ +#' x <- readSource("MAgPIE_BMSWAS_Price") +#' } +#' +#' @importFrom quitte as.quitte +#' @importFrom magclass as.magpie +#' @importFrom tidyr pivot_longer +#' @importFrom utils read.csv +#' +readMAgPIE_BMSWAS_Price <- function() { + sourceFile <- "iPrices_magpie.csv" + x <- read.csv(sourceFile, check.names = FALSE) + + if (ncol(x) < 3) { + stop(sourceFile, " must contain region, SBS, and annual price columns") + } + + names(x)[1:2] <- c("region", "variable") + yearColumns <- names(x)[-(1:2)] + expectedYears <- as.character(2010:2100) + + if (!identical(yearColumns, expectedYears)) { + stop(sourceFile, " must contain annual columns 2010 through 2100 in order") + } + if (nrow(x) != 39 * 34 || length(unique(x$region)) != 39 || + length(unique(x$variable)) != 34) { + stop(sourceFile, " must contain exactly 39 regions x 34 SBS rows") + } + if (anyDuplicated(x[c("region", "variable")])) { + stop(sourceFile, " contains duplicate region-SBS keys") + } + + priceMatrix <- as.matrix(x[yearColumns]) + storage.mode(priceMatrix) <- "numeric" + if (anyNA(priceMatrix) || any(!is.finite(priceMatrix)) || any(priceMatrix < 0)) { + stop(sourceFile, " contains missing, non-finite, or negative prices") + } + + regionVariation <- vapply( + split(seq_len(nrow(x)), x$region), + function(rows) max(apply(priceMatrix[rows, , drop = FALSE], 2, function(v) max(v) - min(v))), + numeric(1) + ) + if (any(regionVariation > 1e-12)) { + stop(sourceFile, " contains subsector-varying prices within a region") + } + + x <- tidyr::pivot_longer( + x, + cols = all_of(yearColumns), + names_to = "period", + values_to = "value" + ) + x$period <- as.integer(x$period) + x$unit <- "kUSD2015/toe" + x <- as.quitte(x) %>% as.magpie() + + list( + x = x, + weight = NULL, + description = c( + category = "Costs", + type = "MAgPIE bioenergy price for OPEN-PROM BMSWAS", + filename = sourceFile, + `Indicative size (MB)` = 1.2, + dimensions = "3D", + unit = "kUSD2015/toe", + Confidential = "project" + ) + ) +} diff --git a/R/toolReplaceBMSWASPrice.R b/R/toolReplaceBMSWASPrice.R new file mode 100644 index 0000000..e6d5af4 --- /dev/null +++ b/R/toolReplaceBMSWASPrice.R @@ -0,0 +1,57 @@ +#' Replace aggregated BMSWAS prices with MAgPIE prices +#' +#' Replaces only existing BMSWAS region-SBS-year values. The MAgPIE source is +#' expressed in kUSD2015/toe, while IFuelPrice is written in USD2015/toe. +#' +#' @param x Regionally aggregated IFuelPrice magpie object. +#' +#' @return IFuelPrice as a quitte data frame with BMSWAS values replaced. +#' +#' @importFrom madrat readSource +#' @importFrom quitte as.quitte +#' +toolReplaceBMSWASPrice <- function(x) { + fuelPrices <- as.quitte(x) + requiredColumns <- c("region", "variable", "new", "period", "value") + if (!all(requiredColumns %in% names(fuelPrices))) { + stop("Aggregated IFuelPrice is missing required dimensions") + } + + magpiePrices <- as.quitte(readSource("MAgPIE_BMSWAS_Price")) + if (!all(c("region", "variable", "period", "unit", "value") %in% names(magpiePrices))) { + stop("MAgPIE BMSWAS price source is missing required dimensions") + } + if (!identical(unique(as.character(magpiePrices$unit)), "kUSD2015/toe")) { + stop("MAgPIE BMSWAS prices must use kUSD2015/toe") + } + + magpieKey <- paste(magpiePrices$region, magpiePrices$variable, magpiePrices$period, sep = "\r") + if (anyDuplicated(magpieKey)) { + stop("MAgPIE BMSWAS price source contains duplicate region-SBS-year keys") + } + + replaceRows <- fuelPrices$new == "BMSWAS" + if (!any(replaceRows)) { + stop("Aggregated IFuelPrice contains no BMSWAS values to replace") + } + if (!identical(unique(as.character(fuelPrices$unit[replaceRows])), "USD2015/toe")) { + stop("IFuelPrice BMSWAS values must use USD2015/toe before replacement") + } + targetKey <- paste( + fuelPrices$region[replaceRows], + fuelPrices$variable[replaceRows], + fuelPrices$period[replaceRows], + sep = "\r" + ) + sourceRows <- match(targetKey, magpieKey) + if (anyNA(sourceRows)) { + missingKeys <- unique(targetKey[is.na(sourceRows)]) + stop( + "MAgPIE BMSWAS prices do not cover all existing IFuelPrice keys; first missing key: ", + missingKeys[[1]] + ) + } + + fuelPrices$value[replaceRows] <- magpiePrices$value[sourceRows] * 1000 + fuelPrices +} diff --git a/man/readMAgPIE_BMSWAS_Price.Rd b/man/readMAgPIE_BMSWAS_Price.Rd new file mode 100644 index 0000000..50c13f8 --- /dev/null +++ b/man/readMAgPIE_BMSWAS_Price.Rd @@ -0,0 +1,25 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/readMAgPIE_BMSWAS_Price.R +\name{readMAgPIE_BMSWAS_Price} +\alias{readMAgPIE_BMSWAS_Price} +\title{readMAgPIE_BMSWAS_Price} +\usage{ +readMAgPIE_BMSWAS_Price() +} +\value{ +The MAgPIE BMSWAS price data as a magpie object. +} +\description{ +Read annual regional bioenergy prices prepared from a MAgPIE report for use +as OPEN-PROM's historical BMSWAS fuel price. The source file is already in +OPEN-PROM region and subsector space and uses kUSD2015/toe. +} +\examples{ +\dontrun{ +x <- readSource("MAgPIE_BMSWAS_Price") +} + +} +\author{ +Songmin Yu +} diff --git a/man/toolReplaceBMSWASPrice.Rd b/man/toolReplaceBMSWASPrice.Rd new file mode 100644 index 0000000..e3c0e93 --- /dev/null +++ b/man/toolReplaceBMSWASPrice.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/toolReplaceBMSWASPrice.R +\name{toolReplaceBMSWASPrice} +\alias{toolReplaceBMSWASPrice} +\title{Replace aggregated BMSWAS prices with MAgPIE prices} +\usage{ +toolReplaceBMSWASPrice(x) +} +\arguments{ +\item{x}{Regionally aggregated IFuelPrice magpie object.} +} +\value{ +IFuelPrice as a quitte data frame with BMSWAS values replaced. +} +\description{ +Replaces only existing BMSWAS region-SBS-year values. The MAgPIE source is +expressed in kUSD2015/toe, while IFuelPrice is written in USD2015/toe. +}