From 820cea6680140e515d1cb2e34894abc83eb0e8ee Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Tue, 15 Nov 2022 15:06:40 -0800 Subject: [PATCH 01/22] Add TML layers --- src/main/resources/raster-catalog-default.json | 8 ++++++++ .../layers/TreesInMosaicLandscapes.scala | 11 +++++++++++ .../globalforestwatch/layers/UmdGlobalLandcover.scala | 11 +++++++++++ .../annualupdate_minimal/AnnualUpdateMinimalDF.scala | 4 ++++ .../AnnualUpdateMinimalDataGroup.scala | 2 ++ .../AnnualUpdateMinimalGridSources.scala | 6 ++++++ .../AnnualUpdateMinimalSummary.scala | 6 ++++++ .../AnnualUpdateMinimalTile.scala | 2 ++ 8 files changed, 50 insertions(+) create mode 100644 src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala create mode 100644 src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala diff --git a/src/main/resources/raster-catalog-default.json b/src/main/resources/raster-catalog-default.json index 638bcc30..596a56c5 100644 --- a/src/main/resources/raster-catalog-default.json +++ b/src/main/resources/raster-catalog-default.json @@ -352,6 +352,14 @@ { "name":"umd_tree_cover_loss_from_fires", "source_uri": "s3://gfw-data-lake/umd_tree_cover_loss_from_fires/v20220324/raster/epsg-4326/10/40000/year/geotiff/{tile_id}.tif" + }, + { + "name":"wri_trees_in_mosaic_landscapes", + "source_uri": "s3://gfw-data-lake/wri_trees_in_mosaic_landscapes/v20220922.1/raster/epsg-4326/{grid_size}/{row_count}/decile/geotiff/{tile_id}.tif" + }, + { + "name":"umd_land_cover", + "source_uri": "s3://gfw-data-lake/umd_land_cover/v2020/raster/epsg-4326/{grid_size}/{row_count}/class/geotiff/{tile_id}.tif" } ] } \ No newline at end of file diff --git a/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala b/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala new file mode 100644 index 00000000..703d7ed2 --- /dev/null +++ b/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala @@ -0,0 +1,11 @@ +package org.globalforestwatch.layers + +import org.globalforestwatch.grids.GridTile + +case class TreesInMosaicLandscapes(gridTile: GridTile, kwargs: Map[String, Any]) + extends IntegerLayer + with OptionalILayer { + val datasetName = "wri_trees_in_mosaic_landscapes" + val uri: String = + uriForGrid(gridTile) +} diff --git a/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala b/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala new file mode 100644 index 00000000..a550f222 --- /dev/null +++ b/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala @@ -0,0 +1,11 @@ +package org.globalforestwatch.layers + +import org.globalforestwatch.grids.GridTile + +case class UmdGlobalLandcover(gridTile: GridTile, kwargs: Map[String, Any]) + extends IntegerLayer + with OptionalILayer { + val datasetName = "umd_land_cover" + val uri: String = + uriForGrid(gridTile) +} diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala index a47a796f..b7599d0b 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala @@ -27,6 +27,8 @@ object AnnualUpdateMinimalDF { "is__umd_tree_cover_gain", "forest_age__category", "is__ifl_intact_forest_landscapes_2000", + "wri_trees_in_mosaic_landscapes__threshold", + "umd_global_land_cover__class", // TODO delete next data update "umd_tree_cover_density__threshold", @@ -75,6 +77,8 @@ object AnnualUpdateMinimalDF { $"data_group.isGain" as "is__umd_tree_cover_gain", $"data_group.forestAge" as "forest_age__category", $"data_group.intactForestLandscapes2000" as "is__ifl_intact_forest_landscapes_2000", + $"data_group.tmlDensity" as "wri_trees_in_mosaic_landscapes__threshold", + $"data_group.landCover" as "umd_global_land_cover__class", $"data.treecoverExtent2000" as "umd_tree_cover_extent_2000__ha", $"data.treecoverExtent2010" as "umd_tree_cover_extent_2010__ha", diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDataGroup.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDataGroup.scala index 6bd37d00..04d8a214 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDataGroup.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDataGroup.scala @@ -22,4 +22,6 @@ case class AnnualUpdateMinimalDataGroup(lossYear: Integer, isGain: Boolean, forestAge: String, intactForestLandscapes2000: Boolean, + landCover: Int, + tmlDensity: Int ) diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala index 765ebf1d..b1d5f580 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala @@ -42,6 +42,8 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String val forestAge: ForestAgeCategory = ForestAgeCategory(gridTile, kwargs = kwargs) val intactForestLandscapes2000: IntactForestLandscapes2000 = IntactForestLandscapes2000(gridTile, kwargs) val treeCoverLossFromFires: TreeCoverLossFromFires = TreeCoverLossFromFires(gridTile, kwargs) + val treesInMosaicLandscapes: TreesInMosaicLandscapes = TreesInMosaicLandscapes(gridTile, kwargs) + val umdGlobalLandCover: UmdGlobalLandcover = UmdGlobalLandcover(gridTile, kwargs) def readWindow( windowKey: SpatialKey, windowLayout: LayoutDefinition @@ -88,6 +90,8 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String val forestAgeTile = forestAge.fetchWindow(windowKey, windowLayout) val intactForestLandscapes2000Tile = intactForestLandscapes2000.fetchWindow(windowKey, windowLayout) val treeCoverLossFromFiresTile = treeCoverLossFromFires.fetchWindow(windowKey, windowLayout) + val treesInMosaicLandscapesTile = treesInMosaicLandscapes.fetchWindow(windowKey, windowLayout) + val umdGlobalLandCoverTile = umdGlobalLandCover.fetchWindow(windowKey, windowLayout) val tile = AnnualUpdateMinimalTile( lossTile, @@ -121,6 +125,8 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String forestAgeTile, intactForestLandscapes2000Tile, treeCoverLossFromFiresTile, + treesInMosaicLandscapesTile, + umdGlobalLandCoverTile, ) Raster(tile, windowKey.extent(windowLayout)) diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala index 71bc355f..ca576d01 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala @@ -69,6 +69,10 @@ object AnnualUpdateMinimalSummary { raster.tile.intactForestLandscapes2000.getData(col, row) val treeCoverLossFromFires: Boolean = raster.tile.treeCoverLossFromFires.getData(col, row) + val treesInMosaicLandscapes: Int = + raster.tile.treesInMosaicLandscapes.getData(col, row) + val umdGlobalLandCover: Int = + raster.tile.umdGlobalLandCover.getData(col, row) val lat: Double = raster.rasterExtent.gridRowToMap(row) val area: Double = Geodesy.pixelArea(lat, raster.cellSize) // uses Pixel's center coordiate. +- raster.cellSize.height/2 doesn't make much of a difference @@ -131,6 +135,8 @@ object AnnualUpdateMinimalSummary { gain, forestAge, intactForestLandscapes2000, + treesInMosaicLandscapes, + umdGlobalLandCover, ) val summary: AnnualUpdateMinimalData = diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala index bcc9f0d3..a0a743d5 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala @@ -40,6 +40,8 @@ case class AnnualUpdateMinimalTile( forestAge: ForestAgeCategory#OptionalITile, intactForestLandscapes2000: IntactForestLandscapes2000#OptionalITile, treeCoverLossFromFires: TreeCoverLossFromFires#OptionalITile, + treesInMosaicLandscapes: TreesInMosaicLandscapes#OptionalITile, + umdGlobalLandCover: UmdGlobalLandcover#OptionalITile, ) extends CellGrid[Int] { def cellType: CellType = loss.cellType def cols: Int = loss.cols From 886a238dd6c319604269088729185e09bdd5b8ad Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Tue, 15 Nov 2022 15:39:16 -0800 Subject: [PATCH 02/22] Map specific values for TML --- .../layers/TreesInMosaicLandscapes.scala | 15 +++++++++++++++ .../layers/UmdGlobalLandcover.scala | 9 +++++++++ 2 files changed, 24 insertions(+) diff --git a/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala b/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala index 703d7ed2..3365061c 100644 --- a/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala +++ b/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala @@ -8,4 +8,19 @@ case class TreesInMosaicLandscapes(gridTile: GridTile, kwargs: Map[String, Any]) val datasetName = "wri_trees_in_mosaic_landscapes" val uri: String = uriForGrid(gridTile) + + override def lookup(value: Int): Integer = { + value match { + case v if v <= 10 => 0 + case v if v <= 20 => 10 + case v if v <= 30 => 20 + case v if v <= 40 => 30 + case v if v <= 50 => 40 + case v if v <= 60 => 50 + case v if v <= 70 => 60 + case v if v <= 80 => 70 + case v if v <= 90 => 80 + case v if v <= 100 => 90 + } + } } diff --git a/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala b/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala index a550f222..b194ca3b 100644 --- a/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala +++ b/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala @@ -8,4 +8,13 @@ case class UmdGlobalLandcover(gridTile: GridTile, kwargs: Map[String, Any]) val datasetName = "umd_land_cover" val uri: String = uriForGrid(gridTile) + + override def lookup(value: Int): Integer = { + value match { + case v if v <= 50 => 1 + case v if v <= 100 => 2 + case v if v <= 150 => 3 + case _ => 4 + } + } } From bfd580d90867fe27a9f82ff267febfd3308c37fc Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Tue, 22 Nov 2022 12:19:35 -0800 Subject: [PATCH 03/22] Split TCD and TML into separate rows --- .../AnnualUpdateMinimalSummary.scala | 89 +++++++++---------- 1 file changed, 41 insertions(+), 48 deletions(-) diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala index ca576d01..0cdd07a3 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala @@ -103,18 +103,13 @@ object AnnualUpdateMinimalSummary { val grossEmissionsCo2ePixel = grossEmissionsCo2e * areaHa val totalCarbonSoil = soilCarbonPerHa * areaHa - val thresholds = List(0, 10, 15, 20, 25, 30, 50, 75) - - @tailrec def updateSummary( - thresholds: List[Int], + loss: Integer, tcd2000: Integer, treesInMosaicLandscapes: Integer, umdGlobalLandCover: Integer, stats: Map[AnnualUpdateMinimalDataGroup, AnnualUpdateMinimalData] ): Map[AnnualUpdateMinimalDataGroup, AnnualUpdateMinimalData] = { - if (thresholds == Nil) stats - else { val pKey = AnnualUpdateMinimalDataGroup( loss, - thresholds.head, + tcd2000, drivers, primaryForest, wdpa, @@ -148,57 +143,55 @@ object AnnualUpdateMinimalSummary { summary.totalArea += areaHa summary.totalGainArea += gainArea - if (tcd2000 >= thresholds.head) { - if (loss != null) { - summary.treecoverLoss += areaHa - summary.biomassLoss += biomassPixel - summary.co2Emissions += co2Pixel - summary.totalGrossEmissionsCo2eCo2Only += grossEmissionsCo2eCo2OnlyPixel - summary.totalGrossEmissionsCo2eNonCo2 += grossEmissionsCo2eNonCo2Pixel - summary.totalGrossEmissionsCo2e += grossEmissionsCo2ePixel - - if (treeCoverLossFromFires) { - summary.treeCoverLossFromFires += areaHa - } - } + if (loss != null) { + summary.treecoverLoss += areaHa + summary.biomassLoss += biomassPixel + summary.co2Emissions += co2Pixel + summary.totalGrossEmissionsCo2eCo2Only += grossEmissionsCo2eCo2OnlyPixel + summary.totalGrossEmissionsCo2eNonCo2 += grossEmissionsCo2eNonCo2Pixel + summary.totalGrossEmissionsCo2e += grossEmissionsCo2ePixel - summary.treecoverExtent2000 += areaHa - summary.totalBiomass += biomassPixel - summary.totalCo2 += co2Pixel - summary.totalGrossCumulAbovegroundRemovalsCo2 += grossCumulAbovegroundRemovalsCo2Pixel - summary.totalGrossCumulBelowgroundRemovalsCo2 += grossCumulBelowgroundRemovalsCo2Pixel - summary.totalGrossCumulAboveBelowgroundRemovalsCo2 += grossCumulAboveBelowgroundRemovalsCo2Pixel - summary.totalNetFluxCo2 += netFluxCo2Pixel - summary.totalSoilCarbon += totalCarbonSoil - } else if (gain) { - // Adds the gain pixels that don't have any tree cover density to the flux model outputs to get - // the correct flux model outputs (TCD>=threshold OR Hansen gain=TRUE) - summary.totalGrossCumulAbovegroundRemovalsCo2 += grossCumulAbovegroundRemovalsCo2Pixel - summary.totalGrossCumulBelowgroundRemovalsCo2 += grossCumulBelowgroundRemovalsCo2Pixel - summary.totalGrossCumulAboveBelowgroundRemovalsCo2 += grossCumulAboveBelowgroundRemovalsCo2Pixel - - summary.totalNetFluxCo2 += netFluxCo2Pixel - - if (loss != null) { - summary.totalGrossEmissionsCo2eCo2Only += grossEmissionsCo2eCo2OnlyPixel - summary.totalGrossEmissionsCo2eNonCo2 += grossEmissionsCo2eNonCo2Pixel - summary.totalGrossEmissionsCo2e += grossEmissionsCo2ePixel + if (treeCoverLossFromFires) { + summary.treeCoverLossFromFires += areaHa } } - if (tcd2010 >= thresholds.head) { - summary.treecoverExtent2010 += areaHa + summary.treecoverExtent2000 += areaHa + summary.totalBiomass += biomassPixel + summary.totalCo2 += co2Pixel + summary.totalGrossCumulAbovegroundRemovalsCo2 += grossCumulAbovegroundRemovalsCo2Pixel + summary.totalGrossCumulBelowgroundRemovalsCo2 += grossCumulBelowgroundRemovalsCo2Pixel + summary.totalGrossCumulAboveBelowgroundRemovalsCo2 += grossCumulAboveBelowgroundRemovalsCo2Pixel + summary.totalNetFluxCo2 += netFluxCo2Pixel + summary.totalSoilCarbon += totalCarbonSoil + + // Adds the gain pixels that don't have any tree cover density to the flux model outputs to get + // the correct flux model outputs (TCD>=threshold OR Hansen gain=TRUE) + summary.totalGrossCumulAbovegroundRemovalsCo2 += grossCumulAbovegroundRemovalsCo2Pixel + summary.totalGrossCumulBelowgroundRemovalsCo2 += grossCumulBelowgroundRemovalsCo2Pixel + summary.totalGrossCumulAboveBelowgroundRemovalsCo2 += grossCumulAboveBelowgroundRemovalsCo2Pixel + + summary.totalNetFluxCo2 += netFluxCo2Pixel + + if (loss != null) { + summary.totalGrossEmissionsCo2eCo2Only += grossEmissionsCo2eCo2OnlyPixel + summary.totalGrossEmissionsCo2eNonCo2 += grossEmissionsCo2eNonCo2Pixel + summary.totalGrossEmissionsCo2e += grossEmissionsCo2ePixel } - updateSummary(thresholds.tail, stats.updated(pKey, summary)) + summary.treecoverExtent2010 += areaHa + + stats.updated(pKey, summary) } - } - val updatedSummary + val lossSummary : Map[AnnualUpdateMinimalDataGroup, AnnualUpdateMinimalData] = - updateSummary(thresholds, acc.stats) + updateSummary(loss, tcd2000, -1, -1, acc.stats) + + val tmlSummary = + updateSummary(-1, -1, treesInMosaicLandscapes, umdGlobalLandCover, lossSummary) - acc = AnnualUpdateMinimalSummary(updatedSummary) + acc = AnnualUpdateMinimalSummary(tmlSummary) } } } From 7f2cf3f548b3b373f2c463572a3c49b380186756 Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Thu, 8 Dec 2022 13:55:05 -0800 Subject: [PATCH 04/22] Use TML with higher res --- src/main/resources/raster-catalog-default.json | 2 +- .../layers/TreeCoverDensity.scala | 16 +++++++++++++++- .../layers/TreesInMosaicLandscapes.scala | 18 +++++++++--------- .../AnnualUpdateMinimalExport.scala | 2 +- .../AnnualUpdateMinimalGrid.scala | 6 ++---- .../AnnualUpdateMinimalGridSources.scala | 12 ++++-------- .../AnnualUpdateMinimalSummary.scala | 2 +- .../AnnualUpdateMinimalTile.scala | 6 +++--- 8 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/main/resources/raster-catalog-default.json b/src/main/resources/raster-catalog-default.json index 596a56c5..bfe05692 100644 --- a/src/main/resources/raster-catalog-default.json +++ b/src/main/resources/raster-catalog-default.json @@ -355,7 +355,7 @@ }, { "name":"wri_trees_in_mosaic_landscapes", - "source_uri": "s3://gfw-data-lake/wri_trees_in_mosaic_landscapes/v20220922.1/raster/epsg-4326/{grid_size}/{row_count}/decile/geotiff/{tile_id}.tif" + "source_uri": "s3://gfw-data-lake/wri_trees_in_mosaic_landscapes/v20220922.4/raster/epsg-4326/{grid_size}/{row_count}/decile/geotiff/{tile_id}.tif" }, { "name":"umd_land_cover", diff --git a/src/main/scala/org/globalforestwatch/layers/TreeCoverDensity.scala b/src/main/scala/org/globalforestwatch/layers/TreeCoverDensity.scala index d70a6a73..d8ee3c9b 100644 --- a/src/main/scala/org/globalforestwatch/layers/TreeCoverDensity.scala +++ b/src/main/scala/org/globalforestwatch/layers/TreeCoverDensity.scala @@ -29,11 +29,25 @@ case class TreeCoverDensityThreshold2000(gridTile: GridTile, kwargs: Map[String, } case class TreeCoverDensityThreshold2010(gridTile: GridTile, kwargs: Map[String, Any]) - extends TreeCoverDensityThreshold { + extends IntegerLayer with OptionalILayer { val datasetName = "umd_tree_cover_density_2010" + override val externalNoDataValue: Integer = 0 val uri: String = uriForGrid(gridTile) + + override def lookup(value: Int): Integer = { + value match { + case v if v <= 10 => 0 + case v if v <= 15 => 10 + case v if v <= 20 => 15 + case v if v <= 25 => 20 + case v if v <= 30 => 25 + case v if v <= 50 => 30 + case v if v <= 75 => 50 + case _ => 75 + } + } } case class TreeCoverDensity2010_60(gridTile: GridTile, kwargs: Map[String, Any]) diff --git a/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala b/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala index 3365061c..0d42c2ac 100644 --- a/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala +++ b/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala @@ -11,15 +11,15 @@ case class TreesInMosaicLandscapes(gridTile: GridTile, kwargs: Map[String, Any]) override def lookup(value: Int): Integer = { value match { - case v if v <= 10 => 0 - case v if v <= 20 => 10 - case v if v <= 30 => 20 - case v if v <= 40 => 30 - case v if v <= 50 => 40 - case v if v <= 60 => 50 - case v if v <= 70 => 60 - case v if v <= 80 => 70 - case v if v <= 90 => 80 + case v if v < 10 => 0 + case v if v < 20 => 10 + case v if v < 30 => 20 + case v if v < 40 => 30 + case v if v < 50 => 40 + case v if v < 60 => 50 + case v if v < 70 => 60 + case v if v < 80 => 70 + case v if v < 90 => 80 case v if v <= 100 => 90 } } diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalExport.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalExport.scala index e6b3a0a7..83dcff28 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalExport.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalExport.scala @@ -85,7 +85,7 @@ object AnnualUpdateMinimalExport extends SummaryExport { val isoApiDF = adm1ApiDF.transform(AnnualUpdateMinimalDF.aggSummary2(List("iso"))) isoApiDF - .coalesce(3) // this should result in an avg file size of 100MB + .coalesce(1) // this should result in an avg file size of 100MB .write .options(csvOptions) .csv(path = outputUrl + "/iso/summary") diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGrid.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGrid.scala index a2f2b042..fe0d53c4 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGrid.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGrid.scala @@ -1,13 +1,11 @@ package org.globalforestwatch.summarystats.annualupdate_minimal import geotrellis.vector.Extent -import org.globalforestwatch.grids.{GridTile, TenByTen30mGrid} +import org.globalforestwatch.grids.{GridTile, TenByTen10mGrid} -object AnnualUpdateMinimalGrid extends TenByTen30mGrid[AnnualUpdateMinimalGridSources] { +object AnnualUpdateMinimalGrid extends TenByTen10mGrid[AnnualUpdateMinimalGridSources] { val gridExtent: Extent = Extent(-180.0000, -90.0000, 180.0000, 90.0000) def getSources(gridTile: GridTile, kwargs: Map[String, Any]) = AnnualUpdateMinimalGridSources.getCachedSources(gridTile, kwargs: Map[String, Any]) - - } diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala index b1d5f580..dfece61e 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala @@ -13,7 +13,7 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String val treeCoverLoss: TreeCoverLoss = TreeCoverLoss(gridTile, kwargs) val treeCoverGain: TreeCoverGain = TreeCoverGain(gridTile, kwargs) - val treeCoverDensity2000: TreeCoverDensityThreshold2000 = TreeCoverDensityThreshold2000(gridTile, kwargs) + val treeCoverDensity2000: TreeCoverDensityThreshold2010 = TreeCoverDensityThreshold2010(gridTile, kwargs) val treeCoverDensity2010: TreeCoverDensityThreshold2010 = TreeCoverDensityThreshold2010(gridTile, kwargs) val biomassPerHectar: BiomassPerHectar = BiomassPerHectar(gridTile, kwargs) val treeCoverLossDrivers = TreeCoverLossDrivers(gridTile, kwargs) @@ -53,15 +53,11 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String // Failure for any of these reads will result in function returning Left[Throwable] // These are effectively required fields without which we can't make sense of the analysis lossTile <- Either.catchNonFatal(treeCoverLoss.fetchWindow(windowKey, windowLayout)).right - tcd2000Tile <- Either - .catchNonFatal(treeCoverDensity2000.fetchWindow(windowKey, windowLayout)) - .right - tcd2010Tile <- Either - .catchNonFatal(treeCoverDensity2010.fetchWindow(windowKey, windowLayout)) - .right - } yield { + val lossTile = treeCoverLoss.fetchWindow(windowKey, windowLayout) // Failure for these will be converted to optional result and propagated with TreeLossTile + val tcd2000Tile = treeCoverDensity2000.fetchWindow(windowKey, windowLayout) + val tcd2010Tile = treeCoverDensity2010.fetchWindow(windowKey, windowLayout) val gainTile = treeCoverGain.fetchWindow(windowKey, windowLayout) val biomassTile = biomassPerHectar.fetchWindow(windowKey, windowLayout) val driversTile = treeCoverLossDrivers.fetchWindow(windowKey, windowLayout) diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala index 0cdd07a3..394f75f3 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala @@ -130,8 +130,8 @@ object AnnualUpdateMinimalSummary { gain, forestAge, intactForestLandscapes2000, - treesInMosaicLandscapes, umdGlobalLandCover, + treesInMosaicLandscapes, ) val summary: AnnualUpdateMinimalData = diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala index a0a743d5..e76b5d68 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala @@ -1,6 +1,6 @@ package org.globalforestwatch.summarystats.annualupdate_minimal -import geotrellis.raster.{CellGrid, CellType} +import geotrellis.raster.{CellGrid, CellType, UShortConstantNoDataCellType} import org.globalforestwatch.layers._ /** @@ -11,8 +11,8 @@ import org.globalforestwatch.layers._ case class AnnualUpdateMinimalTile( loss: TreeCoverLoss#ITile, gain: TreeCoverGain#OptionalITile, - tcd2000: TreeCoverDensityThreshold#ITile, - tcd2010: TreeCoverDensityThreshold#ITile, + tcd2000: TreeCoverDensityThreshold2010#OptionalITile, + tcd2010: TreeCoverDensityThreshold2010#OptionalITile, biomass: BiomassPerHectar#OptionalDTile, drivers: TreeCoverLossDrivers#OptionalITile, primaryForest: PrimaryForest#OptionalITile, From 475977b1c06109fcb6920517e4c0431f0b3bb148 Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Mon, 23 Jan 2023 11:39:08 -0800 Subject: [PATCH 05/22] Land cover --- .../globalforestwatch/layers/UmdGlobalLandcover.scala | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala b/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala index b194ca3b..abd5f196 100644 --- a/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala +++ b/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala @@ -11,10 +11,13 @@ case class UmdGlobalLandcover(gridTile: GridTile, kwargs: Map[String, Any]) override def lookup(value: Int): Integer = { value match { - case v if v <= 50 => 1 - case v if v <= 100 => 2 - case v if v <= 150 => 3 - case _ => 4 + case v if v > 0 && v <= 24 => 1 + case v if v > 24 && v <= 41 => 2 + case v if v > 41 && v <= 48 => 3 + case v if v >= 100 && v <= 124 => 4 + case v if v > 124 && v <= 148 => 5 + case v if v >= 202 && v <= 207 => 6 + case _ => 0 } } } From ed9b31aa3fe0c378f6febfdef7c3ae4766ca92c6 Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Mon, 23 Jan 2023 18:26:58 -0800 Subject: [PATCH 06/22] Use correct land cover mapping --- src/main/resources/raster-catalog-default.json | 2 +- .../layers/UmdGlobalLandcover.scala | 18 +++++++++--------- .../AnnualUpdateMinimalDataGroup.scala | 2 +- .../AnnualUpdateMinimalExport.scala | 2 +- .../AnnualUpdateMinimalGrid.scala | 4 ++-- .../AnnualUpdateMinimalSummary.scala | 6 +++--- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/resources/raster-catalog-default.json b/src/main/resources/raster-catalog-default.json index bfe05692..baf185bf 100644 --- a/src/main/resources/raster-catalog-default.json +++ b/src/main/resources/raster-catalog-default.json @@ -355,7 +355,7 @@ }, { "name":"wri_trees_in_mosaic_landscapes", - "source_uri": "s3://gfw-data-lake/wri_trees_in_mosaic_landscapes/v20220922.4/raster/epsg-4326/{grid_size}/{row_count}/decile/geotiff/{tile_id}.tif" + "source_uri": "s3://gfw-data-lake/wri_tropical_tree_cover/v2020/raster/epsg-4326/{grid_size}/{row_count}/percent/geotiff/{tile_id}.tif" }, { "name":"umd_land_cover", diff --git a/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala b/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala index abd5f196..e1953a72 100644 --- a/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala +++ b/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala @@ -3,21 +3,21 @@ package org.globalforestwatch.layers import org.globalforestwatch.grids.GridTile case class UmdGlobalLandcover(gridTile: GridTile, kwargs: Map[String, Any]) - extends IntegerLayer + extends StringLayer with OptionalILayer { val datasetName = "umd_land_cover" val uri: String = uriForGrid(gridTile) - override def lookup(value: Int): Integer = { + override def lookup(value: Int): String = { value match { - case v if v > 0 && v <= 24 => 1 - case v if v > 24 && v <= 41 => 2 - case v if v > 41 && v <= 48 => 3 - case v if v >= 100 && v <= 124 => 4 - case v if v > 124 && v <= 148 => 5 - case v if v >= 202 && v <= 207 => 6 - case _ => 0 + case v if v >= 0 && v <= 24 => "Grassland" + case v if (v >= 25 && v <= 96) || (v >= 125 && v <= 196) => "Forest" + case v if v >= 100 && v <= 124 => "Wetlands" + case v if v >= 244 && v <= 247 => "Cropland" + case v if v >= 250 && v <= 253 => "Built-Up Area" + case v if (v >= 200 && v <= 215) || (v >= 241 && v <= 243) || v == 254 => "Other" + case _ => "Unknown" } } } diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDataGroup.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDataGroup.scala index 04d8a214..60e55311 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDataGroup.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDataGroup.scala @@ -22,6 +22,6 @@ case class AnnualUpdateMinimalDataGroup(lossYear: Integer, isGain: Boolean, forestAge: String, intactForestLandscapes2000: Boolean, - landCover: Int, + landCover: String, tmlDensity: Int ) diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalExport.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalExport.scala index 83dcff28..e6b3a0a7 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalExport.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalExport.scala @@ -85,7 +85,7 @@ object AnnualUpdateMinimalExport extends SummaryExport { val isoApiDF = adm1ApiDF.transform(AnnualUpdateMinimalDF.aggSummary2(List("iso"))) isoApiDF - .coalesce(1) // this should result in an avg file size of 100MB + .coalesce(3) // this should result in an avg file size of 100MB .write .options(csvOptions) .csv(path = outputUrl + "/iso/summary") diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGrid.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGrid.scala index fe0d53c4..3d435c8a 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGrid.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGrid.scala @@ -1,9 +1,9 @@ package org.globalforestwatch.summarystats.annualupdate_minimal import geotrellis.vector.Extent -import org.globalforestwatch.grids.{GridTile, TenByTen10mGrid} +import org.globalforestwatch.grids.{GridTile, TenByTen10mGrid, TenByTen30mGrid} -object AnnualUpdateMinimalGrid extends TenByTen10mGrid[AnnualUpdateMinimalGridSources] { +object AnnualUpdateMinimalGrid extends TenByTen30mGrid[AnnualUpdateMinimalGridSources] { val gridExtent: Extent = Extent(-180.0000, -90.0000, 180.0000, 90.0000) diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala index 394f75f3..92b46694 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala @@ -71,7 +71,7 @@ object AnnualUpdateMinimalSummary { raster.tile.treeCoverLossFromFires.getData(col, row) val treesInMosaicLandscapes: Int = raster.tile.treesInMosaicLandscapes.getData(col, row) - val umdGlobalLandCover: Int = + val umdGlobalLandCover: String = raster.tile.umdGlobalLandCover.getData(col, row) val lat: Double = raster.rasterExtent.gridRowToMap(row) @@ -104,7 +104,7 @@ object AnnualUpdateMinimalSummary { val totalCarbonSoil = soilCarbonPerHa * areaHa def updateSummary( - loss: Integer, tcd2000: Integer, treesInMosaicLandscapes: Integer, umdGlobalLandCover: Integer, + loss: Integer, tcd2000: Integer, treesInMosaicLandscapes: Integer, umdGlobalLandCover: String, stats: Map[AnnualUpdateMinimalDataGroup, AnnualUpdateMinimalData] ): Map[AnnualUpdateMinimalDataGroup, AnnualUpdateMinimalData] = { val pKey = AnnualUpdateMinimalDataGroup( @@ -186,7 +186,7 @@ object AnnualUpdateMinimalSummary { val lossSummary : Map[AnnualUpdateMinimalDataGroup, AnnualUpdateMinimalData] = - updateSummary(loss, tcd2000, -1, -1, acc.stats) + updateSummary(loss, tcd2000, -1, "", acc.stats) val tmlSummary = updateSummary(-1, -1, treesInMosaicLandscapes, umdGlobalLandCover, lossSummary) From a122f6d269d0a491377d041cd44dcd0b63f3c5e2 Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Tue, 24 Jan 2023 17:18:47 -0800 Subject: [PATCH 07/22] Add field for extent --- .../annualupdate_minimal/AnnualUpdateMinimalDF.scala | 5 ++++- .../annualupdate_minimal/AnnualUpdateMinimalData.scala | 2 ++ .../annualupdate_minimal/AnnualUpdateMinimalSummary.scala | 6 +++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala index 013bfc13..4d161018 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala @@ -98,6 +98,7 @@ object AnnualUpdateMinimalDF { $"data.totalSoilCarbon" as "gfw_soil_carbon_stocks_2000__Mg_C", $"data.totalGrossCumulAboveBelowgroundRemovalsCo2" as "gfw_full_extent_gross_removals__Mg_CO2", $"data.treeCoverLossFromFires" as "umd_tree_cover_loss_from_fires__ha", + $"data.tropicalTreeCoverExtent" as "wri_tropical_tree_cover_extent__ha", $"data_group.threshold" as "umd_tree_cover_density__threshold", $"data_group.drivers" as "tsc_tree_cover_loss_drivers__type", @@ -164,7 +165,7 @@ object AnnualUpdateMinimalDF { sum("gfw_full_extent_gross_emissions__Mg_CO2e") as "gfw_full_extent_gross_emissions__Mg_CO2e", sum("gfw_soil_carbon_stocks_2000__Mg_C") as "gfw_soil_carbon_stocks_2000__Mg_C", sum("umd_tree_cover_loss_from_fires__ha") as "umd_tree_cover_loss_from_fires__ha", - + sum("wri_tropical_tree_cover_extent__ha") as "wri_tropical_tree_cover_extent__ha", sum("umd_tree_cover_gain_2000-2012__ha") as "umd_tree_cover_gain_2000-2012__ha", sum("gfw_gross_cumulative_aboveground_belowground_co2_removals__Mg") as "gfw_gross_cumulative_aboveground_belowground_co2_removals__Mg", sum("gfw_net_flux_co2e__Mg") as "gfw_net_flux_co2e__Mg", @@ -202,6 +203,7 @@ object AnnualUpdateMinimalDF { sum("gfw_full_extent_gross_emissions__Mg_CO2e") as "gfw_full_extent_gross_emissions__Mg_CO2e", sum("gfw_soil_carbon_stocks_2000__Mg_C") as "gfw_soil_carbon_stocks_2000__Mg_C", sum("umd_tree_cover_loss_from_fires__ha") as "umd_tree_cover_loss_from_fires__ha", + sum("wri_tropical_tree_cover_extent__ha") as "wri_tropical_tree_cover_extent__ha", sum("umd_tree_cover_gain_2000-2012__ha") as "umd_tree_cover_gain_2000-2012__ha", sum("gfw_gross_cumulative_aboveground_belowground_co2_removals__Mg") as "gfw_gross_cumulative_aboveground_belowground_co2_removals__Mg", @@ -231,6 +233,7 @@ object AnnualUpdateMinimalDF { sum("gfw_full_extent_gross_emissions__Mg_CO2e") as "gfw_full_extent_gross_emissions__Mg_CO2e", sum("gfw_gross_emissions_co2e_all_gases__Mg") as "gfw_gross_emissions_co2e_all_gases__Mg", sum("umd_tree_cover_loss_from_fires__ha") as "umd_tree_cover_loss_from_fires__ha", + sum("wri_tropical_tree_cover_extent__ha") as "wri_tropical_tree_cover_extent__ha", ) } diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalData.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalData.scala index 29f498f3..b8eb09c9 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalData.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalData.scala @@ -26,6 +26,7 @@ case class AnnualUpdateMinimalData(var treecoverLoss: Double, var totalCo2: Double, var totalSoilCarbon: Double, var treeCoverLossFromFires: Double, + var tropicalTreeCoverExtent: Double, ) { def merge(other: AnnualUpdateMinimalData): AnnualUpdateMinimalData = { AnnualUpdateMinimalData( @@ -49,6 +50,7 @@ case class AnnualUpdateMinimalData(var treecoverLoss: Double, totalCo2 + other.totalCo2, totalSoilCarbon + other.totalSoilCarbon, treeCoverLossFromFires + other.treeCoverLossFromFires, + tropicalTreeCoverExtent + other.tropicalTreeCoverExtent, ) } } diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala index e2a325e7..4ccb7bb0 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala @@ -139,7 +139,7 @@ object AnnualUpdateMinimalSummary { val summary: AnnualUpdateMinimalData = stats.getOrElse( key = pKey, - default = AnnualUpdateMinimalData(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + default = AnnualUpdateMinimalData(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) ) summary.totalArea += areaHa @@ -183,6 +183,10 @@ object AnnualUpdateMinimalSummary { summary.treecoverExtent2010 += areaHa + if (treesInMosaicLandscapes > 0) { + summary.tropicalTreeCoverExtent += areaHa + } + stats.updated(pKey, summary) } From 8517403f6b37cafd0494aad269b323bb0a02f18f Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Fri, 27 Jan 2023 11:32:23 -0800 Subject: [PATCH 08/22] Adjust column names --- .../AnnualUpdateMinimalDF.scala | 2 +- .../AnnualUpdateMinimalSummary.scala | 97 ++++++++++--------- 2 files changed, 54 insertions(+), 45 deletions(-) diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala index 4d161018..340674c1 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala @@ -78,7 +78,7 @@ object AnnualUpdateMinimalDF { $"data_group.forestAge" as "forest_age__category", $"data_group.intactForestLandscapes2000" as "is__ifl_intact_forest_landscapes_2000", $"data_group.tmlDensity" as "wri_tropical_tree_cover__decile", - $"data_group.landCover" as "umd_global_land_cover__class", + $"data_group.landCover" as "umd_global_land_cover__ipcc_class", $"data.treecoverExtent2000" as "umd_tree_cover_extent_2000__ha", $"data.treecoverExtent2010" as "umd_tree_cover_extent_2010__ha", diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala index 4ccb7bb0..d370902f 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala @@ -106,45 +106,46 @@ object AnnualUpdateMinimalSummary { val totalCarbonSoil = soilCarbonPerHa * areaHa def updateSummary( - loss: Integer, tcd2000: Integer, treesInMosaicLandscapes: Integer, umdGlobalLandCover: String, + loss: Integer, tcd2000: Integer, tcdThreshold: Integer, treesInMosaicLandscapes: Integer, umdGlobalLandCover: String, stats: Map[AnnualUpdateMinimalDataGroup, AnnualUpdateMinimalData] ): Map[AnnualUpdateMinimalDataGroup, AnnualUpdateMinimalData] = { - val pKey = AnnualUpdateMinimalDataGroup( - loss, - tcd2000, - drivers, - primaryForest, - wdpa, - aze, - plantedForests, - mangroves1996, - mangroves2016, - tigerLandscapes, - landmark, - keyBiodiversityAreas, - mining, - peatlands, - oilPalm, - idnForestMoratorium, - woodFiber, - resourceRights, - logging, - gain, - forestAge, - intactForestLandscapes2000, - umdGlobalLandCover, - treesInMosaicLandscapes, + val pKey = AnnualUpdateMinimalDataGroup( + loss, + tcdThreshold, + drivers, + primaryForest, + wdpa, + aze, + plantedForests, + mangroves1996, + mangroves2016, + tigerLandscapes, + landmark, + keyBiodiversityAreas, + mining, + peatlands, + oilPalm, + idnForestMoratorium, + woodFiber, + resourceRights, + logging, + gain, + forestAge, + intactForestLandscapes2000, + umdGlobalLandCover, + treesInMosaicLandscapes, + ) + + val summary: AnnualUpdateMinimalData = + stats.getOrElse( + key = pKey, + default = AnnualUpdateMinimalData(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) ) - val summary: AnnualUpdateMinimalData = - stats.getOrElse( - key = pKey, - default = AnnualUpdateMinimalData(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - ) - - summary.totalArea += areaHa - summary.totalGainArea += gainArea + summary.totalArea += areaHa + summary.totalGainArea += gainArea + if (tcd2000 >= tcdThreshold) { if (loss != null) { summary.treecoverLoss += areaHa summary.biomassLoss += biomassPixel @@ -166,7 +167,8 @@ object AnnualUpdateMinimalSummary { summary.totalGrossCumulAboveBelowgroundRemovalsCo2 += grossCumulAboveBelowgroundRemovalsCo2Pixel summary.totalNetFluxCo2 += netFluxCo2Pixel summary.totalSoilCarbon += totalCarbonSoil - + } + else if (gain) { // Adds the gain pixels that don't have any tree cover density to the flux model outputs to get // the correct flux model outputs (TCD>=threshold OR Hansen gain=TRUE) summary.totalGrossCumulAbovegroundRemovalsCo2 += grossCumulAbovegroundRemovalsCo2Pixel @@ -180,24 +182,31 @@ object AnnualUpdateMinimalSummary { summary.totalGrossEmissionsCo2eNonCo2 += grossEmissionsCo2eNonCo2Pixel summary.totalGrossEmissionsCo2e += grossEmissionsCo2ePixel } + } + if (tcd2010 >= tcdThreshold) { summary.treecoverExtent2010 += areaHa + } - if (treesInMosaicLandscapes > 0) { - summary.tropicalTreeCoverExtent += areaHa - } - - stats.updated(pKey, summary) + if (treesInMosaicLandscapes >= 0) { + summary.tropicalTreeCoverExtent += areaHa } + stats.updated(pKey, summary) + } + + val umdTcdThresholds = List(0, 10, 15, 20, 25, 30, 50, 75) + val lossSummary : Map[AnnualUpdateMinimalDataGroup, AnnualUpdateMinimalData] = - updateSummary(loss, tcd2000, -1, "", acc.stats) + umdTcdThresholds.foldLeft(acc.stats) { (stats, threshold) => + updateSummary(loss, tcd2000, threshold, -1, "", stats) + } - val tmlSummary = - updateSummary(-1, -1, treesInMosaicLandscapes, umdGlobalLandCover, lossSummary) + val ttcSummary = + updateSummary(null, -2, -1, treesInMosaicLandscapes, umdGlobalLandCover, lossSummary) - acc = AnnualUpdateMinimalSummary(tmlSummary) + acc = AnnualUpdateMinimalSummary(ttcSummary) } } } From 5485818816539b3a4ab047198272d1050eec0084 Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Fri, 27 Jan 2023 13:26:58 -0800 Subject: [PATCH 09/22] Fix issues with TCD --- .../layers/TreeCoverDensity.scala | 16 +--------------- .../layers/TreesInMosaicLandscapes.scala | 18 +++++++++--------- .../AnnualUpdateMinimalDF.scala | 2 +- .../AnnualUpdateMinimalGrid.scala | 2 +- .../AnnualUpdateMinimalGridSources.scala | 12 ++++++++---- .../AnnualUpdateMinimalTile.scala | 6 +++--- 6 files changed, 23 insertions(+), 33 deletions(-) diff --git a/src/main/scala/org/globalforestwatch/layers/TreeCoverDensity.scala b/src/main/scala/org/globalforestwatch/layers/TreeCoverDensity.scala index 55436d87..eb339b8b 100644 --- a/src/main/scala/org/globalforestwatch/layers/TreeCoverDensity.scala +++ b/src/main/scala/org/globalforestwatch/layers/TreeCoverDensity.scala @@ -29,25 +29,11 @@ case class TreeCoverDensityThreshold2000(gridTile: GridTile, kwargs: Map[String, } case class TreeCoverDensityThreshold2010(gridTile: GridTile, kwargs: Map[String, Any]) - extends IntegerLayer with OptionalILayer { + extends TreeCoverDensityThreshold { val datasetName = "umd_tree_cover_density_2010" - override val externalNoDataValue: Integer = 0 val uri: String = uriForGrid(gridTile, kwargs) - - override def lookup(value: Int): Integer = { - value match { - case v if v <= 10 => 0 - case v if v <= 15 => 10 - case v if v <= 20 => 15 - case v if v <= 25 => 20 - case v if v <= 30 => 25 - case v if v <= 50 => 30 - case v if v <= 75 => 50 - case _ => 75 - } - } } case class TreeCoverDensity2010_60(gridTile: GridTile, kwargs: Map[String, Any]) diff --git a/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala b/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala index 8d1cb466..7dce56ec 100644 --- a/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala +++ b/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala @@ -11,15 +11,15 @@ case class TreesInMosaicLandscapes(gridTile: GridTile, kwargs: Map[String, Any]) override def lookup(value: Int): Integer = { value match { - case v if v < 10 => 0 - case v if v < 20 => 10 - case v if v < 30 => 20 - case v if v < 40 => 30 - case v if v < 50 => 40 - case v if v < 60 => 50 - case v if v < 70 => 60 - case v if v < 80 => 70 - case v if v < 90 => 80 + case v if v <= 10 => 0 + case v if v <= 20 => 10 + case v if v <= 30 => 20 + case v if v <= 40 => 30 + case v if v <= 50 => 40 + case v if v <= 60 => 50 + case v if v <= 70 => 60 + case v if v <= 80 => 70 + case v if v <= 90 => 80 case v if v <= 100 => 90 } } diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala index 340674c1..933c8fe7 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala @@ -28,7 +28,7 @@ object AnnualUpdateMinimalDF { "forest_age__category", "is__ifl_intact_forest_landscapes_2000", "wri_tropical_tree_cover__decile", - "umd_global_land_cover__class", + "umd_global_land_cover__ipcc_class", // TODO delete next data update "umd_tree_cover_density__threshold", diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGrid.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGrid.scala index 3d435c8a..3007d0ae 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGrid.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGrid.scala @@ -1,7 +1,7 @@ package org.globalforestwatch.summarystats.annualupdate_minimal import geotrellis.vector.Extent -import org.globalforestwatch.grids.{GridTile, TenByTen10mGrid, TenByTen30mGrid} +import org.globalforestwatch.grids.{GridTile, TenByTen30mGrid} object AnnualUpdateMinimalGrid extends TenByTen30mGrid[AnnualUpdateMinimalGridSources] { diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala index dfece61e..b1d5f580 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala @@ -13,7 +13,7 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String val treeCoverLoss: TreeCoverLoss = TreeCoverLoss(gridTile, kwargs) val treeCoverGain: TreeCoverGain = TreeCoverGain(gridTile, kwargs) - val treeCoverDensity2000: TreeCoverDensityThreshold2010 = TreeCoverDensityThreshold2010(gridTile, kwargs) + val treeCoverDensity2000: TreeCoverDensityThreshold2000 = TreeCoverDensityThreshold2000(gridTile, kwargs) val treeCoverDensity2010: TreeCoverDensityThreshold2010 = TreeCoverDensityThreshold2010(gridTile, kwargs) val biomassPerHectar: BiomassPerHectar = BiomassPerHectar(gridTile, kwargs) val treeCoverLossDrivers = TreeCoverLossDrivers(gridTile, kwargs) @@ -53,11 +53,15 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String // Failure for any of these reads will result in function returning Left[Throwable] // These are effectively required fields without which we can't make sense of the analysis lossTile <- Either.catchNonFatal(treeCoverLoss.fetchWindow(windowKey, windowLayout)).right + tcd2000Tile <- Either + .catchNonFatal(treeCoverDensity2000.fetchWindow(windowKey, windowLayout)) + .right + tcd2010Tile <- Either + .catchNonFatal(treeCoverDensity2010.fetchWindow(windowKey, windowLayout)) + .right + } yield { - val lossTile = treeCoverLoss.fetchWindow(windowKey, windowLayout) // Failure for these will be converted to optional result and propagated with TreeLossTile - val tcd2000Tile = treeCoverDensity2000.fetchWindow(windowKey, windowLayout) - val tcd2010Tile = treeCoverDensity2010.fetchWindow(windowKey, windowLayout) val gainTile = treeCoverGain.fetchWindow(windowKey, windowLayout) val biomassTile = biomassPerHectar.fetchWindow(windowKey, windowLayout) val driversTile = treeCoverLossDrivers.fetchWindow(windowKey, windowLayout) diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala index e76b5d68..a0a743d5 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala @@ -1,6 +1,6 @@ package org.globalforestwatch.summarystats.annualupdate_minimal -import geotrellis.raster.{CellGrid, CellType, UShortConstantNoDataCellType} +import geotrellis.raster.{CellGrid, CellType} import org.globalforestwatch.layers._ /** @@ -11,8 +11,8 @@ import org.globalforestwatch.layers._ case class AnnualUpdateMinimalTile( loss: TreeCoverLoss#ITile, gain: TreeCoverGain#OptionalITile, - tcd2000: TreeCoverDensityThreshold2010#OptionalITile, - tcd2010: TreeCoverDensityThreshold2010#OptionalITile, + tcd2000: TreeCoverDensityThreshold#ITile, + tcd2010: TreeCoverDensityThreshold#ITile, biomass: BiomassPerHectar#OptionalDTile, drivers: TreeCoverLossDrivers#OptionalITile, primaryForest: PrimaryForest#OptionalITile, From 9f119e5ff2d43fbd31b92cc6ef001f447152e779 Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Thu, 9 Feb 2023 09:07:27 -0800 Subject: [PATCH 10/22] Remove forest age category --- .../layers/TreesInMosaicLandscapes.scala | 18 +++++++++--------- .../AnnualUpdateMinimalDF.scala | 6 ------ .../AnnualUpdateMinimalDataGroup.scala | 1 - .../AnnualUpdateMinimalGridSources.scala | 3 --- .../AnnualUpdateMinimalSummary.scala | 2 -- .../AnnualUpdateMinimalTile.scala | 1 - 6 files changed, 9 insertions(+), 22 deletions(-) diff --git a/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala b/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala index 7dce56ec..8d1cb466 100644 --- a/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala +++ b/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala @@ -11,15 +11,15 @@ case class TreesInMosaicLandscapes(gridTile: GridTile, kwargs: Map[String, Any]) override def lookup(value: Int): Integer = { value match { - case v if v <= 10 => 0 - case v if v <= 20 => 10 - case v if v <= 30 => 20 - case v if v <= 40 => 30 - case v if v <= 50 => 40 - case v if v <= 60 => 50 - case v if v <= 70 => 60 - case v if v <= 80 => 70 - case v if v <= 90 => 80 + case v if v < 10 => 0 + case v if v < 20 => 10 + case v if v < 30 => 20 + case v if v < 40 => 30 + case v if v < 50 => 40 + case v if v < 60 => 50 + case v if v < 70 => 60 + case v if v < 80 => 70 + case v if v < 90 => 80 case v if v <= 100 => 90 } } diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala index 933c8fe7..a59c7a01 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala @@ -25,7 +25,6 @@ object AnnualUpdateMinimalDF { "is__gfw_resource_rights", "is__gfw_managed_forests", "is__umd_tree_cover_gain", - "forest_age__category", "is__ifl_intact_forest_landscapes_2000", "wri_tropical_tree_cover__decile", "umd_global_land_cover__ipcc_class", @@ -75,7 +74,6 @@ object AnnualUpdateMinimalDF { $"data_group.resourceRights" as "is__gfw_resource_rights", $"data_group.logging" as "is__gfw_managed_forests", $"data_group.isGain" as "is__umd_tree_cover_gain", - $"data_group.forestAge" as "forest_age__category", $"data_group.intactForestLandscapes2000" as "is__ifl_intact_forest_landscapes_2000", $"data_group.tmlDensity" as "wri_tropical_tree_cover__decile", $"data_group.landCover" as "umd_global_land_cover__ipcc_class", @@ -262,8 +260,6 @@ object AnnualUpdateMinimalDF { max($"is__gfw_resource_rights") as "is__gfw_resource_rights", max($"is__gfw_managed_forests") as "is__gfw_managed_forests", max($"is__umd_tree_cover_gain") as "is__umd_tree_cover_gain", - max(length($"forest_age__category")) - .cast("boolean") as "forest_age__category", max($"is__ifl_intact_forest_landscapes_2000") as "is__ifl_intact_forest_landscapes_2000", max(length($"tsc_tree_cover_loss_drivers__type")).cast("boolean") as "tsc_tree_cover_loss_drivers__type", @@ -322,8 +318,6 @@ object AnnualUpdateMinimalDF { max($"is__gfw_resource_rights") as "is__gfw_resource_rights", max($"is__gfw_managed_forests") as "is__gfw_managed_forests", max($"is__umd_tree_cover_gain") as "is__umd_tree_cover_gain", - max(length($"forest_age__category")) - .cast("boolean") as "forest_age__category", max($"is__ifl_intact_forest_landscapes_2000") as "is__ifl_intact_forest_landscapes_2000", max($"tsc_tree_cover_loss_drivers__type") as "tsc_tree_cover_loss_drivers__type", diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDataGroup.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDataGroup.scala index 60e55311..0242c922 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDataGroup.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDataGroup.scala @@ -20,7 +20,6 @@ case class AnnualUpdateMinimalDataGroup(lossYear: Integer, resourceRights: Boolean, logging: Boolean, isGain: Boolean, - forestAge: String, intactForestLandscapes2000: Boolean, landCover: String, tmlDensity: Int diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala index b1d5f580..8e74731f 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala @@ -39,7 +39,6 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String val grossEmissionsCo2eNonCo2: GrossEmissionsNonCo2Co2e = GrossEmissionsNonCo2Co2e(gridTile, kwargs = kwargs) val grossEmissionsCo2eCo2Only: GrossEmissionsCo2OnlyCo2e = GrossEmissionsCo2OnlyCo2e(gridTile, kwargs = kwargs) val soilCarbon: SoilCarbon = SoilCarbon(gridTile, kwargs = kwargs) - val forestAge: ForestAgeCategory = ForestAgeCategory(gridTile, kwargs = kwargs) val intactForestLandscapes2000: IntactForestLandscapes2000 = IntactForestLandscapes2000(gridTile, kwargs) val treeCoverLossFromFires: TreeCoverLossFromFires = TreeCoverLossFromFires(gridTile, kwargs) val treesInMosaicLandscapes: TreesInMosaicLandscapes = TreesInMosaicLandscapes(gridTile, kwargs) @@ -87,7 +86,6 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String val grossEmissionsCo2eNonCo2Tile = grossEmissionsCo2eNonCo2.fetchWindow(windowKey, windowLayout) val grossEmissionsCo2eCo2OnlyTile = grossEmissionsCo2eCo2Only.fetchWindow(windowKey, windowLayout) val soilCarbonTile = soilCarbon.fetchWindow(windowKey, windowLayout) - val forestAgeTile = forestAge.fetchWindow(windowKey, windowLayout) val intactForestLandscapes2000Tile = intactForestLandscapes2000.fetchWindow(windowKey, windowLayout) val treeCoverLossFromFiresTile = treeCoverLossFromFires.fetchWindow(windowKey, windowLayout) val treesInMosaicLandscapesTile = treesInMosaicLandscapes.fetchWindow(windowKey, windowLayout) @@ -122,7 +120,6 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String grossCumulBelowgroundRemovalsCo2Tile, netFluxCo2Tile, soilCarbonTile, - forestAgeTile, intactForestLandscapes2000Tile, treeCoverLossFromFiresTile, treesInMosaicLandscapesTile, diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala index d370902f..b932d56a 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala @@ -66,7 +66,6 @@ object AnnualUpdateMinimalSummary { val resourceRights: Boolean = raster.tile.resourceRights.getData(col, row) val logging: Boolean = raster.tile.logging.getData(col, row) - val forestAge: String = raster.tile.forestAge.getData(col, row) val intactForestLandscapes2000: Boolean = raster.tile.intactForestLandscapes2000.getData(col, row) val treeCoverLossFromFires: Boolean = @@ -130,7 +129,6 @@ object AnnualUpdateMinimalSummary { resourceRights, logging, gain, - forestAge, intactForestLandscapes2000, umdGlobalLandCover, treesInMosaicLandscapes, diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala index a0a743d5..7271bff1 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala @@ -37,7 +37,6 @@ case class AnnualUpdateMinimalTile( grossCumulBelowgroundRemovalsCo2: GrossCumulBelowgroundRemovalsCo2#OptionalFTile, netFluxCo2: NetFluxCo2e#OptionalFTile, soilCarbon: SoilCarbon#OptionalFTile, - forestAge: ForestAgeCategory#OptionalITile, intactForestLandscapes2000: IntactForestLandscapes2000#OptionalITile, treeCoverLossFromFires: TreeCoverLossFromFires#OptionalITile, treesInMosaicLandscapes: TreesInMosaicLandscapes#OptionalITile, From 302aebcdc99679ec52d8ede6a43eeeb8bf8b8d12 Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Wed, 15 Feb 2023 18:14:57 -0800 Subject: [PATCH 11/22] Read NoData properly for TML --- .../layers/TreesInMosaicLandscapes.scala | 2 ++ .../AnnualUpdateMinimalSummary.scala | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala b/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala index 8d1cb466..a9462195 100644 --- a/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala +++ b/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala @@ -6,6 +6,8 @@ case class TreesInMosaicLandscapes(gridTile: GridTile, kwargs: Map[String, Any]) extends IntegerLayer with OptionalILayer { val datasetName = "wri_trees_in_mosaic_landscapes" + override val externalNoDataValue: Integer = 255 + val uri: String = uriForGrid(gridTile, kwargs) diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala index b932d56a..1626e304 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala @@ -201,8 +201,13 @@ object AnnualUpdateMinimalSummary { updateSummary(loss, tcd2000, threshold, -1, "", stats) } - val ttcSummary = - updateSummary(null, -2, -1, treesInMosaicLandscapes, umdGlobalLandCover, lossSummary) + val ttcSummary = { + if (treesInMosaicLandscapes == 255) { + lossSummary + } else { + updateSummary(null, -2, -1, treesInMosaicLandscapes, umdGlobalLandCover, lossSummary) + } + } acc = AnnualUpdateMinimalSummary(ttcSummary) } From d8dcd8d59f2ea8c158c05f610c5d9fb5cad0264c Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Wed, 29 Mar 2023 16:19:52 -0700 Subject: [PATCH 12/22] Fix land cover --- src/main/resources/raster-catalog-default.json | 2 +- src/main/resources/raster-catalog-pro.json | 2 +- .../layers/GrossEmissionsNonCo2Co2eSoilOnly.scala | 2 +- .../layers/TreesInMosaicLandscapes.scala | 1 + .../layers/UmdGlobalLandcover.scala | 13 ++++++------- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/resources/raster-catalog-default.json b/src/main/resources/raster-catalog-default.json index baf185bf..317bdc9b 100644 --- a/src/main/resources/raster-catalog-default.json +++ b/src/main/resources/raster-catalog-default.json @@ -359,7 +359,7 @@ }, { "name":"umd_land_cover", - "source_uri": "s3://gfw-data-lake/umd_land_cover/v2020/raster/epsg-4326/{grid_size}/{row_count}/class/geotiff/{tile_id}.tif" + "source_uri": "s3://gfw-data-lake/umd_land_cover/v2020/raster/epsg-4326/{grid_size}/{row_count}/ipcc_class/geotiff/{tile_id}.tif" } ] } \ No newline at end of file diff --git a/src/main/resources/raster-catalog-pro.json b/src/main/resources/raster-catalog-pro.json index bf05a67c..c4c9ed44 100644 --- a/src/main/resources/raster-catalog-pro.json +++ b/src/main/resources/raster-catalog-pro.json @@ -298,7 +298,7 @@ }, { "name":"ifl_intact_forest_landscapes_2000", - "source_uri": "s3://gfw-data-lake/ifl_intact_forest_landscapes_2000/v2021/raster/epsg-4326/{grid_size}/{row_count}/is/geotiff/{tile_id}.tif" + "source_uri": "s3://gfw-data-lake/ifl_intact_forest_landscapes_2000/v2021/raster/epsg-4326/{grid_size}/{row_count}/ipcc_class/geotiff/{tile_id}.tif" } ] } \ No newline at end of file diff --git a/src/main/scala/org/globalforestwatch/layers/GrossEmissionsNonCo2Co2eSoilOnly.scala b/src/main/scala/org/globalforestwatch/layers/GrossEmissionsNonCo2Co2eSoilOnly.scala index 1680f113..56b39af1 100644 --- a/src/main/scala/org/globalforestwatch/layers/GrossEmissionsNonCo2Co2eSoilOnly.scala +++ b/src/main/scala/org/globalforestwatch/layers/GrossEmissionsNonCo2Co2eSoilOnly.scala @@ -11,4 +11,4 @@ case class GrossEmissionsNonCo2Co2eSoilOnly(gridTile: GridTile, kwargs: Map[Stri val uri: String = s"s3://gfw-files/flux_1_2_2/gross_emissions_non_co2_co2e/soil_only/${gridTile.tileId}.tif" -} +} \ No newline at end of file diff --git a/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala b/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala index a9462195..2617fb6a 100644 --- a/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala +++ b/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala @@ -6,6 +6,7 @@ case class TreesInMosaicLandscapes(gridTile: GridTile, kwargs: Map[String, Any]) extends IntegerLayer with OptionalILayer { val datasetName = "wri_trees_in_mosaic_landscapes" + override val internalNoDataValue: Int = 255 override val externalNoDataValue: Integer = 255 val uri: String = diff --git a/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala b/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala index 1571ace1..9d57ae47 100644 --- a/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala +++ b/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala @@ -11,13 +11,12 @@ case class UmdGlobalLandcover(gridTile: GridTile, kwargs: Map[String, Any]) override def lookup(value: Int): String = { value match { - case v if v >= 0 && v <= 24 => "Grassland" - case v if (v >= 25 && v <= 96) || (v >= 125 && v <= 196) => "Forest" - case v if v >= 100 && v <= 124 => "Wetlands" - case v if v >= 244 && v <= 247 => "Cropland" - case v if v >= 250 && v <= 253 => "Built-Up Area" - case v if (v >= 200 && v <= 215) || (v >= 241 && v <= 243) || v == 254 => "Other" - case _ => "Unknown" + case v if v == 1 => "Grassland" + case v if v == 2 => "Forest" + case v if v == 3 => "Wetlands" + case v if v == 4 => "Cropland" + case v if v == 5 => "Settlements" + case v if v == 6 => "Other" } } } From 67d429b6a9c396295f5145d71603a1a681ef2ff5 Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Wed, 29 Mar 2023 16:39:17 -0700 Subject: [PATCH 13/22] Filter out pre-2000 plantations from carbon layers --- .../layers/PlantationsPre2000.scala | 14 ++++++++++++++ .../AnnualUpdateMinimalGridSources.scala | 3 +++ .../AnnualUpdateMinimalSummary.scala | 17 +++++++++++------ .../AnnualUpdateMinimalTile.scala | 1 + 4 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 src/main/scala/org/globalforestwatch/layers/PlantationsPre2000.scala diff --git a/src/main/scala/org/globalforestwatch/layers/PlantationsPre2000.scala b/src/main/scala/org/globalforestwatch/layers/PlantationsPre2000.scala new file mode 100644 index 00000000..883aba51 --- /dev/null +++ b/src/main/scala/org/globalforestwatch/layers/PlantationsPre2000.scala @@ -0,0 +1,14 @@ +package org.globalforestwatch.layers + +import org.globalforestwatch.grids.GridTile +import org.globalforestwatch.layers.{BooleanLayer, OptionalILayer} + +case class PlantationsPre2000(gridTile: GridTile, kwargs: Map[String, Any]) + extends BooleanLayer + with OptionalILayer { + + val datasetName = "Na" + + val uri: String = + s"s3://gfw2-data/climate/carbon_model/other_emissions_inputs/IDN_MYS_plantation_pre_2000/processed/20200724/${gridTile.tileId}_plantation_2000_or_earlier_processed.tif" +} \ No newline at end of file diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala index 8e74731f..45400819 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala @@ -43,6 +43,7 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String val treeCoverLossFromFires: TreeCoverLossFromFires = TreeCoverLossFromFires(gridTile, kwargs) val treesInMosaicLandscapes: TreesInMosaicLandscapes = TreesInMosaicLandscapes(gridTile, kwargs) val umdGlobalLandCover: UmdGlobalLandcover = UmdGlobalLandcover(gridTile, kwargs) + val plantationsPre2000: PlantationsPre2000 = PlantationsPre2000(gridTile, kwargs) def readWindow( windowKey: SpatialKey, windowLayout: LayoutDefinition @@ -90,6 +91,7 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String val treeCoverLossFromFiresTile = treeCoverLossFromFires.fetchWindow(windowKey, windowLayout) val treesInMosaicLandscapesTile = treesInMosaicLandscapes.fetchWindow(windowKey, windowLayout) val umdGlobalLandCoverTile = umdGlobalLandCover.fetchWindow(windowKey, windowLayout) + val plantationsPre2000Tile = plantationsPre2000.fetchWindow(windowKey, windowLayout) val tile = AnnualUpdateMinimalTile( lossTile, @@ -124,6 +126,7 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String treeCoverLossFromFiresTile, treesInMosaicLandscapesTile, umdGlobalLandCoverTile, + plantationsPre2000Tile, ) Raster(tile, windowKey.extent(windowLayout)) diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala index 1626e304..35b5d02b 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala @@ -74,6 +74,8 @@ object AnnualUpdateMinimalSummary { raster.tile.treesInMosaicLandscapes.getData(col, row) val umdGlobalLandCover: String = raster.tile.umdGlobalLandCover.getData(col, row) + val plantationsPre2000: Boolean = + raster.tile.plantationsPre2000.getData(col, row) val lat: Double = raster.rasterExtent.gridRowToMap(row) val area: Double = Geodesy.pixelArea(lat, raster.cellSize) // uses Pixel's center coordiate. +- raster.cellSize.height/2 doesn't make much of a difference @@ -160,13 +162,16 @@ object AnnualUpdateMinimalSummary { summary.treecoverExtent2000 += areaHa summary.totalBiomass += biomassPixel summary.totalCo2 += co2Pixel - summary.totalGrossCumulAbovegroundRemovalsCo2 += grossCumulAbovegroundRemovalsCo2Pixel - summary.totalGrossCumulBelowgroundRemovalsCo2 += grossCumulBelowgroundRemovalsCo2Pixel - summary.totalGrossCumulAboveBelowgroundRemovalsCo2 += grossCumulAboveBelowgroundRemovalsCo2Pixel - summary.totalNetFluxCo2 += netFluxCo2Pixel - summary.totalSoilCarbon += totalCarbonSoil + + if (!plantationsPre2000) { + summary.totalGrossCumulAbovegroundRemovalsCo2 += grossCumulAbovegroundRemovalsCo2Pixel + summary.totalGrossCumulBelowgroundRemovalsCo2 += grossCumulBelowgroundRemovalsCo2Pixel + summary.totalGrossCumulAboveBelowgroundRemovalsCo2 += grossCumulAboveBelowgroundRemovalsCo2Pixel + summary.totalNetFluxCo2 += netFluxCo2Pixel + summary.totalSoilCarbon += totalCarbonSoil + } } - else if (gain) { + else if (gain && !plantationsPre2000) { // Adds the gain pixels that don't have any tree cover density to the flux model outputs to get // the correct flux model outputs (TCD>=threshold OR Hansen gain=TRUE) summary.totalGrossCumulAbovegroundRemovalsCo2 += grossCumulAbovegroundRemovalsCo2Pixel diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala index 7271bff1..58f9dad0 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala @@ -41,6 +41,7 @@ case class AnnualUpdateMinimalTile( treeCoverLossFromFires: TreeCoverLossFromFires#OptionalITile, treesInMosaicLandscapes: TreesInMosaicLandscapes#OptionalITile, umdGlobalLandCover: UmdGlobalLandcover#OptionalITile, + plantationsPre2000: PlantationsPre2000#OptionalITile, ) extends CellGrid[Int] { def cellType: CellType = loss.cellType def cols: Int = loss.cols From c3bdaf90adab2c806bea418fcf1d8bd0f56c29bb Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Thu, 30 Mar 2023 11:13:00 -0700 Subject: [PATCH 14/22] Filter out pre-2000 plantations in TreeCoverLoss analysis --- .../treecoverloss/TreeLossGridSources.scala | 3 +++ .../treecoverloss/TreeLossSummary.scala | 22 +++++++++++-------- .../treecoverloss/TreeLossTile.scala | 1 + 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossGridSources.scala b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossGridSources.scala index 60059bd6..0df1cad8 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossGridSources.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossGridSources.scala @@ -21,6 +21,7 @@ case class TreeLossGridSources(gridTile: GridTile, kwargs: Map[String, Any]) ext val primaryForest = PrimaryForest(gridTile, kwargs) val plantedForestsBool = PlantedForestsBool(gridTile, kwargs) + val plantationsPre2000: PlantationsPre2000 = PlantationsPre2000(gridTile, kwargs) val grossCumulAbovegroundRemovalsCo2: GrossCumulAbovegroundRemovalsCo2 = GrossCumulAbovegroundRemovalsCo2(gridTile, kwargs = kwargs) val grossCumulBelowgroundRemovalsCo2: GrossCumulBelowgroundRemovalsCo2 = GrossCumulBelowgroundRemovalsCo2(gridTile, kwargs = kwargs) @@ -48,6 +49,7 @@ case class TreeLossGridSources(gridTile: GridTile, kwargs: Map[String, Any]) ext val gainTile = treeCoverGain.fetchWindow(windowKey, windowLayout) val primaryForestTile = primaryForest.fetchWindow(windowKey, windowLayout) val plantedForestsBoolTile = plantedForestsBool.fetchWindow(windowKey, windowLayout) + val plantationsPre2000Tile = plantationsPre2000.fetchWindow(windowKey, windowLayout) val biomassTile = biomassPerHectar.fetchWindow(windowKey, windowLayout) val agc2000Tile = agc2000.fetchWindow(windowKey, windowLayout) @@ -72,6 +74,7 @@ case class TreeLossGridSources(gridTile: GridTile, kwargs: Map[String, Any]) ext soilCarbon2000Tile, primaryForestTile, plantedForestsBoolTile, + plantationsPre2000Tile, grossCumulAbovegroundRemovalsCo2Tile, grossCumulBelowgroundRemovalsCo2Tile, netFluxCo2Tile, diff --git a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossSummary.scala b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossSummary.scala index 3a778181..40784dbb 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossSummary.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossSummary.scala @@ -77,6 +77,8 @@ object TreeLossSummary { else false } + val plantationsPre2000: Boolean = + raster.tile.plantationsPre2000.getData(col, row) val lat: Double = raster.rasterExtent.gridRowToMap(row) val area: Double = Geodesy.pixelArea(lat, raster.cellSize) // uses Pixel's center coordinate. +- raster.cellSize.height/2 doesn't make much of a difference @@ -156,18 +158,20 @@ object TreeLossSummary { summary.totalSoilCarbon2000 += soilCarbon2000Pixel } - summary.totalGrossCumulAbovegroundRemovalsCo2 += grossCumulAbovegroundRemovalsCo2Pixel - summary.totalGrossCumulBelowgroundRemovalsCo2 += grossCumulBelowgroundRemovalsCo2Pixel - summary.totalGrossCumulAboveBelowgroundRemovalsCo2 += grossCumulAboveBelowgroundRemovalsCo2Pixel + if (!plantationsPre2000) { + summary.totalGrossCumulAbovegroundRemovalsCo2 += grossCumulAbovegroundRemovalsCo2Pixel + summary.totalGrossCumulBelowgroundRemovalsCo2 += grossCumulBelowgroundRemovalsCo2Pixel + summary.totalGrossCumulAboveBelowgroundRemovalsCo2 += grossCumulAboveBelowgroundRemovalsCo2Pixel - summary.totalGrossEmissionsCo2eCo2Only += grossEmissionsCo2eCo2OnlyPixel - summary.totalGrossEmissionsCo2eNonCo2 += grossEmissionsCo2eNonCo2Pixel - summary.totalGrossEmissionsCo2eAllGases += grossEmissionsCo2eAllGasesPixel + summary.totalGrossEmissionsCo2eCo2Only += grossEmissionsCo2eCo2OnlyPixel + summary.totalGrossEmissionsCo2eNonCo2 += grossEmissionsCo2eNonCo2Pixel + summary.totalGrossEmissionsCo2eAllGases += grossEmissionsCo2eAllGasesPixel - summary.totalNetFluxCo2 += netFluxCo2Pixel + summary.totalNetFluxCo2 += netFluxCo2Pixel - summary.totalFluxModelExtentArea += fluxModelExtentAreaPixel - } else if (gain) { + summary.totalFluxModelExtentArea += fluxModelExtentAreaPixel + } + } else if (gain && !plantationsPre2000) { // Adds the gain pixels that don't have any tree cover density to the flux model outputs to get // the correct flux model outputs (TCD>=threshold OR Hansen gain) summary.totalGrossCumulAbovegroundRemovalsCo2 += grossCumulAbovegroundRemovalsCo2Pixel diff --git a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossTile.scala b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossTile.scala index 14b0aa08..e354f78e 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossTile.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossTile.scala @@ -18,6 +18,7 @@ case class TreeLossTile(loss: TreeCoverLoss#ITile, soilCarbon2000: SoilCarbon2000#OptionalFTile, primaryForest: PrimaryForest#OptionalITile, plantedForestsBool: PlantedForestsBool#OptionalITile, + plantationsPre2000: PlantationsPre2000#OptionalITile, grossCumulAbovegroundRemovalsCo2: GrossCumulAbovegroundRemovalsCo2#OptionalFTile, grossCumulBelowgroundRemovalsCo2: GrossCumulBelowgroundRemovalsCo2#OptionalFTile, netFluxCo2: NetFluxCo2e#OptionalFTile, From f257e1709f2d58e57796816205ddcbfd026aab07 Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Thu, 30 Mar 2023 11:23:43 -0700 Subject: [PATCH 15/22] Don't include -1 in output of tcl download --- .../annualupdate_minimal/AnnualUpdateMinimalDownloadDF.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDownloadDF.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDownloadDF.scala index f8056957..673d86a7 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDownloadDF.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDownloadDF.scala @@ -16,6 +16,7 @@ object AnnualUpdateMinimalDownloadDF { val yearRange = treecoverLossMinYear to treecoverLossMaxYear val annualDF = df + .where($"umd_tree_cover_density_2000__threshold" >= 0) .groupBy($"iso", $"adm1", $"adm2", $"umd_tree_cover_density_2000__threshold") .pivot("umd_tree_cover_loss__year", yearRange) .agg( @@ -26,6 +27,7 @@ object AnnualUpdateMinimalDownloadDF { .na.fill(0, Seq("adm1", "adm2")) val totalDF = df + .where($"umd_tree_cover_density_2000__threshold" >= 0) .groupBy($"iso", $"adm1", $"adm2", $"umd_tree_cover_density_2000__threshold") .agg( sum("umd_tree_cover_extent_2000__ha") as "umd_tree_cover_extent_2000__ha", @@ -121,7 +123,8 @@ object AnnualUpdateMinimalDownloadDF { sum($"gfw_forest_carbon_net_flux__Mg_CO2e_yr-1") as "gfw_forest_carbon_net_flux__Mg_CO2e_yr-1" ) ::: treecoverLossCols ::: totalGrossEmissionsCo2eAllGasesCols - df.groupBy( + df.where($"umd_tree_cover_density_2000__threshold" >= 0) + .groupBy( groupByCols.head, groupByCols.tail ::: List("umd_tree_cover_density_2000__threshold"): _* ) From 165416a09f2c32bb921827caec658e0451b513f1 Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Tue, 4 Apr 2023 11:16:37 -0700 Subject: [PATCH 16/22] Update TCL year --- .../annualupdate_minimal/AnnualUpdateMinimalDownloadDF.scala | 2 +- .../summarystats/treecoverloss/TreeLossDF.scala | 2 +- .../summarystats/treecoverloss/TreeLossYearDataMap.scala | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDownloadDF.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDownloadDF.scala index 673d86a7..6f91a2b7 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDownloadDF.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDownloadDF.scala @@ -5,7 +5,7 @@ import org.apache.spark.sql.{Column, DataFrame, SparkSession} object AnnualUpdateMinimalDownloadDF { val treecoverLossMinYear = 2001 - val treecoverLossMaxYear = 2021 + val treecoverLossMaxYear = 2022 val fluxModelTotalYears = (treecoverLossMaxYear - treecoverLossMinYear) + 1 def sumDownload(df: DataFrame): DataFrame = { diff --git a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossDF.scala b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossDF.scala index c1730df4..90773cef 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossDF.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossDF.scala @@ -8,7 +8,7 @@ import org.apache.spark.sql.{DataFrame, SparkSession} object TreeLossDF { val treecoverLossMinYear = 2001 - val treecoverLossMaxYear = 2021 + val treecoverLossMaxYear = 2022 def unpackValues(carbonPools: Boolean)(df: DataFrame): DataFrame = { val spark: SparkSession = df.sparkSession diff --git a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossYearDataMap.scala b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossYearDataMap.scala index fe4f459a..d3078008 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossYearDataMap.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossYearDataMap.scala @@ -25,7 +25,8 @@ object TreeLossYearDataMap { 2018 -> TreeLossYearData(2018, 0, 0, 0, 0, 0), 2019 -> TreeLossYearData(2019, 0, 0, 0, 0, 0), 2020 -> TreeLossYearData(2020, 0, 0, 0, 0, 0), - 2021 -> TreeLossYearData(2021, 0, 0, 0, 0, 0) + 2021 -> TreeLossYearData(2021, 0, 0, 0, 0, 0), + 2022 -> TreeLossYearData(2022, 0, 0, 0, 0, 0), ) //def mapValuesToList(map: Map[Int, LossYearData]): List[LossYearData] = ??? From a680ea441b6f9896178f0436b1fd900cde1e2419 Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Tue, 4 Apr 2023 15:12:07 -0700 Subject: [PATCH 17/22] Add aboveground and belowground carbon stocks --- src/main/resources/raster-catalog-default.json | 18 +++++++++++++----- .../layers/AbovegroundCarbon2000.scala | 13 +++++++++++++ .../layers/BelowgroundCarbon2000.scala | 13 +++++++++++++ .../AnnualUpdateMinimalDF.scala | 6 ++++++ .../AnnualUpdateMinimalData.scala | 4 ++++ .../AnnualUpdateMinimalGridSources.scala | 6 ++++++ .../AnnualUpdateMinimalSummary.scala | 9 +++++++-- .../AnnualUpdateMinimalTile.scala | 4 +++- 8 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 src/main/scala/org/globalforestwatch/layers/AbovegroundCarbon2000.scala create mode 100644 src/main/scala/org/globalforestwatch/layers/BelowgroundCarbon2000.scala diff --git a/src/main/resources/raster-catalog-default.json b/src/main/resources/raster-catalog-default.json index 317bdc9b..30e3aacd 100644 --- a/src/main/resources/raster-catalog-default.json +++ b/src/main/resources/raster-catalog-default.json @@ -307,23 +307,23 @@ }, { "name":"gfw_full_extent_net_flux", - "source_uri": "s3://gfw-data-lake/gfw_full_extent_net_flux/v20220316/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" + "source_uri": "s3://gfw-data-lake/gfw_full_extent_net_flux/v20230331/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" }, { "name":"gfw_full_extent_aboveground_gross_removals", - "source_uri": "s3://gfw-data-lake/gfw_full_extent_aboveground_gross_removals/v20220309/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" + "source_uri": "s3://gfw-data-lake/gfw_full_extent_aboveground_gross_removals/v20230331/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" }, { "name":"gfw_full_extent_belowground_gross_removals", - "source_uri": "s3://gfw-data-lake/gfw_full_extent_belowground_gross_removals/v20220309/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" + "source_uri": "s3://gfw-data-lake/gfw_full_extent_belowground_gross_removals/v20230331/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" }, { "name":"gfw_full_extent_co2_gross_emissions", - "source_uri": "s3://gfw-data-lake/gfw_full_extent_co2_gross_emissions/v20220316/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" + "source_uri": "s3://gfw-data-lake/gfw_full_extent_co2_gross_emissions/v20230331/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" }, { "name":"gfw_full_extent_non_co2_gross_emissions", - "source_uri": "s3://gfw-data-lake/gfw_full_extent_non_co2_gross_emissions/v20220316/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" + "source_uri": "s3://gfw-data-lake/gfw_full_extent_non_co2_gross_emissions/v20230331/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" }, { "name":"fao_ecozones_2000", @@ -360,6 +360,14 @@ { "name":"umd_land_cover", "source_uri": "s3://gfw-data-lake/umd_land_cover/v2020/raster/epsg-4326/{grid_size}/{row_count}/ipcc_class/geotiff/{tile_id}.tif" + }, + { + "name":"gfw_aboveground_carbon", + "source_uri": "s3://gfw-data-lake/gfw_aboveground_carbon/v20230322/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" + }, + { + "name":"gfw_belowground_carbon", + "source_uri": "s3://gfw-data-lake/gfw_belowground_carbon/v20230322/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" } ] } \ No newline at end of file diff --git a/src/main/scala/org/globalforestwatch/layers/AbovegroundCarbon2000.scala b/src/main/scala/org/globalforestwatch/layers/AbovegroundCarbon2000.scala new file mode 100644 index 00000000..4b5d008e --- /dev/null +++ b/src/main/scala/org/globalforestwatch/layers/AbovegroundCarbon2000.scala @@ -0,0 +1,13 @@ +package org.globalforestwatch.layers + +import org.globalforestwatch.grids.GridTile + +case class AbovegroundCarbon2000(gridTile: GridTile, model: String = "standard", kwargs: Map[String, Any]) + extends FloatLayer + with OptionalFLayer { + + val datasetName = "gfw_aboveground_carbon" + + val uri: String = + uriForGrid(gridTile, kwargs) +} diff --git a/src/main/scala/org/globalforestwatch/layers/BelowgroundCarbon2000.scala b/src/main/scala/org/globalforestwatch/layers/BelowgroundCarbon2000.scala new file mode 100644 index 00000000..04fc6ef3 --- /dev/null +++ b/src/main/scala/org/globalforestwatch/layers/BelowgroundCarbon2000.scala @@ -0,0 +1,13 @@ +package org.globalforestwatch.layers + +import org.globalforestwatch.grids.GridTile + +case class BelowgroundCarbon2000(gridTile: GridTile, model: String = "standard", kwargs: Map[String, Any]) + extends FloatLayer + with OptionalFLayer { + + val datasetName = "gfw_belowground_carbon" + + val uri: String = + uriForGrid(gridTile, kwargs) +} \ No newline at end of file diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala index a59c7a01..e3efe435 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala @@ -97,6 +97,8 @@ object AnnualUpdateMinimalDF { $"data.totalGrossCumulAboveBelowgroundRemovalsCo2" as "gfw_full_extent_gross_removals__Mg_CO2", $"data.treeCoverLossFromFires" as "umd_tree_cover_loss_from_fires__ha", $"data.tropicalTreeCoverExtent" as "wri_tropical_tree_cover_extent__ha", + $"data.abovegroundCarbon2000" as "gfw_aboveground_carbon_stocks_2000__Mg_C", + $"data.belowgroundCarbon2000" as "gfw_belowground_carbon_stocks_2000__Mg_C", $"data_group.threshold" as "umd_tree_cover_density__threshold", $"data_group.drivers" as "tsc_tree_cover_loss_drivers__type", @@ -168,6 +170,8 @@ object AnnualUpdateMinimalDF { sum("gfw_gross_cumulative_aboveground_belowground_co2_removals__Mg") as "gfw_gross_cumulative_aboveground_belowground_co2_removals__Mg", sum("gfw_net_flux_co2e__Mg") as "gfw_net_flux_co2e__Mg", sum("gfw_gross_emissions_co2e_all_gases__Mg") as "gfw_gross_emissions_co2e_all_gases__Mg", + sum("gfw_aboveground_carbon_stocks_2000__Mg_C") as "gfw_aboveground_carbon_stocks_2000__Mg_C", + sum("gfw_belowground_carbon_stocks_2000__Mg_C") as "gfw_belowground_carbon_stocks_2000__Mg_C", ) } @@ -202,6 +206,8 @@ object AnnualUpdateMinimalDF { sum("gfw_soil_carbon_stocks_2000__Mg_C") as "gfw_soil_carbon_stocks_2000__Mg_C", sum("umd_tree_cover_loss_from_fires__ha") as "umd_tree_cover_loss_from_fires__ha", sum("wri_tropical_tree_cover_extent__ha") as "wri_tropical_tree_cover_extent__ha", + sum("gfw_aboveground_carbon_stocks_2000__Mg_C") as "gfw_aboveground_carbon_stocks_2000__Mg_C", + sum("gfw_belowground_carbon_stocks_2000__Mg_C") as "gfw_belowground_carbon_stocks_2000__Mg_C", sum("umd_tree_cover_gain_2000-2012__ha") as "umd_tree_cover_gain_2000-2012__ha", sum("gfw_gross_cumulative_aboveground_belowground_co2_removals__Mg") as "gfw_gross_cumulative_aboveground_belowground_co2_removals__Mg", diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalData.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalData.scala index b8eb09c9..ed71ec05 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalData.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalData.scala @@ -27,6 +27,8 @@ case class AnnualUpdateMinimalData(var treecoverLoss: Double, var totalSoilCarbon: Double, var treeCoverLossFromFires: Double, var tropicalTreeCoverExtent: Double, + var abovegroundCarbon2000: Double, + var belowgroundCarbon2000: Double, ) { def merge(other: AnnualUpdateMinimalData): AnnualUpdateMinimalData = { AnnualUpdateMinimalData( @@ -51,6 +53,8 @@ case class AnnualUpdateMinimalData(var treecoverLoss: Double, totalSoilCarbon + other.totalSoilCarbon, treeCoverLossFromFires + other.treeCoverLossFromFires, tropicalTreeCoverExtent + other.tropicalTreeCoverExtent, + abovegroundCarbon2000 + other.abovegroundCarbon2000, + belowgroundCarbon2000 + other.belowgroundCarbon2000, ) } } diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala index 45400819..fa2f1e16 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala @@ -44,6 +44,8 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String val treesInMosaicLandscapes: TreesInMosaicLandscapes = TreesInMosaicLandscapes(gridTile, kwargs) val umdGlobalLandCover: UmdGlobalLandcover = UmdGlobalLandcover(gridTile, kwargs) val plantationsPre2000: PlantationsPre2000 = PlantationsPre2000(gridTile, kwargs) + val abovegroundCarbon2000: AbovegroundCarbon2000 = AbovegroundCarbon2000(gridTile, kwargs = kwargs) + val belowgroundCarbon2000: BelowgroundCarbon2000 = BelowgroundCarbon2000(gridTile, kwargs = kwargs) def readWindow( windowKey: SpatialKey, windowLayout: LayoutDefinition @@ -92,6 +94,8 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String val treesInMosaicLandscapesTile = treesInMosaicLandscapes.fetchWindow(windowKey, windowLayout) val umdGlobalLandCoverTile = umdGlobalLandCover.fetchWindow(windowKey, windowLayout) val plantationsPre2000Tile = plantationsPre2000.fetchWindow(windowKey, windowLayout) + val abovegroundCarbon2000Tile = abovegroundCarbon2000.fetchWindow(windowKey, windowLayout) + val belowgroundCarbon2000Tile = belowgroundCarbon2000.fetchWindow(windowKey, windowLayout) val tile = AnnualUpdateMinimalTile( lossTile, @@ -127,6 +131,8 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String treesInMosaicLandscapesTile, umdGlobalLandCoverTile, plantationsPre2000Tile, + abovegroundCarbon2000Tile, + belowgroundCarbon2000Tile, ) Raster(tile, windowKey.extent(windowLayout)) diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala index 35b5d02b..2839d4b0 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala @@ -95,6 +95,8 @@ object AnnualUpdateMinimalSummary { raster.tile.grossCumulBelowgroundRemovalsCo2.getData(col, row) val netFluxCo2: Float = raster.tile.netFluxCo2.getData(col, row) val soilCarbonPerHa: Float = raster.tile.soilCarbon.getData(col, row) + val abovegroundCarbon2000: Float = raster.tile.abovegroundCarbon2000.getData(col, row) + val belowgroundCarbon2000: Float = raster.tile.belowgroundCarbon2000.getData(col, row) val netFluxCo2Pixel = netFluxCo2 * areaHa val grossCumulAbovegroundRemovalsCo2Pixel = grossCumulAbovegroundRemovalsCo2 * areaHa @@ -139,7 +141,7 @@ object AnnualUpdateMinimalSummary { val summary: AnnualUpdateMinimalData = stats.getOrElse( key = pKey, - default = AnnualUpdateMinimalData(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + default = AnnualUpdateMinimalData(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) ) summary.totalArea += areaHa @@ -163,12 +165,15 @@ object AnnualUpdateMinimalSummary { summary.totalBiomass += biomassPixel summary.totalCo2 += co2Pixel + summary.totalSoilCarbon += totalCarbonSoil + summary.abovegroundCarbon2000 += abovegroundCarbon2000 + summary.belowgroundCarbon2000 += belowgroundCarbon2000 + if (!plantationsPre2000) { summary.totalGrossCumulAbovegroundRemovalsCo2 += grossCumulAbovegroundRemovalsCo2Pixel summary.totalGrossCumulBelowgroundRemovalsCo2 += grossCumulBelowgroundRemovalsCo2Pixel summary.totalGrossCumulAboveBelowgroundRemovalsCo2 += grossCumulAboveBelowgroundRemovalsCo2Pixel summary.totalNetFluxCo2 += netFluxCo2Pixel - summary.totalSoilCarbon += totalCarbonSoil } } else if (gain && !plantationsPre2000) { diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala index 58f9dad0..f3329edc 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala @@ -42,7 +42,9 @@ case class AnnualUpdateMinimalTile( treesInMosaicLandscapes: TreesInMosaicLandscapes#OptionalITile, umdGlobalLandCover: UmdGlobalLandcover#OptionalITile, plantationsPre2000: PlantationsPre2000#OptionalITile, -) extends CellGrid[Int] { + abovegroundCarbon2000: AbovegroundCarbon2000#OptionalFTile, + belowgroundCarbon2000: BelowgroundCarbon2000#OptionalFTile, + ) extends CellGrid[Int] { def cellType: CellType = loss.cellType def cols: Int = loss.cols def rows: Int = loss.rows From 7d8a0e3a322495244a0502534f1fb8e861f1375d Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Fri, 7 Apr 2023 09:47:42 -0700 Subject: [PATCH 18/22] Update remaining layers --- src/main/resources/raster-catalog-default.json | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/resources/raster-catalog-default.json b/src/main/resources/raster-catalog-default.json index 30e3aacd..85a18ea4 100644 --- a/src/main/resources/raster-catalog-default.json +++ b/src/main/resources/raster-catalog-default.json @@ -54,7 +54,7 @@ }, { "name":"gfw_forest_carbon_net_flux", - "source_uri":"s3://gfw-data-lake/gfw_forest_carbon_net_flux/v20210331/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" + "source_uri":"s3://gfw-data-lake/gfw_forest_carbon_net_flux/v20230331/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" }, { "name":"wdpa_protected_areas", @@ -122,7 +122,7 @@ }, { "name":"gfw_peatlands", - "source_uri":"s3://gfw-data-lake/gfw_peatlands/v20200807/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2_ha/geotiff/{tile_id}.tif" + "source_uri":"s3://gfw-data-lake/gfw_peatlands/v20230302/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2_ha/geotiff/{tile_id}.tif" }, { "name":"gfw_deadwood_carbon", @@ -190,15 +190,15 @@ }, { "name":"gfw_forest_carbon_gross_emissions", - "source_uri":"s3://gfw-data-lake/gfw_forest_carbon_gross_emissions/v20210331/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" + "source_uri":"s3://gfw-data-lake/gfw_forest_carbon_gross_emissions/v20230331/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" }, { "name":"gfw_forest_carbon_gross_removals", - "source_uri":"s3://gfw-data-lake/gfw_forest_carbon_gross_removals/v20210331/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" + "source_uri":"s3://gfw-data-lake/gfw_forest_carbon_gross_removals/v20230331/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" }, { "name":"umd_tree_cover_loss", - "source_uri":"s3://gfw-data-lake/umd_tree_cover_loss/v1.9/raster/epsg-4326/{grid_size}/{row_count}/year/geotiff/{tile_id}.tif" + "source_uri":"s3://gfw-data-lake/umd_tree_cover_loss/v1.10/raster/epsg-4326/{grid_size}/{row_count}/year/geotiff/{tile_id}.tif" }, { "name":"gfw_managed_forests", @@ -351,7 +351,7 @@ }, { "name":"umd_tree_cover_loss_from_fires", - "source_uri": "s3://gfw-data-lake/umd_tree_cover_loss_from_fires/v20220324/raster/epsg-4326/10/40000/year/geotiff/{tile_id}.tif" + "source_uri": "s3://gfw-data-lake/umd_tree_cover_loss_from_fires/v20230315/raster/epsg-4326/10/40000/year/geotiff/{tile_id}.tif" }, { "name":"wri_trees_in_mosaic_landscapes", @@ -368,6 +368,10 @@ { "name":"gfw_belowground_carbon", "source_uri": "s3://gfw-data-lake/gfw_belowground_carbon/v20230322/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" + }, + { + "name":"gfw_soil_carbon", + "source_uri": "s3://gfw-data-lake/gfw_soil_carbon/v20230322.2/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" } ] } \ No newline at end of file From 5917191d3349bcc07b1b2c864b13ec918580fe25 Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Fri, 7 Apr 2023 09:48:09 -0700 Subject: [PATCH 19/22] Fix carbon pools --- .../globalforestwatch/layers/SoilCarbon.scala | 6 +++--- .../layers/UmdGlobalLandcover.scala | 2 ++ .../AnnualUpdateMinimalDF.scala | 1 - .../AnnualUpdateMinimalDownloadDF.scala | 20 +++++++++---------- .../AnnualUpdateMinimalSummary.scala | 8 +++++--- .../AnnualUpdateMinimalTile.scala | 2 +- 6 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/main/scala/org/globalforestwatch/layers/SoilCarbon.scala b/src/main/scala/org/globalforestwatch/layers/SoilCarbon.scala index d3bf0883..1343d0c9 100644 --- a/src/main/scala/org/globalforestwatch/layers/SoilCarbon.scala +++ b/src/main/scala/org/globalforestwatch/layers/SoilCarbon.scala @@ -3,10 +3,10 @@ package org.globalforestwatch.layers import org.globalforestwatch.grids.GridTile case class SoilCarbon(gridTile: GridTile, kwargs: Map[String, Any]) - extends FloatLayer - with OptionalFLayer { + extends IntegerLayer + with OptionalILayer { - val datasetName = "gfw_soil_carbon_stocks" + val datasetName = "gfw_soil_carbon" val uri: String = uriForGrid(gridTile, kwargs) } diff --git a/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala b/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala index 9d57ae47..66e47b83 100644 --- a/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala +++ b/src/main/scala/org/globalforestwatch/layers/UmdGlobalLandcover.scala @@ -6,6 +6,8 @@ case class UmdGlobalLandcover(gridTile: GridTile, kwargs: Map[String, Any]) extends StringLayer with OptionalILayer { val datasetName = "umd_land_cover" + override val externalNoDataValue = "Other" + val uri: String = uriForGrid(gridTile, kwargs) diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala index e3efe435..ddd95886 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDF.scala @@ -208,7 +208,6 @@ object AnnualUpdateMinimalDF { sum("wri_tropical_tree_cover_extent__ha") as "wri_tropical_tree_cover_extent__ha", sum("gfw_aboveground_carbon_stocks_2000__Mg_C") as "gfw_aboveground_carbon_stocks_2000__Mg_C", sum("gfw_belowground_carbon_stocks_2000__Mg_C") as "gfw_belowground_carbon_stocks_2000__Mg_C", - sum("umd_tree_cover_gain_2000-2012__ha") as "umd_tree_cover_gain_2000-2012__ha", sum("gfw_gross_cumulative_aboveground_belowground_co2_removals__Mg") as "gfw_gross_cumulative_aboveground_belowground_co2_removals__Mg", sum("gfw_net_flux_co2e__Mg") as "gfw_net_flux_co2e__Mg", diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDownloadDF.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDownloadDF.scala index 6f91a2b7..54b82e70 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDownloadDF.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalDownloadDF.scala @@ -34,10 +34,10 @@ object AnnualUpdateMinimalDownloadDF { sum("umd_tree_cover_extent_2010__ha") as "umd_tree_cover_extent_2010__ha", sum("area__ha") as "area__ha", sum("umd_tree_cover_gain__ha") as "umd_tree_cover_gain__ha", - sum("whrc_aboveground_biomass_stock_2000__Mg") as "whrc_aboveground_biomass_stock_2000__Mg", - sum("whrc_aboveground_biomass_stock_2000__Mg") / sum( + sum("gfw_aboveground_carbon_stocks_2000__Mg_C") as "gfw_aboveground_carbon_stocks_2000__Mg_C", + sum("gfw_aboveground_carbon_stocks_2000__Mg_C") / sum( "umd_tree_cover_extent_2000__ha" - ) as "avg_whrc_aboveground_biomass_2000_Mg_ha-1", + ) as "avg_gfw_aboveground_carbon_stocks_2000__Mg_C_ha-1", sum($"gfw_full_extent_gross_emissions__Mg_CO2e") / fluxModelTotalYears as "gfw_forest_carbon_gross_emissions__Mg_CO2e_yr-1", sum($"gfw_full_extent_gross_removals__Mg_CO2") / fluxModelTotalYears as "gfw_forest_carbon_gross_removals__Mg_CO2_yr-1", sum($"gfw_full_extent_net_flux__Mg_CO2e") / fluxModelTotalYears as "gfw_forest_carbon_net_flux__Mg_CO2e_yr-1" @@ -114,10 +114,10 @@ object AnnualUpdateMinimalDownloadDF { sum($"umd_tree_cover_extent_2010__ha") as "umd_tree_cover_extent_2010__ha", sum($"area__ha") as "area__ha", sum($"umd_tree_cover_gain__ha") as "umd_tree_cover_gain__ha", - sum($"whrc_aboveground_biomass_stock_2000__Mg") as "whrc_aboveground_biomass_stock_2000__Mg", - sum($"whrc_aboveground_biomass_stock_2000__Mg") / sum( + sum($"gfw_aboveground_carbon_stocks_2000__Mg_C") as "gfw_aboveground_carbon_stocks_2000__Mg_C", + sum($"gfw_aboveground_carbon_stocks_2000__Mg_C") / sum( $"umd_tree_cover_extent_2000__ha" - ) as "avg_whrc_aboveground_biomass_2000_Mg_ha-1", + ) as "avg_gfw_aboveground_carbon_stocks_2000__Mg_C_ha-1", sum($"gfw_forest_carbon_gross_emissions__Mg_CO2e_yr-1") as "gfw_forest_carbon_gross_emissions__Mg_CO2e_yr-1", sum($"gfw_forest_carbon_gross_removals__Mg_CO2_yr-1") as "gfw_forest_carbon_gross_removals__Mg_CO2_yr-1", sum($"gfw_forest_carbon_net_flux__Mg_CO2e_yr-1") as "gfw_forest_carbon_net_flux__Mg_CO2e_yr-1" @@ -129,7 +129,7 @@ object AnnualUpdateMinimalDownloadDF { groupByCols.tail ::: List("umd_tree_cover_density_2000__threshold"): _* ) .agg(aggCols.head, aggCols.tail: _*) - .na.fill(0, Seq("avg_whrc_aboveground_biomass_2000_Mg_ha-1")) + .na.fill(0, Seq("avg_gfw_aboveground_carbon_stocks_2000__Mg_C_ha-1")) } def roundDownload(roundCols: List[Column])(df: DataFrame): DataFrame = { @@ -193,8 +193,8 @@ object AnnualUpdateMinimalDownloadDF { round($"umd_tree_cover_extent_2010__ha") as "umd_tree_cover_extent_2010__ha", round($"area__ha") as "area__ha", round($"umd_tree_cover_gain__ha") as "umd_tree_cover_gain__ha", - round($"whrc_aboveground_biomass_stock_2000__Mg") as "whrc_aboveground_biomass_stock_2000__Mg", - round($"avg_whrc_aboveground_biomass_2000_Mg_ha-1") as "avg_whrc_aboveground_biomass_2000_Mg_ha-1", + round($"gfw_aboveground_carbon_stocks_2000__Mg_C") as "gfw_aboveground_carbon_stocks_2000__Mg_C", + round($"avg_gfw_aboveground_carbon_stocks_2000__Mg_C_ha-1") as "avg_gfw_aboveground_carbon_stocks_2000__Mg_C_ha-1", round($"gfw_forest_carbon_gross_emissions__Mg_CO2e_yr-1") as "gfw_forest_carbon_gross_emissions__Mg_CO2e_yr-1", round($"gfw_forest_carbon_gross_removals__Mg_CO2_yr-1") as "gfw_forest_carbon_gross_removals__Mg_CO2_yr-1", round($"gfw_forest_carbon_net_flux__Mg_CO2e_yr-1") as "gfw_forest_carbon_net_flux__Mg_CO2e_yr-1" @@ -219,7 +219,7 @@ object AnnualUpdateMinimalDownloadDF { s"${i}_gfw_forest_carbon_gross_emissions__Mg_CO2e" }).toList - val cols = "avg_whrc_aboveground_biomass_2000_Mg_ha-1" :: "gfw_forest_carbon_gross_emissions__Mg_CO2e_yr-1" :: "gfw_forest_carbon_gross_removals__Mg_CO2_yr-1" :: "gfw_forest_carbon_net_flux__Mg_CO2e_yr-1" :: treecoverLossCols ::: totalGrossEmissionsCo2eAllGasesCols + val cols = "avg_gfw_aboveground_carbon_stocks_2000__Mg_C_ha-1" :: "gfw_forest_carbon_gross_emissions__Mg_CO2e_yr-1" :: "gfw_forest_carbon_gross_removals__Mg_CO2_yr-1" :: "gfw_forest_carbon_net_flux__Mg_CO2e_yr-1" :: treecoverLossCols ::: totalGrossEmissionsCo2eAllGasesCols val nullColumns = df .select(cols.head, cols.tail: _*) .columns diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala index 2839d4b0..47b920f4 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala @@ -94,9 +94,9 @@ object AnnualUpdateMinimalSummary { val grossCumulBelowgroundRemovalsCo2: Float = raster.tile.grossCumulBelowgroundRemovalsCo2.getData(col, row) val netFluxCo2: Float = raster.tile.netFluxCo2.getData(col, row) - val soilCarbonPerHa: Float = raster.tile.soilCarbon.getData(col, row) - val abovegroundCarbon2000: Float = raster.tile.abovegroundCarbon2000.getData(col, row) - val belowgroundCarbon2000: Float = raster.tile.belowgroundCarbon2000.getData(col, row) + val soilCarbonPerHa: Integer = raster.tile.soilCarbon.getData(col, row) + val abovegroundCarbon2000PerHa: Float = raster.tile.abovegroundCarbon2000.getData(col, row) + val belowgroundCarbon2000PerHa: Float = raster.tile.belowgroundCarbon2000.getData(col, row) val netFluxCo2Pixel = netFluxCo2 * areaHa val grossCumulAbovegroundRemovalsCo2Pixel = grossCumulAbovegroundRemovalsCo2 * areaHa @@ -107,6 +107,8 @@ object AnnualUpdateMinimalSummary { val grossEmissionsCo2e = grossEmissionsCo2eNonCo2 + grossEmissionsCo2eCo2Only val grossEmissionsCo2ePixel = grossEmissionsCo2e * areaHa val totalCarbonSoil = soilCarbonPerHa * areaHa + val abovegroundCarbon2000 = abovegroundCarbon2000PerHa * areaHa + val belowgroundCarbon2000 = belowgroundCarbon2000PerHa * areaHa def updateSummary( loss: Integer, tcd2000: Integer, tcdThreshold: Integer, treesInMosaicLandscapes: Integer, umdGlobalLandCover: String, diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala index f3329edc..eb2fde06 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala @@ -36,7 +36,7 @@ case class AnnualUpdateMinimalTile( grossCumulAbovegroundRemovalsCo2: GrossCumulAbovegroundRemovalsCo2#OptionalFTile, grossCumulBelowgroundRemovalsCo2: GrossCumulBelowgroundRemovalsCo2#OptionalFTile, netFluxCo2: NetFluxCo2e#OptionalFTile, - soilCarbon: SoilCarbon#OptionalFTile, + soilCarbon: SoilCarbon#OptionalITile, intactForestLandscapes2000: IntactForestLandscapes2000#OptionalITile, treeCoverLossFromFires: TreeCoverLossFromFires#OptionalITile, treesInMosaicLandscapes: TreesInMosaicLandscapes#OptionalITile, From 479a58b322a5b4715281d0f11ea75a0e25c4b6b1 Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Mon, 8 May 2023 16:45:33 -0700 Subject: [PATCH 20/22] Update dataa --- .../resources/raster-catalog-default.json | 38 +++++-------------- .../layers/GrossEmissionsCo2OnlyCo2e.scala | 2 +- .../AnnualUpdateMinimalGridSources.scala | 4 ++ .../AnnualUpdateMinimalSummary.scala | 12 ++++-- .../AnnualUpdateMinimalTile.scala | 1 + .../treecoverloss/TreeLossGridSources.scala | 4 +- .../treecoverloss/TreeLossSummary.scala | 9 +++-- .../treecoverloss/TreeLossTile.scala | 4 +- 8 files changed, 33 insertions(+), 41 deletions(-) diff --git a/src/main/resources/raster-catalog-default.json b/src/main/resources/raster-catalog-default.json index 85a18ea4..d95e8d75 100644 --- a/src/main/resources/raster-catalog-default.json +++ b/src/main/resources/raster-catalog-default.json @@ -10,7 +10,7 @@ }, { "name":"wdpa_protected_areas", - "source_uri":"s3://gfw-data-lake/wdpa_protected_areas/v202204/raster/epsg-4326/{grid_size}/{row_count}/iucn_cat/geotiff/{tile_id}.tif" + "source_uri":"s3://gfw-data-lake/wdpa_protected_areas/v202302/raster/epsg-4326/{grid_size}/{row_count}/iucn_cat/geotiff/{tile_id}.tif" }, { "name":"gfw_oil_gas", @@ -56,10 +56,6 @@ "name":"gfw_forest_carbon_net_flux", "source_uri":"s3://gfw-data-lake/gfw_forest_carbon_net_flux/v20230331/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" }, - { - "name":"wdpa_protected_areas", - "source_uri":"s3://gfw-data-lake/wdpa_protected_areas/v202106/raster/epsg-4326/{grid_size}/{row_count}/is/geotiff/{tile_id}.tif" - }, { "name":"gfw_pixel_area", "source_uri":"s3://gfw-data-lake/gfw_pixel_area/v20150327/raster/epsg-4326/{grid_size}/{row_count}/m2/geotiff/{tile_id}.tif" @@ -110,7 +106,7 @@ }, { "name":"tsc_tree_cover_loss_drivers", - "source_uri":"s3://gfw-data-lake/tsc_tree_cover_loss_drivers/v2021.1/raster/epsg-4326/{grid_size}/{row_count}/driver/geotiff/{tile_id}.tif" + "source_uri":"s3://gfw-data-lake/tsc_tree_cover_loss_drivers/v2022/raster/epsg-4326/{grid_size}/{row_count}/driver/geotiff/{tile_id}.tif" }, { "name":"umd_tree_cover_density_2010", @@ -128,14 +124,6 @@ "name":"gfw_deadwood_carbon", "source_uri":"s3://gfw-data-lake/gfw_deadwood_carbon/v20200824/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2_ha/geotiff/{tile_id}.tif" }, - { - "name":"gfw_belowground_carbon", - "source_uri":"s3://gfw-data-lake/gfw_belowground_carbon/v20200824/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2_ha/geotiff/{tile_id}.tif" - }, - { - "name":"gfw_aboveground_carbon", - "source_uri":"s3://gfw-data-lake/gfw_aboveground_carbon/v20200824/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2_ha/geotiff/{tile_id}.tif" - }, { "name":"gfw_litter_carbon", "source_uri":"s3://gfw-data-lake/gfw_litter_carbon/v20200824/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2_ha/geotiff/{tile_id}.tif" @@ -164,14 +152,6 @@ "name":"gfw_resource_rights", "source_uri":"s3://gfw-data-lake/gfw_resource_rights/v2018/raster/epsg-4326/{grid_size}/{row_count}/is/geotiff/{tile_id}.tif" }, - { - "name":"gfw_aboveground_carbon", - "source_uri":"s3://gfw-data-lake/gfw_aboveground_carbon/v20200824/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2_ha-1/geotiff/{tile_id}.tif" - }, - { - "name":"gfw_belowground_carbon", - "source_uri":"s3://gfw-data-lake/gfw_belowground_carbon/v20200824/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2_ha-1/geotiff/{tile_id}.tif" - }, { "name":"gfw_oil_palm", "source_uri":"s3://gfw-data-lake/gfw_oil_palm/v20191031/raster/epsg-4326/{grid_size}/{row_count}/is/geotiff/{tile_id}.tif" @@ -307,7 +287,7 @@ }, { "name":"gfw_full_extent_net_flux", - "source_uri": "s3://gfw-data-lake/gfw_full_extent_net_flux/v20230331/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" + "source_uri": "s3://gfw-data-lake/gfw_full_extent_net_flux/v20230407/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" }, { "name":"gfw_full_extent_aboveground_gross_removals", @@ -319,11 +299,11 @@ }, { "name":"gfw_full_extent_co2_gross_emissions", - "source_uri": "s3://gfw-data-lake/gfw_full_extent_co2_gross_emissions/v20230331/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" + "source_uri": "s3://gfw-data-lake/gfw_full_extent_co2_gross_emissions/v20230407/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" }, { "name":"gfw_full_extent_non_co2_gross_emissions", - "source_uri": "s3://gfw-data-lake/gfw_full_extent_non_co2_gross_emissions/v20230331/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" + "source_uri": "s3://gfw-data-lake/gfw_full_extent_non_co2_gross_emissions/v20230407/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" }, { "name":"fao_ecozones_2000", @@ -351,7 +331,7 @@ }, { "name":"umd_tree_cover_loss_from_fires", - "source_uri": "s3://gfw-data-lake/umd_tree_cover_loss_from_fires/v20230315/raster/epsg-4326/10/40000/year/geotiff/{tile_id}.tif" + "source_uri": "s3://gfw-data-lake/umd_tree_cover_loss_from_fires/v20230424/raster/epsg-4326/10/40000/year/geotiff/{tile_id}.tif" }, { "name":"wri_trees_in_mosaic_landscapes", @@ -363,15 +343,15 @@ }, { "name":"gfw_aboveground_carbon", - "source_uri": "s3://gfw-data-lake/gfw_aboveground_carbon/v20230322/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" + "source_uri": "s3://gfw-data-lake/gfw_aboveground_carbon/v20230322/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2_ha-1/geotiff/{tile_id}.tif" }, { "name":"gfw_belowground_carbon", - "source_uri": "s3://gfw-data-lake/gfw_belowground_carbon/v20230322/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" + "source_uri": "s3://gfw-data-lake/gfw_belowground_carbon/v20230322/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2_ha-1/geotiff/{tile_id}.tif" }, { "name":"gfw_soil_carbon", - "source_uri": "s3://gfw-data-lake/gfw_soil_carbon/v20230322.2/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2e_ha-1/geotiff/{tile_id}.tif" + "source_uri": "s3://gfw-data-lake/gfw_soil_carbon/v20230322.2/raster/epsg-4326/{grid_size}/{row_count}/Mg_CO2_ha-1/geotiff/{tile_id}.tif" } ] } \ No newline at end of file diff --git a/src/main/scala/org/globalforestwatch/layers/GrossEmissionsCo2OnlyCo2e.scala b/src/main/scala/org/globalforestwatch/layers/GrossEmissionsCo2OnlyCo2e.scala index 2ebde2ed..282a663e 100644 --- a/src/main/scala/org/globalforestwatch/layers/GrossEmissionsCo2OnlyCo2e.scala +++ b/src/main/scala/org/globalforestwatch/layers/GrossEmissionsCo2OnlyCo2e.scala @@ -10,5 +10,5 @@ case class GrossEmissionsCo2OnlyCo2e(gridTile: GridTile, val datasetName = "gfw_full_extent_co2_gross_emissions" val uri: String = - s"s3://gfw-files/flux_1_2_2/gross_emissions_co2_only_co2e/standard/${gridTile.tileId}.tif" + uriForGrid(gridTile, kwargs) } diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala index fa2f1e16..6dd930fd 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala @@ -46,6 +46,7 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String val plantationsPre2000: PlantationsPre2000 = PlantationsPre2000(gridTile, kwargs) val abovegroundCarbon2000: AbovegroundCarbon2000 = AbovegroundCarbon2000(gridTile, kwargs = kwargs) val belowgroundCarbon2000: BelowgroundCarbon2000 = BelowgroundCarbon2000(gridTile, kwargs = kwargs) + val mangroveBiomassExtent: MangroveBiomassExtent = MangroveBiomassExtent(gridTile, kwargs) def readWindow( windowKey: SpatialKey, windowLayout: LayoutDefinition @@ -96,6 +97,8 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String val plantationsPre2000Tile = plantationsPre2000.fetchWindow(windowKey, windowLayout) val abovegroundCarbon2000Tile = abovegroundCarbon2000.fetchWindow(windowKey, windowLayout) val belowgroundCarbon2000Tile = belowgroundCarbon2000.fetchWindow(windowKey, windowLayout) + val mangroveBiomassExtentTile = + mangroveBiomassExtent.fetchWindow(windowKey, windowLayout) val tile = AnnualUpdateMinimalTile( lossTile, @@ -133,6 +136,7 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String plantationsPre2000Tile, abovegroundCarbon2000Tile, belowgroundCarbon2000Tile, + mangroveBiomassExtentTile, ) Raster(tile, windowKey.extent(windowLayout)) diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala index 47b920f4..0b47f3ca 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala @@ -97,6 +97,7 @@ object AnnualUpdateMinimalSummary { val soilCarbonPerHa: Integer = raster.tile.soilCarbon.getData(col, row) val abovegroundCarbon2000PerHa: Float = raster.tile.abovegroundCarbon2000.getData(col, row) val belowgroundCarbon2000PerHa: Float = raster.tile.belowgroundCarbon2000.getData(col, row) + val mangroveBiomassExtent: Boolean = raster.tile.mangroveBiomassExtent.getData(col, row) val netFluxCo2Pixel = netFluxCo2 * areaHa val grossCumulAbovegroundRemovalsCo2Pixel = grossCumulAbovegroundRemovalsCo2 * areaHa @@ -154,9 +155,12 @@ object AnnualUpdateMinimalSummary { summary.treecoverLoss += areaHa summary.biomassLoss += biomassPixel summary.co2Emissions += co2Pixel - summary.totalGrossEmissionsCo2eCo2Only += grossEmissionsCo2eCo2OnlyPixel - summary.totalGrossEmissionsCo2eNonCo2 += grossEmissionsCo2eNonCo2Pixel - summary.totalGrossEmissionsCo2e += grossEmissionsCo2ePixel + + if (!plantationsPre2000) { + summary.totalGrossEmissionsCo2eCo2Only += grossEmissionsCo2eCo2OnlyPixel + summary.totalGrossEmissionsCo2eNonCo2 += grossEmissionsCo2eNonCo2Pixel + summary.totalGrossEmissionsCo2e += grossEmissionsCo2ePixel + } if (treeCoverLossFromFires) { summary.treeCoverLossFromFires += areaHa @@ -178,7 +182,7 @@ object AnnualUpdateMinimalSummary { summary.totalNetFluxCo2 += netFluxCo2Pixel } } - else if (gain && !plantationsPre2000) { + else if ((gain || mangroveBiomassExtent) && !plantationsPre2000) { // Adds the gain pixels that don't have any tree cover density to the flux model outputs to get // the correct flux model outputs (TCD>=threshold OR Hansen gain=TRUE) summary.totalGrossCumulAbovegroundRemovalsCo2 += grossCumulAbovegroundRemovalsCo2Pixel diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala index eb2fde06..43113e74 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala @@ -44,6 +44,7 @@ case class AnnualUpdateMinimalTile( plantationsPre2000: PlantationsPre2000#OptionalITile, abovegroundCarbon2000: AbovegroundCarbon2000#OptionalFTile, belowgroundCarbon2000: BelowgroundCarbon2000#OptionalFTile, + mangroveBiomassExtent: MangroveBiomassExtent#OptionalITile, ) extends CellGrid[Int] { def cellType: CellType = loss.cellType def cols: Int = loss.cols diff --git a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossGridSources.scala b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossGridSources.scala index 0df1cad8..92194fe5 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossGridSources.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossGridSources.scala @@ -25,8 +25,8 @@ case class TreeLossGridSources(gridTile: GridTile, kwargs: Map[String, Any]) ext val grossCumulAbovegroundRemovalsCo2: GrossCumulAbovegroundRemovalsCo2 = GrossCumulAbovegroundRemovalsCo2(gridTile, kwargs = kwargs) val grossCumulBelowgroundRemovalsCo2: GrossCumulBelowgroundRemovalsCo2 = GrossCumulBelowgroundRemovalsCo2(gridTile, kwargs = kwargs) - val grossEmissionsCo2eNonCo2: GrossEmissionsNonCo2Co2eBiomassSoil = GrossEmissionsNonCo2Co2eBiomassSoil(gridTile, kwargs = kwargs) - val grossEmissionsCo2eCo2Only: GrossEmissionsCo2OnlyCo2eBiomassSoil = GrossEmissionsCo2OnlyCo2eBiomassSoil(gridTile, kwargs = kwargs) + val grossEmissionsCo2eNonCo2: GrossEmissionsNonCo2Co2e = GrossEmissionsNonCo2Co2e(gridTile, kwargs = kwargs) + val grossEmissionsCo2eCo2Only: GrossEmissionsCo2OnlyCo2e = GrossEmissionsCo2OnlyCo2e(gridTile, kwargs = kwargs) val netFluxCo2: NetFluxCo2e = NetFluxCo2e(gridTile, kwargs = kwargs) val fluxModelExtent: FluxModelExtent = FluxModelExtent(gridTile, kwargs = kwargs) diff --git a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossSummary.scala b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossSummary.scala index 40784dbb..9b8f10a9 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossSummary.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossSummary.scala @@ -139,9 +139,12 @@ object TreeLossSummary { if (loss != null) { summary.lossYear(loss).treecoverLoss += areaHa summary.lossYear(loss).biomassLoss += biomassPixel - summary.lossYear(loss).grossEmissionsCo2eCo2Only += grossEmissionsCo2eCo2OnlyPixel - summary.lossYear(loss).grossEmissionsCo2eNonCo2 += grossEmissionsCo2eNonCo2Pixel - summary.lossYear(loss).grossEmissionsCo2eAllGases += grossEmissionsCo2eAllGasesPixel + + if (!plantationsPre2000) { + summary.lossYear(loss).grossEmissionsCo2eCo2Only += grossEmissionsCo2eCo2OnlyPixel + summary.lossYear(loss).grossEmissionsCo2eNonCo2 += grossEmissionsCo2eNonCo2Pixel + summary.lossYear(loss).grossEmissionsCo2eAllGases += grossEmissionsCo2eAllGasesPixel + } } // TODO: use extent2010 to calculate avg biomass incase year is selected diff --git a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossTile.scala b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossTile.scala index e354f78e..2caf0e8a 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossTile.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossTile.scala @@ -22,8 +22,8 @@ case class TreeLossTile(loss: TreeCoverLoss#ITile, grossCumulAbovegroundRemovalsCo2: GrossCumulAbovegroundRemovalsCo2#OptionalFTile, grossCumulBelowgroundRemovalsCo2: GrossCumulBelowgroundRemovalsCo2#OptionalFTile, netFluxCo2: NetFluxCo2e#OptionalFTile, - grossEmissionsCo2eNonCo2: GrossEmissionsNonCo2Co2eBiomassSoil#OptionalFTile, - grossEmissionsCo2eCo2Only: GrossEmissionsCo2OnlyCo2eBiomassSoil#OptionalFTile, + grossEmissionsCo2eNonCo2: GrossEmissionsNonCo2Co2e#OptionalFTile, + grossEmissionsCo2eCo2Only: GrossEmissionsCo2OnlyCo2e#OptionalFTile, fluxModelExtent: FluxModelExtent#OptionalITile) extends CellGrid[Int] { From 0439b78d4673051248783827a4ca78a187d1aca6 Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Mon, 5 Jun 2023 14:09:08 -0700 Subject: [PATCH 21/22] Add mangrove check to TCL analysis --- .../summarystats/treecoverloss/TreeLossGridSources.scala | 6 +++++- .../summarystats/treecoverloss/TreeLossSummary.scala | 3 ++- .../summarystats/treecoverloss/TreeLossTile.scala | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossGridSources.scala b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossGridSources.scala index 92194fe5..b11007f9 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossGridSources.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossGridSources.scala @@ -22,6 +22,7 @@ case class TreeLossGridSources(gridTile: GridTile, kwargs: Map[String, Any]) ext val primaryForest = PrimaryForest(gridTile, kwargs) val plantedForestsBool = PlantedForestsBool(gridTile, kwargs) val plantationsPre2000: PlantationsPre2000 = PlantationsPre2000(gridTile, kwargs) + val mangroveBiomassExtent: MangroveBiomassExtent = MangroveBiomassExtent(gridTile, kwargs) val grossCumulAbovegroundRemovalsCo2: GrossCumulAbovegroundRemovalsCo2 = GrossCumulAbovegroundRemovalsCo2(gridTile, kwargs = kwargs) val grossCumulBelowgroundRemovalsCo2: GrossCumulBelowgroundRemovalsCo2 = GrossCumulBelowgroundRemovalsCo2(gridTile, kwargs = kwargs) @@ -62,6 +63,8 @@ case class TreeLossGridSources(gridTile: GridTile, kwargs: Map[String, Any]) ext val grossEmissionsCo2eCo2OnlyTile = grossEmissionsCo2eCo2Only.fetchWindow(windowKey, windowLayout) val netFluxCo2Tile = netFluxCo2.fetchWindow(windowKey, windowLayout) val fluxModelExtentTile = fluxModelExtent.fetchWindow(windowKey, windowLayout) + val mangroveBiomassExtentTile = + mangroveBiomassExtent.fetchWindow(windowKey, windowLayout) val tile = TreeLossTile( lossTile, @@ -75,12 +78,13 @@ case class TreeLossGridSources(gridTile: GridTile, kwargs: Map[String, Any]) ext primaryForestTile, plantedForestsBoolTile, plantationsPre2000Tile, + mangroveBiomassExtentTile, grossCumulAbovegroundRemovalsCo2Tile, grossCumulBelowgroundRemovalsCo2Tile, netFluxCo2Tile, grossEmissionsCo2eNonCo2Tile, grossEmissionsCo2eCo2OnlyTile, - fluxModelExtentTile + fluxModelExtentTile, ) Raster(tile, windowKey.extent(windowLayout)) diff --git a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossSummary.scala b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossSummary.scala index 9b8f10a9..a32eef00 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossSummary.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossSummary.scala @@ -79,6 +79,7 @@ object TreeLossSummary { val plantationsPre2000: Boolean = raster.tile.plantationsPre2000.getData(col, row) + val mangroveBiomassExtent: Boolean = raster.tile.mangroveBiomassExtent.getData(col, row) val lat: Double = raster.rasterExtent.gridRowToMap(row) val area: Double = Geodesy.pixelArea(lat, raster.cellSize) // uses Pixel's center coordinate. +- raster.cellSize.height/2 doesn't make much of a difference @@ -174,7 +175,7 @@ object TreeLossSummary { summary.totalFluxModelExtentArea += fluxModelExtentAreaPixel } - } else if (gain && !plantationsPre2000) { + } else if ((gain || mangroveBiomassExtent) && !plantationsPre2000) { // Adds the gain pixels that don't have any tree cover density to the flux model outputs to get // the correct flux model outputs (TCD>=threshold OR Hansen gain) summary.totalGrossCumulAbovegroundRemovalsCo2 += grossCumulAbovegroundRemovalsCo2Pixel diff --git a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossTile.scala b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossTile.scala index 2caf0e8a..7b34e865 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossTile.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/treecoverloss/TreeLossTile.scala @@ -19,6 +19,7 @@ case class TreeLossTile(loss: TreeCoverLoss#ITile, primaryForest: PrimaryForest#OptionalITile, plantedForestsBool: PlantedForestsBool#OptionalITile, plantationsPre2000: PlantationsPre2000#OptionalITile, + mangroveBiomassExtent: MangroveBiomassExtent#OptionalITile, grossCumulAbovegroundRemovalsCo2: GrossCumulAbovegroundRemovalsCo2#OptionalFTile, grossCumulBelowgroundRemovalsCo2: GrossCumulBelowgroundRemovalsCo2#OptionalFTile, netFluxCo2: NetFluxCo2e#OptionalFTile, From e45c6078af06bd966533e9fb362204f520a806bc Mon Sep 17 00:00:00 2001 From: Justin Terry Date: Mon, 5 Jun 2023 14:24:32 -0700 Subject: [PATCH 22/22] Consistently use new name Tropical Tree Cover --- src/main/resources/raster-catalog-default.json | 2 +- ...aicLandscapes.scala => TropicalTreeCover.scala} | 4 ++-- .../AnnualUpdateMinimalGridSources.scala | 6 +++--- .../AnnualUpdateMinimalSummary.scala | 14 +++++++------- .../AnnualUpdateMinimalTile.scala | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) rename src/main/scala/org/globalforestwatch/layers/{TreesInMosaicLandscapes.scala => TropicalTreeCover.scala} (82%) diff --git a/src/main/resources/raster-catalog-default.json b/src/main/resources/raster-catalog-default.json index e40bd766..07165267 100644 --- a/src/main/resources/raster-catalog-default.json +++ b/src/main/resources/raster-catalog-default.json @@ -334,7 +334,7 @@ "source_uri": "s3://gfw-data-lake/umd_tree_cover_loss_from_fires/v20230424/raster/epsg-4326/10/40000/year/geotiff/{tile_id}.tif" }, { - "name":"wri_trees_in_mosaic_landscapes", + "name":"wri_tropical_tree_cover", "source_uri": "s3://gfw-data-lake/wri_tropical_tree_cover/v2020/raster/epsg-4326/{grid_size}/{row_count}/percent/geotiff/{tile_id}.tif" }, { diff --git a/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala b/src/main/scala/org/globalforestwatch/layers/TropicalTreeCover.scala similarity index 82% rename from src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala rename to src/main/scala/org/globalforestwatch/layers/TropicalTreeCover.scala index 2617fb6a..13b7455b 100644 --- a/src/main/scala/org/globalforestwatch/layers/TreesInMosaicLandscapes.scala +++ b/src/main/scala/org/globalforestwatch/layers/TropicalTreeCover.scala @@ -2,10 +2,10 @@ package org.globalforestwatch.layers import org.globalforestwatch.grids.GridTile -case class TreesInMosaicLandscapes(gridTile: GridTile, kwargs: Map[String, Any]) +case class TropicalTreeCover(gridTile: GridTile, kwargs: Map[String, Any]) extends IntegerLayer with OptionalILayer { - val datasetName = "wri_trees_in_mosaic_landscapes" + val datasetName = "wri_tropical_tree_cover" override val internalNoDataValue: Int = 255 override val externalNoDataValue: Integer = 255 diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala index 6dd930fd..f987082b 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalGridSources.scala @@ -41,7 +41,7 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String val soilCarbon: SoilCarbon = SoilCarbon(gridTile, kwargs = kwargs) val intactForestLandscapes2000: IntactForestLandscapes2000 = IntactForestLandscapes2000(gridTile, kwargs) val treeCoverLossFromFires: TreeCoverLossFromFires = TreeCoverLossFromFires(gridTile, kwargs) - val treesInMosaicLandscapes: TreesInMosaicLandscapes = TreesInMosaicLandscapes(gridTile, kwargs) + val tropicalTreeCover: TropicalTreeCover = TropicalTreeCover(gridTile, kwargs) val umdGlobalLandCover: UmdGlobalLandcover = UmdGlobalLandcover(gridTile, kwargs) val plantationsPre2000: PlantationsPre2000 = PlantationsPre2000(gridTile, kwargs) val abovegroundCarbon2000: AbovegroundCarbon2000 = AbovegroundCarbon2000(gridTile, kwargs = kwargs) @@ -92,7 +92,7 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String val soilCarbonTile = soilCarbon.fetchWindow(windowKey, windowLayout) val intactForestLandscapes2000Tile = intactForestLandscapes2000.fetchWindow(windowKey, windowLayout) val treeCoverLossFromFiresTile = treeCoverLossFromFires.fetchWindow(windowKey, windowLayout) - val treesInMosaicLandscapesTile = treesInMosaicLandscapes.fetchWindow(windowKey, windowLayout) + val tropicalTreeCoverTile = tropicalTreeCover.fetchWindow(windowKey, windowLayout) val umdGlobalLandCoverTile = umdGlobalLandCover.fetchWindow(windowKey, windowLayout) val plantationsPre2000Tile = plantationsPre2000.fetchWindow(windowKey, windowLayout) val abovegroundCarbon2000Tile = abovegroundCarbon2000.fetchWindow(windowKey, windowLayout) @@ -131,7 +131,7 @@ case class AnnualUpdateMinimalGridSources(gridTile: GridTile, kwargs: Map[String soilCarbonTile, intactForestLandscapes2000Tile, treeCoverLossFromFiresTile, - treesInMosaicLandscapesTile, + tropicalTreeCoverTile, umdGlobalLandCoverTile, plantationsPre2000Tile, abovegroundCarbon2000Tile, diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala index 0b47f3ca..794df687 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalSummary.scala @@ -70,8 +70,8 @@ object AnnualUpdateMinimalSummary { raster.tile.intactForestLandscapes2000.getData(col, row) val treeCoverLossFromFires: Boolean = raster.tile.treeCoverLossFromFires.getData(col, row) - val treesInMosaicLandscapes: Int = - raster.tile.treesInMosaicLandscapes.getData(col, row) + val tropicalTreeCover: Int = + raster.tile.tropicalTreeCover.getData(col, row) val umdGlobalLandCover: String = raster.tile.umdGlobalLandCover.getData(col, row) val plantationsPre2000: Boolean = @@ -112,7 +112,7 @@ object AnnualUpdateMinimalSummary { val belowgroundCarbon2000 = belowgroundCarbon2000PerHa * areaHa def updateSummary( - loss: Integer, tcd2000: Integer, tcdThreshold: Integer, treesInMosaicLandscapes: Integer, umdGlobalLandCover: String, + loss: Integer, tcd2000: Integer, tcdThreshold: Integer, tropicalTreeCover: Integer, umdGlobalLandCover: String, stats: Map[AnnualUpdateMinimalDataGroup, AnnualUpdateMinimalData] ): Map[AnnualUpdateMinimalDataGroup, AnnualUpdateMinimalData] = { val pKey = AnnualUpdateMinimalDataGroup( @@ -138,7 +138,7 @@ object AnnualUpdateMinimalSummary { gain, intactForestLandscapes2000, umdGlobalLandCover, - treesInMosaicLandscapes, + tropicalTreeCover, ) val summary: AnnualUpdateMinimalData = @@ -202,7 +202,7 @@ object AnnualUpdateMinimalSummary { summary.treecoverExtent2010 += areaHa } - if (treesInMosaicLandscapes >= 0) { + if (tropicalTreeCover >= 0) { summary.tropicalTreeCoverExtent += areaHa } @@ -218,10 +218,10 @@ object AnnualUpdateMinimalSummary { } val ttcSummary = { - if (treesInMosaicLandscapes == 255) { + if (tropicalTreeCover == 255) { lossSummary } else { - updateSummary(null, -2, -1, treesInMosaicLandscapes, umdGlobalLandCover, lossSummary) + updateSummary(null, -2, -1, tropicalTreeCover, umdGlobalLandCover, lossSummary) } } diff --git a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala index 43113e74..1528e2f1 100644 --- a/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala +++ b/src/main/scala/org/globalforestwatch/summarystats/annualupdate_minimal/AnnualUpdateMinimalTile.scala @@ -39,7 +39,7 @@ case class AnnualUpdateMinimalTile( soilCarbon: SoilCarbon#OptionalITile, intactForestLandscapes2000: IntactForestLandscapes2000#OptionalITile, treeCoverLossFromFires: TreeCoverLossFromFires#OptionalITile, - treesInMosaicLandscapes: TreesInMosaicLandscapes#OptionalITile, + tropicalTreeCover: TropicalTreeCover#OptionalITile, umdGlobalLandCover: UmdGlobalLandcover#OptionalITile, plantationsPre2000: PlantationsPre2000#OptionalITile, abovegroundCarbon2000: AbovegroundCarbon2000#OptionalFTile,