-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add a GRIB backend via ECMWF cfgrib / ecCodes #2476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
72606f7
71fcbe7
6faa7b9
1469a0e
12811e8
a4409b6
80b8788
9dfd660
edc4e85
9b5335a
186a504
485a409
81f18c2
5dedb3f
831ae4f
6372e6e
8e9b2e3
07b9469
340720a
4d84f70
0b027db
a4ead54
ec80d86
f30b7d0
223d25c
2ef993f
bbf01e3
da2b9dd
eda96a4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,12 @@ | |
from ..core import indexing | ||
from ..core.utils import Frozen, FrozenOrderedDict | ||
from .common import AbstractDataStore, BackendArray | ||
from .file_manager import CachingFileManager | ||
from .locks import ensure_lock, SerializableLock | ||
|
||
# FIXME: Add a dedicated lock just in case, even if ecCodes is supposed to be thread-safe in most | ||
# circumstances. See: https://confluence.ecmwf.int/display/ECC/Frequently+Asked+Questions | ||
ECCODES_LOCK = SerializableLock() | ||
|
||
|
||
class CfGribArrayWrapper(BackendArray): | ||
|
@@ -50,28 +56,29 @@ class CfGribDataStore(AbstractDataStore): | |
""" | ||
Implements the ``xr.AbstractDataStore`` read-only API for a GRIB file. | ||
""" | ||
def __init__(self, ds, lock=False): | ||
self.ds = ds | ||
self.lock = lock | ||
|
||
@classmethod | ||
def from_path(cls, path, lock=False, **backend_kwargs): | ||
def __init__(self, filename, lock=None, **backend_kwargs): | ||
import cfgrib | ||
return cls(ds=cfgrib.open_file(path, **backend_kwargs), lock=lock) | ||
if lock is None: | ||
lock = ECCODES_LOCK | ||
self.lock = ensure_lock(lock) | ||
backend_kwargs['filter_by_keys'] = tuple(backend_kwargs.get('filter_by_keys', {}).items()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks a little surprising to me -- can we simply pass on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a ugly hack around the fact that
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, that makes please. I think the need to hash arguments used to open files with CachingFileManager is unavoidable, so this is a reasonable workaround. But please add a comment explaining this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I added a comment and made the code more explicit. |
||
self._manager = CachingFileManager( | ||
cfgrib.open_file, filename, lock=lock, mode='r', kwargs=backend_kwargs) | ||
|
||
@property | ||
def ds(self): | ||
return self._manager.acquire() | ||
|
||
def open_store_variable(self, name, var): | ||
if isinstance(var.data, np.ndarray): | ||
data = var.data | ||
else: | ||
data = indexing.LazilyOuterIndexedArray(CfGribArrayWrapper(var.data)) | ||
|
||
dimensions = var.dimensions | ||
attrs = var.attributes | ||
|
||
encoding = self.ds.encoding.copy() | ||
encoding['original_shape'] = var.data.shape | ||
|
||
return Variable(dimensions, data, attrs, encoding) | ||
return Variable(var.dimensions, data, var.attributes, encoding) | ||
|
||
def get_variables(self): | ||
return FrozenOrderedDict((k, self.open_store_variable(k, v)) | ||
|
@@ -87,3 +94,6 @@ def get_encoding(self): | |
encoding = {} | ||
encoding['unlimited_dims'] = {k for k, v in self.ds.dimensions.items() if v is None} | ||
return encoding | ||
|
||
def close(self): | ||
self._manager.close() |
Uh oh!
There was an error while loading. Please reload this page.