LOOS  v2.3.2
WaterBox.py
1 #!/usr/bin/env python
2 
3 import loos
4 
5 # @cond TOOLS_INTERNAL
6 
7 class WaterBox:
8  def __init__(self, filename, template_box, target_box, segname):
9  self.filename = filename
10  self.box = target_box
11  self.template_box = template_box
12  self.segname = segname
13 
14  self.template = loos.createSystem(filename)
15  for i in range(len(self.template)):
16  self.template[i].segid(segname)
17 
18  self.buildBox()
19 
20  def buildBox(self):
21  """
22  Use the template structure to build the full structure by
23  replicating it each dimension until it's bigger than the
24  target box size, then deleting waters with centroid that fall
25  outside the target box.
26  The resulting AtomicGroup is self.full_system
27  """
28 
29  # figure out how many replicas we need in each direction
30  num_x = int(self.box.x() / self.template_box.x()) + 1
31  num_y = int(self.box.y() / self.template_box.y()) + 1
32  num_z = int(self.box.z() / self.template_box.z()) + 1
33 
34  # build up the new system by replicating the target box
35  # and systematically translating it
36  self.full_system = loos.AtomicGroup()
37  for x in range(num_x):
38  for y in range(num_y):
39  for z in range(num_z):
40  new = self.template.copy()
41 
42  trans = loos.GCoord()
43  trans.x( self.template_box.x() * x)
44  trans.y( self.template_box.y() * y)
45  trans.z( self.template_box.z() * z)
46 
47  new.translate(trans)
48  self.full_system.append(new)
49 
50  self.full_system.centerAtOrigin()
51 
52  # trim the waters outside the target box size
53  residues = self.full_system.splitByResidue()
54  print len(residues), len(self.full_system)
55  half_box = 0.5 * self.box
56  to_remove = loos.AtomicGroup()
57  for res in residues:
58  centroid = res.centroid()
59  print centroid, half_box
60  if ( (abs(centroid.x()) > half_box.x()) or
61  (abs(centroid.y()) > half_box.y()) or
62  (abs(centroid.z()) > half_box.z()) ):
63  to_remove.append(res)
64 
65  print "Need to remove: ", len(to_remove)
66  print "before: ", self.full_system.boundingBox(), len(self.full_system)
67  self.full_system.remove(to_remove)
68  print "after: ", self.full_system.boundingBox(), len(self.full_system)
69 
70  self.full_system.periodicBox(self.box)
71 
72  # renumber atom ids and resids
73  self.full_system.renumber()
74  for i in range(len(self.full_system)):
75  self.full_system[i].resid(i/3 + 1)
76  #residues = self.full_system.splitByResidue()
77  #for i in range(len(residues)):
78  # for j in range(len(residues[i])):
79  # residues[i][j].resid(i+1)
80 
81 
82  def append_waters(self, other):
83  """
84  "other" is an AtomicGroup of waters. Merge them
85  into the current WaterBox, renumbering the atoms
86  and residues, and updating their segment name
87  """
88 
89  self.full_system += other
90  self.full_system.renumber()
91  residues = self.full_system.splitByResidue()
92  for i in range(len(residues)):
93  for j in range(len(residues[i])):
94  residues[i][j].resid(i+1)
95  residues[i][j].segid(self.segname)
96 
97 
98  def pdb(self):
99  """
100  Return a string containing a PDB version of the full_system,
101  convenient for writing out the coordinates in PDB format.
102  """
103 
104  p = loos.PDB.fromAtomicGroup(self.full_system)
105  return str(p)
106 
107 # @endcond
108 
109 
110 if __name__ == '__main__':
111  import sys
112 
113  coordfile = 'water_small.crd'
114  box_size = loos.GCoord(15.5516, 15.5516, 15.5516)
115  big_box = loos.GCoord(74.1, 74.1, 95.0)
116 
117  w = WaterBox(coordfile, box_size, big_box, "BULK")
118 
119  f = open("big_water.pdb", "w")
120  f.write(w.pdb())
121  f.close()
122 
123  print w.full_system.periodicBox()
124  print w.full_system.boundingBox()
125 
126 
127 
128 
static PDB fromAtomicGroup(const AtomicGroup &)
Class method for creating a PDB from an AtomicGroup.
Definition: pdb.cpp:528
Class for handling groups of Atoms (pAtoms, actually)
Definition: AtomicGroup.hpp:87
AtomicGroup createSystem(const std::string &filename, const std::string &filetype)
Definition: sfactories.cpp:119