Skip to content

Commit b89708a

Browse files
adacovskclaude
andcommitted
style: apply ruff format to geospatial files
Apply ruff code formatting to files modified in the geospatial index feature branch. No functional changes, only formatting adjustments for consistency. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 949675f commit b89708a

File tree

6 files changed

+107
-108
lines changed

6 files changed

+107
-108
lines changed

autotest/test_edge_cases.py

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,17 @@ def test_thin_sliver_cell():
5050
vertices=vertices,
5151
cell2d=cell2d,
5252
top=np.ones(ncells) * 10.0,
53-
botm=np.zeros(ncells)
53+
botm=np.zeros(ncells),
5454
)
5555

5656
# Build index
5757
index = GeospatialIndex(grid)
5858

5959
# Test points in/near the sliver region
6060
test_points = [
61-
(50.025, 50.0), # Should be in a sliver cell
62-
(50.075, 25.0), # Should be in a sliver cell
63-
(50.025, 75.0), # Should be in a sliver cell
61+
(50.025, 50.0), # Should be in a sliver cell
62+
(50.075, 25.0), # Should be in a sliver cell
63+
(50.025, 75.0), # Should be in a sliver cell
6464
]
6565

6666
found_count = 0
@@ -71,6 +71,7 @@ def test_thin_sliver_cell():
7171
xv, yv, _ = grid.xyzvertices
7272
verts = np.column_stack([xv[result], yv[result]])
7373
from matplotlib.path import Path
74+
7475
path = Path(verts)
7576
is_inside = path.contains_point((x, y), radius=1e-9)
7677

@@ -88,8 +89,7 @@ def test_thin_sliver_cell():
8889
# At least some points should be found
8990
# (not all may be in cells due to Delaunay triangulation specifics)
9091
assert found_count > 0, (
91-
f"Should find at least some points in sliver cells, "
92-
f"found {found_count}/3"
92+
f"Should find at least some points in sliver cells, found {found_count}/3"
9393
)
9494

9595

@@ -114,19 +114,17 @@ def test_boundary_points():
114114
]
115115

116116
grid = VertexGrid(
117-
vertices=vertices,
118-
cell2d=cell2d,
119-
top=np.ones(4) * 10.0,
120-
botm=np.zeros(4)
117+
vertices=vertices, cell2d=cell2d, top=np.ones(4) * 10.0, botm=np.zeros(4)
121118
)
122119

123120
index = GeospatialIndex(grid)
124121

125122
# Test point exactly on a shared edge (between cells 0 and 1)
126123
# Should find one of the two cells
127124
result = index.query_point(1.0, 0.5, k=10)
128-
assert result is not None or result == 0 or result == 1, \
125+
assert result is not None or result == 0 or result == 1, (
129126
"Point on boundary should be found in one of the adjacent cells"
127+
)
130128

131129

132130
def test_corner_points():
@@ -148,10 +146,7 @@ def test_corner_points():
148146
]
149147

150148
grid = VertexGrid(
151-
vertices=vertices,
152-
cell2d=cell2d,
153-
top=np.ones(4) * 10.0,
154-
botm=np.zeros(4)
149+
vertices=vertices, cell2d=cell2d, top=np.ones(4) * 10.0, botm=np.zeros(4)
155150
)
156151

157152
index = GeospatialIndex(grid)
@@ -180,10 +175,7 @@ def test_outside_grid():
180175
]
181176

182177
grid = VertexGrid(
183-
vertices=vertices,
184-
cell2d=cell2d,
185-
top=np.array([10.0]),
186-
botm=np.array([0.0])
178+
vertices=vertices, cell2d=cell2d, top=np.array([10.0]), botm=np.array([0.0])
187179
)
188180

189181
index = GeospatialIndex(grid)
@@ -199,8 +191,7 @@ def test_outside_grid():
199191
for x, y in outside_points:
200192
result = index.query_point(x, y, k=10)
201193
assert result is None, (
202-
f"Point ({x}, {y}) outside grid should return None, "
203-
f"got {result}"
194+
f"Point ({x}, {y}) outside grid should return None, got {result}"
204195
)
205196

206197

autotest/test_geospatial_benchmark.py

Lines changed: 57 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717

1818
def benchmark_decorator(func):
1919
"""Decorator to time function execution."""
20+
2021
def wrapper(*args, **kwargs):
2122
start = time.perf_counter()
2223
result = func(*args, **kwargs)
2324
elapsed = time.perf_counter() - start
2425
return result, elapsed
26+
2527
return wrapper
2628

2729

@@ -45,9 +47,12 @@ def old_vertex_intersect(grid, x, y):
4547
ya = np.array(yv[icell2d])
4648

4749
# Bounding box check
48-
if (np.any(xi <= xa) and np.any(xi >= xa) and
49-
np.any(yi <= ya) and np.any(yi >= ya)):
50-
50+
if (
51+
np.any(xi <= xa)
52+
and np.any(xi >= xa)
53+
and np.any(yi <= ya)
54+
and np.any(yi >= ya)
55+
):
5156
path = Path(np.stack((xa, ya)).transpose())
5257
if is_clockwise(xa, ya):
5358
radius = -1e-9
@@ -110,32 +115,29 @@ def test_benchmark_vertex_grid_small():
110115
# CRITICAL: Verify results are identical (treating None and nan as equivalent)
111116
# Convert both to use nan for unfound points
112117
results_old_normalized = np.array(
113-
[r if r is not None else np.nan for r in results_old],
114-
dtype=float
118+
[r if r is not None else np.nan for r in results_old], dtype=float
115119
)
116120
results_new_normalized = np.array(
117121
[
118-
r if not (isinstance(r, float) and np.isnan(r))
119-
else np.nan
122+
r if not (isinstance(r, float) and np.isnan(r)) else np.nan
120123
for r in results_new
121124
],
122-
dtype=float
125+
dtype=float,
123126
)
124127

125128
# Check matches including nan==nan comparisons
126129
both_valid = ~np.isnan(results_old_normalized) & ~np.isnan(results_new_normalized)
127130
both_invalid = np.isnan(results_old_normalized) & np.isnan(results_new_normalized)
128-
matches = (
129-
np.sum((results_old_normalized == results_new_normalized) & both_valid)
130-
+ np.sum(both_invalid)
131-
)
131+
matches = np.sum(
132+
(results_old_normalized == results_new_normalized) & both_valid
133+
) + np.sum(both_invalid)
132134
mismatches = n_test - matches
133135

134-
print(f"\n{'='*60}")
136+
print(f"\n{'=' * 60}")
135137
print(f"Small VertexGrid Test ({ncells} cells, {n_test} points)")
136-
print(f"{'='*60}")
138+
print(f"{'=' * 60}")
137139
print("CORRECTNESS:")
138-
print(f" Matching results: {matches}/{n_test} ({100*matches/n_test:.1f}%)")
140+
print(f" Matching results: {matches}/{n_test} ({100 * matches / n_test:.1f}%)")
139141
print(f" Mismatches: {mismatches}")
140142
if mismatches > 0:
141143
print(" ERROR: Methods produced different results!")
@@ -150,14 +152,15 @@ def test_benchmark_vertex_grid_small():
150152

151153
speedup = time_old / time_new
152154
print("\nPERFORMANCE:")
153-
print(f" Old method (O(n) loop): {time_old*1000:.2f} ms")
154-
print(f" New method (KD-tree + Hull): {time_new*1000:.2f} ms")
155+
print(f" Old method (O(n) loop): {time_old * 1000:.2f} ms")
156+
print(f" New method (KD-tree + Hull): {time_new * 1000:.2f} ms")
155157
print(f" Speedup: {speedup:.2f}x")
156-
print(f"{'='*60}\n")
158+
print(f"{'=' * 60}\n")
157159

158160
# MUST match exactly (treating None and nan as equivalent)
159-
assert mismatches == 0, \
161+
assert mismatches == 0, (
160162
f"Results don't match! {mismatches} mismatches out of {n_test} points"
163+
)
161164

162165

163166
def test_benchmark_vertex_grid_medium():
@@ -200,32 +203,29 @@ def test_benchmark_vertex_grid_medium():
200203
# CRITICAL: Verify results are identical (treating None and nan as equivalent)
201204
# Convert both to use nan for unfound points
202205
results_old_normalized = np.array(
203-
[r if r is not None else np.nan for r in results_old],
204-
dtype=float
206+
[r if r is not None else np.nan for r in results_old], dtype=float
205207
)
206208
results_new_normalized = np.array(
207209
[
208-
r if not (isinstance(r, float) and np.isnan(r))
209-
else np.nan
210+
r if not (isinstance(r, float) and np.isnan(r)) else np.nan
210211
for r in results_new
211212
],
212-
dtype=float
213+
dtype=float,
213214
)
214215

215216
# Check matches including nan==nan comparisons
216217
both_valid = ~np.isnan(results_old_normalized) & ~np.isnan(results_new_normalized)
217218
both_invalid = np.isnan(results_old_normalized) & np.isnan(results_new_normalized)
218-
matches = (
219-
np.sum((results_old_normalized == results_new_normalized) & both_valid)
220-
+ np.sum(both_invalid)
221-
)
219+
matches = np.sum(
220+
(results_old_normalized == results_new_normalized) & both_valid
221+
) + np.sum(both_invalid)
222222
mismatches = n_test - matches
223223

224-
print(f"\n{'='*60}")
224+
print(f"\n{'=' * 60}")
225225
print(f"Medium VertexGrid Test ({ncells} cells, {n_test} points)")
226-
print(f"{'='*60}")
226+
print(f"{'=' * 60}")
227227
print("CORRECTNESS:")
228-
print(f" Matching results: {matches}/{n_test} ({100*matches/n_test:.1f}%)")
228+
print(f" Matching results: {matches}/{n_test} ({100 * matches / n_test:.1f}%)")
229229
print(f" Mismatches: {mismatches}")
230230
if mismatches > 0:
231231
print(" ERROR: Methods produced different results!")
@@ -245,14 +245,15 @@ def test_benchmark_vertex_grid_medium():
245245

246246
speedup = time_old / time_new
247247
print("\nPERFORMANCE:")
248-
print(f" Old method (O(n) loop): {time_old*1000:.2f} ms")
249-
print(f" New method (KD-tree + Hull): {time_new*1000:.2f} ms")
248+
print(f" Old method (O(n) loop): {time_old * 1000:.2f} ms")
249+
print(f" New method (KD-tree + Hull): {time_new * 1000:.2f} ms")
250250
print(f" Speedup: {speedup:.2f}x")
251-
print(f"{'='*60}\n")
251+
print(f"{'=' * 60}\n")
252252

253253
# MUST match exactly (treating None and nan as equivalent)
254-
assert mismatches == 0, \
254+
assert mismatches == 0, (
255255
f"Results don't match! {mismatches} mismatches out of {n_test} points"
256+
)
256257

257258

258259
@pytest.mark.slow
@@ -293,43 +294,41 @@ def test_benchmark_vertex_grid_large():
293294
# CRITICAL: Verify results are identical (treating None and nan as equivalent)
294295
# Convert both to use nan for unfound points
295296
results_old_normalized = np.array(
296-
[r if r is not None else np.nan for r in results_old],
297-
dtype=float
297+
[r if r is not None else np.nan for r in results_old], dtype=float
298298
)
299299
results_new_normalized = np.array(
300300
[
301-
r if not (isinstance(r, float) and np.isnan(r))
302-
else np.nan
301+
r if not (isinstance(r, float) and np.isnan(r)) else np.nan
303302
for r in results_new
304303
],
305-
dtype=float
304+
dtype=float,
306305
)
307306

308307
# Check matches including nan==nan comparisons
309308
both_valid = ~np.isnan(results_old_normalized) & ~np.isnan(results_new_normalized)
310309
both_invalid = np.isnan(results_old_normalized) & np.isnan(results_new_normalized)
311-
matches = (
312-
np.sum((results_old_normalized == results_new_normalized) & both_valid)
313-
+ np.sum(both_invalid)
314-
)
310+
matches = np.sum(
311+
(results_old_normalized == results_new_normalized) & both_valid
312+
) + np.sum(both_invalid)
315313
mismatches = n_test - matches
316314

317315
speedup = time_old / time_new
318-
print(f"\n{'='*60}")
316+
print(f"\n{'=' * 60}")
319317
print(f"Large VertexGrid Benchmark ({ncells} cells, {n_test} points)")
320-
print(f"{'='*60}")
318+
print(f"{'=' * 60}")
321319
print("CORRECTNESS:")
322-
print(f" Matching results: {matches}/{n_test} ({100*matches/n_test:.1f}%)")
320+
print(f" Matching results: {matches}/{n_test} ({100 * matches / n_test:.1f}%)")
323321
print(f" Mismatches: {mismatches}")
324322
print("\nPERFORMANCE:")
325-
print(f" Old method (O(n) loop): {time_old*1000:.2f} ms")
326-
print(f" New method (KD-tree + Hull): {time_new*1000:.2f} ms")
323+
print(f" Old method (O(n) loop): {time_old * 1000:.2f} ms")
324+
print(f" New method (KD-tree + Hull): {time_new * 1000:.2f} ms")
327325
print(f" Speedup: {speedup:.2f}x")
328-
print(f"{'='*60}\n")
326+
print(f"{'=' * 60}\n")
329327

330328
# MUST match exactly (treating None and nan as equivalent)
331-
assert mismatches == 0, \
329+
assert mismatches == 0, (
332330
f"Results don't match! {mismatches} mismatches out of {n_test} points"
331+
)
333332

334333

335334
def test_benchmark_structured_grid():
@@ -373,16 +372,16 @@ def test_benchmark_structured_grid():
373372
assert np.array_equal(results_new_array, results_old_array), "Results don't match!"
374373

375374
speedup = time_old / time_new
376-
print(f"\n{'='*60}")
375+
print(f"\n{'=' * 60}")
377376
print(
378-
f"StructuredGrid Benchmark ({nrow}x{ncol} = {nrow*ncol} "
377+
f"StructuredGrid Benchmark ({nrow}x{ncol} = {nrow * ncol} "
379378
f"cells, {n_test} points)"
380379
)
381-
print(f"{'='*60}")
382-
print(f"Old method (optimized): {time_old*1000:.2f} ms")
383-
print(f"New method (KD-tree + Hull): {time_new*1000:.2f} ms")
380+
print(f"{'=' * 60}")
381+
print(f"Old method (optimized): {time_old * 1000:.2f} ms")
382+
print(f"New method (KD-tree + Hull): {time_new * 1000:.2f} ms")
384383
print(f"Speedup: {speedup:.2f}x")
385-
print(f"{'='*60}\n")
384+
print(f"{'=' * 60}\n")
386385

387386
# For structured grids, should be comparable (both are fast)
388387
# We're not expecting huge speedup here since old method was already optimized
@@ -403,4 +402,4 @@ def test_benchmark_structured_grid():
403402
print("\nRunning structured grid benchmark...")
404403
test_benchmark_structured_grid()
405404

406-
print("\nAll benchmarks complete!")
405+
print("\nAll benchmarks complete!")

flopy/discretization/structuredgrid.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,7 @@ def intersect(self, x, y, z=None, local=False, forgive=False):
10301030

10311031
# Vectorized column finding using searchsorted
10321032
# For each x[i], find rightmost edge where x[i] > edge
1033-
cols_valid = np.searchsorted(xe, x, side='right') - 1
1033+
cols_valid = np.searchsorted(xe, x, side="right") - 1
10341034
# searchsorted returns index in [0, len(xe)], but valid cols are [0, ncol-1]
10351035
cols_mask = (cols_valid >= 0) & (cols_valid < self.ncol)
10361036
cols[cols_mask] = cols_valid[cols_mask]
@@ -1039,7 +1039,7 @@ def intersect(self, x, y, z=None, local=False, forgive=False):
10391039
# For each y[i], find rightmost edge where y[i] < edge
10401040
# Since ye is in descending order (top to bottom), we need to flip it
10411041
ye_flipped = ye[::-1]
1042-
rows_flipped = np.searchsorted(ye_flipped, y, side='left')
1042+
rows_flipped = np.searchsorted(ye_flipped, y, side="left")
10431043
rows_valid = len(ye) - 1 - rows_flipped
10441044
rows_mask = (rows_valid >= 0) & (rows_valid < self.nrow)
10451045
rows[rows_mask] = rows_valid[rows_mask]

flopy/discretization/unstructuredgrid.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ def intersect(self, x, y, z=None, local=False, forgive=False):
772772
x, y = super().get_coords(x, y)
773773

774774
# Build or retrieve geospatial index for fast queries
775-
if not hasattr(self, '_geospatial_index') or self._geospatial_index is None:
775+
if not hasattr(self, "_geospatial_index") or self._geospatial_index is None:
776776
self._geospatial_index = GeospatialIndex(self)
777777

778778
# Use KD-tree for fast spatial queries
@@ -820,8 +820,7 @@ def intersect(self, x, y, z=None, local=False, forgive=False):
820820
else:
821821
xi, yi = x[i], y[i]
822822
raise ValueError(
823-
f"point ({xi}, {yi}, {zi}) is outside of the "
824-
f"model area"
823+
f"point ({xi}, {yi}, {zi}) is outside of the model area"
825824
)
826825

827826
# Return scalar if input was scalar, otherwise return array

flopy/discretization/vertexgrid.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ def intersect(self, x, y, z=None, local=False, forgive=False):
402402
x, y = super().get_coords(x, y)
403403

404404
# Build or retrieve geospatial index for fast queries
405-
if not hasattr(self, '_geospatial_index') or self._geospatial_index is None:
405+
if not hasattr(self, "_geospatial_index") or self._geospatial_index is None:
406406
self._geospatial_index = GeospatialIndex(self)
407407

408408
# Use KD-tree for fast spatial queries

0 commit comments

Comments
 (0)