Package prompt :: Module structure
[hide private]
[frames] | no frames]

Source Code for Module prompt.structure

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2003-2012 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 the 'structure' user function class.""" 
 25  __docformat__ = 'plaintext' 
 26   
 27  # relax module imports. 
 28  from base_class import User_fn_class, _build_doc 
 29  import arg_check 
 30  import generic_fns.structure.geometric 
 31  import generic_fns.structure.main 
 32   
 33   
34 -class Structure(User_fn_class):
35 """Class containing the structural related functions.""" 36
37 - def add_atom(self, atom_name=None, res_name=None, res_num=None, pos=[None, None, None], element=None, atom_num=None, chain_id=None, segment_id=None, pdb_record=None):
38 # Function intro text. 39 if self._exec_info.intro: 40 text = self._exec_info.ps3 + "structure.add_atom(" 41 text = text + "atom_name=" + repr(atom_name) 42 text = text + ", res_name=" + repr(res_name) 43 text = text + ", res_num=" + repr(res_num) 44 text = text + ", pos=" + repr(pos) 45 text = text + ", element=" + repr(element) 46 text = text + ", atom_num=" + repr(atom_num) 47 text = text + ", chain_id=" + repr(chain_id) 48 text = text + ", segment_id=" + repr(segment_id) 49 text = text + ", pdb_record=" + repr(pdb_record) + ")" 50 print(text) 51 52 # The argument checks. 53 arg_check.is_str(atom_name, 'atom name') 54 arg_check.is_str(res_name, 'residue name') 55 arg_check.is_int(res_num, 'residue number') 56 arg_check.is_float_array(pos, 'atomic position', size=3) 57 arg_check.is_str(element, 'element', can_be_none=True) 58 arg_check.is_int(atom_num, 'atom number', can_be_none=True) 59 arg_check.is_str(chain_id, 'chain ID', can_be_none=True) 60 arg_check.is_str(segment_id, 'segment_id', can_be_none=True) 61 arg_check.is_str(pdb_record, 'pdb_record', can_be_none=True) 62 63 # Execute the functional code. 64 generic_fns.structure.main.add_atom(atom_name=atom_name, res_name=res_name, res_num=res_num, pos=pos, element=element, atom_num=atom_num, chain_id=chain_id, segment_id=segment_id, pdb_record=pdb_record)
65 66 # The function doc info. 67 add_atom._doc_title = "Add an atom." 68 add_atom._doc_title_short = "Atom creation." 69 add_atom._doc_args = [ 70 ["atom_name", "The atom name."], 71 ["res_name", "The residue name."], 72 ["res_num", "The residue number."], 73 ["pos", "The atomic coordinates."], 74 ["element", "The element name."], 75 ["atom_num", "The optional atom number."], 76 ["chain_id", "The optional chain ID string."], 77 ["segment_id", "The optional segment ID string."], 78 ["pdb_record", "The optional PDB record name, e.g. 'ATOM' or 'HETATM'."] 79 ] 80 add_atom._doc_desc = """ 81 This allows atoms to be added to the internal structural object. 82 """ 83 _build_doc(add_atom) 84 85
86 - def connect_atom(self, index1=None, index2=None):
87 # Function intro text. 88 if self._exec_info.intro: 89 text = self._exec_info.ps3 + "structure.connect_atom(" 90 text = text + "index1=" + repr(index1) 91 text = text + ", index2=" + repr(index2) + ")" 92 print(text) 93 94 # The argument checks. 95 arg_check.is_int(index1, 'index 1') 96 arg_check.is_int(index2, 'index 2') 97 98 # Execute the functional code. 99 generic_fns.structure.main.connect_atom(index1=index1, index2=index2)
100 101 # The function doc info. 102 connect_atom._doc_title = "Connect two atoms." 103 connect_atom._doc_title_short = "Atom connection." 104 connect_atom._doc_args = [ 105 ["index1", "The global index of the first atom."], 106 ["index2", "The global index of the second atom."] 107 ] 108 connect_atom._doc_desc = """ 109 This allows atoms to be connected in the internal structural object. The global index is normally equal to the PDB atom number minus 1. 110 """ 111 _build_doc(connect_atom) 112 113
114 - def create_diff_tensor_pdb(self, scale=1.8e-6, file='tensor.pdb', dir=None, force=False):
115 # Function intro text. 116 if self._exec_info.intro: 117 text = self._exec_info.ps3 + "structure.create_diff_tensor_pdb(" 118 text = text + "scale=" + repr(scale) 119 text = text + ", file=" + repr(file) 120 text = text + ", dir=" + repr(dir) 121 text = text + ", force=" + repr(force) + ")" 122 print(text) 123 124 # The argument checks. 125 arg_check.is_num(scale, 'scaling factor') 126 arg_check.is_str(file, 'file name') 127 arg_check.is_str(dir, 'directory name', can_be_none=True) 128 arg_check.is_bool(force, 'force flag') 129 130 # Execute the functional code. 131 generic_fns.structure.geometric.create_diff_tensor_pdb(scale=scale, file=file, dir=dir, force=force)
132 133 # The function doc info. 134 create_diff_tensor_pdb._doc_title = "Create a PDB file to represent the diffusion tensor." 135 create_diff_tensor_pdb._doc_title_short = "Diffusion tensor PDB file creation." 136 create_diff_tensor_pdb._doc_args = [ 137 ["scale", "Value for scaling the diffusion rates."], 138 ["file", "The name of the PDB file."], 139 ["dir", "The directory where the file is located."], 140 ["force", "A flag which, if set to True, will overwrite the any pre-existing file."] 141 ] 142 create_diff_tensor_pdb._doc_desc = """ 143 This creates a PDB file containing an artificial geometric structure to represent the diffusion tensor. A structure must have previously been read into relax. The diffusion tensor is represented by an ellipsoidal, spheroidal, or spherical geometric object with its origin located at the centre of mass (of the selected residues). This diffusion tensor PDB file can subsequently read into any molecular viewer. 144 145 There are four different types of residue within the PDB. The centre of mass of the selected residues is represented as a single carbon atom of the residue 'COM'. The ellipsoidal geometric shape consists of numerous H atoms of the residue 'TNS'. The axes of the tensor, when defined, are presented as the residue 'AXS' and consist of carbon atoms: one at the centre of mass and one at the end of each eigenvector. Finally, if Monte Carlo simulations were run and the diffusion tensor parameters were allowed to vary then there will be multiple 'SIM' residues, one for each simulation. These are essentially the same as the 'AXS' residue, representing the axes of the simulated tensors, and they will appear as a distribution. 146 147 As the Brownian rotational diffusion tensor is a measure of the rate of rotation about different axes - the larger the geometric object, the faster the diffusion of a molecule. For example the diffusion tensor of a water molecule is much larger than that of a macromolecule. 148 149 The effective global correlation time experienced by an XH bond vector, not to be confused with the Lipari and Szabo parameter tau_e, will be approximately proportional to the component of the diffusion tensor parallel to it. The approximation is not exact due to the multiexponential form of the correlation function of Brownian rotational diffusion. If an XH bond vector is parallel to the longest axis of the tensor, it will be unaffected by rotations about that axis, which are the fastest rotations of the molecule, and therefore its effective global correlation time will be maximal. 150 151 To set the size of the diffusion tensor within the PDB frame the unit vectors used to generate the geometric object are first multiplied by the diffusion tensor (which has the units of inverse seconds) then by the scaling factor (which has the units of second Angstroms and has the default value of 1.8e-6 s.Angstrom). Therefore the rotational diffusion rate per Angstrom is equal the inverse of the scale value (which defaults to 5.56e5 s^-1.Angstrom^-1). Using the default scaling value for spherical diffusion, the correspondence between global correlation time, Diso diffusion rate, and the radius of the sphere for a number of discrete cases will be: 152 153 _________________________________________________ 154 | | | | 155 | tm (ns) | Diso (s^-1) | Radius (Angstrom) | 156 |___________|_______________|___________________| 157 | | | | 158 | 1 | 1.67e8 | 300 | 159 | | | | 160 | 3 | 5.56e7 | 100 | 161 | | | | 162 | 10 | 1.67e7 | 30 | 163 | | | | 164 | 30 | 5.56e6 | 10 | 165 |___________|_______________|___________________| 166 167 168 The scaling value has been fixed to facilitate comparisons within or between publications, but can be changed to vary the size of the tensor geometric object if necessary. Reporting the rotational diffusion rate per Angstrom within figure legends would be useful. 169 170 To create the tensor PDB representation, a number of algorithms are utilised. Firstly the centre of mass is calculated for the selected residues and is represented in the PDB by a C atom. Then the axes of the diffusion are calculated, as unit vectors scaled to the appropriate length (multiplied by the eigenvalue Dx, Dy, Dz, Dpar, Dper, or Diso as well as the scale value), and a C atom placed at the position of this vector plus the centre of mass. Finally a uniform distribution of vectors on a sphere is generated using spherical coordinates. By incrementing the polar angle using an arccos distribution, a radial array of vectors representing latitude are created while incrementing the azimuthal angle evenly creates the longitudinal vectors. These unit vectors, which are distributed within the PDB frame and are of 1 Angstrom in length, are first rotated into the diffusion frame using a rotation matrix (the spherical diffusion tensor is not rotated). Then they are multiplied by the diffusion tensor matrix to extend the vector out to the correct length, and finally multiplied by the scale value so that the vectors reasonably superimpose onto the macromolecular structure. The last set of algorithms place all this information into a PDB file. The distribution of vectors are represented by H atoms and are all connected using PDB CONECT records. Each H atom is connected to its two neighbours on the both the longitude and latitude. This creates a geometric PDB object with longitudinal and latitudinal lines. 171 """ 172 _build_doc(create_diff_tensor_pdb) 173 174
175 - def create_vector_dist(self, length=2e-9, file='XH_dist.pdb', dir=None, symmetry=True, force=False):
176 # Function intro text. 177 if self._exec_info.intro: 178 text = self._exec_info.ps3 + "structure.create_vector_dist(" 179 text = text + "length=" + repr(length) 180 text = text + ", file=" + repr(file) 181 text = text + ", dir=" + repr(dir) 182 text = text + ", symmetry=" + repr(symmetry) 183 text = text + ", force=" + repr(force) + ")" 184 print(text) 185 186 # The argument checks. 187 arg_check.is_num(length, 'vector length') 188 arg_check.is_str(file, 'file name') 189 arg_check.is_str(dir, 'directory name', can_be_none=True) 190 arg_check.is_bool(symmetry, 'symmetry flag') 191 arg_check.is_bool(force, 'force flag') 192 193 # Execute the functional code. 194 generic_fns.structure.geometric.create_vector_dist(length=length, symmetry=symmetry, file=file, dir=dir, force=force)
195 196 # The function doc info. 197 create_vector_dist._doc_title = "Create a PDB file representation of the distribution of XH bond vectors." 198 create_vector_dist._doc_title_short = "XH vector distribution PDB representation." 199 create_vector_dist._doc_args = [ 200 ["length", "The length of the vectors in the PDB representation (meters)."], 201 ["file", "The name of the PDB file."], 202 ["dir", "The directory to place the file into."], 203 ["symmetry", "A flag which if True will create a second chain with reversed XH bond orientations."], 204 ["force", "A flag which if True will overwrite the file if it already exists."] 205 ] 206 create_vector_dist._doc_desc = """ 207 This creates a PDB file containing an artificial vectors, the length of which default to the length argument of 20 Angstrom. A structure must have previously been read into relax. The origin of the vector distribution is located at the centre of mass (of the selected residues). This vector distribution PDB file can subsequently be read into any molecular viewer. 208 209 Because of the symmetry of the diffusion tensor reversing the orientation of the XH bond vector has no effect. Therefore by setting the symmetry flag two chains 'A' and 'B' will be added to the PDB file whereby chain 'B' is chain 'A' with the XH bonds reversed. 210 """ 211 _build_doc(create_vector_dist) 212 213
214 - def get_pos(self, spin_id=None, ave_pos=True):
215 # Function intro text. 216 if self._exec_info.intro: 217 text = self._exec_info.ps3 + "structure.get_pos(" 218 text = text + "spin_id=" + repr(spin_id) 219 text = text + ", ave_pos=" + repr(ave_pos) + ")" 220 print(text) 221 222 # The argument checks. 223 arg_check.is_str(spin_id, 'spin identification string', can_be_none=True) 224 arg_check.is_bool(ave_pos, 'average position flag') 225 226 # Execute the functional code. 227 generic_fns.structure.main.get_pos(spin_id=spin_id, ave_pos=ave_pos)
228 229 # The function doc info. 230 get_pos._doc_title = "Extract the atomic positions from the loaded structures for the given spins." 231 get_pos._doc_title_short = "Atomic position extraction." 232 get_pos._doc_args = [ 233 ["spin_id", "The spin identification string."], 234 ["ave_pos", "A flag specifying if the position of the atom is to be averaged across models."] 235 ] 236 get_pos._doc_desc = """ 237 This allows the atomic positions of the spins to be extracted from the loaded structures. This is automatically performed by the structure.load_spins() user function, but if the sequence information is generated in other ways, this user function allows the structural information to be obtained. 238 239 If averaging the atomic positions, then average position of all models will be loaded into the spin container. Otherwise the positions from all models will be loaded separately. 240 """ 241 get_pos._doc_examples = """ 242 For a model-free backbone amide nitrogen analysis whereby the N spins have already been 243 created, to obtain the backbone N positions from the file '1F3Y.pdb' (which is a single 244 protein), type the following two user functions: 245 246 relax> structure.read_pdb('1F3Y.pdb') 247 relax> structure.get_pos(spin_id='@N') 248 """ 249 _build_doc(get_pos) 250 251
252 - def delete(self):
253 # Function intro text. 254 if self._exec_info.intro: 255 text = self._exec_info.ps3 + "structure.delete()" 256 print(text) 257 258 # Execute the functional code. 259 generic_fns.structure.main.delete()
260 261 # The function doc info. 262 delete._doc_title = "Delete all structural information." 263 delete._doc_title_short = "Structure deletion." 264 delete._doc_desc = """ 265 This will delete all the structural information from the current data pipe. All spin and sequence information loaded from these structures will be preserved - this only affects the structural data. 266 """ 267 delete._doc_examples = """ 268 Simply type: 269 270 relax> structure.delete() 271 """ 272 _build_doc(delete) 273 274
275 - def displacement(self, model_from=None, model_to=None, atom_id=None, centroid=None):
276 # Function intro text. 277 if self._exec_info.intro: 278 text = self._exec_info.ps3 + "structure.displacement(" 279 text = text + "model_from=" + repr(model_from) 280 text = text + ", model_to=" + repr(model_to) 281 text = text + ", atom_id=" + repr(atom_id) 282 text = text + ", centroid=" + repr(centroid) + ")" 283 print(text) 284 285 # The argument checks. 286 arg_check.is_int(model_from, 'model from', can_be_none=True) 287 arg_check.is_int(model_to, 'model to', can_be_none=True) 288 arg_check.is_str(atom_id, 'atom identification string', can_be_none=True) 289 arg_check.is_float_array(centroid, 'centroid position', can_be_none=True) 290 291 # Execute the functional code. 292 generic_fns.structure.main.displacement(model_from=model_from, model_to=model_to, atom_id=atom_id, centroid=centroid)
293 294 # The function doc info. 295 displacement._doc_title = "Determine the rotational and translational displacement between a set of models." 296 displacement._doc_title_short = "Rotational and translational displacement." 297 displacement._doc_args = [ 298 ["model_from", "The optional model number for the starting position of the displacement."], 299 ["model_to", "The optional model number for the ending position of the displacement."], 300 ["atom_id", "The atom identification string."], 301 ["centroid", "The alternative position of the centroid."] 302 ] 303 displacement._doc_desc = """ 304 This user function allows the rotational and translational displacement between two models of the same structure to be calculated. The information will be printed out in various formats and held in the relax data store. This is directional, so there is a starting and ending position for each displacement. If the starting and ending models are not specified, then the displacements in all directions between all models will be calculated. 305 306 The atom ID, which uses the same notation as the spin ID strings, can be used to restrict the displacement calculation to certain molecules, residues, or atoms. This is useful if studying domain motions, secondary structure rearrangements, amino acid side chain rotations, etc. 307 308 By supplying the position of the centroid, an alternative position than the standard rigid body centre is used as the focal point of the motion. The allows, for example, a pivot of a rotational domain motion to be specified. This is not a formally correct algorithm, all translations will be zero, but does give an indication to the amplitude of the pivoting angle. 309 """ 310 displacement._doc_examples = """ 311 To determine the rotational and translational displacements between all sets of models, type: 312 313 relax> structure.displacement() 314 315 316 To determine the displacement from model 5 to all other models, type: 317 318 relax> structure.displacement(model_from=5) 319 320 321 To determine the displacement of all models to model 5, type: 322 323 relax> structure.displacement(model_to=5) 324 325 326 327 To determine the displacement of model 2 to model 3, type one of: 328 329 relax> structure.displacement(2, 3) 330 relax> structure.displacement(model_from=2, model_to=3) 331 """ 332 _build_doc(displacement) 333 334
335 - def find_pivot(self, models=None, atom_id=None, init_pos=None):
336 # Function intro text. 337 if self._exec_info.intro: 338 text = self._exec_info.ps3 + "structure.find_pivot(" 339 text = text + "models=" + repr(models) 340 text = text + ", atom_id=" + repr(atom_id) 341 text = text + ", init_pos=" + repr(init_pos) + ")" 342 print(text) 343 344 # The argument checks. 345 arg_check.is_int_list(models, 'model list', can_be_none=True) 346 arg_check.is_str(atom_id, 'atom identification string', can_be_none=True) 347 arg_check.is_float_array(init_pos, 'initial pivot position', can_be_none=True) 348 349 # Execute the functional code. 350 generic_fns.structure.main.find_pivot(models=models, atom_id=atom_id, init_pos=init_pos)
351 352 # The function doc info. 353 find_pivot._doc_title = "Find the pivot point of the motion of a set of structures." 354 find_pivot._doc_title_short = "Pivot search." 355 find_pivot._doc_args = [ 356 ["models", "The list of models to use."], 357 ["atom_id", "The atom identification string."], 358 ["init_pos", "The initial position of the pivot."] 359 ] 360 find_pivot._doc_desc = """ 361 This is used to find pivot point of motion between a set of structural models. If the list of models is not supplied, then all models will be used. 362 363 The atom ID, which uses the same notation as the spin ID strings, can be used to restrict the search to certain molecules, residues, or atoms. For example to only use backbone heavy atoms in a protein, use the atom ID of '@N,C,CA,O', assuming those are the names of the atoms from the structural file. 364 365 By supplying the position of the centroid, an alternative position than the standard rigid body centre is used as the focal point of the superimposition. The allows, for example, the superimposition about a pivot point. 366 """ 367 _build_doc(find_pivot) 368 369
370 - def load_spins(self, spin_id=None, ave_pos=True):
371 # Function intro text. 372 if self._exec_info.intro: 373 text = self._exec_info.ps3 + "structure.load_spins(" 374 text = text + "spin_id=" + repr(spin_id) 375 text = text + ", ave_pos=" + repr(ave_pos) + ")" 376 print(text) 377 378 # The argument checks. 379 arg_check.is_str(spin_id, 'spin identification string', can_be_none=True) 380 arg_check.is_bool(ave_pos, 'average position flag') 381 382 # Execute the functional code. 383 generic_fns.structure.main.load_spins(spin_id=spin_id, ave_pos=ave_pos)
384 385 # The function doc info. 386 load_spins._doc_title = "Load spins from the structure into the relax data store." 387 load_spins._doc_title_short = "Loading spins from structure." 388 load_spins._doc_args = [ 389 ["spin_id", "The spin identification string."], 390 ["ave_pos", "A flag specifying if the position of the atom is to be averaged across models."]] 391 load_spins._doc_desc = """ 392 This allows a sequence to be generated within the relax data store using the atomic information from the structure already associated with this data pipe. The spin ID string is used to select which molecules, which residues, and which atoms will be recognised as spin systems within relax. If the spin ID is left unspecified, then all molecules, residues, and atoms will be placed within the data store (and all atoms will be treated as spins). 393 394 If averaging the atomic positions, then average position of all models will be loaded into the spin container. Otherwise the positions from all models will be loaded separately. 395 """ 396 load_spins._doc_examples = """ 397 For a model-free backbone amide nitrogen analysis, to load just the backbone N sequence from 398 the file '1F3Y.pdb' (which is a single protein), type the following two user functions: 399 400 relax> structure.read_pdb('1F3Y.pdb') 401 relax> structure.load_spins(spin_id='@N') 402 403 404 For an RNA analysis of adenine C8 and C2, guanine C8 and N1, cytidine C5 and C6, and uracil 405 N3, C5, and C6, type the following series of commands (assuming that the PDB file with this 406 atom naming has already been read): 407 408 relax> structure.load_spins(spin_id=":A@C8") 409 relax> structure.load_spins(spin_id=":A@C2") 410 relax> structure.load_spins(spin_id=":G@C8") 411 relax> structure.load_spins(spin_id=":G@N1") 412 relax> structure.load_spins(spin_id=":C@C5") 413 relax> structure.load_spins(spin_id=":C@C6") 414 relax> structure.load_spins(spin_id=":U@N3") 415 relax> structure.load_spins(spin_id=":U@C5") 416 relax> structure.load_spins(spin_id=":U@C6") 417 418 Alternatively using some Python programming: 419 420 relax> for id in [":A@C8", ":A@C2", ":G@C8", ":G@N1", ":C@C5", ":C@C6", ":U@N3", ":U@C5", ":U@C6"]: 421 relax> structure.load_spins(spin_id=id) 422 """ 423 _build_doc(load_spins) 424 425
426 - def read_pdb(self, file=None, dir=None, read_mol=None, set_mol_name=None, read_model=None, set_model_num=None, parser='internal'):
427 # Function intro text. 428 if self._exec_info.intro: 429 text = self._exec_info.ps3 + "structure.read_pdb(" 430 text = text + "file=" + repr(file) 431 text = text + ", dir=" + repr(dir) 432 text = text + ", read_mol=" + repr(read_mol) 433 text = text + ", set_mol_name=" + repr(set_mol_name) 434 text = text + ", read_model=" + repr(read_model) 435 text = text + ", set_model_num=" + repr(set_model_num) 436 text = text + ", parser=" + repr(parser) + ")" 437 print(text) 438 439 # The argument checks. 440 arg_check.is_str(file, 'file name') 441 arg_check.is_str(dir, 'directory name', can_be_none=True) 442 arg_check.is_int_or_int_list(read_mol, 'read molecule number', can_be_none=True) 443 arg_check.is_int_or_int_list(read_model, 'read model', can_be_none=True) 444 arg_check.is_int_or_int_list(set_model_num, 'set model numbers', can_be_none=True) 445 arg_check.is_str_or_str_list(set_mol_name, 'set molecule names', can_be_none=True) 446 arg_check.is_str(parser, 'PDB parser') 447 448 # Execute the functional code. 449 generic_fns.structure.main.read_pdb(file=file, dir=dir, read_mol=read_mol, set_mol_name=set_mol_name, read_model=read_model, set_model_num=set_model_num, parser=parser)
450 451 # The function doc info. 452 read_pdb._doc_title = "Reading structures from PDB files." 453 read_pdb._doc_title_short = "PDB reading." 454 read_pdb._doc_args = [ 455 ["file", "The name of the PDB file."], 456 ["dir", "The directory where the file is located."], 457 ["read_mol", "If set, only the given molecule(s) will be read. The molecules are determined differently by the different parsers, but are numbered consecutively from 1. If unset, then all molecules will be loaded. By providing a list of numbers such as [1, 2], multiple molecules will be read."], 458 ["set_mol_name", "Set the names of the read molecules. If unset, then the molecules will be automatically labelled based on the file name or other information. This can either be a single name or a list of names."], 459 ["read_model", "If set, only the given model number(s) from the PDB file will be read. This can be a single number or list of numbers."], 460 ["set_model_num", "Set the model numbers of the loaded molecules. If unset, then the PDB model numbers will be preserved if they exist. This can be a single number or list of numbers."], 461 ["parser", "The PDB parser used to read the file."]] 462 read_pdb._doc_desc = """ 463 The reading of PDB files into relax is quite a flexible procedure allowing for both models, defined as an ensemble of the same molecule but with different atomic positions, and different molecules within the same model. One of more molecules can exist in one or more models. The flexibility allows PDB models to be converted into different molecules and different PDB files loaded as the same molecule but as different models. 464 465 A few different PDB parsers can be used to read the structural data. The choice of which to use depends on whether your PDB file is supported by that reader. These are selected by setting the 'parser' argument to one of: 466 467 'internal' - a fast PDB parser built into relax. 468 'scientific' - the Scientific Python PDB parser. 469 470 In a PDB file, the models are specified by the MODEL PDB record. All the supported PDB readers in relax recognise this. The molecule level is quite different between the Scientific Python and internal readers. For how Scientific Python defines molecules, please see its documentation. The internal reader is far simpler as it defines molecules using the TER PDB record. In both cases, the molecules will be numbered consecutively from 1. 471 472 Setting the molecule name allows the molecule within the PDB (within one model) to have a custom name. If not set, then the molecules will be named after the file name, with the molecule number appended if more than one exists. 473 474 Note that relax will complain if it cannot work out what to do. 475 476 This is able to handle uncompressed, bzip2 compressed files, or gzip compressed files automatically. The full file name including extension can be supplied, however, if the file cannot be found, this function will search for the file name with '.bz2' appended followed by the file name with '.gz' appended. 477 """ 478 read_pdb._doc_examples = """ 479 To load all structures from the PDB file 'test.pdb' in the directory '~/pdb', including all 480 models and all molecules, type one of: 481 482 relax> structure.read_pdb('test.pdb', '~/pdb') 483 relax> structure.read_pdb(file='test.pdb', dir='pdb') 484 485 486 To load the 10th model from the file 'test.pdb' using the Scientific Python PDB parser and 487 naming it 'CaM', use one of: 488 489 relax> structure.read_pdb('test.pdb', read_model=10, set_mol_name='CaM', 490 parser='scientific') 491 relax> structure.read_pdb(file='test.pdb', read_model=10, set_mol_name='CaM', 492 parser='scientific') 493 494 495 To load models 1 and 5 from the file 'test.pdb' as two different structures of the same 496 model, type one of: 497 498 relax> structure.read_pdb('test.pdb', read_model=[1, 5], set_model_num=[1, 1]) 499 relax> structure.read_pdb('test.pdb', set_mol_name=['CaM_1', 'CaM_2'], read_model=[1, 5], 500 set_model_num=[1, 1]) 501 502 To load the files 'lactose_MCMM4_S1_1.pdb', 'lactose_MCMM4_S1_2.pdb', 503 'lactose_MCMM4_S1_3.pdb' and 'lactose_MCMM4_S1_4.pdb' as models, type the following sequence 504 of commands: 505 506 relax> structure.read_pdb('lactose_MCMM4_S1_1.pdb', set_mol_name='lactose_MCMM4_S1', 507 set_model_num=1) 508 relax> structure.read_pdb('lactose_MCMM4_S1_2.pdb', set_mol_name='lactose_MCMM4_S1', 509 set_model_num=2) 510 relax> structure.read_pdb('lactose_MCMM4_S1_3.pdb', set_mol_name='lactose_MCMM4_S1', 511 set_model_num=3) 512 relax> structure.read_pdb('lactose_MCMM4_S1_4.pdb', set_mol_name='lactose_MCMM4_S1', 513 set_model_num=4) 514 """ 515 _build_doc(read_pdb) 516 517
518 - def read_xyz(self, file=None, dir=None, read_mol=None, set_mol_name=None, read_model=None, set_model_num=None):
519 # Function intro text. 520 if self._exec_info.intro: 521 text = self._exec_info.ps3 + "structure.read_xyz(" 522 text = text + "file=" + repr(file) 523 text = text + ", dir=" + repr(dir) 524 text = text + ", read_mol=" + repr(read_mol) 525 text = text + ", set_mol_name=" + repr(set_mol_name) 526 text = text + ", read_model=" + repr(read_model) 527 text = text + ", set_model_num=" + repr(set_model_num) 528 text = text + ")" 529 print(text) 530 531 # The argument checks. 532 arg_check.is_str(file, 'file name') 533 arg_check.is_str(dir, 'directory name', can_be_none=True) 534 arg_check.is_int_or_int_list(read_mol, 'read molecule number', can_be_none=True) 535 arg_check.is_int_or_int_list(read_model, 'read model', can_be_none=True) 536 arg_check.is_int_or_int_list(set_model_num, 'set model numbers', can_be_none=True) 537 arg_check.is_str_or_str_list(set_mol_name, 'set molecule names', can_be_none=True) 538 539 # Execute the functional code. 540 generic_fns.structure.main.read_xyz(file=file, dir=dir, read_mol=read_mol, set_mol_name=set_mol_name, read_model=read_model, set_model_num=set_model_num)
541 542 543 # The function doc info. 544 read_xyz._doc_title = "Reading structures from XYZ files." 545 read_xyz._doc_title_short = "XYZ reading." 546 read_xyz._doc_args = [ 547 ["file", "The name of the XYZ file."], 548 ["dir", "The directory where the file is located."], 549 ["read_mol", "If set, only the given molecule(s) will be read. The molecules are determined differently by the different parsers, but are numbered consecutively from 1. If unset, then all molecules will be loaded. By providing a list of numbers such as [1, 2], multiple molecules will be read."], 550 ["set_mol_name", "Set the names of the read molecules. If unset, then the molecules will be automatically labelled based on the file name or other information. This can either be a single name or a list of names."], 551 ["read_model", "If set, only the given model number(s) from the PDB file will be read. This can be a single number or list of numbers."], 552 ["set_model_num", "Set the model numbers of the loaded molecules. If unset, then the PDB model numbers will be preserved if they exist. This can be a single number or list of numbers."]] 553 read_xyz._doc_desc = """ 554 The XYZ files with different models, which defined as an ensemble of the same molecule but with different atomic positions, can be read into relax. If there are several molecules in one xyz file, please seperate them into different files and then load them individually. Loading different models and different molecules is controlled by the four keyword arguments 'read_mol', 'set_mol_name', 'read_model', and 'set_model_num'. 555 556 The 'set_mol_name' argument is used to name the molecules within the XYZ (within one model). If not set, then the molecules will be named after the file name, with the molecule number appended if more than one exists. 557 558 Note that relax will complain if it cannot work out what to do. 559 """ 560 read_xyz._doc_examples = """ 561 To load all structures from the XYZ file 'test.xyz' in the directory '~/xyz', including all 562 models and all molecules, type one of: 563 564 relax> structure.read_xyz('test.xyz', '~/xyz') 565 relax> structure.read_xyz(file='test.xyz', dir='xyz') 566 567 568 To load the 10th model from the file 'test.xyz' and 569 naming it 'CaM', use one of: 570 571 relax> structure.read_xyz('test.xyz', read_model=10, set_mol_name='CaM') 572 relax> structure.read_xyz(file='test.xyz', read_model=10, set_mol_name='CaM') 573 574 575 To load models 1 and 5 from the file 'test.xyz' as two different structures of the same 576 model, type one of: 577 578 relax> structure.read_xyz('test.xyz', read_model=[1, 5], set_model_num=[1, 1]) 579 relax> structure.read_xyz('test.xyz', set_mol_name=['CaM_1', 'CaM_2'], read_model=[1, 5], 580 set_model_num=[1, 1]) 581 582 To load the files 'test_1.xyz', 'test_2.xyz', 'test_3.xyz' and 'test_4.xyz' as models, type the 583 following sequence of commands: 584 585 relax> structure.read_xyz('test_1.xyz', set_mol_name='test_1', 586 set_model_num=1) 587 relax> structure.read_xyz('test_2.xyz', set_mol_name='test_2', 588 set_model_num=2) 589 relax> structure.read_xyz('test_3.xyz', set_mol_name='test_3', 590 set_model_num=3) 591 relax> structure.read_xyz('test_4.xyz', set_mol_name='test_4', 592 set_model_num=4) 593 """ 594 _build_doc(read_xyz) 595 596
597 - def rotate(self, R=None, origin=None, model=None, atom_id=None):
598 # Function intro text. 599 if self._exec_info.intro: 600 text = self._exec_info.ps3 + "structure.rotate(" 601 text = text + "R=" + repr(R) 602 text = text + ", origin=" + repr(origin) 603 text = text + ", model=" + repr(model) 604 text = text + ", atom_id=" + repr(atom_id) + ")" 605 print(text) 606 607 # The argument checks. 608 arg_check.is_float_matrix(R, 'rotation matrix', dim=(3, 3)) 609 arg_check.is_float_array(origin, 'origin of rotation', size=3, can_be_none=True) 610 arg_check.is_int(model, 'model', can_be_none=True) 611 arg_check.is_str(atom_id, 'atom identification string', can_be_none=True) 612 613 # Execute the functional code. 614 generic_fns.structure.main.rotate(R=R, origin=origin, model=model, atom_id=atom_id)
615 616 # The function doc info. 617 rotate._doc_title = "Rotate the internal structural object about the given origin by the rotation matrix." 618 rotate._doc_title_short = "Structure rotation." 619 rotate._doc_args = [ 620 ["R", "The rotation matrix in forwards rotation notation."], 621 ["origin", "The origin or pivot of the rotation."], 622 ["model", "The model to rotate (which if not set will cause all models to be rotated)."] 623 ] 624 rotate._doc_desc = """ 625 This is used to rotate the internal structural data by the given rotation matrix. If the origin is supplied, then this will act as the pivot of the rotation. Otherwise, all structural data will be rotated about the point [0, 0, 0]. The model argument can be used to rotate specific models. 626 """ 627 _build_doc(rotate) 628 629
630 - def superimpose(self, models=None, method='fit to mean', atom_id=None, centroid=None):
631 # Function intro text. 632 if self._exec_info.intro: 633 text = self._exec_info.ps3 + "structure.superimpose(" 634 text = text + "models=" + repr(models) 635 text = text + ", method=" + repr(method) 636 text = text + ", atom_id=" + repr(atom_id) 637 text = text + ", centroid=" + repr(centroid) + ")" 638 print(text) 639 640 # The argument checks. 641 arg_check.is_int_list(models, 'model list', can_be_none=True) 642 arg_check.is_str(method, 'superimposition method') 643 arg_check.is_str(atom_id, 'atom identification string', can_be_none=True) 644 arg_check.is_float_array(centroid, 'centroid position', can_be_none=True) 645 646 # Execute the functional code. 647 generic_fns.structure.main.superimpose(models=models, method=method, atom_id=atom_id, centroid=centroid)
648 649 # The function doc info. 650 superimpose._doc_title = "Superimpose a set of models of the same structure." 651 superimpose._doc_title_short = "Structural superimposition." 652 superimpose._doc_args = [ 653 ["models", "The list of models to superimpose."], 654 ["method", "The superimposition method."], 655 ["atom_id", "The atom identification string."], 656 ["centroid", "The alternative position of the centroid."] 657 ] 658 superimpose._doc_desc = """ 659 This allows a set of models of the same structure to be superimposed to each other. Two superimposition methods are currently supported: 660 661 'fit to mean': All models are fit to the mean structure. This is the default and most accurate method for an ensemble description. It is an iterative method which first calculates a mean structure and then fits each model to the mean structure using the Kabsch algorithm. This is repeated until convergence. 662 'fit to first': This is quicker but is not as accurate for an ensemble description. The Kabsch algorithm is used to rotate and translate each model to be superimposed onto the first model. 663 664 If the list of models is not supplied, then all models will be superimposed. 665 666 The atom ID, which uses the same notation as the spin ID strings, can be used to restrict the superimpose calculation to certain molecules, residues, or atoms. For example to only superimpose backbone heavy atoms in a protein, use the atom ID of '@N,C,CA,O', assuming those are the names of the atoms from the structural file. 667 668 By supplying the position of the centroid, an alternative position than the standard rigid body centre is used as the focal point of the superimposition. The allows, for example, the superimposition about a pivot point. 669 """ 670 superimpose._doc_examples = """ 671 To superimpose all sets of models, type one of: 672 673 relax> structure.superimpose() 674 relax> structure.superimpose(method='fit to mean') 675 676 677 To superimpose the models 1, 2, 3, 5 onto model 4, type: 678 679 relax> structure.superimpose(models=[4, 1, 2, 3, 5], method='fit to first') 680 681 682 To superimpose an ensemble of protein structures using only the backbone heavy atoms, type 683 one of: 684 685 relax> structure.superimpose(atom_id='@N,C,CA,O') 686 relax> structure.superimpose(method='fit to mean', atom_id='@N,C,CA,O') 687 688 689 To superimpose model 2 onto model 3 using backbone heavy atoms, type one of: 690 691 relax> structure.superimpose([3, 2], 'fit to first', '@N,C,CA,O') 692 relax> structure.superimpose(models=[3, 2], method='fit to first', atom_id='@N,C,CA,O') 693 """ 694 _build_doc(superimpose) 695 696
697 - def translate(self, T=None, model=None, atom_id=None):
698 # Function intro text. 699 if self._exec_info.intro: 700 text = self._exec_info.ps3 + "structure.translate(" 701 text = text + "T=" + repr(T) 702 text = text + ", model=" + repr(model) 703 text = text + ", atom_id=" + repr(atom_id) + ")" 704 print(text) 705 706 # The argument checks. 707 arg_check.is_float_array(T, 'translation vector', size=3) 708 arg_check.is_int(model, 'model', can_be_none=True) 709 arg_check.is_str(atom_id, 'atom identification string', can_be_none=True) 710 711 # Execute the functional code. 712 generic_fns.structure.main.translate(T=T, model=model, atom_id=atom_id)
713 714 # The function doc info. 715 translate._doc_title = "Laterally displace the internal structural object by the translation vector." 716 translate._doc_title_short = "Structure translation." 717 translate._doc_args = [ 718 ["T", "The translation vector."], 719 ["model", "The model to translate (which if not set will cause all models to be translate)."], 720 ["atom_id", "The atom identification string."] 721 ] 722 translate._doc_desc = """ 723 This is used to translate the internal structural data by the given translation vector. The model argument can be used to translate specific models. 724 """ 725 _build_doc(translate) 726 727
728 - def vectors(self, attached='H', spin_id=None, model=None, verbosity=1, ave=True, unit=True):
729 # Function intro text. 730 if self._exec_info.intro: 731 text = self._exec_info.ps3 + "structure.vectors(" 732 text = text + "attached=" + repr(attached) 733 text = text + ", spin_id=" + repr(spin_id) 734 text = text + ", model=" + repr(model) 735 text = text + ", verbosity=" + repr(verbosity) 736 text = text + ", ave=" + repr(ave) 737 text = text + ", unit=" + repr(unit) + ")" 738 print(text) 739 740 # The argument checks. 741 arg_check.is_str(attached, 'attached atom') 742 arg_check.is_str(spin_id, 'spin identification string', can_be_none=True) 743 arg_check.is_int(model, 'model', can_be_none=True) 744 arg_check.is_int(verbosity, 'verbosity level') 745 arg_check.is_bool(ave, 'average vector flag') 746 arg_check.is_bool(unit, 'unit vector flag') 747 748 # Execute the functional code. 749 generic_fns.structure.main.vectors(attached=attached, spin_id=spin_id, model=model, verbosity=verbosity, ave=ave, unit=unit)
750 751 # The function doc info. 752 vectors._doc_title = "Extract and store the bond vectors from the loaded structures in the spin container." 753 vectors._doc_title_short = "Bond vector extraction." 754 vectors._doc_args = [ 755 ["attached", "The name of the second atom which attached to the spin of interest. Regular expression is allowed, for example 'H*'."], 756 ["spin_id", "The spin identification string."], 757 ["model", "The model to extract bond vectors from (which if not set will cause the vectors of all models to be extracted)."], 758 ["verbosity", "The amount of information to print to screen. Zero corresponds to minimal output while higher values increase the amount of output. The default value is 1."], 759 ["ave", "A flag which if True will cause the bond vectors from all models to be averaged. If vectors from only one model is extracted, this argument will have no effect."], 760 ["unit", "A flag which if True will cause the unit vector to calculated rather than the full length bond vector."] 761 ] 762 vectors._doc_desc = """ 763 For a number of types of analysis, bond vectors or unit bond vectors are required for the calculations. This user function allows these vectors to be extracted from the loaded structures. The bond vector will be that from the atom associated with the spin system loaded in relax to the bonded atom specified by the 'attached' argument. For example if the attached atom is set to 'H' and the protein backbone amide spins 'N' are loaded, the all 'N-H' vectors will be extracted. But if set to 'CA', all atoms named 'CA' in the structures will be searched for and all 'N-Ca' bond vectors will be extracted. 764 765 The extraction of vectors can occur in a number of ways. For example if an NMR structure with N models is loaded or if multiple molecules, from any source, of the same compound are loaded as different models, there are three options for extracting the bond vector. Firstly the bond vector of a single model can be extracted by setting the model number. Secondly the bond vectors from all models can be extracted if the model number is not set and the average vector flag is not set. Thirdly, if the model number is not set and the average vector flag is set, then a single vector which is the average for all models will be calculated. 766 """ 767 vectors._doc_examples = """ 768 To extract the XH vectors of the backbone amide nitrogens where in the PDB file the backbone 769 nitrogen is called 'N' and the attached atom is called 'H', assuming multiple types of 770 spin have already been loaded, type one of: 771 772 relax> structure.vectors(spin_id='@N') 773 relax> structure.vectors('H', spin_id='@N') 774 relax> structure.vectors(attached='H', spin_id='@N') 775 776 If the attached atom is called 'HN', type: 777 778 relax> structure.vectors(attached='HN', spin_id='@N') 779 780 For the 'CA' spin bonded to the 'HA' proton, type: 781 782 relax> structure.vectors(attached='HA', spin_id='@CA') 783 784 785 If you are working with RNA, you can use the residue name identifier to calculate the 786 vectors for each residue separately. For example to calculate the vectors for all possible 787 spins in the bases, type: 788 789 relax> structure.vectors('H2', spin_id=':A') 790 relax> structure.vectors('H8', spin_id=':A') 791 relax> structure.vectors('H1', spin_id=':G') 792 relax> structure.vectors('H8', spin_id=':G') 793 relax> structure.vectors('H5', spin_id=':C') 794 relax> structure.vectors('H6', spin_id=':C') 795 relax> structure.vectors('H3', spin_id=':U') 796 relax> structure.vectors('H5', spin_id=':U') 797 relax> structure.vectors('H6', spin_id=':U') 798 799 Alternatively, assuming the desired spins have been loaded, regular expression can be used: 800 801 relax> structure.vectors('H*') 802 """ 803 _build_doc(vectors) 804 805
806 - def write_pdb(self, file=None, dir=None, model_num=None, compress_type=0, force=False):
807 # Function intro text. 808 if self._exec_info.intro: 809 text = self._exec_info.ps3 + "structure.write_pdb(" 810 text = text + "file=" + repr(file) 811 text = text + ", dir=" + repr(dir) 812 text = text + ", model_num=" + repr(model_num) 813 text = text + ", compress_type=" + repr(compress_type) 814 text = text + ", force=" + repr(force) + ")" 815 print(text) 816 817 # The argument checks. 818 arg_check.is_str(file, 'file name') 819 arg_check.is_str(dir, 'directory name', can_be_none=True) 820 arg_check.is_int(model_num, 'model number', can_be_none=True) 821 arg_check.is_int(compress_type, 'compression type') 822 arg_check.is_bool(force, 'force flag') 823 824 # Execute the functional code. 825 generic_fns.structure.main.write_pdb(file=file, dir=dir, model_num=model_num, compress_type=compress_type, force=force)
826 827 # The function doc info. 828 write_pdb._doc_title = "Writing structures to a PDB file." 829 write_pdb._doc_title_short = "PDB writing." 830 write_pdb._doc_args = [["file", "The name of the PDB file."], 831 ["dir", "The directory where the file is located."], 832 ["model_num", "Restrict the writing of structural data to a single model in the PDB file."], 833 ["compress_type", "The type of compression to use when creating the file."], 834 ["force", "A flag which if set to True will cause any pre-existing files to be overwritten."]] 835 write_pdb._doc_desc = """ 836 This will write all of the structural data loaded in the current data pipe to be converted to the PDB format and written to file. Specifying the model number allows single models to be output. 837 838 The default behaviour of this function is to not compress the file. The compression can, however, be changed to either bzip2 or gzip compression. If the '.bz2' or '.gz' extension is not included in the file name, it will be added. This behaviour is controlled by the compress_type argument which can be set to 839 840 0: No compression (no file extension). 841 1: bzip2 compression ('.bz2' file extension). 842 2: gzip compression ('.gz' file extension). 843 """ 844 write_pdb._doc_examples = """ 845 To write all models and molecules to the PDB file 'ensemble.pdb' within the directory '~/pdb', type 846 one of: 847 848 relax> structure.write_pdb('ensemble.pdb', '~/pdb') 849 relax> structure.write_pdb(file='ensemble.pdb', dir='pdb') 850 851 852 To write model number 3 into the new file 'test.pdb', use one of: 853 854 relax> structure.write_pdb('test.pdb', model_num=3) 855 relax> structure.write_pdb(file='test.pdb', model_num=3) 856 """ 857 _build_doc(write_pdb)
858