Skip to content
Snippets Groups Projects
Commit 5b04798e authored by James Graham's avatar James Graham
Browse files

CFG parser use OrderedDict

Small amounts of tidying elsewhere
parent 08c52fda
Branches
Tags
No related merge requests found
{ {
"H": 1.0080,
"C": 12.0110, "C": 12.0110,
"O": 15.9994,
"N": 14.0067, "N": 14.0067,
"H": 1.0080, "O": 15.9994,
"P": 30.9738 "P": 30.9738,
"S": 32.0600
} }
...@@ -2,7 +2,7 @@ PyCGTOOL Tutorial ...@@ -2,7 +2,7 @@ PyCGTOOL Tutorial
================= =================
This tutorial follows the complete process of parametrising a new molecule within the MARTINI forcefield, covering aspects of mapping design, model generation and model validation. This tutorial follows the complete process of parametrising a new molecule within the MARTINI forcefield, covering aspects of mapping design, model generation and model validation.
PyCGTOOL is used at multiple stages, showing its use in several different situations PyCGTOOL is used at multiple stages, showing its use in several different situations.
All files required to follow this tutorial are present in the ``doc/tutorial_files`` directory. All files required to follow this tutorial are present in the ``doc/tutorial_files`` directory.
The molecule chosen as a target for this parametrisation is the :math:`\beta_1` antagonist atenolol. The molecule chosen as a target for this parametrisation is the :math:`\beta_1` antagonist atenolol.
......
...@@ -358,7 +358,7 @@ class Frame: ...@@ -358,7 +358,7 @@ class Frame:
atoms = [] atoms = []
for res in self.residues: for res in self.residues:
for atom in res: for atom in res:
atoms.append(repr(atom.coords)) atoms.append(repr(atom))
rep += "\n".join(atoms) rep += "\n".join(atoms)
return rep return rep
......
...@@ -84,7 +84,6 @@ class Mapping: ...@@ -84,7 +84,6 @@ class Mapping:
:return: Instance of Mapping :return: Instance of Mapping
""" """
self._mappings = {} self._mappings = {}
self._map_center = options.map_center self._map_center = options.map_center
self._masses_are_set = False self._masses_are_set = False
...@@ -127,6 +126,8 @@ class Mapping: ...@@ -127,6 +126,8 @@ class Mapping:
else: else:
bead.charge += atoms[atom][0] bead.charge += atoms[atom][0]
self._masses_are_set = True
def __len__(self): def __len__(self):
return len(self._mappings) return len(self._mappings)
...@@ -153,7 +154,6 @@ class Mapping: ...@@ -153,7 +154,6 @@ class Mapping:
if bead.mass == 0: if bead.mass == 0:
mass_array = np.zeros((len(bead.atoms), 1), dtype=np.float32) mass_array = np.zeros((len(bead.atoms), 1), dtype=np.float32)
for i, atom in enumerate(bead.atoms): for i, atom in enumerate(bead.atoms):
mass = 0
try: try:
mass = mass_dict[atom[:2]] mass = mass_dict[atom[:2]]
except KeyError: except KeyError:
...@@ -185,6 +185,7 @@ class Mapping: ...@@ -185,6 +185,7 @@ class Mapping:
cgframe.name = name cgframe.name = name
missing_mappings = set() missing_mappings = set()
cg_bead_num = 1
for aares in aa_residues: for aares in aa_residues:
try: try:
...@@ -196,12 +197,15 @@ class Mapping: ...@@ -196,12 +197,15 @@ class Mapping:
continue continue
cgres = Residue(name=aares.name, num=aares.num) cgres = Residue(name=aares.name, num=aares.num)
cgres.atoms = [Atom(name=bead.name, type=bead.type, charge=bead.charge, mass=bead.mass) for bead in molmap] cgres.atoms = [Atom(name=bmap.name, type=bmap.type, charge=bmap.charge, mass=bmap.mass, coords=np.zeros(3)) for bmap in molmap]
for i, (bead, bmap) in enumerate(zip(cgres, molmap)): for i, (bead, bmap) in enumerate(zip(cgres, molmap)):
cgres.name_to_num[bead.name] = i cgres.name_to_num[bead.name] = i
bead.charge = bmap.charge bead.charge = bmap.charge
bead.mass = bmap.mass bead.mass = bmap.mass
bead.num = cg_bead_num
cg_bead_num += 1
cgframe.add_residue(cgres) cgframe.add_residue(cgres)
cgframe.natoms += len(cgres) cgframe.natoms += len(cgres)
...@@ -229,7 +233,7 @@ class Mapping: ...@@ -229,7 +233,7 @@ class Mapping:
cgframe.box = frame.box cgframe.box = frame.box
select_predicate = lambda res: res.name in self._mappings and not (exclude is not None and res.name in exclude) select_predicate = lambda res: res.name in self._mappings and not (exclude is not None and res.name in exclude)
aa_residues = (aares for aares in frame if select_predicate(aares)) aa_residues = filter(select_predicate, frame)
for aares, cgres in zip(aa_residues, cgframe): for aares, cgres in zip(aa_residues, cgframe):
molmap = self._mappings[aares.name] molmap = self._mappings[aares.name]
...@@ -249,7 +253,7 @@ class Mapping: ...@@ -249,7 +253,7 @@ class Mapping:
return cgframe return cgframe
@numba.jit(nopython=True) @numba.jit
def calc_coords_weight(ref_coords, coords, box, weights): def calc_coords_weight(ref_coords, coords, box, weights):
""" """
Calculate the coordinates of a single CG bead from weighted component atom coordinates. Calculate the coordinates of a single CG bead from weighted component atom coordinates.
......
...@@ -5,6 +5,8 @@ Format is based upon GROMACS .itp files but does not support nesting of sections ...@@ -5,6 +5,8 @@ Format is based upon GROMACS .itp files but does not support nesting of sections
""" """
import os import os
from collections import OrderedDict
class Section: class Section:
""" """
...@@ -48,7 +50,7 @@ class CFG: ...@@ -48,7 +50,7 @@ class CFG:
Contains a dictionary of Sections. Contains a dictionary of Sections.
""" """
__slots__ = ["filename", "_sections", "_section_names", "_iter_section"] __slots__ = ["filename", "_sections"]
def __init__(self, filename=None, allow_duplicate=False): def __init__(self, filename=None, allow_duplicate=False):
""" """
...@@ -59,13 +61,12 @@ class CFG: ...@@ -59,13 +61,12 @@ class CFG:
:return: Instance of CFG :return: Instance of CFG
""" """
self.filename = filename self.filename = filename
self._sections = {} self._sections = OrderedDict()
self._section_names = []
with open(self.filename) as f: with open(self.filename) as f:
curr_section = None curr_section = None
for line in f: for line in f:
line = line.strip(" \t\n") line = line.strip()
if not line or line.startswith(";"): if not line or line.startswith(";"):
continue continue
...@@ -73,14 +74,12 @@ class CFG: ...@@ -73,14 +74,12 @@ class CFG:
cfg2 = CFG(os.path.join(os.path.dirname(self.filename), cfg2 = CFG(os.path.join(os.path.dirname(self.filename),
line.split()[1])) line.split()[1]))
self._sections.update(cfg2._sections) self._sections.update(cfg2._sections)
self._section_names += cfg2._section_names
continue continue
elif line.startswith("["): elif line.startswith("["):
curr_section = line.strip("[ ]") curr_section = line.strip("[ ]")
if curr_section in self._sections and not allow_duplicate: if curr_section in self._sections and not allow_duplicate:
raise DuplicateSectionError(curr_section, self.filename) raise DuplicateSectionError(curr_section, self.filename)
self._section_names.append(curr_section)
self._sections[curr_section] = Section(name=curr_section) self._sections[curr_section] = Section(name=curr_section)
continue continue
...@@ -94,21 +93,13 @@ class CFG: ...@@ -94,21 +93,13 @@ class CFG:
pass pass
def __len__(self): def __len__(self):
return len(self._section_names) return len(self._sections)
def __iter__(self): def __iter__(self):
self._iter_section = -1 return iter(self._sections.values())
return self
def __next__(self):
self._iter_section += 1
if self._iter_section >= len(self._section_names):
raise StopIteration
sec = self._section_names[self._iter_section]
return self._sections[sec]
def __contains__(self, item): def __contains__(self, item):
return item in self._section_names return item in self._sections
def __getitem__(self, item): def __getitem__(self, item):
return self._sections[item] return self._sections[item]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment