Try updating gmx to modern versions#313
Conversation
…d a previously failing test affecting others
.github/workflows/ci.yml
Outdated
| # - "3.13" | ||
| gmx-version: | ||
| - "2019" | ||
| - "2022" |
There was a problem hiding this comment.
2020 and 2021 are not on conda-forge. 2022 is not available for Mac, weirdly enough
.github/workflows/ci.yml
Outdated
| which gmx_d | ||
| gmx help | ||
| gmx dump -h | ||
| # - name: Install Gromacs |
There was a problem hiding this comment.
Or could be deleted
| # gmxversion == 5 means "has the unified gmx wrapper" — covers GROMACS 5.x | ||
| # and all 20xx releases, so have left this alone for now. | ||
| # Old-style program names (g_energy, gmxdump, …) | ||
| # are mapped to their modern subcommand equivalents (energy, dump, …). | ||
| # gmxversion == 4 means only a standalone mdrun was found (GROMACS 4.x). | ||
| if self.gmxversion == 5: | ||
| csplit[0] = csplit[0].replace('g_','').replace('gmxdump','dump') | ||
| csplit = ['gmx' + self.gmxsuffix] + csplit | ||
| elif self.gmxversion == 4: | ||
| csplit[0] = prog + self.gmxsuffix | ||
| else: | ||
| raise RuntimeError('gmxversion can only be 4 or 5') | ||
| return _exec(' '.join(csplit), stdin=stdin, print_to_screen=print_to_screen, print_command=print_command, **kwargs) | ||
| raise RuntimeError('gmxversion must be 4 (standalone mdrun) or 5 (gmx wrapper, valid for GROMACS 5.x and all 20xx releases)') | ||
| return _exec(' '.join(csplit), stdin=stdin, print_to_screen=print_to_screen, print_command=print_command, copy_stderr=copy_stderr, **kwargs) |
There was a problem hiding this comment.
This may not make actual sense for gmx versions 2019+ -- as usual I tried to make as minimal changes as possible here.
There was a problem hiding this comment.
Thanks, does gmx version 4 still work? (I assume that would require version 4 to support newer keywords such as verlet list, nstxout-compressed, coulomb-modifier etc.)
There was a problem hiding this comment.
Hmm, could have sworn I left a reply to this earlier ... but no, the hardcoded keywords mean that gmx4 no longer works. To get around that, we could have a version check before swapping out the keywords.
There was a problem hiding this comment.
Could this part be updated to raise an error if gmx version is 4? (So the only valid value of gmxversion is 5).
There was a problem hiding this comment.
Thanks! Yeah I agree, it shouldn't get that far due to the new check but I've updated the code here and elsewhere as well to simply not accept gmxversion == 4.
leeping
left a comment
There was a problem hiding this comment.
Thanks so much for making these extensive updates. I have a number of questions below.
src/gmxio.py
Outdated
|
|
||
| BOX_LENGTH = (maxbox + 20) * 2 | ||
| NSTLIST = int(1e2) | ||
| CUTOFF = BOX_LENGTH / 25 # nm |
There was a problem hiding this comment.
What's the reason for these choices of parameters?
There was a problem hiding this comment.
Thanks, this is one thing that would be valuable to talk about!
One approach is to hard-code a box size, similar to Jeff's old PR (99.9 or 999.9 nm variously) or the Konermann Lab's approach (333.3 nm). I found with Jeff's larger boxes that I started running into memory issues, and 99.9 was small enough that I was still getting numerical differences from the previous vacuum results. (Actually, this might have been why the tests were hanging in CI initially and I put in that timeout flag).
The Konermann lab's 333.3 nm size is a good midpoint, but I suppose I was wary that it might not generalize to all systems due to running into either one or the other of the problems above. The approach here is based on the size of the molecule instead:
- CUTOFF (which is in nm): meant to cover the entire molecule but be slightly under half the box length. Actually, now that I look at this again, I might have a flaw in my maths and logic there, thanks for the catch. I've updated this to 1) scope out every box instead of just the first one, 2) quadruple it in case of conformational change, and 3) have a minimum value of 1.0 nm just in case.
- BOX_LENGTH (which is in angstroms): This is now also set dependent on CUTOFF, to quadruple just in case, and adds a 1 nm additional buffer.
- NSTLIST: the neighbourlist here doesn't really need to be updated, so I've just set it to an arbitrarily high number.
The warning doesn't have to be there except that once the molecule is that big the box will become truly enormous and crash my Mac. :-)
| # gmxversion == 5 means "has the unified gmx wrapper" — covers GROMACS 5.x | ||
| # and all 20xx releases, so have left this alone for now. | ||
| # Old-style program names (g_energy, gmxdump, …) | ||
| # are mapped to their modern subcommand equivalents (energy, dump, …). | ||
| # gmxversion == 4 means only a standalone mdrun was found (GROMACS 4.x). | ||
| if self.gmxversion == 5: | ||
| csplit[0] = csplit[0].replace('g_','').replace('gmxdump','dump') | ||
| csplit = ['gmx' + self.gmxsuffix] + csplit | ||
| elif self.gmxversion == 4: | ||
| csplit[0] = prog + self.gmxsuffix | ||
| else: | ||
| raise RuntimeError('gmxversion can only be 4 or 5') | ||
| return _exec(' '.join(csplit), stdin=stdin, print_to_screen=print_to_screen, print_command=print_command, **kwargs) | ||
| raise RuntimeError('gmxversion must be 4 (standalone mdrun) or 5 (gmx wrapper, valid for GROMACS 5.x and all 20xx releases)') | ||
| return _exec(' '.join(csplit), stdin=stdin, print_to_screen=print_to_screen, print_command=print_command, copy_stderr=copy_stderr, **kwargs) |
There was a problem hiding this comment.
Thanks, does gmx version 4 still work? (I assume that would require version 4 to support newer keywords such as verlet list, nstxout-compressed, coulomb-modifier etc.)
| except ValueError: | ||
| continue | ||
| energies = np.array(energies) | ||
| return energies / 4.184 # kJ/mol → kcal/mol |
There was a problem hiding this comment.
Wow, this looks like it was challenging, thanks...
If Buckingham or other uncommon nonbonded functional forms were used, would this function still work?
There was a problem hiding this comment.
No, good catch -- I fixated on LJ systems. I modified this function to look for all A-B cross terms which should pick up Buckingham potentials, although I haven't added a test case for this...
There was a problem hiding this comment.
Yes, it would be ideal to have a test case because it seems the interaction energy calculation with Gromacs isn't tested at all. Would it be straightforward to add one? If not, perhaps it should be a different PR.
| # gmxversion == 5 means "has the unified gmx wrapper" — covers GROMACS 5.x | ||
| # and all 20xx releases, so have left this alone for now. | ||
| # Old-style program names (g_energy, gmxdump, …) | ||
| # are mapped to their modern subcommand equivalents (energy, dump, …). | ||
| # gmxversion == 4 means only a standalone mdrun was found (GROMACS 4.x). | ||
| if self.gmxversion == 5: | ||
| csplit[0] = csplit[0].replace('g_','').replace('gmxdump','dump') | ||
| csplit = ['gmx' + self.gmxsuffix] + csplit | ||
| elif self.gmxversion == 4: | ||
| csplit[0] = prog + self.gmxsuffix | ||
| else: | ||
| raise RuntimeError('gmxversion can only be 4 or 5') | ||
| return _exec(' '.join(csplit), stdin=stdin, print_to_screen=print_to_screen, print_command=print_command, **kwargs) | ||
| raise RuntimeError('gmxversion must be 4 (standalone mdrun) or 5 (gmx wrapper, valid for GROMACS 5.x and all 20xx releases)') | ||
| return _exec(' '.join(csplit), stdin=stdin, print_to_screen=print_to_screen, print_command=print_command, copy_stderr=copy_stderr, **kwargs) |
There was a problem hiding this comment.
Could this part be updated to raise an error if gmx version is 4? (So the only valid value of gmxversion is 5).
| except ValueError: | ||
| continue | ||
| energies = np.array(energies) | ||
| return energies / 4.184 # kJ/mol → kcal/mol |
There was a problem hiding this comment.
Yes, it would be ideal to have a test case because it seems the interaction energy calculation with Gromacs isn't tested at all. Would it be straightforward to add one? If not, perhaps it should be a different PR.
This PR updates ForceBalance compatibility to 2019, 2022, 2023, 2024, 2025. (with many caveats for 2022 and 2023 -- the bugs present in gromacs themselves mean it's probably a bad idea to use them with forcebalance).
I haven't yet rebased this one off #312, just because of the non-trivial complexity here. So CI is likely to fail sporadically on TestEvaluatorBromineStudy with a ConnectionRefusedError. I'd suggest the following process: 1. reviewing and merging #312 first, and 2. merging main into here, fixing merge conflicts, and 3. fingers crossed nothing explodes on Python 3.9 or 3.10 .
Changes
There are quite a few changes here. Broadly, they touch four areas: gmxio.py, MDP files, test infrastructure, and CI. The easy ones first:
CI
Added gromacs to the testing matrix
Test infrastructure
In the end, I didn't actually wind up needing to modify the test reference values themselves -- although one of the bromine tests can be a bit flaky.
gmxio.py
Main changes:
-pbc wholecall as well in case something gets split across the periodic boundaryMDPs
MDPs have been updated to be compatible with modern gromacs. Main changes:
cutoff=group