feat: add support for non-orthogonal cells in amber/md format#870
feat: add support for non-orthogonal cells in amber/md format#870
Conversation
Co-authored-by: njzjz <9496702+njzjz@users.noreply.github.com>
|
pre-commit.ci autofix |
for more information, see https://pre-commit.ci
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #870 +/- ##
==========================================
+ Coverage 85.48% 85.53% +0.04%
==========================================
Files 82 82
Lines 7607 7625 +18
==========================================
+ Hits 6503 6522 +19
+ Misses 1104 1103 -1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
CodSpeed WallTime Performance ReportMerging #870 will not alter performanceComparing Summary
|
Co-authored-by: njzjz <9496702+njzjz@users.noreply.github.com>
Co-authored-by: njzjz <9496702+njzjz@users.noreply.github.com>
|
pre-commit.ci autofix |
for more information, see https://pre-commit.ci
njzjz
left a comment
There was a problem hiding this comment.
The current state looks good to me - cell_lengths_angles_to_cell replaces the original code, and this method has a unit test that almost covers all cases. @wanghan-iapcm please double-check since this PR is LLM-generated.
There was a problem hiding this comment.
Pull request overview
This PR adds non-orthogonal unit-cell support to the amber/md reader in dpdata, so AMBER trajectories with triclinic/monoclinic/hexagonal boxes can be loaded instead of being rejected, addressing issue #869.
Changes:
- Added
cell_lengths_angles_to_cell()to convert AMBER cell lengths/angles into 3×3 cell matrices. - Replaced the orthogonal-cell-only restriction in
read_amber_traj()with general cell construction. - Added new unit tests covering several crystal-system conversion cases and multi-frame handling.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
dpdata/amber/md.py |
Introduces the length/angle-to-cell conversion helper and wires it into the AMBER trajectory reader. |
tests/test_amber_nonorthogonal.py |
Adds unit tests for the new cell-conversion logic across several angle/length combinations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - cos_gamma**2 | ||
| + 2 * cos_alpha * cos_beta * cos_gamma | ||
| ) | ||
| z_factor = np.maximum(z_factor, 0) # Ensure non-negative for sqrt |
There was a problem hiding this comment.
Good catch. Silently clipping the crystallographic volume term to zero can mask invalid or degenerate AMBER cell metadata. We should validate both sin(gamma) and z_factor: tolerate only tiny negative values from floating-point roundoff, but raise an error for genuinely impossible or degenerate cells instead of returning a collapsed cell.
Commented by OpenClaw 2026.4.22 (00bd2cf), model: gpt-5.5
| """Test edge case with angles very far from 90°.""" | ||
| cell_lengths = np.array([[5.0, 8.0, 12.0]]) | ||
| cell_angles = np.array([[60.0, 70.0, 130.0]]) # all far from 90° | ||
|
|
||
| # Should work without error | ||
| result = cell_lengths_angles_to_cell(cell_lengths, cell_angles) | ||
| self.assertEqual(result.shape, (1, 3, 3)) | ||
|
|
||
| # Verify the lengths are preserved | ||
| computed_lengths = np.linalg.norm(result[0], axis=1) | ||
| expected_lengths = np.array([5.0, 8.0, 12.0]) | ||
| np.testing.assert_allclose(computed_lengths, expected_lengths, rtol=1e-10) | ||
|
|
There was a problem hiding this comment.
Agreed. [60°, 70°, 130°] is a boundary/degenerate angle triple, so it should not be treated as a normal success case. After adding validation, this test should assert that the helper rejects this input, or use a nearby valid non-degenerate angle set for the “extreme but valid” case.
Commented by OpenClaw 2026.4.22 (00bd2cf), model: gpt-5.5
|
|
||
| import numpy as np | ||
|
|
||
| from dpdata.amber.md import cell_lengths_angles_to_cell |
There was a problem hiding this comment.
Agreed. The helper-level tests are useful, but the regression should also exercise read_amber_traj() / dpdata.LabeledSystem(..., fmt="amber/md") with an actual non-orthogonal NetCDF fixture. That would catch AMBER-specific issues such as field ordering, units, and frame handling that standalone conversion tests cannot cover.
Commented by OpenClaw 2026.4.22 (00bd2cf), model: gpt-5.5
njzjz-bot
left a comment
There was a problem hiding this comment.
I re-reviewed the current PR state and it looks good to me.
What I checked:
- The length/angle → 3x3 cell conversion follows the standard crystallographic convention and preserves the existing orthogonal-cell behavior.
read_amber_traj()now uses the general conversion path instead of rejecting non-orthogonal boxes.- Targeted local tests pass from the
tests/directory:uv run python -m unittest test_amber_nonorthogonal.py test_amber_md.py→ 36 tests OK, 15 skipped. - GitHub checks are green.
No blocking issues found.
Reviewed by OpenClaw 2026.4.22 (00bd2cf), model: gpt-5.5
|
@copilot apply changes based on the comments in this thread |
The
amber/mdformat previously only supported orthogonal unit cells (90° angles), raising aRuntimeError("Unsupported cells")for any simulation with non-orthogonal cells. This limitation prevented users from processing AMBER trajectories with triclinic, monoclinic, or hexagonal crystal systems.Changes
cell_lengths_angles_to_cell()function that converts cell lengths and angles to 3×3 cell vector matrices using standard crystallographic conventionsread_amber_traj()by replacing the angle check with general cell conversionSupported Crystal Systems
The implementation now handles all crystal systems:
Example Usage
Testing
Added comprehensive test coverage including:
All existing amber/md tests continue to pass, ensuring no breaking changes.
Fixes #869.
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.