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

support spin for deepmd format #750

Merged
merged 4 commits into from
Nov 6, 2024

Conversation

pxlxingliang
Copy link
Contributor

@pxlxingliang pxlxingliang commented Nov 5, 2024

  • support spin for deepmd format
  • modify name "mag_forces" to "force_mags"

Summary by CodeRabbit

  • New Features

    • Introduced a new function to register spin data types, enhancing data handling capabilities.
    • Added unit tests for reading spin data from NPY and raw formats.
  • Changes

    • Updated dictionary keys from "mag_forces" to "force_mags" across multiple files for consistency.
    • Introduced new data entries and modified existing numerical values in various raw data files.
  • Bug Fixes

    • Adjusted test cases to reflect the updated naming convention for force magnitudes.

Copy link

coderabbitai bot commented Nov 5, 2024

📝 Walkthrough

Walkthrough

The pull request introduces changes across multiple files in the dpdata library, primarily focusing on renaming the dictionary key from "mag_forces" to "force_mags" in the get_frame functions of various modules. This adjustment affects how magnetic forces are stored and accessed in the output data structures without altering the underlying logic or functionality. Additionally, a new function register_spin() is added to the deepmd.py file to register new data types, and corresponding tests are updated or added to reflect these changes.

Changes

File Change Summary
dpdata/abacus/md.py Renamed dictionary key from data["mag_forces"] to data["force_mags"] in get_frame function.
dpdata/abacus/relax.py Renamed dictionary key from data["mag_forces"] to data["force_mags"] in get_frame function.
dpdata/abacus/scf.py Renamed dictionary key from data["mag_forces"] to data["force_mags"] in get_frame function.
dpdata/plugins/abacus.py Renamed parameter from "mag_forces" to "force_mags" in register_mag_data function.
dpdata/plugins/deepmd.py Added new function register_spin() to register "spins" and "force_mags" data types.
tests/test_abacus_spin.py Updated references from mag_forces to force_mags in multiple test methods.
tests/test_deepmd_spin.py Added new test class TestDeepmdReadSpinNPY with methods for testing spin data reading.
tests/tmp.deepmd.spin/Fe16-npy/type_map.raw Added new entry "Fe" to the file.
tests/tmp.deepmd.spin/Fe16-raw/type_map.raw Added new entry "Fe" to the file.
tests/tmp.deepmd.spin/Fe16-raw/virial.raw Added two new lines of numerical data.
tests/tmp.deepmd.spin/Fe16-raw/box.raw Added two new lines of numerical data.
tests/tmp.deepmd.spin/Fe16-raw/coord.raw Updated numerical values in the file.
tests/tmp.deepmd.spin/Fe16-raw/energy.raw Updated numerical values in the file.
tests/tmp.deepmd.spin/Fe16-raw/force.raw Updated numerical values in the file.
tests/tmp.deepmd.spin/Fe16-raw/force_mag.raw Updated numerical values in the file.
tests/tmp.deepmd.spin/Fe16-raw/spin.raw Updated numerical values in the file.
tests/tmp.deepmd.spin/Fe16-npy/type.raw No changes made.
tests/tmp.deepmd.spin/Fe16-raw/type.raw No changes made.

Possibly related PRs

Suggested reviewers

  • wanghan-iapcm
  • njzjz

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (11)
tests/test_deepmd_spin.py (3)

9-9: Remove extra blank line

Consider removing this extra blank line to maintain consistent spacing.


11-17: Consider using tempfile for safer temporary directories

Instead of using a hardcoded temporary path, consider using Python's tempfile module to create unique temporary directories. This prevents potential conflicts in parallel test runs and ensures proper cleanup.

+import tempfile

 def setUp(self):
-    self.tmp_save_path = "tmp.deepmd.spin/dump-tmp"
+    self.tmp_dir = tempfile.mkdtemp(prefix='deepmd_spin_test_')
+    self.tmp_save_path = os.path.join(self.tmp_dir, "dump-tmp")

 def tearDown(self):
-    if os.path.exists(self.tmp_save_path):
-        shutil.rmtree(self.tmp_save_path)
+    if os.path.exists(self.tmp_dir):
+        shutil.rmtree(self.tmp_dir)

18-23: Add docstring and enhance data validation

The helper method would benefit from:

  1. A docstring explaining its purpose and the expected data shape
  2. Additional validation of data values (e.g., range checks for spins)
 def check_Fe16(self, system):
+    """Validate spin data for Fe16 system.
+    
+    Args:
+        system: LabeledSystem containing Fe16 data
+        
+    Expected shapes:
+        - spins: (2 frames, 16 atoms, 3 components)
+        - force_mags: (2 frames, 16 atoms, 3 components)
+    """
     self.assertTrue("spins" in system.data)
     self.assertTrue("force_mags" in system.data)
     self.assertEqual(system.data["spins"].shape, (2, 16, 3))
     self.assertEqual(system.data["force_mags"].shape, (2, 16, 3))
+    # Validate spin values are within physical bounds
+    self.assertTrue(abs(system.data["spins"]).max() <= 1.0,
+                   "Spin values should be normalized")
dpdata/plugins/abacus.py (2)

Line range hint 59-67: Consider aligning singular/plural usage in naming.

There's an inconsistency between the data key name "force_mags" (plural) and the deepmd_name "force_mag" (singular). Consider using consistent plurality in both places.


Line range hint 59-67: Add docstring to explain the register_mag_data function.

The function lacks documentation explaining its purpose, parameters, and return values. Consider adding a docstring to improve code maintainability.

Example:

def register_mag_data(data):
    """Register magnetic-related data types for the system.

    Parameters
    ----------
    data : dict
        Dictionary containing system data with optional 'spins' and 'force_mags' fields

    Notes
    -----
    This function registers the following optional data types:
    - spins: Spin vectors for each atom
    - force_mags: Magnetic force vectors for each atom
    """
tests/test_abacus_spin.py (3)

87-87: Consider updating reference variable name for consistency

While the dictionary key has been updated to "force_mags", the reference variable name magforces_ref could be renamed to force_mags_ref for consistency with the new terminology.

-        magforces_ref = np.array(
+        force_mags_ref = np.array(

Also applies to: 89-89, 99-99


144-144: LGTM with minor naming suggestion

The renaming is consistently applied in the test assertions. As with the test_relax method, consider renaming the magforces_ref variable to force_mags_ref for complete terminology consistency.

-        magforces_ref = np.array(
+        force_mags_ref = np.array(

Also applies to: 146-146, 156-156


Line range hint 1-157: Test coverage is comprehensive and well-structured

The test suite effectively covers all aspects of the spin functionality:

  1. Single-point calculations (SCF)
  2. Geometry optimization (relax)
  3. Molecular dynamics (MD)

Each test method validates both direct data access and format conversion, ensuring robustness of the implementation.

dpdata/abacus/md.py (1)

222-224: Consider adding docstring to clarify magnetic data structure.

Since this PR adds support for spin in deepmd format, it would be helpful to document the structure and units of the magnetic data (spins and force_mags) in the function's docstring. This would make it easier for users to understand how to work with the magnetic data in the deepmd format.

dpdata/plugins/deepmd.py (2)

21-41: Add docstring and type hints to improve code clarity.

The register_spin() function should include documentation explaining its purpose, the data types it registers, and their expected formats.

Consider adding this docstring:

 def register_spin():
+    """Register spin-related data types with the System and LabeledSystem classes.
+    
+    Registers two data types:
+    - spins: 3D array (nframes, natoms, 3) representing atomic spins
+    - force_mags: 3D array (nframes, natoms, 3) representing magnetic forces
+    
+    Returns
+    -------
+    None
+    """

47-47: Consider optimizing multiple register_spin() calls.

The register_spin() function is called multiple times across different format classes. Consider:

  1. Moving the registration to a single initialization point
  2. Adding error handling for registration failures

Consider implementing a singleton pattern or moving the registration to the module initialization:

# At module level
_SPIN_REGISTERED = False

def register_spin():
    """Register spin-related data types if not already registered."""
    global _SPIN_REGISTERED
    if _SPIN_REGISTERED:
        return
    try:
        # ... existing registration code ...
        _SPIN_REGISTERED = True
    except Exception as e:
        raise RuntimeError(f"Failed to register spin data types: {e}")

Also applies to: 57-57, 69-69, 98-98, 179-179, 235-236

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 01a03b3 and b8c454c.

📒 Files selected for processing (18)
  • dpdata/abacus/md.py (1 hunks)
  • dpdata/abacus/relax.py (1 hunks)
  • dpdata/abacus/scf.py (1 hunks)
  • dpdata/plugins/abacus.py (1 hunks)
  • dpdata/plugins/deepmd.py (6 hunks)
  • tests/test_abacus_spin.py (6 hunks)
  • tests/test_deepmd_spin.py (1 hunks)
  • tests/tmp.deepmd.spin/Fe16-npy/type.raw (1 hunks)
  • tests/tmp.deepmd.spin/Fe16-npy/type_map.raw (1 hunks)
  • tests/tmp.deepmd.spin/Fe16-raw/box.raw (1 hunks)
  • tests/tmp.deepmd.spin/Fe16-raw/coord.raw (1 hunks)
  • tests/tmp.deepmd.spin/Fe16-raw/energy.raw (1 hunks)
  • tests/tmp.deepmd.spin/Fe16-raw/force.raw (1 hunks)
  • tests/tmp.deepmd.spin/Fe16-raw/force_mag.raw (1 hunks)
  • tests/tmp.deepmd.spin/Fe16-raw/spin.raw (1 hunks)
  • tests/tmp.deepmd.spin/Fe16-raw/type.raw (1 hunks)
  • tests/tmp.deepmd.spin/Fe16-raw/type_map.raw (1 hunks)
  • tests/tmp.deepmd.spin/Fe16-raw/virial.raw (1 hunks)
✅ Files skipped from review due to trivial changes (13)
  • dpdata/abacus/relax.py
  • dpdata/abacus/scf.py
  • tests/tmp.deepmd.spin/Fe16-npy/type.raw
  • tests/tmp.deepmd.spin/Fe16-npy/type_map.raw
  • tests/tmp.deepmd.spin/Fe16-raw/box.raw
  • tests/tmp.deepmd.spin/Fe16-raw/coord.raw
  • tests/tmp.deepmd.spin/Fe16-raw/energy.raw
  • tests/tmp.deepmd.spin/Fe16-raw/force.raw
  • tests/tmp.deepmd.spin/Fe16-raw/force_mag.raw
  • tests/tmp.deepmd.spin/Fe16-raw/spin.raw
  • tests/tmp.deepmd.spin/Fe16-raw/type.raw
  • tests/tmp.deepmd.spin/Fe16-raw/type_map.raw
  • tests/tmp.deepmd.spin/Fe16-raw/virial.raw
🔇 Additional comments (7)
tests/test_deepmd_spin.py (2)

47-48: LGTM!

The main block follows the standard unittest pattern.


1-48: Verify test data availability

The tests look good and align with PR objectives. However, let's verify the existence of test data files to ensure the tests can run successfully.

dpdata/plugins/abacus.py (1)

59-61: LGTM! Verify the renaming change across the codebase.

The renaming from "mag_forces" to "force_mags" is consistent with the PR objectives and improves terminology clarity.

Let's verify that all occurrences have been updated consistently:

✅ Verification successful

The renaming from "mag_forces" to "force_mags" has been consistently applied across the codebase

The verification shows that:

  • No instances of the old term "mag_forces" remain in the codebase
  • The new term "force_mags" is consistently used across all relevant files:
    • Test files: tests/test_deepmd_spin.py, tests/test_abacus_spin.py
    • Core implementation: dpdata/plugins/deepmd.py, dpdata/plugins/abacus.py
    • ABACUS format handlers: dpdata/abacus/{md,scf,relax}.py
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining instances of the old terminology
echo "Checking for any remaining 'mag_forces' occurrences:"
rg "mag_forces"

# Search for new terminology to verify consistent usage
echo -e "\nVerifying 'force_mags' usage:"
rg "force_mags"

Length of output: 1458

tests/test_abacus_spin.py (1)

34-34: LGTM: Consistent renaming in test_scf method

The renaming from "mag_forces" to "force_mags" is applied consistently in both direct data validation and format conversion tests.

Also applies to: 50-50

dpdata/abacus/md.py (1)

223-223: LGTM! Consistent renaming of magnetic forces key.

The renaming from "mag_forces" to "force_mags" aligns with the PR objectives and maintains consistency across the codebase.

Let's verify the consistency of this renaming across the codebase:

✅ Verification successful

Consistent renaming confirmed across the codebase

The verification shows that:

  • No instances of the old key "mag_forces" remain in the codebase
  • The new key "force_mags" is consistently used across:
    • Test files (tests/test_deepmd_spin.py, tests/test_abacus_spin.py)
    • Plugin modules (dpdata/plugins/abacus.py, dpdata/plugins/deepmd.py)
    • ABACUS-related modules (dpdata/abacus/{md.py,relax.py,scf.py})
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining instances of "mag_forces" and confirm consistent usage of "force_mags"

# Test 1: Search for any remaining instances of the old key name
echo "Checking for remaining instances of 'mag_forces'..."
rg "mag_forces"

# Test 2: Verify the new key name usage
echo "Verifying usage of 'force_mags'..."
rg "force_mags"

Length of output: 1460

dpdata/plugins/deepmd.py (2)

Line range hint 21-236: Implementation looks good with minor suggestions.

The implementation successfully adds spin support to the deepmd format with clean integration into the existing plugin architecture. The changes are backward compatible and align well with the PR objectives.

Consider implementing the suggested improvements for:

  1. Documentation (adding docstrings)
  2. Optimization (singleton pattern for registration)
  3. Test coverage verification

21-41: Verify test coverage for spin data handling.

Please ensure comprehensive test coverage for:

  1. Registration of spin data types
  2. Loading/saving of spin data across different formats
  3. Edge cases (empty systems, systems without spin data)

Let's verify the test coverage:

✅ Verification successful

Let me check the content of the spin-related test files to verify the test coverage:


Test coverage for spin data handling is comprehensive

The test files demonstrate thorough coverage of spin data functionality:

  • test_deepmd_spin.py: Tests registration, reading, and saving of spin data in both NPY and RAW formats
  • test_abacus_spin.py: Verifies spin data handling for SCF, relaxation, and MD calculations with precise numerical validation
  • test_lammps_spin.py: Tests reading/writing spin data from LAMMPS input and dump files, including edge cases like partial/missing spin data

The tests cover all essential aspects:

  • Registration of spin data types
  • Loading/saving across different formats (DeePMD, ABACUS, LAMMPS)
  • Edge cases (zero spins, missing data)
  • Data format conversions and numerical precision checks
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for spin-related test files and coverage
echo "Searching for spin-related test files..."
fd -e py test_.*spin tests/

echo "Checking test coverage in test files..."
rg -l "spin|force_mag" tests/

Length of output: 1959


Script:

#!/bin/bash
# Check content of spin-related test files
echo "=== tests/test_deepmd_spin.py ==="
cat tests/test_deepmd_spin.py

echo -e "\n=== tests/test_abacus_spin.py ==="
cat tests/test_abacus_spin.py

echo -e "\n=== tests/test_lammps_spin.py ==="
cat tests/test_lammps_spin.py

Length of output: 15570

tests/test_deepmd_spin.py Show resolved Hide resolved
Copy link

codspeed-hq bot commented Nov 5, 2024

CodSpeed Performance Report

Merging #750 will not alter performance

Comparing pxlxingliang:force_mag (b8c454c) with devel (01a03b3)

Summary

✅ 2 untouched benchmarks

Copy link

codecov bot commented Nov 5, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 85.10%. Comparing base (01a03b3) to head (b8c454c).
Report is 1 commits behind head on devel.

Additional details and impacted files
@@            Coverage Diff             @@
##            devel     #750      +/-   ##
==========================================
+ Coverage   85.07%   85.10%   +0.02%     
==========================================
  Files          81       81              
  Lines        7478     7492      +14     
==========================================
+ Hits         6362     6376      +14     
  Misses       1116     1116              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@wanghan-iapcm wanghan-iapcm merged commit 32f832b into deepmodeling:devel Nov 6, 2024
12 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Nov 6, 2024
@13yong
Copy link

13yong commented Nov 12, 2024

  • support spin for deepmd format
  • modify name "mag_forces" to "force_mags"

Summary by CodeRabbit

  • New Features

    • Introduced a new function to register spin data types, enhancing data handling capabilities.
    • Added unit tests for reading spin data from NPY and raw formats.
  • Changes

    • Updated dictionary keys from "mag_forces" to "force_mags" across multiple files for consistency.
    • Introduced new data entries and modified existing numerical values in various raw data files.
  • Bug Fixes

    • Adjusted test cases to reflect the updated naming convention for force magnitudes.

Hello, developer! I am interested in adding spin to DP. Here, I have a question about force_mags. I don't know how to get this information from OUTCAR. Can you do some comments about this? Thank you.

@coderabbitai coderabbitai bot mentioned this pull request Dec 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants