diff --git a/README.md b/README.md index f9099aa..b8c8a69 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,7 @@ A tool for standardizing I/O when reducing and analyzing exoplanet data `Xarray` is commonly used for data analysis in geoscience and makes use of two core data structures, called a `DataArray` and a `Dataset`. The former is like a NumPy array, except with coordinates, labels, and attributes. The latter is simply a collection of DataArrays. Both structures can easily be written to and loaded from HDF5 files. This means, even if you are not using Python, you can still read an HDF5 file written by `Astraeus` and maintain the full useability of your data. -## Installation & Documentation +## Installation & Example Usage -Up-to-date installation instructions and documentation can be found at +Up-to-date installation instructions and helpful examples can be found at [https://kevin218.github.io/Astraeus/](https://kevin218.github.io/Astraeus/). - -## Quickstart - -Stay tuned for our quickstart guide. diff --git a/docs/index.rst b/docs/index.rst index 7947835..c6dd626 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -39,8 +39,8 @@ If you plan on contributing to the package, you should instead clone it via GitH The ``-e`` flag makes the install editable, which means that you do not have to install the package again and again after each change. Changes to your files inside the project folder will automatically reflect in changes on your installed package. However, if you are working in an interactive environment (e.g., ipython, Jupyter) you will need to re-import any modules that have changed. -Usage -===== +Example Usage +============= `Astraeus` has several templates for creating Xarray DataArrays: `flux-like`, `time-like`, `wavelength-like`, and `light curve` (which makes use of both time and wavelength). @@ -53,7 +53,8 @@ Creating an `flux-like` DataArray requires a 3D array (time, y, x) of flux-like flux_units = 'e-' time_units = 'MJD' name = 'flux' - flux_da = xrio.makeFluxLikeDA(flux, time, flux_units, time_units, name=name) + flux_da = xrio.makeFluxLikeDA(flux, time, flux_units, time_units, + name=name) The `time-like` and `wavelength-like` DataArrays are quite similar, and are helpful for recording time- and wavelength-dependent variables:: @@ -63,7 +64,8 @@ The `time-like` and `wavelength-like` DataArrays are quite similar, and are help units = 'K' time_units = 'MJD' name = 'detector_temperature' - temp_da = xrio.makeTimeLikeDA(temperature, time, units, time_units, name=name) + temp_da = xrio.makeTimeLikeDA(temperature, time, units, + time_units, name=name) # Create 1D DataArray of wavelength-dependent values depth = 1+np.random.rand(20) @@ -71,7 +73,8 @@ The `time-like` and `wavelength-like` DataArrays are quite similar, and are help units = '%' wave_units = 'microns' name = 'transit_depth' - depth_da = xrio.makeWaveLikeDA(depth, wavelength, units, wave_units, name=name) + depth_da = xrio.makeWaveLikeDA(depth, wavelength, units, + wave_units, name=name) A `light curve` DataArray is used to store, for example, a time series of 1D spectra and requires a 2D array (wavelength, time) of flux-like values, a time array, and (of course) units:: @@ -83,7 +86,8 @@ A `light curve` DataArray is used to store, for example, a time series of 1D spe wave_units = 'microns' time_units = 'MJD' name = 'light_curves' - lc_da = xrio.makeLCDA(spec, wavelength, time, flux_units, wave_units, time_units, name=name) + lc_da = xrio.makeLCDA(spec, wavelength, time, flux_units, + wave_units, time_units, name=name) Maintaining all of these DataArrays can be cumbersome, so it is often helpful to combine DataArrays with similar coordinates (i.e., axes) into an Xarray Dataset:: diff --git a/setup.cfg b/setup.cfg index ff1a671..fbd0e2b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,8 +1,8 @@ [metadata] name = Astraeus -version = 0.1 +version = 0.2 author = Kevin B. Stevenson -author_email = kevin.stevenson@jhuapl.edu +author_email = kbstevenson@gmail.com description = Exoplanet Data Reduction I/O long_description = file: README.md long_description_content_type = text/markdown @@ -11,7 +11,7 @@ license_file = LICENSE url = https://github.com/kevin218/Astraeus project_urls = Bug Tracker = https://github.com/kevin218/Astraeus/issues - Sourse Code = https://github.com/kevin218/Astraeus + Source Code = https://github.com/kevin218/Astraeus classifiers = Programming Language :: Python :: 3 License :: OSI Approved :: BSD 3-Clause License diff --git a/src/astraeus/dataset.py b/src/astraeus/dataset.py index ad1754e..0ad3f22 100644 --- a/src/astraeus/dataset.py +++ b/src/astraeus/dataset.py @@ -7,7 +7,9 @@ class Dataset(xr.Dataset): __slots__ = ("_dataset",) def __setattr__(self, name: str, value: Any) -> None: - """Overwrite the setattr function to allow behaviour like Dataset.name = value instead of the usual Dataset['name'] = (coords, value). + """Overwrite the setattr function to allow behaviour like + Dataset.name = value instead of the usual + Dataset['name'] = (coords, value). """ try: object.__setattr__(self, name, value) diff --git a/src/astraeus/xarrayIO.py b/src/astraeus/xarrayIO.py index 5f93016..266ae07 100644 --- a/src/astraeus/xarrayIO.py +++ b/src/astraeus/xarrayIO.py @@ -1,6 +1,6 @@ import numpy as np import xarray as xr -from .dataset import Dataset +# from .dataset import Dataset def writeXR(filename, ds, verbose=True, append=False): @@ -33,9 +33,10 @@ def writeXR(filename, ds, verbose=True, append=False): filename += ".h5" if append: - ds.to_netcdf(filename, engine='h5netcdf', mode='a') + ds.to_netcdf(filename, engine='h5netcdf', invalid_netcdf=True, + mode='a') else: - ds.to_netcdf(filename, engine='h5netcdf') + ds.to_netcdf(filename, engine='h5netcdf', invalid_netcdf=True) if verbose: print(f"Finished writing to {filename}") @@ -68,7 +69,8 @@ def readXR(filename, verbose=True): (filename.endswith(".h5") == False) and \ (filename.endswith(".nc") == False): filename += ".h5" - ds = Dataset(xr.open_dataset(filename, engine='h5netcdf')) + # ds = Dataset(xr.open_dataset(filename, engine='h5netcdf')) + ds = xr.open_dataset(filename, engine='h5netcdf') if verbose: print(f"Finished loading parameters from {filename}") except Exception as e: @@ -258,12 +260,14 @@ def makeDataset(dictionary=None): ds: object Xarray Dataset """ - ds = Dataset(dictionary) + # ds = Dataset(xr.Dataset(dictionary)) + ds = xr.Dataset(dictionary) return ds def concat(datasets, dim='time', data_vars='minimal', coords='minimal', compat='override'): """ - Concatenate list of Xarray Datasets along given dimension (default is time). See xarray.concat() for details. + Concatenate list of Xarray Datasets along given dimension (default is time). + See xarray.concat() for details. Parameters ---------- @@ -283,5 +287,6 @@ def concat(datasets, dim='time', data_vars='minimal', coords='minimal', compat=' ds: object Xarray Dataset with concatenated parameters """ - ds = xr.concat(datasets, dim=dim, data_vars=data_vars, coords=coords, compat=compat) + ds = xr.concat(datasets, dim=dim, data_vars=data_vars, + coords=coords, compat=compat) return ds diff --git a/tests/test_xr.py b/tests/test_xr.py index b79781a..4e984a4 100644 --- a/tests/test_xr.py +++ b/tests/test_xr.py @@ -31,11 +31,11 @@ def test_writeH5(): }, ) success = xrio.writeXR(filename, ds) - assert success == 1 + assert success success = xrio.writeXR(filename, ds2, append=True) - assert success == 1 + assert success success = xrio.writeXR(filename, None) - assert success == 0 + assert success is False os.remove(filename) def test_readH5(): @@ -52,10 +52,12 @@ def test_readH5(): "z": ("x", list("abcd")), }, ) + ds.attrs['somevalue'] = 0.5 success = xrio.writeXR(filename, ds) ds2 = xrio.readXR(filename) assert ds2 != None assert np.array_equal(ds.foo.values, ds2.foo.values) + assert ds.attrs['somevalue'] == ds2.attrs['somevalue'] ds2 = xrio.readXR("bar.h5") assert ds2 == None os.remove(filename) @@ -110,3 +112,5 @@ def test_makeDA(): datasets = [ds1, ds2] ds = xrio.concat(datasets, dim='time') assert np.array_equal(ds.flux.values, np.concatenate((ds1.flux.values,ds2.flux.values))) + # Test writing to dataset using __setattrs__ + # ds1.t = ds2.t.data