-
Notifications
You must be signed in to change notification settings - Fork 16
Increasing pyMBE interoperability (part I) #151
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
Open
jorch28
wants to merge
77
commits into
pyMBE-dev:main
Choose a base branch
from
jorch28:CheckThisFeature
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 61 commits
Commits
Show all changes
77 commits
Select commit
Hold shift + click to select a range
93f8e93
Add engine factory and unfinished files for the espresso and lammps e…
d98eec9
Add engine factory to init method to instantiate the wanted engine cl…
ec47aaa
Add particle_charge,particle_label,particle_position and particle_fix…
7985bc7
Use attributes inst.particle_label, inst.particle_charge, inst.partic…
731e325
Add tutorial
802cac6
Add modifications to decouple the follwoing methods from espresso:
aa70a25
modify base classes to base engine. Delete engine factory
dd74d6c
Add espresso engine methods
08b2453
Add Espresso protocol classes to simulate the structure of the espres…
4d5163d
Modify manager _get_particle_instances to just add position and fix r…
10fa793
Modify pydantic validation for particle instances enabling arbitrary …
764c716
Add modifications to pymbe tutorial according to the decoupling of es…
43fdd35
Adapt methods:
ae645c8
Modify method add_instances_to_engine in order that takes into accoun…
914f74c
Add LammpsEngineProtocol
7b903b3
Add LammpsSimulation still to be build the code related to LammpsSimu…
7c57df5
Add position and added to engine in pmb_type particle for _load_datab…
0fa66d4
Add into Manager class _update_instance method for pymbe type particl…
6c939ff
Add attributes added_to_engine for both particleinstances and bond in…
fd4572d
Adapt sample/branched_polyampholyte to changes related in decoupling …
c1d3ea8
Add modifications to tests.
e815cea
Add changes to peptide_cpH to account for the decouple of espresso
edaabda
various small revisions together with Jordi
16a8263
Add changes to decouple:
02559f5
Add pymbe warnings to send a deprecate warning for the use of certain…
267cbf8
Add deprecation warnings to the use of handy functions
557971b
Add to espresso engine:
7d8294b
Add methods that might be useful for any engine:
3a04e0a
Add changes in save and load database functions to load and save arra…
d3930fe
Add methods to manager:
322bf3b
Add changes:
6aab5d1
Add comment
685a26e
set the simulation engine in order to use the pmb method to determine…
5533abb
set simulation engine before executing the tests
fc6fa7d
Set simulation engine before executing the tests remove espresso syst…
282d215
Add simulation engine in both tests
919afbf
Add simulation engine before executing the handy functions as now the…
64811b7
Modify method to test column positions from the dataframe as it conta…
7df1750
Adapt sample file to current version decoupling espresso
2348bb4
Adapt current sample files towards decoupling espresso
44aea18
remove espresso_system as an input from methods migrated from handy f…
861f03b
Adapt test_handy_functions towards decoupling espresso
337cf47
Adapt changes to decoupling espresso from pymbe
c8d3f7d
Add modifications to adapt sample script to espresso decoupling
1a9b961
Add changes to pymbe_tutorial
e7c1445
Merge branch 'main' into CheckThisFeature
73404f9
Decouple create_angular_potential,generate_angles_for_entity,
850ec76
Add method add_angle, _create_angle_instance and _get_angle_instance.
4e28d5e
include in io.py _load_database and _save_database added_to_engine fo…
2212e89
Adapt angle tests to decouple it from espresso
39ac794
Add as pmb_type "angle" with attributes particle_id1,particle_id2 and…
1b03f67
Add added_to_engine in AngleInstance data class
61625c4
Adapt test hydrogel_builder_with_angles
72562ee
Adapt test_lattice_setup
27348fa
Adapt to decouple from espresso method test_io_instances
e273215
A commit
b1a99a9
Add box_l argument to _create_hydrogel_chain
jorch28 217d15a
Fix box_l size to match a diamond lattice of monomer chains that cont…
jorch28 3d63646
Modify test so that the expected result is expressed in terms of magn…
jorch28 698afb2
Calculate the resulting quantity of the chain length in reduced units…
jorch28 b5e4523
Delete unused imports.
jorch28 7316798
use np.prod(box_l) to replace box_l[0]*box_l[1]*box_l[2]
jorch28 2ca41b2
Add Copyright Notes
jorch28 06560f8
Clear pymbe_tutorial outputs
jorch28 858fe3e
Delete data.csv
jorch28 32289b7
Add DummyEngine with __getattr__ dunder method to raise RuntimeError
jorch28 0dc430a
Use __getattr__ to setup not ImplementedError for LammpsSimulationEngine
jorch28 8f18d26
remove unused variable espresso_local_system
jorch28 cface83
Add LammpsSimulationEngine that Raises a not ImplementedError
jorch28 807296f
Add a DummyEngine instantiated by default in pyMBE.
jorch28 d8453bc
added jordi to author list, update changelog
ea58a8d
Merge branch 'main' into CheckThisFeature
d20e6b8
Add facade method to lammps engine to comply with the interface contract
jorch28 bcbbaa4
Delete files from titration simulations
jorch28 0663dee
Modify EspressoSystemProtocol into version 4.2.2 and EspressoSystem5.…
jorch28 215a881
Update info from Authors.md
jorch28 fec7a8e
remove cells created to trial functions
jorch28 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import warnings | ||
| from functools import wraps | ||
|
|
||
| def deprecated(new_function): | ||
| """Wrapper function to display a warning deprecation message to all functions that are going to be removed in a future | ||
| """ | ||
| def decorator(func): | ||
| @wraps(func) | ||
| def wrapper(*args, **kwargs): | ||
| warnings.warn( | ||
| f"{func.__name__} is deprecated and it will be removed in the future. Please use"+ new_function +"instead.", | ||
| DeprecationWarning, | ||
| stacklevel=2 | ||
| ) | ||
| return func(*args, **kwargs) | ||
| return wrapper | ||
| return decorator | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,144 @@ | ||
| from abc import ABC,abstractmethod | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here and in other new files: missing copyright notices. |
||
| import numpy as np | ||
|
|
||
| class SimulationEngine(ABC): | ||
| """Base Class for simulation engines contains methods """ | ||
| def __init__(self): | ||
| pass | ||
| @abstractmethod | ||
| def _check_bond_inputs(self): | ||
| return | ||
| @abstractmethod | ||
| def _create_bond_instance(self): | ||
| return | ||
| @abstractmethod | ||
| def _get_bond_instance(self): | ||
| return | ||
| @abstractmethod | ||
| def add_instances_to_engine(self): | ||
| return | ||
| def calculate_center_of_mass(self, instance_id, pmb_type): | ||
| """ | ||
| Calculates the center of mass of a pyMBE object instance in an ESPResSo system. | ||
|
|
||
| Args: | ||
| instance_id ('int'): | ||
| pyMBE instance ID of the object whose center of mass is calculated. | ||
|
|
||
| pmb_type ('str'): | ||
| Type of the pyMBE object. Must correspond to a particle-aggregating | ||
| template type (e.g. '"molecule"', '"residue"', '"peptide"', '"protein"'). | ||
|
|
||
| Returns: | ||
| ('numpy.ndarray'): | ||
| Array of shape '(3,)' containing the Cartesian coordinates of the | ||
| center of mass. | ||
|
|
||
| Notes: | ||
| - This method assumes equal mass for all particles. | ||
| - Periodic boundary conditions are *not* unfolded; positions are taken | ||
| directly from ESPResSo particle coordinates. | ||
| """ | ||
| center_of_mass = np.zeros(3) | ||
| axis_list = [0,1,2] | ||
| inst = self.db.get_instance(pmb_type=pmb_type, | ||
| instance_id=instance_id) | ||
| particle_id_list = self.db.get_particle_id_map(object_name=inst.name)["all"] | ||
| for pid in particle_id_list: | ||
| for axis in axis_list: | ||
| center_of_mass[axis] += self.db.get_instance(pmb_type='particle', | ||
| instance_id=pid).position[axis] | ||
| center_of_mass = center_of_mass / len(particle_id_list) | ||
| return center_of_mass | ||
| def determine_reservoir_concentrations(self, pH_res, c_salt_res, activity_coefficient_monovalent_pair, max_number_sc_runs=200): | ||
| """ | ||
| Determines ionic concentrations in the reservoir at fixed pH and salt concentration. | ||
|
|
||
| Args: | ||
| pH_res ('float'): | ||
| Target pH value in the reservoir. | ||
|
|
||
| c_salt_res ('pint.Quantity'): | ||
| Concentration of monovalent salt (e.g., NaCl) in the reservoir. | ||
|
|
||
| activity_coefficient_monovalent_pair ('callable'): | ||
| Function returning the activity coefficient of a monovalent ion pair | ||
| as a function of ionic strength: | ||
| 'gamma = activity_coefficient_monovalent_pair(I)'. | ||
|
|
||
| max_number_sc_runs ('int', optional): | ||
| Maximum number of self-consistent iterations allowed before | ||
| convergence is enforced. Defaults to 200. | ||
|
|
||
| Returns: | ||
| tuple: | ||
| (cH_res, cOH_res, cNa_res, cCl_res) | ||
| - cH_res ('pint.Quantity'): Concentration of H⁺ ions. | ||
| - cOH_res ('pint.Quantity'): Concentration of OH⁻ ions. | ||
| - cNa_res ('pint.Quantity'): Concentration of Na⁺ ions. | ||
| - cCl_res ('pint.Quantity'): Concentration of Cl⁻ ions. | ||
|
|
||
| Notess: | ||
| - The algorithm enforces electroneutrality in the reservoir. | ||
| - Water autodissociation is included via the equilibrium constant 'Kw'. | ||
| - Non-ideal effects enter through activity coefficients depending on | ||
| ionic strength. | ||
| - The implementation follows the self-consistent scheme described in | ||
| Landsgesell (PhD thesis, Sec. 5.3, doi:10.18419/opus-10831), adapted | ||
| from the original code (doi:10.18419/darus-2237). | ||
| """ | ||
| def determine_reservoir_concentrations_selfconsistently(cH_res, c_salt_res): | ||
| """ | ||
| Iteratively determines reservoir ion concentrations self-consistently. | ||
|
|
||
| Args: | ||
| cH_res ('pint.Quantity'): | ||
| Current estimate of the H⁺ concentration. | ||
| c_salt_res ('pint.Quantity'): | ||
| Concentration of monovalent salt in the reservoir. | ||
|
|
||
| Returns: | ||
| 'tuple': | ||
| (cH_res, cOH_res, cNa_res, cCl_res) | ||
| """ | ||
| # Initial ideal estimate | ||
| cOH_res = self.Kw / cH_res | ||
| if cOH_res >= cH_res: | ||
| cNa_res = c_salt_res + (cOH_res - cH_res) | ||
| cCl_res = c_salt_res | ||
| else: | ||
| cCl_res = c_salt_res + (cH_res - cOH_res) | ||
| cNa_res = c_salt_res | ||
| # Self-consistent iteration | ||
| for _ in range(max_number_sc_runs): | ||
| ionic_strength_res = 0.5 * (cNa_res + cCl_res + cOH_res + cH_res) | ||
| cOH_new = self.Kw / (cH_res * activity_coefficient_monovalent_pair(ionic_strength_res)) | ||
| if cOH_new >= cH_res: | ||
| cNa_new = c_salt_res + (cOH_new - cH_res) | ||
| cCl_new = c_salt_res | ||
| else: | ||
| cCl_new = c_salt_res + (cH_res - cOH_new) | ||
| cNa_new = c_salt_res | ||
| # Update values | ||
| cOH_res = cOH_new | ||
| cNa_res = cNa_new | ||
| cCl_res = cCl_new | ||
| return cH_res, cOH_res, cNa_res, cCl_res | ||
| # Initial guess for H+ concentration from target pH | ||
| cH_res = 10 ** (-pH_res) * self.units.mol / self.units.l | ||
| # First self-consistent solve | ||
| cH_res, cOH_res, cNa_res, cCl_res = (determine_reservoir_concentrations_selfconsistently(cH_res, | ||
| c_salt_res)) | ||
| ionic_strength_res = 0.5 * (cNa_res + cCl_res + cOH_res + cH_res) | ||
| determined_pH = -np.log10(cH_res.to("mol/L").magnitude* np.sqrt(activity_coefficient_monovalent_pair(ionic_strength_res))) | ||
| # Outer loop to enforce target pH | ||
| while abs(determined_pH - pH_res) > 1e-6: | ||
| if determined_pH > pH_res: | ||
| cH_res *= 1.005 | ||
| else: | ||
| cH_res /= 1.003 | ||
| cH_res, cOH_res, cNa_res, cCl_res = (determine_reservoir_concentrations_selfconsistently(cH_res, | ||
| c_salt_res)) | ||
| ionic_strength_res = 0.5 * (cNa_res + cCl_res + cOH_res + cH_res) | ||
| determined_pH = -np.log10(cH_res.to("mol/L").magnitude * np.sqrt(activity_coefficient_monovalent_pair(ionic_strength_res))) | ||
| return cH_res, cOH_res, cNa_res, cCl_res | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| from typing import Protocol,runtime_checkable | ||
|
|
||
| class EspressoParticleProtocol(Protocol): | ||
| """Class that emulates the estructure of the Espresso Particle class""" | ||
| def add(): | ||
| return | ||
| def by_id(): | ||
| return | ||
| class EspressoBondedInterProtocol(Protocol): | ||
| """Class that emulates the structure of the EspressoBondedInterProtocol""" | ||
| def add(): | ||
| return | ||
|
|
||
| @runtime_checkable | ||
| class EspressoSystemProtocol(Protocol): | ||
| """ Class that emulates the structure of the methods employed by Pymbe from the espressomd.System class | ||
| . The decorator @runtime_checkable allows to only check for the structure not the types""" | ||
| part: EspressoParticleProtocol | ||
| bonded_inter: EspressoBondedInterProtocol | ||
|
|
||
| @runtime_checkable | ||
| class LammpsProtocol(Protocol): | ||
| """ Class that emulates the structure of the methods employed by Pymbe from the Lammps class | ||
| . The decorator @runtime_checkable allows to only check for the structure not the types""" | ||
|
|
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit uneasy about pyMBE re-implementing a feature already provided by
@warnings.deprecated(). I understand that it's only available in Python 3.13 onward, but Python 3.12 is old. It's no longer receiving bugfixes, only security fixes, and in about 9 months it won't be supported by new packages in the NumPy ecosystem (NEP 29 drop table). Ubuntu 24.04 LTS is the last OS that still imposes Python 3.12, and a couple of HPC clusters are stuck with Python 3.11 and 3.12.We should discuss in the next meeting to which degree this is an issue for our users. Ubuntu 26.04 LTS is already available and the ICP plans to migrate to it in August. For HPC clusters where EESSI is available, Python 3.13 can be obtained from the 2025 stacks. On HPC clusters that don't provide EESSI, I build Python 3.14 from sources since older Python versions can be tricky to work with in conjunction with Cython and NumPy. Users of conda-like environments can install a new Python version with an extra command line option. I won't oppose this re-implementation, it's not a dealbreaker for me, but I think it's worth considering the maintenance aspects of re-implementing a functionality that is now widely available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I implemented this function so users now are warned that they have to move their usage of the function
setup_langevin_dynamics,relax_espresso_system,setup_electrostatic_interactions, etc. To be employed by the simulation_engine assimulation_engine.setup_langevin_dynamics,simulation_engine.relax_espresso_system,etc. In order that when they start using the new release version not all of their old code breaks due to these changes being implemented.Respect to upgrading pyMBE to python 3.13 we may find some troubles related to incompatibilities between the versions of the external python libraries, although maybe this is not a major issue, as the differences are between 3 minor versions .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pyMBE meeting discussion: keep this re-implementation for now, since it will be a couple of months until our community fully migrates to the newer Python version, but replace it with
@warnings.deprecated()from Python 3.13 before the next minor release of pyMBE.