R/readGCPT.R

Defines functions readGCPT

Documented in readGCPT

#' Data from the Global Coal Plant Tracker January 2021 release by Global Energy Monitor (formerly EndCoal/CoalSwarm)
#' @description  Historical data of operating, under-construction, planned and announced Coal Plants by country (in MW)
#' from the Global Energy Monitor's Global Coal Plant Tracker, and extrapolations for 2025 capacity scenarios
#' @param subtype Options are status, historical, future, lifespans, comp_rates and emissions
#' @author Stephen Bi
#' @importFrom readxl read_excel
#' @importFrom dplyr filter select mutate summarize group_by left_join across everything starts_with
#' @importFrom quitte removeColNa
#' @aliases readEndCoal


readGCPT <- function(subtype) {

  if (!(subtype %in% c("early_retire", "historical", "status", "future",
                       "lifespans", "emissions", "comp_rates", "reg_comp_rates",
                       "glo_comp_rates", "meanAge", "ppca_emi", "G20_FinEx",
                       "PEGASOS", "PEGASOS_pubfinex", "PEGASOS_prefinex",
                       "REM_PEGASOS_pubfinex", "REM_PEGASOS_pubfinex_REsub"))) {
    stop("Invalid subtype!")
  }

  `Announced + Pre-permit + Permitted` <- NULL
  . <- NULL
  Country <- NULL
  CountryCode <- NULL
  MW <- NULL
  `Plant Age` <- NULL
  `Capacity (MW)` <- NULL
  Status <- NULL
  RETIRED <- NULL
  `Planned Retire` <- NULL
  Avg_Ret_Age <- NULL
  `Heat rate` <- NULL
  `Emission factor` <- NULL
  `Combustion technology` <- NULL
  Year <- NULL
  Period <- NULL
  Cap_Factor <- NULL
  green_5yr_emi <- NULL
  bau_5yr_emi <- NULL
  brown_5yr_emi <- NULL
  norm_5yr_emi <- NULL
  BAU_emi <- NULL
  Value <- NULL
  brown_emi <- NULL
  green_emi <- NULL
  norm_emi <- NULL

  map <- toolGetMapping(getConfig("regionmapping"), type = "regional", where = "mappingfolder")

  # Data files to be read in
  summary_data <- "GCPT_data_Jan2023.xlsx"
  status_changes <- "Jan 2023 GCPT Status Changes - 2014 - 2022 (final).csv"
  plant_data <- "Global-Coal-Plant-Tracker-January-2023.xlsx"
  lastCol <- "X"
  sep <- ";"
  latest_col <- 3

  plant_status <- read.csv2(status_changes, sep = sep, stringsAsFactors = FALSE, fileEncoding = "ISO-8859-13")

  plant_status <- plant_status %>%
    select(Country, MW, starts_with("H2")) %>%
    mutate("Country" = ifelse(grepl("rkiye", Country), "Turkey", Country),
           "Country" = ifelse(grepl("Ivoire", Country), "Cote d'Ivoire", Country),
           "MW" = as.numeric(MW))

  colnames(plant_status)[3:ncol(plant_status)] <- as.numeric(gsub("H2.", "", colnames(plant_status)[3:ncol(plant_status)]))

  present_year <- as.numeric(substr(summary_data, nchar(summary_data) - 8, nchar(summary_data) - 5))

  # Capacity by country as of January 2022, with select manual updates according
  # to the Global Coal Finance Tracker and news media
  cap_sum <- read_excel(summary_data, sheet = "Summary", range = "A4:K112") %>%
    filter(!grepl("Total", Country) & !grepl("World", Country))

  cap_sum <- cap_sum %>%
    select(-`Announced + Pre-permit + Permitted`)
  cap_sum <- as.magpie(cap_sum, spatial = 1)
  cap_sum <- toolCountryFill(setItems(dim = 1, x = cap_sum,
                                      value = toolCountry2isocode(mapping = c("DR Congo" = "COD"),
                                                                  country = getItems(dim = 1, x = cap_sum))),
                             fill = 0,
                             no_remove_warning = "KOS",
                             verbosity = 2)

  cap_sum_oper <- cap_sum[, , "Operating"]


  ###################################################
  ### Historical capacity additions & retirements ###
  ###################################################

  additions <- read_excel(summary_data, sheet = "Additions", range = c(paste0("A4:", lastCol, "112"))) %>%
    filter(!grepl("Total", Country) & !grepl("World", Country))
  retirements <- read_excel(summary_data, sheet = "Retirements", range = c(paste0("A4:", lastCol, "112"))) %>%
    filter(!grepl("Total", Country) & !grepl("World", Country))
  add_startyr <- as.numeric(colnames(additions)[2])
  add_endyr <- as.numeric(colnames(additions)[length(additions)])


  # Filter for all plants that were mothballed during this period
  mothballed <- plant_status %>%
    filter(rowSums(across(everything(), ~ grepl("Moth", .))) > 0) %>%
    filter(rowSums(across(everything(), ~ grepl("Oper", .))) > 0)

  # Calculate capacity that was mothballed or restarted each year since 2014
  # (to be fed into back-calculation of annual capacity below)
  cap_moth <- new.magpie(getItems(dim = 1, x = cap_sum),
                         years = as.numeric(colnames(additions)[2:length(additions)]),
                         names = c("Operating", "pre_status"), fill = 0)

  for (j in 4:ncol(mothballed)) {

    # Mothballed plants in 2020 which were operating earlier
    oper_moth <- mothballed %>%
      filter(mothballed[, j] == "Operating" & mothballed[, 3] == "Mothballed") %>%
      group_by(Country) %>%
      summarize(sum = sum(MW))

    oper_moth$Country <- toolCountry2isocode(mapping = c("DR Congo" = "COD"), country = oper_moth$Country)

    oper_moth <- suppressWarnings(
      toolCountryFill(as.magpie(oper_moth, spatial = 1, temporal = as.numeric(colnames(mothballed)[j]), datacol = 2),
                      verbosity = 2, fill = 0, no_remove_warning = "KOS")
    )

    # Retired plants in 2020 which were mothballed earlier
    moth_ret <- mothballed %>%
      filter(mothballed[, j] == "Mothballed" & mothballed[, 3] == "Retired") %>%
      group_by(Country) %>%
      summarize(sum = sum(MW))
    moth_ret$Country <- toolCountry2isocode(mapping = c("DR Congo" = "COD"), country = moth_ret$Country)
    moth_ret <- suppressWarnings(
      toolCountryFill(as.magpie(moth_ret, spatial = 1, temporal = as.numeric(colnames(mothballed)[j]), datacol = 2), verbosity = 2, fill = 0, no_remove_warning = "KOS")
    )
    # Operating plants in 2020 which were mothballed earlier
    moth_oper <- mothballed %>%
      filter(mothballed[, j] == "Mothballed" & mothballed[, 3] == "Operating") %>%
      group_by(Country) %>%
      summarize(sum = sum(MW))
    moth_oper$Country <- toolCountry2isocode(mapping = c("DR Congo" = "COD"), country = moth_oper$Country)
    moth_oper <- suppressWarnings(
      toolCountryFill(as.magpie(moth_oper, spatial = 1, temporal = as.numeric(colnames(mothballed)[j]), datacol = 2), verbosity = 2, fill = 0, no_remove_warning = "KOS")
    )

    constr_moth <- mothballed %>%
      filter(mothballed[, 3] == "Mothballed" & mothballed[, j] != "Mothballed" & mothballed[, j] != "Operating") %>%
      group_by(Country) %>%
      summarize(sum = sum(MW))
    constr_moth$Country <- toolCountry2isocode(mapping = c("DR Congo" = "COD"), country = constr_moth$Country)
    constr_moth <- suppressWarnings(
      toolCountryFill(as.magpie(constr_moth, spatial = 1, temporal = as.numeric(colnames(mothballed)[j]), datacol = 2), verbosity = 2, fill = 0, no_remove_warning = "KOS")
    )

    # Annual flux of mothballing/restarting
    cap_moth[, as.numeric(colnames(mothballed)[j]), "Operating"] <- oper_moth + constr_moth - moth_oper - moth_ret
  }

  # Capacity with mothballed status in the first and last year shall be added as operating capacity in years prior to status tracking
  moth_moth <- mothballed %>%
    filter(mothballed[, 3] == "Mothballed" & mothballed[, j] == "Mothballed") %>%
    group_by(Country) %>%
    summarize(sum = sum(MW))

  moth_moth$Country <- toolCountry2isocode(mapping = c("DR Congo" = "COD"), country = moth_moth$Country)
  moth_moth <- suppressWarnings(
    toolCountryFill(as.magpie(moth_moth, spatial = 1, temporal = as.numeric(colnames(mothballed)[j]), datacol = 2), verbosity = 2, fill = 0, no_remove_warning = "KOS")
  )
  cap_moth[, add_startyr:(as.numeric(colnames(mothballed)[j]) - 1), "pre_status"] <- oper_moth + constr_moth + moth_moth

  # Back-calculate annual capacity by adding retired and mothballed plants and subtracting added plants each year
  cap <- new.magpie(getItems(dim = 1, x = cap_sum), years = as.numeric(colnames(additions)[2:length(additions)]), fill = 0)

  for (i in add_startyr:(add_endyr - 1)) {
    cap_add <- additions %>%
      select(Country, as.character(i + 1):as.character(add_endyr)) %>%
      mutate(Operating = rowSums(.[-1])) %>%
      mutate(Country = toolCountry2isocode(mapping = c("DR Congo" = "COD"), country = Country))
    cap_add <- as.magpie(cap_add[, c("Country", "Operating")])
    cap_add <- toolCountryFill(cap_add, verbosity = 2, fill = 0, no_remove_warning = "KOS")
    getItems(cap_add, dim = 2) <- i

    cap_ret <- retirements %>%
      select(Country, as.character(i + 1):as.character(add_endyr)) %>%
      mutate(Operating = rowSums(.[-1])) %>%
      mutate(Country = toolCountry2isocode(mapping = c("DR Congo" = "COD"), country = Country))
    cap_ret <- as.magpie(cap_ret[, c("Country", "Operating")])
    cap_ret <- toolCountryFill(cap_ret, verbosity = 2, fill = 0, no_remove_warning = "KOS")
    getItems(cap_ret, dim = 2) <- i

    cap[, i, ] <- cap_sum[, , "Operating"] - cap_add[, , "Operating"] + cap_ret[, , "Operating"] + cap_moth[, i, "Operating"] + cap_moth[, i, "pre_status"]
  }
  cap[, add_endyr, ] <- cap_sum_oper

  if (grepl("historical", subtype)) {
    return(cap / 1000)
  } else if (grepl("status", subtype)) {
    return(cap_sum / 1000)
  }

  # Plant-level data detailing capacities, commissioning and retirement dates, location and more.
  retire <- suppressWarnings(read_excel(plant_data, sheet = 2))
  retire$`Capacity (MW)` <- as.numeric(retire$`Capacity (MW)`)
  retire$`Planned Retire` <- suppressWarnings(as.numeric(retire$`Planned Retire`))
  retire$Country <- toolCountry2isocode(mapping = c("DR Congo" = "COD"), country = retire$Country)
  retire <- retire[-which(retire$Country == "KOS"), ]
  if (present_year != 2020) {
    retire <- retire %>%
      mutate(
        `Plant Age` =
          ifelse(is.na(Year),
            NA,
            ifelse(grepl("retire", Status, ignore.case = TRUE),
              ifelse(is.na(RETIRED),
                NA,
                RETIRED - Year
              ),
              present_year - Year
            )
          )
      )
  }

  retAge <- retire %>%
    select(Country, `Plant Age`, `Capacity (MW)`, Status) %>%
    filter(Status %in% c("Retired", "retired")) %>%
    filter(!is.na(`Plant Age`)) %>%
    filter(`Plant Age` > 0) %>%
    filter(!is.na(`Capacity (MW)`))

  avgRetAge <- retAge %>%
    group_by(Country) %>%
    summarise(Avg_Ret_Age = weighted.mean(`Plant Age`, `Capacity (MW)`))
  retCap <- retAge %>%
    group_by(Country) %>%
    summarise(Retired_Cap = sum(`Capacity (MW)`))
  avgRetAge <- avgRetAge[do.call(order, avgRetAge), ]
  retCap <- retCap[do.call(order, retCap), ]

  mavgRetAge <- as.magpie(avgRetAge, spatial = 1)
  mavgRetAge <- toolCountryFill(mavgRetAge, fill = 0, no_remove_warning = "KOS", verbosity = 2)
  retCap <- as.magpie(retCap, spatial = 1)
  retCap <- toolCountryFill(retCap, fill = 0, no_remove_warning = "KOS", verbosity = 2)
  regAvgRetAge <- toolAggregate(mavgRetAge, map, weight = retCap)
  regAvgRetAge[which(regAvgRetAge == 0)] <- mean(regAvgRetAge)
  mavgRetAge[getItems(dim = 1, x = mavgRetAge)[mavgRetAge == 0], , ] <- as.vector(regAvgRetAge[map$RegionCode[which(map$CountryCode %in% getItems(dim = 1, x = mavgRetAge)[mavgRetAge == 0])], , ])

  if (grepl("lifespans", subtype)) {
    return(mavgRetAge)
  } else if (grepl("meanAge", subtype)) {
    meanAge <- retire %>%
      select(Country, `Plant Age`, `Capacity (MW)`, Status) %>%
      filter(Status %in% c("Operating", "operating") & !is.na(`Capacity (MW)`) & !is.na(`Plant Age`))
    meanAge_c <- meanAge %>%
      group_by(Country) %>%
      summarise(meanAge = weighted.mean(`Plant Age`, `Capacity (MW)`))
    meanAge_c <- toolCountryFill(as.magpie(meanAge_c, spatial = 1), fill = 0, verbosity = 2)
    capWeight <- meanAge %>%
      group_by(Country) %>%
      summarise(Capacity = sum(`Capacity (MW)`))
    capWeight <- toolCountryFill(as.magpie(capWeight, spatial = 1), fill = 0, verbosity = 2)
    return(toolAggregate(meanAge_c, map, capWeight))
  }

  # Return national average lifespans to calculate early retirement adjustment factors
  if (grepl("early_retire", subtype)) {
    retired <- retire %>%
      select(Country, `Plant Age`, `Capacity (MW)`, RETIRED) %>%
      left_join(avgRetAge, by = "Country")
    # Sum up capacity retired in each country in each year 2000-2020
    early_ret <- retired %>%
      filter(!is.na(RETIRED) & !is.na(`Plant Age`)) %>%
      filter(`Plant Age` < Avg_Ret_Age) %>%
      group_by(Country, .add = TRUE) %>%
      group_by(RETIRED, .add = TRUE) %>%
      summarise(Retired_cap = sum(`Capacity (MW)`))
    early_ret <- as.magpie(early_ret, spatial = 1, temporal = 2)
    early_ret <- toolCountryFill(early_ret, fill = 0, no_remove_warning = "KOS", verbosity = 0)
    ret_rate <- new.magpie(getItems(dim = 1, x = mavgRetAge), seq(2000, 2015, 5), names = "Early_Retirement", fill = 0)
    for (t in seq(2000, 2015, 5)) {
      ret_rate[, t, ] <- dimSums(early_ret[, t:(t + 5), ], dim = 2) / cap[, t, ]
    }
    ret_rate <- replace_non_finite(ret_rate)
    max_ret <- new.magpie(getItems(dim = 1, x = ret_rate), NULL, names = "Max_Early_Retirement", fill = 0)
    for (reg in getItems(dim = 1, x = ret_rate)) {
      max_ret[reg, , ] <- max(ret_rate[reg, , ])
    }
    return(max_ret)
  }


  # Use the national lifespans to derive scenarios of 2025 coal capacity
  avgRetAge <- data.frame(Country = getItems(dim = 1, x = mavgRetAge), Avg_Ret_Age = array(mavgRetAge))
  retire <- left_join(retire, avgRetAge, by = "Country")

  # Neutral COVID recovery scenario: Countries maintain their historical average lifespans
  retireBAU <- retire %>%
    select(Country, `Planned Retire`, `Plant Age`, `Capacity (MW)`, Status, Avg_Ret_Age) %>%
    filter(Status %in% c("Operating", "operating")) %>%
    filter(`Planned Retire` <= 2028 | `Plant Age` >= (Avg_Ret_Age - 5)) %>%
    filter(!is.na(`Capacity (MW)`)) %>%
    group_by(Country) %>%
    summarise(Retiring_Cap = sum(`Capacity (MW)`))

  retireBAU$Retiring_Cap[which(is.na(retireBAU$Retiring_Cap))] <- 0
  retireBAU <- as.magpie(retireBAU, spatial = 1)
  retireBAU <- toolCountryFill(retireBAU, fill = 0, no_remove_warning = "KOS", verbosity = 2)

  # Brown COVID recovery scenario: Countries extend their average lifespans by 5 years
  retireBrown <- retire %>%
    select(Country, `Planned Retire`, `Plant Age`, `Capacity (MW)`, Status, Avg_Ret_Age) %>%
    filter(Status %in% c("Operating", "operating")) %>%
    filter(`Planned Retire` <= 2028 | `Plant Age` >= (Avg_Ret_Age)) %>%
    filter(!is.na(`Capacity (MW)`)) %>%
    group_by(Country) %>%
    summarise(Retiring_Cap = sum(`Capacity (MW)`))

  retireBrown$Retiring_Cap[which(is.na(retireBrown$Retiring_Cap))] <- 0
  retireBrown <- as.magpie(retireBrown, spatial = 1)
  retireBrown <- toolCountryFill(retireBrown, fill = 0, no_remove_warning = "KOS", verbosity = 2)

  # Green COVID recovery scenario: Countries reduce historical average lifespans by 5 years
  retireGreen <- retire %>%
    select(Country, `Planned Retire`, `Plant Age`, `Capacity (MW)`, Status, Avg_Ret_Age) %>%
    filter(Status %in% c("Operating", "operating")) %>%
    filter(`Planned Retire` <= 2028 | `Plant Age` >= (Avg_Ret_Age - 10)) %>%
    filter(!is.na(`Capacity (MW)`)) %>%
    group_by(Country) %>%
    summarise(Retiring_Cap = sum(`Capacity (MW)`))

  retireGreen$Retiring_Cap[which(is.na(retireGreen$Retiring_Cap))] <- 0
  retireGreen <- as.magpie(retireGreen, spatial = 1)
  retireGreen <- toolCountryFill(retireGreen, fill = 0, no_remove_warning = "KOS", verbosity = 2)

  # Literature norm scenario: Popular choice in literature has been to use a globally uniform 40-yr lifespan
  retireNorm <- retire %>%
    select(Country, `Planned Retire`, `Plant Age`, `Capacity (MW)`, Status, Avg_Ret_Age) %>%
    filter(Status %in% c("Operating", "operating")) %>%
    filter(`Plant Age` >= 35) %>%
    filter(!is.na(`Capacity (MW)`)) %>%
    group_by(Country) %>%
    summarise(Retiring_Cap = sum(`Capacity (MW)`))
  retireNorm$Retiring_Cap[which(is.na(retireNorm$Retiring_Cap))] <- 0
  retireNorm <- as.magpie(retireNorm, spatial = 1)
  retireNorm <- toolCountryFill(retireNorm, fill = 0, no_remove_warning = "KOS", verbosity = 2)


  # Relevant regional mappings and country classifications
  # Current members of PPCA
  PPCAmap <- toolGetMapping("regionmappingPPCA.csv", type = "regional", where = "mappingfolder")
  # Current OECD members
  OECDmap <- toolGetMapping("regionmappingOECD.csv", type = "regional", where = "mappingfolder")
  ppca <- PPCAmap$CountryCode[which(PPCAmap$RegionCode == "PPCA")]
  oecd <- OECDmap$CountryCode[which(OECDmap$RegionCode == "OECD")]
  EU27 <- map$CountryCode[which(map$RegionCode == "EUR")]
  # The PPCA stipulates that OECD and EU members must phase out coal power by 2030
  oecdPPCA <- ppca[which(ppca %in% oecd | ppca %in% EU27)]
  # While non-OECD members must phase out coal power by 2050
  nonOECDppca <- ppca[which(!(ppca %in% oecdPPCA))]
  # There are several countries which have explicit plans to abandon coal power in their COVID recovery packages
  greenNations <- c(EU27[-which(EU27 == "POL")][-which(EU27 %in% ppca)], "EGY", "AUS", "KOR", "CHL")
  if (subtype != "PEGASOS") greenNations <- c(greenNations, "BGD", "PAK", "PHL", "VNM")

  ###########################
  ### ANNUAL PLANT STATUS ###
  ###########################
  # Remove any plants with unknown (NA) capacity from plant status data frame
  plant_status <- plant_status %>%
    filter(!is.na(MW))

  tran <- data.frame(Country = unique(plant_status$Country), shelved = 0, she2she = 0, she2can = 0, she2oper = 0, she2ann = 0, she2pre = 0, pre2she = 0, pre2con = 0,
                     she2perm = 0, she2con = 0, newcon = 0, con2she = 0, con2she2oper = 0, con2she2con = 0, con2she2can = 0, con2can = 0, perm2she = 0, perm2con = 0,
                     con2oper = 0, con2she2she = 0, plan2she = 0, ann = 0, ann2oper = 0, ann2can = 0, ann2she = 0, ann2con = 0, pre = 0, pre2oper = 0, pre2can = 0, perm = 0,
                     perm2oper = 0, perm2can = 0, moth = 0, moth2ret = 0, moth2oper = 0)

  for (i in 1:nrow(plant_status)) {
    j <- ncol(plant_status)
    if (plant_status[i, j] == "XXX") {
      plant_status[i, which(plant_status[i, ] == "XXX")] <- "Announced"
    }
    while (j > latest_col) {
      if (grepl("She", plant_status[i, j])) {
        if (j == ncol(plant_status) || !any(grepl("She", plant_status[i, j:ncol(plant_status)]))) {
          tran$shelved[which(tran$Country == plant_status$Country[i])] <- tran$shelved[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          if (grepl("Can", plant_status[i, latest_col])) {
            tran$she2can[which(tran$Country == plant_status$Country[i])] <- tran$she2can[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("She", plant_status[i, latest_col])) {
            tran$she2she[which(tran$Country == plant_status$Country[i])] <- tran$she2she[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("Oper", plant_status[i, latest_col])) {
            tran$she2oper[which(tran$Country == plant_status$Country[i])] <- tran$she2oper[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("Ann", plant_status[i, latest_col])) {
            tran$she2ann[which(tran$Country == plant_status$Country[i])] <- tran$she2ann[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("Pre", plant_status[i, latest_col])) {
            tran$she2pre[which(tran$Country == plant_status$Country[i])] <- tran$she2pre[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("Perm", plant_status[i, latest_col])) {
            tran$she2perm[which(tran$Country == plant_status$Country[i])] <- tran$she2perm[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("Con", plant_status[i, latest_col])) {
            tran$she2con[which(tran$Country == plant_status$Country[i])] <- tran$she2con[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          }
        }
      } else if (grepl("Con", plant_status[i, j])) {
        if (j == ncol(plant_status)  || !any(grepl("Con", plant_status[i, (j + 1):ncol(plant_status)]))) {
          tran$newcon[which(tran$Country == plant_status$Country[i])] <- tran$newcon[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          if (grepl("Can", plant_status[i, latest_col])) {
            tran$con2can[which(tran$Country == plant_status$Country[i])] <- tran$con2can[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("She", plant_status[i, latest_col])) {
            tran$con2she2she[which(tran$Country == plant_status$Country[i])] <- tran$con2she2she[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("Oper", plant_status[i, latest_col])) {
            tran$con2oper[which(tran$Country == plant_status$Country[i])] <- tran$con2oper[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("Con", plant_status[i, latest_col])) {
            tran$con2con[which(tran$Country == plant_status$Country[i])] <- tran$con2con[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          }
        }
      } else if (grepl("Ann", plant_status[i, j])) {
        if (j == ncol(plant_status)  || !any(grepl("Ann", plant_status[i, (j + 1):ncol(plant_status)]))) {
          tran$ann[which(tran$Country == plant_status$Country[i])] <- tran$ann[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          if (grepl("Can", plant_status[i, latest_col])) {
            tran$ann2can[which(tran$Country == plant_status$Country[i])] <- tran$ann2can[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("She", plant_status[i, latest_col])) {
            tran$ann2she[which(tran$Country == plant_status$Country[i])] <- tran$ann2she[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("Oper", plant_status[i, latest_col])) {
            tran$ann2oper[which(tran$Country == plant_status$Country[i])] <- tran$ann2oper[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("Con", plant_status[i, latest_col])) {
            tran$ann2con[which(tran$Country == plant_status$Country[i])] <- tran$ann2con[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          }
        }
      } else if (grepl("Pre", plant_status[i, j])) {
        if (j == ncol(plant_status)  || !any(grepl("Pre", plant_status[i, (j + 1):ncol(plant_status)]))) {
          tran$pre[which(tran$Country == plant_status$Country[i])] <- tran$pre[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          if (grepl("Can", plant_status[i, latest_col])) {
            tran$pre2can[which(tran$Country == plant_status$Country[i])] <- tran$pre2can[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("She", plant_status[i, latest_col])) {
            tran$pre2she[which(tran$Country == plant_status$Country[i])] <- tran$pre2she[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("Oper", plant_status[i, latest_col])) {
            tran$pre2oper[which(tran$Country == plant_status$Country[i])] <- tran$pre2oper[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("Con", plant_status[i, latest_col])) {
            tran$pre2con[which(tran$Country == plant_status$Country[i])] <- tran$pre2con[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          }
        }
      } else if (grepl("Perm", plant_status[i, j])) {
        if (j == ncol(plant_status)  || !any(grepl("Perm", plant_status[i, (j + 1):ncol(plant_status)]))) {
          tran$perm[which(tran$Country == plant_status$Country[i])] <- tran$perm[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          if (grepl("Can", plant_status[i, latest_col])) {
            tran$perm2can[which(tran$Country == plant_status$Country[i])] <- tran$perm2can[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("She", plant_status[i, latest_col])) {
            tran$perm2she[which(tran$Country == plant_status$Country[i])] <- tran$perm2she[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("Oper", plant_status[i, latest_col])) {
            tran$perm2oper[which(tran$Country == plant_status$Country[i])] <- tran$perm2oper[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("Con", plant_status[i, latest_col])) {
            tran$perm2con[which(tran$Country == plant_status$Country[i])] <- tran$perm2con[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          }
        }
      } else if (grepl("Moth", plant_status[i, j])) {
        if (j == ncol(plant_status)  || !any(grepl("Moth", plant_status[i, (j + 1):ncol(plant_status)]))) {
          tran$moth[which(tran$Country == plant_status$Country[i])] <- tran$moth[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          if (grepl("Ret", plant_status[i, latest_col])) {
            tran$moth2ret[which(tran$Country == plant_status$Country[i])] <- tran$moth2ret[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (any(grepl("Oper", plant_status[i, latest_col:(j - 1)]))) {
            tran$moth2oper[which(tran$Country == plant_status$Country[i])] <- tran$moth2oper[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          }
        }
      }

      j <- j - 1
      if (grepl("She", plant_status[i, j])) {
        if (plant_status[i, j + 1] == "Con") {
          tran$con2she[which(tran$Country == plant_status$Country[i])] <- tran$con2she[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          if (grepl("Oper", plant_status[i, latest_col])) {
            tran$con2she2oper[which(tran$Country == plant_status$Country[i])] <- tran$con2she2oper[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("Con", plant_status[i, latest_col])) {
            tran$con2she2con[which(tran$Country == plant_status$Country[i])] <- tran$con2she2con[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          } else if (grepl("Can", plant_status[i, latest_col])) {
            tran$con2she2can[which(tran$Country == plant_status$Country[i])] <- tran$con2she2can[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
          }
        } else if (grepl("Ann", plant_status[i, j + 1]) || grepl("Pre", plant_status[i, j + 1]) || grepl("Perm", plant_status[i, j + 1])) {
          tran$plan2she[which(tran$Country == plant_status$Country[i])] <- tran$plan2she[which(tran$Country == plant_status$Country[i])] + plant_status$MW[i]
        }
      }
    }
  }
  tran <- tran[-which(tran$Country == "Kosovo"), ]


  mtran <- as.magpie(tran, spatial = 1)
  getYears(mtran) <- "y2020"
  mtran <- setItems(dim = 1, x = mtran,
                    value = toolCountry2isocode(mapping = c("DR Congo" = "COD"), country = getItems(dim = 1, x = mtran)))
  mtran <- toolCountryFill(mtran, fill = 0, verbosity = 2)
  # Combined cancellation + shelving rates of each project phase, to be used for completion rate calculation
  can_she_rate <- new.magpie(getItems(dim = 1, x = mtran), getYears(mtran), getNames(mtran)[which(!grepl("2", getNames(mtran)) & getNames(mtran) != "moth")], fill = NA)
  # Shelving rate of projects in each phase
  she_rate <- new.magpie(getItems(dim = 1, x = mtran), getYears(mtran), getNames(can_she_rate), fill = NA)
  # Cancellation rate of projects in the shelving phase
  can_rate <- new.magpie(getItems(dim = 1, x = mtran), getYears(mtran), "shelved", fill = NA)

  reg_can_rate <- new.magpie(getItems(dim = 1, x = regAvgRetAge), getYears(mtran), getNames(can_rate))
  reg_can_she_rate <- new.magpie(getItems(dim = 1, x = regAvgRetAge), getYears(mtran), getNames(can_she_rate))
  reg_she_rate <- new.magpie(getItems(dim = 1, x = regAvgRetAge), getYears(mtran), getNames(she_rate))
  for (phase in getNames(can_she_rate)) {
    nonzero_countries <- getItems(dim = 1, x = mtran)[which(mtran[, , phase] != 0)]
    zero_countries <- getItems(dim = 1, x = mtran)[which(mtran[, , phase] == 0)]
    if (phase == "newcon") {
      can_she_rate[, , phase] <- (mtran[, , "con2can"] + mtran[, , "con2she2she"]) / mtran[, , "newcon"]
      she_rate[, , phase] <- mtran[, , "con2she2she"] / mtran[, , "newcon"]
    } else if (phase == "shelved") {
      can_she_rate[, , phase] <- (mtran[, , "she2can"] + mtran[, , "she2she"]) / mtran[, , phase]
      she_rate[, , phase] <- mtran[, , "she2she"] / mtran[, , "shelved"]
      can_rate[nonzero_countries, , phase] <- mtran[nonzero_countries, , "she2can"] / mtran[nonzero_countries, , "shelved"]
      # Calculate global mean rates
      glo_can_rate <- weighted.mean(can_rate[nonzero_countries, , phase], mtran[nonzero_countries, , phase])
      # Calculate regional rates
      tmp <- toolAggregate(can_rate[nonzero_countries, , phase], rel = map[which(map$CountryCode %in% nonzero_countries), ], mtran[nonzero_countries, , phase])
      # For regions which had zero projects in a certain phase, assign the global weighted mean
      reg_can_rate <- suppressWarnings(mbind(tmp, new.magpie(getItems(dim = 1, x = reg_can_rate)[which(!(getItems(dim = 1, x = reg_can_rate)) %in% getItems(dim = 1, x = tmp))], getYears(can_rate), phase, glo_can_rate)))
      # Assign regional rates to countries without projects in the present phase
      can_rate[zero_countries, , phase] <- as.numeric(reg_can_rate[map$RegionCode[which(map$CountryCode %in% zero_countries)], , phase])

    } else {
      can_she_rate[, , phase] <- (mtran[, , paste0(phase, "2can")] + mtran[, , paste0(phase, "2she")]) / mtran[, , phase]
      she_rate[, , phase] <- mtran[, , paste0(phase, "2she")] / mtran[, , phase]
    }
    # Calculate global mean rates
    glo_can_she_rate <- weighted.mean(can_she_rate[nonzero_countries, , phase], mtran[nonzero_countries, , phase])
    glo_she_rate <- weighted.mean(she_rate[nonzero_countries, , phase], mtran[nonzero_countries, , phase])

    # Calculate regional rates
    tmp_can_she <- toolAggregate(can_she_rate[nonzero_countries, , phase], rel = map[which(map$CountryCode %in% nonzero_countries), ], mtran[nonzero_countries, , phase])
    tmp_she <- toolAggregate(she_rate[nonzero_countries, , phase], rel = map[which(map$CountryCode %in% nonzero_countries), ], mtran[nonzero_countries, , phase])

    # For regions which had zero projects in a certain phase, assign the global weighted mean
    reg_can_she_rate[, , phase] <- suppressWarnings(mbind(tmp_can_she,
                                       new.magpie(getItems(dim = 1, x = reg_can_she_rate)[which(!(getItems(dim = 1, x = reg_can_she_rate)) %in% getItems(dim = 1, x = tmp_can_she))], getYears(mtran), phase, glo_can_she_rate)))
    reg_she_rate[, , phase] <- suppressWarnings(mbind(tmp_she,
                                   new.magpie(getItems(dim = 1, x = reg_she_rate)[which(!(getItems(dim = 1, x = reg_she_rate)) %in% getItems(dim = 1, x = tmp_she))], getYears(mtran), phase, glo_she_rate)))

    # Assign regional rates to countries without projects in the present phase
    can_she_rate[zero_countries, , phase] <- as.numeric(reg_can_she_rate[map$RegionCode[which(map$CountryCode %in% zero_countries)], , phase])
    she_rate[zero_countries, , phase] <- as.numeric(reg_she_rate[map$RegionCode[which(map$CountryCode %in% zero_countries)], , phase])
  }

  # Immaturity index formula to determine nascent coal consuming nations, where >50% of all coal plants are in the current pipeline
  immaturity <- (cap_sum[, , "Announced"] + cap_sum[, , "Pre-permit"] + cap_sum[, , "Permitted"] + cap_sum[, , "Construction"] + cap_sum[, , "Shelved"]) /
    (dimSums(cap_sum, dim = 3))

  # Nascent coal consumers AND countries without any projects in the past 6 years are assigned their regional cancellation/shelving rates
  can_rate[which(immaturity > 0.5)] <- reg_can_rate[map$RegionCode[which(map$CountryCode %in% getItems(dim = 1, x = immaturity)[which(immaturity > 0.5)])], , ]
  can_rate[which(can_rate == 0.5)] <- reg_can_rate[map$RegionCode[which(map$CountryCode %in% getItems(dim = 1, x = immaturity)[which(immaturity > 0.5)])], , ]

  comp_rate <- new.magpie(getItems(dim = 1, x = can_she_rate), getYears(mtran), getNames(can_she_rate), fill = NA)
  comp_rate_brown <- new.magpie(getItems(dim = 1, x = can_she_rate), getYears(mtran), getNames(can_she_rate), fill = NA)
  reg_comp_rate <- new.magpie(getItems(dim = 1, x = reg_can_rate), getYears(mtran), getNames(can_she_rate), fill = NA)
  reg_comp_rate_brown <- new.magpie(getItems(dim = 1, x = reg_can_rate), getYears(mtran), getNames(can_she_rate), fill = NA)
  glo_comp_rate <- new.magpie("GLO", getYears(mtran), getNames(can_she_rate), fill = NA)
  glo_comp_rate_brown <- new.magpie("GLO", getYears(mtran), getNames(can_she_rate), fill = NA)
  for (status in getNames(can_she_rate)) {
    nonzero_countries <- getItems(dim = 1, x = mtran)[which(mtran[, , status] != 0)]
    zero_countries <- getItems(dim = 1, x = mtran)[which(mtran[, , status] == 0)]
    can_she_rate[, , status][which(immaturity > 0.5)] <- reg_can_she_rate[map$RegionCode[which(map$CountryCode %in% getItems(dim = 1, x = immaturity)[which(immaturity > 0.5)])], , status]
    she_rate[, , status][which(immaturity > 0.5)] <- reg_she_rate[map$RegionCode[which(map$CountryCode %in% getItems(dim = 1, x = immaturity)[which(immaturity > 0.5)])], , status]
    # Derive completion rates to be used in the 2025 capacity estimation
    if (status == "shelved") {
      comp_rate[, , status] <- 1 - can_rate[, , status]
      comp_rate_brown[, , status] <- 1 - 0.5 * can_rate[, , status]
    } else {
      comp_rate[, , status] <- 1 - can_she_rate[, , status]
      comp_rate_brown[, , status] <- 1 - 0.5 * can_she_rate[, , status]
    }
    glo_comp_rate[, , status] <- weighted.mean(comp_rate[nonzero_countries, , status], mtran[nonzero_countries, , status])
    glo_comp_rate_brown[, , status] <- weighted.mean(comp_rate_brown[nonzero_countries, , status], mtran[nonzero_countries, , status])

    if (length(nonzero_countries)) {
      # Calculate regional rates
      tmp <- toolAggregate(comp_rate[nonzero_countries, , status], filter(map, CountryCode %in% nonzero_countries), mtran[nonzero_countries, , status])
      tmp_brown <- toolAggregate(comp_rate_brown[nonzero_countries, , status], filter(map, CountryCode %in% nonzero_countries), mtran[nonzero_countries, , status])
      # For regions which had zero projects in a certain status, assign the global weighted mean
      reg_comp_rate[, , status] <- suppressWarnings(mbind(tmp, new.magpie(getItems(dim = 1, x = reg_comp_rate)[which(!(getItems(dim = 1, x = reg_comp_rate)) %in% getItems(dim = 1, x = tmp))], getYears(comp_rate), status, glo_comp_rate)))
      reg_comp_rate_brown[, , status] <- suppressWarnings(mbind(tmp_brown, new.magpie(getItems(dim = 1, x = reg_comp_rate_brown)[which(!(getItems(dim = 1, x = reg_comp_rate_brown)) %in% getItems(dim = 1, x = tmp_brown))], getYears(comp_rate_brown), status, glo_comp_rate_brown)))
    } else {
      reg_comp_rate[, , status] <- 0
      reg_comp_rate_brown[, , status] <- 0
    }
  }

  # OECD PPCA members and green recovery nations are assumed to cancel all shelved projects and retire mothballed ones.
  comp_rate[c(greenNations, oecdPPCA, nonOECDppca), , "shelved"] <- 0
  comp_rate_brown[c(greenNations, oecdPPCA, nonOECDppca), , "shelved"] <- 0
  cap_sum[c(oecdPPCA, greenNations, nonOECDppca), , "Mothballed"] <- 0

  # Return completion rate magpies
  if (grepl("comp_rates", subtype)) {
    getNames(comp_rate) <- c("Shelved", "Construction", "Announced", "Pre-permit", "Permitted")
    getNames(comp_rate_brown) <- c("Shelved_brown", "Construction_brown", "Announced_brown", "Pre-permit_brown", "Permitted_brown")
    getNames(glo_comp_rate) <- c("Shelved", "Construction", "Announced", "Pre-permit", "Permitted")
    getNames(glo_comp_rate_brown) <- c("Shelved_brown", "Construction_brown", "Announced_brown", "Pre-permit_brown", "Permitted_brown")
    getNames(reg_comp_rate) <- c("Shelved", "Construction", "Announced", "Pre-permit", "Permitted")
    getNames(reg_comp_rate_brown) <- c("Shelved_brown", "Construction_brown", "Announced_brown", "Pre-permit_brown", "Permitted_brown")
    getNames(she_rate) <- c("Shelved_shelving", "Construction_shelving", "Announced_shelving", "Pre-permit_shelving", "Permitted_shelving")
    getNames(reg_she_rate) <- c("Shelved_shelving", "Construction_shelving", "Announced_shelving", "Pre-permit_shelving", "Permitted_shelving")

    if (grepl("reg", subtype)) {
      reg_mtran <- toolAggregate(
        setNames(mtran[, , c("shelved", "newcon", "ann", "pre", "perm")],
                 c("Shelved", "Construction", "Announced", "Pre-permit", "Permitted")), map, NULL)
      reg_all_comp_rate <- toolAggregate(reg_comp_rate, weight = reg_mtran, dim = 3, rel = data.frame(from = getNames(reg_mtran), to = rep("all", 5)))

      out <- suppressWarnings(mbind(reg_comp_rate, reg_all_comp_rate, reg_she_rate))
    } else if (grepl("glo", subtype)) {
      out <- suppressWarnings(mbind(glo_comp_rate, glo_comp_rate_brown))
    } else {
      out <- suppressWarnings(mbind(comp_rate, comp_rate_brown, she_rate))
    }
    return(out)
  }

  # *********************************Derive Coal capacity in 2025******************************
  # browser
  cap2025_brown <- cap_sum[, , "Operating"] +
    cap_sum[, , "Mothballed"] * 0.5 +
    cap_sum[, , "Announced"] * comp_rate_brown[, , "ann"] +
    cap_sum[, , "Pre-permit"] * comp_rate_brown[, , "pre"] +
    cap_sum[, , "Permitted"] * comp_rate_brown[, , "perm"] +
    cap_sum[, , "Construction"] * comp_rate_brown[, , "newcon"] +
    comp_rate_brown[, , "shelved"] * (cap_sum[, , "Shelved"] +
                                      cap_sum[, , "Announced"] * (she_rate[, , "ann"]) +
                                      cap_sum[, , "Pre-permit"] * (she_rate[, , "pre"]) +
                                      cap_sum[, , "Permitted"] * (she_rate[, , "perm"]) +
                                      cap_sum[, , "Construction"] * (she_rate[, , "newcon"])) -
    retireBrown[, , "Retiring_Cap"]

  cap2025_BAU <- cap_sum[, , "Operating"] +
    cap_sum[, , "Mothballed"] * 0.5 +
    cap_sum[, , "Announced"] * comp_rate[, , "ann"] +
    cap_sum[, , "Pre-permit"] * comp_rate[, , "pre"] +
    cap_sum[, , "Permitted"] * comp_rate[, , "perm"] +
    cap_sum[, , "Construction"] * comp_rate[, , "newcon"] +
    comp_rate[, , "shelved"] * (cap_sum[, , "Shelved"] +
                                cap_sum[, , "Announced"] * (she_rate[, , "ann"]) +
                                cap_sum[, , "Pre-permit"] * (she_rate[, , "pre"]) +
                                cap_sum[, , "Permitted"] * (she_rate[, , "perm"]) +
                                cap_sum[, , "Construction"] * (she_rate[, , "newcon"])) -
    retireBAU[, , "Retiring_Cap"]

  cap2025_green <- cap_sum[, , "Operating"] +
    cap_sum[, , "Announced"] * comp_rate[, , "ann"] / 2 +
    cap_sum[, , "Pre-permit"] * comp_rate[, , "pre"] / 2 +
    cap_sum[, , "Permitted"] * comp_rate[, , "perm"] / 2 +
    0.5 * comp_rate[, , "newcon"] * cap_sum[, , "Construction"] +
    0.5 * comp_rate[, , "shelved"] * cap_sum[, , "Construction"] * (she_rate[, , "newcon"]) -
    retireBAU[, , "Retiring_Cap"]

  cap2025_norm <- cap_sum[, , "Operating"] +
    cap_sum[, , "Mothballed"] * 0.5 +
    cap_sum[, , "Announced"] +
    cap_sum[, , "Pre-permit"] +
    cap_sum[, , "Permitted"] +
    cap_sum[, , "Construction"] +
    cap_sum[, , "Shelved"] -
    retireNorm[, , "Retiring_Cap"]

  cap2025_brown[which(cap2025_brown < 0)] <- 0
  cap2025_green[which(cap2025_green < 0)] <- 0
  cap2025_norm[which(cap2025_norm < 0)] <- 0
  cap2025_BAU[which(cap2025_BAU < 0)] <- 0

  getNames(cap2025_brown) <- "Brown"
  getNames(cap2025_green) <- "Green"
  getNames(cap2025_norm) <- "Norm"
  getNames(cap2025_BAU) <- "Neutral"


  getYears(cap2025_brown) <- "y2025"
  getYears(cap2025_green) <- "y2025"
  getYears(cap2025_norm) <- "y2025"
  getYears(cap2025_BAU) <- "y2025"

  mcap2025 <- suppressWarnings(mbind(cap2025_brown / 1000, cap2025_green / 1000, cap2025_BAU / 1000, cap2025_norm / 1000))

  # Return Capacity scenarios
  if (grepl("future", subtype) || grepl("FinEx", subtype)) {
    return(mcap2025)
  }
  ###### PEGASOS Policy Brief Calcs ##########
  if (grepl("PEGASOS", subtype)) {
    # PEGASOS policy brief scenario: Popular choice in literature has been to use a globally uniform 35-yr lifespan
    retirePEGA <- retire %>%
      select(Country, `Planned Retire`, `Plant Age`, `Capacity (MW)`, Status, Avg_Ret_Age, `Heat rate`, `Emission factor`) %>%
      filter(Status %in% c("Operating", "operating")) %>%
      filter(`Plant Age` >= 25) %>%
      filter(!is.na(`Capacity (MW)`)) %>%
      group_by(Country) %>%
      summarise(Retiring_Cap = sum(`Capacity (MW)`))
    retirePEGA$Retiring_Cap[which(is.na(retirePEGA$Retiring_Cap))] <- 0
    retirePEGA <- as.magpie(retirePEGA, spatial = 1)
    retirePEGA <- toolCountryFill(retirePEGA, fill = 0, no_remove_warning = "KOS", verbosity = 2)

    retireNorm <- retire %>%
      select(Country, `Planned Retire`, `Plant Age`, `Capacity (MW)`, Status, Avg_Ret_Age, `Heat rate`, `Emission factor`) %>%
      filter(Status %in% c("Operating", "operating")) %>%
      filter(`Plant Age` >= 30) %>%
      filter(!is.na(`Capacity (MW)`)) %>%
      group_by(Country) %>%
      summarise(Retiring_Cap = sum(`Capacity (MW)`))
    retireNorm$Retiring_Cap[which(is.na(retireNorm$Retiring_Cap))] <- 0
    retireNorm <- as.magpie(retireNorm, spatial = 1)
    retireNorm <- toolCountryFill(retireNorm, fill = 0, no_remove_warning = "KOS", verbosity = 2)

    retire1p5C <- retire %>%
      select(Country, `Planned Retire`, `Plant Age`, `Capacity (MW)`, Status, Avg_Ret_Age) %>%
      filter(Status %in% c("Operating", "operating")) %>%
      filter(`Plant Age` >= 10) %>%
      filter(!is.na(`Capacity (MW)`)) %>%
      group_by(Country) %>%
      summarise(Retiring_Cap = sum(`Capacity (MW)`))
    retire1p5C$Retiring_Cap[which(is.na(retire1p5C$Retiring_Cap))] <- 0
    retire1p5C <- as.magpie(retire1p5C, spatial = 1)
    retire1p5C <- toolCountryFill(retire1p5C, fill = 0, no_remove_warning = "KOS", verbosity = 2)

    getYears(retireBAU) <- "y2025"
    getYears(retireGreen) <- "y2025"
    getYears(retireBrown) <- "y2025"
    getYears(retirePEGA) <- "y2025"
    getYears(retire1p5C) <- "y2025"
    getYears(retireNorm) <- "y2025"

    for (ts in seq(2030, 2070, 5)) {
      # BAU COVID recovery scenario: Countries maintain their historical average lifespans
      retireBAUts <- retire %>%
        select(Country, `Planned Retire`, `Plant Age`, `Capacity (MW)`, Status, Avg_Ret_Age) %>%
        filter(Status %in% c("Operating", "operating")) %>%
        filter(`Planned Retire` <= ts | `Plant Age` >= (Avg_Ret_Age - (ts - 2020))) %>%
        filter(!is.na(`Capacity (MW)`)) %>%
        group_by(Country) %>%
        summarise(Retiring_Cap = sum(`Capacity (MW)`))

      retireBAUts$Retiring_Cap[which(is.na(retireBAUts$Retiring_Cap))] <- 0
      retireBAUts <- as.magpie(retireBAUts, spatial = 1)
      retireBAUts <- toolCountryFill(setYears(retireBAUts, ts), fill = 0, no_remove_warning = "KOS", verbosity = 2)

      # Green COVID recovery scenario: Countries maintain their historical average lifespans
      retireGreents <- retire %>%
        select(Country, `Planned Retire`, `Plant Age`, `Capacity (MW)`, Status, Avg_Ret_Age) %>%
        filter(Status %in% c("Operating", "operating")) %>%
        filter(`Planned Retire` <= ts | `Plant Age` >= (Avg_Ret_Age - (ts - 2015))) %>%
        filter(!is.na(`Capacity (MW)`)) %>%
        group_by(Country) %>%
        summarise(Retiring_Cap = sum(`Capacity (MW)`))

      retireGreents$Retiring_Cap[which(is.na(retireGreents$Retiring_Cap))] <- 0
      retireGreents <- as.magpie(retireGreents, spatial = 1)
      retireGreents <- toolCountryFill(setYears(retireGreents, ts), fill = 0, no_remove_warning = "KOS", verbosity = 2)

      # Brown COVID recovery scenario: Countries maintain their historical average lifespans
      retireBrownts <- retire %>%
        select(Country, `Planned Retire`, `Plant Age`, `Capacity (MW)`, Status, Avg_Ret_Age) %>%
        filter(Status %in% c("Operating", "operating")) %>%
        filter(`Planned Retire` <= ts | `Plant Age` >= (Avg_Ret_Age - (ts - 2025))) %>%
        filter(!is.na(`Capacity (MW)`)) %>%
        group_by(Country) %>%
        summarise(Retiring_Cap = sum(`Capacity (MW)`))

      retireBrownts$Retiring_Cap[which(is.na(retireBrownts$Retiring_Cap))] <- 0
      retireBrownts <- as.magpie(retireBrownts, spatial = 1)
      retireBrownts <- toolCountryFill(setYears(retireBrownts, ts), fill = 0, no_remove_warning = "KOS", verbosity = 2)

      # PEGASOS policy brief scenario: Popular choice in literature has been to use a globally uniform 35-yr lifespan
      retirePEGAts <- retire %>%
        select(Country, `Planned Retire`, `Plant Age`, `Capacity (MW)`, Status, Avg_Ret_Age) %>%
        filter(Status %in% c("Operating", "operating")) %>%
        filter(`Plant Age` + (ts - 2020) >= 35) %>%
        filter(!is.na(`Capacity (MW)`)) %>%
        group_by(Country) %>%
        summarise(Retiring_Cap = sum(`Capacity (MW)`))
      retirePEGAts$Retiring_Cap[which(is.na(retirePEGAts$Retiring_Cap))] <- 0
      retirePEGAts <- as.magpie(retirePEGAts, spatial = 1)
      retirePEGAts <- toolCountryFill(setYears(retirePEGAts, ts), fill = 0, no_remove_warning = "KOS", verbosity = 2)

      # Another common literature figure has been to use a globally uniform 40-yr lifespan
      retireNormts <- retire %>%
        select(Country, `Planned Retire`, `Plant Age`, `Capacity (MW)`, Status, Avg_Ret_Age) %>%
        filter(Status %in% c("Operating", "operating")) %>%
        filter(`Plant Age` + (ts - 2020) >= 40) %>%
        filter(!is.na(`Capacity (MW)`)) %>%
        group_by(Country) %>%
        summarise(Retiring_Cap = sum(`Capacity (MW)`))
      retireNormts$Retiring_Cap[which(is.na(retireNormts$Retiring_Cap))] <- 0
      retireNormts <- as.magpie(retireNormts, spatial = 1)
      retireNormts <- toolCountryFill(setYears(retireNormts, ts), fill = 0, no_remove_warning = "KOS", verbosity = 2)

      # 20 year lifespans are roughly compatible with Hi-1p5C scenarios
      retire1p5Cts <- retire %>%
        select(Country, `Planned Retire`, `Plant Age`, `Capacity (MW)`, Status, Avg_Ret_Age) %>%
        filter(Status %in% c("Operating", "operating")) %>%
        filter(`Plant Age` + (ts - 2020) >= 20) %>%
        filter(!is.na(`Capacity (MW)`)) %>%
        group_by(Country) %>%
        summarise(Retiring_Cap = sum(`Capacity (MW)`))
      retire1p5Cts$Retiring_Cap[which(is.na(retire1p5Cts$Retiring_Cap))] <- 0
      retire1p5Cts <- as.magpie(retire1p5Cts, spatial = 1)
      retire1p5Cts <- toolCountryFill(setYears(retire1p5Cts, ts), fill = 0, no_remove_warning = "KOS", verbosity = 2)


      retireBAU <- mbind(retireBAU, retireBAUts)
      retireGreen <- mbind(retireGreen, retireGreents)
      retireBrown <- mbind(retireBrown, retireBrownts)
      retirePEGA <- mbind(retirePEGA, retirePEGAts)
      retire1p5C <- mbind(retire1p5C, retire1p5Cts)
      retireNorm <- mbind(retireNorm, retireNormts)

    }

    if (grepl("pubfinex", subtype)) {
      pubfinex <- read.csv(file.path("Coal_Finance_Exit", "Public_Foreign_Finance_Cap_2021.csv"), sep = ";")
      if (grepl("REsub", subtype)) {
        output <- new.magpie(pubfinex$Country, c(2025, 2030), NULL, fill = 0)

        output[, 2025, ] <- as.numeric(pubfinex$Foreign) * (1 - as.numeric(pubfinex$Ann_share))
        output[, 2030, ] <- as.numeric(pubfinex$Foreign) * as.numeric(pubfinex$Ann_share)
        return(toolCountryFill(output, fill = 0, verbosity = 2))
      }
      for (iii in c("Ann", "Pre", "Perm")) {
        cap_sum[pubfinex$Country, , grepl(iii, getNames(cap_sum), ignore.case = FALSE)] <- pubfinex[, paste0(iii, "_dom")]
      }
    }

    ############ CALCULATE FUTURE CAPACITY TRAJECTORIES #################
    brown_PEGA <- cap_sum[, , "Operating"] +
      cap_sum[, , "Mothballed"] * 0.5 +
      cap_sum[, , "Announced"] * comp_rate[, , "ann"] +
      cap_sum[, , "Pre-permit"] * comp_rate[, , "pre"] +
      cap_sum[, , "Permitted"] * comp_rate[, , "perm"] +
      cap_sum[, , "Construction"] * comp_rate[, , "newcon"] +
      comp_rate[, , "shelved"] * (cap_sum[, , "Shelved"] +
                                  cap_sum[, , "Announced"] * (she_rate[, , "ann"]) +
                                  cap_sum[, , "Pre-permit"] * (she_rate[, , "pre"]) +
                                  cap_sum[, , "Permitted"] * (she_rate[, , "perm"]) +
                                  cap_sum[, , "Construction"] * (she_rate[, , "newcon"])) -
      retireBAU[, , "Retiring_Cap"]

    cap_green <- cap_sum[, , "Operating"] +
      cap_sum[, , "Announced"] * comp_rate[, , "ann"] / 2 +
      cap_sum[, , "Pre-permit"] * comp_rate[, , "pre"] / 2 +
      cap_sum[, , "Permitted"] * comp_rate[, , "perm"] / 2 +
      0.5 * comp_rate[, , "newcon"] * cap_sum[, , "Construction"] +
      0.5 * comp_rate[, , "shelved"] * cap_sum[, , "Construction"] * (she_rate[, , "newcon"]) -
      retireGreen[, , "Retiring_Cap"]

    upper_gray_PEGA <- cap_sum[, , "Operating"] +
      cap_sum[, , "Mothballed"] * 0.5 +
      cap_sum[, , "Announced"] * comp_rate_brown[, , "ann"] +
      cap_sum[, , "Pre-permit"] * comp_rate_brown[, , "pre"] +
      cap_sum[, , "Permitted"] * comp_rate_brown[, , "perm"] +
      cap_sum[, , "Construction"] * comp_rate_brown[, , "newcon"] +
      comp_rate_brown[, , "shelved"] * (cap_sum[, , "Shelved"] +
                                        cap_sum[, , "Announced"] * (she_rate[, , "ann"]) +
                                        cap_sum[, , "Pre-permit"] * (she_rate[, , "pre"]) +
                                        cap_sum[, , "Permitted"] * (she_rate[, , "perm"]) +
                                        cap_sum[, , "Construction"] * (she_rate[, , "newcon"])) -
      retireBrown[, , "Retiring_Cap"]

    if (grepl("PEGASOS", subtype)) {
      red_PEGA <- cap_sum[, , "Operating"] +
        cap_sum[, , "Mothballed"] * 0.5 +
        cap_sum[, , "Announced"] +
        cap_sum[, , "Pre-permit"] +
        cap_sum[, , "Permitted"] +
        cap_sum[, , "Construction"] +
        cap_sum[, , "Shelved"] -
        retirePEGA[, , "Retiring_Cap"]
    } else {
      red_PEGA <- cap_sum[, , "Operating"] +
        cap_sum[, , "Mothballed"] * 0.5 +
        cap_sum[, , "Announced"] +
        cap_sum[, , "Pre-permit"] +
        cap_sum[, , "Permitted"] +
        cap_sum[, , "Construction"] +
        cap_sum[, , "Shelved"] -
        retireNorm[, , "Retiring_Cap"]
    }

    silver_PEGA <- setYears(cap_sum[, , "Operating"], NULL) - retirePEGA
    lower_gray_PEGA <- setYears(cap_sum[, , "Operating"], NULL) - retire1p5C

    green_PEGA <- setYears(cap_sum[, , "Operating"], NULL) - retireGreen

    gold_PEGA <- setYears(cap_sum[, , "Operating"], NULL) - retireGreen

    bronze_PEGA <- setYears(cap_sum[, , "Operating"], NULL) - retireBrown

    silver_PEGA[which(silver_PEGA < 0)] <- 0
    cap_green[which(cap_green < 0)] <- 0
    gold_PEGA[which(gold_PEGA < 0)] <- 0
    brown_PEGA[which(brown_PEGA < 0)] <- 0

    getYears(silver_PEGA) <- seq(2025, 2070, 5)
    getYears(cap_green) <- seq(2025, 2070, 5)
    getYears(gold_PEGA) <- seq(2025, 2070, 5)
    getYears(brown_PEGA) <- seq(2025, 2070, 5)
    getYears(bronze_PEGA) <- seq(2025, 2070, 5)
    getYears(upper_gray_PEGA) <- seq(2025, 2070, 5)
    getYears(red_PEGA) <- seq(2025, 2070, 5)
    getYears(green_PEGA) <- seq(2025, 2070, 5)
    getYears(lower_gray_PEGA) <- seq(2025, 2070, 5)

    ### Time Series: Announced and pre-permit projects finish in 2030 ##
    if (!grepl("2025", subtype)) {
      brown_PEGA[, 2025, ] <- brown_PEGA[, 2025, ] - (cap_sum[, , "Announced"] * comp_rate[, , "ann"] +
                                                    cap_sum[, , "Pre-permit"] * comp_rate[, , "pre"])

      cap_green[, 2025, ] <- cap_green[, 2025, ] - (cap_sum[, , "Announced"] * comp_rate[, , "ann"] +
                                                  cap_sum[, , "Pre-permit"] * comp_rate[, , "pre"])

      upper_gray_PEGA[, 2025, ] <- upper_gray_PEGA[, 2025, ] - (cap_sum[, , "Announced"] * comp_rate[, , "ann"] +
                                                              cap_sum[, , "Pre-permit"] * comp_rate[, , "pre"])

      red_PEGA[, 2025, ] <- red_PEGA[, 2025, ] - (cap_sum[, , "Announced"] * comp_rate[, , "ann"] +
                                                cap_sum[, , "Pre-permit"] * comp_rate[, , "pre"])
    }

    getNames(cap_green) <- "Green"
    getNames(brown_PEGA) <- ifelse(grepl("REM", subtype), "Neutral", "Brown")
    getNames(upper_gray_PEGA) <- ifelse(grepl("REM", subtype), "Brown", "upGray")
    getNames(red_PEGA) <- "Red"
    getNames(green_PEGA) <- "Green"
    getNames(lower_gray_PEGA) <- "lowGray"

    if (grepl("REM", subtype)) {
      mcap <- mbind(brown_PEGA, upper_gray_PEGA, cap_green) / 1000
      mcap <- mcap[, getYears(mcap) <= "y2030", ]
    } else {
      mcap <- mbind(brown_PEGA, upper_gray_PEGA, red_PEGA, lower_gray_PEGA, cap_green) / 1000
    }

    # Return Capacity scenarios
    return(mcap)
  }


  # Prepare completion rate data frames
  getNames(comp_rate) <- c("Shelved", "Construction", "Announced", "Pre-permit", "Permitted")
  df_comp <- as.data.frame(comp_rate)
  colnames(df_comp)[2] <- "Country"
  df_comp <- df_comp[, -3]
  df_comp <- df_comp[, -1]
  colnames(df_comp)[2] <- "Status"

  getNames(comp_rate_brown) <- c("Shelved", "Construction", "Announced", "Pre-permit", "Permitted")
  df_comp_brown <- as.data.frame(comp_rate_brown)
  colnames(df_comp_brown)[2] <- "Country"
  df_comp_brown <- df_comp_brown[, -3]
  df_comp_brown <- df_comp_brown[, -1]
  colnames(df_comp_brown)[2] <- "Status"

  # Calculate committed emissions
  # Select necessary columns from plant-level database
  emi_data <- retire %>%
    select(Country, `Plant Age`, `Capacity (MW)`, Status, `Heat rate`, `Emission factor`, `Combustion technology`, RETIRED, Year) %>%
    filter(!(Status %in% c("Retired", "Cancelled", "retired", "cancelled")) & !is.na(`Capacity (MW)`) & is.na(RETIRED) & !is.na(`Emission factor`)) %>%
    left_join(avgRetAge, by = "Country") %>%
    mutate(Brown_Ret_Age = Avg_Ret_Age + 5) %>%
    mutate(Norm_Ret_Age = 40)

  # Convert Year column to numeric, first handling the special non-numeric cases
  emi_data$Year[which(grepl("after", emi_data$Year, ignore.case = TRUE))] <-
    as.numeric(gsub("after ", "", emi_data$Year[which(grepl("after", emi_data$Year, ignore.case = TRUE))], ignore.case = TRUE)) + 1
  emi_data$Year[which(grepl("/", emi_data$Year, fixed = TRUE) | grepl("-", emi_data$Year, fixed = TRUE))] <-
    substr(emi_data$Year[which(grepl("/", emi_data$Year, fixed = TRUE) | grepl("-", emi_data$Year, fixed = TRUE))], 1, 4)
  emi_data$Year <- as.numeric(emi_data$Year)

  # Set operating plants with an unknown age to 50% of the national average lifespan
  emi_data <- emi_data %>%
    mutate(`Plant Age` =
             ifelse(is.na(Year) & Status %in% c("Operating", "operating"),
                    0.5 * Avg_Ret_Age,
                    `Plant Age`))

  # Set pipeline plants to appropriate ages
  for (Phase in getNames(comp_rate)) {

    emi_data <- emi_data %>%
      mutate(`Plant Age` =
               ifelse(grepl(Phase, Status, ignore.case = FALSE) & is.finite(Year) & Year >= 2020,
                      2020 - Year,
                      `Plant Age`))

    meanAge <- emi_data %>%
      filter(grepl(Phase, Status, ignore.case = FALSE) & is.finite(Year) & Year >= 2020) %>%
      summarise(age = mean(`Plant Age`))

    emi_data$`Plant Age`[which(emi_data$Status == Phase & is.na(emi_data$Year))] <- meanAge$age
  }
  # Read in national average capacity factor assumption for each 5-year time-step
  capFac <- calcOutput("CapacityFactor", aggregate = FALSE)[, seq(2020, 2100, 5), "pc"]
  capFac <- removeColNa(as.data.frame(capFac))[, -3]
  colnames(capFac) <- c("Country", "Period", "Cap_Factor")
  capFac$Period <- as.numeric(as.character(capFac$Period))

  # Assign each coal plant its country's average capacity factor per time-step
  emi_data <- emi_data %>% left_join(capFac, by = "Country") %>% mutate(`Plant Age` = `Plant Age` + (Period - 2020))

  # Calculate emissions from each plant for each 5-yr timestep in each scenario using GCPT methodology
  # 5 * MW * cf * Btu/kWh * kgCO2/TJ * 9.2427e-12 #nolint
  emi_data <- emi_data %>% mutate(green_5yr_emi = ifelse(emi_data$`Plant Age` >= 0 & (emi_data$`Plant Age` < emi_data$Avg_Ret_Age),
                                                         5 * `Capacity (MW)` * Cap_Factor * `Heat rate` * `Emission factor` * 9.2427e-12, 0)) %>%
    mutate(bau_5yr_emi = ifelse(emi_data$`Plant Age` >= 0 & (emi_data$`Plant Age` < emi_data$Avg_Ret_Age),
                                 5 * `Capacity (MW)` * Cap_Factor * `Heat rate` * `Emission factor` * 9.2427e-12, 0)) %>%
    mutate(brown_5yr_emi = ifelse(emi_data$`Plant Age` >= 0 & (emi_data$`Plant Age` < emi_data$Brown_Ret_Age),
                                 5 * `Capacity (MW)` * Cap_Factor * `Heat rate` * `Emission factor` * 9.2427e-12, 0)) %>%
    mutate(norm_5yr_emi = ifelse(emi_data$`Plant Age` >= 0 & (emi_data$`Plant Age` < emi_data$Norm_Ret_Age),
                                 5 * `Capacity (MW)` * 0.53 * `Heat rate` * `Emission factor` * 9.2427e-12, 0))

  # Calculate total emissions (MtCO2) over the lifespan of plants in operation and development for each scenario
  green_emi <- emi_data %>%
    group_by(Country, .add = TRUE) %>%
    group_by(Status, .add = TRUE) %>%
    summarise(green_emi = sum(green_5yr_emi))

  bau_emi <- emi_data %>%
    group_by(Country, .add = TRUE) %>%
    group_by(Status, .add = TRUE) %>%
    summarise(BAU_emi = sum(bau_5yr_emi))

  brown_emi <- emi_data %>%
    group_by(Country, .add = TRUE) %>%
    group_by(Status, .add = TRUE) %>%
    summarise(brown_emi = sum(brown_5yr_emi))

  norm_emi <- emi_data %>%
    group_by(Country, .add = TRUE) %>%
    group_by(Status, .add = TRUE) %>%
    summarise(norm_emi = sum(norm_5yr_emi))

  # Calculate total emissions from all operating & pipeline plants with 40-yr lifespans
  norm_emi <- norm_emi %>% group_by(Country) %>% summarise(norm_total_emi = sum(norm_emi) / 1000)

  # Calculate committed emissions reduced by PPCA members based on norm assumptions
  ppca_emi <- emi_data %>%
    filter(Period >= 2030 & Country %in% ppca) %>%
    mutate(norm_5yr_emi = ifelse(Period == 2030, norm_5yr_emi / 2, norm_5yr_emi)) %>%
    summarise(avoided_emissions = sum(norm_5yr_emi) / 1000)

  # Calculate total emissions from operating & pipeline plants in each recovery scenario
  bau_emi <- left_join(bau_emi, df_comp, by = c("Country", "Status"))
  bau_emi$Value[which(bau_emi$Status == "Operating")] <- 1
  bau_emi$Value[which(bau_emi$Status == "Mothballed")] <- 0.5
  bau_emi <- bau_emi %>% group_by(Country) %>% summarize(BAU_total_emi = sum(BAU_emi * Value) / 1000)

  green_emi <- left_join(green_emi, df_comp, by = c("Country", "Status"))
  green_emi$Value <- 0.5 * green_emi$Value
  green_emi$Value[which(green_emi$Status == "Operating")] <- 1
  green_emi$Value[which(green_emi$Status == "Mothballed")] <- 0
  green_emi <- green_emi %>% group_by(Country) %>% summarize(green_total_emi = sum(green_emi * Value) / 1000)

  brown_emi <- left_join(brown_emi, df_comp_brown, by = c("Country", "Status"))
  brown_emi$Value[which(brown_emi$Status == "Operating")] <- 1
  brown_emi$Value[which(brown_emi$Status == "Mothballed")] <- 0.5
  brown_emi <- brown_emi %>% group_by(Country) %>% summarize(brown_total_emi = sum(brown_emi * Value) / 1000)

  bau_emi <- toolCountryFill(as.magpie(bau_emi), fill = 0, verbosity = 2)
  green_emi <- toolCountryFill(as.magpie(green_emi), fill = 0, verbosity = 2)
  brown_emi <- toolCountryFill(as.magpie(brown_emi), fill = 0, verbosity = 2)
  norm_emi <- toolCountryFill(as.magpie(norm_emi), fill = 0, verbosity = 2)

  if (grepl("emissions", subtype)) {
    return(mbind(bau_emi, green_emi, brown_emi, norm_emi))
  } else if (grepl("ppca_emi", subtype)) {
    return(as.magpie(ppca_emi))
  }
}
pik-piam/mrremind documentation built on Sept. 26, 2024, 1:15 p.m.