Skip to content

ENM Base class#22

Open
stratixs wants to merge 63 commits into
biotite-dev:masterfrom
stratixs:base-class
Open

ENM Base class#22
stratixs wants to merge 63 commits into
biotite-dev:masterfrom
stratixs:base-class

Conversation

@stratixs

@stratixs stratixs commented Jun 8, 2026

Copy link
Copy Markdown

Logical changes

  • Adds a base class ENM that handles common logic across GNM and ANM (specifically constructor, covariance calculation, calls to NMA). The goal is to reduce code duplications.
  • The covariance is calculated with np.linalg.pinv. Internally this method uses np.linalg.eigh to calculate the eigenvalues/-vectors and constructs the pseudo-inverse using the reciprocal eigenvalues. This change makes this calculation explicitly and stores the eigenvalues/-vectors in the process so that they can be easily reused for NMA calculations without recalculation.
  • Instead of relying on fixed number of trivial nodes the number of zero eigenvalues can be centrally calculated and returned alongside when calling the ENM.eigen() function.
  • Optimize NMA calculations to reduce complexity for maintainers. These changes are also a result from the common attributes introduced by the ENM base class.

Bug fixes

  • Use direct evaluation of coord difference between atoms instead of calling struc.displacement as the latter one forces float32 precision but float64 is desired.

Housekeeping

  • Switches to hatch build system (the same as the biotite parent project)
  • Extends/corrects docstrings to adhere to numpydoc standard (uses the same numpydoc lint rules as the parent project)
  • Adds type information to attributes and return values so that users can utilize IDE's static analyzers when calling the functions
  • Switches from .pdb to .cif files for tests because RCSB will phase out the old format.
  • Boost test coverage from
Name                             Stmts   Miss Branch BrPart  Cover
------------------------------------------------------------------
src/springcraft/__init__.py          8      0      0      0   100%
src/springcraft/anm.py              79     18     24      4    73%
src/springcraft/forcefield.py      249     25     64     17    86%
src/springcraft/gnm.py              70     17     24      4    71%
src/springcraft/interaction.py      61      3     18      3    92%
src/springcraft/nma.py             151     44     58     10    66%
------------------------------------------------------------------
TOTAL                              618    107    188     38    78%

to

Name                             Stmts   Miss Branch BrPart  Cover
------------------------------------------------------------------
src/springcraft/__init__.py          8      0      0      0   100%
src/springcraft/anm.py              61      2      8      0    97%
src/springcraft/enm.py             112      5     28      2    95%
src/springcraft/forcefield.py      276     18     64     10    91%
src/springcraft/gnm.py              51      0      8      0   100%
src/springcraft/interaction.py      62      3     18      3    92%
src/springcraft/nma.py             109     35     42      7    62%
------------------------------------------------------------------
TOTAL                              679     63    168     22    88%

stratixs added 30 commits May 1, 2026 18:33

@JHKru JHKru left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hi, thanks for your extensive contributions!
They are well-thought out and structured, but for the future, feel free to size them down to multiple individual commits that are easier to handle and review on their own.

A few additional points for discussion:

  • Regarding changes to the build system -> To what extent/why are these necessary? Any need to (mostly) switch away from conda here?
  • You might like to squash/combine some of intermediate commits, because it is a bit difficult to follow.
    For instance, in intermediate commits a Cython extension for ENM-perturbation is set up, that is not part of the overall PR, if I'm not mistaken (commit 39d2795)?

- uses: actions/upload-artifact@v7
with:
name: Springcraft distribution
name: release-dist

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Any reason for this change here?

Comment thread src/springcraft/anm.py
This is not a copy: Create a copy before modifying this matrix.
masses : None or ndarray, shape=(n,), dtype=float
The mass for each atom, `None` if no mass weighting is applied.
hessian : ndarray, shape=(n,n), dtype=float

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If I'm not mistaken shape=(n3, n3) is expected here (Hessian).

Comment thread tests/util.py
return join(dirname(realpath(__file__)), "data")


def load_protein_structure(pdb_id: str) -> struc.AtomArray:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

pdb_id could be replaced with cif_id for clarity here.

Comment thread src/springcraft/enm.py
Comment on lines +228 to +234
i = 0
while self._eig_values[i] < -threshold:
i = i + 1
n_neg = i
while self._eig_values[i] <= threshold:
i = i + 1
n_triv = i + n_neg

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This could be handled by regular Numpy indexing/Boolean masks, instead of directly looping through the Array.

Comment thread src/springcraft/nma.py
enm : ANM or GNM
Elastic network model; an instance of either an GNM or ANM
object.
enm : ENM

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could be kept it specific here and in the remainder of the file, like in the example above (eigen):
"Elastic network model; an instance of either a GNM or ANM"

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.

2 participants