Skip to content

Commit

Permalink
Optional output of CO2 and non-CO2 emissions by year seems to be work…
Browse files Browse the repository at this point in the history
…ing. Changes to treecoverloss package for ArcPy client are essentially complete.
  • Loading branch information
dagibbs22 committed Oct 14, 2023
1 parent d21288e commit 4cbf760
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ object TreeCoverLossCommand extends SummaryCommand {
)
.orFalse

val emisGasOpts: Opts[Boolean] = Opts
val emisGasAnnualOpts: Opts[Boolean] = Opts
.flag(
"emissions_by_gas",
"emissions_by_gas_annually",
"Output emissions for CO2 and non-CO2 gases (CH4 and N2O) separately"
)
.orFalse

val treeCoverLossOptions: Opts[(NonEmptyList[String], Int, Product with Serializable, Boolean, Boolean, Boolean)] = // If new options are added below, the corresponding types must be added here
(contextualLayersOpts, tcdOpt, thresholdOpts, carbonPoolOpts, simpleAGBEmisOpts, emisGasOpts).tupled // If new options are added here, the corresponding types must be added in the row above
(contextualLayersOpts, tcdOpt, thresholdOpts, carbonPoolOpts, simpleAGBEmisOpts, emisGasAnnualOpts).tupled // If new options are added here, the corresponding types must be added in the row above

val treeCoverLossCommand: Opts[Unit] = Opts.subcommand(
name = TreeLossAnalysis.name,
Expand All @@ -66,7 +66,7 @@ object TreeCoverLossCommand extends SummaryCommand {
"thresholdFilter" -> treeCoverLoss._3,
"carbonPools" -> treeCoverLoss._4,
"simpleAGBEmis" -> treeCoverLoss._5,
"emisGas" -> treeCoverLoss._6,
"emisGasAnnual" -> treeCoverLoss._6,
"config" -> GfwConfig.get
)
val featureFilter = FeatureFilter.fromOptions(default.featureType, filterOptions)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object TreeLossDF {
val treecoverLossMinYear = 2001
val treecoverLossMaxYear = 2022

def unpackValues(carbonPools: Boolean, simpleAGBEmis: Boolean)(df: DataFrame): DataFrame = {
def unpackValues(carbonPools: Boolean, simpleAGBEmis: Boolean, emisGasAnnual: Boolean)(df: DataFrame): DataFrame = {
val spark: SparkSession = df.sparkSession
import spark.implicits._

Expand Down Expand Up @@ -71,9 +71,30 @@ object TreeLossDF {
List()
}

val totalGrossEmissionsCo2Co2OnlyCols = if (emisGasAnnual) {
(for (i <- treecoverLossMinYear to treecoverLossMaxYear) yield {
$"data.lossYear"
.getItem(i)
.getItem("grossEmissionsCo2eCo2Only") as s"gfw_forest_carbon_gross_emissions_co2_only_${i}__Mg"
}).toList
} else {
List()
}

val totalGrossEmissionsCo2eNonCo2Cols = if (emisGasAnnual) {
(for (i <- treecoverLossMinYear to treecoverLossMaxYear) yield {
$"data.lossYear"
.getItem(i)
.getItem("grossEmissionsCo2eNonCo2") as s"gfw_forest_carbon_gross_emissions_non_co2_${i}__Mg"
}).toList
} else {
List()
}


df.select(
cols ::: carbonPoolCols ::: treecoverLossCols ::: abovegroundBiomassLossCols ::: totalGrossEmissionsCo2eAllGasesCols : _*
cols ::: carbonPoolCols ::: treecoverLossCols ::: abovegroundBiomassLossCols
::: totalGrossEmissionsCo2eAllGasesCols ::: totalGrossEmissionsCo2Co2OnlyCols ::: totalGrossEmissionsCo2eNonCo2Cols : _*
)

}
Expand All @@ -84,16 +105,20 @@ object TreeLossDF {
includeGlobalPeat: Boolean,
includeTclDriverClass: Boolean,
carbonPools: Boolean,
simpleAGBEmis: Boolean
simpleAGBEmis: Boolean,
emisGasAnnual: Boolean
)(df: DataFrame): DataFrame = {

val spark: SparkSession = df.sparkSession
import spark.implicits._



val treecoverLossCols =
(for (i <- treecoverLossMinYear to treecoverLossMaxYear) yield {
sum(s"umd_tree_cover_loss_${i}__ha") as s"umd_tree_cover_loss_${i}__ha"
}).toList

val abovegroundBiomassLossCols = if (simpleAGBEmis) {
(for (i <- treecoverLossMinYear to treecoverLossMaxYear) yield {
sum(s"whrc_aboveground_biomass_loss_${i}__Mg") as s"whrc_aboveground_biomass_loss_${i}__Mg"
Expand All @@ -107,6 +132,22 @@ object TreeLossDF {
sum(s"gfw_gross_emissions_co2e_all_gases_${i}__Mg") as s"gfw_gross_emissions_co2e_all_gases_${i}__Mg"
}).toList

val totalGrossEmissionsCo2Co2OnlyCols = if (emisGasAnnual) {
(for (i <- treecoverLossMinYear to treecoverLossMaxYear) yield {
sum(s"gfw_forest_carbon_gross_emissions_co2_only_${i}__Mg") as s"gfw_forest_carbon_gross_emissions_co2_only_${i}__Mg"
}).toList
} else {
List()
}

val totalGrossEmissionsCo2eNonCo2Cols = if (emisGasAnnual) {
(for (i <- treecoverLossMinYear to treecoverLossMaxYear) yield {
sum(s"gfw_forest_carbon_gross_emissions_non_co2_${i}__Mg") as s"gfw_forest_carbon_gross_emissions_non_co2_${i}__Mg"
}).toList
} else {
List()
}

val cols = List(
sum("area__ha") as "area__ha",
sum("umd_tree_cover_extent_2000__ha") as "umd_tree_cover_extent_2000__ha",
Expand Down Expand Up @@ -173,7 +214,8 @@ object TreeLossDF {
df.groupBy(groupByCols ::: pfGroupByCol ::: plGroupByCol ::: ptGroupByCol ::: drGroupByCol : _*)
.agg(
cols.head,
cols.tail ::: carbonPoolCols ::: treecoverLossCols ::: abovegroundBiomassLossCols ::: totalGrossEmissionsCo2eAllGasesCols: _*
cols.tail ::: carbonPoolCols ::: treecoverLossCols ::: abovegroundBiomassLossCols
::: totalGrossEmissionsCo2eAllGasesCols ::: totalGrossEmissionsCo2Co2OnlyCols ::: totalGrossEmissionsCo2eNonCo2Cols : _*
)

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,15 @@ object TreeLossExport extends SummaryExport {
val simpleAGBEmis: Boolean =
getAnyMapValue[Boolean](kwargs, "simpleAGBEmis")

val emisGasAnnual: Boolean =
getAnyMapValue[Boolean](kwargs, "emisGasAnnual")


summaryDF
.transform(TreeLossDF.unpackValues(carbonPools, simpleAGBEmis))
.transform(TreeLossDF.unpackValues(carbonPools, simpleAGBEmis, emisGasAnnual))
.transform(TreeLossDF.contextualLayerFilter(
includePrimaryForest, includePlantations, includeGlobalPeat, includeTclDriverClass,
carbonPools, simpleAGBEmis))
carbonPools, simpleAGBEmis, emisGasAnnual))
.coalesce(1)
.orderBy($"feature__id", $"umd_tree_cover_density__threshold")
.write
Expand Down

0 comments on commit 4cbf760

Please sign in to comment.