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
Add support for s3 buckets in OLCI and ABI l1 readers #1439
Changes from 20 commits
0ef06c0
36ff447
47a4dcf
973ca18
f04c137
dedeaea
8afdb38
445fe1b
02ff1f8
407fa63
719386f
9c5b55f
034b521
b2956f2
2b3f026
4bffac3
eb7b9c2
4dd8b20
ecdcbce
be6c757
4e3b7b5
81505c6
d7d227b
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 |
---|---|---|
|
@@ -20,9 +20,8 @@ | |
from abc import ABCMeta | ||
|
||
import numpy as np | ||
from pathlib import PurePath | ||
|
||
from pyresample.geometry import SwathDefinition | ||
|
||
from satpy.dataset import combine_metadata | ||
|
||
|
||
|
@@ -31,10 +30,7 @@ class BaseFileHandler(metaclass=ABCMeta): | |
|
||
def __init__(self, filename, filename_info, filetype_info): | ||
"""Initialize file handler.""" | ||
if isinstance(filename, PurePath): | ||
self.filename = str(filename) | ||
else: | ||
self.filename = filename | ||
self.filename = filename | ||
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 change will break pathlib objects for all other readers right? (assuming the low-level I/O library doesn't support them) 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. That said, I'm ok with 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. probably yes... Is this bad? 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. I think @gerritholl was the first user to point out that Satpy didn't work with pathlib objects so he should maybe make the final decision. It probably isn't great that this breaks it for all other readers, but I'm not sure how many readers need strings for their lower-level I/O libraries either. |
||
self.navigation_reader = None | ||
self.filename_info = filename_info | ||
self.filetype_info = filetype_info | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,16 +40,17 @@ | |
|
||
|
||
import logging | ||
from datetime import datetime | ||
from contextlib import suppress | ||
from functools import lru_cache | ||
from functools import reduce | ||
|
||
import dask.array as da | ||
import numpy as np | ||
import xarray as xr | ||
|
||
from satpy import CHUNK_SIZE | ||
from satpy.readers import open_file_or_filename | ||
from satpy.readers.file_handlers import BaseFileHandler | ||
from satpy.utils import angle2xyz, xyz2angle | ||
from satpy import CHUNK_SIZE | ||
from functools import reduce | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
@@ -100,30 +101,36 @@ def __init__(self, filename, filename_info, filetype_info, | |
"""Init the olci reader base.""" | ||
super(NCOLCIBase, self).__init__(filename, filename_info, | ||
filetype_info) | ||
self.nc = xr.open_dataset(self.filename, | ||
self._engine = engine | ||
self._start_time = filename_info['start_time'] | ||
self._end_time = filename_info['end_time'] | ||
# TODO: get metadata from the manifest file (xfdumanifest.xml) | ||
self.platform_name = PLATFORM_NAMES[filename_info['mission_id']] | ||
self.sensor = 'olci' | ||
self.open_file = None | ||
|
||
@property | ||
@lru_cache(maxsize=2) | ||
def nc(self): | ||
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. Mostly for my curiosity: I've never seen 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. I put size 2 for safety, but in principle only 1 is needed, as this is a property on the instance. So each instance of the file handler will have a different cache for this accessor, and allows repeated calls to the property not to trigger a reread (especially important when this is a remote file of course). 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. Wasn't this cached_property before? What's the difference? 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. it was, but 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. Ah ok. What about a try/except ImportError on that? Can lru_cache take a maxsize=1? Does it default to that? Basically can we use cached_property when it exists, but use lru_cache for backwards compatibility for now? 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. I can do 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. Hmmm, I thought this would do it, but no... Will investigate more tomorrow def cached_property(func):
return property(lru_cache(maxsize=1)(func)) 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, got it to work now. |
||
"""Get the nc xr dataset.""" | ||
f_obj = open_file_or_filename(self.filename) | ||
dataset = xr.open_dataset(f_obj, | ||
decode_cf=True, | ||
mask_and_scale=True, | ||
engine=engine, | ||
engine=self._engine, | ||
chunks={'columns': CHUNK_SIZE, | ||
'rows': CHUNK_SIZE}) | ||
|
||
self.nc = self.nc.rename({'columns': 'x', 'rows': 'y'}) | ||
|
||
# TODO: get metadata from the manifest file (xfdumanifest.xml) | ||
self.platform_name = PLATFORM_NAMES[filename_info['mission_id']] | ||
self.sensor = 'olci' | ||
return dataset.rename({'columns': 'x', 'rows': 'y'}) | ||
|
||
@property | ||
def start_time(self): | ||
"""Start time property.""" | ||
return datetime.strptime(self.nc.attrs['start_time'], | ||
'%Y-%m-%dT%H:%M:%S.%fZ') | ||
return self._start_time | ||
|
||
@property | ||
def end_time(self): | ||
"""End time property.""" | ||
return datetime.strptime(self.nc.attrs['stop_time'], | ||
'%Y-%m-%dT%H:%M:%S.%fZ') | ||
return self._end_time | ||
|
||
def get_dataset(self, key, info): | ||
"""Load a dataset.""" | ||
|
@@ -134,10 +141,8 @@ def get_dataset(self, key, info): | |
|
||
def __del__(self): | ||
"""Close the NetCDF file that may still be open.""" | ||
try: | ||
with suppress(IOError, OSError, AttributeError): | ||
self.nc.close() | ||
except (IOError, OSError, AttributeError): | ||
pass | ||
|
||
|
||
class NCOLCICal(NCOLCIBase): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused by this line. Is it a file object or a path object? If it's a file object it's already opened? I think
os.PathLike
represents a path, not an open file.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a path indeed, but can be opened to return a file object.