Package generic_fns :: Module xplor
[hide private]
[frames] | no frames]

Source Code for Module generic_fns.xplor

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2009 Edward d'Auvergne                                        # 
  4  #                                                                             # 
  5  # This file is part of the program relax.                                     # 
  6  #                                                                             # 
  7  # relax is free software; you can redistribute it and/or modify               # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation; either version 2 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # relax is distributed in the hope that it will be useful,                    # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with relax; if not, write to the Free Software                        # 
 19  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   # 
 20  #                                                                             # 
 21  ############################################################################### 
 22   
 23  # Module docstring. 
 24  """Module containing functions for the parsing and creation of Xplor formatted files.""" 
 25   
 26  # Python module imports. 
 27  from re import search 
 28  from string import split 
 29   
 30  # relax module imports. 
 31  from relax_errors import RelaxError 
 32   
 33   
34 -def __convert_to_id(string):
35 """Convert the string into a relax atom id representation. 36 37 @param string: The Xplor atom string. 38 @type string: str 39 @return: The relax atom id. 40 @rtype: str 41 """ 42 43 # Split up the string by the 'and' statements. 44 data = split(string, 'and') 45 46 # Loop over the data. 47 relax_id = '' 48 for i in range(len(data)): 49 # Split by whitespace. 50 info = split(data[i]) 51 52 # Don't know what this is! 53 if len(info) != 2: 54 raise RelaxError("Cannot convert the Xplor atom string '%s' to relax format." % string) 55 56 # A molecule identifier. 57 if info[0] == 'segid': 58 relax_id = relax_id + '#' + info[1] 59 60 # A residue identifier. 61 elif info[0] == 'resid': 62 relax_id = relax_id + ':' + info[1] 63 64 # An atom identifier. 65 elif info[0] == 'name': 66 relax_id = relax_id + '@' + info[1] 67 68 # Return the relax id. 69 return relax_id
70 71
72 -def parse_noe_restraints(lines):
73 """Parse and return the NOE restraints from the Xplor lines. 74 75 @param lines: The Xplor formatted file, or file fragment, split into lines. 76 @type lines: list of str 77 @return: The NOE restraint list in the format of two atom identification strings (or list 78 of str for pseudoatoms) and the lower and upper restraints. 79 @rtype: list of lists of str, str, float, float 80 """ 81 82 # Strip all comments from the data. 83 lines = strip_comments(lines) 84 85 # Init. 86 data = [] 87 88 # First level pass (assign statements). 89 for id1, id2, noe, lower, upper in first_parse(lines): 90 # Second parse (pseudoatoms). 91 id1 = second_parse(id1) 92 id2 = second_parse(id2) 93 94 # Convert to relax spin IDs. 95 if isinstance(id1, list): 96 relax_id1 = [] 97 for i in range(len(id1)): 98 relax_id1.append(__convert_to_id(id1[i])) 99 else: 100 relax_id1 = __convert_to_id(id1) 101 102 if isinstance(id2, list): 103 relax_id2 = [] 104 for i in range(len(id2)): 105 relax_id2.append(__convert_to_id(id2[i])) 106 else: 107 relax_id2 = __convert_to_id(id2) 108 109 # Convert to upper and lower bounds. 110 lower_bound = noe - lower 111 upper_bound = noe + upper 112 113 # Add the data to the list. 114 data.append([relax_id1, relax_id2, lower_bound, upper_bound]) 115 116 # Return the data. 117 return data
118 119
120 -def first_parse(lines):
121 """Generator function to parse and extract the 2 atom IDs and NOE info from the lines. 122 123 The first parse loops over and returns the data from assign statements, returning pseudo atoms 124 as single strings. The second parse splits the pseudoatoms. 125 126 @param lines: The Xplor formatted file, or file fragment, split into lines. 127 @type lines: list of str 128 @return: The 2 atom IDs, and NOE info (NOE, upper, and lower bounds). 129 @rtype: str, str, float, float, float 130 """ 131 132 # Extract the data. 133 line_index = 0 134 while True: 135 # Break out! 136 if line_index >= len(lines): 137 break 138 139 # Find the assign statements. 140 if search('^assign', lines[line_index]): 141 # Init. 142 char_index = -1 143 144 # Extract the atom ID strings. 145 id = ['', ''] 146 id_index = 0 147 inside = 0 148 while True: 149 # Inc the character index. 150 char_index = char_index + 1 151 152 # Break out! 153 if line_index >= len(lines): 154 break 155 156 # Check if we need to go to the next line. 157 if char_index >= len(lines[line_index]): 158 line_index = line_index + 1 159 char_index = -1 160 continue 161 162 # A starting bracket, so increment the inside counter. 163 if lines[line_index][char_index] == '(': 164 inside = inside + 1 165 166 # Don't include the first bracket in the ID string. 167 if inside == 1: 168 continue 169 170 # Not inside, so jump to the next character. 171 if not inside: 172 continue 173 174 # An ending bracket. 175 elif lines[line_index][char_index] == ')': 176 inside = inside - 1 177 178 # A logical test (debugging). 179 if inside < 0: 180 raise RelaxError("Improperly formatted Xplor file, unmatched ')'.") 181 182 # Append the character. 183 if inside: 184 id[id_index] = id[id_index] + lines[line_index][char_index] 185 186 # Go to the second id_index, or break. 187 if inside == 0: 188 if id_index == 1: 189 break 190 else: 191 id_index = 1 192 193 # The rest of the data (NOE restraint info). 194 info = split(lines[line_index][char_index+1:]) 195 196 # NOE dist, lower, upper. 197 noe = float(info[0]) 198 lower = float(info[1]) 199 upper = float(info[2]) 200 201 # Non-data line. 202 else: 203 # Line index. 204 line_index = line_index + 1 205 206 # Skip to the next line without yielding. 207 continue 208 209 # Line index. 210 line_index = line_index + 1 211 212 # Return the data. 213 yield id[0], id[1], noe, lower, upper
214 215
216 -def second_parse(id):
217 """Split up pseudoatoms. 218 219 @param id: The Xplor atom id without outer brackets, i.e. a single atom or a list of atoms in 220 the case of pseudoatoms. 221 @type id: str 222 @return: For normal atoms, the id string is returned unmodified. For pseudoatoms, a list of 223 strings, with brackets removed, is returned. 224 @rtype: str or list of str 225 """ 226 227 # Loop over the characters. 228 atoms = [''] 229 index = -1 230 inside = False 231 while True: 232 # Inc the character index. 233 index = index + 1 234 235 # Break out. 236 if index >= len(id): 237 break 238 239 # A starting bracket, so flip the inside flag. 240 if id[index] == '(': 241 # 2 brackets?!? 242 if inside: 243 raise RelaxError("The Xplor pseudoatom ID string '%s' is invalid." % id) 244 245 # The flag. 246 inside = True 247 248 # Don't include the first bracket in the ID string. 249 continue 250 251 # Not inside, so jump to the next character. 252 if not inside: 253 continue 254 255 # An ending bracket. 256 if id[index] == ')': 257 inside = False 258 259 # Append the character. 260 if inside: 261 atoms[-1] = atoms[-1] + id[index] 262 263 # Add another atom. 264 if not inside: 265 atoms.append('') 266 267 # Remove the last empty atom string. 268 if atoms[0] and atoms[-1] == '': 269 atoms = atoms[:-1] 270 271 # Return the data. 272 if not atoms[0]: 273 return id 274 else: 275 return atoms
276 277
278 -def strip_comments(lines):
279 """Remove all Xplor comments from the data. 280 281 @param lines: The Xplor formatted file, or file fragment, split into lines. 282 @type lines: list of str 283 @return: The file data with all comments removed. 284 @rtype: list of str 285 """ 286 287 # Loop over the lines. 288 new_lines = [] 289 for line in lines: 290 # Comment lines. 291 if search('^!', line): 292 continue 293 294 # Partial comment lines. 295 new_line = '' 296 for char in line: 297 # Comment - so skip the rest of the line. 298 if char == '!': 299 continue 300 301 # Build the new line. 302 new_line = new_line + char 303 304 # Add the new line. 305 new_lines.append(new_line) 306 307 # Return the stripped data. 308 return new_lines
309