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

save units in attrs of H5 #90

Merged
merged 13 commits into from
May 17, 2024
23 changes: 16 additions & 7 deletions .github/workflows/pytest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,39 @@ on:
- cron: '14 3 * * 1' # at 03:14 on Monday.

jobs:
test:

runs-on: ubuntu-latest
pytest:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
python-version:
- "3.12"
- "3.11"
- "3.10"
- "3.9"
os:
- ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Poetry
uses: abatilo/actions-poetry@v2
uses: snok/install-poetry@v1
with:
poetry-version: 1.3.2
virtualenvs-create: true
virtualenvs-in-project: true
- name: Install package
run: |
poetry install --no-interaction --without=notebook --all-extras
- name: Install package
run: |
poetry install --without=notebook --all-extras
- name: Pytest
run: |
poetry run python --version
poetry run coverage run -m pytest
poetry run coverage lcov
- name: Coveralls
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ import ase
atoms: list[ase.Atoms]

db = znh5md.io.DataWriter(filename="db.h5")
db.initialize_database_groups()

db.add(znh5md.io.AtomsReader(atoms)) # or znh5md.io.ChemfilesReader

Expand Down
2 changes: 0 additions & 2 deletions examples/ase.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@
"source": [
"%%time\n",
"db = znh5md.io.DataWriter(filename=\"db.h5\")\n",
"db.initialize_database_groups()\n",
"db.add(znh5md.io.AtomsReader(atoms_list, step=1, time=0.1))"
]
},
Expand Down Expand Up @@ -253,7 +252,6 @@
],
"source": [
"db = znh5md.io.DataWriter(filename=\"from_file.h5\")\n",
"db.initialize_database_groups()\n",
"db.add(znh5md.io.ASEFileReader(\"traj.xyz\", step=1, time=0.1))"
]
},
Expand Down
219 changes: 214 additions & 5 deletions poetry.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "znh5md"
version = "0.1.9"
version = "0.2.0"
description = "High Performance Interface for H5MD Trajectories"
authors = ["zincwarecode <zincwarecode@gmail.com>"]
license = "Apache-2.0"
Expand All @@ -22,6 +22,7 @@ pre-commit = "^2.20.0"
coverage = "^7.1.0"
pytest-profiling = "^1.7.0"
pytest-benchmark = "^4.0.0"
mdanalysis = "^2"
PythonFZ marked this conversation as resolved.
Show resolved Hide resolved

[tool.poetry.group.notebook.dependencies]
jupyterlab = "^4"
Expand Down
3 changes: 0 additions & 3 deletions tests/test_ASEH5MD.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ def test_get_slice(tmp_path, atoms_list, remove_calc):
atoms.calc = None

db = znh5md.io.DataWriter(filename="db.h5")
db.initialize_database_groups()
db.add(znh5md.io.AtomsReader(atoms_list))

traj = znh5md.ASEH5MD("db.h5")
Expand All @@ -56,7 +55,6 @@ def test_request_missing_properties(tmp_path, atoms_list, remove_calc):
atoms.calc = None

db = znh5md.io.DataWriter(filename="db.h5")
db.initialize_database_groups()

if remove_calc:
with pytest.raises(RuntimeError):
Expand All @@ -77,7 +75,6 @@ def test_skip_property(tmp_path, atoms_list):
os.chdir(tmp_path)

db = znh5md.io.DataWriter(filename="db.h5")
db.initialize_database_groups()

atoms_list[-1].arrays.pop("momenta")
atoms_list[-1].get_momenta()
Expand Down
2 changes: 0 additions & 2 deletions tests/test_benchmarks.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@
def test_bench_DataWriter(tmp_path, atoms_list, benchmark):
os.chdir(tmp_path)
db = znh5md.io.DataWriter(filename="db.h5")
db.initialize_database_groups()
reader = znh5md.io.AtomsReader(atoms_list)
benchmark(db.add, reader)


def test_bench_ASEH5MD(tmp_path, atoms_list, benchmark):
os.chdir(tmp_path)
db = znh5md.io.DataWriter(filename="db.h5")
db.initialize_database_groups()
reader = znh5md.io.AtomsReader(atoms_list)
db.add(reader)

Expand Down
1 change: 0 additions & 1 deletion tests/test_custom_file_handle.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ def test_AtomsReader(tmp_path, atoms_list):
print(tmp_path)

db = znh5md.io.DataWriter(filename="db.h5")
db.initialize_database_groups()

reader = znh5md.io.AtomsReader(atoms_list, frames_per_chunk=10)
db.add(reader)
Expand Down
41 changes: 41 additions & 0 deletions tests/test_mdanalysis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""Use the MDAnalysis library to read H5 files and check compliance with the H5MD standard."""
import pathlib

import ase.build
import MDAnalysis as mda
import numpy as np
import pytest
from MDAnalysis.coordinates.H5MD import H5MDReader

import znh5md


@pytest.fixture
def trajectory() -> list[ase.Atoms]:
"""Generate ase.Atoms objects that moves linearly in space."""
water = ase.build.molecule("H2O")
atoms_list = [water]
while len(atoms_list) < 100:
atoms = atoms_list[-1].copy()
atoms.positions += [0.1, 0.1, 0.1]
atoms_list.append(atoms)
return atoms_list


@pytest.fixture
def h5_trajectory(tmp_path, trajectory) -> pathlib.Path:
"""Write the trajectory to an H5 file."""
filename = tmp_path / "trajectory.h5"
db = znh5md.io.DataWriter(filename=filename)
reader = znh5md.io.AtomsReader(trajectory)
db.add(reader)
return filename


def test_read_h5md(h5_trajectory, trajectory):
u = mda.Universe.empty(n_atoms=3, trajectory=True)
reader = H5MDReader(h5_trajectory)
u.trajectory = reader
assert len(u.trajectory) == 100
for ref, ts in zip(trajectory, u.trajectory):
assert np.allclose(ref.positions, ts.positions)
2 changes: 0 additions & 2 deletions tests/test_readers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ def test_AtomsReader(tmp_path, reader, atoms_list, use_add):
print(tmp_path)

db = znh5md.io.DataWriter(filename="db.h5")
db.initialize_database_groups()

if reader == znh5md.io.AtomsReader:
inputs = atoms_list
Expand Down Expand Up @@ -72,7 +71,6 @@ def test_ChemfilesReader(tmp_path, atoms_list, frames_per_chunk):
print(tmp_path)

db = znh5md.io.DataWriter(filename="db.h5")
db.initialize_database_groups()

inputs = "traj.xyz"
ase.io.write(inputs, atoms_list)
Expand Down
1 change: 0 additions & 1 deletion tests/test_writing.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ def test_DataWriter(tmp_path, atoms_list):
os.chdir(tmp_path)

db = DataWriter(filename="db.h5")
db.initialize_database_groups()

reader = AtomsReader(atoms_list)

Expand Down
2 changes: 1 addition & 1 deletion tests/test_znh5md.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


def test_version():
assert znh5md.__version__ == "0.1.9"
assert znh5md.__version__ == "0.2.0"


def test_shape(example_h5):
Expand Down
3 changes: 0 additions & 3 deletions znh5md/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ def convert(file: str, db_file: str):
import znh5md

db = znh5md.io.DataWriter(db_file)
if not pathlib.Path(db_file).exists():
db.initialize_database_groups()

db.add(znh5md.io.ASEFileReader(file))


Expand Down
19 changes: 19 additions & 0 deletions znh5md/format/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,25 @@ def decode_boundary(value) -> np.ndarray:
OBSERVABLES_GRP = [GRP.energy, GRP.stress]


@dataclasses.dataclass
class StepTimeChunkUnits:
value: str
time: str


# We store everything in ASE units
UNITS_PER_GRP = {
GRP.position: StepTimeChunkUnits(value="Angstrom", time="fs"),
GRP.velocity: StepTimeChunkUnits(value="Angstrom/fs", time="fs"),
GRP.forces: StepTimeChunkUnits(value="eV/Angstrom", time="fs"),
GRP.energy: StepTimeChunkUnits(value="eV", time="fs"),
GRP.stress: StepTimeChunkUnits(value="GPa", time="fs"),
GRP.momentum: StepTimeChunkUnits(value="eV/fs", time="fs"),
GRP.edges: StepTimeChunkUnits(value="Angstrom", time="fs"),
GRP.boundary: StepTimeChunkUnits(value="Angstrom", time="fs"),
}
PythonFZ marked this conversation as resolved.
Show resolved Hide resolved


@dataclasses.dataclass
class FormatHandler:
filename: str
Expand Down
Loading
Loading