Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update molecule mapping #475

Merged
merged 84 commits into from
Jan 31, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
aebc211
Adapt molecule mapper to take arbitrary dict with non-regular species…
SamTov Jan 21, 2022
6050087
Update tqdm descriptions and run black + isort.
SamTov Jan 21, 2022
461d072
add tensor cutoff test for molecule mapping.
SamTov Jan 21, 2022
562e809
add smiles string tests for various molecules.
SamTov Jan 21, 2022
b94b4b8
Merge branch 'main' into SamTov_Molecule_Mapping
SamTov Jan 21, 2022
03ca751
Fix issues in ADF calculator and transformations.py
SamTov Jan 21, 2022
bf0b6ef
change minibatch default to avoid issue with minibatching in adf.
SamTov Jan 21, 2022
58cbd3c
run black and isort
SamTov Jan 21, 2022
ae58bf1
run black and isort
SamTov Jan 21, 2022
7146614
add comprehensive molecule mapping tests and update ADF to work with …
SamTov Jan 21, 2022
5f6ba4d
fix flake8 problem
SamTov Jan 21, 2022
866fc63
more flake8 fixes.
SamTov Jan 21, 2022
2ba8de5
update loading bars lengths in file readers and add mapping notebook.
SamTov Jan 22, 2022
b4b47f5
Update RDF and ADF to work with atom selection, issues still with RDF.
SamTov Jan 22, 2022
04f9205
run black and isort
SamTov Jan 22, 2022
c6017c6
Fix indexing error in molecule mapping and update tests
SamTov Jan 23, 2022
baace8e
update tests to enforce no molecules in species dict and run formatters.
SamTov Jan 23, 2022
2132e92
set remainder to True for any operation if a remainder exists. Move m…
SamTov Jan 23, 2022
0385007
Merge branch 'main' into SamTov_Molecule_Mapping
SamTov Jan 24, 2022
346a9cc
more small updates
SamTov Jan 24, 2022
c9f7b2c
Merge remote-tracking branch 'origin/SamTov_Molecule_Mapping' into Sa…
SamTov Jan 24, 2022
ad9a237
Merge branch 'main' into SamTov_Molecule_Mapping
SamTov Jan 24, 2022
d799194
Fix ensemble loop generator such that it correclty computes the remai…
SamTov Jan 25, 2022
8d92f09
Merge remote-tracking branch 'origin/SamTov_Molecule_Mapping' into Sa…
SamTov Jan 25, 2022
f46a495
fix critical bug in ensemble generator which renders system propertie…
SamTov Jan 25, 2022
baac20b
run black and isort
SamTov Jan 25, 2022
34eec7b
Fix persistent bug in RDF and ADF computations.
SamTov Jan 25, 2022
829994e
run black and isort
SamTov Jan 25, 2022
230ce9f
Merge branch 'main' into SamTov_Molecule_Mapping
SamTov Jan 25, 2022
368d7f8
move all graph related operations into graph module and trim molecula…
SamTov Jan 26, 2022
c823a3b
run black and isort
SamTov Jan 26, 2022
237c23c
update tests to run with new API.
SamTov Jan 26, 2022
b49f110
update molecular mapping example and fix small bugs.
SamTov Jan 26, 2022
716ac30
run black and isort
SamTov Jan 26, 2022
7876121
fix flake8 complaint
SamTov Jan 26, 2022
3de95d5
Fix issues with mapper.
SamTov Jan 26, 2022
ec1f25d
add data class for test case.
SamTov Jan 27, 2022
7c4edb7
fix flake8 complaint
SamTov Jan 27, 2022
975b4b0
add numbers to smiles string.
SamTov Jan 27, 2022
3f70ce2
update RDF doc string.
SamTov Jan 27, 2022
c7fb82a
fix remainder decleration and naming.
SamTov Jan 27, 2022
a0330c4
implement molecule data class and move bmim test to integration test.
SamTov Jan 27, 2022
f48b573
run black and isort
SamTov Jan 27, 2022
675ce61
add test for molecule class.
SamTov Jan 27, 2022
dd677ab
run black and isort
SamTov Jan 27, 2022
6463235
remove assigning of unused variables to make flake happy
SamTov Jan 27, 2022
bfe6536
remove indices from molecules.
SamTov Jan 27, 2022
13017c0
Add data to functional test and allow ADF to return max value angle.
SamTov Jan 27, 2022
6636fa0
resolve flake8 complaints
SamTov Jan 27, 2022
f855102
adjust add_experiment test to work again.
SamTov Jan 27, 2022
7dd2729
Start new functional test on proper data and add example.
SamTov Jan 28, 2022
d6273e3
get tests running and remove exclamation marks from comments. Please …
SamTov Jan 28, 2022
f3de358
add mol_pbc argument to molecules and update tests.
SamTov Jan 28, 2022
6a64769
run black and isort
SamTov Jan 28, 2022
119c7c6
resolve flake8 issues
SamTov Jan 28, 2022
f4a722f
Merge branch 'main' into SamTov_Molecule_Mapping
PythonFZ Jan 28, 2022
acd12d0
Remove unused variable
SamTov Jan 28, 2022
94fd6e1
remove old data manager code.
SamTov Jan 31, 2022
854fca7
Add pytest fixture
SamTov Jan 31, 2022
ee80299
move if statement to isinstance
SamTov Jan 31, 2022
a3af13d
Move to mdsuite properties
SamTov Jan 31, 2022
548ff32
shorten mass computation.
SamTov Jan 31, 2022
7052eed
move function out of class method
SamTov Jan 31, 2022
5a142bc
adapt reshape call
SamTov Jan 31, 2022
fc52e12
remove return statement.
SamTov Jan 31, 2022
abdb92b
Change pass to exception raise.
SamTov Jan 31, 2022
559a9bf
remove assert statement.
SamTov Jan 31, 2022
b04555b
remove redundant 0 instantiation.
SamTov Jan 31, 2022
b8ec7bc
update properties
SamTov Jan 31, 2022
24dc27a
adapt get mass array method.
SamTov Jan 31, 2022
98b8619
change build to get
SamTov Jan 31, 2022
413096d
split one-liner into two liner
SamTov Jan 31, 2022
42b89f1
adapt frame rate
SamTov Jan 31, 2022
556e75f
assert almost equal on water mass
SamTov Jan 31, 2022
84b4e87
convert strings to dunders
SamTov Jan 31, 2022
9992849
remove old code.
SamTov Jan 31, 2022
836ea79
add test for BMIM, update example.
SamTov Jan 31, 2022
b903601
add unit test for shifted function.
SamTov Jan 31, 2022
7cac760
change name to highlight idx
SamTov Jan 31, 2022
b8747e9
fix ambiguous loop
SamTov Jan 31, 2022
03b932f
Move loop to cumsum
SamTov Jan 31, 2022
85d3ae8
Fix final review comments
SamTov Jan 31, 2022
fb8ee66
adjust slice for speed
SamTov Jan 31, 2022
f73025f
fix false argument in test
SamTov Jan 31, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions mdsuite/graph_modules/molecular_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def __init__(
from_smiles: bool = False,
from_configuration: bool = True,
smiles_string: str = None,
reference_dict: dict = None,
species: list = None,
):
"""
Expand All @@ -65,7 +66,17 @@ def __init__(
from_configuration : bool
Build graphs from a configuration.
smiles_string : str
SMILES string to read
SMILES string to read and used in the construction of a reference
graph with molecule information.
reference_dict : dict
Alternatively to the SMILES string a reference dict can be given to
construct a reference molecule. This dict should be of the form:

.. code-block: python

{'PF6': {'P': 1, 'F': 6}}}

for a PF6 molecule.
species : list
List of species to build a graph with.
"""
Expand All @@ -74,6 +85,7 @@ def __init__(
self.from_configuration = from_configuration

self.smiles_string = smiles_string
self.reference_dict = reference_dict
self.species = species

self.database = Database(self.experiment.database_path / "database.hdf5")
Expand Down Expand Up @@ -101,18 +113,11 @@ def get_neighbour_list(positions: tf.Tensor, cell: list = None) -> tf.Tensor:
If periodic boundary conditions are used, please supply the cell
dimensions, e.g. [13.97, 13.97, 13.97]. If the cell is provided
minimum image convention will be applied!
batch_size: int
Has to be evenly divisible by the the number of configurations.

Returns
-------
generator object which results all distances for the current batch of
time steps

To get the real r_ij matrix for one time_step you can use the following:
r_ij_mat = np.zeros((n_atoms, n_atoms, 3))
r_ij_mat[np.triu_indices(n_atoms, k = 1)] = get_neighbour_list(``*args``)
r_ij_mat -= r_ij_mat.transpose(1, 0, 2)
neighbour_list : tf.Tensor
Neighbour list for a single configuration.

"""
r_ij_matrix = tf.reshape(positions, (1, len(positions), 3)) - tf.reshape(
Expand Down Expand Up @@ -163,8 +168,9 @@ def build_configuration_graph(self, cutoff: float, adjacency: bool = True):
Parameters
----------
cutoff : float
Cutoff over which to look for molecules.
adjacency : bool
If true, the adjacent matrix is returned.
If true, the adjacency matrix is returned.
Returns
-------

Expand Down Expand Up @@ -252,9 +258,9 @@ def check_a_in_b(a, b):
else:
if len(molecules) != n_molecules:
raise ValueError(
"Expected number of molecules does not "
"match the amount computed, please adjust"
"parameters."
f"Expected number of molecules ({n_molecules}) does not "
f"match the amount computed ({len(molecules)}), please adjust "
f"parameters."
)
else:
return molecules
90 changes: 65 additions & 25 deletions mdsuite/transformations/map_molecules.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
from mdsuite.transformations.transformations import Transformations
from mdsuite.utils.meta_functions import join_path

import logging

log = logging.getLogger(__name__)


switcher_transformations = {
"Translational_Dipole_Moment": "TranslationalDipoleMoment",
"Ionic_Current": "IonicCurrent",
Expand All @@ -53,8 +58,6 @@ class MolecularMap(Transformations):
scale_function : dict
A dictionary referencing the memory/time scaling function of the
transformation.
experiment : object
Experiment object to work within.
molecules : dict
Molecule dictionary to use as reference. e.g.

Expand All @@ -67,19 +70,8 @@ class MolecularMap(Transformations):
"""

def __init__(self):
"""Constructor for the MolecularMap class.

Parameters
----------
molecules : dict
Molecule dictionary to use as reference. e.g, the input for
emim-PF6 ionic liquid would be.

.. code-block::

{'emim': {'smiles': 'CCN1C=C[N+](+C1)C', 'amount': 20},
'PF6': {'smiles': 'F[P-](F)(F)(F)(F)F', 'amount': 20}}

"""
Constructor for the MolecularMap class.
"""
super().__init__()
self.molecules = None
Expand All @@ -88,9 +80,16 @@ def __init__(self):
self.dependency = "Unwrapped_Positions"
self.scale_function = {"quadratic": {"outer_scale_factor": 5}}

def _prepare_database_entry(self, species, number_of_molecules: int) -> dict:
def _prepare_database_entry(self, species: str, number_of_molecules: int) -> dict:
"""
Call some housekeeping methods and prepare for the transformations.

Parameters
----------
species
Name of the species to be added
number_of_molecules : int
Number of molecules to be added to the database.
Returns
-------
data_structure : dict
Expand Down Expand Up @@ -240,20 +239,38 @@ def _update_species_type_dict(

def _build_reference_graphs(self):
"""
Build the reference graphs from the SMILES strings.
Build the reference graphs from the reference input.
.
Returns
-------
Nothing.
Updates the reference molecules attribute of the class. It should be populated
after this call and look something like:

{'bmim': {'species': ['C', 'H', 'N'], 'mass': 200, 'graph': tf.Tensor}}

If a dict is used as a reference, the graph will not exist and stronger
isomorphism checks will not be possible.
"""
for item in self.molecules:
self.reference_molecules[item] = {}
mol, species = MolecularGraph(
self.experiment,
from_smiles=True,
smiles_string=self.molecules[item]["smiles"],
).build_smiles_graph()
if 'smiles' in self.molecules[item]:
mol, species = MolecularGraph(
self.experiment,
from_smiles=True,
smiles_string=self.molecules[item]["smiles"],
).build_smiles_graph()
self.reference_molecules[item]["graph"] = mol
elif 'reference' in self.molecules[item]:
species = self.molecules[item]['reference']
else:
error_msg = "The minimum amount of data was not given to the mapping." \
"Either provide a reference key with information about" \
"Which species and the number of them are in the molecule," \
"or provide a SMILES string that can be used to compute " \
"this information."
log.info(error_msg)
raise ValueError("Provide either a reference key or smiles string")
SamTov marked this conversation as resolved.
Show resolved Hide resolved
self.reference_molecules[item]["species"] = list(species)
self.reference_molecules[item]["graph"] = mol
self.reference_molecules[item]["mass"] = self._get_molecular_mass(species)

def _get_molecular_mass(self, species_dict: dict) -> float:
Expand Down Expand Up @@ -399,6 +416,7 @@ def _map_molecules(self):
for t, molecule in enumerate(
self.adjacency_graphs[molecule_name]["molecules"]
):
# indices of the atoms inside the specific molecule.
indices = list(
self.adjacency_graphs[molecule_name]["molecules"][
molecule
Expand All @@ -425,7 +443,7 @@ def _build_indices_dict(self, indices: List[int], species: List[str]) -> dict:
indices : list[int]
Indices of atoms belonging in the molecule
species : list[str]
Elements in the molecules, in the order that they are loaded.
Species in the molecules, in the order that they are loaded.
Returns
-------
group_dict : dict
Expand Down Expand Up @@ -458,6 +476,28 @@ def _build_indices_dict(self, indices: List[int], species: List[str]) -> dict:
def run_transformation(self, molecules: dict):
"""
Perform the transformation.

Parameters
----------
molecules : dict
Molecule dictionary to use as reference. The reference component is the
most critical part. One can either use a smiles string or a reference
dict as demonstrated below.

e.g, the input for emim-PF6 ionic liquid would be:

.. code-block::

{'emim': {'smiles': 'CCN1C=C[N+](+C1)C', 'amount': 20},
'PF6': {'smiles': 'F[P-](F)(F)(F)(F)F', 'amount': 20}}
SamTov marked this conversation as resolved.
Show resolved Hide resolved

or:

.. code-block::

{'emim': {'reference': {'C': , 'N': 'H': }}, 'amount': 20},
SamTov marked this conversation as resolved.
Show resolved Hide resolved
'PF6': {'reference': {'P': 1, 'F': 6}, 'amount': 20}}

Returns
-------
Update the experiment database.
Expand Down
2 changes: 1 addition & 1 deletion mdsuite/transformations/transformation_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
-------
"""

# TODO remvoe this!
# TODO remove when molecule mapping is adjusted.
christophlohrmann marked this conversation as resolved.
Show resolved Hide resolved
# map_molecules is the only transformation still working with it

from mdsuite.transformations.integrated_heat_current import IntegratedHeatCurrent
Expand Down
4 changes: 2 additions & 2 deletions mdsuite/visualizer/znvis_visualizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def __init__(
"""
self.counter = 0
# Particle information
self.database = Database(name=join_path(database_path, "database.hdf5"))
self.database = Database(join_path(database_path, "database.hdf5"))
self.frame_rate = frame_rate
self.species = species
if unwrapped:
Expand Down Expand Up @@ -138,5 +138,5 @@ def run_visualization(self):
Opens the ZnVis app and runs the visualization.
"""
particle_list = self._prepare_species()
visualizer = znvis.Visualizer(particles=particle_list, frame_rate=50)
visualizer = znvis.Visualizer(particles=particle_list, frame_rate=17)
SamTov marked this conversation as resolved.
Show resolved Hide resolved
visualizer.run_visualization()