API reference#
earthcarekit.filter
Dataset filtering utilities.
Notes#
This module depends on other internal modules:
filter_frame
#
filter_frame(
ds: Dataset,
frame_id: str | None = None,
along_track_dim: str = ALONG_TRACK_DIM,
lat_var: str = TRACK_LAT_VAR,
add_trim_index_offset_var: bool = True,
trim_index_offset_var: str = "trim_index_offset",
) -> Dataset
Trims the dataset to the region within the latitude frame bounds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds
|
Dataset
|
Input dataset to be trimmed. |
required |
frame_id
|
str | None
|
EarthCARE frame (single character between "A" and "H"). If given, speeds up trimming. |
None
|
along_track_dim
|
str
|
Dimension along which to trim. |
ALONG_TRACK_DIM
|
lat_var
|
str
|
Name of the latitude variable. |
TRACK_LAT_VAR
|
add_trim_index_offset_var
|
bool
|
Whether the index offset between the original and trimmed dataset should be stored in the trimmed dataset (variable: "trim_index_offset"). |
True
|
trim_index_offset_var
|
str
|
Variable tracking index offsets from trimming/filtering. |
'trim_index_offset'
|
Returns:
| Type | Description |
|---|---|
Dataset
|
Filtered dataset containing only samples within the EarthCARE frame. |
Examples:
>>> import earthcarekit as eck
>>> ds = eck.ecload("CPR_FMR_2A", "09167F", download=True, trim_to_frame=False)
>>> ds_filtered = eck.filter_frame(ds)
>>> print("non-trimmed:", ds.along_track.shape)
>>> print("timmed:", ds_filtered.along_track.shape)
non-trimmed: (4992,)
timmed: (4964,)
Source code in earthcarekit/filter/_frame.py
filter_index
#
filter_index(
ds: Dataset,
index: int | slice | tuple[_Start, _Stop] | NDArray | Sequence,
along_track_dim: str = ALONG_TRACK_DIM,
trim_index_offset_var: str = "trim_index_offset",
pad_idxs: int = 0,
) -> Dataset
Filters a dataset given an along-track index number, list/array or range/slice.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds
|
Dataset
|
Input dataset with along-track dimension. |
required |
index
|
int | slice | tuple[_Start, _Stop] | NDArray | Sequence
|
Index, indices or slice to filter. |
required |
along_track_dim
|
str
|
Dimension along which to apply filtering. |
ALONG_TRACK_DIM
|
trim_index_offset_var
|
str
|
Variable tracking index offsets from trimming/filtering. |
'trim_index_offset'
|
pad_idxs
|
int
|
Number of additional samples added at both ends. |
0
|
Returns:
| Type | Description |
|---|---|
Dataset
|
Filtered dataset. |
Examples:
>>> ds = eck.ecload("CPR_FMR_2A", "09167F", download=True)
>>> ds_filtered = eck.filter_index(ds, 123)
>>> print(ds_filtered.sizes)
Frozen({'along_track': 1, 'vertical': 218})
>>> ds_filtered = eck.filter_index(ds, slice(0, 1000))
>>> print(ds_filtered.sizes)
Frozen({'along_track': 1000, 'vertical': 218})
A 2-element tuple is interpreted as (start, stop) and treated like a slice():
>>> ds_filtered = eck.filter_index(ds, (0, 1000))
>>> print(ds_filtered.sizes)
Frozen({'along_track': 1000, 'vertical': 218})
Any other n-element tuple is treated as a sequence of indices to select:
>>> ds_filtered = eck.filter_index(ds, (0, 1000, 2000))
>>> print(ds_filtered.sizes)
Frozen({'along_track': 3, 'vertical': 218})
Finally, any other sequence is treated as a sequence of indices to select:
>>> ds_filtered = eck.filter_index(ds, [0, 1000])
>>> print(ds_filtered.sizes)
Frozen({'along_track': 2, 'vertical': 218})
Source code in earthcarekit/filter/_filter_index.py
filter_latitude
#
filter_latitude(
ds: Dataset,
lat_range: NumberPairNoneLike,
start_before_pole: bool = True,
end_before_pole: bool = True,
only_center: bool = False,
lat_var: str = TRACK_LAT_VAR,
along_track_dim: str = ALONG_TRACK_DIM,
trim_index_offset_var: str = "trim_index_offset",
pad_idxs: int = 0,
shift_idxs: int = 0,
pad_time: TimedeltaLike | tuple[TimedeltaLike, TimedeltaLike] | None = None,
time_var: str = TIME_VAR,
) -> Dataset
Filters a dataset to include only points within a specified latitude range.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds
|
Dataset
|
Input dataset with geolocation data. |
required |
lat_range
|
NumberPairNoneLike
|
A pair of latitude values (min_lat, max_lat) defining the selection range. |
required |
start_before_pole
|
bool
|
If True, selection starts before the pole when the track crosses one. |
True
|
end_before_pole
|
bool
|
If True, selection ends before the pole when the track crosses one. |
True
|
only_center
|
bool
|
If True, only the sample at the center index of selection is returned. |
False
|
lat_var
|
str
|
Name of the latitude variable. |
TRACK_LAT_VAR
|
along_track_dim
|
str
|
Dimension along which to apply filtering. |
ALONG_TRACK_DIM
|
trim_index_offset_var
|
str
|
Variable tracking index offsets from trimming/filtering. |
'trim_index_offset'
|
pad_idxs
|
int
|
Number of additional samples added at both ends. |
0
|
shift_idxs
|
int
|
Offset number to shift selection of samples. |
0
|
pad_time
|
TimedeltaLike | tuple[TimedeltaLike, TimedeltaLike] | None
|
Additional time padding; applied before index-based padding ( |
None
|
time_var
|
str
|
Name of the time variable in |
TIME_VAR
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If selection is empty. |
Returns:
| Type | Description |
|---|---|
Dataset
|
Filtered dataset containing only points within the specified latitude range. |
Examples:
>>> import numpy as np
>>> import earthcarekit as eck
>>> np.set_printoptions(precision=3)
>>> ds = eck.ecload("CPR_FMR_2A", "09167F", download=True)
>>> print(ds.latitude.values)
[-22.503 -22.512 -22.521 ... -67.482 -67.491 -67.499]
>>> ds_filtered = eck.filter_latitude(ds, (-40, -30))
>>> print(ds_filtered.latitude.values)
[-30.004 -30.013 -30.021 ... -39.981 -39.99 -39.998]
Source code in earthcarekit/filter/_filter_latitude.py
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | |
filter_radius
#
filter_radius(
ds: Dataset,
radius_km: float = 100.0,
center_lat: float | None = None,
center_lon: float | None = None,
site: SiteLike | None = None,
lat_var: str = TRACK_LAT_VAR,
lon_var: str = TRACK_LON_VAR,
along_track_dim: str = ALONG_TRACK_DIM,
method: Literal["geodesic", "haversine"] = "geodesic",
closest: bool = False,
trim_index_offset_var: str = "trim_index_offset",
pad_idxs: int = 0,
shift_idxs: int = 0,
pad_time: TimedeltaLike | tuple[TimedeltaLike, TimedeltaLike] | None = None,
time_var: str = TIME_VAR,
) -> Dataset
Filters a dataset to include only points within a specified radius of a geographic location.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds
|
Dataset
|
Input dataset with geolocation data. |
required |
radius_km
|
float
|
Radius (in kilometers) around the center location. |
100.0
|
site
|
SiteLike | None
|
Site object or name; center location retrieved if provided. |
None
|
center_lat
|
float | None
|
Latitude of the center point; required if |
None
|
center_lon
|
float | None
|
Longitude of the center point; required if |
None
|
lat_var
|
str
|
Name of the latitude variable. |
TRACK_LAT_VAR
|
lon_var
|
str
|
Name of the longitude variable. |
TRACK_LON_VAR
|
along_track_dim
|
str
|
Dimension along which to apply filtering. |
ALONG_TRACK_DIM
|
method
|
Literal['geodesic', 'haversine']
|
Distance calculation method. |
'geodesic'
|
closest
|
bool
|
If True, returns only the single closest sample; otherwise returns all within radius. |
False
|
trim_index_offset_var
|
str
|
Variable tracking index offsets from trimming/filtering. |
'trim_index_offset'
|
pad_idxs
|
int
|
Number of additional samples added at both ends. |
0
|
shift_idxs
|
int
|
Offset to shift the selected sample indices. |
0
|
pad_time
|
TimedeltaLike | tuple[TimedeltaLike, TimedeltaLike] | None
|
Additional time padding applied before index-based padding; applied first. |
None
|
time_var
|
str
|
Name of the time variable in |
TIME_VAR
|
Returns:
| Type | Description |
|---|---|
Dataset
|
Filtered dataset containing only points within the specified radius. |
Raises:
| Type | Description |
|---|---|
EmptyFilterResultError
|
If no data points are found within the radius. |
ValueError
|
If the |
Examples:
>>> import earthcarekit as eck
>>> ds = eck.ecload("ATL_EBD_2A", "01508B", download=True)
>>> print(ds.sizes)
Frozen({'along_track': 5143, 'vertical': 242, 'layer': 25, 'n_state': 351})
>>> ds_filtered = eck.filter_radius(ds, site="dushanbe")
>>> print(ds_filtered.sizes)
Frozen({'along_track': 197, 'vertical': 242, 'layer': 25, 'n_state': 351})
>>> ds_filtered = eck.filter_radius(ds, site="dushanbe", radius_km=200)
>>> print(ds_filtered.sizes)
Frozen({'along_track': 399, 'vertical': 242, 'layer': 25, 'n_state': 351})
Source code in earthcarekit/filter/_filter_radius.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | |
filter_time
#
filter_time(
ds: Dataset,
time_range: TimeRangeLike | Iterable | None = None,
timestamp: TimestampLike | None = None,
only_center: bool = False,
time_var: str = TIME_VAR,
along_track_dim: str = ALONG_TRACK_DIM,
trim_index_offset_var: str = "trim_index_offset",
pad_idxs: int = 0,
shift_idxs: int = 0,
pad_time: TimedeltaLike | tuple[TimedeltaLike, TimedeltaLike] | None = None,
) -> Dataset
Filters an xarray Dataset to include only samples within a given time range.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds
|
Dataset
|
Input dataset containing a time coordinate. |
required |
time_range
|
TimeRangeLike | Iterable | None
|
Start and end time of the range to filter. |
None
|
timestamp
|
TimestampLike | None
|
Single timestamp; returns closest sample if provided. |
None
|
only_center
|
bool
|
If True, returns only the center sample of the selection. |
False
|
time_var
|
str
|
Name of the time variable in |
TIME_VAR
|
along_track_dim
|
str
|
Dimension name along which time is defined. |
ALONG_TRACK_DIM
|
trim_index_offset_var
|
str
|
Variable tracking index offsets from trimming/filtering. |
'trim_index_offset'
|
pad_idxs
|
int
|
Number of additional samples added at both ends. |
0
|
shift_idxs
|
int
|
Offset to shift selected sample indices. |
0
|
pad_time
|
TimedeltaLike | tuple[TimedeltaLike, TimedeltaLike] | None
|
Additional time padding applied before index-based padding. |
None
|
Returns:
| Type | Description |
|---|---|
Dataset
|
Filtered dataset containing only samples within the specified time range. |
Examples:
>>> import earthcarekit as eck
>>> ds = eck.ecload("CPR_FMR_2A", "09167F", download=True)
>>> print(ds.time.values[[0, -1]])
['2026-01-08T03:04:08.393852234' '2026-01-08T03:15:57.401298285']
>>> ds_filtered = eck.filter_time(ds, time_range=("2026-01-08 03:10", "2026-01-08 03:12"))
>>> print(ds_filtered.time.values[[0, -1]])
['2026-01-08T03:10:00.115605354' '2026-01-08T03:11:59.985651731']
Source code in earthcarekit/filter/_filter_time.py
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | |
get_frame_index_range
#
get_frame_index_range(
latitude: ArrayLike | None = None,
frame_id: str | None = None,
ds: Dataset | None = None,
lat_var: str = TRACK_LAT_VAR,
) -> tuple[int, int]
Generate an index range for trimming arrays or datasets to EarthCARE latitude frame bounds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
latitude
|
ArrayLike | None
|
Sequence of along-track latitude values. |
None
|
frame_id
|
str | None
|
EarthCARE frame ID (letter between "A" and "H"). |
None
|
ds
|
Dataset | None
|
EarthCARE dataset containing along-track latitude values. |
None
|
lat_var
|
str
|
Name of the latitude dataset variable. |
TRACK_LAT_VAR
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If inputs are missing (requires |
Returns:
| Type | Description |
|---|---|
tuple[int, int]
|
Index range of the EarthCARE frame (i.e., slice tuple). |
Examples:
>>> import earthcarekit as eck
>>> ds = eck.ecload("CPR_FMR_2A", "09167F", download=True, trim_to_frame=False)
>>> slice_tuple = eck.filter.get_frame_index_range(ds=ds, frame_id="F")
>>> # Or: eck.filter.get_frame_index_range(latitude=ds.latitude.values, frame_id="F")
>>> ds_sliced = ds.isel({"along_track": slice(*slice_tuple)})
>>> print("non-trimmed:", ds.along_track.shape)
>>> print("timming slice:", slice_tuple)
>>> print("timmed:", ds_sliced.along_track.shape)
non-trimmed: (4992,)
timming slice: (14, 4978)
timmed: (4964,)
Source code in earthcarekit/filter/_frame.py
get_frame_slice_tuple
#
Return start and end index of an EarthCARE frame for a along-track latitude sequence.
This method assumes input latitudes from a continous sequence of satellite track coordinates spanning at most a single EarthCARE frame. The coordinates may extend slightly beyond the frame's limits (e.g., due to margins), but they must not span multiple frames or full orbits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
latitude
|
ArrayLike
|
EarthCARE dataset. |
required |
frame_id
|
str
|
EarthCARE frame ID letter (A-H). |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
When not able to retrieve frame ID from either the dataset encoding (i.e., |
Returns:
| Type | Description |
|---|---|
tuple[int, int]
|
Slice tuple matching the data within the EarthCARE frame. |