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

Convert itp files to ff files #327

Open
wants to merge 86 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
5968f83
init draft itp to ff
fgrunewald Jun 13, 2023
c577052
imporve graph matching
fgrunewald Jun 15, 2023
7eff22a
fragment finder with prints
fgrunewald Jun 19, 2023
95c4b87
add tests for fragment finder
fgrunewald Jun 19, 2023
ae2794c
add test for 100% coverage
fgrunewald Jun 20, 2023
101d2b7
refactor graph matchin post isomorph check
fgrunewald Jun 20, 2023
6261186
add check on node naming
fgrunewald Jun 20, 2023
a8ce5a1
add pysmiles to tests
fgrunewald Jun 20, 2023
b8dfa7b
tests for ffoutput
fgrunewald Jun 20, 2023
b3ea5ac
use tmp-file for testing ffoutput
fgrunewald Jun 20, 2023
79c38fb
modify extract block and use in itp_to_ff
fgrunewald Jun 20, 2023
77dfe16
update test for generate templates accordingly
fgrunewald Jun 20, 2023
214f5f2
add isomorphism naming
fgrunewald Jun 21, 2023
ef70012
properly check if interactions are equal
fgrunewald Jun 21, 2023
2410b0a
read itp files
fgrunewald Jun 21, 2023
450ebc4
draft round robin tests
fgrunewald Jun 21, 2023
888515b
fix input types
fgrunewald Jun 21, 2023
44cc867
add test print
fgrunewald Jun 26, 2023
0877210
Merge branch 'master' into itp_to_ff
fgrunewald Jun 29, 2023
32cd8f8
clean up output
fgrunewald Nov 22, 2023
a8d1bb9
methods to deal with charges
fgrunewald Nov 22, 2023
37bad71
methods to deal with charges
fgrunewald Nov 22, 2023
7409098
methods to deal with charges
fgrunewald Nov 22, 2023
362372e
adjust test
fgrunewald Nov 22, 2023
4ed2979
move extract block to molecule utils
fgrunewald Nov 22, 2023
fa32f76
small fix
fgrunewald Nov 22, 2023
5207801
allow for charged residues and make pysmiles optional import
fgrunewald Nov 23, 2023
737b45c
make mass optional
fgrunewald Nov 23, 2023
9a1e800
add doc-strings and rename equalize_charge
fgrunewald Nov 23, 2023
c9621a3
remove print
fgrunewald Nov 24, 2023
fdae3db
remove martini2 from ffoutput test as it fails on GH
fgrunewald Nov 24, 2023
e50e232
add test for extract links
fgrunewald Nov 24, 2023
6c94485
add test for extract links with redundant interaction
fgrunewald Nov 24, 2023
e343211
test for charge balancing
fgrunewald Nov 24, 2023
7db6462
test for charge balancing
fgrunewald Nov 24, 2023
c9dadac
implement tolerances for charge balancing
fgrunewald Nov 24, 2023
b693735
add integration tests itp_to_ff and adjust CLI
fgrunewald Nov 24, 2023
1c542cb
fix bug in integration tests itp_to_ff
fgrunewald Nov 24, 2023
aa0865d
complex integration test itp_to_ff plus charged mol
fgrunewald Nov 24, 2023
a39c3ac
use top file for ACOL test and fix bug in test
fgrunewald Nov 24, 2023
39f7ad4
fix toplevel itp_to_ff parser
fgrunewald Dec 28, 2023
8f80a99
bigsmile_draft
fgrunewald Jan 15, 2024
40b89af
infrastructure for big smile parsing
fgrunewald Jan 19, 2024
05ed045
optional dep. for pysmiles
fgrunewald Jan 19, 2024
82a2acc
add a processor that reads a big smile string and returns a full meta…
fgrunewald Jan 19, 2024
257b76b
atest-big-smile parsing part I
fgrunewald Jan 20, 2024
061c8ef
fix hcount for single atom; fix nexted branches
fgrunewald Jan 22, 2024
20e2e49
tests for smile iter and test nested branches
fgrunewald Jan 22, 2024
f505129
add pysmiles to test requrm.
fgrunewald Jan 22, 2024
0c67ecc
add tests for bonding descriptor evaluation
fgrunewald Jan 22, 2024
52235c9
add tests for big smile molecule prc
fgrunewald Jan 23, 2024
9a0a674
allow multiple bonding per atom; fix bugs
fgrunewald Jan 23, 2024
ceccc3d
remove mpl import
fgrunewald Jan 24, 2024
158fd37
add changed tests for multiple bonding per atom
fgrunewald Jan 24, 2024
8f2887f
delete old processor file
fgrunewald Jan 24, 2024
08021c2
have charge balancing for itps but raise error when bond length is mi…
fgrunewald Jan 24, 2024
8d48cb2
Merge branch 'big_smiles' into itp_to_ff
fgrunewald Jan 25, 2024
681004f
add closing bracket to special characters
fgrunewald Feb 29, 2024
3537239
only balance charges for blocks with at least 2 atoms
fgrunewald Feb 29, 2024
929b5d1
refactor fragment finder
fgrunewald Feb 29, 2024
87510bb
refactor fragment itp_to_ff
fgrunewald Feb 29, 2024
05df2e5
change input for itp_to_ff to allow bigmsiles
fgrunewald Feb 29, 2024
0ebfa6a
take most central fragment
fgrunewald Mar 1, 2024
a7cd590
add special links for terminal modifications
fgrunewald Mar 1, 2024
8e0c257
type the charges to float in itp to ff
fgrunewald Mar 3, 2024
7cb3b4c
add H and ] as special characters in big smile parser
fgrunewald Mar 3, 2024
097ec84
account for explicit hydrogen in the smiles string input
fgrunewald Mar 3, 2024
514ba1b
test accounting for explicit hydrogen in the smiles string input
fgrunewald Mar 3, 2024
3e4a737
read provided ff file and use these blocks instead of making new ones
fgrunewald Mar 4, 2024
d97632d
adjust doc string
fgrunewald Mar 4, 2024
b6acc73
skip termini mods if none atoms are different
fgrunewald Mar 4, 2024
6095dc6
Merge branch 'big_smiles' into itp_to_ff
fgrunewald Mar 5, 2024
9d9ee89
redo hydrogen based on valency not based on how many bonding descript…
fgrunewald Mar 6, 2024
c4f1652
parse force-field in molprocessor, adjust hydrogen reconstruction
fgrunewald Mar 6, 2024
7a5dd1f
fix tests
fgrunewald Mar 6, 2024
2b9e7a9
Apply suggestions from code review
fgrunewald Mar 6, 2024
b6d891f
allow nested branch expansion
fgrunewald Mar 7, 2024
a867329
test branch expansion
fgrunewald Mar 7, 2024
b6f5cc0
add comments all over residue expansion functions
fgrunewald Mar 7, 2024
f965e1d
address comments
fgrunewald Mar 7, 2024
0335956
allow for ionic bonds with . syntax
fgrunewald Mar 7, 2024
1f25c32
Merge branch 'big_smiles' into itp_to_ff
fgrunewald Mar 7, 2024
47fef23
fix previous issue with link appending
fgrunewald Mar 7, 2024
7f7fe21
update itp_to_ff tests
fgrunewald Mar 7, 2024
7268663
update tests for fragment finder
fgrunewald Mar 7, 2024
15be6a6
remove leftover files
fgrunewald Mar 7, 2024
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
21 changes: 20 additions & 1 deletion bin/polyply
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import argparse
from pathlib import Path
import numpy as np
import polyply
from polyply import (gen_itp, gen_coords, gen_seq, DATA_PATH)
from polyply import (gen_itp, gen_coords, gen_seq, itp_to_ff, DATA_PATH)
from polyply.src.load_library import load_ff_library
from polyply.src.logging import LOGGER, LOGLEVELS

Expand Down Expand Up @@ -51,6 +51,7 @@ def main(): # pylint: disable=too-many-locals,too-many-statements
parser_gen_itp = subparsers.add_parser('gen_params', aliases=['gen_itp'])
parser_gen_coords = subparsers.add_parser('gen_coords')
parser_gen_seq = subparsers.add_parser('gen_seq')
parser_itp_ff = subparsers.add_parser('itp_to_ff')

# =============================================================================
# Input Arguments for the itp generation tool
Expand Down Expand Up @@ -228,6 +229,24 @@ def main(): # pylint: disable=too-many-locals,too-many-statements
default=[])
parser_gen_seq.set_defaults(func=gen_seq)

# =============================================================================
# Input Arguments for the itp to ff tool
# =============================================================================

parser_itp_ff.add_argument('-v', dest='verbosity', action='count',
help='Enable debug logging output. Can be given '
'multiple times.', default=0)

parser_itp_ff.add_argument('-i', dest="itppath", type=Path, required=True)
parser_itp_ff.add_argument('-s', dest="smile_str", required=True)
parser_itp_ff.add_argument('-o', dest="outpath", type=Path)
parser_itp_ff.add_argument('-c', dest="res_charges", nargs='+', type=lambda s: s.split(':'),)
Copy link
Member

Choose a reason for hiding this comment

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

Needs a help with the format/syntax

parser_itp_ff.add_argument('-f', dest='inpath', type=Path, required=False, default=[],
help='Input file (ITP|FF)', nargs='*')
Comment on lines +244 to +245
Copy link
Member

Choose a reason for hiding this comment

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

https://docs.python.org/3/library/argparse.html#argparse.FileType

Maybe also in other places. Optional though


parser_itp_ff.set_defaults(func=itp_to_ff)


# ============================================================================
# Deal with queries of the polyply library
# ============================================================================
Expand Down
1 change: 1 addition & 0 deletions polyply/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,4 @@
from .src.gen_itp import gen_itp, gen_params
from .src.gen_coords import gen_coords
from .src.gen_seq import gen_seq
from .src.itp_to_ff import itp_to_ff
143 changes: 143 additions & 0 deletions polyply/src/big_smile_mol_processor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import re
import networkx as nx
import pysmiles
from polyply.src.big_smile_parsing import (res_pattern_to_meta_mol,
force_field_from_fragments)
from polyply.src.map_to_molecule import MapToMolecule

VALENCES = pysmiles.smiles_helper.VALENCES
VALENCES.update({"H":(1,)})

def compatible(left, right):
"""
Check bonding descriptor compatibility according
to the BigSmiles syntax convetions.

Parameters
----------
left: str
right: str

Returns
-------
bool
"""
if left == right and left not in '> <':
return True
l, r = left[0], right[0]
if (l, r) == ('<', '>') or (l, r) == ('>', '<'):
return left[1:] == right[1:]
return False

def generate_edge(source, target, bond_attribute="bonding"):
"""
Given a source and a target graph, which have bonding
descriptors stored as node attributes, find a pair of
matching descriptors and return the respective nodes.
The function also returns the bonding descriptors. If
no bonding descriptor is found an instance of LookupError
is raised.

Parameters
----------
source: :class:`nx.Graph`
target: :class:`nx.Graph`
bond_attribute: `abc.hashable`
under which attribute are the bonding descriptors
stored.

Returns
-------
((abc.hashable, abc.hashable), (str, str))
the nodes as well as bonding descriptors

Raises
------
LookupError
if no match is found
"""
source_nodes = nx.get_node_attributes(source, bond_attribute)
target_nodes = nx.get_node_attributes(target, bond_attribute)
for source_node in source_nodes:
for target_node in target_nodes:
#print(source_node, target_node)
bond_sources = source_nodes[source_node]
bond_targets = target_nodes[target_node]
for bond_source in bond_sources:
for bond_target in bond_targets:
#print(bond_source, bond_target)
if compatible(bond_source, bond_target):
return ((source_node, target_node), (bond_source, bond_target))
raise LookupError

Check warning on line 71 in polyply/src/big_smile_mol_processor.py

View check run for this annotation

Codecov / codecov/patch

polyply/src/big_smile_mol_processor.py#L71

Added line #L71 was not covered by tests

class DefBigSmileParser:
"""
Parse an a string instance of a defined BigSmile,
which describes a polymer molecule.
"""

def __init__(self, force_field):
self.force_field = force_field
self.meta_molecule = None
self.molecule = None

def edges_from_bonding_descrpt(self):
"""
Make edges according to the bonding descriptors stored
in the node attributes of meta_molecule residue graph.
If a bonding descriptor is consumed it is removed from the list,
however, the meta_molecule edge gets an attribute with the
bonding descriptors that formed the edge. Later uncomsumed
bonding descriptors are replaced by hydrogen atoms.
"""
for prev_node, node in nx.dfs_edges(self.meta_molecule):
prev_graph = self.meta_molecule.nodes[prev_node]['graph']
node_graph = self.meta_molecule.nodes[node]['graph']
edge, bonding = generate_edge(prev_graph,
node_graph)
# this is a bit of a workaround because at this stage the
# bonding list is actually shared between all residues of
# of the same type; so we first make a copy then we replace
# the list sans used bonding descriptor
prev_bond_list = prev_graph.nodes[edge[0]]['bonding'].copy()
prev_bond_list.remove(bonding[0])
prev_graph.nodes[edge[0]]['bonding'] = prev_bond_list
node_bond_list = node_graph.nodes[edge[1]]['bonding'].copy()
node_bond_list.remove(bonding[1])
node_graph.nodes[edge[1]]['bonding'] = node_bond_list
self.meta_molecule.molecule.add_edge(edge[0], edge[1], bonding=bonding)

def replace_unconsumed_bonding_descrpt(self):
"""
We allow multiple bonding descriptors per atom, which
however, are not always consumed. In this case the left
over bonding descriptors are replaced by hydrogen atoms.
"""
for node in self.meta_molecule.nodes:
graph = self.meta_molecule.nodes[node]['graph']
bonding = nx.get_node_attributes(graph, "bonding")
for node, bondings in bonding.items():
element = graph.nodes[node]['element']
hcount = VALENCES[element][0] -\
self.meta_molecule.molecule.degree(node) + 1
attrs = {attr: graph.nodes[node][attr] for attr in ['resname', 'resid']}
attrs['element'] = 'H'
for new_id in range(1, hcount):
new_node = len(self.meta_molecule.molecule.nodes) + 1
graph.add_edge(node, new_node)
attrs['atomname'] = "H" + str(new_id + len(graph.nodes))
graph.nodes[new_node].update(attrs)
self.meta_molecule.molecule.add_edge(node, new_node)
self.meta_molecule.molecule.nodes[new_node].update(attrs)

def parse(self, big_smile_str):
res_pattern, residues = re.findall(r"\{[^\}]+\}", big_smile_str)
self.meta_molecule = res_pattern_to_meta_mol(res_pattern)
self.force_field = force_field_from_fragments(residues)
MapToMolecule(self.force_field).run_molecule(self.meta_molecule)
self.edges_from_bonding_descrpt()
self.replace_unconsumed_bonding_descrpt()
return self.meta_molecule

# ToDo
# - clean copying of bond-list attributes L100
Loading
Loading