What is the issue or question you have?
I am trying to run the crop pollination model. My issue is that the model fails complete due to ‘NoneType’ values in the raster (.tif) for my LULC maps when mapped to my correspondence of the LULC and biophysical table. I have struggled to resolve this for a few days after consulting a few colleagues as well as ChatGPT.
Specifically, I get the following error message:
ERROR:root:Error running InVEST pollination:
Traceback (most recent call last):
File "c:\Users\ryanm\mambaforge\envs\teem_devstack\Lib\site-packages\natcap\invest\pollination.py", line 767, in execute
alpha_kernel_raster_task = alpha_kernel_map[kernel_path]
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
KeyError: 'C:/Users/ryanm/Desktop/temp/pollinator_maps_invest\\intermediate_outputs\\kernel_180000.000000_UGA_2010.tif'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<ipython-input-4-d8f523ebc967>", line 54, in <module>
natcap.invest.pollination.execute(args)
File "c:\Users\ryanm\mambaforge\envs\teem_devstack\Lib\site-packages\natcap\invest\pollination.py", line 769, in execute
alpha_kernel_raster_task = task_graph.add_task(
^^^^^^^^^^^^^^^^^^^^
File "c:\Users\ryanm\mambaforge\envs\teem_devstack\Lib\site-packages\taskgraph\Task.py", line 674, in add_task
new_task._call()
File "c:\Users\ryanm\mambaforge\envs\teem_devstack\Lib\site-packages\taskgraph\Task.py", line 1093, in _call
payload = self._func(*self._args, **self._kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\ryanm\mambaforge\envs\teem_devstack\Lib\site-packages\pygeoprocessing\kernels.py", line 133, in exponential_decay_kernel
create_distance_decay_kernel(
File "c:\Users\ryanm\mambaforge\envs\teem_devstack\Lib\site-packages\pygeoprocessing\kernels.py", line 254, in create_distance_decay_kernel
kernel_band = kernel_dataset.GetRasterBand(1)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'GetRasterBand'
DEBUG:taskgraph.Task:Invoking terminate. already terminated? True
What do you expect to happen?
I expect the following python script to run. This should translate LULC maps using the biophysical table and guide tables for crop pollination by pollinator species into pollinator abundance and supply raster maps (.tif) that I can then merge with my other data to assess changes in pollinator abundance spatiallly.
"""
Purpose: To calculate pollinator abundance and supply at high spatial resolution given land-use cover and biophysical tables.
This produces a pollination abundance and supply raster data set for each country for each year in the data.
This additionally will break down for each type of pollinator identified in the biophysical table.
"""
# Dependencies
import natcap.invest.pollination
import natcap.invest.utils
import os
import logging
logging.basicConfig(level=logging.DEBUG)
# Input Agrument for Data
args = {
# Determine the folder for outputs.
'workspace_dir': 'C:/Users/ryanm/Desktop/temp/pollinator_maps_invest',
# Farmer specific plots. If added, this would make values specific to farmer plots.
'farm_vector_path': '',
# Translation of pollination abundance given the lulc
'guild_table_path': 'C:/Users/ryanm/Desktop/temp/pollination_guild_table.csv',
# Determines requirements for each species of pollinator
'landcover_biophysical_table_path': "C:/Users/ryanm/Desktop/temp/pollination_lulc_biophysical_table.csv",
'n_workers': '-1',
'results_suffix': '',
}
# Sample countries and years
# sample_countries = ['ETH', 'NER', 'NGA', 'UGA', 'TZA', 'MWI']
# sample_years = range(2010, 2021)
# TEST:
sample_countries = ['UGA']
sample_years = [2010]
# Loop through each country and year
for country in sample_countries:
for year in sample_years:
# Update the LULC raster path dynamically for each country and year
lulc_raster_path = f'C:/Users/ryanm/Desktop/temp/lulc_cropped/{country}/lulc_esa_{year}.tif'
# Ensure the LULC raster file exists for the current combination of country and year
if os.path.exists(lulc_raster_path):
# Update the 'landcover_raster_path' in the arguments dictionary
args['landcover_raster_path'] = lulc_raster_path
# Optionally, you could add a results suffix for each country-year combination
args['results_suffix'] = f'_{country}_{year}'
# Execute the InVEST pollination model for the current country and year
print(f"Running InVEST Pollination for {country} in {year}...")
try:
natcap.invest.pollination.execute(args)
except Exception as e:
logging.error("Error running InVEST pollination:", exc_info=True)
else:
print(f"Warning: LULC raster file for {country} in {year} does not exist.")
What have you tried so far?
I took ESA CCI data for LULC maps as my base data. This has metadata describing the LULC codes. It labels no data as zero. So in the biophysical table I create a row to capture this value. Putting the raster maps into QGIS, I notice that it determines no data as 255. So I add this value as well. Despite this, the script fails because it is reading some grid values as ‘NoneType’. If I add NoneType to the biophysical table to give it a correspondence, the script fails stating that the lulc codes are no longer integers and are instead string values (which makes sense). I asked two colleagues about this, and we unsuccessfully troubleshooted for a couple of days. I then asked ChatGPT for a solution using my code and the error messages. This suggested I check the paths to the lulc maps (they read in fine), the path to my intermediate files (that exists and is okay), that I check my biophysical table (and as mentioned that can’t hold NoneType as a correspondence value). So this was a dead end. My suspicion is that intermediate_outputs\\kernel_180000.000000_UGA_2010.tif
is the key to my answer but I can’t figure out how to resolve it.