Skip to content

Commit 76abe1c

Browse files
committed
Add missing docs
1 parent 7bce961 commit 76abe1c

5 files changed

Lines changed: 367 additions & 65 deletions

File tree

src/implicit_filter/latlon_filter.py

Lines changed: 158 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -17,33 +17,38 @@
1717

1818
class LatLonFilter(Filter):
1919
"""
20-
A filter class for data based on regular latitude and longitude grids using NumPy arrays.
21-
22-
Methods
23-
-------
24-
many_compute(n: int, k: float, data: Union[np.ndarray, List[np.ndarray]]) -> List[np.ndarray]:
25-
Placeholder method to compute filtering on multiple datasets. Not implemented yet.
26-
27-
compute_velocity(n: int, k: float, ux: np.ndarray, vy: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
28-
Computes the filtered velocity fields.
29-
30-
compute(n: int, k: float, data: np.ndarray) → np.ndarray:
31-
Computes the filtered data.
32-
20+
Filter implementation for regular latitude-longitude grids.
21+
22+
This class provides implicit filtering capabilities for data on structured
23+
lat-lon grids. It supports both Cartesian and spherical coordinate systems
24+
with configurable boundary conditions and land-sea masks.
25+
26+
Parameters
27+
----------
28+
See Filter class for inherited parameters.
29+
30+
Attributes
31+
----------
32+
_e2d : int
33+
Total number of grid points (nx * ny)
34+
_nx : int
35+
Number of longitude points
36+
_ny : int
37+
Number of latitude points
38+
_ss : np.ndarray
39+
Non-zero values of sparse filter matrix
40+
_ii : np.ndarray
41+
Row indices for sparse matrix entries
42+
_jj : np.ndarray
43+
Column indices for sparse matrix entries
44+
_area : np.ndarray
45+
Area associated with each grid cell
46+
_backend : str
47+
Computational backend ('cpu' or 'gpu')
48+
_mask_n : np.ndarray
49+
Boolean mask for valid grid points (False indicates land)
3350
"""
34-
3551
def __init__(self, *initial_data, **kwargs):
36-
"""
37-
Initializes the LatLonNumpyFilter with the given data and keyword arguments.
38-
39-
Parameters
40-
----------
41-
initial_data : tuple
42-
Initial data to be passed to the parent class.
43-
kwargs : dict
44-
Additional keyword arguments.
45-
46-
"""
4752
super().__init__(initial_data, **kwargs)
4853
it = lambda ar: int(ar)
4954
ar = lambda ar: np.array(ar)
@@ -67,24 +72,37 @@ def prepare(
6772
longitude: np.ndarray,
6873
cartesian: bool = False,
6974
local: bool = True,
75+
cyclic_length: float = 2 * math.pi,
7076
mask: np.ndarray | None = None,
7177
gpu: bool = False,
7278
):
7379
"""
74-
Prepares the filter for latitude and longitude grids regular grids
80+
Configure filter for a latitude-longitude grid.
81+
82+
Computes grid topology, geometric properties, and assembles the filter
83+
operator matrix. Must be called before any filtering operations.
7584
7685
Parameters
7786
----------
78-
latitude: np.ndarray
79-
1D np.ndarray of floats with latitude values
80-
longitude: np.ndarray
81-
1D np.ndarray of floats with longitude values
82-
cartesian: bool
83-
If true, the conversion from degrees to km should assume that mesh is cartesian.
84-
local: bool
85-
If true, neighborhood calculation doesn't wrap around an East/West direction
87+
latitude : np.ndarray
88+
Latitude values in degrees (1D array)
89+
longitude : np.ndarray
90+
Longitude values in degrees (1D array)
91+
cartesian : bool, optional
92+
True for Cartesian coordinates, False for spherical (default)
93+
local : bool, optional
94+
True for 4-point local neighborhood, False for 8-point global (default: True)
95+
cyclic_length : float, optional
96+
Cyclic domain length in radians (default: 2π).
97+
mask : np.ndarray, optional
98+
Land-sea mask where True indicates land (default: all ocean)
99+
gpu : bool, optional
100+
True to enable GPU acceleration (default: False)
101+
102+
Notes
103+
-----
104+
- Land points are masked using Neumann boundary conditions
86105
"""
87-
88106
nx = len(longitude)
89107
ny = len(latitude)
90108
e2d = nx * ny
@@ -123,10 +141,7 @@ def prepare(
123141
hh = np.ones((4, e2d)) # Edge lengths
124142
hc = np.ones((4, e2d)) # Distance to next cell centers
125143
r_earth = 6400.0
126-
cyclic_length = (
127-
360 # in degrees; if not cyclic, take it larger than zonal size
128-
)
129-
cyclic_length = cyclic_length * math.pi / 180
144+
130145
# Fill ee_pos, arrangement is W;N;E;S
131146
for i in range(e2d):
132147
if ee_pos[1, i] == i:
@@ -204,9 +219,29 @@ def prepare(
204219
self.set_backend("gpu" if gpu else "cpu")
205220

206221
def get_backend(self) -> str:
222+
"""
223+
Get current computational backend.
224+
225+
Returns
226+
-------
227+
str
228+
Current backend ('cpu' or 'gpu').
229+
"""
207230
return self._backend
208231

209232
def set_backend(self, backend: str):
233+
"""
234+
Set computational backend for filtering operations.
235+
236+
Parameters
237+
----------
238+
backend : str
239+
Desired backend ('cpu' or 'gpu').
240+
241+
Notes
242+
-----
243+
Configures appropriate sparse linear algebra functions for the backend.
244+
"""
210245
self.csc_matrix, self.identity, self.cg, self.convers, self.tonumpy = (
211246
get_backend(backend)
212247
)
@@ -247,6 +282,28 @@ def _compute(
247282
return self.tonumpy(tts)
248283

249284
def compute(self, n: int, k: float, data: np.ndarray) -> np.ndarray:
285+
"""
286+
Apply filter to scalar field on lat-lon grid.
287+
288+
Parameters
289+
----------
290+
n : int
291+
Filter order (must be positive).
292+
k : float
293+
Filter wavelength in spatial units.
294+
data : np.ndarray
295+
Scalar field values on grid (shape: (nx, ny)).
296+
297+
Returns
298+
-------
299+
np.ndarray
300+
Filtered scalar field (shape: (nx, ny)).
301+
302+
Raises
303+
------
304+
ValueError
305+
If filter order n < 1.
306+
"""
250307
if n < 1:
251308
raise ValueError("Filter order must be positive")
252309

@@ -257,6 +314,30 @@ def compute(self, n: int, k: float, data: np.ndarray) -> np.ndarray:
257314
def compute_velocity(
258315
self, n: int, k: float, ux: np.ndarray, vy: np.ndarray
259316
) -> Tuple[np.ndarray, np.ndarray]:
317+
"""
318+
Apply filter to velocity components on lat-lon grid.
319+
320+
Parameters
321+
----------
322+
n : int
323+
Filter order (must be positive).
324+
k : float
325+
Filter wavelength in spatial units.
326+
ux : np.ndarray
327+
Eastward velocity component (shape: (nx, ny)).
328+
vy : np.ndarray
329+
Northward velocity component (shape: (nx, ny)).
330+
331+
Returns
332+
-------
333+
Tuple[np.ndarray, np.ndarray]
334+
Filtered velocity components (ux_filt, vy_filt) each with shape (nx, ny).
335+
336+
Raises
337+
------
338+
ValueError
339+
If filter order n < 1.
340+
"""
260341
if n < 1:
261342
raise ValueError("Filter order must be positive")
262343

@@ -276,6 +357,27 @@ def compute_spectra_scalar(
276357
data: np.ndarray,
277358
mask: np.ndarray | None = None,
278359
) -> np.ndarray:
360+
"""
361+
Compute power spectra for scalar field at specified wavelengths.
362+
363+
Parameters
364+
----------
365+
n : int
366+
Filter order (must be positive).
367+
k : Iterable | np.ndarray
368+
Target wavelengths for spectral analysis.
369+
data : np.ndarray
370+
Scalar field values on grid (shape: (nx, ny)).
371+
mask : np.ndarray, optional
372+
Boolean mask where True excludes points from spectra computation.
373+
374+
Returns
375+
-------
376+
np.ndarray
377+
Power spectral density at wavelengths [0, k0, k1, ...]:
378+
[0] : Total variance
379+
[1:] : Variance at each wavelength k
380+
"""
279381
nr = len(k)
280382
tt = np.reshape(data, self._e2d)
281383
spectra = np.zeros(nr + 1)
@@ -309,34 +411,29 @@ def compute_spectra_velocity(
309411
mask: np.ndarray | None = None,
310412
) -> np.ndarray:
311413
"""
312-
Computes power spectra for given wavelengths.
313-
Data must be placed on mesh nodes
414+
Compute power spectra for velocity field at specified wavelengths.
314415
315-
For details refer to https://arxiv.org/abs/2404.07398
316-
Parameters:
317-
-----------
416+
Parameters
417+
----------
318418
n : int
319-
Order of filter, one is recommended
320-
419+
Filter order (must be positive).
321420
k : Iterable | np.ndarray
322-
List of wavelengths to be filtered.
323-
421+
Target wavelengths for spectral analysis.
324422
ux : np.ndarray
325-
NumPy array containing an eastward velocity component to be filtered.
326-
423+
Eastward velocity component (shape: (nx, ny)).
327424
vy : np.ndarray
328-
NumPy array containing a northwards velocity component to be filtered.
329-
330-
mask : np.ndarray | None
331-
Mask applied to data while computing spectra.
332-
True means selected data won't be used for computing spectra.
333-
This mask won't be used during filtering.
334-
335-
Returns:
336-
--------
337-
np.ndarray:
338-
Array containing power spectra for given wavelengths.
425+
Northward velocity component (shape: (nx, ny)).
426+
mask : np.ndarray, optional
427+
Boolean mask where True excludes points from spectra computation.
428+
429+
Returns
430+
-------
431+
np.ndarray
432+
Kinetic energy spectral density at wavelengths [0, k0, k1, ...]:
433+
[0] : Total kinetic energy
434+
[1:] : Kinetic energy at each wavelength k
339435
"""
436+
340437
nr = len(k)
341438
unod = np.reshape(ux, self._e2d)
342439
vnod = np.reshape(vy, self._e2d)

0 commit comments

Comments
 (0)