Metadata-Version: 2.4
Name: astropy-hdf5io
Version: 0.1.0
Summary: HDF5 serialization support for AstroPy objects using fsc.hdf5-io
Author-email: astropy-hdf5io contributors <838019+liamh@users.noreply.github.com>
Maintainer-email: "Liam M. Healy" <838019+liamh@users.noreply.github.com>
License: BSD-3-Clause
Project-URL: Homepage, https://github.com/liamh/astropy-hdf5io
Project-URL: Documentation, https://astropy-hdf5io.readthedocs.io/
Project-URL: Repository, https://github.com/liamh/astropy-hdf5io.git
Project-URL: Issues, https://github.com/liamh/astropy-hdf5io/issues
Project-URL: Changelog, https://github.com/liamh/astropy-hdf5io/blob/main/CHANGELOG.md
Keywords: astropy,hdf5,serialization,astronomy,astrophysics,io,data
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Astronomy
Classifier: Topic :: Scientific/Engineering :: Physics
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: astropy>=5.0
Requires-Dist: fsc.hdf5-io>=1.0
Requires-Dist: h5py>=3.0
Requires-Dist: numpy>=1.20
Provides-Extra: munch
Requires-Dist: munch>=2.5; extra == "munch"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: black>=23.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: mypy>=1.0; extra == "dev"
Requires-Dist: munch>=2.5; extra == "dev"
Dynamic: license-file

# astropy-hdf5io

[![PyPI version](https://badge.fury.io/py/astropy-hdf5io.svg)](https://badge.fury.io/py/astropy-hdf5io)
[![Tests](https://github.com/liamh/astropy-hdf5io/workflows/Tests/badge.svg)](https://github.com/liamh/astropy-hdf5io/actions)
[![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)

HDF5 serialization support for AstroPy objects using `fsc.hdf5-io`.

## Features

- **Seamless integration** with `fsc.hdf5-io` for saving/loading AstroPy objects to HDF5
- **Hierarchical organization** with group-level save/load and recursive dict/Munch support
- **Comprehensive type support** including:
  - `Quantity` (with units, including logarithmic units)
  - `Time` (all formats and scales)
  - `SkyCoord` and coordinate frames
  - `Table`, `QTable`, and `TimeSeries`
  - Coordinate representations and differentials
  - `EarthLocation`, `Angle`, `Longitude`, `Latitude`, `Distance`
- **Metadata preservation** for tables and columns
- **Nested structures** support (tables in dicts/lists)
- **Masked columns** support

## Installation

```bash
pip install astropy-hdf5io
```

### Requirements

- Python ≥ 3.9
- astropy ≥ 5.0
- fsc.hdf5-io ≥ 1.0
- h5py ≥ 3.0
- numpy ≥ 1.20

## Quick Start

```python
import astropy.units as u
from astropy.table import QTable
from astropy.time import Time
from astropy.coordinates import SkyCoord
from fsc.hdf5_io import save, load

# Just import astropy_hdf5io to enable serialization
import astropy_hdf5io

# Create AstroPy objects
distance = 1171 * u.Mpc
time = Time('2023-01-01T00:00:00')
coord = SkyCoord(ra=10.68458*u.degree, dec=41.26917*u.degree, distance=distance)

# Save to HDF5
save(distance, 'distance.hdf5')
save(time, 'time.hdf5')
save(coord, 'coord.hdf5')

# Load from HDF5
loaded_distance = load('distance.hdf5')
loaded_time = load('time.hdf5')
loaded_coord = load('coord.hdf5')

print(loaded_distance)  # 1171.0 Mpc
print(loaded_time)      # 2023-01-01 00:00:00.000
print(loaded_coord)     # <SkyCoord ...>
```

## Examples

### Working with Quantities

```python
import astropy.units as u
from fsc.hdf5_io import save, load
import astropy_hdf5io

# Scalar and array quantities
distance = 42.0 * u.pc
velocities = [100, 200, 300] * u.km / u.s

save(distance, 'distance.hdf5')
save(velocities, 'velocities.hdf5')

loaded_distance = load('distance.hdf5')
loaded_velocities = load('velocities.hdf5')

# Complex units work too!
luminosity = 1e10 * u.solLum
flux = 1.2e-15 * u.erg / u.s / u.cm**2
```

### Working with Times

```python
from astropy.time import Time
from fsc.hdf5_io import save, load
import astropy_hdf5io

# Different time formats
t_iso = Time('2023-01-01T12:00:00')
t_jd = Time(2459945.5, format='jd')
t_mjd = Time(59945.0, format='mjd')

# Different time scales
t_utc = Time('2023-01-01', scale='utc')
t_tai = Time('2023-01-01', scale='tai')

save(t_iso, 'time.hdf5')
loaded = load('time.hdf5')
```

### Working with Coordinates

```python
from astropy.coordinates import SkyCoord
import astropy.units as u
from fsc.hdf5_io import save, load
import astropy_hdf5io

# 2D coordinates
coord_2d = SkyCoord(ra=10.68*u.degree, dec=41.27*u.degree, frame='icrs')

# 3D coordinates with distance
coord_3d = SkyCoord(ra=10.68*u.degree, dec=41.27*u.degree,
                     distance=770*u.kpc, frame='icrs')

# Arrays of coordinates
coords = SkyCoord(ra=[10, 20, 30]*u.degree,
                  dec=[40, 50, 60]*u.degree)

save(coord_3d, 'coord.hdf5')
loaded = load('coord.hdf5')
```

### Working with Tables

```python
from astropy.table import Table, QTable
import astropy.units as u
from fsc.hdf5_io import save, load
import astropy_hdf5io

# Regular Table
t = Table({
    'name': ['Star A', 'Star B', 'Star C'],
    'magnitude': [10.5, 12.3, 11.8],
    'distance': [100, 150, 120]
})

# QTable with Quantities
qt = QTable({
    'name': ['Galaxy 1', 'Galaxy 2'],
    'redshift': [0.1, 0.2],
    'distance': [500, 1000] * u.Mpc,
    'flux': [1.2e-15, 8.5e-16] * u.erg / u.s / u.cm**2
})

# Add metadata
qt.meta['telescope'] = 'HST'
qt.meta['observer'] = 'J. Smith'
qt['distance'].info.description = 'Luminosity distance'

save(qt, 'galaxies.hdf5')
loaded = load('galaxies.hdf5')

print(loaded.meta['telescope'])  # 'HST'
print(loaded['distance'].info.description)  # 'Luminosity distance'
```

### Working with TimeSeries

```python
from astropy.timeseries import TimeSeries
from astropy.time import Time
import astropy.units as u
from fsc.hdf5_io import save, load
import astropy_hdf5io

times = Time(['2023-01-01T00:00:00',
              '2023-01-01T01:00:00',
              '2023-01-01T02:00:00'])

ts = TimeSeries(time=times)
ts['flux'] = [100, 120, 110] * u.Jy
ts['temperature'] = [5800, 5850, 5820] * u.K

ts.meta['target'] = 'Variable Star XYZ'

save(ts, 'timeseries.hdf5')
loaded = load('timeseries.hdf5')
```

### Complex Nested Structures

```python
from astropy.table import QTable
from astropy.time import Time
from astropy.coordinates import SkyCoord
import astropy.units as u
from fsc.hdf5_io import save, load
import astropy_hdf5io

# Complex nested data structure
observation_data = {
    'metadata': {
        'telescope': 'VLT',
        'observer': 'J. Smith',
        'date': Time('2023-01-01')
    },
    'targets': [
        SkyCoord(ra=10*u.degree, dec=40*u.degree, distance=1000*u.pc),
        SkyCoord(ra=20*u.degree, dec=50*u.degree, distance=2000*u.pc)
    ],
    'photometry': QTable({
        'time': Time(['2023-01-01', '2023-01-02']),
        'flux': [1.2, 1.5] * u.Jy,
        'magnitude': [18.5, 18.3]
    })
}

save(observation_data, 'observation.hdf5')
loaded = load('observation.hdf5')
```

## How It Works

`astropy-hdf5io` extends `fsc.hdf5-io` by:

1. **Monkey-patching** `to_hdf5()` methods onto AstroPy classes
2. **Registering deserializers** using the `@subscribe_hdf5` decorator
3. **Preserving metadata** including units, coordinate frames, and table information

Simply importing `astropy_hdf5io` automatically registers all serializers. After that, you can use `fsc.hdf5_io.save()` and `fsc.hdf5_io.load()` with AstroPy objects seamlessly.

## Supported Types

### Units and Quantities
- `astropy.units.Quantity` (including logarithmic units like magnitudes)

### Time
- `astropy.time.Time` (all formats: ISO, JD, MJD, etc.)

### Coordinates
- `astropy.coordinates.SkyCoord`
- `astropy.coordinates.Angle`
- `astropy.coordinates.Longitude`
- `astropy.coordinates.Latitude`
- `astropy.coordinates.Distance`
- `astropy.coordinates.EarthLocation`

### Representations
- `CartesianRepresentation`
- `SphericalRepresentation`
- `CylindricalRepresentation`
- `PhysicsSphericalRepresentation`

### Differentials
- `CartesianDifferential`
- `SphericalDifferential`
- `SphericalCosLatDifferential`
- `CylindricalDifferential`

### Tables
- `astropy.table.Table` (including masked columns)
- `astropy.table.QTable` (with Quantity columns)
- `astropy.timeseries.TimeSeries`

### Groups

`astropy-hdf5io` provides utilities for organizing data in group hierarchies in the HDF5 file:

```python
from astropy_hdf5io import save_to_group, load_from_group, print_tree
from astropy.coordinates import SkyCoord
import astropy.units as u


# Save to nested groups
coord = SkyCoord(ra=10*u.degree, dec=40*u.degree, distance=1000*u.pc)
save_to_group(coord, 'astronomy.h5', 'observations/targets/ngc1234')

# Load from specific group
loaded = load_from_group('astronomy.h5', 'observations/targets/ngc1234')

# Show structure
print_tree('astronomy.hdf5')
```

## Development

### Setup

```bash
git clone https://github.com/liamh/astropy-hdf5io.git
cd astropy-hdf5io
pip install -e ".[dev]"
```

### Running Tests

```bash
pytest tests/ -v
```

### Building Documentation

```bash
cd docs
make html
```

## Contributing

Contributions are welcome! Please:

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Make your changes and add tests
4. Run the test suite (`pytest`)
5. Commit your changes (`git commit -m 'Add amazing feature'`)
6. Push to the branch (`git push origin feature/amazing-feature`)
7. Open a Pull Request

## License

This project is licensed under the BSD 3-Clause License - see the [LICENSE](LICENSE) file for details.

## Acknowledgments

- Built on top of [fsc.hdf5-io](https://github.com/FrescolinoGroup/pyhdf5io/)
- Designed for seamless integration with [AstroPy](https://www.astropy.org/)
- Inspired by the AstroPy community's need for efficient HDF5 storage

## Citation

If you use this package in your research, please cite:

```bibtex
@software{astropy_hdf5io,
  author = {{astropy-hdf5io contributors}},
  title = {astropy-hdf5io: HDF5 serialization for AstroPy},
  url = {https://github.com/liamh/astropy-hdf5io},
  version = {0.1.0},
  year = {2026}
}
```

## Support

- **Issues**: [GitHub Issues](https://github.com/liamh/astropy-hdf5io/issues)
- **Discussions**: [GitHub Discussions](https://github.com/liamh/astropy-hdf5io/discussions)
- **Documentation**: [Read the Docs](https://astropy-hdf5io.readthedocs.io/)
