From 93f8e93cb5b52a9a9accf3d7a9b73756774839bd Mon Sep 17 00:00:00 2001 From: jsd94 Date: Wed, 8 Apr 2026 21:21:13 +0200 Subject: [PATCH 01/75] Add engine factory and unfinished files for the espresso and lammps engines --- pyMBE/simulation_builder/base_classes.py | 17 ++++ pyMBE/simulation_builder/engine_factory.py | 12 +++ pyMBE/simulation_builder/espresso_engine.py | 101 ++++++++++++++++++++ pyMBE/simulation_builder/lammps_engine.py | 8 ++ 4 files changed, 138 insertions(+) create mode 100644 pyMBE/simulation_builder/base_classes.py create mode 100644 pyMBE/simulation_builder/engine_factory.py create mode 100644 pyMBE/simulation_builder/espresso_engine.py create mode 100644 pyMBE/simulation_builder/lammps_engine.py diff --git a/pyMBE/simulation_builder/base_classes.py b/pyMBE/simulation_builder/base_classes.py new file mode 100644 index 00000000..1245ffc5 --- /dev/null +++ b/pyMBE/simulation_builder/base_classes.py @@ -0,0 +1,17 @@ +from abc import ABC,abstractmethod + +class SimulationBuilder(ABC): + 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 save_molecule(self): + return \ No newline at end of file diff --git a/pyMBE/simulation_builder/engine_factory.py b/pyMBE/simulation_builder/engine_factory.py new file mode 100644 index 00000000..20d71b18 --- /dev/null +++ b/pyMBE/simulation_builder/engine_factory.py @@ -0,0 +1,12 @@ +from espresso_engine import EspressoSimulation +from lammps_engine import LammpsSimulation + +class EngineFactory: + @staticmethod + def get_simulation_engine(engine_name,box_l,db): + if engine_name=='espresso': + return EspressoSimulation(Box_L=box_l,db=db) + elif engine_name=='lammps': + return LammpsSimulation() + else: + raise ValueError('Only engines "espresso" and "lammps" have been implemented') \ No newline at end of file diff --git a/pyMBE/simulation_builder/espresso_engine.py b/pyMBE/simulation_builder/espresso_engine.py new file mode 100644 index 00000000..b37b96de --- /dev/null +++ b/pyMBE/simulation_builder/espresso_engine.py @@ -0,0 +1,101 @@ +from base_classes import SimulationBuilder +import espressomd + + + +class EspressoSimulation(SimulationBuilder): + def __init__(self,box_l,db): + self.db=db + self.box_l=box_l + self.espresso_system=espressomd.System(box_l = [self.box_l.to('reduced_length').magnitude]*3) + pass + + def _check_bond_inputs(self, bond_type, bond_parameters): + """ + Checks that the input bond parameters are valid within the current pyMBE implementation. + + Args: + bond_type ('str'): + label to identify the potential to model the bond. + + bond_parameters ('dict'): + parameters of the potential of the bond. + """ + valid_bond_types = ["harmonic", "FENE"] + if bond_type not in valid_bond_types: + raise NotImplementedError(f"Bond type '{bond_type}' currently not implemented in pyMBE, accepted types are {valid_bond_types}") + required_parameters = {"harmonic": ["r_0","k"], + "FENE": ["r_0","k","d_r_max"]} + for required_parameter in required_parameters[bond_type]: + if required_parameter not in bond_parameters.keys(): + raise ValueError(f"Missing required parameter {required_parameter} for {bond_type} bond") + + def _create_bond_instance(self, bond_type, bond_parameters): + """ + Creates an ESPResSo bond instance. + + Args: + bond_type ('str'): + label to identify the potential to model the bond. + + bond_parameters ('dict'): + parameters of the potential of the bond. + + Notes: + Currently, only HARMONIC and FENE bonds are supported. + + For a HARMONIC bond the dictionary must contain: + - k ('Pint.Quantity') : Magnitude of the bond. It should have units of energy/length**2 + using the 'pmb.units' UnitRegistry. + - r_0 ('Pint.Quantity') : Equilibrium bond length. It should have units of length using + the 'pmb.units' UnitRegistry. + + For a FENE bond the dictionary must additionally contain: + - d_r_max ('Pint.Quantity'): Maximal stretching length for FENE. It should have + units of length using the 'pmb.units' UnitRegistry. Default 'None'. + + Returns: + ('espressomd.interactions'): instance of an ESPResSo bond object + """ + + self._check_bond_inputs(bond_parameters=bond_parameters, + bond_type=bond_type) + if bond_type == 'harmonic': + bond_instance = espressomd.interactions.HarmonicBond(k = bond_parameters["k"].m_as("reduced_energy/reduced_length**2"), + r_0 = bond_parameters["r_0"].m_as("reduced_length")) + elif bond_type == 'FENE': + bond_instance = espressomd.interactions.FeneBond(k = bond_parameters["k"].m_as("reduced_energy/reduced_length**2"), + r_0 = bond_parameters["r_0"].m_as("reduced_length"), + d_r_max = bond_parameters["d_r_max"].m_as("reduced_length")) + return bond_instance + + def _get_bond_instance(self, bond_template, espresso_system): + """ + Retrieve or create a bond instance in an ESPResSo system for a given pair of particle names. + + Args: + bond_template ('BondTemplate'): + BondTemplate object from the pyMBE database. + espresso_system ('espressomd.system.System'): + An ESPResSo system object where the bond will be added or retrieved. + + Returns: + ('espressomd.interactions.BondedInteraction'): + The ESPResSo bond instance object. + + Notes: + When a new bond instance is created, it is not added to the ESPResSo system. + """ + if bond_template.name in self.db.espresso_bond_instances.keys(): + bond_inst = self.db.espresso_bond_instances[bond_template.name] + else: + # Create an instance of the bond + bond_inst = self._create_bond_instance(bond_type=bond_template.bond_type, + bond_parameters=bond_template.get_parameters(self.units)) + self.db.espresso_bond_instances[bond_template.name]= bond_inst + espresso_system.bonded_inter.add(bond_inst) + return bond_inst + def get_box_side_length(self): + return self.Box_L + def save_molecule(self): + return diff --git a/pyMBE/simulation_builder/lammps_engine.py b/pyMBE/simulation_builder/lammps_engine.py new file mode 100644 index 00000000..eebf9aef --- /dev/null +++ b/pyMBE/simulation_builder/lammps_engine.py @@ -0,0 +1,8 @@ +from base_classes import SimulationBuilder + + +class LammpsSimulation(SimulationBuilder): + def __init__(self): + pass + def save_molecule(self): + return \ No newline at end of file From d98eec9cde71e0132acba4362d20fe540292f2ea Mon Sep 17 00:00:00 2001 From: jsd94 Date: Wed, 8 Apr 2026 21:22:14 +0200 Subject: [PATCH 02/75] Add engine factory to init method to instantiate the wanted engine class when the pymbe class is instantiated --- pyMBE/pyMBE.py | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/pyMBE/pyMBE.py b/pyMBE/pyMBE.py index f2bd213b..ba475d6c 100644 --- a/pyMBE/pyMBE.py +++ b/pyMBE/pyMBE.py @@ -46,6 +46,7 @@ from pyMBE.storage.instances.protein import ProteinInstance from pyMBE.storage.instances.bond import BondInstance from pyMBE.storage.instances.hydrogel import HydrogelInstance +from pyMBE.simulation_builder.engine_factory import EngineFactory ## Reactions from pyMBE.storage.reactions.reaction import Reaction, ReactionParticipant # Utilities @@ -88,7 +89,7 @@ class pymbe_library(): Root path to the pyMBE package resources. """ - def __init__(self, seed, temperature=None, unit_length=None, unit_charge=None, Kw=None): + def __init__(self, seed, temperature=None, unit_length=None, unit_charge=None, Kw=None,simulation_engine='espresso'): """ Initializes the pyMBE library. @@ -124,6 +125,7 @@ def __init__(self, seed, temperature=None, unit_length=None, unit_charge=None, K Kw=Kw) self.db = Manager(units=self.units) + self.simulation_engine=EngineFactory.get_simulation_engine(engine_name=simulation_engine,db=self.db) ### Add simulation factory. self.lattice_builder = None self.root = importlib.resources.files(__package__) @@ -220,7 +222,7 @@ def _create_espresso_bond_instance(self, bond_type, bond_parameters): bond_instance = interactions.HarmonicBond(k = bond_parameters["k"].m_as("reduced_energy/reduced_length**2"), r_0 = bond_parameters["r_0"].m_as("reduced_length")) elif bond_type == 'FENE': - bond_instance = interactions.FeneBond(k = bond_parameters["k"].m_as("reduced_energy/reduced_length**2"), + bond_instance = interactions.FeneBond(k = bond_parameters["k"].m_as("reduced_energy/reduced_length**2"), r_0 = bond_parameters["r_0"].m_as("reduced_length"), d_r_max = bond_parameters["d_r_max"].m_as("reduced_length")) return bond_instance @@ -1026,6 +1028,8 @@ def create_molecule(self, name, number_of_molecules, espresso_system, list_of_fi if list_of_first_residue_positions is None: central_bead_pos = None else: + ### This seems like a bug + ### the variable central bead pos gets assigned the same value for the lengthh of list_of_first_residue_positions for item in list_of_first_residue_positions: central_bead_pos = [np.array(list_of_first_residue_positions[pos_index])] @@ -1046,7 +1050,9 @@ def create_molecule(self, name, number_of_molecules, espresso_system, list_of_fi prev_central_bead_id = particle_ids_in_residue[0] prev_central_bead_name = self.db.get_instance(pmb_type="particle", instance_id=prev_central_bead_id).name - prev_central_bead_pos = espresso_system.part.by_id(prev_central_bead_id).pos + prev_central_bead_pos = self.db.get_instance(pmb_type="particle", + instance_id=prev_central_bead_id).particle_position + # prev_central_bead_pos = espresso_system.part.by_id(prev_central_bead_id).pos first_residue = False else: @@ -1145,13 +1151,16 @@ def create_particle(self, name, espresso_system, number_of_particles, position=N particle_id = self.db._propose_instance_id(pmb_type="particle") created_pid_list.append(particle_id) - kwargs = dict(id=particle_id, pos=particle_position, type=es_type, q=z) - if fix: - kwargs["fix"] = 3 * [fix] - espresso_system.part.add(**kwargs) + # kwargs = dict(id=particle_id, pos=particle_position, type=es_type, q=z) + # if fix: + # kwargs["fix"] = 3 * [fix] ### Is the fix attribute something concrete from espresso_system? + # espresso_system.part.add(**kwargs) part_inst = ParticleInstance(name=name, particle_id=particle_id, - initial_state=part_state.name) + initial_state=part_state.name, + particle_position=particle_position, + particle_label=es_type, + particle_charge=z) self.db._register_instance(part_inst) return created_pid_list @@ -1286,7 +1295,10 @@ def create_residue(self, name, espresso_system, central_bead_position=None,use_d position=central_bead_position, number_of_particles = 1)[0] - central_bead_position=espresso_system.part.by_id(central_bead_id).pos + central_bead_position = self.db.get_instance(pmb_type="particle", + instance_id=central_bead_id).particle_position + # # central_bead_position=espresso_system.part.by_id(central_bead_id).pos + # Assigns residue_id to the central_bead particle created. self.db._update_instance(pmb_type="particle", instance_id=central_bead_id, From ec47aaa19750219e899c8d96b7a824c886206ba4 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Wed, 8 Apr 2026 21:23:07 +0200 Subject: [PATCH 03/75] Add particle_charge,particle_label,particle_position and particle_fix to ParticleInstance class --- pyMBE/storage/instances/particle.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pyMBE/storage/instances/particle.py b/pyMBE/storage/instances/particle.py index 33ce56e5..6ed9aeb3 100644 --- a/pyMBE/storage/instances/particle.py +++ b/pyMBE/storage/instances/particle.py @@ -17,7 +17,7 @@ # along with this program. If not, see . # -from typing import Literal, Optional +from typing import Literal, Optional,List from pydantic import validator from ..base_type import PMBBaseModel @@ -56,6 +56,10 @@ class ParticleInstance(PMBBaseModel): name: str particle_id: int initial_state: str + particle_charge: int + particle_label: str + particle_position: List[float] + particle_fix: Optional[List[bool]]=None residue_id: Optional[int] = None molecule_id: Optional[int] = None assembly_id: Optional[int] = None From 7985bc7863e25e6887d74e9b35a29b611e662c11 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Wed, 8 Apr 2026 21:24:33 +0200 Subject: [PATCH 04/75] Use attributes inst.particle_label, inst.particle_charge, inst.particle_position,inst._particle_fix to _get_instances_df method --- pyMBE/storage/manager.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pyMBE/storage/manager.py b/pyMBE/storage/manager.py index f4b3f404..041e4538 100644 --- a/pyMBE/storage/manager.py +++ b/pyMBE/storage/manager.py @@ -256,6 +256,10 @@ def _get_instances_df(self, pmb_type): rows.append({"pmb_type": pmb_type, "name": inst.name, "particle_id": inst.particle_id, + "particle_label": inst.particle_label, + "particle_charge": inst.particle_charge, + "particle_position":inst.particle_position, + "particle_fix":inst.particle_fix, "initial_state": inst.initial_state, "residue_id": int(inst.residue_id) if inst.residue_id is not None else pd.NA, "molecule_id": int(inst.molecule_id) if inst.molecule_id is not None else pd.NA, From 731e325537fdaae2b90b314f8c689dfa6ab30de4 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 9 Apr 2026 14:59:29 +0200 Subject: [PATCH 05/75] Add tutorial --- tutorials/pyMBE_tutorial.ipynb | 4713 ++++++++++++++++++++++++-------- 1 file changed, 3514 insertions(+), 1199 deletions(-) diff --git a/tutorials/pyMBE_tutorial.ipynb b/tutorials/pyMBE_tutorial.ipynb index 82b43d05..d35dc2ea 100644 --- a/tutorials/pyMBE_tutorial.ipynb +++ b/tutorials/pyMBE_tutorial.ipynb @@ -65,6 +65,7 @@ "metadata": {}, "outputs": [], "source": [ + "import pyMBE\n", "pmb = pyMBE.pymbe_library(seed=42)" ] }, @@ -103,6 +104,27 @@ "print(reduced_unit_set)" ] }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Current set of reduced units:\n", + "0.355 nanometer = 1 reduced_length\n", + "4.1164e-21 joule = 1 reduced_energy\n", + "1.6022e-19 coulomb = 1 reduced_charge\n", + "Temperature: 298.15 kelvin\n" + ] + } + ], + "source": [ + "print(reduced_unit_set)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -131,6 +153,28 @@ " #, temperature=300*pmb.units.K)" ] }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Current set of reduced units:\n", + "0.5 nanometer = 1 reduced_length\n", + "4.1164e-21 joule = 1 reduced_energy\n", + "8.0109e-19 coulomb = 1 reduced_charge\n", + "Temperature: 298.15 kelvin\n" + ] + } + ], + "source": [ + "reduced_unit_set = pmb.get_reduced_units()\n", + "print(reduced_unit_set)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -154,7 +198,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "The side of the simulation box is 7.5 nanometer = 15.0 reduced_length\n" + "The side of the simulation box is 7.5 nanometer = 21.126760563380284 reduced_length\n" ] } ], @@ -182,7 +226,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -202,7 +246,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -241,8 +285,8 @@ " particle\n", " Na\n", " 0.35 nanometer\n", - " 25.69257912108585 millielectron_volt\n", - " 0.5612310241546865 nanometer\n", + " 25.692579121085853 millielectron_volt\n", + " 0.5612310241546864 nanometer\n", " 0.0 nanometer\n", " Na\n", " \n", @@ -251,14 +295,14 @@ "" ], "text/plain": [ - " pmb_type name sigma epsilon \\\n", - "0 particle Na 0.35 nanometer 25.69257912108585 millielectron_volt \n", + " pmb_type name sigma epsilon \\\n", + "0 particle Na 0.35 nanometer 25.692579121085853 millielectron_volt \n", "\n", " cutoff offset initial_state \n", - "0 0.5612310241546865 nanometer 0.0 nanometer Na " + "0 0.5612310241546864 nanometer 0.0 nanometer Na " ] }, - "execution_count": 7, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -276,7 +320,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -285,7 +329,7 @@ "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]" ] }, - "execution_count": 8, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -306,7 +350,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -590,7 +634,7 @@ "19 " ] }, - "execution_count": 9, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -608,9 +652,21 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'espresso_system' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[4], line 24\u001b[0m\n\u001b[1;32m 22\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[1;32m 23\u001b[0m picture_name \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mcation_system.png\u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[0;32m---> 24\u001b[0m create_snapshot_of_espresso_system(espresso_system \u001b[38;5;241m=\u001b[39m \u001b[43mespresso_system\u001b[49m, \n\u001b[1;32m 25\u001b[0m filename \u001b[38;5;241m=\u001b[39m picture_name)\n\u001b[1;32m 26\u001b[0m img \u001b[38;5;241m=\u001b[39m Image\u001b[38;5;241m.\u001b[39mopen(picture_name)\n\u001b[1;32m 27\u001b[0m img\u001b[38;5;241m.\u001b[39mshow()\n", + "\u001b[0;31mNameError\u001b[0m: name 'espresso_system' is not defined" + ] + } + ], "source": [ "# Only necessary to produce the pictures used in this tutorial\n", "from PIL import Image\n", @@ -650,9 +706,21 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 43, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'cation_name' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[43], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# First search for the ids of the particles to delete\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m particle_id_map \u001b[38;5;241m=\u001b[39m pmb\u001b[38;5;241m.\u001b[39mget_particle_id_map(object_name\u001b[38;5;241m=\u001b[39m\u001b[43mcation_name\u001b[49m)\n\u001b[1;32m 3\u001b[0m \u001b[38;5;66;03m# This will delete all particles that we created before\u001b[39;00m\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m pid \u001b[38;5;129;01min\u001b[39;00m particle_id_map[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mall\u001b[39m\u001b[38;5;124m\"\u001b[39m]:\n", + "\u001b[0;31mNameError\u001b[0m: name 'cation_name' is not defined" + ] + } + ], "source": [ "# First search for the ids of the particles to delete\n", "particle_id_map = pmb.get_particle_id_map(object_name=cation_name)\n", @@ -672,7 +740,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -709,7 +777,7 @@ "Index: []" ] }, - "execution_count": 12, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -744,7 +812,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 39, "metadata": {}, "outputs": [], "source": [ @@ -777,7 +845,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 49, "metadata": {}, "outputs": [], "source": [ @@ -797,7 +865,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 50, "metadata": {}, "outputs": [ { @@ -844,13 +912,13 @@ "0 residue PDha_mon BB-PDha [COOH-PDha, NH3-PDha]" ] }, - "execution_count": 15, + "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "pmb.get_templates_df(pmb_type = 'residue')" + "pmb.get_templates_df(pmb_type='residue')" ] }, { @@ -862,7 +930,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 55, "metadata": {}, "outputs": [], "source": [ @@ -889,16 +957,9 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 56, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/bin/eog: symbol lookup error: /snap/core20/current/lib/x86_64-linux-gnu/libpthread.so.0: undefined symbol: __libc_pthread_init, version GLIBC_PRIVATE\n" - ] - }, { "data": { "text/html": [ @@ -936,7 +997,7 @@ " harmonic\n", " BB-PDha\n", " BB-PDha\n", - " {'r_0': 0.4 nanometer, 'k': 41108.12659373736 ...\n", + " {'r_0': 0.4 nanometer, 'k': 41108.126593737354...\n", " \n", " \n", " 1\n", @@ -945,7 +1006,7 @@ " harmonic\n", " BB-PDha\n", " COOH-PDha\n", - " {'r_0': 0.4 nanometer, 'k': 41108.12659373736 ...\n", + " {'r_0': 0.4 nanometer, 'k': 41108.126593737354...\n", " \n", " \n", " 2\n", @@ -954,7 +1015,7 @@ " harmonic\n", " BB-PDha\n", " NH3-PDha\n", - " {'r_0': 0.4 nanometer, 'k': 41108.12659373736 ...\n", + " {'r_0': 0.4 nanometer, 'k': 41108.126593737354...\n", " \n", " \n", "\n", @@ -967,12 +1028,12 @@ "2 bond BB-PDha-NH3-PDha harmonic BB-PDha NH3-PDha \n", "\n", " parameters \n", - "0 {'r_0': 0.4 nanometer, 'k': 41108.12659373736 ... \n", - "1 {'r_0': 0.4 nanometer, 'k': 41108.12659373736 ... \n", - "2 {'r_0': 0.4 nanometer, 'k': 41108.12659373736 ... " + "0 {'r_0': 0.4 nanometer, 'k': 41108.126593737354... \n", + "1 {'r_0': 0.4 nanometer, 'k': 41108.126593737354... \n", + "2 {'r_0': 0.4 nanometer, 'k': 41108.126593737354... " ] }, - "execution_count": 17, + "execution_count": 56, "metadata": {}, "output_type": "execute_result" } @@ -997,7 +1058,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 57, "metadata": {}, "outputs": [], "source": [ @@ -1017,7 +1078,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 58, "metadata": {}, "outputs": [ { @@ -1062,7 +1123,7 @@ "0 molecule PDha [PDha_mon, PDha_mon, PDha_mon, PDha_mon, PDha_..." ] }, - "execution_count": 19, + "execution_count": 58, "metadata": {}, "output_type": "execute_result" } @@ -1080,7 +1141,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 59, "metadata": {}, "outputs": [], "source": [ @@ -1101,7 +1162,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 60, "metadata": {}, "outputs": [ { @@ -1505,161 +1566,20 @@ "29 " ] }, - "execution_count": 21, + "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Check particle instances\n", - "pmb.get_instances_df(pmb_type = 'particle')" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenameresidue_idmolecule_idassembly_id
0residuePDha_mon00<NA>
1residuePDha_mon10<NA>
2residuePDha_mon20<NA>
3residuePDha_mon30<NA>
4residuePDha_mon40<NA>
5residuePDha_mon50<NA>
6residuePDha_mon60<NA>
7residuePDha_mon70<NA>
8residuePDha_mon80<NA>
9residuePDha_mon90<NA>
\n", - "
" - ], - "text/plain": [ - " pmb_type name residue_id molecule_id assembly_id\n", - "0 residue PDha_mon 0 0 \n", - "1 residue PDha_mon 1 0 \n", - "2 residue PDha_mon 2 0 \n", - "3 residue PDha_mon 3 0 \n", - "4 residue PDha_mon 4 0 \n", - "5 residue PDha_mon 5 0 \n", - "6 residue PDha_mon 6 0 \n", - "7 residue PDha_mon 7 0 \n", - "8 residue PDha_mon 8 0 \n", - "9 residue PDha_mon 9 0 " - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Check residue instances\n", - "pmb.get_instances_df(pmb_type = 'residue')" + "pmb.get_instances_df(pmb_type = 'particle')\n", + "\n" ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 61, "metadata": {}, "outputs": [ { @@ -1960,19 +1880,18 @@ "28 bond BB-PDha-BB-PDha 28 24 27" ] }, - "execution_count": 23, + "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# Check bond instances\n", - "pmb.get_instances_df(pmb_type = 'bond')" + "pmb.get_instances_df(pmb_type='bond')" ] }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 47, "metadata": {}, "outputs": [ { @@ -1996,69 +1915,32 @@ " \n", " \n", " \n", - " pmb_type\n", - " name\n", - " molecule_id\n", - " assembly_id\n", " \n", " \n", " \n", - " \n", - " 0\n", - " molecule\n", - " PDha\n", - " 0\n", - " <NA>\n", - " \n", " \n", "\n", "" ], "text/plain": [ - " pmb_type name molecule_id assembly_id\n", - "0 molecule PDha 0 " + "Empty DataFrame\n", + "Columns: []\n", + "Index: []" ] }, - "execution_count": 24, + "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# Check molecule instances\n", - "pmb.get_instances_df(pmb_type = 'molecule')" + "# Check residue instances\n", + "pmb.get_instances_df(pmb_type = 'residue')" ] }, { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, let us see what we have created..." - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [], - "source": [ - "picture_name = 'PDha_system.png'\n", - "create_snapshot_of_espresso_system(espresso_system = espresso_system, \n", - " filename = picture_name)\n", - "img = Image.open(picture_name)\n", - "img.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Delete the particles and check that there are no particle instances in the pyMBE database" - ] - }, - { - "cell_type": "code", - "execution_count": 26, + "cell_type": "code", + "execution_count": null, "metadata": {}, "outputs": [ { @@ -2082,783 +1964,296 @@ " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - "\n", - "" - ], - "text/plain": [ - "Empty DataFrame\n", - "Columns: []\n", - "Index: []" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pmb.delete_instances_in_system(instance_id=molecule_ids[0],\n", - " pmb_type=\"molecule\", \n", - " espresso_system = espresso_system)\n", - "# Check particle instances\n", - "pmb.get_instances_df(pmb_type = 'particle')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How to create complex polymers " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "pyMBE can also be used to setup models that requiere more complex side chains, i.e. with more than one bead per side chain. One example of these complex molecules is the poly(N,N-diallylglutamate) (PDAGA), whose structure is depicted in the figure below. Following the logic of the previous example, one would construct PDAGA with pyMBE by defining a `residue` with a `central_bead` for the polymer backbone (grey) and a `side_chain` attached to it. In this case, the group in the side chain of the PDAGA monomer has a complex structure. This group can be coarse-grained by defining another `residue` composed by a new `central_bead` which represents the cyclic amine group (blue) and two `side_chains` ($\\alpha$ and $\\beta$ carboxyl) attached to it (red and orange).\n", - "\n", - "" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "One can start by defining templates for each different bead of the PDAGA." - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [], - "source": [ - "PDAGA_backbone_bead = 'BB-PDAGA'\n", - "PDAGA_cyclic_amine_bead = 'NH3-PDAGA'\n", - "PDAGA_alpha_carboxyl_bead = 'aCOOH-PDAGA'\n", - "PDAGA_beta_carboxyl_bead = 'bCOOH-PDAGA'\n", - "\n", - "pmb.define_particle(name = PDAGA_backbone_bead, \n", - " z = 0,\n", - " sigma = 0.4*pmb.units.nm, \n", - " epsilon = 1*pmb.units('reduced_energy'))\n", - "\n", - "pmb.define_particle(name = PDAGA_cyclic_amine_bead, \n", - " z = 0, \n", - " sigma = 0.3*pmb.units.nm, \n", - " epsilon = 1*pmb.units('reduced_energy'))\n", - "\n", - "pmb.define_particle(name = PDAGA_alpha_carboxyl_bead, \n", - " z = 0, \n", - " sigma = 0.2*pmb.units.nm, \n", - " epsilon = 1*pmb.units('reduced_energy'))\n", - "\n", - "pmb.define_particle(name = PDAGA_beta_carboxyl_bead, \n", - " z = 0, \n", - " sigma = 0.4*pmb.units.nm, \n", - " epsilon = 1*pmb.units('reduced_energy'))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The next step is to define the two different residue templates: \n", - "1. The side chain: two carboxyl beads attached to the cyclic amine bead." - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [], - "source": [ - "PDAGA_side_chain_residue = 'PDAGA_side_chain_residue'\n", - "\n", - "pmb.define_residue (name = PDAGA_side_chain_residue,\n", - " central_bead = PDAGA_cyclic_amine_bead,\n", - " side_chains = [PDAGA_alpha_carboxyl_bead, PDAGA_beta_carboxyl_bead])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "2. Each monomeric unit of the PDAGA: the side chain defined above attached to the backbone." - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [], - "source": [ - "PDAGA_monomer_residue = 'PDAGA_monomer_residue'\n", - "pmb.define_residue( name = PDAGA_monomer_residue,\n", - " central_bead = PDAGA_backbone_bead,\n", - " side_chains = [PDAGA_side_chain_residue])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Then, we need to define bond templates in a similar way as for the case of the simple polymer." - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [], - "source": [ - "bond_type = 'harmonic'\n", - "generic_bond_lenght=0.4 * pmb.units.nm\n", - "generic_harmonic_constant = 400 * pmb.units('reduced_energy / reduced_length**2')\n", - "\n", - "harmonic_bond = {'r_0' : generic_bond_lenght,\n", - " 'k' : generic_harmonic_constant,\n", - " }\n", - "\n", - "pmb.define_bond(bond_type = bond_type,\n", - " bond_parameters = harmonic_bond,\n", - " particle_pairs = [[PDAGA_backbone_bead, PDAGA_backbone_bead],\n", - " [PDAGA_backbone_bead, PDAGA_cyclic_amine_bead],\n", - " [PDAGA_alpha_carboxyl_bead, PDAGA_cyclic_amine_bead],\n", - " [PDAGA_beta_carboxyl_bead, PDAGA_cyclic_amine_bead]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, let us define an octamer of PDAGA." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/bin/eog: symbol lookup error: /snap/core20/current/lib/x86_64-linux-gnu/libpthread.so.0: undefined symbol: __libc_pthread_init, version GLIBC_PRIVATE\n" - ] - } - ], - "source": [ - "PDAGA_polymer = 'PDAGA'\n", - "N_monomers = 8\n", - "\n", - "pmb.define_molecule(name = PDAGA_polymer,\n", - " residue_list = [PDAGA_monomer_residue]*N_monomers)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, we are able to create a PDAGA polymer into the ESPResSo system." - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [], - "source": [ - "N_polymers = 1\n", - "\n", - "mol_ids = pmb.create_molecule(name = PDAGA_polymer,\n", - " number_of_molecules= N_polymers,\n", - " espresso_system = espresso_system,\n", - " list_of_first_residue_positions = [[Box_L.to('reduced_length').magnitude/2]*3])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, let us see our PDAGA molecule." - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [], - "source": [ - "picture_name = 'PDAGA_system.png'\n", - "create_snapshot_of_espresso_system(espresso_system = espresso_system, \n", - " filename = picture_name)\n", - "img = Image.open(picture_name)\n", - "img.show()\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Delete the particles and check that the pyMBE database is empty." - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
\n", - "
" - ], - "text/plain": [ - "Empty DataFrame\n", - "Columns: []\n", - "Index: []" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "\n", - "for mol_id in mol_ids:\n", - " pmb.delete_instances_in_system(instance_id=mol_id,\n", - " pmb_type=\"molecule\",\n", - " espresso_system=espresso_system)\n", - "pmb.get_instances_df(pmb_type = 'particle')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How to create di-block copolymers " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In turn, the residues previously defined to build the PDAGA and PDha molecules can be used to build more complex polymers such as a di-block PDha-PDAGA copolymer, as shown in the picture below\n", - "\n", - "" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Define the bond template between the backbone particle of PDha and the backbone particle of PDAGA" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "pmb.define_bond(bond_type = bond_type,\n", - " bond_parameters = harmonic_bond,\n", - " particle_pairs = [[PDha_backbone_bead, PDAGA_backbone_bead]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Define a molecule template for the di-block polymer molecule using Python list comprehension methods" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [], - "source": [ - "N_monomers_PDha = 4\n", - "N_monomers_PDAGA = 4\n", - "diblock_polymer = 'diblock'\n", - "\n", - "pmb.define_molecule(name = diblock_polymer,\n", - " residue_list = [PDha_residue]*N_monomers_PDha+[PDAGA_monomer_residue]*N_monomers_PDAGA)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Creating the di-block polymer into the ESPResSo system" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/bin/eog: symbol lookup error: /snap/core20/current/lib/x86_64-linux-gnu/libpthread.so.0: undefined symbol: __libc_pthread_init, version GLIBC_PRIVATE\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", " \n", - " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", " \n", " \n", "
pmb_typenameparticle_idinitial_stateresidue_idmolecule_idassembly_idpmb_typenamebond_idparticle_id1particle_id2
0particleBB-PDha0BB-PDhabondBB-PDha-COOH-PDha00<NA>1
1particleCOOH-PDhabondBB-PDha-NH3-PDha1COOH-PDha00<NA>2
2particleNH3-PDhabondBB-PDha-COOH-PDha2NH3-PDha00<NA>34
3particleBB-PDhabondBB-PDha-NH3-PDha3BB-PDha10<NA>35
4particleCOOH-PDhabondBB-PDha-BB-PDha4COOH-PDha10<NA>3
5particleNH3-PDhabondBB-PDha-COOH-PDha5NH3-PDha10<NA>67
6particleBB-PDhabondBB-PDha-NH3-PDha6BB-PDha20<NA>68
7particleCOOH-PDhabondBB-PDha-BB-PDha7COOH-PDha20<NA>36
8particleNH3-PDhabondBB-PDha-COOH-PDha8NH3-PDha20<NA>910
9particleBB-PDhabondBB-PDha-NH3-PDha9BB-PDha30<NA>911
10particleCOOH-PDhabondBB-PDha-BB-PDha10COOH-PDha30<NA>69
11particleNH3-PDha11NH3-PDha30<NA>bondBB-PDha-COOH-PDha111213
12particleBB-PDAGAbondBB-PDha-NH3-PDha12BB-PDAGA40<NA>1214
13particleNH3-PDAGAbondBB-PDha-BB-PDha13NH3-PDAGA40<NA>912
14particleaCOOH-PDAGAbondBB-PDha-COOH-PDha14aCOOH-PDAGA40<NA>1516
15particlebCOOH-PDAGAbondBB-PDha-NH3-PDha15bCOOH-PDAGA40<NA>1517
16particleBB-PDAGAbondBB-PDha-BB-PDha16BB-PDAGA50<NA>1215
17particleNH3-PDAGAbondBB-PDha-COOH-PDha17NH3-PDAGA50<NA>1819
18particleaCOOH-PDAGAbondBB-PDha-NH3-PDha18aCOOH-PDAGA50<NA>1820
19particlebCOOH-PDAGAbondBB-PDha-BB-PDha19bCOOH-PDAGA50<NA>1518
20particleBB-PDAGAbondBB-PDha-COOH-PDha20BB-PDAGA60<NA>2122
21particleNH3-PDAGAbondBB-PDha-NH3-PDha21NH3-PDAGA60<NA>2123
22particleaCOOH-PDAGAbondBB-PDha-BB-PDha22aCOOH-PDAGA60<NA>1821
23particlebCOOH-PDAGAbondBB-PDha-COOH-PDha23bCOOH-PDAGA60<NA>2425
24particleBB-PDAGAbondBB-PDha-NH3-PDha24BB-PDAGA70<NA>2426
25particleNH3-PDAGAbondBB-PDha-BB-PDha25NH3-PDAGA70<NA>2124
26particleaCOOH-PDAGAbondBB-PDha-COOH-PDha26aCOOH-PDAGA70<NA>2728
27particlebCOOH-PDAGAbondBB-PDha-NH3-PDha272729
28bondBB-PDha-BB-PDha282427bCOOH-PDAGA70<NA>
\n", "
" ], "text/plain": [ - " pmb_type name particle_id initial_state residue_id molecule_id \\\n", - "0 particle BB-PDha 0 BB-PDha 0 0 \n", - "1 particle COOH-PDha 1 COOH-PDha 0 0 \n", - "2 particle NH3-PDha 2 NH3-PDha 0 0 \n", - "3 particle BB-PDha 3 BB-PDha 1 0 \n", - "4 particle COOH-PDha 4 COOH-PDha 1 0 \n", - "5 particle NH3-PDha 5 NH3-PDha 1 0 \n", - "6 particle BB-PDha 6 BB-PDha 2 0 \n", - "7 particle COOH-PDha 7 COOH-PDha 2 0 \n", - "8 particle NH3-PDha 8 NH3-PDha 2 0 \n", - "9 particle BB-PDha 9 BB-PDha 3 0 \n", - "10 particle COOH-PDha 10 COOH-PDha 3 0 \n", - "11 particle NH3-PDha 11 NH3-PDha 3 0 \n", - "12 particle BB-PDAGA 12 BB-PDAGA 4 0 \n", - "13 particle NH3-PDAGA 13 NH3-PDAGA 4 0 \n", - "14 particle aCOOH-PDAGA 14 aCOOH-PDAGA 4 0 \n", - "15 particle bCOOH-PDAGA 15 bCOOH-PDAGA 4 0 \n", - "16 particle BB-PDAGA 16 BB-PDAGA 5 0 \n", - "17 particle NH3-PDAGA 17 NH3-PDAGA 5 0 \n", - "18 particle aCOOH-PDAGA 18 aCOOH-PDAGA 5 0 \n", - "19 particle bCOOH-PDAGA 19 bCOOH-PDAGA 5 0 \n", - "20 particle BB-PDAGA 20 BB-PDAGA 6 0 \n", - "21 particle NH3-PDAGA 21 NH3-PDAGA 6 0 \n", - "22 particle aCOOH-PDAGA 22 aCOOH-PDAGA 6 0 \n", - "23 particle bCOOH-PDAGA 23 bCOOH-PDAGA 6 0 \n", - "24 particle BB-PDAGA 24 BB-PDAGA 7 0 \n", - "25 particle NH3-PDAGA 25 NH3-PDAGA 7 0 \n", - "26 particle aCOOH-PDAGA 26 aCOOH-PDAGA 7 0 \n", - "27 particle bCOOH-PDAGA 27 bCOOH-PDAGA 7 0 \n", - "\n", - " assembly_id \n", - "0 \n", - "1 \n", - "2 \n", - "3 \n", - "4 \n", - "5 \n", - "6 \n", - "7 \n", - "8 \n", - "9 \n", - "10 \n", - "11 \n", - "12 \n", - "13 \n", - "14 \n", - "15 \n", - "16 \n", - "17 \n", - "18 \n", - "19 \n", - "20 \n", - "21 \n", - "22 \n", - "23 \n", - "24 \n", - "25 \n", - "26 \n", - "27 " - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "N_polymers = 1\n", - "\n", - "mol_ids = pmb.create_molecule(name = diblock_polymer,\n", - " number_of_molecules= N_polymers,\n", - " espresso_system = espresso_system,\n", - " list_of_first_residue_positions = [[Box_L.to('reduced_length').magnitude/2]*3]) \n", - "# See the particle instances you have created\n", - "pmb.get_instances_df(pmb_type=\"particle\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, let us see our di-block PDha-PDAGA molecule." - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [], - "source": [ - "picture_name = 'diblock_system.png'\n", - "create_snapshot_of_espresso_system(espresso_system = espresso_system, \n", - " filename = picture_name)\n", - "img = Image.open(picture_name)\n", - "img.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, + " pmb_type name bond_id particle_id1 particle_id2\n", + "0 bond BB-PDha-COOH-PDha 0 0 1\n", + "1 bond BB-PDha-NH3-PDha 1 0 2\n", + "2 bond BB-PDha-COOH-PDha 2 3 4\n", + "3 bond BB-PDha-NH3-PDha 3 3 5\n", + "4 bond BB-PDha-BB-PDha 4 0 3\n", + "5 bond BB-PDha-COOH-PDha 5 6 7\n", + "6 bond BB-PDha-NH3-PDha 6 6 8\n", + "7 bond BB-PDha-BB-PDha 7 3 6\n", + "8 bond BB-PDha-COOH-PDha 8 9 10\n", + "9 bond BB-PDha-NH3-PDha 9 9 11\n", + "10 bond BB-PDha-BB-PDha 10 6 9\n", + "11 bond BB-PDha-COOH-PDha 11 12 13\n", + "12 bond BB-PDha-NH3-PDha 12 12 14\n", + "13 bond BB-PDha-BB-PDha 13 9 12\n", + "14 bond BB-PDha-COOH-PDha 14 15 16\n", + "15 bond BB-PDha-NH3-PDha 15 15 17\n", + "16 bond BB-PDha-BB-PDha 16 12 15\n", + "17 bond BB-PDha-COOH-PDha 17 18 19\n", + "18 bond BB-PDha-NH3-PDha 18 18 20\n", + "19 bond BB-PDha-BB-PDha 19 15 18\n", + "20 bond BB-PDha-COOH-PDha 20 21 22\n", + "21 bond BB-PDha-NH3-PDha 21 21 23\n", + "22 bond BB-PDha-BB-PDha 22 18 21\n", + "23 bond BB-PDha-COOH-PDha 23 24 25\n", + "24 bond BB-PDha-NH3-PDha 24 24 26\n", + "25 bond BB-PDha-BB-PDha 25 21 24\n", + "26 bond BB-PDha-COOH-PDha 26 27 28\n", + "27 bond BB-PDha-NH3-PDha 27 27 29\n", + "28 bond BB-PDha-BB-PDha 28 24 27" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "Delete the particles and check that our df is empty." + "# Check bond instances\n", + "pmb.get_instances_df(pmb_type = 'bond')" ] }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 60, "metadata": {}, "outputs": [ { @@ -2895,59 +2290,41 @@ "Index: []" ] }, - "execution_count": 39, + "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "for mol_id in mol_ids:\n", - " pmb.delete_instances_in_system(instance_id=0, \n", - " pmb_type=\"molecule\",\n", - " espresso_system = espresso_system)\n", - "pmb.get_instances_df(pmb_type=\"particle\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Practice by creating a custom polyampholyte chain " + "# Check molecule instances\n", + "pmb.get_instances_df(pmb_type = 'molecule')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Polyampholytes are polymers containing both acidic and basic groups on the same molecule, one example of a branched polyampholyte is depicted in the figure below.\n", - "\n", - "" + "Now, let us see what we have created..." ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ - "We will create the polyampholyte chain in the figure, starting by defining two different residues, 'Res_1' and 'Res_2'. The polyampholyte chain is then defined by following residue_list:\n", - "\n", - "residue_list = 2*[\"Res_1\"] + [\"Res_2\"] + 2*[\"Res_1\"] + 2*[\"Res_2\"]\n", - "\n", - "### Tasks to do:\n", - "\n", - "1. Define particle templates for each different bead in the residues using \"pmb.define_particle\". There are 3 different particles, an inert particle, an acidic particle with pKa = 4, and a basic particle with pKa = 9.\n", - "2. Define residue templates using \"pmb.define_residue\". \"Res_1\" consists of an inert particle as central bead and acidic and basic particles as side chain. \"Res_2\" consists of an inert particle as central bead and \"Res_1\" as side chain.\n", - "3. Define bond templates for each pair of particle templates. \n", - "4. Define a molecule template for the branched polyampholyte chain using \"pmb.define_molecule\" with the above \"residue_list.\" \n", - "5. Create the branched polyampholyte into the ESPResSo system.\n", - "6. Visualize your creation.\n", - "7. Delete the molecule and check that the pyMBE database is empty." + "picture_name = 'PDha_system.png'\n", + "create_snapshot_of_espresso_system(espresso_system = espresso_system, \n", + " filename = picture_name)\n", + "img = Image.open(picture_name)\n", + "img.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### 1. Define particle templates for each different bead of Res_1 and Res_2." + "Delete the particles and check that there are no particle instances in the pyMBE database" ] }, { @@ -2955,149 +2332,3271 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "pmb.delete_instances_in_system(instance_id=molecule_ids[0],\n", + " pmb_type=\"molecule\", \n", + " espresso_system = espresso_system)\n", + "# Check particle instances\n", + "pmb.get_instances_df(pmb_type = 'particle')" + ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### 2. Define the residue templates for Res_1 and Res_2." + "## How to create complex polymers " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "markdown", "metadata": {}, "source": [ - "3. Define bond templates for each pair of particle templates. " + "pyMBE can also be used to setup models that requiere more complex side chains, i.e. with more than one bead per side chain. One example of these complex molecules is the poly(N,N-diallylglutamate) (PDAGA), whose structure is depicted in the figure below. Following the logic of the previous example, one would construct PDAGA with pyMBE by defining a `residue` with a `central_bead` for the polymer backbone (grey) and a `side_chain` attached to it. In this case, the group in the side chain of the PDAGA monomer has a complex structure. This group can be coarse-grained by defining another `residue` composed by a new `central_bead` which represents the cyclic amine group (blue) and two `side_chains` ($\\alpha$ and $\\beta$ carboxyl) attached to it (red and orange).\n", + "\n", + "" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### 3. Define a molecule template for the diblock polyampholyte. " + "One can start by defining templates for each different bead of the PDAGA." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "PDAGA_backbone_bead = 'BB-PDAGA'\n", + "PDAGA_cyclic_amine_bead = 'NH3-PDAGA'\n", + "PDAGA_alpha_carboxyl_bead = 'aCOOH-PDAGA'\n", + "PDAGA_beta_carboxyl_bead = 'bCOOH-PDAGA'\n", + "\n", + "pmb.define_particle(name = PDAGA_backbone_bead, \n", + " z = 0,\n", + " sigma = 0.4*pmb.units.nm, \n", + " epsilon = 1*pmb.units('reduced_energy'))\n", + "\n", + "pmb.define_particle(name = PDAGA_cyclic_amine_bead, \n", + " z = 0, \n", + " sigma = 0.3*pmb.units.nm, \n", + " epsilon = 1*pmb.units('reduced_energy'))\n", + "\n", + "pmb.define_particle(name = PDAGA_alpha_carboxyl_bead, \n", + " z = 0, \n", + " sigma = 0.2*pmb.units.nm, \n", + " epsilon = 1*pmb.units('reduced_energy'))\n", + "\n", + "pmb.define_particle(name = PDAGA_beta_carboxyl_bead, \n", + " z = 0, \n", + " sigma = 0.4*pmb.units.nm, \n", + " epsilon = 1*pmb.units('reduced_energy'))" + ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### 4. Create the diblock polyampholyte chain into the ESPResSo system." + "The next step is to define the two different residue templates: \n", + "1. The side chain: two carboxyl beads attached to the cyclic amine bead." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "PDAGA_side_chain_residue = 'PDAGA_side_chain_residue'\n", + "\n", + "pmb.define_residue (name = PDAGA_side_chain_residue,\n", + " central_bead = PDAGA_cyclic_amine_bead,\n", + " side_chains = [PDAGA_alpha_carboxyl_bead, PDAGA_beta_carboxyl_bead])" + ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### 5. Visualize your creation." + "2. Each monomeric unit of the PDAGA: the side chain defined above attached to the backbone." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "PDAGA_monomer_residue = 'PDAGA_monomer_residue'\n", + "pmb.define_residue( name = PDAGA_monomer_residue,\n", + " central_bead = PDAGA_backbone_bead,\n", + " side_chains = [PDAGA_side_chain_residue])" + ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### 6. Delete the molecule and check that the pyMBE database is empty." + "Then, we need to define bond templates in a similar way as for the case of the simple polymer." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, "source": [ - "Refer to the sample script \"branched_polyampholyte.py\" in the samples folder for a complete solution of this exercise." + "bond_type = 'harmonic'\n", + "generic_bond_lenght=0.4 * pmb.units.nm\n", + "generic_harmonic_constant = 400 * pmb.units('reduced_energy / reduced_length**2')\n", + "\n", + "harmonic_bond = {'r_0' : generic_bond_lenght,\n", + " 'k' : generic_harmonic_constant,\n", + " }\n", + "\n", + "pmb.define_bond(bond_type = bond_type,\n", + " bond_parameters = harmonic_bond,\n", + " particle_pairs = [[PDAGA_backbone_bead, PDAGA_backbone_bead],\n", + " [PDAGA_backbone_bead, PDAGA_cyclic_amine_bead],\n", + " [PDAGA_alpha_carboxyl_bead, PDAGA_cyclic_amine_bead],\n", + " [PDAGA_beta_carboxyl_bead, PDAGA_cyclic_amine_bead]])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## How to create peptides " + "Now, let us define an octamer of PDAGA." ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": 10, "metadata": {}, + "outputs": [], "source": [ - "pyMBE includes built-on functions to facilitate the setting up of coarse-grained models for peptides from their aminoacid sequence. Currently, there are two different coarse-grained models implemented: \n", - "\n", - "* `1beadAA`, where the aminoacid is represented by one single bead.\n", - "* `2beadAA`, where the aminoacid is represented by two beads (backbone and side-chain). \n", - "\n", - "We provide reference parameters in the folder (`pyMBE/parameters`) which can be loaded into pyMBE. The peptide sequence should be provided as a `str` composed either by the list of the one letter code or the list of the three letter code of the corresponding aminoacids. For example, the two possible ways to provide the peptide Cysteine$_3$ - Glutamic acid$_2$ - Histidine$_4$ - Valine are:\n", + "PDAGA_polymer = 'PDAGA'\n", + "N_monomers = 8\n", "\n", - "* one letter code: 'CCCEEHHHHV'\n", - "* three letter code: 'CYS-CYS-CYS-GLU-GLU-HIS-HIS-HIS-HIS-VAL'" + "pmb.define_molecule(name = PDAGA_polymer,\n", + " residue_list = [PDAGA_monomer_residue]*N_monomers)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Let's set up the peptide Lysine$_5$ - Glutamic acid$_5$ using a two beads coarse-grained model." + "Finally, we are able to create a PDAGA polymer into the ESPResSo system." ] }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ - "N_peptide = 1\n", - "sequence = \"KKKKKEEEEE\"\n", - "model = '2beadAA'" + "N_polymers = 1\n", + "\n", + "mol_ids = pmb.create_molecule(name = PDAGA_polymer,\n", + " number_of_molecules= N_polymers,\n", + " espresso_system = espresso_system,\n", + " list_of_first_residue_positions = [[Box_L.to('reduced_length').magnitude/2]*3])" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": 13, "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
pmb_typenameparticle_idinitial_stateresidue_idmolecule_idassembly_id
0particleBB-PDAGA0BB-PDAGA00<NA>
1particleNH3-PDAGA1NH3-PDAGA00<NA>
2particleaCOOH-PDAGA2aCOOH-PDAGA00<NA>
3particlebCOOH-PDAGA3bCOOH-PDAGA00<NA>
4particleBB-PDAGA4BB-PDAGA10<NA>
5particleNH3-PDAGA5NH3-PDAGA10<NA>
6particleaCOOH-PDAGA6aCOOH-PDAGA10<NA>
7particlebCOOH-PDAGA7bCOOH-PDAGA10<NA>
8particleBB-PDAGA8BB-PDAGA20<NA>
9particleNH3-PDAGA9NH3-PDAGA20<NA>
10particleaCOOH-PDAGA10aCOOH-PDAGA20<NA>
11particlebCOOH-PDAGA11bCOOH-PDAGA20<NA>
12particleBB-PDAGA12BB-PDAGA30<NA>
13particleNH3-PDAGA13NH3-PDAGA30<NA>
14particleaCOOH-PDAGA14aCOOH-PDAGA30<NA>
15particlebCOOH-PDAGA15bCOOH-PDAGA30<NA>
16particleBB-PDAGA16BB-PDAGA40<NA>
17particleNH3-PDAGA17NH3-PDAGA40<NA>
18particleaCOOH-PDAGA18aCOOH-PDAGA40<NA>
19particlebCOOH-PDAGA19bCOOH-PDAGA40<NA>
20particleBB-PDAGA20BB-PDAGA50<NA>
21particleNH3-PDAGA21NH3-PDAGA50<NA>
22particleaCOOH-PDAGA22aCOOH-PDAGA50<NA>
23particlebCOOH-PDAGA23bCOOH-PDAGA50<NA>
24particleBB-PDAGA24BB-PDAGA60<NA>
25particleNH3-PDAGA25NH3-PDAGA60<NA>
26particleaCOOH-PDAGA26aCOOH-PDAGA60<NA>
27particlebCOOH-PDAGA27bCOOH-PDAGA60<NA>
28particleBB-PDAGA28BB-PDAGA70<NA>
29particleNH3-PDAGA29NH3-PDAGA70<NA>
30particleaCOOH-PDAGA30aCOOH-PDAGA70<NA>
31particlebCOOH-PDAGA31bCOOH-PDAGA70<NA>
\n", + "
" + ], + "text/plain": [ + " pmb_type name particle_id initial_state residue_id molecule_id \\\n", + "0 particle BB-PDAGA 0 BB-PDAGA 0 0 \n", + "1 particle NH3-PDAGA 1 NH3-PDAGA 0 0 \n", + "2 particle aCOOH-PDAGA 2 aCOOH-PDAGA 0 0 \n", + "3 particle bCOOH-PDAGA 3 bCOOH-PDAGA 0 0 \n", + "4 particle BB-PDAGA 4 BB-PDAGA 1 0 \n", + "5 particle NH3-PDAGA 5 NH3-PDAGA 1 0 \n", + "6 particle aCOOH-PDAGA 6 aCOOH-PDAGA 1 0 \n", + "7 particle bCOOH-PDAGA 7 bCOOH-PDAGA 1 0 \n", + "8 particle BB-PDAGA 8 BB-PDAGA 2 0 \n", + "9 particle NH3-PDAGA 9 NH3-PDAGA 2 0 \n", + "10 particle aCOOH-PDAGA 10 aCOOH-PDAGA 2 0 \n", + "11 particle bCOOH-PDAGA 11 bCOOH-PDAGA 2 0 \n", + "12 particle BB-PDAGA 12 BB-PDAGA 3 0 \n", + "13 particle NH3-PDAGA 13 NH3-PDAGA 3 0 \n", + "14 particle aCOOH-PDAGA 14 aCOOH-PDAGA 3 0 \n", + "15 particle bCOOH-PDAGA 15 bCOOH-PDAGA 3 0 \n", + "16 particle BB-PDAGA 16 BB-PDAGA 4 0 \n", + "17 particle NH3-PDAGA 17 NH3-PDAGA 4 0 \n", + "18 particle aCOOH-PDAGA 18 aCOOH-PDAGA 4 0 \n", + "19 particle bCOOH-PDAGA 19 bCOOH-PDAGA 4 0 \n", + "20 particle BB-PDAGA 20 BB-PDAGA 5 0 \n", + "21 particle NH3-PDAGA 21 NH3-PDAGA 5 0 \n", + "22 particle aCOOH-PDAGA 22 aCOOH-PDAGA 5 0 \n", + "23 particle bCOOH-PDAGA 23 bCOOH-PDAGA 5 0 \n", + "24 particle BB-PDAGA 24 BB-PDAGA 6 0 \n", + "25 particle NH3-PDAGA 25 NH3-PDAGA 6 0 \n", + "26 particle aCOOH-PDAGA 26 aCOOH-PDAGA 6 0 \n", + "27 particle bCOOH-PDAGA 27 bCOOH-PDAGA 6 0 \n", + "28 particle BB-PDAGA 28 BB-PDAGA 7 0 \n", + "29 particle NH3-PDAGA 29 NH3-PDAGA 7 0 \n", + "30 particle aCOOH-PDAGA 30 aCOOH-PDAGA 7 0 \n", + "31 particle bCOOH-PDAGA 31 bCOOH-PDAGA 7 0 \n", + "\n", + " assembly_id \n", + "0 \n", + "1 \n", + "2 \n", + "3 \n", + "4 \n", + "5 \n", + "6 \n", + "7 \n", + "8 \n", + "9 \n", + "10 \n", + "11 \n", + "12 \n", + "13 \n", + "14 \n", + "15 \n", + "16 \n", + "17 \n", + "18 \n", + "19 \n", + "20 \n", + "21 \n", + "22 \n", + "23 \n", + "24 \n", + "25 \n", + "26 \n", + "27 \n", + "28 \n", + "29 \n", + "30 \n", + "31 " + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pmb.get_instances_df(pmb_type = 'particle')" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
pmb_typenameresidue_idmolecule_idassembly_id
0residuePDAGA_monomer_residue00<NA>
1residuePDAGA_monomer_residue10<NA>
2residuePDAGA_monomer_residue20<NA>
3residuePDAGA_monomer_residue30<NA>
4residuePDAGA_monomer_residue40<NA>
5residuePDAGA_monomer_residue50<NA>
6residuePDAGA_monomer_residue60<NA>
7residuePDAGA_monomer_residue70<NA>
\n", + "
" + ], + "text/plain": [ + " pmb_type name residue_id molecule_id assembly_id\n", + "0 residue PDAGA_monomer_residue 0 0 \n", + "1 residue PDAGA_monomer_residue 1 0 \n", + "2 residue PDAGA_monomer_residue 2 0 \n", + "3 residue PDAGA_monomer_residue 3 0 \n", + "4 residue PDAGA_monomer_residue 4 0 \n", + "5 residue PDAGA_monomer_residue 5 0 \n", + "6 residue PDAGA_monomer_residue 6 0 \n", + "7 residue PDAGA_monomer_residue 7 0 " + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pmb.get_instances_df(pmb_type = 'residue')" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
pmb_typenamebond_idparticle_id1particle_id2
0bondNH3-PDAGA-aCOOH-PDAGA012
1bondNH3-PDAGA-bCOOH-PDAGA113
2bondBB-PDAGA-NH3-PDAGA201
3bondNH3-PDAGA-aCOOH-PDAGA356
4bondNH3-PDAGA-bCOOH-PDAGA457
5bondBB-PDAGA-NH3-PDAGA545
6bondBB-PDAGA-BB-PDAGA604
7bondNH3-PDAGA-aCOOH-PDAGA7910
8bondNH3-PDAGA-bCOOH-PDAGA8911
9bondBB-PDAGA-NH3-PDAGA989
10bondBB-PDAGA-BB-PDAGA1048
11bondNH3-PDAGA-aCOOH-PDAGA111314
12bondNH3-PDAGA-bCOOH-PDAGA121315
13bondBB-PDAGA-NH3-PDAGA131213
14bondBB-PDAGA-BB-PDAGA14812
15bondNH3-PDAGA-aCOOH-PDAGA151718
16bondNH3-PDAGA-bCOOH-PDAGA161719
17bondBB-PDAGA-NH3-PDAGA171617
18bondBB-PDAGA-BB-PDAGA181216
19bondNH3-PDAGA-aCOOH-PDAGA192122
20bondNH3-PDAGA-bCOOH-PDAGA202123
21bondBB-PDAGA-NH3-PDAGA212021
22bondBB-PDAGA-BB-PDAGA221620
23bondNH3-PDAGA-aCOOH-PDAGA232526
24bondNH3-PDAGA-bCOOH-PDAGA242527
25bondBB-PDAGA-NH3-PDAGA252425
26bondBB-PDAGA-BB-PDAGA262024
27bondNH3-PDAGA-aCOOH-PDAGA272930
28bondNH3-PDAGA-bCOOH-PDAGA282931
29bondBB-PDAGA-NH3-PDAGA292829
30bondBB-PDAGA-BB-PDAGA302428
\n", + "
" + ], + "text/plain": [ + " pmb_type name bond_id particle_id1 particle_id2\n", + "0 bond NH3-PDAGA-aCOOH-PDAGA 0 1 2\n", + "1 bond NH3-PDAGA-bCOOH-PDAGA 1 1 3\n", + "2 bond BB-PDAGA-NH3-PDAGA 2 0 1\n", + "3 bond NH3-PDAGA-aCOOH-PDAGA 3 5 6\n", + "4 bond NH3-PDAGA-bCOOH-PDAGA 4 5 7\n", + "5 bond BB-PDAGA-NH3-PDAGA 5 4 5\n", + "6 bond BB-PDAGA-BB-PDAGA 6 0 4\n", + "7 bond NH3-PDAGA-aCOOH-PDAGA 7 9 10\n", + "8 bond NH3-PDAGA-bCOOH-PDAGA 8 9 11\n", + "9 bond BB-PDAGA-NH3-PDAGA 9 8 9\n", + "10 bond BB-PDAGA-BB-PDAGA 10 4 8\n", + "11 bond NH3-PDAGA-aCOOH-PDAGA 11 13 14\n", + "12 bond NH3-PDAGA-bCOOH-PDAGA 12 13 15\n", + "13 bond BB-PDAGA-NH3-PDAGA 13 12 13\n", + "14 bond BB-PDAGA-BB-PDAGA 14 8 12\n", + "15 bond NH3-PDAGA-aCOOH-PDAGA 15 17 18\n", + "16 bond NH3-PDAGA-bCOOH-PDAGA 16 17 19\n", + "17 bond BB-PDAGA-NH3-PDAGA 17 16 17\n", + "18 bond BB-PDAGA-BB-PDAGA 18 12 16\n", + "19 bond NH3-PDAGA-aCOOH-PDAGA 19 21 22\n", + "20 bond NH3-PDAGA-bCOOH-PDAGA 20 21 23\n", + "21 bond BB-PDAGA-NH3-PDAGA 21 20 21\n", + "22 bond BB-PDAGA-BB-PDAGA 22 16 20\n", + "23 bond NH3-PDAGA-aCOOH-PDAGA 23 25 26\n", + "24 bond NH3-PDAGA-bCOOH-PDAGA 24 25 27\n", + "25 bond BB-PDAGA-NH3-PDAGA 25 24 25\n", + "26 bond BB-PDAGA-BB-PDAGA 26 20 24\n", + "27 bond NH3-PDAGA-aCOOH-PDAGA 27 29 30\n", + "28 bond NH3-PDAGA-bCOOH-PDAGA 28 29 31\n", + "29 bond BB-PDAGA-NH3-PDAGA 29 28 29\n", + "30 bond BB-PDAGA-BB-PDAGA 30 24 28" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pmb.get_instances_df(pmb_type = 'bond')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, let us see our PDAGA molecule." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [], + "source": [ + "picture_name = 'PDAGA_system.png'\n", + "create_snapshot_of_espresso_system(espresso_system = espresso_system, \n", + " filename = picture_name)\n", + "img = Image.open(picture_name)\n", + "img.show()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Delete the particles and check that the pyMBE database is empty." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "for mol_id in mol_ids:\n", + " pmb.delete_instances_in_system(instance_id=mol_id,\n", + " pmb_type=\"molecule\",\n", + " espresso_system=espresso_system)\n", + "pmb.get_instances_df(pmb_type = 'particle')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## How to create di-block copolymers " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In turn, the residues previously defined to build the PDAGA and PDha molecules can be used to build more complex polymers such as a di-block PDha-PDAGA copolymer, as shown in the picture below\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the bond template between the backbone particle of PDha and the backbone particle of PDAGA" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "pmb.define_bond(bond_type = bond_type,\n", + " bond_parameters = harmonic_bond,\n", + " particle_pairs = [[PDha_backbone_bead, PDAGA_backbone_bead]])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define a molecule template for the di-block polymer molecule using Python list comprehension methods" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "N_monomers_PDha = 4\n", + "N_monomers_PDAGA = 4\n", + "diblock_polymer = 'diblock'\n", + "\n", + "pmb.define_molecule(name = diblock_polymer,\n", + " residue_list = [PDha_residue]*N_monomers_PDha+[PDAGA_monomer_residue]*N_monomers_PDAGA)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Creating the di-block polymer into the ESPResSo system" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/bin/eog: symbol lookup error: /snap/core20/current/lib/x86_64-linux-gnu/libpthread.so.0: undefined symbol: __libc_pthread_init, version GLIBC_PRIVATE\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
pmb_typenameparticle_idinitial_stateresidue_idmolecule_idassembly_id
0particleBB-PDha0BB-PDha00<NA>
1particleCOOH-PDha1COOH-PDha00<NA>
2particleNH3-PDha2NH3-PDha00<NA>
3particleBB-PDha3BB-PDha10<NA>
4particleCOOH-PDha4COOH-PDha10<NA>
5particleNH3-PDha5NH3-PDha10<NA>
6particleBB-PDha6BB-PDha20<NA>
7particleCOOH-PDha7COOH-PDha20<NA>
8particleNH3-PDha8NH3-PDha20<NA>
9particleBB-PDha9BB-PDha30<NA>
10particleCOOH-PDha10COOH-PDha30<NA>
11particleNH3-PDha11NH3-PDha30<NA>
12particleBB-PDAGA12BB-PDAGA40<NA>
13particleNH3-PDAGA13NH3-PDAGA40<NA>
14particleaCOOH-PDAGA14aCOOH-PDAGA40<NA>
15particlebCOOH-PDAGA15bCOOH-PDAGA40<NA>
16particleBB-PDAGA16BB-PDAGA50<NA>
17particleNH3-PDAGA17NH3-PDAGA50<NA>
18particleaCOOH-PDAGA18aCOOH-PDAGA50<NA>
19particlebCOOH-PDAGA19bCOOH-PDAGA50<NA>
20particleBB-PDAGA20BB-PDAGA60<NA>
21particleNH3-PDAGA21NH3-PDAGA60<NA>
22particleaCOOH-PDAGA22aCOOH-PDAGA60<NA>
23particlebCOOH-PDAGA23bCOOH-PDAGA60<NA>
24particleBB-PDAGA24BB-PDAGA70<NA>
25particleNH3-PDAGA25NH3-PDAGA70<NA>
26particleaCOOH-PDAGA26aCOOH-PDAGA70<NA>
27particlebCOOH-PDAGA27bCOOH-PDAGA70<NA>
\n", + "
" + ], + "text/plain": [ + " pmb_type name particle_id initial_state residue_id molecule_id \\\n", + "0 particle BB-PDha 0 BB-PDha 0 0 \n", + "1 particle COOH-PDha 1 COOH-PDha 0 0 \n", + "2 particle NH3-PDha 2 NH3-PDha 0 0 \n", + "3 particle BB-PDha 3 BB-PDha 1 0 \n", + "4 particle COOH-PDha 4 COOH-PDha 1 0 \n", + "5 particle NH3-PDha 5 NH3-PDha 1 0 \n", + "6 particle BB-PDha 6 BB-PDha 2 0 \n", + "7 particle COOH-PDha 7 COOH-PDha 2 0 \n", + "8 particle NH3-PDha 8 NH3-PDha 2 0 \n", + "9 particle BB-PDha 9 BB-PDha 3 0 \n", + "10 particle COOH-PDha 10 COOH-PDha 3 0 \n", + "11 particle NH3-PDha 11 NH3-PDha 3 0 \n", + "12 particle BB-PDAGA 12 BB-PDAGA 4 0 \n", + "13 particle NH3-PDAGA 13 NH3-PDAGA 4 0 \n", + "14 particle aCOOH-PDAGA 14 aCOOH-PDAGA 4 0 \n", + "15 particle bCOOH-PDAGA 15 bCOOH-PDAGA 4 0 \n", + "16 particle BB-PDAGA 16 BB-PDAGA 5 0 \n", + "17 particle NH3-PDAGA 17 NH3-PDAGA 5 0 \n", + "18 particle aCOOH-PDAGA 18 aCOOH-PDAGA 5 0 \n", + "19 particle bCOOH-PDAGA 19 bCOOH-PDAGA 5 0 \n", + "20 particle BB-PDAGA 20 BB-PDAGA 6 0 \n", + "21 particle NH3-PDAGA 21 NH3-PDAGA 6 0 \n", + "22 particle aCOOH-PDAGA 22 aCOOH-PDAGA 6 0 \n", + "23 particle bCOOH-PDAGA 23 bCOOH-PDAGA 6 0 \n", + "24 particle BB-PDAGA 24 BB-PDAGA 7 0 \n", + "25 particle NH3-PDAGA 25 NH3-PDAGA 7 0 \n", + "26 particle aCOOH-PDAGA 26 aCOOH-PDAGA 7 0 \n", + "27 particle bCOOH-PDAGA 27 bCOOH-PDAGA 7 0 \n", + "\n", + " assembly_id \n", + "0 \n", + "1 \n", + "2 \n", + "3 \n", + "4 \n", + "5 \n", + "6 \n", + "7 \n", + "8 \n", + "9 \n", + "10 \n", + "11 \n", + "12 \n", + "13 \n", + "14 \n", + "15 \n", + "16 \n", + "17 \n", + "18 \n", + "19 \n", + "20 \n", + "21 \n", + "22 \n", + "23 \n", + "24 \n", + "25 \n", + "26 \n", + "27 " + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "N_polymers = 1\n", + "\n", + "mol_ids = pmb.create_molecule(name = diblock_polymer,\n", + " number_of_molecules= N_polymers,\n", + " espresso_system = espresso_system,\n", + " list_of_first_residue_positions = [[Box_L.to('reduced_length').magnitude/2]*3]) \n", + "# See the particle instances you have created\n", + "pmb.get_instances_df(pmb_type=\"particle\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, let us see our di-block PDha-PDAGA molecule." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "picture_name = 'diblock_system.png'\n", + "create_snapshot_of_espresso_system(espresso_system = espresso_system, \n", + " filename = picture_name)\n", + "img = Image.open(picture_name)\n", + "img.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Delete the particles and check that our df is empty." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for mol_id in mol_ids:\n", + " pmb.delete_instances_in_system(instance_id=0, \n", + " pmb_type=\"molecule\",\n", + " espresso_system = espresso_system)\n", + "pmb.get_instances_df(pmb_type=\"particle\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Practice by creating a custom polyampholyte chain " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Polyampholytes are polymers containing both acidic and basic groups on the same molecule, one example of a branched polyampholyte is depicted in the figure below.\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will create the polyampholyte chain in the figure, starting by defining two different residues, 'Res_1' and 'Res_2'. The polyampholyte chain is then defined by following residue_list:\n", + "\n", + "residue_list = 2*[\"Res_1\"] + [\"Res_2\"] + 2*[\"Res_1\"] + 2*[\"Res_2\"]\n", + "\n", + "### Tasks to do:\n", + "\n", + "1. Define particle templates for each different bead in the residues using \"pmb.define_particle\". There are 3 different particles, an inert particle, an acidic particle with pKa = 4, and a basic particle with pKa = 9.\n", + "2. Define residue templates using \"pmb.define_residue\". \"Res_1\" consists of an inert particle as central bead and acidic and basic particles as side chain. \"Res_2\" consists of an inert particle as central bead and \"Res_1\" as side chain.\n", + "3. Define bond templates for each pair of particle templates. \n", + "4. Define a molecule template for the branched polyampholyte chain using \"pmb.define_molecule\" with the above \"residue_list.\" \n", + "5. Create the branched polyampholyte into the ESPResSo system.\n", + "6. Visualize your creation.\n", + "7. Delete the molecule and check that the pyMBE database is empty." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 1. Define particle templates for each different bead of Res_1 and Res_2." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "PDha_backbone_bead = 'BB-part1'\n", + "PDha_carboxyl_bead = 'COOH-part1'\n", + "PDha_amine_bead = 'NH3-part1'\n", + "\n", + "pmb.define_particle(name = PDha_backbone_bead, \n", + " z = 0, \n", + " sigma = 0.4*pmb.units.nm,\n", + " epsilon = 1*pmb.units('reduced_energy'))\n", + "\n", + "pmb.define_particle(name = PDha_carboxyl_bead, \n", + " z = 0, \n", + " sigma = 0.5*pmb.units.nm, \n", + " epsilon = 1*pmb.units('reduced_energy'))\n", + "\n", + "pmb.define_particle(name = PDha_amine_bead, \n", + " z = 0, \n", + " sigma = 0.3*pmb.units.nm, \n", + " epsilon = 1*pmb.units('reduced_energy'))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 2. Define the residue templates for Res_1 and Res_2." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
pmb_typenamesigmaepsiloncutoffoffsetinitial_state
0particleBB-part10.4 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerBB-part1
1particleCOOH-part10.5 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerCOOH-part1
2particleNH3-part10.3 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerNH3-part1
\n", + "
" + ], + "text/plain": [ + " pmb_type name sigma epsilon \\\n", + "0 particle BB-part1 0.4 nanometer 25.692579121085853 millielectron_volt \n", + "1 particle COOH-part1 0.5 nanometer 25.692579121085853 millielectron_volt \n", + "2 particle NH3-part1 0.3 nanometer 25.692579121085853 millielectron_volt \n", + "\n", + " cutoff offset initial_state \n", + "0 0.5612310241546864 nanometer 0.0 nanometer BB-part1 \n", + "1 0.5612310241546864 nanometer 0.0 nanometer COOH-part1 \n", + "2 0.5612310241546864 nanometer 0.0 nanometer NH3-part1 " + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pmb.get_templates_df('particle')\n", + "# pmb.get_instances_df('particle')" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
pmb_typenameparticle_namezes_type
0particle_stateBB-part1BB-part100
1particle_stateCOOH-part1COOH-part101
2particle_stateNH3-part1NH3-part102
\n", + "
" + ], + "text/plain": [ + " pmb_type name particle_name z es_type\n", + "0 particle_state BB-part1 BB-part1 0 0\n", + "1 particle_state COOH-part1 COOH-part1 0 1\n", + "2 particle_state NH3-part1 NH3-part1 0 2" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pmb.get_templates_df('particle_state')" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
pmb_typenamecentral_beadside_chains
0residueResidue1BB-part1[COOH-part1, NH3-part1]
1residueside_chain_res_2BB-part1[COOH-part1, NH3-part1]
2residueResidue2BB-part1[side_chain_res_2]
\n", + "
" + ], + "text/plain": [ + " pmb_type name central_bead side_chains\n", + "0 residue Residue1 BB-part1 [COOH-part1, NH3-part1]\n", + "1 residue side_chain_res_2 BB-part1 [COOH-part1, NH3-part1]\n", + "2 residue Residue2 BB-part1 [side_chain_res_2]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pmb.get_templates_df('residue')" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
" + ], + "text/plain": [ + "Empty DataFrame\n", + "Columns: []\n", + "Index: []" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pmb.get_templates_df('molecule')" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.db.delete_templates(\"bond\")" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.db.delete_instances('particle_state')" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "res1='Residue1'\n", + "pmb.define_residue(name = res1,\n", + " central_bead = PDha_backbone_bead,\n", + " side_chains = [PDha_carboxyl_bead,PDha_amine_bead])\n", + "\n", + "side_chain_name_res2='side_chain_res_2'\n", + "pmb.define_residue( name = side_chain_name_res2,\n", + " central_bead = PDha_backbone_bead,\n", + " side_chains = [PDha_carboxyl_bead,PDha_amine_bead])\n", + "\n", + "res2='Residue2'\n", + "pmb.define_residue(name = res2,\n", + " central_bead = PDha_backbone_bead,\n", + " side_chains = [side_chain_name_res2])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "3. Define bond templates for each pair of particle templates. " + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['Kw', 'N_A', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_check_bond_inputs', '_check_dimensionality', '_check_pka_set', '_create_espresso_bond_instance', '_create_hydrogel_chain', '_create_hydrogel_node', '_delete_particles_from_espresso', '_get_espresso_bond_instance', '_get_label_id_map', '_get_residue_list_from_sequence', '_get_template_type', 'calculate_HH', 'calculate_HH_Donnan', 'calculate_center_of_mass', 'calculate_net_charge', 'center_object_in_simulation_box', 'create_added_salt', 'create_bond', 'create_counterions', 'create_hydrogel', 'create_molecule', 'create_particle', 'create_protein', 'create_residue', 'db', 'define_bond', 'define_default_bond', 'define_hydrogel', 'define_molecule', 'define_monoprototic_acidbase_reaction', 'define_monoprototic_particle_states', 'define_particle', 'define_particle_states', 'define_peptide', 'define_protein', 'define_residue', 'delete_instances_in_system', 'determine_reservoir_concentrations', 'e', 'enable_motion_of_rigid_object', 'generate_coordinates_outside_sphere', 'generate_random_points_in_a_sphere', 'generate_trial_perpendicular_vector', 'get_bond_template', 'get_charge_number_map', 'get_instances_df', 'get_lj_parameters', 'get_particle_id_map', 'get_pka_set', 'get_radius_map', 'get_reactions_df', 'get_reduced_units', 'get_templates_df', 'get_type_map', 'initialize_lattice_builder', 'kB', 'kT', 'lattice_builder', 'load_database', 'load_pka_set', 'propose_unused_type', 'read_protein_vtf', 'rng', 'root', 'save_database', 'seed', 'set_particle_initial_state', 'set_reduced_units', 'setup_cpH', 'setup_gcmc', 'setup_grxmc_reactions', 'setup_grxmc_unified', 'setup_lj_interactions', 'units']\n", + "Empty DataFrame\n", + "Columns: []\n", + "Index: []\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
" + ], + "text/plain": [ + "Empty DataFrame\n", + "Columns: []\n", + "Index: []" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(dir(pmb))\n", + "print(pmb.get_instances_df(pmb_type=\"residue\"))\n", + "pmb.get_instances_df(pmb_type = 'bond')" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "bond_type = 'harmonic'\n", + "generic_bond_lenght=0.4 * pmb.units.nm\n", + "generic_harmonic_constant = 400 * pmb.units('reduced_energy / reduced_length**2')\n", + "\n", + "harmonic_bond = {'r_0' : generic_bond_lenght,\n", + " 'k' : generic_harmonic_constant,\n", + " }\n", + "\n", + "pmb.define_bond(bond_type = bond_type,\n", + " bond_parameters = harmonic_bond,\n", + " particle_pairs = [[PDha_backbone_bead, PDha_backbone_bead],\n", + " [PDha_backbone_bead, PDha_carboxyl_bead],\n", + " [PDha_backbone_bead, PDha_amine_bead]])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 3. Define a molecule template for the diblock polyampholyte. " + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "diblock_polymer='custom_polyampholyte'\n", + "pmb.define_molecule(name = diblock_polymer,\n", + " residue_list = 2*[res1]+[res2]+2*[res1]+2*[res2])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 4. Create the diblock polyampholyte chain into the ESPResSo system." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
pmb_typenameparticle_idinitial_stateresidue_idmolecule_idassembly_id
0particleBB-part10BB-part100<NA>
1particleCOOH-part11COOH-part100<NA>
2particleNH3-part12NH3-part100<NA>
3particleBB-part13BB-part110<NA>
4particleCOOH-part14COOH-part110<NA>
5particleNH3-part15NH3-part110<NA>
6particleBB-part16BB-part120<NA>
7particleBB-part17BB-part120<NA>
8particleCOOH-part18COOH-part120<NA>
9particleNH3-part19NH3-part120<NA>
10particleBB-part110BB-part130<NA>
11particleCOOH-part111COOH-part130<NA>
12particleNH3-part112NH3-part130<NA>
13particleBB-part113BB-part140<NA>
14particleCOOH-part114COOH-part140<NA>
15particleNH3-part115NH3-part140<NA>
16particleBB-part116BB-part150<NA>
17particleBB-part117BB-part150<NA>
18particleCOOH-part118COOH-part150<NA>
19particleNH3-part119NH3-part150<NA>
20particleBB-part120BB-part160<NA>
21particleBB-part121BB-part160<NA>
22particleCOOH-part122COOH-part160<NA>
23particleNH3-part123NH3-part160<NA>
\n", + "
" + ], + "text/plain": [ + " pmb_type name particle_id initial_state residue_id molecule_id \\\n", + "0 particle BB-part1 0 BB-part1 0 0 \n", + "1 particle COOH-part1 1 COOH-part1 0 0 \n", + "2 particle NH3-part1 2 NH3-part1 0 0 \n", + "3 particle BB-part1 3 BB-part1 1 0 \n", + "4 particle COOH-part1 4 COOH-part1 1 0 \n", + "5 particle NH3-part1 5 NH3-part1 1 0 \n", + "6 particle BB-part1 6 BB-part1 2 0 \n", + "7 particle BB-part1 7 BB-part1 2 0 \n", + "8 particle COOH-part1 8 COOH-part1 2 0 \n", + "9 particle NH3-part1 9 NH3-part1 2 0 \n", + "10 particle BB-part1 10 BB-part1 3 0 \n", + "11 particle COOH-part1 11 COOH-part1 3 0 \n", + "12 particle NH3-part1 12 NH3-part1 3 0 \n", + "13 particle BB-part1 13 BB-part1 4 0 \n", + "14 particle COOH-part1 14 COOH-part1 4 0 \n", + "15 particle NH3-part1 15 NH3-part1 4 0 \n", + "16 particle BB-part1 16 BB-part1 5 0 \n", + "17 particle BB-part1 17 BB-part1 5 0 \n", + "18 particle COOH-part1 18 COOH-part1 5 0 \n", + "19 particle NH3-part1 19 NH3-part1 5 0 \n", + "20 particle BB-part1 20 BB-part1 6 0 \n", + "21 particle BB-part1 21 BB-part1 6 0 \n", + "22 particle COOH-part1 22 COOH-part1 6 0 \n", + "23 particle NH3-part1 23 NH3-part1 6 0 \n", + "\n", + " assembly_id \n", + "0 \n", + "1 \n", + "2 \n", + "3 \n", + "4 \n", + "5 \n", + "6 \n", + "7 \n", + "8 \n", + "9 \n", + "10 \n", + "11 \n", + "12 \n", + "13 \n", + "14 \n", + "15 \n", + "16 \n", + "17 \n", + "18 \n", + "19 \n", + "20 \n", + "21 \n", + "22 \n", + "23 " + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "N_polymers = 1\n", + "\n", + "mol_ids = pmb.create_molecule(name = diblock_polymer,\n", + " number_of_molecules= N_polymers,\n", + " espresso_system = espresso_system,\n", + " list_of_first_residue_positions = [[Box_L.to('reduced_length').magnitude/2]*3]) \n", + "# See the particle instances you have created\n", + "pmb.get_instances_df(pmb_type=\"particle\")" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
pmb_typenameresidue_idmolecule_idassembly_id
0residueResidue100<NA>
1residueResidue110<NA>
2residueResidue220<NA>
3residueResidue130<NA>
4residueResidue140<NA>
5residueResidue250<NA>
6residueResidue260<NA>
\n", + "
" + ], + "text/plain": [ + " pmb_type name residue_id molecule_id assembly_id\n", + "0 residue Residue1 0 0 \n", + "1 residue Residue1 1 0 \n", + "2 residue Residue2 2 0 \n", + "3 residue Residue1 3 0 \n", + "4 residue Residue1 4 0 \n", + "5 residue Residue2 5 0 \n", + "6 residue Residue2 6 0 " + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pmb.get_instances_df(pmb_type=\"residue\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 5. Visualize your creation." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "picture_name = 'CustomPolyampholite2.png'\n", + "create_snapshot_of_espresso_system(espresso_system = espresso_system, \n", + " filename = picture_name)\n", + "img = Image.open(picture_name)\n", + "img.show()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 6. Delete the molecule and check that the pyMBE database is empty." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
" + ], + "text/plain": [ + "Empty DataFrame\n", + "Columns: []\n", + "Index: []" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "for mol_id in mol_ids:\n", + " pmb.delete_instances_in_system(instance_id=mol_id,\n", + " pmb_type=\"molecule\",\n", + " espresso_system=espresso_system)\n", + "pmb.get_instances_df(pmb_type = 'particle')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Refer to the sample script \"branched_polyampholyte.py\" in the samples folder for a complete solution of this exercise." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## How to create peptides " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "pyMBE includes built-on functions to facilitate the setting up of coarse-grained models for peptides from their aminoacid sequence. Currently, there are two different coarse-grained models implemented: \n", + "\n", + "* `1beadAA`, where the aminoacid is represented by one single bead.\n", + "* `2beadAA`, where the aminoacid is represented by two beads (backbone and side-chain). \n", + "\n", + "We provide reference parameters in the folder (`pyMBE/parameters`) which can be loaded into pyMBE. The peptide sequence should be provided as a `str` composed either by the list of the one letter code or the list of the three letter code of the corresponding aminoacids. For example, the two possible ways to provide the peptide Cysteine$_3$ - Glutamic acid$_2$ - Histidine$_4$ - Valine are:\n", + "\n", + "* one letter code: 'CCCEEHHHHV'\n", + "* three letter code: 'CYS-CYS-CYS-GLU-GLU-HIS-HIS-HIS-HIS-VAL'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's set up the peptide Lysine$_5$ - Glutamic acid$_5$ using a two beads coarse-grained model." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "N_peptide = 1\n", + "sequence = \"KKKKKEEEEE\"\n", + "model = '2beadAA'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can use the peptide parametrization reported by Lunkad et al. [2], which is provided in the reference folder. This parametrization includes information about the particles (i.e. their Lennard-Jones parameters) and their bonding potentials (harmonic bonds)." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
pmb_typenamebond_typeparticle_name1particle_name2parameters
0bondCA-CAharmonicCACA{'r_0': 0.382 nanometer, 'k': 10277.0316484343...
1bondCA-DharmonicCAD{'r_0': 0.329 nanometer, 'k': 10277.0316484343...
2bondCA-EharmonicCAE{'r_0': 0.435 nanometer, 'k': 10277.0316484343...
3bondCA-HharmonicCAH{'r_0': 0.452 nanometer, 'k': 10277.0316484343...
4bondCA-YharmonicCAY{'r_0': 0.648 nanometer, 'k': 10277.0316484343...
5bondCA-KharmonicCAK{'r_0': 0.558 nanometer, 'k': 10277.0316484343...
\n", + "
" + ], + "text/plain": [ + " pmb_type name bond_type particle_name1 particle_name2 \\\n", + "0 bond CA-CA harmonic CA CA \n", + "1 bond CA-D harmonic CA D \n", + "2 bond CA-E harmonic CA E \n", + "3 bond CA-H harmonic CA H \n", + "4 bond CA-Y harmonic CA Y \n", + "5 bond CA-K harmonic CA K \n", + "\n", + " parameters \n", + "0 {'r_0': 0.382 nanometer, 'k': 10277.0316484343... \n", + "1 {'r_0': 0.329 nanometer, 'k': 10277.0316484343... \n", + "2 {'r_0': 0.435 nanometer, 'k': 10277.0316484343... \n", + "3 {'r_0': 0.452 nanometer, 'k': 10277.0316484343... \n", + "4 {'r_0': 0.648 nanometer, 'k': 10277.0316484343... \n", + "5 {'r_0': 0.558 nanometer, 'k': 10277.0316484343... " + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "path_to_interactions=pmb.root / \"parameters\" / \"peptides\" / \"Lunkad2021\"\n", + "path_to_pka=pmb.root / \"parameters\" / \"pka_sets\" / \"Hass2015.json\"\n", + "pmb.load_database(folder=path_to_interactions) \n", + "pmb.get_templates_df(pmb_type=\"particle\")\n", + "pmb.get_templates_df(pmb_type=\"bond\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Additionally, we can load one of the reference sets of pKa values for amino acids that we provide in pyMBE" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
reactionstoichiometrypKreaction_typemetadatasimulation_method
0DH <-> D{'DH': -1, 'D': 1}4.0monoprotic_acid{'summary': 'pKa-values of Hass et al.', 'sour...None
1EH <-> E{'EH': -1, 'E': 1}4.4monoprotic_acid{'summary': 'pKa-values of Hass et al.', 'sour...None
2YH <-> Y{'YH': -1, 'Y': 1}9.6monoprotic_acid{'summary': 'pKa-values of Hass et al.', 'sour...None
3CH <-> C{'CH': -1, 'C': 1}8.3monoprotic_acid{'summary': 'pKa-values of Hass et al.', 'sour...None
4HH <-> H{'HH': -1, 'H': 1}6.8monoprotic_base{'summary': 'pKa-values of Hass et al.', 'sour...None
5KH <-> K{'KH': -1, 'K': 1}10.4monoprotic_base{'summary': 'pKa-values of Hass et al.', 'sour...None
6RH <-> R{'RH': -1, 'R': 1}13.5monoprotic_base{'summary': 'pKa-values of Hass et al.', 'sour...None
7nH <-> n{'nH': -1, 'n': 1}8.0monoprotic_base{'summary': 'pKa-values of Hass et al.', 'sour...None
8cH <-> c{'cH': -1, 'c': 1}3.6monoprotic_acid{'summary': 'pKa-values of Hass et al.', 'sour...None
\n", + "
" + ], + "text/plain": [ + " reaction stoichiometry pK reaction_type \\\n", + "0 DH <-> D {'DH': -1, 'D': 1} 4.0 monoprotic_acid \n", + "1 EH <-> E {'EH': -1, 'E': 1} 4.4 monoprotic_acid \n", + "2 YH <-> Y {'YH': -1, 'Y': 1} 9.6 monoprotic_acid \n", + "3 CH <-> C {'CH': -1, 'C': 1} 8.3 monoprotic_acid \n", + "4 HH <-> H {'HH': -1, 'H': 1} 6.8 monoprotic_base \n", + "5 KH <-> K {'KH': -1, 'K': 1} 10.4 monoprotic_base \n", + "6 RH <-> R {'RH': -1, 'R': 1} 13.5 monoprotic_base \n", + "7 nH <-> n {'nH': -1, 'n': 1} 8.0 monoprotic_base \n", + "8 cH <-> c {'cH': -1, 'c': 1} 3.6 monoprotic_acid \n", + "\n", + " metadata simulation_method \n", + "0 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", + "1 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", + "2 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", + "3 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", + "4 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", + "5 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", + "6 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", + "7 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", + "8 {'summary': 'pKa-values of Hass et al.', 'sour... None " + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pmb.load_pka_set(path_to_pka)\n", + "# Check the loaded pKa set\n", + "pmb.get_reactions_df()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since monoprotic acid/base particles can be in two possible states, protonated and deprotonated, we need to define templates for those particle states" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'D': {'pka_value': 4.0, 'acidity': 'acidic'}, 'E': {'pka_value': 4.4, 'acidity': 'acidic'}, 'Y': {'pka_value': 9.6, 'acidity': 'acidic'}, 'C': {'pka_value': 8.3, 'acidity': 'acidic'}, 'H': {'pka_value': 6.8, 'acidity': 'basic'}, 'K': {'pka_value': 10.4, 'acidity': 'basic'}, 'R': {'pka_value': 13.5, 'acidity': 'basic'}, 'n': {'pka_value': 8.0, 'acidity': 'basic'}, 'c': {'pka_value': 3.6, 'acidity': 'acidic'}}\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
pmb_typenameparticle_namezes_type
0particle_stateCACA00
1particle_stateDHD01
2particle_stateDD-12
3particle_stateEHE03
4particle_stateEE-14
5particle_stateYHY05
6particle_stateYY-16
7particle_stateCHC07
8particle_stateCC-18
9particle_stateHHH19
10particle_stateHH010
11particle_stateKHK111
12particle_stateKK012
13particle_stateRHR113
14particle_stateRR014
15particle_statenHn115
16particle_statenn016
17particle_statecHc017
18particle_statecc-118
\n", + "
" + ], + "text/plain": [ + " pmb_type name particle_name z es_type\n", + "0 particle_state CA CA 0 0\n", + "1 particle_state DH D 0 1\n", + "2 particle_state D D -1 2\n", + "3 particle_state EH E 0 3\n", + "4 particle_state E E -1 4\n", + "5 particle_state YH Y 0 5\n", + "6 particle_state Y Y -1 6\n", + "7 particle_state CH C 0 7\n", + "8 particle_state C C -1 8\n", + "9 particle_state HH H 1 9\n", + "10 particle_state H H 0 10\n", + "11 particle_state KH K 1 11\n", + "12 particle_state K K 0 12\n", + "13 particle_state RH R 1 13\n", + "14 particle_state R R 0 14\n", + "15 particle_state nH n 1 15\n", + "16 particle_state n n 0 16\n", + "17 particle_state cH c 0 17\n", + "18 particle_state c c -1 18" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "We can use the peptide parametrization reported by Lunkad et al. [2], which is provided in the reference folder. This parametrization includes information about the particles (i.e. their Lennard-Jones parameters) and their bonding potentials (harmonic bonds)." + "# Get the pKa set stored in pyMBE\n", + "pka_set = pmb.get_pka_set()\n", + "# Check the pka_set\n", + "print(pka_set)\n", + "# define templates for the different particle states of monoprotic acid an basic groups:\n", + "for acidbase_particle in pka_set.keys():\n", + " pmb.define_monoprototic_particle_states(particle_name=acidbase_particle,\n", + " acidity=pka_set[acidbase_particle][\"acidity\"])\n", + "pmb.get_templates_df(pmb_type=\"particle_state\")" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 30, "metadata": {}, "outputs": [ { @@ -3213,36 +5712,25 @@ "5 0.3984740271498274 nanometer 0.0 nanometer KH " ] }, - "execution_count": 41, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/bin/eog: symbol lookup error: /snap/core20/current/lib/x86_64-linux-gnu/libpthread.so.0: undefined symbol: __libc_pthread_init, version GLIBC_PRIVATE\n" - ] } ], "source": [ - "path_to_interactions=pmb.root / \"parameters\" / \"peptides\" / \"Lunkad2021\"\n", - "path_to_pka=pmb.root / \"parameters\" / \"pka_sets\" / \"Hass2015.json\"\n", - "pmb.load_database(folder=path_to_interactions) \n", - "pmb.get_templates_df(pmb_type=\"particle\")\n", - "pmb.get_templates_df(pmb_type=\"bond\")" + "pmb.get_templates_df(pmb_type=\"particle\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Additionally, we can load one of the reference sets of pKa values for amino acids that we provide in pyMBE" + "The above functions define templates for particles and particle states Before creating a peptide molecule, we also need to define templates for the aminoacid residues and the peptide molecule" ] }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 31, "metadata": {}, "outputs": [ { @@ -3266,189 +5754,64 @@ " \n", " \n", " \n", - " reaction\n", - " stoichiometry\n", - " pK\n", - " reaction_type\n", - " metadata\n", - " simulation_method\n", + " pmb_type\n", + " name\n", + " model\n", + " residue_list\n", + " sequence\n", " \n", " \n", " \n", " \n", " 0\n", - " DH <-> D\n", - " {'DH': -1, 'D': 1}\n", - " 4.0\n", - " monoprotic_acid\n", - " {'summary': 'pKa-values of Hass et al.', 'sour...\n", - " None\n", - " \n", - " \n", - " 1\n", - " EH <-> E\n", - " {'EH': -1, 'E': 1}\n", - " 4.4\n", - " monoprotic_acid\n", - " {'summary': 'pKa-values of Hass et al.', 'sour...\n", - " None\n", - " \n", - " \n", - " 2\n", - " YH <-> Y\n", - " {'YH': -1, 'Y': 1}\n", - " 9.6\n", - " monoprotic_acid\n", - " {'summary': 'pKa-values of Hass et al.', 'sour...\n", - " None\n", - " \n", - " \n", - " 3\n", - " CH <-> C\n", - " {'CH': -1, 'C': 1}\n", - " 8.3\n", - " monoprotic_acid\n", - " {'summary': 'pKa-values of Hass et al.', 'sour...\n", - " None\n", - " \n", - " \n", - " 4\n", - " HH <-> H\n", - " {'HH': -1, 'H': 1}\n", - " 6.8\n", - " monoprotic_base\n", - " {'summary': 'pKa-values of Hass et al.', 'sour...\n", - " None\n", - " \n", - " \n", - " 5\n", - " KH <-> K\n", - " {'KH': -1, 'K': 1}\n", - " 10.4\n", - " monoprotic_base\n", - " {'summary': 'pKa-values of Hass et al.', 'sour...\n", - " None\n", - " \n", - " \n", - " 6\n", - " RH <-> R\n", - " {'RH': -1, 'R': 1}\n", - " 13.5\n", - " monoprotic_base\n", - " {'summary': 'pKa-values of Hass et al.', 'sour...\n", - " None\n", - " \n", - " \n", - " 7\n", - " nH <-> n\n", - " {'nH': -1, 'n': 1}\n", - " 8.0\n", - " monoprotic_base\n", - " {'summary': 'pKa-values of Hass et al.', 'sour...\n", - " None\n", - " \n", - " \n", - " 8\n", - " cH <-> c\n", - " {'cH': -1, 'c': 1}\n", - " 3.6\n", - " monoprotic_acid\n", - " {'summary': 'pKa-values of Hass et al.', 'sour...\n", - " None\n", + " peptide\n", + " KKKKKEEEEE\n", + " 2beadAA\n", + " [AA-K, AA-K, AA-K, AA-K, AA-K, AA-E, AA-E, AA-...\n", + " KKKKKEEEEE\n", " \n", " \n", "\n", "" ], "text/plain": [ - " reaction stoichiometry pK reaction_type \\\n", - "0 DH <-> D {'DH': -1, 'D': 1} 4.0 monoprotic_acid \n", - "1 EH <-> E {'EH': -1, 'E': 1} 4.4 monoprotic_acid \n", - "2 YH <-> Y {'YH': -1, 'Y': 1} 9.6 monoprotic_acid \n", - "3 CH <-> C {'CH': -1, 'C': 1} 8.3 monoprotic_acid \n", - "4 HH <-> H {'HH': -1, 'H': 1} 6.8 monoprotic_base \n", - "5 KH <-> K {'KH': -1, 'K': 1} 10.4 monoprotic_base \n", - "6 RH <-> R {'RH': -1, 'R': 1} 13.5 monoprotic_base \n", - "7 nH <-> n {'nH': -1, 'n': 1} 8.0 monoprotic_base \n", - "8 cH <-> c {'cH': -1, 'c': 1} 3.6 monoprotic_acid \n", + " pmb_type name model \\\n", + "0 peptide KKKKKEEEEE 2beadAA \n", "\n", - " metadata simulation_method \n", - "0 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", - "1 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", - "2 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", - "3 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", - "4 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", - "5 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", - "6 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", - "7 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", - "8 {'summary': 'pKa-values of Hass et al.', 'sour... None " + " residue_list sequence \n", + "0 [AA-K, AA-K, AA-K, AA-K, AA-K, AA-E, AA-E, AA-... KKKKKEEEEE " ] }, - "execution_count": 42, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "pmb.load_pka_set(path_to_pka)\n", - "# Check the loaded pKa set\n", - "pmb.get_reactions_df()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Since monoprotic acid/base particles can be in two possible states, protonated and deprotonated, we need to define templates for those particle states" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'D': {'pka_value': 4.0, 'acidity': 'acidic'}, 'E': {'pka_value': 4.4, 'acidity': 'acidic'}, 'Y': {'pka_value': 9.6, 'acidity': 'acidic'}, 'C': {'pka_value': 8.3, 'acidity': 'acidic'}, 'H': {'pka_value': 6.8, 'acidity': 'basic'}, 'K': {'pka_value': 10.4, 'acidity': 'basic'}, 'R': {'pka_value': 13.5, 'acidity': 'basic'}, 'n': {'pka_value': 8.0, 'acidity': 'basic'}, 'c': {'pka_value': 3.6, 'acidity': 'acidic'}}\n" - ] - }, - { - "ename": "ValueError", - "evalue": "Acidity {'pka_value': 4.0, 'acidity': 'acidic'} provided for particle name D is not supported. Valid keys are: ['acidic', 'basic']", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mValueError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[45]\u001b[39m\u001b[32m, line 7\u001b[39m\n\u001b[32m 5\u001b[39m \u001b[38;5;66;03m# define templates for the different particle states of monoprotic acid an basic groups:\u001b[39;00m\n\u001b[32m 6\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m acidbase_particle \u001b[38;5;129;01min\u001b[39;00m pka_set.keys():\n\u001b[32m----> \u001b[39m\u001b[32m7\u001b[39m \u001b[43mpmb\u001b[49m\u001b[43m.\u001b[49m\u001b[43mdefine_monoprototic_particle_states\u001b[49m\u001b[43m(\u001b[49m\u001b[43mparticle_name\u001b[49m\u001b[43m=\u001b[49m\u001b[43macidbase_particle\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 8\u001b[39m \u001b[43m \u001b[49m\u001b[43macidity\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpka_set\u001b[49m\u001b[43m[\u001b[49m\u001b[43macidbase_particle\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 9\u001b[39m pmb.get_templates_df(pmb_type=\u001b[33m\"\u001b[39m\u001b[33mparticle_state\u001b[39m\u001b[33m\"\u001b[39m)\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/Desktop/pyMBE_pmb/pyMBE/pyMBE.py:1561\u001b[39m, in \u001b[36mpymbe_library.define_monoprototic_particle_states\u001b[39m\u001b[34m(self, particle_name, acidity)\u001b[39m\n\u001b[32m 1559\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m pd.isna(acidity):\n\u001b[32m 1560\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m acidity \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m acidity_valid_keys:\n\u001b[32m-> \u001b[39m\u001b[32m1561\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mAcidity \u001b[39m\u001b[38;5;132;01m{\u001b[39;00macidity\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m provided for particle name \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mparticle_name\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m is not supported. Valid keys are: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00macidity_valid_keys\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m 1562\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m acidity == \u001b[33m\"\u001b[39m\u001b[33macidic\u001b[39m\u001b[33m\"\u001b[39m:\n\u001b[32m 1563\u001b[39m states = [{\u001b[33m\"\u001b[39m\u001b[33mname\u001b[39m\u001b[33m\"\u001b[39m: \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mparticle_name\u001b[38;5;132;01m}\u001b[39;00m\u001b[33mH\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mz\u001b[39m\u001b[33m\"\u001b[39m: \u001b[32m0\u001b[39m}, \n\u001b[32m 1564\u001b[39m {\u001b[33m\"\u001b[39m\u001b[33mname\u001b[39m\u001b[33m\"\u001b[39m: \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mparticle_name\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mz\u001b[39m\u001b[33m\"\u001b[39m: -\u001b[32m1\u001b[39m}]\n", - "\u001b[31mValueError\u001b[39m: Acidity {'pka_value': 4.0, 'acidity': 'acidic'} provided for particle name D is not supported. Valid keys are: ['acidic', 'basic']" - ] - } - ], - "source": [ - "# Get the pKa set stored in pyMBE\n", - "pka_set = pmb.get_pka_set()\n", - "# Check the pka_set\n", - "print(pka_set)\n", - "# define templates for the different particle states of monoprotic acid an basic groups:\n", - "for acidbase_particle in pka_set.keys():\n", - " pmb.define_monoprototic_particle_states(particle_name=acidbase_particle,\n", - " acidity=pka_set[acidbase_particle][\"acidity\"])\n", - "pmb.get_templates_df(pmb_type=\"particle_state\")" + "from pyMBE.lib.handy_functions import define_peptide_AA_residues\n", + "\n", + "# This is a convinience function that defines residue templates\n", + "# for aminoacids based on some pre-defined models\n", + "define_peptide_AA_residues(sequence=sequence,\n", + " model=model,\n", + " pmb=pmb)\n", + "pmb.define_peptide(name = sequence, \n", + " sequence = sequence, \n", + " model = model)\n", + "pmb.get_templates_df(pmb_type=\"residue\")\n", + "pmb.get_templates_df(pmb_type=\"peptide\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "The above functions define templates for particles and particle states Before creating a peptide molecule, we also need to define templates for the aminoacid residues and the peptide molecule" + "Now, we can create instances of our peptide template into the ESPResSo system. " ] }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 32, "metadata": {}, "outputs": [ { @@ -3474,9 +5837,8 @@ " \n", " pmb_type\n", " name\n", - " model\n", - " residue_list\n", - " sequence\n", + " molecule_id\n", + " assembly_id\n", " \n", " \n", " \n", @@ -3484,70 +5846,23 @@ " 0\n", " peptide\n", " KKKKKEEEEE\n", - " 2beadAA\n", - " [AA-K, AA-K, AA-K, AA-K, AA-K, AA-E, AA-E, AA-...\n", - " KKKKKEEEEE\n", + " 0\n", + " <NA>\n", " \n", " \n", "\n", "" ], "text/plain": [ - " pmb_type name model \\\n", - "0 peptide KKKKKEEEEE 2beadAA \n", - "\n", - " residue_list sequence \n", - "0 [AA-K, AA-K, AA-K, AA-K, AA-K, AA-E, AA-E, AA-... KKKKKEEEEE " + " pmb_type name molecule_id assembly_id\n", + "0 peptide KKKKKEEEEE 0 " ] }, - "execution_count": 43, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], - "source": [ - "from pyMBE.lib.handy_functions import define_peptide_AA_residues\n", - "\n", - "# This is a convinience function that defines residue templates\n", - "# for aminoacids based on some pre-defined models\n", - "define_peptide_AA_residues(sequence=sequence,\n", - " model=model,\n", - " pmb=pmb)\n", - "pmb.define_peptide(name = sequence, \n", - " sequence = sequence, \n", - " model = model)\n", - "pmb.get_templates_df(pmb_type=\"residue\")\n", - "pmb.get_templates_df(pmb_type=\"peptide\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, we can create instances of our peptide template into the ESPResSo system. " - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "ename": "ValueError", - "evalue": "Template 'KH' not found in type 'particle_state'.", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mValueError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[44]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m mol_ids = \u001b[43mpmb\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_molecule\u001b[49m\u001b[43m(\u001b[49m\u001b[43mname\u001b[49m\u001b[43m \u001b[49m\u001b[43m=\u001b[49m\u001b[43m \u001b[49m\u001b[43msequence\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 2\u001b[39m \u001b[43m \u001b[49m\u001b[43mnumber_of_molecules\u001b[49m\u001b[43m=\u001b[49m\u001b[43m \u001b[49m\u001b[43mN_peptide\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 3\u001b[39m \u001b[43m \u001b[49m\u001b[43mespresso_system\u001b[49m\u001b[43m \u001b[49m\u001b[43m=\u001b[49m\u001b[43m \u001b[49m\u001b[43mespresso_system\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 4\u001b[39m \u001b[43m \u001b[49m\u001b[43mlist_of_first_residue_positions\u001b[49m\u001b[43m \u001b[49m\u001b[43m=\u001b[49m\u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[43m[\u001b[49m\u001b[43mBox_L\u001b[49m\u001b[43m.\u001b[49m\u001b[43mto\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mreduced_length\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmagnitude\u001b[49m\u001b[43m/\u001b[49m\u001b[32;43m2\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m*\u001b[49m\u001b[32;43m3\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 5\u001b[39m pmb.get_instances_df(pmb_type=\u001b[33m\"\u001b[39m\u001b[33mpeptide\u001b[39m\u001b[33m\"\u001b[39m)\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/Desktop/pyMBE_pmb/pyMBE/pyMBE.py:1030\u001b[39m, in \u001b[36mpymbe_library.create_molecule\u001b[39m\u001b[34m(self, name, number_of_molecules, espresso_system, list_of_first_residue_positions, backbone_vector, use_default_bond, reverse_residue_order)\u001b[39m\n\u001b[32m 1027\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m item \u001b[38;5;129;01min\u001b[39;00m list_of_first_residue_positions:\n\u001b[32m 1028\u001b[39m central_bead_pos = [np.array(list_of_first_residue_positions[pos_index])]\n\u001b[32m-> \u001b[39m\u001b[32m1030\u001b[39m residue_id = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mcreate_residue\u001b[49m\u001b[43m(\u001b[49m\u001b[43mname\u001b[49m\u001b[43m=\u001b[49m\u001b[43mresidue\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1031\u001b[39m \u001b[43m \u001b[49m\u001b[43mespresso_system\u001b[49m\u001b[43m=\u001b[49m\u001b[43mespresso_system\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\n\u001b[32m 1032\u001b[39m \u001b[43m \u001b[49m\u001b[43mcentral_bead_position\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcentral_bead_pos\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\n\u001b[32m 1033\u001b[39m \u001b[43m \u001b[49m\u001b[43muse_default_bond\u001b[49m\u001b[43m=\u001b[49m\u001b[43m \u001b[49m\u001b[43muse_default_bond\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\n\u001b[32m 1034\u001b[39m \u001b[43m \u001b[49m\u001b[43mbackbone_vector\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbackbone_vector\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1036\u001b[39m \u001b[38;5;66;03m# Add molecule_id to the residue instance and all particles associated\u001b[39;00m\n\u001b[32m 1037\u001b[39m \u001b[38;5;28mself\u001b[39m.db._propagate_id(root_type=\u001b[33m\"\u001b[39m\u001b[33mresidue\u001b[39m\u001b[33m\"\u001b[39m, \n\u001b[32m 1038\u001b[39m root_id=residue_id,\n\u001b[32m 1039\u001b[39m attribute=\u001b[33m\"\u001b[39m\u001b[33mmolecule_id\u001b[39m\u001b[33m\"\u001b[39m, \n\u001b[32m 1040\u001b[39m value=molecule_id)\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/Desktop/pyMBE_pmb/pyMBE/pyMBE.py:1319\u001b[39m, in \u001b[36mpymbe_library.create_residue\u001b[39m\u001b[34m(self, name, espresso_system, central_bead_position, use_default_bond, backbone_vector)\u001b[39m\n\u001b[32m 1315\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 1316\u001b[39m bead_position=central_bead_position+\u001b[38;5;28mself\u001b[39m.generate_trial_perpendicular_vector(vector=np.array(backbone_vector),\n\u001b[32m 1317\u001b[39m magnitude=l0)\n\u001b[32m-> \u001b[39m\u001b[32m1319\u001b[39m side_bead_id = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mcreate_particle\u001b[49m\u001b[43m(\u001b[49m\u001b[43mname\u001b[49m\u001b[43m=\u001b[49m\u001b[43mside_chain_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\n\u001b[32m 1320\u001b[39m \u001b[43m \u001b[49m\u001b[43mespresso_system\u001b[49m\u001b[43m=\u001b[49m\u001b[43mespresso_system\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1321\u001b[39m \u001b[43m \u001b[49m\u001b[43mposition\u001b[49m\u001b[43m=\u001b[49m\u001b[43m[\u001b[49m\u001b[43mbead_position\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\n\u001b[32m 1322\u001b[39m \u001b[43m \u001b[49m\u001b[43mnumber_of_particles\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m1\u001b[39;49m\u001b[43m)\u001b[49m[\u001b[32m0\u001b[39m]\n\u001b[32m 1323\u001b[39m side_chain_beads_ids.append(side_bead_id)\n\u001b[32m 1324\u001b[39m \u001b[38;5;28mself\u001b[39m.db._update_instance(pmb_type=\u001b[33m\"\u001b[39m\u001b[33mparticle\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 1325\u001b[39m instance_id=side_bead_id,\n\u001b[32m 1326\u001b[39m attribute=\u001b[33m\"\u001b[39m\u001b[33mresidue_id\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 1327\u001b[39m value=residue_id)\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/Desktop/pyMBE_pmb/pyMBE/pyMBE.py:1133\u001b[39m, in \u001b[36mpymbe_library.create_particle\u001b[39m\u001b[34m(self, name, espresso_system, number_of_particles, position, fix)\u001b[39m\n\u001b[32m 1129\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m []\n\u001b[32m 1131\u001b[39m part_tpl = \u001b[38;5;28mself\u001b[39m.db.get_template(pmb_type=\u001b[33m\"\u001b[39m\u001b[33mparticle\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 1132\u001b[39m name=name)\n\u001b[32m-> \u001b[39m\u001b[32m1133\u001b[39m part_state = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mdb\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget_template\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpmb_type\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mparticle_state\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 1134\u001b[39m \u001b[43m \u001b[49m\u001b[43mname\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpart_tpl\u001b[49m\u001b[43m.\u001b[49m\u001b[43minitial_state\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1135\u001b[39m z = part_state.z\n\u001b[32m 1136\u001b[39m es_type = part_state.es_type\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/Desktop/pyMBE_pmb/pyMBE/storage/manager.py:935\u001b[39m, in \u001b[36mManager.get_template\u001b[39m\u001b[34m(self, pmb_type, name)\u001b[39m\n\u001b[32m 932\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mThere are no \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mpmb_type\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m templates defined in the database\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 934\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m._templates[pmb_type]:\n\u001b[32m--> \u001b[39m\u001b[32m935\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mTemplate \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mname\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m not found in type \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mpmb_type\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m.\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 936\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 937\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m._templates[pmb_type][name]\n", - "\u001b[31mValueError\u001b[39m: Template 'KH' not found in type 'particle_state'." - ] - } - ], "source": [ "\n", "mol_ids = pmb.create_molecule(name = sequence,\n", @@ -3566,7 +5881,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 33, "metadata": {}, "outputs": [], "source": [ @@ -3586,7 +5901,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 38, "metadata": {}, "outputs": [], "source": [ @@ -3629,7 +5944,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.3" + "version": "3.10.20" } }, "nbformat": 4, From 802cac6b60fd4d53b823ee0092146f679391d68a Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 16 Apr 2026 14:16:07 +0200 Subject: [PATCH 06/75] Add modifications to decouple the follwoing methods from espresso: - create_espresso_bond_instance -_create_hydrogel_chain - create_hydrogel -_get_espresso_bond_instance - create_added_salt - create_counterions - create_bond -create_particle -create_residue -create_molecule -create_protein add methods to enable the decoupling: -set_simulation_engine -add_instances_to_engine --- pyMBE/pyMBE.py | 149 ++++++++++++++++++++++++++----------------------- 1 file changed, 79 insertions(+), 70 deletions(-) diff --git a/pyMBE/pyMBE.py b/pyMBE/pyMBE.py index ba475d6c..97b8f006 100644 --- a/pyMBE/pyMBE.py +++ b/pyMBE/pyMBE.py @@ -46,7 +46,10 @@ from pyMBE.storage.instances.protein import ProteinInstance from pyMBE.storage.instances.bond import BondInstance from pyMBE.storage.instances.hydrogel import HydrogelInstance -from pyMBE.simulation_builder.engine_factory import EngineFactory + +from pyMBE.simulation_builder.espresso_engine import EspressoSimulation +from pyMBE.simulation_builder.lammps_engine import LammpsSimulation +from pyMBE.simulation_builder.engine_protocol import EspressoSystemProtocol ## Reactions from pyMBE.storage.reactions.reaction import Reaction, ReactionParticipant # Utilities @@ -125,7 +128,7 @@ def __init__(self, seed, temperature=None, unit_length=None, unit_charge=None, K Kw=Kw) self.db = Manager(units=self.units) - self.simulation_engine=EngineFactory.get_simulation_engine(engine_name=simulation_engine,db=self.db) ### Add simulation factory. + self.simulation_engine=None self.lattice_builder = None self.root = importlib.resources.files(__package__) @@ -215,16 +218,7 @@ def _create_espresso_bond_instance(self, bond_type, bond_parameters): Returns: ('espressomd.interactions'): instance of an ESPResSo bond object """ - from espressomd import interactions - self._check_bond_inputs(bond_parameters=bond_parameters, - bond_type=bond_type) - if bond_type == 'harmonic': - bond_instance = interactions.HarmonicBond(k = bond_parameters["k"].m_as("reduced_energy/reduced_length**2"), - r_0 = bond_parameters["r_0"].m_as("reduced_length")) - elif bond_type == 'FENE': - bond_instance = interactions.FeneBond(k = bond_parameters["k"].m_as("reduced_energy/reduced_length**2"), - r_0 = bond_parameters["r_0"].m_as("reduced_length"), - d_r_max = bond_parameters["d_r_max"].m_as("reduced_length")) + bond_instance = self.simulation_engine._create_bond_instance(bond_type,bond_parameters) return bond_instance def _create_hydrogel_chain(self, hydrogel_chain, nodes, espresso_system, use_default_bond=False): @@ -300,24 +294,23 @@ def _create_hydrogel_chain(self, hydrogel_chain, nodes, espresso_system, use_def use_default_bond=use_default_bond, reverse_residue_order=reverse_residue_order)[0] # Bond chain to the hydrogel nodes + ### The following implementation belongs to espresso engine chain_pids = self.db._find_instance_ids_by_attribute(pmb_type="particle", attribute="molecule_id", value=mol_id) bond_tpl1 = self.get_bond_template(particle_name1=nodes[node_start_label]["name"], particle_name2=part_start_chain_name, use_default_bond=use_default_bond) - start_bond_instance = self._get_espresso_bond_instance(bond_template=bond_tpl1, - espresso_system=espresso_system) + start_bond_instance = self._get_espresso_bond_instance(bond_template=bond_tpl1) bond_tpl2 = self.get_bond_template(particle_name1=nodes[node_end_label]["name"], particle_name2=part_end_chain_name, use_default_bond=use_default_bond) - end_bond_instance = self._get_espresso_bond_instance(bond_template=bond_tpl2, - espresso_system=espresso_system) + end_bond_instance = self._get_espresso_bond_instance(bond_template=bond_tpl2) espresso_system.part.by_id(start_node_id).add_bond((start_bond_instance, chain_pids[0])) espresso_system.part.by_id(chain_pids[-1]).add_bond((end_bond_instance, end_node_id)) return mol_id - def _create_hydrogel_node(self, node_index, node_name, espresso_system): + def _create_hydrogel_node(self, node_index, node_name): """ Set a node residue type. @@ -340,14 +333,14 @@ def _create_hydrogel_node(self, node_index, node_name, espresso_system): raise ValueError("LatticeBuilder is not initialized. Use 'initialize_lattice_builder' first.") node_position = np.array(node_index)*0.25*self.lattice_builder.box_l p_id = self.create_particle(name = node_name, - espresso_system=espresso_system, + box_l=self.lattice_builder.box_l, number_of_particles=1, position = [node_position]) key = self.lattice_builder._get_node_by_label(f"[{node_index[0]} {node_index[1]} {node_index[2]}]") self.lattice_builder.nodes[key] = node_name return node_position.tolist(), p_id[0] - def _get_espresso_bond_instance(self, bond_template, espresso_system): + def _get_espresso_bond_instance(self, bond_template): """ Retrieve or create a bond instance in an ESPResSo system for a given pair of particle names. @@ -364,14 +357,7 @@ def _get_espresso_bond_instance(self, bond_template, espresso_system): Notes: When a new bond instance is created, it is not added to the ESPResSo system. """ - if bond_template.name in self.db.espresso_bond_instances.keys(): - bond_inst = self.db.espresso_bond_instances[bond_template.name] - else: - # Create an instance of the bond - bond_inst = self._create_espresso_bond_instance(bond_type=bond_template.bond_type, - bond_parameters=bond_template.get_parameters(self.units)) - self.db.espresso_bond_instances[bond_template.name]= bond_inst - espresso_system.bonded_inter.add(bond_inst) + bond_inst=self.simulation_engine._get_bond_instance(bond_template) return bond_inst def _get_label_id_map(self, pmb_type): @@ -461,6 +447,9 @@ def _delete_particles_from_espresso(self, particle_ids, espresso_system): for pid in particle_ids: espresso_system.part.by_id(pid).remove() + def add_instances_to_engine(self): + self.simulation_engine.add_instances_to_engine() + def calculate_center_of_mass(self, instance_id, pmb_type, espresso_system): """ Calculates the center of mass of a pyMBE object instance in an ESPResSo system. @@ -738,7 +727,7 @@ def center_object_in_simulation_box(self, instance_id, espresso_system, pmb_type es_pos = espresso_system.part.by_id(pid).pos espresso_system.part.by_id(pid).pos = es_pos - center_of_mass + box_center - def create_added_salt(self, espresso_system, cation_name, anion_name, c_salt): + def create_added_salt(self, box_l, cation_name, anion_name, c_salt): """ Creates a 'c_salt' concentration of 'cation_name' and 'anion_name' ions into the 'espresso_system'. @@ -766,7 +755,7 @@ def create_added_salt(self, espresso_system, cation_name, anion_name, c_salt): if anion_charge >= 0: raise ValueError(f'ERROR anion charge must be negative, charge {anion_charge}') # Calculate the number of ions in the simulation box - volume=self.units.Quantity(espresso_system.volume(), 'reduced_length**3') + volume=self.units.Quantity(box_l**3, 'reduced_length**3') ### Changed espresso.volume() to box_l**3 if c_salt.check('[substance] [length]**-3'): N_ions= int((volume*c_salt.to('mol/reduced_length**3')*self.N_A).magnitude) c_salt_calculated=N_ions/(volume*self.N_A) @@ -777,10 +766,10 @@ def create_added_salt(self, espresso_system, cation_name, anion_name, c_salt): raise ValueError('Unknown units for c_salt, please provided it in [mol / volume] or [particle / volume]', c_salt) N_cation = N_ions*abs(anion_charge) N_anion = N_ions*abs(cation_charge) - self.create_particle(espresso_system=espresso_system, + self.create_particle(box_l=box_l, name=cation_name, number_of_particles=N_cation) - self.create_particle(espresso_system=espresso_system, + self.create_particle(box_l=box_l, name=anion_name, number_of_particles=N_anion) if c_salt_calculated.check('[substance] [length]**-3'): @@ -789,7 +778,7 @@ def create_added_salt(self, espresso_system, cation_name, anion_name, c_salt): logging.info(f"added salt concentration of {c_salt_calculated.to('reduced_length**-3')} given by {N_cation} cations and {N_anion} anions") return c_salt_calculated - def create_bond(self, particle_id1, particle_id2, espresso_system, use_default_bond=False): + def create_bond(self, particle_id1, particle_id2, use_default_bond=False): """ Creates a bond between two particle instances in an ESPResSo system and registers it in the pyMBE database. @@ -824,9 +813,9 @@ def create_bond(self, particle_id1, particle_id2, espresso_system, use_default_b bond_tpl = self.get_bond_template(particle_name1=particle_inst_1.name, particle_name2=particle_inst_2.name, use_default_bond=use_default_bond) - bond_inst = self._get_espresso_bond_instance(bond_template=bond_tpl, - espresso_system=espresso_system) - espresso_system.part.by_id(particle_id1).add_bond((bond_inst, particle_id2)) + # bond_inst = self._get_espresso_bond_instance(bond_template=bond_tpl, + # espresso_system=espresso_system) + # espresso_system.part.by_id(particle_id1).add_bond((bond_inst, particle_id2)) bond_id = self.db._propose_instance_id(pmb_type="bond") pmb_bond_instance = BondInstance(bond_id=bond_id, name=bond_tpl.name, @@ -834,7 +823,7 @@ def create_bond(self, particle_id1, particle_id2, espresso_system, use_default_b particle_id2=particle_id2) self.db._register_instance(instance=pmb_bond_instance) - def create_counterions(self, object_name, cation_name, anion_name, espresso_system): + def create_counterions(self, object_name, cation_name, anion_name, box_l): """ Creates particles of 'cation_name' and 'anion_name' in 'espresso_system' to counter the net charge of 'object_name'. @@ -874,10 +863,17 @@ def create_counterions(self, object_name, cation_name, anion_name, espresso_syst for name in ['positive', 'negative']: object_charge[name]=0 for id in object_ids: - if espresso_system.part.by_id(id).q > 0: - object_charge['positive']+=1*(np.abs(espresso_system.part.by_id(id).q )) - elif espresso_system.part.by_id(id).q < 0: - object_charge['negative']+=1*(np.abs(espresso_system.part.by_id(id).q )) + object_name = self.db.get_instance(pmb_type="particle", + instance_id=id).name + object_tpl = self.db.get_template(pmb_type="particle", + name=object_name) + object_state = self.db.get_template(pmb_type="particle_state", + name=object_tpl.initial_state) + object_charge = object_state.z + if object_charge > 0: + object_charge['positive']+=1*(np.abs(object_charge )) + elif object_charge < 0: + object_charge['negative']+=1*(np.abs(object_charge )) if object_charge['positive'] % abs(anion_charge) == 0: counterion_number[anion_name]=int(object_charge['positive']/abs(anion_charge)) else: @@ -887,13 +883,13 @@ def create_counterions(self, object_name, cation_name, anion_name, espresso_syst else: raise ValueError('The number of negative charges in the pmb_object must be divisible by the charge of the cation') if counterion_number[cation_name] > 0: - self.create_particle(espresso_system=espresso_system, + self.create_particle(box_l=box_l, name=cation_name, number_of_particles=counterion_number[cation_name]) else: counterion_number[cation_name]=0 if counterion_number[anion_name] > 0: - self.create_particle(espresso_system=espresso_system, + self.create_particle(box_l=box_l, name=anion_name, number_of_particles=counterion_number[anion_name]) else: @@ -932,8 +928,7 @@ def create_hydrogel(self, name, espresso_system, use_default_bond=False): node_index = node.lattice_index node_name = node.particle_name node_pos, node_id = self._create_hydrogel_node(node_index=node_index, - node_name=node_name, - espresso_system=espresso_system) + node_name=node_name) node_label = self.lattice_builder._create_node_label(node_index=node_index) nodes[node_label] = {"name": node_name, "id": node_id, "pos": node_pos} self.db._update_instance(instance_id=node_id, @@ -943,7 +938,6 @@ def create_hydrogel(self, name, espresso_system, use_default_bond=False): for hydrogel_chain in hydrogel_tpl.chain_map: molecule_id = self._create_hydrogel_chain(hydrogel_chain=hydrogel_chain, nodes=nodes, - espresso_system=espresso_system, use_default_bond=use_default_bond) self.db._update_instance(instance_id=molecule_id, pmb_type="molecule", @@ -958,7 +952,7 @@ def create_hydrogel(self, name, espresso_system, use_default_bond=False): assembly_id=assembly_id)) return assembly_id - def create_molecule(self, name, number_of_molecules, espresso_system, list_of_first_residue_positions=None, backbone_vector=None, use_default_bond=False, reverse_residue_order = False): + def create_molecule(self, name, number_of_molecules, box_l, list_of_first_residue_positions=None, backbone_vector=None, use_default_bond=False, reverse_residue_order = False): """ Creates instances of a given molecule template name into ESPResSo. @@ -1034,7 +1028,7 @@ def create_molecule(self, name, number_of_molecules, espresso_system, list_of_fi central_bead_pos = [np.array(list_of_first_residue_positions[pos_index])] residue_id = self.create_residue(name=residue, - espresso_system=espresso_system, + box_l=box_l, central_bead_position=central_bead_pos, use_default_bond= use_default_bond, backbone_vector=backbone_vector) @@ -1051,7 +1045,7 @@ def create_molecule(self, name, number_of_molecules, espresso_system, list_of_fi prev_central_bead_name = self.db.get_instance(pmb_type="particle", instance_id=prev_central_bead_id).name prev_central_bead_pos = self.db.get_instance(pmb_type="particle", - instance_id=prev_central_bead_id).particle_position + instance_id=prev_central_bead_id).position # prev_central_bead_pos = espresso_system.part.by_id(prev_central_bead_id).pos first_residue = False else: @@ -1070,7 +1064,7 @@ def create_molecule(self, name, number_of_molecules, espresso_system, list_of_fi central_bead_pos = prev_central_bead_pos+backbone_vector*l0 # Create the residue residue_id = self.create_residue(name=residue, - espresso_system=espresso_system, + box_l=box_l, central_bead_position=[central_bead_pos], use_default_bond= use_default_bond, backbone_vector=backbone_vector) @@ -1087,7 +1081,6 @@ def create_molecule(self, name, number_of_molecules, espresso_system, list_of_fi # Bond the central beads of the new and previous residues self.create_bond(particle_id1=prev_central_bead_id, particle_id2=central_bead_id, - espresso_system=espresso_system, use_default_bond=use_default_bond) prev_central_bead_id = central_bead_id @@ -1106,7 +1099,7 @@ def create_molecule(self, name, number_of_molecules, espresso_system, list_of_fi molecule_ids.append(molecule_id) return molecule_ids - def create_particle(self, name, espresso_system, number_of_particles, position=None, fix=False): + def create_particle(self, name, box_l, number_of_particles, position=None, fix=False): """ Creates one or more particles in an ESPResSo system based on the particle template in the pyMBE database. @@ -1139,33 +1132,36 @@ def create_particle(self, name, espresso_system, number_of_particles, position=N name=name) part_state = self.db.get_template(pmb_type="particle_state", name=part_tpl.initial_state) - z = part_state.z - es_type = part_state.es_type + name_state=part_state.name + #z= part_state.z + #es_type = part_state.es_type # Create the new particles into ESPResSo created_pid_list=[] for index in range(number_of_particles): if position is None: - particle_position = self.rng.random((1, 3))[0] *np.copy(espresso_system.box_l) + particle_position = self.rng.random((1, 3))[0] *np.copy(box_l) else: particle_position = position[index] particle_id = self.db._propose_instance_id(pmb_type="particle") created_pid_list.append(particle_id) # kwargs = dict(id=particle_id, pos=particle_position, type=es_type, q=z) - # if fix: - # kwargs["fix"] = 3 * [fix] ### Is the fix attribute something concrete from espresso_system? + if fix: + particle_fix= 3 * [fix] ### Is the fix attribute something concrete from espresso_system? + else: + particle_fix=None # espresso_system.part.add(**kwargs) + part_inst = ParticleInstance(name=name, particle_id=particle_id, - initial_state=part_state.name, - particle_position=particle_position, - particle_label=es_type, - particle_charge=z) + initial_state=name_state, + position=particle_position, + fix=particle_fix) self.db._register_instance(part_inst) return created_pid_list - def create_protein(self, name, number_of_proteins, espresso_system, topology_dict): + def create_protein(self, name, number_of_proteins, box_l, topology_dict): """ Creates one or more protein molecules in an ESPResSo system based on the protein template in the pyMBE database and a provided topology. @@ -1207,7 +1203,7 @@ def create_protein(self, name, number_of_proteins, espresso_system, topology_dic if not self.db._has_template(name=name, pmb_type="protein"): raise ValueError(f"Protein template with name '{name}' is not defined in the pyMBE database.") protein_tpl = self.db.get_template(pmb_type="protein", name=name) - box_half = espresso_system.box_l[0] / 2.0 + box_half = box_l[0] / 2.0 # Create protein mol_ids = [] for _ in range(number_of_proteins): @@ -1236,7 +1232,7 @@ def create_protein(self, name, number_of_proteins, espresso_system, topology_dic relative_pos = topology_dict[bead_id]["initial_pos"] absolute_pos = relative_pos + protein_center particle_id = self.create_particle(name=bead_type, - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1, position=[absolute_pos], fix=True)[0] @@ -1255,7 +1251,7 @@ def create_protein(self, name, number_of_proteins, espresso_system, topology_dic mol_ids.append(molecule_id) return mol_ids - def create_residue(self, name, espresso_system, central_bead_position=None,use_default_bond=False, backbone_vector=None): + def create_residue(self, name, box_l, central_bead_position=None,use_default_bond=False, backbone_vector=None): """ Creates a residue into ESPResSo. @@ -1291,12 +1287,12 @@ def create_residue(self, name, espresso_system, central_bead_position=None,use_d # create the principal bead central_bead_name = res_tpl.central_bead central_bead_id = self.create_particle(name=central_bead_name, - espresso_system=espresso_system, + box_l=box_l, position=central_bead_position, number_of_particles = 1)[0] central_bead_position = self.db.get_instance(pmb_type="particle", - instance_id=central_bead_id).particle_position + instance_id=central_bead_id).position # # central_bead_position=espresso_system.part.by_id(central_bead_id).pos # Assigns residue_id to the central_bead particle created. @@ -1330,7 +1326,7 @@ def create_residue(self, name, espresso_system, central_bead_position=None,use_d magnitude=l0) side_bead_id = self.create_particle(name=side_chain_name, - espresso_system=espresso_system, + box_l=box_l, position=[bead_position], number_of_particles=1)[0] side_chain_beads_ids.append(side_bead_id) @@ -1340,9 +1336,10 @@ def create_residue(self, name, espresso_system, central_bead_position=None,use_d value=residue_id) self.create_bond(particle_id1=central_bead_id, particle_id2=side_bead_id, - espresso_system=espresso_system, use_default_bond=use_default_bond) + elif pmb_type == 'residue': + side_residue_tpl = self.db.get_template(name=side_chain_name, pmb_type=pmb_type) central_bead_side_chain = side_residue_tpl.central_bead @@ -1363,7 +1360,7 @@ def create_residue(self, name, espresso_system, central_bead_position=None,use_d residue_position=central_bead_position+self.generate_trial_perpendicular_vector(vector=backbone_vector, magnitude=l0) side_residue_id = self.create_residue(name=side_chain_name, - espresso_system=espresso_system, + box_l=box_l, central_bead_position=[residue_position], use_default_bond=use_default_bond) # Find particle ids of the inner residue @@ -1381,7 +1378,6 @@ def create_residue(self, name, espresso_system, central_bead_position=None,use_d instance_id=side_residue_id) self.create_bond(particle_id1=central_bead_id, particle_id2=side_chain_beads_ids[0], - espresso_system=espresso_system, use_default_bond=use_default_bond) return residue_id @@ -1749,6 +1745,7 @@ def define_residue(self, name, central_bead, side_chains): side_chains=side_chains) self.db._register_template(tpl) + def delete_instances_in_system(self, instance_id, pmb_type, espresso_system): """ Deletes the instance with instance_id from the ESPResSo system. @@ -2565,6 +2562,18 @@ def set_reduced_units(self, unit_length=None, unit_charge=None, temperature=None self.units.define(f'reduced_charge = {unit_charge}') logging.info(self.get_reduced_units()) + def set_simulation_engine(self,simulation_engine,box_l=None): + if isinstance(simulation_engine,EspressoSystemProtocol): + self.simulation_engine=EspressoSimulation(box_l=simulation_engine.box_l, + db=self.db, + espresso_system=simulation_engine, + units=self.units) + elif 'lammps' in type(simulation_engine): + self.simulation_engine=LammpsSimulation(box_l=box_l, + db=self.db) + else: + raise ValueError('The specified simulation engine is not implemented yet') + def setup_cpH (self, counter_ion, constant_pH, exclusion_range=None, use_exclusion_radius_per_type = False): """ Sets up the Acid/Base reactions for acidic/basic particles defined in the pyMBE database From aa70a2591c56ff4935d2d45117bf8218ac5afdb4 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 16 Apr 2026 14:16:45 +0200 Subject: [PATCH 07/75] modify base classes to base engine. Delete engine factory --- .../{base_classes.py => base_engine.py} | 4 ++-- pyMBE/simulation_builder/engine_factory.py | 12 ------------ 2 files changed, 2 insertions(+), 14 deletions(-) rename pyMBE/simulation_builder/{base_classes.py => base_engine.py} (82%) delete mode 100644 pyMBE/simulation_builder/engine_factory.py diff --git a/pyMBE/simulation_builder/base_classes.py b/pyMBE/simulation_builder/base_engine.py similarity index 82% rename from pyMBE/simulation_builder/base_classes.py rename to pyMBE/simulation_builder/base_engine.py index 1245ffc5..3d43d7d4 100644 --- a/pyMBE/simulation_builder/base_classes.py +++ b/pyMBE/simulation_builder/base_engine.py @@ -1,6 +1,6 @@ from abc import ABC,abstractmethod -class SimulationBuilder(ABC): +class SimulationEngine(ABC): def __init__(self): pass @abstractmethod @@ -13,5 +13,5 @@ def _create_bond_instance(self): def _get_bond_instance(self): return @abstractmethod - def save_molecule(self): + def add_instances_to_engine(self): return \ No newline at end of file diff --git a/pyMBE/simulation_builder/engine_factory.py b/pyMBE/simulation_builder/engine_factory.py deleted file mode 100644 index 20d71b18..00000000 --- a/pyMBE/simulation_builder/engine_factory.py +++ /dev/null @@ -1,12 +0,0 @@ -from espresso_engine import EspressoSimulation -from lammps_engine import LammpsSimulation - -class EngineFactory: - @staticmethod - def get_simulation_engine(engine_name,box_l,db): - if engine_name=='espresso': - return EspressoSimulation(Box_L=box_l,db=db) - elif engine_name=='lammps': - return LammpsSimulation() - else: - raise ValueError('Only engines "espresso" and "lammps" have been implemented') \ No newline at end of file From dd74d6c9679490f489d5dd2362ee4532229fa498 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 16 Apr 2026 14:17:15 +0200 Subject: [PATCH 08/75] Add espresso engine methods - algorithm to add instances to espresso system --- pyMBE/simulation_builder/espresso_engine.py | 71 ++++++++++++++++++--- 1 file changed, 63 insertions(+), 8 deletions(-) diff --git a/pyMBE/simulation_builder/espresso_engine.py b/pyMBE/simulation_builder/espresso_engine.py index b37b96de..96dbe5c4 100644 --- a/pyMBE/simulation_builder/espresso_engine.py +++ b/pyMBE/simulation_builder/espresso_engine.py @@ -1,13 +1,14 @@ -from base_classes import SimulationBuilder +from pyMBE.simulation_builder.base_engine import SimulationEngine import espressomd -class EspressoSimulation(SimulationBuilder): - def __init__(self,box_l,db): +class EspressoSimulation(SimulationEngine): + def __init__(self,box_l,db,espresso_system,units): self.db=db self.box_l=box_l - self.espresso_system=espressomd.System(box_l = [self.box_l.to('reduced_length').magnitude]*3) + self.espresso_system=espresso_system + self.units=units pass def _check_bond_inputs(self, bond_type, bond_parameters): @@ -69,7 +70,7 @@ def _create_bond_instance(self, bond_type, bond_parameters): d_r_max = bond_parameters["d_r_max"].m_as("reduced_length")) return bond_instance - def _get_bond_instance(self, bond_template, espresso_system): + def _get_bond_instance(self, bond_template): """ Retrieve or create a bond instance in an ESPResSo system for a given pair of particle names. @@ -93,9 +94,63 @@ def _get_bond_instance(self, bond_template, espresso_system): bond_inst = self._create_bond_instance(bond_type=bond_template.bond_type, bond_parameters=bond_template.get_parameters(self.units)) self.db.espresso_bond_instances[bond_template.name]= bond_inst - espresso_system.bonded_inter.add(bond_inst) + self.espresso_system.bonded_inter.add(bond_inst) return bond_inst + + def _add_bond(self,particle_id1,particle_id2,bond_inst): + bond_tpl=self.db.get_template(name=bond_inst.name, + pmb_type="bond") + espresso_bond_inst=self._get_bond_instance(bond_template=bond_tpl) + self.espresso_system.part.by_id(particle_id1).add_bond((espresso_bond_inst, particle_id2)) + + def _add_particle(self,particle_id): + particle_instance=self.db.get_instance(pmb_type='particle', + instance_id=particle_id) + # part_tpl = self.db.get_template(pmb_type="particle", + # name=particle_instance.name) + part_state = self.db.get_template(pmb_type="particle_state", + name=particle_instance.initial_state) + + if particle_instance.fix: + kwargs = dict(id=particle_id, pos=particle_instance.position, type=part_state.es_type, q=part_state.z,fix=particle_instance.fix) + else: + kwargs = dict(id=particle_id, pos=particle_instance.position, type=part_state.es_type, q=part_state.z) + + self.espresso_system.part.add(**kwargs) + def get_box_side_length(self): - return self.Box_L - def save_molecule(self): + return self.box_l + + + def add_instances_to_engine(self): + ### test the method + bond_instances=self.db._get_instances_df(pmb_type='bond') + particle_instances=self.db._get_instances_df(pmb_type='particle') + if bond_instances.index.size>0: + + particles_added=set() + for i in range(bond_instances.index.size): + bond_instance=self.db.get_instance(pmb_type='bond', + instance_id=i) + particle_id1=bond_instance.particle_id1 + particle_id2=bond_instance.particle_id2 + + if particle_id1 not in particles_added: + self._add_particle(particle_id1) + particles_added.add(particle_id1) + + if particle_id2 not in particles_added: + self._add_particle(particle_id2) + particles_added.add(particle_id2) + + self._add_bond(particle_id1,particle_id2,bond_instance) + + elif particle_instances.index.size>0: + for i in range(particle_instances.index.size): + self._add_particle(i) + else: + raise RuntimeError('No particles, residues or molecules have been created so far') + + + return From 08b245329b7c9031f914dbfac3750ec6b785e311 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 16 Apr 2026 14:18:11 +0200 Subject: [PATCH 09/75] Add Espresso protocol classes to simulate the structure of the espresso system object --- pyMBE/simulation_builder/engine_protocol.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 pyMBE/simulation_builder/engine_protocol.py diff --git a/pyMBE/simulation_builder/engine_protocol.py b/pyMBE/simulation_builder/engine_protocol.py new file mode 100644 index 00000000..1e65de2a --- /dev/null +++ b/pyMBE/simulation_builder/engine_protocol.py @@ -0,0 +1,17 @@ +from typing import Protocol,runtime_checkable + +class EspressoParticleProtocol(Protocol): + def add(): + return + def by_id(): + return +class EspressoBondedInterProtocol(Protocol): + 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 From 4d5163d0f96377824a45ffc56904decf28317c40 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 16 Apr 2026 14:19:09 +0200 Subject: [PATCH 10/75] Modify manager _get_particle_instances to just add position and fix rows to the instance dataframe --- pyMBE/storage/manager.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pyMBE/storage/manager.py b/pyMBE/storage/manager.py index 041e4538..3a2e13c6 100644 --- a/pyMBE/storage/manager.py +++ b/pyMBE/storage/manager.py @@ -256,10 +256,8 @@ def _get_instances_df(self, pmb_type): rows.append({"pmb_type": pmb_type, "name": inst.name, "particle_id": inst.particle_id, - "particle_label": inst.particle_label, - "particle_charge": inst.particle_charge, - "particle_position":inst.particle_position, - "particle_fix":inst.particle_fix, + "position":inst.position, + "fix":inst.fix, "initial_state": inst.initial_state, "residue_id": int(inst.residue_id) if inst.residue_id is not None else pd.NA, "molecule_id": int(inst.molecule_id) if inst.molecule_id is not None else pd.NA, From 10fa7935accaf4356165079cb4a46d23cd63d989 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 16 Apr 2026 14:20:26 +0200 Subject: [PATCH 11/75] Modify pydantic validation for particle instances enabling arbitrary type in config class in order to be able to set the position as NDarrays --- pyMBE/storage/instances/particle.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/pyMBE/storage/instances/particle.py b/pyMBE/storage/instances/particle.py index 6ed9aeb3..29067236 100644 --- a/pyMBE/storage/instances/particle.py +++ b/pyMBE/storage/instances/particle.py @@ -17,10 +17,15 @@ # along with this program. If not, see . # -from typing import Literal, Optional,List +from typing import Literal, Optional,List,Annotated +from numpy.typing import NDArray from pydantic import validator from ..base_type import PMBBaseModel +def validate_position(position): + if not isinstance(position,NDArray): + raise TypeError("Position has to be a numpy array") + return position class ParticleInstance(PMBBaseModel): """ @@ -56,14 +61,17 @@ class ParticleInstance(PMBBaseModel): name: str particle_id: int initial_state: str - particle_charge: int - particle_label: str - particle_position: List[float] - particle_fix: Optional[List[bool]]=None + position: Annotated[NDArray,validate_position] + fix: Optional[List[bool]]=None residue_id: Optional[int] = None molecule_id: Optional[int] = None assembly_id: Optional[int] = None - + + class Config: + arbitrary_types_allowed=True + validate_assignment = True + extra = "forbid" + @validator("particle_id") def validate_particle_id(cls, pid): if pid < 0: From 764c716db1b6ffe998971cbd50dfb41db34d1b92 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 16 Apr 2026 14:21:00 +0200 Subject: [PATCH 12/75] Add modifications to pymbe tutorial according to the decoupling of espresso from pymbe --- tutorials/pyMBE_tutorial.ipynb | 3035 ++++++++++++++------------------ 1 file changed, 1329 insertions(+), 1706 deletions(-) diff --git a/tutorials/pyMBE_tutorial.ipynb b/tutorials/pyMBE_tutorial.ipynb index d35dc2ea..b5d71075 100644 --- a/tutorials/pyMBE_tutorial.ipynb +++ b/tutorials/pyMBE_tutorial.ipynb @@ -52,6 +52,13 @@ "from espressomd import interactions" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "markdown", "metadata": {}, @@ -134,7 +141,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -191,23 +198,26 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "The side of the simulation box is 7.5 nanometer = 21.126760563380284 reduced_length\n" + "The side of the simulation box is 7.5 nanometer = 14.999999999999998 reduced_length\n", + " type\n" ] } ], "source": [ "Box_L = 7.5*pmb.units.nm\n", + "box_l=[Box_L.to('reduced_length').magnitude]*3\n", "\n", - "espresso_system = espressomd.System(box_l = [Box_L.to('reduced_length').magnitude]*3)\n", + "espresso_system = espressomd.System(box_l = box_l)\n", "\n", - "print('The side of the simulation box is ', Box_L, '=' ,Box_L.to('reduced_length'))" + "print('The side of the simulation box is ', Box_L, '=' ,Box_L.to('reduced_length'))\n", + "print(type(espresso_system),\"type\")" ] }, { @@ -226,7 +236,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -246,7 +256,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -302,7 +312,7 @@ "0 0.5612310241546864 nanometer 0.0 nanometer Na " ] }, - "execution_count": 12, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -320,7 +330,28 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cation_name\n", + "pmb.db._has_template(name=cation_name, pmb_type=\"particle\")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -329,7 +360,7 @@ "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]" ] }, - "execution_count": 13, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -338,7 +369,7 @@ "N_cations = 20\n", "pmb.create_particle(name = cation_name,\n", " number_of_particles = N_cations,\n", - " espresso_system = espresso_system)" + " box_l=box_l)" ] }, { @@ -350,7 +381,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -377,6 +408,8 @@ " pmb_type\n", " name\n", " particle_id\n", + " position\n", + " fix\n", " initial_state\n", " residue_id\n", " molecule_id\n", @@ -389,6 +422,8 @@ " particle\n", " Na\n", " 0\n", + " [11.609340728339449, 6.583176596280784, 12.878...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -399,6 +434,8 @@ " particle\n", " Na\n", " 1\n", + " [10.460520435890457, 1.4126602183147428, 14.63...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -409,6 +446,8 @@ " particle\n", " Na\n", " 2\n", + " [11.417095529855294, 11.790964579154306, 1.921...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -419,6 +458,8 @@ " particle\n", " Na\n", " 3\n", + " [6.755789068433506, 5.561970363488718, 13.9014...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -429,6 +470,8 @@ " particle\n", " Na\n", " 4\n", + " [9.657976801209967, 12.341424199062448, 6.6512...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -439,6 +482,8 @@ " particle\n", " Na\n", " 5\n", + " [3.408580826771653, 8.318771805237521, 0.95725...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -449,6 +494,8 @@ " particle\n", " Na\n", " 6\n", + " [12.41446757988873, 9.474965986830972, 11.3713...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -459,6 +506,8 @@ " particle\n", " Na\n", " 7\n", + " [5.3178895219480244, 14.560470365923548, 13.39...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -469,6 +518,8 @@ " particle\n", " Na\n", " 8\n", + " [11.675752456106427, 2.919580617779513, 7.0008...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -479,6 +530,8 @@ " particle\n", " Na\n", " 9\n", + " [0.6570564868084315, 2.3143423810132173, 10.24...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -489,6 +542,8 @@ " particle\n", " Na\n", " 10\n", + " [11.171432338617256, 14.512645986513148, 4.887...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -499,6 +554,8 @@ " particle\n", " Na\n", " 11\n", + " [5.556895590523033, 7.043337169137118, 2.84207...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -509,6 +566,8 @@ " particle\n", " Na\n", " 12\n", + " [1.9488225800320744, 7.135573893389005, 3.4036...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -519,6 +578,8 @@ " particle\n", " Na\n", " 13\n", + " [10.047209920237654, 6.557278783084961, 12.490...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -529,6 +590,8 @@ " particle\n", " Na\n", " 14\n", + " [10.503976530033736, 4.685499620730615, 12.483...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -539,6 +602,8 @@ " particle\n", " Na\n", " 15\n", + " [12.071465362452027, 5.812175685452616, 4.3249...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -549,6 +614,8 @@ " particle\n", " Na\n", " 16\n", + " [10.237432559624631, 2.096287254139647, 2.9986...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -559,6 +626,8 @@ " particle\n", " Na\n", " 17\n", + " [0.11043404626508267, 11.803865662532074, 9.97...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -569,6 +638,8 @@ " particle\n", " Na\n", " 18\n", + " [10.577480679395025, 11.710935465329516, 6.883...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -579,6 +650,8 @@ " particle\n", " Na\n", " 19\n", + " [8.531117939293406, 2.0969549719148612, 1.7179...\n", + " None\n", " Na\n", " <NA>\n", " <NA>\n", @@ -589,52 +662,74 @@ "" ], "text/plain": [ - " pmb_type name particle_id initial_state residue_id molecule_id \\\n", - "0 particle Na 0 Na \n", - "1 particle Na 1 Na \n", - "2 particle Na 2 Na \n", - "3 particle Na 3 Na \n", - "4 particle Na 4 Na \n", - "5 particle Na 5 Na \n", - "6 particle Na 6 Na \n", - "7 particle Na 7 Na \n", - "8 particle Na 8 Na \n", - "9 particle Na 9 Na \n", - "10 particle Na 10 Na \n", - "11 particle Na 11 Na \n", - "12 particle Na 12 Na \n", - "13 particle Na 13 Na \n", - "14 particle Na 14 Na \n", - "15 particle Na 15 Na \n", - "16 particle Na 16 Na \n", - "17 particle Na 17 Na \n", - "18 particle Na 18 Na \n", - "19 particle Na 19 Na \n", + " pmb_type name particle_id \\\n", + "0 particle Na 0 \n", + "1 particle Na 1 \n", + "2 particle Na 2 \n", + "3 particle Na 3 \n", + "4 particle Na 4 \n", + "5 particle Na 5 \n", + "6 particle Na 6 \n", + "7 particle Na 7 \n", + "8 particle Na 8 \n", + "9 particle Na 9 \n", + "10 particle Na 10 \n", + "11 particle Na 11 \n", + "12 particle Na 12 \n", + "13 particle Na 13 \n", + "14 particle Na 14 \n", + "15 particle Na 15 \n", + "16 particle Na 16 \n", + "17 particle Na 17 \n", + "18 particle Na 18 \n", + "19 particle Na 19 \n", + "\n", + " position fix initial_state \\\n", + "0 [11.609340728339449, 6.583176596280784, 12.878... None Na \n", + "1 [10.460520435890457, 1.4126602183147428, 14.63... None Na \n", + "2 [11.417095529855294, 11.790964579154306, 1.921... None Na \n", + "3 [6.755789068433506, 5.561970363488718, 13.9014... None Na \n", + "4 [9.657976801209967, 12.341424199062448, 6.6512... None Na \n", + "5 [3.408580826771653, 8.318771805237521, 0.95725... None Na \n", + "6 [12.41446757988873, 9.474965986830972, 11.3713... None Na \n", + "7 [5.3178895219480244, 14.560470365923548, 13.39... None Na \n", + "8 [11.675752456106427, 2.919580617779513, 7.0008... None Na \n", + "9 [0.6570564868084315, 2.3143423810132173, 10.24... None Na \n", + "10 [11.171432338617256, 14.512645986513148, 4.887... None Na \n", + "11 [5.556895590523033, 7.043337169137118, 2.84207... None Na \n", + "12 [1.9488225800320744, 7.135573893389005, 3.4036... None Na \n", + "13 [10.047209920237654, 6.557278783084961, 12.490... None Na \n", + "14 [10.503976530033736, 4.685499620730615, 12.483... None Na \n", + "15 [12.071465362452027, 5.812175685452616, 4.3249... None Na \n", + "16 [10.237432559624631, 2.096287254139647, 2.9986... None Na \n", + "17 [0.11043404626508267, 11.803865662532074, 9.97... None Na \n", + "18 [10.577480679395025, 11.710935465329516, 6.883... None Na \n", + "19 [8.531117939293406, 2.0969549719148612, 1.7179... None Na \n", "\n", - " assembly_id \n", - "0 \n", - "1 \n", - "2 \n", - "3 \n", - "4 \n", - "5 \n", - "6 \n", - "7 \n", - "8 \n", - "9 \n", - "10 \n", - "11 \n", - "12 \n", - "13 \n", - "14 \n", - "15 \n", - "16 \n", - "17 \n", - "18 \n", - "19 " + " residue_id molecule_id assembly_id \n", + "0 \n", + "1 \n", + "2 \n", + "3 \n", + "4 \n", + "5 \n", + "6 \n", + "7 \n", + "8 \n", + "9 \n", + "10 \n", + "11 \n", + "12 \n", + "13 \n", + "14 \n", + "15 \n", + "16 \n", + "17 \n", + "18 \n", + "19 " ] }, - "execution_count": 14, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -643,6 +738,16 @@ "pmb.get_instances_df(pmb_type = 'particle')" ] }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.set_simulation_engine(espresso_system)\n", + "pmb.add_instances_to_engine()" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -652,21 +757,38 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 8, "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'espresso_system' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[4], line 24\u001b[0m\n\u001b[1;32m 22\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[1;32m 23\u001b[0m picture_name \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mcation_system.png\u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[0;32m---> 24\u001b[0m create_snapshot_of_espresso_system(espresso_system \u001b[38;5;241m=\u001b[39m \u001b[43mespresso_system\u001b[49m, \n\u001b[1;32m 25\u001b[0m filename \u001b[38;5;241m=\u001b[39m picture_name)\n\u001b[1;32m 26\u001b[0m img \u001b[38;5;241m=\u001b[39m Image\u001b[38;5;241m.\u001b[39mopen(picture_name)\n\u001b[1;32m 27\u001b[0m img\u001b[38;5;241m.\u001b[39mshow()\n", - "\u001b[0;31mNameError\u001b[0m: name 'espresso_system' is not defined" - ] - } - ], + "outputs": [], + "source": [ + "from PIL import Image\n", + "def create_snapshot_of_espresso_system(espresso_system, filename):\n", + " \"\"\"\n", + " Uses espresso visualizer for creating a snapshot of the current state of the espresso_system\n", + "\n", + " Args:\n", + " espresso_system(`espressomd.system.System`): Instance of a system object from the espressomd library.\n", + " filename(`str`): Name of the ouput file for the snapshot\n", + " \"\"\" \n", + " from espressomd import visualization\n", + " visualizer = visualization.openGLLive(\n", + " espresso_system, bond_type_radius=[0.3], particle_coloring='type', draw_axis=False, background_color=[1, 1, 1],\n", + " particle_type_colors=[[1.02,0.51,0], # Brown\n", + " [1,1,1], # Grey\n", + " [2.55,0,0], # Red\n", + " [0,0,2.05], # Blue\n", + " [0,0,2.05], # Blue\n", + " [2.55,0,0], # Red\n", + " [2.05,1.02,0]]) # Orange\n", + " visualizer.screenshot(filename)\n", + " return" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], "source": [ "# Only necessary to produce the pictures used in this tutorial\n", "from PIL import Image\n", @@ -706,21 +828,9 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 18, "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'cation_name' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[43], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# First search for the ids of the particles to delete\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m particle_id_map \u001b[38;5;241m=\u001b[39m pmb\u001b[38;5;241m.\u001b[39mget_particle_id_map(object_name\u001b[38;5;241m=\u001b[39m\u001b[43mcation_name\u001b[49m)\n\u001b[1;32m 3\u001b[0m \u001b[38;5;66;03m# This will delete all particles that we created before\u001b[39;00m\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m pid \u001b[38;5;129;01min\u001b[39;00m particle_id_map[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mall\u001b[39m\u001b[38;5;124m\"\u001b[39m]:\n", - "\u001b[0;31mNameError\u001b[0m: name 'cation_name' is not defined" - ] - } - ], + "outputs": [], "source": [ "# First search for the ids of the particles to delete\n", "particle_id_map = pmb.get_particle_id_map(object_name=cation_name)\n", @@ -740,7 +850,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -777,7 +887,7 @@ "Index: []" ] }, - "execution_count": 17, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -812,7 +922,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -836,6 +946,97 @@ " epsilon = 1*pmb.units('reduced_energy'))\n" ] }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
pmb_typenamesigmaepsiloncutoffoffsetinitial_state
0particleBB-PDha0.4 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerBB-PDha
1particleCOOH-PDha0.5 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerCOOH-PDha
2particleNH3-PDha0.3 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerNH3-PDha
\n", + "
" + ], + "text/plain": [ + " pmb_type name sigma epsilon \\\n", + "0 particle BB-PDha 0.4 nanometer 25.692579121085853 millielectron_volt \n", + "1 particle COOH-PDha 0.5 nanometer 25.692579121085853 millielectron_volt \n", + "2 particle NH3-PDha 0.3 nanometer 25.692579121085853 millielectron_volt \n", + "\n", + " cutoff offset initial_state \n", + "0 0.5612310241546864 nanometer 0.0 nanometer BB-PDha \n", + "1 0.5612310241546864 nanometer 0.0 nanometer COOH-PDha \n", + "2 0.5612310241546864 nanometer 0.0 nanometer NH3-PDha " + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pmb.get_templates_df(pmb_type = 'particle')" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -845,7 +1046,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -865,7 +1066,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -912,7 +1113,7 @@ "0 residue PDha_mon BB-PDha [COOH-PDha, NH3-PDha]" ] }, - "execution_count": 50, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -930,7 +1131,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -957,7 +1158,7 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -1033,7 +1234,7 @@ "2 {'r_0': 0.4 nanometer, 'k': 41108.126593737354... " ] }, - "execution_count": 56, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -1058,12 +1259,12 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "PDha_polymer = 'PDha'\n", - "N_monomers = 10\n", + "N_monomers = 2\n", "\n", "pmb.define_molecule(name = PDha_polymer,\n", " residue_list = [PDha_residue]*N_monomers)" @@ -1078,7 +1279,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -1112,18 +1313,18 @@ " 0\n", " molecule\n", " PDha\n", - " [PDha_mon, PDha_mon, PDha_mon, PDha_mon, PDha_...\n", + " [PDha_mon, PDha_mon]\n", " \n", " \n", "\n", "" ], "text/plain": [ - " pmb_type name residue_list\n", - "0 molecule PDha [PDha_mon, PDha_mon, PDha_mon, PDha_mon, PDha_..." + " pmb_type name residue_list\n", + "0 molecule PDha [PDha_mon, PDha_mon]" ] }, - "execution_count": 58, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -1141,7 +1342,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -1149,7 +1350,7 @@ "\n", "molecule_ids = pmb.create_molecule(name = PDha_polymer, \n", " number_of_molecules = N_polymers,\n", - " espresso_system = espresso_system, \n", + " box_l = box_l, \n", " list_of_first_residue_positions = [[Box_L.to('reduced_length').magnitude/2]*3]) " ] }, @@ -1162,7 +1363,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -1189,6 +1390,8 @@ " pmb_type\n", " name\n", " particle_id\n", + " position\n", + " fix\n", " initial_state\n", " residue_id\n", " molecule_id\n", @@ -1201,6 +1404,8 @@ " particle\n", " BB-PDha\n", " 0\n", + " [7.499999999999999, 7.499999999999999, 7.49999...\n", + " None\n", " BB-PDha\n", " 0\n", " 0\n", @@ -1211,6 +1416,8 @@ " particle\n", " COOH-PDha\n", " 1\n", + " [7.770562720511088, 7.059202339683819, 6.77927...\n", + " None\n", " COOH-PDha\n", " 0\n", " 0\n", @@ -1221,6 +1428,8 @@ " particle\n", " NH3-PDha\n", " 2\n", + " [7.749050564056614, 7.106238951223266, 6.85319...\n", + " None\n", " NH3-PDha\n", " 0\n", " 0\n", @@ -1231,6 +1440,8 @@ " particle\n", " BB-PDha\n", " 3\n", + " [7.692460718229277, 6.8431412239990514, 7.9739...\n", + " None\n", " BB-PDha\n", " 1\n", " 0\n", @@ -1241,6 +1452,8 @@ " particle\n", " COOH-PDha\n", " 4\n", + " [7.2107917459456745, 7.181071829992744, 8.6378...\n", + " None\n", " COOH-PDha\n", " 1\n", " 0\n", @@ -1251,1009 +1464,223 @@ " particle\n", " NH3-PDha\n", " 5\n", + " [7.847768489420128, 7.330068748851457, 8.58571...\n", + " None\n", " NH3-PDha\n", " 1\n", " 0\n", " <NA>\n", " \n", - " \n", - " 6\n", - " particle\n", - " BB-PDha\n", - " 6\n", - " BB-PDha\n", - " 2\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 7\n", - " particle\n", - " COOH-PDha\n", - " 7\n", - " COOH-PDha\n", - " 2\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 8\n", - " particle\n", - " NH3-PDha\n", - " 8\n", - " NH3-PDha\n", - " 2\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 9\n", - " particle\n", - " BB-PDha\n", - " 9\n", - " BB-PDha\n", - " 3\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 10\n", - " particle\n", - " COOH-PDha\n", - " 10\n", - " COOH-PDha\n", - " 3\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 11\n", - " particle\n", - " NH3-PDha\n", - " 11\n", - " NH3-PDha\n", - " 3\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 12\n", - " particle\n", - " BB-PDha\n", - " 12\n", - " BB-PDha\n", - " 4\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 13\n", - " particle\n", - " COOH-PDha\n", - " 13\n", - " COOH-PDha\n", - " 4\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 14\n", - " particle\n", - " NH3-PDha\n", - " 14\n", - " NH3-PDha\n", - " 4\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 15\n", - " particle\n", - " BB-PDha\n", - " 15\n", - " BB-PDha\n", - " 5\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 16\n", - " particle\n", - " COOH-PDha\n", - " 16\n", - " COOH-PDha\n", - " 5\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 17\n", - " particle\n", - " NH3-PDha\n", - " 17\n", - " NH3-PDha\n", - " 5\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 18\n", - " particle\n", - " BB-PDha\n", - " 18\n", - " BB-PDha\n", - " 6\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 19\n", - " particle\n", - " COOH-PDha\n", - " 19\n", - " COOH-PDha\n", - " 6\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 20\n", - " particle\n", - " NH3-PDha\n", - " 20\n", - " NH3-PDha\n", - " 6\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 21\n", - " particle\n", - " BB-PDha\n", - " 21\n", - " BB-PDha\n", - " 7\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 22\n", - " particle\n", - " COOH-PDha\n", - " 22\n", - " COOH-PDha\n", - " 7\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 23\n", - " particle\n", - " NH3-PDha\n", - " 23\n", - " NH3-PDha\n", - " 7\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 24\n", - " particle\n", - " BB-PDha\n", - " 24\n", - " BB-PDha\n", - " 8\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 25\n", - " particle\n", - " COOH-PDha\n", - " 25\n", - " COOH-PDha\n", - " 8\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 26\n", - " particle\n", - " NH3-PDha\n", - " 26\n", - " NH3-PDha\n", - " 8\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 27\n", - " particle\n", - " BB-PDha\n", - " 27\n", - " BB-PDha\n", - " 9\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 28\n", - " particle\n", - " COOH-PDha\n", - " 28\n", - " COOH-PDha\n", - " 9\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 29\n", - " particle\n", - " NH3-PDha\n", - " 29\n", - " NH3-PDha\n", - " 9\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - "\n", - "" - ], - "text/plain": [ - " pmb_type name particle_id initial_state residue_id molecule_id \\\n", - "0 particle BB-PDha 0 BB-PDha 0 0 \n", - "1 particle COOH-PDha 1 COOH-PDha 0 0 \n", - "2 particle NH3-PDha 2 NH3-PDha 0 0 \n", - "3 particle BB-PDha 3 BB-PDha 1 0 \n", - "4 particle COOH-PDha 4 COOH-PDha 1 0 \n", - "5 particle NH3-PDha 5 NH3-PDha 1 0 \n", - "6 particle BB-PDha 6 BB-PDha 2 0 \n", - "7 particle COOH-PDha 7 COOH-PDha 2 0 \n", - "8 particle NH3-PDha 8 NH3-PDha 2 0 \n", - "9 particle BB-PDha 9 BB-PDha 3 0 \n", - "10 particle COOH-PDha 10 COOH-PDha 3 0 \n", - "11 particle NH3-PDha 11 NH3-PDha 3 0 \n", - "12 particle BB-PDha 12 BB-PDha 4 0 \n", - "13 particle COOH-PDha 13 COOH-PDha 4 0 \n", - "14 particle NH3-PDha 14 NH3-PDha 4 0 \n", - "15 particle BB-PDha 15 BB-PDha 5 0 \n", - "16 particle COOH-PDha 16 COOH-PDha 5 0 \n", - "17 particle NH3-PDha 17 NH3-PDha 5 0 \n", - "18 particle BB-PDha 18 BB-PDha 6 0 \n", - "19 particle COOH-PDha 19 COOH-PDha 6 0 \n", - "20 particle NH3-PDha 20 NH3-PDha 6 0 \n", - "21 particle BB-PDha 21 BB-PDha 7 0 \n", - "22 particle COOH-PDha 22 COOH-PDha 7 0 \n", - "23 particle NH3-PDha 23 NH3-PDha 7 0 \n", - "24 particle BB-PDha 24 BB-PDha 8 0 \n", - "25 particle COOH-PDha 25 COOH-PDha 8 0 \n", - "26 particle NH3-PDha 26 NH3-PDha 8 0 \n", - "27 particle BB-PDha 27 BB-PDha 9 0 \n", - "28 particle COOH-PDha 28 COOH-PDha 9 0 \n", - "29 particle NH3-PDha 29 NH3-PDha 9 0 \n", - "\n", - " assembly_id \n", - "0 \n", - "1 \n", - "2 \n", - "3 \n", - "4 \n", - "5 \n", - "6 \n", - "7 \n", - "8 \n", - "9 \n", - "10 \n", - "11 \n", - "12 \n", - "13 \n", - "14 \n", - "15 \n", - "16 \n", - "17 \n", - "18 \n", - "19 \n", - "20 \n", - "21 \n", - "22 \n", - "23 \n", - "24 \n", - "25 \n", - "26 \n", - "27 \n", - "28 \n", - "29 " - ] - }, - "execution_count": 60, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Check particle instances\n", - "pmb.get_instances_df(pmb_type = 'particle')\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenamebond_idparticle_id1particle_id2
0bondBB-PDha-COOH-PDha001
1bondBB-PDha-NH3-PDha102
2bondBB-PDha-COOH-PDha234
3bondBB-PDha-NH3-PDha335
4bondBB-PDha-BB-PDha403
5bondBB-PDha-COOH-PDha567
6bondBB-PDha-NH3-PDha668
7bondBB-PDha-BB-PDha736
8bondBB-PDha-COOH-PDha8910
9bondBB-PDha-NH3-PDha9911
10bondBB-PDha-BB-PDha1069
11bondBB-PDha-COOH-PDha111213
12bondBB-PDha-NH3-PDha121214
13bondBB-PDha-BB-PDha13912
14bondBB-PDha-COOH-PDha141516
15bondBB-PDha-NH3-PDha151517
16bondBB-PDha-BB-PDha161215
17bondBB-PDha-COOH-PDha171819
18bondBB-PDha-NH3-PDha181820
19bondBB-PDha-BB-PDha191518
20bondBB-PDha-COOH-PDha202122
21bondBB-PDha-NH3-PDha212123
22bondBB-PDha-BB-PDha221821
23bondBB-PDha-COOH-PDha232425
24bondBB-PDha-NH3-PDha242426
25bondBB-PDha-BB-PDha252124
26bondBB-PDha-COOH-PDha262728
27bondBB-PDha-NH3-PDha272729
28bondBB-PDha-BB-PDha282427
\n", - "
" - ], - "text/plain": [ - " pmb_type name bond_id particle_id1 particle_id2\n", - "0 bond BB-PDha-COOH-PDha 0 0 1\n", - "1 bond BB-PDha-NH3-PDha 1 0 2\n", - "2 bond BB-PDha-COOH-PDha 2 3 4\n", - "3 bond BB-PDha-NH3-PDha 3 3 5\n", - "4 bond BB-PDha-BB-PDha 4 0 3\n", - "5 bond BB-PDha-COOH-PDha 5 6 7\n", - "6 bond BB-PDha-NH3-PDha 6 6 8\n", - "7 bond BB-PDha-BB-PDha 7 3 6\n", - "8 bond BB-PDha-COOH-PDha 8 9 10\n", - "9 bond BB-PDha-NH3-PDha 9 9 11\n", - "10 bond BB-PDha-BB-PDha 10 6 9\n", - "11 bond BB-PDha-COOH-PDha 11 12 13\n", - "12 bond BB-PDha-NH3-PDha 12 12 14\n", - "13 bond BB-PDha-BB-PDha 13 9 12\n", - "14 bond BB-PDha-COOH-PDha 14 15 16\n", - "15 bond BB-PDha-NH3-PDha 15 15 17\n", - "16 bond BB-PDha-BB-PDha 16 12 15\n", - "17 bond BB-PDha-COOH-PDha 17 18 19\n", - "18 bond BB-PDha-NH3-PDha 18 18 20\n", - "19 bond BB-PDha-BB-PDha 19 15 18\n", - "20 bond BB-PDha-COOH-PDha 20 21 22\n", - "21 bond BB-PDha-NH3-PDha 21 21 23\n", - "22 bond BB-PDha-BB-PDha 22 18 21\n", - "23 bond BB-PDha-COOH-PDha 23 24 25\n", - "24 bond BB-PDha-NH3-PDha 24 24 26\n", - "25 bond BB-PDha-BB-PDha 25 21 24\n", - "26 bond BB-PDha-COOH-PDha 26 27 28\n", - "27 bond BB-PDha-NH3-PDha 27 27 29\n", - "28 bond BB-PDha-BB-PDha 28 24 27" - ] - }, - "execution_count": 61, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pmb.get_instances_df(pmb_type='bond')" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
\n", - "
" - ], - "text/plain": [ - "Empty DataFrame\n", - "Columns: []\n", - "Index: []" - ] - }, - "execution_count": 47, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Check residue instances\n", - "pmb.get_instances_df(pmb_type = 'residue')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + "
pmb_typenamebond_idparticle_id1particle_id2
0bondBB-PDha-COOH-PDha001
1bondBB-PDha-NH3-PDha102
2bondBB-PDha-COOH-PDha234
3bondBB-PDha-NH3-PDha335
4bondBB-PDha-BB-PDha403
5bondBB-PDha-COOH-PDha567
6bondBB-PDha-NH3-PDha668
7bondBB-PDha-BB-PDha736
8bondBB-PDha-COOH-PDha8910
9bondBB-PDha-NH3-PDha9911
10bondBB-PDha-BB-PDha1069
11bondBB-PDha-COOH-PDha111213
12bondBB-PDha-NH3-PDha121214
13bondBB-PDha-BB-PDha13912
14bondBB-PDha-COOH-PDha141516
15bondBB-PDha-NH3-PDha151517
16bondBB-PDha-BB-PDha161215
17bondBB-PDha-COOH-PDha171819
18bondBB-PDha-NH3-PDha181820
19bondBB-PDha-BB-PDha191518
\n", + "
" + ], + "text/plain": [ + " pmb_type name particle_id \\\n", + "0 particle BB-PDha 0 \n", + "1 particle COOH-PDha 1 \n", + "2 particle NH3-PDha 2 \n", + "3 particle BB-PDha 3 \n", + "4 particle COOH-PDha 4 \n", + "5 particle NH3-PDha 5 \n", + "\n", + " position fix initial_state \\\n", + "0 [7.499999999999999, 7.499999999999999, 7.49999... None BB-PDha \n", + "1 [7.770562720511088, 7.059202339683819, 6.77927... None COOH-PDha \n", + "2 [7.749050564056614, 7.106238951223266, 6.85319... None NH3-PDha \n", + "3 [7.692460718229277, 6.8431412239990514, 7.9739... None BB-PDha \n", + "4 [7.2107917459456745, 7.181071829992744, 8.6378... None COOH-PDha \n", + "5 [7.847768489420128, 7.330068748851457, 8.58571... None NH3-PDha \n", + "\n", + " residue_id molecule_id assembly_id \n", + "0 0 0 \n", + "1 0 0 \n", + "2 0 0 \n", + "3 1 0 \n", + "4 1 0 \n", + "5 1 0 " + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Check particle instances\n", + "pmb.get_instances_df(pmb_type = 'particle')\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", + " \n", + " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + "
pmb_typenamebond_idparticle_id1particle_id2
200bondBB-PDha-COOH-PDha202122001
211bondBB-PDha-NH3-PDha212123
22bondBB-PDha-BB-PDha221821102
232bondBB-PDha-COOH-PDha232425234
243bondBB-PDha-NH3-PDha242426335
254bondBB-PDha-BB-PDha252124403
26bondBB-PDha-COOH-PDha262728
\n", + "
" + ], + "text/plain": [ + " pmb_type name bond_id particle_id1 particle_id2\n", + "0 bond BB-PDha-COOH-PDha 0 0 1\n", + "1 bond BB-PDha-NH3-PDha 1 0 2\n", + "2 bond BB-PDha-COOH-PDha 2 3 4\n", + "3 bond BB-PDha-NH3-PDha 3 3 5\n", + "4 bond BB-PDha-BB-PDha 4 0 3" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pmb.get_instances_df(pmb_type='bond')" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", "
pmb_typenameresidue_idmolecule_idassembly_id
27bondBB-PDha-NH3-PDha2727290residuePDha_mon00<NA>
28bondBB-PDha-BB-PDha2824271residuePDha_mon10<NA>
\n", "
" ], "text/plain": [ - " pmb_type name bond_id particle_id1 particle_id2\n", - "0 bond BB-PDha-COOH-PDha 0 0 1\n", - "1 bond BB-PDha-NH3-PDha 1 0 2\n", - "2 bond BB-PDha-COOH-PDha 2 3 4\n", - "3 bond BB-PDha-NH3-PDha 3 3 5\n", - "4 bond BB-PDha-BB-PDha 4 0 3\n", - "5 bond BB-PDha-COOH-PDha 5 6 7\n", - "6 bond BB-PDha-NH3-PDha 6 6 8\n", - "7 bond BB-PDha-BB-PDha 7 3 6\n", - "8 bond BB-PDha-COOH-PDha 8 9 10\n", - "9 bond BB-PDha-NH3-PDha 9 9 11\n", - "10 bond BB-PDha-BB-PDha 10 6 9\n", - "11 bond BB-PDha-COOH-PDha 11 12 13\n", - "12 bond BB-PDha-NH3-PDha 12 12 14\n", - "13 bond BB-PDha-BB-PDha 13 9 12\n", - "14 bond BB-PDha-COOH-PDha 14 15 16\n", - "15 bond BB-PDha-NH3-PDha 15 15 17\n", - "16 bond BB-PDha-BB-PDha 16 12 15\n", - "17 bond BB-PDha-COOH-PDha 17 18 19\n", - "18 bond BB-PDha-NH3-PDha 18 18 20\n", - "19 bond BB-PDha-BB-PDha 19 15 18\n", - "20 bond BB-PDha-COOH-PDha 20 21 22\n", - "21 bond BB-PDha-NH3-PDha 21 21 23\n", - "22 bond BB-PDha-BB-PDha 22 18 21\n", - "23 bond BB-PDha-COOH-PDha 23 24 25\n", - "24 bond BB-PDha-NH3-PDha 24 24 26\n", - "25 bond BB-PDha-BB-PDha 25 21 24\n", - "26 bond BB-PDha-COOH-PDha 26 27 28\n", - "27 bond BB-PDha-NH3-PDha 27 27 29\n", - "28 bond BB-PDha-BB-PDha 28 24 27" + " pmb_type name residue_id molecule_id assembly_id\n", + "0 residue PDha_mon 0 0 \n", + "1 residue PDha_mon 1 0 " ] }, - "execution_count": 23, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# Check bond instances\n", - "pmb.get_instances_df(pmb_type = 'bond')" + "# Check residue instances\n", + "pmb.get_instances_df(pmb_type = 'residue')" ] }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 21, "metadata": {}, "outputs": [ { @@ -2277,20 +1704,30 @@ " \n", " \n", " \n", + " pmb_type\n", + " name\n", + " molecule_id\n", + " assembly_id\n", " \n", " \n", " \n", + " \n", + " 0\n", + " molecule\n", + " PDha\n", + " 0\n", + " <NA>\n", + " \n", " \n", "\n", "" ], "text/plain": [ - "Empty DataFrame\n", - "Columns: []\n", - "Index: []" + " pmb_type name molecule_id assembly_id\n", + "0 molecule PDha 0 " ] }, - "execution_count": 60, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -2300,6 +1737,16 @@ "pmb.get_instances_df(pmb_type = 'molecule')" ] }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.set_simulation_engine(espresso_system)\n", + "pmb.add_instances_to_engine()" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -2309,7 +1756,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, "metadata": {}, "outputs": [], "source": [ @@ -2324,7 +1771,59 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Delete the particles and check that there are no particle instances in the pyMBE database" + "Delete the particles and check that there are no particle instances in the pyMBE database" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
" + ], + "text/plain": [ + "Empty DataFrame\n", + "Columns: []\n", + "Index: []" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pmb.delete_instances_in_system(instance_id=molecule_ids[0],\n", + " pmb_type=\"molecule\", \n", + " espresso_system = espresso_system)\n", + "# Check particle instances\n", + "pmb.get_instances_df(pmb_type = 'particle')" ] }, { @@ -2333,11 +1832,12 @@ "metadata": {}, "outputs": [], "source": [ - "pmb.delete_instances_in_system(instance_id=molecule_ids[0],\n", - " pmb_type=\"molecule\", \n", - " espresso_system = espresso_system)\n", - "# Check particle instances\n", - "pmb.get_instances_df(pmb_type = 'particle')" + "particle_id_map = pmb.get_particle_id_map(object_name=cation_name)\n", + "# This will delete all particles that we created before\n", + "for pid in particle_id_map[\"all\"]:\n", + " pmb.delete_instances_in_system(instance_id=pid, \n", + " pmb_type=\"particle\",\n", + " espresso_system = espresso_system)" ] }, { @@ -2365,7 +1865,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -2405,7 +1905,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 26, "metadata": {}, "outputs": [], "source": [ @@ -2425,7 +1925,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 27, "metadata": {}, "outputs": [], "source": [ @@ -2444,7 +1944,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 28, "metadata": {}, "outputs": [], "source": [ @@ -2464,6 +1964,13 @@ " [PDAGA_beta_carboxyl_bead, PDAGA_cyclic_amine_bead]])" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "markdown", "metadata": {}, @@ -2473,12 +1980,12 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "PDAGA_polymer = 'PDAGA'\n", - "N_monomers = 8\n", + "N_monomers = 4\n", "\n", "pmb.define_molecule(name = PDAGA_polymer,\n", " residue_list = [PDAGA_monomer_residue]*N_monomers)" @@ -2493,7 +2000,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 39, "metadata": {}, "outputs": [], "source": [ @@ -2501,13 +2008,13 @@ "\n", "mol_ids = pmb.create_molecule(name = PDAGA_polymer,\n", " number_of_molecules= N_polymers,\n", - " espresso_system = espresso_system,\n", + " box_l= box_l,\n", " list_of_first_residue_positions = [[Box_L.to('reduced_length').magnitude/2]*3])" ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 40, "metadata": {}, "outputs": [ { @@ -2534,6 +2041,8 @@ " pmb_type\n", " name\n", " particle_id\n", + " position\n", + " fix\n", " initial_state\n", " residue_id\n", " molecule_id\n", @@ -2546,6 +2055,8 @@ " particle\n", " BB-PDAGA\n", " 0\n", + " [7.499999999999999, 7.499999999999999, 7.49999...\n", + " None\n", " BB-PDAGA\n", " 0\n", " 0\n", @@ -2556,6 +2067,8 @@ " particle\n", " NH3-PDAGA\n", " 1\n", + " [8.006035046780134, 6.983156096845676, 7.83500...\n", + " None\n", " NH3-PDAGA\n", " 0\n", " 0\n", @@ -2566,6 +2079,8 @@ " particle\n", " aCOOH-PDAGA\n", " 2\n", + " [7.228892589749606, 6.828507543870596, 7.91016...\n", + " None\n", " aCOOH-PDAGA\n", " 0\n", " 0\n", @@ -2576,6 +2091,8 @@ " particle\n", " bCOOH-PDAGA\n", " 3\n", + " [8.390296523191001, 7.449356309621872, 8.35503...\n", + " None\n", " bCOOH-PDAGA\n", " 0\n", " 0\n", @@ -2586,6 +2103,8 @@ " particle\n", " BB-PDAGA\n", " 4\n", + " [7.033629851553653, 6.866558505888692, 7.22719...\n", + " None\n", " BB-PDAGA\n", " 1\n", " 0\n", @@ -2596,6 +2115,8 @@ " particle\n", " NH3-PDAGA\n", " 5\n", + " [6.874476454747638, 6.659394433454941, 7.98031...\n", + " None\n", " NH3-PDAGA\n", " 1\n", " 0\n", @@ -2606,6 +2127,8 @@ " particle\n", " aCOOH-PDAGA\n", " 6\n", + " [6.785798310596719, 6.068056544244533, 7.45498...\n", + " None\n", " aCOOH-PDAGA\n", " 1\n", " 0\n", @@ -2616,6 +2139,8 @@ " particle\n", " bCOOH-PDAGA\n", " 7\n", + " [6.179699453438731, 7.035070100567888, 8.08793...\n", + " None\n", " bCOOH-PDAGA\n", " 1\n", " 0\n", @@ -2626,6 +2151,8 @@ " particle\n", " BB-PDAGA\n", " 8\n", + " [6.567259703107307, 6.233117011777386, 6.95439...\n", + " None\n", " BB-PDAGA\n", " 2\n", " 0\n", @@ -2636,6 +2163,8 @@ " particle\n", " NH3-PDAGA\n", " 9\n", + " [7.17699479917509, 5.733385942628339, 7.072389...\n", + " None\n", " NH3-PDAGA\n", " 2\n", " 0\n", @@ -2646,6 +2175,8 @@ " particle\n", " aCOOH-PDAGA\n", " 10\n", + " [7.773970921102857, 5.43818879862679, 7.508271...\n", + " None\n", " aCOOH-PDAGA\n", " 2\n", " 0\n", @@ -2656,6 +2187,8 @@ " particle\n", " bCOOH-PDAGA\n", " 11\n", + " [6.553282284209572, 5.391291436792669, 6.71268...\n", + " None\n", " bCOOH-PDAGA\n", " 2\n", " 0\n", @@ -2666,6 +2199,8 @@ " particle\n", " BB-PDAGA\n", " 12\n", + " [6.10088955466096, 5.59967551766608, 6.6815969...\n", + " None\n", " BB-PDAGA\n", " 3\n", " 0\n", @@ -2676,6 +2211,8 @@ " particle\n", " NH3-PDAGA\n", " 13\n", + " [5.521927644541596, 6.110879482807433, 6.48435...\n", + " None\n", " NH3-PDAGA\n", " 3\n", " 0\n", @@ -2686,6 +2223,8 @@ " particle\n", " aCOOH-PDAGA\n", " 14\n", + " [5.537081221656859, 6.693956347003686, 7.02593...\n", + " None\n", " aCOOH-PDAGA\n", " 3\n", " 0\n", @@ -2696,246 +2235,74 @@ " particle\n", " bCOOH-PDAGA\n", " 15\n", + " [6.1893175157746745, 6.012097267908542, 6.0597...\n", + " None\n", " bCOOH-PDAGA\n", " 3\n", " 0\n", " <NA>\n", " \n", - " \n", - " 16\n", - " particle\n", - " BB-PDAGA\n", - " 16\n", - " BB-PDAGA\n", - " 4\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 17\n", - " particle\n", - " NH3-PDAGA\n", - " 17\n", - " NH3-PDAGA\n", - " 4\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 18\n", - " particle\n", - " aCOOH-PDAGA\n", - " 18\n", - " aCOOH-PDAGA\n", - " 4\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 19\n", - " particle\n", - " bCOOH-PDAGA\n", - " 19\n", - " bCOOH-PDAGA\n", - " 4\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 20\n", - " particle\n", - " BB-PDAGA\n", - " 20\n", - " BB-PDAGA\n", - " 5\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 21\n", - " particle\n", - " NH3-PDAGA\n", - " 21\n", - " NH3-PDAGA\n", - " 5\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 22\n", - " particle\n", - " aCOOH-PDAGA\n", - " 22\n", - " aCOOH-PDAGA\n", - " 5\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 23\n", - " particle\n", - " bCOOH-PDAGA\n", - " 23\n", - " bCOOH-PDAGA\n", - " 5\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 24\n", - " particle\n", - " BB-PDAGA\n", - " 24\n", - " BB-PDAGA\n", - " 6\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 25\n", - " particle\n", - " NH3-PDAGA\n", - " 25\n", - " NH3-PDAGA\n", - " 6\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 26\n", - " particle\n", - " aCOOH-PDAGA\n", - " 26\n", - " aCOOH-PDAGA\n", - " 6\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 27\n", - " particle\n", - " bCOOH-PDAGA\n", - " 27\n", - " bCOOH-PDAGA\n", - " 6\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 28\n", - " particle\n", - " BB-PDAGA\n", - " 28\n", - " BB-PDAGA\n", - " 7\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 29\n", - " particle\n", - " NH3-PDAGA\n", - " 29\n", - " NH3-PDAGA\n", - " 7\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 30\n", - " particle\n", - " aCOOH-PDAGA\n", - " 30\n", - " aCOOH-PDAGA\n", - " 7\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 31\n", - " particle\n", - " bCOOH-PDAGA\n", - " 31\n", - " bCOOH-PDAGA\n", - " 7\n", - " 0\n", - " <NA>\n", - " \n", " \n", "\n", "" ], "text/plain": [ - " pmb_type name particle_id initial_state residue_id molecule_id \\\n", - "0 particle BB-PDAGA 0 BB-PDAGA 0 0 \n", - "1 particle NH3-PDAGA 1 NH3-PDAGA 0 0 \n", - "2 particle aCOOH-PDAGA 2 aCOOH-PDAGA 0 0 \n", - "3 particle bCOOH-PDAGA 3 bCOOH-PDAGA 0 0 \n", - "4 particle BB-PDAGA 4 BB-PDAGA 1 0 \n", - "5 particle NH3-PDAGA 5 NH3-PDAGA 1 0 \n", - "6 particle aCOOH-PDAGA 6 aCOOH-PDAGA 1 0 \n", - "7 particle bCOOH-PDAGA 7 bCOOH-PDAGA 1 0 \n", - "8 particle BB-PDAGA 8 BB-PDAGA 2 0 \n", - "9 particle NH3-PDAGA 9 NH3-PDAGA 2 0 \n", - "10 particle aCOOH-PDAGA 10 aCOOH-PDAGA 2 0 \n", - "11 particle bCOOH-PDAGA 11 bCOOH-PDAGA 2 0 \n", - "12 particle BB-PDAGA 12 BB-PDAGA 3 0 \n", - "13 particle NH3-PDAGA 13 NH3-PDAGA 3 0 \n", - "14 particle aCOOH-PDAGA 14 aCOOH-PDAGA 3 0 \n", - "15 particle bCOOH-PDAGA 15 bCOOH-PDAGA 3 0 \n", - "16 particle BB-PDAGA 16 BB-PDAGA 4 0 \n", - "17 particle NH3-PDAGA 17 NH3-PDAGA 4 0 \n", - "18 particle aCOOH-PDAGA 18 aCOOH-PDAGA 4 0 \n", - "19 particle bCOOH-PDAGA 19 bCOOH-PDAGA 4 0 \n", - "20 particle BB-PDAGA 20 BB-PDAGA 5 0 \n", - "21 particle NH3-PDAGA 21 NH3-PDAGA 5 0 \n", - "22 particle aCOOH-PDAGA 22 aCOOH-PDAGA 5 0 \n", - "23 particle bCOOH-PDAGA 23 bCOOH-PDAGA 5 0 \n", - "24 particle BB-PDAGA 24 BB-PDAGA 6 0 \n", - "25 particle NH3-PDAGA 25 NH3-PDAGA 6 0 \n", - "26 particle aCOOH-PDAGA 26 aCOOH-PDAGA 6 0 \n", - "27 particle bCOOH-PDAGA 27 bCOOH-PDAGA 6 0 \n", - "28 particle BB-PDAGA 28 BB-PDAGA 7 0 \n", - "29 particle NH3-PDAGA 29 NH3-PDAGA 7 0 \n", - "30 particle aCOOH-PDAGA 30 aCOOH-PDAGA 7 0 \n", - "31 particle bCOOH-PDAGA 31 bCOOH-PDAGA 7 0 \n", + " pmb_type name particle_id \\\n", + "0 particle BB-PDAGA 0 \n", + "1 particle NH3-PDAGA 1 \n", + "2 particle aCOOH-PDAGA 2 \n", + "3 particle bCOOH-PDAGA 3 \n", + "4 particle BB-PDAGA 4 \n", + "5 particle NH3-PDAGA 5 \n", + "6 particle aCOOH-PDAGA 6 \n", + "7 particle bCOOH-PDAGA 7 \n", + "8 particle BB-PDAGA 8 \n", + "9 particle NH3-PDAGA 9 \n", + "10 particle aCOOH-PDAGA 10 \n", + "11 particle bCOOH-PDAGA 11 \n", + "12 particle BB-PDAGA 12 \n", + "13 particle NH3-PDAGA 13 \n", + "14 particle aCOOH-PDAGA 14 \n", + "15 particle bCOOH-PDAGA 15 \n", "\n", - " assembly_id \n", - "0 \n", - "1 \n", - "2 \n", - "3 \n", - "4 \n", - "5 \n", - "6 \n", - "7 \n", - "8 \n", - "9 \n", - "10 \n", - "11 \n", - "12 \n", - "13 \n", - "14 \n", - "15 \n", - "16 \n", - "17 \n", - "18 \n", - "19 \n", - "20 \n", - "21 \n", - "22 \n", - "23 \n", - "24 \n", - "25 \n", - "26 \n", - "27 \n", - "28 \n", - "29 \n", - "30 \n", - "31 " + " position fix initial_state \\\n", + "0 [7.499999999999999, 7.499999999999999, 7.49999... None BB-PDAGA \n", + "1 [8.006035046780134, 6.983156096845676, 7.83500... None NH3-PDAGA \n", + "2 [7.228892589749606, 6.828507543870596, 7.91016... None aCOOH-PDAGA \n", + "3 [8.390296523191001, 7.449356309621872, 8.35503... None bCOOH-PDAGA \n", + "4 [7.033629851553653, 6.866558505888692, 7.22719... None BB-PDAGA \n", + "5 [6.874476454747638, 6.659394433454941, 7.98031... None NH3-PDAGA \n", + "6 [6.785798310596719, 6.068056544244533, 7.45498... None aCOOH-PDAGA \n", + "7 [6.179699453438731, 7.035070100567888, 8.08793... None bCOOH-PDAGA \n", + "8 [6.567259703107307, 6.233117011777386, 6.95439... None BB-PDAGA \n", + "9 [7.17699479917509, 5.733385942628339, 7.072389... None NH3-PDAGA \n", + "10 [7.773970921102857, 5.43818879862679, 7.508271... None aCOOH-PDAGA \n", + "11 [6.553282284209572, 5.391291436792669, 6.71268... None bCOOH-PDAGA \n", + "12 [6.10088955466096, 5.59967551766608, 6.6815969... None BB-PDAGA \n", + "13 [5.521927644541596, 6.110879482807433, 6.48435... None NH3-PDAGA \n", + "14 [5.537081221656859, 6.693956347003686, 7.02593... None aCOOH-PDAGA \n", + "15 [6.1893175157746745, 6.012097267908542, 6.0597... None bCOOH-PDAGA \n", + "\n", + " residue_id molecule_id assembly_id \n", + "0 0 0 \n", + "1 0 0 \n", + "2 0 0 \n", + "3 0 0 \n", + "4 1 0 \n", + "5 1 0 \n", + "6 1 0 \n", + "7 1 0 \n", + "8 2 0 \n", + "9 2 0 \n", + "10 2 0 \n", + "11 2 0 \n", + "12 3 0 \n", + "13 3 0 \n", + "14 3 0 \n", + "15 3 0 " ] }, - "execution_count": 13, + "execution_count": 40, "metadata": {}, "output_type": "execute_result" } @@ -2946,7 +2313,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 41, "metadata": {}, "outputs": [ { @@ -2990,55 +2357,23 @@ " 1\n", " residue\n", " PDAGA_monomer_residue\n", - " 1\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 2\n", - " residue\n", - " PDAGA_monomer_residue\n", - " 2\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 3\n", - " residue\n", - " PDAGA_monomer_residue\n", - " 3\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 4\n", - " residue\n", - " PDAGA_monomer_residue\n", - " 4\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 5\n", - " residue\n", - " PDAGA_monomer_residue\n", - " 5\n", + " 1\n", " 0\n", " <NA>\n", " \n", " \n", - " 6\n", + " 2\n", " residue\n", " PDAGA_monomer_residue\n", - " 6\n", + " 2\n", " 0\n", " <NA>\n", " \n", " \n", - " 7\n", + " 3\n", " residue\n", " PDAGA_monomer_residue\n", - " 7\n", + " 3\n", " 0\n", " <NA>\n", " \n", @@ -3051,14 +2386,10 @@ "0 residue PDAGA_monomer_residue 0 0 \n", "1 residue PDAGA_monomer_residue 1 0 \n", "2 residue PDAGA_monomer_residue 2 0 \n", - "3 residue PDAGA_monomer_residue 3 0 \n", - "4 residue PDAGA_monomer_residue 4 0 \n", - "5 residue PDAGA_monomer_residue 5 0 \n", - "6 residue PDAGA_monomer_residue 6 0 \n", - "7 residue PDAGA_monomer_residue 7 0 " + "3 residue PDAGA_monomer_residue 3 0 " ] }, - "execution_count": 14, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -3069,7 +2400,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 42, "metadata": {}, "outputs": [ { @@ -3221,134 +2552,6 @@ " 8\n", " 12\n", " \n", - " \n", - " 15\n", - " bond\n", - " NH3-PDAGA-aCOOH-PDAGA\n", - " 15\n", - " 17\n", - " 18\n", - " \n", - " \n", - " 16\n", - " bond\n", - " NH3-PDAGA-bCOOH-PDAGA\n", - " 16\n", - " 17\n", - " 19\n", - " \n", - " \n", - " 17\n", - " bond\n", - " BB-PDAGA-NH3-PDAGA\n", - " 17\n", - " 16\n", - " 17\n", - " \n", - " \n", - " 18\n", - " bond\n", - " BB-PDAGA-BB-PDAGA\n", - " 18\n", - " 12\n", - " 16\n", - " \n", - " \n", - " 19\n", - " bond\n", - " NH3-PDAGA-aCOOH-PDAGA\n", - " 19\n", - " 21\n", - " 22\n", - " \n", - " \n", - " 20\n", - " bond\n", - " NH3-PDAGA-bCOOH-PDAGA\n", - " 20\n", - " 21\n", - " 23\n", - " \n", - " \n", - " 21\n", - " bond\n", - " BB-PDAGA-NH3-PDAGA\n", - " 21\n", - " 20\n", - " 21\n", - " \n", - " \n", - " 22\n", - " bond\n", - " BB-PDAGA-BB-PDAGA\n", - " 22\n", - " 16\n", - " 20\n", - " \n", - " \n", - " 23\n", - " bond\n", - " NH3-PDAGA-aCOOH-PDAGA\n", - " 23\n", - " 25\n", - " 26\n", - " \n", - " \n", - " 24\n", - " bond\n", - " NH3-PDAGA-bCOOH-PDAGA\n", - " 24\n", - " 25\n", - " 27\n", - " \n", - " \n", - " 25\n", - " bond\n", - " BB-PDAGA-NH3-PDAGA\n", - " 25\n", - " 24\n", - " 25\n", - " \n", - " \n", - " 26\n", - " bond\n", - " BB-PDAGA-BB-PDAGA\n", - " 26\n", - " 20\n", - " 24\n", - " \n", - " \n", - " 27\n", - " bond\n", - " NH3-PDAGA-aCOOH-PDAGA\n", - " 27\n", - " 29\n", - " 30\n", - " \n", - " \n", - " 28\n", - " bond\n", - " NH3-PDAGA-bCOOH-PDAGA\n", - " 28\n", - " 29\n", - " 31\n", - " \n", - " \n", - " 29\n", - " bond\n", - " BB-PDAGA-NH3-PDAGA\n", - " 29\n", - " 28\n", - " 29\n", - " \n", - " \n", - " 30\n", - " bond\n", - " BB-PDAGA-BB-PDAGA\n", - " 30\n", - " 24\n", - " 28\n", - " \n", " \n", "\n", "" @@ -3369,26 +2572,10 @@ "11 bond NH3-PDAGA-aCOOH-PDAGA 11 13 14\n", "12 bond NH3-PDAGA-bCOOH-PDAGA 12 13 15\n", "13 bond BB-PDAGA-NH3-PDAGA 13 12 13\n", - "14 bond BB-PDAGA-BB-PDAGA 14 8 12\n", - "15 bond NH3-PDAGA-aCOOH-PDAGA 15 17 18\n", - "16 bond NH3-PDAGA-bCOOH-PDAGA 16 17 19\n", - "17 bond BB-PDAGA-NH3-PDAGA 17 16 17\n", - "18 bond BB-PDAGA-BB-PDAGA 18 12 16\n", - "19 bond NH3-PDAGA-aCOOH-PDAGA 19 21 22\n", - "20 bond NH3-PDAGA-bCOOH-PDAGA 20 21 23\n", - "21 bond BB-PDAGA-NH3-PDAGA 21 20 21\n", - "22 bond BB-PDAGA-BB-PDAGA 22 16 20\n", - "23 bond NH3-PDAGA-aCOOH-PDAGA 23 25 26\n", - "24 bond NH3-PDAGA-bCOOH-PDAGA 24 25 27\n", - "25 bond BB-PDAGA-NH3-PDAGA 25 24 25\n", - "26 bond BB-PDAGA-BB-PDAGA 26 20 24\n", - "27 bond NH3-PDAGA-aCOOH-PDAGA 27 29 30\n", - "28 bond NH3-PDAGA-bCOOH-PDAGA 28 29 31\n", - "29 bond BB-PDAGA-NH3-PDAGA 29 28 29\n", - "30 bond BB-PDAGA-BB-PDAGA 30 24 28" + "14 bond BB-PDAGA-BB-PDAGA 14 8 12" ] }, - "execution_count": 12, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } @@ -3397,6 +2584,16 @@ "pmb.get_instances_df(pmb_type = 'bond')" ] }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.set_simulation_engine(espresso_system)\n", + "pmb.add_instances_to_engine()" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -3406,7 +2603,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 44, "metadata": {}, "outputs": [], "source": [ @@ -3426,9 +2623,48 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 37, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
" + ], + "text/plain": [ + "Empty DataFrame\n", + "Columns: []\n", + "Index: []" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "\n", "for mol_id in mol_ids:\n", @@ -3463,7 +2699,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 48, "metadata": {}, "outputs": [], "source": [ @@ -3482,7 +2718,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 49, "metadata": {}, "outputs": [], "source": [ @@ -3503,16 +2739,9 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 50, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/bin/eog: symbol lookup error: /snap/core20/current/lib/x86_64-linux-gnu/libpthread.so.0: undefined symbol: __libc_pthread_init, version GLIBC_PRIVATE\n" - ] - }, { "data": { "text/html": [ @@ -3537,6 +2766,8 @@ " pmb_type\n", " name\n", " particle_id\n", + " position\n", + " fix\n", " initial_state\n", " residue_id\n", " molecule_id\n", @@ -3549,6 +2780,8 @@ " particle\n", " BB-PDha\n", " 0\n", + " [7.499999999999999, 7.499999999999999, 7.49999...\n", + " None\n", " BB-PDha\n", " 0\n", " 0\n", @@ -3559,6 +2792,8 @@ " particle\n", " COOH-PDha\n", " 1\n", + " [7.571167527771879, 7.604628201186956, 8.37803...\n", + " None\n", " COOH-PDha\n", " 0\n", " 0\n", @@ -3569,6 +2804,8 @@ " particle\n", " NH3-PDha\n", " 2\n", + " [7.61187816904253, 7.692330966595771, 6.734544...\n", + " None\n", " NH3-PDha\n", " 0\n", " 0\n", @@ -3579,6 +2816,8 @@ " particle\n", " BB-PDha\n", " 3\n", + " [8.209680803443417, 7.064694517707376, 7.49434...\n", + " None\n", " BB-PDha\n", " 1\n", " 0\n", @@ -3589,6 +2828,8 @@ " particle\n", " COOH-PDha\n", " 4\n", + " [7.96317931944196, 6.672642643457426, 6.737725...\n", + " None\n", " COOH-PDha\n", " 1\n", " 0\n", @@ -3599,6 +2840,8 @@ " particle\n", " NH3-PDha\n", " 5\n", + " [7.949794989096124, 6.632984135848388, 8.11201...\n", + " None\n", " NH3-PDha\n", " 1\n", " 0\n", @@ -3609,6 +2852,8 @@ " particle\n", " BB-PDha\n", " 6\n", + " [8.919361606886834, 6.629389035414753, 7.48869...\n", + " None\n", " BB-PDha\n", " 2\n", " 0\n", @@ -3619,6 +2864,8 @@ " particle\n", " COOH-PDha\n", " 7\n", + " [8.542953602465508, 6.0225607419657345, 6.9623...\n", + " None\n", " COOH-PDha\n", " 2\n", " 0\n", @@ -3629,6 +2876,8 @@ " particle\n", " NH3-PDha\n", " 8\n", + " [9.250938657970849, 7.163600709092095, 7.97870...\n", + " None\n", " NH3-PDha\n", " 2\n", " 0\n", @@ -3639,6 +2888,8 @@ " particle\n", " BB-PDha\n", " 9\n", + " [9.629042410330252, 6.194083553122129, 7.48304...\n", + " None\n", " BB-PDha\n", " 3\n", " 0\n", @@ -3649,6 +2900,8 @@ " particle\n", " COOH-PDha\n", " 10\n", + " [9.920338499649748, 6.677865071931392, 6.79890...\n", + " None\n", " COOH-PDha\n", " 3\n", " 0\n", @@ -3659,6 +2912,8 @@ " particle\n", " NH3-PDha\n", " 11\n", + " [9.82370132285253, 6.502235290435076, 8.191978...\n", + " None\n", " NH3-PDha\n", " 3\n", " 0\n", @@ -3669,6 +2924,8 @@ " particle\n", " BB-PDAGA\n", " 12\n", + " [10.338723213773669, 5.758778070829506, 7.4773...\n", + " None\n", " BB-PDAGA\n", " 4\n", " 0\n", @@ -3679,6 +2936,8 @@ " particle\n", " NH3-PDAGA\n", " 13\n", + " [9.960891826868739, 5.138532624129924, 7.80598...\n", + " None\n", " NH3-PDAGA\n", " 4\n", " 0\n", @@ -3689,6 +2948,8 @@ " particle\n", " aCOOH-PDAGA\n", " 14\n", + " [10.5766803499623, 5.597619531889813, 7.597277...\n", + " None\n", " aCOOH-PDAGA\n", " 4\n", " 0\n", @@ -3699,6 +2960,8 @@ " particle\n", " bCOOH-PDAGA\n", " 15\n", + " [9.818081425019205, 4.411299358991621, 7.51244...\n", + " None\n", " bCOOH-PDAGA\n", " 4\n", " 0\n", @@ -3709,6 +2972,8 @@ " particle\n", " BB-PDAGA\n", " 16\n", + " [11.048404017217086, 5.323472588536883, 7.4717...\n", + " None\n", " BB-PDAGA\n", " 5\n", " 0\n", @@ -3719,6 +2984,8 @@ " particle\n", " NH3-PDAGA\n", " 17\n", + " [11.401299152618178, 5.9042080625154485, 7.055...\n", + " None\n", " NH3-PDAGA\n", " 5\n", " 0\n", @@ -3729,6 +2996,8 @@ " particle\n", " aCOOH-PDAGA\n", " 18\n", + " [11.169957143049839, 5.144809052085453, 6.9975...\n", + " None\n", " aCOOH-PDAGA\n", " 5\n", " 0\n", @@ -3739,6 +3008,8 @@ " particle\n", " bCOOH-PDAGA\n", " 19\n", + " [10.827437362182199, 5.6182320306354745, 6.581...\n", + " None\n", " bCOOH-PDAGA\n", " 5\n", " 0\n", @@ -3749,6 +3020,8 @@ " particle\n", " BB-PDAGA\n", " 20\n", + " [11.758084820660503, 4.88816710624426, 7.46609...\n", + " None\n", " BB-PDAGA\n", " 6\n", " 0\n", @@ -3759,6 +3032,8 @@ " particle\n", " NH3-PDAGA\n", " 21\n", + " [11.451876185073228, 4.396056855078196, 6.9188...\n", + " None\n", " NH3-PDAGA\n", " 6\n", " 0\n", @@ -3769,6 +3044,8 @@ " particle\n", " aCOOH-PDAGA\n", " 22\n", + " [12.075126241658626, 4.019216519310867, 6.5977...\n", + " None\n", " aCOOH-PDAGA\n", " 6\n", " 0\n", @@ -3779,6 +3056,8 @@ " particle\n", " bCOOH-PDAGA\n", " 23\n", + " [11.855114840563605, 5.033776247620462, 6.6616...\n", + " None\n", " bCOOH-PDAGA\n", " 6\n", " 0\n", @@ -3789,6 +3068,8 @@ " particle\n", " BB-PDAGA\n", " 24\n", + " [12.46776562410392, 4.4528616239516365, 7.4604...\n", + " None\n", " BB-PDAGA\n", " 7\n", " 0\n", @@ -3799,6 +3080,8 @@ " particle\n", " NH3-PDAGA\n", " 25\n", + " [12.49615134833019, 4.4888094718484215, 8.2562...\n", + " None\n", " NH3-PDAGA\n", " 7\n", " 0\n", @@ -3809,6 +3092,8 @@ " particle\n", " aCOOH-PDAGA\n", " 26\n", + " [11.882479934601875, 4.33628485023324, 8.73965...\n", + " None\n", " aCOOH-PDAGA\n", " 7\n", " 0\n", @@ -3819,6 +3104,8 @@ " particle\n", " bCOOH-PDAGA\n", " 27\n", + " [13.08328337253056, 3.9808276202572306, 8.0755...\n", + " None\n", " bCOOH-PDAGA\n", " 7\n", " 0\n", @@ -3829,68 +3116,98 @@ "" ], "text/plain": [ - " pmb_type name particle_id initial_state residue_id molecule_id \\\n", - "0 particle BB-PDha 0 BB-PDha 0 0 \n", - "1 particle COOH-PDha 1 COOH-PDha 0 0 \n", - "2 particle NH3-PDha 2 NH3-PDha 0 0 \n", - "3 particle BB-PDha 3 BB-PDha 1 0 \n", - "4 particle COOH-PDha 4 COOH-PDha 1 0 \n", - "5 particle NH3-PDha 5 NH3-PDha 1 0 \n", - "6 particle BB-PDha 6 BB-PDha 2 0 \n", - "7 particle COOH-PDha 7 COOH-PDha 2 0 \n", - "8 particle NH3-PDha 8 NH3-PDha 2 0 \n", - "9 particle BB-PDha 9 BB-PDha 3 0 \n", - "10 particle COOH-PDha 10 COOH-PDha 3 0 \n", - "11 particle NH3-PDha 11 NH3-PDha 3 0 \n", - "12 particle BB-PDAGA 12 BB-PDAGA 4 0 \n", - "13 particle NH3-PDAGA 13 NH3-PDAGA 4 0 \n", - "14 particle aCOOH-PDAGA 14 aCOOH-PDAGA 4 0 \n", - "15 particle bCOOH-PDAGA 15 bCOOH-PDAGA 4 0 \n", - "16 particle BB-PDAGA 16 BB-PDAGA 5 0 \n", - "17 particle NH3-PDAGA 17 NH3-PDAGA 5 0 \n", - "18 particle aCOOH-PDAGA 18 aCOOH-PDAGA 5 0 \n", - "19 particle bCOOH-PDAGA 19 bCOOH-PDAGA 5 0 \n", - "20 particle BB-PDAGA 20 BB-PDAGA 6 0 \n", - "21 particle NH3-PDAGA 21 NH3-PDAGA 6 0 \n", - "22 particle aCOOH-PDAGA 22 aCOOH-PDAGA 6 0 \n", - "23 particle bCOOH-PDAGA 23 bCOOH-PDAGA 6 0 \n", - "24 particle BB-PDAGA 24 BB-PDAGA 7 0 \n", - "25 particle NH3-PDAGA 25 NH3-PDAGA 7 0 \n", - "26 particle aCOOH-PDAGA 26 aCOOH-PDAGA 7 0 \n", - "27 particle bCOOH-PDAGA 27 bCOOH-PDAGA 7 0 \n", + " pmb_type name particle_id \\\n", + "0 particle BB-PDha 0 \n", + "1 particle COOH-PDha 1 \n", + "2 particle NH3-PDha 2 \n", + "3 particle BB-PDha 3 \n", + "4 particle COOH-PDha 4 \n", + "5 particle NH3-PDha 5 \n", + "6 particle BB-PDha 6 \n", + "7 particle COOH-PDha 7 \n", + "8 particle NH3-PDha 8 \n", + "9 particle BB-PDha 9 \n", + "10 particle COOH-PDha 10 \n", + "11 particle NH3-PDha 11 \n", + "12 particle BB-PDAGA 12 \n", + "13 particle NH3-PDAGA 13 \n", + "14 particle aCOOH-PDAGA 14 \n", + "15 particle bCOOH-PDAGA 15 \n", + "16 particle BB-PDAGA 16 \n", + "17 particle NH3-PDAGA 17 \n", + "18 particle aCOOH-PDAGA 18 \n", + "19 particle bCOOH-PDAGA 19 \n", + "20 particle BB-PDAGA 20 \n", + "21 particle NH3-PDAGA 21 \n", + "22 particle aCOOH-PDAGA 22 \n", + "23 particle bCOOH-PDAGA 23 \n", + "24 particle BB-PDAGA 24 \n", + "25 particle NH3-PDAGA 25 \n", + "26 particle aCOOH-PDAGA 26 \n", + "27 particle bCOOH-PDAGA 27 \n", + "\n", + " position fix initial_state \\\n", + "0 [7.499999999999999, 7.499999999999999, 7.49999... None BB-PDha \n", + "1 [7.571167527771879, 7.604628201186956, 8.37803... None COOH-PDha \n", + "2 [7.61187816904253, 7.692330966595771, 6.734544... None NH3-PDha \n", + "3 [8.209680803443417, 7.064694517707376, 7.49434... None BB-PDha \n", + "4 [7.96317931944196, 6.672642643457426, 6.737725... None COOH-PDha \n", + "5 [7.949794989096124, 6.632984135848388, 8.11201... None NH3-PDha \n", + "6 [8.919361606886834, 6.629389035414753, 7.48869... None BB-PDha \n", + "7 [8.542953602465508, 6.0225607419657345, 6.9623... None COOH-PDha \n", + "8 [9.250938657970849, 7.163600709092095, 7.97870... None NH3-PDha \n", + "9 [9.629042410330252, 6.194083553122129, 7.48304... None BB-PDha \n", + "10 [9.920338499649748, 6.677865071931392, 6.79890... None COOH-PDha \n", + "11 [9.82370132285253, 6.502235290435076, 8.191978... None NH3-PDha \n", + "12 [10.338723213773669, 5.758778070829506, 7.4773... None BB-PDAGA \n", + "13 [9.960891826868739, 5.138532624129924, 7.80598... None NH3-PDAGA \n", + "14 [10.5766803499623, 5.597619531889813, 7.597277... None aCOOH-PDAGA \n", + "15 [9.818081425019205, 4.411299358991621, 7.51244... None bCOOH-PDAGA \n", + "16 [11.048404017217086, 5.323472588536883, 7.4717... None BB-PDAGA \n", + "17 [11.401299152618178, 5.9042080625154485, 7.055... None NH3-PDAGA \n", + "18 [11.169957143049839, 5.144809052085453, 6.9975... None aCOOH-PDAGA \n", + "19 [10.827437362182199, 5.6182320306354745, 6.581... None bCOOH-PDAGA \n", + "20 [11.758084820660503, 4.88816710624426, 7.46609... None BB-PDAGA \n", + "21 [11.451876185073228, 4.396056855078196, 6.9188... None NH3-PDAGA \n", + "22 [12.075126241658626, 4.019216519310867, 6.5977... None aCOOH-PDAGA \n", + "23 [11.855114840563605, 5.033776247620462, 6.6616... None bCOOH-PDAGA \n", + "24 [12.46776562410392, 4.4528616239516365, 7.4604... None BB-PDAGA \n", + "25 [12.49615134833019, 4.4888094718484215, 8.2562... None NH3-PDAGA \n", + "26 [11.882479934601875, 4.33628485023324, 8.73965... None aCOOH-PDAGA \n", + "27 [13.08328337253056, 3.9808276202572306, 8.0755... None bCOOH-PDAGA \n", "\n", - " assembly_id \n", - "0 \n", - "1 \n", - "2 \n", - "3 \n", - "4 \n", - "5 \n", - "6 \n", - "7 \n", - "8 \n", - "9 \n", - "10 \n", - "11 \n", - "12 \n", - "13 \n", - "14 \n", - "15 \n", - "16 \n", - "17 \n", - "18 \n", - "19 \n", - "20 \n", - "21 \n", - "22 \n", - "23 \n", - "24 \n", - "25 \n", - "26 \n", - "27 " + " residue_id molecule_id assembly_id \n", + "0 0 0 \n", + "1 0 0 \n", + "2 0 0 \n", + "3 1 0 \n", + "4 1 0 \n", + "5 1 0 \n", + "6 2 0 \n", + "7 2 0 \n", + "8 2 0 \n", + "9 3 0 \n", + "10 3 0 \n", + "11 3 0 \n", + "12 4 0 \n", + "13 4 0 \n", + "14 4 0 \n", + "15 4 0 \n", + "16 5 0 \n", + "17 5 0 \n", + "18 5 0 \n", + "19 5 0 \n", + "20 6 0 \n", + "21 6 0 \n", + "22 6 0 \n", + "23 6 0 \n", + "24 7 0 \n", + "25 7 0 \n", + "26 7 0 \n", + "27 7 0 " ] }, - "execution_count": 37, + "execution_count": 50, "metadata": {}, "output_type": "execute_result" } @@ -3900,12 +3217,21 @@ "\n", "mol_ids = pmb.create_molecule(name = diblock_polymer,\n", " number_of_molecules= N_polymers,\n", - " espresso_system = espresso_system,\n", + " box_l= box_l,\n", " list_of_first_residue_positions = [[Box_L.to('reduced_length').magnitude/2]*3]) \n", "# See the particle instances you have created\n", "pmb.get_instances_df(pmb_type=\"particle\")" ] }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.add_instances_to_engine()" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -3915,7 +3241,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 53, "metadata": {}, "outputs": [], "source": [ @@ -3935,9 +3261,48 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 54, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
" + ], + "text/plain": [ + "Empty DataFrame\n", + "Columns: []\n", + "Index: []" + ] + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "for mol_id in mol_ids:\n", " pmb.delete_instances_in_system(instance_id=0, \n", @@ -3990,7 +3355,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 55, "metadata": {}, "outputs": [], "source": [ @@ -4024,7 +3389,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 47, "metadata": {}, "outputs": [ { @@ -4061,50 +3426,120 @@ " \n", " 0\n", " particle\n", - " BB-part1\n", - " 0.4 nanometer\n", + " Na\n", + " 0.35 nanometer\n", " 25.692579121085853 millielectron_volt\n", " 0.5612310241546864 nanometer\n", " 0.0 nanometer\n", - " BB-part1\n", + " Na\n", " \n", " \n", " 1\n", " particle\n", - " COOH-part1\n", - " 0.5 nanometer\n", + " BB-PDha\n", + " 0.4 nanometer\n", " 25.692579121085853 millielectron_volt\n", " 0.5612310241546864 nanometer\n", " 0.0 nanometer\n", - " COOH-part1\n", + " BB-PDha\n", " \n", " \n", " 2\n", " particle\n", - " NH3-part1\n", + " COOH-PDha\n", + " 0.5 nanometer\n", + " 25.692579121085853 millielectron_volt\n", + " 0.5612310241546864 nanometer\n", + " 0.0 nanometer\n", + " COOH-PDha\n", + " \n", + " \n", + " 3\n", + " particle\n", + " NH3-PDha\n", " 0.3 nanometer\n", " 25.692579121085853 millielectron_volt\n", " 0.5612310241546864 nanometer\n", " 0.0 nanometer\n", - " NH3-part1\n", + " NH3-PDha\n", + " \n", + " \n", + " 4\n", + " particle\n", + " BB-PDAGA\n", + " 0.4 nanometer\n", + " 25.692579121085853 millielectron_volt\n", + " 0.5612310241546864 nanometer\n", + " 0.0 nanometer\n", + " BB-PDAGA\n", + " \n", + " \n", + " 5\n", + " particle\n", + " NH3-PDAGA\n", + " 0.3 nanometer\n", + " 25.692579121085853 millielectron_volt\n", + " 0.5612310241546864 nanometer\n", + " 0.0 nanometer\n", + " NH3-PDAGA\n", + " \n", + " \n", + " 6\n", + " particle\n", + " aCOOH-PDAGA\n", + " 0.2 nanometer\n", + " 25.692579121085853 millielectron_volt\n", + " 0.5612310241546864 nanometer\n", + " 0.0 nanometer\n", + " aCOOH-PDAGA\n", + " \n", + " \n", + " 7\n", + " particle\n", + " bCOOH-PDAGA\n", + " 0.4 nanometer\n", + " 25.692579121085853 millielectron_volt\n", + " 0.5612310241546864 nanometer\n", + " 0.0 nanometer\n", + " bCOOH-PDAGA\n", " \n", " \n", "\n", "" ], "text/plain": [ - " pmb_type name sigma epsilon \\\n", - "0 particle BB-part1 0.4 nanometer 25.692579121085853 millielectron_volt \n", - "1 particle COOH-part1 0.5 nanometer 25.692579121085853 millielectron_volt \n", - "2 particle NH3-part1 0.3 nanometer 25.692579121085853 millielectron_volt \n", + " pmb_type name sigma \\\n", + "0 particle Na 0.35 nanometer \n", + "1 particle BB-PDha 0.4 nanometer \n", + "2 particle COOH-PDha 0.5 nanometer \n", + "3 particle NH3-PDha 0.3 nanometer \n", + "4 particle BB-PDAGA 0.4 nanometer \n", + "5 particle NH3-PDAGA 0.3 nanometer \n", + "6 particle aCOOH-PDAGA 0.2 nanometer \n", + "7 particle bCOOH-PDAGA 0.4 nanometer \n", "\n", - " cutoff offset initial_state \n", - "0 0.5612310241546864 nanometer 0.0 nanometer BB-part1 \n", - "1 0.5612310241546864 nanometer 0.0 nanometer COOH-part1 \n", - "2 0.5612310241546864 nanometer 0.0 nanometer NH3-part1 " + " epsilon cutoff \\\n", + "0 25.692579121085853 millielectron_volt 0.5612310241546864 nanometer \n", + "1 25.692579121085853 millielectron_volt 0.5612310241546864 nanometer \n", + "2 25.692579121085853 millielectron_volt 0.5612310241546864 nanometer \n", + "3 25.692579121085853 millielectron_volt 0.5612310241546864 nanometer \n", + "4 25.692579121085853 millielectron_volt 0.5612310241546864 nanometer \n", + "5 25.692579121085853 millielectron_volt 0.5612310241546864 nanometer \n", + "6 25.692579121085853 millielectron_volt 0.5612310241546864 nanometer \n", + "7 25.692579121085853 millielectron_volt 0.5612310241546864 nanometer \n", + "\n", + " offset initial_state \n", + "0 0.0 nanometer Na \n", + "1 0.0 nanometer BB-PDha \n", + "2 0.0 nanometer COOH-PDha \n", + "3 0.0 nanometer NH3-PDha \n", + "4 0.0 nanometer BB-PDAGA \n", + "5 0.0 nanometer NH3-PDAGA \n", + "6 0.0 nanometer aCOOH-PDAGA \n", + "7 0.0 nanometer bCOOH-PDAGA " ] }, - "execution_count": 7, + "execution_count": 47, "metadata": {}, "output_type": "execute_result" } @@ -4116,7 +3551,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 57, "metadata": {}, "outputs": [ { @@ -4151,39 +3586,111 @@ " \n", " 0\n", " particle_state\n", - " BB-part1\n", - " BB-part1\n", + " Na\n", + " Na\n", " 0\n", " 0\n", " \n", " \n", " 1\n", " particle_state\n", - " COOH-part1\n", - " COOH-part1\n", + " BB-PDha\n", + " BB-PDha\n", " 0\n", " 1\n", " \n", " \n", " 2\n", " particle_state\n", + " COOH-PDha\n", + " COOH-PDha\n", + " 0\n", + " 2\n", + " \n", + " \n", + " 3\n", + " particle_state\n", + " NH3-PDha\n", + " NH3-PDha\n", + " 0\n", + " 3\n", + " \n", + " \n", + " 4\n", + " particle_state\n", + " BB-PDAGA\n", + " BB-PDAGA\n", + " 0\n", + " 4\n", + " \n", + " \n", + " 5\n", + " particle_state\n", + " NH3-PDAGA\n", + " NH3-PDAGA\n", + " 0\n", + " 5\n", + " \n", + " \n", + " 6\n", + " particle_state\n", + " aCOOH-PDAGA\n", + " aCOOH-PDAGA\n", + " 0\n", + " 6\n", + " \n", + " \n", + " 7\n", + " particle_state\n", + " bCOOH-PDAGA\n", + " bCOOH-PDAGA\n", + " 0\n", + " 7\n", + " \n", + " \n", + " 8\n", + " particle_state\n", + " BB-part1\n", + " BB-part1\n", + " 0\n", + " 8\n", + " \n", + " \n", + " 9\n", + " particle_state\n", + " COOH-part1\n", + " COOH-part1\n", + " 0\n", + " 9\n", + " \n", + " \n", + " 10\n", + " particle_state\n", " NH3-part1\n", " NH3-part1\n", " 0\n", - " 2\n", + " 10\n", " \n", " \n", "\n", "" ], "text/plain": [ - " pmb_type name particle_name z es_type\n", - "0 particle_state BB-part1 BB-part1 0 0\n", - "1 particle_state COOH-part1 COOH-part1 0 1\n", - "2 particle_state NH3-part1 NH3-part1 0 2" + " pmb_type name particle_name z es_type\n", + "0 particle_state Na Na 0 0\n", + "1 particle_state BB-PDha BB-PDha 0 1\n", + "2 particle_state COOH-PDha COOH-PDha 0 2\n", + "3 particle_state NH3-PDha NH3-PDha 0 3\n", + "4 particle_state BB-PDAGA BB-PDAGA 0 4\n", + "5 particle_state NH3-PDAGA NH3-PDAGA 0 5\n", + "6 particle_state aCOOH-PDAGA aCOOH-PDAGA 0 6\n", + "7 particle_state bCOOH-PDAGA bCOOH-PDAGA 0 7\n", + "8 particle_state BB-part1 BB-part1 0 8\n", + "9 particle_state COOH-part1 COOH-part1 0 9\n", + "10 particle_state NH3-part1 NH3-part1 0 10" ] }, - "execution_count": 8, + "execution_count": 57, "metadata": {}, "output_type": "execute_result" } @@ -4194,7 +3701,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 59, "metadata": {}, "outputs": [ { @@ -4228,36 +3735,36 @@ " \n", " 0\n", " residue\n", - " Residue1\n", - " BB-part1\n", - " [COOH-part1, NH3-part1]\n", + " PDha_mon\n", + " BB-PDha\n", + " [COOH-PDha, NH3-PDha]\n", " \n", " \n", " 1\n", " residue\n", - " side_chain_res_2\n", - " BB-part1\n", - " [COOH-part1, NH3-part1]\n", + " PDAGA_side_chain_residue\n", + " NH3-PDAGA\n", + " [aCOOH-PDAGA, bCOOH-PDAGA]\n", " \n", " \n", " 2\n", " residue\n", - " Residue2\n", - " BB-part1\n", - " [side_chain_res_2]\n", + " PDAGA_monomer_residue\n", + " BB-PDAGA\n", + " [PDAGA_side_chain_residue]\n", " \n", " \n", "\n", "" ], "text/plain": [ - " pmb_type name central_bead side_chains\n", - "0 residue Residue1 BB-part1 [COOH-part1, NH3-part1]\n", - "1 residue side_chain_res_2 BB-part1 [COOH-part1, NH3-part1]\n", - "2 residue Residue2 BB-part1 [side_chain_res_2]" + " pmb_type name central_bead side_chains\n", + "0 residue PDha_mon BB-PDha [COOH-PDha, NH3-PDha]\n", + "1 residue PDAGA_side_chain_residue NH3-PDAGA [aCOOH-PDAGA, bCOOH-PDAGA]\n", + "2 residue PDAGA_monomer_residue BB-PDAGA [PDAGA_side_chain_residue]" ] }, - "execution_count": 13, + "execution_count": 59, "metadata": {}, "output_type": "execute_result" } @@ -4268,7 +3775,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 60, "metadata": {}, "outputs": [ { @@ -4292,20 +3799,42 @@ " \n", " \n", " \n", + " pmb_type\n", + " name\n", + " residue_list\n", " \n", " \n", " \n", + " \n", + " 0\n", + " molecule\n", + " PDha\n", + " [PDha_mon, PDha_mon, PDha_mon, PDha_mon, PDha_...\n", + " \n", + " \n", + " 1\n", + " molecule\n", + " PDAGA\n", + " [PDAGA_monomer_residue, PDAGA_monomer_residue,...\n", + " \n", + " \n", + " 2\n", + " molecule\n", + " diblock\n", + " [PDha_mon, PDha_mon, PDha_mon, PDha_mon, PDAGA...\n", + " \n", " \n", "\n", "" ], "text/plain": [ - "Empty DataFrame\n", - "Columns: []\n", - "Index: []" + " pmb_type name residue_list\n", + "0 molecule PDha [PDha_mon, PDha_mon, PDha_mon, PDha_mon, PDha_...\n", + "1 molecule PDAGA [PDAGA_monomer_residue, PDAGA_monomer_residue,...\n", + "2 molecule diblock [PDha_mon, PDha_mon, PDha_mon, PDha_mon, PDAGA..." ] }, - "execution_count": 10, + "execution_count": 60, "metadata": {}, "output_type": "execute_result" } @@ -4316,7 +3845,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 61, "metadata": {}, "outputs": [], "source": [ @@ -4325,7 +3854,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 62, "metadata": {}, "outputs": [], "source": [ @@ -4334,7 +3863,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 63, "metadata": {}, "outputs": [], "source": [ @@ -4363,14 +3892,14 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 64, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "['Kw', 'N_A', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_check_bond_inputs', '_check_dimensionality', '_check_pka_set', '_create_espresso_bond_instance', '_create_hydrogel_chain', '_create_hydrogel_node', '_delete_particles_from_espresso', '_get_espresso_bond_instance', '_get_label_id_map', '_get_residue_list_from_sequence', '_get_template_type', 'calculate_HH', 'calculate_HH_Donnan', 'calculate_center_of_mass', 'calculate_net_charge', 'center_object_in_simulation_box', 'create_added_salt', 'create_bond', 'create_counterions', 'create_hydrogel', 'create_molecule', 'create_particle', 'create_protein', 'create_residue', 'db', 'define_bond', 'define_default_bond', 'define_hydrogel', 'define_molecule', 'define_monoprototic_acidbase_reaction', 'define_monoprototic_particle_states', 'define_particle', 'define_particle_states', 'define_peptide', 'define_protein', 'define_residue', 'delete_instances_in_system', 'determine_reservoir_concentrations', 'e', 'enable_motion_of_rigid_object', 'generate_coordinates_outside_sphere', 'generate_random_points_in_a_sphere', 'generate_trial_perpendicular_vector', 'get_bond_template', 'get_charge_number_map', 'get_instances_df', 'get_lj_parameters', 'get_particle_id_map', 'get_pka_set', 'get_radius_map', 'get_reactions_df', 'get_reduced_units', 'get_templates_df', 'get_type_map', 'initialize_lattice_builder', 'kB', 'kT', 'lattice_builder', 'load_database', 'load_pka_set', 'propose_unused_type', 'read_protein_vtf', 'rng', 'root', 'save_database', 'seed', 'set_particle_initial_state', 'set_reduced_units', 'setup_cpH', 'setup_gcmc', 'setup_grxmc_reactions', 'setup_grxmc_unified', 'setup_lj_interactions', 'units']\n", + "['Kw', 'N_A', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_check_bond_inputs', '_check_dimensionality', '_check_pka_set', '_create_espresso_bond_instance', '_create_hydrogel_chain', '_create_hydrogel_node', '_delete_particles_from_espresso', '_get_espresso_bond_instance', '_get_label_id_map', '_get_residue_list_from_sequence', '_get_template_type', 'add_instances_to_engine', 'calculate_HH', 'calculate_HH_Donnan', 'calculate_center_of_mass', 'calculate_net_charge', 'center_object_in_simulation_box', 'create_added_salt', 'create_bond', 'create_counterions', 'create_hydrogel', 'create_molecule', 'create_particle', 'create_protein', 'create_residue', 'db', 'define_bond', 'define_default_bond', 'define_hydrogel', 'define_molecule', 'define_monoprototic_acidbase_reaction', 'define_monoprototic_particle_states', 'define_particle', 'define_particle_states', 'define_peptide', 'define_protein', 'define_residue', 'delete_instances_in_system', 'determine_reservoir_concentrations', 'e', 'enable_motion_of_rigid_object', 'generate_coordinates_outside_sphere', 'generate_random_points_in_a_sphere', 'generate_trial_perpendicular_vector', 'get_bond_template', 'get_charge_number_map', 'get_instances_df', 'get_lj_parameters', 'get_particle_id_map', 'get_pka_set', 'get_radius_map', 'get_reactions_df', 'get_reduced_units', 'get_templates_df', 'get_type_map', 'initialize_lattice_builder', 'kB', 'kT', 'lattice_builder', 'load_database', 'load_pka_set', 'propose_unused_type', 'read_protein_vtf', 'rng', 'root', 'save_database', 'seed', 'set_particle_initial_state', 'set_reduced_units', 'set_simulation_engine', 'setup_cpH', 'setup_gcmc', 'setup_grxmc_reactions', 'setup_grxmc_unified', 'setup_lj_interactions', 'simulation_engine', 'units']\n", "Empty DataFrame\n", "Columns: []\n", "Index: []\n" @@ -4410,7 +3939,7 @@ "Index: []" ] }, - "execution_count": 16, + "execution_count": 64, "metadata": {}, "output_type": "execute_result" } @@ -4423,7 +3952,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 65, "metadata": {}, "outputs": [], "source": [ @@ -4451,7 +3980,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 66, "metadata": {}, "outputs": [], "source": [ @@ -4469,7 +3998,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 68, "metadata": {}, "outputs": [ { @@ -4496,6 +4025,8 @@ " pmb_type\n", " name\n", " particle_id\n", + " position\n", + " fix\n", " initial_state\n", " residue_id\n", " molecule_id\n", @@ -4508,6 +4039,8 @@ " particle\n", " BB-part1\n", " 0\n", + " [7.499999999999999, 7.499999999999999, 7.49999...\n", + " None\n", " BB-part1\n", " 0\n", " 0\n", @@ -4518,6 +4051,8 @@ " particle\n", " COOH-part1\n", " 1\n", + " [7.523286897123127, 6.7825727593903675, 8.0212...\n", + " None\n", " COOH-part1\n", " 0\n", " 0\n", @@ -4528,6 +4063,8 @@ " particle\n", " NH3-part1\n", " 2\n", + " [7.37125134474576, 7.37461010141046, 8.2766151...\n", + " None\n", " NH3-part1\n", " 0\n", " 0\n", @@ -4538,6 +4075,8 @@ " particle\n", " BB-part1\n", " 3\n", + " [6.694202325055984, 7.360411350475328, 7.34387...\n", + " None\n", " BB-part1\n", " 1\n", " 0\n", @@ -4548,6 +4087,8 @@ " particle\n", " COOH-part1\n", " 4\n", + " [6.8599927657093085, 7.377868784266711, 6.4725...\n", + " None\n", " COOH-part1\n", " 1\n", " 0\n", @@ -4558,6 +4099,8 @@ " particle\n", " NH3-part1\n", " 5\n", + " [6.5574917981405205, 7.276291078140914, 8.1246...\n", + " None\n", " NH3-part1\n", " 1\n", " 0\n", @@ -4568,6 +4111,8 @@ " particle\n", " BB-part1\n", " 6\n", + " [5.888404650111968, 7.220822700950657, 7.18775...\n", + " None\n", " BB-part1\n", " 2\n", " 0\n", @@ -4578,6 +4123,8 @@ " particle\n", " BB-part1\n", " 7\n", + " [6.0263924170157, 7.333839572897158, 6.3745136...\n", + " None\n", " BB-part1\n", " 2\n", " 0\n", @@ -4588,6 +4135,8 @@ " particle\n", " COOH-part1\n", " 8\n", + " [5.428627933302976, 7.973911138422894, 6.51570...\n", + " None\n", " COOH-part1\n", " 2\n", " 0\n", @@ -4598,6 +4147,8 @@ " particle\n", " NH3-part1\n", " 9\n", + " [6.214629818479694, 6.6498848824883945, 6.7381...\n", + " None\n", " NH3-part1\n", " 2\n", " 0\n", @@ -4608,6 +4159,8 @@ " particle\n", " BB-part1\n", " 10\n", + " [5.082606975167953, 7.0812340514259855, 7.0316...\n", + " None\n", " BB-part1\n", " 3\n", " 0\n", @@ -4618,6 +4171,8 @@ " particle\n", " COOH-part1\n", " 11\n", + " [5.286960752808877, 6.291537548321099, 6.68296...\n", + " None\n", " COOH-part1\n", " 3\n", " 0\n", @@ -4628,6 +4183,8 @@ " particle\n", " NH3-part1\n", " 12\n", + " [5.227170116100419, 7.1222992787424255, 6.2487...\n", + " None\n", " NH3-part1\n", " 3\n", " 0\n", @@ -4638,6 +4195,8 @@ " particle\n", " BB-part1\n", " 13\n", + " [4.276809300223937, 6.941645401901314, 6.87550...\n", + " None\n", " BB-part1\n", " 4\n", " 0\n", @@ -4648,6 +4207,8 @@ " particle\n", " COOH-part1\n", " 14\n", + " [4.297103791116088, 6.231022116744782, 7.40611...\n", + " None\n", " COOH-part1\n", " 4\n", " 0\n", @@ -4658,6 +4219,8 @@ " particle\n", " NH3-part1\n", " 15\n", + " [4.433450913961003, 6.168947892154966, 6.75789...\n", + " None\n", " NH3-part1\n", " 4\n", " 0\n", @@ -4668,6 +4231,8 @@ " particle\n", " BB-part1\n", " 16\n", + " [3.471011625279922, 6.802056752376643, 6.71937...\n", + " None\n", " BB-part1\n", " 5\n", " 0\n", @@ -4678,6 +4243,8 @@ " particle\n", " BB-part1\n", " 17\n", + " [3.523700228085275, 7.267635439887332, 6.03117...\n", + " None\n", " BB-part1\n", " 5\n", " 0\n", @@ -4688,6 +4255,8 @@ " particle\n", " COOH-part1\n", " 18\n", + " [2.8966913762229116, 7.384703534397699, 6.6476...\n", + " None\n", " COOH-part1\n", " 5\n", " 0\n", @@ -4698,6 +4267,8 @@ " particle\n", " NH3-part1\n", " 19\n", + " [2.8409213570311107, 7.6521574795497465, 5.884...\n", + " None\n", " NH3-part1\n", " 5\n", " 0\n", @@ -4708,6 +4279,8 @@ " particle\n", " BB-part1\n", " 20\n", + " [2.6652139503359065, 6.662468102851972, 6.5632...\n", + " None\n", " BB-part1\n", " 6\n", " 0\n", @@ -4718,6 +4291,8 @@ " particle\n", " BB-part1\n", " 21\n", + " [2.84313386885597, 5.87878434992065, 6.3456456...\n", + " None\n", " BB-part1\n", " 6\n", " 0\n", @@ -4728,6 +4303,8 @@ " particle\n", " COOH-part1\n", " 22\n", + " [3.3573262392838927, 6.109235583087225, 7.0308...\n", + " None\n", " COOH-part1\n", " 6\n", " 0\n", @@ -4738,6 +4315,8 @@ " particle\n", " NH3-part1\n", " 23\n", + " [3.2797726587483904, 6.041618000523718, 6.9923...\n", + " None\n", " NH3-part1\n", " 6\n", " 0\n", @@ -4748,60 +4327,86 @@ "" ], "text/plain": [ - " pmb_type name particle_id initial_state residue_id molecule_id \\\n", - "0 particle BB-part1 0 BB-part1 0 0 \n", - "1 particle COOH-part1 1 COOH-part1 0 0 \n", - "2 particle NH3-part1 2 NH3-part1 0 0 \n", - "3 particle BB-part1 3 BB-part1 1 0 \n", - "4 particle COOH-part1 4 COOH-part1 1 0 \n", - "5 particle NH3-part1 5 NH3-part1 1 0 \n", - "6 particle BB-part1 6 BB-part1 2 0 \n", - "7 particle BB-part1 7 BB-part1 2 0 \n", - "8 particle COOH-part1 8 COOH-part1 2 0 \n", - "9 particle NH3-part1 9 NH3-part1 2 0 \n", - "10 particle BB-part1 10 BB-part1 3 0 \n", - "11 particle COOH-part1 11 COOH-part1 3 0 \n", - "12 particle NH3-part1 12 NH3-part1 3 0 \n", - "13 particle BB-part1 13 BB-part1 4 0 \n", - "14 particle COOH-part1 14 COOH-part1 4 0 \n", - "15 particle NH3-part1 15 NH3-part1 4 0 \n", - "16 particle BB-part1 16 BB-part1 5 0 \n", - "17 particle BB-part1 17 BB-part1 5 0 \n", - "18 particle COOH-part1 18 COOH-part1 5 0 \n", - "19 particle NH3-part1 19 NH3-part1 5 0 \n", - "20 particle BB-part1 20 BB-part1 6 0 \n", - "21 particle BB-part1 21 BB-part1 6 0 \n", - "22 particle COOH-part1 22 COOH-part1 6 0 \n", - "23 particle NH3-part1 23 NH3-part1 6 0 \n", + " pmb_type name particle_id \\\n", + "0 particle BB-part1 0 \n", + "1 particle COOH-part1 1 \n", + "2 particle NH3-part1 2 \n", + "3 particle BB-part1 3 \n", + "4 particle COOH-part1 4 \n", + "5 particle NH3-part1 5 \n", + "6 particle BB-part1 6 \n", + "7 particle BB-part1 7 \n", + "8 particle COOH-part1 8 \n", + "9 particle NH3-part1 9 \n", + "10 particle BB-part1 10 \n", + "11 particle COOH-part1 11 \n", + "12 particle NH3-part1 12 \n", + "13 particle BB-part1 13 \n", + "14 particle COOH-part1 14 \n", + "15 particle NH3-part1 15 \n", + "16 particle BB-part1 16 \n", + "17 particle BB-part1 17 \n", + "18 particle COOH-part1 18 \n", + "19 particle NH3-part1 19 \n", + "20 particle BB-part1 20 \n", + "21 particle BB-part1 21 \n", + "22 particle COOH-part1 22 \n", + "23 particle NH3-part1 23 \n", + "\n", + " position fix initial_state \\\n", + "0 [7.499999999999999, 7.499999999999999, 7.49999... None BB-part1 \n", + "1 [7.523286897123127, 6.7825727593903675, 8.0212... None COOH-part1 \n", + "2 [7.37125134474576, 7.37461010141046, 8.2766151... None NH3-part1 \n", + "3 [6.694202325055984, 7.360411350475328, 7.34387... None BB-part1 \n", + "4 [6.8599927657093085, 7.377868784266711, 6.4725... None COOH-part1 \n", + "5 [6.5574917981405205, 7.276291078140914, 8.1246... None NH3-part1 \n", + "6 [5.888404650111968, 7.220822700950657, 7.18775... None BB-part1 \n", + "7 [6.0263924170157, 7.333839572897158, 6.3745136... None BB-part1 \n", + "8 [5.428627933302976, 7.973911138422894, 6.51570... None COOH-part1 \n", + "9 [6.214629818479694, 6.6498848824883945, 6.7381... None NH3-part1 \n", + "10 [5.082606975167953, 7.0812340514259855, 7.0316... None BB-part1 \n", + "11 [5.286960752808877, 6.291537548321099, 6.68296... None COOH-part1 \n", + "12 [5.227170116100419, 7.1222992787424255, 6.2487... None NH3-part1 \n", + "13 [4.276809300223937, 6.941645401901314, 6.87550... None BB-part1 \n", + "14 [4.297103791116088, 6.231022116744782, 7.40611... None COOH-part1 \n", + "15 [4.433450913961003, 6.168947892154966, 6.75789... None NH3-part1 \n", + "16 [3.471011625279922, 6.802056752376643, 6.71937... None BB-part1 \n", + "17 [3.523700228085275, 7.267635439887332, 6.03117... None BB-part1 \n", + "18 [2.8966913762229116, 7.384703534397699, 6.6476... None COOH-part1 \n", + "19 [2.8409213570311107, 7.6521574795497465, 5.884... None NH3-part1 \n", + "20 [2.6652139503359065, 6.662468102851972, 6.5632... None BB-part1 \n", + "21 [2.84313386885597, 5.87878434992065, 6.3456456... None BB-part1 \n", + "22 [3.3573262392838927, 6.109235583087225, 7.0308... None COOH-part1 \n", + "23 [3.2797726587483904, 6.041618000523718, 6.9923... None NH3-part1 \n", "\n", - " assembly_id \n", - "0 \n", - "1 \n", - "2 \n", - "3 \n", - "4 \n", - "5 \n", - "6 \n", - "7 \n", - "8 \n", - "9 \n", - "10 \n", - "11 \n", - "12 \n", - "13 \n", - "14 \n", - "15 \n", - "16 \n", - "17 \n", - "18 \n", - "19 \n", - "20 \n", - "21 \n", - "22 \n", - "23 " + " residue_id molecule_id assembly_id \n", + "0 0 0 \n", + "1 0 0 \n", + "2 0 0 \n", + "3 1 0 \n", + "4 1 0 \n", + "5 1 0 \n", + "6 2 0 \n", + "7 2 0 \n", + "8 2 0 \n", + "9 2 0 \n", + "10 3 0 \n", + "11 3 0 \n", + "12 3 0 \n", + "13 4 0 \n", + "14 4 0 \n", + "15 4 0 \n", + "16 5 0 \n", + "17 5 0 \n", + "18 5 0 \n", + "19 5 0 \n", + "20 6 0 \n", + "21 6 0 \n", + "22 6 0 \n", + "23 6 0 " ] }, - "execution_count": 17, + "execution_count": 68, "metadata": {}, "output_type": "execute_result" } @@ -4811,7 +4416,7 @@ "\n", "mol_ids = pmb.create_molecule(name = diblock_polymer,\n", " number_of_molecules= N_polymers,\n", - " espresso_system = espresso_system,\n", + " box_l = box_l,\n", " list_of_first_residue_positions = [[Box_L.to('reduced_length').magnitude/2]*3]) \n", "# See the particle instances you have created\n", "pmb.get_instances_df(pmb_type=\"particle\")" @@ -4819,7 +4424,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 69, "metadata": {}, "outputs": [ { @@ -4922,7 +4527,7 @@ "6 residue Residue2 6 0 " ] }, - "execution_count": 20, + "execution_count": 69, "metadata": {}, "output_type": "execute_result" } @@ -4931,6 +4536,15 @@ "pmb.get_instances_df(pmb_type=\"residue\")" ] }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.add_instances_to_engine()" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -4940,11 +4554,11 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 71, "metadata": {}, "outputs": [], "source": [ - "picture_name = 'CustomPolyampholite2.png'\n", + "picture_name = 'CustomPolyampholite2_new.png'\n", "create_snapshot_of_espresso_system(espresso_system = espresso_system, \n", " filename = picture_name)\n", "img = Image.open(picture_name)\n", @@ -4960,7 +4574,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 72, "metadata": {}, "outputs": [ { @@ -4997,7 +4611,7 @@ "Index: []" ] }, - "execution_count": 24, + "execution_count": 72, "metadata": {}, "output_type": "execute_result" } @@ -5048,7 +4662,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 73, "metadata": {}, "outputs": [], "source": [ @@ -5066,7 +4680,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 74, "metadata": {}, "outputs": [ { @@ -5175,7 +4789,7 @@ "5 {'r_0': 0.558 nanometer, 'k': 10277.0316484343... " ] }, - "execution_count": 27, + "execution_count": 74, "metadata": {}, "output_type": "execute_result" } @@ -5197,7 +4811,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 75, "metadata": {}, "outputs": [ { @@ -5339,7 +4953,7 @@ "8 {'summary': 'pKa-values of Hass et al.', 'sour... None " ] }, - "execution_count": 28, + "execution_count": 75, "metadata": {}, "output_type": "execute_result" } @@ -5359,7 +4973,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 76, "metadata": {}, "outputs": [ { @@ -5577,7 +5191,7 @@ "18 particle_state c c -1 18" ] }, - "execution_count": 29, + "execution_count": 76, "metadata": {}, "output_type": "execute_result" } @@ -5596,7 +5210,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 77, "metadata": {}, "outputs": [ { @@ -5712,7 +5326,7 @@ "5 0.3984740271498274 nanometer 0.0 nanometer KH " ] }, - "execution_count": 30, + "execution_count": 77, "metadata": {}, "output_type": "execute_result" } @@ -5730,7 +5344,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 78, "metadata": {}, "outputs": [ { @@ -5782,7 +5396,7 @@ "0 [AA-K, AA-K, AA-K, AA-K, AA-K, AA-E, AA-E, AA-... KKKKKEEEEE " ] }, - "execution_count": 31, + "execution_count": 78, "metadata": {}, "output_type": "execute_result" } @@ -5811,7 +5425,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 80, "metadata": {}, "outputs": [ { @@ -5858,7 +5472,7 @@ "0 peptide KKKKKEEEEE 0 " ] }, - "execution_count": 32, + "execution_count": 80, "metadata": {}, "output_type": "execute_result" } @@ -5867,11 +5481,20 @@ "\n", "mol_ids = pmb.create_molecule(name = sequence,\n", " number_of_molecules= N_peptide,\n", - " espresso_system = espresso_system,\n", + " box_l = box_l,\n", " list_of_first_residue_positions = [[Box_L.to('reduced_length').magnitude/2]*3])\n", "pmb.get_instances_df(pmb_type=\"peptide\")" ] }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.add_instances_to_engine()" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -5881,11 +5504,11 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 83, "metadata": {}, "outputs": [], "source": [ - "picture_name = 'peptide.png'\n", + "picture_name = 'peptide_new.png'\n", "create_snapshot_of_espresso_system(espresso_system = espresso_system, \n", " filename = picture_name)\n", "img = Image.open(picture_name)\n", @@ -5901,7 +5524,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 84, "metadata": {}, "outputs": [], "source": [ From 43fdd35ecb174da17a527c294c5f92c29aef1165 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 30 Apr 2026 09:39:12 +0200 Subject: [PATCH 13/75] Adapt methods: _create_hydrogel_chain _delete_particles_from_engine calculate_net_charge center_object_simulation_box create_counterions create_hydrogel create_particle delete_instances_in_system Add methods: change_volume_and_rescale_particles update_instances_ids_according_to_engine_particle_ids --- pyMBE/pyMBE.py | 160 +++++++++++++++++++++++++++++++------------------ 1 file changed, 103 insertions(+), 57 deletions(-) diff --git a/pyMBE/pyMBE.py b/pyMBE/pyMBE.py index 97b8f006..57e61a8a 100644 --- a/pyMBE/pyMBE.py +++ b/pyMBE/pyMBE.py @@ -25,6 +25,7 @@ import scipy.optimize import logging import importlib.resources +import warnings # Database from pyMBE.storage.manager import Manager @@ -49,7 +50,7 @@ from pyMBE.simulation_builder.espresso_engine import EspressoSimulation from pyMBE.simulation_builder.lammps_engine import LammpsSimulation -from pyMBE.simulation_builder.engine_protocol import EspressoSystemProtocol +from pyMBE.simulation_builder.engine_protocol import EspressoSystemProtocol,LammpsProtocol ## Reactions from pyMBE.storage.reactions.reaction import Reaction, ReactionParticipant # Utilities @@ -92,7 +93,7 @@ class pymbe_library(): Root path to the pyMBE package resources. """ - def __init__(self, seed, temperature=None, unit_length=None, unit_charge=None, Kw=None,simulation_engine='espresso'): + def __init__(self, seed, temperature=None, unit_length=None, unit_charge=None, Kw=None): """ Initializes the pyMBE library. @@ -128,7 +129,7 @@ def __init__(self, seed, temperature=None, unit_length=None, unit_charge=None, K Kw=Kw) self.db = Manager(units=self.units) - self.simulation_engine=None + self.simulation_engine = None self.lattice_builder = None self.root = importlib.resources.files(__package__) @@ -221,7 +222,7 @@ def _create_espresso_bond_instance(self, bond_type, bond_parameters): bond_instance = self.simulation_engine._create_bond_instance(bond_type,bond_parameters) return bond_instance - def _create_hydrogel_chain(self, hydrogel_chain, nodes, espresso_system, use_default_bond=False): + def _create_hydrogel_chain(self, hydrogel_chain, nodes, use_default_bond=False): """ Creates a chain between two nodes of a hydrogel. @@ -256,8 +257,11 @@ def _create_hydrogel_chain(self, hydrogel_chain, nodes, espresso_system, use_def node_start_label = self.lattice_builder._create_node_label(node_start) node_end_label = self.lattice_builder._create_node_label(node_end) _, reverse = self.lattice_builder._get_node_vector_pair(node_start, node_end) - if node_start != node_end or residue_list == residue_list[::-1]: - ValueError(f"Aborted creation of hydrogel chain between '{node_start}' and '{node_end}' because pyMBE could not resolve a unique topology for that chain") + # if node_start != node_end or residue_list == residue_list[::-1]: + ### Hydrogels are not a circular structure thus node_start has to be different that node_end + if node_start == node_end or (residue_list == residue_list[::-1] and len(residue_list)>1): + # ValueError(f"Aborted creation of hydrogel chain between '{node_start}' and '{node_end}' because pyMBE could not resolve a unique topology for that chain") + raise ValueError(f"Aborted creation of hydrogel chain between '{node_start}' and '{node_end}' because pyMBE could not resolve a unique topology for that chain") if reverse: reverse_residue_order=True else: @@ -277,6 +281,7 @@ def _create_hydrogel_chain(self, hydrogel_chain, nodes, espresso_system, use_def name=chain_residues[0]).central_bead part_end_chain_name = self.db.get_template(pmb_type="residue", name=chain_residues[-1]).central_bead + lj_parameters = self.get_lj_parameters(particle_name1=nodes[node_start_label]["name"], particle_name2=part_start_chain_name) bond_tpl = self.get_bond_template(particle_name1=nodes[node_start_label]["name"], @@ -288,29 +293,24 @@ def _create_hydrogel_chain(self, hydrogel_chain, nodes, espresso_system, use_def first_bead_pos = np.array((nodes[node_start_label]["pos"])) + np.array(backbone_vector)*l0 mol_id = self.create_molecule(name=molecule_name, # Use the name defined earlier number_of_molecules=1, # Creating one chain - espresso_system=espresso_system, + box_l=self.lattice_builder.box_l, ### Add lattice_builder box length size list_of_first_residue_positions=[first_bead_pos.tolist()], #Start at the first node backbone_vector=np.array(backbone_vector)/l0, use_default_bond=use_default_bond, reverse_residue_order=reverse_residue_order)[0] + # Bond chain to the hydrogel nodes ### The following implementation belongs to espresso engine chain_pids = self.db._find_instance_ids_by_attribute(pmb_type="particle", attribute="molecule_id", value=mol_id) - bond_tpl1 = self.get_bond_template(particle_name1=nodes[node_start_label]["name"], - particle_name2=part_start_chain_name, - use_default_bond=use_default_bond) - start_bond_instance = self._get_espresso_bond_instance(bond_template=bond_tpl1) - bond_tpl2 = self.get_bond_template(particle_name1=nodes[node_end_label]["name"], - particle_name2=part_end_chain_name, - use_default_bond=use_default_bond) - end_bond_instance = self._get_espresso_bond_instance(bond_template=bond_tpl2) - espresso_system.part.by_id(start_node_id).add_bond((start_bond_instance, chain_pids[0])) - espresso_system.part.by_id(chain_pids[-1]).add_bond((end_bond_instance, end_node_id)) + + self.create_bond(particle_id1=start_node_id,particle_id2=chain_pids[0],use_default_bond=use_default_bond) + self.create_bond(particle_id1=chain_pids[-1],particle_id2=end_node_id,use_default_bond=use_default_bond) + return mol_id - def _create_hydrogel_node(self, node_index, node_name): + def _create_hydrogel_node(self, node_index, node_name,box_l): """ Set a node residue type. @@ -333,7 +333,7 @@ def _create_hydrogel_node(self, node_index, node_name): raise ValueError("LatticeBuilder is not initialized. Use 'initialize_lattice_builder' first.") node_position = np.array(node_index)*0.25*self.lattice_builder.box_l p_id = self.create_particle(name = node_name, - box_l=self.lattice_builder.box_l, + box_l=box_l, number_of_particles=1, position = [node_position]) key = self.lattice_builder._get_node_by_label(f"[{node_index[0]} {node_index[1]} {node_index[2]}]") @@ -425,7 +425,7 @@ def _get_template_type(self, name, allowed_types): raise ValueError(f"No {allowed_types} template found with name '{name}'. Found templates of types: {filtered_types}.") return next(iter(filtered_types)) - def _delete_particles_from_espresso(self, particle_ids, espresso_system): + def _delete_particles_from_engine(self, particle_ids): """ Remove a list of particles from an ESPResSo simulation system. @@ -444,13 +444,14 @@ def _delete_particles_from_espresso(self, particle_ids, espresso_system): - Attempting to remove a non-existent particle ID will raise an ESPResSo error. """ - for pid in particle_ids: - espresso_system.part.by_id(pid).remove() + # for pid in particle_ids: + # espresso_system.part.by_id(pid).remove() + self.simulation_engine._delete_particles(particle_ids) def add_instances_to_engine(self): self.simulation_engine.add_instances_to_engine() - def calculate_center_of_mass(self, instance_id, pmb_type, espresso_system): + def calculate_center_of_mass(self, instance_id, pmb_type): """ Calculates the center of mass of a pyMBE object instance in an ESPResSo system. @@ -479,10 +480,13 @@ def calculate_center_of_mass(self, instance_id, pmb_type, espresso_system): axis_list = [0,1,2] inst = self.db.get_instance(pmb_type=pmb_type, instance_id=instance_id) + print(inst," instance center of mass") + print(inst.name,"name instance") particle_id_list = self.get_particle_id_map(object_name=inst.name)["all"] for pid in particle_id_list: for axis in axis_list: - center_of_mass [axis] += espresso_system.part.by_id(pid).pos[axis] + 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 @@ -654,7 +658,7 @@ def calc_partition_coefficient(charge, c_macro): partition_coefficients_list.append(partition_coefficient) return {"charges_dict": Z_HH_Donnan, "pH_system_list": pH_system_list, "partition_coefficients": partition_coefficients_list} - def calculate_net_charge(self,espresso_system,object_name,pmb_type,dimensionless=False): + def calculate_net_charge(self,object_name,pmb_type,dimensionless=False): """ Calculates the net charge per instance of a given pmb object type. @@ -683,7 +687,14 @@ def calculate_net_charge(self,espresso_system,object_name,pmb_type,dimensionless else: net_charge = 0 * self.units.Quantity(1, "reduced_charge") for pid in particle_ids: - q = espresso_system.part.by_id(pid).q + particle_instance=self.db.get_instance(pmb_type='particle', + instance_id=pid) + particle_name=particle_instance.name + particle_tpl = self.db.get_template(pmb_type="particle", + name=particle_name) + particle_state = self.db.get_template(pmb_type="particle_state", + name=particle_tpl.initial_state) + q = particle_state.z if not dimensionless: q *= self.units.Quantity(1, "reduced_charge") net_charge += q @@ -695,7 +706,7 @@ def calculate_net_charge(self,espresso_system,object_name,pmb_type,dimensionless mean_charge = (np.mean([q.magnitude for q in charges.values()])* self.units.Quantity(1, "reduced_charge")) return {"mean": mean_charge, "instances": charges} - def center_object_in_simulation_box(self, instance_id, espresso_system, pmb_type): + def center_object_in_simulation_box(self, instance_id, box_l,pmb_type): """ Centers a pyMBE object instance in the simulation box of an ESPResSo system. The object is translated such that its center of mass coincides with the @@ -717,15 +728,21 @@ def center_object_in_simulation_box(self, instance_id, espresso_system, pmb_type inst = self.db.get_instance(instance_id=instance_id, pmb_type=pmb_type) center_of_mass = self.calculate_center_of_mass(instance_id=instance_id, - espresso_system=espresso_system, pmb_type=pmb_type) - box_center = [espresso_system.box_l[0]/2.0, - espresso_system.box_l[1]/2.0, - espresso_system.box_l[2]/2.0] + box_center = [box_l[0]/2.0, + box_l[1]/2.0, + box_l[2]/2.0] particle_id_list = self.get_particle_id_map(object_name=inst.name)["all"] + print(particle_id_list,"particle_id_list") for pid in particle_id_list: - es_pos = espresso_system.part.by_id(pid).pos - espresso_system.part.by_id(pid).pos = es_pos - center_of_mass + box_center + es_pos=self.db.get_instance(instance_id=pid, + pmb_type='particle').position + centered_position=es_pos - center_of_mass + box_center + + self.db._update_instance(instance_id=pid, + pmb_type='particle', + attribute='position', + value=centered_position) def create_added_salt(self, box_l, cation_name, anion_name, c_salt): """ @@ -755,7 +772,7 @@ def create_added_salt(self, box_l, cation_name, anion_name, c_salt): if anion_charge >= 0: raise ValueError(f'ERROR anion charge must be negative, charge {anion_charge}') # Calculate the number of ions in the simulation box - volume=self.units.Quantity(box_l**3, 'reduced_length**3') ### Changed espresso.volume() to box_l**3 + volume=self.units.Quantity(box_l[0]*box_l[1]*box_l[2], 'reduced_length**3') ### Changed espresso.volume() to box_l**3 if c_salt.check('[substance] [length]**-3'): N_ions= int((volume*c_salt.to('mol/reduced_length**3')*self.N_A).magnitude) c_salt_calculated=N_ions/(volume*self.N_A) @@ -869,11 +886,11 @@ def create_counterions(self, object_name, cation_name, anion_name, box_l): name=object_name) object_state = self.db.get_template(pmb_type="particle_state", name=object_tpl.initial_state) - object_charge = object_state.z - if object_charge > 0: - object_charge['positive']+=1*(np.abs(object_charge )) - elif object_charge < 0: - object_charge['negative']+=1*(np.abs(object_charge )) + object_z = object_state.z + if object_z > 0: + object_charge['positive']+=1*(np.abs(object_z )) + elif object_z < 0: + object_charge['negative']+=1*(np.abs(object_z )) if object_charge['positive'] % abs(anion_charge) == 0: counterion_number[anion_name]=int(object_charge['positive']/abs(anion_charge)) else: @@ -899,7 +916,7 @@ def create_counterions(self, object_name, cation_name, anion_name, box_l): logging.info(f'Ion type: {name} created number: {counterion_number[name]}') return counterion_number - def create_hydrogel(self, name, espresso_system, use_default_bond=False): + def create_hydrogel(self, name, box_l,use_default_bond=False): """ Creates a hydrogel in espresso_system using a pyMBE hydrogel template given by 'name' @@ -928,7 +945,8 @@ def create_hydrogel(self, name, espresso_system, use_default_bond=False): node_index = node.lattice_index node_name = node.particle_name node_pos, node_id = self._create_hydrogel_node(node_index=node_index, - node_name=node_name) + node_name=node_name, + box_l=box_l) node_label = self.lattice_builder._create_node_label(node_index=node_index) nodes[node_label] = {"name": node_name, "id": node_id, "pos": node_pos} self.db._update_instance(instance_id=node_id, @@ -1099,7 +1117,7 @@ def create_molecule(self, name, number_of_molecules, box_l, list_of_first_residu molecule_ids.append(molecule_id) return molecule_ids - def create_particle(self, name, box_l, number_of_particles, position=None, fix=False): + def create_particle(self, name, box_l, number_of_particles, position=None, fix=[False,False,False]): """ Creates one or more particles in an ESPResSo system based on the particle template in the pyMBE database. @@ -1141,22 +1159,17 @@ def create_particle(self, name, box_l, number_of_particles, position=None, fix=F if position is None: particle_position = self.rng.random((1, 3))[0] *np.copy(box_l) else: - particle_position = position[index] + particle_position = np.array(position[index]) particle_id = self.db._propose_instance_id(pmb_type="particle") created_pid_list.append(particle_id) # kwargs = dict(id=particle_id, pos=particle_position, type=es_type, q=z) - if fix: - particle_fix= 3 * [fix] ### Is the fix attribute something concrete from espresso_system? - else: - particle_fix=None # espresso_system.part.add(**kwargs) - part_inst = ParticleInstance(name=name, particle_id=particle_id, initial_state=name_state, position=particle_position, - fix=particle_fix) + fix=fix) self.db._register_instance(part_inst) return created_pid_list @@ -1235,7 +1248,7 @@ def create_protein(self, name, number_of_proteins, box_l, topology_dict): box_l=box_l, number_of_particles=1, position=[absolute_pos], - fix=True)[0] + fix=[True,True,True])[0] # update metadata self.db._update_instance(instance_id=particle_id, pmb_type="particle", @@ -1379,8 +1392,35 @@ def create_residue(self, name, box_l, central_bead_position=None,use_default_bon self.create_bond(particle_id1=central_bead_id, particle_id2=side_chain_beads_ids[0], use_default_bond=use_default_bond) - return residue_id + return residue_id + + def change_volume_and_rescale_particles(self, d_new, dir="xyz"): + + rescale_factor=np.array([1,1,1]) + if d_new<=0: + raise ValueError("The dimension cannot be negative, neither 0") + if "x" in dir: + rescale_factor[0]=d_new/self.simulation_engine.box_l[0] + if "y" in dir: + rescale_factor[1]=d_new/self.simulation_engine.box_l[1] + if "z" in dir: + rescale_factor[2]=d_new/self.simulation_engine.box_l[2] + + instances=self.get_instances_df(pmb_type='particle') + for pid in range(instances.index.size): + es_pos=self.db.get_instance(instance_id=pid, + pmb_type='particle').position + rescaled_position=es_pos*rescale_factor + print(rescaled_position,"rescaled_position") + self.db._update_instance(instance_id=pid, + pmb_type='particle', + attribute='position', + value=rescaled_position) + + self.simulation_engine.change_volume_and_rescale_particles(d_new=d_new, + dir=dir) + return def define_bond(self, bond_type, bond_parameters, particle_pairs): """ Defines bond templates for each particle pair in 'particle_pairs' in the pyMBE database. @@ -1746,7 +1786,7 @@ def define_residue(self, name, central_bead, side_chains): self.db._register_template(tpl) - def delete_instances_in_system(self, instance_id, pmb_type, espresso_system): + def delete_instances_in_system(self, instance_id, pmb_type): """ Deletes the instance with instance_id from the ESPResSo system. Related assembly, molecule, residue, particles and bond instances will also be deleted from the pyMBE dataframe. @@ -1772,8 +1812,7 @@ def delete_instances_in_system(self, instance_id, pmb_type, espresso_system): particle_ids = self.db._find_instance_ids_by_attribute(pmb_type="particle", attribute=instance_identifier, value=instance_id) - self._delete_particles_from_espresso(particle_ids=particle_ids, - espresso_system=espresso_system) + self._delete_particles_from_engine(particle_ids=particle_ids) self.db.delete_instance(pmb_type=pmb_type, instance_id=instance_id) @@ -1906,7 +1945,6 @@ def enable_motion_of_rigid_object(self, instance_id, pmb_type, espresso_system): label = self._get_label_id_map(pmb_type=pmb_type) particle_ids_list = self.get_particle_id_map(object_name=inst.name)[label][instance_id] center_of_mass = self.calculate_center_of_mass (instance_id=instance_id, - espresso_system=espresso_system, pmb_type=pmb_type) rigid_object_center = espresso_system.part.add(pos=center_of_mass, rotation=[True,True,True], @@ -2568,9 +2606,11 @@ def set_simulation_engine(self,simulation_engine,box_l=None): db=self.db, espresso_system=simulation_engine, units=self.units) - elif 'lammps' in type(simulation_engine): + elif isinstance(simulation_engine,LammpsProtocol): self.simulation_engine=LammpsSimulation(box_l=box_l, - db=self.db) + db=self.db, + lammps=simulation_engine, + units=self.units) else: raise ValueError('The specified simulation engine is not implemented yet') @@ -3238,3 +3278,9 @@ def setup_lj_interactions(self, espresso_system, shift_potential=True, combining ureg=self.units), shift=shift_tpl) self.db._register_template(lj_template) + + def update_instances_ids_according_to_engine_particles_ids(self): + """ + Method to be called if particles have been previously added to a simulation engine without using pymbe. + """ + self.simulation_engine.update_instances_ids_according_to_engine_particles_ids() \ No newline at end of file From ae645c8d4afce08f51aa9051f2c9c925aa18a97f Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 30 Apr 2026 09:43:28 +0200 Subject: [PATCH 14/75] Modify method add_instances_to_engine in order that takes into account the missing particles from pymbe DB and the particles that have not been transferred yet to espresso. Add methods _add_bond, _add_particle,_check_particle_exists_in_espresso,_get_last_particle_id_in_espresso,update_instances_ids_according_to_engine_particles_ids --- pyMBE/simulation_builder/espresso_engine.py | 220 ++++++++++++++++---- 1 file changed, 174 insertions(+), 46 deletions(-) diff --git a/pyMBE/simulation_builder/espresso_engine.py b/pyMBE/simulation_builder/espresso_engine.py index 96dbe5c4..aabdb977 100644 --- a/pyMBE/simulation_builder/espresso_engine.py +++ b/pyMBE/simulation_builder/espresso_engine.py @@ -1,16 +1,53 @@ from pyMBE.simulation_builder.base_engine import SimulationEngine import espressomd +import warnings +from typing import List,Set class EspressoSimulation(SimulationEngine): def __init__(self,box_l,db,espresso_system,units): self.db=db - self.box_l=box_l + self.box_l: List[float]=box_l self.espresso_system=espresso_system self.units=units pass + + def _add_bond(self,particle_id1,particle_id2,bond_inst): + bond_tpl=self.db.get_template(name=bond_inst.name, + pmb_type="bond") + espresso_bond_inst=self._get_bond_instance(bond_template=bond_tpl) + self.espresso_system.part.by_id(particle_id1).add_bond((espresso_bond_inst, particle_id2)) + self.db._update_instance(instance_id=bond_inst.bond_id, + pmb_type='bond', + attribute='added_to_engine', + value=True) + + def _add_particle(self,particle_id): + particle_instance=self.db.get_instance(pmb_type='particle', + instance_id=particle_id) + # part_tpl = self.db.get_template(pmb_type="particle", + # name=particle_instance.name) + part_state = self.db.get_template(pmb_type="particle_state", + name=particle_instance.initial_state) + + if particle_instance.fix: + kwargs = dict(id=particle_id, pos=particle_instance.position, type=part_state.es_type, q=part_state.z,fix=particle_instance.fix) + else: + kwargs = dict(id=particle_id, pos=particle_instance.position, type=part_state.es_type, q=part_state.z) + + self.espresso_system.part.add(**kwargs) + self.db._update_instance(instance_id=particle_id, + pmb_type='particle', + attribute='added_to_engine', + value=True) + + + def _check_particle_exists_in_espresso(self,particle_id): + particle_exists=self.espresso_system.exists(particle_id) + return particle_exists + def _check_bond_inputs(self, bond_type, bond_parameters): """ Checks that the input bond parameters are valid within the current pyMBE implementation. @@ -30,7 +67,7 @@ def _check_bond_inputs(self, bond_type, bond_parameters): for required_parameter in required_parameters[bond_type]: if required_parameter not in bond_parameters.keys(): raise ValueError(f"Missing required parameter {required_parameter} for {bond_type} bond") - + def _create_bond_instance(self, bond_type, bond_parameters): """ Creates an ESPResSo bond instance. @@ -65,11 +102,37 @@ def _create_bond_instance(self, bond_type, bond_parameters): bond_instance = espressomd.interactions.HarmonicBond(k = bond_parameters["k"].m_as("reduced_energy/reduced_length**2"), r_0 = bond_parameters["r_0"].m_as("reduced_length")) elif bond_type == 'FENE': - bond_instance = espressomd.interactions.FeneBond(k = bond_parameters["k"].m_as("reduced_energy/reduced_length**2"), + bond_instance = espressomd.interactions.FeneBond(k = bond_parameters["k"].m_as("reduced_energy/reduced_length**2"), r_0 = bond_parameters["r_0"].m_as("reduced_length"), d_r_max = bond_parameters["d_r_max"].m_as("reduced_length")) return bond_instance + def _delete_particles(self, particle_ids): + """ + Remove a list of particles from an ESPResSo simulation system. + + Args: + particle_ids ('Iterable[int]'): + A list (or other iterable) of ESPResSo particle IDs to remove. + + espresso_system ('espressomd.system.System'): + The ESPResSo simulation system from which the particles + will be removed. + + Notess: + - This method removes particles only from the ESPResSo simulation, + **not** from the pyMBE database. Database cleanup must be handled + separately by the caller. + - Attempting to remove a non-existent particle ID will raise + an ESPResSo error. + """ + for pid in particle_ids: + self.espresso_system.part.by_id(pid).remove() + self.db._update_instance(instance_id=pid, + pmb_type='particle', + attribute='added_to_engine', + value=False) + def _get_bond_instance(self, bond_template): """ Retrieve or create a bond instance in an ESPResSo system for a given pair of particle names. @@ -97,60 +160,125 @@ def _get_bond_instance(self, bond_template): self.espresso_system.bonded_inter.add(bond_inst) return bond_inst - def _add_bond(self,particle_id1,particle_id2,bond_inst): - bond_tpl=self.db.get_template(name=bond_inst.name, - pmb_type="bond") - espresso_bond_inst=self._get_bond_instance(bond_template=bond_tpl) - self.espresso_system.part.by_id(particle_id1).add_bond((espresso_bond_inst, particle_id2)) + + + + def _get_last_particle_id_in_espresso(self): + espresso_particles=self.espresso_system.part.all() + if len(espresso_particles)==0: + return None + last_particle_id=espresso_particles.id + return last_particle_id[-1] + + def _get_particle_pos_espresso(self,id): + return self.espresso_system.part.by_id(id).pos - def _add_particle(self,particle_id): - particle_instance=self.db.get_instance(pmb_type='particle', - instance_id=particle_id) - # part_tpl = self.db.get_template(pmb_type="particle", - # name=particle_instance.name) - part_state = self.db.get_template(pmb_type="particle_state", - name=particle_instance.initial_state) - - if particle_instance.fix: - kwargs = dict(id=particle_id, pos=particle_instance.position, type=part_state.es_type, q=part_state.z,fix=particle_instance.fix) - else: - kwargs = dict(id=particle_id, pos=particle_instance.position, type=part_state.es_type, q=part_state.z) - - self.espresso_system.part.add(**kwargs) - def get_box_side_length(self): return self.box_l + def change_volume_and_rescale_particles(self, d_new, dir="xyz"): + """ + Change the volume for a particular dimension into the espresso system. + args: + d_new(float): new value for the dimension + dir(Literal[x,y,z]): coordinate in which to set the new dimension. + + """ + self.espresso_system.change_volume_and_rescale_particles(d_new=d_new, + dir=dir) + return + + def update_instances_ids_according_to_engine_particles_ids(self): + """ + Method to be called if particles have been previously added to a simulation engine without using pymbe. + """ + + if self.espresso_system == None: + raise ValueError('No simulation engine has been set to pymbe') + + last_id=self._get_last_particle_id_in_espresso() + + if last_id == None: + raise ValueError('This method is intended to be used if particles have been previously added to a simulation engine') + + particle_instances=self.db.get_instances(pmb_type='particle') + for i in range(particle_instances.index.size): + self.db._update_instance(instance_id=i, + pmb_type='particle', + attribute='particle_id', + value=last_id+i) + + bond_instances=self.db.get_instances(pmb_type='bond') + for i in range(bond_instances.index.size): + bond_instance=self.db.get_instance(pmb_type='bond', + instance_id=i) + self.db._update_instance(instance_id=i, + pmb_type='bond', + attribute='particle_id1', + value=last_id+bond_instance.particle_id1) + self.db._update_instance(instance_id=i, + pmb_type='bond', + attribute='particle_id2', + value=last_id+bond_instance.particle_id2) + warnings.warn("""Please review your setup, you have previously added a set of particles to ESPResSo. The particle ids of the pyMBE database have been updated taking into account the id of the last particle from ESPResSo. """ + ) + def add_instance_to_engine(self,pmb_type,instance_id): + + if pmb_type=='particle': + self._add_particle(instance_id) + elif pmb_type=='bond': + + bond_instance=self.db.get_instance(pmb_type='bond', + instance_id=instance_id) + particle_id1=bond_instance.particle_id1 + particle_id2=bond_instance.particle_id2 + self._add_bond(particle_id1,particle_id2,bond_instance) + + elif pmb_type=='residue': + raise TypeError('Use add instances to engine to add particles and bonds not residue instances') + elif pmb_type=='molecule': + raise TypeError('Use add instances to engine to add particles and bonds that correspond to a molecule instance') + elif pmb_type=='protein': + raise TypeError('Use add instances to engine to add particles and bonds not protein instances') + elif pmb_type=='assembly': + raise TypeError('Use add instances to engine to add particles and bonds not assembly instances') def add_instances_to_engine(self): + """ + This method adds the set of particles instances and bond instances that are not present in the pymbe data base + """ ### test the method - bond_instances=self.db._get_instances_df(pmb_type='bond') - particle_instances=self.db._get_instances_df(pmb_type='particle') - if bond_instances.index.size>0: + all_particles=self.db._get_instances_df(pmb_type='particle') + missing_particle_ids=self.db._find_instance_ids_by_attribute(pmb_type='particle', + attribute='added_to_engine', + value=False) + + last_id=self._get_last_particle_id_in_espresso() - particles_added=set() - for i in range(bond_instances.index.size): + if last_id!=None and len(missing_particle_ids)>0: + ### this condition takes into account the following edge case: + ### A set of particles have been added to espresso without using pyMBE. + ### And a second set of particles have been added to the pyMBE database and the user wants them to be added to espresso + if last_id>=missing_particle_ids[0]: + self.update_instances_ids_according_to_engine_particles_ids() + + if all_particles.index.size>0: + for id in missing_particle_ids: + self._add_particle(id) + else: + raise RuntimeError('No particles, residues or molecules have been created so far') + + missing_bond_ids=self.db._find_instance_ids_by_attribute(pmb_type='bond', + attribute='added_to_engine', + value=False) + + if len(missing_bond_ids)>0: + for id in missing_bond_ids: bond_instance=self.db.get_instance(pmb_type='bond', - instance_id=i) + instance_id=id) particle_id1=bond_instance.particle_id1 particle_id2=bond_instance.particle_id2 - if particle_id1 not in particles_added: - self._add_particle(particle_id1) - particles_added.add(particle_id1) - - if particle_id2 not in particles_added: - self._add_particle(particle_id2) - particles_added.add(particle_id2) - self._add_bond(particle_id1,particle_id2,bond_instance) - - elif particle_instances.index.size>0: - for i in range(particle_instances.index.size): - self._add_particle(i) - else: - raise RuntimeError('No particles, residues or molecules have been created so far') - - - + return From 914f74ce6e321b4bedd644884affcb87d1940612 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 30 Apr 2026 09:43:46 +0200 Subject: [PATCH 15/75] Add LammpsEngineProtocol --- pyMBE/simulation_builder/engine_protocol.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pyMBE/simulation_builder/engine_protocol.py b/pyMBE/simulation_builder/engine_protocol.py index 1e65de2a..5e8a4ee8 100644 --- a/pyMBE/simulation_builder/engine_protocol.py +++ b/pyMBE/simulation_builder/engine_protocol.py @@ -15,3 +15,9 @@ class EspressoSystemProtocol(Protocol): . 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""" + From 7b903b3db134dc8b391cd99034da9b94619ca7b8 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 30 Apr 2026 09:44:12 +0200 Subject: [PATCH 16/75] Add LammpsSimulation still to be build the code related to LammpsSimulation --- pyMBE/simulation_builder/lammps_engine.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyMBE/simulation_builder/lammps_engine.py b/pyMBE/simulation_builder/lammps_engine.py index eebf9aef..e80e2cd7 100644 --- a/pyMBE/simulation_builder/lammps_engine.py +++ b/pyMBE/simulation_builder/lammps_engine.py @@ -1,8 +1,8 @@ -from base_classes import SimulationBuilder +from pyMBE.simulation_builder.base_engine import SimulationEngine -class LammpsSimulation(SimulationBuilder): +class LammpsSimulation(SimulationEngine): def __init__(self): pass - def save_molecule(self): + def add_instances_to_engine(self): return \ No newline at end of file From 7c57df571a7adf33199a350c3c95bf28a133690f Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 30 Apr 2026 09:49:44 +0200 Subject: [PATCH 17/75] Add position and added to engine in pmb_type particle for _load_database_csv and _save_database_csv Add added_to_engine for pmb_type bond in _load_database_csv and _save_database_csv. This methods still have to pass the test due float point accuracy between save/load --- pyMBE/storage/io.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pyMBE/storage/io.py b/pyMBE/storage/io.py index 70826528..2b42640b 100644 --- a/pyMBE/storage/io.py +++ b/pyMBE/storage/io.py @@ -22,6 +22,7 @@ from pathlib import Path from typing import Any, Dict import pandas as pd +import numpy as np import logging from pyMBE.storage.pint_quantity import PintQuantity @@ -259,7 +260,7 @@ def _load_database_csv(db, folder): csv_file = folder / f"instances_{pmb_type}.csv" if not csv_file.exists(): continue - df = pd.read_csv(csv_file, dtype=str).fillna("") + df = pd.read_csv(csv_file, dtype=str,float_precision='round_trip').fillna("") instances: Dict[Any, Any] = {} @@ -272,6 +273,8 @@ def _load_database_csv(db, folder): inst = ParticleInstance(name=row["name"], particle_id=int(row["particle_id"]), initial_state=row["initial_state"], + position=np.array(row["position"]), + added_to_engine=row["added_to_engine"], residue_id=None if residue_val == "" else int(residue_val), molecule_id=None if molecule_val == "" else int(molecule_val), assembly_id=None if assembly_val == "" else int(assembly_val)) @@ -305,6 +308,7 @@ def _load_database_csv(db, folder): elif pmb_type == "bond": inst = BondInstance(name=row["name"], bond_id=int(row["bond_id"]), + added_to_engine=row["added_to_engine"], particle_id1=int(row["particle_id1"]), particle_id2=int(row["particle_id2"])) instances[inst.bond_id] = inst @@ -435,6 +439,8 @@ def _save_database_csv(db, folder): "name": inst.name, "particle_id": int(inst.particle_id), "initial_state": inst.initial_state, + "position": inst.position, + "added_to_engine":inst.added_to_engine, "residue_id": int(inst.residue_id) if inst.residue_id is not None else "", "molecule_id": int(inst.molecule_id) if inst.molecule_id is not None else "", "assembly_id": int(inst.assembly_id) if inst.assembly_id is not None else ""}) @@ -463,6 +469,7 @@ def _save_database_csv(db, folder): rows.append({"pmb_type": pmb_type, "name": inst.name, "bond_id": int(inst.bond_id), + "added_to_engine":inst.added_to_engine, "particle_id1": int(inst.particle_id1), "particle_id2": int(inst.particle_id2)}) elif pmb_type == "hydrogel" and isinstance(inst, HydrogelInstance): @@ -477,7 +484,7 @@ def _save_database_csv(db, folder): rows.append({"name": getattr(inst, "name", None)}) df = pd.DataFrame(rows) - df.to_csv(os.path.join(folder, f"instances_{pmb_type}.csv"), index=False) + df.to_csv(os.path.join(folder, f"instances_{pmb_type}.csv"), index=False,float_format="%.17g") # REACTIONS rows = [] @@ -488,4 +495,4 @@ def _save_database_csv(db, folder): "reaction_type": rx.reaction_type, "metadata": _encode(rx.metadata) if getattr(rx, "metadata", None) is not None else ""}) if rows: - pd.DataFrame(rows).to_csv(os.path.join(folder, "reactions.csv"), index=False) \ No newline at end of file + pd.DataFrame(rows).to_csv(os.path.join(folder, "reactions.csv"), index=False,float_format="%.4f") \ No newline at end of file From 0fa66d401b1449a8a95766e6e319bd9f5e4a206b Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 30 Apr 2026 09:51:23 +0200 Subject: [PATCH 18/75] Add into Manager class _update_instance method for pymbe type particle, particle_id,position and added_to_engine. Add pymbe type bond and allowed particle_id1,particle_id2 and added_to_engine --- pyMBE/storage/manager.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pyMBE/storage/manager.py b/pyMBE/storage/manager.py index 3a2e13c6..f8af9eb9 100644 --- a/pyMBE/storage/manager.py +++ b/pyMBE/storage/manager.py @@ -225,7 +225,7 @@ def _find_template_types(self, name): if name in group: found.append(pmb_type) return found - + def _get_instances_df(self, pmb_type): """ @@ -504,11 +504,13 @@ def _update_instance(self, instance_id, pmb_type, attribute, value): if instance_id not in self._instances[pmb_type]: raise ValueError(f"Instance '{instance_id}' not found for type '{pmb_type}' in the pyMBE database.") if pmb_type == "particle": - allowed = ["initial_state", "residue_id", "molecule_id", "assembly_id"] + allowed = ["initial_state", "residue_id", "molecule_id", "assembly_id","particle_id","position","added_to_engine"] elif pmb_type == "residue": allowed = ["molecule_id", "assembly_id"] elif pmb_type in self._molecule_like_types: allowed = ["assembly_id"] + elif pmb_type =="bond": + allowed = ["particle_id1","particle_id2","added_to_engine"] else: allowed = [None] # No attributes allowed for other types if attribute not in allowed: @@ -1070,3 +1072,5 @@ def get_particle_states_templates(self, particle_name): particle_states = {state.name: state for state in states.values() if state.particle_name == particle_name} return particle_states + + From 6c939ff46868eb4e95e371330f57b0fbe30d50f9 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 30 Apr 2026 09:52:38 +0200 Subject: [PATCH 19/75] Add attributes added_to_engine for both particleinstances and bond instances --- pyMBE/storage/instances/bond.py | 1 + pyMBE/storage/instances/particle.py | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pyMBE/storage/instances/bond.py b/pyMBE/storage/instances/bond.py index 24b07f2b..e38eb340 100644 --- a/pyMBE/storage/instances/bond.py +++ b/pyMBE/storage/instances/bond.py @@ -53,6 +53,7 @@ class BondInstance(PMBBaseModel): name : str # bond template name particle_id1: int particle_id2: int + added_to_engine: bool = False @validator("bond_id", "particle_id1", "particle_id2") def validate_non_negative_int(cls, value, field): diff --git a/pyMBE/storage/instances/particle.py b/pyMBE/storage/instances/particle.py index 29067236..407cb98b 100644 --- a/pyMBE/storage/instances/particle.py +++ b/pyMBE/storage/instances/particle.py @@ -18,12 +18,13 @@ # from typing import Literal, Optional,List,Annotated +import numpy as np from numpy.typing import NDArray from pydantic import validator from ..base_type import PMBBaseModel def validate_position(position): - if not isinstance(position,NDArray): + if not isinstance(position,np.ndarray): raise TypeError("Position has to be a numpy array") return position @@ -62,10 +63,11 @@ class ParticleInstance(PMBBaseModel): particle_id: int initial_state: str position: Annotated[NDArray,validate_position] - fix: Optional[List[bool]]=None + fix: List[bool]=[False,False,False] residue_id: Optional[int] = None molecule_id: Optional[int] = None assembly_id: Optional[int] = None + added_to_engine: bool = False class Config: arbitrary_types_allowed=True From fd4572d70867f500d71232a5ac4d2a967add39b5 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 30 Apr 2026 09:53:15 +0200 Subject: [PATCH 20/75] Adapt sample/branched_polyampholyte to changes related in decoupling pymbe --- samples/branched_polyampholyte.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/samples/branched_polyampholyte.py b/samples/branched_polyampholyte.py index 5478be72..a6064e3c 100644 --- a/samples/branched_polyampholyte.py +++ b/samples/branched_polyampholyte.py @@ -143,21 +143,22 @@ calculated_polyampholyte_concentration = N_polyampholyte_chains/(volume*pmb.N_A) # Create an instance of an espresso system -espresso_system=espressomd.System(box_l = [L.to('reduced_length').magnitude]*3) +box_l = [L.to('reduced_length').magnitude]*3 +espresso_system=espressomd.System(box_l = box_l) espresso_system.time_step=dt espresso_system.cell_system.skin=0.4 # Create your molecules into the espresso system pmb.create_molecule(name="polyampholyte", number_of_molecules=N_polyampholyte_chains, - espresso_system=espresso_system, + box_l=box_l, use_default_bond=True) pmb.create_counterions(object_name="polyampholyte", cation_name=cation_name, anion_name=anion_name, - espresso_system=espresso_system) + box_l=box_l) -c_salt_calculated = pmb.create_added_salt(espresso_system=espresso_system, +c_salt_calculated = pmb.create_added_salt(box_l=box_l, cation_name=cation_name, anion_name=anion_name, c_salt=c_salt) @@ -189,6 +190,9 @@ cpH.set_non_interacting_type (type=non_interacting_type) if verbose: print(f"The non interacting type is set to {non_interacting_type}") + +pmb.set_simulation_engine(espresso_system) +pmb.add_instances_to_engine() if not ideal: ##Setup the potential energy From c1d3ea8a97659d95a10dfd3ff68e1765dd4f46aa Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 30 Apr 2026 10:08:59 +0200 Subject: [PATCH 21/75] Add modifications to tests. The main modification consists on setting as the simulation engine espresso and adding to the simulation engine the instances (particles and bonds ) to the engine. Also removing espresso as an argument from pymbe methods. Adding box_l as argument to pymbe methods --- testsuite/bond_tests.py | 58 +++++++++--------- testsuite/calculate_net_charge_unit_test.py | 26 +++----- testsuite/create_molecule_position_test.py | 50 +++++++++------ testsuite/database_unit_tests.py | 20 +++--- .../define_and_create_molecules_unit_tests.py | 61 +++++++++++-------- testsuite/globular_protein_unit_tests.py | 22 ++++--- testsuite/hydrogel_builder.py | 14 +++-- testsuite/lattice_builder.py | 11 ++-- testsuite/seed_test.py | 11 ++-- testsuite/setup_salt_ions_unit_tests.py | 55 +++++++++-------- testsuite/test_io_database.py | 39 ++++++++---- 11 files changed, 208 insertions(+), 159 deletions(-) diff --git a/testsuite/bond_tests.py b/testsuite/bond_tests.py index bd3b2f8d..bbac0d16 100644 --- a/testsuite/bond_tests.py +++ b/testsuite/bond_tests.py @@ -23,7 +23,8 @@ import espressomd # Create an instance of pyMBE library -espresso_system=espressomd.System (box_l = [10]*3) +box_l=[10]*3 +espresso_system=espressomd.System (box_l = box_l) @@ -90,14 +91,16 @@ def test_bond_setup(self): particle_pairs = [['A', 'A']]) # Create two particles pids = pmb.create_particle(name="A", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=2) pmb.create_bond(particle_id1=pids[0], particle_id2=pids[1], - espresso_system=espresso_system, use_default_bond=False) + pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() + bond_object = self.get_bond_object(particle_id_pair=pids) self.check_bond_setup(bond_object=bond_object, @@ -106,10 +109,9 @@ def test_bond_setup(self): # Clean-up database for inst_id in pids: pmb.delete_instances_in_system(instance_id=inst_id, - pmb_type="particle", - espresso_system=espresso_system) + pmb_type="particle") pid_A = pmb.create_particle(name="A", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) harmonic_params_test = {'r_0' : 0.5 * pmb.units.nm, @@ -119,7 +121,7 @@ def test_bond_setup(self): particle_pairs = [['A', 'B']]) pid_B = pmb.create_particle(name="B", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) # Test that the bond is properly setup when there is a default bond @@ -128,9 +130,10 @@ def test_bond_setup(self): pmb.create_bond(particle_id1=pid_B[0], particle_id2=pid_A[0], - espresso_system=espresso_system, use_default_bond=True) + pmb.add_instances_to_engine() + bond_object = self.get_bond_object(particle_id_pair=[pid_B[0],pid_A[0]]) self.check_bond_setup(bond_object=bond_object, @@ -139,8 +142,7 @@ def test_bond_setup(self): # Clean-up database for inst_id in pid_B+pid_A: pmb.delete_instances_in_system(instance_id=inst_id, - pmb_type="particle", - espresso_system=espresso_system) + pmb_type="particle") pmb.db.delete_templates(pmb_type="bond") # Test setup of FENE bonds @@ -149,14 +151,15 @@ def test_bond_setup(self): particle_pairs = [['A', 'A']]) # Create two particles pids = pmb.create_particle(name="A", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=2) pmb.create_bond(particle_id1=pids[0], particle_id2=pids[1], - espresso_system=espresso_system, use_default_bond=False) + pmb.add_instances_to_engine() + bond_object = self.get_bond_object(particle_id_pair=pids) self.check_bond_setup(bond_object=bond_object, @@ -165,10 +168,9 @@ def test_bond_setup(self): # Clean-up database for inst_id in pids: pmb.delete_instances_in_system(instance_id=inst_id, - pmb_type="particle", - espresso_system=espresso_system) + pmb_type="particle") pid_A = pmb.create_particle(name="A", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) FENE_params_test = {'r_0' : 0.5 * pmb.units.nm, @@ -179,7 +181,7 @@ def test_bond_setup(self): particle_pairs = [['A', 'B']]) pid_B = pmb.create_particle(name="B", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) # Test that the FENE bond is properly setup when there is a default bond @@ -188,9 +190,10 @@ def test_bond_setup(self): pmb.create_bond(particle_id1=pid_B[0], particle_id2=pid_A[0], - espresso_system=espresso_system, use_default_bond=True) + pmb.add_instances_to_engine() + bond_object = self.get_bond_object(particle_id_pair=[pid_B[0],pid_A[0]]) self.check_bond_setup(bond_object=bond_object, @@ -199,8 +202,7 @@ def test_bond_setup(self): # Clean-up database for inst_id in pid_B+pid_A: pmb.delete_instances_in_system(instance_id=inst_id, - pmb_type="particle", - espresso_system=espresso_system) + pmb_type="particle") pmb.db.delete_templates(pmb_type="bond") @@ -209,14 +211,15 @@ def test_bond_setup(self): bond_parameters = self.harmonic_params) pids = pmb.create_particle(name="A", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=2) pmb.create_bond(particle_id1=pids[0], particle_id2=pids[1], - espresso_system=espresso_system, use_default_bond=True) + pmb.add_instances_to_engine() + bond_object = self.get_bond_object(particle_id_pair=pids) self.check_bond_setup(bond_object=bond_object, @@ -225,16 +228,15 @@ def test_bond_setup(self): # Clean-up database for inst_id in pids: pmb.delete_instances_in_system(instance_id=inst_id, - pmb_type="particle", - espresso_system=espresso_system) + pmb_type="particle") pmb.db.delete_templates(pmb_type="bond") # Test setup of default bond when there are other bonds defined pid_A = pmb.create_particle(name="A", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_B = pmb.create_particle(name="B", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pmb.define_default_bond(bond_type = "FENE", @@ -245,9 +247,10 @@ def test_bond_setup(self): pmb.create_bond(particle_id1=pid_B[0], particle_id2=pid_A[0], - espresso_system=espresso_system, use_default_bond=True) + pmb.add_instances_to_engine() + bond_object = self.get_bond_object(particle_id_pair=[pid_B[0],pid_A[0]]) self.check_bond_setup(bond_object=bond_object, @@ -256,8 +259,7 @@ def test_bond_setup(self): # Clean-up database for inst_id in pid_B+pid_A: pmb.delete_instances_in_system(instance_id=inst_id, - pmb_type="particle", - espresso_system=espresso_system) + pmb_type="particle") pmb.db.delete_templates(pmb_type="bond") def test_bond_raised_exceptions(self): diff --git a/testsuite/calculate_net_charge_unit_test.py b/testsuite/calculate_net_charge_unit_test.py index 2f3992e8..ca6432f2 100644 --- a/testsuite/calculate_net_charge_unit_test.py +++ b/testsuite/calculate_net_charge_unit_test.py @@ -68,7 +68,8 @@ residue_list = ['R1']*2+['R2']*3) # Create an instance of an espresso system -espresso_system=espressomd.System(box_l = [10]*3) +box_l=[10]*3 +espresso_system=espressomd.System(box_l = box_l ) # Create your molecules into the espresso system @@ -93,9 +94,10 @@ node_topology, chain_topology) pmb.create_hydrogel(name="my_hydrogel", - espresso_system=espresso_system, - use_default_bond=True) - + use_default_bond=True, + box_l=box_l) +pmb.set_simulation_engine(espresso_system) +pmb.add_instances_to_engine() class Test(ut.TestCase): def test_calculate_net_charge_with_units(self): """ @@ -104,16 +106,14 @@ def test_calculate_net_charge_with_units(self): # Check that it calculates properly the charge of the whole hydrogel charge_map = pmb.calculate_net_charge(object_name="my_hydrogel", - pmb_type="hydrogel", - espresso_system=espresso_system) + pmb_type="hydrogel") np.testing.assert_equal(charge_map["mean"], 40.0*pmb.units.Quantity(1,'reduced_charge')) np.testing.assert_equal(charge_map["instances"], {0: 40.0*pmb.units.Quantity(1,'reduced_charge')}) # Check that it calculates properly the charge of the chains in the hydrogel charge_map = pmb.calculate_net_charge(object_name=molecule_name, - pmb_type="molecule", - espresso_system=espresso_system) + pmb_type="molecule") # Check mean charge np.testing.assert_equal(charge_map["mean"], 2.0*pmb.units.Quantity(1,'reduced_charge')) # Check molecule charge map @@ -137,11 +137,9 @@ def test_calculate_net_charge_with_units(self): # Check that it calculates properly the charge of the residues in the hydrogel charge_map_r1 = pmb.calculate_net_charge(object_name="R1", - pmb_type="residue", - espresso_system=espresso_system) + pmb_type="residue") charge_map_r2 = pmb.calculate_net_charge(object_name="R2", - pmb_type="residue", - espresso_system=espresso_system) + pmb_type="residue") res_charge_map = charge_map_r1["instances"] | charge_map_r2["instances"] np.testing.assert_equal(res_charge_map[0], 1.0*pmb.units.Quantity(1,'reduced_charge')) np.testing.assert_equal(res_charge_map[1], 1.0*pmb.units.Quantity(1,'reduced_charge')) @@ -157,14 +155,12 @@ def test_calculate_net_charge_without_units(self): # Check that it calculates properly the charge of the whole hydrogel charge_map = pmb.calculate_net_charge(object_name="my_hydrogel", pmb_type="hydrogel", - espresso_system=espresso_system, dimensionless=True) np.testing.assert_equal(charge_map["mean"], 40.0) np.testing.assert_equal(charge_map["instances"], {0: 40.0}) # Check the case where the returned charge does not have a dimension charge_map = pmb.calculate_net_charge(object_name=molecule_name, pmb_type="molecule", - espresso_system=espresso_system, dimensionless=True) # Check mean charge np.testing.assert_equal(charge_map["mean"], 2.0) @@ -188,11 +184,9 @@ def test_calculate_net_charge_without_units(self): 15: 2.0}) charge_map_r1 = pmb.calculate_net_charge(object_name="R1", pmb_type="residue", - espresso_system=espresso_system, dimensionless=True) charge_map_r2 = pmb.calculate_net_charge(object_name="R2", pmb_type="residue", - espresso_system=espresso_system, dimensionless=True) res_charge_map = charge_map_r1["instances"] | charge_map_r2["instances"] np.testing.assert_equal(res_charge_map[0], 1.0) diff --git a/testsuite/create_molecule_position_test.py b/testsuite/create_molecule_position_test.py index f6edb529..208b28f4 100644 --- a/testsuite/create_molecule_position_test.py +++ b/testsuite/create_molecule_position_test.py @@ -19,6 +19,7 @@ import espressomd import pyMBE import unittest as ut +import pandas as pd pmb = pyMBE.pymbe_library(seed=42) @@ -49,7 +50,9 @@ # Create an instance of an espresso system L = 52 -espresso_system=espressomd.System(box_l = [L]*3) +box_l=[L]*3 +espresso_system=espressomd.System(box_l = box_l) +pmb.set_simulation_engine(espresso_system) pos_list = [[10,10,10], [20,20,20], [30,30,30]] class Test(ut.TestCase): @@ -59,9 +62,11 @@ def test_create_molecule_at_position(self): """ molecule_ids = pmb.create_molecule(name=molecule_name, number_of_molecules= 3, - espresso_system=espresso_system, + box_l=box_l, use_default_bond=True, list_of_first_residue_positions = pos_list) + + pmb.add_instances_to_engine() particle_id_map = pmb.get_particle_id_map(object_name=molecule_name) central_bead_pos = [] for molecule_id in molecule_ids: @@ -72,8 +77,7 @@ def test_create_molecule_at_position(self): central_bead_pos) for molid in molecule_ids: pmb.delete_instances_in_system(instance_id=molid, - pmb_type="molecule", - espresso_system=espresso_system) + pmb_type="molecule") def test_sanity_create_molecule(self): """ @@ -83,7 +87,7 @@ def test_sanity_create_molecule(self): # Check that create_molecule raises a ValueError if the user does not provide a nested list for list_of_first_residue_positions input_parameters={"name": "generic_molecule", "number_of_molecules": 1, - "espresso_system": espresso_system, + "box_l": box_l, "list_of_first_residue_positions": [1,2,3]} self.assertRaises(ValueError, pmb.create_molecule, @@ -91,7 +95,7 @@ def test_sanity_create_molecule(self): # Check that create_molecule raises a ValueError if the user does not provide a nested list with three coordinates input_parameters={"name": "generic_molecule", "number_of_molecules": 1, - "espresso_system": espresso_system, + "box_l": box_l, "list_of_first_residue_positions": [[1,2]]} self.assertRaises(ValueError, pmb.create_molecule, @@ -99,7 +103,7 @@ def test_sanity_create_molecule(self): # Check that create_molecule raises a ValueError if the user does not provide a the same number of first_residue_positions as number_of_molecules input_parameters={"name": "generic_molecule", "number_of_molecules": 2, - "espresso_system": espresso_system, + "box_l": box_l, "list_of_first_residue_positions": [[1,2,3]]} self.assertRaises(ValueError, pmb.create_molecule, @@ -111,30 +115,40 @@ def test_center_molecule_in_simulation_box(self): """ molecule_ids = pmb.create_molecule(name=molecule_name, number_of_molecules= 3, - espresso_system=espresso_system, + box_l=box_l, use_default_bond=True, list_of_first_residue_positions = pos_list) - + + # Check that center_molecule_in_simulation_box works correctly for cubic boxes + pmb.center_object_in_simulation_box(instance_id=molecule_ids[0], - espresso_system=espresso_system, + box_l=box_l, pmb_type="molecule") + + center_of_mass = pmb.calculate_center_of_mass(instance_id=molecule_ids[0], - pmb_type="molecule", - espresso_system=espresso_system) + pmb_type="molecule") + + pmb.add_instances_to_engine() + center_of_mass_ref = [L/2]*3 + for ind in range(len(center_of_mass)): self.assertAlmostEqual(center_of_mass[ind], center_of_mass_ref[ind]) #Check that center_molecule_in_simulation_box works correctly for non-cubic boxes - espresso_system.change_volume_and_rescale_particles(d_new=3*L, dir="z") - + ### New implementation in order to avoid using espresso + # espresso_system.change_volume_and_rescale_particles(d_new=3*L, dir="z") + + pmb.change_volume_and_rescale_particles(d_new=3*L, dir="z") + new_box_l=[box_l[0],box_l[1],3*L] pmb.center_object_in_simulation_box(instance_id=molecule_ids[2], pmb_type="molecule", - espresso_system=espresso_system) + box_l=new_box_l) center_of_mass = pmb.calculate_center_of_mass(instance_id=molecule_ids[2], - pmb_type="molecule", - espresso_system=espresso_system) + pmb_type="molecule") + center_of_mass_ref = [L/2, L/2, 1.5*L] for ind in range(len(center_of_mass)): self.assertAlmostEqual(center_of_mass[ind], @@ -148,7 +162,7 @@ def test_sanity_center_object_in_simulation_box(self): input_parameters = {"instance_id": 20 , "pmb_type": "molecule", - "espresso_system":espresso_system} + "box_l":box_l} self.assertRaises(ValueError, pmb.center_object_in_simulation_box, diff --git a/testsuite/database_unit_tests.py b/testsuite/database_unit_tests.py index af3f3b10..e59dc077 100644 --- a/testsuite/database_unit_tests.py +++ b/testsuite/database_unit_tests.py @@ -32,7 +32,9 @@ from pyMBE.storage.pint_quantity import PintQuantity from pyMBE.storage.reactions.reaction import Reaction, ReactionParticipant import pint -espresso_system=espressomd.System(box_l = [10]*3) +import numpy as np +box_l=[10]*3 +espresso_system=espressomd.System(box_l =box_l ) class Test(ut.TestCase): @@ -75,7 +77,8 @@ class DummyInstance(): acidity="acidic") part_inst = ParticleInstance(name="A", particle_id=0, - initial_state="A") + initial_state="A", + position=np.array([box_l[0]*0.5,box_l[1]*0.5,box_l[2]*0.5])) pmb.db._register_instance(part_inst) inputs = {"instance": part_inst} self.assertRaises(ValueError, @@ -83,7 +86,8 @@ class DummyInstance(): **inputs) templateless_part_inst = ParticleInstance(name="B", particle_id=1, - initial_state="B") + initial_state="B", + position=np.array([box_l[0]*0.5,box_l[1]*0.5,box_l[2]*0.5])) inputs = {"instance": templateless_part_inst} self.assertRaises(ValueError, pmb.db._register_instance, @@ -185,7 +189,8 @@ class DummyInstance(): ## Calling the function deletes all instances of a given pmb_type part_inst = ParticleInstance(name="A", particle_id=1, - initial_state="A") + initial_state="A", + position=np.array([box_l[0]*0.5,box_l[1]*0.5,box_l[2]*0.5])) pmb.db._register_instance(part_inst) pmb.db.delete_instances(pmb_type="particle") assert "particle" not in pmb.db._instances.keys() @@ -216,9 +221,9 @@ def test_find_instance_ids(self): pmb.define_molecule(name="M1", residue_list=["R1"]*2) pmb.create_molecule(name="M1", - espresso_system=espresso_system, number_of_molecules=1, - use_default_bond=True) + use_default_bond=True, + box_l=box_l) instance_ids_r1 = pmb.db._find_instance_ids_by_attribute(pmb_type="particle", attribute="residue_id", value=0) @@ -360,7 +365,8 @@ def test_instance_id_validators(self): """ inputs = {"name":"A", "particle_id":-1, - "initial_state":"A"} + "initial_state":"A", + "position":np.array([box_l[0]*0.5,box_l[1]*0.5,box_l[2]*0.5])} self.assertRaises(ValueError, ParticleInstance, **inputs) diff --git a/testsuite/define_and_create_molecules_unit_tests.py b/testsuite/define_and_create_molecules_unit_tests.py index 8060556b..5d1185f5 100644 --- a/testsuite/define_and_create_molecules_unit_tests.py +++ b/testsuite/define_and_create_molecules_unit_tests.py @@ -69,7 +69,8 @@ pmb.define_molecule(**parameter_set) # Create an instance of an espresso system -espresso_system=espressomd.System(box_l = [10]*3) +box_l=[10]*3 +espresso_system=espressomd.System(box_l = box_l) particle_positions=[[0,0,0],[1,1,1]] bond_type = 'harmonic' @@ -115,10 +116,14 @@ def test_create_and_delete_particles(self): """ retval = pmb.create_particle(name="S1", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=2, - fix=True, + fix=[True,True,True], position=particle_positions) + + pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() + self.assertListEqual(retval, [0, 1]) particle_ids=pmb.get_particle_id_map(object_name="S1")["all"] @@ -135,30 +140,36 @@ def test_create_and_delete_particles(self): list2=particle_positions[pid]) starting_number_of_particles=len(espresso_system.part.all()) + ### Tests that when number of particles is 0 or -1 no particles is created for number_of_particles in [0, -1]: retval = pmb.create_particle(name="S1", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=number_of_particles) self.assertEqual(len(retval), 0) + + # If no particles have been created, only two particles should be in the system (from the previous test) self.assertEqual(first=len(espresso_system.part.all()), second=starting_number_of_particles) + + ### Returns ValueError as no particle with name S23 has been previously defined. with self.assertRaises(ValueError): pmb.create_particle(name="S23", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) # If no particles have been created, only two particles should be in the system (from the previous test) + self.assertEqual(first=len(espresso_system.part.all()), second=starting_number_of_particles) + # Unit tests for delete particle starting_number_of_particles=len(espresso_system.part.all()) starting_number_of_rows=len(pmb.get_instances_df(pmb_type="particle")) # This should delete one particle instance pmb.delete_instances_in_system(instance_id=0, - pmb_type="particle", - espresso_system=espresso_system) + pmb_type="particle") self.assertEqual(first=len(espresso_system.part.all()), second=starting_number_of_particles-1) particle_df = pmb.get_instances_df(pmb_type="particle") @@ -167,21 +178,21 @@ def test_create_and_delete_particles(self): # Delete the other particle instance to simplify the rest of the tests pmb.delete_instances_in_system(instance_id=1, - pmb_type="particle", - espresso_system=espresso_system) + pmb_type="particle") central_bead_position=[[0,0,0]] backbone_vector=np.array([1.,2.,3.]) pmb.create_residue(name="R2", - espresso_system=espresso_system, + box_l=box_l, central_bead_position=central_bead_position, backbone_vector=backbone_vector, use_default_bond=True) particle_ids=pmb.get_particle_id_map(object_name="R2")["all"] + pmb.add_instances_to_engine() # Check that the particle properties are correct for pid in particle_ids: particle=espresso_system.part.by_id(pid) @@ -228,11 +239,11 @@ def test_create_and_delete_particles(self): second=frozenset([frozenset([0,1]),frozenset([0,2])])) pmb.create_residue(name="R3", - espresso_system=espresso_system, + box_l=box_l, use_default_bond=True) particle_ids=pmb.get_particle_id_map(object_name="R3")["all"] - + pmb.add_instances_to_engine() # Check that the particle properties are correct for pid in particle_ids: particle=espresso_system.part.by_id(pid) @@ -254,6 +265,7 @@ def test_create_and_delete_particles(self): bonded_pairs=[] bond_df = pmb.get_instances_df(pmb_type="bond") + for bond_index in bond_df.index: particle_id1= bond_df.loc[bond_index,"particle_id1"] @@ -278,7 +290,7 @@ def test_create_and_delete_particles(self): starting_number_of_particles=len(espresso_system.part.all()) with self.assertRaises(ValueError): pmb.create_residue(name="R51", - espresso_system=espresso_system, + box_l=box_l, use_default_bond=True) # If no particles have been created, the number of particles should be the same as before self.assertEqual(first=len(espresso_system.part.all()), @@ -288,8 +300,7 @@ def test_create_and_delete_particles(self): # This should delete 3 particles (residue 0 is a R2 residue) starting_number_of_particles=len(espresso_system.part.all()) pmb.delete_instances_in_system(instance_id=0, - pmb_type="residue", - espresso_system=espresso_system) + pmb_type="residue") self.assertEqual(first=len(espresso_system.part.all()), second=starting_number_of_particles-3) # There should be only one residue instance now in the pyMBE database @@ -300,18 +311,17 @@ def test_create_and_delete_particles(self): second=4) # Delete the other residue instance to simplify the rest of the tests pmb.delete_instances_in_system(instance_id=1, - pmb_type="residue", - espresso_system=espresso_system) + pmb_type="residue") backbone_vector = np.array([1,3,-4]) magnitude = np.linalg.norm(backbone_vector) backbone_vector = backbone_vector/magnitude pmb.create_molecule(name="M2", number_of_molecules=1, - espresso_system=espresso_system, + box_l=box_l, backbone_vector = backbone_vector, use_default_bond=True) - + pmb.add_instances_to_engine() particle_ids=pmb.get_particle_id_map(object_name="M2")["all"] # Residue and molecule IDs expected @@ -405,12 +415,13 @@ def test_create_and_delete_particles(self): starting_number_of_particles=len(espresso_system.part.all()) pmb.create_molecule(name="M2", number_of_molecules=0, - espresso_system=espresso_system, + box_l=box_l, use_default_bond=True) pmb.create_molecule(name="M2", number_of_molecules=-1, - espresso_system=espresso_system, + box_l=box_l, use_default_bond=True) + pmb.add_instances_to_engine() # If no particles have been created, only two particles should be in the system (from the previous test) self.assertEqual(first=len(espresso_system.part.all()), second=starting_number_of_particles) @@ -418,21 +429,21 @@ def test_create_and_delete_particles(self): self.assertRaises(ValueError, pmb.create_molecule, name="M3", number_of_molecules=1, - espresso_system=espresso_system, + box_l=box_l, use_default_bond=True) # Tests for delete_molecule # create another molecule just to have two molecules in the system pmb.create_molecule(name="M2", number_of_molecules=1, - espresso_system=espresso_system, + box_l=box_l, backbone_vector = backbone_vector, use_default_bond=True) # This should delete 8 particles (molecule 0 is a M2 molecule) + pmb.add_instances_to_engine() starting_number_of_particles=len(espresso_system.part.all()) pmb.delete_instances_in_system(instance_id=0, - pmb_type="molecule", - espresso_system=espresso_system) + pmb_type="molecule") self.assertEqual(first=len(espresso_system.part.all()), second=starting_number_of_particles-8) # There should only one molecule instance now in the pyMBE database diff --git a/testsuite/globular_protein_unit_tests.py b/testsuite/globular_protein_unit_tests.py index 19c6634d..23af38a7 100644 --- a/testsuite/globular_protein_unit_tests.py +++ b/testsuite/globular_protein_unit_tests.py @@ -38,6 +38,7 @@ ref_residue_list.append(f"AA-{key}") + class Test(ut.TestCase): def test_protein_setup(self): """ @@ -101,20 +102,23 @@ def custom_deserializer(dct): np.testing.assert_raises(ValueError, pmb.define_protein, **input_parameters) - espresso_system=espressomd.System(box_l = [Box_L.to('reduced_length').magnitude] * 3) + box_l=[Box_L.to('reduced_length').magnitude] * 3 + espresso_system=espressomd.System(box_l = box_l) + pmb.set_simulation_engine(espresso_system) + with self.assertRaises(ValueError): pmb.create_protein(name="missing_protein_template", number_of_proteins=1, - espresso_system=espresso_system, + box_l=box_l, topology_dict=topology_dict) molecule_id = pmb.create_protein(name=protein_pdb, number_of_proteins=1, - espresso_system=espresso_system, + box_l=box_l, topology_dict=topology_dict)[0] + pmb.add_instances_to_engine() particle_id_list = pmb.get_particle_id_map(object_name=protein_pdb)["all"] center_of_mass_es = pmb.calculate_center_of_mass(instance_id=molecule_id, - pmb_type="protein", - espresso_system=espresso_system) + pmb_type="protein") center_of_mass = np.zeros(3) axis_list = [0,1,2] for aminoacid in topology_dict.keys(): @@ -156,12 +160,13 @@ def custom_deserializer(dct): starting_number_of_particles=len(espresso_system.part.all()) pmb.create_protein(name=protein_pdb, number_of_proteins=0, - espresso_system=espresso_system, + box_l=box_l, topology_dict=topology_dict) pmb.create_protein(name=protein_pdb, number_of_proteins=-1, - espresso_system=espresso_system, + box_l=box_l, topology_dict=topology_dict) + pmb.add_instances_to_engine() np.testing.assert_equal(actual=len(espresso_system.part.all()), desired=starting_number_of_particles, verbose=True) @@ -174,8 +179,7 @@ def custom_deserializer(dct): momI = 0 center_of_mass = pmb.calculate_center_of_mass(instance_id=molecule_id, - pmb_type="protein", - espresso_system=espresso_system) + pmb_type="protein") for p in espresso_system.part: if p.mass > 1: rigid_object_id = p.id diff --git a/testsuite/hydrogel_builder.py b/testsuite/hydrogel_builder.py index eeb0fab5..d387391e 100644 --- a/testsuite/hydrogel_builder.py +++ b/testsuite/hydrogel_builder.py @@ -73,16 +73,16 @@ [NodeType, BeadType2]]) diamond_lattice = DiamondLattice(mpc, generic_bond_length) -box_l = diamond_lattice.box_l -espresso_system = espressomd.System(box_l = [box_l]*3) +box_l = [diamond_lattice.box_l]*3 +espresso_system = espressomd.System(box_l = box_l) lattice_builder = pmb.initialize_lattice_builder(diamond_lattice) pmb.create_molecule(name=molecule_name, number_of_molecules=1, - espresso_system=espresso_system, + box_l=box_l, use_default_bond=False, - list_of_first_residue_positions = [[np.random.uniform(0,box_l)]*3]) + list_of_first_residue_positions = [[np.random.uniform(0,diamond_lattice.box_l)]*3]) # Setting up node topology indices = diamond_lattice.indices @@ -106,12 +106,14 @@ pmb.define_hydrogel(hydrogel_name,node_topology, chain_topology) # Creating hydrogel -hydrogel_id= pmb.create_hydrogel(hydrogel_name, espresso_system) +hydrogel_id= pmb.create_hydrogel(hydrogel_name,box_l=box_l) hydrogel_tpl = pmb.db.get_template(pmb_type="hydrogel", name=hydrogel_name) hydrogel_inst = pmb.db.get_instance(pmb_type="hydrogel", instance_id=hydrogel_id) +pmb.set_simulation_engine(espresso_system) +pmb.add_instances_to_engine() class Test(ut.TestCase): def test_create_hydrogel_missing_template(self): @@ -119,7 +121,7 @@ def test_create_hydrogel_missing_template(self): Unit test that create_hydrogel raises if the template is missing. """ with self.assertRaises(ValueError): - pmb.create_hydrogel("missing_hydrogel_template", espresso_system) + pmb.create_hydrogel("missing_hydrogel_template",box_l=box_l) def test_hydrogel_template_storage(self): """ diff --git a/testsuite/lattice_builder.py b/testsuite/lattice_builder.py index b84fdeb0..a20bb85f 100644 --- a/testsuite/lattice_builder.py +++ b/testsuite/lattice_builder.py @@ -36,7 +36,8 @@ diamond = pyMBE.lib.lattice.DiamondLattice(mpc, bond_l) -espresso_system = espressomd.System(box_l=[diamond.box_l] * 3) +box_l=[diamond.box_l] * 3 +espresso_system = espressomd.System(box_l=box_l) # Define node particle @@ -120,13 +121,12 @@ def test_lattice_setup(self): define_templates(pmb=pmb) # --- Invalid low-level operations --- with self.assertRaises(ValueError): - pmb._create_hydrogel_node("[1 1 1]", NodeType1, espresso_system) + pmb._create_hydrogel_node("[1 1 1]", NodeType1,box_l=box_l) with self.assertRaises(ValueError): pmb._create_hydrogel_chain( "[0 0 0]", "[1 1 1]", - {0: [0, 0, 0], 1: diamond.box_l / 4.0 * np.ones(3)}, - espresso_system, + {0: [0, 0, 0], 1: diamond.box_l / 4.0 * np.ones(3)} ) # --- Lattice initialization --- @@ -155,7 +155,7 @@ def test_lattice_setup(self): np.testing.assert_equal(lattice.get_node("[3 1 3]"), "default_linker") # Clean espresso system - espresso_system.part.clear() + # espresso_system.part.clear() pmb2 = pyMBE.pymbe_library(23) define_templates(pmb=pmb2) @@ -240,7 +240,6 @@ def test_lattice_setup(self): molecule_name="test_chain") mol_id = pmb2._create_hydrogel_chain(hydrogel_chain=hydrogel_chain, nodes=nodes, - espresso_system=espresso_system, use_default_bond=True) # Extract created particle IDs chain_pids = pmb2.db._find_instance_ids_by_attribute(pmb_type="particle", diff --git a/testsuite/seed_test.py b/testsuite/seed_test.py index 9885b2fc..8548bf87 100644 --- a/testsuite/seed_test.py +++ b/testsuite/seed_test.py @@ -22,7 +22,8 @@ from pyMBE.lib import handy_functions as hf import unittest as ut -espresso_system = espressomd.System(box_l = [100]*3) +box_l=[100]*3 +espresso_system = espressomd.System(box_l = box_l) def build_peptide_in_espresso(seed): pmb = pyMBE.pymbe_library(seed=seed) @@ -57,15 +58,17 @@ def build_peptide_in_espresso(seed): # Create molecule in the espresso system pmb.create_molecule(name=peptide_name, number_of_molecules=1, - espresso_system=espresso_system, + box_l=box_l, use_default_bond=True) + + pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() # Extract positions of particles in the peptide particle_id_list = pmb.get_particle_id_map("generic_peptide")["all"] positions = [] for pid in particle_id_list: positions.append(espresso_system.part.by_id(pid).pos) - pmb.delete_instances_in_system(espresso_system=espresso_system, - instance_id=0, + pmb.delete_instances_in_system(instance_id=0, pmb_type="peptide") return np.asarray(positions) diff --git a/testsuite/setup_salt_ions_unit_tests.py b/testsuite/setup_salt_ions_unit_tests.py index 085fc77c..a0a3e88a 100644 --- a/testsuite/setup_salt_ions_unit_tests.py +++ b/testsuite/setup_salt_ions_unit_tests.py @@ -51,9 +51,9 @@ N_SALT_ION_PAIRS = 50 volume = N_SALT_ION_PAIRS/(pmb.N_A*c_salt_input) L = volume ** (1./3.) # Side of the simulation box - +box_l=[L.to('reduced_length').magnitude]*3 # Create an instance of an espresso system -espresso_system=espressomd.System (box_l = [L.to('reduced_length').magnitude]*3) +espresso_system=espressomd.System (box_l = box_l ) espresso_system.setup_type_map(type_list=type_map.values()) pmb.define_particle(name='0P', @@ -114,6 +114,7 @@ pmb.define_molecule(name='neutral_molecule', residue_list = ['R0']) +pmb.set_simulation_engine(espresso_system) class Test(ut.TestCase): @@ -125,11 +126,11 @@ def check_salt_concentration(espresso_system,cation_name,anion_name,c_salt,N_SAL charge_number_map=pmb.get_charge_number_map() type_map=pmb.get_type_map() espresso_system.setup_type_map(type_list=type_map.values()) - c_salt_calculated = pmb.create_added_salt(espresso_system=espresso_system, + c_salt_calculated = pmb.create_added_salt(box_l=box_l, cation_name=cation_name, anion_name=anion_name, c_salt=c_salt) - + pmb.add_instances_to_engine() self.assertEqual(get_number_of_particles(espresso_system, type_map[cation_name]),N_SALT_ION_PAIRS*abs(charge_number_map[type_map[anion_name]])) self.assertEqual(get_number_of_particles(espresso_system, type_map[anion_name]),N_SALT_ION_PAIRS*abs(charge_number_map[type_map[cation_name]])) self.assertAlmostEqual(c_salt_calculated.m_as("mol/L"), c_salt.m_as("mol/L")) @@ -137,7 +138,6 @@ def check_salt_concentration(espresso_system,cation_name,anion_name,c_salt,N_SAL anion_ids = pmb.get_particle_id_map(object_name=anion_name)["all"] for id in cation_ids+anion_ids: pmb.delete_instances_in_system(instance_id=id, - espresso_system=espresso_system, pmb_type="particle") # Unit test: test that create_added_salt works for a 1:1 salt (NaCl-like). @@ -171,10 +171,11 @@ def test_salt_addition_concentration_units(self): """ c_salt_part=c_salt_input*pmb.N_A espresso_system.setup_type_map(type_list=type_map.values()) - c_salt_calculated = pmb.create_added_salt(espresso_system=espresso_system, + c_salt_calculated = pmb.create_added_salt(box_l=box_l, cation_name="Na", anion_name="Cl", c_salt=c_salt_part) + pmb.add_instances_to_engine() self.assertEqual(get_number_of_particles(espresso_system, type_map["Na"]),N_SALT_ION_PAIRS) self.assertEqual(get_number_of_particles(espresso_system, type_map["Cl"]),N_SALT_ION_PAIRS) self.assertAlmostEqual(c_salt_calculated.m_as("reduced_length**-3"), c_salt_part.m_as("reduced_length**-3")) @@ -182,7 +183,6 @@ def test_salt_addition_concentration_units(self): anion_ids = pmb.get_particle_id_map(object_name="Cl")["all"] for id in cation_ids+anion_ids: pmb.delete_instances_in_system(instance_id=id, - espresso_system=espresso_system, pmb_type="particle") def test_sanity_create_salt(self): @@ -194,30 +194,30 @@ def test_sanity_create_salt(self): input_parameters={"cation_name":"Cl", "anion_name":"SO4", "c_salt":c_salt_input, - "espresso_system":espresso_system} + "box_l":box_l} self.assertRaises(ValueError, pmb.create_added_salt, **input_parameters) # check that create_added_salt raises a ValueError if one provides a anion_name of an object that has been defined with a non-negative charge input_parameters={"cation_name":"Na", "anion_name":"Ca", "c_salt":c_salt_input, - "espresso_system":espresso_system} + "box_l":box_l} self.assertRaises(ValueError, pmb.create_added_salt, **input_parameters) # check that create_added_salt raises a ValueError if one provides a c_salt with the wrong dimensionality input_parameters={"cation_name":"Na", "anion_name":"Cl", "c_salt":1*pmb.units.nm, - "espresso_system":espresso_system} + "box_l":box_l} self.assertRaises(ValueError, pmb.create_added_salt, **input_parameters) # Test that no salt ions are created if the wrong object names are provided input_parameters={"cation_name":"Na", "anion_name":"X", "c_salt":c_salt_input, - "espresso_system":espresso_system} + "box_l":box_l} self.assertRaises(ValueError, pmb.create_added_salt, **input_parameters) input_parameters={"cation_name":"X", "anion_name":"Cl", "c_salt":c_salt_input, - "espresso_system":espresso_system} + "box_l":box_l} self.assertRaises(ValueError, pmb.create_added_salt, **input_parameters) def test_counterions_setup(self): @@ -227,12 +227,13 @@ def test_counterions_setup(self): def test_counterions(molecule_name, cation_name, anion_name, espresso_system, expected_numbers): pmb.create_molecule(name=molecule_name, number_of_molecules= 2, - espresso_system=espresso_system, + box_l=box_l, use_default_bond=True) pmb.create_counterions(object_name=molecule_name, cation_name=cation_name, anion_name=anion_name, - espresso_system=espresso_system) + box_l=box_l) + pmb.add_instances_to_engine() espresso_system.setup_type_map(type_list=type_map.values()) self.assertEqual(get_number_of_particles(espresso_system, type_map[cation_name]), @@ -243,14 +244,12 @@ def test_counterions(molecule_name, cation_name, anion_name, espresso_system, ex molecule_ids = list(pmb.get_particle_id_map(object_name=molecule_name)["molecule_map"].keys()) for mol_id in molecule_ids: pmb.delete_instances_in_system(instance_id=mol_id, - espresso_system=espresso_system, pmb_type="molecule") cation_ids = pmb.get_particle_id_map(object_name=cation_name)["all"] anion_ids = pmb.get_particle_id_map(object_name=anion_name)["all"] for id in cation_ids+anion_ids: pmb.delete_instances_in_system(instance_id=id, - espresso_system=espresso_system, pmb_type="particle") # Check that create_counterions creates the right number of monovalent counter ions for a polyampholyte with positive net charge. @@ -288,30 +287,32 @@ def test_sanity_create_counterions(self): # Check that create_counterions raises a ValueError if the charge number of the cation is not divisible by the negative charge of the polyampholyte pmb.create_molecule(name='isoelectric_polyampholyte', number_of_molecules= 1, - espresso_system=espresso_system, + box_l=box_l, use_default_bond=True) + pmb.add_instances_to_engine() input_parameters={"cation_name":"Ca", "anion_name":"Cl", "object_name":'isoelectric_polyampholyte', - "espresso_system":espresso_system} + "box_l":box_l} self.assertRaises(ValueError, pmb.create_counterions, **input_parameters) # Check that create_counterions raises a ValueError if the charge number of the anion is not divisible by the positive charge of the polyampholyte input_parameters={"cation_name":"Na", "anion_name":"SO4", "object_name":'isoelectric_polyampholyte', - "espresso_system":espresso_system} + "box_l":box_l} self.assertRaises(ValueError, pmb.create_counterions, **input_parameters) pmb.delete_instances_in_system(instance_id=0, - espresso_system=espresso_system, pmb_type="molecule") # Check that no create_counterions does not create counterions for molecules with no charge pmb.create_molecule(name='neutral_molecule', number_of_molecules= 1, - espresso_system=espresso_system) + box_l=box_l) + pmb.create_counterions(object_name='neutral_molecule', cation_name="Na", anion_name="Cl", - espresso_system=espresso_system) + box_l=box_l) + pmb.add_instances_to_engine() espresso_system.setup_type_map(type_list=type_map.values()) self.assertEqual(get_number_of_particles(espresso_system, type_map["Na"]),0) @@ -320,35 +321,35 @@ def test_sanity_create_counterions(self): inputs = {"object_name":'test', "cation_name":"Na", "anion_name":"Cl", - "espresso_system":espresso_system} + "box_l":box_l} self.assertRaises(ValueError, pmb.create_counterions, **inputs) inputs = {"object_name":'isoelectric_polyampholyte', "cation_name":"Z", "anion_name":"Cl", - "espresso_system":espresso_system} + "box_l":box_l} self.assertRaises(ValueError, pmb.create_counterions, **inputs) inputs = {"object_name":'isoelectric_polyampholyte', "cation_name":"Na", "anion_name":"Y", - "espresso_system":espresso_system} + "box_l":box_l} self.assertRaises(ValueError, pmb.create_counterions, **inputs) input_parameters={"object_name":'isoelectric_polyampholyte', "cation_name":"isoelectric_polyampholyte", "anion_name":"Cl", - "espresso_system":espresso_system} + "box_l":box_l} self.assertRaises(ValueError, pmb.create_counterions, **input_parameters) input_parameters={"object_name":'isoelectric_polyampholyte', "cation_name":"Na", "anion_name":'isoelectric_polyampholyte', - "espresso_system":espresso_system} + "box_l":box_l} self.assertRaises(ValueError, pmb.create_counterions, **input_parameters) if __name__ == "__main__": diff --git a/testsuite/test_io_database.py b/testsuite/test_io_database.py index 7c03c522..cf4d4d21 100644 --- a/testsuite/test_io_database.py +++ b/testsuite/test_io_database.py @@ -31,8 +31,8 @@ from pathlib import Path import csv - -espresso_system=espressomd.System (box_l = [100]*3) +box_l=[100]*3 +espresso_system=espressomd.System (box_l = box_l) class DummyDB: def __init__(self): @@ -486,7 +486,11 @@ def test_io_instances(self): node_topology, chain_topology) assembly_id = pmb.create_hydrogel(name="my_hydrogel", - espresso_system=espresso_system) + box_l=box_l) + + pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() + new_pmb = pyMBE.pymbe_library(23) with tempfile.TemporaryDirectory() as tmp_directory: # Save and load the database @@ -504,14 +508,14 @@ def test_io_instances(self): pd.testing.assert_frame_equal(pmb.get_instances_df(pmb_type="particle"), new_pmb.get_instances_df(pmb_type="particle")) # Clean up before the next test - pmb.delete_instances_in_system(espresso_system=espresso_system, + pmb.delete_instances_in_system( instance_id=assembly_id, pmb_type="hydrogel") # Test instances of a peptide (tests peptide, residue, bond and particle instances) path_to_interactions=pmb.root / "parameters" / "peptides" / "Lunkad2021" path_to_pka=pmb.root / "parameters" / "pka_sets" / "Hass2015.json" - pmb.load_database (folder=path_to_interactions) # Defines particles - pmb.load_pka_set(filename=path_to_pka) + ### pmb.load_database(folder): Returns metadata, but not used ? + pmb.load_database (folder=path_to_interactions) # Defines particles load_pka_set(filename=path_to_pka) pka_set = pmb.get_pka_set() for particle_name in pka_set.keys(): pmb.define_monoprototic_particle_states(particle_name=particle_name, @@ -529,8 +533,12 @@ def test_io_instances(self): sequence="KKKKDDDD") pep_ids = pmb.create_molecule(name="Peptide1", number_of_molecules=2, - espresso_system=espresso_system, + box_l=box_l, ###set box_l use_default_bond=True) + + pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() + new_pmb = pyMBE.pymbe_library(23) with tempfile.TemporaryDirectory() as tmp_directory: # Save and load the database @@ -547,7 +555,7 @@ def test_io_instances(self): new_pmb.get_instances_df(pmb_type="particle")) # Clean up before the next test for pepid in pep_ids: - pmb.delete_instances_in_system(espresso_system=espresso_system, + pmb.delete_instances_in_system( instance_id=pepid, pmb_type="peptide") pmb.db.delete_templates(pmb_type="particle") @@ -570,8 +578,12 @@ def test_io_instances(self): sequence="KKKKKK") prot_ids = pmb.create_protein(name="1beb", number_of_proteins=1, - espresso_system=espresso_system, + box_l=box_l, topology_dict=topology_dict) + + pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() + new_pmb = pyMBE.pymbe_library(23) with tempfile.TemporaryDirectory() as tmp_directory: # Save and load the database @@ -588,7 +600,7 @@ def test_io_instances(self): new_pmb.get_instances_df(pmb_type="particle")) # Clean up for protid in prot_ids: - pmb.delete_instances_in_system(espresso_system=espresso_system, + pmb.delete_instances_in_system( instance_id=protid, pmb_type="protein") @@ -718,9 +730,10 @@ def test_default_bond_particle_names(self): Test io for default bonds """ pmb = pyMBE.pymbe_library(1) - pmb.define_default_bond(bond_type="FENE", bond_parameters={'r_0' : 0.5 * pmb.units.nm, - 'k' : 500 * pmb.units('reduced_energy / reduced_length**2'), - 'd_r_max': 0.5 * pmb.units.nm}) + pmb.define_default_bond(bond_type="FENE", + bond_parameters={'r_0' : 0.5 * pmb.units.nm, + 'k' : 500 * pmb.units('reduced_energy / reduced_length**2'), + 'd_r_max': 0.5 * pmb.units.nm}) with tempfile.TemporaryDirectory() as tmp: pmb.save_database(tmp) From e815cea3f89078f861ae6257d81157a246d22031 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 30 Apr 2026 17:09:36 +0200 Subject: [PATCH 22/75] Add changes to peptide_cpH to account for the decouple of espresso --- samples/peptide_cpH.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/samples/peptide_cpH.py b/samples/peptide_cpH.py index 5bd6ed40..9eefa75d 100644 --- a/samples/peptide_cpH.py +++ b/samples/peptide_cpH.py @@ -135,27 +135,31 @@ # Create an instance of an espresso system -espresso_system=espressomd.System (box_l = [L.to('reduced_length').magnitude]*3) +box_l=[L.to('reduced_length').magnitude]*3 +espresso_system=espressomd.System (box_l = box_l) espresso_system.time_step=dt espresso_system.cell_system.skin=0.4 # Create your molecules into the espresso system pmb.create_molecule(name=peptide_name, number_of_molecules=N_peptide_chains, - espresso_system=espresso_system, - use_default_bond=True) + use_default_bond=True, + box_l=box_l) # Create counterions for the peptide chains pmb.create_counterions(object_name=peptide_name, cation_name=cation_name, anion_name=anion_name, - espresso_system=espresso_system) + box_l=box_l) # check what is the actual salt concentration in the box # if the number of salt ions is a small integer, then the actual and desired salt concentration may significantly differ -c_salt_calculated = pmb.create_added_salt(espresso_system=espresso_system, +c_salt_calculated = pmb.create_added_salt( cation_name=cation_name, anion_name=anion_name, - c_salt=c_salt) + c_salt=c_salt, + box_l=box_l) +pmb.set_simulation_engine(espresso_system) +pmb.add_instances_to_engine() with open(frames_path / "trajectory0.vtf", mode='w+t') as coordinates: vtf.writevsf(espresso_system, coordinates) @@ -178,6 +182,7 @@ print(f"The peptide concentration in your system is {calculated_peptide_concentration.to('mol/L')} with {N_peptide_chains} peptides") print(f"The ionisable groups in your peptide are {list_ionisable_groups}") +print(pmb.get_reactions_df(),"before the acid-base reaction has been setup") cpH = pmb.setup_cpH(counter_ion=cation_name, constant_pH=pH_value) if verbose: @@ -241,7 +246,7 @@ # cpH sampling of the reaction space do_reaction(cpH, steps=total_ionisable_groups) # rule of thumb: one reaction step per titratable group (on average) # Get peptide net charge - charge_dict=pmb.calculate_net_charge(espresso_system=espresso_system, + charge_dict=pmb.calculate_net_charge( object_name=peptide_name, pmb_type="peptide", dimensionless=True) From edaabda40c136c615de1b9e6c03646d981b47380 Mon Sep 17 00:00:00 2001 From: Pablo Date: Thu, 30 Apr 2026 21:44:29 +0200 Subject: [PATCH 23/75] various small revisions together with Jordi --- pyMBE/pyMBE.py | 13 +-- pyMBE/simulation_builder/espresso_engine.py | 118 +++++++++++++------- 2 files changed, 86 insertions(+), 45 deletions(-) diff --git a/pyMBE/pyMBE.py b/pyMBE/pyMBE.py index 57e61a8a..2f843e5a 100644 --- a/pyMBE/pyMBE.py +++ b/pyMBE/pyMBE.py @@ -883,9 +883,9 @@ def create_counterions(self, object_name, cation_name, anion_name, box_l): object_name = self.db.get_instance(pmb_type="particle", instance_id=id).name object_tpl = self.db.get_template(pmb_type="particle", - name=object_name) + name=object_name) object_state = self.db.get_template(pmb_type="particle_state", - name=object_tpl.initial_state) + name=object_tpl.initial_state) object_z = object_state.z if object_z > 0: object_charge['positive']+=1*(np.abs(object_z )) @@ -1396,7 +1396,6 @@ def create_residue(self, name, box_l, central_bead_position=None,use_default_bon def change_volume_and_rescale_particles(self, d_new, dir="xyz"): - rescale_factor=np.array([1,1,1]) if d_new<=0: raise ValueError("The dimension cannot be negative, neither 0") @@ -1410,17 +1409,17 @@ def change_volume_and_rescale_particles(self, d_new, dir="xyz"): instances=self.get_instances_df(pmb_type='particle') for pid in range(instances.index.size): es_pos=self.db.get_instance(instance_id=pid, - pmb_type='particle').position + pmb_type='particle').position rescaled_position=es_pos*rescale_factor - print(rescaled_position,"rescaled_position") self.db._update_instance(instance_id=pid, pmb_type='particle', attribute='position', value=rescaled_position) self.simulation_engine.change_volume_and_rescale_particles(d_new=d_new, - dir=dir) - return + dir=dir) + + def define_bond(self, bond_type, bond_parameters, particle_pairs): """ Defines bond templates for each particle pair in 'particle_pairs' in the pyMBE database. diff --git a/pyMBE/simulation_builder/espresso_engine.py b/pyMBE/simulation_builder/espresso_engine.py index aabdb977..89979796 100644 --- a/pyMBE/simulation_builder/espresso_engine.py +++ b/pyMBE/simulation_builder/espresso_engine.py @@ -26,23 +26,19 @@ def _add_bond(self,particle_id1,particle_id2,bond_inst): def _add_particle(self,particle_id): particle_instance=self.db.get_instance(pmb_type='particle', instance_id=particle_id) - # part_tpl = self.db.get_template(pmb_type="particle", - # name=particle_instance.name) part_state = self.db.get_template(pmb_type="particle_state", name=particle_instance.initial_state) - - if particle_instance.fix: - kwargs = dict(id=particle_id, pos=particle_instance.position, type=part_state.es_type, q=part_state.z,fix=particle_instance.fix) - else: - kwargs = dict(id=particle_id, pos=particle_instance.position, type=part_state.es_type, q=part_state.z) - + kwargs = dict(id=particle_id, + pos=particle_instance.position, + type=part_state.es_type, + q=part_state.z, + fix=particle_instance.fix) self.espresso_system.part.add(**kwargs) self.db._update_instance(instance_id=particle_id, pmb_type='particle', attribute='added_to_engine', value=True) - def _check_particle_exists_in_espresso(self,particle_id): particle_exists=self.espresso_system.exists(particle_id) @@ -100,11 +96,11 @@ def _create_bond_instance(self, bond_type, bond_parameters): bond_type=bond_type) if bond_type == 'harmonic': bond_instance = espressomd.interactions.HarmonicBond(k = bond_parameters["k"].m_as("reduced_energy/reduced_length**2"), - r_0 = bond_parameters["r_0"].m_as("reduced_length")) + r_0 = bond_parameters["r_0"].m_as("reduced_length")) elif bond_type == 'FENE': bond_instance = espressomd.interactions.FeneBond(k = bond_parameters["k"].m_as("reduced_energy/reduced_length**2"), - r_0 = bond_parameters["r_0"].m_as("reduced_length"), - d_r_max = bond_parameters["d_r_max"].m_as("reduced_length")) + r_0 = bond_parameters["r_0"].m_as("reduced_length"), + d_r_max = bond_parameters["d_r_max"].m_as("reduced_length")) return bond_instance def _delete_particles(self, particle_ids): @@ -155,13 +151,14 @@ def _get_bond_instance(self, bond_template): else: # Create an instance of the bond bond_inst = self._create_bond_instance(bond_type=bond_template.bond_type, - bond_parameters=bond_template.get_parameters(self.units)) + bond_parameters=bond_template.get_parameters(self.units)) self.db.espresso_bond_instances[bond_template.name]= bond_inst self.espresso_system.bonded_inter.add(bond_inst) return bond_inst - - + def _get_particle_ids_in_espresso(self): + espresso_particles=self.espresso_system.part.all() + return espresso_particles.id def _get_last_particle_id_in_espresso(self): espresso_particles=self.espresso_system.part.all() @@ -188,6 +185,42 @@ def change_volume_and_rescale_particles(self, d_new, dir="xyz"): dir=dir) return + def update_particle_id(self, old_pid, new_pid): + """ + Method to be called if particles have been previously added to a simulation engine without using pyMBE. + + Args: + old_pid (int): old particle id to be replaced. + new_pid (int): new particle id to be assigned to instance in the pyMBE database. + """ + + if self.espresso_system == None: + raise ValueError('No simulation engine has been set to pymbe') + + self.db._update_instance(instance_id=old_pid, + pmb_type='particle', + attribute='particle_id', + value=new_pid) + + particle_id1_instances_ids=self.db._find_instance_ids_by_attribute(pmb_type='bond', + attribute='particle_id1', + value=old_pid) + for bond_id in particle_id1_instances_ids: + self.db._update_instance(instance_id=bond_id, + pmb_type='bond', + attribute='particle_id1', + value=new_pid) + particle_id2_instances_ids=self.db._find_instance_ids_by_attribute(pmb_type='bond', + attribute='particle_id2', + value=old_pid) + for bond_id in particle_id2_instances_ids: + self.db._update_instance(instance_id=bond_id, + pmb_type='bond', + attribute='particle_id2', + value=new_pid) + + + def update_instances_ids_according_to_engine_particles_ids(self): """ Method to be called if particles have been previously added to a simulation engine without using pymbe. @@ -245,40 +278,49 @@ def add_instance_to_engine(self,pmb_type,instance_id): def add_instances_to_engine(self): """ - This method adds the set of particles instances and bond instances that are not present in the pymbe data base + This method adds the set of particles instances and bond instances + that are not present in the pymbe data base """ - ### test the method - all_particles=self.db._get_instances_df(pmb_type='particle') + missing_particle_ids=self.db._find_instance_ids_by_attribute(pmb_type='particle', - attribute='added_to_engine', - value=False) + attribute='added_to_engine', + value=False) + if not missing_particle_ids: + raise RuntimeError('No particles instances in the pyMBE database set to be added to the simulation engine') - last_id=self._get_last_particle_id_in_espresso() - - if last_id!=None and len(missing_particle_ids)>0: - ### this condition takes into account the following edge case: - ### A set of particles have been added to espresso without using pyMBE. - ### And a second set of particles have been added to the pyMBE database and the user wants them to be added to espresso - if last_id>=missing_particle_ids[0]: - self.update_instances_ids_according_to_engine_particles_ids() + added_particle_ids=self.db._find_instance_ids_by_attribute(pmb_type='particle', + attribute='added_to_engine', + value=True) + ids_in_espresso = list(self._get_particle_ids_in_espresso()) + + overlapping_ids = set(ids_in_espresso).intersection(set(missing_particle_ids)) + for overlapping_id in overlapping_ids: + missing_particle_ids.remove(overlapping_id) + new_id = max(ids_in_espresso+added_particle_ids+missing_particle_ids)+1 + self.update_particle_id(old_pid=overlapping_id, + new_pid=new_id) + missing_particle_ids.append(new_id) - if all_particles.index.size>0: - for id in missing_particle_ids: - self._add_particle(id) - else: - raise RuntimeError('No particles, residues or molecules have been created so far') + if overlapping_ids: + warnings.warn("""Please review your setup, you have previously added a set of particles to ESPResSo. + The particle ids of the pyMBE database have been updated taking into account the id of + the last particle from ESPResSo. The following particle ids were updated: {}. """.format(overlapping_ids)) + + for id in missing_particle_ids: + self._add_particle(id) missing_bond_ids=self.db._find_instance_ids_by_attribute(pmb_type='bond', - attribute='added_to_engine', - value=False) + attribute='added_to_engine', + value=False) if len(missing_bond_ids)>0: for id in missing_bond_ids: bond_instance=self.db.get_instance(pmb_type='bond', - instance_id=id) + instance_id=id) particle_id1=bond_instance.particle_id1 particle_id2=bond_instance.particle_id2 - - self._add_bond(particle_id1,particle_id2,bond_instance) + self._add_bond(particle_id1, + particle_id2, + bond_instance) return From 16a8263f81599d55b1212a20de51b2c7c5a878e7 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Sat, 9 May 2026 21:04:40 +0200 Subject: [PATCH 24/75] Add changes to decouple: -reaction_montecarlomethods -determine_reservoir_concentrations Migrate methods the following methods to the manager: -propose_unused_types -get_lj_parameters -get_radius_map -_get_label_id_map --- pyMBE/pyMBE.py | 779 ++++++------------------------------------------- 1 file changed, 89 insertions(+), 690 deletions(-) diff --git a/pyMBE/pyMBE.py b/pyMBE/pyMBE.py index 2f843e5a..9881ee21 100644 --- a/pyMBE/pyMBE.py +++ b/pyMBE/pyMBE.py @@ -372,12 +372,7 @@ def _get_label_id_map(self, pmb_type): 'str': Label identifying the appropriate particle ID map. """ - if pmb_type in self.db._assembly_like_types: - label="assembly_map" - elif pmb_type in self.db._molecule_like_types: - label="molecule_map" - else: - label=f"{pmb_type}_map" + label=self.db._get_label_id_map(pmb_type=pmb_type) return label def _get_residue_list_from_sequence(self, sequence): @@ -476,20 +471,14 @@ def calculate_center_of_mass(self, instance_id, pmb_type): - 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) - print(inst," instance center of mass") - print(inst.name,"name instance") - particle_id_list = self.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) + if isinstance(self.simulation_engine,EspressoSimulation): + center_of_mass=self.simulation_engine.calculate_center_of_mass(instance_id=instance_id, + pmb_type=pmb_type) + elif isinstance(self.simulation_engine,LammpsSimulation): + raise NotImplementedError('In this version it has not yet been implemented this method for LammpsSimulation engine') + else: + raise RuntimeError('Please set a currently working simulation engine') return center_of_mass - def calculate_HH(self, template_name, pH_list=None, pka_set=None): """ Calculates the charge in the template object according to the ideal Henderson–Hasselbalch titration curve. @@ -677,35 +666,13 @@ def calculate_net_charge(self,object_name,pmb_type,dimensionless=False): dict: {"mean": mean_net_charge, "instances": {instance_id: net_charge}} """ - id_map = self.get_particle_id_map(object_name=object_name) - label = self._get_label_id_map(pmb_type=pmb_type) - instance_map = id_map[label] - charges = {} - for instance_id, particle_ids in instance_map.items(): - if dimensionless: - net_charge = 0.0 - else: - net_charge = 0 * self.units.Quantity(1, "reduced_charge") - for pid in particle_ids: - particle_instance=self.db.get_instance(pmb_type='particle', - instance_id=pid) - particle_name=particle_instance.name - particle_tpl = self.db.get_template(pmb_type="particle", - name=particle_name) - particle_state = self.db.get_template(pmb_type="particle_state", - name=particle_tpl.initial_state) - q = particle_state.z - if not dimensionless: - q *= self.units.Quantity(1, "reduced_charge") - net_charge += q - charges[instance_id] = net_charge - # Mean charge - if dimensionless: - mean_charge = float(np.mean(list(charges.values()))) + if isinstance(self.simulation_engine,EspressoSimulation): + net_charge=self.simulation_engine.calculate_net_charge(object_name,pmb_type,dimensionless) + elif isinstance(self.simulation_engine,LammpsSimulation): + raise NotImplementedError('In this version this method is only implemented with espresso') else: - mean_charge = (np.mean([q.magnitude for q in charges.values()])* self.units.Quantity(1, "reduced_charge")) - return {"mean": mean_charge, "instances": charges} - + raise RuntimeError('Please set a currently working simulation engine') + return net_charge def center_object_in_simulation_box(self, instance_id, box_l,pmb_type): """ Centers a pyMBE object instance in the simulation box of an ESPResSo system. @@ -1393,31 +1360,6 @@ def create_residue(self, name, box_l, central_bead_position=None,use_default_bon particle_id2=side_chain_beads_ids[0], use_default_bond=use_default_bond) return residue_id - - def change_volume_and_rescale_particles(self, d_new, dir="xyz"): - - rescale_factor=np.array([1,1,1]) - if d_new<=0: - raise ValueError("The dimension cannot be negative, neither 0") - if "x" in dir: - rescale_factor[0]=d_new/self.simulation_engine.box_l[0] - if "y" in dir: - rescale_factor[1]=d_new/self.simulation_engine.box_l[1] - if "z" in dir: - rescale_factor[2]=d_new/self.simulation_engine.box_l[2] - - instances=self.get_instances_df(pmb_type='particle') - for pid in range(instances.index.size): - es_pos=self.db.get_instance(instance_id=pid, - pmb_type='particle').position - rescaled_position=es_pos*rescale_factor - self.db._update_instance(instance_id=pid, - pmb_type='particle', - attribute='position', - value=rescaled_position) - - self.simulation_engine.change_volume_and_rescale_particles(d_new=d_new, - dir=dir) def define_bond(self, bond_type, bond_parameters, particle_pairs): @@ -1852,63 +1794,10 @@ def determine_reservoir_concentrations(self, pH_res, c_salt_res, activity_coeffi 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))) + cH_res, cOH_res, cNa_res, cCl_res = self.simulation_engine.determine_reservoir_concentrations( pH_res, c_salt_res, activity_coefficient_monovalent_pair, max_number_sc_runs) return cH_res, cOH_res, cNa_res, cCl_res - def enable_motion_of_rigid_object(self, instance_id, pmb_type, espresso_system): + def enable_motion_of_rigid_object(self, instance_id, pmb_type): """ Enables translational and rotational motion of a rigid pyMBE object instance in an ESPResSo system.This method creates a rigid-body center particle at the center of mass of @@ -1938,24 +1827,12 @@ def enable_motion_of_rigid_object(self, instance_id, pmb_type, espresso_system): - The rotational inertia tensor is approximated from the squared distances of the particles to the center of mass. """ - logging.info('enable_motion_of_rigid_object requires that espressomd has the following features activated: ["VIRTUAL_SITES_RELATIVE", "MASS"]') - inst = self.db.get_instance(pmb_type=pmb_type, - instance_id=instance_id) - label = self._get_label_id_map(pmb_type=pmb_type) - particle_ids_list = self.get_particle_id_map(object_name=inst.name)[label][instance_id] - center_of_mass = self.calculate_center_of_mass (instance_id=instance_id, - pmb_type=pmb_type) - rigid_object_center = espresso_system.part.add(pos=center_of_mass, - rotation=[True,True,True], - type=self.propose_unused_type()) - rigid_object_center.mass = len(particle_ids_list) - momI = 0 - for pid in particle_ids_list: - momI += np.power(np.linalg.norm(center_of_mass - espresso_system.part.by_id(pid).pos), 2) - rigid_object_center.rinertia = np.ones(3) * momI - for particle_id in particle_ids_list: - pid = espresso_system.part.by_id(particle_id) - pid.vs_auto_relate_to(rigid_object_center.id) + if isinstance(self.simulation_engine,EspressoSimulation): + self.simulation_engine.enable_motion_of_rigid_object(instance_id, pmb_type) + elif isinstance(self.simulation_engine,LammpsSimulation): + raise NotImplementedError('In this current version LammpsSimulation is not yet implemented') + else: + raise RuntimeError('Please setup a currently working simulation engine') def generate_coordinates_outside_sphere(self, center, radius, max_dist, n_samples): """ @@ -2173,26 +2050,8 @@ def get_lj_parameters(self, particle_name1, particle_name2, combining_rule='Lore - Currently, the only 'combining_rule' supported is Lorentz-Berthelot. - If the sigma value of 'particle_name1' or 'particle_name2' is 0, the function will return an empty dictionary. No LJ interactions are set up for particles with sigma = 0. """ - supported_combining_rules=["Lorentz-Berthelot"] - if combining_rule not in supported_combining_rules: - raise ValueError(f"Combining_rule {combining_rule} currently not implemented in pyMBE, valid keys are {supported_combining_rules}") - part_tpl1 = self.db.get_template(name=particle_name1, - pmb_type="particle") - part_tpl2 = self.db.get_template(name=particle_name2, - pmb_type="particle") - lj_parameters1 = part_tpl1.get_lj_parameters(ureg=self.units) - lj_parameters2 = part_tpl2.get_lj_parameters(ureg=self.units) - - # If one of the particle has sigma=0, no LJ interations are set up between that particle type and the others - if part_tpl1.sigma.magnitude == 0 or part_tpl2.sigma.magnitude == 0: - return {} - # Apply combining rule - if combining_rule == 'Lorentz-Berthelot': - sigma=(lj_parameters1["sigma"]+lj_parameters2["sigma"])/2 - cutoff=(lj_parameters1["cutoff"]+lj_parameters2["cutoff"])/2 - offset=(lj_parameters1["offset"]+lj_parameters2["offset"])/2 - epsilon=np.sqrt(lj_parameters1["epsilon"]*lj_parameters2["epsilon"]) - return {"sigma": sigma, "cutoff": cutoff, "offset": offset, "epsilon": epsilon} + lj_parameters=self.db.get_lj_parameters(particle_name1=particle_name1,particle_name2=particle_name2,combining_rule=combining_rule) + return lj_parameters def get_particle_id_map(self, object_name): """ @@ -2263,17 +2122,7 @@ def get_radius_map(self, dimensionless=True): Notes: - The radius corresponds to (sigma+offset)/2 """ - if "particle" not in self.db._templates: - return {} - result = {} - for _, tpl in self.db._templates["particle"].items(): - radius = (tpl.sigma.to_quantity(self.units) + tpl.offset.to_quantity(self.units))/2.0 - if dimensionless: - magnitude_reduced_length = radius.m_as("reduced_length") - radius = magnitude_reduced_length - for state in self.db.get_particle_states_templates(particle_name=tpl.name).values(): - result[state.es_type] = radius - return result + return self.db.get_radius_map(dimensionless) def get_reactions_df(self): """ @@ -2415,15 +2264,8 @@ def propose_unused_type(self): ('int'): The next available integer ESPResSo type. Returns ''0'' if no integer types are currently defined. """ - type_map = self.get_type_map() - # Flatten all es_type values across all particles and states - all_types = [] - for es_type in type_map.values(): - all_types.append(es_type) - # If no es_types exist, start at 0 - if not all_types: - return 0 - return max(all_types) + 1 + + return self.db.propose_unused_type() def read_protein_vtf(self, filename, unit_length=None): """ @@ -2604,12 +2446,18 @@ def set_simulation_engine(self,simulation_engine,box_l=None): self.simulation_engine=EspressoSimulation(box_l=simulation_engine.box_l, db=self.db, espresso_system=simulation_engine, - units=self.units) + units=self.units, + kT=self.kT, + Kw=self.Kw, + seed=self.seed) elif isinstance(simulation_engine,LammpsProtocol): self.simulation_engine=LammpsSimulation(box_l=box_l, db=self.db, lammps=simulation_engine, - units=self.units) + units=self.units, + kT=self.kT, + Kw=self.Kw, + seed=self.seed) else: raise ValueError('The specified simulation engine is not implemented yet') @@ -2635,50 +2483,18 @@ def setup_cpH (self, counter_ion, constant_pH, exclusion_range=None, use_exclusi ('reaction_methods.ConstantpHEnsemble'): Instance of a reaction_methods.ConstantpHEnsemble object from the espressomd library. """ - from espressomd import reaction_methods - if exclusion_range is None: - exclusion_range = max(self.get_radius_map().values())*2.0 - if use_exclusion_radius_per_type: - exclusion_radius_per_type = self.get_radius_map() + + if isinstance(self.simulation_engine,EspressoSimulation): + RE = self.simulation_engine.setup_cpH(counter_ion=counter_ion, + constant_pH=constant_pH, + exclusion_range=exclusion_range, + use_exclusion_radius_per_type = use_exclusion_radius_per_type) + return RE + elif isinstance(self.simulation_engine,LammpsSimulation): + raise NotImplementedError('In this version espresso has only been decoupled. Interoperability with other engines is not yet provided') else: - exclusion_radius_per_type = {} - RE = reaction_methods.ConstantpHEnsemble(kT=self.kT.to('reduced_energy').magnitude, - exclusion_range=exclusion_range, - seed=self.seed, - constant_pH=constant_pH, - exclusion_radius_per_type = exclusion_radius_per_type) - conterion_tpl = self.db.get_template(name=counter_ion, - pmb_type="particle") - conterion_state = self.db.get_template(name=conterion_tpl.initial_state, - pmb_type="particle_state") - for reaction in self.db.get_reactions(): - if reaction.reaction_type not in ["monoprotic_acid", "monoprotic_base"]: - continue - default_charges = {} - reactant_types = [] - product_types = [] - for participant in reaction.participants: - state_tpl = self.db.get_template(name=participant.state_name, - pmb_type="particle_state") - default_charges[state_tpl.es_type] = state_tpl.z - if participant.coefficient < 0: - reactant_types.append(state_tpl.es_type) - elif participant.coefficient > 0: - product_types.append(state_tpl.es_type) - # Add counterion to the products - if conterion_state.es_type not in product_types: - product_types.append(conterion_state.es_type) - default_charges[conterion_state.es_type] = conterion_state.z - reaction.add_participant(particle_name=counter_ion, - state_name=conterion_tpl.initial_state, - coefficient=1) - gamma=10**-reaction.pK - RE.add_reaction(gamma=gamma, - reactant_types=reactant_types, - product_types=product_types, - default_charges=default_charges) - reaction.add_simulation_method(simulation_method="cpH") - return RE + raise RuntimeError('You need to set your simulation Engine') + def setup_gcmc(self, c_salt_res, salt_cation_name, salt_anion_name, activity_coefficient, exclusion_range=None, use_exclusion_radius_per_type = False): """ @@ -2708,55 +2524,19 @@ def setup_gcmc(self, c_salt_res, salt_cation_name, salt_anion_name, activity_coe ('reaction_methods.ReactionEnsemble'): Instance of a reaction_methods.ReactionEnsemble object from the espressomd library. """ - from espressomd import reaction_methods - if exclusion_range is None: - exclusion_range = max(self.get_radius_map().values())*2.0 - if use_exclusion_radius_per_type: - exclusion_radius_per_type = self.get_radius_map() + if isinstance(self.simulation_engine,EspressoSimulation): + RE = self.simulation_engine.setup_gcmc(c_salt_res=c_salt_res, + salt_anion_name=salt_anion_name, + salt_cation_name=salt_cation_name, + activity_coefficient=activity_coefficient, + exclusion_range=exclusion_range, + use_exclusion_radius_per_type = use_exclusion_radius_per_type) + return RE + elif isinstance(self.simulation_engine,LammpsSimulation): + raise NotImplementedError('In this version espresso has only been decoupled. Interoperability with other engines is not yet provided') else: - exclusion_radius_per_type = {} - RE = reaction_methods.ReactionEnsemble(kT=self.kT.to('reduced_energy').magnitude, - exclusion_range=exclusion_range, - seed=self.seed, - exclusion_radius_per_type = exclusion_radius_per_type) - # Determine the concentrations of the various species in the reservoir and the equilibrium constants - determined_activity_coefficient = activity_coefficient(c_salt_res) - K_salt = (c_salt_res.to('1/(N_A * reduced_length**3)')**2) * determined_activity_coefficient - cation_tpl = self.db.get_template(pmb_type="particle", - name=salt_cation_name) - cation_state = self.db.get_template(pmb_type="particle_state", - name=cation_tpl.initial_state) - anion_tpl = self.db.get_template(pmb_type="particle", - name=salt_anion_name) - anion_state = self.db.get_template(pmb_type="particle_state", - name=anion_tpl.initial_state) - salt_cation_es_type = cation_state.es_type - salt_anion_es_type = anion_state.es_type - salt_cation_charge = cation_state.z - salt_anion_charge = anion_state.z - if salt_cation_charge <= 0: - raise ValueError('ERROR salt cation charge must be positive, charge ', salt_cation_charge) - if salt_anion_charge >= 0: - raise ValueError('ERROR salt anion charge must be negative, charge ', salt_anion_charge) - # Grand-canonical coupling to the reservoir - RE.add_reaction(gamma = K_salt.magnitude, - reactant_types = [], - reactant_coefficients = [], - product_types = [ salt_cation_es_type, salt_anion_es_type ], - product_coefficients = [ 1, 1 ], - default_charges = {salt_cation_es_type: salt_cation_charge, - salt_anion_es_type: salt_anion_charge}) - rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=salt_cation_name, - state_name=cation_state.name, - coefficient=1), - ReactionParticipant(particle_name=salt_anion_name, - state_name=anion_state.name, - coefficient=1)], - pK=-np.log10(K_salt.magnitude), - reaction_type="ion_insertion", - simulation_method="GCMC") - self.db._register_reaction(rx_tpl) - return RE + raise RuntimeError('You need to set your simulation Engine') + def setup_grxmc_reactions(self, pH_res, c_salt_res, proton_name, hydroxide_name, salt_cation_name, salt_anion_name, activity_coefficient, exclusion_range=None, use_exclusion_radius_per_type = False): """ @@ -2805,259 +2585,21 @@ def setup_grxmc_reactions(self, pH_res, c_salt_res, proton_name, hydroxide_name, [1] Landsgesell, J., Hebbeker, P., Rud, O., Lunkad, R., Košovan, P., & Holm, C. (2020). Grand-reaction method for simulations of ionization equilibria coupled to ion partitioning. Macromolecules, 53(8), 3007-3020. """ - from espressomd import reaction_methods - if exclusion_range is None: - exclusion_range = max(self.get_radius_map().values())*2.0 - if use_exclusion_radius_per_type: - exclusion_radius_per_type = self.get_radius_map() + if isinstance(self.simulation_engine,EspressoSimulation): + RE, ionic_strength_res=self.simulation_engine.setup_grxmc_reactions(pH_res=pH_res, + c_salt_res=c_salt_res, + proton_name=proton_name, + hydroxide_name=hydroxide_name, + salt_cation_name=salt_cation_name, + salt_anion_name=salt_anion_name, + activity_coefficient=activity_coefficient, + exclusion_range=exclusion_range, + use_exclusion_radius_per_type=use_exclusion_radius_per_type) + return RE, ionic_strength_res + elif isinstance(self.simulation_engine,LammpsSimulation): + raise NotImplementedError('In this version espresso has only been decoupled. Interoperability with other engines is not yet provided') else: - exclusion_radius_per_type = {} - RE = reaction_methods.ReactionEnsemble(kT=self.kT.to('reduced_energy').magnitude, - exclusion_range=exclusion_range, - seed=self.seed, - exclusion_radius_per_type = exclusion_radius_per_type) - # Determine the concentrations of the various species in the reservoir and the equilibrium constants - cH_res, cOH_res, cNa_res, cCl_res = self.determine_reservoir_concentrations(pH_res, c_salt_res, activity_coefficient) - ionic_strength_res = 0.5*(cNa_res+cCl_res+cOH_res+cH_res) - determined_activity_coefficient = activity_coefficient(ionic_strength_res) - K_W = cH_res.to('1/(N_A * reduced_length**3)') * cOH_res.to('1/(N_A * reduced_length**3)') * determined_activity_coefficient - K_NACL = cNa_res.to('1/(N_A * reduced_length**3)') * cCl_res.to('1/(N_A * reduced_length**3)') * determined_activity_coefficient - K_HCL = cH_res.to('1/(N_A * reduced_length**3)') * cCl_res.to('1/(N_A * reduced_length**3)') * determined_activity_coefficient - cation_tpl = self.db.get_template(pmb_type="particle", - name=salt_cation_name) - cation_state = self.db.get_template(pmb_type="particle_state", - name=cation_tpl.initial_state) - anion_tpl = self.db.get_template(pmb_type="particle", - name=salt_anion_name) - anion_state = self.db.get_template(pmb_type="particle_state", - name=anion_tpl.initial_state) - proton_tpl = self.db.get_template(pmb_type="particle", - name=proton_name) - proton_state = self.db.get_template(pmb_type="particle_state", - name=proton_tpl.initial_state) - hydroxide_tpl = self.db.get_template(pmb_type="particle", - name=hydroxide_name) - hydroxide_state = self.db.get_template(pmb_type="particle_state", - name=hydroxide_tpl.initial_state) - proton_es_type = proton_state.es_type - hydroxide_es_type = hydroxide_state.es_type - salt_cation_es_type = cation_state.es_type - salt_anion_es_type = anion_state.es_type - proton_charge = proton_state.z - hydroxide_charge = hydroxide_state.z - salt_cation_charge = cation_state.z - salt_anion_charge = anion_state.z - if proton_charge <= 0: - raise ValueError('ERROR proton charge must be positive, charge ', proton_charge) - if salt_cation_charge <= 0: - raise ValueError('ERROR salt cation charge must be positive, charge ', salt_cation_charge) - if hydroxide_charge >= 0: - raise ValueError('ERROR hydroxide charge must be negative, charge ', hydroxide_charge) - if salt_anion_charge >= 0: - raise ValueError('ERROR salt anion charge must be negative, charge ', salt_anion_charge) - # Grand-canonical coupling to the reservoir - # 0 = H+ + OH- - RE.add_reaction(gamma = K_W.magnitude, - reactant_types = [], - reactant_coefficients = [], - product_types = [ proton_es_type, hydroxide_es_type ], - product_coefficients = [ 1, 1 ], - default_charges = {proton_es_type: proton_charge, - hydroxide_es_type: hydroxide_charge}) - rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=proton_name, - state_name=proton_state.name, - coefficient=1), - ReactionParticipant(particle_name=hydroxide_name, - state_name=hydroxide_state.name, - coefficient=1)], - pK=-np.log10(K_W.magnitude), - reaction_type="ion_insertion", - simulation_method="GRxMC") - self.db._register_reaction(rx_tpl) - # 0 = Na+ + Cl- - RE.add_reaction(gamma = K_NACL.magnitude, - reactant_types = [], - reactant_coefficients = [], - product_types = [ salt_cation_es_type, salt_anion_es_type ], - product_coefficients = [ 1, 1 ], - default_charges = {salt_cation_es_type: salt_cation_charge, - salt_anion_es_type: salt_anion_charge}) - rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=salt_cation_name, - state_name=cation_state.name, - coefficient=1), - ReactionParticipant(particle_name=salt_anion_name, - state_name=anion_state.name, - coefficient=1)], - pK=-np.log10(K_NACL.magnitude), - reaction_type="ion_insertion", - simulation_method="GRxMC") - self.db._register_reaction(rx_tpl) - # 0 = Na+ + OH- - RE.add_reaction(gamma = (K_NACL * K_W / K_HCL).magnitude, - reactant_types = [], - reactant_coefficients = [], - product_types = [ salt_cation_es_type, hydroxide_es_type ], - product_coefficients = [ 1, 1 ], - default_charges = {salt_cation_es_type: salt_cation_charge, - hydroxide_es_type: hydroxide_charge}) - rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=salt_cation_name, - state_name=cation_state.name, - coefficient=1), - ReactionParticipant(particle_name=hydroxide_name, - state_name=hydroxide_state.name, - coefficient=1)], - pK=-np.log10((K_NACL * K_W / K_HCL).magnitude), - reaction_type="ion_insertion", - simulation_method="GRxMC") - self.db._register_reaction(rx_tpl) - # 0 = H+ + Cl- - RE.add_reaction(gamma = K_HCL.magnitude, - reactant_types = [], - reactant_coefficients = [], - product_types = [ proton_es_type, salt_anion_es_type ], - product_coefficients = [ 1, 1 ], - default_charges = {proton_es_type: proton_charge, - salt_anion_es_type: salt_anion_charge}) - rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=proton_name, - state_name=proton_state.name, - coefficient=1), - ReactionParticipant(particle_name=salt_anion_name, - state_name=anion_state.name, - coefficient=1)], - pK=-np.log10(K_HCL.magnitude), - reaction_type="ion_insertion", - simulation_method="GRxMC") - self.db._register_reaction(rx_tpl) - # Annealing moves to ensure sufficient sampling - # Cation annealing H+ = Na+ - RE.add_reaction(gamma = (K_NACL / K_HCL).magnitude, - reactant_types = [proton_es_type], - reactant_coefficients = [ 1 ], - product_types = [ salt_cation_es_type ], - product_coefficients = [ 1 ], - default_charges = {proton_es_type: proton_charge, - salt_cation_es_type: salt_cation_charge}) - rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=proton_name, - state_name=proton_state.name, - coefficient=-1), - ReactionParticipant(particle_name=salt_cation_name, - state_name=cation_state.name, - coefficient=1)], - pK=-np.log10((K_NACL / K_HCL).magnitude), - reaction_type="particle replacement", - simulation_method="GRxMC") - self.db._register_reaction(rx_tpl) - # Anion annealing OH- = Cl- - RE.add_reaction(gamma = (K_HCL / K_W).magnitude, - reactant_types = [hydroxide_es_type], - reactant_coefficients = [ 1 ], - product_types = [ salt_anion_es_type ], - product_coefficients = [ 1 ], - default_charges = {hydroxide_es_type: hydroxide_charge, - salt_anion_es_type: salt_anion_charge}) - rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=hydroxide_name, - state_name=hydroxide_state.name, - coefficient=-1), - ReactionParticipant(particle_name=salt_anion_name, - state_name=anion_state.name, - coefficient=1)], - pK=-np.log10((K_HCL / K_W).magnitude), - reaction_type="particle replacement", - simulation_method="GRxMC") - self.db._register_reaction(rx_tpl) - for reaction in self.db.get_reactions(): - if reaction.reaction_type not in ["monoprotic_acid", "monoprotic_base"]: - continue - default_charges = {} - reactant_types = [] - product_types = [] - for participant in reaction.participants: - state_tpl = self.db.get_template(name=participant.state_name, - pmb_type="particle_state") - default_charges[state_tpl.es_type] = state_tpl.z - if participant.coefficient < 0: - reactant_types.append(state_tpl.es_type) - reactant_name=state_tpl.particle_name - reactant_state_name=state_tpl.name - elif participant.coefficient > 0: - product_types.append(state_tpl.es_type) - product_name=state_tpl.particle_name - product_state_name=state_tpl.name - - Ka = (10**-reaction.pK * self.units.mol/self.units.l).to('1/(N_A * reduced_length**3)') - # Reaction in terms of proton: HA = A + H+ - RE.add_reaction(gamma=Ka.magnitude, - reactant_types=reactant_types, - reactant_coefficients=[1], - product_types=product_types+[proton_es_type], - product_coefficients=[1, 1], - default_charges= default_charges | {proton_es_type: proton_charge}) - reaction.add_participant(particle_name=proton_name, - state_name=proton_state.name, - coefficient=1) - reaction.add_simulation_method("GRxMC") - # Reaction in terms of salt cation: HA = A + Na+ - RE.add_reaction(gamma=(Ka * K_NACL / K_HCL).magnitude, - reactant_types=reactant_types, - reactant_coefficients=[1], - product_types=product_types+[salt_cation_es_type], - product_coefficients=[1, 1], - default_charges=default_charges | {salt_cation_es_type: salt_cation_charge}) - rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=reactant_name, - state_name=reactant_state_name, - coefficient=-1), - ReactionParticipant(particle_name=product_name, - state_name=product_state_name, - coefficient=1), - ReactionParticipant(particle_name=salt_cation_name, - state_name=cation_state.name, - coefficient=1),], - pK=-np.log10((Ka * K_NACL / K_HCL).magnitude), - reaction_type=reaction.reaction_type+"_salt", - simulation_method="GRxMC") - self.db._register_reaction(rx_tpl) - # Reaction in terms of hydroxide: OH- + HA = A - RE.add_reaction(gamma=(Ka / K_W).magnitude, - reactant_types=reactant_types+[hydroxide_es_type], - reactant_coefficients=[1, 1], - product_types=product_types, - product_coefficients=[1], - default_charges=default_charges | {hydroxide_es_type: hydroxide_charge}) - rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=reactant_name, - state_name=reactant_state_name, - coefficient=-1), - ReactionParticipant(particle_name=product_name, - state_name=product_state_name, - coefficient=1), - ReactionParticipant(particle_name=hydroxide_name, - state_name=hydroxide_state.name, - coefficient=-1),], - pK=-np.log10((Ka / K_W).magnitude), - reaction_type=reaction.reaction_type+"_conjugate", - simulation_method="GRxMC") - self.db._register_reaction(rx_tpl) - # Reaction in terms of salt anion: Cl- + HA = A - RE.add_reaction(gamma=(Ka / K_HCL).magnitude, - reactant_types=reactant_types+[salt_anion_es_type], - reactant_coefficients=[1, 1], - product_types=product_types, - product_coefficients=[1], - default_charges=default_charges | {salt_anion_es_type: salt_anion_charge}) - rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=reactant_name, - state_name=reactant_state_name, - coefficient=-1), - ReactionParticipant(particle_name=product_name, - state_name=product_state_name, - coefficient=1), - ReactionParticipant(particle_name=salt_anion_name, - state_name=anion_state.name, - coefficient=-1),], - pK=-np.log10((Ka / K_HCL).magnitude), - reaction_type=reaction.reaction_type+"_salt", - simulation_method="GRxMC") - self.db._register_reaction(rx_tpl) - return RE, ionic_strength_res - + raise RuntimeError('You need to set your simulation Engine') def setup_grxmc_unified(self, pH_res, c_salt_res, cation_name, anion_name, activity_coefficient, exclusion_range=None, use_exclusion_radius_per_type = False): """ Sets up acid/base reactions for acidic/basic 'particles' defined in the pyMBE database, as well as a grand-canonical coupling to a @@ -3101,114 +2643,22 @@ def setup_grxmc_unified(self, pH_res, c_salt_res, cation_name, anion_name, activ [1] Curk, T., Yuan, J., & Luijten, E. (2022). Accelerated simulation method for charge regulation effects. The Journal of Chemical Physics, 156(4). [2] Landsgesell, J., Hebbeker, P., Rud, O., Lunkad, R., Košovan, P., & Holm, C. (2020). Grand-reaction method for simulations of ionization equilibria coupled to ion partitioning. Macromolecules, 53(8), 3007-3020. """ - from espressomd import reaction_methods - if exclusion_range is None: - exclusion_range = max(self.get_radius_map().values())*2.0 - if use_exclusion_radius_per_type: - exclusion_radius_per_type = self.get_radius_map() + if isinstance(self.simulation_engine,EspressoSimulation): + RE, ionic_strength_res=self.simulation_engine.setup_grxmc_unified(pH_res=pH_res, + c_salt_res=c_salt_res, + cation_name=cation_name, + anion_name=anion_name, + activity_coefficient=activity_coefficient, + exclusion_range=exclusion_range, + use_exclusion_radius_per_type = use_exclusion_radius_per_type) + return RE, ionic_strength_res + elif isinstance(self.simulation_engine,LammpsSimulation): + raise NotImplementedError('In this version espresso has only been decoupled. Interoperability with other engines is not yet provided') else: - exclusion_radius_per_type = {} - RE = reaction_methods.ReactionEnsemble(kT=self.kT.to('reduced_energy').magnitude, - exclusion_range=exclusion_range, - seed=self.seed, - exclusion_radius_per_type = exclusion_radius_per_type) - # Determine the concentrations of the various species in the reservoir and the equilibrium constants - cH_res, cOH_res, cNa_res, cCl_res = self.determine_reservoir_concentrations(pH_res, c_salt_res, activity_coefficient) - ionic_strength_res = 0.5*(cNa_res+cCl_res+cOH_res+cH_res) - determined_activity_coefficient = activity_coefficient(ionic_strength_res) - a_hydrogen = (10 ** (-pH_res) * self.units.mol/self.units.l).to('1/(N_A * reduced_length**3)') - a_cation = (cH_res+cNa_res).to('1/(N_A * reduced_length**3)') * np.sqrt(determined_activity_coefficient) - a_anion = (cH_res+cNa_res).to('1/(N_A * reduced_length**3)') * np.sqrt(determined_activity_coefficient) - K_XX = a_cation * a_anion - cation_tpl = self.db.get_template(pmb_type="particle", - name=cation_name) - cation_state = self.db.get_template(pmb_type="particle_state", - name=cation_tpl.initial_state) - anion_tpl = self.db.get_template(pmb_type="particle", - name=anion_name) - anion_state = self.db.get_template(pmb_type="particle_state", - name=anion_tpl.initial_state) - cation_es_type = cation_state.es_type - anion_es_type = anion_state.es_type - cation_charge = cation_state.z - anion_charge = anion_state.z - if cation_charge <= 0: - raise ValueError('ERROR cation charge must be positive, charge ', cation_charge) - if anion_charge >= 0: - raise ValueError('ERROR anion charge must be negative, charge ', anion_charge) - # Coupling to the reservoir: 0 = X+ + X- - RE.add_reaction(gamma = K_XX.magnitude, - reactant_types = [], - reactant_coefficients = [], - product_types = [ cation_es_type, anion_es_type ], - product_coefficients = [ 1, 1 ], - default_charges = {cation_es_type: cation_charge, - anion_es_type: anion_charge}) - rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=cation_name, - state_name=cation_state.name, - coefficient=1), - ReactionParticipant(particle_name=anion_name, - state_name=anion_state.name, - coefficient=1)], - pK=-np.log10(K_XX.magnitude), - reaction_type="ion_insertion", - simulation_method="GCMC") - self.db._register_reaction(rx_tpl) - for reaction in self.db.get_reactions(): - if reaction.reaction_type not in ["monoprotic_acid", "monoprotic_base"]: - continue - default_charges = {} - reactant_types = [] - product_types = [] - for participant in reaction.participants: - state_tpl = self.db.get_template(name=participant.state_name, - pmb_type="particle_state") - default_charges[state_tpl.es_type] = state_tpl.z - if participant.coefficient < 0: - reactant_types.append(state_tpl.es_type) - reactant_name=state_tpl.particle_name - reactant_state_name=state_tpl.name - elif participant.coefficient > 0: - product_types.append(state_tpl.es_type) - product_name=state_tpl.particle_name - product_state_name=state_tpl.name - - Ka = (10**-reaction.pK * self.units.mol/self.units.l).to('1/(N_A * reduced_length**3)') - gamma_K_AX = Ka.to('1/(N_A * reduced_length**3)').magnitude * a_cation / a_hydrogen - # Reaction in terms of small cation: HA = A + X+ - RE.add_reaction(gamma=gamma_K_AX.magnitude, - reactant_types=reactant_types, - reactant_coefficients=[1], - product_types=product_types+[cation_es_type], - product_coefficients=[1, 1], - default_charges=default_charges|{cation_es_type: cation_charge}) - reaction.add_participant(particle_name=cation_name, - state_name=cation_state.name, - coefficient=1) - reaction.add_simulation_method("GRxMC") - # Reaction in terms of small anion: X- + HA = A - RE.add_reaction(gamma=gamma_K_AX.magnitude / K_XX.magnitude, - reactant_types=reactant_types+[anion_es_type], - reactant_coefficients=[1, 1], - product_types=product_types, - product_coefficients=[1], - default_charges=default_charges|{anion_es_type: anion_charge}) - rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=reactant_name, - state_name=reactant_state_name, - coefficient=-1), - ReactionParticipant(particle_name=product_name, - state_name=product_state_name, - coefficient=1), - ReactionParticipant(particle_name=anion_name, - state_name=anion_state.name, - coefficient=-1),], - pK=-np.log10(gamma_K_AX.magnitude / K_XX.magnitude), - reaction_type=reaction.reaction_type+"_conjugate", - simulation_method="GRxMC") - self.db._register_reaction(rx_tpl) - return RE, ionic_strength_res - - def setup_lj_interactions(self, espresso_system, shift_potential=True, combining_rule='Lorentz-Berthelot'): + raise RuntimeError('You need to set your simulation Engine') + + + def setup_lj_interactions(self, shift_potential=True, combining_rule='Lorentz-Berthelot'): """ Sets up the Lennard-Jones (LJ) potential between all pairs of particle states defined in the pyMBE database. @@ -3230,56 +2680,5 @@ def setup_lj_interactions(self, espresso_system, shift_potential=True, combining - Check the documentation of ESPResSo for more info about the potential https://espressomd.github.io/doc4.2.0/inter_non-bonded.html """ - from itertools import combinations_with_replacement - particle_templates = self.db.get_templates("particle") - shift = "auto" if shift_potential else 0 - if shift == "auto": - shift_tpl = shift - else: - shift_tpl = PintQuantity.from_quantity(q=shift*self.units.reduced_length, - expected_dimension="length", - ureg=self.units) - # Get all particle states registered in pyMBE - state_entries = [] - for tpl in particle_templates.values(): - for state in self.db.get_particle_states_templates(particle_name=tpl.name).values(): - state_entries.append((tpl, state)) - - # Iterate over all unique state pairs - for (tpl1, state1), (tpl2, state2) in combinations_with_replacement(state_entries, 2): - - lj_parameters = self.get_lj_parameters(particle_name1=tpl1.name, - particle_name2=tpl2.name, - combining_rule=combining_rule) - if not lj_parameters: - continue - - espresso_system.non_bonded_inter[state1.es_type, state2.es_type].lennard_jones.set_params( - epsilon=lj_parameters["epsilon"].to("reduced_energy").magnitude, - sigma=lj_parameters["sigma"].to("reduced_length").magnitude, - cutoff=lj_parameters["cutoff"].to("reduced_length").magnitude, - offset=lj_parameters["offset"].to("reduced_length").magnitude, - shift=shift) - - lj_template = LJInteractionTemplate(state1=state1.name, - state2=state2.name, - sigma=PintQuantity.from_quantity(q=lj_parameters["sigma"], - expected_dimension="length", - ureg=self.units), - epsilon=PintQuantity.from_quantity(q=lj_parameters["epsilon"], - expected_dimension="energy", - ureg=self.units), - cutoff=PintQuantity.from_quantity(q=lj_parameters["cutoff"], - expected_dimension="length", - ureg=self.units), - offset=PintQuantity.from_quantity(q=lj_parameters["offset"], - expected_dimension="length", - ureg=self.units), - shift=shift_tpl) - self.db._register_template(lj_template) - - def update_instances_ids_according_to_engine_particles_ids(self): - """ - Method to be called if particles have been previously added to a simulation engine without using pymbe. - """ - self.simulation_engine.update_instances_ids_according_to_engine_particles_ids() \ No newline at end of file + self.simulation_engine.setup_lj_interactions(shift_potential=shift_potential, + combining_rule=combining_rule) From 02559f5ba02ff284cd23e12d4600e67ff92a9949 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Sat, 9 May 2026 21:05:08 +0200 Subject: [PATCH 25/75] Add pymbe warnings to send a deprecate warning for the use of certain handy functions --- pyMBE/exceptions/pmb_warnings.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 pyMBE/exceptions/pmb_warnings.py diff --git a/pyMBE/exceptions/pmb_warnings.py b/pyMBE/exceptions/pmb_warnings.py new file mode 100644 index 00000000..8ddcf23e --- /dev/null +++ b/pyMBE/exceptions/pmb_warnings.py @@ -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 From 267cbf818d2bfb79091e606415b9ba9e0cec6cf6 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Sat, 9 May 2026 21:05:26 +0200 Subject: [PATCH 26/75] Add deprecation warnings to the use of handy functions --- pyMBE/lib/handy_functions.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pyMBE/lib/handy_functions.py b/pyMBE/lib/handy_functions.py index 33da68b0..78ac8977 100644 --- a/pyMBE/lib/handy_functions.py +++ b/pyMBE/lib/handy_functions.py @@ -20,6 +20,7 @@ import re import numpy as np import scipy +from pyMBE.exceptions.pmb_warnings import deprecated def calculate_initial_bond_length(bond_parameters, bond_type, lj_parameters): """ @@ -281,7 +282,7 @@ def define_peptide_AA_residues(sequence,model, pmb): pmb.define_residue(name = residue_name, central_bead = central_bead, side_chains = side_chains) - +@deprecated('pmb.simulation_engine.do_reaction') def do_reaction(algorithm, steps): """ Executes reaction steps using an ESPResSo reaction algorithm with @@ -311,6 +312,7 @@ def do_reaction(algorithm, steps): else: algorithm.reaction(steps=steps) +@deprecated('pmb.simulation_engine.get_number_of_particles') def get_number_of_particles(espresso_system, ptype): """ Returns the number of particles of a given ESPResSo particle type. @@ -508,7 +510,7 @@ def protein_sequence_parser(sequence): clean_sequence.append(residue_ok) return clean_sequence - +@deprecated('pmb.simulation_engine.relax_system') def relax_espresso_system(espresso_system, seed, gamma=1e-3, Nsteps_steepest_descent=5000, max_displacement=0.01, Nsteps_iter_relax=500): """ Relaxes the energy of the given ESPResSo system by performing the following steps: @@ -571,7 +573,7 @@ def relax_espresso_system(espresso_system, seed, gamma=1e-3, Nsteps_steepest_des logging.info(f"*** Minimum particle distance after relaxation: {espresso_system.analysis.min_dist()} ***") logging.debug("*** Relaxation finished ***") return espresso_system.analysis.min_dist() - +@deprecated('pmb.simulation_engine.setup_langevin_dynamics') def setup_langevin_dynamics(espresso_system, kT, seed,time_step=1e-2, gamma=1, tune_skin=True, min_skin=1, max_skin=None, tolerance=1e-3, int_steps=200, adjust_max_skin=True): """ Sets up Langevin Dynamics for an ESPResSo simulation system. @@ -634,7 +636,7 @@ def setup_langevin_dynamics(espresso_system, kT, seed,time_step=1e-2, gamma=1, t int_steps=int_steps, adjust_max_skin=adjust_max_skin) logging.info(f"Optimized skin value: {espresso_system.cell_system.skin}") - +@deprecated('pmb.simulation_engine.setup_electrostatic_interactions') def setup_electrostatic_interactions(units, espresso_system, kT, c_salt=None, solvent_permittivity=78.5, method='p3m', tune_p3m=True, accuracy=1e-3, params=None, verbose=False): """ Sets up electrostatic interactions in an ESPResSo system. From 557971b8ec43d8325fd68bdd3eec689a1d413132 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Sat, 9 May 2026 21:06:02 +0200 Subject: [PATCH 27/75] Add to espresso engine: - handy functions - reaction methods --- pyMBE/simulation_builder/espresso_engine.py | 1157 ++++++++++++++++++- 1 file changed, 1093 insertions(+), 64 deletions(-) diff --git a/pyMBE/simulation_builder/espresso_engine.py b/pyMBE/simulation_builder/espresso_engine.py index 89979796..25f3fe83 100644 --- a/pyMBE/simulation_builder/espresso_engine.py +++ b/pyMBE/simulation_builder/espresso_engine.py @@ -1,16 +1,30 @@ -from pyMBE.simulation_builder.base_engine import SimulationEngine + import espressomd +import espressomd.electrostatics +import espressomd.version import warnings from typing import List,Set +import numpy as np +import logging +from pyMBE.simulation_builder.base_engine import SimulationEngine +from pyMBE.storage.reactions.reaction import Reaction, ReactionParticipant +from pyMBE.storage.templates.lj import LJInteractionTemplate +from pyMBE.storage.pint_quantity import PintQuantity + + + class EspressoSimulation(SimulationEngine): - def __init__(self,box_l,db,espresso_system,units): + def __init__(self,box_l,db,espresso_system,units,kT,Kw,seed): self.db=db self.box_l: List[float]=box_l self.espresso_system=espresso_system self.units=units + self.kT=kT + self.Kw=Kw + self.seed=seed pass def _add_bond(self,particle_id1,particle_id2,bond_inst): @@ -160,12 +174,6 @@ def _get_particle_ids_in_espresso(self): espresso_particles=self.espresso_system.part.all() return espresso_particles.id - def _get_last_particle_id_in_espresso(self): - espresso_particles=self.espresso_system.part.all() - if len(espresso_particles)==0: - return None - last_particle_id=espresso_particles.id - return last_particle_id[-1] def _get_particle_pos_espresso(self,id): return self.espresso_system.part.by_id(id).pos @@ -173,6 +181,46 @@ def _get_particle_pos_espresso(self,id): def get_box_side_length(self): return self.box_l + def calculate_net_charge(self,object_name,pmb_type,dimensionless=False): + """ + Calculates the net charge per instance of a given pmb object type. + + Args: + espresso_system (espressomd.system.System): + ESPResSo system containing the particles. + object_name (str): + Name of the object (e.g. molecule, residue, peptide, protein). + pmb_type (str): + Type of object to analyze. Must be molecule-like. + dimensionless (bool, optional): + If True, return charge as a pure number. + If False, return a quantity with reduced_charge units. + + Returns: + dict: + {"mean": mean_net_charge, "instances": {instance_id: net_charge}} + """ + id_map = self.db.get_particle_id_map(object_name=object_name) + label = self.db._get_label_id_map(pmb_type=pmb_type) + instance_map = id_map[label] + charges = {} + for instance_id, particle_ids in instance_map.items(): + if dimensionless: + net_charge = 0.0 + else: + net_charge = 0 * self.units.Quantity(1, "reduced_charge") + for pid in particle_ids: + q = self.espresso_system.part.by_id(pid).q + if not dimensionless: + q *= self.units.Quantity(1, "reduced_charge") + net_charge += q + charges[instance_id] = net_charge + # Mean charge + if dimensionless: + mean_charge = float(np.mean(list(charges.values()))) + else: + mean_charge = (np.mean([q.magnitude for q in charges.values()])* self.units.Quantity(1, "reduced_charge")) + return {"mean": mean_charge, "instances": charges} def change_volume_and_rescale_particles(self, d_new, dir="xyz"): """ Change the volume for a particular dimension into the espresso system. @@ -181,9 +229,1045 @@ def change_volume_and_rescale_particles(self, d_new, dir="xyz"): dir(Literal[x,y,z]): coordinate in which to set the new dimension. """ + rescale_factor=np.array([1,1,1]) + if d_new<=0: + raise ValueError("The dimension cannot be negative, neither 0") + if "x" in dir: + rescale_factor[0]=d_new/self.box_l[0] + if "y" in dir: + rescale_factor[1]=d_new/self.box_l[1] + if "z" in dir: + rescale_factor[2]=d_new/self.box_l[2] + + instances=self.db._get_instances_df(pmb_type='particle') + for pid in range(instances.index.size): + es_pos=self.db.get_instance(instance_id=pid, + pmb_type='particle').position + rescaled_position=es_pos*rescale_factor + self.db._update_instance(instance_id=pid, + pmb_type='particle', + attribute='position', + value=rescaled_position) + self.espresso_system.change_volume_and_rescale_particles(d_new=d_new, dir=dir) return + def do_reaction(self,algorithm, steps): + """ + Executes reaction steps using an ESPResSo reaction algorithm with + version-compatible calling semantics. + + This function wraps the `reaction` method of an ESPResSo reaction + algorithm to account for differences in the method signature between + ESPResSo versions. + + Args: + algorithm ('espressomd.reaction_methods'): + ESPResSo reaction algorithm object (e.g. constant pH, + reaction ensemble, or similar). + steps ('int'): + Number of reaction steps to perform. + + Notes: + - In ESPResSo 4.2, the `reaction` method expects the number of steps + to be passed as the keyword argument `reaction_steps`. + - In newer ESPResSo versions, the keyword argument is `steps`. + - This helper function provides a stable interface across ESPResSo + versions by dispatching to the appropriate keyword internally. + """ + import espressomd.version + if espressomd.version.friendly() == '4.2': + algorithm.reaction(reaction_steps=steps) + else: + algorithm.reaction(steps=steps) + + def enable_motion_of_rigid_object(self, instance_id, pmb_type): + """ + Enables translational and rotational motion of a rigid pyMBE object instance + in an ESPResSo system.This method creates a rigid-body center particle at the center of mass of + the specified pyMBE object and attaches all constituent particles to it + using ESPResSo virtual sites. The resulting rigid object can translate and + rotate as a single body. + + Args: + instance_id ('int'): + Instance ID of the pyMBE object whose rigid-body motion is enabled. + + pmb_type ('str'): + pyMBE object type of the instance (e.g. '"molecule"', '"peptide"', + '"protein"', or any assembly-like type). + + espresso_system ('espressomd.system.System'): + ESPResSo system in which the rigid object is defined. + + Notess: + - This method requires ESPResSo to be compiled with the following + features enabled: + - '"VIRTUAL_SITES_RELATIVE"' + - '"MASS"' + - A new ESPResSo particle is created to represent the rigid-body center. + - The mass of the rigid-body center is set to the number of particles + belonging to the object. + - The rotational inertia tensor is approximated from the squared + distances of the particles to the center of mass. + """ + logging.info('enable_motion_of_rigid_object requires that espressomd has the following features activated: ["VIRTUAL_SITES_RELATIVE", "MASS"]') + inst = self.db.get_instance(pmb_type=pmb_type, + instance_id=instance_id) + label = self.db._get_label_id_map(pmb_type=pmb_type) + particle_ids_list = self.db.get_particle_id_map(object_name=inst.name)[label][instance_id] + center_of_mass = self.calculate_center_of_mass (instance_id=instance_id, + pmb_type=pmb_type) + rigid_object_center = self.espresso_system.part.add(pos=center_of_mass, + rotation=[True,True,True], + type=self.db.propose_unused_type()) + rigid_object_center.mass = len(particle_ids_list) + momI = 0 + for pid in particle_ids_list: + momI += np.power(np.linalg.norm(center_of_mass - self.espresso_system.part.by_id(pid).pos), 2) + rigid_object_center.rinertia = np.ones(3) * momI + for particle_id in particle_ids_list: + pid = self.espresso_system.part.by_id(particle_id) + pid.vs_auto_relate_to(rigid_object_center.id) + + def get_number_of_particles(self,espresso_system, ptype): + """ + Returns the number of particles of a given ESPResSo particle type. + + Args: + espresso_system ('espressomd.system.System'): + ESPResSo system object from which the particle count is queried. + ptype ('int'): + ESPResSo particle type identifier. + + Returns: + ('int'): + Number of particles in `espresso_system` with particle type `ptype`. + + Notes: + - In ESPResSo 4.2, `number_of_particles` expects the particle type + as a positional argument. + - In later ESPResSo versions, the particle type must be passed as a + keyword argument (`type=ptype`). + - This helper function hides these API differences and provides + a uniform interface across ESPResSo versions. + """ + import espressomd.version + if espressomd.version.friendly() == "4.2": + args = (ptype,) + kwargs = {} + else: + args = () + kwargs = {"type": ptype} + return espresso_system.number_of_particles(*args, **kwargs) + + def relax_espresso_system(self,espresso_system, seed, gamma=1e-3, Nsteps_steepest_descent=5000, max_displacement=0.01, Nsteps_iter_relax=500): + """ + Relaxes the energy of the given ESPResSo system by performing the following steps: + (1) Steepest descent energy minimization, to remove large forces and relax the system to a local minimum. + (2) A Langevin Dynamics run, to further relax the system and ensure that it is in thermal equilibrium. + + This function is useful to avoid code repetition in the sample scripts of pyMBE, but it is by no means general-purpose. + Similarly, the default parameters are not universal and should be adapted to the specific system at hand. + In general, system relaxation is a complex procedure and should be adapted for each particular application. + If you experience crashes or unexpected behavior, please consider using your own relaxation procedure. + + Args: + espresso_system (`espressomd.system.System`): + system object of espressomd library. + + seed (`int`): + Seed for the random number generator for the thermostat. + + gamma (`float`, optional): + Starting damping constant for Langevin dynamics. Defaults to 1e-3 reduced time**-1. + + Nsteps_steepest_descent (`int`, optional): + Total number of steps for steepest descent minimization. Defaults to 5000. + + max_displacement (`float`, optional): + Maximum particle displacement allowed during minimization. Defaults to 0.01 reduced length. + + Nsteps_iter_relax (`int`, optional): + Number of steps per iteration for Langevin dynamics relaxation. Defaults to 500. + + Return: + (`float`): + minimum distance between particles in the system after the relaxation + + Notes: + - The thermostat is turned off by the end of the procedure. + - Make sure the system is initialized properly before calling this function. + """ + # Sanity checks + if gamma <= 0: + raise ValueError("The damping constant 'gamma' must be positive.") + if Nsteps_steepest_descent <= 0 or Nsteps_iter_relax <= 0: + raise ValueError("Step counts must be positive integers.") + if max_displacement <= 0: + raise ValueError("'max_displacement' must be positive.") + logging.debug("*** Relaxing the energy of the system... ***") + logging.debug("*** Starting steepest descent minimization ***") + espresso_system.thermostat.turn_off() + espresso_system.integrator.set_steepest_descent(f_max=0, + gamma=gamma, + max_displacement=max_displacement) + espresso_system.integrator.run(Nsteps_steepest_descent) + logging.debug("*** Finished steepest descent minimization ***") + logging.debug("*** Starting Langevin Dynamics relaxation ***") + espresso_system.integrator.set_vv() + espresso_system.thermostat.set_langevin(kT=1., gamma=gamma, seed=seed) + espresso_system.integrator.run(Nsteps_iter_relax) + espresso_system.thermostat.turn_off() + logging.debug("*** Finished Langevin Dynamics relaxation ***") + logging.info(f"*** Minimum particle distance after relaxation: {espresso_system.analysis.min_dist()} ***") + logging.debug("*** Relaxation finished ***") + return espresso_system.analysis.min_dist() + + def setup_electrostatic_interactions(self,units, espresso_system, kT, c_salt=None, solvent_permittivity=78.5, method='p3m', tune_p3m=True, accuracy=1e-3, params=None, verbose=False): + """ + Sets up electrostatic interactions in an ESPResSo system. + + Args: + units (`pint.UnitRegistry`): + Unit registry for handling physical units. + + espresso_system (`espressomd.system.System`): + system object of espressomd library. + + kT (`pint.Quantity`): + Thermal energy. + + c_salt (`pint.Quantity`): + Added salt concentration. If provided, the program outputs the debye screening length. It is a mandatory parameter for the Debye-Hückel method. + + solvent_permittivity (`float`): + Solvent relative permittivity. Defaults to 78.5, correspoding to its value in water at 298.15 K. + + method (`str`): + Method for computing electrostatic interactions. Defaults to "p3m". + + tune_p3m (`bool`): + If True, tunes P3M parameters for efficiency. Defaults to True. + + accuracy (`float`): + Desired accuracy for electrostatics. Defaults to 1e-3. + + params (`dict`): + Additional parameters for the electrostatic method. For P3M, it can include 'mesh', 'alpha', 'cao' and `r_cut`. For Debye-Hückel, it can include 'r_cut'. + + verbose (`bool`): + If True, enables verbose output for P3M tuning. Defaults to False. + + Notes: + - `c_salt` is a mandatory argument for setting up the Debye-Hückel electrostatic potential. + - The calculated Bjerrum length is ouput to the log. If `c_salt` is provided, the calculated Debye screening length is also output to the log. + - Currently, the only supported electrostatic methods are P3M ("p3m") and Debye-Hückel ("dh"). + """ + import numpy as np + import scipy.constants + + logging.debug("*** Starting electrostatic interactions setup... ***") + # Initial sanity checks + if not hasattr(units, 'Quantity'): + raise TypeError("Invalid 'units' argument: Expected a pint.UnitRegistry object") + valid_methods_list=['p3m', 'dh'] + if method not in valid_methods_list: + raise ValueError('Method not supported, supported methods are', valid_methods_list) + if c_salt is None and method == 'dh': + raise ValueError('Please provide the added salt concentration c_salt to setup the Debye-Huckel potential') + e = scipy.constants.e * units.C + N_A = scipy.constants.N_A / units.mol + BJERRUM_LENGTH = e**2 / (4 * units.pi * units.eps0 * solvent_permittivity * kT) + logging.info(f" Bjerrum length {BJERRUM_LENGTH.to('nm')} = {BJERRUM_LENGTH.to('reduced_length')}") + COULOMB_PREFACTOR=BJERRUM_LENGTH * kT + if c_salt is not None: + if c_salt.check('[substance] [length]**-3'): + KAPPA=1./np.sqrt(8*units.pi*BJERRUM_LENGTH*N_A*c_salt) + elif c_salt.check('[length]**-3'): + KAPPA=1./np.sqrt(8*units.pi*BJERRUM_LENGTH*c_salt) + else: + raise ValueError('Unknown units for c_salt, supported units for salt concentration are [mol / volume] or [particle / volume]', c_salt) + + logging.info(f"Debye kappa {KAPPA.to('nm')} = {KAPPA.to('reduced_length')}") + + if params is None: + params = {} + + if method == 'p3m': + logging.debug("*** Setting up Coulomb electrostatics using the P3M method ***") + coulomb = espressomd.electrostatics.P3M(prefactor = COULOMB_PREFACTOR.m_as("reduced_length * reduced_energy"), + accuracy=accuracy, + verbose=verbose, + tune=tune_p3m, + **params) + + if tune_p3m: + espresso_system.time_step=0.01 + if espressomd.version.friendly() == "4.2": + espresso_system.actors.add(coulomb) + else: + espresso_system.electrostatics.solver = coulomb + + + # save the optimal parameters and add them by hand + + p3m_params = coulomb.get_params() + if espressomd.version.friendly() == "4.2": + espresso_system.actors.remove(coulomb) + else: + espresso_system.electrostatics.solver = None + coulomb = espressomd.electrostatics.P3M(prefactor = COULOMB_PREFACTOR.m_as("reduced_length * reduced_energy"), + accuracy = accuracy, + mesh = p3m_params['mesh'], + alpha = p3m_params['alpha'] , + cao = p3m_params['cao'], + r_cut = p3m_params['r_cut'], + tune = False) + + elif method == 'dh': + logging.debug("*** Setting up Debye-Hückel electrostatics ***") + if params: + r_cut = params['r_cut'] + else: + r_cut = 3*KAPPA.to('reduced_length').magnitude + + coulomb = espressomd.electrostatics.DH(prefactor = COULOMB_PREFACTOR.m_as("reduced_length * reduced_energy"), + kappa = (1./KAPPA).to('1/ reduced_length').magnitude, + r_cut = r_cut) + if espressomd.version.friendly() == "4.2": + espresso_system.actors.add(coulomb) + else: + espresso_system.electrostatics.solver = coulomb + logging.debug("*** Electrostatics successfully added to the system ***") + + def setup_cpH (self, counter_ion, constant_pH, exclusion_range=None, use_exclusion_radius_per_type = False): + """ + Sets up the Acid/Base reactions for acidic/basic particles defined in the pyMBE database + to be sampled in the constant pH ensemble. + + Args: + counter_ion ('str'): + 'name' of the counter_ion 'particle'. + + constant_pH ('float'): + pH-value. + + exclusion_range ('pint.Quantity', optional): + Below this value, no particles will be inserted. + + use_exclusion_radius_per_type ('bool', optional): + Controls if one exclusion_radius for each espresso_type is used. Defaults to 'False'. + + Returns: + ('reaction_methods.ConstantpHEnsemble'): + Instance of a reaction_methods.ConstantpHEnsemble object from the espressomd library. + """ + from espressomd import reaction_methods + if exclusion_range is None: + exclusion_range = max(self.db.get_radius_map().values())*2.0 + if use_exclusion_radius_per_type: + exclusion_radius_per_type = self.db.get_radius_map() + else: + exclusion_radius_per_type = {} + RE = reaction_methods.ConstantpHEnsemble(kT=self.kT.to('reduced_energy').magnitude, + exclusion_range=exclusion_range, + seed=self.seed, + constant_pH=constant_pH, + exclusion_radius_per_type = exclusion_radius_per_type) + conterion_tpl = self.db.get_template(name=counter_ion, + pmb_type="particle") + conterion_state = self.db.get_template(name=conterion_tpl.initial_state, + pmb_type="particle_state") + for reaction in self.db.get_reactions(): + if reaction.reaction_type not in ["monoprotic_acid", "monoprotic_base"]: + continue + default_charges = {} + reactant_types = [] + product_types = [] + for participant in reaction.participants: + state_tpl = self.db.get_template(name=participant.state_name, + pmb_type="particle_state") + default_charges[state_tpl.es_type] = state_tpl.z + if participant.coefficient < 0: + reactant_types.append(state_tpl.es_type) + elif participant.coefficient > 0: + product_types.append(state_tpl.es_type) + # Add counterion to the products + if conterion_state.es_type not in product_types: + product_types.append(conterion_state.es_type) + default_charges[conterion_state.es_type] = conterion_state.z + reaction.add_participant(particle_name=counter_ion, + state_name=conterion_tpl.initial_state, + coefficient=1) + gamma=10**-reaction.pK + RE.add_reaction(gamma=gamma, + reactant_types=reactant_types, + product_types=product_types, + default_charges=default_charges) + reaction.add_simulation_method(simulation_method="cpH") + return RE + + def setup_gcmc(self, c_salt_res, salt_cation_name, salt_anion_name, activity_coefficient, exclusion_range=None, use_exclusion_radius_per_type = False): + """ + Sets up grand-canonical coupling to a reservoir of salt. + For reactive systems coupled to a reservoir, the grand-reaction method has to be used instead. + + Args: + c_salt_res ('pint.Quantity'): + Concentration of monovalent salt (e.g. NaCl) in the reservoir. + + salt_cation_name ('str'): + Name of the salt cation (e.g. Na+) particle. + + salt_anion_name ('str'): + Name of the salt anion (e.g. Cl-) particle. + + activity_coefficient ('callable'): + A function that calculates the activity coefficient of an ion pair as a function of the ionic strength. + + exclusion_range('pint.Quantity', optional): + For distances shorter than this value, no particles will be inserted. + + use_exclusion_radius_per_type('bool',optional): + Controls if one exclusion_radius for each espresso_type is used. Defaults to 'False'. + + Returns: + ('reaction_methods.ReactionEnsemble'): + Instance of a reaction_methods.ReactionEnsemble object from the espressomd library. + """ + from espressomd import reaction_methods + if exclusion_range is None: + exclusion_range = max(self.db.get_radius_map().values())*2.0 + if use_exclusion_radius_per_type: + exclusion_radius_per_type = self.db.get_radius_map() + else: + exclusion_radius_per_type = {} + RE = reaction_methods.ReactionEnsemble(kT=self.kT.to('reduced_energy').magnitude, + exclusion_range=exclusion_range, + seed=self.seed, + exclusion_radius_per_type = exclusion_radius_per_type) + # Determine the concentrations of the various species in the reservoir and the equilibrium constants + determined_activity_coefficient = activity_coefficient(c_salt_res) + K_salt = (c_salt_res.to('1/(N_A * reduced_length**3)')**2) * determined_activity_coefficient + cation_tpl = self.db.get_template(pmb_type="particle", + name=salt_cation_name) + cation_state = self.db.get_template(pmb_type="particle_state", + name=cation_tpl.initial_state) + anion_tpl = self.db.get_template(pmb_type="particle", + name=salt_anion_name) + anion_state = self.db.get_template(pmb_type="particle_state", + name=anion_tpl.initial_state) + salt_cation_es_type = cation_state.es_type + salt_anion_es_type = anion_state.es_type + salt_cation_charge = cation_state.z + salt_anion_charge = anion_state.z + if salt_cation_charge <= 0: + raise ValueError('ERROR salt cation charge must be positive, charge ', salt_cation_charge) + if salt_anion_charge >= 0: + raise ValueError('ERROR salt anion charge must be negative, charge ', salt_anion_charge) + # Grand-canonical coupling to the reservoir + RE.add_reaction(gamma = K_salt.magnitude, + reactant_types = [], + reactant_coefficients = [], + product_types = [ salt_cation_es_type, salt_anion_es_type ], + product_coefficients = [ 1, 1 ], + default_charges = {salt_cation_es_type: salt_cation_charge, + salt_anion_es_type: salt_anion_charge}) + rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=salt_cation_name, + state_name=cation_state.name, + coefficient=1), + ReactionParticipant(particle_name=salt_anion_name, + state_name=anion_state.name, + coefficient=1)], + pK=-np.log10(K_salt.magnitude), + reaction_type="ion_insertion", + simulation_method="GCMC") + self.db._register_reaction(rx_tpl) + return RE + + def setup_grxmc_reactions(self, pH_res, c_salt_res, proton_name, hydroxide_name, salt_cation_name, salt_anion_name, activity_coefficient, exclusion_range=None, use_exclusion_radius_per_type = False): + """ + Sets up acid/base reactions for acidic/basic monoprotic particles defined in the pyMBE database, + as well as a grand-canonical coupling to a reservoir of small ions. + + Args: + pH_res ('float'): + pH-value in the reservoir. + + c_salt_res ('pint.Quantity'): + Concentration of monovalent salt (e.g. NaCl) in the reservoir. + + proton_name ('str'): + Name of the proton (H+) particle. + + hydroxide_name ('str'): + Name of the hydroxide (OH-) particle. + + salt_cation_name ('str'): + Name of the salt cation (e.g. Na+) particle. + + salt_anion_name ('str'): + Name of the salt anion (e.g. Cl-) particle. + + activity_coefficient ('callable'): + A function that calculates the activity coefficient of an ion pair as a function of the ionic strength. + + exclusion_range('pint.Quantity', optional): + For distances shorter than this value, no particles will be inserted. + + use_exclusion_radius_per_type('bool', optional): + Controls if one exclusion_radius for each espresso_type is used. Defaults to 'False'. + + Returns: + 'tuple(reaction_methods.ReactionEnsemble,pint.Quantity)': + + 'reaction_methods.ReactionEnsemble': + espressomd reaction_methods object with all reactions necesary to run the GRxMC ensamble. + + 'pint.Quantity': + Ionic strength of the reservoir (useful for calculating partition coefficients). + + Notess: + - This implementation uses the original formulation of the grand-reaction method by Landsgesell et al. [1]. + + [1] Landsgesell, J., Hebbeker, P., Rud, O., Lunkad, R., Košovan, P., & Holm, C. (2020). Grand-reaction method for simulations of ionization equilibria coupled to ion partitioning. Macromolecules, 53(8), 3007-3020. + """ + from espressomd import reaction_methods + if exclusion_range is None: + exclusion_range = max(self.db.get_radius_map().values())*2.0 + if use_exclusion_radius_per_type: + exclusion_radius_per_type = self.db.get_radius_map() + else: + exclusion_radius_per_type = {} + RE = reaction_methods.ReactionEnsemble(kT=self.kT.to('reduced_energy').magnitude, + exclusion_range=exclusion_range, + seed=self.seed, + exclusion_radius_per_type = exclusion_radius_per_type) + # Determine the concentrations of the various species in the reservoir and the equilibrium constants + cH_res, cOH_res, cNa_res, cCl_res = self.determine_reservoir_concentrations(pH_res, c_salt_res, activity_coefficient) + ionic_strength_res = 0.5*(cNa_res+cCl_res+cOH_res+cH_res) + determined_activity_coefficient = activity_coefficient(ionic_strength_res) + K_W = cH_res.to('1/(N_A * reduced_length**3)') * cOH_res.to('1/(N_A * reduced_length**3)') * determined_activity_coefficient + K_NACL = cNa_res.to('1/(N_A * reduced_length**3)') * cCl_res.to('1/(N_A * reduced_length**3)') * determined_activity_coefficient + K_HCL = cH_res.to('1/(N_A * reduced_length**3)') * cCl_res.to('1/(N_A * reduced_length**3)') * determined_activity_coefficient + cation_tpl = self.db.get_template(pmb_type="particle", + name=salt_cation_name) + cation_state = self.db.get_template(pmb_type="particle_state", + name=cation_tpl.initial_state) + anion_tpl = self.db.get_template(pmb_type="particle", + name=salt_anion_name) + anion_state = self.db.get_template(pmb_type="particle_state", + name=anion_tpl.initial_state) + proton_tpl = self.db.get_template(pmb_type="particle", + name=proton_name) + proton_state = self.db.get_template(pmb_type="particle_state", + name=proton_tpl.initial_state) + hydroxide_tpl = self.db.get_template(pmb_type="particle", + name=hydroxide_name) + hydroxide_state = self.db.get_template(pmb_type="particle_state", + name=hydroxide_tpl.initial_state) + proton_es_type = proton_state.es_type + hydroxide_es_type = hydroxide_state.es_type + salt_cation_es_type = cation_state.es_type + salt_anion_es_type = anion_state.es_type + proton_charge = proton_state.z + hydroxide_charge = hydroxide_state.z + salt_cation_charge = cation_state.z + salt_anion_charge = anion_state.z + if proton_charge <= 0: + raise ValueError('ERROR proton charge must be positive, charge ', proton_charge) + if salt_cation_charge <= 0: + raise ValueError('ERROR salt cation charge must be positive, charge ', salt_cation_charge) + if hydroxide_charge >= 0: + raise ValueError('ERROR hydroxide charge must be negative, charge ', hydroxide_charge) + if salt_anion_charge >= 0: + raise ValueError('ERROR salt anion charge must be negative, charge ', salt_anion_charge) + # Grand-canonical coupling to the reservoir + # 0 = H+ + OH- + RE.add_reaction(gamma = K_W.magnitude, + reactant_types = [], + reactant_coefficients = [], + product_types = [ proton_es_type, hydroxide_es_type ], + product_coefficients = [ 1, 1 ], + default_charges = {proton_es_type: proton_charge, + hydroxide_es_type: hydroxide_charge}) + rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=proton_name, + state_name=proton_state.name, + coefficient=1), + ReactionParticipant(particle_name=hydroxide_name, + state_name=hydroxide_state.name, + coefficient=1)], + pK=-np.log10(K_W.magnitude), + reaction_type="ion_insertion", + simulation_method="GRxMC") + self.db._register_reaction(rx_tpl) + # 0 = Na+ + Cl- + RE.add_reaction(gamma = K_NACL.magnitude, + reactant_types = [], + reactant_coefficients = [], + product_types = [ salt_cation_es_type, salt_anion_es_type ], + product_coefficients = [ 1, 1 ], + default_charges = {salt_cation_es_type: salt_cation_charge, + salt_anion_es_type: salt_anion_charge}) + rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=salt_cation_name, + state_name=cation_state.name, + coefficient=1), + ReactionParticipant(particle_name=salt_anion_name, + state_name=anion_state.name, + coefficient=1)], + pK=-np.log10(K_NACL.magnitude), + reaction_type="ion_insertion", + simulation_method="GRxMC") + self.db._register_reaction(rx_tpl) + # 0 = Na+ + OH- + RE.add_reaction(gamma = (K_NACL * K_W / K_HCL).magnitude, + reactant_types = [], + reactant_coefficients = [], + product_types = [ salt_cation_es_type, hydroxide_es_type ], + product_coefficients = [ 1, 1 ], + default_charges = {salt_cation_es_type: salt_cation_charge, + hydroxide_es_type: hydroxide_charge}) + rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=salt_cation_name, + state_name=cation_state.name, + coefficient=1), + ReactionParticipant(particle_name=hydroxide_name, + state_name=hydroxide_state.name, + coefficient=1)], + pK=-np.log10((K_NACL * K_W / K_HCL).magnitude), + reaction_type="ion_insertion", + simulation_method="GRxMC") + self.db._register_reaction(rx_tpl) + # 0 = H+ + Cl- + RE.add_reaction(gamma = K_HCL.magnitude, + reactant_types = [], + reactant_coefficients = [], + product_types = [ proton_es_type, salt_anion_es_type ], + product_coefficients = [ 1, 1 ], + default_charges = {proton_es_type: proton_charge, + salt_anion_es_type: salt_anion_charge}) + rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=proton_name, + state_name=proton_state.name, + coefficient=1), + ReactionParticipant(particle_name=salt_anion_name, + state_name=anion_state.name, + coefficient=1)], + pK=-np.log10(K_HCL.magnitude), + reaction_type="ion_insertion", + simulation_method="GRxMC") + self.db._register_reaction(rx_tpl) + # Annealing moves to ensure sufficient sampling + # Cation annealing H+ = Na+ + RE.add_reaction(gamma = (K_NACL / K_HCL).magnitude, + reactant_types = [proton_es_type], + reactant_coefficients = [ 1 ], + product_types = [ salt_cation_es_type ], + product_coefficients = [ 1 ], + default_charges = {proton_es_type: proton_charge, + salt_cation_es_type: salt_cation_charge}) + rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=proton_name, + state_name=proton_state.name, + coefficient=-1), + ReactionParticipant(particle_name=salt_cation_name, + state_name=cation_state.name, + coefficient=1)], + pK=-np.log10((K_NACL / K_HCL).magnitude), + reaction_type="particle replacement", + simulation_method="GRxMC") + self.db._register_reaction(rx_tpl) + # Anion annealing OH- = Cl- + RE.add_reaction(gamma = (K_HCL / K_W).magnitude, + reactant_types = [hydroxide_es_type], + reactant_coefficients = [ 1 ], + product_types = [ salt_anion_es_type ], + product_coefficients = [ 1 ], + default_charges = {hydroxide_es_type: hydroxide_charge, + salt_anion_es_type: salt_anion_charge}) + rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=hydroxide_name, + state_name=hydroxide_state.name, + coefficient=-1), + ReactionParticipant(particle_name=salt_anion_name, + state_name=anion_state.name, + coefficient=1)], + pK=-np.log10((K_HCL / K_W).magnitude), + reaction_type="particle replacement", + simulation_method="GRxMC") + self.db._register_reaction(rx_tpl) + for reaction in self.db.get_reactions(): + if reaction.reaction_type not in ["monoprotic_acid", "monoprotic_base"]: + continue + default_charges = {} + reactant_types = [] + product_types = [] + for participant in reaction.participants: + state_tpl = self.db.get_template(name=participant.state_name, + pmb_type="particle_state") + default_charges[state_tpl.es_type] = state_tpl.z + if participant.coefficient < 0: + reactant_types.append(state_tpl.es_type) + reactant_name=state_tpl.particle_name + reactant_state_name=state_tpl.name + elif participant.coefficient > 0: + product_types.append(state_tpl.es_type) + product_name=state_tpl.particle_name + product_state_name=state_tpl.name + + Ka = (10**-reaction.pK * self.units.mol/self.units.l).to('1/(N_A * reduced_length**3)') + # Reaction in terms of proton: HA = A + H+ + RE.add_reaction(gamma=Ka.magnitude, + reactant_types=reactant_types, + reactant_coefficients=[1], + product_types=product_types+[proton_es_type], + product_coefficients=[1, 1], + default_charges= default_charges | {proton_es_type: proton_charge}) + reaction.add_participant(particle_name=proton_name, + state_name=proton_state.name, + coefficient=1) + reaction.add_simulation_method("GRxMC") + # Reaction in terms of salt cation: HA = A + Na+ + RE.add_reaction(gamma=(Ka * K_NACL / K_HCL).magnitude, + reactant_types=reactant_types, + reactant_coefficients=[1], + product_types=product_types+[salt_cation_es_type], + product_coefficients=[1, 1], + default_charges=default_charges | {salt_cation_es_type: salt_cation_charge}) + rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=reactant_name, + state_name=reactant_state_name, + coefficient=-1), + ReactionParticipant(particle_name=product_name, + state_name=product_state_name, + coefficient=1), + ReactionParticipant(particle_name=salt_cation_name, + state_name=cation_state.name, + coefficient=1),], + pK=-np.log10((Ka * K_NACL / K_HCL).magnitude), + reaction_type=reaction.reaction_type+"_salt", + simulation_method="GRxMC") + self.db._register_reaction(rx_tpl) + # Reaction in terms of hydroxide: OH- + HA = A + RE.add_reaction(gamma=(Ka / K_W).magnitude, + reactant_types=reactant_types+[hydroxide_es_type], + reactant_coefficients=[1, 1], + product_types=product_types, + product_coefficients=[1], + default_charges=default_charges | {hydroxide_es_type: hydroxide_charge}) + rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=reactant_name, + state_name=reactant_state_name, + coefficient=-1), + ReactionParticipant(particle_name=product_name, + state_name=product_state_name, + coefficient=1), + ReactionParticipant(particle_name=hydroxide_name, + state_name=hydroxide_state.name, + coefficient=-1),], + pK=-np.log10((Ka / K_W).magnitude), + reaction_type=reaction.reaction_type+"_conjugate", + simulation_method="GRxMC") + self.db._register_reaction(rx_tpl) + # Reaction in terms of salt anion: Cl- + HA = A + RE.add_reaction(gamma=(Ka / K_HCL).magnitude, + reactant_types=reactant_types+[salt_anion_es_type], + reactant_coefficients=[1, 1], + product_types=product_types, + product_coefficients=[1], + default_charges=default_charges | {salt_anion_es_type: salt_anion_charge}) + rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=reactant_name, + state_name=reactant_state_name, + coefficient=-1), + ReactionParticipant(particle_name=product_name, + state_name=product_state_name, + coefficient=1), + ReactionParticipant(particle_name=salt_anion_name, + state_name=anion_state.name, + coefficient=-1),], + pK=-np.log10((Ka / K_HCL).magnitude), + reaction_type=reaction.reaction_type+"_salt", + simulation_method="GRxMC") + self.db._register_reaction(rx_tpl) + return RE, ionic_strength_res + + def setup_grxmc_unified(self, pH_res, c_salt_res, cation_name, anion_name, activity_coefficient, exclusion_range=None, use_exclusion_radius_per_type = False): + """ + Sets up acid/base reactions for acidic/basic 'particles' defined in the pyMBE database, as well as a grand-canonical coupling to a + reservoir of small ions using a unified formulation for small ions. + + Args: + pH_res ('float'): + pH-value in the reservoir. + + c_salt_res ('pint.Quantity'): + Concentration of monovalent salt (e.g. NaCl) in the reservoir. + + cation_name ('str'): + Name of the cationic particle. + + anion_name ('str'): + Name of the anionic particle. + + activity_coefficient ('callable'): + A function that calculates the activity coefficient of an ion pair as a function of the ionic strength. + + exclusion_range('pint.Quantity', optional): + Below this value, no particles will be inserted. + + use_exclusion_radius_per_type('bool', optional): + Controls if one exclusion_radius per each espresso_type. Defaults to 'False'. + + Returns: + 'tuple(reaction_methods.ReactionEnsemble,pint.Quantity)': + + 'reaction_methods.ReactionEnsemble': + espressomd reaction_methods object with all reactions necesary to run the GRxMC ensamble. + + 'pint.Quantity': + Ionic strength of the reservoir (useful for calculating partition coefficients). + + Notes: + - This implementation uses the formulation of the grand-reaction method by Curk et al. [1], which relies on "unified" ion types X+ = {H+, Na+} and X- = {OH-, Cl-}. + - A function that implements the original version of the grand-reaction method by Landsgesell et al. [2] is also available under the name 'setup_grxmc_reactions'. + + [1] Curk, T., Yuan, J., & Luijten, E. (2022). Accelerated simulation method for charge regulation effects. The Journal of Chemical Physics, 156(4). + [2] Landsgesell, J., Hebbeker, P., Rud, O., Lunkad, R., Košovan, P., & Holm, C. (2020). Grand-reaction method for simulations of ionization equilibria coupled to ion partitioning. Macromolecules, 53(8), 3007-3020. + """ + from espressomd import reaction_methods + if exclusion_range is None: + exclusion_range = max(self.db.get_radius_map().values())*2.0 + if use_exclusion_radius_per_type: + exclusion_radius_per_type = self.db.get_radius_map() + else: + exclusion_radius_per_type = {} + RE = reaction_methods.ReactionEnsemble(kT=self.kT.to('reduced_energy').magnitude, + exclusion_range=exclusion_range, + seed=self.seed, + exclusion_radius_per_type = exclusion_radius_per_type) + # Determine the concentrations of the various species in the reservoir and the equilibrium constants + cH_res, cOH_res, cNa_res, cCl_res = self.determine_reservoir_concentrations(pH_res, c_salt_res, activity_coefficient) + ionic_strength_res = 0.5*(cNa_res+cCl_res+cOH_res+cH_res) + determined_activity_coefficient = activity_coefficient(ionic_strength_res) + a_hydrogen = (10 ** (-pH_res) * self.units.mol/self.units.l).to('1/(N_A * reduced_length**3)') + a_cation = (cH_res+cNa_res).to('1/(N_A * reduced_length**3)') * np.sqrt(determined_activity_coefficient) + a_anion = (cH_res+cNa_res).to('1/(N_A * reduced_length**3)') * np.sqrt(determined_activity_coefficient) + K_XX = a_cation * a_anion + cation_tpl = self.db.get_template(pmb_type="particle", + name=cation_name) + cation_state = self.db.get_template(pmb_type="particle_state", + name=cation_tpl.initial_state) + anion_tpl = self.db.get_template(pmb_type="particle", + name=anion_name) + anion_state = self.db.get_template(pmb_type="particle_state", + name=anion_tpl.initial_state) + cation_es_type = cation_state.es_type + anion_es_type = anion_state.es_type + cation_charge = cation_state.z + anion_charge = anion_state.z + if cation_charge <= 0: + raise ValueError('ERROR cation charge must be positive, charge ', cation_charge) + if anion_charge >= 0: + raise ValueError('ERROR anion charge must be negative, charge ', anion_charge) + # Coupling to the reservoir: 0 = X+ + X- + RE.add_reaction(gamma = K_XX.magnitude, + reactant_types = [], + reactant_coefficients = [], + product_types = [ cation_es_type, anion_es_type ], + product_coefficients = [ 1, 1 ], + default_charges = {cation_es_type: cation_charge, + anion_es_type: anion_charge}) + rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=cation_name, + state_name=cation_state.name, + coefficient=1), + ReactionParticipant(particle_name=anion_name, + state_name=anion_state.name, + coefficient=1)], + pK=-np.log10(K_XX.magnitude), + reaction_type="ion_insertion", + simulation_method="GCMC") + self.db._register_reaction(rx_tpl) + for reaction in self.db.get_reactions(): + if reaction.reaction_type not in ["monoprotic_acid", "monoprotic_base"]: + continue + default_charges = {} + reactant_types = [] + product_types = [] + for participant in reaction.participants: + state_tpl = self.db.get_template(name=participant.state_name, + pmb_type="particle_state") + default_charges[state_tpl.es_type] = state_tpl.z + if participant.coefficient < 0: + reactant_types.append(state_tpl.es_type) + reactant_name=state_tpl.particle_name + reactant_state_name=state_tpl.name + elif participant.coefficient > 0: + product_types.append(state_tpl.es_type) + product_name=state_tpl.particle_name + product_state_name=state_tpl.name + + Ka = (10**-reaction.pK * self.units.mol/self.units.l).to('1/(N_A * reduced_length**3)') + gamma_K_AX = Ka.to('1/(N_A * reduced_length**3)').magnitude * a_cation / a_hydrogen + # Reaction in terms of small cation: HA = A + X+ + RE.add_reaction(gamma=gamma_K_AX.magnitude, + reactant_types=reactant_types, + reactant_coefficients=[1], + product_types=product_types+[cation_es_type], + product_coefficients=[1, 1], + default_charges=default_charges|{cation_es_type: cation_charge}) + reaction.add_participant(particle_name=cation_name, + state_name=cation_state.name, + coefficient=1) + reaction.add_simulation_method("GRxMC") + # Reaction in terms of small anion: X- + HA = A + RE.add_reaction(gamma=gamma_K_AX.magnitude / K_XX.magnitude, + reactant_types=reactant_types+[anion_es_type], + reactant_coefficients=[1, 1], + product_types=product_types, + product_coefficients=[1], + default_charges=default_charges|{anion_es_type: anion_charge}) + rx_tpl = Reaction(participants=[ReactionParticipant(particle_name=reactant_name, + state_name=reactant_state_name, + coefficient=-1), + ReactionParticipant(particle_name=product_name, + state_name=product_state_name, + coefficient=1), + ReactionParticipant(particle_name=anion_name, + state_name=anion_state.name, + coefficient=-1),], + pK=-np.log10(gamma_K_AX.magnitude / K_XX.magnitude), + reaction_type=reaction.reaction_type+"_conjugate", + simulation_method="GRxMC") + self.db._register_reaction(rx_tpl) + return RE, ionic_strength_res + + def setup_langevin_dynamics(self,espresso_system, kT, seed,time_step=1e-2, gamma=1, tune_skin=True, min_skin=1, max_skin=None, tolerance=1e-3, int_steps=200, adjust_max_skin=True): + """ + Sets up Langevin Dynamics for an ESPResSo simulation system. + + Args: + espresso_system (`espressomd.system.System`): + system object of espressomd library. + + kT (`pint.Quantity`): + Target temperature in reduced energy units. + + seed (`int`): + Seed for the random number generator for the thermostat. + + time_step (`float`, optional): + Integration time step. Defaults to 1e-2. + + gamma (`float`, optional): + Damping coefficient for the Langevin thermostat. Defaults to 1. + + tune_skin (`bool`, optional): + Whether to optimize the skin parameter. Defaults to True. + + min_skin (`float`, optional): + Minimum skin value for optimization. Defaults to 1. + + max_skin (`float`, optional): + Maximum skin value for optimization. Defaults to None, which is handled by setting its value to box length / 2. + + tolerance (`float`, optional): + Tolerance for skin optimization. Defaults to 1e-3. + + int_steps (`int`, optional): + Number of integration steps for tuning. Defaults to 200. + + adjust_max_skin (`bool`, optional): + Whether to adjust the maximum skin value during tuning. Defaults to True. + """ + if not isinstance(seed, int): + raise TypeError("seed must be an integer.") + if not isinstance(time_step, (float, int)) or time_step <= 0: + raise ValueError("time_step must be a positive number.") + if not isinstance(gamma, (float, int)) or gamma <= 0: + raise ValueError("gamma must be a positive number.") + if max_skin is None: + max_skin=espresso_system.box_l[0]/2 + if min_skin >= max_skin: + raise ValueError("min_skin must be smaller than max_skin.") + espresso_system.time_step=time_step + espresso_system.integrator.set_vv() + espresso_system.thermostat.set_langevin(kT= kT.to('reduced_energy').magnitude, + gamma= gamma, + seed= seed) + # Optimize the value of skin + if tune_skin: + logging.debug("*** Optimizing skin ... ***") + espresso_system.cell_system.tune_skin(min_skin=min_skin, + max_skin=max_skin, + tol=tolerance, + int_steps=int_steps, + adjust_max_skin=adjust_max_skin) + logging.info(f"Optimized skin value: {espresso_system.cell_system.skin}") + + def setup_lj_interactions(self, shift_potential=True, combining_rule='Lorentz-Berthelot'): + """ + Sets up the Lennard-Jones (LJ) potential between all pairs of particle states defined in the pyMBE database. + + Args: + espresso_system('espressomd.system.System'): + Instance of a system object from the espressomd library. + + shift_potential('bool', optional): + If True, a shift will be automatically computed such that the potential is continuous at the cutoff radius. Otherwise, no shift will be applied. Defaults to True. + + combining_rule('string', optional): + combining rule used to calculate 'sigma' and 'epsilon' for the potential between a pair of particles. Defaults to 'Lorentz-Berthelot'. + + warning('bool', optional): + switch to activate/deactivate warning messages. Defaults to True. + + Notes: + - Currently, the only 'combining_rule' supported is Lorentz-Berthelot. + - Check the documentation of ESPResSo for more info about the potential https://espressomd.github.io/doc4.2.0/inter_non-bonded.html + + """ + from itertools import combinations_with_replacement + particle_templates = self.db.get_templates("particle") + shift = "auto" if shift_potential else 0 + if shift == "auto": + shift_tpl = shift + else: + shift_tpl = PintQuantity.from_quantity(q=shift*self.units.reduced_length, + expected_dimension="length", + ureg=self.units) + # Get all particle states registered in pyMBE + state_entries = [] + for tpl in particle_templates.values(): + for state in self.db.get_particle_states_templates(particle_name=tpl.name).values(): + state_entries.append((tpl, state)) + + # Iterate over all unique state pairs + for (tpl1, state1), (tpl2, state2) in combinations_with_replacement(state_entries, 2): + + lj_parameters = self.db.get_lj_parameters(particle_name1=tpl1.name, + particle_name2=tpl2.name, + combining_rule=combining_rule) + if not lj_parameters: + continue + + self.espresso_system.non_bonded_inter[state1.es_type, state2.es_type].lennard_jones.set_params( + epsilon=lj_parameters["epsilon"].to("reduced_energy").magnitude, + sigma=lj_parameters["sigma"].to("reduced_length").magnitude, + cutoff=lj_parameters["cutoff"].to("reduced_length").magnitude, + offset=lj_parameters["offset"].to("reduced_length").magnitude, + shift=shift) + + lj_template = LJInteractionTemplate(state1=state1.name, + state2=state2.name, + sigma=PintQuantity.from_quantity(q=lj_parameters["sigma"], + expected_dimension="length", + ureg=self.units), + epsilon=PintQuantity.from_quantity(q=lj_parameters["epsilon"], + expected_dimension="energy", + ureg=self.units), + cutoff=PintQuantity.from_quantity(q=lj_parameters["cutoff"], + expected_dimension="length", + ureg=self.units), + offset=PintQuantity.from_quantity(q=lj_parameters["offset"], + expected_dimension="length", + ureg=self.units), + shift=shift_tpl) + self.db._register_template(lj_template) def update_particle_id(self, old_pid, new_pid): """ @@ -219,62 +1303,6 @@ def update_particle_id(self, old_pid, new_pid): attribute='particle_id2', value=new_pid) - - - def update_instances_ids_according_to_engine_particles_ids(self): - """ - Method to be called if particles have been previously added to a simulation engine without using pymbe. - """ - - if self.espresso_system == None: - raise ValueError('No simulation engine has been set to pymbe') - - last_id=self._get_last_particle_id_in_espresso() - - if last_id == None: - raise ValueError('This method is intended to be used if particles have been previously added to a simulation engine') - - particle_instances=self.db.get_instances(pmb_type='particle') - for i in range(particle_instances.index.size): - self.db._update_instance(instance_id=i, - pmb_type='particle', - attribute='particle_id', - value=last_id+i) - - bond_instances=self.db.get_instances(pmb_type='bond') - for i in range(bond_instances.index.size): - bond_instance=self.db.get_instance(pmb_type='bond', - instance_id=i) - self.db._update_instance(instance_id=i, - pmb_type='bond', - attribute='particle_id1', - value=last_id+bond_instance.particle_id1) - self.db._update_instance(instance_id=i, - pmb_type='bond', - attribute='particle_id2', - value=last_id+bond_instance.particle_id2) - warnings.warn("""Please review your setup, you have previously added a set of particles to ESPResSo. The particle ids of the pyMBE database have been updated taking into account the id of the last particle from ESPResSo. """ - ) - def add_instance_to_engine(self,pmb_type,instance_id): - - if pmb_type=='particle': - self._add_particle(instance_id) - elif pmb_type=='bond': - - bond_instance=self.db.get_instance(pmb_type='bond', - instance_id=instance_id) - particle_id1=bond_instance.particle_id1 - particle_id2=bond_instance.particle_id2 - self._add_bond(particle_id1,particle_id2,bond_instance) - - elif pmb_type=='residue': - raise TypeError('Use add instances to engine to add particles and bonds not residue instances') - elif pmb_type=='molecule': - raise TypeError('Use add instances to engine to add particles and bonds that correspond to a molecule instance') - elif pmb_type=='protein': - raise TypeError('Use add instances to engine to add particles and bonds not protein instances') - elif pmb_type=='assembly': - raise TypeError('Use add instances to engine to add particles and bonds not assembly instances') def add_instances_to_engine(self): """ @@ -324,3 +1352,4 @@ def add_instances_to_engine(self): bond_instance) return + From 7d8294b4d430ad9b5bbde06b4ac1dc6f510b903c Mon Sep 17 00:00:00 2001 From: jsd94 Date: Sat, 9 May 2026 21:06:54 +0200 Subject: [PATCH 28/75] Add methods that might be useful for any engine: - calculate_center_of_mass -determine_reservoir_concentrations --- pyMBE/simulation_builder/base_engine.py | 131 +++++++++++++++++++++++- 1 file changed, 130 insertions(+), 1 deletion(-) diff --git a/pyMBE/simulation_builder/base_engine.py b/pyMBE/simulation_builder/base_engine.py index 3d43d7d4..f2b84a8c 100644 --- a/pyMBE/simulation_builder/base_engine.py +++ b/pyMBE/simulation_builder/base_engine.py @@ -1,4 +1,5 @@ from abc import ABC,abstractmethod +import numpy as np class SimulationEngine(ABC): def __init__(self): @@ -14,4 +15,132 @@ def _get_bond_instance(self): return @abstractmethod def add_instances_to_engine(self): - return \ No newline at end of file + 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"'). + + espresso_system ('espressomd.system.System'): + ESPResSo system containing the particle instances. + + 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 \ No newline at end of file From 3a04e0a44dcef1f95ad5f0323b218b36f2f68d94 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Sat, 9 May 2026 21:07:39 +0200 Subject: [PATCH 29/75] Add changes in save and load database functions to load and save arrays and lists into the instances dataframe --- pyMBE/storage/io.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pyMBE/storage/io.py b/pyMBE/storage/io.py index 2b42640b..f9ba4066 100644 --- a/pyMBE/storage/io.py +++ b/pyMBE/storage/io.py @@ -273,8 +273,9 @@ def _load_database_csv(db, folder): inst = ParticleInstance(name=row["name"], particle_id=int(row["particle_id"]), initial_state=row["initial_state"], - position=np.array(row["position"]), + position=np.array([row["posx"],row["posy"],row["posz"]],dtype='float64'), added_to_engine=row["added_to_engine"], + fix=[row["fixx"],row["fixy"],row["fixz"]], residue_id=None if residue_val == "" else int(residue_val), molecule_id=None if molecule_val == "" else int(molecule_val), assembly_id=None if assembly_val == "" else int(assembly_val)) @@ -439,8 +440,13 @@ def _save_database_csv(db, folder): "name": inst.name, "particle_id": int(inst.particle_id), "initial_state": inst.initial_state, - "position": inst.position, + "posx": inst.position[0], + "posy": inst.position[1], + "posz": inst.position[2], "added_to_engine":inst.added_to_engine, + "fixx":inst.fix[0], + "fixy":inst.fix[1], + "fixz":inst.fix[2], "residue_id": int(inst.residue_id) if inst.residue_id is not None else "", "molecule_id": int(inst.molecule_id) if inst.molecule_id is not None else "", "assembly_id": int(inst.assembly_id) if inst.assembly_id is not None else ""}) @@ -484,7 +490,7 @@ def _save_database_csv(db, folder): rows.append({"name": getattr(inst, "name", None)}) df = pd.DataFrame(rows) - df.to_csv(os.path.join(folder, f"instances_{pmb_type}.csv"), index=False,float_format="%.17g") + df.to_csv(os.path.join(folder, f"instances_{pmb_type}.csv"), index=False,float_format="%.12f") # REACTIONS rows = [] From d3930feba2368ac12d8876d10e192689d20ba229 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Sat, 9 May 2026 21:08:30 +0200 Subject: [PATCH 30/75] Add methods to manager: -get_label_id_map -get_lj_parameters -get_radius_map -propose_unused_type --- pyMBE/storage/manager.py | 110 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/pyMBE/storage/manager.py b/pyMBE/storage/manager.py index f8af9eb9..d8e09a7d 100644 --- a/pyMBE/storage/manager.py +++ b/pyMBE/storage/manager.py @@ -18,6 +18,8 @@ # import pandas as pd +import numpy as np + from collections import defaultdict from typing import Dict, Any from pyMBE.storage.templates.particle import ParticleTemplate @@ -277,7 +279,27 @@ def _get_instances_df(self, pmb_type): # Generic representation for other types rows.append(inst.dict()) return pd.DataFrame(rows) + + def _get_label_id_map(self, pmb_type): + """ + Returns the key used to access the particle ID map for a given pyMBE object type. + + Args: + pmb_type ('str'): + pyMBE object type for which the particle ID map label is requested. + Returns: + 'str': + Label identifying the appropriate particle ID map. + """ + if pmb_type in self._assembly_like_types: + label="assembly_map" + elif pmb_type in self._molecule_like_types: + label="molecule_map" + else: + label=f"{pmb_type}_map" + return label + def _get_reactions_df(self): """ Returns a DataFrame summarizing all registered chemical reactions. @@ -847,7 +869,78 @@ def get_instances(self, pmb_type): Returns an empty dict if no instances exist for the given type. """ return self._instances.get(pmb_type, {}).copy() + + def get_lj_parameters(self, particle_name1, particle_name2, combining_rule='Lorentz-Berthelot'): + """ + Returns the Lennard-Jones parameters for the interaction between the particle types given by + 'particle_name1' and 'particle_name2' in the pyMBE database, calculated according to the provided combining rule. + + Args: + particle_name1 ('str'): + label of the type of the first particle type + + particle_name2 ('str'): + label of the type of the second particle type + + combining_rule ('string', optional): + combining rule used to calculate 'sigma' and 'epsilon' for the potential betwen a pair of particles. Defaults to 'Lorentz-Berthelot'. + Returns: + ('dict'): + {"epsilon": epsilon_value, "sigma": sigma_value, "offset": offset_value, "cutoff": cutoff_value} + + Notes: + - Currently, the only 'combining_rule' supported is Lorentz-Berthelot. + - If the sigma value of 'particle_name1' or 'particle_name2' is 0, the function will return an empty dictionary. No LJ interactions are set up for particles with sigma = 0. + """ + supported_combining_rules=["Lorentz-Berthelot"] + if combining_rule not in supported_combining_rules: + raise ValueError(f"Combining_rule {combining_rule} currently not implemented in pyMBE, valid keys are {supported_combining_rules}") + part_tpl1 = self.get_template(name=particle_name1, + pmb_type="particle") + part_tpl2 = self.get_template(name=particle_name2, + pmb_type="particle") + lj_parameters1 = part_tpl1.get_lj_parameters(ureg=self._units) + lj_parameters2 = part_tpl2.get_lj_parameters(ureg=self._units) + + # If one of the particle has sigma=0, no LJ interations are set up between that particle type and the others + if part_tpl1.sigma.magnitude == 0 or part_tpl2.sigma.magnitude == 0: + return {} + # Apply combining rule + if combining_rule == 'Lorentz-Berthelot': + sigma=(lj_parameters1["sigma"]+lj_parameters2["sigma"])/2 + cutoff=(lj_parameters1["cutoff"]+lj_parameters2["cutoff"])/2 + offset=(lj_parameters1["offset"]+lj_parameters2["offset"])/2 + epsilon=np.sqrt(lj_parameters1["epsilon"]*lj_parameters2["epsilon"]) + return {"sigma": sigma, "cutoff": cutoff, "offset": offset, "epsilon": epsilon} + + def get_radius_map(self, dimensionless=True): + """ + Gets the effective radius of each particle defined in the pyMBE database. + + Args: + dimensionless ('bool'): + If ``True``, return magnitudes expressed in ``reduced_length``. + If ``False``, return Pint quantities with units. + + Returns: + ('dict'): + {espresso_type: radius}. + + Notes: + - The radius corresponds to (sigma+offset)/2 + """ + if "particle" not in self._templates: + return {} + result = {} + for _, tpl in self._templates["particle"].items(): + radius = (tpl.sigma.to_quantity(self._units) + tpl.offset.to_quantity(self._units))/2.0 + if dimensionless: + magnitude_reduced_length = radius.m_as("reduced_length") + radius = magnitude_reduced_length + for state in self.get_particle_states_templates(particle_name=tpl.name).values(): + result[state.es_type] = radius + return result def get_reaction(self, name): """ Retrieve a reaction stored in the pyMBE database by name. @@ -1072,5 +1165,22 @@ def get_particle_states_templates(self, particle_name): particle_states = {state.name: state for state in states.values() if state.particle_name == particle_name} return particle_states + def propose_unused_type(self): + """ + Propose an unused ESPResSo particle type. + + Returns: + ('int'): + The next available integer ESPResSo type. Returns ''0'' if no integer types are currently defined. + """ + type_map = self.get_es_types_map() + # Flatten all es_type values across all particles and states + all_types = [] + for es_type in type_map.values(): + all_types.append(es_type) + # If no es_types exist, start at 0 + if not all_types: + return 0 + return max(all_types) + 1 From 322bf3b239df300eb5e5c02cf0a0f3e32e75a1b9 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Sat, 9 May 2026 21:09:24 +0200 Subject: [PATCH 31/75] Add changes: -use attribute simulation engine to call change_volume_and_rescale_particles --- testsuite/create_molecule_position_test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testsuite/create_molecule_position_test.py b/testsuite/create_molecule_position_test.py index 208b28f4..d278049c 100644 --- a/testsuite/create_molecule_position_test.py +++ b/testsuite/create_molecule_position_test.py @@ -129,9 +129,8 @@ def test_center_molecule_in_simulation_box(self): center_of_mass = pmb.calculate_center_of_mass(instance_id=molecule_ids[0], pmb_type="molecule") + ### The method is decoupled from espresso and the center of mass can be calculated without using any simulation engine - pmb.add_instances_to_engine() - center_of_mass_ref = [L/2]*3 for ind in range(len(center_of_mass)): @@ -141,7 +140,8 @@ def test_center_molecule_in_simulation_box(self): ### New implementation in order to avoid using espresso # espresso_system.change_volume_and_rescale_particles(d_new=3*L, dir="z") - pmb.change_volume_and_rescale_particles(d_new=3*L, dir="z") + pmb.simulation_engine.change_volume_and_rescale_particles(d_new=3*L, dir="z") + new_box_l=[box_l[0],box_l[1],3*L] pmb.center_object_in_simulation_box(instance_id=molecule_ids[2], pmb_type="molecule", From 6aab5d1b5c4a12e2d3569e99c8415e9ddd0e37c9 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Sat, 9 May 2026 21:09:35 +0200 Subject: [PATCH 32/75] Add comment --- testsuite/define_and_create_molecules_unit_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/define_and_create_molecules_unit_tests.py b/testsuite/define_and_create_molecules_unit_tests.py index 5d1185f5..7e01a6c0 100644 --- a/testsuite/define_and_create_molecules_unit_tests.py +++ b/testsuite/define_and_create_molecules_unit_tests.py @@ -421,7 +421,7 @@ def test_create_and_delete_particles(self): number_of_molecules=-1, box_l=box_l, use_default_bond=True) - pmb.add_instances_to_engine() + ### No particle instances are added thus no need to add them to the engine # If no particles have been created, only two particles should be in the system (from the previous test) self.assertEqual(first=len(espresso_system.part.all()), second=starting_number_of_particles) From 685a26e4592974b02ea6ac0e2d36943e9e90bb02 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Sat, 9 May 2026 21:10:16 +0200 Subject: [PATCH 33/75] set the simulation engine in order to use the pmb method to determine reservoir concentrations --- .../determine_reservoir_concentrations_unit_test.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/testsuite/determine_reservoir_concentrations_unit_test.py b/testsuite/determine_reservoir_concentrations_unit_test.py index 87d1909f..0ffbea67 100644 --- a/testsuite/determine_reservoir_concentrations_unit_test.py +++ b/testsuite/determine_reservoir_concentrations_unit_test.py @@ -20,13 +20,18 @@ import pyMBE import numpy as np import pandas as pd +import espressomd from scipy import interpolate +pmb = pyMBE.pymbe_library(seed=42) +Box_L = 7.5*pmb.units.nm +box_l=[Box_L.to('reduced_length').magnitude]*3 +espresso_system = espressomd.System(box_l = box_l) +pmb.set_simulation_engine(espresso_system) def determine_reservoir_concentrations_test_ideal(pH_res, c_salt_res): # Create an instance of the pyMBE library - pmb = pyMBE.pymbe_library(seed=42) - + # Determine the reservoir composition using pyMBE cH_res_pyMBE, cOH_res_pyMBE, cNa_res_pyMBE, cCl_res_pyMBE = pmb.determine_reservoir_concentrations( pH_res, @@ -49,8 +54,7 @@ def determine_reservoir_concentrations_test_ideal(pH_res, c_salt_res): def determine_reservoir_concentrations_test_interacting(pH_res, c_salt_res, reference_data): # Create an instance of the pyMBE library - pmb = pyMBE.pymbe_library(seed=42) - + # Load the excess chemical potential data monovalent_salt_ref_data=pd.read_csv(pmb.root / "parameters" / "salt" / "excess_chemical_potential_excess_pressure.csv") ionic_strength = pmb.units.Quantity(monovalent_salt_ref_data["cs_bulk_[1/sigma^3]"].values, "1/reduced_length**3") From 5533abb68fbc026883fbd392fd5bc7f513182d5f Mon Sep 17 00:00:00 2001 From: jsd94 Date: Sat, 9 May 2026 21:11:34 +0200 Subject: [PATCH 34/75] set simulation engine before executing the tests --- testsuite/globular_protein_unit_tests.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/testsuite/globular_protein_unit_tests.py b/testsuite/globular_protein_unit_tests.py index 23af38a7..be130734 100644 --- a/testsuite/globular_protein_unit_tests.py +++ b/testsuite/globular_protein_unit_tests.py @@ -28,6 +28,10 @@ # Create an instance of pyMBE library pmb = pyMBE.pymbe_library(seed=42) +Box_L = 100 * pmb.units.reduced_length +box_l=[Box_L.to('reduced_length').magnitude] * 3 +espresso_system=espressomd.System(box_l = box_l) +pmb.set_simulation_engine(espresso_system) protein_pdb = '1f6s' path_to_parfile = pathlib.Path(__file__).parent / "tests_data" / "protein_topology_dict.json" path_to_cg=pmb.root / "parameters" / "globular_proteins" / f"{protein_pdb}.vtf" @@ -44,7 +48,7 @@ def test_protein_setup(self): """ Unit tests for setting up globular proteins in pyMBE. """ - Box_L = 100 * pmb.units.reduced_length + def custom_deserializer(dct): if "value" in dct and "unit" in dct: return pmb.units.Quantity(dct["value"], dct["unit"]) @@ -102,9 +106,9 @@ def custom_deserializer(dct): np.testing.assert_raises(ValueError, pmb.define_protein, **input_parameters) - box_l=[Box_L.to('reduced_length').magnitude] * 3 - espresso_system=espressomd.System(box_l = box_l) - pmb.set_simulation_engine(espresso_system) + + + with self.assertRaises(ValueError): pmb.create_protein(name="missing_protein_template", @@ -166,7 +170,7 @@ def custom_deserializer(dct): number_of_proteins=-1, box_l=box_l, topology_dict=topology_dict) - pmb.add_instances_to_engine() + ### No particles instances are created, thus it is not needed to call add_instances_to_engine np.testing.assert_equal(actual=len(espresso_system.part.all()), desired=starting_number_of_particles, verbose=True) @@ -174,7 +178,6 @@ def custom_deserializer(dct): for pid in particle_id_list: positions.append(espresso_system.part.by_id(pid).pos) pmb.enable_motion_of_rigid_object(instance_id=molecule_id, - espresso_system=espresso_system, pmb_type="protein") momI = 0 From fc6fa7d54be5a269f55b22c358675c041d3ec5a0 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Sat, 9 May 2026 21:12:08 +0200 Subject: [PATCH 35/75] Set simulation engine before executing the tests remove espresso system from setup_lj interactions --- testsuite/lj_tests.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/testsuite/lj_tests.py b/testsuite/lj_tests.py index 35f89e62..138b3ced 100644 --- a/testsuite/lj_tests.py +++ b/testsuite/lj_tests.py @@ -24,8 +24,10 @@ # Create an instance of pyMBE library pmb = pyMBE.pymbe_library(seed=42) import espressomd -espresso_system=espressomd.System(box_l = [50]*3) +box_l=[50]*3 +espresso_system=espressomd.System(box_l = box_l) +pmb.set_simulation_engine(espresso_system,box_l) class Test(ut.TestCase): @@ -124,7 +126,7 @@ def test_lj_interaction_setup(self): pmb.define_particle(**B_input_parameters) pmb.define_particle(**C_input_parameters) # Setup LJ interactions shift="auto" - pmb.setup_lj_interactions(espresso_system=espresso_system) + pmb.setup_lj_interactions() # Check A-A LJ setup lj_templates = pmb.db.get_templates(pmb_type="lj") # Check B-B, B-BH, BH-BH setup @@ -144,10 +146,10 @@ def test_lj_interaction_setup(self): # Clean LJ interactions pmb.db.delete_templates(pmb_type="lj") # ValueError if combining-rule other than Lorentz_-Berthelot is used - input_params = {"espresso_system":espresso_system, "combining_rule": "Geometric"} + input_params = { "combining_rule": "Geometric"} self.assertRaises(ValueError, pmb.setup_lj_interactions, **input_params) # Check initialization with shift=0 - pmb.setup_lj_interactions(espresso_system=espresso_system, shift_potential=False) + pmb.setup_lj_interactions( shift_potential=False) # Calculate the reference parameters using Lorentz-Berthelot combining rule # Check A-BH, A-B, setup labels=["A-BH", "A-B"] From 282d21574abf638bf42109d173177ff50f8b41bc Mon Sep 17 00:00:00 2001 From: jsd94 Date: Sat, 9 May 2026 21:13:11 +0200 Subject: [PATCH 36/75] Add simulation engine in both tests --- testsuite/reaction_methods_unit_tests.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/testsuite/reaction_methods_unit_tests.py b/testsuite/reaction_methods_unit_tests.py index e5732714..1df6d77d 100644 --- a/testsuite/reaction_methods_unit_tests.py +++ b/testsuite/reaction_methods_unit_tests.py @@ -29,7 +29,8 @@ def reaction_method_test_template(parameters): # Create an instance of the pyMBE library pmb = pyMBE.pymbe_library(seed=42) - + pmb.set_simulation_engine(espresso_system) + if parameters["method"] in ["cpH", "grxmc", "grxmc_unified"]: # Define the acidic particle pmb.define_particle( @@ -377,7 +378,8 @@ def test_mixed_setup(self): "salt_cation_name": "Na", "salt_anion_name": "Cl", "activity_coefficient": lambda x: 1.0} - + + pmb.set_simulation_engine(espresso_system) # Add the reactions using pyMBE pmb.setup_gcmc(**input_parameters) pmb.setup_cpH(counter_ion="Na", From 919afbf3e14b896cc2e0d693aefcae7ac3efd3e5 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Sat, 9 May 2026 21:14:32 +0200 Subject: [PATCH 37/75] Add simulation engine before executing the handy functions as now they are migrated to espresso_engine class --- testsuite/test_handy_functions.py | 48 ++++++++++++++++--------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/testsuite/test_handy_functions.py b/testsuite/test_handy_functions.py index 61ad4fce..54ab48bb 100644 --- a/testsuite/test_handy_functions.py +++ b/testsuite/test_handy_functions.py @@ -22,7 +22,6 @@ import espressomd import espressomd.version import pyMBE -import pyMBE.lib.handy_functions as hf import logging import io import re @@ -34,9 +33,11 @@ handlers=[logging.StreamHandler(log_stream)] ) # Create instances of espresso and pyMBE -espresso_system = espressomd.System(box_l=[60,60,60]) +box_l=[60,60,60] +espresso_system = espressomd.System(box_l=box_l) seed = 23 pmb = pyMBE.pymbe_library(seed=seed) +pmb.set_simulation_engine(espresso_system) kT = pmb.kT langevin_inputs={"espresso_system":espresso_system, @@ -68,6 +69,7 @@ "accuracy":1e-3, "verbose":False} +#### To import handy_functions is no longer needed as the methods employed in this tests now they belong to the simulation_engine class Test(ut.TestCase): @@ -83,21 +85,21 @@ def test_exceptions_langevin_setup(self): """Test exceptions in :func:`lib.handy_functions.setup_langevin_dynamics`""" broken_inputs = langevin_inputs.copy() broken_inputs["seed"] = "pyMBE" - self.assertRaises(TypeError, hf.setup_langevin_dynamics, **broken_inputs) + self.assertRaises(TypeError, pmb.simulation_engine.setup_langevin_dynamics, **broken_inputs) broken_inputs = langevin_inputs.copy() broken_inputs["time_step"] = -1 - self.assertRaises(ValueError, hf.setup_langevin_dynamics, **broken_inputs) + self.assertRaises(ValueError, pmb.simulation_engine.setup_langevin_dynamics, **broken_inputs) broken_inputs = langevin_inputs.copy() broken_inputs["gamma"] = -1 - self.assertRaises(ValueError, hf.setup_langevin_dynamics, **broken_inputs) + self.assertRaises(ValueError, pmb.simulation_engine.setup_langevin_dynamics, **broken_inputs) broken_inputs = langevin_inputs.copy() broken_inputs["min_skin"] = 10 broken_inputs["max_skin"] = 1 - self.assertRaises(ValueError, hf.setup_langevin_dynamics, **broken_inputs) + self.assertRaises(ValueError, pmb.simulation_engine.setup_langevin_dynamics, **broken_inputs) def test_langevin_setup(self): """Test :func:`lib.handy_functions.setup_langevin_dynamics`""" - hf.setup_langevin_dynamics(**langevin_inputs) + pmb.simulation_engine.setup_langevin_dynamics(**langevin_inputs) ## Test setup of the integrator self.assertEqual(first=langevin_inputs["time_step"], second=espresso_system.time_step, @@ -130,7 +132,7 @@ def test_langevin_setup(self): epsilon = 1, sigma = 1, cutoff = 3, shift = "auto") langevin_inputs_opt_skin = langevin_inputs.copy() langevin_inputs_opt_skin["tune_skin"] = True - hf.setup_langevin_dynamics(**langevin_inputs_opt_skin) + pmb.simulation_engine.setup_langevin_dynamics(**langevin_inputs_opt_skin) log_contents = log_stream.getvalue() optimized_skin = float(re.search(r"Optimized skin value: ([\d.]+)", log_contents).group(1)) self.assertEqual(first=optimized_skin, @@ -141,16 +143,16 @@ def test_exceptions_relax_espresso_system(self): """Test exceptions in :func:`lib.handy_functions.relax_espresso_system`""" broken_inputs = relax_inputs.copy() broken_inputs["gamma"] = -1 - self.assertRaises(ValueError, hf.relax_espresso_system, **broken_inputs) + self.assertRaises(ValueError, pmb.simulation_engine.relax_espresso_system, **broken_inputs) broken_inputs = relax_inputs.copy() broken_inputs["Nsteps_steepest_descent"] = -1 - self.assertRaises(ValueError, hf.relax_espresso_system, **broken_inputs) + self.assertRaises(ValueError, pmb.simulation_engine.relax_espresso_system, **broken_inputs) broken_inputs = relax_inputs.copy() broken_inputs["Nsteps_iter_relax"] = -1 - self.assertRaises(ValueError, hf.relax_espresso_system, **broken_inputs) + self.assertRaises(ValueError, pmb.simulation_engine.relax_espresso_system, **broken_inputs) broken_inputs = relax_inputs.copy() broken_inputs["max_displacement"] = -1 - self.assertRaises(ValueError, hf.relax_espresso_system, **broken_inputs) + self.assertRaises(ValueError, pmb.simulation_engine.relax_espresso_system, **broken_inputs) broken_inputs = relax_inputs.copy() def test_relax_espresso_system(self): @@ -165,7 +167,7 @@ def test_relax_espresso_system(self): espresso_system.part.add(pos=pos) espresso_system.non_bonded_inter[0,0].lennard_jones.set_params( epsilon = 1, sigma = 1, cutoff = 2**(1./6.), shift = "auto") - min_dist = hf.relax_espresso_system(**relax_inputs) + min_dist = pmb.simulation_engine.relax_espresso_system(**relax_inputs) self.assertGreater(a=min_dist, b=0.9, msg="lib.handy_functions.relax_espresso_system is unable to relax a simple lj system") @@ -176,7 +178,7 @@ def test_relax_espresso_system(self): test_inputs = relax_inputs.copy() test_inputs["Nsteps_steepest_descent"] = 1 test_inputs["max_displacement"] = 0 - hf.relax_espresso_system(**relax_inputs) + pmb.simulation_engine.relax_espresso_system(**relax_inputs) new_positions = espresso_system.part.all().pos distances = np.linalg.norm(np.array(positions) - new_positions, axis=1) @@ -190,16 +192,16 @@ def test_exceptions_electrostatics(self): """Test exceptions in :func:`lib.handy_functions.setup_electrostatic_interactions`""" broken_inputs = electrostatics_inputs.copy() broken_inputs["units"] = "pyMBE" - self.assertRaises(TypeError, hf.setup_electrostatic_interactions, **broken_inputs) + self.assertRaises(TypeError, pmb.simulation_engine.setup_electrostatic_interactions, **broken_inputs) broken_inputs = electrostatics_inputs.copy() broken_inputs["method"] = "dH" - self.assertRaises(ValueError, hf.setup_electrostatic_interactions, **broken_inputs) + self.assertRaises(ValueError, pmb.simulation_engine.setup_electrostatic_interactions, **broken_inputs) broken_inputs = electrostatics_inputs.copy() broken_inputs["method"] = "dh" - self.assertRaises(ValueError, hf.setup_electrostatic_interactions, **broken_inputs) + self.assertRaises(ValueError, pmb.simulation_engine.setup_electrostatic_interactions, **broken_inputs) broken_inputs = electrostatics_inputs.copy() broken_inputs["c_salt"] = 10*pmb.units.nm - self.assertRaises(ValueError, hf.setup_electrostatic_interactions, **broken_inputs) + self.assertRaises(ValueError, pmb.simulation_engine.setup_electrostatic_interactions, **broken_inputs) def test_setup_electrostatics(self): """Test :func:`lib.handy_functions.setup_electrostatic_interactions`""" @@ -208,7 +210,7 @@ def test_setup_electrostatics(self): Bjerrum_length = pmb.e.to('reduced_charge')**2 / (4 * pmb.units.pi * pmb.units.eps0 * electrostatics_inputs["solvent_permittivity"] * electrostatics_inputs["kT"].to('reduced_energy')) coulomb_prefactor=Bjerrum_length*electrostatics_inputs["kT"] # Test the P3M setup - hf.setup_electrostatic_interactions(**electrostatics_inputs) + pmb.simulation_engine.setup_electrostatic_interactions(**electrostatics_inputs) if espressomd.version.friendly() == "4.2": coulomb = espresso_system.actors.active_actors.copy()[0] else: @@ -236,7 +238,7 @@ def test_setup_electrostatics(self): "cao": 5, "alpha": 1.1265e+01, "r_cut": 1} - hf.setup_electrostatic_interactions(**electrostatics_inputs) + pmb.simulation_engine.setup_electrostatic_interactions(**electrostatics_inputs) if espressomd.version.friendly() == "4.2": coulomb = espresso_system.actors.active_actors.copy()[0] else: @@ -256,7 +258,7 @@ def test_setup_electrostatics(self): electrostatics_inputs["method"] = "dh" electrostatics_inputs["c_salt"] = pmb.units.Quantity(1, "mol/L") kappa=1./np.sqrt(8*pmb.units.pi*Bjerrum_length*pmb.N_A*electrostatics_inputs["c_salt"]) - hf.setup_electrostatic_interactions(**electrostatics_inputs) + pmb.simulation_engine.setup_electrostatic_interactions(**electrostatics_inputs) if espressomd.version.friendly() == "4.2": dh = espresso_system.actors.active_actors.copy()[0] else: @@ -279,7 +281,7 @@ def test_setup_electrostatics(self): else: coulomb = espresso_system.electrostatics.solver = None electrostatics_inputs["c_salt"] = pmb.units.Quantity(1, "mol/L")*pmb.N_A - hf.setup_electrostatic_interactions(**electrostatics_inputs) + pmb.simulation_engine.setup_electrostatic_interactions(**electrostatics_inputs) if espressomd.version.friendly() == "4.2": dh = espresso_system.actors.active_actors.copy()[0] else: @@ -297,7 +299,7 @@ def test_setup_electrostatics(self): coulomb = espresso_system.electrostatics.solver = None # Test a non-default cut-off electrostatics_inputs["params"] = {"r_cut": 3} - hf.setup_electrostatic_interactions(**electrostatics_inputs) + pmb.simulation_engine.setup_electrostatic_interactions(**electrostatics_inputs) if espressomd.version.friendly() == "4.2": dh = espresso_system.actors.active_actors.copy()[0] else: From 64811b75ddb23fd399398b5ae53e372dcbac3cd1 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Sat, 9 May 2026 21:16:17 +0200 Subject: [PATCH 38/75] Modify method to test column positions from the dataframe as it contains a numpy array that contains arrays. Thus, the approach that has worked is to loop through the array and compare them element by element --- testsuite/test_io_database.py | 42 ++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/testsuite/test_io_database.py b/testsuite/test_io_database.py index cf4d4d21..48be8876 100644 --- a/testsuite/test_io_database.py +++ b/testsuite/test_io_database.py @@ -30,6 +30,7 @@ from pyMBE.storage.instances.bond import BondInstance from pathlib import Path import csv +import numpy as np box_l=[100]*3 espresso_system=espressomd.System (box_l = box_l) @@ -256,7 +257,8 @@ def test_io_lj_templates(self): offset=0 * units.reduced_length, epsilon=0.2 * units.reduced_energy, z=1) - pmb.setup_lj_interactions(espresso_system=espresso_system) + pmb.set_simulation_engine(espresso_system) + pmb.setup_lj_interactions() new_pmb = pyMBE.pymbe_library(23) with tempfile.TemporaryDirectory() as tmp_directory: # Save and load the database @@ -505,8 +507,15 @@ def test_io_instances(self): new_pmb.get_instances_df(pmb_type="residues")) pd.testing.assert_frame_equal(pmb.get_instances_df(pmb_type="bond"), new_pmb.get_instances_df(pmb_type="bond")) - pd.testing.assert_frame_equal(pmb.get_instances_df(pmb_type="particle"), - new_pmb.get_instances_df(pmb_type="particle")) + instances_before=pmb.get_instances_df(pmb_type="particle").copy() + positions_before=instances_before['position'].to_numpy() + instances_after=new_pmb.get_instances_df(pmb_type="particle").copy() + positions_after=instances_after['position'].to_numpy() + pd.testing.assert_frame_equal(instances_before.drop(columns=['position']), + instances_after.drop(columns=['position'])) + for i in range(len(positions_after)): + self.assertTrue(np.allclose(positions_after[i],positions_before[i],atol=1e-12)) + # Clean up before the next test pmb.delete_instances_in_system( instance_id=assembly_id, @@ -515,7 +524,8 @@ def test_io_instances(self): path_to_interactions=pmb.root / "parameters" / "peptides" / "Lunkad2021" path_to_pka=pmb.root / "parameters" / "pka_sets" / "Hass2015.json" ### pmb.load_database(folder): Returns metadata, but not used ? - pmb.load_database (folder=path_to_interactions) # Defines particles load_pka_set(filename=path_to_pka) + pmb.load_database (folder=path_to_interactions) # Defines particles + pmb.load_pka_set(filename=path_to_pka) pka_set = pmb.get_pka_set() for particle_name in pka_set.keys(): pmb.define_monoprototic_particle_states(particle_name=particle_name, @@ -531,6 +541,7 @@ def test_io_instances(self): pmb.define_peptide(name="Peptide1", model="1beadAA", sequence="KKKKDDDD") + pep_ids = pmb.create_molecule(name="Peptide1", number_of_molecules=2, box_l=box_l, ###set box_l @@ -551,8 +562,16 @@ def test_io_instances(self): new_pmb.get_instances_df(pmb_type="residues")) pd.testing.assert_frame_equal(pmb.get_instances_df(pmb_type="bond"), new_pmb.get_instances_df(pmb_type="bond")) - pd.testing.assert_frame_equal(pmb.get_instances_df(pmb_type="particle"), - new_pmb.get_instances_df(pmb_type="particle")) + + instances_before=pmb.get_instances_df(pmb_type="particle") + positions_before=instances_before['position'].to_numpy() + instances_after=new_pmb.get_instances_df(pmb_type="particle") + positions_after=instances_after['position'].to_numpy() + + pd.testing.assert_frame_equal(instances_before.drop(columns=['position']), + instances_after.drop(columns=['position'])) + for i in range(len(positions_after)): + self.assertTrue(np.allclose(positions_after[i],positions_before[i],atol=1e-12)) # Clean up before the next test for pepid in pep_ids: pmb.delete_instances_in_system( @@ -596,8 +615,15 @@ def test_io_instances(self): new_pmb.get_instances_df(pmb_type="residues")) pd.testing.assert_frame_equal(pmb.get_instances_df(pmb_type="bond"), new_pmb.get_instances_df(pmb_type="bond")) - pd.testing.assert_frame_equal(pmb.get_instances_df(pmb_type="particle"), - new_pmb.get_instances_df(pmb_type="particle")) + instances_before=pmb.get_instances_df(pmb_type="particle") + positions_before=instances_before['position'].to_numpy() + instances_after=new_pmb.get_instances_df(pmb_type="particle") + positions_after=instances_after['position'].to_numpy() + pd.testing.assert_frame_equal(instances_before.drop(columns=['position']), + instances_after.drop(columns=['position'])) + + for i in range(len(positions_after)): + self.assertTrue(np.allclose(positions_after[i],positions_before[i],atol=1e-12)) # Clean up for protid in prot_ids: pmb.delete_instances_in_system( From 7df17500f562395de9f8afebd2901571a46ec2e4 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Mon, 11 May 2026 23:10:36 +0200 Subject: [PATCH 39/75] Adapt sample file to current version decoupling espresso --- samples/branched_polyampholyte.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/samples/branched_polyampholyte.py b/samples/branched_polyampholyte.py index a6064e3c..032b3fc7 100644 --- a/samples/branched_polyampholyte.py +++ b/samples/branched_polyampholyte.py @@ -32,6 +32,7 @@ from pyMBE.lib.handy_functions import do_reaction from pyMBE.lib.analysis import built_output_name + # Create an instance of pyMBE library pmb = pyMBE.pymbe_library(seed=42) @@ -175,6 +176,8 @@ print(f"The box length of your system is {L.to('reduced_length')}, {L.to('nm')}") print(f"The polyampholyte concentration in your system is {calculated_polyampholyte_concentration.to('mol/L')} with {N_polyampholyte_chains} molecules") +pmb.set_simulation_engine(espresso_system) + cpH = pmb.setup_cpH(counter_ion=cation_name, constant_pH=pH_value) if verbose: print("The acid-base reaction has been successfully set up for:") @@ -191,32 +194,31 @@ if verbose: print(f"The non interacting type is set to {non_interacting_type}") -pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() if not ideal: ##Setup the potential energy if verbose: print('Setup LJ interaction (this can take a few seconds)') - pmb.setup_lj_interactions (espresso_system=espresso_system) + pmb.setup_lj_interactions() if verbose: print('Minimize energy before adding electrostatics') - relax_espresso_system(espresso_system=espresso_system, + pmb.simulation_engine.relax_espresso_system( seed=langevin_seed) if verbose: print('Setup and tune electrostatics (this can take a few seconds)') - setup_electrostatic_interactions(units=pmb.units, - espresso_system=espresso_system, + pmb.simulation_engine.setup_electrostatic_interactions(units=pmb.units, kT=pmb.kT) if verbose: print('Minimize energy after adding electrostatics') - relax_espresso_system(espresso_system=espresso_system, + pmb.simulation_engine.relax_espresso_system( seed=langevin_seed) #Setup Langevin -setup_langevin_dynamics(espresso_system=espresso_system, +pmb.simulation_engine.setup_langevin_dynamics( kT = pmb.kT, seed = langevin_seed, time_step=dt, @@ -235,9 +237,9 @@ N_frame=0 for step in tqdm.trange(N_samples): espresso_system.integrator.run(steps=MD_steps_per_sample) - do_reaction(cpH, steps=total_ionisable_groups) + pmb.simulation_engine.do_reaction(cpH, steps=total_ionisable_groups) # Get polyampholyte net charge - charge_dict=pmb.calculate_net_charge(espresso_system=espresso_system, + charge_dict=pmb.calculate_net_charge( object_name="polyampholyte", pmb_type="molecule", dimensionless=True) From 2348bb464753a788075f14d5af2087f38beda66a Mon Sep 17 00:00:00 2001 From: jsd94 Date: Mon, 11 May 2026 23:11:19 +0200 Subject: [PATCH 40/75] Adapt current sample files towards decoupling espresso --- samples/Beyer2024/globular_protein.py | 29 +++++++++---------- samples/Beyer2024/peptide.py | 25 ++++++++-------- .../weak_polyelectrolyte_dialysis.py | 25 +++++++++------- samples/peptide_cpH.py | 13 ++++----- samples/peptide_mixture_grxmc_ideal.py | 28 ++++++++++-------- 5 files changed, 62 insertions(+), 58 deletions(-) diff --git a/samples/Beyer2024/globular_protein.py b/samples/Beyer2024/globular_protein.py index f1adcef0..6cbbaf63 100644 --- a/samples/Beyer2024/globular_protein.py +++ b/samples/Beyer2024/globular_protein.py @@ -130,8 +130,8 @@ # The trajectories of the simulations will be stored using espresso built-up functions in separed files in the folder 'frames' frames_path = args.output / "frames" frames_path.mkdir(parents=True, exist_ok=True) - -espresso_system = espressomd.System(box_l=[Box_L.to('reduced_length').magnitude] * 3) +box_l=[Box_L.to('reduced_length').magnitude] * 3 +espresso_system = espressomd.System(box_l=box_l) espresso_system.time_step=dt espresso_system.cell_system.skin=0.4 #Reads the VTF file of the protein model @@ -178,18 +178,16 @@ #We create the protein in espresso protein_id = pmb.create_protein(name=protein_name, number_of_proteins=1, - espresso_system=espresso_system, + box_l=box_l, topology_dict=topology_dict)[0] #Here we activate the motion of the protein if args.move_protein: pmb.enable_motion_of_rigid_object(instance_id=protein_id, - pmb_type="protein", - espresso_system=espresso_system) + pmb_type="protein") # Here we put the protein on the center of the simulation box pmb.center_object_in_simulation_box(instance_id=protein_id, - pmb_type="protein", - espresso_system=espresso_system) + pmb_type="protein") if not args.ideal: # Estimate the radius of the protein @@ -218,7 +216,7 @@ counter_ion_name=cation_name pmb.create_particle(name=counter_ion_name, - espresso_system=espresso_system, + box_l=box_l, number_of_particles=int(abs(protein_net_charge)), position=counter_ion_coords) @@ -232,12 +230,12 @@ n_samples=N_ions*2) ## Create cations pmb.create_particle(name=cation_name, - espresso_system=espresso_system, + box_l=box_l, number_of_particles=N_ions, position=added_salt_ions_coords[:N_ions]) ## Create anions pmb.create_particle(name=anion_name, - espresso_system=espresso_system, + box_l=box_l, number_of_particles=N_ions, position=added_salt_ions_coords[N_ions:]) @@ -282,15 +280,14 @@ # Setup the potential energy if WCA: - pmb.setup_lj_interactions(espresso_system=espresso_system) - relax_espresso_system(espresso_system=espresso_system, + pmb.setup_lj_interactions() + relax_espresso_system( seed=langevin_seed) if Electrostatics: setup_electrostatic_interactions(units=pmb.units, - espresso_system=espresso_system, kT=pmb.kT) -setup_langevin_dynamics(espresso_system=espresso_system, +setup_langevin_dynamics( kT = pmb.kT, seed = langevin_seed) @@ -319,7 +316,7 @@ for step in tqdm.trange(N_samples, disable=not verbose): espresso_system.integrator.run (steps = integ_steps) do_reaction(cpH, steps=total_ionisable_groups) - protein_net_charge = pmb.calculate_net_charge(espresso_system=espresso_system, + protein_net_charge = pmb.calculate_net_charge( object_name=protein_name, pmb_type="protein", dimensionless=True)["mean"] @@ -329,7 +326,7 @@ charge_residues_per_type = {} for label in AA_label_list: charge_residues_per_type[label]=[] - charge_res=pmb.calculate_net_charge (espresso_system=espresso_system, + charge_res=pmb.calculate_net_charge ( object_name=label, pmb_type="residue", dimensionless=True)["mean"] diff --git a/samples/Beyer2024/peptide.py b/samples/Beyer2024/peptide.py index 6dd1c8fd..9a34a39f 100644 --- a/samples/Beyer2024/peptide.py +++ b/samples/Beyer2024/peptide.py @@ -151,7 +151,8 @@ L = volume ** (1./3.) # Side of the simulation box # Create an instance of an espresso system -espresso_system=espressomd.System (box_l = [L.to('reduced_length').magnitude]*3) +box_l=[L.to('reduced_length').magnitude]*3 +espresso_system=espressomd.System (box_l = box_l) espresso_system.time_step=dt espresso_system.cell_system.skin=0.4 @@ -159,17 +160,18 @@ # Create your molecules into the espresso system pmb.create_molecule(name=sequence, number_of_molecules=N_peptide_chains, - espresso_system=espresso_system) + box_l=box_l) # Create counterions for the peptide chains pmb.create_counterions(object_name=sequence, cation_name=cation_name, anion_name=anion_name, - espresso_system=espresso_system) + box_l=box_l) -c_salt_calculated = pmb.create_added_salt(espresso_system=espresso_system, +c_salt_calculated = pmb.create_added_salt( cation_name=cation_name, anion_name=anion_name, - c_salt=c_salt) + c_salt=c_salt, + box_l=box_l) cpH = pmb.setup_cpH(counter_ion=cation_name, constant_pH=pH) @@ -190,18 +192,17 @@ print(f"The non-interacting type is set to {non_interacting_type}") #Setup the potential energy -pmb.setup_lj_interactions (espresso_system=espresso_system) -hf.relax_espresso_system(espresso_system=espresso_system, +pmb.setup_lj_interactions () +pmb.simulation_engine.relax_espresso_system( seed=langevin_seed) -hf.setup_electrostatic_interactions(units=pmb.units, - espresso_system=espresso_system, +pmb.simulation_engine.setup_electrostatic_interactions(units=pmb.units, kT=pmb.kT, verbose=verbose) -hf.relax_espresso_system(espresso_system=espresso_system, +pmb.simulation_engine.relax_espresso_system( seed=langevin_seed) -hf.setup_langevin_dynamics(espresso_system=espresso_system, +pmb.simulation_engine.setup_langevin_dynamics( kT = pmb.kT, seed = langevin_seed, time_step=dt, @@ -223,7 +224,7 @@ # Run MC do_reaction(cpH, steps=len(sequence)) # Sample observables - charge_dict=pmb.calculate_net_charge(espresso_system=espresso_system, + charge_dict=pmb.calculate_net_charge( object_name=sequence, pmb_type="peptide", dimensionless=True) diff --git a/samples/Beyer2024/weak_polyelectrolyte_dialysis.py b/samples/Beyer2024/weak_polyelectrolyte_dialysis.py index 71dc2012..0c88fff7 100644 --- a/samples/Beyer2024/weak_polyelectrolyte_dialysis.py +++ b/samples/Beyer2024/weak_polyelectrolyte_dialysis.py @@ -170,22 +170,25 @@ ####################################################### # Create an instance of an espresso system -espresso_system = espressomd.System(box_l = [L.to('reduced_length').magnitude]*3) +box_l=[L.to('reduced_length').magnitude]*3 +espresso_system = espressomd.System(box_l =box_l ) espresso_system.time_step=dt espresso_system.cell_system.skin=0.4 # Create molecules and ions in the espresso system pmb.create_molecule(name=polyacid_name, number_of_molecules=N_chains, - espresso_system=espresso_system) + box_l=box_l) pmb.create_counterions(object_name=polyacid_name, cation_name=proton_name, anion_name=hydroxide_name, - espresso_system=espresso_system) -c_salt_calculated = pmb.create_added_salt(espresso_system=espresso_system, + box_l=box_l) +c_salt_calculated = pmb.create_added_salt(box_l=box_l, cation_name=sodium_name, anion_name=chloride_name, c_salt=c_salt_res) +pmb.set_simulation_engine(espresso_system) +pmb.add_instances_to_engine() if verbose: print("Created molecules") @@ -220,12 +223,12 @@ grxmc.set_non_interacting_type (type=non_interacting_type) #Set up the interactions -pmb.setup_lj_interactions(espresso_system=espresso_system) +pmb.setup_lj_interactions() # Relax the system -relax_espresso_system(espresso_system=espresso_system, +pmb.simulation_engine.relax_espresso_system( seed=langevin_seed) -setup_langevin_dynamics(espresso_system=espresso_system, +pmb.simulation_engine.setup_langevin_dynamics( kT = pmb.kT, seed = langevin_seed, time_step=dt, @@ -236,16 +239,16 @@ espresso_system.integrator.run(steps=1000) do_reaction(grxmc, steps=1000) -setup_electrostatic_interactions(units=pmb.units, +pmb.simulation_engine.setup_electrostatic_interactions(units=pmb.units, espresso_system=espresso_system, kT=pmb.kT, solvent_permittivity=solvent_permittivity, verbose=verbose) espresso_system.thermostat.turn_off() -relax_espresso_system(espresso_system=espresso_system, +pmb.simulation_engine.relax_espresso_system(espresso_system=espresso_system, seed=langevin_seed, max_displacement=0.01) -setup_langevin_dynamics(espresso_system=espresso_system, +pmb.simulation_engine.setup_langevin_dynamics(espresso_system=espresso_system, kT = pmb.kT, seed = langevin_seed, time_step=dt, @@ -279,7 +282,7 @@ # Measure time time_series["time"].append(espresso_system.time) # Measure degree of ionization - charge_dict=pmb.calculate_net_charge(espresso_system=espresso_system, + charge_dict=pmb.calculate_net_charge( object_name=polyacid_name, pmb_type="molecule", dimensionless=True) diff --git a/samples/peptide_cpH.py b/samples/peptide_cpH.py index 9eefa75d..d67bf24e 100644 --- a/samples/peptide_cpH.py +++ b/samples/peptide_cpH.py @@ -203,25 +203,24 @@ ##Setup the potential energy if verbose: print('Setup LJ interaction (this can take a few seconds)') - pmb.setup_lj_interactions (espresso_system=espresso_system) + pmb.setup_lj_interactions() if verbose: print('Minimize energy before adding electrostatics') - relax_espresso_system(espresso_system=espresso_system, + pmb.simulation_engine.relax_espresso_system( seed=langevin_seed) if verbose: print('Setup and tune electrostatics (this can take a few seconds)') - setup_electrostatic_interactions(units=pmb.units, - espresso_system=espresso_system, + pmb.simulation_engine.setup_electrostatic_interactions(units=pmb.units, kT=pmb.kT, verbose=verbose) if verbose: print('Minimize energy after adding electrostatics') - relax_espresso_system(espresso_system=espresso_system, + pmb.simulation_engine.relax_espresso_system( seed=langevin_seed) if verbose: print('Setup Langevin dynamics') -setup_langevin_dynamics(espresso_system=espresso_system, +pmb.simulation_engine.setup_langevin_dynamics( kT = pmb.kT, seed = langevin_seed, time_step=dt, @@ -244,7 +243,7 @@ # LD sampling of the configuration space espresso_system.integrator.run(steps=MD_steps_per_sample) # cpH sampling of the reaction space - do_reaction(cpH, steps=total_ionisable_groups) # rule of thumb: one reaction step per titratable group (on average) + pmb.simulation_engine.do_reaction(cpH, steps=total_ionisable_groups) # rule of thumb: one reaction step per titratable group (on average) # Get peptide net charge charge_dict=pmb.calculate_net_charge( object_name=peptide_name, diff --git a/samples/peptide_mixture_grxmc_ideal.py b/samples/peptide_mixture_grxmc_ideal.py index deb35d3b..64d7184c 100644 --- a/samples/peptide_mixture_grxmc_ideal.py +++ b/samples/peptide_mixture_grxmc_ideal.py @@ -189,29 +189,30 @@ calculated_peptide_concentration = N_peptide1_chains/(volume*pmb.N_A) # Create an instance of an espresso system -espresso_system=espressomd.System (box_l = [L.to('reduced_length').magnitude]*3) +box_l=[L.to('reduced_length').magnitude]*3 +espresso_system=espressomd.System (box_l = box_l) # Create your molecules into the espresso system pmb.create_molecule(name=peptide1, number_of_molecules=N_peptide1_chains, - espresso_system=espresso_system, + box_l=box_l, use_default_bond=True) pmb.create_molecule(name=peptide2, number_of_molecules=N_peptide2_chains, - espresso_system=espresso_system, + box_l=box_l, use_default_bond=True) if args.mode == 'standard': pmb.create_counterions(object_name=peptide1, cation_name=proton_name, anion_name=hydroxide_name, - espresso_system=espresso_system) # Create counterions for the peptide chains with sequence 1 + box_l=box_l,) # Create counterions for the peptide chains with sequence 1 pmb.create_counterions(object_name=peptide2, cation_name=proton_name, anion_name=hydroxide_name, - espresso_system=espresso_system) # Create counterions for the peptide chains with sequence 2 + box_l=box_l,) # Create counterions for the peptide chains with sequence 2 - c_salt_calculated = pmb.create_added_salt(espresso_system=espresso_system, + c_salt_calculated = pmb.create_added_salt(box_l=box_l, cation_name=sodium_name, anion_name=chloride_name, c_salt=c_salt) @@ -219,13 +220,13 @@ pmb.create_counterions(object_name=peptide1, cation_name=cation_name, anion_name=anion_name, - espresso_system=espresso_system) # Create counterions for the peptide chains with sequence 1 + box_l=box_l,) # Create counterions for the peptide chains with sequence 1 pmb.create_counterions(object_name=peptide2, cation_name=cation_name, anion_name=anion_name, - espresso_system=espresso_system) # Create counterions for the peptide chains with sequence 2 + box_l=box_l,) # Create counterions for the peptide chains with sequence 2 - c_salt_calculated = pmb.create_added_salt(espresso_system=espresso_system, + c_salt_calculated = pmb.create_added_salt(box_l=box_l, cation_name=cation_name, anion_name=anion_name, c_salt=c_salt) @@ -246,6 +247,9 @@ if verbose: print("The box length of your system is", L.to('reduced_length'), L.to('nm')) +pmb.set_simulation_engine(espresso_system) +pmb.add_instances_to_engine() + if args.mode == 'standard': grxmc, ionic_strength_res = pmb.setup_grxmc_reactions(pH_res=pH_value, c_salt_res=c_salt, @@ -298,14 +302,14 @@ N_frame=0 for step in range(N_samples): espresso_system.integrator.run(steps=MD_steps_per_sample) - do_reaction(grxmc, steps=total_ionisable_groups) + pmb.simulation_engine.do_reaction(grxmc, steps=total_ionisable_groups) time_series["time"].append(espresso_system.time) # Get net charge of peptide1 and peptide2 - charge_dict_peptide1=pmb.calculate_net_charge(espresso_system=espresso_system, + charge_dict_peptide1=pmb.calculate_net_charge( object_name=peptide1, pmb_type="peptide", dimensionless=True) - charge_dict_peptide2=pmb.calculate_net_charge(espresso_system=espresso_system, + charge_dict_peptide2=pmb.calculate_net_charge( object_name=peptide2, pmb_type="peptide", dimensionless=True) From 44aea181bc3b82d4d5596de1d435157596d2ec67 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Mon, 11 May 2026 23:12:11 +0200 Subject: [PATCH 41/75] remove espresso_system as an input from methods migrated from handy functions --- pyMBE/simulation_builder/espresso_engine.py | 54 ++++++++++----------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/pyMBE/simulation_builder/espresso_engine.py b/pyMBE/simulation_builder/espresso_engine.py index 25f3fe83..97a9b798 100644 --- a/pyMBE/simulation_builder/espresso_engine.py +++ b/pyMBE/simulation_builder/espresso_engine.py @@ -330,7 +330,7 @@ def enable_motion_of_rigid_object(self, instance_id, pmb_type): pid = self.espresso_system.part.by_id(particle_id) pid.vs_auto_relate_to(rigid_object_center.id) - def get_number_of_particles(self,espresso_system, ptype): + def get_number_of_particles(self, ptype): """ Returns the number of particles of a given ESPResSo particle type. @@ -359,9 +359,9 @@ def get_number_of_particles(self,espresso_system, ptype): else: args = () kwargs = {"type": ptype} - return espresso_system.number_of_particles(*args, **kwargs) + return self.espresso_system.number_of_particles(*args, **kwargs) - def relax_espresso_system(self,espresso_system, seed, gamma=1e-3, Nsteps_steepest_descent=5000, max_displacement=0.01, Nsteps_iter_relax=500): + def relax_espresso_system(self, seed, gamma=1e-3, Nsteps_steepest_descent=5000, max_displacement=0.01, Nsteps_iter_relax=500): """ Relaxes the energy of the given ESPResSo system by performing the following steps: (1) Steepest descent energy minimization, to remove large forces and relax the system to a local minimum. @@ -408,23 +408,23 @@ def relax_espresso_system(self,espresso_system, seed, gamma=1e-3, Nsteps_steepes raise ValueError("'max_displacement' must be positive.") logging.debug("*** Relaxing the energy of the system... ***") logging.debug("*** Starting steepest descent minimization ***") - espresso_system.thermostat.turn_off() - espresso_system.integrator.set_steepest_descent(f_max=0, + self.espresso_system.thermostat.turn_off() + self.espresso_system.integrator.set_steepest_descent(f_max=0, gamma=gamma, max_displacement=max_displacement) - espresso_system.integrator.run(Nsteps_steepest_descent) + self.espresso_system.integrator.run(Nsteps_steepest_descent) logging.debug("*** Finished steepest descent minimization ***") logging.debug("*** Starting Langevin Dynamics relaxation ***") - espresso_system.integrator.set_vv() - espresso_system.thermostat.set_langevin(kT=1., gamma=gamma, seed=seed) - espresso_system.integrator.run(Nsteps_iter_relax) - espresso_system.thermostat.turn_off() + self.espresso_system.integrator.set_vv() + self.espresso_system.thermostat.set_langevin(kT=1., gamma=gamma, seed=seed) + self.espresso_system.integrator.run(Nsteps_iter_relax) + self.espresso_system.thermostat.turn_off() logging.debug("*** Finished Langevin Dynamics relaxation ***") - logging.info(f"*** Minimum particle distance after relaxation: {espresso_system.analysis.min_dist()} ***") + logging.info(f"*** Minimum particle distance after relaxation: {self.espresso_system.analysis.min_dist()} ***") logging.debug("*** Relaxation finished ***") - return espresso_system.analysis.min_dist() + return self.espresso_system.analysis.min_dist() - def setup_electrostatic_interactions(self,units, espresso_system, kT, c_salt=None, solvent_permittivity=78.5, method='p3m', tune_p3m=True, accuracy=1e-3, params=None, verbose=False): + def setup_electrostatic_interactions(self,units, kT, c_salt=None, solvent_permittivity=78.5, method='p3m', tune_p3m=True, accuracy=1e-3, params=None, verbose=False): """ Sets up electrostatic interactions in an ESPResSo system. @@ -503,20 +503,20 @@ def setup_electrostatic_interactions(self,units, espresso_system, kT, c_salt=Non **params) if tune_p3m: - espresso_system.time_step=0.01 + self.espresso_system.time_step=0.01 if espressomd.version.friendly() == "4.2": - espresso_system.actors.add(coulomb) + self.espresso_system.actors.add(coulomb) else: - espresso_system.electrostatics.solver = coulomb + self.espresso_system.electrostatics.solver = coulomb # save the optimal parameters and add them by hand p3m_params = coulomb.get_params() if espressomd.version.friendly() == "4.2": - espresso_system.actors.remove(coulomb) + self.espresso_system.actors.remove(coulomb) else: - espresso_system.electrostatics.solver = None + self.espresso_system.electrostatics.solver = None coulomb = espressomd.electrostatics.P3M(prefactor = COULOMB_PREFACTOR.m_as("reduced_length * reduced_energy"), accuracy = accuracy, mesh = p3m_params['mesh'], @@ -536,9 +536,9 @@ def setup_electrostatic_interactions(self,units, espresso_system, kT, c_salt=Non kappa = (1./KAPPA).to('1/ reduced_length').magnitude, r_cut = r_cut) if espressomd.version.friendly() == "4.2": - espresso_system.actors.add(coulomb) + self.espresso_system.actors.add(coulomb) else: - espresso_system.electrostatics.solver = coulomb + self.espresso_system.electrostatics.solver = coulomb logging.debug("*** Electrostatics successfully added to the system ***") def setup_cpH (self, counter_ion, constant_pH, exclusion_range=None, use_exclusion_radius_per_type = False): @@ -1136,7 +1136,7 @@ def setup_grxmc_unified(self, pH_res, c_salt_res, cation_name, anion_name, activ self.db._register_reaction(rx_tpl) return RE, ionic_strength_res - def setup_langevin_dynamics(self,espresso_system, kT, seed,time_step=1e-2, gamma=1, tune_skin=True, min_skin=1, max_skin=None, tolerance=1e-3, int_steps=200, adjust_max_skin=True): + def setup_langevin_dynamics(self, kT, seed,time_step=1e-2, gamma=1, tune_skin=True, min_skin=1, max_skin=None, tolerance=1e-3, int_steps=200, adjust_max_skin=True): """ Sets up Langevin Dynamics for an ESPResSo simulation system. @@ -1181,23 +1181,23 @@ def setup_langevin_dynamics(self,espresso_system, kT, seed,time_step=1e-2, gamma if not isinstance(gamma, (float, int)) or gamma <= 0: raise ValueError("gamma must be a positive number.") if max_skin is None: - max_skin=espresso_system.box_l[0]/2 + max_skin=self.espresso_system.box_l[0]/2 if min_skin >= max_skin: raise ValueError("min_skin must be smaller than max_skin.") - espresso_system.time_step=time_step - espresso_system.integrator.set_vv() - espresso_system.thermostat.set_langevin(kT= kT.to('reduced_energy').magnitude, + self.espresso_system.time_step=time_step + self.espresso_system.integrator.set_vv() + self.espresso_system.thermostat.set_langevin(kT= kT.to('reduced_energy').magnitude, gamma= gamma, seed= seed) # Optimize the value of skin if tune_skin: logging.debug("*** Optimizing skin ... ***") - espresso_system.cell_system.tune_skin(min_skin=min_skin, + self.espresso_system.cell_system.tune_skin(min_skin=min_skin, max_skin=max_skin, tol=tolerance, int_steps=int_steps, adjust_max_skin=adjust_max_skin) - logging.info(f"Optimized skin value: {espresso_system.cell_system.skin}") + logging.info(f"Optimized skin value: {self.espresso_system.cell_system.skin}") def setup_lj_interactions(self, shift_potential=True, combining_rule='Lorentz-Berthelot'): """ From 861f03b3ad55abdba6bb5ce67b52165529051260 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Mon, 11 May 2026 23:12:46 +0200 Subject: [PATCH 42/75] Adapt test_handy_functions towards decoupling espresso --- testsuite/test_handy_functions.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/testsuite/test_handy_functions.py b/testsuite/test_handy_functions.py index 54ab48bb..6939e253 100644 --- a/testsuite/test_handy_functions.py +++ b/testsuite/test_handy_functions.py @@ -40,7 +40,7 @@ pmb.set_simulation_engine(espresso_system) kT = pmb.kT -langevin_inputs={"espresso_system":espresso_system, +langevin_inputs={ "kT" : kT, "seed" : seed, "time_step" : 1e-2, @@ -52,7 +52,7 @@ "int_steps": 200, "adjust_max_skin": True} -relax_inputs={"espresso_system":espresso_system, +relax_inputs={ "gamma":0.01, "Nsteps_steepest_descent":5000, "max_displacement":0.1, @@ -60,7 +60,6 @@ "seed": seed} electrostatics_inputs={"units": pmb.units, - "espresso_system": espresso_system, "kT": pmb.kT, "c_salt": None, "solvent_permittivity":78.5, From 337cf47717b23e552cc85e832285c4e64ac2868f Mon Sep 17 00:00:00 2001 From: jsd94 Date: Mon, 11 May 2026 23:44:56 +0200 Subject: [PATCH 43/75] Adapt changes to decoupling espresso from pymbe --- samples/weak_polyacid_hydrogel_grxmc.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/samples/weak_polyacid_hydrogel_grxmc.py b/samples/weak_polyacid_hydrogel_grxmc.py index 2e883b85..2255552b 100644 --- a/samples/weak_polyacid_hydrogel_grxmc.py +++ b/samples/weak_polyacid_hydrogel_grxmc.py @@ -142,7 +142,8 @@ epsilon=1*pmb.units('reduced_energy')) diamond_lattice = DiamondLattice(args.mpc, bond_length) -espresso_system = espressomd.System(box_l = [diamond_lattice.box_l]*3) +box_l=[diamond_lattice.box_l]*3 +espresso_system = espressomd.System(box_l = box_l) lattice_builder = pmb.initialize_lattice_builder(diamond_lattice) # Setting up node topology @@ -163,12 +164,14 @@ 'molecule_name':molecule_name}) pmb.define_hydrogel("my_hydrogel", node_topology, chain_topology) -hydrogel_info = pmb.create_hydrogel("my_hydrogel", espresso_system) +hydrogel_info = pmb.create_hydrogel("my_hydrogel", box_l=box_l) -c_salt_calculated = pmb.create_added_salt(espresso_system=espresso_system, +c_salt_calculated = pmb.create_added_salt(box_l=box_l, cation_name=sodium_name, anion_name=chloride_name, c_salt=c_salt_res) +pmb.set_simulation_engine(espresso_system) +pmb.add_instances_to_engine() print(f"Salt concentration {c_salt_calculated.to('mol/L')} added") @@ -176,7 +179,7 @@ dt = 0.01 # Timestep espresso_system.time_step = dt -pmb.setup_lj_interactions(espresso_system=espresso_system) +pmb.setup_lj_interactions() #Save the initial state n_frame = 0 frames_dir = data_path / "frames" @@ -186,11 +189,11 @@ vtf.writevcf(espresso_system, coordinates) print("*** Relaxing the system... ***") -relax_espresso_system(espresso_system=espresso_system, +pmb.simulation_engine.relax_espresso_system( seed=seed, Nsteps_iter_relax=100) -setup_langevin_dynamics(espresso_system=espresso_system, +pmb.simulation_engine.setup_langevin_dynamics( kT = pmb.kT, seed = seed, time_step=dt, @@ -210,7 +213,7 @@ # Just to make sure that the system has the target size espresso_system.change_volume_and_rescale_particles( d_new=L_target, dir="xyz") -relax_espresso_system(espresso_system=espresso_system, +pmb.simulation_engine.relax_espresso_system( seed=seed, Nsteps_iter_relax=100, max_displacement=0.01) @@ -249,8 +252,7 @@ espresso_system.integrator.run(steps=1000) do_reaction(grxmc,1000) -setup_electrostatic_interactions(units=pmb.units, - espresso_system=espresso_system, +pmb.simulation_engine.setup_electrostatic_interactions(units=pmb.units, kT=pmb.kT, solvent_permittivity=solvent_permittivity) @@ -262,7 +264,7 @@ print("*** Running warmup with electrostatics... ***") for i in tqdm.trange(N_warmup_loops): espresso_system.integrator.run(steps=1000) - do_reaction(grxmc,100) + pmb.simulation_engine.do_reaction(grxmc,100) # Main loop print("*** Starting production run... ***") @@ -282,7 +284,7 @@ for i in tqdm.trange(N_production_loops): espresso_system.integrator.run(steps=1000) - do_reaction(grxmc,200) + pmb.simulation_engine.do_reaction(grxmc,200) # Measure time time_series["time"].append(espresso_system.time) From c8d3f7df80d3372d2b475532b77bd83037bcedcb Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 14 May 2026 12:41:51 +0200 Subject: [PATCH 44/75] Add modifications to adapt sample script to espresso decoupling --- samples/salt_solution_gcmc.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/samples/salt_solution_gcmc.py b/samples/salt_solution_gcmc.py index 704053cb..967a6c5c 100644 --- a/samples/salt_solution_gcmc.py +++ b/samples/salt_solution_gcmc.py @@ -94,12 +94,13 @@ L = volume ** (1./3.) # Side of the simulation box # Create an instance of an espresso system -espresso_system=espressomd.System (box_l = [L.to('reduced_length').magnitude]*3) +box_l= [L.to('reduced_length').magnitude]*3 +espresso_system=espressomd.System (box_l =box_l) if verbose: print("Created espresso object") # Add salt -c_salt_calculated = pmb.create_added_salt(espresso_system=espresso_system, +c_salt_calculated = pmb.create_added_salt(box_l=box_l, cation_name=cation_name, anion_name=anion_name, c_salt=0.5*c_salt_res) @@ -145,9 +146,9 @@ pmb.setup_lj_interactions(espresso_system=espresso_system) # Minimzation -relax_espresso_system(espresso_system=espresso_system, +pmb.simulation_engine.relax_espresso_system( seed=langevin_seed) -setup_langevin_dynamics(espresso_system=espresso_system, +pmb.simulation_engine.setup_langevin_dynamics( kT = pmb.kT, seed = langevin_seed, time_step=dt, @@ -157,18 +158,17 @@ print("Running warmup without electrostatics") for i in tqdm.trange(100, disable=not verbose): espresso_system.integrator.run(steps=100) - do_reaction(RE, steps=100) + pmb.simulation_engine.do_reaction(RE, steps=100) if args.mode == "interacting": - setup_electrostatic_interactions(units=pmb.units, - espresso_system=espresso_system, + pmb.simulation_engine.setup_electrostatic_interactions(units=pmb.units, kT=pmb.kT, solvent_permittivity=solvent_permittivity) espresso_system.thermostat.turn_off() -relax_espresso_system(espresso_system=espresso_system, +pmb.simulation_engine.relax_espresso_system( seed=langevin_seed) -setup_langevin_dynamics(espresso_system=espresso_system, +pmb.simulation_engine.setup_langevin_dynamics( kT = pmb.kT, seed = langevin_seed, time_step=dt, @@ -180,7 +180,7 @@ N_warmup_loops = 100 for i in tqdm.trange(N_warmup_loops, disable=not verbose): espresso_system.integrator.run(steps=100) - do_reaction(RE, steps=100) + pmb.simulation_engine.do_reaction(RE, steps=100) # Main loop print("Started production run.") @@ -194,7 +194,7 @@ N_production_loops = 100 for i in tqdm.trange(N_production_loops, disable=not verbose): espresso_system.integrator.run(steps=100) - do_reaction(RE, steps=100) + pmb.simulation_engine.do_reaction(RE, steps=100) # Measure time time_series["time"].append(espresso_system.time) From 1a9b961e5a2dee28eb043bfdb2e99fdfcd58594e Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 14 May 2026 13:16:02 +0200 Subject: [PATCH 45/75] Add changes to pymbe_tutorial --- tutorials/pyMBE_tutorial.ipynb | 2700 +++++++++++++++++++++++--------- 1 file changed, 1920 insertions(+), 780 deletions(-) diff --git a/tutorials/pyMBE_tutorial.ipynb b/tutorials/pyMBE_tutorial.ipynb index b5d71075..24afbbb9 100644 --- a/tutorials/pyMBE_tutorial.ipynb +++ b/tutorials/pyMBE_tutorial.ipynb @@ -40,25 +40,6 @@ "Let us get started by importing pyMBE library and other important libraries for this tutorial, such as ESPResSo." ] }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "# Import pyMBE and ESPResSo\n", - "import pyMBE\n", - "import espressomd\n", - "from espressomd import interactions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "markdown", "metadata": {}, @@ -68,11 +49,12 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import pyMBE\n", + "import espressomd\n", "pmb = pyMBE.pymbe_library(seed=42)" ] }, @@ -91,7 +73,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -111,27 +93,6 @@ "print(reduced_unit_set)" ] }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Current set of reduced units:\n", - "0.355 nanometer = 1 reduced_length\n", - "4.1164e-21 joule = 1 reduced_energy\n", - "1.6022e-19 coulomb = 1 reduced_charge\n", - "Temperature: 298.15 kelvin\n" - ] - } - ], - "source": [ - "print(reduced_unit_set)" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -141,7 +102,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -162,7 +123,28 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "ename": "TypeError", + "evalue": "GenericPlainRegistry.get_dimensionality() missing 1 required positional argument: 'input_units'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[8], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43mpmb\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43munits\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_dimensionality\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m)\n", + "\u001b[0;31mTypeError\u001b[0m: GenericPlainRegistry.get_dimensionality() missing 1 required positional argument: 'input_units'" + ] + } + ], + "source": [ + "print(pmb.units.get_group())" + ] + }, + { + "cell_type": "code", + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -198,7 +180,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -236,7 +218,16 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.set_simulation_engine(espresso_system)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -256,7 +247,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -312,7 +303,7 @@ "0 0.5612310241546864 nanometer 0.0 nanometer Na " ] }, - "execution_count": 10, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -330,7 +321,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -339,7 +330,7 @@ "True" ] }, - "execution_count": 11, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -351,7 +342,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -360,7 +351,7 @@ "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]" ] }, - "execution_count": 12, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -381,7 +372,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -423,7 +414,7 @@ " Na\n", " 0\n", " [11.609340728339449, 6.583176596280784, 12.878...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -435,7 +426,7 @@ " Na\n", " 1\n", " [10.460520435890457, 1.4126602183147428, 14.63...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -447,7 +438,7 @@ " Na\n", " 2\n", " [11.417095529855294, 11.790964579154306, 1.921...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -459,7 +450,7 @@ " Na\n", " 3\n", " [6.755789068433506, 5.561970363488718, 13.9014...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -471,7 +462,7 @@ " Na\n", " 4\n", " [9.657976801209967, 12.341424199062448, 6.6512...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -483,7 +474,7 @@ " Na\n", " 5\n", " [3.408580826771653, 8.318771805237521, 0.95725...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -495,7 +486,7 @@ " Na\n", " 6\n", " [12.41446757988873, 9.474965986830972, 11.3713...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -507,7 +498,7 @@ " Na\n", " 7\n", " [5.3178895219480244, 14.560470365923548, 13.39...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -519,7 +510,7 @@ " Na\n", " 8\n", " [11.675752456106427, 2.919580617779513, 7.0008...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -531,7 +522,7 @@ " Na\n", " 9\n", " [0.6570564868084315, 2.3143423810132173, 10.24...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -543,7 +534,7 @@ " Na\n", " 10\n", " [11.171432338617256, 14.512645986513148, 4.887...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -555,7 +546,7 @@ " Na\n", " 11\n", " [5.556895590523033, 7.043337169137118, 2.84207...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -567,7 +558,7 @@ " Na\n", " 12\n", " [1.9488225800320744, 7.135573893389005, 3.4036...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -579,7 +570,7 @@ " Na\n", " 13\n", " [10.047209920237654, 6.557278783084961, 12.490...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -591,7 +582,7 @@ " Na\n", " 14\n", " [10.503976530033736, 4.685499620730615, 12.483...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -603,7 +594,7 @@ " Na\n", " 15\n", " [12.071465362452027, 5.812175685452616, 4.3249...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -615,7 +606,7 @@ " Na\n", " 16\n", " [10.237432559624631, 2.096287254139647, 2.9986...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -627,7 +618,7 @@ " Na\n", " 17\n", " [0.11043404626508267, 11.803865662532074, 9.97...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -639,7 +630,7 @@ " Na\n", " 18\n", " [10.577480679395025, 11.710935465329516, 6.883...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -651,7 +642,7 @@ " Na\n", " 19\n", " [8.531117939293406, 2.0969549719148612, 1.7179...\n", - " None\n", + " [False, False, False]\n", " Na\n", " <NA>\n", " <NA>\n", @@ -684,52 +675,52 @@ "18 particle Na 18 \n", "19 particle Na 19 \n", "\n", - " position fix initial_state \\\n", - "0 [11.609340728339449, 6.583176596280784, 12.878... None Na \n", - "1 [10.460520435890457, 1.4126602183147428, 14.63... None Na \n", - "2 [11.417095529855294, 11.790964579154306, 1.921... None Na \n", - "3 [6.755789068433506, 5.561970363488718, 13.9014... None Na \n", - "4 [9.657976801209967, 12.341424199062448, 6.6512... None Na \n", - "5 [3.408580826771653, 8.318771805237521, 0.95725... None Na \n", - "6 [12.41446757988873, 9.474965986830972, 11.3713... None Na \n", - "7 [5.3178895219480244, 14.560470365923548, 13.39... None Na \n", - "8 [11.675752456106427, 2.919580617779513, 7.0008... None Na \n", - "9 [0.6570564868084315, 2.3143423810132173, 10.24... None Na \n", - "10 [11.171432338617256, 14.512645986513148, 4.887... None Na \n", - "11 [5.556895590523033, 7.043337169137118, 2.84207... None Na \n", - "12 [1.9488225800320744, 7.135573893389005, 3.4036... None Na \n", - "13 [10.047209920237654, 6.557278783084961, 12.490... None Na \n", - "14 [10.503976530033736, 4.685499620730615, 12.483... None Na \n", - "15 [12.071465362452027, 5.812175685452616, 4.3249... None Na \n", - "16 [10.237432559624631, 2.096287254139647, 2.9986... None Na \n", - "17 [0.11043404626508267, 11.803865662532074, 9.97... None Na \n", - "18 [10.577480679395025, 11.710935465329516, 6.883... None Na \n", - "19 [8.531117939293406, 2.0969549719148612, 1.7179... None Na \n", + " position fix \\\n", + "0 [11.609340728339449, 6.583176596280784, 12.878... [False, False, False] \n", + "1 [10.460520435890457, 1.4126602183147428, 14.63... [False, False, False] \n", + "2 [11.417095529855294, 11.790964579154306, 1.921... [False, False, False] \n", + "3 [6.755789068433506, 5.561970363488718, 13.9014... [False, False, False] \n", + "4 [9.657976801209967, 12.341424199062448, 6.6512... [False, False, False] \n", + "5 [3.408580826771653, 8.318771805237521, 0.95725... [False, False, False] \n", + "6 [12.41446757988873, 9.474965986830972, 11.3713... [False, False, False] \n", + "7 [5.3178895219480244, 14.560470365923548, 13.39... [False, False, False] \n", + "8 [11.675752456106427, 2.919580617779513, 7.0008... [False, False, False] \n", + "9 [0.6570564868084315, 2.3143423810132173, 10.24... [False, False, False] \n", + "10 [11.171432338617256, 14.512645986513148, 4.887... [False, False, False] \n", + "11 [5.556895590523033, 7.043337169137118, 2.84207... [False, False, False] \n", + "12 [1.9488225800320744, 7.135573893389005, 3.4036... [False, False, False] \n", + "13 [10.047209920237654, 6.557278783084961, 12.490... [False, False, False] \n", + "14 [10.503976530033736, 4.685499620730615, 12.483... [False, False, False] \n", + "15 [12.071465362452027, 5.812175685452616, 4.3249... [False, False, False] \n", + "16 [10.237432559624631, 2.096287254139647, 2.9986... [False, False, False] \n", + "17 [0.11043404626508267, 11.803865662532074, 9.97... [False, False, False] \n", + "18 [10.577480679395025, 11.710935465329516, 6.883... [False, False, False] \n", + "19 [8.531117939293406, 2.0969549719148612, 1.7179... [False, False, False] \n", "\n", - " residue_id molecule_id assembly_id \n", - "0 \n", - "1 \n", - "2 \n", - "3 \n", - "4 \n", - "5 \n", - "6 \n", - "7 \n", - "8 \n", - "9 \n", - "10 \n", - "11 \n", - "12 \n", - "13 \n", - "14 \n", - "15 \n", - "16 \n", - "17 \n", - "18 \n", - "19 " + " initial_state residue_id molecule_id assembly_id \n", + "0 Na \n", + "1 Na \n", + "2 Na \n", + "3 Na \n", + "4 Na \n", + "5 Na \n", + "6 Na \n", + "7 Na \n", + "8 Na \n", + "9 Na \n", + "10 Na \n", + "11 Na \n", + "12 Na \n", + "13 Na \n", + "14 Na \n", + "15 Na \n", + "16 Na \n", + "17 Na \n", + "18 Na \n", + "19 Na " ] }, - "execution_count": 13, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -740,7 +731,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -757,7 +748,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 29, "metadata": {}, "outputs": [], "source": [ @@ -786,7 +777,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -828,7 +819,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 31, "metadata": {}, "outputs": [], "source": [ @@ -837,8 +828,7 @@ "# This will delete all particles that we created before\n", "for pid in particle_id_map[\"all\"]:\n", " pmb.delete_instances_in_system(instance_id=pid, \n", - " pmb_type=\"particle\",\n", - " espresso_system = espresso_system)" + " pmb_type=\"particle\")" ] }, { @@ -850,105 +840,7 @@ }, { "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
\n", - "
" - ], - "text/plain": [ - "Empty DataFrame\n", - "Columns: []\n", - "Index: []" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pmb.get_instances_df(pmb_type = 'particle')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "## How to create simple polymers " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "pyMBE can be used to easily construct coarse-grained models of simple polymers. Let us consider a coarse grained model for polydehydroalanaline (PDha) (figure below) in which its monomeric unit can be represented by three beads, as depicted in the schematics below: a backbone bead (grey), a bead for the carboxylic acid group (red) and a bead for the amino group (blue).\n", - "\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To set up such polymer with pyMBE first one has to define templates for the different particles in the monomer." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "PDha_backbone_bead = 'BB-PDha'\n", - "PDha_carboxyl_bead = 'COOH-PDha'\n", - "PDha_amine_bead = 'NH3-PDha'\n", - "\n", - "pmb.define_particle(name = PDha_backbone_bead, \n", - " z = 0, \n", - " sigma = 0.4*pmb.units.nm,\n", - " epsilon = 1*pmb.units('reduced_energy'))\n", - "\n", - "pmb.define_particle(name = PDha_carboxyl_bead, \n", - " z = 0, \n", - " sigma = 0.5*pmb.units.nm, \n", - " epsilon = 1*pmb.units('reduced_energy'))\n", - "\n", - "pmb.define_particle(name = PDha_amine_bead, \n", - " z = 0, \n", - " sigma = 0.3*pmb.units.nm, \n", - " epsilon = 1*pmb.units('reduced_energy'))\n" - ] - }, - { - "cell_type": "code", - "execution_count": 10, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -974,114 +866,535 @@ " \n", " pmb_type\n", " name\n", - " sigma\n", - " epsilon\n", - " cutoff\n", - " offset\n", + " particle_id\n", + " position\n", + " fix\n", " initial_state\n", + " residue_id\n", + " molecule_id\n", + " assembly_id\n", " \n", " \n", " \n", " \n", " 0\n", " particle\n", - " BB-PDha\n", - " 0.4 nanometer\n", - " 25.692579121085853 millielectron_volt\n", - " 0.5612310241546864 nanometer\n", - " 0.0 nanometer\n", - " BB-PDha\n", + " Na\n", + " 0\n", + " [11.609340728339449, 6.583176596280784, 12.878...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", " \n", " \n", " 1\n", " particle\n", - " COOH-PDha\n", - " 0.5 nanometer\n", - " 25.692579121085853 millielectron_volt\n", - " 0.5612310241546864 nanometer\n", - " 0.0 nanometer\n", - " COOH-PDha\n", + " Na\n", + " 1\n", + " [10.460520435890457, 1.4126602183147428, 14.63...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", " \n", " \n", " 2\n", " particle\n", - " NH3-PDha\n", - " 0.3 nanometer\n", - " 25.692579121085853 millielectron_volt\n", - " 0.5612310241546864 nanometer\n", - " 0.0 nanometer\n", - " NH3-PDha\n", - " \n", - " \n", - "\n", - "" + " Na\n", + " 2\n", + " [11.417095529855294, 11.790964579154306, 1.921...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 3\n", + " particle\n", + " Na\n", + " 3\n", + " [6.755789068433506, 5.561970363488718, 13.9014...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 4\n", + " particle\n", + " Na\n", + " 4\n", + " [9.657976801209967, 12.341424199062448, 6.6512...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 5\n", + " particle\n", + " Na\n", + " 5\n", + " [3.408580826771653, 8.318771805237521, 0.95725...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 6\n", + " particle\n", + " Na\n", + " 6\n", + " [12.41446757988873, 9.474965986830972, 11.3713...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 7\n", + " particle\n", + " Na\n", + " 7\n", + " [5.3178895219480244, 14.560470365923548, 13.39...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 8\n", + " particle\n", + " Na\n", + " 8\n", + " [11.675752456106427, 2.919580617779513, 7.0008...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 9\n", + " particle\n", + " Na\n", + " 9\n", + " [0.6570564868084315, 2.3143423810132173, 10.24...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 10\n", + " particle\n", + " Na\n", + " 10\n", + " [11.171432338617256, 14.512645986513148, 4.887...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 11\n", + " particle\n", + " Na\n", + " 11\n", + " [5.556895590523033, 7.043337169137118, 2.84207...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 12\n", + " particle\n", + " Na\n", + " 12\n", + " [1.9488225800320744, 7.135573893389005, 3.4036...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 13\n", + " particle\n", + " Na\n", + " 13\n", + " [10.047209920237654, 6.557278783084961, 12.490...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 14\n", + " particle\n", + " Na\n", + " 14\n", + " [10.503976530033736, 4.685499620730615, 12.483...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 15\n", + " particle\n", + " Na\n", + " 15\n", + " [12.071465362452027, 5.812175685452616, 4.3249...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 16\n", + " particle\n", + " Na\n", + " 16\n", + " [10.237432559624631, 2.096287254139647, 2.9986...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 17\n", + " particle\n", + " Na\n", + " 17\n", + " [0.11043404626508267, 11.803865662532074, 9.97...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 18\n", + " particle\n", + " Na\n", + " 18\n", + " [10.577480679395025, 11.710935465329516, 6.883...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 19\n", + " particle\n", + " Na\n", + " 19\n", + " [8.531117939293406, 2.0969549719148612, 1.7179...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + "\n", + "" ], "text/plain": [ - " pmb_type name sigma epsilon \\\n", - "0 particle BB-PDha 0.4 nanometer 25.692579121085853 millielectron_volt \n", - "1 particle COOH-PDha 0.5 nanometer 25.692579121085853 millielectron_volt \n", - "2 particle NH3-PDha 0.3 nanometer 25.692579121085853 millielectron_volt \n", + " pmb_type name particle_id \\\n", + "0 particle Na 0 \n", + "1 particle Na 1 \n", + "2 particle Na 2 \n", + "3 particle Na 3 \n", + "4 particle Na 4 \n", + "5 particle Na 5 \n", + "6 particle Na 6 \n", + "7 particle Na 7 \n", + "8 particle Na 8 \n", + "9 particle Na 9 \n", + "10 particle Na 10 \n", + "11 particle Na 11 \n", + "12 particle Na 12 \n", + "13 particle Na 13 \n", + "14 particle Na 14 \n", + "15 particle Na 15 \n", + "16 particle Na 16 \n", + "17 particle Na 17 \n", + "18 particle Na 18 \n", + "19 particle Na 19 \n", "\n", - " cutoff offset initial_state \n", - "0 0.5612310241546864 nanometer 0.0 nanometer BB-PDha \n", - "1 0.5612310241546864 nanometer 0.0 nanometer COOH-PDha \n", - "2 0.5612310241546864 nanometer 0.0 nanometer NH3-PDha " + " position fix \\\n", + "0 [11.609340728339449, 6.583176596280784, 12.878... [False, False, False] \n", + "1 [10.460520435890457, 1.4126602183147428, 14.63... [False, False, False] \n", + "2 [11.417095529855294, 11.790964579154306, 1.921... [False, False, False] \n", + "3 [6.755789068433506, 5.561970363488718, 13.9014... [False, False, False] \n", + "4 [9.657976801209967, 12.341424199062448, 6.6512... [False, False, False] \n", + "5 [3.408580826771653, 8.318771805237521, 0.95725... [False, False, False] \n", + "6 [12.41446757988873, 9.474965986830972, 11.3713... [False, False, False] \n", + "7 [5.3178895219480244, 14.560470365923548, 13.39... [False, False, False] \n", + "8 [11.675752456106427, 2.919580617779513, 7.0008... [False, False, False] \n", + "9 [0.6570564868084315, 2.3143423810132173, 10.24... [False, False, False] \n", + "10 [11.171432338617256, 14.512645986513148, 4.887... [False, False, False] \n", + "11 [5.556895590523033, 7.043337169137118, 2.84207... [False, False, False] \n", + "12 [1.9488225800320744, 7.135573893389005, 3.4036... [False, False, False] \n", + "13 [10.047209920237654, 6.557278783084961, 12.490... [False, False, False] \n", + "14 [10.503976530033736, 4.685499620730615, 12.483... [False, False, False] \n", + "15 [12.071465362452027, 5.812175685452616, 4.3249... [False, False, False] \n", + "16 [10.237432559624631, 2.096287254139647, 2.9986... [False, False, False] \n", + "17 [0.11043404626508267, 11.803865662532074, 9.97... [False, False, False] \n", + "18 [10.577480679395025, 11.710935465329516, 6.883... [False, False, False] \n", + "19 [8.531117939293406, 2.0969549719148612, 1.7179... [False, False, False] \n", + "\n", + " initial_state residue_id molecule_id assembly_id \n", + "0 Na \n", + "1 Na \n", + "2 Na \n", + "3 Na \n", + "4 Na \n", + "5 Na \n", + "6 Na \n", + "7 Na \n", + "8 Na \n", + "9 Na \n", + "10 Na \n", + "11 Na \n", + "12 Na \n", + "13 Na \n", + "14 Na \n", + "15 Na \n", + "16 Na \n", + "17 Na \n", + "18 Na \n", + "19 Na " ] }, - "execution_count": 10, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "pmb.get_templates_df(pmb_type = 'particle')" + "pmb.get_instances_df(pmb_type = 'particle')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Then, one defines templates for the polymer residues. A residue is composed by a `central_bead` where one or various `side_chains` are attached. Each side chain can contain one particle or other residues. " + "\n", + "## How to create simple polymers " ] }, { - "cell_type": "code", - "execution_count": 11, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "PDha_residue = 'PDha_mon'\n", + "pyMBE can be used to easily construct coarse-grained models of simple polymers. Let us consider a coarse grained model for polydehydroalanaline (PDha) (figure below) in which its monomeric unit can be represented by three beads, as depicted in the schematics below: a backbone bead (grey), a bead for the carboxylic acid group (red) and a bead for the amino group (blue).\n", "\n", - "pmb.define_residue(name = PDha_residue, \n", - " central_bead = PDha_backbone_bead,\n", - " side_chains = [PDha_carboxyl_bead, PDha_amine_bead])\n" + "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "We can check the residue templates we defined in the pyMBE database:" + "To set up such polymer with pyMBE first one has to define templates for the different particles in the monomer." ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
pmb_typenamesigmaepsiloncutoffoffsetinitial_state
0particleNa0.35 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerNa
1particleBB-PDha0.4 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerBB-PDha
2particleCOOH-PDha0.5 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerCOOH-PDha
3particleNH3-PDha0.3 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerNH3-PDha
\n", + "
" + ], + "text/plain": [ + " pmb_type name sigma epsilon \\\n", + "0 particle Na 0.35 nanometer 25.692579121085853 millielectron_volt \n", + "1 particle BB-PDha 0.4 nanometer 25.692579121085853 millielectron_volt \n", + "2 particle COOH-PDha 0.5 nanometer 25.692579121085853 millielectron_volt \n", + "3 particle NH3-PDha 0.3 nanometer 25.692579121085853 millielectron_volt \n", + "\n", + " cutoff offset initial_state \n", + "0 0.5612310241546864 nanometer 0.0 nanometer Na \n", + "1 0.5612310241546864 nanometer 0.0 nanometer BB-PDha \n", + "2 0.5612310241546864 nanometer 0.0 nanometer COOH-PDha \n", + "3 0.5612310241546864 nanometer 0.0 nanometer NH3-PDha " + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pmb.get_templates_df(pmb_type = 'particle')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then, one defines templates for the polymer residues. A residue is composed by a `central_bead` where one or various `side_chains` are attached. Each side chain can contain one particle or other residues. " + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "PDha_residue = 'PDha_mon'\n", + "\n", + "pmb.define_residue(name = PDha_residue, \n", + " central_bead = PDha_backbone_bead,\n", + " side_chains = [PDha_carboxyl_bead, PDha_amine_bead])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can check the residue templates we defined in the pyMBE database:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", "
pmb_typenameparticle_idpositionfixinitial_stateresidue_idmolecule_idassembly_id
0particleNa0[11.609340728339449, 6.583176596280784, 12.878...[False, False, False]Na<NA><NA><NA>
1particleNa1[10.460520435890457, 1.4126602183147428, 14.63...[False, False, False]Na<NA><NA><NA>
2particleNa2[11.417095529855294, 11.790964579154306, 1.921...[False, False, False]Na<NA><NA><NA>
3particleNa3[6.755789068433506, 5.561970363488718, 13.9014...[False, False, False]Na<NA><NA><NA>
4particleNa4[9.657976801209967, 12.341424199062448, 6.6512...[False, False, False]Na<NA><NA><NA>
5particleNa5[3.408580826771653, 8.318771805237521, 0.95725...[False, False, False]Na<NA><NA><NA>
6particleNa6[12.41446757988873, 9.474965986830972, 11.3713...[False, False, False]Na<NA><NA><NA>
7particleNa7[5.3178895219480244, 14.560470365923548, 13.39...[False, False, False]Na<NA><NA><NA>
8particleNa8[11.675752456106427, 2.919580617779513, 7.0008...[False, False, False]Na<NA><NA><NA>
9particleNa9[0.6570564868084315, 2.3143423810132173, 10.24...[False, False, False]Na<NA><NA><NA>
10particleNa10[11.171432338617256, 14.512645986513148, 4.887...[False, False, False]Na<NA><NA><NA>
11particleNa11[5.556895590523033, 7.043337169137118, 2.84207...[False, False, False]Na<NA><NA><NA>
12particleNa12[1.9488225800320744, 7.135573893389005, 3.4036...[False, False, False]Na<NA><NA><NA>
13particleNa13[10.047209920237654, 6.557278783084961, 12.490...[False, False, False]Na<NA><NA><NA>
14particleNa14[10.503976530033736, 4.685499620730615, 12.483...[False, False, False]Na<NA><NA><NA>
15particleNa15[12.071465362452027, 5.812175685452616, 4.3249...[False, False, False]Na<NA><NA><NA>
16particleNa16[10.237432559624631, 2.096287254139647, 2.9986...[False, False, False]Na<NA><NA><NA>
17particleNa17[0.11043404626508267, 11.803865662532074, 9.97...[False, False, False]Na<NA><NA><NA>
18particleNa18[10.577480679395025, 11.710935465329516, 6.883...[False, False, False]Na<NA><NA><NA>
19particleNa19[8.531117939293406, 2.0969549719148612, 1.7179...[False, False, False]Na<NA><NA><NA>
20particleBB-PDha20[7.499999999999999, 7.499999999999999, 7.49999...[False, False, False]BB-PDha00<NA>
21particleCOOH-PDha21[6.898824919599952, 7.881760682233023, 8.02895...[False, False, False]COOH-PDha00<NA>
22particleNH3-PDha22[8.137870547785395, 7.97490337881395, 7.445064...[False, False, False]NH3-PDha00<NA>
23particleBB-PDha23[7.160907281551002, 7.879214991841518, 6.84092...[False, False, False]BB-PDha10<NA>
24particleCOOH-PDha24[6.943630111611255, 8.571635891712093, 7.35111...[False, False, False]COOH-PDha10<NA>
25particleNH3-PDha25[6.726674552857768, 7.228064210684457, 6.68968...[False, False, False]NH3-PDha10<NA>
0moleculePDha[PDha_mon, PDha_mon]26particleBB-PDha26[6.821814563102005, 8.258429983683039, 6.18184...[False, False, False]BB-PDha20<NA>
27particleCOOH-PDha27[7.190700895656628, 9.025057023826212, 6.43315...[False, False, False]COOH-PDha20<NA>
28particleNH3-PDha28[6.246753526388499, 8.554250283754568, 6.64792...[False, False, False]NH3-PDha20<NA>
29particleBB-PDha29[6.482721844653008, 8.637644975524559, 5.52277...[False, False, False]BB-PDha30<NA>
30particleCOOH-PDha30[6.93253697328386, 9.377201114906299, 5.716863...[False, False, False]COOH-PDha30<NA>
31particleNH3-PDha31[6.492959901480784, 7.949057245973125, 5.12130...[False, False, False]NH3-PDha30<NA>
\n", "
" ], "text/plain": [ - " pmb_type name residue_list\n", - "0 molecule PDha [PDha_mon, PDha_mon]" + " pmb_type name particle_id \\\n", + "0 particle Na 0 \n", + "1 particle Na 1 \n", + "2 particle Na 2 \n", + "3 particle Na 3 \n", + "4 particle Na 4 \n", + "5 particle Na 5 \n", + "6 particle Na 6 \n", + "7 particle Na 7 \n", + "8 particle Na 8 \n", + "9 particle Na 9 \n", + "10 particle Na 10 \n", + "11 particle Na 11 \n", + "12 particle Na 12 \n", + "13 particle Na 13 \n", + "14 particle Na 14 \n", + "15 particle Na 15 \n", + "16 particle Na 16 \n", + "17 particle Na 17 \n", + "18 particle Na 18 \n", + "19 particle Na 19 \n", + "20 particle BB-PDha 20 \n", + "21 particle COOH-PDha 21 \n", + "22 particle NH3-PDha 22 \n", + "23 particle BB-PDha 23 \n", + "24 particle COOH-PDha 24 \n", + "25 particle NH3-PDha 25 \n", + "26 particle BB-PDha 26 \n", + "27 particle COOH-PDha 27 \n", + "28 particle NH3-PDha 28 \n", + "29 particle BB-PDha 29 \n", + "30 particle COOH-PDha 30 \n", + "31 particle NH3-PDha 31 \n", + "\n", + " position fix \\\n", + "0 [11.609340728339449, 6.583176596280784, 12.878... [False, False, False] \n", + "1 [10.460520435890457, 1.4126602183147428, 14.63... [False, False, False] \n", + "2 [11.417095529855294, 11.790964579154306, 1.921... [False, False, False] \n", + "3 [6.755789068433506, 5.561970363488718, 13.9014... [False, False, False] \n", + "4 [9.657976801209967, 12.341424199062448, 6.6512... [False, False, False] \n", + "5 [3.408580826771653, 8.318771805237521, 0.95725... [False, False, False] \n", + "6 [12.41446757988873, 9.474965986830972, 11.3713... [False, False, False] \n", + "7 [5.3178895219480244, 14.560470365923548, 13.39... [False, False, False] \n", + "8 [11.675752456106427, 2.919580617779513, 7.0008... [False, False, False] \n", + "9 [0.6570564868084315, 2.3143423810132173, 10.24... [False, False, False] \n", + "10 [11.171432338617256, 14.512645986513148, 4.887... [False, False, False] \n", + "11 [5.556895590523033, 7.043337169137118, 2.84207... [False, False, False] \n", + "12 [1.9488225800320744, 7.135573893389005, 3.4036... [False, False, False] \n", + "13 [10.047209920237654, 6.557278783084961, 12.490... [False, False, False] \n", + "14 [10.503976530033736, 4.685499620730615, 12.483... [False, False, False] \n", + "15 [12.071465362452027, 5.812175685452616, 4.3249... [False, False, False] \n", + "16 [10.237432559624631, 2.096287254139647, 2.9986... [False, False, False] \n", + "17 [0.11043404626508267, 11.803865662532074, 9.97... [False, False, False] \n", + "18 [10.577480679395025, 11.710935465329516, 6.883... [False, False, False] \n", + "19 [8.531117939293406, 2.0969549719148612, 1.7179... [False, False, False] \n", + "20 [7.499999999999999, 7.499999999999999, 7.49999... [False, False, False] \n", + "21 [6.898824919599952, 7.881760682233023, 8.02895... [False, False, False] \n", + "22 [8.137870547785395, 7.97490337881395, 7.445064... [False, False, False] \n", + "23 [7.160907281551002, 7.879214991841518, 6.84092... [False, False, False] \n", + "24 [6.943630111611255, 8.571635891712093, 7.35111... [False, False, False] \n", + "25 [6.726674552857768, 7.228064210684457, 6.68968... [False, False, False] \n", + "26 [6.821814563102005, 8.258429983683039, 6.18184... [False, False, False] \n", + "27 [7.190700895656628, 9.025057023826212, 6.43315... [False, False, False] \n", + "28 [6.246753526388499, 8.554250283754568, 6.64792... [False, False, False] \n", + "29 [6.482721844653008, 8.637644975524559, 5.52277... [False, False, False] \n", + "30 [6.93253697328386, 9.377201114906299, 5.716863... [False, False, False] \n", + "31 [6.492959901480784, 7.949057245973125, 5.12130... [False, False, False] \n", + "\n", + " initial_state residue_id molecule_id assembly_id \n", + "0 Na \n", + "1 Na \n", + "2 Na \n", + "3 Na \n", + "4 Na \n", + "5 Na \n", + "6 Na \n", + "7 Na \n", + "8 Na \n", + "9 Na \n", + "10 Na \n", + "11 Na \n", + "12 Na \n", + "13 Na \n", + "14 Na \n", + "15 Na \n", + "16 Na \n", + "17 Na \n", + "18 Na \n", + "19 Na \n", + "20 BB-PDha 0 0 \n", + "21 COOH-PDha 0 0 \n", + "22 NH3-PDha 0 0 \n", + "23 BB-PDha 1 0 \n", + "24 COOH-PDha 1 0 \n", + "25 NH3-PDha 1 0 \n", + "26 BB-PDha 2 0 \n", + "27 COOH-PDha 2 0 \n", + "28 NH3-PDha 2 0 \n", + "29 BB-PDha 3 0 \n", + "30 COOH-PDha 3 0 \n", + "31 NH3-PDha 3 0 " ] }, - "execution_count": 16, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "pmb.get_templates_df(pmb_type = 'molecule')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "After defining a template for the polymer, we are ready to create one PdHa polymer in the center of the simulation box." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "N_polymers = 1\n", - "\n", - "molecule_ids = pmb.create_molecule(name = PDha_polymer, \n", - " number_of_molecules = N_polymers,\n", - " box_l = box_l, \n", - " list_of_first_residue_positions = [[Box_L.to('reduced_length').magnitude/2]*3]) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "All instances of particles, residues, bonds and molecules created into ESPResSo are bookkept in the pyMBE database:" + "# Check particle instances\n", + "pmb.get_instances_df(pmb_type = 'particle')\n", + "\n" ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 23, "metadata": {}, "outputs": [ { @@ -1389,132 +2243,156 @@ " \n", " pmb_type\n", " name\n", - " particle_id\n", - " position\n", - " fix\n", - " initial_state\n", - " residue_id\n", - " molecule_id\n", - " assembly_id\n", + " bond_id\n", + " particle_id1\n", + " particle_id2\n", + " added_to_engine\n", " \n", " \n", " \n", " \n", " 0\n", - " particle\n", - " BB-PDha\n", - " 0\n", - " [7.499999999999999, 7.499999999999999, 7.49999...\n", - " None\n", - " BB-PDha\n", - " 0\n", + " bond\n", + " BB-PDha-COOH-PDha\n", " 0\n", - " <NA>\n", + " 20\n", + " 21\n", + " False\n", " \n", " \n", " 1\n", - " particle\n", - " COOH-PDha\n", + " bond\n", + " BB-PDha-NH3-PDha\n", " 1\n", - " [7.770562720511088, 7.059202339683819, 6.77927...\n", - " None\n", - " COOH-PDha\n", - " 0\n", - " 0\n", - " <NA>\n", + " 20\n", + " 22\n", + " False\n", " \n", " \n", " 2\n", - " particle\n", - " NH3-PDha\n", + " bond\n", + " BB-PDha-COOH-PDha\n", " 2\n", - " [7.749050564056614, 7.106238951223266, 6.85319...\n", - " None\n", - " NH3-PDha\n", - " 0\n", - " 0\n", - " <NA>\n", + " 23\n", + " 24\n", + " False\n", " \n", " \n", " 3\n", - " particle\n", - " BB-PDha\n", + " bond\n", + " BB-PDha-NH3-PDha\n", " 3\n", - " [7.692460718229277, 6.8431412239990514, 7.9739...\n", - " None\n", - " BB-PDha\n", - " 1\n", - " 0\n", - " <NA>\n", + " 23\n", + " 25\n", + " False\n", " \n", " \n", " 4\n", - " particle\n", - " COOH-PDha\n", + " bond\n", + " BB-PDha-BB-PDha\n", " 4\n", - " [7.2107917459456745, 7.181071829992744, 8.6378...\n", - " None\n", - " COOH-PDha\n", - " 1\n", - " 0\n", - " <NA>\n", + " 20\n", + " 23\n", + " False\n", " \n", " \n", " 5\n", - " particle\n", - " NH3-PDha\n", + " bond\n", + " BB-PDha-COOH-PDha\n", " 5\n", - " [7.847768489420128, 7.330068748851457, 8.58571...\n", - " None\n", - " NH3-PDha\n", - " 1\n", - " 0\n", - " <NA>\n", + " 26\n", + " 27\n", + " False\n", + " \n", + " \n", + " 6\n", + " bond\n", + " BB-PDha-NH3-PDha\n", + " 6\n", + " 26\n", + " 28\n", + " False\n", + " \n", + " \n", + " 7\n", + " bond\n", + " BB-PDha-BB-PDha\n", + " 7\n", + " 23\n", + " 26\n", + " False\n", + " \n", + " \n", + " 8\n", + " bond\n", + " BB-PDha-COOH-PDha\n", + " 8\n", + " 29\n", + " 30\n", + " False\n", + " \n", + " \n", + " 9\n", + " bond\n", + " BB-PDha-NH3-PDha\n", + " 9\n", + " 29\n", + " 31\n", + " False\n", + " \n", + " \n", + " 10\n", + " bond\n", + " BB-PDha-BB-PDha\n", + " 10\n", + " 26\n", + " 29\n", + " False\n", " \n", " \n", "\n", "" ], "text/plain": [ - " pmb_type name particle_id \\\n", - "0 particle BB-PDha 0 \n", - "1 particle COOH-PDha 1 \n", - "2 particle NH3-PDha 2 \n", - "3 particle BB-PDha 3 \n", - "4 particle COOH-PDha 4 \n", - "5 particle NH3-PDha 5 \n", - "\n", - " position fix initial_state \\\n", - "0 [7.499999999999999, 7.499999999999999, 7.49999... None BB-PDha \n", - "1 [7.770562720511088, 7.059202339683819, 6.77927... None COOH-PDha \n", - "2 [7.749050564056614, 7.106238951223266, 6.85319... None NH3-PDha \n", - "3 [7.692460718229277, 6.8431412239990514, 7.9739... None BB-PDha \n", - "4 [7.2107917459456745, 7.181071829992744, 8.6378... None COOH-PDha \n", - "5 [7.847768489420128, 7.330068748851457, 8.58571... None NH3-PDha \n", + " pmb_type name bond_id particle_id1 particle_id2 \\\n", + "0 bond BB-PDha-COOH-PDha 0 20 21 \n", + "1 bond BB-PDha-NH3-PDha 1 20 22 \n", + "2 bond BB-PDha-COOH-PDha 2 23 24 \n", + "3 bond BB-PDha-NH3-PDha 3 23 25 \n", + "4 bond BB-PDha-BB-PDha 4 20 23 \n", + "5 bond BB-PDha-COOH-PDha 5 26 27 \n", + "6 bond BB-PDha-NH3-PDha 6 26 28 \n", + "7 bond BB-PDha-BB-PDha 7 23 26 \n", + "8 bond BB-PDha-COOH-PDha 8 29 30 \n", + "9 bond BB-PDha-NH3-PDha 9 29 31 \n", + "10 bond BB-PDha-BB-PDha 10 26 29 \n", "\n", - " residue_id molecule_id assembly_id \n", - "0 0 0 \n", - "1 0 0 \n", - "2 0 0 \n", - "3 1 0 \n", - "4 1 0 \n", - "5 1 0 " + " added_to_engine \n", + "0 False \n", + "1 False \n", + "2 False \n", + "3 False \n", + "4 False \n", + "5 False \n", + "6 False \n", + "7 False \n", + "8 False \n", + "9 False \n", + "10 False " ] }, - "execution_count": 18, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# Check particle instances\n", - "pmb.get_instances_df(pmb_type = 'particle')\n", - "\n" + "pmb.get_instances_df(pmb_type='bond')" ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 24, "metadata": {}, "outputs": [ { @@ -1540,77 +2418,69 @@ " \n", " pmb_type\n", " name\n", - " bond_id\n", - " particle_id1\n", - " particle_id2\n", + " residue_id\n", + " molecule_id\n", + " assembly_id\n", " \n", " \n", " \n", " \n", " 0\n", - " bond\n", - " BB-PDha-COOH-PDha\n", + " residue\n", + " PDha_mon\n", " 0\n", " 0\n", - " 1\n", + " <NA>\n", " \n", " \n", " 1\n", - " bond\n", - " BB-PDha-NH3-PDha\n", + " residue\n", + " PDha_mon\n", " 1\n", " 0\n", - " 2\n", + " <NA>\n", " \n", " \n", " 2\n", - " bond\n", - " BB-PDha-COOH-PDha\n", + " residue\n", + " PDha_mon\n", " 2\n", - " 3\n", - " 4\n", + " 0\n", + " <NA>\n", " \n", " \n", " 3\n", - " bond\n", - " BB-PDha-NH3-PDha\n", - " 3\n", + " residue\n", + " PDha_mon\n", " 3\n", - " 5\n", - " \n", - " \n", - " 4\n", - " bond\n", - " BB-PDha-BB-PDha\n", - " 4\n", " 0\n", - " 3\n", + " <NA>\n", " \n", " \n", "\n", "" ], "text/plain": [ - " pmb_type name bond_id particle_id1 particle_id2\n", - "0 bond BB-PDha-COOH-PDha 0 0 1\n", - "1 bond BB-PDha-NH3-PDha 1 0 2\n", - "2 bond BB-PDha-COOH-PDha 2 3 4\n", - "3 bond BB-PDha-NH3-PDha 3 3 5\n", - "4 bond BB-PDha-BB-PDha 4 0 3" + " pmb_type name residue_id molecule_id assembly_id\n", + "0 residue PDha_mon 0 0 \n", + "1 residue PDha_mon 1 0 \n", + "2 residue PDha_mon 2 0 \n", + "3 residue PDha_mon 3 0 " ] }, - "execution_count": 19, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "pmb.get_instances_df(pmb_type='bond')" + "# Check residue instances\n", + "pmb.get_instances_df(pmb_type = 'residue')" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 25, "metadata": {}, "outputs": [ { @@ -1636,7 +2506,6 @@ " \n", " pmb_type\n", " name\n", - " residue_id\n", " molecule_id\n", " assembly_id\n", " \n", @@ -1644,17 +2513,8 @@ " \n", " \n", " 0\n", - " residue\n", - " PDha_mon\n", - " 0\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 1\n", - " residue\n", - " PDha_mon\n", - " 1\n", + " molecule\n", + " PDha\n", " 0\n", " <NA>\n", " \n", @@ -1663,24 +2523,60 @@ "" ], "text/plain": [ - " pmb_type name residue_id molecule_id assembly_id\n", - "0 residue PDha_mon 0 0 \n", - "1 residue PDha_mon 1 0 " + " pmb_type name molecule_id assembly_id\n", + "0 molecule PDha 0 " ] }, - "execution_count": 20, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# Check residue instances\n", - "pmb.get_instances_df(pmb_type = 'residue')" + "# Check molecule instances\n", + "pmb.get_instances_df(pmb_type = 'molecule')" ] }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.set_simulation_engine(espresso_system)\n", + "pmb.add_instances_to_engine()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, let us see what we have created..." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "picture_name = 'PDha_system.png'\n", + "create_snapshot_of_espresso_system(espresso_system = espresso_system, \n", + " filename = picture_name)\n", + "img = Image.open(picture_name)\n", + "img.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Delete the particles and check that there are no particle instances in the pyMBE database" + ] + }, + { + "cell_type": "code", + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -1706,16 +2602,254 @@ " \n", " pmb_type\n", " name\n", + " particle_id\n", + " position\n", + " fix\n", + " initial_state\n", + " residue_id\n", " molecule_id\n", " assembly_id\n", " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " 0\n", + " particle\n", + " Na\n", + " 0\n", + " [11.609340728339449, 6.583176596280784, 12.878...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 1\n", + " particle\n", + " Na\n", + " 1\n", + " [10.460520435890457, 1.4126602183147428, 14.63...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 2\n", + " particle\n", + " Na\n", + " 2\n", + " [11.417095529855294, 11.790964579154306, 1.921...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 3\n", + " particle\n", + " Na\n", + " 3\n", + " [6.755789068433506, 5.561970363488718, 13.9014...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 4\n", + " particle\n", + " Na\n", + " 4\n", + " [9.657976801209967, 12.341424199062448, 6.6512...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 5\n", + " particle\n", + " Na\n", + " 5\n", + " [3.408580826771653, 8.318771805237521, 0.95725...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 6\n", + " particle\n", + " Na\n", + " 6\n", + " [12.41446757988873, 9.474965986830972, 11.3713...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 7\n", + " particle\n", + " Na\n", + " 7\n", + " [5.3178895219480244, 14.560470365923548, 13.39...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 8\n", + " particle\n", + " Na\n", + " 8\n", + " [11.675752456106427, 2.919580617779513, 7.0008...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 9\n", + " particle\n", + " Na\n", + " 9\n", + " [0.6570564868084315, 2.3143423810132173, 10.24...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 10\n", + " particle\n", + " Na\n", + " 10\n", + " [11.171432338617256, 14.512645986513148, 4.887...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 11\n", + " particle\n", + " Na\n", + " 11\n", + " [5.556895590523033, 7.043337169137118, 2.84207...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 12\n", + " particle\n", + " Na\n", + " 12\n", + " [1.9488225800320744, 7.135573893389005, 3.4036...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 13\n", + " particle\n", + " Na\n", + " 13\n", + " [10.047209920237654, 6.557278783084961, 12.490...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 14\n", + " particle\n", + " Na\n", + " 14\n", + " [10.503976530033736, 4.685499620730615, 12.483...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 15\n", + " particle\n", + " Na\n", + " 15\n", + " [12.071465362452027, 5.812175685452616, 4.3249...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 16\n", + " particle\n", + " Na\n", + " 16\n", + " [10.237432559624631, 2.096287254139647, 2.9986...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", " \n", - " 0\n", - " molecule\n", - " PDha\n", - " 0\n", + " 17\n", + " particle\n", + " Na\n", + " 17\n", + " [0.11043404626508267, 11.803865662532074, 9.97...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 18\n", + " particle\n", + " Na\n", + " 18\n", + " [10.577480679395025, 11.710935465329516, 6.883...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", + " <NA>\n", + " \n", + " \n", + " 19\n", + " particle\n", + " Na\n", + " 19\n", + " [8.531117939293406, 2.0969549719148612, 1.7179...\n", + " [False, False, False]\n", + " Na\n", + " <NA>\n", + " <NA>\n", " <NA>\n", " \n", " \n", @@ -1723,105 +2857,81 @@ "" ], "text/plain": [ - " pmb_type name molecule_id assembly_id\n", - "0 molecule PDha 0 " - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Check molecule instances\n", - "pmb.get_instances_df(pmb_type = 'molecule')" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [], - "source": [ - "pmb.set_simulation_engine(espresso_system)\n", - "pmb.add_instances_to_engine()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, let us see what we have created..." - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [], - "source": [ - "picture_name = 'PDha_system.png'\n", - "create_snapshot_of_espresso_system(espresso_system = espresso_system, \n", - " filename = picture_name)\n", - "img = Image.open(picture_name)\n", - "img.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Delete the particles and check that there are no particle instances in the pyMBE database" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
\n", - "
" - ], - "text/plain": [ - "Empty DataFrame\n", - "Columns: []\n", - "Index: []" + " initial_state residue_id molecule_id assembly_id \n", + "0 Na \n", + "1 Na \n", + "2 Na \n", + "3 Na \n", + "4 Na \n", + "5 Na \n", + "6 Na \n", + "7 Na \n", + "8 Na \n", + "9 Na \n", + "10 Na \n", + "11 Na \n", + "12 Na \n", + "13 Na \n", + "14 Na \n", + "15 Na \n", + "16 Na \n", + "17 Na \n", + "18 Na \n", + "19 Na " ] }, - "execution_count": 25, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pmb.delete_instances_in_system(instance_id=molecule_ids[0],\n", - " pmb_type=\"molecule\", \n", - " espresso_system = espresso_system)\n", + " pmb_type=\"molecule\")\n", "# Check particle instances\n", "pmb.get_instances_df(pmb_type = 'particle')" ] @@ -1836,8 +2946,7 @@ "# This will delete all particles that we created before\n", "for pid in particle_id_map[\"all\"]:\n", " pmb.delete_instances_in_system(instance_id=pid, \n", - " pmb_type=\"particle\",\n", - " espresso_system = espresso_system)" + " pmb_type=\"particle\")" ] }, { @@ -1865,7 +2974,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 32, "metadata": {}, "outputs": [], "source": [ @@ -1905,7 +3014,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 33, "metadata": {}, "outputs": [], "source": [ @@ -1925,7 +3034,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 34, "metadata": {}, "outputs": [], "source": [ @@ -1944,7 +3053,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 35, "metadata": {}, "outputs": [], "source": [ @@ -1980,7 +3089,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 36, "metadata": {}, "outputs": [], "source": [ @@ -2000,7 +3109,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 37, "metadata": {}, "outputs": [], "source": [ @@ -2014,7 +3123,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 38, "metadata": {}, "outputs": [ { @@ -2056,7 +3165,7 @@ " BB-PDAGA\n", " 0\n", " [7.499999999999999, 7.499999999999999, 7.49999...\n", - " None\n", + " [False, False, False]\n", " BB-PDAGA\n", " 0\n", " 0\n", @@ -2067,8 +3176,8 @@ " particle\n", " NH3-PDAGA\n", " 1\n", - " [8.006035046780134, 6.983156096845676, 7.83500...\n", - " None\n", + " [7.880814267857025, 7.910176242823781, 8.06759...\n", + " [False, False, False]\n", " NH3-PDAGA\n", " 0\n", " 0\n", @@ -2079,8 +3188,8 @@ " particle\n", " aCOOH-PDAGA\n", " 2\n", - " [7.228892589749606, 6.828507543870596, 7.91016...\n", - " None\n", + " [7.703407151110378, 7.147666585308814, 7.92399...\n", + " [False, False, False]\n", " aCOOH-PDAGA\n", " 0\n", " 0\n", @@ -2091,8 +3200,8 @@ " particle\n", " bCOOH-PDAGA\n", " 3\n", - " [8.390296523191001, 7.449356309621872, 8.35503...\n", - " None\n", + " [7.360821755419828, 7.464213880431073, 7.65997...\n", + " [False, False, False]\n", " bCOOH-PDAGA\n", " 0\n", " 0\n", @@ -2103,8 +3212,8 @@ " particle\n", " BB-PDAGA\n", " 4\n", - " [7.033629851553653, 6.866558505888692, 7.22719...\n", - " None\n", + " [8.099326782445562, 6.9222971413656, 7.5153767...\n", + " [False, False, False]\n", " BB-PDAGA\n", " 1\n", " 0\n", @@ -2115,8 +3224,8 @@ " particle\n", " NH3-PDAGA\n", " 5\n", - " [6.874476454747638, 6.659394433454941, 7.98031...\n", - " None\n", + " [7.8795304975820475, 6.67497036026838, 6.79015...\n", + " [False, False, False]\n", " NH3-PDAGA\n", " 1\n", " 0\n", @@ -2127,8 +3236,8 @@ " particle\n", " aCOOH-PDAGA\n", " 6\n", - " [6.785798310596719, 6.068056544244533, 7.45498...\n", - " None\n", + " [7.664421253102207, 7.414007090791623, 6.58750...\n", + " [False, False, False]\n", " aCOOH-PDAGA\n", " 1\n", " 0\n", @@ -2139,8 +3248,8 @@ " particle\n", " bCOOH-PDAGA\n", " 7\n", - " [6.179699453438731, 7.035070100567888, 8.08793...\n", - " None\n", + " [8.366452812103642, 6.058577566590047, 6.65451...\n", + " [False, False, False]\n", " bCOOH-PDAGA\n", " 1\n", " 0\n", @@ -2151,8 +3260,8 @@ " particle\n", " BB-PDAGA\n", " 8\n", - " [6.567259703107307, 6.233117011777386, 6.95439...\n", - " None\n", + " [8.698653564891124, 6.3445942827312, 7.5307535...\n", + " [False, False, False]\n", " BB-PDAGA\n", " 2\n", " 0\n", @@ -2163,8 +3272,8 @@ " particle\n", " NH3-PDAGA\n", " 9\n", - " [7.17699479917509, 5.733385942628339, 7.072389...\n", - " None\n", + " [8.288142706210909, 5.933240394956417, 8.07637...\n", + " [False, False, False]\n", " NH3-PDAGA\n", " 2\n", " 0\n", @@ -2175,8 +3284,8 @@ " particle\n", " aCOOH-PDAGA\n", " 10\n", - " [7.773970921102857, 5.43818879862679, 7.508271...\n", - " None\n", + " [7.523029527750901, 6.125667492007267, 8.18167...\n", + " [False, False, False]\n", " aCOOH-PDAGA\n", " 2\n", " 0\n", @@ -2187,8 +3296,8 @@ " particle\n", " bCOOH-PDAGA\n", " 11\n", - " [6.553282284209572, 5.391291436792669, 6.71268...\n", - " None\n", + " [7.985514841088506, 5.196696704056294, 8.11311...\n", + " [False, False, False]\n", " bCOOH-PDAGA\n", " 2\n", " 0\n", @@ -2199,8 +3308,8 @@ " particle\n", " BB-PDAGA\n", " 12\n", - " [6.10088955466096, 5.59967551766608, 6.6815969...\n", - " None\n", + " [9.297980347336686, 5.7668914240968006, 7.5461...\n", + " [False, False, False]\n", " BB-PDAGA\n", " 3\n", " 0\n", @@ -2211,8 +3320,8 @@ " particle\n", " NH3-PDAGA\n", " 13\n", - " [5.521927644541596, 6.110879482807433, 6.48435...\n", - " None\n", + " [8.749995437793478, 5.2017343109241185, 7.6715...\n", + " [False, False, False]\n", " NH3-PDAGA\n", " 3\n", " 0\n", @@ -2223,8 +3332,8 @@ " particle\n", " aCOOH-PDAGA\n", " 14\n", - " [5.537081221656859, 6.693956347003686, 7.02593...\n", - " None\n", + " [9.41544713832268, 5.102295112295519, 7.246381...\n", + " [False, False, False]\n", " aCOOH-PDAGA\n", " 3\n", " 0\n", @@ -2235,8 +3344,8 @@ " particle\n", " bCOOH-PDAGA\n", " 15\n", - " [6.1893175157746745, 6.012097267908542, 6.0597...\n", - " None\n", + " [8.852917761630236, 5.328034630296977, 8.45190...\n", + " [False, False, False]\n", " bCOOH-PDAGA\n", " 3\n", " 0\n", @@ -2265,44 +3374,44 @@ "14 particle aCOOH-PDAGA 14 \n", "15 particle bCOOH-PDAGA 15 \n", "\n", - " position fix initial_state \\\n", - "0 [7.499999999999999, 7.499999999999999, 7.49999... None BB-PDAGA \n", - "1 [8.006035046780134, 6.983156096845676, 7.83500... None NH3-PDAGA \n", - "2 [7.228892589749606, 6.828507543870596, 7.91016... None aCOOH-PDAGA \n", - "3 [8.390296523191001, 7.449356309621872, 8.35503... None bCOOH-PDAGA \n", - "4 [7.033629851553653, 6.866558505888692, 7.22719... None BB-PDAGA \n", - "5 [6.874476454747638, 6.659394433454941, 7.98031... None NH3-PDAGA \n", - "6 [6.785798310596719, 6.068056544244533, 7.45498... None aCOOH-PDAGA \n", - "7 [6.179699453438731, 7.035070100567888, 8.08793... None bCOOH-PDAGA \n", - "8 [6.567259703107307, 6.233117011777386, 6.95439... None BB-PDAGA \n", - "9 [7.17699479917509, 5.733385942628339, 7.072389... None NH3-PDAGA \n", - "10 [7.773970921102857, 5.43818879862679, 7.508271... None aCOOH-PDAGA \n", - "11 [6.553282284209572, 5.391291436792669, 6.71268... None bCOOH-PDAGA \n", - "12 [6.10088955466096, 5.59967551766608, 6.6815969... None BB-PDAGA \n", - "13 [5.521927644541596, 6.110879482807433, 6.48435... None NH3-PDAGA \n", - "14 [5.537081221656859, 6.693956347003686, 7.02593... None aCOOH-PDAGA \n", - "15 [6.1893175157746745, 6.012097267908542, 6.0597... None bCOOH-PDAGA \n", + " position fix \\\n", + "0 [7.499999999999999, 7.499999999999999, 7.49999... [False, False, False] \n", + "1 [7.880814267857025, 7.910176242823781, 8.06759... [False, False, False] \n", + "2 [7.703407151110378, 7.147666585308814, 7.92399... [False, False, False] \n", + "3 [7.360821755419828, 7.464213880431073, 7.65997... [False, False, False] \n", + "4 [8.099326782445562, 6.9222971413656, 7.5153767... [False, False, False] \n", + "5 [7.8795304975820475, 6.67497036026838, 6.79015... [False, False, False] \n", + "6 [7.664421253102207, 7.414007090791623, 6.58750... [False, False, False] \n", + "7 [8.366452812103642, 6.058577566590047, 6.65451... [False, False, False] \n", + "8 [8.698653564891124, 6.3445942827312, 7.5307535... [False, False, False] \n", + "9 [8.288142706210909, 5.933240394956417, 8.07637... [False, False, False] \n", + "10 [7.523029527750901, 6.125667492007267, 8.18167... [False, False, False] \n", + "11 [7.985514841088506, 5.196696704056294, 8.11311... [False, False, False] \n", + "12 [9.297980347336686, 5.7668914240968006, 7.5461... [False, False, False] \n", + "13 [8.749995437793478, 5.2017343109241185, 7.6715... [False, False, False] \n", + "14 [9.41544713832268, 5.102295112295519, 7.246381... [False, False, False] \n", + "15 [8.852917761630236, 5.328034630296977, 8.45190... [False, False, False] \n", "\n", - " residue_id molecule_id assembly_id \n", - "0 0 0 \n", - "1 0 0 \n", - "2 0 0 \n", - "3 0 0 \n", - "4 1 0 \n", - "5 1 0 \n", - "6 1 0 \n", - "7 1 0 \n", - "8 2 0 \n", - "9 2 0 \n", - "10 2 0 \n", - "11 2 0 \n", - "12 3 0 \n", - "13 3 0 \n", - "14 3 0 \n", - "15 3 0 " + " initial_state residue_id molecule_id assembly_id \n", + "0 BB-PDAGA 0 0 \n", + "1 NH3-PDAGA 0 0 \n", + "2 aCOOH-PDAGA 0 0 \n", + "3 bCOOH-PDAGA 0 0 \n", + "4 BB-PDAGA 1 0 \n", + "5 NH3-PDAGA 1 0 \n", + "6 aCOOH-PDAGA 1 0 \n", + "7 bCOOH-PDAGA 1 0 \n", + "8 BB-PDAGA 2 0 \n", + "9 NH3-PDAGA 2 0 \n", + "10 aCOOH-PDAGA 2 0 \n", + "11 bCOOH-PDAGA 2 0 \n", + "12 BB-PDAGA 3 0 \n", + "13 NH3-PDAGA 3 0 \n", + "14 aCOOH-PDAGA 3 0 \n", + "15 bCOOH-PDAGA 3 0 " ] }, - "execution_count": 40, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } @@ -2313,7 +3422,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 39, "metadata": {}, "outputs": [ { @@ -2389,7 +3498,7 @@ "3 residue PDAGA_monomer_residue 3 0 " ] }, - "execution_count": 41, + "execution_count": 39, "metadata": {}, "output_type": "execute_result" } @@ -2400,7 +3509,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 40, "metadata": {}, "outputs": [ { @@ -2429,6 +3538,7 @@ " bond_id\n", " particle_id1\n", " particle_id2\n", + " added_to_engine\n", " \n", " \n", " \n", @@ -2439,6 +3549,7 @@ " 0\n", " 1\n", " 2\n", + " False\n", " \n", " \n", " 1\n", @@ -2447,6 +3558,7 @@ " 1\n", " 1\n", " 3\n", + " False\n", " \n", " \n", " 2\n", @@ -2455,6 +3567,7 @@ " 2\n", " 0\n", " 1\n", + " False\n", " \n", " \n", " 3\n", @@ -2463,6 +3576,7 @@ " 3\n", " 5\n", " 6\n", + " False\n", " \n", " \n", " 4\n", @@ -2471,6 +3585,7 @@ " 4\n", " 5\n", " 7\n", + " False\n", " \n", " \n", " 5\n", @@ -2479,6 +3594,7 @@ " 5\n", " 4\n", " 5\n", + " False\n", " \n", " \n", " 6\n", @@ -2487,6 +3603,7 @@ " 6\n", " 0\n", " 4\n", + " False\n", " \n", " \n", " 7\n", @@ -2495,6 +3612,7 @@ " 7\n", " 9\n", " 10\n", + " False\n", " \n", " \n", " 8\n", @@ -2503,6 +3621,7 @@ " 8\n", " 9\n", " 11\n", + " False\n", " \n", " \n", " 9\n", @@ -2511,6 +3630,7 @@ " 9\n", " 8\n", " 9\n", + " False\n", " \n", " \n", " 10\n", @@ -2519,6 +3639,7 @@ " 10\n", " 4\n", " 8\n", + " False\n", " \n", " \n", " 11\n", @@ -2527,6 +3648,7 @@ " 11\n", " 13\n", " 14\n", + " False\n", " \n", " \n", " 12\n", @@ -2535,6 +3657,7 @@ " 12\n", " 13\n", " 15\n", + " False\n", " \n", " \n", " 13\n", @@ -2543,6 +3666,7 @@ " 13\n", " 12\n", " 13\n", + " False\n", " \n", " \n", " 14\n", @@ -2551,31 +3675,49 @@ " 14\n", " 8\n", " 12\n", + " False\n", " \n", " \n", "\n", "" ], "text/plain": [ - " pmb_type name bond_id particle_id1 particle_id2\n", - "0 bond NH3-PDAGA-aCOOH-PDAGA 0 1 2\n", - "1 bond NH3-PDAGA-bCOOH-PDAGA 1 1 3\n", - "2 bond BB-PDAGA-NH3-PDAGA 2 0 1\n", - "3 bond NH3-PDAGA-aCOOH-PDAGA 3 5 6\n", - "4 bond NH3-PDAGA-bCOOH-PDAGA 4 5 7\n", - "5 bond BB-PDAGA-NH3-PDAGA 5 4 5\n", - "6 bond BB-PDAGA-BB-PDAGA 6 0 4\n", - "7 bond NH3-PDAGA-aCOOH-PDAGA 7 9 10\n", - "8 bond NH3-PDAGA-bCOOH-PDAGA 8 9 11\n", - "9 bond BB-PDAGA-NH3-PDAGA 9 8 9\n", - "10 bond BB-PDAGA-BB-PDAGA 10 4 8\n", - "11 bond NH3-PDAGA-aCOOH-PDAGA 11 13 14\n", - "12 bond NH3-PDAGA-bCOOH-PDAGA 12 13 15\n", - "13 bond BB-PDAGA-NH3-PDAGA 13 12 13\n", - "14 bond BB-PDAGA-BB-PDAGA 14 8 12" + " pmb_type name bond_id particle_id1 particle_id2 \\\n", + "0 bond NH3-PDAGA-aCOOH-PDAGA 0 1 2 \n", + "1 bond NH3-PDAGA-bCOOH-PDAGA 1 1 3 \n", + "2 bond BB-PDAGA-NH3-PDAGA 2 0 1 \n", + "3 bond NH3-PDAGA-aCOOH-PDAGA 3 5 6 \n", + "4 bond NH3-PDAGA-bCOOH-PDAGA 4 5 7 \n", + "5 bond BB-PDAGA-NH3-PDAGA 5 4 5 \n", + "6 bond BB-PDAGA-BB-PDAGA 6 0 4 \n", + "7 bond NH3-PDAGA-aCOOH-PDAGA 7 9 10 \n", + "8 bond NH3-PDAGA-bCOOH-PDAGA 8 9 11 \n", + "9 bond BB-PDAGA-NH3-PDAGA 9 8 9 \n", + "10 bond BB-PDAGA-BB-PDAGA 10 4 8 \n", + "11 bond NH3-PDAGA-aCOOH-PDAGA 11 13 14 \n", + "12 bond NH3-PDAGA-bCOOH-PDAGA 12 13 15 \n", + "13 bond BB-PDAGA-NH3-PDAGA 13 12 13 \n", + "14 bond BB-PDAGA-BB-PDAGA 14 8 12 \n", + "\n", + " added_to_engine \n", + "0 False \n", + "1 False \n", + "2 False \n", + "3 False \n", + "4 False \n", + "5 False \n", + "6 False \n", + "7 False \n", + "8 False \n", + "9 False \n", + "10 False \n", + "11 False \n", + "12 False \n", + "13 False \n", + "14 False " ] }, - "execution_count": 42, + "execution_count": 40, "metadata": {}, "output_type": "execute_result" } @@ -2586,7 +3728,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 41, "metadata": {}, "outputs": [], "source": [ @@ -2603,7 +3745,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 42, "metadata": {}, "outputs": [], "source": [ @@ -2623,7 +3765,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 44, "metadata": {}, "outputs": [ { @@ -2660,7 +3802,7 @@ "Index: []" ] }, - "execution_count": 37, + "execution_count": 44, "metadata": {}, "output_type": "execute_result" } @@ -2669,8 +3811,7 @@ "\n", "for mol_id in mol_ids:\n", " pmb.delete_instances_in_system(instance_id=mol_id,\n", - " pmb_type=\"molecule\",\n", - " espresso_system=espresso_system)\n", + " pmb_type=\"molecule\")\n", "pmb.get_instances_df(pmb_type = 'particle')" ] }, @@ -2699,7 +3840,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 45, "metadata": {}, "outputs": [], "source": [ @@ -2718,7 +3859,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 46, "metadata": {}, "outputs": [], "source": [ @@ -2739,7 +3880,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 47, "metadata": {}, "outputs": [ { @@ -2781,7 +3922,7 @@ " BB-PDha\n", " 0\n", " [7.499999999999999, 7.499999999999999, 7.49999...\n", - " None\n", + " [False, False, False]\n", " BB-PDha\n", " 0\n", " 0\n", @@ -2792,8 +3933,8 @@ " particle\n", " COOH-PDha\n", " 1\n", - " [7.571167527771879, 7.604628201186956, 8.37803...\n", - " None\n", + " [6.882014811497537, 7.060136570708298, 7.95996...\n", + " [False, False, False]\n", " COOH-PDha\n", " 0\n", " 0\n", @@ -2804,8 +3945,8 @@ " particle\n", " NH3-PDha\n", " 2\n", - " [7.61187816904253, 7.692330966595771, 6.734544...\n", - " None\n", + " [7.285177148531093, 6.791465416767111, 7.79539...\n", + " [False, False, False]\n", " NH3-PDha\n", " 0\n", " 0\n", @@ -2816,8 +3957,8 @@ " particle\n", " BB-PDha\n", " 3\n", - " [8.209680803443417, 7.064694517707376, 7.49434...\n", - " None\n", + " [7.903716808160374, 7.672521739623884, 8.20740...\n", + " [False, False, False]\n", " BB-PDha\n", " 1\n", " 0\n", @@ -2828,8 +3969,8 @@ " particle\n", " COOH-PDha\n", " 4\n", - " [7.96317931944196, 6.672642643457426, 6.737725...\n", - " None\n", + " [8.180114479235312, 6.830918531233496, 8.25491...\n", + " [False, False, False]\n", " COOH-PDha\n", " 1\n", " 0\n", @@ -2840,8 +3981,8 @@ " particle\n", " NH3-PDha\n", " 5\n", - " [7.949794989096124, 6.632984135848388, 8.11201...\n", - " None\n", + " [7.267322603293363, 8.07232460191931, 8.473090...\n", + " [False, False, False]\n", " NH3-PDha\n", " 1\n", " 0\n", @@ -2852,8 +3993,8 @@ " particle\n", " BB-PDha\n", " 6\n", - " [8.919361606886834, 6.629389035414753, 7.48869...\n", - " None\n", + " [8.30743361632075, 7.845043479247768, 8.914805...\n", + " [False, False, False]\n", " BB-PDha\n", " 2\n", " 0\n", @@ -2864,8 +4005,8 @@ " particle\n", " COOH-PDha\n", " 7\n", - " [8.542953602465508, 6.0225607419657345, 6.9623...\n", - " None\n", + " [9.065973263843503, 7.926327346705838, 8.46208...\n", + " [False, False, False]\n", " COOH-PDha\n", " 2\n", " 0\n", @@ -2876,8 +4017,8 @@ " particle\n", " NH3-PDha\n", " 8\n", - " [9.250938657970849, 7.163600709092095, 7.97870...\n", - " None\n", + " [7.639560864585886, 8.154858106740047, 9.22040...\n", + " [False, False, False]\n", " NH3-PDha\n", " 2\n", " 0\n", @@ -2888,8 +4029,8 @@ " particle\n", " BB-PDha\n", " 9\n", - " [9.629042410330252, 6.194083553122129, 7.48304...\n", - " None\n", + " [8.711150424481126, 8.017565218871653, 9.62220...\n", + " [False, False, False]\n", " BB-PDha\n", " 3\n", " 0\n", @@ -2900,8 +4041,8 @@ " particle\n", " COOH-PDha\n", " 10\n", - " [9.920338499649748, 6.677865071931392, 6.79890...\n", - " None\n", + " [8.420714798426259, 7.25654675606315, 9.973558...\n", + " [False, False, False]\n", " COOH-PDha\n", " 3\n", " 0\n", @@ -2912,8 +4053,8 @@ " particle\n", " NH3-PDha\n", " 11\n", - " [9.82370132285253, 6.502235290435076, 8.191978...\n", - " None\n", + " [9.395759771279486, 8.073863280999081, 9.21776...\n", + " [False, False, False]\n", " NH3-PDha\n", " 3\n", " 0\n", @@ -2924,8 +4065,8 @@ " particle\n", " BB-PDAGA\n", " 12\n", - " [10.338723213773669, 5.758778070829506, 7.4773...\n", - " None\n", + " [9.114867232641501, 8.190086958495536, 10.3296...\n", + " [False, False, False]\n", " BB-PDAGA\n", " 4\n", " 0\n", @@ -2936,8 +4077,8 @@ " particle\n", " NH3-PDAGA\n", " 13\n", - " [9.960891826868739, 5.138532624129924, 7.80598...\n", - " None\n", + " [8.902203284857888, 7.480496262888388, 10.6240...\n", + " [False, False, False]\n", " NH3-PDAGA\n", " 4\n", " 0\n", @@ -2948,8 +4089,8 @@ " particle\n", " aCOOH-PDAGA\n", " 14\n", - " [10.5766803499623, 5.597619531889813, 7.597277...\n", - " None\n", + " [8.87806650829381, 8.27391585076135, 10.682499...\n", + " [False, False, False]\n", " aCOOH-PDAGA\n", " 4\n", " 0\n", @@ -2960,8 +4101,8 @@ " particle\n", " bCOOH-PDAGA\n", " 15\n", - " [9.818081425019205, 4.411299358991621, 7.51244...\n", - " None\n", + " [9.386253989715097, 7.234567017453472, 10.0403...\n", + " [False, False, False]\n", " bCOOH-PDAGA\n", " 4\n", " 0\n", @@ -2972,8 +4113,8 @@ " particle\n", " BB-PDAGA\n", " 16\n", - " [11.048404017217086, 5.323472588536883, 7.4717...\n", - " None\n", + " [9.518584040801876, 8.36260869811942, 11.03701...\n", + " [False, False, False]\n", " BB-PDAGA\n", " 5\n", " 0\n", @@ -2984,8 +4125,8 @@ " particle\n", " NH3-PDAGA\n", " 17\n", - " [11.401299152618178, 5.9042080625154485, 7.055...\n", - " None\n", + " [8.943572120033956, 8.000263443775438, 11.4535...\n", + " [False, False, False]\n", " NH3-PDAGA\n", " 5\n", " 0\n", @@ -2996,8 +4137,8 @@ " particle\n", " aCOOH-PDAGA\n", " 18\n", - " [11.169957143049839, 5.144809052085453, 6.9975...\n", - " None\n", + " [8.502098074958806, 8.450929652381193, 10.9682...\n", + " [False, False, False]\n", " aCOOH-PDAGA\n", " 5\n", " 0\n", @@ -3008,8 +4149,8 @@ " particle\n", " bCOOH-PDAGA\n", " 19\n", - " [10.827437362182199, 5.6182320306354745, 6.581...\n", - " None\n", + " [9.671551490730199, 8.301084053842303, 11.3311...\n", + " [False, False, False]\n", " bCOOH-PDAGA\n", " 5\n", " 0\n", @@ -3020,8 +4161,8 @@ " particle\n", " BB-PDAGA\n", " 20\n", - " [11.758084820660503, 4.88816710624426, 7.46609...\n", - " None\n", + " [9.922300848962252, 8.535130437743303, 11.7444...\n", + " [False, False, False]\n", " BB-PDAGA\n", " 6\n", " 0\n", @@ -3032,8 +4173,8 @@ " particle\n", " NH3-PDAGA\n", " 21\n", - " [11.451876185073228, 4.396056855078196, 6.9188...\n", - " None\n", + " [9.766086613096551, 7.80090455938704, 12.01263...\n", + " [False, False, False]\n", " NH3-PDAGA\n", " 6\n", " 0\n", @@ -3044,8 +4185,8 @@ " particle\n", " aCOOH-PDAGA\n", " 22\n", - " [12.075126241658626, 4.019216519310867, 6.5977...\n", - " None\n", + " [9.567999989832561, 7.267311324275074, 11.4562...\n", + " [False, False, False]\n", " aCOOH-PDAGA\n", " 6\n", " 0\n", @@ -3056,8 +4197,8 @@ " particle\n", " bCOOH-PDAGA\n", " 23\n", - " [11.855114840563605, 5.033776247620462, 6.6616...\n", - " None\n", + " [9.85225872249835, 8.589335327303903, 12.09251...\n", + " [False, False, False]\n", " bCOOH-PDAGA\n", " 6\n", " 0\n", @@ -3068,8 +4209,8 @@ " particle\n", " BB-PDAGA\n", " 24\n", - " [12.46776562410392, 4.4528616239516365, 7.4604...\n", - " None\n", + " [10.326017657122627, 8.707652177367187, 12.451...\n", + " [False, False, False]\n", " BB-PDAGA\n", " 7\n", " 0\n", @@ -3080,8 +4221,8 @@ " particle\n", " NH3-PDAGA\n", " 25\n", - " [12.49615134833019, 4.4888094718484215, 8.2562...\n", - " None\n", + " [9.62948770871752, 8.76647867070694, 12.834984...\n", + " [False, False, False]\n", " NH3-PDAGA\n", " 7\n", " 0\n", @@ -3092,8 +4233,8 @@ " particle\n", " aCOOH-PDAGA\n", " 26\n", - " [11.882479934601875, 4.33628485023324, 8.73965...\n", - " None\n", + " [9.774956218875849, 8.494000366005105, 13.5685...\n", + " [False, False, False]\n", " aCOOH-PDAGA\n", " 7\n", " 0\n", @@ -3104,8 +4245,8 @@ " particle\n", " bCOOH-PDAGA\n", " 27\n", - " [13.08328337253056, 3.9808276202572306, 8.0755...\n", - " None\n", + " [9.842436658608339, 9.529237189173736, 12.9259...\n", + " [False, False, False]\n", " bCOOH-PDAGA\n", " 7\n", " 0\n", @@ -3146,68 +4287,68 @@ "26 particle aCOOH-PDAGA 26 \n", "27 particle bCOOH-PDAGA 27 \n", "\n", - " position fix initial_state \\\n", - "0 [7.499999999999999, 7.499999999999999, 7.49999... None BB-PDha \n", - "1 [7.571167527771879, 7.604628201186956, 8.37803... None COOH-PDha \n", - "2 [7.61187816904253, 7.692330966595771, 6.734544... None NH3-PDha \n", - "3 [8.209680803443417, 7.064694517707376, 7.49434... None BB-PDha \n", - "4 [7.96317931944196, 6.672642643457426, 6.737725... None COOH-PDha \n", - "5 [7.949794989096124, 6.632984135848388, 8.11201... None NH3-PDha \n", - "6 [8.919361606886834, 6.629389035414753, 7.48869... None BB-PDha \n", - "7 [8.542953602465508, 6.0225607419657345, 6.9623... None COOH-PDha \n", - "8 [9.250938657970849, 7.163600709092095, 7.97870... None NH3-PDha \n", - "9 [9.629042410330252, 6.194083553122129, 7.48304... None BB-PDha \n", - "10 [9.920338499649748, 6.677865071931392, 6.79890... None COOH-PDha \n", - "11 [9.82370132285253, 6.502235290435076, 8.191978... None NH3-PDha \n", - "12 [10.338723213773669, 5.758778070829506, 7.4773... None BB-PDAGA \n", - "13 [9.960891826868739, 5.138532624129924, 7.80598... None NH3-PDAGA \n", - "14 [10.5766803499623, 5.597619531889813, 7.597277... None aCOOH-PDAGA \n", - "15 [9.818081425019205, 4.411299358991621, 7.51244... None bCOOH-PDAGA \n", - "16 [11.048404017217086, 5.323472588536883, 7.4717... None BB-PDAGA \n", - "17 [11.401299152618178, 5.9042080625154485, 7.055... None NH3-PDAGA \n", - "18 [11.169957143049839, 5.144809052085453, 6.9975... None aCOOH-PDAGA \n", - "19 [10.827437362182199, 5.6182320306354745, 6.581... None bCOOH-PDAGA \n", - "20 [11.758084820660503, 4.88816710624426, 7.46609... None BB-PDAGA \n", - "21 [11.451876185073228, 4.396056855078196, 6.9188... None NH3-PDAGA \n", - "22 [12.075126241658626, 4.019216519310867, 6.5977... None aCOOH-PDAGA \n", - "23 [11.855114840563605, 5.033776247620462, 6.6616... None bCOOH-PDAGA \n", - "24 [12.46776562410392, 4.4528616239516365, 7.4604... None BB-PDAGA \n", - "25 [12.49615134833019, 4.4888094718484215, 8.2562... None NH3-PDAGA \n", - "26 [11.882479934601875, 4.33628485023324, 8.73965... None aCOOH-PDAGA \n", - "27 [13.08328337253056, 3.9808276202572306, 8.0755... None bCOOH-PDAGA \n", + " position fix \\\n", + "0 [7.499999999999999, 7.499999999999999, 7.49999... [False, False, False] \n", + "1 [6.882014811497537, 7.060136570708298, 7.95996... [False, False, False] \n", + "2 [7.285177148531093, 6.791465416767111, 7.79539... [False, False, False] \n", + "3 [7.903716808160374, 7.672521739623884, 8.20740... [False, False, False] \n", + "4 [8.180114479235312, 6.830918531233496, 8.25491... [False, False, False] \n", + "5 [7.267322603293363, 8.07232460191931, 8.473090... [False, False, False] \n", + "6 [8.30743361632075, 7.845043479247768, 8.914805... [False, False, False] \n", + "7 [9.065973263843503, 7.926327346705838, 8.46208... [False, False, False] \n", + "8 [7.639560864585886, 8.154858106740047, 9.22040... [False, False, False] \n", + "9 [8.711150424481126, 8.017565218871653, 9.62220... [False, False, False] \n", + "10 [8.420714798426259, 7.25654675606315, 9.973558... [False, False, False] \n", + "11 [9.395759771279486, 8.073863280999081, 9.21776... [False, False, False] \n", + "12 [9.114867232641501, 8.190086958495536, 10.3296... [False, False, False] \n", + "13 [8.902203284857888, 7.480496262888388, 10.6240... [False, False, False] \n", + "14 [8.87806650829381, 8.27391585076135, 10.682499... [False, False, False] \n", + "15 [9.386253989715097, 7.234567017453472, 10.0403... [False, False, False] \n", + "16 [9.518584040801876, 8.36260869811942, 11.03701... [False, False, False] \n", + "17 [8.943572120033956, 8.000263443775438, 11.4535... [False, False, False] \n", + "18 [8.502098074958806, 8.450929652381193, 10.9682... [False, False, False] \n", + "19 [9.671551490730199, 8.301084053842303, 11.3311... [False, False, False] \n", + "20 [9.922300848962252, 8.535130437743303, 11.7444... [False, False, False] \n", + "21 [9.766086613096551, 7.80090455938704, 12.01263... [False, False, False] \n", + "22 [9.567999989832561, 7.267311324275074, 11.4562... [False, False, False] \n", + "23 [9.85225872249835, 8.589335327303903, 12.09251... [False, False, False] \n", + "24 [10.326017657122627, 8.707652177367187, 12.451... [False, False, False] \n", + "25 [9.62948770871752, 8.76647867070694, 12.834984... [False, False, False] \n", + "26 [9.774956218875849, 8.494000366005105, 13.5685... [False, False, False] \n", + "27 [9.842436658608339, 9.529237189173736, 12.9259... [False, False, False] \n", "\n", - " residue_id molecule_id assembly_id \n", - "0 0 0 \n", - "1 0 0 \n", - "2 0 0 \n", - "3 1 0 \n", - "4 1 0 \n", - "5 1 0 \n", - "6 2 0 \n", - "7 2 0 \n", - "8 2 0 \n", - "9 3 0 \n", - "10 3 0 \n", - "11 3 0 \n", - "12 4 0 \n", - "13 4 0 \n", - "14 4 0 \n", - "15 4 0 \n", - "16 5 0 \n", - "17 5 0 \n", - "18 5 0 \n", - "19 5 0 \n", - "20 6 0 \n", - "21 6 0 \n", - "22 6 0 \n", - "23 6 0 \n", - "24 7 0 \n", - "25 7 0 \n", - "26 7 0 \n", - "27 7 0 " + " initial_state residue_id molecule_id assembly_id \n", + "0 BB-PDha 0 0 \n", + "1 COOH-PDha 0 0 \n", + "2 NH3-PDha 0 0 \n", + "3 BB-PDha 1 0 \n", + "4 COOH-PDha 1 0 \n", + "5 NH3-PDha 1 0 \n", + "6 BB-PDha 2 0 \n", + "7 COOH-PDha 2 0 \n", + "8 NH3-PDha 2 0 \n", + "9 BB-PDha 3 0 \n", + "10 COOH-PDha 3 0 \n", + "11 NH3-PDha 3 0 \n", + "12 BB-PDAGA 4 0 \n", + "13 NH3-PDAGA 4 0 \n", + "14 aCOOH-PDAGA 4 0 \n", + "15 bCOOH-PDAGA 4 0 \n", + "16 BB-PDAGA 5 0 \n", + "17 NH3-PDAGA 5 0 \n", + "18 aCOOH-PDAGA 5 0 \n", + "19 bCOOH-PDAGA 5 0 \n", + "20 BB-PDAGA 6 0 \n", + "21 NH3-PDAGA 6 0 \n", + "22 aCOOH-PDAGA 6 0 \n", + "23 bCOOH-PDAGA 6 0 \n", + "24 BB-PDAGA 7 0 \n", + "25 NH3-PDAGA 7 0 \n", + "26 aCOOH-PDAGA 7 0 \n", + "27 bCOOH-PDAGA 7 0 " ] }, - "execution_count": 50, + "execution_count": 47, "metadata": {}, "output_type": "execute_result" } @@ -3225,7 +4366,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 48, "metadata": {}, "outputs": [], "source": [ @@ -3241,7 +4382,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 49, "metadata": {}, "outputs": [], "source": [ @@ -3261,7 +4402,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 51, "metadata": {}, "outputs": [ { @@ -3298,7 +4439,7 @@ "Index: []" ] }, - "execution_count": 54, + "execution_count": 51, "metadata": {}, "output_type": "execute_result" } @@ -3306,8 +4447,7 @@ "source": [ "for mol_id in mol_ids:\n", " pmb.delete_instances_in_system(instance_id=0, \n", - " pmb_type=\"molecule\",\n", - " espresso_system = espresso_system)\n", + " pmb_type=\"molecule\")\n", "pmb.get_instances_df(pmb_type=\"particle\")" ] }, From 73404f957b1e787c098a19c08b5778810f56a93e Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 14 May 2026 20:14:50 +0200 Subject: [PATCH 46/75] Decouple create_angular_potential,generate_angles_for_entity, migrate create_angle_instance to simulation engine --- pyMBE/pyMBE.py | 51 ++++++++++++++------------------------------------ 1 file changed, 14 insertions(+), 37 deletions(-) diff --git a/pyMBE/pyMBE.py b/pyMBE/pyMBE.py index b0cb214e..f6a2ffc3 100644 --- a/pyMBE/pyMBE.py +++ b/pyMBE/pyMBE.py @@ -224,7 +224,7 @@ def _create_espresso_bond_instance(self, bond_type, bond_parameters): bond_instance = self.simulation_engine._create_bond_instance(bond_type,bond_parameters) return bond_instance - def _create_hydrogel_chain(self, hydrogel_chain, nodes, espresso_system, use_default_bond=False, gen_angle=False): + def _create_hydrogel_chain(self, hydrogel_chain, nodes, use_default_bond=False, gen_angle=False): """ Creates a chain between two nodes of a hydrogel. @@ -309,17 +309,9 @@ def _create_hydrogel_chain(self, hydrogel_chain, nodes, espresso_system, use_def self.create_bond(particle_id1=start_node_id,particle_id2=chain_pids[0],use_default_bond=use_default_bond) self.create_bond(particle_id1=chain_pids[-1],particle_id2=end_node_id,use_default_bond=use_default_bond) - self.create_bond(particle_id1=start_node_id, - particle_id2=chain_pids[0], - espresso_system=espresso_system, - use_default_bond=use_default_bond) - self.create_bond(particle_id1=chain_pids[-1], - particle_id2=end_node_id, - espresso_system=espresso_system, - use_default_bond=use_default_bond) return mol_id - def _generate_hydrogel_crosslinker_angles(self, espresso_system, central_particle_ids): + def _generate_hydrogel_crosslinker_angles(self, central_particle_ids): """ Generate hydrogel angles centered on crosslinkers and adjacent terminal beads. @@ -377,10 +369,8 @@ def _generate_hydrogel_crosslinker_angles(self, espresso_system, central_particl self.create_angular_potential(particle_id1=side_particle_id1, particle_id2=central_particle_id, particle_id3=side_particle_id3, - espresso_system=espresso_system, use_default_angle=False) - def _create_hydrogel_node(self, node_index, node_name, espresso_system): def _create_hydrogel_node(self, node_index, node_name,box_l): """ Set a node residue type. @@ -954,8 +944,8 @@ def create_counterions(self, object_name, cation_name, anion_name, box_l): logging.info(f'Ion type: {name} created number: {counterion_number[name]}') return counterion_number - def create_hydrogel(self, name, box_l,use_default_bond=False): - def create_hydrogel(self, name, espresso_system, use_default_bond=False, gen_angle=False): + + def create_hydrogel(self, name, box_l, use_default_bond=False, gen_angle=False): """ Creates a hydrogel in espresso_system using a pyMBE hydrogel template given by 'name' @@ -1052,15 +1042,15 @@ def create_hydrogel(self, name, espresso_system, use_default_bond=False, gen_ang attribute="assembly_id", value=assembly_id) if gen_angle: - self._generate_hydrogel_crosslinker_angles(espresso_system=espresso_system, + self._generate_hydrogel_crosslinker_angles( central_particle_ids=hydrogel_angle_centers) # Register an hydrogel instance in the pyMBE databasegit self.db._register_instance(HydrogelInstance(name=name, assembly_id=assembly_id)) return assembly_id - def create_molecule(self, name, number_of_molecules, box_l, list_of_first_residue_positions=None, backbone_vector=None, use_default_bond=False, reverse_residue_order = False): - def create_molecule(self, name, number_of_molecules, espresso_system, list_of_first_residue_positions=None, backbone_vector=None, use_default_bond=False, reverse_residue_order = False, gen_angle=False): + + def create_molecule(self, name, number_of_molecules, box_l, list_of_first_residue_positions=None, backbone_vector=None, use_default_bond=False, reverse_residue_order = False, gen_angle=False): """ Creates instances of a given molecule template name into ESPResSo. @@ -1204,7 +1194,6 @@ def create_molecule(self, name, number_of_molecules, espresso_system, list_of_fi self.db._register_instance(inst) if gen_angle: self._generate_angles_for_entity( - espresso_system=espresso_system, entity_id=molecule_id, entity_id_col='molecule_id') first_residue = True @@ -1359,7 +1348,7 @@ def create_protein(self, name, number_of_proteins, box_l, topology_dict): mol_ids.append(molecule_id) return mol_ids - def create_residue(self, name, espresso_system, central_bead_position=None,use_default_bond=False, backbone_vector=None, gen_angle=False): + def create_residue(self, name, box_l, central_bead_position=None,use_default_bond=False, backbone_vector=None, gen_angle=False): """ Creates a residue into ESPResSo. @@ -1486,10 +1475,9 @@ def create_residue(self, name, espresso_system, central_bead_position=None,use_d instance_id=side_residue_id) self.create_bond(particle_id1=central_bead_id, particle_id2=side_chain_beads_ids[0], - espresso_system=espresso_system, use_default_bond=use_default_bond) if gen_angle: - self._generate_angles_for_entity(espresso_system=espresso_system, + self._generate_angles_for_entity( entity_id=residue_id, entity_id_col="residue_id") return residue_id @@ -1654,7 +1642,7 @@ def define_default_angular_potential(self, angle_type, angle_parameters): tpl.name = "default" self.db._register_template(tpl) - def create_angular_potential(self, particle_id1, particle_id2, particle_id3, espresso_system, use_default_angle=False): + def create_angular_potential(self, particle_id1, particle_id2, particle_id3, use_default_angle=False): """ Creates an angle between three particle instances in an ESPResSo system and registers it in the pyMBE database. @@ -1685,10 +1673,10 @@ def create_angular_potential(self, particle_id1, particle_id2, particle_id3, esp central_name=particle_inst_2.name, side_name2=particle_inst_3.name, use_default_angle=use_default_angle) - angle_inst = self._get_espresso_angle_instance(angle_template=angle_tpl, espresso_system=espresso_system) + # angle_inst = self._get_espresso_angle_instance(angle_template=angle_tpl, espresso_system=espresso_system) # ESPResSo angle bonds are added to the central particle - espresso_system.part.by_id(particle_id2).add_bond((angle_inst, particle_id1, particle_id3)) + # espresso_system.part.by_id(particle_id2).add_bond((angle_inst, particle_id1, particle_id3)) angle_id = self.db._propose_instance_id(pmb_type="angle") pmb_angle_instance = AngleInstance(angle_id=angle_id, @@ -1752,19 +1740,9 @@ def _create_espresso_angle_instance(self, angle_type, angle_parameters): Returns: ('espressomd.interactions.BondedInteraction'): The ESPResSo angle interaction object. """ - from espressomd import interactions - - k = angle_parameters["k"].m_as("reduced_energy") - phi_0 = float(angle_parameters["phi_0"].magnitude) - - if angle_type == "harmonic": - return interactions.AngleHarmonic(bend=k, phi0=phi_0) - elif angle_type == "cosine": - return interactions.AngleCosine(bend=k, phi0=phi_0) - elif angle_type == "harmonic_cosine": - return interactions.AngleCossquare(bend=k, phi0=phi_0) + self.simulation_engine._create_angle_instance(angle_type, angle_parameters) - def _generate_angles_for_entity(self, espresso_system, entity_id, entity_id_col): + def _generate_angles_for_entity(self, entity_id, entity_id_col): """ Auto-generates angles from bond topology for an entity (molecule or residue). @@ -1807,7 +1785,6 @@ def _generate_angles_for_entity(self, espresso_system, entity_id, entity_id_col) self.create_angular_potential(particle_id1=i, particle_id2=j, particle_id3=k, - espresso_system=espresso_system, use_default_angle=True) except ValueError: # No angle template defined for this triplet — skip From 850ec76a58ac41e4696878533207aefc94fe1426 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 14 May 2026 20:15:49 +0200 Subject: [PATCH 47/75] Add method add_angle, _create_angle_instance and _get_angle_instance. Modify add_instances_to_engine to account for added angles. --- pyMBE/simulation_builder/espresso_engine.py | 74 ++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/pyMBE/simulation_builder/espresso_engine.py b/pyMBE/simulation_builder/espresso_engine.py index 97a9b798..15f6f60e 100644 --- a/pyMBE/simulation_builder/espresso_engine.py +++ b/pyMBE/simulation_builder/espresso_engine.py @@ -26,7 +26,19 @@ def __init__(self,box_l,db,espresso_system,units,kT,Kw,seed): self.Kw=Kw self.seed=seed pass - + + def _add_angle(self,particle_id1,particle_id2,particle_id3, angle_inst): + + angle_tpl=self.db.get_template(name=angle_inst.name, + pmb_type="angle") + espresso_angle_inst=self._get_angle_instance(angle_template=angle_tpl) + + self.espresso_system.part.by_id(particle_id2).add_bond((espresso_angle_inst, particle_id1, particle_id3)) + self.db._update_instance(instance_id=angle_inst.angle_id, + pmb_type='angle', + attribute='added_to_engine', + value=True) + def _add_bond(self,particle_id1,particle_id2,bond_inst): bond_tpl=self.db.get_template(name=bond_inst.name, pmb_type="bond") @@ -170,6 +182,51 @@ def _get_bond_instance(self, bond_template): self.espresso_system.bonded_inter.add(bond_inst) return bond_inst + def _get_angle_instance(self,angle_template): + """ + Retrieve or create an angle interaction in an ESPResSo system for a given angle template. + + Args: + angle_template ('AngleTemplate'): The angle template to use. + espresso_system ('espressomd.system.System'): ESPResSo system. + + Returns: + ('espressomd.interactions.BondedInteraction'): The ESPResSo angle interaction object. + """ + if angle_template.name in self.db.espresso_angle_instances: + return self.db.espresso_angle_instances[angle_template.name] + + angle_inst = self._create_angle_instance(angle_type=angle_template.angle_type, + angle_parameters=angle_template.get_parameters(self.units)) + self.db.espresso_angle_instances[angle_template.name] = angle_inst + self.espresso_system.bonded_inter.add(angle_inst) + + return angle_inst + + def _create_angle_instance(self, angle_type, angle_parameters): + """ + Creates an ESPResSo angle interaction object. + + Args: + angle_type ('str'): Type of angle potential ("harmonic", "cosine", "harmonic_cosine"). + angle_parameters ('dict'): Parameters of the angle potential (k, phi_0). + + Returns: + ('espressomd.interactions.BondedInteraction'): The ESPResSo angle interaction object. + """ + from espressomd import interactions + + k = angle_parameters["k"].m_as("reduced_energy") + phi_0 = float(angle_parameters["phi_0"].magnitude) + + if angle_type == "harmonic": + return interactions.AngleHarmonic(bend=k, phi0=phi_0) + elif angle_type == "cosine": + return interactions.AngleCosine(bend=k, phi0=phi_0) + elif angle_type == "harmonic_cosine": + return interactions.AngleCossquare(bend=k, phi0=phi_0) + + def _get_particle_ids_in_espresso(self): espresso_particles=self.espresso_system.part.all() return espresso_particles.id @@ -1350,6 +1407,21 @@ def add_instances_to_engine(self): self._add_bond(particle_id1, particle_id2, bond_instance) + + missing_angle_ids=self.db._find_instance_ids_by_attribute(pmb_type='angle', + attribute='added_to_engine', + value=False) + if len(missing_angle_ids)>0: + for id in missing_angle_ids: + angle_instance=self.db.get_instance(pmb_type='angle', + instance_id=id) + particle_id1=angle_instance.particle_id1 + particle_id2=angle_instance.particle_id2 + particle_id3=angle_instance.particle_id3 + self._add_angle(particle_id1, + particle_id2, + particle_id3, + angle_instance) return From 4e28d5e216e77b5f073a0f1466ddef84d483d53b Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 14 May 2026 20:16:44 +0200 Subject: [PATCH 48/75] include in io.py _load_database and _save_database added_to_engine for the pmb_type angle --- pyMBE/storage/io.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pyMBE/storage/io.py b/pyMBE/storage/io.py index 11a80aa6..0469ce1b 100644 --- a/pyMBE/storage/io.py +++ b/pyMBE/storage/io.py @@ -337,7 +337,8 @@ def _load_database_csv(db, folder): angle_id=int(row["angle_id"]), particle_id1=int(row["particle_id1"]), particle_id2=int(row["particle_id2"]), - particle_id3=int(row["particle_id3"])) + particle_id3=int(row["particle_id3"]), + added_to_engine=row["added_to_engine"]) instances[inst.angle_id] = inst elif pmb_type == "hydrogel": inst = HydrogelInstance(name=row["name"], @@ -521,7 +522,8 @@ def _save_database_csv(db, folder): "angle_id": int(inst.angle_id), "particle_id1": int(inst.particle_id1), "particle_id2": int(inst.particle_id2), - "particle_id3": int(inst.particle_id3)}) + "particle_id3": int(inst.particle_id3), + "added_to_engine":inst.added_to_engine,}) elif pmb_type == "hydrogel" and isinstance(inst, HydrogelInstance): rows.append({"pmb_type": pmb_type, "name": inst.name, From 2212e8933720ade05d84ede20b2dfc6d88a7b0ea Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 14 May 2026 20:17:37 +0200 Subject: [PATCH 49/75] Adapt angle tests to decouple it from espresso --- testsuite/angle_tests.py | 197 ++++++++++++++++++--------------------- 1 file changed, 91 insertions(+), 106 deletions(-) diff --git a/testsuite/angle_tests.py b/testsuite/angle_tests.py index 14f97f8f..f1e0e0cf 100644 --- a/testsuite/angle_tests.py +++ b/testsuite/angle_tests.py @@ -23,7 +23,8 @@ import espressomd # Create an instance of the ESPResSo system -espresso_system = espressomd.System(box_l=[10]*3) +box_l=[10]*3 +espresso_system = espressomd.System(box_l=box_l) class Test(ut.TestCase): @@ -125,29 +126,28 @@ def test_angle_setup_harmonic(self): # Create three particles: A, B, C pid_A = pmb.create_particle(name="A", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_B = pmb.create_particle(name="B", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_C = pmb.create_particle(name="C", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) # Create bonds: A-B and B-C pmb.create_bond(particle_id1=pid_A[0], - particle_id2=pid_B[0], - espresso_system=espresso_system) + particle_id2=pid_B[0]) pmb.create_bond(particle_id1=pid_B[0], - particle_id2=pid_C[0], - espresso_system=espresso_system) + particle_id2=pid_C[0]) # Create the angle: A-B-C (B is central) + pmb.create_angular_potential(particle_id1=pid_A[0], particle_id2=pid_B[0], - particle_id3=pid_C[0], - espresso_system=espresso_system) - + particle_id3=pid_C[0]) + pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() angle_object = self.get_angle_object(central_particle_id=pid_B[0]) self.assertIsNotNone(angle_object, "No angle object found on the central particle") @@ -158,8 +158,7 @@ def test_angle_setup_harmonic(self): # Clean-up for inst_id in pid_A + pid_B + pid_C: pmb.delete_instances_in_system(instance_id=inst_id, - pmb_type="particle", - espresso_system=espresso_system) + pmb_type="particle") pmb.db.delete_templates(pmb_type="angle") pmb.db.delete_templates(pmb_type="bond") @@ -182,27 +181,29 @@ def test_angle_setup_cosine(self): # Create three particles pid_A1 = pmb.create_particle(name="A", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_B = pmb.create_particle(name="B", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_A2 = pmb.create_particle(name="A", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) # Create bonds: A1-B and B-A2 pmb.create_bond(particle_id1=pid_A1[0], particle_id2=pid_B[0], - espresso_system=espresso_system) + ) pmb.create_bond(particle_id1=pid_B[0], particle_id2=pid_A2[0], - espresso_system=espresso_system) + ) pmb.create_angular_potential(particle_id1=pid_A1[0], particle_id2=pid_B[0], particle_id3=pid_A2[0], - espresso_system=espresso_system) + ) + pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() angle_object = self.get_angle_object(central_particle_id=pid_B[0]) self.assertIsNotNone(angle_object, "No angle object found on the central particle") @@ -214,8 +215,7 @@ def test_angle_setup_cosine(self): # Clean-up for inst_id in pid_A1 + pid_B + pid_A2: pmb.delete_instances_in_system(instance_id=inst_id, - pmb_type="particle", - espresso_system=espresso_system) + pmb_type="particle") pmb.db.delete_templates(pmb_type="angle") pmb.db.delete_templates(pmb_type="bond") @@ -235,27 +235,25 @@ def test_angle_setup_harmonic_cosine(self): particle_triplets=[('A', 'B', 'C')]) pid_A = pmb.create_particle(name="A", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_B = pmb.create_particle(name="B", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_C = pmb.create_particle(name="C", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pmb.create_bond(particle_id1=pid_A[0], - particle_id2=pid_B[0], - espresso_system=espresso_system) + particle_id2=pid_B[0]) pmb.create_bond(particle_id1=pid_B[0], - particle_id2=pid_C[0], - espresso_system=espresso_system) + particle_id2=pid_C[0]) pmb.create_angular_potential(particle_id1=pid_A[0], particle_id2=pid_B[0], - particle_id3=pid_C[0], - espresso_system=espresso_system) - + particle_id3=pid_C[0]) + pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() angle_object = self.get_angle_object(central_particle_id=pid_B[0]) self.assertIsNotNone(angle_object, "No angle object found on the central particle") @@ -265,8 +263,7 @@ def test_angle_setup_harmonic_cosine(self): for inst_id in pid_A + pid_B + pid_C: pmb.delete_instances_in_system(instance_id=inst_id, - pmb_type="particle", - espresso_system=espresso_system) + pmb_type="particle") pmb.db.delete_templates(pmb_type="angle") pmb.db.delete_templates(pmb_type="bond") @@ -313,30 +310,28 @@ def test_default_angle(self): # Create three particles pid_A = pmb.create_particle(name="A", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_B = pmb.create_particle(name="B", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_C = pmb.create_particle(name="C", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) # Create bonds: A-B and B-C pmb.create_bond(particle_id1=pid_A[0], - particle_id2=pid_B[0], - espresso_system=espresso_system) + particle_id2=pid_B[0]) pmb.create_bond(particle_id1=pid_B[0], - particle_id2=pid_C[0], - espresso_system=espresso_system) + particle_id2=pid_C[0]) # Create angle using default (no specific A-B-C template exists) pmb.create_angular_potential(particle_id1=pid_A[0], particle_id2=pid_B[0], particle_id3=pid_C[0], - espresso_system=espresso_system, use_default_angle=True) - + pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() angle_object = self.get_angle_object(central_particle_id=pid_B[0]) self.assertIsNotNone(angle_object, "No angle object found on the central particle") @@ -347,8 +342,7 @@ def test_default_angle(self): # Clean-up for inst_id in pid_A + pid_B + pid_C: pmb.delete_instances_in_system(instance_id=inst_id, - pmb_type="particle", - espresso_system=espresso_system) + pmb_type="particle") pmb.db.delete_templates(pmb_type="angle") pmb.db.delete_templates(pmb_type="bond") @@ -374,30 +368,28 @@ def test_specific_angle_over_default(self): particle_triplets=[('A', 'B', 'C')]) pid_A = pmb.create_particle(name="A", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_B = pmb.create_particle(name="B", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_C = pmb.create_particle(name="C", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) # Create bonds: A-B and B-C pmb.create_bond(particle_id1=pid_A[0], - particle_id2=pid_B[0], - espresso_system=espresso_system) + particle_id2=pid_B[0]) pmb.create_bond(particle_id1=pid_B[0], - particle_id2=pid_C[0], - espresso_system=espresso_system) + particle_id2=pid_C[0]) # Should use the specific A-B-C template, not the default pmb.create_angular_potential(particle_id1=pid_A[0], particle_id2=pid_B[0], particle_id3=pid_C[0], - espresso_system=espresso_system, use_default_angle=True) - + pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() angle_object = self.get_angle_object(central_particle_id=pid_B[0]) self.assertIsNotNone(angle_object) @@ -409,8 +401,7 @@ def test_specific_angle_over_default(self): # Clean-up for inst_id in pid_A + pid_B + pid_C: pmb.delete_instances_in_system(instance_id=inst_id, - pmb_type="particle", - espresso_system=espresso_system) + pmb_type="particle") pmb.db.delete_templates(pmb_type="angle") pmb.db.delete_templates(pmb_type="bond") @@ -519,27 +510,26 @@ def test_angle_without_bonds_raises_error(self): # Create three particles without any bonds between them pid_A = pmb.create_particle(name="A", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_B = pmb.create_particle(name="B", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_C = pmb.create_particle(name="C", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) - + pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() # Attempting to create angle without bonds should raise ValueError with self.assertRaises(ValueError, msg="create_angular_potential should raise ValueError when no bonds exist"): pmb.create_angular_potential(particle_id1=pid_A[0], particle_id2=pid_B[0], - particle_id3=pid_C[0], - espresso_system=espresso_system) + particle_id3=pid_C[0]) # Clean-up for inst_id in pid_A + pid_B + pid_C: pmb.delete_instances_in_system(instance_id=inst_id, - pmb_type="particle", - espresso_system=espresso_system) + pmb_type="particle") pmb.db.delete_templates(pmb_type="angle") def test_angle_with_partial_bonds_raises_error(self): @@ -559,32 +549,30 @@ def test_angle_with_partial_bonds_raises_error(self): particle_triplets=[('A', 'B', 'C')]) pid_A = pmb.create_particle(name="A", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_B = pmb.create_particle(name="B", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_C = pmb.create_particle(name="C", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) # Create only the A-B bond, not B-C pmb.create_bond(particle_id1=pid_A[0], - particle_id2=pid_B[0], - espresso_system=espresso_system) - + particle_id2=pid_B[0]) + pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() # Should raise ValueError because B-C bond is missing with self.assertRaises(ValueError, msg="create_angular_potential should raise ValueError when a bond is missing"): pmb.create_angular_potential(particle_id1=pid_A[0], particle_id2=pid_B[0], - particle_id3=pid_C[0], - espresso_system=espresso_system) + particle_id3=pid_C[0]) # Clean-up for inst_id in pid_A + pid_B + pid_C: pmb.delete_instances_in_system(instance_id=inst_id, - pmb_type="particle", - espresso_system=espresso_system) + pmb_type="particle") pmb.db.delete_templates(pmb_type="angle") pmb.db.delete_templates(pmb_type="bond") @@ -595,7 +583,7 @@ def test_generate_angles_for_entity_without_particles_returns(self): pmb = pyMBE.pymbe_library(seed=42) self.define_templates(pmb) - pmb._generate_angles_for_entity(espresso_system=espresso_system, + pmb._generate_angles_for_entity( entity_id=999, entity_id_col="residue_id") @@ -616,15 +604,15 @@ def test_generate_angles_for_entity_creates_angle_from_bonds(self): particle_triplets=[('A', 'B', 'C')]) pid_A = pmb.create_particle(name="A", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_B = pmb.create_particle(name="B", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_C = pmb.create_particle(name="C", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) - + for particle_id in (pid_A[0], pid_B[0], pid_C[0]): pmb.db._update_instance(instance_id=particle_id, pmb_type="particle", @@ -632,24 +620,23 @@ def test_generate_angles_for_entity_creates_angle_from_bonds(self): value=0) pmb.create_bond(particle_id1=pid_A[0], - particle_id2=pid_B[0], - espresso_system=espresso_system) + particle_id2=pid_B[0]) pmb.create_bond(particle_id1=pid_B[0], - particle_id2=pid_C[0], - espresso_system=espresso_system) + particle_id2=pid_C[0]) + - pmb._generate_angles_for_entity(espresso_system=espresso_system, + pmb._generate_angles_for_entity( entity_id=0, entity_id_col="residue_id") - + pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() angle_object = self.get_angle_object(central_particle_id=pid_B[0]) self.assertIsNotNone(angle_object, "No angle object found on the central particle") self.assertEqual(len(pmb.get_instances_df(pmb_type="angle")), 1) for inst_id in pid_A + pid_B + pid_C: pmb.delete_instances_in_system(instance_id=inst_id, - pmb_type="particle", - espresso_system=espresso_system) + pmb_type="particle") pmb.db.delete_templates(pmb_type="angle") pmb.db.delete_templates(pmb_type="bond") @@ -665,15 +652,15 @@ def test_generate_angles_for_entity_skips_missing_templates(self): particle_pairs=[['A', 'B'], ['B', 'C']]) pid_A = pmb.create_particle(name="A", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_B = pmb.create_particle(name="B", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) pid_C = pmb.create_particle(name="C", - espresso_system=espresso_system, + box_l=box_l, number_of_particles=1) - + for particle_id in (pid_A[0], pid_B[0], pid_C[0]): pmb.db._update_instance(instance_id=particle_id, pmb_type="particle", @@ -681,13 +668,12 @@ def test_generate_angles_for_entity_skips_missing_templates(self): value=0) pmb.create_bond(particle_id1=pid_A[0], - particle_id2=pid_B[0], - espresso_system=espresso_system) + particle_id2=pid_B[0]) pmb.create_bond(particle_id1=pid_B[0], - particle_id2=pid_C[0], - espresso_system=espresso_system) - - pmb._generate_angles_for_entity(espresso_system=espresso_system, + particle_id2=pid_C[0]) + pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() + pmb._generate_angles_for_entity( entity_id=0, entity_id_col="residue_id") @@ -696,8 +682,7 @@ def test_generate_angles_for_entity_skips_missing_templates(self): for inst_id in pid_A + pid_B + pid_C: pmb.delete_instances_in_system(instance_id=inst_id, - pmb_type="particle", - espresso_system=espresso_system) + pmb_type="particle") pmb.db.delete_templates(pmb_type="bond") def test_create_residue_with_gen_angle_generates_angles(self): @@ -718,9 +703,10 @@ def test_create_residue_with_gen_angle_generates_angles(self): side_chains=["A", "C"]) residue_id = pmb.create_residue(name="R_angle", - espresso_system=espresso_system, + box_l=box_l, gen_angle=True) - + pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() particle_ids = pmb.db._find_instance_ids_by_attribute(pmb_type="particle", attribute="residue_id", value=residue_id) @@ -733,8 +719,7 @@ def test_create_residue_with_gen_angle_generates_angles(self): self.assertEqual(len(pmb.get_instances_df(pmb_type="angle")), 1) pmb.delete_instances_in_system(instance_id=residue_id, - pmb_type="residue", - espresso_system=espresso_system) + pmb_type="residue") pmb.db.delete_templates(pmb_type="angle") pmb.db.delete_templates(pmb_type="bond") @@ -765,9 +750,10 @@ def test_create_molecule_with_gen_angle_generates_angles(self): molecule_ids = pmb.create_molecule(name="M_angle", number_of_molecules=1, - espresso_system=espresso_system, + box_l=box_l, gen_angle=True) - + pmb.set_simulation_engine(espresso_system) + pmb.add_instances_to_engine() particle_ids = pmb.db._find_instance_ids_by_attribute(pmb_type="particle", attribute="molecule_id", value=molecule_ids[0]) @@ -780,8 +766,7 @@ def test_create_molecule_with_gen_angle_generates_angles(self): self.assertEqual(len(pmb.get_instances_df(pmb_type="angle")), 1) pmb.delete_instances_in_system(instance_id=molecule_ids[0], - pmb_type="molecule", - espresso_system=espresso_system) + pmb_type="molecule") pmb.db.delete_templates(pmb_type="angle") pmb.db.delete_templates(pmb_type="bond") From 39ac794b9b718810169707a47a131510d7a16639 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 14 May 2026 20:18:49 +0200 Subject: [PATCH 50/75] Add as pmb_type "angle" with attributes particle_id1,particle_id2 and particle_id3 and added_to_engine --- pyMBE/storage/manager.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyMBE/storage/manager.py b/pyMBE/storage/manager.py index 6284e4d7..5119c54f 100644 --- a/pyMBE/storage/manager.py +++ b/pyMBE/storage/manager.py @@ -572,6 +572,8 @@ def _update_instance(self, instance_id, pmb_type, attribute, value): allowed = ["assembly_id"] elif pmb_type =="bond": allowed = ["particle_id1","particle_id2","added_to_engine"] + elif pmb_type =="angle": + allowed = ["particle_id1","particle_id2","particle_id3","added_to_engine"] else: allowed = [None] # No attributes allowed for other types if attribute not in allowed: From 1b03f679bfe9481f8f4476d85407bc5232ecbdb1 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 14 May 2026 20:19:07 +0200 Subject: [PATCH 51/75] Add added_to_engine in AngleInstance data class --- pyMBE/storage/instances/angle.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyMBE/storage/instances/angle.py b/pyMBE/storage/instances/angle.py index 34adbb80..ef9b004e 100644 --- a/pyMBE/storage/instances/angle.py +++ b/pyMBE/storage/instances/angle.py @@ -50,6 +50,7 @@ class AngleInstance(PMBBaseModel): particle_id1: int particle_id2: int particle_id3: int + added_to_engine: bool = False @validator("angle_id", "particle_id1", "particle_id2", "particle_id3") def validate_non_negative_int(cls, value, field): From 61625c4435a0b5cff15aa5cbdf39f1d829977525 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 14 May 2026 20:19:39 +0200 Subject: [PATCH 52/75] Adapt test hydrogel_builder_with_angles --- testsuite/hydrogel_builder_with_angles.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/testsuite/hydrogel_builder_with_angles.py b/testsuite/hydrogel_builder_with_angles.py index 632c1f74..6817c5ad 100644 --- a/testsuite/hydrogel_builder_with_angles.py +++ b/testsuite/hydrogel_builder_with_angles.py @@ -22,8 +22,8 @@ import pyMBE from pyMBE.lib.lattice import DiamondLattice import espressomd - -espresso_system = espressomd.System(box_l=[10] * 3) +box_l=[10] * 3 +espresso_system = espressomd.System(box_l=box_l) def build_simple_hydrogel_with_optional_angles(junction_angle_mode="none", mpc_local=4): @@ -179,7 +179,7 @@ def test_hydrogel_gen_angle_defaults_to_false(self): pmb_local, espresso_system_local, hydrogel_name_local, _ = build_simple_hydrogel_with_optional_angles( junction_angle_mode="full" ) - pmb_local.create_hydrogel(hydrogel_name_local, espresso_system_local) + pmb_local.create_hydrogel(hydrogel_name_local, box_l) self.assertEqual(len(pmb_local.db.get_instances(pmb_type="angle")), 0) def test_hydrogel_chain_angles_are_created_without_crosslinker_templates(self): @@ -191,9 +191,11 @@ def test_hydrogel_chain_angles_are_created_without_crosslinker_templates(self): junction_angle_mode="none" ) with self.assertLogs(level="WARNING") as log_context: - pmb_local.create_hydrogel(hydrogel_name_local, espresso_system_local, gen_angle=True) + pmb_local.create_hydrogel(hydrogel_name_local, box_l, gen_angle=True) angle_counts = get_angle_counts(pmb_local) + pmb_local.set_simulation_engine(espresso_system_local) + pmb_local.add_instances_to_engine() self.assertEqual( angle_counts, {"C-C-C": len(diamond_lattice_local.connectivity) * (diamond_lattice_local.mpc - 2)}, @@ -210,7 +212,9 @@ def test_hydrogel_junction_angle_counts_are_correct_when_defined(self): pmb_local, espresso_system_local, hydrogel_name_local, diamond_lattice_local = build_simple_hydrogel_with_optional_angles( junction_angle_mode="full" ) - pmb_local.create_hydrogel(hydrogel_name_local, espresso_system_local, gen_angle=True) + pmb_local.create_hydrogel(hydrogel_name_local, box_l, gen_angle=True) + pmb_local.set_simulation_engine(espresso_system_local) + pmb_local.add_instances_to_engine() self.assertEqual(get_angle_counts(pmb_local), expected_crosslinker_angle_counts(diamond_lattice_local)) @@ -222,7 +226,7 @@ def test_hydrogel_partial_crosslinker_angle_definitions_raise(self): junction_angle_mode="partial" ) with self.assertRaises(ValueError): - pmb_local.create_hydrogel(hydrogel_name_local, espresso_system_local, gen_angle=True) + pmb_local.create_hydrogel(hydrogel_name_local, box_l, gen_angle=True) if __name__ == "__main__": From 72562ee4f947e99a0574ca052bdd134936bca97a Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 14 May 2026 20:20:00 +0200 Subject: [PATCH 53/75] Adapt test_lattice_setup --- testsuite/lattice_builder.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/testsuite/lattice_builder.py b/testsuite/lattice_builder.py index 20e501bb..6a43e621 100644 --- a/testsuite/lattice_builder.py +++ b/testsuite/lattice_builder.py @@ -231,9 +231,9 @@ def test_lattice_setup(self): for label, index in lattice.node_labels.items(): node_index = lattice.lattice.indices[index] node_name = lattice.get_node(label) - node_pos, node_id = pmb2._create_hydrogel_node(node_index=node_index, - node_name=node_name, - espresso_system=espresso_system) + node_pos, node_id = pmb2._create_hydrogel_node(box_l=box_l, + node_index=node_index, + node_name=node_name) nodes[label] = {"name": node_name, "pos": node_pos, "id": node_id} @@ -284,7 +284,6 @@ def test_non_palindromic_self_loop_chain_raises(self): ): pmb._create_hydrogel_chain(hydrogel_chain=hydrogel_chain, nodes={}, - espresso_system=espresso_system, use_default_bond=False) def test_plot(self): From 27348fa864f523d58843752cd677739842fc94f7 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 14 May 2026 20:20:55 +0200 Subject: [PATCH 54/75] Adapt to decouple from espresso method test_io_instances --- testsuite/test_io_database.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testsuite/test_io_database.py b/testsuite/test_io_database.py index 404d3a24..7667f365 100644 --- a/testsuite/test_io_database.py +++ b/testsuite/test_io_database.py @@ -497,7 +497,7 @@ def test_io_instances(self): pmb.define_molecule(name="M1", residue_list=["R1"]*1) angle_residue_id = pmb.create_residue(name="R1", - espresso_system=espresso_system, + box_l=box_l, gen_angle=True) diamond_lattice = DiamondLattice(4, 3.5 * pmb.units.reduced_length) lattice_builder = pmb.initialize_lattice_builder(diamond_lattice) @@ -556,7 +556,7 @@ def test_io_instances(self): pmb.delete_instances_in_system( instance_id=assembly_id, pmb_type="hydrogel") - pmb.delete_instances_in_system(espresso_system=espresso_system, + pmb.delete_instances_in_system( instance_id=angle_residue_id, pmb_type="residue") pmb.db.delete_templates(pmb_type="angle") From e2732153caa5de42813d99f698eeba3c544f749d Mon Sep 17 00:00:00 2001 From: jsd94 Date: Tue, 19 May 2026 00:09:51 +0200 Subject: [PATCH 55/75] A commit --- pyMBE/exceptions/pmb_warnings.py | 2 +- pyMBE/pyMBE.py | 91 ++++++---------- pyMBE/simulation_builder/base_engine.py | 4 +- pyMBE/simulation_builder/engine_protocol.py | 2 + pyMBE/simulation_builder/espresso_engine.py | 70 ++++++++---- samples/Beyer2024/globular_protein.py | 13 ++- samples/Beyer2024/peptide.py | 5 +- .../weak_polyelectrolyte_dialysis.py | 5 +- samples/Landsgesell2022/plot_P_vs_V.py | 3 +- .../time_series/analyzed_data.csv | 6 ++ ...Lfraction_0.366_pH_4_pKa_4_time_series.csv | 101 ++++++++++++++++++ ...Lfraction_0.557_pH_6_pKa_4_time_series.csv | 101 ++++++++++++++++++ ...Lfraction_0.303_pH_5_pKa_4_time_series.csv | 101 ++++++++++++++++++ ..._Lfraction_0.51_pH_5_pKa_4_time_series.csv | 101 ++++++++++++++++++ samples/salt_solution_gcmc.py | 12 ++- samples/weak_polyacid_hydrogel_grxmc.py | 4 +- testsuite/angle_tests.py | 10 +- 17 files changed, 523 insertions(+), 108 deletions(-) create mode 100644 samples/Landsgesell2022/time_series/analyzed_data.csv create mode 100644 samples/Landsgesell2022/time_series/csalt_0.01_Lfraction_0.366_pH_4_pKa_4_time_series.csv create mode 100644 samples/Landsgesell2022/time_series/csalt_0.01_Lfraction_0.557_pH_6_pKa_4_time_series.csv create mode 100644 samples/Landsgesell2022/time_series/csalt_0.05_Lfraction_0.303_pH_5_pKa_4_time_series.csv create mode 100644 samples/Landsgesell2022/time_series/csalt_0.05_Lfraction_0.51_pH_5_pKa_4_time_series.csv diff --git a/pyMBE/exceptions/pmb_warnings.py b/pyMBE/exceptions/pmb_warnings.py index 8ddcf23e..fdf849ff 100644 --- a/pyMBE/exceptions/pmb_warnings.py +++ b/pyMBE/exceptions/pmb_warnings.py @@ -8,7 +8,7 @@ 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.", + f"{func.__name__} is deprecated and it will be removed in the future. Please use"+ new_function +"instead.", DeprecationWarning, stacklevel=2 ) diff --git a/pyMBE/pyMBE.py b/pyMBE/pyMBE.py index f6a2ffc3..d45f71ed 100644 --- a/pyMBE/pyMBE.py +++ b/pyMBE/pyMBE.py @@ -234,9 +234,6 @@ def _create_hydrogel_chain(self, hydrogel_chain, nodes, use_default_bond=False, nodes ('dict'): {node_index: {"name": node_particle_name, "pos": node_position, "id": node_particle_instance_id}} - espresso_system ('espressomd.system.System'): - ESPResSo system object where the hydrogel chain will be created. - use_default_bond ('bool', optional): If True, use a default bond template if no specific template exists. Defaults to False. @@ -381,9 +378,8 @@ def _create_hydrogel_node(self, node_index, node_name,box_l): node_name ('str'): name of the node particle defined in pyMBE. - - espresso_system (espressomd.system.System): - ESPResSo system object where the hydrogel node will be created. + + box_l('list[float,float,float]'): list of floats with the dimensions of the box Returns: ('tuple(list,int)'): @@ -408,8 +404,6 @@ def _get_espresso_bond_instance(self, bond_template): Args: bond_template ('BondTemplate'): BondTemplate object from the pyMBE database. - espresso_system ('espressomd.system.System'): - An ESPResSo system object where the bond will be added or retrieved. Returns: ('espressomd.interactions.BondedInteraction'): @@ -489,10 +483,6 @@ def _delete_particles_from_engine(self, particle_ids): particle_ids ('Iterable[int]'): A list (or other iterable) of ESPResSo particle IDs to remove. - espresso_system ('espressomd.system.System'): - The ESPResSo simulation system from which the particles - will be removed. - Notess: - This method removes particles only from the ESPResSo simulation, **not** from the pyMBE database. Database cleanup must be handled @@ -519,9 +509,6 @@ def calculate_center_of_mass(self, instance_id, pmb_type): Type of the pyMBE object. Must correspond to a particle-aggregating template type (e.g. '"molecule"', '"residue"', '"peptide"', '"protein"'). - espresso_system ('espressomd.system.System'): - ESPResSo system containing the particle instances. - Returns: ('numpy.ndarray'): Array of shape '(3,)' containing the Cartesian coordinates of the @@ -713,8 +700,6 @@ def calculate_net_charge(self,object_name,pmb_type,dimensionless=False): Calculates the net charge per instance of a given pmb object type. Args: - espresso_system (espressomd.system.System): - ESPResSo system containing the particles. object_name (str): Name of the object (e.g. molecule, residue, peptide, protein). pmb_type (str): @@ -743,13 +728,12 @@ def center_object_in_simulation_box(self, instance_id, box_l,pmb_type): Args: instance_id ('int'): ID of the pyMBE object instance to be centered. + + box_l('list[float,float,float]'): list of floats with the dimensions of the box pmb_type ('str'): Type of the pyMBE object. - espresso_system ('espressomd.system.System'): - ESPResSo system object in which the particles are defined. - Notes: - Works for both cubic and non-cubic simulation boxes. """ @@ -777,7 +761,6 @@ def create_added_salt(self, box_l, cation_name, anion_name, c_salt): Creates a 'c_salt' concentration of 'cation_name' and 'anion_name' ions into the 'espresso_system'. Args: - espresso_system('espressomd.system.System'): instance of an espresso system object. cation_name('str'): 'name' of a particle with a positive charge. anion_name('str'): 'name' of a particle with a negative charge. c_salt('float'): Salt concentration. @@ -841,9 +824,6 @@ def create_bond(self, particle_id1, particle_id2, use_default_bond=False): particle_id2 ('int'): pyMBE and ESPResSo ID of the second particle. - espresso_system ('espressomd.system.System'): - ESPResSo system object where the bond will be created. - use_default_bond ('bool', optional): If True, use a default bond template if no specific template exists. Defaults to False. @@ -876,14 +856,13 @@ def create_counterions(self, object_name, cation_name, anion_name, box_l): object_name ('str'): 'name' of a pyMBE object. - espresso_system ('espressomd.system.System'): - Instance of a system object from the espressomd library. - cation_name ('str'): 'name' of a particle with a positive charge. anion_name ('str'): 'name' of a particle with a negative charge. + + box_l('list[float,float,float]'): list of floats with the dimensions of the box Returns: ('dict'): @@ -950,12 +929,11 @@ def create_hydrogel(self, name, box_l, use_default_bond=False, gen_angle=False): Creates a hydrogel in espresso_system using a pyMBE hydrogel template given by 'name' Args: + box_l('list[float,float,float]'): list of floats with the dimensions of the box + name ('str'): name of the hydrogel template in the pyMBE database. - espresso_system ('espressomd.system.System'): - ESPResSo system object where the hydrogel will be created. - use_default_bond ('bool', optional): If True, use a default bond template if no specific template exists. Defaults to False. @@ -1058,8 +1036,7 @@ def create_molecule(self, name, number_of_molecules, box_l, list_of_first_residu name ('str'): Label of the molecule type to be created. 'name'. - espresso_system ('espressomd.system.System'): - Instance of a system object from espressomd library. + box_l('list[float,float,float]'): list of floats with the dimensions of the box number_of_molecules ('int'): Number of molecules or peptides of type 'name' to be created. @@ -1208,9 +1185,8 @@ def create_particle(self, name, box_l, number_of_particles, position=None, fix=[ Args: name ('str'): Label of the particle template in the pyMBE database. - - espresso_system ('espressomd.system.System'): - Instance of a system object from the espressomd library. + + box_l('list[float,float,float]'): list of floats with the dimensions of the box number_of_particles ('int'): Number of particles to be created. @@ -1268,10 +1244,9 @@ def create_protein(self, name, number_of_proteins, box_l, topology_dict): Name of the protein template stored in the pyMBE database. number_of_proteins (int): - Number of protein molecules to generate. - - espresso_system (espressomd.system.System): - The ESPResSo simulation system where the protein molecules will be created. + Number of protein molecules to generate. + + box_l('list[float,float,float]'): list of floats with the dimensions of the box topology_dict (dict): Dictionary defining the internal structure of the protein. Expected format: @@ -1356,11 +1331,10 @@ def create_residue(self, name, box_l, central_bead_position=None,use_default_bon name ('str'): Label of the residue type to be created. - espresso_system ('espressomd.system.System'): - Instance of a system object from espressomd library. - central_bead_position ('list' of 'float'): Position of the central bead. + + box_l('list[float,float,float]'): list of floats with the dimensions of the box use_default_bond ('bool'): Switch to control if a bond of type 'default' is used to bond a particle whose bonds types are not defined in the pyMBE database. @@ -1651,7 +1625,6 @@ def create_angular_potential(self, particle_id1, particle_id2, particle_id3, use particle_id1 ('int'): ID of the first side particle. particle_id2 ('int'): ID of the central particle. particle_id3 ('int'): ID of the second side particle. - espresso_system ('espressomd.system.System'): ESPResSo system. use_default_angle ('bool', optional): If True, use the default angle if no specific one is found. """ particle_inst_1 = self.db.get_instance(pmb_type="particle", instance_id=particle_id1) @@ -1710,24 +1683,23 @@ def get_angle_template(self, side_name1, central_name, side_name2, use_default_a raise ValueError(f"No angle template found for '{side_name1}-{central_name}-{side_name2}', and default angles are deactivated.") - def _get_espresso_angle_instance(self, angle_template, espresso_system): + def _get_espresso_angle_instance(self, angle_template): """ Retrieve or create an angle interaction in an ESPResSo system for a given angle template. Args: angle_template ('AngleTemplate'): The angle template to use. - espresso_system ('espressomd.system.System'): ESPResSo system. Returns: ('espressomd.interactions.BondedInteraction'): The ESPResSo angle interaction object. """ - if angle_template.name in self.db.espresso_angle_instances: - return self.db.espresso_angle_instances[angle_template.name] - angle_inst = self._create_espresso_angle_instance(angle_type=angle_template.angle_type, - angle_parameters=angle_template.get_parameters(self.units)) - self.db.espresso_angle_instances[angle_template.name] = angle_inst - espresso_system.bonded_inter.add(angle_inst) - return angle_inst + if isinstance(self.simulation_engine,EspressoSimulation): + angle_inst=self.simulation_engine._get_angle_instance(angle_template=angle_template) + return angle_inst + elif isinstance(self.simulation_engine,LammpsSimulation): + raise NotImplementedError('It has not yet been implemented for Lammps') + else: + raise RuntimeError('You have not set up any simulation engine yet') def _create_espresso_angle_instance(self, angle_type, angle_parameters): """ @@ -1750,7 +1722,6 @@ def _generate_angles_for_entity(self, entity_id, entity_id_col): this method finds all neighbor pairs and applies any matching angle potential. Args: - espresso_system ('espressomd.system.System'): ESPResSo system. entity_id ('int'): The molecule_id or residue_id to generate angles for. entity_id_col ('str'): Either "molecule_id" or "residue_id". """ @@ -2161,9 +2132,6 @@ def enable_motion_of_rigid_object(self, instance_id, pmb_type): pyMBE object type of the instance (e.g. '"molecule"', '"peptide"', '"protein"', or any assembly-like type). - espresso_system ('espressomd.system.System'): - ESPResSo system in which the rigid object is defined. - Notess: - This method requires ESPResSo to be compiled with the following features enabled: @@ -2790,6 +2758,15 @@ def set_reduced_units(self, unit_length=None, unit_charge=None, temperature=None logging.info(self.get_reduced_units()) def set_simulation_engine(self,simulation_engine,box_l=None): + """_summary_ + + Args: + simulation_engine (Any): object which contains the methods to setup molecular dynamics and montecarlo simulations + box_l('list[float,float,float]'): list of floats with the dimensions of the box + + Raises: + ValueError: _description_ + """ if isinstance(simulation_engine,EspressoSystemProtocol): self.simulation_engine=EspressoSimulation(box_l=simulation_engine.box_l, db=self.db, @@ -3011,8 +2988,6 @@ def setup_lj_interactions(self, shift_potential=True, combining_rule='Lorentz-Be Sets up the Lennard-Jones (LJ) potential between all pairs of particle states defined in the pyMBE database. Args: - espresso_system('espressomd.system.System'): - Instance of a system object from the espressomd library. shift_potential('bool', optional): If True, a shift will be automatically computed such that the potential is continuous at the cutoff radius. Otherwise, no shift will be applied. Defaults to True. diff --git a/pyMBE/simulation_builder/base_engine.py b/pyMBE/simulation_builder/base_engine.py index f2b84a8c..cfec24a9 100644 --- a/pyMBE/simulation_builder/base_engine.py +++ b/pyMBE/simulation_builder/base_engine.py @@ -2,6 +2,7 @@ import numpy as np class SimulationEngine(ABC): + """Base Class for simulation engines contains methods """ def __init__(self): pass @abstractmethod @@ -28,9 +29,6 @@ def calculate_center_of_mass(self, instance_id, pmb_type): Type of the pyMBE object. Must correspond to a particle-aggregating template type (e.g. '"molecule"', '"residue"', '"peptide"', '"protein"'). - espresso_system ('espressomd.system.System'): - ESPResSo system containing the particle instances. - Returns: ('numpy.ndarray'): Array of shape '(3,)' containing the Cartesian coordinates of the diff --git a/pyMBE/simulation_builder/engine_protocol.py b/pyMBE/simulation_builder/engine_protocol.py index 5e8a4ee8..840c7071 100644 --- a/pyMBE/simulation_builder/engine_protocol.py +++ b/pyMBE/simulation_builder/engine_protocol.py @@ -1,11 +1,13 @@ 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 diff --git a/pyMBE/simulation_builder/espresso_engine.py b/pyMBE/simulation_builder/espresso_engine.py index 15f6f60e..c4fe74a5 100644 --- a/pyMBE/simulation_builder/espresso_engine.py +++ b/pyMBE/simulation_builder/espresso_engine.py @@ -28,7 +28,15 @@ def __init__(self,box_l,db,espresso_system,units,kT,Kw,seed): pass def _add_angle(self,particle_id1,particle_id2,particle_id3, angle_inst): + """ helper function to add angle instances to espresso + + Args: + particle_id1 (int): pid of the particle instance 1 that composes the angle + particle_id2 (int): pid of the particle instance 2 that composes the angle + particle_id3 (int): pid of the particle instance 3 that composes the angle + angle_inst (pmb.AngleInstance): dataclass containing information of an angle instance + """ angle_tpl=self.db.get_template(name=angle_inst.name, pmb_type="angle") espresso_angle_inst=self._get_angle_instance(angle_template=angle_tpl) @@ -40,6 +48,13 @@ def _add_angle(self,particle_id1,particle_id2,particle_id3, angle_inst): value=True) def _add_bond(self,particle_id1,particle_id2,bond_inst): + """helper function to add bond instances to espresso + + Args: + particle_id1 (int): pid of the particle instance 1 that composes the bond + particle_id2 (int): pid of the particle instance 2 that composes the bond + bond_inst (pmb.BondInstance): dataclass containing information of a bond instance + """ bond_tpl=self.db.get_template(name=bond_inst.name, pmb_type="bond") espresso_bond_inst=self._get_bond_instance(bond_template=bond_tpl) @@ -50,6 +65,11 @@ def _add_bond(self,particle_id1,particle_id2,bond_inst): value=True) def _add_particle(self,particle_id): + """helper function to add particle instances to espresso + + Args: + particle_id (int): pid of the particle instance + """ particle_instance=self.db.get_instance(pmb_type='particle', instance_id=particle_id) part_state = self.db.get_template(pmb_type="particle_state", @@ -67,6 +87,14 @@ def _add_particle(self,particle_id): def _check_particle_exists_in_espresso(self,particle_id): + """_summary_ + + Args: + particle_id (int): pid of the particle that we want to check that exists within espresso + + Returns: + particle_exists(bool): result of the espresso_exists function + """ particle_exists=self.espresso_system.exists(particle_id) return particle_exists @@ -137,9 +165,6 @@ def _delete_particles(self, particle_ids): particle_ids ('Iterable[int]'): A list (or other iterable) of ESPResSo particle IDs to remove. - espresso_system ('espressomd.system.System'): - The ESPResSo simulation system from which the particles - will be removed. Notess: - This method removes particles only from the ESPResSo simulation, @@ -162,8 +187,6 @@ def _get_bond_instance(self, bond_template): Args: bond_template ('BondTemplate'): BondTemplate object from the pyMBE database. - espresso_system ('espressomd.system.System'): - An ESPResSo system object where the bond will be added or retrieved. Returns: ('espressomd.interactions.BondedInteraction'): @@ -188,7 +211,6 @@ def _get_angle_instance(self,angle_template): Args: angle_template ('AngleTemplate'): The angle template to use. - espresso_system ('espressomd.system.System'): ESPResSo system. Returns: ('espressomd.interactions.BondedInteraction'): The ESPResSo angle interaction object. @@ -228,14 +250,31 @@ def _create_angle_instance(self, angle_type, angle_parameters): def _get_particle_ids_in_espresso(self): + """_summary_ + + Returns: + espresso_particles_id(list): list of pids of the particles that are saved in espresso + """ espresso_particles=self.espresso_system.part.all() return espresso_particles.id def _get_particle_pos_espresso(self,id): + """_summary_ + Args: + id (int): pid of the particle that we want to check that exists within espresso + + Returns: + espresso_particles_id(List[List[float,float,float]]): returns a nested list of floats containing x,y,z coordinates for each particle in espresso + """ return self.espresso_system.part.by_id(id).pos def get_box_side_length(self): + """_summary_ + + Returns: + box_l(list[float,float,float]): return a list of floats regarding the dimensions of the box + """ return self.box_l def calculate_net_charge(self,object_name,pmb_type,dimensionless=False): @@ -243,8 +282,6 @@ def calculate_net_charge(self,object_name,pmb_type,dimensionless=False): Calculates the net charge per instance of a given pmb object type. Args: - espresso_system (espressomd.system.System): - ESPResSo system containing the particles. object_name (str): Name of the object (e.g. molecule, residue, peptide, protein). pmb_type (str): @@ -278,6 +315,7 @@ def calculate_net_charge(self,object_name,pmb_type,dimensionless=False): else: mean_charge = (np.mean([q.magnitude for q in charges.values()])* self.units.Quantity(1, "reduced_charge")) return {"mean": mean_charge, "instances": charges} + def change_volume_and_rescale_particles(self, d_new, dir="xyz"): """ Change the volume for a particular dimension into the espresso system. @@ -354,9 +392,6 @@ def enable_motion_of_rigid_object(self, instance_id, pmb_type): pyMBE object type of the instance (e.g. '"molecule"', '"peptide"', '"protein"', or any assembly-like type). - espresso_system ('espressomd.system.System'): - ESPResSo system in which the rigid object is defined. - Notess: - This method requires ESPResSo to be compiled with the following features enabled: @@ -392,8 +427,6 @@ def get_number_of_particles(self, ptype): Returns the number of particles of a given ESPResSo particle type. Args: - espresso_system ('espressomd.system.System'): - ESPResSo system object from which the particle count is queried. ptype ('int'): ESPResSo particle type identifier. @@ -430,8 +463,6 @@ def relax_espresso_system(self, seed, gamma=1e-3, Nsteps_steepest_descent=5000, If you experience crashes or unexpected behavior, please consider using your own relaxation procedure. Args: - espresso_system (`espressomd.system.System`): - system object of espressomd library. seed (`int`): Seed for the random number generator for the thermostat. @@ -489,8 +520,6 @@ def setup_electrostatic_interactions(self,units, kT, c_salt=None, solvent_permit units (`pint.UnitRegistry`): Unit registry for handling physical units. - espresso_system (`espressomd.system.System`): - system object of espressomd library. kT (`pint.Quantity`): Thermal energy. @@ -1198,8 +1227,6 @@ def setup_langevin_dynamics(self, kT, seed,time_step=1e-2, gamma=1, tune_skin=Tr Sets up Langevin Dynamics for an ESPResSo simulation system. Args: - espresso_system (`espressomd.system.System`): - system object of espressomd library. kT (`pint.Quantity`): Target temperature in reduced energy units. @@ -1261,9 +1288,6 @@ def setup_lj_interactions(self, shift_potential=True, combining_rule='Lorentz-Be Sets up the Lennard-Jones (LJ) potential between all pairs of particle states defined in the pyMBE database. Args: - espresso_system('espressomd.system.System'): - Instance of a system object from the espressomd library. - shift_potential('bool', optional): If True, a shift will be automatically computed such that the potential is continuous at the cutoff radius. Otherwise, no shift will be applied. Defaults to True. @@ -1363,7 +1387,7 @@ def update_particle_id(self, old_pid, new_pid): def add_instances_to_engine(self): """ - This method adds the set of particles instances and bond instances + This method adds the set of particles instances and bond instances and angle instances that are not present in the pymbe data base """ diff --git a/samples/Beyer2024/globular_protein.py b/samples/Beyer2024/globular_protein.py index 6cbbaf63..2d2b9bd1 100644 --- a/samples/Beyer2024/globular_protein.py +++ b/samples/Beyer2024/globular_protein.py @@ -180,6 +180,9 @@ number_of_proteins=1, box_l=box_l, topology_dict=topology_dict)[0] + +pmb.set_simulation_engine(espresso_system) +pmb.add_instances_to_engine() #Here we activate the motion of the protein if args.move_protein: pmb.enable_motion_of_rigid_object(instance_id=protein_id, @@ -187,6 +190,7 @@ # Here we put the protein on the center of the simulation box pmb.center_object_in_simulation_box(instance_id=protein_id, + box_l=box_l, pmb_type="protein") if not args.ideal: @@ -201,7 +205,7 @@ if dist > protein_radius: protein_radius = dist # Create counter-ions - protein_net_charge = pmb.calculate_net_charge(espresso_system=espresso_system, + protein_net_charge = pmb.calculate_net_charge( object_name=protein_name, pmb_type="protein", dimensionless=True)["mean"] @@ -238,6 +242,7 @@ box_l=box_l, number_of_particles=N_ions, position=added_salt_ions_coords[N_ions:]) + pmb.add_instances_to_engine() #Here we calculated the ionisable groups acid_base_ids = [] @@ -281,13 +286,13 @@ if WCA: pmb.setup_lj_interactions() - relax_espresso_system( + pmb.simulation_engine.relax_espresso_system( seed=langevin_seed) if Electrostatics: - setup_electrostatic_interactions(units=pmb.units, + pmb.simulation_engine.setup_electrostatic_interactions(units=pmb.units, kT=pmb.kT) -setup_langevin_dynamics( +pmb.simulation_engine.setup_langevin_dynamics( kT = pmb.kT, seed = langevin_seed) diff --git a/samples/Beyer2024/peptide.py b/samples/Beyer2024/peptide.py index 9a34a39f..d3e59816 100644 --- a/samples/Beyer2024/peptide.py +++ b/samples/Beyer2024/peptide.py @@ -173,6 +173,9 @@ c_salt=c_salt, box_l=box_l) +pmb.set_simulation_engine(espresso_system) +pmb.add_instances_to_engine() + cpH = pmb.setup_cpH(counter_ion=cation_name, constant_pH=pH) @@ -192,7 +195,7 @@ print(f"The non-interacting type is set to {non_interacting_type}") #Setup the potential energy -pmb.setup_lj_interactions () +pmb.setup_lj_interactions() pmb.simulation_engine.relax_espresso_system( seed=langevin_seed) pmb.simulation_engine.setup_electrostatic_interactions(units=pmb.units, diff --git a/samples/Beyer2024/weak_polyelectrolyte_dialysis.py b/samples/Beyer2024/weak_polyelectrolyte_dialysis.py index 0c88fff7..c1ebfbc2 100644 --- a/samples/Beyer2024/weak_polyelectrolyte_dialysis.py +++ b/samples/Beyer2024/weak_polyelectrolyte_dialysis.py @@ -240,15 +240,14 @@ do_reaction(grxmc, steps=1000) pmb.simulation_engine.setup_electrostatic_interactions(units=pmb.units, - espresso_system=espresso_system, kT=pmb.kT, solvent_permittivity=solvent_permittivity, verbose=verbose) espresso_system.thermostat.turn_off() -pmb.simulation_engine.relax_espresso_system(espresso_system=espresso_system, +pmb.simulation_engine.relax_espresso_system( seed=langevin_seed, max_displacement=0.01) -pmb.simulation_engine.setup_langevin_dynamics(espresso_system=espresso_system, +pmb.simulation_engine.setup_langevin_dynamics( kT = pmb.kT, seed = langevin_seed, time_step=dt, diff --git a/samples/Landsgesell2022/plot_P_vs_V.py b/samples/Landsgesell2022/plot_P_vs_V.py index 069d555a..2130320c 100644 --- a/samples/Landsgesell2022/plot_P_vs_V.py +++ b/samples/Landsgesell2022/plot_P_vs_V.py @@ -39,8 +39,7 @@ unit_length=0.355*pmb.units.nm temperature=300*pmb.units.K pmb.set_reduced_units(unit_length=unit_length, - temperature=temperature, - verbose=False) + temperature=temperature) ref_cs = pmb.units.Quantity(0.00134770889, "1/reduced_length**3") ref_pH = 5 ref_max_L = 89.235257606948 # Maximum chain length for mpc=39 diff --git a/samples/Landsgesell2022/time_series/analyzed_data.csv b/samples/Landsgesell2022/time_series/analyzed_data.csv new file mode 100644 index 00000000..63f60f57 --- /dev/null +++ b/samples/Landsgesell2022/time_series/analyzed_data.csv @@ -0,0 +1,6 @@ +csalt,Lfraction,pH,pKa,time,mean,mean,err_mean,err_mean,n_eff,n_eff,tau_int,tau_int +value,value,value,value,value,alpha,pressure,alpha,pressure,alpha,pressure,alpha,pressure +0.05,0.303,5,4,series,0.3130902777777778,0.006637673197545152,0.002348016788745247,0.0013057389029067687,17.500047448881645,90.31837090146261,25.714215994228017,4.982375075174151 +0.01,0.366,4,4,series,0.09690972222222223,0.001441469395807051,0.0013700323136557884,0.0007015271738029402,25.341153861183148,94.24725327642176,17.75767601092228,4.774674957263725 +0.01,0.557,6,4,series,0.40944444444444444,0.0008973248364742591,0.002686687336756199,0.00028626814053342827,17.001784654504764,59.07799341029799,26.46780965377016,7.617049497340954 +0.05,0.51,5,4,series,0.3374652777777778,0.0018863979052295033,0.002469214964174571,0.00024059635451635818,19.06727554652686,93.48485942962414,23.600644932820035,4.813613699110119 diff --git a/samples/Landsgesell2022/time_series/csalt_0.01_Lfraction_0.366_pH_4_pKa_4_time_series.csv b/samples/Landsgesell2022/time_series/csalt_0.01_Lfraction_0.366_pH_4_pKa_4_time_series.csv new file mode 100644 index 00000000..2e842236 --- /dev/null +++ b/samples/Landsgesell2022/time_series/csalt_0.01_Lfraction_0.366_pH_4_pKa_4_time_series.csv @@ -0,0 +1,101 @@ +time,alpha,pressure +4977.000000062216,0.090625,0.007298596818290803 +4987.000000062434,0.096875,-0.006066162057896683 +4997.000000062652,0.096875,-0.0029993456649585483 +5007.000000062871,0.09375,-0.011162997567484312 +5017.000000063089,0.1,0.01293812398736898 +5027.000000063307,0.0984375,-0.006051894856802519 +5037.0000000635255,0.1109375,-0.001765460318838193 +5047.000000063744,0.1015625,-0.0009893883701956303 +5057.000000063962,0.096875,0.0015979402025707162 +5067.00000006418,0.10625,0.0007466553290843234 +5077.000000064399,0.1,0.004794223237512022 +5087.000000064617,0.0984375,0.004241926461831794 +5097.000000064835,0.1015625,-0.008202366080594428 +5107.000000065053,0.103125,0.008345479559010396 +5117.000000065272,0.10625,-0.0058258008384603184 +5127.00000006549,0.0953125,0.0007072667408184794 +5137.000000065708,0.0921875,0.0011183638553823958 +5147.0000000659265,0.1078125,-0.003915076519523996 +5157.000000066145,0.1015625,-0.0031989050077965444 +5167.000000066363,0.103125,0.0019481253035433166 +5177.000000066581,0.1015625,-0.015500163927000809 +5187.0000000668,0.0921875,0.011803551686278358 +5197.000000067018,0.0953125,-0.0027557407321090045 +5207.000000067236,0.0890625,0.003285337201455372 +5217.0000000674545,0.0921875,0.0058088488001194405 +5227.000000067673,0.10625,0.005342584201808266 +5237.000000067891,0.0984375,0.0034547366715992054 +5247.000000068109,0.1015625,0.000327779875972272 +5257.000000068328,0.103125,0.002204999011639492 +5267.000000068546,0.103125,0.0032067550910004836 +5277.000000068764,0.1,0.002455368917916059 +5287.000000068982,0.1,-0.0038840227147260878 +5297.000000069201,0.096875,0.004577942078110133 +5307.000000069419,0.0984375,0.011505673538528221 +5317.000000069637,0.0921875,0.0010202208394521027 +5327.000000069856,0.09375,-0.004640448438885074 +5337.000000070074,0.096875,0.0001271164909220631 +5347.000000070292,0.103125,-0.00522511030843317 +5357.00000007051,0.1078125,0.005008166963682322 +5367.000000070729,0.1015625,0.012071109497163161 +5377.000000070947,0.10625,0.014507800821739145 +5387.000000071165,0.109375,-0.01204681711916665 +5397.0000000713835,0.10625,0.004275632773751453 +5407.000000071602,0.1046875,-0.0038676353026881965 +5417.00000007182,0.096875,0.010019996005446737 +5427.000000072038,0.1046875,-0.0019236942533183237 +5437.000000072257,0.09375,0.0013243782009882946 +5447.000000072475,0.1,0.005655784827135663 +5457.000000072693,0.096875,0.0030909174662658713 +5467.0000000729115,0.09375,0.0045785640155599295 +5477.00000007313,0.0984375,0.0010566772196602865 +5487.000000073348,0.0890625,0.002083088825904527 +5497.000000073566,0.0921875,-0.005050485577207009 +5507.000000073785,0.0953125,0.006127146463186975 +5517.000000074003,0.090625,0.003942592687401529 +5527.000000074221,0.090625,-0.005389849273466112 +5537.000000074439,0.096875,-0.004582164044854593 +5547.000000074658,0.0921875,-0.0008746486761736144 +5557.000000074876,0.0828125,-0.007893658444952956 +5567.000000075094,0.08125,0.0039859580064869745 +5577.0000000753125,0.084375,0.006125012890202206 +5587.000000075531,0.0875,-0.00687059267421311 +5597.000000075749,0.0875,0.0029516612247224134 +5607.000000075967,0.0890625,-0.0008450135969176407 +5617.000000076186,0.0859375,5.8010322138158646e-05 +5627.000000076404,0.0921875,0.005509682691983357 +5637.000000076622,0.1046875,-0.0013718345244492565 +5647.0000000768405,0.09375,0.012793031565432674 +5657.000000077059,0.0859375,7.775405745543325e-05 +5667.000000077277,0.0921875,-0.004566809620667924 +5677.000000077495,0.1,-0.006600931741901173 +5687.000000077714,0.103125,0.019546635957261662 +5697.000000077932,0.096875,0.0135289713867134 +5707.00000007815,0.1,0.005491030539945144 +5717.000000078368,0.090625,0.007463639095545582 +5727.000000078587,0.084375,-0.006433400476846697 +5737.000000078805,0.0859375,-0.001680232945786643 +5747.000000079023,0.0859375,0.002621531149280668 +5757.0000000792415,0.0890625,-0.0006063492574107833 +5767.00000007946,0.0859375,-0.011087742084978168 +5777.000000079678,0.0875,-0.0023919430175641777 +5787.000000079896,0.1,0.0018199208060117238 +5797.000000080115,0.1046875,0.010322597888276767 +5807.000000080333,0.109375,0.0011026104435534207 +5817.000000080551,0.1,0.008507325881111956 +5827.0000000807695,0.096875,-0.00034799852696410817 +5837.000000080988,0.0953125,0.0035011182276818453 +5847.000000081206,0.09375,0.00431882516647842 +5857.000000081424,0.1,-0.011847547531173848 +5867.000000081643,0.10625,-0.004969443923626165 +5877.000000081861,0.1109375,-0.003107740773928227 +5887.000000082079,0.1046875,0.012924554326465365 +5897.000000082297,0.1015625,-0.004848074735727097 +5907.000000082516,0.09375,0.014380415269018154 +5917.000000082734,0.096875,-0.011353035433259807 +5927.000000082952,0.096875,-0.009318143020031864 +5937.000000083171,0.103125,0.013227677947344673 +5947.000000083389,0.0984375,0.00255448301462788 +5957.000000083607,0.0984375,0.004365789168266012 +5967.000000083825,0.09375,0.005559274410649666 diff --git a/samples/Landsgesell2022/time_series/csalt_0.01_Lfraction_0.557_pH_6_pKa_4_time_series.csv b/samples/Landsgesell2022/time_series/csalt_0.01_Lfraction_0.557_pH_6_pKa_4_time_series.csv new file mode 100644 index 00000000..290a0354 --- /dev/null +++ b/samples/Landsgesell2022/time_series/csalt_0.01_Lfraction_0.557_pH_6_pKa_4_time_series.csv @@ -0,0 +1,101 @@ +time,alpha,pressure +4082.0000000426803,0.3921875,0.00036499039922930883 +4092.0000000428986,0.3953125,8.975779910861546e-05 +4102.000000043116,0.396875,0.0010055773366355572 +4112.000000043335,0.3890625,-0.0007715054700716869 +4122.000000043553,0.4,0.0022068316690098603 +4132.000000043771,0.3953125,-0.00027404684533329074 +4142.0000000439895,0.3890625,0.0038149090885986766 +4152.000000044208,0.3859375,0.004083517197976683 +4162.000000044426,0.39375,-0.00031514263751571044 +4172.000000044644,0.396875,0.0038428126740801746 +4182.000000044863,0.4140625,0.002295048194401955 +4192.000000045081,0.4078125,0.005078253970089698 +4202.000000045299,0.409375,0.0005379446158911607 +4212.0000000455175,0.40625,0.00024285745682037075 +4222.000000045736,0.4109375,-0.0005489343817979694 +4232.000000045954,0.403125,0.0008397356128196125 +4242.000000046172,0.40625,0.0009201663537082064 +4252.000000046391,0.4046875,-0.00010794922356432153 +4262.000000046609,0.3984375,0.0008260050674024056 +4272.000000046827,0.396875,-0.0010016599501987498 +4282.000000047045,0.3921875,0.0037744757257149107 +4292.000000047264,0.3984375,0.0022381752319531978 +4302.000000047482,0.403125,-0.0005404661785675507 +4312.0000000477,0.3984375,0.0019567021348493043 +4322.000000047919,0.4078125,0.0038235590241885646 +4332.000000048137,0.40625,-0.0009551330907727352 +4342.000000048355,0.4125,-0.00039836221176166986 +4352.000000048573,0.4046875,-0.0021133834192513493 +4362.000000048792,0.409375,-0.0012468615165295864 +4372.00000004901,0.415625,-0.0015427437847578193 +4382.000000049228,0.4109375,0.0013417683008758322 +4392.0000000494465,0.4125,0.0017053975357111649 +4402.000000049665,0.409375,0.0030148047876002843 +4412.000000049883,0.40625,-0.00270723941114844 +4422.000000050101,0.4015625,0.006078028581797966 +4432.00000005032,0.3984375,0.002275925515133006 +4442.000000050538,0.3875,0.0020337096126363534 +4452.000000050756,0.3875,0.001652823981434018 +4462.000000050974,0.390625,-0.0018523064752998739 +4472.000000051193,0.3828125,-0.0012821177788007747 +4482.000000051411,0.3890625,0.0033761126888831854 +4492.000000051629,0.384375,0.0026795780087570304 +4502.000000051848,0.3921875,0.0042517381329556375 +4512.000000052066,0.3875,0.004281254409079208 +4522.000000052284,0.3890625,0.0035150735736647256 +4532.000000052502,0.4015625,0.0004952259103612795 +4542.000000052721,0.4,0.00279333599561581 +4552.000000052939,0.3953125,-0.0015716807689500787 +4562.000000053157,0.4046875,0.0021942090985900067 +4572.0000000533755,0.4,0.0027298238255471104 +4582.000000053594,0.4,0.0007487899088797675 +4592.000000053812,0.40625,0.003240796283508576 +4602.00000005403,0.4140625,-0.001026754904132663 +4612.000000054249,0.409375,0.003913789269131982 +4622.000000054467,0.409375,0.0017390190902873987 +4632.000000054685,0.40625,0.003389106715033901 +4642.0000000549035,0.403125,0.002577307680653623 +4652.000000055122,0.4046875,-0.0021169435311988384 +4662.00000005534,0.4078125,0.002793546071384313 +4672.000000055558,0.4078125,-0.0021410346467737626 +4682.000000055777,0.415625,0.0016358654144971341 +4692.000000055995,0.4171875,0.001841379329859525 +4702.000000056213,0.4109375,0.00020203919973331495 +4712.000000056431,0.4265625,0.0012460490849767693 +4722.00000005665,0.4234375,0.0017307700875192303 +4732.000000056868,0.4296875,-0.0014226227654321629 +4742.000000057086,0.4296875,0.001285856416274927 +4752.0000000573045,0.4265625,-0.00023221444410965585 +4762.000000057523,0.4171875,0.002027995257783206 +4772.000000057741,0.41875,0.00199168188908604 +4782.000000057959,0.415625,0.002651702462944648 +4792.000000058178,0.4234375,0.0009439421439512492 +4802.000000058396,0.41875,0.002341744791181546 +4812.000000058614,0.4203125,0.003451878472839611 +4822.0000000588325,0.41875,-0.0010234162003669187 +4832.000000059051,0.4203125,-0.0007776730822806373 +4842.000000059269,0.4109375,0.0007165328856179685 +4852.000000059487,0.4125,-0.002546639058536727 +4862.000000059706,0.421875,0.0008722695075175038 +4872.000000059924,0.41875,-0.00042043966744822743 +4882.000000060142,0.415625,-0.00330648696701416 +4892.00000006036,0.4234375,0.0009414815580792917 +4902.000000060579,0.4125,-0.006169263831269538 +4912.000000060797,0.41875,-0.001700417830375587 +4922.000000061015,0.415625,0.0027615962624003513 +4932.000000061234,0.4203125,0.0018433387774753436 +4942.000000061452,0.421875,0.002484782348788227 +4952.00000006167,0.4203125,0.002555373496495365 +4962.000000061888,0.41875,-0.00333011949604362 +4972.000000062107,0.425,0.004069055665510145 +4982.000000062325,0.425,-0.00037257808172680857 +4992.000000062543,0.421875,-0.0002404356532255738 +5002.0000000627615,0.41875,7.650438935894058e-05 +5012.00000006298,0.4234375,0.0011598445520450893 +5022.000000063198,0.421875,-0.0040981157978188945 +5032.000000063416,0.4140625,0.0011824036594570585 +5042.000000063635,0.4109375,-0.0009128256914903895 +5052.000000063853,0.409375,0.0018052077977814675 +5062.000000064071,0.403125,-0.0007615639302759686 +5072.000000064289,0.40625,0.0020542352370697225 diff --git a/samples/Landsgesell2022/time_series/csalt_0.05_Lfraction_0.303_pH_5_pKa_4_time_series.csv b/samples/Landsgesell2022/time_series/csalt_0.05_Lfraction_0.303_pH_5_pKa_4_time_series.csv new file mode 100644 index 00000000..95ba686b --- /dev/null +++ b/samples/Landsgesell2022/time_series/csalt_0.05_Lfraction_0.303_pH_5_pKa_4_time_series.csv @@ -0,0 +1,101 @@ +time,alpha,pressure +5277.000000068764,0.3046875,-0.00525602049939856 +5287.000000068982,0.30625,0.011121494906860159 +5297.000000069201,0.309375,0.008174206795178678 +5307.000000069419,0.30625,-0.000797768585701541 +5317.000000069637,0.3109375,0.021921773713701038 +5327.000000069856,0.309375,0.02127582564284194 +5337.000000070074,0.3,-0.0005388735487219203 +5347.000000070292,0.3,0.0033853197067596433 +5357.00000007051,0.303125,0.012843467362114292 +5367.000000070729,0.3046875,0.010987477426987689 +5377.000000070947,0.3109375,0.027787335109421687 +5387.000000071165,0.3078125,1.6786562582514833e-05 +5397.0000000713835,0.3109375,0.028954262297802735 +5407.000000071602,0.3140625,0.012132399739407038 +5417.00000007182,0.3171875,0.004075652494757091 +5427.000000072038,0.3125,0.014639854262636842 +5437.000000072257,0.3125,0.006857696667907971 +5447.000000072475,0.303125,-0.011524013334012253 +5457.000000072693,0.3125,0.017098606679452455 +5467.0000000729115,0.3109375,0.004280494854826324 +5477.00000007313,0.3125,0.0034997417254259908 +5487.000000073348,0.3125,0.03165750274759563 +5497.000000073566,0.3015625,0.010295262845157345 +5507.000000073785,0.29375,0.009230031118647378 +5517.000000074003,0.2984375,0.015375237303064485 +5527.000000074221,0.284375,0.008151754139703626 +5537.000000074439,0.2921875,-0.01785722168507675 +5547.000000074658,0.3,0.010511369511764517 +5557.000000074876,0.303125,-0.017320359317595253 +5567.000000075094,0.315625,0.025334956785596625 +5577.0000000753125,0.315625,0.03841059560426624 +5587.000000075531,0.321875,-0.009763745338235113 +5597.000000075749,0.321875,0.018930760346552764 +5607.000000075967,0.3265625,0.02580411489431204 +5617.000000076186,0.3265625,0.010246947994203955 +5627.000000076404,0.315625,0.006807820394994242 +5637.000000076622,0.3140625,0.019177499990728347 +5647.0000000768405,0.3140625,0.019555620008108874 +5657.000000077059,0.309375,0.009666503971831213 +5667.000000077277,0.3078125,-0.0019718827839153726 +5677.000000077495,0.30625,0.0010047638618087505 +5687.000000077714,0.3046875,-0.021982679509196214 +5697.000000077932,0.3140625,0.011786026473541685 +5707.00000007815,0.3125,0.012767758428125971 +5717.000000078368,0.309375,0.010419379527526853 +5727.000000078587,0.3078125,-0.0033552022286734047 +5737.000000078805,0.3109375,0.0166805737930335 +5747.000000079023,0.303125,0.01887441054716652 +5757.0000000792415,0.303125,-0.002565214448872702 +5767.00000007946,0.3,0.01990372058188579 +5777.000000079678,0.30625,0.004708031717746801 +5787.000000079896,0.30625,-0.011984568362775264 +5797.000000080115,0.303125,0.01576818989755958 +5807.000000080333,0.303125,-0.00790555661921247 +5817.000000080551,0.2984375,-0.0001334700355421352 +5827.0000000807695,0.2953125,-0.003847025711096349 +5837.000000080988,0.29375,0.014728176426108136 +5847.000000081206,0.3,-0.005128123777579772 +5857.000000081424,0.3046875,0.021572931395397493 +5867.000000081643,0.3015625,-0.009267635938509945 +5877.000000081861,0.309375,0.004355899415920146 +5887.000000082079,0.3140625,0.012270714772339368 +5897.000000082297,0.3109375,0.0052253722842176146 +5907.000000082516,0.309375,0.01065547683298493 +5917.000000082734,0.3140625,0.014468038129548664 +5927.000000082952,0.30625,-0.006063194879796736 +5937.000000083171,0.31875,-0.003563922951325347 +5947.000000083389,0.321875,0.009750528334802477 +5957.000000083607,0.3203125,-0.006040739540940765 +5967.000000083825,0.3171875,-0.0046372580690026 +5977.000000084044,0.309375,0.015250888726299608 +5987.000000084262,0.3171875,0.002295311878945728 +5997.00000008448,0.3125,0.0063310230747670735 +6007.0000000846985,0.3171875,-0.020658240115409978 +6017.000000084917,0.315625,-0.0002894241173200876 +6027.000000085135,0.3203125,0.011162091258089868 +6037.000000085353,0.31875,-0.01463174588686673 +6047.000000085572,0.3140625,0.0022683857782851056 +6057.00000008579,0.321875,-0.0039562682767511695 +6067.000000086008,0.321875,0.015593198392859497 +6077.0000000862265,0.325,0.00803976513064207 +6087.000000086445,0.3234375,0.009216590019220441 +6097.000000086663,0.3140625,0.019747145662176186 +6107.000000086881,0.31875,0.03661114535129495 +6117.0000000871,0.321875,0.00812025513121504 +6127.000000087318,0.321875,-0.009530487585460504 +6137.000000087536,0.325,0.0001277299569873294 +6147.000000087754,0.3296875,0.021491965549969117 +6157.000000087973,0.3265625,0.0008374358688529966 +6167.000000088191,0.3296875,0.004307883794832469 +6177.000000088409,0.325,-0.004702823953360071 +6187.0000000886275,0.3171875,0.0013038470724201303 +6197.000000088846,0.31875,0.010352469437553023 +6207.000000089064,0.3203125,0.023765564283934046 +6217.000000089282,0.3234375,-0.0021930126804463965 +6227.000000089501,0.3234375,0.008906912770784191 +6237.000000089719,0.3296875,0.0016534844888732392 +6247.000000089937,0.33125,0.006805810996978819 +6257.0000000901555,0.3234375,0.007783828251230674 +6267.000000090374,0.334375,-0.007147128420634772 diff --git a/samples/Landsgesell2022/time_series/csalt_0.05_Lfraction_0.51_pH_5_pKa_4_time_series.csv b/samples/Landsgesell2022/time_series/csalt_0.05_Lfraction_0.51_pH_5_pKa_4_time_series.csv new file mode 100644 index 00000000..ffd27e54 --- /dev/null +++ b/samples/Landsgesell2022/time_series/csalt_0.05_Lfraction_0.51_pH_5_pKa_4_time_series.csv @@ -0,0 +1,101 @@ +time,alpha,pressure +4307.000000047591,0.334375,0.007295379117841711 +4317.000000047809,0.31875,0.0024741150086576816 +4327.000000048028,0.3125,-0.0001349766957618122 +4337.000000048246,0.315625,0.006489525556953459 +4347.000000048464,0.325,0.0026029493258455105 +4357.0000000486825,0.3234375,0.002771205767589858 +4367.000000048901,0.334375,-0.0023479847518030816 +4377.000000049119,0.3453125,-0.00014976506257215034 +4387.000000049337,0.346875,0.0005307378686189346 +4397.000000049556,0.3390625,0.0030026599366683535 +4407.000000049774,0.34375,0.0045147370945092915 +4417.000000049992,0.346875,0.004855490017274356 +4427.0000000502105,0.3390625,0.00017312959759600995 +4437.000000050429,0.33125,0.0010438694922435146 +4447.000000050647,0.3328125,-0.0016545418127208323 +4457.000000050865,0.334375,0.0020358084942147955 +4467.000000051084,0.334375,0.007003699446159239 +4477.000000051302,0.334375,0.0006872312193505157 +4487.00000005152,0.3296875,0.00716836702098914 +4497.000000051738,0.3171875,0.00570291013976616 +4507.000000051957,0.321875,-0.00046307874239099575 +4517.000000052175,0.33125,-0.00045315223571652623 +4527.000000052393,0.3375,0.001726007534394617 +4537.0000000526115,0.328125,-0.0005228050607182867 +4547.00000005283,0.3296875,0.005428000568497918 +4557.000000053048,0.340625,0.001023994788816869 +4567.000000053266,0.334375,0.0030087437630384995 +4577.000000053485,0.33125,0.0012014294848683596 +4587.000000053703,0.334375,0.0002851605432010945 +4597.000000053921,0.3359375,0.002292324611379094 +4607.0000000541395,0.3296875,0.002934686900233493 +4617.000000054358,0.3265625,0.0003788334062213324 +4627.000000054576,0.31875,0.004472918820112234 +4637.000000054794,0.334375,0.002667056684959741 +4647.000000055013,0.3328125,0.0008274935831574509 +4657.000000055231,0.3328125,0.005518542415398456 +4667.000000055449,0.3359375,0.003827070944783175 +4677.000000055667,0.3265625,0.0011991423888822017 +4687.000000055886,0.3234375,0.002680204760694091 +4697.000000056104,0.321875,0.0019455650671982158 +4707.000000056322,0.3125,0.0013823397542306437 +4717.000000056541,0.325,0.0008333857958227315 +4727.000000056759,0.3203125,0.002655082037080553 +4737.000000056977,0.325,-0.0034109607449900555 +4747.000000057195,0.328125,0.0008881753998886049 +4757.000000057414,0.328125,0.0025642989235529563 +4767.000000057632,0.328125,0.006456678275483456 +4777.00000005785,0.325,0.0020866475194106 +4787.0000000580685,0.3203125,0.007387601119542534 +4797.000000058287,0.325,-6.947113587710476e-05 +4807.000000058505,0.321875,0.004612416748054225 +4817.000000058723,0.31875,0.002808570997889602 +4827.000000058942,0.3265625,0.0016899912223727516 +4837.00000005916,0.3390625,-0.0003034299791002461 +4847.000000059378,0.34375,0.002656120538925814 +4857.0000000595965,0.353125,0.002730461941785284 +4867.000000059815,0.353125,0.002209603970293915 +4877.000000060033,0.35625,0.00042501235693333483 +4887.000000060251,0.35,-0.0013040895753778754 +4897.00000006047,0.3390625,-0.0004369041668293343 +4907.000000060688,0.3421875,0.002437538786254292 +4917.000000060906,0.3390625,0.0006544250520181524 +4927.000000061124,0.3296875,0.0036071081068100603 +4937.000000061343,0.3296875,0.0005685672910608655 +4947.000000061561,0.33125,0.0007682451204520665 +4957.000000061779,0.34375,-0.0021749117494678353 +4967.0000000619975,0.3375,0.0008770112460226891 +4977.000000062216,0.3359375,0.0011141433953479596 +4987.000000062434,0.340625,0.0027987880364485174 +4997.000000062652,0.34375,0.0005646310561778439 +5007.000000062871,0.3421875,0.0033101786033502517 +5017.000000063089,0.346875,0.004561222994358272 +5027.000000063307,0.35,0.00012991585823010033 +5037.0000000635255,0.3453125,0.0017898959648241714 +5047.000000063744,0.346875,0.002586003745628818 +5057.000000063962,0.3421875,-0.0006811161943429777 +5067.00000006418,0.340625,-0.001382007238706989 +5077.000000064399,0.33125,0.007081072376181341 +5087.000000064617,0.334375,0.004459376325592985 +5097.000000064835,0.346875,0.0013808755737096806 +5107.000000065053,0.3421875,-0.0007150728563269929 +5117.000000065272,0.3484375,-0.0022713586224796405 +5127.00000006549,0.35625,0.003439844338875147 +5137.000000065708,0.3421875,0.0013376032449136236 +5147.0000000659265,0.3484375,0.0035713153607207903 +5157.000000066145,0.340625,0.001197897665585768 +5167.000000066363,0.3375,0.0027995219727905 +5177.000000066581,0.340625,0.001620918478132281 +5187.0000000668,0.35,-0.0014653182956971187 +5197.000000067018,0.35,0.00011811783857307847 +5207.000000067236,0.353125,-0.0001493417849880627 +5217.0000000674545,0.3515625,0.006010853779104497 +5227.000000067673,0.35625,0.0019356838178235282 +5237.000000067891,0.35,0.0048513485609838316 +5247.000000068109,0.3484375,-0.0007992211439831735 +5257.000000068328,0.3546875,0.0005822763795813079 +5267.000000068546,0.353125,0.004337316254469169 +5277.000000068764,0.35625,-0.001398564476115319 +5287.000000068982,0.3515625,0.0026483058891762466 +5297.000000069201,0.35,0.000302348784082541 diff --git a/samples/salt_solution_gcmc.py b/samples/salt_solution_gcmc.py index 967a6c5c..9aeb4aba 100644 --- a/samples/salt_solution_gcmc.py +++ b/samples/salt_solution_gcmc.py @@ -29,11 +29,8 @@ import pyMBE from pyMBE.lib import analysis #Import functions from handy_functions script -from pyMBE.lib.handy_functions import relax_espresso_system -from pyMBE.lib.handy_functions import setup_electrostatic_interactions -from pyMBE.lib.handy_functions import setup_langevin_dynamics + from pyMBE.lib.handy_functions import get_number_of_particles -from pyMBE.lib.handy_functions import do_reaction # Create an instance of pyMBE library pmb = pyMBE.pymbe_library(seed=42) @@ -96,6 +93,8 @@ # Create an instance of an espresso system box_l= [L.to('reduced_length').magnitude]*3 espresso_system=espressomd.System (box_l =box_l) +pmb.set_simulation_engine(espresso_system) + if verbose: print("Created espresso object") @@ -103,7 +102,10 @@ c_salt_calculated = pmb.create_added_salt(box_l=box_l, cation_name=cation_name, anion_name=anion_name, + c_salt=0.5*c_salt_res) +pmb.add_instances_to_engine() + if verbose: print("Added salt") @@ -143,7 +145,7 @@ espresso_system.cell_system.skin=0.4 if args.mode == "interacting": #Set up the short-range interactions - pmb.setup_lj_interactions(espresso_system=espresso_system) + pmb.setup_lj_interactions() # Minimzation pmb.simulation_engine.relax_espresso_system( diff --git a/samples/weak_polyacid_hydrogel_grxmc.py b/samples/weak_polyacid_hydrogel_grxmc.py index 2255552b..c3be55fa 100644 --- a/samples/weak_polyacid_hydrogel_grxmc.py +++ b/samples/weak_polyacid_hydrogel_grxmc.py @@ -33,9 +33,7 @@ pmb = pyMBE.pymbe_library(seed=42) # Load some functions from the handy_scripts library for convenience -from pyMBE.lib.handy_functions import setup_electrostatic_interactions -from pyMBE.lib.handy_functions import relax_espresso_system -from pyMBE.lib.handy_functions import setup_langevin_dynamics + from pyMBE.lib.handy_functions import do_reaction ####################################################### diff --git a/testsuite/angle_tests.py b/testsuite/angle_tests.py index f1e0e0cf..d022670e 100644 --- a/testsuite/angle_tests.py +++ b/testsuite/angle_tests.py @@ -281,11 +281,11 @@ def test_get_espresso_angle_instance_reuses_cached_object(self): angle_template = pmb.get_angle_template(side_name1="A", central_name="B", side_name2="C") - - first_angle_object = pmb._get_espresso_angle_instance(angle_template=angle_template, - espresso_system=espresso_system) - second_angle_object = pmb._get_espresso_angle_instance(angle_template=angle_template, - espresso_system=espresso_system) + + pmb.set_simulation_engine(espresso_system) + print(espresso_system,"espresso_system") + first_angle_object = pmb._get_espresso_angle_instance(angle_template=angle_template) + second_angle_object = pmb._get_espresso_angle_instance(angle_template=angle_template) self.assertIs(first_angle_object, second_angle_object) self.assertEqual(len(pmb.db.espresso_angle_instances), 1) From b1a99a92755988c50bd2e4e89564a6f444bf1f9d Mon Sep 17 00:00:00 2001 From: jsd94 Date: Wed, 10 Jun 2026 23:21:28 +0200 Subject: [PATCH 56/75] Add box_l argument to _create_hydrogel_chain --- pyMBE/pyMBE.py | 13 ++++++++----- pyMBE/simulation_builder/espresso_engine.py | 2 ++ samples/weak_polyacid_hydrogel_grxmc.py | 4 +--- testsuite/lattice_builder.py | 5 ++++- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/pyMBE/pyMBE.py b/pyMBE/pyMBE.py index d45f71ed..79b46e01 100644 --- a/pyMBE/pyMBE.py +++ b/pyMBE/pyMBE.py @@ -224,7 +224,7 @@ def _create_espresso_bond_instance(self, bond_type, bond_parameters): bond_instance = self.simulation_engine._create_bond_instance(bond_type,bond_parameters) return bond_instance - def _create_hydrogel_chain(self, hydrogel_chain, nodes, use_default_bond=False, gen_angle=False): + def _create_hydrogel_chain(self, hydrogel_chain, nodes,box_l, use_default_bond=False, gen_angle=False): """ Creates a chain between two nodes of a hydrogel. @@ -233,7 +233,7 @@ def _create_hydrogel_chain(self, hydrogel_chain, nodes, use_default_bond=False, template of a hydrogel chain nodes ('dict'): {node_index: {"name": node_particle_name, "pos": node_position, "id": node_particle_instance_id}} - + box_l('list[float,float,float]'): side length of the simulation box for x,y and z coordinates. use_default_bond ('bool', optional): If True, use a default bond template if no specific template exists. Defaults to False. @@ -291,7 +291,7 @@ def _create_hydrogel_chain(self, hydrogel_chain, nodes, use_default_bond=False, first_bead_pos = np.array((nodes[node_start_label]["pos"])) + np.array(backbone_vector)*l0 mol_id = self.create_molecule(name=molecule_name, # Use the name defined earlier number_of_molecules=1, # Creating one chain - box_l=self.lattice_builder.box_l, ### Add lattice_builder box length size + box_l=box_l, ### Add lattice_builder box length size, this should be box_l=[self.lattice_builder.box_l]*3 list_of_first_residue_positions=[first_bead_pos.tolist()], #Start at the first node backbone_vector=np.array(backbone_vector)/l0, use_default_bond=use_default_bond, @@ -968,9 +968,11 @@ def create_hydrogel(self, name, box_l, use_default_bond=False, gen_angle=False): value=assembly_id) for hydrogel_chain in hydrogel_tpl.chain_map: molecule_id = self._create_hydrogel_chain(hydrogel_chain=hydrogel_chain, - nodes=nodes, + nodes=nodes, + box_l=box_l, use_default_bond=use_default_bond, - gen_angle=gen_angle) + gen_angle=gen_angle, + ) self.db._update_instance(instance_id=molecule_id, pmb_type="molecule", attribute="assembly_id", @@ -2920,6 +2922,7 @@ def setup_grxmc_reactions(self, pH_res, c_salt_res, proton_name, hydroxide_name, activity_coefficient=activity_coefficient, exclusion_range=exclusion_range, use_exclusion_radius_per_type=use_exclusion_radius_per_type) + return RE, ionic_strength_res elif isinstance(self.simulation_engine,LammpsSimulation): raise NotImplementedError('In this version espresso has only been decoupled. Interoperability with other engines is not yet provided') diff --git a/pyMBE/simulation_builder/espresso_engine.py b/pyMBE/simulation_builder/espresso_engine.py index c4fe74a5..5e646e5c 100644 --- a/pyMBE/simulation_builder/espresso_engine.py +++ b/pyMBE/simulation_builder/espresso_engine.py @@ -347,6 +347,8 @@ def change_volume_and_rescale_particles(self, d_new, dir="xyz"): self.espresso_system.change_volume_and_rescale_particles(d_new=d_new, dir=dir) return + + def do_reaction(self,algorithm, steps): """ Executes reaction steps using an ESPResSo reaction algorithm with diff --git a/samples/weak_polyacid_hydrogel_grxmc.py b/samples/weak_polyacid_hydrogel_grxmc.py index c3be55fa..944118ee 100644 --- a/samples/weak_polyacid_hydrogel_grxmc.py +++ b/samples/weak_polyacid_hydrogel_grxmc.py @@ -34,8 +34,6 @@ # Load some functions from the handy_scripts library for convenience -from pyMBE.lib.handy_functions import do_reaction - ####################################################### # Setting parameters for the simulation ####################################################### @@ -248,7 +246,7 @@ for i in tqdm.trange(100): espresso_system.integrator.run(steps=1000) - do_reaction(grxmc,1000) + pmb.simulation_engine.do_reaction(grxmc,1000) pmb.simulation_engine.setup_electrostatic_interactions(units=pmb.units, kT=pmb.kT, diff --git a/testsuite/lattice_builder.py b/testsuite/lattice_builder.py index 6a43e621..acc5f3c2 100644 --- a/testsuite/lattice_builder.py +++ b/testsuite/lattice_builder.py @@ -126,7 +126,8 @@ def test_lattice_setup(self): with self.assertRaises(ValueError): pmb._create_hydrogel_chain( "[0 0 0]", "[1 1 1]", - {0: [0, 0, 0], 1: diamond.box_l / 4.0 * np.ones(3)} + {0: [0, 0, 0], 1: diamond.box_l / 4.0 * np.ones(3)}, + [diamond.box_l]*3 ) # --- Lattice initialization --- @@ -244,6 +245,7 @@ def test_lattice_setup(self): molecule_name="test_chain") mol_id = pmb2._create_hydrogel_chain(hydrogel_chain=hydrogel_chain, nodes=nodes, + box_l=box_l, use_default_bond=True) # Extract created particle IDs chain_pids = pmb2.db._find_instance_ids_by_attribute(pmb_type="particle", @@ -284,6 +286,7 @@ def test_non_palindromic_self_loop_chain_raises(self): ): pmb._create_hydrogel_chain(hydrogel_chain=hydrogel_chain, nodes={}, + box_l=box_l, use_default_bond=False) def test_plot(self): From 217d15a41a0fda0c05d7125646c31ae3132376cd Mon Sep 17 00:00:00 2001 From: jsd94 Date: Mon, 22 Jun 2026 18:49:54 +0200 Subject: [PATCH 57/75] Fix box_l size to match a diamond lattice of monomer chains that contain mpc monomer + 2 nodes Fix backbone vector so that accounts for the number of monomers in the chain --- pyMBE/lib/lattice.py | 2 +- pyMBE/pyMBE.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyMBE/lib/lattice.py b/pyMBE/lib/lattice.py index 6b19a25a..4d63c492 100644 --- a/pyMBE/lib/lattice.py +++ b/pyMBE/lib/lattice.py @@ -333,5 +333,5 @@ def __init__(self,mpc,bond_l): raise ValueError("mpc must be a non-zero positive integer.") self.mpc = mpc self.bond_l = bond_l - self.box_l = (self.mpc+2)*self.bond_l.magnitude / (np.sqrt(3)*0.25) + self.box_l = (self.mpc+1)*self.bond_l.magnitude / (np.sqrt(3)*0.25) diff --git a/pyMBE/pyMBE.py b/pyMBE/pyMBE.py index 79b46e01..8e302901 100644 --- a/pyMBE/pyMBE.py +++ b/pyMBE/pyMBE.py @@ -272,7 +272,7 @@ def _create_hydrogel_chain(self, hydrogel_chain, nodes,box_l, use_default_bond=F # Finding a backbone vector between node_start and node_end vec_between_nodes = np.array(nodes[node_end_label]["pos"]) - np.array(nodes[node_start_label]["pos"]) vec_between_nodes = vec_between_nodes - self.lattice_builder.box_l * np.round(vec_between_nodes/self.lattice_builder.box_l) - backbone_vector = vec_between_nodes / np.linalg.norm(vec_between_nodes) + backbone_vector = vec_between_nodes / (self.lattice_builder.mpc+1) if reverse_residue_order: vec_between_nodes *= -1.0 # Calculate the start position of the chain From 3d63646a2186326bd90d296ca74c4d29ab335357 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Mon, 22 Jun 2026 18:51:05 +0200 Subject: [PATCH 58/75] Modify test so that the expected result is expressed in terms of magnitude instead of reduced length, because now the backbone vector in the polymeric chain between nodes is not normalized --- testsuite/hydrogel_builder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/hydrogel_builder.py b/testsuite/hydrogel_builder.py index d387391e..875492a3 100644 --- a/testsuite/hydrogel_builder.py +++ b/testsuite/hydrogel_builder.py @@ -203,7 +203,7 @@ def test_chain_length(self): molecule_ids = pmb.db._find_instance_ids_by_attribute(pmb_type="molecule", attribute="assembly_id", value=hydrogel_id) - expected = (diamond_lattice.mpc - 1) * generic_bond_length.m_as("reduced_length") + expected = (diamond_lattice.mpc -1) * generic_bond_length.magnitude for mol_id in molecule_ids: particle_ids = pmb.db._find_instance_ids_by_attribute(pmb_type="particle", attribute="molecule_id", From 698afb25bcc79e294262759634f30c3a191dd78b Mon Sep 17 00:00:00 2001 From: jsd94 Date: Wed, 24 Jun 2026 19:14:31 +0200 Subject: [PATCH 59/75] Calculate the resulting quantity of the chain length in reduced units instead of using the magnitude --- testsuite/hydrogel_builder.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testsuite/hydrogel_builder.py b/testsuite/hydrogel_builder.py index 875492a3..f7586136 100644 --- a/testsuite/hydrogel_builder.py +++ b/testsuite/hydrogel_builder.py @@ -203,14 +203,14 @@ def test_chain_length(self): molecule_ids = pmb.db._find_instance_ids_by_attribute(pmb_type="molecule", attribute="assembly_id", value=hydrogel_id) - expected = (diamond_lattice.mpc -1) * generic_bond_length.magnitude + expected = (diamond_lattice.mpc -1) * generic_bond_length.m_as('reduced_length') for mol_id in molecule_ids: particle_ids = pmb.db._find_instance_ids_by_attribute(pmb_type="particle", attribute="molecule_id", value=mol_id) positions = np.array([espresso_system.part.by_id(pid).pos for pid in particle_ids]) - contour = np.sum(np.linalg.norm(np.diff(positions, axis=0), axis=1)) - np.testing.assert_allclose(contour, expected, atol=1e-7) + contour = np.sum(np.linalg.norm(np.diff(positions, axis=0), axis=1))*pmb.units.nm + np.testing.assert_allclose(contour.m_as('reduced_length'), expected, atol=1e-7) def test_exceptions(self): """ From b5e4523decce2fd69cc415d91b05f8e9f2790b18 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Tue, 30 Jun 2026 17:06:26 +0200 Subject: [PATCH 60/75] Delete unused imports. Add box_l in create methods from hydrogel_builder_with_angles and setup_angular_potential. --- pyMBE/pyMBE.py | 2 -- samples/Beyer2024/globular_protein.py | 2 +- samples/Beyer2024/peptide.py | 1 - .../Beyer2024/weak_polyelectrolyte_dialysis.py | 3 --- samples/branched_polyampholyte.py | 4 ---- samples/build_hydrogel.py | 2 +- samples/peptide_cpH.py | 2 +- samples/peptide_mixture_grxmc_ideal.py | 2 +- samples/setup_angular_potential.py | 16 ++++++++-------- testsuite/create_molecule_position_test.py | 1 - testsuite/hydrogel_builder_with_angles.py | 2 +- 11 files changed, 13 insertions(+), 24 deletions(-) diff --git a/pyMBE/pyMBE.py b/pyMBE/pyMBE.py index 8e302901..81e107d8 100644 --- a/pyMBE/pyMBE.py +++ b/pyMBE/pyMBE.py @@ -25,7 +25,6 @@ import scipy.optimize import logging import importlib.resources -import warnings # Database from pyMBE.storage.manager import Manager @@ -39,7 +38,6 @@ from pyMBE.storage.templates.hydrogel import HydrogelTemplate, HydrogelNode, HydrogelChain from pyMBE.storage.templates.bond import BondTemplate from pyMBE.storage.templates.angle import AngleTemplate -from pyMBE.storage.templates.lj import LJInteractionTemplate ## Instances from pyMBE.storage.instances.particle import ParticleInstance from pyMBE.storage.instances.residue import ResidueInstance diff --git a/samples/Beyer2024/globular_protein.py b/samples/Beyer2024/globular_protein.py index 2d2b9bd1..b172ddce 100644 --- a/samples/Beyer2024/globular_protein.py +++ b/samples/Beyer2024/globular_protein.py @@ -28,7 +28,7 @@ pmb = pyMBE.pymbe_library(seed=42) #Import functions from handy_functions script -from pyMBE.lib.handy_functions import setup_electrostatic_interactions, relax_espresso_system, setup_langevin_dynamics, do_reaction, define_protein_AA_particles, define_protein_AA_residues +from pyMBE.lib.handy_functions import do_reaction, define_protein_AA_particles, define_protein_AA_residues from pyMBE.lib import analysis # Here you can adjust the width of the panda columns displayed when running the code pd.options.display.max_colwidth = 10 diff --git a/samples/Beyer2024/peptide.py b/samples/Beyer2024/peptide.py index d3e59816..d82f8cbf 100644 --- a/samples/Beyer2024/peptide.py +++ b/samples/Beyer2024/peptide.py @@ -26,7 +26,6 @@ # Import pyMBE import pyMBE from pyMBE.lib import analysis -from pyMBE.lib import handy_functions as hf from pyMBE.lib.handy_functions import do_reaction, define_peptide_AA_residues # Create an instance of pyMBE library diff --git a/samples/Beyer2024/weak_polyelectrolyte_dialysis.py b/samples/Beyer2024/weak_polyelectrolyte_dialysis.py index c1ebfbc2..0b15084b 100644 --- a/samples/Beyer2024/weak_polyelectrolyte_dialysis.py +++ b/samples/Beyer2024/weak_polyelectrolyte_dialysis.py @@ -37,9 +37,6 @@ pmb = pyMBE.pymbe_library(seed=42) # Load some functions from the handy_scripts library for convenience -from pyMBE.lib.handy_functions import setup_electrostatic_interactions -from pyMBE.lib.handy_functions import relax_espresso_system -from pyMBE.lib.handy_functions import setup_langevin_dynamics from pyMBE.lib.handy_functions import do_reaction diff --git a/samples/branched_polyampholyte.py b/samples/branched_polyampholyte.py index 032b3fc7..70715a76 100644 --- a/samples/branched_polyampholyte.py +++ b/samples/branched_polyampholyte.py @@ -26,10 +26,6 @@ import pyMBE # Load some functions from the handy_scripts library for convenience -from pyMBE.lib.handy_functions import setup_langevin_dynamics -from pyMBE.lib.handy_functions import relax_espresso_system -from pyMBE.lib.handy_functions import setup_electrostatic_interactions -from pyMBE.lib.handy_functions import do_reaction from pyMBE.lib.analysis import built_output_name diff --git a/samples/build_hydrogel.py b/samples/build_hydrogel.py index df6c61db..caf53cde 100644 --- a/samples/build_hydrogel.py +++ b/samples/build_hydrogel.py @@ -149,7 +149,7 @@ def define_hydrogel_with_angular_potential(espresso_system, include_crosslinker_ node_map=node_topology, chain_map=chain_topology) hydrogel_id = pmb.create_hydrogel(name="simple_hydrogel", - espresso_system=espresso_system, + box_l=espresso_system.box_l, gen_angle=True) return pmb, hydrogel_id, lattice_builder diff --git a/samples/peptide_cpH.py b/samples/peptide_cpH.py index d67bf24e..046aa326 100644 --- a/samples/peptide_cpH.py +++ b/samples/peptide_cpH.py @@ -29,7 +29,7 @@ pmb = pyMBE.pymbe_library(seed=42) # Load some functions from the handy_scripts library for convenience -from pyMBE.lib.handy_functions import setup_electrostatic_interactions, relax_espresso_system, setup_langevin_dynamics, do_reaction, define_peptide_AA_residues +from pyMBE.lib.handy_functions import define_peptide_AA_residues from pyMBE.lib.analysis import built_output_name parser = argparse.ArgumentParser(description='Sample script to run the pre-made peptide models with pyMBE') diff --git a/samples/peptide_mixture_grxmc_ideal.py b/samples/peptide_mixture_grxmc_ideal.py index 64d7184c..3cb6a482 100644 --- a/samples/peptide_mixture_grxmc_ideal.py +++ b/samples/peptide_mixture_grxmc_ideal.py @@ -24,7 +24,7 @@ from espressomd.io.writer import vtf import pyMBE from pyMBE.lib.analysis import built_output_name -from pyMBE.lib.handy_functions import do_reaction, define_peptide_AA_residues +from pyMBE.lib.handy_functions import define_peptide_AA_residues # Create an instance of pyMBE library pmb = pyMBE.pymbe_library(seed=42) diff --git a/samples/setup_angular_potential.py b/samples/setup_angular_potential.py index 4f6bb3da..8c12b116 100644 --- a/samples/setup_angular_potential.py +++ b/samples/setup_angular_potential.py @@ -36,7 +36,8 @@ # ---------------------------------------------------------------------- # Set up the ESPResSo system and pyMBE # ---------------------------------------------------------------------- -espresso_system = espressomd.System(box_l=[20] * 3) +box_l=[20] * 3 +espresso_system = espressomd.System(box_l=box_l) pmb = pyMBE.pymbe_library(seed=42) # ---------------------------------------------------------------------- @@ -102,7 +103,7 @@ def show_database(label): side_chains=["A", "B", "C"]) residue_id = pmb.create_residue(name="Res_1", - espresso_system=espresso_system, + box_l=box_l, use_default_bond=True, gen_angle=True) @@ -113,8 +114,7 @@ def show_database(label): # both ESPResSo and the pyMBE database before running Demo 2. # ---------------------------------------------------------------------- pmb.delete_instances_in_system(instance_id=residue_id, - pmb_type="residue", - espresso_system=espresso_system) + pmb_type="residue") # ====================================================================== @@ -146,7 +146,7 @@ def show_database(label): side_chains=["D", "SubRes_3"]) nested_residue_id = pmb.create_residue(name="NestedRes_3", - espresso_system=espresso_system, + box_l=box_l, use_default_bond=True, gen_angle=True) @@ -188,7 +188,7 @@ def show_database(label): molecule_ids = pmb.create_molecule(name="Mol_1", number_of_molecules=1, - espresso_system=espresso_system, + box_l=box_l, backbone_vector=[1.0, 0.0, 0.0], use_default_bond=True, gen_angle=True) @@ -196,6 +196,6 @@ def show_database(label): show_database("Demo 3: linear molecule with gen_angle=True") pmb.delete_instances_in_system(instance_id=molecule_ids[0], - pmb_type="molecule", - espresso_system=espresso_system) + pmb_type="molecule" + ) diff --git a/testsuite/create_molecule_position_test.py b/testsuite/create_molecule_position_test.py index d278049c..cbbc0583 100644 --- a/testsuite/create_molecule_position_test.py +++ b/testsuite/create_molecule_position_test.py @@ -19,7 +19,6 @@ import espressomd import pyMBE import unittest as ut -import pandas as pd pmb = pyMBE.pymbe_library(seed=42) diff --git a/testsuite/hydrogel_builder_with_angles.py b/testsuite/hydrogel_builder_with_angles.py index 6817c5ad..83726ec6 100644 --- a/testsuite/hydrogel_builder_with_angles.py +++ b/testsuite/hydrogel_builder_with_angles.py @@ -176,7 +176,7 @@ def test_hydrogel_gen_angle_defaults_to_false(self): """ Hydrogel creation should not generate angles unless gen_angle is requested. """ - pmb_local, espresso_system_local, hydrogel_name_local, _ = build_simple_hydrogel_with_optional_angles( + pmb_local, _, hydrogel_name_local, _ = build_simple_hydrogel_with_optional_angles( junction_angle_mode="full" ) pmb_local.create_hydrogel(hydrogel_name_local, box_l) From 7316798e9f9b4f4facd4c0e205aaefd32937ba79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jordi=20Sans=20Du=C3=B1=C3=B3?= <36412436+jorch28@users.noreply.github.com> Date: Tue, 30 Jun 2026 20:07:54 +0200 Subject: [PATCH 61/75] use np.prod(box_l) to replace box_l[0]*box_l[1]*box_l[2] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jean-Noël Grad --- pyMBE/pyMBE.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyMBE/pyMBE.py b/pyMBE/pyMBE.py index 81e107d8..add0dc49 100644 --- a/pyMBE/pyMBE.py +++ b/pyMBE/pyMBE.py @@ -781,7 +781,7 @@ def create_added_salt(self, box_l, cation_name, anion_name, c_salt): if anion_charge >= 0: raise ValueError(f'ERROR anion charge must be negative, charge {anion_charge}') # Calculate the number of ions in the simulation box - volume=self.units.Quantity(box_l[0]*box_l[1]*box_l[2], 'reduced_length**3') ### Changed espresso.volume() to box_l**3 + volume=self.units.Quantity(np.prod(box_l), 'reduced_length**3') if c_salt.check('[substance] [length]**-3'): N_ions= int((volume*c_salt.to('mol/reduced_length**3')*self.N_A).magnitude) c_salt_calculated=N_ions/(volume*self.N_A) From 2ca41b27c3f8cdc4740601db5724477c399638a0 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Tue, 30 Jun 2026 20:46:55 +0200 Subject: [PATCH 62/75] Add Copyright Notes --- pyMBE/exceptions/pmb_warnings.py | 18 ++++++++++++++++++ pyMBE/simulation_builder/base_engine.py | 18 ++++++++++++++++++ pyMBE/simulation_builder/engine_protocol.py | 18 ++++++++++++++++++ pyMBE/simulation_builder/espresso_engine.py | 17 +++++++++++++++++ pyMBE/simulation_builder/lammps_engine.py | 18 ++++++++++++++++++ 5 files changed, 89 insertions(+) diff --git a/pyMBE/exceptions/pmb_warnings.py b/pyMBE/exceptions/pmb_warnings.py index fdf849ff..aa1284f8 100644 --- a/pyMBE/exceptions/pmb_warnings.py +++ b/pyMBE/exceptions/pmb_warnings.py @@ -1,3 +1,21 @@ +# +# Copyright (C) 2023-2026 pyMBE-dev team +# +# This file is part of pyMBE. +# +# pyMBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# pyMBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + import warnings from functools import wraps diff --git a/pyMBE/simulation_builder/base_engine.py b/pyMBE/simulation_builder/base_engine.py index cfec24a9..8a4dd5f3 100644 --- a/pyMBE/simulation_builder/base_engine.py +++ b/pyMBE/simulation_builder/base_engine.py @@ -1,3 +1,21 @@ +# +# Copyright (C) 2023-2026 pyMBE-dev team +# +# This file is part of pyMBE. +# +# pyMBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# pyMBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + from abc import ABC,abstractmethod import numpy as np diff --git a/pyMBE/simulation_builder/engine_protocol.py b/pyMBE/simulation_builder/engine_protocol.py index 840c7071..8308cf97 100644 --- a/pyMBE/simulation_builder/engine_protocol.py +++ b/pyMBE/simulation_builder/engine_protocol.py @@ -1,3 +1,21 @@ +# +# Copyright (C) 2023-2026 pyMBE-dev team +# +# This file is part of pyMBE. +# +# pyMBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# pyMBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + from typing import Protocol,runtime_checkable class EspressoParticleProtocol(Protocol): diff --git a/pyMBE/simulation_builder/espresso_engine.py b/pyMBE/simulation_builder/espresso_engine.py index 5e646e5c..a1753d20 100644 --- a/pyMBE/simulation_builder/espresso_engine.py +++ b/pyMBE/simulation_builder/espresso_engine.py @@ -1,3 +1,20 @@ +# +# Copyright (C) 2023-2026 pyMBE-dev team +# +# This file is part of pyMBE. +# +# pyMBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# pyMBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . import espressomd import espressomd.electrostatics diff --git a/pyMBE/simulation_builder/lammps_engine.py b/pyMBE/simulation_builder/lammps_engine.py index e80e2cd7..9ef4bf39 100644 --- a/pyMBE/simulation_builder/lammps_engine.py +++ b/pyMBE/simulation_builder/lammps_engine.py @@ -1,3 +1,21 @@ +# +# Copyright (C) 2023-2026 pyMBE-dev team +# +# This file is part of pyMBE. +# +# pyMBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# pyMBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + from pyMBE.simulation_builder.base_engine import SimulationEngine From 06560f81d2cf14ec3768401cc00eb307bbacd4c2 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Tue, 30 Jun 2026 20:50:24 +0200 Subject: [PATCH 63/75] Clear pymbe_tutorial outputs --- tutorials/pyMBE_tutorial.ipynb | 6049 ++++---------------------------- 1 file changed, 608 insertions(+), 5441 deletions(-) diff --git a/tutorials/pyMBE_tutorial.ipynb b/tutorials/pyMBE_tutorial.ipynb index 24afbbb9..e365f02b 100644 --- a/tutorials/pyMBE_tutorial.ipynb +++ b/tutorials/pyMBE_tutorial.ipynb @@ -125,19 +125,7 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "GenericPlainRegistry.get_dimensionality() missing 1 required positional argument: 'input_units'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[8], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43mpmb\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43munits\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_dimensionality\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m)\n", - "\u001b[0;31mTypeError\u001b[0m: GenericPlainRegistry.get_dimensionality() missing 1 required positional argument: 'input_units'" - ] - } - ], + "outputs": [], "source": [ "print(pmb.units.get_group())" ] @@ -372,359 +360,9 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenameparticle_idpositionfixinitial_stateresidue_idmolecule_idassembly_id
0particleNa0[11.609340728339449, 6.583176596280784, 12.878...[False, False, False]Na<NA><NA><NA>
1particleNa1[10.460520435890457, 1.4126602183147428, 14.63...[False, False, False]Na<NA><NA><NA>
2particleNa2[11.417095529855294, 11.790964579154306, 1.921...[False, False, False]Na<NA><NA><NA>
3particleNa3[6.755789068433506, 5.561970363488718, 13.9014...[False, False, False]Na<NA><NA><NA>
4particleNa4[9.657976801209967, 12.341424199062448, 6.6512...[False, False, False]Na<NA><NA><NA>
5particleNa5[3.408580826771653, 8.318771805237521, 0.95725...[False, False, False]Na<NA><NA><NA>
6particleNa6[12.41446757988873, 9.474965986830972, 11.3713...[False, False, False]Na<NA><NA><NA>
7particleNa7[5.3178895219480244, 14.560470365923548, 13.39...[False, False, False]Na<NA><NA><NA>
8particleNa8[11.675752456106427, 2.919580617779513, 7.0008...[False, False, False]Na<NA><NA><NA>
9particleNa9[0.6570564868084315, 2.3143423810132173, 10.24...[False, False, False]Na<NA><NA><NA>
10particleNa10[11.171432338617256, 14.512645986513148, 4.887...[False, False, False]Na<NA><NA><NA>
11particleNa11[5.556895590523033, 7.043337169137118, 2.84207...[False, False, False]Na<NA><NA><NA>
12particleNa12[1.9488225800320744, 7.135573893389005, 3.4036...[False, False, False]Na<NA><NA><NA>
13particleNa13[10.047209920237654, 6.557278783084961, 12.490...[False, False, False]Na<NA><NA><NA>
14particleNa14[10.503976530033736, 4.685499620730615, 12.483...[False, False, False]Na<NA><NA><NA>
15particleNa15[12.071465362452027, 5.812175685452616, 4.3249...[False, False, False]Na<NA><NA><NA>
16particleNa16[10.237432559624631, 2.096287254139647, 2.9986...[False, False, False]Na<NA><NA><NA>
17particleNa17[0.11043404626508267, 11.803865662532074, 9.97...[False, False, False]Na<NA><NA><NA>
18particleNa18[10.577480679395025, 11.710935465329516, 6.883...[False, False, False]Na<NA><NA><NA>
19particleNa19[8.531117939293406, 2.0969549719148612, 1.7179...[False, False, False]Na<NA><NA><NA>
\n", - "
" - ], - "text/plain": [ - " pmb_type name particle_id \\\n", - "0 particle Na 0 \n", - "1 particle Na 1 \n", - "2 particle Na 2 \n", - "3 particle Na 3 \n", - "4 particle Na 4 \n", - "5 particle Na 5 \n", - "6 particle Na 6 \n", - "7 particle Na 7 \n", - "8 particle Na 8 \n", - "9 particle Na 9 \n", - "10 particle Na 10 \n", - "11 particle Na 11 \n", - "12 particle Na 12 \n", - "13 particle Na 13 \n", - "14 particle Na 14 \n", - "15 particle Na 15 \n", - "16 particle Na 16 \n", - "17 particle Na 17 \n", - "18 particle Na 18 \n", - "19 particle Na 19 \n", - "\n", - " position fix \\\n", - "0 [11.609340728339449, 6.583176596280784, 12.878... [False, False, False] \n", - "1 [10.460520435890457, 1.4126602183147428, 14.63... [False, False, False] \n", - "2 [11.417095529855294, 11.790964579154306, 1.921... [False, False, False] \n", - "3 [6.755789068433506, 5.561970363488718, 13.9014... [False, False, False] \n", - "4 [9.657976801209967, 12.341424199062448, 6.6512... [False, False, False] \n", - "5 [3.408580826771653, 8.318771805237521, 0.95725... [False, False, False] \n", - "6 [12.41446757988873, 9.474965986830972, 11.3713... [False, False, False] \n", - "7 [5.3178895219480244, 14.560470365923548, 13.39... [False, False, False] \n", - "8 [11.675752456106427, 2.919580617779513, 7.0008... [False, False, False] \n", - "9 [0.6570564868084315, 2.3143423810132173, 10.24... [False, False, False] \n", - "10 [11.171432338617256, 14.512645986513148, 4.887... [False, False, False] \n", - "11 [5.556895590523033, 7.043337169137118, 2.84207... [False, False, False] \n", - "12 [1.9488225800320744, 7.135573893389005, 3.4036... [False, False, False] \n", - "13 [10.047209920237654, 6.557278783084961, 12.490... [False, False, False] \n", - "14 [10.503976530033736, 4.685499620730615, 12.483... [False, False, False] \n", - "15 [12.071465362452027, 5.812175685452616, 4.3249... [False, False, False] \n", - "16 [10.237432559624631, 2.096287254139647, 2.9986... [False, False, False] \n", - "17 [0.11043404626508267, 11.803865662532074, 9.97... [False, False, False] \n", - "18 [10.577480679395025, 11.710935465329516, 6.883... [False, False, False] \n", - "19 [8.531117939293406, 2.0969549719148612, 1.7179... [False, False, False] \n", - "\n", - " initial_state residue_id molecule_id assembly_id \n", - "0 Na \n", - "1 Na \n", - "2 Na \n", - "3 Na \n", - "4 Na \n", - "5 Na \n", - "6 Na \n", - "7 Na \n", - "8 Na \n", - "9 Na \n", - "10 Na \n", - "11 Na \n", - "12 Na \n", - "13 Na \n", - "14 Na \n", - "15 Na \n", - "16 Na \n", - "17 Na \n", - "18 Na \n", - "19 Na " - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "pmb.get_instances_df(pmb_type = 'particle')" ] @@ -840,359 +478,9 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenameparticle_idpositionfixinitial_stateresidue_idmolecule_idassembly_id
0particleNa0[11.609340728339449, 6.583176596280784, 12.878...[False, False, False]Na<NA><NA><NA>
1particleNa1[10.460520435890457, 1.4126602183147428, 14.63...[False, False, False]Na<NA><NA><NA>
2particleNa2[11.417095529855294, 11.790964579154306, 1.921...[False, False, False]Na<NA><NA><NA>
3particleNa3[6.755789068433506, 5.561970363488718, 13.9014...[False, False, False]Na<NA><NA><NA>
4particleNa4[9.657976801209967, 12.341424199062448, 6.6512...[False, False, False]Na<NA><NA><NA>
5particleNa5[3.408580826771653, 8.318771805237521, 0.95725...[False, False, False]Na<NA><NA><NA>
6particleNa6[12.41446757988873, 9.474965986830972, 11.3713...[False, False, False]Na<NA><NA><NA>
7particleNa7[5.3178895219480244, 14.560470365923548, 13.39...[False, False, False]Na<NA><NA><NA>
8particleNa8[11.675752456106427, 2.919580617779513, 7.0008...[False, False, False]Na<NA><NA><NA>
9particleNa9[0.6570564868084315, 2.3143423810132173, 10.24...[False, False, False]Na<NA><NA><NA>
10particleNa10[11.171432338617256, 14.512645986513148, 4.887...[False, False, False]Na<NA><NA><NA>
11particleNa11[5.556895590523033, 7.043337169137118, 2.84207...[False, False, False]Na<NA><NA><NA>
12particleNa12[1.9488225800320744, 7.135573893389005, 3.4036...[False, False, False]Na<NA><NA><NA>
13particleNa13[10.047209920237654, 6.557278783084961, 12.490...[False, False, False]Na<NA><NA><NA>
14particleNa14[10.503976530033736, 4.685499620730615, 12.483...[False, False, False]Na<NA><NA><NA>
15particleNa15[12.071465362452027, 5.812175685452616, 4.3249...[False, False, False]Na<NA><NA><NA>
16particleNa16[10.237432559624631, 2.096287254139647, 2.9986...[False, False, False]Na<NA><NA><NA>
17particleNa17[0.11043404626508267, 11.803865662532074, 9.97...[False, False, False]Na<NA><NA><NA>
18particleNa18[10.577480679395025, 11.710935465329516, 6.883...[False, False, False]Na<NA><NA><NA>
19particleNa19[8.531117939293406, 2.0969549719148612, 1.7179...[False, False, False]Na<NA><NA><NA>
\n", - "
" - ], - "text/plain": [ - " pmb_type name particle_id \\\n", - "0 particle Na 0 \n", - "1 particle Na 1 \n", - "2 particle Na 2 \n", - "3 particle Na 3 \n", - "4 particle Na 4 \n", - "5 particle Na 5 \n", - "6 particle Na 6 \n", - "7 particle Na 7 \n", - "8 particle Na 8 \n", - "9 particle Na 9 \n", - "10 particle Na 10 \n", - "11 particle Na 11 \n", - "12 particle Na 12 \n", - "13 particle Na 13 \n", - "14 particle Na 14 \n", - "15 particle Na 15 \n", - "16 particle Na 16 \n", - "17 particle Na 17 \n", - "18 particle Na 18 \n", - "19 particle Na 19 \n", - "\n", - " position fix \\\n", - "0 [11.609340728339449, 6.583176596280784, 12.878... [False, False, False] \n", - "1 [10.460520435890457, 1.4126602183147428, 14.63... [False, False, False] \n", - "2 [11.417095529855294, 11.790964579154306, 1.921... [False, False, False] \n", - "3 [6.755789068433506, 5.561970363488718, 13.9014... [False, False, False] \n", - "4 [9.657976801209967, 12.341424199062448, 6.6512... [False, False, False] \n", - "5 [3.408580826771653, 8.318771805237521, 0.95725... [False, False, False] \n", - "6 [12.41446757988873, 9.474965986830972, 11.3713... [False, False, False] \n", - "7 [5.3178895219480244, 14.560470365923548, 13.39... [False, False, False] \n", - "8 [11.675752456106427, 2.919580617779513, 7.0008... [False, False, False] \n", - "9 [0.6570564868084315, 2.3143423810132173, 10.24... [False, False, False] \n", - "10 [11.171432338617256, 14.512645986513148, 4.887... [False, False, False] \n", - "11 [5.556895590523033, 7.043337169137118, 2.84207... [False, False, False] \n", - "12 [1.9488225800320744, 7.135573893389005, 3.4036... [False, False, False] \n", - "13 [10.047209920237654, 6.557278783084961, 12.490... [False, False, False] \n", - "14 [10.503976530033736, 4.685499620730615, 12.483... [False, False, False] \n", - "15 [12.071465362452027, 5.812175685452616, 4.3249... [False, False, False] \n", - "16 [10.237432559624631, 2.096287254139647, 2.9986... [False, False, False] \n", - "17 [0.11043404626508267, 11.803865662532074, 9.97... [False, False, False] \n", - "18 [10.577480679395025, 11.710935465329516, 6.883... [False, False, False] \n", - "19 [8.531117939293406, 2.0969549719148612, 1.7179... [False, False, False] \n", - "\n", - " initial_state residue_id molecule_id assembly_id \n", - "0 Na \n", - "1 Na \n", - "2 Na \n", - "3 Na \n", - "4 Na \n", - "5 Na \n", - "6 Na \n", - "7 Na \n", - "8 Na \n", - "9 Na \n", - "10 Na \n", - "11 Na \n", - "12 Na \n", - "13 Na \n", - "14 Na \n", - "15 Na \n", - "16 Na \n", - "17 Na \n", - "18 Na \n", - "19 Na " - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "pmb.get_instances_df(pmb_type = 'particle')" ] @@ -1249,103 +537,9 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenamesigmaepsiloncutoffoffsetinitial_state
0particleNa0.35 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerNa
1particleBB-PDha0.4 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerBB-PDha
2particleCOOH-PDha0.5 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerCOOH-PDha
3particleNH3-PDha0.3 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerNH3-PDha
\n", - "
" - ], - "text/plain": [ - " pmb_type name sigma epsilon \\\n", - "0 particle Na 0.35 nanometer 25.692579121085853 millielectron_volt \n", - "1 particle BB-PDha 0.4 nanometer 25.692579121085853 millielectron_volt \n", - "2 particle COOH-PDha 0.5 nanometer 25.692579121085853 millielectron_volt \n", - "3 particle NH3-PDha 0.3 nanometer 25.692579121085853 millielectron_volt \n", - "\n", - " cutoff offset initial_state \n", - "0 0.5612310241546864 nanometer 0.0 nanometer Na \n", - "1 0.5612310241546864 nanometer 0.0 nanometer BB-PDha \n", - "2 0.5612310241546864 nanometer 0.0 nanometer COOH-PDha \n", - "3 0.5612310241546864 nanometer 0.0 nanometer NH3-PDha " - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "pmb.get_templates_df(pmb_type = 'particle')" ] @@ -1379,58 +573,9 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenamecentral_beadside_chains
0residuePDha_monBB-PDha[COOH-PDha, NH3-PDha]
\n", - "
" - ], - "text/plain": [ - " pmb_type name central_bead side_chains\n", - "0 residue PDha_mon BB-PDha [COOH-PDha, NH3-PDha]" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "pmb.get_templates_df(pmb_type='residue')" ] @@ -1471,87 +616,9 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenamebond_typeparticle_name1particle_name2parameters
0bondBB-PDha-BB-PDhaharmonicBB-PDhaBB-PDha{'r_0': 0.4 nanometer, 'k': 41108.126593737354...
1bondBB-PDha-COOH-PDhaharmonicBB-PDhaCOOH-PDha{'r_0': 0.4 nanometer, 'k': 41108.126593737354...
2bondBB-PDha-NH3-PDhaharmonicBB-PDhaNH3-PDha{'r_0': 0.4 nanometer, 'k': 41108.126593737354...
\n", - "
" - ], - "text/plain": [ - " pmb_type name bond_type particle_name1 particle_name2 \\\n", - "0 bond BB-PDha-BB-PDha harmonic BB-PDha BB-PDha \n", - "1 bond BB-PDha-COOH-PDha harmonic BB-PDha COOH-PDha \n", - "2 bond BB-PDha-NH3-PDha harmonic BB-PDha NH3-PDha \n", - "\n", - " parameters \n", - "0 {'r_0': 0.4 nanometer, 'k': 41108.126593737354... \n", - "1 {'r_0': 0.4 nanometer, 'k': 41108.126593737354... \n", - "2 {'r_0': 0.4 nanometer, 'k': 41108.126593737354... " - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "pmb.get_templates_df(pmb_type = 'bond')" ] @@ -1676,539 +743,9 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenameparticle_idpositionfixinitial_stateresidue_idmolecule_idassembly_id
0particleNa0[11.609340728339449, 6.583176596280784, 12.878...[False, False, False]Na<NA><NA><NA>
1particleNa1[10.460520435890457, 1.4126602183147428, 14.63...[False, False, False]Na<NA><NA><NA>
2particleNa2[11.417095529855294, 11.790964579154306, 1.921...[False, False, False]Na<NA><NA><NA>
3particleNa3[6.755789068433506, 5.561970363488718, 13.9014...[False, False, False]Na<NA><NA><NA>
4particleNa4[9.657976801209967, 12.341424199062448, 6.6512...[False, False, False]Na<NA><NA><NA>
5particleNa5[3.408580826771653, 8.318771805237521, 0.95725...[False, False, False]Na<NA><NA><NA>
6particleNa6[12.41446757988873, 9.474965986830972, 11.3713...[False, False, False]Na<NA><NA><NA>
7particleNa7[5.3178895219480244, 14.560470365923548, 13.39...[False, False, False]Na<NA><NA><NA>
8particleNa8[11.675752456106427, 2.919580617779513, 7.0008...[False, False, False]Na<NA><NA><NA>
9particleNa9[0.6570564868084315, 2.3143423810132173, 10.24...[False, False, False]Na<NA><NA><NA>
10particleNa10[11.171432338617256, 14.512645986513148, 4.887...[False, False, False]Na<NA><NA><NA>
11particleNa11[5.556895590523033, 7.043337169137118, 2.84207...[False, False, False]Na<NA><NA><NA>
12particleNa12[1.9488225800320744, 7.135573893389005, 3.4036...[False, False, False]Na<NA><NA><NA>
13particleNa13[10.047209920237654, 6.557278783084961, 12.490...[False, False, False]Na<NA><NA><NA>
14particleNa14[10.503976530033736, 4.685499620730615, 12.483...[False, False, False]Na<NA><NA><NA>
15particleNa15[12.071465362452027, 5.812175685452616, 4.3249...[False, False, False]Na<NA><NA><NA>
16particleNa16[10.237432559624631, 2.096287254139647, 2.9986...[False, False, False]Na<NA><NA><NA>
17particleNa17[0.11043404626508267, 11.803865662532074, 9.97...[False, False, False]Na<NA><NA><NA>
18particleNa18[10.577480679395025, 11.710935465329516, 6.883...[False, False, False]Na<NA><NA><NA>
19particleNa19[8.531117939293406, 2.0969549719148612, 1.7179...[False, False, False]Na<NA><NA><NA>
20particleBB-PDha20[7.499999999999999, 7.499999999999999, 7.49999...[False, False, False]BB-PDha00<NA>
21particleCOOH-PDha21[6.898824919599952, 7.881760682233023, 8.02895...[False, False, False]COOH-PDha00<NA>
22particleNH3-PDha22[8.137870547785395, 7.97490337881395, 7.445064...[False, False, False]NH3-PDha00<NA>
23particleBB-PDha23[7.160907281551002, 7.879214991841518, 6.84092...[False, False, False]BB-PDha10<NA>
24particleCOOH-PDha24[6.943630111611255, 8.571635891712093, 7.35111...[False, False, False]COOH-PDha10<NA>
25particleNH3-PDha25[6.726674552857768, 7.228064210684457, 6.68968...[False, False, False]NH3-PDha10<NA>
26particleBB-PDha26[6.821814563102005, 8.258429983683039, 6.18184...[False, False, False]BB-PDha20<NA>
27particleCOOH-PDha27[7.190700895656628, 9.025057023826212, 6.43315...[False, False, False]COOH-PDha20<NA>
28particleNH3-PDha28[6.246753526388499, 8.554250283754568, 6.64792...[False, False, False]NH3-PDha20<NA>
29particleBB-PDha29[6.482721844653008, 8.637644975524559, 5.52277...[False, False, False]BB-PDha30<NA>
30particleCOOH-PDha30[6.93253697328386, 9.377201114906299, 5.716863...[False, False, False]COOH-PDha30<NA>
31particleNH3-PDha31[6.492959901480784, 7.949057245973125, 5.12130...[False, False, False]NH3-PDha30<NA>
\n", - "
" - ], - "text/plain": [ - " pmb_type name particle_id \\\n", - "0 particle Na 0 \n", - "1 particle Na 1 \n", - "2 particle Na 2 \n", - "3 particle Na 3 \n", - "4 particle Na 4 \n", - "5 particle Na 5 \n", - "6 particle Na 6 \n", - "7 particle Na 7 \n", - "8 particle Na 8 \n", - "9 particle Na 9 \n", - "10 particle Na 10 \n", - "11 particle Na 11 \n", - "12 particle Na 12 \n", - "13 particle Na 13 \n", - "14 particle Na 14 \n", - "15 particle Na 15 \n", - "16 particle Na 16 \n", - "17 particle Na 17 \n", - "18 particle Na 18 \n", - "19 particle Na 19 \n", - "20 particle BB-PDha 20 \n", - "21 particle COOH-PDha 21 \n", - "22 particle NH3-PDha 22 \n", - "23 particle BB-PDha 23 \n", - "24 particle COOH-PDha 24 \n", - "25 particle NH3-PDha 25 \n", - "26 particle BB-PDha 26 \n", - "27 particle COOH-PDha 27 \n", - "28 particle NH3-PDha 28 \n", - "29 particle BB-PDha 29 \n", - "30 particle COOH-PDha 30 \n", - "31 particle NH3-PDha 31 \n", - "\n", - " position fix \\\n", - "0 [11.609340728339449, 6.583176596280784, 12.878... [False, False, False] \n", - "1 [10.460520435890457, 1.4126602183147428, 14.63... [False, False, False] \n", - "2 [11.417095529855294, 11.790964579154306, 1.921... [False, False, False] \n", - "3 [6.755789068433506, 5.561970363488718, 13.9014... [False, False, False] \n", - "4 [9.657976801209967, 12.341424199062448, 6.6512... [False, False, False] \n", - "5 [3.408580826771653, 8.318771805237521, 0.95725... [False, False, False] \n", - "6 [12.41446757988873, 9.474965986830972, 11.3713... [False, False, False] \n", - "7 [5.3178895219480244, 14.560470365923548, 13.39... [False, False, False] \n", - "8 [11.675752456106427, 2.919580617779513, 7.0008... [False, False, False] \n", - "9 [0.6570564868084315, 2.3143423810132173, 10.24... [False, False, False] \n", - "10 [11.171432338617256, 14.512645986513148, 4.887... [False, False, False] \n", - "11 [5.556895590523033, 7.043337169137118, 2.84207... [False, False, False] \n", - "12 [1.9488225800320744, 7.135573893389005, 3.4036... [False, False, False] \n", - "13 [10.047209920237654, 6.557278783084961, 12.490... [False, False, False] \n", - "14 [10.503976530033736, 4.685499620730615, 12.483... [False, False, False] \n", - "15 [12.071465362452027, 5.812175685452616, 4.3249... [False, False, False] \n", - "16 [10.237432559624631, 2.096287254139647, 2.9986... [False, False, False] \n", - "17 [0.11043404626508267, 11.803865662532074, 9.97... [False, False, False] \n", - "18 [10.577480679395025, 11.710935465329516, 6.883... [False, False, False] \n", - "19 [8.531117939293406, 2.0969549719148612, 1.7179... [False, False, False] \n", - "20 [7.499999999999999, 7.499999999999999, 7.49999... [False, False, False] \n", - "21 [6.898824919599952, 7.881760682233023, 8.02895... [False, False, False] \n", - "22 [8.137870547785395, 7.97490337881395, 7.445064... [False, False, False] \n", - "23 [7.160907281551002, 7.879214991841518, 6.84092... [False, False, False] \n", - "24 [6.943630111611255, 8.571635891712093, 7.35111... [False, False, False] \n", - "25 [6.726674552857768, 7.228064210684457, 6.68968... [False, False, False] \n", - "26 [6.821814563102005, 8.258429983683039, 6.18184... [False, False, False] \n", - "27 [7.190700895656628, 9.025057023826212, 6.43315... [False, False, False] \n", - "28 [6.246753526388499, 8.554250283754568, 6.64792... [False, False, False] \n", - "29 [6.482721844653008, 8.637644975524559, 5.52277... [False, False, False] \n", - "30 [6.93253697328386, 9.377201114906299, 5.716863... [False, False, False] \n", - "31 [6.492959901480784, 7.949057245973125, 5.12130... [False, False, False] \n", - "\n", - " initial_state residue_id molecule_id assembly_id \n", - "0 Na \n", - "1 Na \n", - "2 Na \n", - "3 Na \n", - "4 Na \n", - "5 Na \n", - "6 Na \n", - "7 Na \n", - "8 Na \n", - "9 Na \n", - "10 Na \n", - "11 Na \n", - "12 Na \n", - "13 Na \n", - "14 Na \n", - "15 Na \n", - "16 Na \n", - "17 Na \n", - "18 Na \n", - "19 Na \n", - "20 BB-PDha 0 0 \n", - "21 COOH-PDha 0 0 \n", - "22 NH3-PDha 0 0 \n", - "23 BB-PDha 1 0 \n", - "24 COOH-PDha 1 0 \n", - "25 NH3-PDha 1 0 \n", - "26 BB-PDha 2 0 \n", - "27 COOH-PDha 2 0 \n", - "28 NH3-PDha 2 0 \n", - "29 BB-PDha 3 0 \n", - "30 COOH-PDha 3 0 \n", - "31 NH3-PDha 3 0 " - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# Check particle instances\n", "pmb.get_instances_df(pmb_type = 'particle')\n", @@ -2217,2159 +754,40 @@ }, { "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenamebond_idparticle_id1particle_id2added_to_engine
0bondBB-PDha-COOH-PDha02021False
1bondBB-PDha-NH3-PDha12022False
2bondBB-PDha-COOH-PDha22324False
3bondBB-PDha-NH3-PDha32325False
4bondBB-PDha-BB-PDha42023False
5bondBB-PDha-COOH-PDha52627False
6bondBB-PDha-NH3-PDha62628False
7bondBB-PDha-BB-PDha72326False
8bondBB-PDha-COOH-PDha82930False
9bondBB-PDha-NH3-PDha92931False
10bondBB-PDha-BB-PDha102629False
\n", - "
" - ], - "text/plain": [ - " pmb_type name bond_id particle_id1 particle_id2 \\\n", - "0 bond BB-PDha-COOH-PDha 0 20 21 \n", - "1 bond BB-PDha-NH3-PDha 1 20 22 \n", - "2 bond BB-PDha-COOH-PDha 2 23 24 \n", - "3 bond BB-PDha-NH3-PDha 3 23 25 \n", - "4 bond BB-PDha-BB-PDha 4 20 23 \n", - "5 bond BB-PDha-COOH-PDha 5 26 27 \n", - "6 bond BB-PDha-NH3-PDha 6 26 28 \n", - "7 bond BB-PDha-BB-PDha 7 23 26 \n", - "8 bond BB-PDha-COOH-PDha 8 29 30 \n", - "9 bond BB-PDha-NH3-PDha 9 29 31 \n", - "10 bond BB-PDha-BB-PDha 10 26 29 \n", - "\n", - " added_to_engine \n", - "0 False \n", - "1 False \n", - "2 False \n", - "3 False \n", - "4 False \n", - "5 False \n", - "6 False \n", - "7 False \n", - "8 False \n", - "9 False \n", - "10 False " - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pmb.get_instances_df(pmb_type='bond')" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenameresidue_idmolecule_idassembly_id
0residuePDha_mon00<NA>
1residuePDha_mon10<NA>
2residuePDha_mon20<NA>
3residuePDha_mon30<NA>
\n", - "
" - ], - "text/plain": [ - " pmb_type name residue_id molecule_id assembly_id\n", - "0 residue PDha_mon 0 0 \n", - "1 residue PDha_mon 1 0 \n", - "2 residue PDha_mon 2 0 \n", - "3 residue PDha_mon 3 0 " - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Check residue instances\n", - "pmb.get_instances_df(pmb_type = 'residue')" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenamemolecule_idassembly_id
0moleculePDha0<NA>
\n", - "
" - ], - "text/plain": [ - " pmb_type name molecule_id assembly_id\n", - "0 molecule PDha 0 " - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Check molecule instances\n", - "pmb.get_instances_df(pmb_type = 'molecule')" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [], - "source": [ - "pmb.set_simulation_engine(espresso_system)\n", - "pmb.add_instances_to_engine()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, let us see what we have created..." - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [], - "source": [ - "picture_name = 'PDha_system.png'\n", - "create_snapshot_of_espresso_system(espresso_system = espresso_system, \n", - " filename = picture_name)\n", - "img = Image.open(picture_name)\n", - "img.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Delete the particles and check that there are no particle instances in the pyMBE database" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenameparticle_idpositionfixinitial_stateresidue_idmolecule_idassembly_id
0particleNa0[11.609340728339449, 6.583176596280784, 12.878...[False, False, False]Na<NA><NA><NA>
1particleNa1[10.460520435890457, 1.4126602183147428, 14.63...[False, False, False]Na<NA><NA><NA>
2particleNa2[11.417095529855294, 11.790964579154306, 1.921...[False, False, False]Na<NA><NA><NA>
3particleNa3[6.755789068433506, 5.561970363488718, 13.9014...[False, False, False]Na<NA><NA><NA>
4particleNa4[9.657976801209967, 12.341424199062448, 6.6512...[False, False, False]Na<NA><NA><NA>
5particleNa5[3.408580826771653, 8.318771805237521, 0.95725...[False, False, False]Na<NA><NA><NA>
6particleNa6[12.41446757988873, 9.474965986830972, 11.3713...[False, False, False]Na<NA><NA><NA>
7particleNa7[5.3178895219480244, 14.560470365923548, 13.39...[False, False, False]Na<NA><NA><NA>
8particleNa8[11.675752456106427, 2.919580617779513, 7.0008...[False, False, False]Na<NA><NA><NA>
9particleNa9[0.6570564868084315, 2.3143423810132173, 10.24...[False, False, False]Na<NA><NA><NA>
10particleNa10[11.171432338617256, 14.512645986513148, 4.887...[False, False, False]Na<NA><NA><NA>
11particleNa11[5.556895590523033, 7.043337169137118, 2.84207...[False, False, False]Na<NA><NA><NA>
12particleNa12[1.9488225800320744, 7.135573893389005, 3.4036...[False, False, False]Na<NA><NA><NA>
13particleNa13[10.047209920237654, 6.557278783084961, 12.490...[False, False, False]Na<NA><NA><NA>
14particleNa14[10.503976530033736, 4.685499620730615, 12.483...[False, False, False]Na<NA><NA><NA>
15particleNa15[12.071465362452027, 5.812175685452616, 4.3249...[False, False, False]Na<NA><NA><NA>
16particleNa16[10.237432559624631, 2.096287254139647, 2.9986...[False, False, False]Na<NA><NA><NA>
17particleNa17[0.11043404626508267, 11.803865662532074, 9.97...[False, False, False]Na<NA><NA><NA>
18particleNa18[10.577480679395025, 11.710935465329516, 6.883...[False, False, False]Na<NA><NA><NA>
19particleNa19[8.531117939293406, 2.0969549719148612, 1.7179...[False, False, False]Na<NA><NA><NA>
\n", - "
" - ], - "text/plain": [ - " pmb_type name particle_id \\\n", - "0 particle Na 0 \n", - "1 particle Na 1 \n", - "2 particle Na 2 \n", - "3 particle Na 3 \n", - "4 particle Na 4 \n", - "5 particle Na 5 \n", - "6 particle Na 6 \n", - "7 particle Na 7 \n", - "8 particle Na 8 \n", - "9 particle Na 9 \n", - "10 particle Na 10 \n", - "11 particle Na 11 \n", - "12 particle Na 12 \n", - "13 particle Na 13 \n", - "14 particle Na 14 \n", - "15 particle Na 15 \n", - "16 particle Na 16 \n", - "17 particle Na 17 \n", - "18 particle Na 18 \n", - "19 particle Na 19 \n", - "\n", - " position fix \\\n", - "0 [11.609340728339449, 6.583176596280784, 12.878... [False, False, False] \n", - "1 [10.460520435890457, 1.4126602183147428, 14.63... [False, False, False] \n", - "2 [11.417095529855294, 11.790964579154306, 1.921... [False, False, False] \n", - "3 [6.755789068433506, 5.561970363488718, 13.9014... [False, False, False] \n", - "4 [9.657976801209967, 12.341424199062448, 6.6512... [False, False, False] \n", - "5 [3.408580826771653, 8.318771805237521, 0.95725... [False, False, False] \n", - "6 [12.41446757988873, 9.474965986830972, 11.3713... [False, False, False] \n", - "7 [5.3178895219480244, 14.560470365923548, 13.39... [False, False, False] \n", - "8 [11.675752456106427, 2.919580617779513, 7.0008... [False, False, False] \n", - "9 [0.6570564868084315, 2.3143423810132173, 10.24... [False, False, False] \n", - "10 [11.171432338617256, 14.512645986513148, 4.887... [False, False, False] \n", - "11 [5.556895590523033, 7.043337169137118, 2.84207... [False, False, False] \n", - "12 [1.9488225800320744, 7.135573893389005, 3.4036... [False, False, False] \n", - "13 [10.047209920237654, 6.557278783084961, 12.490... [False, False, False] \n", - "14 [10.503976530033736, 4.685499620730615, 12.483... [False, False, False] \n", - "15 [12.071465362452027, 5.812175685452616, 4.3249... [False, False, False] \n", - "16 [10.237432559624631, 2.096287254139647, 2.9986... [False, False, False] \n", - "17 [0.11043404626508267, 11.803865662532074, 9.97... [False, False, False] \n", - "18 [10.577480679395025, 11.710935465329516, 6.883... [False, False, False] \n", - "19 [8.531117939293406, 2.0969549719148612, 1.7179... [False, False, False] \n", - "\n", - " initial_state residue_id molecule_id assembly_id \n", - "0 Na \n", - "1 Na \n", - "2 Na \n", - "3 Na \n", - "4 Na \n", - "5 Na \n", - "6 Na \n", - "7 Na \n", - "8 Na \n", - "9 Na \n", - "10 Na \n", - "11 Na \n", - "12 Na \n", - "13 Na \n", - "14 Na \n", - "15 Na \n", - "16 Na \n", - "17 Na \n", - "18 Na \n", - "19 Na " - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pmb.delete_instances_in_system(instance_id=molecule_ids[0],\n", - " pmb_type=\"molecule\")\n", - "# Check particle instances\n", - "pmb.get_instances_df(pmb_type = 'particle')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "particle_id_map = pmb.get_particle_id_map(object_name=cation_name)\n", - "# This will delete all particles that we created before\n", - "for pid in particle_id_map[\"all\"]:\n", - " pmb.delete_instances_in_system(instance_id=pid, \n", - " pmb_type=\"particle\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How to create complex polymers " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "pyMBE can also be used to setup models that requiere more complex side chains, i.e. with more than one bead per side chain. One example of these complex molecules is the poly(N,N-diallylglutamate) (PDAGA), whose structure is depicted in the figure below. Following the logic of the previous example, one would construct PDAGA with pyMBE by defining a `residue` with a `central_bead` for the polymer backbone (grey) and a `side_chain` attached to it. In this case, the group in the side chain of the PDAGA monomer has a complex structure. This group can be coarse-grained by defining another `residue` composed by a new `central_bead` which represents the cyclic amine group (blue) and two `side_chains` ($\\alpha$ and $\\beta$ carboxyl) attached to it (red and orange).\n", - "\n", - "" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "One can start by defining templates for each different bead of the PDAGA." - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [], - "source": [ - "PDAGA_backbone_bead = 'BB-PDAGA'\n", - "PDAGA_cyclic_amine_bead = 'NH3-PDAGA'\n", - "PDAGA_alpha_carboxyl_bead = 'aCOOH-PDAGA'\n", - "PDAGA_beta_carboxyl_bead = 'bCOOH-PDAGA'\n", - "\n", - "pmb.define_particle(name = PDAGA_backbone_bead, \n", - " z = 0,\n", - " sigma = 0.4*pmb.units.nm, \n", - " epsilon = 1*pmb.units('reduced_energy'))\n", - "\n", - "pmb.define_particle(name = PDAGA_cyclic_amine_bead, \n", - " z = 0, \n", - " sigma = 0.3*pmb.units.nm, \n", - " epsilon = 1*pmb.units('reduced_energy'))\n", - "\n", - "pmb.define_particle(name = PDAGA_alpha_carboxyl_bead, \n", - " z = 0, \n", - " sigma = 0.2*pmb.units.nm, \n", - " epsilon = 1*pmb.units('reduced_energy'))\n", - "\n", - "pmb.define_particle(name = PDAGA_beta_carboxyl_bead, \n", - " z = 0, \n", - " sigma = 0.4*pmb.units.nm, \n", - " epsilon = 1*pmb.units('reduced_energy'))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The next step is to define the two different residue templates: \n", - "1. The side chain: two carboxyl beads attached to the cyclic amine bead." - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [], - "source": [ - "PDAGA_side_chain_residue = 'PDAGA_side_chain_residue'\n", - "\n", - "pmb.define_residue (name = PDAGA_side_chain_residue,\n", - " central_bead = PDAGA_cyclic_amine_bead,\n", - " side_chains = [PDAGA_alpha_carboxyl_bead, PDAGA_beta_carboxyl_bead])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "2. Each monomeric unit of the PDAGA: the side chain defined above attached to the backbone." - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [], - "source": [ - "PDAGA_monomer_residue = 'PDAGA_monomer_residue'\n", - "pmb.define_residue( name = PDAGA_monomer_residue,\n", - " central_bead = PDAGA_backbone_bead,\n", - " side_chains = [PDAGA_side_chain_residue])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Then, we need to define bond templates in a similar way as for the case of the simple polymer." - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [], - "source": [ - "bond_type = 'harmonic'\n", - "generic_bond_lenght=0.4 * pmb.units.nm\n", - "generic_harmonic_constant = 400 * pmb.units('reduced_energy / reduced_length**2')\n", - "\n", - "harmonic_bond = {'r_0' : generic_bond_lenght,\n", - " 'k' : generic_harmonic_constant,\n", - " }\n", - "\n", - "pmb.define_bond(bond_type = bond_type,\n", - " bond_parameters = harmonic_bond,\n", - " particle_pairs = [[PDAGA_backbone_bead, PDAGA_backbone_bead],\n", - " [PDAGA_backbone_bead, PDAGA_cyclic_amine_bead],\n", - " [PDAGA_alpha_carboxyl_bead, PDAGA_cyclic_amine_bead],\n", - " [PDAGA_beta_carboxyl_bead, PDAGA_cyclic_amine_bead]])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, let us define an octamer of PDAGA." - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [], - "source": [ - "PDAGA_polymer = 'PDAGA'\n", - "N_monomers = 4\n", - "\n", - "pmb.define_molecule(name = PDAGA_polymer,\n", - " residue_list = [PDAGA_monomer_residue]*N_monomers)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, we are able to create a PDAGA polymer into the ESPResSo system." - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [], - "source": [ - "N_polymers = 1\n", - "\n", - "mol_ids = pmb.create_molecule(name = PDAGA_polymer,\n", - " number_of_molecules= N_polymers,\n", - " box_l= box_l,\n", - " list_of_first_residue_positions = [[Box_L.to('reduced_length').magnitude/2]*3])" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenameparticle_idpositionfixinitial_stateresidue_idmolecule_idassembly_id
0particleBB-PDAGA0[7.499999999999999, 7.499999999999999, 7.49999...[False, False, False]BB-PDAGA00<NA>
1particleNH3-PDAGA1[7.880814267857025, 7.910176242823781, 8.06759...[False, False, False]NH3-PDAGA00<NA>
2particleaCOOH-PDAGA2[7.703407151110378, 7.147666585308814, 7.92399...[False, False, False]aCOOH-PDAGA00<NA>
3particlebCOOH-PDAGA3[7.360821755419828, 7.464213880431073, 7.65997...[False, False, False]bCOOH-PDAGA00<NA>
4particleBB-PDAGA4[8.099326782445562, 6.9222971413656, 7.5153767...[False, False, False]BB-PDAGA10<NA>
5particleNH3-PDAGA5[7.8795304975820475, 6.67497036026838, 6.79015...[False, False, False]NH3-PDAGA10<NA>
6particleaCOOH-PDAGA6[7.664421253102207, 7.414007090791623, 6.58750...[False, False, False]aCOOH-PDAGA10<NA>
7particlebCOOH-PDAGA7[8.366452812103642, 6.058577566590047, 6.65451...[False, False, False]bCOOH-PDAGA10<NA>
8particleBB-PDAGA8[8.698653564891124, 6.3445942827312, 7.5307535...[False, False, False]BB-PDAGA20<NA>
9particleNH3-PDAGA9[8.288142706210909, 5.933240394956417, 8.07637...[False, False, False]NH3-PDAGA20<NA>
10particleaCOOH-PDAGA10[7.523029527750901, 6.125667492007267, 8.18167...[False, False, False]aCOOH-PDAGA20<NA>
11particlebCOOH-PDAGA11[7.985514841088506, 5.196696704056294, 8.11311...[False, False, False]bCOOH-PDAGA20<NA>
12particleBB-PDAGA12[9.297980347336686, 5.7668914240968006, 7.5461...[False, False, False]BB-PDAGA30<NA>
13particleNH3-PDAGA13[8.749995437793478, 5.2017343109241185, 7.6715...[False, False, False]NH3-PDAGA30<NA>
14particleaCOOH-PDAGA14[9.41544713832268, 5.102295112295519, 7.246381...[False, False, False]aCOOH-PDAGA30<NA>
15particlebCOOH-PDAGA15[8.852917761630236, 5.328034630296977, 8.45190...[False, False, False]bCOOH-PDAGA30<NA>
\n", - "
" - ], - "text/plain": [ - " pmb_type name particle_id \\\n", - "0 particle BB-PDAGA 0 \n", - "1 particle NH3-PDAGA 1 \n", - "2 particle aCOOH-PDAGA 2 \n", - "3 particle bCOOH-PDAGA 3 \n", - "4 particle BB-PDAGA 4 \n", - "5 particle NH3-PDAGA 5 \n", - "6 particle aCOOH-PDAGA 6 \n", - "7 particle bCOOH-PDAGA 7 \n", - "8 particle BB-PDAGA 8 \n", - "9 particle NH3-PDAGA 9 \n", - "10 particle aCOOH-PDAGA 10 \n", - "11 particle bCOOH-PDAGA 11 \n", - "12 particle BB-PDAGA 12 \n", - "13 particle NH3-PDAGA 13 \n", - "14 particle aCOOH-PDAGA 14 \n", - "15 particle bCOOH-PDAGA 15 \n", - "\n", - " position fix \\\n", - "0 [7.499999999999999, 7.499999999999999, 7.49999... [False, False, False] \n", - "1 [7.880814267857025, 7.910176242823781, 8.06759... [False, False, False] \n", - "2 [7.703407151110378, 7.147666585308814, 7.92399... [False, False, False] \n", - "3 [7.360821755419828, 7.464213880431073, 7.65997... [False, False, False] \n", - "4 [8.099326782445562, 6.9222971413656, 7.5153767... [False, False, False] \n", - "5 [7.8795304975820475, 6.67497036026838, 6.79015... [False, False, False] \n", - "6 [7.664421253102207, 7.414007090791623, 6.58750... [False, False, False] \n", - "7 [8.366452812103642, 6.058577566590047, 6.65451... [False, False, False] \n", - "8 [8.698653564891124, 6.3445942827312, 7.5307535... [False, False, False] \n", - "9 [8.288142706210909, 5.933240394956417, 8.07637... [False, False, False] \n", - "10 [7.523029527750901, 6.125667492007267, 8.18167... [False, False, False] \n", - "11 [7.985514841088506, 5.196696704056294, 8.11311... [False, False, False] \n", - "12 [9.297980347336686, 5.7668914240968006, 7.5461... [False, False, False] \n", - "13 [8.749995437793478, 5.2017343109241185, 7.6715... [False, False, False] \n", - "14 [9.41544713832268, 5.102295112295519, 7.246381... [False, False, False] \n", - "15 [8.852917761630236, 5.328034630296977, 8.45190... [False, False, False] \n", - "\n", - " initial_state residue_id molecule_id assembly_id \n", - "0 BB-PDAGA 0 0 \n", - "1 NH3-PDAGA 0 0 \n", - "2 aCOOH-PDAGA 0 0 \n", - "3 bCOOH-PDAGA 0 0 \n", - "4 BB-PDAGA 1 0 \n", - "5 NH3-PDAGA 1 0 \n", - "6 aCOOH-PDAGA 1 0 \n", - "7 bCOOH-PDAGA 1 0 \n", - "8 BB-PDAGA 2 0 \n", - "9 NH3-PDAGA 2 0 \n", - "10 aCOOH-PDAGA 2 0 \n", - "11 bCOOH-PDAGA 2 0 \n", - "12 BB-PDAGA 3 0 \n", - "13 NH3-PDAGA 3 0 \n", - "14 aCOOH-PDAGA 3 0 \n", - "15 bCOOH-PDAGA 3 0 " - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pmb.get_instances_df(pmb_type = 'particle')" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenameresidue_idmolecule_idassembly_id
0residuePDAGA_monomer_residue00<NA>
1residuePDAGA_monomer_residue10<NA>
2residuePDAGA_monomer_residue20<NA>
3residuePDAGA_monomer_residue30<NA>
\n", - "
" - ], - "text/plain": [ - " pmb_type name residue_id molecule_id assembly_id\n", - "0 residue PDAGA_monomer_residue 0 0 \n", - "1 residue PDAGA_monomer_residue 1 0 \n", - "2 residue PDAGA_monomer_residue 2 0 \n", - "3 residue PDAGA_monomer_residue 3 0 " - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pmb.get_instances_df(pmb_type = 'residue')" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenamebond_idparticle_id1particle_id2added_to_engine
0bondNH3-PDAGA-aCOOH-PDAGA012False
1bondNH3-PDAGA-bCOOH-PDAGA113False
2bondBB-PDAGA-NH3-PDAGA201False
3bondNH3-PDAGA-aCOOH-PDAGA356False
4bondNH3-PDAGA-bCOOH-PDAGA457False
5bondBB-PDAGA-NH3-PDAGA545False
6bondBB-PDAGA-BB-PDAGA604False
7bondNH3-PDAGA-aCOOH-PDAGA7910False
8bondNH3-PDAGA-bCOOH-PDAGA8911False
9bondBB-PDAGA-NH3-PDAGA989False
10bondBB-PDAGA-BB-PDAGA1048False
11bondNH3-PDAGA-aCOOH-PDAGA111314False
12bondNH3-PDAGA-bCOOH-PDAGA121315False
13bondBB-PDAGA-NH3-PDAGA131213False
14bondBB-PDAGA-BB-PDAGA14812False
\n", - "
" - ], - "text/plain": [ - " pmb_type name bond_id particle_id1 particle_id2 \\\n", - "0 bond NH3-PDAGA-aCOOH-PDAGA 0 1 2 \n", - "1 bond NH3-PDAGA-bCOOH-PDAGA 1 1 3 \n", - "2 bond BB-PDAGA-NH3-PDAGA 2 0 1 \n", - "3 bond NH3-PDAGA-aCOOH-PDAGA 3 5 6 \n", - "4 bond NH3-PDAGA-bCOOH-PDAGA 4 5 7 \n", - "5 bond BB-PDAGA-NH3-PDAGA 5 4 5 \n", - "6 bond BB-PDAGA-BB-PDAGA 6 0 4 \n", - "7 bond NH3-PDAGA-aCOOH-PDAGA 7 9 10 \n", - "8 bond NH3-PDAGA-bCOOH-PDAGA 8 9 11 \n", - "9 bond BB-PDAGA-NH3-PDAGA 9 8 9 \n", - "10 bond BB-PDAGA-BB-PDAGA 10 4 8 \n", - "11 bond NH3-PDAGA-aCOOH-PDAGA 11 13 14 \n", - "12 bond NH3-PDAGA-bCOOH-PDAGA 12 13 15 \n", - "13 bond BB-PDAGA-NH3-PDAGA 13 12 13 \n", - "14 bond BB-PDAGA-BB-PDAGA 14 8 12 \n", - "\n", - " added_to_engine \n", - "0 False \n", - "1 False \n", - "2 False \n", - "3 False \n", - "4 False \n", - "5 False \n", - "6 False \n", - "7 False \n", - "8 False \n", - "9 False \n", - "10 False \n", - "11 False \n", - "12 False \n", - "13 False \n", - "14 False " - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pmb.get_instances_df(pmb_type = 'bond')" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [], - "source": [ - "pmb.set_simulation_engine(espresso_system)\n", - "pmb.add_instances_to_engine()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, let us see our PDAGA molecule." - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [], - "source": [ - "picture_name = 'PDAGA_system.png'\n", - "create_snapshot_of_espresso_system(espresso_system = espresso_system, \n", - " filename = picture_name)\n", - "img = Image.open(picture_name)\n", - "img.show()\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Delete the particles and check that the pyMBE database is empty." - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
\n", - "
" - ], - "text/plain": [ - "Empty DataFrame\n", - "Columns: []\n", - "Index: []" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "\n", - "for mol_id in mol_ids:\n", - " pmb.delete_instances_in_system(instance_id=mol_id,\n", - " pmb_type=\"molecule\")\n", - "pmb.get_instances_df(pmb_type = 'particle')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How to create di-block copolymers " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In turn, the residues previously defined to build the PDAGA and PDha molecules can be used to build more complex polymers such as a di-block PDha-PDAGA copolymer, as shown in the picture below\n", - "\n", - "" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Define the bond template between the backbone particle of PDha and the backbone particle of PDAGA" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "pmb.define_bond(bond_type = bond_type,\n", - " bond_parameters = harmonic_bond,\n", - " particle_pairs = [[PDha_backbone_bead, PDAGA_backbone_bead]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Define a molecule template for the di-block polymer molecule using Python list comprehension methods" - ] - }, - { - "cell_type": "code", - "execution_count": 46, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "N_monomers_PDha = 4\n", - "N_monomers_PDAGA = 4\n", - "diblock_polymer = 'diblock'\n", - "\n", - "pmb.define_molecule(name = diblock_polymer,\n", - " residue_list = [PDha_residue]*N_monomers_PDha+[PDAGA_monomer_residue]*N_monomers_PDAGA)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Creating the di-block polymer into the ESPResSo system" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenameparticle_idpositionfixinitial_stateresidue_idmolecule_idassembly_id
0particleBB-PDha0[7.499999999999999, 7.499999999999999, 7.49999...[False, False, False]BB-PDha00<NA>
1particleCOOH-PDha1[6.882014811497537, 7.060136570708298, 7.95996...[False, False, False]COOH-PDha00<NA>
2particleNH3-PDha2[7.285177148531093, 6.791465416767111, 7.79539...[False, False, False]NH3-PDha00<NA>
3particleBB-PDha3[7.903716808160374, 7.672521739623884, 8.20740...[False, False, False]BB-PDha10<NA>
4particleCOOH-PDha4[8.180114479235312, 6.830918531233496, 8.25491...[False, False, False]COOH-PDha10<NA>
5particleNH3-PDha5[7.267322603293363, 8.07232460191931, 8.473090...[False, False, False]NH3-PDha10<NA>
6particleBB-PDha6[8.30743361632075, 7.845043479247768, 8.914805...[False, False, False]BB-PDha20<NA>
7particleCOOH-PDha7[9.065973263843503, 7.926327346705838, 8.46208...[False, False, False]COOH-PDha20<NA>
8particleNH3-PDha8[7.639560864585886, 8.154858106740047, 9.22040...[False, False, False]NH3-PDha20<NA>
9particleBB-PDha9[8.711150424481126, 8.017565218871653, 9.62220...[False, False, False]BB-PDha30<NA>
10particleCOOH-PDha10[8.420714798426259, 7.25654675606315, 9.973558...[False, False, False]COOH-PDha30<NA>
11particleNH3-PDha11[9.395759771279486, 8.073863280999081, 9.21776...[False, False, False]NH3-PDha30<NA>
12particleBB-PDAGA12[9.114867232641501, 8.190086958495536, 10.3296...[False, False, False]BB-PDAGA40<NA>
13particleNH3-PDAGA13[8.902203284857888, 7.480496262888388, 10.6240...[False, False, False]NH3-PDAGA40<NA>
14particleaCOOH-PDAGA14[8.87806650829381, 8.27391585076135, 10.682499...[False, False, False]aCOOH-PDAGA40<NA>
15particlebCOOH-PDAGA15[9.386253989715097, 7.234567017453472, 10.0403...[False, False, False]bCOOH-PDAGA40<NA>
16particleBB-PDAGA16[9.518584040801876, 8.36260869811942, 11.03701...[False, False, False]BB-PDAGA50<NA>
17particleNH3-PDAGA17[8.943572120033956, 8.000263443775438, 11.4535...[False, False, False]NH3-PDAGA50<NA>
18particleaCOOH-PDAGA18[8.502098074958806, 8.450929652381193, 10.9682...[False, False, False]aCOOH-PDAGA50<NA>
19particlebCOOH-PDAGA19[9.671551490730199, 8.301084053842303, 11.3311...[False, False, False]bCOOH-PDAGA50<NA>
20particleBB-PDAGA20[9.922300848962252, 8.535130437743303, 11.7444...[False, False, False]BB-PDAGA60<NA>
21particleNH3-PDAGA21[9.766086613096551, 7.80090455938704, 12.01263...[False, False, False]NH3-PDAGA60<NA>
22particleaCOOH-PDAGA22[9.567999989832561, 7.267311324275074, 11.4562...[False, False, False]aCOOH-PDAGA60<NA>
23particlebCOOH-PDAGA23[9.85225872249835, 8.589335327303903, 12.09251...[False, False, False]bCOOH-PDAGA60<NA>
24particleBB-PDAGA24[10.326017657122627, 8.707652177367187, 12.451...[False, False, False]BB-PDAGA70<NA>
25particleNH3-PDAGA25[9.62948770871752, 8.76647867070694, 12.834984...[False, False, False]NH3-PDAGA70<NA>
26particleaCOOH-PDAGA26[9.774956218875849, 8.494000366005105, 13.5685...[False, False, False]aCOOH-PDAGA70<NA>
27particlebCOOH-PDAGA27[9.842436658608339, 9.529237189173736, 12.9259...[False, False, False]bCOOH-PDAGA70<NA>
\n", - "
" - ], - "text/plain": [ - " pmb_type name particle_id \\\n", - "0 particle BB-PDha 0 \n", - "1 particle COOH-PDha 1 \n", - "2 particle NH3-PDha 2 \n", - "3 particle BB-PDha 3 \n", - "4 particle COOH-PDha 4 \n", - "5 particle NH3-PDha 5 \n", - "6 particle BB-PDha 6 \n", - "7 particle COOH-PDha 7 \n", - "8 particle NH3-PDha 8 \n", - "9 particle BB-PDha 9 \n", - "10 particle COOH-PDha 10 \n", - "11 particle NH3-PDha 11 \n", - "12 particle BB-PDAGA 12 \n", - "13 particle NH3-PDAGA 13 \n", - "14 particle aCOOH-PDAGA 14 \n", - "15 particle bCOOH-PDAGA 15 \n", - "16 particle BB-PDAGA 16 \n", - "17 particle NH3-PDAGA 17 \n", - "18 particle aCOOH-PDAGA 18 \n", - "19 particle bCOOH-PDAGA 19 \n", - "20 particle BB-PDAGA 20 \n", - "21 particle NH3-PDAGA 21 \n", - "22 particle aCOOH-PDAGA 22 \n", - "23 particle bCOOH-PDAGA 23 \n", - "24 particle BB-PDAGA 24 \n", - "25 particle NH3-PDAGA 25 \n", - "26 particle aCOOH-PDAGA 26 \n", - "27 particle bCOOH-PDAGA 27 \n", - "\n", - " position fix \\\n", - "0 [7.499999999999999, 7.499999999999999, 7.49999... [False, False, False] \n", - "1 [6.882014811497537, 7.060136570708298, 7.95996... [False, False, False] \n", - "2 [7.285177148531093, 6.791465416767111, 7.79539... [False, False, False] \n", - "3 [7.903716808160374, 7.672521739623884, 8.20740... [False, False, False] \n", - "4 [8.180114479235312, 6.830918531233496, 8.25491... [False, False, False] \n", - "5 [7.267322603293363, 8.07232460191931, 8.473090... [False, False, False] \n", - "6 [8.30743361632075, 7.845043479247768, 8.914805... [False, False, False] \n", - "7 [9.065973263843503, 7.926327346705838, 8.46208... [False, False, False] \n", - "8 [7.639560864585886, 8.154858106740047, 9.22040... [False, False, False] \n", - "9 [8.711150424481126, 8.017565218871653, 9.62220... [False, False, False] \n", - "10 [8.420714798426259, 7.25654675606315, 9.973558... [False, False, False] \n", - "11 [9.395759771279486, 8.073863280999081, 9.21776... [False, False, False] \n", - "12 [9.114867232641501, 8.190086958495536, 10.3296... [False, False, False] \n", - "13 [8.902203284857888, 7.480496262888388, 10.6240... [False, False, False] \n", - "14 [8.87806650829381, 8.27391585076135, 10.682499... [False, False, False] \n", - "15 [9.386253989715097, 7.234567017453472, 10.0403... [False, False, False] \n", - "16 [9.518584040801876, 8.36260869811942, 11.03701... [False, False, False] \n", - "17 [8.943572120033956, 8.000263443775438, 11.4535... [False, False, False] \n", - "18 [8.502098074958806, 8.450929652381193, 10.9682... [False, False, False] \n", - "19 [9.671551490730199, 8.301084053842303, 11.3311... [False, False, False] \n", - "20 [9.922300848962252, 8.535130437743303, 11.7444... [False, False, False] \n", - "21 [9.766086613096551, 7.80090455938704, 12.01263... [False, False, False] \n", - "22 [9.567999989832561, 7.267311324275074, 11.4562... [False, False, False] \n", - "23 [9.85225872249835, 8.589335327303903, 12.09251... [False, False, False] \n", - "24 [10.326017657122627, 8.707652177367187, 12.451... [False, False, False] \n", - "25 [9.62948770871752, 8.76647867070694, 12.834984... [False, False, False] \n", - "26 [9.774956218875849, 8.494000366005105, 13.5685... [False, False, False] \n", - "27 [9.842436658608339, 9.529237189173736, 12.9259... [False, False, False] \n", - "\n", - " initial_state residue_id molecule_id assembly_id \n", - "0 BB-PDha 0 0 \n", - "1 COOH-PDha 0 0 \n", - "2 NH3-PDha 0 0 \n", - "3 BB-PDha 1 0 \n", - "4 COOH-PDha 1 0 \n", - "5 NH3-PDha 1 0 \n", - "6 BB-PDha 2 0 \n", - "7 COOH-PDha 2 0 \n", - "8 NH3-PDha 2 0 \n", - "9 BB-PDha 3 0 \n", - "10 COOH-PDha 3 0 \n", - "11 NH3-PDha 3 0 \n", - "12 BB-PDAGA 4 0 \n", - "13 NH3-PDAGA 4 0 \n", - "14 aCOOH-PDAGA 4 0 \n", - "15 bCOOH-PDAGA 4 0 \n", - "16 BB-PDAGA 5 0 \n", - "17 NH3-PDAGA 5 0 \n", - "18 aCOOH-PDAGA 5 0 \n", - "19 bCOOH-PDAGA 5 0 \n", - "20 BB-PDAGA 6 0 \n", - "21 NH3-PDAGA 6 0 \n", - "22 aCOOH-PDAGA 6 0 \n", - "23 bCOOH-PDAGA 6 0 \n", - "24 BB-PDAGA 7 0 \n", - "25 NH3-PDAGA 7 0 \n", - "26 aCOOH-PDAGA 7 0 \n", - "27 bCOOH-PDAGA 7 0 " - ] - }, - "execution_count": 47, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "N_polymers = 1\n", - "\n", - "mol_ids = pmb.create_molecule(name = diblock_polymer,\n", - " number_of_molecules= N_polymers,\n", - " box_l= box_l,\n", - " list_of_first_residue_positions = [[Box_L.to('reduced_length').magnitude/2]*3]) \n", - "# See the particle instances you have created\n", - "pmb.get_instances_df(pmb_type=\"particle\")" + "pmb.get_instances_df(pmb_type='bond')" ] }, { "cell_type": "code", - "execution_count": 48, + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Check residue instances\n", + "pmb.get_instances_df(pmb_type = 'residue')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Check molecule instances\n", + "pmb.get_instances_df(pmb_type = 'molecule')" + ] + }, + { + "cell_type": "code", + "execution_count": 26, "metadata": {}, "outputs": [], "source": [ + "pmb.set_simulation_engine(espresso_system)\n", "pmb.add_instances_to_engine()" ] }, @@ -4377,18 +795,18 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now, let us see our di-block PDha-PDAGA molecule." + "Now, let us see what we have created..." ] }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 30, "metadata": {}, "outputs": [], "source": [ - "picture_name = 'diblock_system.png'\n", + "picture_name = 'PDha_system.png'\n", "create_snapshot_of_espresso_system(espresso_system = espresso_system, \n", - " filename = picture_name)\n", + " filename = picture_name)\n", "img = Image.open(picture_name)\n", "img.show()" ] @@ -4397,748 +815,273 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Delete the particles and check that our df is empty." + "Delete the particles and check that there are no particle instances in the pyMBE database" ] }, { "cell_type": "code", - "execution_count": 51, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
\n", - "
" - ], - "text/plain": [ - "Empty DataFrame\n", - "Columns: []\n", - "Index: []" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "for mol_id in mol_ids:\n", - " pmb.delete_instances_in_system(instance_id=0, \n", - " pmb_type=\"molecule\")\n", - "pmb.get_instances_df(pmb_type=\"particle\")" + "pmb.delete_instances_in_system(instance_id=molecule_ids[0],\n", + " pmb_type=\"molecule\")\n", + "# Check particle instances\n", + "pmb.get_instances_df(pmb_type = 'particle')" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ - "## Practice by creating a custom polyampholyte chain " + "particle_id_map = pmb.get_particle_id_map(object_name=cation_name)\n", + "# This will delete all particles that we created before\n", + "for pid in particle_id_map[\"all\"]:\n", + " pmb.delete_instances_in_system(instance_id=pid, \n", + " pmb_type=\"particle\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Polyampholytes are polymers containing both acidic and basic groups on the same molecule, one example of a branched polyampholyte is depicted in the figure below.\n", - "\n", - "" + "## How to create complex polymers " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "We will create the polyampholyte chain in the figure, starting by defining two different residues, 'Res_1' and 'Res_2'. The polyampholyte chain is then defined by following residue_list:\n", - "\n", - "residue_list = 2*[\"Res_1\"] + [\"Res_2\"] + 2*[\"Res_1\"] + 2*[\"Res_2\"]\n", - "\n", - "### Tasks to do:\n", + "pyMBE can also be used to setup models that requiere more complex side chains, i.e. with more than one bead per side chain. One example of these complex molecules is the poly(N,N-diallylglutamate) (PDAGA), whose structure is depicted in the figure below. Following the logic of the previous example, one would construct PDAGA with pyMBE by defining a `residue` with a `central_bead` for the polymer backbone (grey) and a `side_chain` attached to it. In this case, the group in the side chain of the PDAGA monomer has a complex structure. This group can be coarse-grained by defining another `residue` composed by a new `central_bead` which represents the cyclic amine group (blue) and two `side_chains` ($\\alpha$ and $\\beta$ carboxyl) attached to it (red and orange).\n", "\n", - "1. Define particle templates for each different bead in the residues using \"pmb.define_particle\". There are 3 different particles, an inert particle, an acidic particle with pKa = 4, and a basic particle with pKa = 9.\n", - "2. Define residue templates using \"pmb.define_residue\". \"Res_1\" consists of an inert particle as central bead and acidic and basic particles as side chain. \"Res_2\" consists of an inert particle as central bead and \"Res_1\" as side chain.\n", - "3. Define bond templates for each pair of particle templates. \n", - "4. Define a molecule template for the branched polyampholyte chain using \"pmb.define_molecule\" with the above \"residue_list.\" \n", - "5. Create the branched polyampholyte into the ESPResSo system.\n", - "6. Visualize your creation.\n", - "7. Delete the molecule and check that the pyMBE database is empty." + "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### 1. Define particle templates for each different bead of Res_1 and Res_2." + "One can start by defining templates for each different bead of the PDAGA." ] }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 32, "metadata": {}, "outputs": [], "source": [ - "PDha_backbone_bead = 'BB-part1'\n", - "PDha_carboxyl_bead = 'COOH-part1'\n", - "PDha_amine_bead = 'NH3-part1'\n", + "PDAGA_backbone_bead = 'BB-PDAGA'\n", + "PDAGA_cyclic_amine_bead = 'NH3-PDAGA'\n", + "PDAGA_alpha_carboxyl_bead = 'aCOOH-PDAGA'\n", + "PDAGA_beta_carboxyl_bead = 'bCOOH-PDAGA'\n", "\n", - "pmb.define_particle(name = PDha_backbone_bead, \n", - " z = 0, \n", - " sigma = 0.4*pmb.units.nm,\n", + "pmb.define_particle(name = PDAGA_backbone_bead, \n", + " z = 0,\n", + " sigma = 0.4*pmb.units.nm, \n", " epsilon = 1*pmb.units('reduced_energy'))\n", "\n", - "pmb.define_particle(name = PDha_carboxyl_bead, \n", + "pmb.define_particle(name = PDAGA_cyclic_amine_bead, \n", " z = 0, \n", - " sigma = 0.5*pmb.units.nm, \n", + " sigma = 0.3*pmb.units.nm, \n", " epsilon = 1*pmb.units('reduced_energy'))\n", "\n", - "pmb.define_particle(name = PDha_amine_bead, \n", + "pmb.define_particle(name = PDAGA_alpha_carboxyl_bead, \n", " z = 0, \n", - " sigma = 0.3*pmb.units.nm, \n", + " sigma = 0.2*pmb.units.nm, \n", " epsilon = 1*pmb.units('reduced_energy'))\n", - "\n" + "\n", + "pmb.define_particle(name = PDAGA_beta_carboxyl_bead, \n", + " z = 0, \n", + " sigma = 0.4*pmb.units.nm, \n", + " epsilon = 1*pmb.units('reduced_energy'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### 2. Define the residue templates for Res_1 and Res_2." - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenamesigmaepsiloncutoffoffsetinitial_state
0particleNa0.35 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerNa
1particleBB-PDha0.4 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerBB-PDha
2particleCOOH-PDha0.5 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerCOOH-PDha
3particleNH3-PDha0.3 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerNH3-PDha
4particleBB-PDAGA0.4 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerBB-PDAGA
5particleNH3-PDAGA0.3 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerNH3-PDAGA
6particleaCOOH-PDAGA0.2 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometeraCOOH-PDAGA
7particlebCOOH-PDAGA0.4 nanometer25.692579121085853 millielectron_volt0.5612310241546864 nanometer0.0 nanometerbCOOH-PDAGA
\n", - "
" - ], - "text/plain": [ - " pmb_type name sigma \\\n", - "0 particle Na 0.35 nanometer \n", - "1 particle BB-PDha 0.4 nanometer \n", - "2 particle COOH-PDha 0.5 nanometer \n", - "3 particle NH3-PDha 0.3 nanometer \n", - "4 particle BB-PDAGA 0.4 nanometer \n", - "5 particle NH3-PDAGA 0.3 nanometer \n", - "6 particle aCOOH-PDAGA 0.2 nanometer \n", - "7 particle bCOOH-PDAGA 0.4 nanometer \n", - "\n", - " epsilon cutoff \\\n", - "0 25.692579121085853 millielectron_volt 0.5612310241546864 nanometer \n", - "1 25.692579121085853 millielectron_volt 0.5612310241546864 nanometer \n", - "2 25.692579121085853 millielectron_volt 0.5612310241546864 nanometer \n", - "3 25.692579121085853 millielectron_volt 0.5612310241546864 nanometer \n", - "4 25.692579121085853 millielectron_volt 0.5612310241546864 nanometer \n", - "5 25.692579121085853 millielectron_volt 0.5612310241546864 nanometer \n", - "6 25.692579121085853 millielectron_volt 0.5612310241546864 nanometer \n", - "7 25.692579121085853 millielectron_volt 0.5612310241546864 nanometer \n", - "\n", - " offset initial_state \n", - "0 0.0 nanometer Na \n", - "1 0.0 nanometer BB-PDha \n", - "2 0.0 nanometer COOH-PDha \n", - "3 0.0 nanometer NH3-PDha \n", - "4 0.0 nanometer BB-PDAGA \n", - "5 0.0 nanometer NH3-PDAGA \n", - "6 0.0 nanometer aCOOH-PDAGA \n", - "7 0.0 nanometer bCOOH-PDAGA " - ] - }, - "execution_count": 47, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pmb.get_templates_df('particle')\n", - "# pmb.get_instances_df('particle')" + "The next step is to define the two different residue templates: \n", + "1. The side chain: two carboxyl beads attached to the cyclic amine bead." ] }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 33, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenameparticle_namezes_type
0particle_stateNaNa00
1particle_stateBB-PDhaBB-PDha01
2particle_stateCOOH-PDhaCOOH-PDha02
3particle_stateNH3-PDhaNH3-PDha03
4particle_stateBB-PDAGABB-PDAGA04
5particle_stateNH3-PDAGANH3-PDAGA05
6particle_stateaCOOH-PDAGAaCOOH-PDAGA06
7particle_statebCOOH-PDAGAbCOOH-PDAGA07
8particle_stateBB-part1BB-part108
9particle_stateCOOH-part1COOH-part109
10particle_stateNH3-part1NH3-part1010
\n", - "
" - ], - "text/plain": [ - " pmb_type name particle_name z es_type\n", - "0 particle_state Na Na 0 0\n", - "1 particle_state BB-PDha BB-PDha 0 1\n", - "2 particle_state COOH-PDha COOH-PDha 0 2\n", - "3 particle_state NH3-PDha NH3-PDha 0 3\n", - "4 particle_state BB-PDAGA BB-PDAGA 0 4\n", - "5 particle_state NH3-PDAGA NH3-PDAGA 0 5\n", - "6 particle_state aCOOH-PDAGA aCOOH-PDAGA 0 6\n", - "7 particle_state bCOOH-PDAGA bCOOH-PDAGA 0 7\n", - "8 particle_state BB-part1 BB-part1 0 8\n", - "9 particle_state COOH-part1 COOH-part1 0 9\n", - "10 particle_state NH3-part1 NH3-part1 0 10" - ] - }, - "execution_count": 57, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "pmb.get_templates_df('particle_state')" + "PDAGA_side_chain_residue = 'PDAGA_side_chain_residue'\n", + "\n", + "pmb.define_residue (name = PDAGA_side_chain_residue,\n", + " central_bead = PDAGA_cyclic_amine_bead,\n", + " side_chains = [PDAGA_alpha_carboxyl_bead, PDAGA_beta_carboxyl_bead])" ] }, { - "cell_type": "code", - "execution_count": 59, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenamecentral_beadside_chains
0residuePDha_monBB-PDha[COOH-PDha, NH3-PDha]
1residuePDAGA_side_chain_residueNH3-PDAGA[aCOOH-PDAGA, bCOOH-PDAGA]
2residuePDAGA_monomer_residueBB-PDAGA[PDAGA_side_chain_residue]
\n", - "
" - ], - "text/plain": [ - " pmb_type name central_bead side_chains\n", - "0 residue PDha_mon BB-PDha [COOH-PDha, NH3-PDha]\n", - "1 residue PDAGA_side_chain_residue NH3-PDAGA [aCOOH-PDAGA, bCOOH-PDAGA]\n", - "2 residue PDAGA_monomer_residue BB-PDAGA [PDAGA_side_chain_residue]" - ] - }, - "execution_count": 59, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "pmb.get_templates_df('residue')" + "2. Each monomeric unit of the PDAGA: the side chain defined above attached to the backbone." ] }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 34, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenameresidue_list
0moleculePDha[PDha_mon, PDha_mon, PDha_mon, PDha_mon, PDha_...
1moleculePDAGA[PDAGA_monomer_residue, PDAGA_monomer_residue,...
2moleculediblock[PDha_mon, PDha_mon, PDha_mon, PDha_mon, PDAGA...
\n", - "
" - ], - "text/plain": [ - " pmb_type name residue_list\n", - "0 molecule PDha [PDha_mon, PDha_mon, PDha_mon, PDha_mon, PDha_...\n", - "1 molecule PDAGA [PDAGA_monomer_residue, PDAGA_monomer_residue,...\n", - "2 molecule diblock [PDha_mon, PDha_mon, PDha_mon, PDha_mon, PDAGA..." - ] - }, - "execution_count": 60, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "pmb.get_templates_df('molecule')" + "PDAGA_monomer_residue = 'PDAGA_monomer_residue'\n", + "pmb.define_residue( name = PDAGA_monomer_residue,\n", + " central_bead = PDAGA_backbone_bead,\n", + " side_chains = [PDAGA_side_chain_residue])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then, we need to define bond templates in a similar way as for the case of the simple polymer." ] }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 35, "metadata": {}, "outputs": [], "source": [ - "pmb.db.delete_templates(\"bond\")" + "bond_type = 'harmonic'\n", + "generic_bond_lenght=0.4 * pmb.units.nm\n", + "generic_harmonic_constant = 400 * pmb.units('reduced_energy / reduced_length**2')\n", + "\n", + "harmonic_bond = {'r_0' : generic_bond_lenght,\n", + " 'k' : generic_harmonic_constant,\n", + " }\n", + "\n", + "pmb.define_bond(bond_type = bond_type,\n", + " bond_parameters = harmonic_bond,\n", + " particle_pairs = [[PDAGA_backbone_bead, PDAGA_backbone_bead],\n", + " [PDAGA_backbone_bead, PDAGA_cyclic_amine_bead],\n", + " [PDAGA_alpha_carboxyl_bead, PDAGA_cyclic_amine_bead],\n", + " [PDAGA_beta_carboxyl_bead, PDAGA_cyclic_amine_bead]])" ] }, { "cell_type": "code", - "execution_count": 62, + "execution_count": null, "metadata": {}, "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, "source": [ - "pmb.db.delete_instances('particle_state')" + "Now, let us define an octamer of PDAGA." ] }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 36, "metadata": {}, "outputs": [], "source": [ - "res1='Residue1'\n", - "pmb.define_residue(name = res1,\n", - " central_bead = PDha_backbone_bead,\n", - " side_chains = [PDha_carboxyl_bead,PDha_amine_bead])\n", + "PDAGA_polymer = 'PDAGA'\n", + "N_monomers = 4\n", "\n", - "side_chain_name_res2='side_chain_res_2'\n", - "pmb.define_residue( name = side_chain_name_res2,\n", - " central_bead = PDha_backbone_bead,\n", - " side_chains = [PDha_carboxyl_bead,PDha_amine_bead])\n", + "pmb.define_molecule(name = PDAGA_polymer,\n", + " residue_list = [PDAGA_monomer_residue]*N_monomers)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, we are able to create a PDAGA polymer into the ESPResSo system." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [], + "source": [ + "N_polymers = 1\n", "\n", - "res2='Residue2'\n", - "pmb.define_residue(name = res2,\n", - " central_bead = PDha_backbone_bead,\n", - " side_chains = [side_chain_name_res2])" + "mol_ids = pmb.create_molecule(name = PDAGA_polymer,\n", + " number_of_molecules= N_polymers,\n", + " box_l= box_l,\n", + " list_of_first_residue_positions = [[Box_L.to('reduced_length').magnitude/2]*3])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.get_instances_df(pmb_type = 'particle')" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ - "3. Define bond templates for each pair of particle templates. " + "pmb.get_instances_df(pmb_type = 'residue')" ] }, { "cell_type": "code", - "execution_count": 64, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['Kw', 'N_A', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_check_bond_inputs', '_check_dimensionality', '_check_pka_set', '_create_espresso_bond_instance', '_create_hydrogel_chain', '_create_hydrogel_node', '_delete_particles_from_espresso', '_get_espresso_bond_instance', '_get_label_id_map', '_get_residue_list_from_sequence', '_get_template_type', 'add_instances_to_engine', 'calculate_HH', 'calculate_HH_Donnan', 'calculate_center_of_mass', 'calculate_net_charge', 'center_object_in_simulation_box', 'create_added_salt', 'create_bond', 'create_counterions', 'create_hydrogel', 'create_molecule', 'create_particle', 'create_protein', 'create_residue', 'db', 'define_bond', 'define_default_bond', 'define_hydrogel', 'define_molecule', 'define_monoprototic_acidbase_reaction', 'define_monoprototic_particle_states', 'define_particle', 'define_particle_states', 'define_peptide', 'define_protein', 'define_residue', 'delete_instances_in_system', 'determine_reservoir_concentrations', 'e', 'enable_motion_of_rigid_object', 'generate_coordinates_outside_sphere', 'generate_random_points_in_a_sphere', 'generate_trial_perpendicular_vector', 'get_bond_template', 'get_charge_number_map', 'get_instances_df', 'get_lj_parameters', 'get_particle_id_map', 'get_pka_set', 'get_radius_map', 'get_reactions_df', 'get_reduced_units', 'get_templates_df', 'get_type_map', 'initialize_lattice_builder', 'kB', 'kT', 'lattice_builder', 'load_database', 'load_pka_set', 'propose_unused_type', 'read_protein_vtf', 'rng', 'root', 'save_database', 'seed', 'set_particle_initial_state', 'set_reduced_units', 'set_simulation_engine', 'setup_cpH', 'setup_gcmc', 'setup_grxmc_reactions', 'setup_grxmc_unified', 'setup_lj_interactions', 'simulation_engine', 'units']\n", - "Empty DataFrame\n", - "Columns: []\n", - "Index: []\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
\n", - "
" - ], - "text/plain": [ - "Empty DataFrame\n", - "Columns: []\n", - "Index: []" - ] - }, - "execution_count": 64, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "print(dir(pmb))\n", - "print(pmb.get_instances_df(pmb_type=\"residue\"))\n", "pmb.get_instances_df(pmb_type = 'bond')" ] }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 41, "metadata": {}, "outputs": [], "source": [ - "bond_type = 'harmonic'\n", - "generic_bond_lenght=0.4 * pmb.units.nm\n", - "generic_harmonic_constant = 400 * pmb.units('reduced_energy / reduced_length**2')\n", - "\n", - "harmonic_bond = {'r_0' : generic_bond_lenght,\n", - " 'k' : generic_harmonic_constant,\n", - " }\n", - "\n", - "pmb.define_bond(bond_type = bond_type,\n", - " bond_parameters = harmonic_bond,\n", - " particle_pairs = [[PDha_backbone_bead, PDha_backbone_bead],\n", - " [PDha_backbone_bead, PDha_carboxyl_bead],\n", - " [PDha_backbone_bead, PDha_amine_bead]])" + "pmb.set_simulation_engine(espresso_system)\n", + "pmb.add_instances_to_engine()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### 3. Define a molecule template for the diblock polyampholyte. " + "Now, let us see our PDAGA molecule." ] }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 42, "metadata": {}, "outputs": [], "source": [ - "diblock_polymer='custom_polyampholyte'\n", - "pmb.define_molecule(name = diblock_polymer,\n", - " residue_list = 2*[res1]+[res2]+2*[res1]+2*[res2])" + "picture_name = 'PDAGA_system.png'\n", + "create_snapshot_of_espresso_system(espresso_system = espresso_system, \n", + " filename = picture_name)\n", + "img = Image.open(picture_name)\n", + "img.show()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### 4. Create the diblock polyampholyte chain into the ESPResSo system." + "Delete the particles and check that the pyMBE database is empty." ] }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 44, "metadata": {}, "outputs": [ { @@ -5162,523 +1105,114 @@ " \n", " \n", " \n", - " pmb_type\n", - " name\n", - " particle_id\n", - " position\n", - " fix\n", - " initial_state\n", - " residue_id\n", - " molecule_id\n", - " assembly_id\n", " \n", " \n", " \n", - " \n", - " 0\n", - " particle\n", - " BB-part1\n", - " 0\n", - " [7.499999999999999, 7.499999999999999, 7.49999...\n", - " None\n", - " BB-part1\n", - " 0\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 1\n", - " particle\n", - " COOH-part1\n", - " 1\n", - " [7.523286897123127, 6.7825727593903675, 8.0212...\n", - " None\n", - " COOH-part1\n", - " 0\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 2\n", - " particle\n", - " NH3-part1\n", - " 2\n", - " [7.37125134474576, 7.37461010141046, 8.2766151...\n", - " None\n", - " NH3-part1\n", - " 0\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 3\n", - " particle\n", - " BB-part1\n", - " 3\n", - " [6.694202325055984, 7.360411350475328, 7.34387...\n", - " None\n", - " BB-part1\n", - " 1\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 4\n", - " particle\n", - " COOH-part1\n", - " 4\n", - " [6.8599927657093085, 7.377868784266711, 6.4725...\n", - " None\n", - " COOH-part1\n", - " 1\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 5\n", - " particle\n", - " NH3-part1\n", - " 5\n", - " [6.5574917981405205, 7.276291078140914, 8.1246...\n", - " None\n", - " NH3-part1\n", - " 1\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 6\n", - " particle\n", - " BB-part1\n", - " 6\n", - " [5.888404650111968, 7.220822700950657, 7.18775...\n", - " None\n", - " BB-part1\n", - " 2\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 7\n", - " particle\n", - " BB-part1\n", - " 7\n", - " [6.0263924170157, 7.333839572897158, 6.3745136...\n", - " None\n", - " BB-part1\n", - " 2\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 8\n", - " particle\n", - " COOH-part1\n", - " 8\n", - " [5.428627933302976, 7.973911138422894, 6.51570...\n", - " None\n", - " COOH-part1\n", - " 2\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 9\n", - " particle\n", - " NH3-part1\n", - " 9\n", - " [6.214629818479694, 6.6498848824883945, 6.7381...\n", - " None\n", - " NH3-part1\n", - " 2\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 10\n", - " particle\n", - " BB-part1\n", - " 10\n", - " [5.082606975167953, 7.0812340514259855, 7.0316...\n", - " None\n", - " BB-part1\n", - " 3\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 11\n", - " particle\n", - " COOH-part1\n", - " 11\n", - " [5.286960752808877, 6.291537548321099, 6.68296...\n", - " None\n", - " COOH-part1\n", - " 3\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 12\n", - " particle\n", - " NH3-part1\n", - " 12\n", - " [5.227170116100419, 7.1222992787424255, 6.2487...\n", - " None\n", - " NH3-part1\n", - " 3\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 13\n", - " particle\n", - " BB-part1\n", - " 13\n", - " [4.276809300223937, 6.941645401901314, 6.87550...\n", - " None\n", - " BB-part1\n", - " 4\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 14\n", - " particle\n", - " COOH-part1\n", - " 14\n", - " [4.297103791116088, 6.231022116744782, 7.40611...\n", - " None\n", - " COOH-part1\n", - " 4\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 15\n", - " particle\n", - " NH3-part1\n", - " 15\n", - " [4.433450913961003, 6.168947892154966, 6.75789...\n", - " None\n", - " NH3-part1\n", - " 4\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 16\n", - " particle\n", - " BB-part1\n", - " 16\n", - " [3.471011625279922, 6.802056752376643, 6.71937...\n", - " None\n", - " BB-part1\n", - " 5\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 17\n", - " particle\n", - " BB-part1\n", - " 17\n", - " [3.523700228085275, 7.267635439887332, 6.03117...\n", - " None\n", - " BB-part1\n", - " 5\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 18\n", - " particle\n", - " COOH-part1\n", - " 18\n", - " [2.8966913762229116, 7.384703534397699, 6.6476...\n", - " None\n", - " COOH-part1\n", - " 5\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 19\n", - " particle\n", - " NH3-part1\n", - " 19\n", - " [2.8409213570311107, 7.6521574795497465, 5.884...\n", - " None\n", - " NH3-part1\n", - " 5\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 20\n", - " particle\n", - " BB-part1\n", - " 20\n", - " [2.6652139503359065, 6.662468102851972, 6.5632...\n", - " None\n", - " BB-part1\n", - " 6\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 21\n", - " particle\n", - " BB-part1\n", - " 21\n", - " [2.84313386885597, 5.87878434992065, 6.3456456...\n", - " None\n", - " BB-part1\n", - " 6\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 22\n", - " particle\n", - " COOH-part1\n", - " 22\n", - " [3.3573262392838927, 6.109235583087225, 7.0308...\n", - " None\n", - " COOH-part1\n", - " 6\n", - " 0\n", - " <NA>\n", - " \n", - " \n", - " 23\n", - " particle\n", - " NH3-part1\n", - " 23\n", - " [3.2797726587483904, 6.041618000523718, 6.9923...\n", - " None\n", - " NH3-part1\n", - " 6\n", - " 0\n", - " <NA>\n", - " \n", " \n", "\n", "" ], "text/plain": [ - " pmb_type name particle_id \\\n", - "0 particle BB-part1 0 \n", - "1 particle COOH-part1 1 \n", - "2 particle NH3-part1 2 \n", - "3 particle BB-part1 3 \n", - "4 particle COOH-part1 4 \n", - "5 particle NH3-part1 5 \n", - "6 particle BB-part1 6 \n", - "7 particle BB-part1 7 \n", - "8 particle COOH-part1 8 \n", - "9 particle NH3-part1 9 \n", - "10 particle BB-part1 10 \n", - "11 particle COOH-part1 11 \n", - "12 particle NH3-part1 12 \n", - "13 particle BB-part1 13 \n", - "14 particle COOH-part1 14 \n", - "15 particle NH3-part1 15 \n", - "16 particle BB-part1 16 \n", - "17 particle BB-part1 17 \n", - "18 particle COOH-part1 18 \n", - "19 particle NH3-part1 19 \n", - "20 particle BB-part1 20 \n", - "21 particle BB-part1 21 \n", - "22 particle COOH-part1 22 \n", - "23 particle NH3-part1 23 \n", - "\n", - " position fix initial_state \\\n", - "0 [7.499999999999999, 7.499999999999999, 7.49999... None BB-part1 \n", - "1 [7.523286897123127, 6.7825727593903675, 8.0212... None COOH-part1 \n", - "2 [7.37125134474576, 7.37461010141046, 8.2766151... None NH3-part1 \n", - "3 [6.694202325055984, 7.360411350475328, 7.34387... None BB-part1 \n", - "4 [6.8599927657093085, 7.377868784266711, 6.4725... None COOH-part1 \n", - "5 [6.5574917981405205, 7.276291078140914, 8.1246... None NH3-part1 \n", - "6 [5.888404650111968, 7.220822700950657, 7.18775... None BB-part1 \n", - "7 [6.0263924170157, 7.333839572897158, 6.3745136... None BB-part1 \n", - "8 [5.428627933302976, 7.973911138422894, 6.51570... None COOH-part1 \n", - "9 [6.214629818479694, 6.6498848824883945, 6.7381... None NH3-part1 \n", - "10 [5.082606975167953, 7.0812340514259855, 7.0316... None BB-part1 \n", - "11 [5.286960752808877, 6.291537548321099, 6.68296... None COOH-part1 \n", - "12 [5.227170116100419, 7.1222992787424255, 6.2487... None NH3-part1 \n", - "13 [4.276809300223937, 6.941645401901314, 6.87550... None BB-part1 \n", - "14 [4.297103791116088, 6.231022116744782, 7.40611... None COOH-part1 \n", - "15 [4.433450913961003, 6.168947892154966, 6.75789... None NH3-part1 \n", - "16 [3.471011625279922, 6.802056752376643, 6.71937... None BB-part1 \n", - "17 [3.523700228085275, 7.267635439887332, 6.03117... None BB-part1 \n", - "18 [2.8966913762229116, 7.384703534397699, 6.6476... None COOH-part1 \n", - "19 [2.8409213570311107, 7.6521574795497465, 5.884... None NH3-part1 \n", - "20 [2.6652139503359065, 6.662468102851972, 6.5632... None BB-part1 \n", - "21 [2.84313386885597, 5.87878434992065, 6.3456456... None BB-part1 \n", - "22 [3.3573262392838927, 6.109235583087225, 7.0308... None COOH-part1 \n", - "23 [3.2797726587483904, 6.041618000523718, 6.9923... None NH3-part1 \n", - "\n", - " residue_id molecule_id assembly_id \n", - "0 0 0 \n", - "1 0 0 \n", - "2 0 0 \n", - "3 1 0 \n", - "4 1 0 \n", - "5 1 0 \n", - "6 2 0 \n", - "7 2 0 \n", - "8 2 0 \n", - "9 2 0 \n", - "10 3 0 \n", - "11 3 0 \n", - "12 3 0 \n", - "13 4 0 \n", - "14 4 0 \n", - "15 4 0 \n", - "16 5 0 \n", - "17 5 0 \n", - "18 5 0 \n", - "19 5 0 \n", - "20 6 0 \n", - "21 6 0 \n", - "22 6 0 \n", - "23 6 0 " + "Empty DataFrame\n", + "Columns: []\n", + "Index: []" ] }, - "execution_count": 68, + "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "N_polymers = 1\n", "\n", - "mol_ids = pmb.create_molecule(name = diblock_polymer,\n", - " number_of_molecules= N_polymers,\n", - " box_l = box_l,\n", - " list_of_first_residue_positions = [[Box_L.to('reduced_length').magnitude/2]*3]) \n", - "# See the particle instances you have created\n", - "pmb.get_instances_df(pmb_type=\"particle\")" + "for mol_id in mol_ids:\n", + " pmb.delete_instances_in_system(instance_id=mol_id,\n", + " pmb_type=\"molecule\")\n", + "pmb.get_instances_df(pmb_type = 'particle')" ] }, { - "cell_type": "code", - "execution_count": 69, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenameresidue_idmolecule_idassembly_id
0residueResidue100<NA>
1residueResidue110<NA>
2residueResidue220<NA>
3residueResidue130<NA>
4residueResidue140<NA>
5residueResidue250<NA>
6residueResidue260<NA>
\n", - "
" - ], - "text/plain": [ - " pmb_type name residue_id molecule_id assembly_id\n", - "0 residue Residue1 0 0 \n", - "1 residue Residue1 1 0 \n", - "2 residue Residue2 2 0 \n", - "3 residue Residue1 3 0 \n", - "4 residue Residue1 4 0 \n", - "5 residue Residue2 5 0 \n", - "6 residue Residue2 6 0 " - ] - }, - "execution_count": 69, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "pmb.get_instances_df(pmb_type=\"residue\")" + "## How to create di-block copolymers " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In turn, the residues previously defined to build the PDAGA and PDha molecules can be used to build more complex polymers such as a di-block PDha-PDAGA copolymer, as shown in the picture below\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the bond template between the backbone particle of PDha and the backbone particle of PDAGA" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "pmb.define_bond(bond_type = bond_type,\n", + " bond_parameters = harmonic_bond,\n", + " particle_pairs = [[PDha_backbone_bead, PDAGA_backbone_bead]])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define a molecule template for the di-block polymer molecule using Python list comprehension methods" ] }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 46, + "metadata": {}, + "outputs": [], + "source": [ + "N_monomers_PDha = 4\n", + "N_monomers_PDAGA = 4\n", + "diblock_polymer = 'diblock'\n", + "\n", + "pmb.define_molecule(name = diblock_polymer,\n", + " residue_list = [PDha_residue]*N_monomers_PDha+[PDAGA_monomer_residue]*N_monomers_PDAGA)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Creating the di-block polymer into the ESPResSo system" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "N_polymers = 1\n", + "\n", + "mol_ids = pmb.create_molecule(name = diblock_polymer,\n", + " number_of_molecules= N_polymers,\n", + " box_l= box_l,\n", + " list_of_first_residue_positions = [[Box_L.to('reduced_length').magnitude/2]*3]) \n", + "# See the particle instances you have created\n", + "pmb.get_instances_df(pmb_type=\"particle\")" + ] + }, + { + "cell_type": "code", + "execution_count": 48, "metadata": {}, "outputs": [], "source": [ @@ -5689,32 +1223,32 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### 5. Visualize your creation." + "Now, let us see our di-block PDha-PDAGA molecule." ] }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 49, "metadata": {}, "outputs": [], "source": [ - "picture_name = 'CustomPolyampholite2_new.png'\n", + "picture_name = 'diblock_system.png'\n", "create_snapshot_of_espresso_system(espresso_system = espresso_system, \n", " filename = picture_name)\n", "img = Image.open(picture_name)\n", - "img.show()\n" + "img.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### 6. Delete the molecule and check that the pyMBE database is empty." + "Delete the particles and check that our df is empty." ] }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 51, "metadata": {}, "outputs": [ { @@ -5751,606 +1285,299 @@ "Index: []" ] }, - "execution_count": 72, + "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "for mol_id in mol_ids:\n", - " pmb.delete_instances_in_system(instance_id=mol_id,\n", - " pmb_type=\"molecule\",\n", - " espresso_system=espresso_system)\n", - "pmb.get_instances_df(pmb_type = 'particle')" + " pmb.delete_instances_in_system(instance_id=0, \n", + " pmb_type=\"molecule\")\n", + "pmb.get_instances_df(pmb_type=\"particle\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Refer to the sample script \"branched_polyampholyte.py\" in the samples folder for a complete solution of this exercise." + "## Practice by creating a custom polyampholyte chain " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## How to create peptides " + "Polyampholytes are polymers containing both acidic and basic groups on the same molecule, one example of a branched polyampholyte is depicted in the figure below.\n", + "\n", + "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "pyMBE includes built-on functions to facilitate the setting up of coarse-grained models for peptides from their aminoacid sequence. Currently, there are two different coarse-grained models implemented: \n", + "We will create the polyampholyte chain in the figure, starting by defining two different residues, 'Res_1' and 'Res_2'. The polyampholyte chain is then defined by following residue_list:\n", "\n", - "* `1beadAA`, where the aminoacid is represented by one single bead.\n", - "* `2beadAA`, where the aminoacid is represented by two beads (backbone and side-chain). \n", + "residue_list = 2*[\"Res_1\"] + [\"Res_2\"] + 2*[\"Res_1\"] + 2*[\"Res_2\"]\n", "\n", - "We provide reference parameters in the folder (`pyMBE/parameters`) which can be loaded into pyMBE. The peptide sequence should be provided as a `str` composed either by the list of the one letter code or the list of the three letter code of the corresponding aminoacids. For example, the two possible ways to provide the peptide Cysteine$_3$ - Glutamic acid$_2$ - Histidine$_4$ - Valine are:\n", + "### Tasks to do:\n", "\n", - "* one letter code: 'CCCEEHHHHV'\n", - "* three letter code: 'CYS-CYS-CYS-GLU-GLU-HIS-HIS-HIS-HIS-VAL'" + "1. Define particle templates for each different bead in the residues using \"pmb.define_particle\". There are 3 different particles, an inert particle, an acidic particle with pKa = 4, and a basic particle with pKa = 9.\n", + "2. Define residue templates using \"pmb.define_residue\". \"Res_1\" consists of an inert particle as central bead and acidic and basic particles as side chain. \"Res_2\" consists of an inert particle as central bead and \"Res_1\" as side chain.\n", + "3. Define bond templates for each pair of particle templates. \n", + "4. Define a molecule template for the branched polyampholyte chain using \"pmb.define_molecule\" with the above \"residue_list.\" \n", + "5. Create the branched polyampholyte into the ESPResSo system.\n", + "6. Visualize your creation.\n", + "7. Delete the molecule and check that the pyMBE database is empty." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 1. Define particle templates for each different bead of Res_1 and Res_2." + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [], + "source": [ + "PDha_backbone_bead = 'BB-part1'\n", + "PDha_carboxyl_bead = 'COOH-part1'\n", + "PDha_amine_bead = 'NH3-part1'\n", + "\n", + "pmb.define_particle(name = PDha_backbone_bead, \n", + " z = 0, \n", + " sigma = 0.4*pmb.units.nm,\n", + " epsilon = 1*pmb.units('reduced_energy'))\n", + "\n", + "pmb.define_particle(name = PDha_carboxyl_bead, \n", + " z = 0, \n", + " sigma = 0.5*pmb.units.nm, \n", + " epsilon = 1*pmb.units('reduced_energy'))\n", + "\n", + "pmb.define_particle(name = PDha_amine_bead, \n", + " z = 0, \n", + " sigma = 0.3*pmb.units.nm, \n", + " epsilon = 1*pmb.units('reduced_energy'))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 2. Define the residue templates for Res_1 and Res_2." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.get_templates_df('particle')\n", + "# pmb.get_instances_df('particle')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.get_templates_df('particle_state')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.get_templates_df('residue')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.get_templates_df('molecule')" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.db.delete_templates(\"bond\")" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.db.delete_instances('particle_state')" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [], + "source": [ + "res1='Residue1'\n", + "pmb.define_residue(name = res1,\n", + " central_bead = PDha_backbone_bead,\n", + " side_chains = [PDha_carboxyl_bead,PDha_amine_bead])\n", + "\n", + "side_chain_name_res2='side_chain_res_2'\n", + "pmb.define_residue( name = side_chain_name_res2,\n", + " central_bead = PDha_backbone_bead,\n", + " side_chains = [PDha_carboxyl_bead,PDha_amine_bead])\n", + "\n", + "res2='Residue2'\n", + "pmb.define_residue(name = res2,\n", + " central_bead = PDha_backbone_bead,\n", + " side_chains = [side_chain_name_res2])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "3. Define bond templates for each pair of particle templates. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(dir(pmb))\n", + "print(pmb.get_instances_df(pmb_type=\"residue\"))\n", + "pmb.get_instances_df(pmb_type = 'bond')" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [], + "source": [ + "bond_type = 'harmonic'\n", + "generic_bond_lenght=0.4 * pmb.units.nm\n", + "generic_harmonic_constant = 400 * pmb.units('reduced_energy / reduced_length**2')\n", + "\n", + "harmonic_bond = {'r_0' : generic_bond_lenght,\n", + " 'k' : generic_harmonic_constant,\n", + " }\n", + "\n", + "pmb.define_bond(bond_type = bond_type,\n", + " bond_parameters = harmonic_bond,\n", + " particle_pairs = [[PDha_backbone_bead, PDha_backbone_bead],\n", + " [PDha_backbone_bead, PDha_carboxyl_bead],\n", + " [PDha_backbone_bead, PDha_amine_bead]])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Let's set up the peptide Lysine$_5$ - Glutamic acid$_5$ using a two beads coarse-grained model." + "#### 3. Define a molecule template for the diblock polyampholyte. " ] }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 66, "metadata": {}, "outputs": [], "source": [ - "N_peptide = 1\n", - "sequence = \"KKKKKEEEEE\"\n", - "model = '2beadAA'" + "diblock_polymer='custom_polyampholyte'\n", + "pmb.define_molecule(name = diblock_polymer,\n", + " residue_list = 2*[res1]+[res2]+2*[res1]+2*[res2])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "We can use the peptide parametrization reported by Lunkad et al. [2], which is provided in the reference folder. This parametrization includes information about the particles (i.e. their Lennard-Jones parameters) and their bonding potentials (harmonic bonds)." + "#### 4. Create the diblock polyampholyte chain into the ESPResSo system." ] }, { "cell_type": "code", - "execution_count": 74, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenamebond_typeparticle_name1particle_name2parameters
0bondCA-CAharmonicCACA{'r_0': 0.382 nanometer, 'k': 10277.0316484343...
1bondCA-DharmonicCAD{'r_0': 0.329 nanometer, 'k': 10277.0316484343...
2bondCA-EharmonicCAE{'r_0': 0.435 nanometer, 'k': 10277.0316484343...
3bondCA-HharmonicCAH{'r_0': 0.452 nanometer, 'k': 10277.0316484343...
4bondCA-YharmonicCAY{'r_0': 0.648 nanometer, 'k': 10277.0316484343...
5bondCA-KharmonicCAK{'r_0': 0.558 nanometer, 'k': 10277.0316484343...
\n", - "
" - ], - "text/plain": [ - " pmb_type name bond_type particle_name1 particle_name2 \\\n", - "0 bond CA-CA harmonic CA CA \n", - "1 bond CA-D harmonic CA D \n", - "2 bond CA-E harmonic CA E \n", - "3 bond CA-H harmonic CA H \n", - "4 bond CA-Y harmonic CA Y \n", - "5 bond CA-K harmonic CA K \n", - "\n", - " parameters \n", - "0 {'r_0': 0.382 nanometer, 'k': 10277.0316484343... \n", - "1 {'r_0': 0.329 nanometer, 'k': 10277.0316484343... \n", - "2 {'r_0': 0.435 nanometer, 'k': 10277.0316484343... \n", - "3 {'r_0': 0.452 nanometer, 'k': 10277.0316484343... \n", - "4 {'r_0': 0.648 nanometer, 'k': 10277.0316484343... \n", - "5 {'r_0': 0.558 nanometer, 'k': 10277.0316484343... " - ] - }, - "execution_count": 74, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "path_to_interactions=pmb.root / \"parameters\" / \"peptides\" / \"Lunkad2021\"\n", - "path_to_pka=pmb.root / \"parameters\" / \"pka_sets\" / \"Hass2015.json\"\n", - "pmb.load_database(folder=path_to_interactions) \n", - "pmb.get_templates_df(pmb_type=\"particle\")\n", - "pmb.get_templates_df(pmb_type=\"bond\")" + "N_polymers = 1\n", + "\n", + "mol_ids = pmb.create_molecule(name = diblock_polymer,\n", + " number_of_molecules= N_polymers,\n", + " box_l = box_l,\n", + " list_of_first_residue_positions = [[Box_L.to('reduced_length').magnitude/2]*3]) \n", + "# See the particle instances you have created\n", + "pmb.get_instances_df(pmb_type=\"particle\")" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ - "Additionally, we can load one of the reference sets of pKa values for amino acids that we provide in pyMBE" + "pmb.get_instances_df(pmb_type=\"residue\")" ] }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 70, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
reactionstoichiometrypKreaction_typemetadatasimulation_method
0DH <-> D{'DH': -1, 'D': 1}4.0monoprotic_acid{'summary': 'pKa-values of Hass et al.', 'sour...None
1EH <-> E{'EH': -1, 'E': 1}4.4monoprotic_acid{'summary': 'pKa-values of Hass et al.', 'sour...None
2YH <-> Y{'YH': -1, 'Y': 1}9.6monoprotic_acid{'summary': 'pKa-values of Hass et al.', 'sour...None
3CH <-> C{'CH': -1, 'C': 1}8.3monoprotic_acid{'summary': 'pKa-values of Hass et al.', 'sour...None
4HH <-> H{'HH': -1, 'H': 1}6.8monoprotic_base{'summary': 'pKa-values of Hass et al.', 'sour...None
5KH <-> K{'KH': -1, 'K': 1}10.4monoprotic_base{'summary': 'pKa-values of Hass et al.', 'sour...None
6RH <-> R{'RH': -1, 'R': 1}13.5monoprotic_base{'summary': 'pKa-values of Hass et al.', 'sour...None
7nH <-> n{'nH': -1, 'n': 1}8.0monoprotic_base{'summary': 'pKa-values of Hass et al.', 'sour...None
8cH <-> c{'cH': -1, 'c': 1}3.6monoprotic_acid{'summary': 'pKa-values of Hass et al.', 'sour...None
\n", - "
" - ], - "text/plain": [ - " reaction stoichiometry pK reaction_type \\\n", - "0 DH <-> D {'DH': -1, 'D': 1} 4.0 monoprotic_acid \n", - "1 EH <-> E {'EH': -1, 'E': 1} 4.4 monoprotic_acid \n", - "2 YH <-> Y {'YH': -1, 'Y': 1} 9.6 monoprotic_acid \n", - "3 CH <-> C {'CH': -1, 'C': 1} 8.3 monoprotic_acid \n", - "4 HH <-> H {'HH': -1, 'H': 1} 6.8 monoprotic_base \n", - "5 KH <-> K {'KH': -1, 'K': 1} 10.4 monoprotic_base \n", - "6 RH <-> R {'RH': -1, 'R': 1} 13.5 monoprotic_base \n", - "7 nH <-> n {'nH': -1, 'n': 1} 8.0 monoprotic_base \n", - "8 cH <-> c {'cH': -1, 'c': 1} 3.6 monoprotic_acid \n", - "\n", - " metadata simulation_method \n", - "0 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", - "1 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", - "2 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", - "3 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", - "4 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", - "5 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", - "6 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", - "7 {'summary': 'pKa-values of Hass et al.', 'sour... None \n", - "8 {'summary': 'pKa-values of Hass et al.', 'sour... None " - ] - }, - "execution_count": 75, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "pmb.load_pka_set(path_to_pka)\n", - "# Check the loaded pKa set\n", - "pmb.get_reactions_df()" + "pmb.add_instances_to_engine()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Since monoprotic acid/base particles can be in two possible states, protonated and deprotonated, we need to define templates for those particle states" + "#### 5. Visualize your creation." ] }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 71, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'D': {'pka_value': 4.0, 'acidity': 'acidic'}, 'E': {'pka_value': 4.4, 'acidity': 'acidic'}, 'Y': {'pka_value': 9.6, 'acidity': 'acidic'}, 'C': {'pka_value': 8.3, 'acidity': 'acidic'}, 'H': {'pka_value': 6.8, 'acidity': 'basic'}, 'K': {'pka_value': 10.4, 'acidity': 'basic'}, 'R': {'pka_value': 13.5, 'acidity': 'basic'}, 'n': {'pka_value': 8.0, 'acidity': 'basic'}, 'c': {'pka_value': 3.6, 'acidity': 'acidic'}}\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenameparticle_namezes_type
0particle_stateCACA00
1particle_stateDHD01
2particle_stateDD-12
3particle_stateEHE03
4particle_stateEE-14
5particle_stateYHY05
6particle_stateYY-16
7particle_stateCHC07
8particle_stateCC-18
9particle_stateHHH19
10particle_stateHH010
11particle_stateKHK111
12particle_stateKK012
13particle_stateRHR113
14particle_stateRR014
15particle_statenHn115
16particle_statenn016
17particle_statecHc017
18particle_statecc-118
\n", - "
" - ], - "text/plain": [ - " pmb_type name particle_name z es_type\n", - "0 particle_state CA CA 0 0\n", - "1 particle_state DH D 0 1\n", - "2 particle_state D D -1 2\n", - "3 particle_state EH E 0 3\n", - "4 particle_state E E -1 4\n", - "5 particle_state YH Y 0 5\n", - "6 particle_state Y Y -1 6\n", - "7 particle_state CH C 0 7\n", - "8 particle_state C C -1 8\n", - "9 particle_state HH H 1 9\n", - "10 particle_state H H 0 10\n", - "11 particle_state KH K 1 11\n", - "12 particle_state K K 0 12\n", - "13 particle_state RH R 1 13\n", - "14 particle_state R R 0 14\n", - "15 particle_state nH n 1 15\n", - "16 particle_state n n 0 16\n", - "17 particle_state cH c 0 17\n", - "18 particle_state c c -1 18" - ] - }, - "execution_count": 76, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "# Get the pKa set stored in pyMBE\n", - "pka_set = pmb.get_pka_set()\n", - "# Check the pka_set\n", - "print(pka_set)\n", - "# define templates for the different particle states of monoprotic acid an basic groups:\n", - "for acidbase_particle in pka_set.keys():\n", - " pmb.define_monoprototic_particle_states(particle_name=acidbase_particle,\n", - " acidity=pka_set[acidbase_particle][\"acidity\"])\n", - "pmb.get_templates_df(pmb_type=\"particle_state\")" + "picture_name = 'CustomPolyampholite2_new.png'\n", + "create_snapshot_of_espresso_system(espresso_system = espresso_system, \n", + " filename = picture_name)\n", + "img = Image.open(picture_name)\n", + "img.show()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 6. Delete the molecule and check that the pyMBE database is empty." ] }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 72, "metadata": {}, "outputs": [ { @@ -6374,103 +1601,146 @@ " \n", " \n", " \n", - " pmb_type\n", - " name\n", - " sigma\n", - " epsilon\n", - " cutoff\n", - " offset\n", - " initial_state\n", " \n", " \n", " \n", - " \n", - " 0\n", - " particle\n", - " CA\n", - " 0.35 nanometer\n", - " 25.69257912108585 millielectron_volt\n", - " 0.3984740271498274 nanometer\n", - " 0.0 nanometer\n", - " CA\n", - " \n", - " \n", - " 1\n", - " particle\n", - " D\n", - " 0.35 nanometer\n", - " 25.69257912108585 millielectron_volt\n", - " 0.3984740271498274 nanometer\n", - " 0.0 nanometer\n", - " DH\n", - " \n", - " \n", - " 2\n", - " particle\n", - " E\n", - " 0.35 nanometer\n", - " 25.69257912108585 millielectron_volt\n", - " 0.3984740271498274 nanometer\n", - " 0.0 nanometer\n", - " EH\n", - " \n", - " \n", - " 3\n", - " particle\n", - " H\n", - " 0.35 nanometer\n", - " 25.69257912108585 millielectron_volt\n", - " 0.3984740271498274 nanometer\n", - " 0.0 nanometer\n", - " HH\n", - " \n", - " \n", - " 4\n", - " particle\n", - " Y\n", - " 0.35 nanometer\n", - " 25.69257912108585 millielectron_volt\n", - " 0.3984740271498274 nanometer\n", - " 0.0 nanometer\n", - " YH\n", - " \n", - " \n", - " 5\n", - " particle\n", - " K\n", - " 0.35 nanometer\n", - " 25.69257912108585 millielectron_volt\n", - " 0.3984740271498274 nanometer\n", - " 0.0 nanometer\n", - " KH\n", - " \n", " \n", "\n", "" ], "text/plain": [ - " pmb_type name sigma epsilon \\\n", - "0 particle CA 0.35 nanometer 25.69257912108585 millielectron_volt \n", - "1 particle D 0.35 nanometer 25.69257912108585 millielectron_volt \n", - "2 particle E 0.35 nanometer 25.69257912108585 millielectron_volt \n", - "3 particle H 0.35 nanometer 25.69257912108585 millielectron_volt \n", - "4 particle Y 0.35 nanometer 25.69257912108585 millielectron_volt \n", - "5 particle K 0.35 nanometer 25.69257912108585 millielectron_volt \n", - "\n", - " cutoff offset initial_state \n", - "0 0.3984740271498274 nanometer 0.0 nanometer CA \n", - "1 0.3984740271498274 nanometer 0.0 nanometer DH \n", - "2 0.3984740271498274 nanometer 0.0 nanometer EH \n", - "3 0.3984740271498274 nanometer 0.0 nanometer HH \n", - "4 0.3984740271498274 nanometer 0.0 nanometer YH \n", - "5 0.3984740271498274 nanometer 0.0 nanometer KH " + "Empty DataFrame\n", + "Columns: []\n", + "Index: []" ] }, - "execution_count": 77, + "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], + "source": [ + "for mol_id in mol_ids:\n", + " pmb.delete_instances_in_system(instance_id=mol_id,\n", + " pmb_type=\"molecule\",\n", + " espresso_system=espresso_system)\n", + "pmb.get_instances_df(pmb_type = 'particle')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Refer to the sample script \"branched_polyampholyte.py\" in the samples folder for a complete solution of this exercise." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## How to create peptides " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "pyMBE includes built-on functions to facilitate the setting up of coarse-grained models for peptides from their aminoacid sequence. Currently, there are two different coarse-grained models implemented: \n", + "\n", + "* `1beadAA`, where the aminoacid is represented by one single bead.\n", + "* `2beadAA`, where the aminoacid is represented by two beads (backbone and side-chain). \n", + "\n", + "We provide reference parameters in the folder (`pyMBE/parameters`) which can be loaded into pyMBE. The peptide sequence should be provided as a `str` composed either by the list of the one letter code or the list of the three letter code of the corresponding aminoacids. For example, the two possible ways to provide the peptide Cysteine$_3$ - Glutamic acid$_2$ - Histidine$_4$ - Valine are:\n", + "\n", + "* one letter code: 'CCCEEHHHHV'\n", + "* three letter code: 'CYS-CYS-CYS-GLU-GLU-HIS-HIS-HIS-HIS-VAL'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's set up the peptide Lysine$_5$ - Glutamic acid$_5$ using a two beads coarse-grained model." + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": {}, + "outputs": [], + "source": [ + "N_peptide = 1\n", + "sequence = \"KKKKKEEEEE\"\n", + "model = '2beadAA'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can use the peptide parametrization reported by Lunkad et al. [2], which is provided in the reference folder. This parametrization includes information about the particles (i.e. their Lennard-Jones parameters) and their bonding potentials (harmonic bonds)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "path_to_interactions=pmb.root / \"parameters\" / \"peptides\" / \"Lunkad2021\"\n", + "path_to_pka=pmb.root / \"parameters\" / \"pka_sets\" / \"Hass2015.json\"\n", + "pmb.load_database(folder=path_to_interactions) \n", + "pmb.get_templates_df(pmb_type=\"particle\")\n", + "pmb.get_templates_df(pmb_type=\"bond\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Additionally, we can load one of the reference sets of pKa values for amino acids that we provide in pyMBE" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pmb.load_pka_set(path_to_pka)\n", + "# Check the loaded pKa set\n", + "pmb.get_reactions_df()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since monoprotic acid/base particles can be in two possible states, protonated and deprotonated, we need to define templates for those particle states" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Get the pKa set stored in pyMBE\n", + "pka_set = pmb.get_pka_set()\n", + "# Check the pka_set\n", + "print(pka_set)\n", + "# define templates for the different particle states of monoprotic acid an basic groups:\n", + "for acidbase_particle in pka_set.keys():\n", + " pmb.define_monoprototic_particle_states(particle_name=acidbase_particle,\n", + " acidity=pka_set[acidbase_particle][\"acidity\"])\n", + "pmb.get_templates_df(pmb_type=\"particle_state\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "pmb.get_templates_df(pmb_type=\"particle\")" ] @@ -6484,63 +1754,9 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenamemodelresidue_listsequence
0peptideKKKKKEEEEE2beadAA[AA-K, AA-K, AA-K, AA-K, AA-K, AA-E, AA-E, AA-...KKKKKEEEEE
\n", - "
" - ], - "text/plain": [ - " pmb_type name model \\\n", - "0 peptide KKKKKEEEEE 2beadAA \n", - "\n", - " residue_list sequence \n", - "0 [AA-K, AA-K, AA-K, AA-K, AA-K, AA-E, AA-E, AA-... KKKKKEEEEE " - ] - }, - "execution_count": 78, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from pyMBE.lib.handy_functions import define_peptide_AA_residues\n", "\n", @@ -6565,58 +1781,9 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pmb_typenamemolecule_idassembly_id
0peptideKKKKKEEEEE0<NA>
\n", - "
" - ], - "text/plain": [ - " pmb_type name molecule_id assembly_id\n", - "0 peptide KKKKKEEEEE 0 " - ] - }, - "execution_count": 80, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "\n", "mol_ids = pmb.create_molecule(name = sequence,\n", From 858fe3e2ab2420184caa8bdadef03f1f009c1e07 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Wed, 1 Jul 2026 17:47:59 +0200 Subject: [PATCH 64/75] Delete data.csv --- testsuite/weak_polyelectrolyte_dialysis_test_data/data.csv | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 testsuite/weak_polyelectrolyte_dialysis_test_data/data.csv diff --git a/testsuite/weak_polyelectrolyte_dialysis_test_data/data.csv b/testsuite/weak_polyelectrolyte_dialysis_test_data/data.csv deleted file mode 100644 index 7633410b..00000000 --- a/testsuite/weak_polyelectrolyte_dialysis_test_data/data.csv +++ /dev/null @@ -1,6 +0,0 @@ -csalt,cmon,pH,pKa,n_blocks,block_size,mean,err_mean,n_eff,tau_int -value,value,value,value,nan,nan,alpha,alpha,alpha,alpha -0.01,0.435,9,4,16.0,5.625,0.9938888888888889,0.0009782669231040671,69.726915596805,6.453748830676951 -0.01,0.435,3,4,16.0,5.625,0.03822222222222222,0.002196173720894064,49.65617564819513,9.062316904704018 -0.01,0.435,7,4,16.0,5.625,0.7143333333333334,0.008198146056605243,20.631416329721212,21.811396406718313 -0.01,0.435,5,4,16.0,5.625,0.24022222222222223,0.005238508882176492,29.478155904183986,15.265541082769019 From 32289b708f4ac3b579e2eaf18692b4dda1450c86 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Wed, 1 Jul 2026 17:50:19 +0200 Subject: [PATCH 65/75] Add DummyEngine with __getattr__ dunder method to raise RuntimeError Add methods descriptions,remove unused import --- pyMBE/simulation_builder/base_engine.py | 8 +++++++- pyMBE/simulation_builder/espresso_engine.py | 11 +++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/pyMBE/simulation_builder/base_engine.py b/pyMBE/simulation_builder/base_engine.py index 8a4dd5f3..5c596074 100644 --- a/pyMBE/simulation_builder/base_engine.py +++ b/pyMBE/simulation_builder/base_engine.py @@ -159,4 +159,10 @@ def determine_reservoir_concentrations_selfconsistently(cH_res, c_salt_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 \ No newline at end of file + return cH_res, cOH_res, cNa_res, cCl_res + +class DummyEngine: + def __getattr__(self, attr): + if attr not in self.__dict__: + raise RuntimeError('You have not set up any simulation engine yet') + return super().__getattr__(attr) \ No newline at end of file diff --git a/pyMBE/simulation_builder/espresso_engine.py b/pyMBE/simulation_builder/espresso_engine.py index a1753d20..500c1e59 100644 --- a/pyMBE/simulation_builder/espresso_engine.py +++ b/pyMBE/simulation_builder/espresso_engine.py @@ -20,7 +20,7 @@ import espressomd.electrostatics import espressomd.version import warnings -from typing import List,Set +from typing import List import numpy as np import logging from pyMBE.simulation_builder.base_engine import SimulationEngine @@ -104,7 +104,8 @@ def _add_particle(self,particle_id): def _check_particle_exists_in_espresso(self,particle_id): - """_summary_ + """ + Checks the existance of a particle_id in a espresso_system instance. Args: particle_id (int): pid of the particle that we want to check that exists within espresso @@ -267,7 +268,8 @@ def _create_angle_instance(self, angle_type, angle_parameters): def _get_particle_ids_in_espresso(self): - """_summary_ + """ + Gets a list of all the particles_id in espresso_system instance. Returns: espresso_particles_id(list): list of pids of the particles that are saved in espresso @@ -277,7 +279,8 @@ def _get_particle_ids_in_espresso(self): def _get_particle_pos_espresso(self,id): - """_summary_ + """ + Gets the particle position of Args: id (int): pid of the particle that we want to check that exists within espresso From 0dc430a2d45dc2fc741034cf9019bef44f0d36c0 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Wed, 1 Jul 2026 17:50:54 +0200 Subject: [PATCH 66/75] Use __getattr__ to setup not ImplementedError for LammpsSimulationEngine --- pyMBE/simulation_builder/lammps_engine.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pyMBE/simulation_builder/lammps_engine.py b/pyMBE/simulation_builder/lammps_engine.py index 9ef4bf39..e9307082 100644 --- a/pyMBE/simulation_builder/lammps_engine.py +++ b/pyMBE/simulation_builder/lammps_engine.py @@ -22,5 +22,7 @@ class LammpsSimulation(SimulationEngine): def __init__(self): pass - def add_instances_to_engine(self): - return \ No newline at end of file + def __getattr__(self, attr): + if attr not in self.__dict__: + raise NotImplementedError('Lammps Simulation Engine is not yet implemented') + return super().__getattr__(attr) \ No newline at end of file From 8f18d26278191502ce4e4784a469627cfb43e0b3 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Wed, 1 Jul 2026 17:51:35 +0200 Subject: [PATCH 67/75] remove unused variable espresso_local_system --- testsuite/hydrogel_builder_with_angles.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/hydrogel_builder_with_angles.py b/testsuite/hydrogel_builder_with_angles.py index 83726ec6..d3686ad6 100644 --- a/testsuite/hydrogel_builder_with_angles.py +++ b/testsuite/hydrogel_builder_with_angles.py @@ -222,7 +222,7 @@ def test_hydrogel_partial_crosslinker_angle_definitions_raise(self): """ Defining only a subset of required crosslinker-adjacent angles should fail. """ - pmb_local, espresso_system_local, hydrogel_name_local, _ = build_simple_hydrogel_with_optional_angles( + pmb_local, _, hydrogel_name_local, _ = build_simple_hydrogel_with_optional_angles( junction_angle_mode="partial" ) with self.assertRaises(ValueError): From cface834e17ee1774db205121351cfc8f7ae849b Mon Sep 17 00:00:00 2001 From: jsd94 Date: Wed, 1 Jul 2026 18:24:01 +0200 Subject: [PATCH 68/75] Add LammpsSimulationEngine that Raises a not ImplementedError --- pyMBE/simulation_builder/lammps_engine.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/pyMBE/simulation_builder/lammps_engine.py b/pyMBE/simulation_builder/lammps_engine.py index e9307082..b6cc968c 100644 --- a/pyMBE/simulation_builder/lammps_engine.py +++ b/pyMBE/simulation_builder/lammps_engine.py @@ -23,6 +23,15 @@ class LammpsSimulation(SimulationEngine): def __init__(self): pass def __getattr__(self, attr): - if attr not in self.__dict__: - raise NotImplementedError('Lammps Simulation Engine is not yet implemented') - return super().__getattr__(attr) \ No newline at end of file + raise NotImplementedError('Lammps Simulation Engine is not yet implemented') + + def _add_angle(self): + return + def _create_bond_instance(self): + return + def _get_bond_instance(self): + return + def add_instances_to_engine(self): + return + + \ No newline at end of file From 807296fe74a926f8ddc0628b072f5205ee610331 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Wed, 1 Jul 2026 18:30:09 +0200 Subject: [PATCH 69/75] Add a DummyEngine instantiated by default in pyMBE. Modify default value for fix=False. As fix=[False,False,False] is considered as a dangerous default value for pylint. Modify if/else chain ,that raised different exceptions depending on the instantiated simulation Engine, in class pymbe_library methods implemented by espresso by simulation_engine.method --- pyMBE/pyMBE.py | 103 ++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 57 deletions(-) diff --git a/pyMBE/pyMBE.py b/pyMBE/pyMBE.py index add0dc49..fd5d5829 100644 --- a/pyMBE/pyMBE.py +++ b/pyMBE/pyMBE.py @@ -50,6 +50,7 @@ from pyMBE.simulation_builder.espresso_engine import EspressoSimulation from pyMBE.simulation_builder.lammps_engine import LammpsSimulation +from pyMBE.simulation_builder.base_engine import DummyEngine from pyMBE.simulation_builder.engine_protocol import EspressoSystemProtocol,LammpsProtocol ## Reactions from pyMBE.storage.reactions.reaction import Reaction, ReactionParticipant @@ -129,7 +130,7 @@ def __init__(self, seed, temperature=None, unit_length=None, unit_charge=None, K Kw=Kw) self.db = Manager(units=self.units) - self.simulation_engine = None + self.simulation_engine = DummyEngine() self.lattice_builder = None self.root = importlib.resources.files(__package__) @@ -1178,7 +1179,7 @@ def create_molecule(self, name, number_of_molecules, box_l, list_of_first_residu molecule_ids.append(molecule_id) return molecule_ids - def create_particle(self, name, box_l, number_of_particles, position=None, fix=[False,False,False]): + def create_particle(self, name, box_l, number_of_particles, position=None, fix=False): """ Creates one or more particles in an ESPResSo system based on the particle template in the pyMBE database. @@ -1211,9 +1212,10 @@ def create_particle(self, name, box_l, number_of_particles, position=None, fix=[ part_state = self.db.get_template(pmb_type="particle_state", name=part_tpl.initial_state) name_state=part_state.name - #z= part_state.z - #es_type = part_state.es_type - # Create the new particles into ESPResSo + + if fix is False: + fix=[fix]*3 + created_pid_list=[] for index in range(number_of_particles): if position is None: @@ -1223,8 +1225,6 @@ def create_particle(self, name, box_l, number_of_particles, position=None, fix=[ particle_id = self.db._propose_instance_id(pmb_type="particle") created_pid_list.append(particle_id) - # kwargs = dict(id=particle_id, pos=particle_position, type=es_type, q=z) - # espresso_system.part.add(**kwargs) part_inst = ParticleInstance(name=name, particle_id=particle_id, initial_state=name_state, @@ -2758,8 +2758,9 @@ def set_reduced_units(self, unit_length=None, unit_charge=None, temperature=None logging.info(self.get_reduced_units()) def set_simulation_engine(self,simulation_engine,box_l=None): - """_summary_ - + """ + Sets the instance attribute simulation_engine to an instance of a class of type SimulationEngine. + Args: simulation_engine (Any): object which contains the methods to setup molecular dynamics and montecarlo simulations box_l('list[float,float,float]'): list of floats with the dimensions of the box @@ -2809,17 +2810,12 @@ def setup_cpH (self, counter_ion, constant_pH, exclusion_range=None, use_exclusi Instance of a reaction_methods.ConstantpHEnsemble object from the espressomd library. """ - if isinstance(self.simulation_engine,EspressoSimulation): - RE = self.simulation_engine.setup_cpH(counter_ion=counter_ion, - constant_pH=constant_pH, - exclusion_range=exclusion_range, - use_exclusion_radius_per_type = use_exclusion_radius_per_type) - return RE - elif isinstance(self.simulation_engine,LammpsSimulation): - raise NotImplementedError('In this version espresso has only been decoupled. Interoperability with other engines is not yet provided') - else: - raise RuntimeError('You need to set your simulation Engine') - + + RE = self.simulation_engine.setup_cpH(counter_ion=counter_ion, + constant_pH=constant_pH, + exclusion_range=exclusion_range, + use_exclusion_radius_per_type = use_exclusion_radius_per_type) + return RE def setup_gcmc(self, c_salt_res, salt_cation_name, salt_anion_name, activity_coefficient, exclusion_range=None, use_exclusion_radius_per_type = False): """ @@ -2849,18 +2845,14 @@ def setup_gcmc(self, c_salt_res, salt_cation_name, salt_anion_name, activity_coe ('reaction_methods.ReactionEnsemble'): Instance of a reaction_methods.ReactionEnsemble object from the espressomd library. """ - if isinstance(self.simulation_engine,EspressoSimulation): - RE = self.simulation_engine.setup_gcmc(c_salt_res=c_salt_res, - salt_anion_name=salt_anion_name, - salt_cation_name=salt_cation_name, - activity_coefficient=activity_coefficient, - exclusion_range=exclusion_range, - use_exclusion_radius_per_type = use_exclusion_radius_per_type) - return RE - elif isinstance(self.simulation_engine,LammpsSimulation): - raise NotImplementedError('In this version espresso has only been decoupled. Interoperability with other engines is not yet provided') - else: - raise RuntimeError('You need to set your simulation Engine') + + RE = self.simulation_engine.setup_gcmc(c_salt_res=c_salt_res, + salt_anion_name=salt_anion_name, + salt_cation_name=salt_cation_name, + activity_coefficient=activity_coefficient, + exclusion_range=exclusion_range, + use_exclusion_radius_per_type = use_exclusion_radius_per_type) + return RE def setup_grxmc_reactions(self, pH_res, c_salt_res, proton_name, hydroxide_name, salt_cation_name, salt_anion_name, activity_coefficient, exclusion_range=None, use_exclusion_radius_per_type = False): @@ -2868,6 +2860,7 @@ def setup_grxmc_reactions(self, pH_res, c_salt_res, proton_name, hydroxide_name, Sets up acid/base reactions for acidic/basic monoprotic particles defined in the pyMBE database, as well as a grand-canonical coupling to a reservoir of small ions. + Args: pH_res ('float'): pH-value in the reservoir. @@ -2897,7 +2890,8 @@ def setup_grxmc_reactions(self, pH_res, c_salt_res, proton_name, hydroxide_name, Controls if one exclusion_radius for each espresso_type is used. Defaults to 'False'. Returns: - 'tuple(reaction_methods.ReactionEnsemble,pint.Quantity)': + For the Espresso system class: + Output ('tuple(reaction_methods.ReactionEnsemble,pint.Quantity)'): 'reaction_methods.ReactionEnsemble': espressomd reaction_methods object with all reactions necesary to run the GRxMC ensamble. @@ -2910,22 +2904,19 @@ def setup_grxmc_reactions(self, pH_res, c_salt_res, proton_name, hydroxide_name, [1] Landsgesell, J., Hebbeker, P., Rud, O., Lunkad, R., Košovan, P., & Holm, C. (2020). Grand-reaction method for simulations of ionization equilibria coupled to ion partitioning. Macromolecules, 53(8), 3007-3020. """ - if isinstance(self.simulation_engine,EspressoSimulation): - RE, ionic_strength_res=self.simulation_engine.setup_grxmc_reactions(pH_res=pH_res, - c_salt_res=c_salt_res, - proton_name=proton_name, - hydroxide_name=hydroxide_name, - salt_cation_name=salt_cation_name, - salt_anion_name=salt_anion_name, - activity_coefficient=activity_coefficient, - exclusion_range=exclusion_range, - use_exclusion_radius_per_type=use_exclusion_radius_per_type) - - return RE, ionic_strength_res - elif isinstance(self.simulation_engine,LammpsSimulation): - raise NotImplementedError('In this version espresso has only been decoupled. Interoperability with other engines is not yet provided') - else: - raise RuntimeError('You need to set your simulation Engine') + + output=self.simulation_engine.setup_grxmc_reactions(pH_res=pH_res, + c_salt_res=c_salt_res, + proton_name=proton_name, + hydroxide_name=hydroxide_name, + salt_cation_name=salt_cation_name, + salt_anion_name=salt_anion_name, + activity_coefficient=activity_coefficient, + exclusion_range=exclusion_range, + use_exclusion_radius_per_type=use_exclusion_radius_per_type) + + return output + def setup_grxmc_unified(self, pH_res, c_salt_res, cation_name, anion_name, activity_coefficient, exclusion_range=None, use_exclusion_radius_per_type = False): """ Sets up acid/base reactions for acidic/basic 'particles' defined in the pyMBE database, as well as a grand-canonical coupling to a @@ -2954,7 +2945,8 @@ def setup_grxmc_unified(self, pH_res, c_salt_res, cation_name, anion_name, activ Controls if one exclusion_radius per each espresso_type. Defaults to 'False'. Returns: - 'tuple(reaction_methods.ReactionEnsemble,pint.Quantity)': + For the Espresso system class: + Output ('tuple(reaction_methods.ReactionEnsemble,pint.Quantity)'): 'reaction_methods.ReactionEnsemble': espressomd reaction_methods object with all reactions necesary to run the GRxMC ensamble. @@ -2969,19 +2961,16 @@ def setup_grxmc_unified(self, pH_res, c_salt_res, cation_name, anion_name, activ [1] Curk, T., Yuan, J., & Luijten, E. (2022). Accelerated simulation method for charge regulation effects. The Journal of Chemical Physics, 156(4). [2] Landsgesell, J., Hebbeker, P., Rud, O., Lunkad, R., Košovan, P., & Holm, C. (2020). Grand-reaction method for simulations of ionization equilibria coupled to ion partitioning. Macromolecules, 53(8), 3007-3020. """ - if isinstance(self.simulation_engine,EspressoSimulation): - RE, ionic_strength_res=self.simulation_engine.setup_grxmc_unified(pH_res=pH_res, + + output=self.simulation_engine.setup_grxmc_unified(pH_res=pH_res, c_salt_res=c_salt_res, cation_name=cation_name, anion_name=anion_name, activity_coefficient=activity_coefficient, exclusion_range=exclusion_range, use_exclusion_radius_per_type = use_exclusion_radius_per_type) - return RE, ionic_strength_res - elif isinstance(self.simulation_engine,LammpsSimulation): - raise NotImplementedError('In this version espresso has only been decoupled. Interoperability with other engines is not yet provided') - else: - raise RuntimeError('You need to set your simulation Engine') + return output + def setup_lj_interactions(self, shift_potential=True, combining_rule='Lorentz-Berthelot'): From d8453bc190140e2facd2cfd40965f18a42ea1e93 Mon Sep 17 00:00:00 2001 From: Pablo Date: Thu, 2 Jul 2026 20:47:08 +0200 Subject: [PATCH 70/75] added jordi to author list, update changelog --- AUTHORS.md | 3 ++- CHANGELOG.md | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/AUTHORS.md b/AUTHORS.md index d1e7e256..06da0f84 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -12,6 +12,7 @@ The following people have contributed to pyMBE (Github username, Name, current a - paobtorres, Paola B. Torres (Universidad Tecnológica Nacional, Argentina) - pinedaps, Sebastian P. Pineda (University of Lund, Sweden) - 1234somesh, Somesh Kurahatti (University of Stuttgart, Germany) +- jorch28, Jordi Sans Figuero (Freelance, Spain) ## Tier-1 Contributors - TommyTraan, Duy Tommy Tran (Norwegian University of Science and Technology, Norway) @@ -28,4 +29,4 @@ The following people have contributed to pyMBE (Github username, Name, current a - Magdaléna Nejedlá (Charles University, Czech Republic) - Raju Lunkad (University of Goettingen, Germany) - Rita S. Dias (Norwegian University of Science and Technology, Norway) -- Sergio Madurga (University of Barcelona, Spain) \ No newline at end of file +- Sergio Madurga (University of Barcelona, Spain) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b513a04..b1b4ef1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ## Added +- Simulation-engine abstraction layer to decouple pyMBE molecular-building logic from simulation-engine-specific implementation details. (#151) +- Added `EspressoEngine` to delegate ESPResSo-specific operations, including reaction methods, setup utilities, and particle/bond/angle insertion. (#151) +- Added `add_instances_to_engine()` to transfer pyMBE particles, bonds, and angles to the selected simulation engine. (#151) +- Added protocol classes to validate supported simulation-engine interfaces, including ESPResSo-system compatibility checks. (#151) +- Added preliminary LAMMPS engine scaffolding to prepare pyMBE for future interoperability with additional simulation backends. (#151) - Support to setup angular potentials with pyMBE. All flexible pyMBE templates now support angula potentials: hydrogels, molecules, peptides and residues (including residues with nested residues). (#150) - Sample scripts and tests for the new functionality. (#150) - Template and instance `Angle` to store information about angular potentials in the pyMBE database. (#150) @@ -22,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added utility functions in `lib/handy_functions` to define residue and particle templates for aminoacids en peptides and residues: `define_protein_AA_particles`, `define_protein_AA_residues` and `define_peptide_AA_residues`. (#147) ## Changed +- Moved engine-dependent functionality from pyMBE-level methods and helper functions to the selected simulation engine. (#151) - Create methods (`create_particle`, `create_residue`, `create_molecule`, `create_protein`, `create_hydrogel`) now raise a ValueError if no template is found for an input `name` instead than a warning. (#147) - Refactored core modules to use the new database schema based on templates and instances for particles, residues, molecules, hydrogels, proteins and peptides. (#147) - Particle states now are independent templates and are now disentangled from particle templates. (#147) @@ -35,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed +- Deprecated legacy ESPResSo-specific helper functions in favor of the corresponding pmb.simulation_engine.* methods, including reaction execution, particle counting, system relaxation, Langevin dynamics setup, and electrostatic-interaction setup. - Methods that interact directly with the pyMBE dataframe. These methods have been replaced by private methods that instead interact with the new canonical pyMBE database in (`pyMBE/storage/manager`). This includes the methods: `add_bond_in_df`, `add_value_to_df`, `assign_molecule_id`, `check_if_df_cell_has_a_value`, `check_if_name_is_defined_in_df`, `check_if_multiple_pmb_types_for_name`, `clean_df_row`, `clean_ids_in_df_row`, `copy_df_entry`, `create_variable_with_units`, `convert_columns_to_original_format`, `convert_str_to_bond_object`, `delete_entries_in_df`, `find_bond_key`, `setup_df`, `define_particle_entry_in_df`, custom `NumpyEncoder`. (#145,#147) - Method `add_bonds_to_espresso` has been removed from the API. pyMBE now adds bonds internally to ESPResSo when molecule instances are created into ESPResSo. (#147) - Tutorial `lattice_builder.ipynb` has been removed because its content is redundant with sample script `build_hydrogel.py`. (#147) From d20e6b8afcd0efafa5642bb200710224510a94bc Mon Sep 17 00:00:00 2001 From: jsd94 Date: Thu, 2 Jul 2026 23:51:29 +0200 Subject: [PATCH 71/75] Add facade method to lammps engine to comply with the interface contract --- pyMBE/simulation_builder/lammps_engine.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyMBE/simulation_builder/lammps_engine.py b/pyMBE/simulation_builder/lammps_engine.py index b6cc968c..2984ccef 100644 --- a/pyMBE/simulation_builder/lammps_engine.py +++ b/pyMBE/simulation_builder/lammps_engine.py @@ -24,9 +24,10 @@ def __init__(self): pass def __getattr__(self, attr): raise NotImplementedError('Lammps Simulation Engine is not yet implemented') - def _add_angle(self): return + def _check_bond_inputs(self): + return def _create_bond_instance(self): return def _get_bond_instance(self): From bcbbaa448b1378000768b506e8b8caea72326c38 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Fri, 3 Jul 2026 00:01:30 +0200 Subject: [PATCH 72/75] Delete files from titration simulations --- .../time_series/analyzed_data.csv | 6 -- ...Lfraction_0.366_pH_4_pKa_4_time_series.csv | 101 ------------------ ...Lfraction_0.557_pH_6_pKa_4_time_series.csv | 101 ------------------ ...Lfraction_0.303_pH_5_pKa_4_time_series.csv | 101 ------------------ ..._Lfraction_0.51_pH_5_pKa_4_time_series.csv | 101 ------------------ 5 files changed, 410 deletions(-) delete mode 100644 samples/Landsgesell2022/time_series/analyzed_data.csv delete mode 100644 samples/Landsgesell2022/time_series/csalt_0.01_Lfraction_0.366_pH_4_pKa_4_time_series.csv delete mode 100644 samples/Landsgesell2022/time_series/csalt_0.01_Lfraction_0.557_pH_6_pKa_4_time_series.csv delete mode 100644 samples/Landsgesell2022/time_series/csalt_0.05_Lfraction_0.303_pH_5_pKa_4_time_series.csv delete mode 100644 samples/Landsgesell2022/time_series/csalt_0.05_Lfraction_0.51_pH_5_pKa_4_time_series.csv diff --git a/samples/Landsgesell2022/time_series/analyzed_data.csv b/samples/Landsgesell2022/time_series/analyzed_data.csv deleted file mode 100644 index 63f60f57..00000000 --- a/samples/Landsgesell2022/time_series/analyzed_data.csv +++ /dev/null @@ -1,6 +0,0 @@ -csalt,Lfraction,pH,pKa,time,mean,mean,err_mean,err_mean,n_eff,n_eff,tau_int,tau_int -value,value,value,value,value,alpha,pressure,alpha,pressure,alpha,pressure,alpha,pressure -0.05,0.303,5,4,series,0.3130902777777778,0.006637673197545152,0.002348016788745247,0.0013057389029067687,17.500047448881645,90.31837090146261,25.714215994228017,4.982375075174151 -0.01,0.366,4,4,series,0.09690972222222223,0.001441469395807051,0.0013700323136557884,0.0007015271738029402,25.341153861183148,94.24725327642176,17.75767601092228,4.774674957263725 -0.01,0.557,6,4,series,0.40944444444444444,0.0008973248364742591,0.002686687336756199,0.00028626814053342827,17.001784654504764,59.07799341029799,26.46780965377016,7.617049497340954 -0.05,0.51,5,4,series,0.3374652777777778,0.0018863979052295033,0.002469214964174571,0.00024059635451635818,19.06727554652686,93.48485942962414,23.600644932820035,4.813613699110119 diff --git a/samples/Landsgesell2022/time_series/csalt_0.01_Lfraction_0.366_pH_4_pKa_4_time_series.csv b/samples/Landsgesell2022/time_series/csalt_0.01_Lfraction_0.366_pH_4_pKa_4_time_series.csv deleted file mode 100644 index 2e842236..00000000 --- a/samples/Landsgesell2022/time_series/csalt_0.01_Lfraction_0.366_pH_4_pKa_4_time_series.csv +++ /dev/null @@ -1,101 +0,0 @@ -time,alpha,pressure -4977.000000062216,0.090625,0.007298596818290803 -4987.000000062434,0.096875,-0.006066162057896683 -4997.000000062652,0.096875,-0.0029993456649585483 -5007.000000062871,0.09375,-0.011162997567484312 -5017.000000063089,0.1,0.01293812398736898 -5027.000000063307,0.0984375,-0.006051894856802519 -5037.0000000635255,0.1109375,-0.001765460318838193 -5047.000000063744,0.1015625,-0.0009893883701956303 -5057.000000063962,0.096875,0.0015979402025707162 -5067.00000006418,0.10625,0.0007466553290843234 -5077.000000064399,0.1,0.004794223237512022 -5087.000000064617,0.0984375,0.004241926461831794 -5097.000000064835,0.1015625,-0.008202366080594428 -5107.000000065053,0.103125,0.008345479559010396 -5117.000000065272,0.10625,-0.0058258008384603184 -5127.00000006549,0.0953125,0.0007072667408184794 -5137.000000065708,0.0921875,0.0011183638553823958 -5147.0000000659265,0.1078125,-0.003915076519523996 -5157.000000066145,0.1015625,-0.0031989050077965444 -5167.000000066363,0.103125,0.0019481253035433166 -5177.000000066581,0.1015625,-0.015500163927000809 -5187.0000000668,0.0921875,0.011803551686278358 -5197.000000067018,0.0953125,-0.0027557407321090045 -5207.000000067236,0.0890625,0.003285337201455372 -5217.0000000674545,0.0921875,0.0058088488001194405 -5227.000000067673,0.10625,0.005342584201808266 -5237.000000067891,0.0984375,0.0034547366715992054 -5247.000000068109,0.1015625,0.000327779875972272 -5257.000000068328,0.103125,0.002204999011639492 -5267.000000068546,0.103125,0.0032067550910004836 -5277.000000068764,0.1,0.002455368917916059 -5287.000000068982,0.1,-0.0038840227147260878 -5297.000000069201,0.096875,0.004577942078110133 -5307.000000069419,0.0984375,0.011505673538528221 -5317.000000069637,0.0921875,0.0010202208394521027 -5327.000000069856,0.09375,-0.004640448438885074 -5337.000000070074,0.096875,0.0001271164909220631 -5347.000000070292,0.103125,-0.00522511030843317 -5357.00000007051,0.1078125,0.005008166963682322 -5367.000000070729,0.1015625,0.012071109497163161 -5377.000000070947,0.10625,0.014507800821739145 -5387.000000071165,0.109375,-0.01204681711916665 -5397.0000000713835,0.10625,0.004275632773751453 -5407.000000071602,0.1046875,-0.0038676353026881965 -5417.00000007182,0.096875,0.010019996005446737 -5427.000000072038,0.1046875,-0.0019236942533183237 -5437.000000072257,0.09375,0.0013243782009882946 -5447.000000072475,0.1,0.005655784827135663 -5457.000000072693,0.096875,0.0030909174662658713 -5467.0000000729115,0.09375,0.0045785640155599295 -5477.00000007313,0.0984375,0.0010566772196602865 -5487.000000073348,0.0890625,0.002083088825904527 -5497.000000073566,0.0921875,-0.005050485577207009 -5507.000000073785,0.0953125,0.006127146463186975 -5517.000000074003,0.090625,0.003942592687401529 -5527.000000074221,0.090625,-0.005389849273466112 -5537.000000074439,0.096875,-0.004582164044854593 -5547.000000074658,0.0921875,-0.0008746486761736144 -5557.000000074876,0.0828125,-0.007893658444952956 -5567.000000075094,0.08125,0.0039859580064869745 -5577.0000000753125,0.084375,0.006125012890202206 -5587.000000075531,0.0875,-0.00687059267421311 -5597.000000075749,0.0875,0.0029516612247224134 -5607.000000075967,0.0890625,-0.0008450135969176407 -5617.000000076186,0.0859375,5.8010322138158646e-05 -5627.000000076404,0.0921875,0.005509682691983357 -5637.000000076622,0.1046875,-0.0013718345244492565 -5647.0000000768405,0.09375,0.012793031565432674 -5657.000000077059,0.0859375,7.775405745543325e-05 -5667.000000077277,0.0921875,-0.004566809620667924 -5677.000000077495,0.1,-0.006600931741901173 -5687.000000077714,0.103125,0.019546635957261662 -5697.000000077932,0.096875,0.0135289713867134 -5707.00000007815,0.1,0.005491030539945144 -5717.000000078368,0.090625,0.007463639095545582 -5727.000000078587,0.084375,-0.006433400476846697 -5737.000000078805,0.0859375,-0.001680232945786643 -5747.000000079023,0.0859375,0.002621531149280668 -5757.0000000792415,0.0890625,-0.0006063492574107833 -5767.00000007946,0.0859375,-0.011087742084978168 -5777.000000079678,0.0875,-0.0023919430175641777 -5787.000000079896,0.1,0.0018199208060117238 -5797.000000080115,0.1046875,0.010322597888276767 -5807.000000080333,0.109375,0.0011026104435534207 -5817.000000080551,0.1,0.008507325881111956 -5827.0000000807695,0.096875,-0.00034799852696410817 -5837.000000080988,0.0953125,0.0035011182276818453 -5847.000000081206,0.09375,0.00431882516647842 -5857.000000081424,0.1,-0.011847547531173848 -5867.000000081643,0.10625,-0.004969443923626165 -5877.000000081861,0.1109375,-0.003107740773928227 -5887.000000082079,0.1046875,0.012924554326465365 -5897.000000082297,0.1015625,-0.004848074735727097 -5907.000000082516,0.09375,0.014380415269018154 -5917.000000082734,0.096875,-0.011353035433259807 -5927.000000082952,0.096875,-0.009318143020031864 -5937.000000083171,0.103125,0.013227677947344673 -5947.000000083389,0.0984375,0.00255448301462788 -5957.000000083607,0.0984375,0.004365789168266012 -5967.000000083825,0.09375,0.005559274410649666 diff --git a/samples/Landsgesell2022/time_series/csalt_0.01_Lfraction_0.557_pH_6_pKa_4_time_series.csv b/samples/Landsgesell2022/time_series/csalt_0.01_Lfraction_0.557_pH_6_pKa_4_time_series.csv deleted file mode 100644 index 290a0354..00000000 --- a/samples/Landsgesell2022/time_series/csalt_0.01_Lfraction_0.557_pH_6_pKa_4_time_series.csv +++ /dev/null @@ -1,101 +0,0 @@ -time,alpha,pressure -4082.0000000426803,0.3921875,0.00036499039922930883 -4092.0000000428986,0.3953125,8.975779910861546e-05 -4102.000000043116,0.396875,0.0010055773366355572 -4112.000000043335,0.3890625,-0.0007715054700716869 -4122.000000043553,0.4,0.0022068316690098603 -4132.000000043771,0.3953125,-0.00027404684533329074 -4142.0000000439895,0.3890625,0.0038149090885986766 -4152.000000044208,0.3859375,0.004083517197976683 -4162.000000044426,0.39375,-0.00031514263751571044 -4172.000000044644,0.396875,0.0038428126740801746 -4182.000000044863,0.4140625,0.002295048194401955 -4192.000000045081,0.4078125,0.005078253970089698 -4202.000000045299,0.409375,0.0005379446158911607 -4212.0000000455175,0.40625,0.00024285745682037075 -4222.000000045736,0.4109375,-0.0005489343817979694 -4232.000000045954,0.403125,0.0008397356128196125 -4242.000000046172,0.40625,0.0009201663537082064 -4252.000000046391,0.4046875,-0.00010794922356432153 -4262.000000046609,0.3984375,0.0008260050674024056 -4272.000000046827,0.396875,-0.0010016599501987498 -4282.000000047045,0.3921875,0.0037744757257149107 -4292.000000047264,0.3984375,0.0022381752319531978 -4302.000000047482,0.403125,-0.0005404661785675507 -4312.0000000477,0.3984375,0.0019567021348493043 -4322.000000047919,0.4078125,0.0038235590241885646 -4332.000000048137,0.40625,-0.0009551330907727352 -4342.000000048355,0.4125,-0.00039836221176166986 -4352.000000048573,0.4046875,-0.0021133834192513493 -4362.000000048792,0.409375,-0.0012468615165295864 -4372.00000004901,0.415625,-0.0015427437847578193 -4382.000000049228,0.4109375,0.0013417683008758322 -4392.0000000494465,0.4125,0.0017053975357111649 -4402.000000049665,0.409375,0.0030148047876002843 -4412.000000049883,0.40625,-0.00270723941114844 -4422.000000050101,0.4015625,0.006078028581797966 -4432.00000005032,0.3984375,0.002275925515133006 -4442.000000050538,0.3875,0.0020337096126363534 -4452.000000050756,0.3875,0.001652823981434018 -4462.000000050974,0.390625,-0.0018523064752998739 -4472.000000051193,0.3828125,-0.0012821177788007747 -4482.000000051411,0.3890625,0.0033761126888831854 -4492.000000051629,0.384375,0.0026795780087570304 -4502.000000051848,0.3921875,0.0042517381329556375 -4512.000000052066,0.3875,0.004281254409079208 -4522.000000052284,0.3890625,0.0035150735736647256 -4532.000000052502,0.4015625,0.0004952259103612795 -4542.000000052721,0.4,0.00279333599561581 -4552.000000052939,0.3953125,-0.0015716807689500787 -4562.000000053157,0.4046875,0.0021942090985900067 -4572.0000000533755,0.4,0.0027298238255471104 -4582.000000053594,0.4,0.0007487899088797675 -4592.000000053812,0.40625,0.003240796283508576 -4602.00000005403,0.4140625,-0.001026754904132663 -4612.000000054249,0.409375,0.003913789269131982 -4622.000000054467,0.409375,0.0017390190902873987 -4632.000000054685,0.40625,0.003389106715033901 -4642.0000000549035,0.403125,0.002577307680653623 -4652.000000055122,0.4046875,-0.0021169435311988384 -4662.00000005534,0.4078125,0.002793546071384313 -4672.000000055558,0.4078125,-0.0021410346467737626 -4682.000000055777,0.415625,0.0016358654144971341 -4692.000000055995,0.4171875,0.001841379329859525 -4702.000000056213,0.4109375,0.00020203919973331495 -4712.000000056431,0.4265625,0.0012460490849767693 -4722.00000005665,0.4234375,0.0017307700875192303 -4732.000000056868,0.4296875,-0.0014226227654321629 -4742.000000057086,0.4296875,0.001285856416274927 -4752.0000000573045,0.4265625,-0.00023221444410965585 -4762.000000057523,0.4171875,0.002027995257783206 -4772.000000057741,0.41875,0.00199168188908604 -4782.000000057959,0.415625,0.002651702462944648 -4792.000000058178,0.4234375,0.0009439421439512492 -4802.000000058396,0.41875,0.002341744791181546 -4812.000000058614,0.4203125,0.003451878472839611 -4822.0000000588325,0.41875,-0.0010234162003669187 -4832.000000059051,0.4203125,-0.0007776730822806373 -4842.000000059269,0.4109375,0.0007165328856179685 -4852.000000059487,0.4125,-0.002546639058536727 -4862.000000059706,0.421875,0.0008722695075175038 -4872.000000059924,0.41875,-0.00042043966744822743 -4882.000000060142,0.415625,-0.00330648696701416 -4892.00000006036,0.4234375,0.0009414815580792917 -4902.000000060579,0.4125,-0.006169263831269538 -4912.000000060797,0.41875,-0.001700417830375587 -4922.000000061015,0.415625,0.0027615962624003513 -4932.000000061234,0.4203125,0.0018433387774753436 -4942.000000061452,0.421875,0.002484782348788227 -4952.00000006167,0.4203125,0.002555373496495365 -4962.000000061888,0.41875,-0.00333011949604362 -4972.000000062107,0.425,0.004069055665510145 -4982.000000062325,0.425,-0.00037257808172680857 -4992.000000062543,0.421875,-0.0002404356532255738 -5002.0000000627615,0.41875,7.650438935894058e-05 -5012.00000006298,0.4234375,0.0011598445520450893 -5022.000000063198,0.421875,-0.0040981157978188945 -5032.000000063416,0.4140625,0.0011824036594570585 -5042.000000063635,0.4109375,-0.0009128256914903895 -5052.000000063853,0.409375,0.0018052077977814675 -5062.000000064071,0.403125,-0.0007615639302759686 -5072.000000064289,0.40625,0.0020542352370697225 diff --git a/samples/Landsgesell2022/time_series/csalt_0.05_Lfraction_0.303_pH_5_pKa_4_time_series.csv b/samples/Landsgesell2022/time_series/csalt_0.05_Lfraction_0.303_pH_5_pKa_4_time_series.csv deleted file mode 100644 index 95ba686b..00000000 --- a/samples/Landsgesell2022/time_series/csalt_0.05_Lfraction_0.303_pH_5_pKa_4_time_series.csv +++ /dev/null @@ -1,101 +0,0 @@ -time,alpha,pressure -5277.000000068764,0.3046875,-0.00525602049939856 -5287.000000068982,0.30625,0.011121494906860159 -5297.000000069201,0.309375,0.008174206795178678 -5307.000000069419,0.30625,-0.000797768585701541 -5317.000000069637,0.3109375,0.021921773713701038 -5327.000000069856,0.309375,0.02127582564284194 -5337.000000070074,0.3,-0.0005388735487219203 -5347.000000070292,0.3,0.0033853197067596433 -5357.00000007051,0.303125,0.012843467362114292 -5367.000000070729,0.3046875,0.010987477426987689 -5377.000000070947,0.3109375,0.027787335109421687 -5387.000000071165,0.3078125,1.6786562582514833e-05 -5397.0000000713835,0.3109375,0.028954262297802735 -5407.000000071602,0.3140625,0.012132399739407038 -5417.00000007182,0.3171875,0.004075652494757091 -5427.000000072038,0.3125,0.014639854262636842 -5437.000000072257,0.3125,0.006857696667907971 -5447.000000072475,0.303125,-0.011524013334012253 -5457.000000072693,0.3125,0.017098606679452455 -5467.0000000729115,0.3109375,0.004280494854826324 -5477.00000007313,0.3125,0.0034997417254259908 -5487.000000073348,0.3125,0.03165750274759563 -5497.000000073566,0.3015625,0.010295262845157345 -5507.000000073785,0.29375,0.009230031118647378 -5517.000000074003,0.2984375,0.015375237303064485 -5527.000000074221,0.284375,0.008151754139703626 -5537.000000074439,0.2921875,-0.01785722168507675 -5547.000000074658,0.3,0.010511369511764517 -5557.000000074876,0.303125,-0.017320359317595253 -5567.000000075094,0.315625,0.025334956785596625 -5577.0000000753125,0.315625,0.03841059560426624 -5587.000000075531,0.321875,-0.009763745338235113 -5597.000000075749,0.321875,0.018930760346552764 -5607.000000075967,0.3265625,0.02580411489431204 -5617.000000076186,0.3265625,0.010246947994203955 -5627.000000076404,0.315625,0.006807820394994242 -5637.000000076622,0.3140625,0.019177499990728347 -5647.0000000768405,0.3140625,0.019555620008108874 -5657.000000077059,0.309375,0.009666503971831213 -5667.000000077277,0.3078125,-0.0019718827839153726 -5677.000000077495,0.30625,0.0010047638618087505 -5687.000000077714,0.3046875,-0.021982679509196214 -5697.000000077932,0.3140625,0.011786026473541685 -5707.00000007815,0.3125,0.012767758428125971 -5717.000000078368,0.309375,0.010419379527526853 -5727.000000078587,0.3078125,-0.0033552022286734047 -5737.000000078805,0.3109375,0.0166805737930335 -5747.000000079023,0.303125,0.01887441054716652 -5757.0000000792415,0.303125,-0.002565214448872702 -5767.00000007946,0.3,0.01990372058188579 -5777.000000079678,0.30625,0.004708031717746801 -5787.000000079896,0.30625,-0.011984568362775264 -5797.000000080115,0.303125,0.01576818989755958 -5807.000000080333,0.303125,-0.00790555661921247 -5817.000000080551,0.2984375,-0.0001334700355421352 -5827.0000000807695,0.2953125,-0.003847025711096349 -5837.000000080988,0.29375,0.014728176426108136 -5847.000000081206,0.3,-0.005128123777579772 -5857.000000081424,0.3046875,0.021572931395397493 -5867.000000081643,0.3015625,-0.009267635938509945 -5877.000000081861,0.309375,0.004355899415920146 -5887.000000082079,0.3140625,0.012270714772339368 -5897.000000082297,0.3109375,0.0052253722842176146 -5907.000000082516,0.309375,0.01065547683298493 -5917.000000082734,0.3140625,0.014468038129548664 -5927.000000082952,0.30625,-0.006063194879796736 -5937.000000083171,0.31875,-0.003563922951325347 -5947.000000083389,0.321875,0.009750528334802477 -5957.000000083607,0.3203125,-0.006040739540940765 -5967.000000083825,0.3171875,-0.0046372580690026 -5977.000000084044,0.309375,0.015250888726299608 -5987.000000084262,0.3171875,0.002295311878945728 -5997.00000008448,0.3125,0.0063310230747670735 -6007.0000000846985,0.3171875,-0.020658240115409978 -6017.000000084917,0.315625,-0.0002894241173200876 -6027.000000085135,0.3203125,0.011162091258089868 -6037.000000085353,0.31875,-0.01463174588686673 -6047.000000085572,0.3140625,0.0022683857782851056 -6057.00000008579,0.321875,-0.0039562682767511695 -6067.000000086008,0.321875,0.015593198392859497 -6077.0000000862265,0.325,0.00803976513064207 -6087.000000086445,0.3234375,0.009216590019220441 -6097.000000086663,0.3140625,0.019747145662176186 -6107.000000086881,0.31875,0.03661114535129495 -6117.0000000871,0.321875,0.00812025513121504 -6127.000000087318,0.321875,-0.009530487585460504 -6137.000000087536,0.325,0.0001277299569873294 -6147.000000087754,0.3296875,0.021491965549969117 -6157.000000087973,0.3265625,0.0008374358688529966 -6167.000000088191,0.3296875,0.004307883794832469 -6177.000000088409,0.325,-0.004702823953360071 -6187.0000000886275,0.3171875,0.0013038470724201303 -6197.000000088846,0.31875,0.010352469437553023 -6207.000000089064,0.3203125,0.023765564283934046 -6217.000000089282,0.3234375,-0.0021930126804463965 -6227.000000089501,0.3234375,0.008906912770784191 -6237.000000089719,0.3296875,0.0016534844888732392 -6247.000000089937,0.33125,0.006805810996978819 -6257.0000000901555,0.3234375,0.007783828251230674 -6267.000000090374,0.334375,-0.007147128420634772 diff --git a/samples/Landsgesell2022/time_series/csalt_0.05_Lfraction_0.51_pH_5_pKa_4_time_series.csv b/samples/Landsgesell2022/time_series/csalt_0.05_Lfraction_0.51_pH_5_pKa_4_time_series.csv deleted file mode 100644 index ffd27e54..00000000 --- a/samples/Landsgesell2022/time_series/csalt_0.05_Lfraction_0.51_pH_5_pKa_4_time_series.csv +++ /dev/null @@ -1,101 +0,0 @@ -time,alpha,pressure -4307.000000047591,0.334375,0.007295379117841711 -4317.000000047809,0.31875,0.0024741150086576816 -4327.000000048028,0.3125,-0.0001349766957618122 -4337.000000048246,0.315625,0.006489525556953459 -4347.000000048464,0.325,0.0026029493258455105 -4357.0000000486825,0.3234375,0.002771205767589858 -4367.000000048901,0.334375,-0.0023479847518030816 -4377.000000049119,0.3453125,-0.00014976506257215034 -4387.000000049337,0.346875,0.0005307378686189346 -4397.000000049556,0.3390625,0.0030026599366683535 -4407.000000049774,0.34375,0.0045147370945092915 -4417.000000049992,0.346875,0.004855490017274356 -4427.0000000502105,0.3390625,0.00017312959759600995 -4437.000000050429,0.33125,0.0010438694922435146 -4447.000000050647,0.3328125,-0.0016545418127208323 -4457.000000050865,0.334375,0.0020358084942147955 -4467.000000051084,0.334375,0.007003699446159239 -4477.000000051302,0.334375,0.0006872312193505157 -4487.00000005152,0.3296875,0.00716836702098914 -4497.000000051738,0.3171875,0.00570291013976616 -4507.000000051957,0.321875,-0.00046307874239099575 -4517.000000052175,0.33125,-0.00045315223571652623 -4527.000000052393,0.3375,0.001726007534394617 -4537.0000000526115,0.328125,-0.0005228050607182867 -4547.00000005283,0.3296875,0.005428000568497918 -4557.000000053048,0.340625,0.001023994788816869 -4567.000000053266,0.334375,0.0030087437630384995 -4577.000000053485,0.33125,0.0012014294848683596 -4587.000000053703,0.334375,0.0002851605432010945 -4597.000000053921,0.3359375,0.002292324611379094 -4607.0000000541395,0.3296875,0.002934686900233493 -4617.000000054358,0.3265625,0.0003788334062213324 -4627.000000054576,0.31875,0.004472918820112234 -4637.000000054794,0.334375,0.002667056684959741 -4647.000000055013,0.3328125,0.0008274935831574509 -4657.000000055231,0.3328125,0.005518542415398456 -4667.000000055449,0.3359375,0.003827070944783175 -4677.000000055667,0.3265625,0.0011991423888822017 -4687.000000055886,0.3234375,0.002680204760694091 -4697.000000056104,0.321875,0.0019455650671982158 -4707.000000056322,0.3125,0.0013823397542306437 -4717.000000056541,0.325,0.0008333857958227315 -4727.000000056759,0.3203125,0.002655082037080553 -4737.000000056977,0.325,-0.0034109607449900555 -4747.000000057195,0.328125,0.0008881753998886049 -4757.000000057414,0.328125,0.0025642989235529563 -4767.000000057632,0.328125,0.006456678275483456 -4777.00000005785,0.325,0.0020866475194106 -4787.0000000580685,0.3203125,0.007387601119542534 -4797.000000058287,0.325,-6.947113587710476e-05 -4807.000000058505,0.321875,0.004612416748054225 -4817.000000058723,0.31875,0.002808570997889602 -4827.000000058942,0.3265625,0.0016899912223727516 -4837.00000005916,0.3390625,-0.0003034299791002461 -4847.000000059378,0.34375,0.002656120538925814 -4857.0000000595965,0.353125,0.002730461941785284 -4867.000000059815,0.353125,0.002209603970293915 -4877.000000060033,0.35625,0.00042501235693333483 -4887.000000060251,0.35,-0.0013040895753778754 -4897.00000006047,0.3390625,-0.0004369041668293343 -4907.000000060688,0.3421875,0.002437538786254292 -4917.000000060906,0.3390625,0.0006544250520181524 -4927.000000061124,0.3296875,0.0036071081068100603 -4937.000000061343,0.3296875,0.0005685672910608655 -4947.000000061561,0.33125,0.0007682451204520665 -4957.000000061779,0.34375,-0.0021749117494678353 -4967.0000000619975,0.3375,0.0008770112460226891 -4977.000000062216,0.3359375,0.0011141433953479596 -4987.000000062434,0.340625,0.0027987880364485174 -4997.000000062652,0.34375,0.0005646310561778439 -5007.000000062871,0.3421875,0.0033101786033502517 -5017.000000063089,0.346875,0.004561222994358272 -5027.000000063307,0.35,0.00012991585823010033 -5037.0000000635255,0.3453125,0.0017898959648241714 -5047.000000063744,0.346875,0.002586003745628818 -5057.000000063962,0.3421875,-0.0006811161943429777 -5067.00000006418,0.340625,-0.001382007238706989 -5077.000000064399,0.33125,0.007081072376181341 -5087.000000064617,0.334375,0.004459376325592985 -5097.000000064835,0.346875,0.0013808755737096806 -5107.000000065053,0.3421875,-0.0007150728563269929 -5117.000000065272,0.3484375,-0.0022713586224796405 -5127.00000006549,0.35625,0.003439844338875147 -5137.000000065708,0.3421875,0.0013376032449136236 -5147.0000000659265,0.3484375,0.0035713153607207903 -5157.000000066145,0.340625,0.001197897665585768 -5167.000000066363,0.3375,0.0027995219727905 -5177.000000066581,0.340625,0.001620918478132281 -5187.0000000668,0.35,-0.0014653182956971187 -5197.000000067018,0.35,0.00011811783857307847 -5207.000000067236,0.353125,-0.0001493417849880627 -5217.0000000674545,0.3515625,0.006010853779104497 -5227.000000067673,0.35625,0.0019356838178235282 -5237.000000067891,0.35,0.0048513485609838316 -5247.000000068109,0.3484375,-0.0007992211439831735 -5257.000000068328,0.3546875,0.0005822763795813079 -5267.000000068546,0.353125,0.004337316254469169 -5277.000000068764,0.35625,-0.001398564476115319 -5287.000000068982,0.3515625,0.0026483058891762466 -5297.000000069201,0.35,0.000302348784082541 From 0663deeb26d6689a4e5abf94edf613517ce4f8b1 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Fri, 3 Jul 2026 19:35:48 +0200 Subject: [PATCH 73/75] Modify EspressoSystemProtocol into version 4.2.2 and EspressoSystem5.0.1 (which is compatible with EspressoSystem5.0.0 version) --- pyMBE/pyMBE.py | 4 ++-- pyMBE/simulation_builder/engine_protocol.py | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/pyMBE/pyMBE.py b/pyMBE/pyMBE.py index fd5d5829..2788d90a 100644 --- a/pyMBE/pyMBE.py +++ b/pyMBE/pyMBE.py @@ -51,7 +51,7 @@ from pyMBE.simulation_builder.espresso_engine import EspressoSimulation from pyMBE.simulation_builder.lammps_engine import LammpsSimulation from pyMBE.simulation_builder.base_engine import DummyEngine -from pyMBE.simulation_builder.engine_protocol import EspressoSystemProtocol,LammpsProtocol +from pyMBE.simulation_builder.engine_protocol import EspressoSystemProtocolversion422,EspressoSystemProtocolversion501,LammpsProtocol ## Reactions from pyMBE.storage.reactions.reaction import Reaction, ReactionParticipant # Utilities @@ -2768,7 +2768,7 @@ def set_simulation_engine(self,simulation_engine,box_l=None): Raises: ValueError: _description_ """ - if isinstance(simulation_engine,EspressoSystemProtocol): + if isinstance(simulation_engine,EspressoSystemProtocolversion422) or isinstance(simulation_engine,EspressoSystemProtocolversion501): self.simulation_engine=EspressoSimulation(box_l=simulation_engine.box_l, db=self.db, espresso_system=simulation_engine, diff --git a/pyMBE/simulation_builder/engine_protocol.py b/pyMBE/simulation_builder/engine_protocol.py index 8308cf97..2efa40b8 100644 --- a/pyMBE/simulation_builder/engine_protocol.py +++ b/pyMBE/simulation_builder/engine_protocol.py @@ -30,12 +30,28 @@ def add(): return @runtime_checkable -class EspressoSystemProtocol(Protocol): +class EspressoSystemProtocolversion422(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 EspressoSystemProtocolversion501(Protocol): + def change_volume_and_rescale_particles(self, d_new, dir="xyz"): + return + def volume(self): + return + def distance(self, p1, p2): + return + def distance_vec(self, p1, p2): + return + def velocity_difference(self, p1, p2): + return + def auto_exclusions(self, distance): + pass + @runtime_checkable class LammpsProtocol(Protocol): """ Class that emulates the structure of the methods employed by Pymbe from the Lammps class From 215a88107ec28335bc1cfd9ee283f485f112d0c8 Mon Sep 17 00:00:00 2001 From: jsd94 Date: Fri, 3 Jul 2026 20:06:22 +0200 Subject: [PATCH 74/75] Update info from Authors.md --- AUTHORS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS.md b/AUTHORS.md index 06da0f84..e6860353 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -12,7 +12,7 @@ The following people have contributed to pyMBE (Github username, Name, current a - paobtorres, Paola B. Torres (Universidad Tecnológica Nacional, Argentina) - pinedaps, Sebastian P. Pineda (University of Lund, Sweden) - 1234somesh, Somesh Kurahatti (University of Stuttgart, Germany) -- jorch28, Jordi Sans Figuero (Freelance, Spain) +- jorch28, Jordi Sans-Duñó (Freelance,Figaró, Spain) ## Tier-1 Contributors - TommyTraan, Duy Tommy Tran (Norwegian University of Science and Technology, Norway) From fec7a8e34daa7e61a43873b0af870173d93822ba Mon Sep 17 00:00:00 2001 From: jsd94 Date: Fri, 3 Jul 2026 20:06:53 +0200 Subject: [PATCH 75/75] remove cells created to trial functions --- tutorials/pyMBE_tutorial.ipynb | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/tutorials/pyMBE_tutorial.ipynb b/tutorials/pyMBE_tutorial.ipynb index e365f02b..5ca47d3f 100644 --- a/tutorials/pyMBE_tutorial.ipynb +++ b/tutorials/pyMBE_tutorial.ipynb @@ -100,36 +100,6 @@ "This default definition of reduced units can be changed at the convience of the user using the following command:" ] }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING:pint.util:Redefining 'reduced_energy' ()\n", - "WARNING:pint.util:Redefining 'reduced_length' ()\n", - "WARNING:pint.util:Redefining 'reduced_charge' ()\n" - ] - } - ], - "source": [ - "pmb.set_reduced_units(unit_length = 0.5*pmb.units.nm, \n", - " unit_charge = 5*pmb.units.e)\n", - " #, temperature=300*pmb.units.K)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(pmb.units.get_group())" - ] - }, { "cell_type": "code", "execution_count": 4,