Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Calculate Average Potential Carbon Sequestration in Ecozones, Countries, and Continents\n",
"\n",
"This script calculates statistics on potential carbon sequestration rates over ecozones, countries, and continents. We use per-pixel estimates of the average potential carbon sequestration rate in Mg C/ha/year and per-pixel variance of model estimates from [Cook-Patton et. al 2020](https://www.nature.com/articles/s41586-020-2686-x) to calculate the regional average potential carbon sequestration rate, standard deviation of model variance, and the 95% cofidence interval for the average rate in the region.\n",
"\n",
"Ecozones sourced from FAO [Global Ecological Zones (GEZ) mapping](https://www.fao.org/forest-resources-assessment/remote-sensing/global-ecological-zones-gez-mapping/en/) which can be [downlaoded here](https://data.apps.fao.org/map/catalog/static/api/records/2fb209d0-fd34-4e5e-a3d8-a13c241eb61b).\n",
"\n",
"Country boundaries are sourced from [GADM version 3.6](https://gadm.org/download_world36.html)\n",
"\n",
"Ecozones and country boundaries were intersected using QGIS.\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"import ee\n",
"import numpy as np\n",
"import pandas as pd\n",
"import time"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"#Initialize earth engine\n",
"try:\n",
" ee.Initialize()\n",
"except Exception as e:\n",
" ee.Authenticate()\n",
" ee.Initialize()"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"# load in image collection from Data Lab repository\n",
"imageCollection = ee.ImageCollection('projects/wri-datalab/GFWCarbonSequestrationYoungForests')\n",
"\n",
"# save projection information\n",
"projection = imageCollection.first().projection().getInfo()\n",
"projection_gee = imageCollection.first().projection()\n",
"crs = projection.get('crs')\n",
"crs_transform = projection.get('transform')\n",
"\n",
"# convert image collection to image\n",
"image = imageCollection.toBands()\n",
"# select bands and rename them\n",
"image = image.select(['AboveGround_CoefVariation_b1', 'AboveGround_Lower_CI_b1', 'AboveGround_Mean_b1', \n",
" 'AboveGround_StandardDeviation_b1', 'AboveGround_Upper_CI_b1', 'AboveGround_Variance_b1', \n",
" 'BelowGround_Mean_b1', 'BelowGround_Variance_b1'])\n",
"image = image.rename(['AboveGround_CoefVariation', 'AboveGround_Lower_CI', 'AboveGround_Mean', \n",
" 'AboveGround_StandardDeviation', 'AboveGround_Upper_CI', 'AboveGround_Variance', \n",
" 'BelowGround_Mean', 'BelowGround_Variance'])\n",
"\n",
"def calculate_rate_statistics(feature_collection, region_name, file_name, folder_name):\n",
" \"\"\"\n",
" Function to calculate statistics on potential carbon sequestion rate over a given feature collection,\n",
" including the mean, minimum, and maximum of rates in each region, the 95% confidence interval for the \n",
" mean rate in each region, and the standard deviation of the rate in the region. \n",
"\n",
" Parameters:\n",
" feature_collection (ee.FeatureCollection): feature collection over which to calculate statistics\n",
" region_name (String): name to be included in column names (e.g., 'Average Rate in X' where X is region_name)\n",
" file_name (String): file name of CSV to export to in Google Drive\n",
" folder_name (String): folder name to export to in Google Drive\n",
"\n",
" Returns:\n",
" ee.FeatureCollection of regions with calculated potential carbon sequestration rates\n",
" \"\"\"\n",
" # create combined reducer for calculating the mean, minimum, and maximum of rates in region\n",
" min_max_reducers = ee.Reducer.mean().unweighted().combine(ee.Reducer.min().unweighted(), sharedInputs=True)\n",
" min_max_reducers = min_max_reducers.combine(ee.Reducer.max().unweighted(), sharedInputs=True)\n",
" \n",
" # create combined reducer for calculating sum of variance and count of pixels, which will be used\n",
" # to calculate confidence intervals for the average rate in the region\n",
" sum_count_reducers = ee.Reducer.sum().unweighted().combine(ee.Reducer.count().unweighted(), sharedInputs=True)\n",
"\n",
" # calculate mean, minimum, and maximum of rates over regions\n",
" reduce_region_results = image.select(['AboveGround_Mean']).reduceRegions(\n",
" feature_collection, \n",
" reducer=min_max_reducers.setOutputs(['AboveGround_Mean_mean','AboveGround_Mean_min','AboveGround_Mean_max']), \n",
" crs=crs, crsTransform=crs_transform, \n",
" tileScale=16)\n",
" # calculate sum of model variance and count of pixels over regions\n",
" reduce_region_results = image.select(['AboveGround_Variance']).reduceRegions(\n",
" reduce_region_results, \n",
" reducer=sum_count_reducers.setOutputs(['AboveGround_Variance_sum','AboveGround_Variance_count']), \n",
" crs=crs, crsTransform=crs_transform, \n",
" tileScale=16)\n",
" \n",
" # function to format results from reduce regions and calculate confidence intervals from\n",
" # regional variance sum and pixel count\n",
" def format_results(feature):\n",
" feature = ee.Feature(feature)\n",
" # select statistics\n",
" mean = ee.Number(feature.get('AboveGround_Mean_mean'))\n",
" minimum = ee.Number(feature.get('AboveGround_Mean_min'))\n",
" maximum = ee.Number(feature.get('AboveGround_Mean_max'))\n",
" variance_sum = ee.Number(feature.get('AboveGround_Variance_sum'))\n",
" variance_count = ee.Number(feature.get('AboveGround_Variance_count'))\n",
" \n",
" # calculate standard deviation and 95% confidence intervals\n",
" # with GEE, Null values can cause errors in calculations, so use If statement to catch\n",
" # Null values and otherwise return value\n",
" \n",
" # calculate variance\n",
" variance = ee.Algorithms.If(variance_sum, variance_sum.divide(variance_count.pow(2)), None)\n",
" \n",
" # calculate standard deviation taking the square root of the variance\n",
" standard_deviation = ee.Algorithms.If(variance_sum, ee.Number(variance).sqrt(), None)\n",
" \n",
" # calculate 95% confidence itnervals\n",
" lower_bound = ee.Algorithms.If(mean, mean.subtract(ee.Number(standard_deviation).multiply(1.96)), None)\n",
" upper_bound = ee.Algorithms.If(mean, mean.add(ee.Number(standard_deviation).multiply(1.96)), None)\n",
" \n",
" # save to features with formatted names\n",
" feature = feature.set({\n",
" 'Above Ground Rate Average in '+region_name: mean,\n",
" 'Above Ground Rate Minimum in '+region_name: minimum,\n",
" 'Above Ground Rate Maximum in '+region_name: maximum,\n",
" 'AboveGroundSequestration_Unit'+region_name: 'Mg C/ha/year',\n",
" 'Variance of Above Ground Rate Average in '+region_name:variance,\n",
" 'Standard Deviation of Above Ground Rate Average in '+region_name:standard_deviation,\n",
" 'Lower Bound of 95% Confidence Interval of Above Ground Rate Average in '+region_name:lower_bound,\n",
" 'Upper Bound of 95% Confidence Interval of Above Ground Rate Average in '+region_name:upper_bound,\n",
" 'Number of Pixels in ': variance_count\n",
" })\n",
" \n",
" # remove property names from reduce regions calculation\n",
" property_names = feature.propertyNames()\n",
" property_names = property_names.removeAll(ee.List(['AboveGround_Mean_mean',\n",
" 'AboveGround_Mean_min',\n",
" 'AboveGround_Mean_max',\n",
" 'AboveGround_Variance_sum',\n",
" 'AboveGround_Variance_count']))\n",
" # drop geometry so file can be easily read in Excel\n",
" feature = feature.select(property_names,retainGeometry=False)\n",
" return feature\n",
" \n",
" # loop over results to format and return\n",
" results = reduce_region_results.map(format_results)\n",
" results = ee.FeatureCollection(results)\n",
" # export to Google Drive\n",
" export_results_task = ee.batch.Export.table.toDrive(\n",
" collection = results, \n",
" folder = folder_name,\n",
" description = file_name, \n",
" fileNamePrefix = file_name)\n",
"\n",
" export_results_task.start()\n",
" \n"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"# define regions asset\n",
"regions = ee.FeatureCollection('projects/wri-datalab/GFWCarbonSequestrationYoungForestsBoundaries/FAO_GEZ_Ecozones_By_Country')\n",
"# define name for columns\n",
"region_name = 'Ecozone and Country'\n",
"# define file name to export to\n",
"output_name = 'CarbonSequestration_AboveGroundAverage_Ecozone_Country_GEE'\n",
"# define folder to export to\n",
"folder_name = 'CarbonRateCalculationsForIPCC'\n",
"\n",
"# rename columns from FAO Ecozones and GADM country boundaries to be easily readable\n",
"regions = ee.FeatureCollection(regions.map(lambda x: ee.Feature(x).select(['GID_0','NAME_0','gez_abbrev','gez_code','gez_name','RootShoot'], \n",
" ['ISO Code','Country','Ecozone Abbreviation','Ecozone Code','Ecozone Name','RootShoot'], True)))\n",
"\n",
"# calculate rates for regions\n",
"calculate_rate_statistics(regions,region_name,output_name,folder_name)\n"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [],
"source": [
"# define regions asset\n",
"regions = ee.FeatureCollection('projects/wri-datalab/GFWCarbonSequestrationYoungForestsBoundaries/FAO_GEZ_Ecozones_By_Continent')\n",
"# define name for columns\n",
"region_name = 'Ecozone and Continent'\n",
"# define file name to export to\n",
"output_name = 'CarbonSequestration_AboveGroundAverage_Ecozone_Continent_GEE'\n",
"# define folder to export to\n",
"folder_name = 'CarbonRateCalculationsForIPCC'\n",
"\n",
"#rename columns from FAO Ecozones and continent boundaries to be easily readable\n",
"regions = ee.FeatureCollection(regions.map(lambda x: ee.Feature(x).select(['REGION','gez_abbrev','gez_code','gez_name','RootShoot'], \n",
" ['Continent','Ecozone Abbreviation','Ecozone Code','Ecozone Name','RootShoot'], True)))\n",
"\n",
"#calculate rates for regions\n",
"calculate_rate_statistics(regions,region_name,output_name,folder_name)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# define regions asset\n",
"regions = ee.FeatureCollection('projects/wri-datalab/GFWCarbonSequestrationYoungForestsBoundaries/FAO_GEZ_Ecozones')\n",
"# define name for columns\n",
"region_name = 'Ecozone'\n",
"# define file name to export to\n",
"output_name = 'CarbonSequestration_AboveGroundAverage_Ecozone_GEE'\n",
"# define folder to export to\n",
"folder_name = 'CarbonRateCalculationsForIPCC'\n",
"\n",
"#rename columns from FAO Ecozones and continent boundaries to be easily readable\n",
"regions = ee.FeatureCollection(regions.map(lambda x: ee.Feature(x).select(['gez_abbrev','gez_code','gez_name','RootShoot'], \n",
" ['Ecozone Abbreviation','Ecozone Code','Ecozone Name','RootShoot'], True)))\n",
"\n",
"#calculate rates for regions\n",
"calculate_rate_statistics(regions,region_name,output_name,folder_name)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
7 changes: 7 additions & 0 deletions MappingGlobalCarbon/CalculateRatesInRegions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## Calculate Average Carbon Sequestration Rate and Other Statistics in Areas of Interest

This folder contains code to calculate the average carbon sequestration rate and other statistics in areas of interest. Other statistics include the lower and upper confidence interval bounds for the average rate in a region, the variance in modeled rates over the region, and the minimum and maximum observed rate in the region.

Contents:
1. CalculateRateStatisticsInRegion.ipynb: Jupyter notebook using [Google Earth Engine's Python API](https://developers.google.com/earth-engine/guides/python_install) to calculate rate statistics in ecozones by country and continent.
2. SreamlitApp-CarbonRate-GriscomAreas: Python code for a locally deployable [Streamlit](https://streamlit.io/) based web-app that allows users to calculate carbon sequestration rate and accumulation statistics for inputted regions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## Calculate Carbon Sequestration Rate and Other Statistics in Areas of Interest over [Griscom et al. 2017](https://www.pnas.org/doi/full/10.1073/pnas.1710465114) Potential Restoration Areas
This folder contains code for locally deploying a Python based [Streamlit](https://streamlit.io/) app for calculating the average carbon sequestration rate and total accumulation for an inputted area of interest over potential restoration areas defined in [Griscom et al. 2017](https://www.pnas.org/doi/full/10.1073/pnas.1710465114).

To deploy the app, install required models by running
1. `pip install -r requirements.txt` to install required modules
2. `streamlit run carbon-app.py` to run the streamlit app

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Column Name,Description
Griscom_Restoration_Area_Hectares,"Area of restoration opportunity from Griscom et al 2017, in hectares"
Modeled_AboveGround_Restoration_Area_Hectares,"Area of restoration opportunity from Griscom et al 2017 and included in modeled sequestration rates, in hectares"
AboveGround_Sequestration_Rate_Mean,"Estimated average rate of aboveground carbon sequestration in polygon(s), in Mg C/ha/year"
AboveGround_Sequestration_Rate_Variance,"Variance of the estimate of average rate of aboveground carbon sequestration in polygon(s), in (Mg C/ha/year)^2"
AboveGround_Sequestration_Rate_LowerBound,"Lower bound of estimate of average rate of aboveground carbon sequestration in polygon(s), in Mg C/ha/year"
AboveGround_Sequestration_Rate_UpperBound,"Upper bound of estimate of average rate of aboveground carbon sequestration in polygon(s), in Mg C/ha/year"
AboveGround_Sequestration_Rate_Max,"Maximum observed rate of aboveground carbon sequestration in polygon(s), in Mg C/ha/year"
AboveGround_Sequestration_Rate_Min,"Minimum observed rate of aboveground carbon sequestration in polygon(s), in Mg C/ha/year"
AboveGround_Carbon_Accumulation,"Estimated total aboveground carbon accumulation per year in polygon(s), in Mg C/year"
AboveGround_Carbon_Accumulation_Variance,"Variance of the estimate of total aboveground carbon accumulation per year in polygon(s), in (Mg C/year)^2"
AboveGround_Carbon_Accumulation_LowerBound,"Lower bound of estimate of total aboveground carbon accumulation per year in polygon(s), in Mg C/year"
AboveGround_Carbon_Accumulation_UpperBound,"Upper bound of estimate of total aboveground carbon accumulation per year in polygon(s), in Mg C/year"
Modeled_BelowGround_Restoration_Area_Hectares,"Area of restoration opportunity from Griscom et al 2017 and included in modeled sequestration rates, in hectares"
BelowGround_Sequestration_Rate_Mean,"Estimated average rate of belowground carbon sequestration in polygon(s), in Mg C/ha/year"
BelowGround_Sequestration_Rate_Variance,"Variance of the estimate of average rate of belowground carbon sequestration in polygon(s), in (Mg C/ha/year)^2"
BelowGround_Sequestration_Rate_LowerBound,"Lower bound of estimate of average rate of belowground carbon sequestration in polygon(s), in Mg C/ha/year"
BelowGround_Sequestration_Rate_UpperBound,"Upper bound of estimate of average rate of belowground carbon sequestration in polygon(s), in Mg C/ha/year"
BelowGround_Sequestration_Rate_Max,"Maximum observed rate of belowground carbon sequestration in polygon(s), in Mg C/ha/year"
BelowGround_Sequestration_Rate_Min,"Minimum observed rate of belowground carbon sequestration in polygon(s), in Mg C/ha/year"
BelowGround_Carbon_Accumulation,"Estimated total belowground carbon accumulation per year in polygon(s), in Mg C/year"
BelowGround_Carbon_Accumulation_Variance,"Variance of the estimate of total belowground carbon accumulation per year in polygon(s), in (Mg C/year)^2"
BelowGround_Carbon_Accumulation_LowerBound,"Lower bound of estimate of total belowground carbon accumulation per year in polygon(s), in Mg C/year"
BelowGround_Carbon_Accumulation_UpperBound,"Upper bound of estimate of total belowground carbon accumulation per year in polygon(s), in Mg C/year"
Loading