Global InVEST
The standard version of InVEST, provided by the Natural Capital Project, is a set of tools for quantifying the values of natural capital in clear, credible, and practical ways. InVEST enables decision-makers to assess the trade-offs associated with alternative management choices and to identify the policies and practices that can best balance human needs with environmental sustainability. InVEST is designed to be accessible to a broad audience, including conservation organizations, governments, development banks, academics, and the private sector.
The InVEST software comprises an easy-to-use graphical interface version as well as direct access to the Python library for advanced users. Typical InVEST applications looked at individual watersheds or small administrative regions. Starting withChaplin-Kramer et al. (2019), however, a series of global applications of InVEST have developed. These applications have sometimes used the standard InVEST Python library, but in most cases, custom versions were created to enable calculation of the models globally (which was challenging for both computation and data reasons). The term Global InVEST refers informally to the multiple code repositories behind these applications. Although the code-base for Global InVEST is still fragmented, we are working to organize and standardize these models.
The three main sources for Global InVEST is
- Nature’s Contributions to People: Chaplin-Kramer et al. (2019)
- GTAP-InVEST: Johnson et al. (2023)
- Nature’s Frontiers: Damania et al. (2023)
Setting Up Global InVEST Models
To run the Global InVEST models within the Earth Economy Dev Stack standard, you first need to follow the installation steps in the earth_economy_devstack
guide to include global_invest
and hazelbean
in your workspace.
Folder Structure of Global InVEST
Within the global_invest_dev/global_invest
directory, you will find the following structure:
global_invest
│-- ecosystem_services_subfolders
│-- global_invest_main.py
│-- ecosystem_services_functions.py
│-- ecosystem_services_tasks.py
│-- example_run_file.py
│-- example_execute_invest_ES.py
│-- run_global_ES.py
ecosystem_services_subfolders
contains the scripts for the specific ecosystem service models. Currently, it includes folders likepollination_sufficiency
andcnc_global_cv
.global_invest_main.py
is the primary script for running the global InVEST models.ecosystem_services_functions.py
includes general functions used by the global InVEST models. Files ending in_functions.py
are not project-specific and contain general utility functions.ecosystem_services_tasks.py
includes tasks specific to the global InVEST models. Files ending in_tasks.py
are project-specific and include the project objectp
, which is handled byProject Flow
inhazelbean
.example_run_file.py
is a script to run an example at the global level. This script demonstrates how to run a carbon storage model for a specific area of interest (AOI). The default AOI isRWA
.example_execute_invest_ES.py
is similar to the run script created by InVEST but uses different paths.run_global_ES.py
is the script for running the global InVEST models for a specific Ecosystem Service. Files ending in_ES.py
are provided as examples, such as the Global-InVEST-Carbon Storage model (run_global_carbon.py
).
Run Global InVEST Models
To have a testing run of Global InVEST Model, you can run the example_run_file.py
script. This script runs the carbon storage model for a specific AOI (Rwanda). The script will download the necessary data, run the model, and save the results in the workspace
directory. It is well-documented script with the following major steps:
- Create a
Project
objectp
, and set up corresponding project-directories.
# Create the project flow object
= hb.ProjectFlow()
p
# Set project-directories
= os.path.expanduser('~') # EE Devstack is defined relative to the user's directory, but could be overwritten if running not for the Devstack.
p.user_dir = ['Files', 'global_invest', 'projects'] # Extra directories used inside the user_dir
p.extra_dirs = 'test_global_invest' # Name of the project, which will be used to create the project_dir
p.project_name = p.project_name + '_' + hb.pretty_time() # Comment this line out if you want it to use an existing project. Will skip recreation of files that already exist.
p.project_name = os.path.join(p.user_dir, os.sep.join(p.extra_dirs), p.project_name) # Combines above to set the user_dir.
p.project_dir # Based on the project_dir, create all other relevant dirs, like input, intermediate, and output.
p.set_project_dir(p.project_dir)
# Set basa_data_dir. Will download required files here.
= os.path.join(p.user_dir, 'Files', 'base_data') # Could be anywhere, including external storage. But, should not be cloud-controlled (like Google Drive). p.base_data_dir
- Define the test and paths for the LULC, region_ids, and global_regions_vector. By default, the AOI is set to Rwanda. The paths are set to the
catographic/ee
folder in the base data directory.
# Set model-paths and details
= 'RWA'
p.aoi = p.get_path('lulc/esa/lulc_esa_2017.tif') # Defines the fine_resolution
p.base_year_lulc_path = p.get_path('cartographic/ee/id_rasters/eemarine_r566_ids_900sec.tif') # Defines the coarse_resolution
p.region_ids_coarse_path = p.get_path('cartographic/ee/eemarine_r566_correspondence.gpkg') # Will be used to create the aoi vector p.global_regions_vector_path
- Create your own tasks trees and execute the task tree.
For example, in the following task tree, the project object p
has 4 tasks:
project_aoi_task
: Clips the global regions vector to the AOI selected.aoi_inputs_task
: Clips global inputs based on the AOI.ecosystem_services_task
: Empty task just to contain all the other ES tasks (by being set as their parent task).carbon_storage_biophysical_task
: Actually implements the model logic.
Note: if parent=p.ecosystem_services_task
is not set for carbon_storage_biophysical_task
, the task will not be set as the child-task of the ecosystem_services_task
.
def build_task_tree(p):
= p.add_task(ecosystem_services_tasks.project_aoi) # Clips the global_regions_vector to the aoi selected
p.project_aoi_task = p.add_task(ecosystem_services_tasks.aoi_inputs) # Clips global inputs based on the aoi
p.aoi_inputs_task = p.add_task(ecosystem_services_tasks.ecosystem_services) # Empty task just to contain all the other ES tasks (by being set as their parent task)
p.ecosystem_services_task = p.add_task(ecosystem_services_tasks.example_ecosystem_services_invest_task, parent=p.ecosystem_services_task) # Actually implements the model logic
p.carbon_storage_biophysical_task
# Build the task tree and excute it!
build_task_tree(p) p.execute()
Customizing _tasks
, _functions
, and run_
Files in Global InVEST
If you are a new user who has forked the global_invest_dev
repository and want to add a new ecosystem service model, you can follow these steps:
- Copy and paste the
example_run_file.py
, then rename it torun_global_<new_es>.py
. In the newly created file, ensure you define your ownp.<new_es>_biophysical_task
in theecosystem_services_tasks.py
file. For instance, if your new ecosystem service model issediment_retention
, in yourrun_global_sdr.py
, you should define your own task tree as follows:
def build_task_tree(p):
= p.add_task(ecosystem_services_tasks.project_aoi) # Clips the global_regions_vector to the selected AOI
p.project_aoi_task = p.add_task(ecosystem_services_tasks.aoi_inputs) # Clips global inputs based on the AOI
p.aoi_inputs_task = p.add_task(ecosystem_services_tasks.ecosystem_services) # Empty task to contain all other ES tasks (set as their parent task)
p.ecosystem_services_task = p.add_task(ecosystem_services_tasks.sediment_retention_invest_task, parent=p.ecosystem_services_task) # CHANGED FROM CARBON STORAGE TO SEDIMENT RETENTION p.sediment_retention_biophysical_task
- In the
ecosystem_services_tasks.py
file, add a new task for the new ecosystem service model. For example:
def sediment_retention_invest_task(p):
"""Iterate over a scenarios file to calculate SDR from LULC maps."""
if p.run_this:
ecosystem_services_functions.sdr_biophysical(current_lulc_path, current_sdr_path, p.exhaustive_sdr_path, sdr_output_path)
- Any functions used in the
sediment_retention_invest_task
in theecosystem_services_tasks.py
file should be called from theecosystem_services_functions.py
file. For example, thesdr_biophysical
function called in thedef sediment_retention_invest_task(p):
function should be defined inecosystem_services_functions.py
. Alternatively, you can save this function in a separate Python or C script compiled by Cython for faster calculation, similar tocarbon_storage_ipcc_tier_1_cython.pyx
. However, keep the main calculation core in a single Cython file and retain the main body of the function in theecosystem_services_functions.py
file.