Skip to content

Commit 445eb74

Browse files
committed
dev
1 parent c181de2 commit 445eb74

File tree

10 files changed

+77
-58
lines changed

10 files changed

+77
-58
lines changed

cf/cfdatetime.py

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import datetime
22
from functools import partial
33

4-
import cftime
54
import numpy as np
65

76
from .functions import _DEPRECATION_ERROR_CLASS
@@ -10,17 +9,10 @@
109
default_calendar = "gregorian"
1110

1211
# --------------------------------------------------------------------
13-
# Mapping of CF calendars to cftime date-time objects
12+
# Mapping of CF calendars to cftime date-time objects (that gets
13+
# populated in the `dt` function).
1414
# --------------------------------------------------------------------
15-
_datetime_object = {
16-
("",): partial(cftime.datetime, calendar=""),
17-
(None, "gregorian", "standard", "none"): cftime.DatetimeGregorian,
18-
("proleptic_gregorian",): cftime.DatetimeProlepticGregorian,
19-
("360_day",): cftime.Datetime360Day,
20-
("noleap", "365_day"): cftime.DatetimeNoLeap,
21-
("all_leap", "366_day"): cftime.DatetimeAllLeap,
22-
("julian",): cftime.DatetimeJulian,
23-
}
15+
_datetime_object = {}
2416

2517
canonical_calendar = {
2618
None: "standard",
@@ -40,7 +32,7 @@
4032
_calendar_map = {None: "gregorian"}
4133

4234

43-
class Datetime(cftime.datetime):
35+
class Datetime:
4436
"""A date-time object which supports CF calendars.
4537
4638
Deprecated at version 3.0.0. Use function 'cf.dt' to create date-
@@ -134,6 +126,26 @@ def dt(
134126
(2003, 4, 5, 12, 30, 15)
135127
136128
"""
129+
import cftime
130+
131+
if not _datetime_object:
132+
_datetime_object.update(
133+
{
134+
("",): partial(cftime.datetime, calendar=""),
135+
(
136+
None,
137+
"gregorian",
138+
"standard",
139+
"none",
140+
): cftime.DatetimeGregorian,
141+
("proleptic_gregorian",): cftime.DatetimeProlepticGregorian,
142+
("360_day",): cftime.Datetime360Day,
143+
("noleap", "365_day"): cftime.DatetimeNoLeap,
144+
("all_leap", "366_day"): cftime.DatetimeAllLeap,
145+
("julian",): cftime.DatetimeJulian,
146+
}
147+
)
148+
137149
if isinstance(arg, str):
138150
(year, month, day, hour, minute, second, microsecond) = st2elements(
139151
arg
@@ -161,11 +173,6 @@ def dt(
161173
else:
162174
year = arg
163175

164-
# calendar=_calendar_map.get(calendar, calendar)
165-
#
166-
# return cftime.datetime(year, month, day, hour, minute, second,
167-
# microsecond, calendar=calendar)
168-
169176
for calendars, datetime_cls in _datetime_object.items():
170177
if calendar in calendars:
171178
return datetime_cls(
@@ -354,6 +361,8 @@ def st2datetime(date_string, calendar=None):
354361
`cftime.datetime`
355362
356363
"""
364+
import cftime
365+
357366
if date_string.count("-") != 2:
358367
raise ValueError(
359368
"Input date-time string must contain at least a year, a month "
@@ -388,6 +397,8 @@ def st2elements(date_string):
388397
`tuple`
389398
390399
"""
400+
import cftime
401+
391402
if date_string.count("-") != 2:
392403
raise ValueError(
393404
"Input date-time string must contain at least a year, a month "
@@ -450,6 +461,8 @@ def rt2dt(array, units_in, units_out=None, dummy1=None):
450461
# mask
451462
return np.ma.masked_all((), dtype=object)
452463

464+
import cftime
465+
453466
units = units_in.units
454467
calendar = getattr(units_in, "calendar", "standard")
455468

@@ -510,6 +523,8 @@ def dt2rt(array, units_in, units_out, dummy1=None):
510523
[-- 685.5]
511524
512525
"""
526+
import cftime
527+
513528
isscalar = not np.ndim(array)
514529

515530
array = cftime.date2num(
@@ -545,8 +560,9 @@ def st2rt(array, units_in, units_out, dummy1=None):
545560
An array of floats with the same shape as *array*.
546561
547562
"""
563+
import cftime
564+
548565
array = st2dt(array, units_in)
549-
# array = units_out._utime.date2num(array)
550566
array = cftime.date2num(
551567
array, units=units_out.units, calendar=units_out._utime.calendar
552568
)

cf/data/collapse/collapse_active.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,14 @@
1-
import datetime
21
import logging
3-
import time
42
from functools import wraps
53
from numbers import Integral
64

7-
from ...functions import (
5+
from cf.functions import (
86
active_storage,
97
active_storage_max_requests,
108
active_storage_url,
119
is_log_level_info,
1210
)
1311

14-
# try:
15-
# from activestorage import Active
16-
# except ModuleNotFoundError:
17-
# pass
18-
19-
2012
logger = logging.getLogger(__name__)
2113

2214
# --------------------------------------------------------------------
@@ -185,6 +177,12 @@ def active_chunk_function(method, *args, **kwargs):
185177
# reason, then this will trigger (inside `actify`) a local
186178
# reduction being carried out instead.
187179
# ----------------------------------------------------------------
180+
import datetime
181+
import time
182+
183+
# Note: We know that the optional `activestorage` pacakge exists
184+
# because this was checked when active storage was enabled
185+
# with `cf.active_storage(True)`
188186
from activestorage import Active
189187

190188
filename = x.get_filename()

cf/data/dask_utils.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
from ..cfdatetime import dt, dt2rt, rt2dt
1414
from ..units import Units
1515

16-
# from scipy.ndimage import convolve1d
17-
1816

1917
def cf_contains(a, value):
2018
"""Whether or not an array contains a value.

cf/data/data.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from operator import mul
66

77
import cfdm
8-
import cftime
98
import numpy as np
109
from cfdm.data.dask_utils import cfdm_where
1110
from cfdm.data.utils import new_axis_identifier
@@ -2198,6 +2197,8 @@ def _binary_operation(cls, data, other, method):
21982197
# so that combination with cf.Query objects works.
21992198
# ------------------------------------------------------------
22002199
if not isinstance(other, cls):
2200+
import cftime
2201+
22012202
if (
22022203
isinstance(other, cftime.datetime)
22032204
and other.calendar == ""

cf/field.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9949,12 +9949,12 @@ def convolution_filter(
99499949
An unweighted 5-point moving average can be computed
99509950
with ``window=[0.2, 0.2, 0.2, 0.2, 0.2]``
99519951

9952-
Note that the `scipy.signal.windows` package has suite
9953-
of window functions for creating window weights for
9954-
filtering (see the examples for details).
9952+
.. note:: The `scipy.signal.windows` package has a
9953+
suite of window functions for creating
9954+
window weights for filtering (see the
9955+
examples for details).
99559956

9956-
.. versionadded:: 3.3.0 (replaces the old weights
9957-
parameter)
9957+
.. versionadded:: 3.3.0
99589958

99599959
axis:
99609960
Select the domain axis over which the filter is to be

cf/functions.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import warnings
88
from collections.abc import Iterable
99
from functools import partial
10+
from importlib.util import find_spec
1011
from itertools import product
1112
from math import isnan
1213
from os import mkdir
@@ -19,9 +20,7 @@
1920
from urllib.parse import urljoin, urlparse
2021

2122
import cfdm
22-
import netCDF4
2323
import numpy as np
24-
from psutil import virtual_memory
2524

2625
from . import __file__, __version__
2726
from .constants import OperandBoundsCombination, _stash2standard_name
@@ -150,6 +149,8 @@ def _free_memory():
150149
96496240.0
151150
152151
"""
152+
from psutil import virtual_memory
153+
153154
return float(virtual_memory().available)
154155

155156

@@ -1189,18 +1190,15 @@ def _parse(cls, arg):
11891190
insertion into the `_constants` dictionary.
11901191
11911192
"""
1192-
try:
1193-
import activestorage # noqa: F401
1194-
except ModuleNotFoundError as error:
1195-
if arg:
1196-
error.msg += (
1197-
". Install the 'activestorage' package "
1198-
"(https://pypi.org/project/PyActiveStorage) to enable "
1199-
"active storage reductions"
1200-
)
1201-
raise
1193+
arg = bool(arg)
1194+
if arg and not find_spec("activestorage"):
1195+
raise ModuleNotFoundError(
1196+
"Must install the 'activestorage' package "
1197+
"(https://pypi.org/project/PyActiveStorage) to enable "
1198+
"active storage reductions"
1199+
)
12021200

1203-
return bool(arg)
1201+
return arg
12041202

12051203

12061204
class active_storage_url(ConstantAccess):
@@ -1488,6 +1486,8 @@ def min_total_memory():
14881486

14891487
def total_memory():
14901488
"""The total amount of physical memory (in bytes)."""
1489+
from psutil import virtual_memory
1490+
14911491
return float(virtual_memory().total)
14921492

14931493

@@ -3275,6 +3275,8 @@ def default_netCDF_fillvals():
32753275
'f8': 9.969209968386869e+36}
32763276
32773277
"""
3278+
import netCDF4
3279+
32783280
return netCDF4.default_fillvals
32793281

32803282

cf/mixin/coordinate.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# from itertools import chain
2-
31
from ..data.data import Data
42
from ..decorators import (
53
_deprecated_kwarg_check,

cf/mixin/fielddomain.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -726,9 +726,9 @@ def _indices(self, config, data_axes, ancillary_mask, kwargs):
726726
for i, p in zip(identities, points)
727727
]
728728
)
729-
raise ImportError(
730-
"Must install matplotlib to create indices "
731-
f"for {self!r} from: {x}"
729+
raise ModuleNotFoundError(
730+
"Must install the 'matplotlib' package to "
731+
f"create indices for {self!r} from: {x}"
732732
)
733733

734734
def _point_not_in_cell(nodes_x, nodes_y, point):

cf/read_write/um/umread.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@
55
from uuid import uuid4
66

77
import cfdm
8-
import cftime
98
import numpy as np
109
from cfdm import Constructs, is_log_level_info
1110
from cfdm.read_write.exceptions import DatasetTypeError
12-
from netCDF4 import date2num as netCDF4_date2num
1311

1412
from cf import __Conventions__, __version__
1513
from cf.constants import _stash2standard_name
@@ -1866,6 +1864,8 @@ def coord_positive(self, c, axiscode, domain_axis_key):
18661864
def ctime(self, rec):
18671865
"""Return elapsed time since the clock time of the given
18681866
record."""
1867+
import cftime
1868+
18691869
reftime = self.refUnits
18701870
LBVTIME = tuple(self.header_vtime(rec))
18711871
LBDTIME = tuple(self.header_dtime(rec))
@@ -2287,13 +2287,17 @@ def dtime(self, rec):
22872287
key = (LBDTIME, units, calendar)
22882288
time = _cached_date2num.get(key, None)
22892289
if time is None:
2290+
from netCDF4 import date2num as netCDF4_date2num
2291+
22902292
# It is important to use the same time_units as vtime
22912293
try:
22922294
if self.calendar == "gregorian":
22932295
time = netCDF4_date2num(
22942296
datetime(*LBDTIME), units, calendar
22952297
)
22962298
else:
2299+
import cftime
2300+
22972301
time = netCDF4_date2num(
22982302
cftime.datetime(*LBDTIME, calendar=self.calendar),
22992303
units,
@@ -2949,6 +2953,8 @@ def vtime(self, rec):
29492953

29502954
time = _cached_date2num.get(key, None)
29512955
if time is None:
2956+
import cftime
2957+
29522958
# It is important to use the same time_units as dtime
29532959
try:
29542960
time = cftime.date2num(

cf/regrid/regrid.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,9 +1904,9 @@ def esmpy_initialise():
19041904
"""
19051905
try:
19061906
import esmpy
1907-
except ImportError:
1908-
raise RuntimeError(
1909-
"Regridding will not work unless the esmpy library is installed"
1907+
except ModuleNotFoundError:
1908+
raise ModuleNotFoundError(
1909+
"Must install the 'esmpy' package to enable regridding"
19101910
)
19111911

19121912
# Update the global 'esmpy_methods' dictionary

0 commit comments

Comments
 (0)