Skip to content

Handle rasters without a defined NoData value in align_and_resize_raster_stack#477

Open
claire-simpson wants to merge 3 commits intonatcap:mainfrom
claire-simpson:bugfix/476-align-and-resize-with-missing-nodata
Open

Handle rasters without a defined NoData value in align_and_resize_raster_stack#477
claire-simpson wants to merge 3 commits intonatcap:mainfrom
claire-simpson:bugfix/476-align-and-resize-with-missing-nodata

Conversation

@claire-simpson
Copy link
Copy Markdown
Contributor

@claire-simpson claire-simpson commented Mar 27, 2026

If a raster input to align_and_resize_raster_stack does not have a defined NoData value, the function will now automatically pick one. It will also log a warning in the rare instance that a multiband raster input has some but not all bands with undefined NoData values. This is because in this instance, defined NoData values in any bands in that multiband raster (that has mixed NoData conditions) may be redefined as whatever pygeoprocessing picks using choose_nodata.

Steps:

  1. Detects rasters with missing NoData values
  2. Creates a temporary VRT for those rasters and assigns a NoData value using choose_nodata (this is to avoid modifying a user's original data)
  3. Uses the temporary VRT path during warping/alignment
  4. Logs different warnings if (a) a raster has no NoData defined on any band, or (b) a multiband raster has NoData defined on some bands but not others, in which case a single NoData value is applied to all bands in the temporary VRT

Fixes: #476

chosen_nodata = choose_nodata(raster_info['numpy_type'])

if set(nodata_list) != {None}:
LOGGER.warning(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I can tell, gdal does not create geotiffs that have different NoData values (even if you try to explicitly set different NoData values for different bands, it won't work), so I think this would be a very rare situation and therefore not super important or easy to handle gracefully (i.e., by setting NoData only for the bands that lack a defined NoData value, since gdal doesn't support this for tiffs). I also decided not to raise an error as a raster that has the pygeoprocessing-approved NoData value for its datatype (e.g., 32767 for an int16 raster) would be fine.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think gdal handles different nodata values for different bands. See the "UNIFIED_SRC_NODATA" option from gdalwarpoptions.

@claire-simpson claire-simpson requested a review from dcdenu4 March 27, 2026 00:19
@claire-simpson claire-simpson marked this pull request as ready for review March 27, 2026 00:20
Copy link
Copy Markdown
Member

@dcdenu4 dcdenu4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @claire-simpson , I had a comment about taking a look at gdalwarpoptions, to see if that also could be a clean way to pass along the desired destination nodata value to gdal.Warp.

chosen_nodata = choose_nodata(raster_info['numpy_type'])

if set(nodata_list) != {None}:
LOGGER.warning(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think gdal handles different nodata values for different bands. See the "UNIFIED_SRC_NODATA" option from gdalwarpoptions.


vrt_path = os.path.join(temp_working_dir_nodata,
f'input_with_nodata_{index}.vrt')
vrt = gdal.Translate(vrt_path, raster, format='VRT',
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if the creation of the VRT is necessary or if we could take advantage of gdal_warp_options and the dstnodata (?) argument. Like the resample list, could we keep a list of destination nodata values and pass those along through the gdal_warp_options?

I'm not sure it's a better approach than the VRT one other than it reduces a call to gdal.Translate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

align_and_resize_raster_stack should ensure output rasters have a defined NoData value

2 participants