From e1076d9b7274403179f071d7914cb4686b8164eb Mon Sep 17 00:00:00 2001 From: Ben Young Date: Thu, 1 Aug 2024 11:44:51 -0400 Subject: [PATCH] replace `Q_t` with `M_m`, #303 --- R/CalculationFunctions.R | 33 +++++++--------------------- R/ExternalImportFactors.R | 35 ++++++++++++------------------ R/ValidateModel.R | 8 +++---- format_specs/Model.md | 3 ++- format_specs/ModelCustomization.md | 10 +++++++++ format_specs/ModelSpecification.md | 1 + man/loadExternalImportFactors.Rd | 2 +- 7 files changed, 40 insertions(+), 52 deletions(-) diff --git a/R/CalculationFunctions.R b/R/CalculationFunctions.R index 3a56e672..e659489b 100644 --- a/R/CalculationFunctions.R +++ b/R/CalculationFunctions.R @@ -143,8 +143,8 @@ calculateResultsWithExternalFactors <- function(model, perspective = "FINAL", de # parentheses used to denote (domestic) and (import) components r1 <- model$B %*% model$L_d %*% diag(as.vector(y_d)) - r2 <- model$Q_t %*% model$A_m %*% model$L_d %*% diag(as.vector(y_d)) - r3 <- model$Q_t %*% diag(as.vector(y_m)) + r2 <- model$M_m %*% model$A_m %*% model$L_d %*% diag(as.vector(y_d)) + r3 <- model$M_m %*% diag(as.vector(y_m)) if (use_domestic_requirements) { result$LCI_f <- r1 @@ -157,8 +157,8 @@ calculateResultsWithExternalFactors <- function(model, perspective = "FINAL", de result$LCI_f <- t(result$LCI_f) result$LCIA_f <- t(result$LCIA_f) - colnames(result$LCI_f) <- rownames(model$Q_t) - rownames(result$LCI_f) <- colnames(model$Q_t) + colnames(result$LCI_f) <- rownames(model$M_m) + rownames(result$LCI_f) <- colnames(model$M_m) colnames(result$LCIA_f) <- rownames(model$D) rownames(result$LCIA_f) <- colnames(model$D) @@ -174,8 +174,8 @@ calculateResultsWithExternalFactors <- function(model, perspective = "FINAL", de s <- getScalingVector(model$L_d, y_d) r1 <- calculateDirectPerspectiveLCI(model$B, s) # Domestic emissions from domestic production - r2 <- calculateDirectPerspectiveLCI(model$Q_t, (model$A_m %*% model$L_d %*% y_d)) # Emissions from imported goods consumed as intermediate products - r3 <- t(model$Q_t %*% diag(as.vector(y_m))) # Emissions from imported goods consumed as final products + r2 <- calculateDirectPerspectiveLCI(model$M_m, (model$A_m %*% model$L_d %*% y_d)) # Emissions from imported goods consumed as intermediate products + r3 <- t(model$M_m %*% diag(as.vector(y_m))) # Emissions from imported goods consumed as final products if (use_domestic_requirements) { result$LCI_d <- r1 @@ -183,30 +183,13 @@ calculateResultsWithExternalFactors <- function(model, perspective = "FINAL", de result$LCI_d <- r1 + r2 + r3 } - # # Alternate approach for calculating Direct LCI for IF - # # Attempting to duplicate calculateDirectPerspectiveLCI for IF models - # econTermOne <- model$L_d %*% y_d - # econTermTwo <- model$A_m %*% model$L_d %*% y_d - # econTermThree <- y_m - # directLCIOne <- model$B %*% diag(as.vector(econTermOne)) - # directLCITwo <- model$Q_t %*% diag(as.vector(econTermTwo)) - # directLCIThree <- model$Q_t %*% diag(as.vector(econTermThree)) - # directLCITotal <- directLCIOne + directLCITwo + directLCIThree - # directLCITotal <- t(directLCITotal) - # result$LCI_d <- directLCITotal - # colnames(result$LCI_d) <- rownames(model$Q_t) - # rownames(result$LCI_d) <- colnames(model$Q_t) - # # Compare column sums from this approach with column sums from final perspective approach: - # LCI_f <- t((model$B %*% model$L_d %*% y_d) + (model$Q_t %*% model$A_m %*% model$L_d %*% y_d + model$Q_t %*% y_m)) - # colSums(LCI_f) / colSums(directLCITotal) - # Calculate Direct Perspective LCIA (matrix with direct impacts in form of sector x impacts) logging::loginfo("Calculating Direct Perspective LCIA with external import factors...") result$LCIA_d <- model$C %*% t(result$LCI_d) result$LCIA_d <- t(result$LCIA_d) - colnames(result$LCI_d) <- rownames(model$Q_t) - rownames(result$LCI_d) <- colnames(model$Q_t) + colnames(result$LCI_d) <- rownames(model$M_m) + rownames(result$LCI_d) <- colnames(model$M_m) colnames(result$LCIA_d) <- rownames(model$D) rownames(result$LCIA_d) <- colnames(model$D) diff --git a/R/ExternalImportFactors.R b/R/ExternalImportFactors.R index 0d92e661..06119e87 100644 --- a/R/ExternalImportFactors.R +++ b/R/ExternalImportFactors.R @@ -4,18 +4,18 @@ #' @param model An EEIO form USEEIO model object with model specs loaded #' @param configpaths str vector, paths (including file name) of model configuration file. #' If NULL, built-in config files are used. -#' @return Q_t, matrix of import coefficients (flow x sector). +#' @return M_m, matrix of import coefficients (flow x sector). loadExternalImportFactors <- function(model, configpaths = NULL) { IFTable <- readImportFactorTable(IFSpec=model$specs$ImportFactors, configpaths=configpaths) IFTable <- processImportFactors(model, IFTable) - Q_t <- standardizeandcastSatelliteTable(IFTable, model) + M_m <- standardizeandcastSatelliteTable(IFTable, model) # standardizeandcast prepares df for industries, convert to commodities - Q_t[, setdiff(model$Commodities$Code_Loc, colnames(Q_t))] <- 0 + M_m[, setdiff(model$Commodities$Code_Loc, colnames(M_m))] <- 0 # Adjust column order to be the same with V_n rownames - Q_t <- Q_t[, model$Commodities$Code_Loc] - Q_t <- as.matrix(Q_t) + M_m <- M_m[, model$Commodities$Code_Loc] + M_m <- as.matrix(M_m) - return(Q_t) + return(M_m) } #' Load and prepare import coefficients @@ -85,15 +85,8 @@ processImportFactors <- function(model, IFTable) { #' and optional agg/disagg configuration file(s). If NULL, built-in config files are used. #' @return A model object with explicit import components. buildModelwithImportFactors <- function(model, configpaths = NULL) { - # Deriving the economic component of the Swedish equation (see Palm et al. 2019) for import factors: - # f^(d+m) = s^d*L^d*y^d + Q^t*A^m*L^d*y^d + Q^t*y^m + f^h - # s^d are the domestic direct environmental coefficients, and Q are the environmental import multipliers, s_m*L_m. Dropping s_d and s_m we get - # x^(d+m) = s^d*L^d*y^d + L^m*A^m*L^d*y^d + L^m*y^m + f^h - # Since f^h is not currently part of the useeior model calculations, we drop it: - # x^(d+m) = L^d*y^d + L^m*A^m*L^d*y^d + L^m*y^m - # The resulting expression should be equivalent to the x = L*y such that - # x^(d+m) = x = L*y - + # (see Palm et al. 2019) + logging::loginfo("Building Import A (A_m) accounting for ITA in Domestic FD.\n") # Re-derive import values in Use and final demand # _m denotes import-related structures @@ -111,14 +104,14 @@ buildModelwithImportFactors <- function(model, configpaths = NULL) { logging::loginfo("Calculating M_d matrix (total emissions and resource use per dollar from domestic activity)...") model$M_d <- model$B %*% model$L_d - logging::loginfo("Calculating Q_t matrix (total emissions and resource use per dollar from imported activity)...") - Q_t <- loadExternalImportFactors(model, configpaths) + logging::loginfo("Calculating M_m matrix (total emissions and resource use per dollar from imported activity)...") + M_m <- loadExternalImportFactors(model, configpaths) - # Fill in flows for Q_t not found in Import Factors but that exist in model and align order - Q_t <- rbind(Q_t, model$M_d[setdiff(rownames(model$M_d), rownames(Q_t)),]) - Q_t <- Q_t[rownames(model$M_d), ] + # Fill in flows for M_m not found in Import Factors but that exist in model and align order + M_m <- rbind(M_m, model$M_d[setdiff(rownames(model$M_d), rownames(M_m)),]) + M_m <- M_m[rownames(model$M_d), ] - model$Q_t <- Q_t + model$M_m <- M_m return(model) } diff --git a/R/ValidateModel.R b/R/ValidateModel.R index 019c64b4..d8c3a6e8 100644 --- a/R/ValidateModel.R +++ b/R/ValidateModel.R @@ -404,7 +404,7 @@ compareOutputfromMakeandUse <- function(model, output_type = "Commodity") { #' @param demand, A demand vector, has to be name of a built-in model demand vector, e.g. "Production" or "Consumption". Consumption used as default. #' @return A calculated direct requirements table validateImportFactorsApproach <- function(model, demand = "Consumption"){ - if(is.null(model$Q_t)) { + if(is.null(model$M_m)) { return() } @@ -451,12 +451,12 @@ validateImportFactorsApproach <- function(model, demand = "Consumption"){ # Calculate LCI using coupled model approach # Revised equation from RW email (2023-11-01): # LCI <- (s_d * L_d * Y_d) + (s*L*A_m*L_d*Y_d + s*L*Y_m). I.e., s in RW email is analogous to model$B - # For validation, we use M as a stand-in for import emissions , whereas in normally we'd be using model$Q_t + # For validation, we use M as a stand-in for import emissions , whereas in normally we'd be using model$M_m LCI_dm <- (model$M_d %*% y_d) + (M %*% model$A_m %*% model$L_d %*% y_d + M %*% y_m) cat("\nTesting that LCI results are equivalent between standard and coupled model approaches (i.e., LCI = LCI_dm) when\n") - cat("assuming model$M = model$Q_t.\n") + cat("assuming model$M = model$M_m.\n") print(all.equal(LCI, LCI_dm)) # Calculate LCIA using standard approach @@ -475,7 +475,7 @@ validateImportFactorsApproach <- function(model, demand = "Consumption"){ rownames(LCIA_dm) <- colnames(model$N_m) cat("\nTesting that LCIA results are equivalent between standard and coupled model approaches (i.e., LCIA = LCIA_dm) when\n") - cat("assuming model$M = model$Q_t.\n") + cat("assuming model$M = model$M_m.\n") print(all.equal(LCIA_dm, LCIA)) } diff --git a/format_specs/Model.md b/format_specs/Model.md index 21ffc879..2825c8d0 100644 --- a/format_specs/Model.md +++ b/format_specs/Model.md @@ -57,12 +57,12 @@ Items are listed in the order in which they appear in a built Model object in R. | D | matrix | result matrix | [The direct impact matrix](#D) | | M | matrix | result matrix | [The total emissions and resource use matrix](#M) | | M_d | matrix | result matrix | [The total emissions and resource use (from and by domestic activity) matrix](#M) | +| M_m| matrix | component matrix | [The total emissions and resource use from imported activity matrix](#M) | | N | matrix | result matrix | [The total impact matrix](#N) | | N_d | matrix | result matrix | [The total impact (from domestic activity) matrix](#N) | | Rho | matrix | component matrix | [The CPI1 price year ratio matrix for a given model](#Rho)| | Phi | matrix | component matrix | [The producer-to-purchaser price ratio matrix for a given model](#Phi)| | Tau | matrix | component matrix | [The basic-to-producer price ratio matrix for a given model](#Tau)| -| Q_t| matrix | component matrix | [The total emissions and resource use from imported activity matrix](#Q_t) | 1 Chain-type Price Index @@ -386,6 +386,7 @@ flows | | ``` The related `M_d` matrix provides direct + indirect emissions and resources per dollar output that are only from the US. +While the `M_m` matrix provides direct + indirect emissions and resources per dollar of imported goods if a model is built with [ExternalImportFactors](ModelSpecification.md). #### N The matrix `N` is a `indicator x sector` matrix and contains in each column diff --git a/format_specs/ModelCustomization.md b/format_specs/ModelCustomization.md index a286aa22..ca86f825 100644 --- a/format_specs/ModelCustomization.md +++ b/format_specs/ModelCustomization.md @@ -154,3 +154,13 @@ Unit | str | Y | | WIO Section | str | N | | Note | string | N | | +## Import Emission Factors + +Specifications for import emission factors file, e.g., + +``` +ImportFactors: + StaticFile: "useeior/US_summary_import_factors_exio_2019_17sch.csv" + FileLocation: "DataCommons" +``` + diff --git a/format_specs/ModelSpecification.md b/format_specs/ModelSpecification.md index 3324a24c..ba3c4f03 100644 --- a/format_specs/ModelSpecification.md +++ b/format_specs/ModelSpecification.md @@ -19,6 +19,7 @@ Model specifications are assigned in a yml file based on the parameters shown be | HybridizationSpecs | str | N | The [hybridization specifications](ModelCustomization.md#hybridization-file-specification) | | MUIOSpecs | str | N | The [mixed unit hybridization specifications](ModelCustomization.md#mixed-unit-file-specification) | | WIOSpecs | str | N | The [waste input output specifications](ModelCustomization.md#waste-input-output-file-specification) | +| ExternalImportFactors | bool | N | Whether the model includes specifications for [Import Emission Factors](ModelCustomization.md#import-emission-factors) | | SatelliteTable | list | | The [satellite table specifications](#Satellite-Table-Specifications) | | Indicators | list | N | The [indicator specifications](#Indicator-Specifications) | | DemandVectors | list | | The [demand vector specifications](#Demand-Vector-Specifications) | diff --git a/man/loadExternalImportFactors.Rd b/man/loadExternalImportFactors.Rd index 3af3b5ce..738195e4 100644 --- a/man/loadExternalImportFactors.Rd +++ b/man/loadExternalImportFactors.Rd @@ -13,7 +13,7 @@ loadExternalImportFactors(model, configpaths = NULL) If NULL, built-in config files are used.} } \value{ -Q_t, matrix of import coefficients (flow x sector). +M_m, matrix of import coefficients (flow x sector). } \description{ Load and prepare import coefficients