LOOS  v2.3.2
PSFGen.py
1 #!/usr/bin/env python
2 import sys
3 import LipidLibrary
4 import loos
5 import subprocess
6 import os
7 
8 # @cond TOOLS_INTERNAL
9 
10 
11 class Segment:
12  """
13  Class describing a segment of a PSF file. Contains the information
14  needed to write a psf, and to build this set ouf lipids.
15 
16  The input value line is expected to look like:
17 SEGMENT TPC POPC 90 19 P 1 ./popc_c36
18  where:
19  TPC = segment name (all of 1 lipid type, 1 res/lipid)
20  POPC= residue name
21  90 = number of lipids (and residues) in the segment
22  19 = distance of phosphate from center of bilayer
23  P = atom to be placed at the distance (usually P for lipid phosphate)
24  1 = placement (1 for upper leaflet, -1 for lower, 0 for TM)
25  ./popc_c36= path to the lipid library where the configurations are stored
26  """
27  def __init__(self, line):
28  (segment, segname, resname, number, phos_pos, phos_atom, placement, library) = line.split()
29 
30  self.segname = segname
31  self.resname = resname
32  self.numres = int(number)
33  self.library = LipidLibrary.LipidLibrary(library)
34 
35  self.placement = int(placement)
36  self.phos_height = float(phos_pos)
37  self.phos_atom = phos_atom
38 
39  def write(self):
40  arr = ["segment " + self.segname + " {"]
41  for i in range(1, self.numres + 1):
42  arr.append(" residue " + str(i) + " " + self.resname)
43 
44  arr.append("}")
45  string = "\n".join(arr)
46 
47  return string
48 
49 class WaterSeg(Segment):
50  """
51  Subclass of Segment (done to inherit the write() method) intended to handle
52  water.
53  """
54  def __init__(self, line):
55  (tag, segname, resname, number, thickness, box_size, coords) = line.split()
56  self.segname = segname
57  self.resname = resname
58  self.numres = int(number)
59  self.thickness = thickness
60  self.box_size = float(box_size)
61  self.coords_filename = coords
62 
63  def write(self):
64  arr = ["segment " + self.segname + " {"]
65  arr.append(" auto none")
66  for i in range(1, self.numres + 1):
67  arr.append(" residue " + str(i) + " " + self.resname)
68 
69  arr.append("}")
70  string = "\n".join(arr)
71 
72  return string
73 
74 
75 class SaltSeg(Segment):
76  """
77  Subclass of Segment (done to inherit the write() method) intended to handle
78  single atom ions.
79  """
80  def __init__(self, line):
81  (tag, segname, resname, number) = line.split()
82  self.segname = segname
83  self.resname = resname
84  self.numres = int(number)
85 
86 class Protein:
87  """
88  Analogous to Segment class, handles things like proteins embedded in the
89  membrane
90  """
91  def __init__(self, line):
92  (tag, model_file, psf_file, water_seg, scale_by_molecule) = line.split()
93  self.model_file = os.path.abspath(model_file)
94  self.psf_file = os.path.abspath(psf_file)
95  self.water_segname = water_seg.upper()
96  self.scale = int(scale_by_molecule)
97 
98  self.model = loos.createSystem(self.model_file)
99  self.segments = self.model.splitByUniqueSegid()
100 
101  self.has_water = False
102  for s in self.segments:
103  if s[0].segid() == self.water_segname:
104  self.has_water = True
105  break
106 
107  def is_water(self, segname):
108  return segname == self.water_segname
109 
110  def water_seg(self):
111  for s in self.segments:
112  if s[0].segid() == self.water_segname:
113  return s
114  return None
115 
116  def write(self, include_water=False):
117  """
118  Write psfgen input for all of the segments EXCEPT the water
119  segment
120  """
121 
122  string = "readpsf " + self.psf_file + "\n"
123  if not include_water:
124  string += "# remove the water segment from the psf because\n"
125  string += "# waters are part of the main water segment now\n"
126  string += "delatom " + self.water_segname + "\n\n"
127 
128  return string
129 
130 
131 class ReadConfig:
132  """
133  Class to read the config file and set up the segments. Used to drive
134  psfgen and to guide lipid construction.
135  """
136  def __init__(self, filename):
137 
138  self.segments = []
139  self.water = None
140  self.salt = []
141  self.protein = None
142 
143  self.topology = []
144  self.parameters = []
145  self.psfname = None
146  self.directory = "./out/"
147 
148  self.box = None
149 
150  self.namd_binary = None
151  self.psfgen_binary = None
152 
153  file = open(filename)
154 
155  for line in file.readlines():
156  # skip blanks and comments
157  if line.startswith("#") or line.isspace() or len(line) == 0:
158  continue
159  if line.upper().startswith("TOPOLOGY"):
160  (top, filename) = line.split()
161  self.topology.append(os.path.abspath(filename))
162  elif line.upper().startswith("PARAMETERS"):
163  (par, filename) = line.split()
164  self.parameters.append(os.path.abspath(filename))
165  elif line.upper().startswith("PSFGEN"):
166  (n, psfgen) = line.split()
167  self.psfgen_binary = psfgen
168  elif line.upper().startswith("PSF"):
169  (p, psfname) = line.split()
170  self.psfname = psfname
171  elif line.upper().startswith("SEGMENT"):
172  s = Segment(line)
173  self.segments.append(s)
174  elif line.upper().startswith("WATER"):
175  self.water = WaterSeg(line)
176  elif line.upper().startswith("SALT"):
177  s = SaltSeg(line)
178  self.salt.append(s)
179  elif line.upper().startswith("PROTEIN"):
180  self.protein = Protein(line)
181  elif line.upper().startswith("BOX"):
182  (b,x,y,z) = line.split()
183  x = float(x)
184  y = float(y)
185  z = float(z)
186  self.box = loos.GCoord(x,y,z)
187  #elif line.upper().startswith("DIRECTORY"):
188  # (d, directory) = line.split()
189  # self.directory = directory
190  elif line.upper().startswith("NAMD"):
191  (n, namd) = line.split()
192  self.namd_binary = namd
193 
194  else:
195  sys.stderr.write("Unrecognized line type: %s" % line)
196 
197  if len(self.topology) == 0:
198  sys.stderr.write("No topology file specified... exiting\n")
199  sys.exit(1)
200 
201  if len(self.parameters) == 0:
202  sys.stderr.write("No parameter file specified... exiting\n")
203  sys.exit(1)
204 
205  if self.psfname is None:
206  sys.stderr.write("No output psf file specified... exiting\n")
207  sys.exit(1)
208 
209  # Warn but don't exit if there are no lipids
210  if len(self.segments) == 0:
211  sys.stderr.write("No segments specified... your system has no lipids\n")
212 
213  # TODO: may want to add similar checks for the other keys
214 
215  def generate_psf(self, include_lipid=True,
216  include_water=False,
217  include_other=False,
218  include_other_water=True,
219  output_psf = None):
220 
221  if output_psf is None:
222  output_psf = self.psfname
223 
224  lines = []
225  for t in self.topology:
226  line = "topology " + t
227  lines.append(line)
228 
229  lines.append("\n")
230 
231  if include_other and self.protein is not None:
232  line = self.protein.write(include_other_water)
233  lines.append(line)
234 
235  lines.append("\n")
236 
237  if include_lipid:
238  for s in self.segments:
239  line = s.write()
240  lines.append(line)
241  lines.append("\n")
242 
243  line = ""
244  if include_other:
245  if self.water is not None and include_water:
246  line = self.water.write()
247  lines.append(line)
248  if len(self.salt) > 0:
249  for s in self.salt:
250  line = s.write()
251  lines.append(line)
252  lines.append("\n")
253 
254 
255  lines.append("writepsf x-plor cmap " + output_psf)
256  a = "\n".join(lines)
257  return a
258 
259  def __getitem__(self, index):
260  return self.segments[index]
261 
262 class PSFGen:
263  def __init__(self, psf_string, command = None):
264  if command is None:
265  self.command = "/opt/bin/psfgen"
266  else:
267  self.command = command
268 
269  self.psf_string = psf_string
270 
271  def run(self):
272  #sys.stderr.write(self.psf_string)
273  psfgen = subprocess.Popen("", 0, self.command, stdin=subprocess.PIPE)
274  psfgen.communicate(self.psf_string)
275 
276 # @endcond
277 
278 
279 
280 if __name__ == '__main__':
281 
282  config_file = sys.argv[1]
283 
284  conf = ReadConfig(config_file)
285 
286  #print conf.generate_psf()
287  print conf.generate_psf(True, True)
288  #print conf.generate_psf(True, False)
289  #print conf.generate_psf(False, True)
290 
Definition: PSFGen.py:1
AtomicGroup createSystem(const std::string &filename, const std::string &filetype)
Definition: sfactories.cpp:119