Skip to content

Re-enable FHI-aims total energy mapping#183

Open
ndaelman-hu wants to merge 2 commits into
developfrom
fix/fhiaims-enable-energy-mapping
Open

Re-enable FHI-aims total energy mapping#183
ndaelman-hu wants to merge 2 commits into
developfrom
fix/fhiaims-enable-energy-mapping

Conversation

@ndaelman-hu

Copy link
Copy Markdown
Collaborator

Purpose

Re-enables the total_energies mapping for FHI-aims parser that was disabled in commit 0e00561 (PR #150, March 2026). The parser's get_energies() method has remained functional - only the schema mapping annotation was commented out.

Scope

Included

  • Re-enable total_energies mapping annotation in fhiaims.py
  • Add comprehensive test coverage for energy extraction
  • Validate energy values and contributions structure

Out of scope

Context & Links

Why it was disabled: During the convergence targets migration (#150), the energy mapping was intentionally commented out using the old m_annotations.setdefault() syntax. The commit message stated: "Future migration to dict-based m_def mapping annotations should be tracked separately (see PR #162 for reference)."

Related PRs:

Investigation notes: See .investigation-notes.md in branch (not committed) for detailed impact analysis.

Reviewer Notes

Key changes:

  1. Replace commented m_annotations.setdefault() with active add_mapping_annotation() for consistency with other parsers (VASP, GPAW, QE all use this pattern)
  2. New test test_total_energies() validates:
    • Energy extraction across all 5 geometry optimization steps
    • Correct energy value (-15696.12 eV for first step)
    • Energy contributions/components structure
    • Pint Quantity handling

Risk assessment: LOW

  • Parser method get_energies() already works (parser.py:289-301)
  • MD parser utils are defensive (check if total_energies is empty before appending)
  • No existing tests affected (no prior energy tests)
  • Follows established pattern from 10+ other parsers

Status

  • Ready for review

Breaking Changes

  • None

Dependencies / Blockers

Testing / Validation

  • Unit tests: Added test_total_energies() with comprehensive validation
  • All FHI-aims tests pass (7/7)
  • Energy values match test data analysis
  • Energy contributions properly structured

Re-enables the `total_energies` mapping for FHI-aims parser that was
disabled in commit 0e00561 (PR #150, March 2026). The parser's
`get_energies()` method has remained functional, only the schema
mapping annotation was commented out.

Changes:
- Replace commented `m_annotations.setdefault()` syntax with active
  `add_mapping_annotation()` for consistency with other parsers
- Add comprehensive test coverage for `total_energies` extraction
- Verify all 5 geometry optimization outputs populate energies
- Test energy value accuracy and contributions/components structure

Impact analysis:
- Parser method `get_energies()` verified working (parser.py:289-301)
- MD parser utils handle both empty and populated energies defensively
- No existing tests affected (no prior energy tests existed)
- Test data contains valid energy values across all outputs
- Follows same pattern as VASP, GPAW, QE, and other parsers

The energy mapping was intentionally deferred during the convergence
targets migration. This PR completes that migration for energies as
a standalone, minimal change.
- Break long lines to comply with 88 char limit
- Reformat test assertions for readability
- All tests still passing
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 26894435401

Coverage increased (+0.2%) to 74.352%

Details

  • Coverage increased (+0.2%) from the base build.
  • Patch coverage: 26 of 26 lines across 2 files are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 10371
Covered Lines: 7711
Line Coverage: 74.35%
Coverage Strength: 0.74 hits per line

💛 - Coveralls

@ndaelman-hu ndaelman-hu requested review from EBB2675, JFRudzinski and Copilot and removed request for JFRudzinski June 23, 2026 09:08
@ndaelman-hu ndaelman-hu self-assigned this Jun 23, 2026
@ndaelman-hu ndaelman-hu added enhancement New feature or request electronic parser labels Jun 23, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR re-enables the FHI-aims total_energies schema mapping by restoring an active mapping annotation (using add_mapping_annotation) and adds unit tests to verify total energy extraction and contribution structure for a geometry optimization run.

Changes:

  • Re-enabled outputs.Outputs.total_energies mapping annotation in the FHI-aims schema package.
  • Added a new test_total_energies() to validate extracted total energies across all geometry optimization steps, including units and contribution presence.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/nomad_simulation_parsers/schema_packages/fhiaims.py Restores total_energies mapping annotation using add_mapping_annotation under the FHI-aims text mapping key.
tests/parsers/test_fhiaims_parser.py Adds coverage ensuring total_energies are populated for each output step and validates the first-step reference value and contributions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


# Check each output has total_energies
for i, output in enumerate(outputs):
assert output.total_energies is not None, f'Output {i} has no total_energies'

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Aren't is not None assertions on total_energies and contributions vacuous?

afaik, SubSection with repeats=True never returns None on access, but it returns an empty MSubSectionList

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

(source: metainfo.py:3487-3494)

def __get__(self, obj, cls=None):
    if obj is None:
        return self

    if self.repeats:
        return obj.__dict__.setdefault(self.name, MSubSectionList(obj, self))
    # non-repeating:
    return obj.__dict__.get(self.name, None)

@EBB2675 EBB2675 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, one nit on dead is not None assertions in the tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

electronic parser enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants