Skip to content
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

Allow access of the filenames from the dataset object #56

Merged
merged 3 commits into from
May 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelog/56.feature.1.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Allow easy access to the filenames contained in an
`dkist.io.BaseFITSArrayContainer` object via a `~dkist.io.BaseFITSArrayContainer.filenames` property.
1 change: 1 addition & 0 deletions changelog/56.feature.2.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`dkist.io.BaseFITSArrayContainer` objects are now sliceable.
11 changes: 9 additions & 2 deletions dkist/dataset/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def __init__(self, data, uncertainty=None, mask=None, wcs=None,
else:
self.missing_axis = missing_axis

self.array_container = None
self._array_container = None

@classmethod
def from_directory(cls, directory):
Expand Down Expand Up @@ -128,9 +128,16 @@ def from_asdf(cls, filepath):
raise TypeError(f"This file is not a valid DKIST asdf file, it fails validation with: {e.message}.")

cls = cls(data, wcs=wcs)
cls.array_container = array_container
cls._array_container = array_container
return cls

@property
def array_container(self):
"""
A reference to the files containing the data.
"""
return self._array_container

@property
def pixel_axes_names(self):
if self.wcs.input_frame:
Expand Down
9 changes: 9 additions & 0 deletions dkist/dataset/tests/test_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,12 @@ def test_no_wcs_slice(dataset):
def test_crop_few_slices(dataset_4d):
sds = dataset_4d[0, 0]
assert len(sds.wcs.input_frame.axes_order)


def test_array_container():
dataset = Dataset.from_directory(os.path.join(rootdir, 'EIT'))
assert dataset.array_container is dataset._array_container
with pytest.raises(AttributeError):
dataset.array_container = 10

assert len(dataset.array_container.filenames) == 11
6 changes: 4 additions & 2 deletions dkist/io/fits.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,16 @@ def __repr__(self):
if self._array is None:
return "<FITS array (unloaded) in {0} shape: {1} dtype: {2}>".format(
self.fitsarray.fileuri, self.fitsarray.shape, self.fitsarray.dtype)
return repr(self._array)
return "<FITS array (loaded) in {0} shape: {1} dtype: {2}>\n{3!r}".format(
self.fitsarray.fileuri, self.fitsarray.shape, self.fitsarray.dtype, self._array)

def __str__(self):
# str alone should not force loading of the data
if self._array is None:
return "<FITS array (unloaded) in {0} shape: {1} dtype: {2}>".format(
self.fitsarray.fileuri, self.fitsarray.shape, self.fitsarray.dtype)
return str(self._array)
return "<FITS array (loaded) in {0} shape: {1} dtype: {2}>\n{3!r}".format(
self.fitsarray.fileuri, self.fitsarray.shape, self.fitsarray.dtype, self._array)

def __array__(self):
return self.fits_array
Expand Down
18 changes: 16 additions & 2 deletions dkist/io/reference_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ class BaseFITSArrayContainer(metaclass=abc.ABCMeta):
"""

def __init__(self, reference_array, *, loader, **kwargs):

reference_array = np.asarray(reference_array, dtype=object)

self._check_contents(reference_array)

# If the first dimension is one we are going to squash it.
Expand All @@ -52,7 +50,10 @@ def __init__(self, reference_array, *, loader, **kwargs):
loader_array = np.empty_like(reference_array, dtype=object)
for i, ele in enumerate(reference_array.flat):
loader_array.flat[i] = loader(ele, **kwargs)

self.loader_array = loader_array
self._loader = partial(loader, **kwargs)
self.reference_array = reference_array

def _check_contents(self, reference_array):
"""
Expand All @@ -67,6 +68,19 @@ def _check_contents(self, reference_array):
assert ele.dtype == dtype
assert ele.shape == shape

def __getitem__(self, item):
return type(self)(self.reference_array[item], loader=self._loader)

@property
def filenames(self):
"""
Return a list of file names referenced by this Array Container.
"""
names = []
for ear in self.reference_array.flat:
names.append(ear.fileuri)
return names

@abc.abstractproperty
def array(self):
"""
Expand Down
24 changes: 24 additions & 0 deletions dkist/io/tests/test_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,30 @@ def externalarray():
return f.tree['data']


def test_slicing(externalarray):
ac = NumpyFITSArrayContainer(externalarray, loader=AstropyFITSLoader, basepath=eitdir)
ext_shape = np.array(externalarray, dtype=object).shape
assert ac.loader_array.shape == ext_shape
assert ac.shape == tuple(list(ext_shape) + [128, 128])

assert isinstance(ac.array, np.ndarray)
assert_allclose(ac.array, np.array(ac))

ac = ac[5:8]
ext_shape = np.array(externalarray[5:8], dtype=object).shape
assert ac.loader_array.shape == ext_shape
assert ac.shape == tuple(list(ext_shape) + [128, 128])

assert isinstance(ac.array, np.ndarray)
assert_allclose(ac.array, np.array(ac))


def test_filenames(externalarray):
ac = NumpyFITSArrayContainer(externalarray, loader=AstropyFITSLoader, basepath=eitdir)
assert len(ac.filenames) == len(externalarray)
assert ac.filenames == [e.fileuri for e in externalarray]


def test_numpy(externalarray):
ac = NumpyFITSArrayContainer(externalarray, loader=AstropyFITSLoader, basepath=eitdir)
ext_shape = np.array(externalarray, dtype=object).shape
Expand Down
4 changes: 2 additions & 2 deletions dkist/io/tests/test_fits.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ def test_array(absolute_fl):
assert isinstance(absolute_fl.fits_header, fits.Header)

for contain in ("efz20040301.000010_s.fits", str(absolute_fl.shape), absolute_fl.dtype):
assert contain not in repr(absolute_fl)
assert contain not in str(absolute_fl)
assert contain in repr(absolute_fl)
assert contain in str(absolute_fl)


def test_nan():
Expand Down