Skip to content

Commit e2b18bf

Browse files
joelfiddesclaude
andcommitted
Auto-mask nodata DEM pixels before clustering
Prevents KMeans crash when DEM contains NaN pixels (e.g. from reprojected rasters with non-rectangular valid regions). Nodata pixels are now automatically excluded from clustering, both with and without a user-provided mask file. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 8a3a535 commit e2b18bf

1 file changed

Lines changed: 9 additions & 3 deletions

File tree

TopoPyScale/topoclass.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,9 +306,15 @@ def extract_topo_cluster_param(self):
306306
# read df param
307307
df_param = ts.ds_to_indexed_dataframe(self.toposub.ds_param)
308308

309+
# Auto-mask nodata pixels (e.g. from reprojected DEMs with non-rectangular valid regions)
310+
valid_elev = ~df_param['elevation'].isna()
311+
n_nodata = (~valid_elev).sum()
312+
if n_nodata > 0:
313+
print(f'---> Auto-masking {n_nodata} nodata pixels from DEM')
314+
309315
# add mask and cluster feature
310316
if mask_file in [None, {}]:
311-
mask = [True] * len(df_param)
317+
mask = valid_elev
312318
else:
313319
if not os.path.isabs(mask_file):
314320
mask_file = Path(self.config.project.directory, mask_file)
@@ -330,8 +336,8 @@ def extract_topo_cluster_param(self):
330336
f'The GeoTIFFS of the DEM and the MASK need to have the same bounds/resolution. \n{str_bounds}\n{str_res}')
331337
print(f'---> Only consider grid cells inside mask ({Path(mask_file).name})')
332338

333-
# get mask
334-
mask = ts.ds_to_indexed_dataframe(ds_mask)['mask'] == 1
339+
# get mask (combine with nodata auto-mask)
340+
mask = (ts.ds_to_indexed_dataframe(ds_mask)['mask'] == 1) & valid_elev
335341

336342
# add cluster groups. Groups can be landcover classes for instance
337343
if groups_file in [None, {}]:

0 commit comments

Comments
 (0)