Skip to content

Commit 2933673

Browse files
committed
Replace Cube.subset by fast custom slicer
1 parent b7e1a2b commit 2933673

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

esmvalcore/preprocessor/_time.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,22 @@ def _duration_to_date(duration, reference, sign):
135135
return date
136136

137137

138+
def _select_timeslice(
139+
cube: iris.cube.Cube,
140+
select: np.ndarray,
141+
) -> iris.cube.Cube | None:
142+
"""Slice a cube along its time axis."""
143+
if select.any():
144+
coord = cube.coord('time')
145+
time_dim = cube.coord_dims(coord)[0]
146+
slices = tuple(select if i == time_dim else slice(None)
147+
for i in range(cube.ndim))
148+
cube_slice = cube[slices]
149+
else:
150+
cube_slice = None
151+
return cube_slice
152+
153+
138154
def _extract_datetime(
139155
cube: iris.cube.Cube,
140156
start_datetime: PartialDateTime,
@@ -182,12 +198,10 @@ def _extract_datetime(
182198
# than using a constraint.
183199
dates = time_coord.units.num2date(time_coord.points)
184200
select = (dates >= start_datetime) & (dates < end_datetime)
185-
if select.any():
186-
cube_slice = cube.subset(time_coord[select])
187-
else:
188-
cube_slice = None
201+
cube_slice = _select_timeslice(cube, select)
189202

190203
if cube_slice is None:
204+
191205
def dt2str(time: PartialDateTime) -> str:
192206
txt = f"{time.year}-{time.month:02d}-{time.day:02d}"
193207
if any([time.hour, time.minute, time.second]):
@@ -1103,11 +1117,12 @@ def resample_hours(cube, interval, offset=0):
11031117
select = np.zeros(len(dates), dtype=bool)
11041118
for hour in hours:
11051119
select |= dates == hour
1106-
if not select.any():
1120+
cube = _select_timeslice(cube, select)
1121+
if cube is None:
11071122
raise ValueError(
11081123
f"Time coordinate {dates} does not contain {hours} for {cube}")
11091124

1110-
return cube.subset(time[select])
1125+
return cube
11111126

11121127

11131128
def resample_time(cube, month=None, day=None, hour=None):
@@ -1152,7 +1167,8 @@ def resample_time(cube, month=None, day=None, hour=None):
11521167
dates = time.units.num2date(time.points)
11531168
requested = PartialDateTime(month=month, day=day, hour=hour)
11541169
select = dates == requested
1155-
if not select.any():
1170+
cube = _select_timeslice(cube, select)
1171+
if cube is None:
11561172
raise ValueError(
11571173
f"Time coordinate {dates} does not contain {requested} for {cube}")
1158-
return cube.subset(time[select])
1174+
return cube

0 commit comments

Comments
 (0)