Package Pmv :: Module fileCommands
[hide private]
[frames] | no frames]

Source Code for Module Pmv.fileCommands

   1  ############################################################################# 
   2  # 
   3  # Authors: Michel F. SANNER, Ruth Huey, Daniel Stoffler 
   4  # 
   5  # Copyright: M. Sanner TSRI 2000 
   6  # 
   7  ############################################################################# 
   8   
   9   
  10  """ 
  11  This Module implements commands to load molecules from files in the following 
  12  formats: 
  13      PDB: Brookhaven Data Bank format 
  14      PQR: Don Bashford's modified PDB format used by MEAD 
  15      PDBQ: Autodock file format 
  16      PDBQS: Autodock file format 
  17      PDBQT: Autodock file format 
  18      MMCIF: Macromolecular Crystallographic Information File 
  19  The module implements commands to save molecules in additional formats:     
  20      STL: Stereolithography file format 
  21  """ 
  22   
  23  from ViewerFramework.VFCommand import CommandGUI 
  24  from Pmv.mvCommand import MVCommand 
  25  from MolKit.protein import Protein 
  26  from MolKit.pdbParser import PdbParser, PdbqParser, PdbqsParser, PdbqtParser, PQRParser 
  27  from MolKit.pdbWriter import PdbWriter, PdbqWriter, PdbqsWriter, PdbqtWriter 
  28  from MolKit.pqrWriter import PqrWriter 
  29  from MolKit.groParser import groParser 
  30  from MolKit.molecule import Atom, AtomSet 
  31  from MolKit.mol2Parser import Mol2Parser 
  32  from MolKit.mmcifParser import MMCIFParser 
  33  from MolKit.mmcifWriter import MMCIFWriter 
  34   
  35  import types, os, sys, string 
  36  import Numeric 
  37  import Tkinter, Pmw 
  38  ##  from ViewerFramework.gui import InputFormDescr 
  39  from mglutil.gui.InputForm.Tk.gui import InputFormDescr 
  40  from mglutil.gui.BasicWidgets.Tk.customizedWidgets import SaveButton 
  41  from MolKit.tree import TreeNode, TreeNodeSet 
  42  from MolKit.molecule import Atom 
  43  from tkMessageBox import * 
  44   
  45  pdbDescr = """ 
  46  By default the PDB writer will create the following records: 
  47  - ATOM and TER records 
  48  - CONECT records when bond information is available (bonds have been built by distance, 
  49    the user defined bond information or the original file contained connectivity information. 
  50  - HELIX, SHEET, TURN when secondary structure information is available (either from the original 
  51    file or computed). 
  52   
  53  Other records can be created from the molecular data structure such as : 
  54  - HYDBND when hydrogne bonds information is available. 
  55   
  56  The information below can be found at http://www.rcsb.org/pdb/docs/format/pdbguide2.2/guide2.2_frame.html 
  57   
  58  The PDBQ format is similar to the PDB format but has charges information in the field adjacent to the 
  59  temperature factor. 
  60  The PDBQS format is the PDBQS format with some solvation information at the end of the ATOM/HETATM records. 
  61  The PDBQT format is the PDBQ format with autodock element information at the end of the ATOM/HETATM records. 
  62   
  63  1- TITLE SECTION 
  64   
  65  HEADER  
  66  ---------------------------------- 
  67  The HEADER record uniquely identifies a PDB entry through the idCode field. 
  68  This record also provides a classification for the entry. Finally, it contains 
  69  the date the coordinates were deposited at the PDB. 
  70   
  71  OBSLTE  
  72  ---------------------------------- 
  73  OBSLTE appears in entries which have been withdrawn from distribution. 
  74  This record acts as a flag in an entry which has been withdrawn from the PDB's 
  75  full release. It indicates which, if any, new entries have replaced the withdrawn entry. 
  76  The format allows for the case of multiple new entries replacing one existing entry.    
  77   
  78  TITLE  
  79  ---------------------------------- 
  80  The TITLE record contains a title for the experiment or analysis that is represented 
  81  in the entry. It should identify an entry in the PDB in the same way that a title 
  82  identifies a paper. 
  83   
  84  CAVEAT  
  85  ---------------------------------- 
  86  CAVEAT warns of severe errors in an entry. Use caution when using an entry containing 
  87  this record.  
  88   
  89  COMPND  
  90  ---------------------------------- 
  91  The COMPND record describes the macromolecular contents of an entry. Each macromolecule 
  92  found in the entry is described by a set of token: value pairs, and is referred to as a 
  93  COMPND record component. Since the concept of a molecule is difficult to specify exactly, 
  94  PDB staff may exercise editorial judgment in consultation with depositors in assigning 
  95  these names. 
  96  For each macromolecular component, the molecule name, synonyms, number assigned 
  97  by the Enzyme Commission (EC), and other relevant details are specified.    
  98   
  99  SOURCE  
 100  ---------------------------------- 
 101  The SOURCE record specifies the biological and/or chemical source of each biological 
 102  molecule in the entry. Sources are described by both the common name and the scientific 
 103  name, e.g., genus and species. Strain and/or cell-line for immortalized cells are given 
 104  when they help to uniquely identify the biological entity studied. 
 105   
 106  KEYWDS  
 107  ---------------------------------- 
 108  The KEYWDS record contains a set of terms relevant to the entry. Terms in the KEYWDS 
 109  record provide a simple means of categorizing entries and may be used to generate 
 110  index files. This record addresses some of the limitations found in the classification 
 111  field of the HEADER record. It provides the opportunity to add further annotation to 
 112  the entry in a concise and computer-searchable fashion. 
 113   
 114  EXPDTA  
 115  ---------------------------------- 
 116  The EXPDTA record presents information about the experiment. 
 117  The EXPDTA record identifies the experimental technique used. This may refer to the 
 118  type of radiation and sample, or include the spectroscopic or modeling technique. 
 119  Permitted values include: 
 120     ELECTRON DIFFRACTION 
 121     FIBER DIFFRACTION 
 122     FLUORESCENCE TRANSFER 
 123     NEUTRON DIFFRACTION 
 124     NMR 
 125     THEORETICAL MODEL 
 126     X-RAY DIFFRACTION   
 127   
 128  AUTHOR  
 129  ---------------------------------- 
 130  The AUTHOR record contains the names of the people responsible for the contents of 
 131  the entry.  
 132   
 133  REVDAT  
 134  ---------------------------------- 
 135  REVDAT records contain a history of the modifications made to an entry since its release. 
 136   
 137  SPRSDE  
 138  ---------------------------------- 
 139  The SPRSDE records contain a list of the ID codes of entries that were made obsolete 
 140  by the given coordinate entry and withdrawn from the PDB release set. One entry may 
 141  replace many. It is PDB policy that only the principal investigator of a structure has 
 142  the authority to withdraw it. 
 143   
 144  JRNL  
 145  ---------------------------------- 
 146  The JRNL record contains the primary literature citation that describes the experiment 
 147  which resulted in the deposited coordinate set. There is at most one JRNL reference per 
 148  entry. If there is no primary reference, then there is no JRNL reference. Other references 
 149  are given in REMARK 1. 
 150  PDB is in the process of linking and/or adding all references to CitDB, the literature 
 151  database used by the Genome Data Base (available at URL 
 152  http://gdbwww.gdb.org/gdb-bin/genera/genera/citation/Citation). 
 153   
 154  REMARK  
 155  ---------------------------------- 
 156  REMARK records present experimental details, annotations, comments, and information not 
 157  included in other records. In a number of cases, REMARKs are used to expand the contents 
 158  of other record types. A new level of structure is being used for some REMARK records. 
 159  This is expected to facilitate searching and will assist in the conversion to a relational 
 160  database. 
 161   
 162  REMARK 1 
 163  ---------------------------------- 
 164  REMARK 1 lists important publications related to the structure presented in the entry. 
 165  These citations are chosen by the depositor. They are listed in reverse-chronological 
 166  order. Citations are not repeated from the JRNL records. After the first blank record 
 167  and the REFERENCE sub-record, the sub-record types for REMARK 1 are the same as in the 
 168  JRNL sub-record types. For details, see the JRNL section. 
 169   
 170  PDB is in the process of linking and/or adding references to CitDB, the literature 
 171  database of the Genome Data Base (available at URL 
 172  http://gdbwww.gdb.org/gdb-bin/genera/genera/citation/Citation). 
 173   
 174  REMARK 2  
 175  ---------------------------------- 
 176  REMARK 2 states the highest resolution, in Angstroms, that was used in building the model. 
 177  As with all the remarks, the first REMARK 2 record is empty and is used as a spacer. 
 178   
 179  REMARK 3  
 180  ---------------------------------- 
 181  REMARK 3 presents information on refinement program(s) used and the related statistics. 
 182  For non-diffraction studies, REMARK 3 is used to describe any refinement done, but its 
 183  format in those cases is mostly free text. 
 184   
 185  If more than one refinement package was used, they may be named in 
 186  'OTHER REFINEMENT REMARKS'. However, Remark 3 statistics are given for the final 
 187  refinement run. 
 188   
 189  Refinement packages are being enhanced to output PDB REMARK 3. A token: value 
 190  template style facilitates parsing. Spacer REMARK 3 lines are interspersed for 
 191  visually organizing the information. 
 192   
 193  The templates below have been adopted in consultation with program authors. PDB is 
 194  continuing this dialogue with program authors, and expects the library of PDB records 
 195  output by the programs to greatly increase in the near future. 
 196   
 197  Instead of providing aRecord Formattable, each template is given as it appears in 
 198  PDB entries.  
 199   
 200  REMARK N   
 201  ---------------------------------- 
 202  REMARKs following the refinement remark consist of free text annotation, predefined 
 203  boilerplate remarks, and token: value pair styled templates. PDB is beginning to organize 
 204  the most often used remarks, and assign numbers and topics to them. 
 205   
 206  Presented here is the scheme being followed in the remark section of PDB files. 
 207  The PDB expects to continue to adopt standard text or tables for certain remarks, 
 208  as details are worked out.  
 209   
 210  2- PRIMARY STRUCTURE SECTION: 
 211   
 212  DBREF  
 213  ---------------------------------- 
 214  The DBREF record provides cross-reference links between PDB sequences and the 
 215  corresponding database entry or entries. A cross reference to the sequence database 
 216  is mandatory for each peptide chain with a length greater than ten (10) residues. 
 217  For nucleic acid entries a DBREF record pointing to the Nucleic Acid Database (NDB) 
 218  is mandatory when the corresponding entry exists in NDB. 
 219   
 220  SEQADV  
 221  ---------------------------------- 
 222  The SEQADV record identifies conflicts between sequence information in the ATOM records 
 223  of the PDB entry and the sequence database entry given on DBREF. Please note that these 
 224  records were designed to identify differences and not errors. No assumption is made as 
 225  to which database contains the correct data. PDB may include REMARK records in the entry 
 226  that reflect the depositor's view of which database has the correct sequence. 
 227   
 228  SEQRES  
 229  ---------------------------------- 
 230  SEQRES records contain the amino acid or nucleic acid sequence of residues in each 
 231  chain of the macromolecule that was studied. 
 232   
 233  MODRES  
 234  ---------------------------------- 
 235  The MODRES record provides descriptions of modifications (e.g., chemical or 
 236  post-translational) to protein and nucleic acid residues. Included are a mapping 
 237  between residue names given in a PDB entry and standard residues. 
 238   
 239  3- HETEROGEN SECTION 
 240   
 241  HET  
 242  ---------------------------------- 
 243  HET records are used to describe non-standard residues, such as prosthetic groups, 
 244  inhibitors, solvent molecules, and ions for which coordinates are supplied. Groups 
 245  are considered HET if they are: 
 246    - not one of the standard amino acids, and  
 247    - not one of the nucleic acids (C, G, A, T, U, and I), and  
 248    - not one of the modified versions of nucleic acids (+C, +G, +A, +T, +U, and +I), and  
 249    - not an unknown amino acid or nucleic acid where UNK is used to indicate the 
 250  unknown residue name.  
 251  Het records also describe heterogens for which the chemical identity is unknown, 
 252  in which case the group is assigned the hetID UNK.  
 253   
 254  HETNAM  
 255  ---------------------------------- 
 256  This record gives the chemical name of the compound with the given hetID. 
 257   
 258  HETSYN  
 259  ---------------------------------- 
 260  This record provides synonyms, if any, for the compound in the corresponding 
 261  (i.e., same hetID) HETNAM record. This is to allow greater flexibility in searching 
 262  for HET groups. 
 263   
 264  FORMUL  
 265  ---------------------------------- 
 266  The FORMUL record presents the chemical formula and charge of a non-standard group. 
 267  (The formulas for the standard residues are given in Appendix 5.) 
 268   
 269  4- SECONDARY STRUCTURE SECTION 
 270   
 271  HELIX  
 272  ---------------------------------- 
 273  HELIX records are used to identify the position of helices in the molecule. 
 274  Helices are both named and numbered. The residues where the helix begins and ends are 
 275  noted, as well as the total length. 
 276   
 277  SHEET  
 278  ---------------------------------- 
 279  SHEET records are used to identify the position of sheets in the molecule. 
 280  Sheets are both named and numbered. The residues where the sheet begins and ends are 
 281  noted. 
 282   
 283  TURN  
 284  ---------------------------------- 
 285  The TURN records identify turns and other short loop turns which normally connect other 
 286  secondary structure segments. 
 287   
 288  5- CONNECTIVITY ANNOTATION SECTION: 
 289   
 290  SSBOND  
 291  ---------------------------------- 
 292  The SSBOND record identifies each disulfide bond in protein and polypeptide structures 
 293  by identifying the two residues involved in the bond. 
 294   
 295  LINK : 
 296  ---------------------------------- 
 297  The LINK records specify connectivity between residues that is not implied by the 
 298  primary structure. Connectivity is expressed in terms of the atom names. 
 299  This record supplements information given in CONECT records and is provided here 
 300  for convenience in searching. 
 301   
 302  HYDBND  
 303  ---------------------------------- 
 304  The HYDBND records specify hydrogen bonds in the entry. 
 305   
 306  SLTBRG  
 307  ---------------------------------- 
 308  The SLTBRG records specify salt bridges in the entry. 
 309   
 310  CISPEP  
 311  ---------------------------------- 
 312  CISPEP records specify the prolines and other peptides found to be in the cis 
 313  conformation. This record replaces the use of footnote records to list cis peptides. 
 314   
 315  6- MISCELLANEOUS FEATURES SECTION: 
 316   
 317  SITE  
 318  ---------------------------------- 
 319  The SITE records supply the identification of groups comprising important sites 
 320  in the macromolecule. 
 321   
 322  7- CRYSTALLOGRAPHIC COORDINATE TRANSFORMATION SECTION 
 323   
 324  CRYST1  
 325  ---------------------------------- 
 326  The CRYST1 record presents the unit cell parameters, space group, and Z value. 
 327  If the structure was not determined by crystallographic means, CRYST1 simply defines 
 328  a unit cube. 
 329   
 330  ORIGX 1,2,3 
 331  ---------------------------------- 
 332  The ORIGXn (n = 1, 2, or 3) records present the transformation from the orthogonal 
 333  coordinates contained in the entry to the submitted coordinates. 
 334   
 335  SCALE 1,2,3 
 336  ---------------------------------- 
 337  The SCALEn (n = 1, 2, or 3) records present the transformation from the orthogonal 
 338  coordinates as contained in the entry to fractional crystallographic coordinates. 
 339  Non-standard coordinate systems should be explained in the remarks. 
 340   
 341  MTRIX 1,2,3 
 342  ---------------------------------- 
 343  The MTRIXn (n = 1, 2, or 3) records present transformations expressing 
 344  non-crystallographic symmetry. 
 345   
 346  TVECT  
 347  ---------------------------------- 
 348  The TVECT records present the translation vector for infinite covalently 
 349  connected structures. 
 350   
 351  8- COORDINATE SECTION 
 352  ====================================================== 
 353   
 354  MODEL  
 355  ---------------------------------- 
 356  The MODEL record specifies the model serial number when multiple structures are 
 357  presented in a single coordinate entry, as is often the case with structures determined 
 358  by NMR. 
 359                                          
 360  ATOM  
 361  ---------------------------------- 
 362  The ATOM records present the atomic coordinates for standard residues. 
 363  They also present the occupancy and temperature factor for each atom. Heterogen 
 364  coordinates use the HETATM record type. The element symbol is always present on each 
 365  ATOM record; segment identifier and charge are optional. 
 366   
 367  SIGATM  
 368  ---------------------------------- 
 369  The SIGATM records present the standard deviation of atomic parameters as they appear 
 370  in ATOM and HETATM records. 
 371   
 372  ANISOU  
 373  ---------------------------------- 
 374  The ANISOU records present the anisotropic temperature factors. 
 375   
 376  SIGUIJ  
 377  ---------------------------------- 
 378  The SIGUIJ records present the standard deviations of anisotropic temperature factors 
 379  scaled by a factor of 10**4 (Angstroms**2). 
 380   
 381  TER  
 382  ---------------------------------- 
 383  The TER record indicates the end of a list of ATOM/HETATM records for a chain. 
 384   
 385  HETATM  
 386  ---------------------------------- 
 387  The HETATM records present the atomic coordinate records for atoms within 
 388  'non-standard' groups. These records are used for water molecules and atoms presented 
 389  in HET groups. 
 390   
 391  ENDMDL  
 392  ---------------------------------- 
 393  The ENDMDL records are paired with MODEL records to group individual structures 
 394  found in a coordinate entry. 
 395   
 396  9- CONNECTIVITY SECTION 
 397   
 398  CONECT  
 399  ---------------------------------- 
 400  The CONECT records specify connectivity between atoms for which coordinates are 
 401  supplied. The connectivity is described using the atom serial number as found in 
 402  the entry. CONECT records are mandatory for HET groups (excluding water) and for 
 403  other bonds not specified in the standard residue connectivity table which involve 
 404  atoms in standard residues (see Appendix 4 for the list of standard residues). 
 405  These records are generated by the PDB. 
 406   
 407  10- BOOKKEEPING SECTION: 
 408   
 409  MASTER  
 410  ---------------------------------- 
 411  The MASTER record is a control record for bookkeeping. It lists the number of lines 
 412  in the coordinate entry or file for selected record types. 
 413   
 414  END 
 415  ---------------------------------- 
 416  The END record marks the end of the PDB file 
 417  """ 
 418   
 419   
420 -class MoleculeLoader(MVCommand):
421 """Base class for all the classes in this module 422 \nPackage : Pmv 423 \nModule : bondsCommands 424 \nClass : MoleculeLoader 425 """
426 - def __init__(self):
427 MVCommand.__init__(self) 428 self.fileTypes = [('all', '*')] 429 self.fileBrowserTitle = "Read File" 430 self.lastDir = "."
431
432 - def onRemoveObjectFromViewer(self, obj):
433 """ Function to remove the sets able to reference a TreeNode created 434 in this command : Here remove the alternate location list created 435 when a pdb File is read.""" 436 try: 437 atms = obj.findType(Atom) 438 for a in atms: 439 if hasattr(a, 'alternate'): 440 delattr(a, 'alternate') 441 except: 442 print "exception in MolecularLoader.onRemoveObjectFromViewer", obj.name
443 #del atms 444 445
446 - def guiCallback(self, event=None, *args, **kw):
447 cmdmenuEntry = self.GUI.menu[4]['label'] 448 file = self.vf.askFileOpen(types=self.fileTypes, 449 idir=self.lastDir, 450 title=self.fileBrowserTitle) 451 mol = None 452 if file != None: 453 self.lastDir = os.path.split(file)[0] 454 self.vf.GUI.configMenuEntry(self.GUI.menuButton, cmdmenuEntry, 455 state='disabled') 456 mol = self.vf.tryto(self.doitWrapper, file) 457 self.vf.GUI.configMenuEntry(self.GUI.menuButton, 458 cmdmenuEntry,state='normal') 459 460 return mol
461 462
463 -class MoleculeReader(MoleculeLoader):
464 """Command to read molecule 465 \nPackage : Pmv 466 \nModule : fileCommands 467 \nClass : MoleculeReader 468 \nCommand :readMolecule 469 \nSynopsis:\n 470 mols <- readMolecule(filename,parser=None, **kw) 471 \nRequired Arguments:\n 472 filename --- path to a file describing a molecule\n 473 parser --- you can specify the parser to use to parse the file has to be one of 'PDB', 'PDBQ', 'PDBQS','PDBQT', 'PQR', 'MOL2'.This is useful when your file doesn't have the correct extension. 474 """ 475 lastDir = None 476
477 - def __init__(self):
478 MoleculeLoader.__init__(self) 479 self.fileTypes =[('All supported files', '*.cif *.mol2 *.pdb *.pqr *.pdbq *.pdbqs *.pdbqt *.gro')] 480 self.fileTypes += [('PDB files', '*.pdb'), 481 ('MEAD files', '*.pqr'),('MOL2 files', '*.mol2'), 482 ('AutoDock files (pdbq)', '*.pdbq'), 483 ('AutoDock files (pdbqs)', '*.pdbqs'), 484 ('AutoDock files (pdbqt)', '*.pdbqt'), 485 ('Gromacs files (gro)', '*.gro'), 486 ] 487 488 self.parserToExt = {'PDB':'.pdb', 'PDBQ':'.pdbq', 489 'PDBQS':'.pdbqs', 'PDBQT':'.pdbqt', 490 'MOL2':'.mol2', 491 'PQR':'.pqr', 492 'GRO':'.gro', 493 } 494 self.fileTypes += [('MMCIF files', '*.cif'),] 495 self.parserToExt['CIF'] = '.cif' 496 497 self.fileTypes += [('All files', '*')] 498 499 self.fileBrowserTitle ="Read Molecule:"
500 501
502 - def onAddCmdToViewer(self):
503 # Do that better 504 self.vf.loadCommand("fileCommands", ["readPDBQ", 505 "readPDBQS", 506 "readPDBQT", 507 "readPQR", 508 "readMOL2","readPDB","readGRO", 509 ], "Pmv", 510 topCommand=0) 511 self.vf.loadCommand("fileCommands", ["readMMCIF"], "Pmv", 512 topCommand=0)
513 514
515 - def buildFormDescr(self, formName):
516 if formName == 'parser': 517 idf = InputFormDescr(title=self.name) 518 label = self.fileExt + " has not been recognized\n please choose a parser:" 519 l = ['PDB','PDBQ', 'PDBQS', 'PDBQT','MOL2','PQR'] 520 l.append('MMCIF') 521 idf.append({'name':'parser', 522 'widgetType':Pmw.RadioSelect, 523 'listtext':l, 524 'defaultValue':'PDB', 525 'wcfg':{'labelpos':'nw', 'label_text':label, 526 'orient':'horizontal', 527 'buttontype':'radiobutton'}, 528 'gridcfg':{'sticky': 'we'}}) 529 return idf
530 531
532 - def guiCallback(self, event=None, *args, **kw):
533 cmdmenuEntry = self.GUI.menu[4]['label'] 534 file = self.vf.askFileOpen(types=self.fileTypes, 535 idir=self.lastDir, 536 title=self.fileBrowserTitle) 537 mol = None 538 if file is not None: 539 self.lastDir = os.path.split(file)[0] 540 self.fileExt = os.path.splitext(file)[1] 541 if not self.fileExt in [".pdb",".pdbq", ".pdbqs", ".pdbqt", 542 ".mol2", ".pqr", ".cif",".gro"]: 543 # popup a pannel to allow the user to choose the parser 544 val = self.showForm('parser') 545 if not val == {}: 546 self.fileExt = self.parserToExt[val['parser']] 547 self.vf.GUI.configMenuEntry(self.GUI.menuButton, 548 cmdmenuEntry, 549 state='disabled') 550 551 mol = self.vf.tryto(self.doitWrapper, file) 552 self.vf.GUI.configMenuEntry(self.GUI.menuButton, 553 cmdmenuEntry,state='normal') 554 self.vf.recentFiles.add(file, self.name) 555 return mol
556
557 - def __call__(self, filename, parser=None, **kw):
558 """mols <- readMolecule(filename,parser=None, **kw) 559 \nfilename --- path to a file describing a molecule 560 \nparser --- you can specify the parser to use to parse the file 561 has to be one of 'PDB', 'PDBQ', 'PDBQS','PDBQT', 'PQR', 'MOL2'. 562 This is useful when your file doesn't have the correct 563 extension. 564 """ 565 self.fileExt = os.path.splitext(filename)[1] 566 kw['parser'] = parser 567 kw['ask']=0 568 return apply ( self.doitWrapper, (filename,), kw)
569 570
571 - def doit(self, filename, parser=None, ask=True):
572 import os 573 if not os.path.exists(filename): 574 self.warningMsg("ERROR: %s doesn't exists"%filename) 575 return None 576 577 if not parser is None and self.parserToExt.has_key(parser): 578 self.fileExt = self.parserToExt[parser] 579 # Call the right parser 580 if self.fileExt == ".pdb": 581 # Call readPDB 582 mols = self.vf.readPDB(filename,ask=ask, topCommand=0) 583 elif self.fileExt == ".pdbq": 584 # Call readPDBQ 585 mols = self.vf.readPDBQ(filename, ask=ask,topCommand=0) 586 elif self.fileExt == ".pdbqs": 587 # Call readPDBQS 588 mols = self.vf.readPDBQS(filename,ask=ask, topCommand=0) 589 elif self.fileExt == ".pdbqt": 590 # Call readPDBQT 591 mols = self.vf.readPDBQT(filename,ask=ask, topCommand=0) 592 elif self.fileExt == ".pqr": 593 # Call readPQR 594 mols = self.vf.readPQR(filename,ask=ask, topCommand=0) 595 elif self.fileExt == ".mol2": 596 # Call readMOL2 597 mols = self.vf.readMOL2(filename,ask=ask, topCommand=0) 598 elif self.fileExt == ".cif": 599 # Call readMMCIF 600 mols = self.vf.readMMCIF(filename, ask=ask, topCommand=0) 601 elif self.fileExt == ".gro": 602 # Call readGRO 603 mols = self.vf.readGRO(filename, ask=ask, topCommand=0) 604 else: 605 self.warningMsg("ERROR: Extension %s not recognized"%self.fileExt) 606 return None 607 if mols is None: 608 self.warningMsg("ERROR: Could not read %s"%filename) 609 610 return mols
611 612 MoleculeReaderGUI = CommandGUI() 613 ## MoleculeReaderGUI.addMenuCommand('menuRoot', 'File', 'Molecule', 614 ## cascadeName='Read',index=0) 615 MoleculeReaderGUI.addMenuCommand('menuRoot', 'File', 'Read Molecule', 616 index=0) 617
618 -class PDBReader(MoleculeLoader):
619 """Command to load PDB files using a PDB spec compliant parser 620 \nPackage : Pmv 621 \nModule : fileCommands 622 \nClass : MoleculeReader 623 \nCommand : readMolecule 624 \nSynopsis:\n 625 mols <--- readPDB(filename, **kw) 626 \nRequired Arguments:\n 627 filename --- path to the PDB file 628 """ 629 630 lastDir = None 631
632 - def onAddCmdToViewer(self):
633 if not hasattr(self.vf,'readMolecule'): 634 self.vf.loadCommand('fileCommands', ['readMolecule'], 'Pmv', 635 topCommand=0)
636
637 - def onRemoveObjectFromViewer(self, obj):
638 """ Function to remove the sets able to reference a TreeNode created 639 in this command : Here remove the alternate location list created 640 when a pdb File is read.""" 641 if not hasattr(obj, 'parser') or \ 642 not isinstance(obj.parser, PdbParser): return 643 MoleculeLoader.onRemoveObjectFromViewer(self, obj) 644 # Free the parser too ! 645 # this dictionary contains referneces to itself through function. 646 if hasattr(obj.parser, 'pdbRecordParser'): 647 del obj.parser.pdbRecordParser 648 if hasattr(obj.parser, 'mol'): 649 del obj.parser.mol 650 del obj.parser
651 652
653 - def doit(self, filename, ask=True):
654 newparser = PdbParser(filename) 655 656 # overwrite progress bar methods 657 if self.vf.hasGui: 658 newparser.updateProgressBar = self.vf.GUI.updateProgressBar 659 newparser.configureProgressBar = self.vf.GUI.configureProgressBar 660 661 mols = newparser.parse() 662 if mols is None: return 663 newmol = [] 664 for m in mols: 665 mol = self.vf.addMolecule(m, ask) 666 if mol is None: 667 del newparser 668 return mols.__class__([]) 669 newmol.append(mol) 670 671 return mols.__class__(newmol)
672 673
674 - def __call__(self, filename, **kw):
675 """mols <- readPDB(filename, **kw) 676 \nfilename --- path to the PDB file""" 677 678 kw['ask']=0 679 return apply ( self.doitWrapper, (filename,), kw)
680 681 pdbReaderGuiDescr = {'widgetType':'Menu', 'menyBarName':'menuRoot', 682 'menuButtonName':'File', 683 'menyEntryLabel':'Read PDB ...', 684 'index':0} 685 686 #PDBReaderGUI = CommandGUI() 687 #PDBReaderGUI.addMenuCommand('menuRoot', 'File', 'Read PDB ...',index=0) 688
689 -class MMCIFReader(MoleculeLoader):
690 """This command reads macromolecular Crystallographic Information File (mmCIF) 691 \nPackage : Pmv 692 \nModule : fileCommands 693 \nClass : MMCIFReader 694 \nCommand :readMMCIF 695 \nSynopsis:\n 696 mols <- readMMCIF(filename, **kw) 697 \nRequired Arguments:\n 698 filename --- path to the MMCIF file 699 """ 700 lastDir = None 701
702 - def onAddCmdToViewer(self):
703 if not hasattr(self.vf,'readMolecule'): 704 self.vf.loadCommand('fileCommands', ['readMolecule'], 'Pmv', 705 topCommand=0)
706
707 - def onRemoveObjectFromViewer(self, obj):
708 """ Function to remove the sets able to reference a TreeNode created 709 in this command : Here remove the alternate location list created 710 when a pdb File is read.""" 711 if not hasattr(obj, 'parser') or \ 712 not isinstance(obj.parser, PdbParser): return 713 MoleculeLoader.onRemoveObjectFromViewer(self, obj) 714 # Free the parser too ! 715 # this dictionary contains referneces to itself through function. 716 if hasattr(obj.parser, 'pdbRecordParser'): 717 del obj.parser.pdbRecordParser 718 if hasattr(obj.parser, 'mol'): 719 del obj.parser.mol 720 del obj.parser
721 722
723 - def doit(self, filename, ask=True):
724 newparser = MMCIFParser(filename) 725 726 # overwrite progress bar methods 727 if self.vf.hasGui: 728 newparser.updateProgressBar = self.vf.GUI.updateProgressBar 729 newparser.configureProgressBar = self.vf.GUI.configureProgressBar 730 731 mols = newparser.parse() 732 if mols is None: return 733 newmol = [] 734 for m in mols: 735 mol = self.vf.addMolecule(m, ask) 736 if mol is None: 737 del newparser 738 return mols.__class__([]) 739 newmol.append(mol) 740 741 return mols.__class__(newmol)
742 743
744 - def __call__(self, filename, **kw):
745 """mols <- readMMCIF(filename, **kw) 746 \nfilename --- path to the PDB file""" 747 748 kw['ask']=0 749 return apply ( self.doitWrapper, (filename,), kw)
750 751
752 -class GROReader(MoleculeLoader):
753 """This command reads macromolecular Crystallographic Information File (mmCIF) 754 \nPackage : Pmv 755 \nModule : fileCommands 756 \nClass : MMCIFReader 757 \nCommand :readMMCIF 758 \nSynopsis:\n 759 mols <- readMMCIF(filename, **kw) 760 \nRequired Arguments:\n 761 filename --- path to the MMCIF file 762 """ 763 lastDir = None 764
765 - def onAddCmdToViewer(self):
766 if not hasattr(self.vf,'readMolecule'): 767 self.vf.loadCommand('fileCommands', ['readMolecule'], 'Pmv', 768 topCommand=0)
769
770 - def onRemoveObjectFromViewer(self, obj):
771 """ Function to remove the sets able to reference a TreeNode created 772 in this command : Here remove the alternate location list created 773 when a pdb File is read.""" 774 if not hasattr(obj, 'parser') or \ 775 not isinstance(obj.parser, PdbParser): return 776 MoleculeLoader.onRemoveObjectFromViewer(self, obj) 777 # Free the parser too ! 778 # this dictionary contains referneces to itself through function. 779 if hasattr(obj.parser, 'pdbRecordParser'): 780 del obj.parser.pdbRecordParser 781 if hasattr(obj.parser, 'mol'): 782 del obj.parser.mol 783 del obj.parser
784 785
786 - def doit(self, filename, ask=True):
787 newparser = groParser(filename) 788 789 # overwrite progress bar methods 790 if self.vf.hasGui: 791 newparser.updateProgressBar = self.vf.GUI.updateProgressBar 792 newparser.configureProgressBar = self.vf.GUI.configureProgressBar 793 794 mols = newparser.parse() 795 if mols is None: return 796 newmol = [] 797 for m in mols: 798 mol = self.vf.addMolecule(m, ask) 799 if mol is None: 800 del newparser 801 return mols.__class__([]) 802 newmol.append(mol) 803 804 return mols.__class__(newmol)
805 806
807 - def __call__(self, filename, **kw):
808 """mols <- readGRO(filename, **kw) 809 \nfilename --- path to the PDB file""" 810 811 kw['ask']=0 812 return apply ( self.doitWrapper, (filename,), kw)
813 814
815 -class PDBQReader(MoleculeLoader):
816 """Command to load AutoDock PDBQ files. 817 \nPackage : Pmv 818 \nModule : fileCommands 819 \nClass : PDBQReader 820 \nCommand : readPDBQ 821 \nSynopsis:\n 822 mols <--- readPDBQ(filename, **kw) 823 \nRequired Arguments:\n 824 filename --- path to the PDBQ file 825 """ 826 827
828 - def onAddCmdToViewer(self):
829 if not hasattr(self.vf,'readMolecule'): 830 self.vf.loadCommand('fileCommands', ['readMolecule'], 'Pmv', 831 topCommand=0)
832
833 - def onRemoveObjectFromViewer(self, obj):
834 """ Function to remove the sets able to reference a TreeNode created 835 in this command : Here remove the alternate location list created 836 when a pdb File is read.""" 837 if not hasattr(obj, 'parser') or \ 838 not isinstance(obj.parser, PdbqParser): return 839 MoleculeLoader.onRemoveObjectFromViewer(self, obj) 840 # Free the parser too ! 841 # this dictionary contains referneces to itself through function. 842 if hasattr(obj.parser, 'pdbRecordParser'): 843 del obj.parser.pdbRecordParser 844 if hasattr(obj.parser, 'mol'): 845 del obj.parser.mol 846 if hasattr(obj, 'ROOT'): 847 delattr(obj, 'ROOT') 848 if hasattr(obj, 'torTree') and hasattr(obj.torTree, 'parser'): 849 delattr(obj.torTree, 'parser') 850 del obj.parser
851 852
853 - def doit(self, filename, ask=True ):
854 newparser = PdbqParser(filename ) 855 mols = newparser.parse() 856 if mols is None: return 857 newmol = [] 858 for m in mols: 859 mol = self.vf.addMolecule(m, ask) 860 if mol is None: 861 del newparser 862 return mols.__class__([]) 863 newmol.append(mol) 864 return mols.__class__(newmol)
865
866 - def __call__(self, filename, **kw):
867 """mols <- readPDBQ(filename, **kw) 868 \nfilename --- path to the PDBQ file""" 869 870 kw['ask']=0 871 return apply ( self.doitWrapper, (filename,), kw)
872 873 pdbqReaderGuiDescr = {'widgetType':'Menu', 'menyBarName':'menuRoot', 874 'menuButtonName':'File', 875 'menyEntryLabel':'Read PDBQ ...', 876 'index':0} 877 878 #PDBQReaderGUI = CommandGUI() 879 #PDBQReaderGUI.addMenuCommand('menuRoot', 'File', 'Read PDBQ ...', index=0) 880 881 882
883 -class PDBQSReader(MoleculeLoader):
884 """Command to load AutoDock PDBQS files 885 \nPackage : Pmv 886 \nModule : fileCommands 887 \nClass : PDBQSReader 888 \nCommand : readPDBQS 889 \nSynopsis:\n 890 mols <--- readPDBQS(filename, **kw) 891 \nRequired Arguments:\n 892 filename --- path to the PDBQS file 893 """ 894 895
896 - def onAddCmdToViewer(self):
897 if not hasattr(self.vf,'readMolecule'): 898 self.vf.loadCommand('fileCommands', ['readMolecule'], 'Pmv', 899 topCommand=0)
900
901 - def onRemoveObjectFromViewer(self, obj):
902 """ Function to remove the sets able to reference a TreeNode created 903 in this command : Here remove the alternate location list created 904 when a pdb File is read.""" 905 if not hasattr(obj, 'parser') or \ 906 not isinstance(obj.parser, PdbqsParser): return 907 MoleculeLoader.onRemoveObjectFromViewer(self, obj) 908 # Free the parser too ! 909 # this dictionary contains referneces to itself through function. 910 if hasattr(obj.parser, 'pdbRecordParser'): 911 del obj.parser.pdbRecordParser 912 if hasattr(obj.parser, 'mol'): 913 del obj.parser.mol 914 if hasattr(obj, 'ROOT'): 915 delattr(obj, 'ROOT') 916 if hasattr(obj, 'torTree') and hasattr(obj.torTree, 'parser'): 917 delattr(obj.torTree, 'parser') 918 del obj.parser
919 920
921 - def doit(self, filename, ask=True):
922 newparser = PdbqsParser(filename) 923 mols = newparser.parse() 924 if mols is None: return 925 newmol = [] 926 for m in mols: 927 mol = self.vf.addMolecule(m, ask) 928 if mol is None: 929 del newparser 930 return mols.__class__([]) 931 newmol.append(mol) 932 return mols.__class__(newmol)
933 934
935 - def __call__(self, filename, **kw):
936 """mols <--- readPDBQS(filename, **kw) 937 \nfilename --- path to the PDBQS file""" 938 939 kw['ask']=0 940 return apply ( self.doitWrapper, (filename,), kw)
941 942 pdbqsReaderGuiDescr = {'widgetType':'Menu', 'menyBarName':'menuRoot', 943 'menuButtonName':'File', 944 'menyEntryLabel':'Read PDBQS ...', 945 'index':0} 946 947 #PDBQSReaderGUI = CommandGUI() 948 #PDBQSReaderGUI.addMenuCommand('menuRoot', 'File', 'Read PDBQS ...', index=0) 949 950
951 -class PDBQTReader(MoleculeLoader):
952 """Command to load AutoDock PDBQT files 953 \nPackage : Pmv 954 \nModule : fileCommands 955 \nClass : PDBQTReader 956 \nCommand :readPDBQT 957 \nSynopsis:\n 958 mols <--- readPDBQT(filename, **kw) 959 \nRequired Arguments:\n 960 filename --- path to the PDBQT file 961 """ 962 963
964 - def onAddCmdToViewer(self):
965 if not hasattr(self.vf,'readMolecule'): 966 self.vf.loadCommand('fileCommands', ['readMolecule'], 'Pmv', 967 topCommand=0)
968
969 - def onRemoveObjectFromViewer(self, obj):
970 """ Function to remove the sets able to reference a TreeNode created 971 in this command : Here remove the alternate location list created 972 when a pdb File is read.""" 973 if not hasattr(obj, 'parser') or \ 974 not isinstance(obj.parser, PdbqtParser): return 975 MoleculeLoader.onRemoveObjectFromViewer(self, obj) 976 # Free the parser too ! 977 # this dictionary contains referneces to itself through function. 978 if hasattr(obj.parser, 'pdbRecordParser'): 979 del obj.parser.pdbRecordParser 980 if hasattr(obj.parser, 'mol'): 981 del obj.parser.mol 982 if hasattr(obj, 'ROOT'): 983 delattr(obj, 'ROOT') 984 if hasattr(obj, 'torTree') and hasattr(obj.torTree, 'parser'): 985 delattr(obj.torTree, 'parser') 986 del obj.parser
987 988
989 - def doit(self, filename, ask=True):
990 newparser = PdbqtParser(filename) 991 mols = newparser.parse() 992 if mols is None: return 993 newmol = [] 994 for m in mols: 995 mol = self.vf.addMolecule(m, ask) 996 if mol is None: 997 del newparser 998 return mols.__class__([]) 999 newmol.append(mol) 1000 return mols.__class__(newmol)
1001 1002
1003 - def __call__(self, filename, **kw):
1004 """mols <--- readPDBQT(filename, **kw) 1005 \nfilename --- path to the PDBQT file""" 1006 1007 kw['ask']=0 1008 return apply ( self.doitWrapper, (filename,), kw)
1009 1010 pdbqtReaderGuiDescr = {'widgetType':'Menu', 'menyBarName':'menuRoot', 1011 'menuButtonName':'File', 1012 'menyEntryLabel':'Read PDBQT ...', 1013 'index':0} 1014 1015 #PDBQTReaderGUI = CommandGUI() 1016 #PDBQTReaderGUI.addMenuCommand('menuRoot', 'File', 'Read PDBQT ...', index=0) 1017 1018
1019 -class PQRReader(MoleculeLoader):
1020 """Command to load MEAD PQR files 1021 \nPackage : Pmv 1022 \nModule : fileCommands 1023 \nClass : PQRReader 1024 \nCommand : readpqr 1025 \nSynopsis:\n 1026 mols <- readPQR(filename, **kw) 1027 \nRequired Arguments:\n 1028 filename --- path to the PQR file 1029 """ 1030 1031
1032 - def onAddCmdToViewer(self):
1033 if not hasattr(self.vf,'readMolecule'): 1034 self.vf.loadCommand('fileCommands', ['readMolecule'], 'Pmv', 1035 topCommand=0)
1036
1037 - def onRemoveObjectFromViewer(self, obj):
1038 """ Function to remove the sets able to reference a TreeNode created 1039 in this command : Here remove the alternate location list created 1040 when a pdb File is read.""" 1041 if not hasattr(obj, 'parser') or \ 1042 not isinstance(obj.parser, PQRParser): return 1043 MoleculeLoader.onRemoveObjectFromViewer(self, obj) 1044 # Free the parser too ! 1045 # this dictionary contains referneces to itself through function. 1046 if hasattr(obj.parser, 'pdbRecordParser'): 1047 del obj.parser.pdbRecordParser 1048 if hasattr(obj.parser, 'mol'): 1049 del obj.parser.mol 1050 del obj.parser
1051 1052
1053 - def doit(self, filename, ask=True):
1054 newparser = PQRParser(filename) 1055 mols = newparser.parse() 1056 if mols is None : return 1057 newmol = [] 1058 for m in mols: 1059 mol = self.vf.addMolecule(m, ask) 1060 if mol is None: 1061 del newparser 1062 return mols.__class__([]) 1063 newmol.append(mol) 1064 return mols.__class__(newmol)
1065 1066
1067 - def __call__(self, filename, **kw):
1068 """mols <--- readPQR(filename, **kw) 1069 \nfilename --- path to the PQR file""" 1070 1071 kw['ask']=0 1072 return apply ( self.doitWrapper, (filename,), kw)
1073 1074 pqrReaderGuiDescr = {'widgetType':'Menu', 'menyBarName':'menuRoot', 1075 'menuButtonName':'File', 1076 'menyEntryLabel':'Read PQR ...', 1077 'index':0} 1078 1079 #PQRReaderGUI = CommandGUI() 1080 #PQRReaderGUI.addMenuCommand('menuRoot', 'File', 'Read PQR ...',index=0) 1081 1082 1083
1084 -class MOL2Reader(MoleculeLoader):
1085 """Command to load MOL2 files 1086 \nPackage : Pmv 1087 \nModule : fileCommands 1088 \nClass : MOL2Reader 1089 \nCommand : readMOL2 1090 \nSynopsis:\n 1091 mols <- readMOL2(filename, **kw) 1092 \nRequired Arguments:\n 1093 filename --- path to the MOL2 file 1094 """ 1095 from MolKit.mol2Parser import Mol2Parser 1096 1097
1098 - def onAddCmdToViewer(self):
1099 if not hasattr(self.vf,'readMolecule'): 1100 self.vf.loadCommand('fileCommands', ['readMolecule'], 'Pmv', 1101 topCommand=0)
1102
1103 - def onRemoveObjectFromViewer(self, obj):
1104 """ Function to remove the sets able to reference a TreeNode created 1105 in this command : Here remove the alternate location list created 1106 when a pdb File is read.""" 1107 if not hasattr(obj, 'parser') or \ 1108 not isinstance(obj.parser, Mol2Parser): return 1109 MoleculeLoader.onRemoveObjectFromViewer(self, obj) 1110 if hasattr(obj.parser, 'mol2RecordParser'): 1111 del obj.parser.mol2RecordParser 1112 if hasattr(obj.parser, 'mol'): 1113 del obj.parser.mol 1114 del obj.parser
1115 1116
1117 - def doit(self, filename, ask=True):
1118 newparser = Mol2Parser(filename) 1119 mols = newparser.parse() 1120 newmol = [] 1121 if mols is None: return 1122 for m in mols: 1123 mol = self.vf.addMolecule(m, ask) 1124 if mol is None: 1125 del newparser 1126 return mols.__class__([]) 1127 newmol.append(mol) 1128 return mols.__class__(newmol)
1129 1130
1131 - def __call__(self, filename, **kw):
1132 """mols <- readMOL2(filename, **kw) 1133 \nfilename --- path to the MOL2 file""" 1134 kw['ask']=0 1135 return apply ( self.doitWrapper, (filename,), kw )
1136 1137 mol2ReaderGuiDescr = {'widgetType':'Menu', 'menyBarName':'menuRoot', 1138 'menuButtonName':'File', 1139 'menyEntryLabel':'Read MOL2 ...', 1140 'index':0} 1141 1142 #MOL2ReaderGUI = CommandGUI() 1143 #MOL2ReaderGUI.addMenuCommand('menuRoot', 'File', 'Read MOL2',index=0) 1144
1145 -class PDBWriter(MVCommand):
1146 """ 1147 Command to write the given molecule or the given subset of atoms 1148 of one molecule as PDB file. 1149 \nPackage : Pmv 1150 \nModule : fileCommands 1151 \nClass : PDBWriter 1152 \nCommand : writePDB 1153 \nSynopsis:\n 1154 None <- writePDB( nodes, filename=None, sort=True, 1155 pdbRec=['ATOM', 'HETATM', 'CONECT'], 1156 bondOrigin='all', ssOrigin=None, **kw) 1157 \nRequired Arguments:\n 1158 nodes --- TreeNodeSet holding the current selection 1159 \nOptional Arguments:\n 1160 filename --- name of the PDB file (default=None). If None is given 1161 The name of the molecule plus the .pdb extension will be used\n 1162 sort --- Boolean flag to either sort or not the nodes before writing 1163 the PDB file (default=True)\n 1164 pdbRec --- List of the PDB Record to save in the PDB file. 1165 (default: ['ATOM', 'HETATM', 'CONECT']\n 1166 bondOrigin --- string or list specifying the origin of the bonds to save 1167 as CONECT records in the PDB file. Can be 'all' or a tuple\n 1168 1169 ssOrigin --- Flag to specify the origin of the secondary structure 1170 information to be saved in the HELIX, SHEET and TURN 1171 record. Can either be None, File or Stride.\n 1172 """
1173 - def __init__(self, func=None):
1174 MVCommand.__init__(self, func) 1175 self.flag = self.flag | self.objArgOnly
1176
1177 - def doit(self, nodes, filename=None, sort=True, transformed=False, 1178 pdbRec=['ATOM', 'HETATM', 'CONECT'], 1179 bondOrigin='all', ssOrigin=None):
1180 nodes = self.vf.expandNodes(nodes) 1181 molecules = nodes.top.uniq() 1182 if len(molecules)==0: return 'ERROR' 1183 if len(molecules)>1: 1184 self.warningMsg("ERROR: Cannot create the PDB file, the current selection contains more than one molecule") 1185 return 'ERROR' 1186 1187 mol = molecules[0] 1188 if filename is None: 1189 filename = './%s.pdb'%mol.name 1190 1191 if transformed: 1192 oldConf = mol.allAtoms[0].conformation 1193 self.setNewCoords(mol) 1194 1195 writer = PdbWriter() 1196 writer.write(filename, nodes, sort=sort, records=pdbRec, 1197 bondOrigin=bondOrigin, ssOrigin=ssOrigin) 1198 1199 if transformed: 1200 mol.allAtoms.setConformation(oldConf)
1201 1202
1203 - def setNewCoords(self, mol):
1204 """ set the current conformation to be 1""" 1205 allAtoms = mol.allAtoms 1206 # get a handle on the master geometry 1207 mg = mol.geomContainer.masterGeom 1208 1209 # get the transformation matrix of the root 1210 matrix = mg.GetMatrix(mg) # followed the code in DejaVu/ViewerGUI.py 1211 #def saveTransformation(self, filename, geom) 1212 1213 # Transpose the transformation matrix. 1214 trMatrix = Numeric.transpose(matrix) 1215 # Get the coords of the atoms of your molecule. 1216 allAtoms.setConformation(0) 1217 coords = allAtoms.coords 1218 # Transform them into homogeneous coords. 1219 hCoords = Numeric.concatenate((coords,Numeric.ones( (len(coords), 1), 'd')), 1) 1220 # tranform the coords 1221 #tCoords = Numeric.matrixmultiply(hCoords, matrix) 1222 tCoords = Numeric.matrixmultiply(hCoords, trMatrix) 1223 # number of conformations available 1224 confNum = len(allAtoms[0]._coords) 1225 if hasattr(mol, 'transformedCoordsIndex'): 1226 # uses the same conformation to store the transformed data 1227 allAtoms.updateCoords(tCoords[:,:3].tolist(), \ 1228 mol.transformedCoordsIndex) 1229 else: 1230 # add new conformation to be written to file 1231 allAtoms.addConformation(tCoords[:,:3].tolist()) 1232 mol.transformedCoordsIndex = confNum 1233 allAtoms.setConformation( mol.transformedCoordsIndex )
1234 1235 1236
1237 - def __call__(self, nodes, filename=None, sort=True, transformed=False, 1238 pdbRec=['ATOM', 'HETATM', 'CONECT'], 1239 bondOrigin='all', ssOrigin=None, **kw):
1240 """None <- writePDB( nodes, filename=None, sort=True, 1241 pdbRec=['ATOM', 'HETATM', 'CONECT'], 1242 bondOrigin='all', ssOrigin=None, **kw) 1243 \nRequired Argument:\n 1244 nodes --- TreeNodeSet holding the current selection 1245 \nOptional Arguments:\n 1246 filename --- name of the PDB file (default=None). If None is given 1247 The name of the molecule plus the .pdb extension will be used\n 1248 sort --- Boolean flag to either sort or not the nodes before writing 1249 the PDB file (default=True)\n 1250 pdbRec --- List of the PDB Record to save in the PDB file. 1251 (default: ['ATOM', 'HETATM', 'CONECT']\n 1252 bondOrigin --- string or list specifying the origin of the bonds to save 1253 as CONECT records in the PDB file. Can be 'all' or a tuple\n 1254 1255 ssOrigin --- Flag to specify the origin of the secondary structure 1256 information to be saved in the HELIX, SHEET and TURN 1257 record. Can either be None, File or Stride.\n 1258 """ 1259 kw['sort'] = sort 1260 kw['bondOrigin'] = bondOrigin 1261 kw['pdbRec'] = pdbRec 1262 kw['ssOrigin'] = ssOrigin 1263 kw['filename'] = filename 1264 kw['transformed'] = transformed 1265 apply(self.doitWrapper, (nodes,), kw)
1266 1267
1268 - def dismiss_cb(self):
1269 if not self.cmdForms.has_key('PDBHelp'): return 1270 f = self.cmdForms['PDBHelp'] 1271 if f.root.winfo_ismapped(): 1272 f.root.withdraw() 1273 f.releaseFocus()
1274 1275
1276 - def showPDBHelp(self):
1277 f = self.cmdForms['saveOptions'] 1278 f.releaseFocus() 1279 nf = self.showForm("PDBHelp", modal=0, blocking=0)
1280 1281
1282 - def add_cb(self):
1283 from mglutil.util.misc import uniq 1284 ebn = self.cmdForms['saveOptions'].descr.entryByName 1285 lb1 = ebn['avRec']['widget'] 1286 lb2 = ebn['pdbRec']['widget'] 1287 newlist = uniq(list(lb2.get()) + list(lb1.getcurselection())) 1288 lb2.setlist(newlist)
1289 1290
1291 - def remove_cb(self):
1292 ebn = self.cmdForms['saveOptions'].descr.entryByName 1293 lb2 = ebn['pdbRec']['widget'] 1294 sel = lb2.getcurselection() 1295 all = lb2.get() 1296 if sel: 1297 remaining = filter(lambda x: not x in sel, all) 1298 lb2.setlist(remaining)
1299 1300
1301 - def setEntry_cb(self, filename ):
1302 ebn = self.cmdForms['saveOptions'].descr.entryByName 1303 entry = ebn['filename']['widget'] 1304 entry.setentry(filename)
1305 1306
1307 - def buildFormDescr(self, formName):
1308 from mglutil.util.misc import uniq 1309 if formName=='saveOptions': 1310 idf = InputFormDescr(title='Write Options') 1311 idf.append({'name':'fileGroup', 1312 'widgetType':Pmw.Group, 1313 'container':{'fileGroup':"w.interior()"}, 1314 'wcfg':{}, 1315 'gridcfg':{'sticky':'wnse', 'columnspan':4}}) 1316 1317 idf.append({'name':'filename', 1318 'widgetType':Pmw.EntryField, 1319 'parent':'fileGroup', 1320 'tooltip':'Enter a filename', 1321 'wcfg':{'label_text':'Filename:', 1322 'labelpos':'w', 'value':self.defaultFilename}, 1323 'gridcfg':{'sticky':'we'}, 1324 }) 1325 1326 idf.append({'widgetType':SaveButton, 1327 'name':'filebrowse', 1328 'parent':'fileGroup', 1329 'wcfg':{'buttonType':Tkinter.Button, 1330 'title':self.title, 1331 'types':self.fileType, 1332 'callback':self.setEntry_cb, 1333 'widgetwcfg':{'text':'BROWSE'}}, 1334 'gridcfg':{'row':-1, 'sticky':'we'}}) 1335 1336 # Find the available records and the avalaibe options 1337 # bond origin and secondary structure origin) 1338 # default records 1339 defRec = ['ATOM', 'HETATM', 'CONECT'] 1340 if isinstance(self.mol.parser, PdbParser): 1341 defRec = ['ATOM', 'HETATM', 'CONECT', 'SHEET', 'TURN', 'HELIX'] 1342 avRec = uniq(self.mol.parser.keys) 1343 #sargis added the following line to make sure that only 1344 #PdbParser.PDBtags are displayed 1345 avRec = filter(lambda x: x in avRec, PdbParser.PDBtags) 1346 defRec = filter(lambda x: x in avRec, defRec) 1347 1348 else: 1349 avRec = ['ATOM', 'HETATM', 'CONECT'] 1350 1351 # Source of the secondary structure information 1352 ssRec = filter(lambda x: x in avRec, ['HELIX', 'SHEET', 'TURN']) 1353 if self.mol.hasSS != []: 1354 avRec = avRec + ['HELIX', 'SHEET', 'TURN'] 1355 ssOrigin = [self.mol.hasSS[0].split('From ')[1],] 1356 if len(ssRec) !=0 and self.mol.hasSS != 'From File': 1357 ssOrigin.append('File') 1358 elif len(ssRec) != 0: 1359 ssOrigin=['File',] 1360 else: 1361 ssOrigin = None 1362 # Source of the CONECT information 1363 atms = self.nodes.findType(Atom) 1364 bonds = atms.bonds[0] 1365 bondOrigin = uniq(bonds.origin) 1366 if len(bondOrigin)>0 and not 'CONECT' in avRec: avRec.append('CONECT') 1367 1368 # HYBND is also a record that can be created from 1369 # the molecular data structure. 1370 hydbnd = atms.get(lambda x: hasattr(x, 'hbonds')) 1371 if hydbnd is not None and len(hydbnd) and not "HYDBND" in avRec: 1372 avRec.append("HYDBND") 1373 1374 avRec.sort() 1375 # Available records to write out 1376 idf.append({'name':'recGroup', 1377 'widgetType':Pmw.Group, 1378 'container':{'recGroup':"w.interior()"}, 1379 'wcfg':{'tag_text':"PDB Records:"}, 1380 'gridcfg':{'sticky':'wnse', 'columnspan':2}}) 1381 1382 idf.append({'name':'avRec', 1383 'widgetType':Pmw.ScrolledListBox, 1384 'parent':'recGroup', 1385 'tooltip':'The available PDB records are the records present in the original PDB \n\ 1386 file when relevant and the PDB records that can be created from the MolKit data structure \n\ 1387 (such as ATOM, HETATM, CONECT, TER, HELIX, SHEET, TURN, HYDBND). The TER record will be automatically \n\ 1388 created with the ATOM records.', 1389 'wcfg':{'label_text':'Available PDB Records: ', 1390 'labelpos':'nw', 1391 'items':avRec, 1392 'listbox_selectmode':'extended', 1393 'listbox_exportselection':0, 1394 'listbox_height':5,'listbox_width':10, 1395 }, 1396 'gridcfg':{'sticky': 'wesn','row':1, 'column':0,'rowspan':2}}) 1397 1398 idf.append({'name':'pdbinfo', 1399 'parent':'recGroup', 1400 'widgetType':Tkinter.Button, 1401 'tooltip':'Show PDB record description', 1402 'wcfg':{'text':'Records \nInfo', 1403 'command':self.showPDBHelp}, 1404 'gridcfg':{'sticky':'we', 'row':1, 'column':1}}) 1405 1406 idf.append({'name':'add', 1407 'parent':'recGroup', 1408 'widgetType':Tkinter.Button, 1409 'tooltip':""" Add the selected PDB record to the list 1410 of saved in the file""", 1411 'wcfg':{'text':'Add','command':self.add_cb}, 1412 'gridcfg':{'sticky':'we','row':2, 'column':1}}) 1413 1414 1415 idf.append({'name':'pdbRec', 1416 'parent':'recGroup', 1417 'widgetType':Pmw.ScrolledListBox, 1418 'wcfg':{'label_text':'PDB Records to be saved: ', 1419 'labelpos':'nw', 1420 'items':defRec, 1421 'listbox_selectmode':'extended', 1422 'listbox_exportselection':0, 1423 'listbox_height':5,'listbox_width':10, 1424 }, 1425 'gridcfg':{'sticky': 'wesn', 'row':1, 'column':2, 'rowspan':2}}) 1426 1427 1428 idf.append({'name':'remove', 1429 'parent':'recGroup', 1430 'widgetType':Tkinter.Button, 1431 'tooltip':""" Remove the selected records from the list of records to be saved in the file.""", 1432 'wcfg':{'text':'REMOVE','width':10, 1433 'command':self.remove_cb}, 1434 'gridcfg':{'sticky':'we', 'row':1, 'column':3}}) 1435 1436 1437 # OTHER OPTIONS 1438 idf.append({'name':'optionGroup', 1439 'widgetType':Pmw.Group, 1440 'container':{'optionGroup':"w.interior()"}, 1441 'wcfg':{'tag_text':"Other write options:"}, 1442 'gridcfg':{'sticky':'wnse', 'columnspan':3}}) 1443 1444 # sort the nodes 1445 idf.append({'name':'sort', 1446 'parent':'optionGroup', 1447 'widgetType':Tkinter.Checkbutton, 1448 'tooltip':'Choose whether or not to sort the nodes before writing in the PDB files', 1449 'wcfg':{'text':'Sort Nodes', 'variable':Tkinter.IntVar()}, 1450 'gridcfg':{'sticky':'w'}}) 1451 1452 # save transformed coords 1453 idf.append({'name':'transformed', 1454 'parent':'optionGroup', 1455 'widgetType':Tkinter.Checkbutton, 1456 'tooltip':'Choose to save original coordinates or the transformed coordinates in Viewer.', 1457 'wcfg':{'text':'Save Transformed Coords', 'variable':Tkinter.IntVar()}, 1458 'gridcfg':{'sticky':'w'}}) 1459 1460 1461 # bond origin 1462 idf.append({'name':'bondOrigin', 1463 'widgetType':Pmw.RadioSelect, 1464 'listtext':bondOrigin, 1465 'parent':'optionGroup', 1466 'tooltip':"Choose which bond types you wish to save as a CONECT record.\n\ 1467 This option will be used if the CONECT records has been selected.", 1468 'wcfg':{'label_text': 'Available Bond type:', 1469 'labelpos':'w','buttontype':'checkbutton', 1470 'selectmode':'multiple',}, 1471 'gridcfg':{'sticky':'w'}}) 1472 # secondary structure origin 1473 if not ssOrigin is None and len(ssOrigin)>1: 1474 idf.append({'name':'ssOrigin', 1475 'widgetType':Pmw.RadioSelect, 1476 'listtext':ssOrigin,'defaultValue':ssOrigin[0], 1477 'parent':'optionGroup', 1478 'tooltip':"", 1479 'wcfg':{'label_text': 'Secondary structure information source:', 1480 'labelpos':'w','buttontype':'radiobutton', 'selectmode':'single', 1481 }, 1482 'gridcfg':{'sticky':'w'}}) 1483 return idf 1484 1485 elif formName == 'PDBHelp': 1486 idf = InputFormDescr(title='PDB FORMAT HELP') 1487 idf.append({'name':'pdbHelp', 1488 'widgetType':Pmw.ScrolledText, 1489 'defaultValue':pdbDescr, 1490 'wcfg':{ 'labelpos':'nw', 1491 'label_text':'PDB Format description:', 1492 'text_width':50, 1493 'text_height':20}, 1494 'gridcfg':{'sticky':'we'}}) 1495 idf.append({'name':'dismiss', 1496 'widgetType':Tkinter.Button, 1497 'wcfg':{'text':'DISMISS', 1498 'command':self.dismiss_cb}, 1499 'gridcfg':{'sticky':'we'}}) 1500 return idf
1501 1502
1503 - def guiCallback(self):
1504 # Get the current selection 1505 nodes = self.vf.getSelection() 1506 if not len(nodes): return None 1507 molecules, nodes = self.vf.getNodesByMolecule(nodes) 1508 # Make sure that the current selection only belong to 1 molecule 1509 if len(molecules)>1: 1510 self.warningMsg("ERROR: Cannot create the PDB file.\n\ 1511 The current selection contains more than one molecule.") 1512 return 1513 self.mol = molecules[0] 1514 self.nodes = nodes[0] 1515 self.title = "Write PDB file" 1516 self.fileType = [('PDB file', '*.pdb')] 1517 currentPath = os.getcwd() 1518 self.defaultFilename = os.path.join(currentPath,self.mol.name) + '.pdb' 1519 val = self.showForm('saveOptions', force=1, 1520 cancelCfg={'text':'Cancel', 1521 'command':self.dismiss_cb}, 1522 okCfg={'text':'OK', 1523 'command':self.dismiss_cb}) 1524 if val: 1525 if val.has_key('filebrowse'): 1526 del val['filebrowse'] 1527 del val['avRec'] 1528 ebn = self.cmdForms['saveOptions'].descr.entryByName 1529 w = ebn['pdbRec']['widget'] 1530 val['pdbRec'] = w.get() 1531 if len(val['pdbRec'])==0: return 1532 apply(self.doitWrapper, (self.nodes,), val)
1533 1534 1535 pdbWriterDescr = {'widgetType':'Menu', 'menyBarName':'menuRoot', 1536 'menuButtonName':'File', 1537 'menyEntryLabel':'Write PDB ...', 1538 'index':0} 1539 1540 PDBWriterGUI = CommandGUI() 1541 PDBWriterGUI.addMenuCommand('menuRoot', 'File', 'Write PDB', 1542 cascadeName='Save', index=3, separatorAbove=1) 1543
1544 -class PQRWriter(PDBWriter):
1545 """Command to write PQR files using a PQR spec compliant writer 1546 \nPackage : Pmv 1547 \nModule : fileCommands 1548 \nClass : PQRWriter 1549 \nCommand : writePQR 1550 \nSynopsis:\n 1551 None <- writePQR(filename, nodes, sort=True, **kw) 1552 \nRequired Arguments:\n 1553 filename --- name of the PQR file 1554 nodes --- TreeNodeSet holding the current selection\n 1555 \nOptional Arguments:\n 1556 sort --- default is 1 1557 """ 1558 from MolKit.pqrWriter import PqrWriter 1559
1560 - def doit(self, filename, nodes, sort):
1561 nodes = self.vf.expandNodes(nodes) 1562 if len(nodes)==0: return 'ERROR' 1563 1564 mol = nodes.top.uniq() 1565 assert len(mol)==1 1566 1567 if sort: 1568 #print 'nodes are sorted' 1569 nodes.sort() 1570 writer = self.PqrWriter() 1571 writer.write(filename, nodes)
1572 1573
1574 - def __call__(self, filename, nodes, sort=True, recType='all', **kw):
1575 """None <--- writePQR(filename, nodes, sort=True, **kw) 1576 \nfilename --- name of the PQR file 1577 \nnodes --- TreeNodeSet holding the current selection 1578 \nsort --- default is 1 1579 """ 1580 kw['sort'] = sort 1581 apply(self.doitWrapper, (filename, nodes,), kw)
1582 1583 1584
1585 - def guiCallback(self):
1586 file = self.vf.askFileSave(types=[('prq files', '*.pqr')], 1587 title="write PQR file:") 1588 if file == None: return 1589 nodes = self.vf.getSelection() 1590 if not len(nodes): return None 1591 if len(nodes.top.uniq())>1: 1592 self.warningMsg("more than one molecule in selection") 1593 return 1594 elif len(nodes)!=len(nodes.top.uniq().findType(nodes[0].__class__)): 1595 msg = 'writing only selected portion of '+ nodes[0].top.name 1596 self.warningMsg(msg) 1597 ans = Tkinter.IntVar() 1598 ans.set(1) 1599 1600 ifd = InputFormDescr(title='Write Options') 1601 ifd.append({'name':'sortLab', 1602 'widgetType': Tkinter.Label, 1603 'wcfg':{'text':'Sort Nodes:'}, 1604 'gridcfg': {'sticky':Tkinter.W}}) 1605 ifd.append({'name': 'yesWid', 1606 'widgetType':Tkinter.Radiobutton, 1607 'value': '1', 1608 'variable': ans, 1609 'text': 'Yes', 1610 'gridcfg': {'sticky':Tkinter.W}}) 1611 ifd.append({'name': 'noWid', 1612 'widgetType':Tkinter.Radiobutton, 1613 'value': '0', 1614 'text': 'No', 1615 'variable': ans, 1616 'gridcfg': {'sticky':Tkinter.W, 'row':-1,'column':1}}) 1617 1618 val = self.vf.getUserInput(ifd) 1619 if val: 1620 sort = ans.get() 1621 if sort == 1: 1622 nodes.sort() 1623 1624 self.doitWrapper(file, nodes, sort)
1625 1626 1627 pqrWriterDescr = {'widgetType':'Menu', 'menyBarName':'menuRoot', 1628 'menuButtonName':'File', 1629 'menyEntryLabel':'Write PQR ...', 1630 'index':0} 1631 1632 PQRWriterGUI = CommandGUI() 1633 PQRWriterGUI.addMenuCommand('menuRoot', 'File', 'Write PQR', 1634 cascadeName='Save', index=8) 1635
1636 -class PDBQWriter(PDBWriter):
1637 """Command to write PDBQ files using a PDBQ spec compliant writer 1638 \nPackage : Pmv 1639 \nModule : fileCommands 1640 \nClass : PDBQWriter 1641 \nCommand : writePDBQ 1642 \nSynopsis:\n 1643 None <- writePDBQ( nodes, filename=None, sort=True, 1644 pdbRec=['ATOM', 'HETATM', 'CONECT'], 1645 bondOrigin='all', ssOrigin=None, **kw) 1646 \nRequired Argument:\n 1647 nodes --- TreeNodeSet holding the current selection 1648 1649 \nOptional arguments:\n 1650 filename --- name of the PDB file (default=None). If None is given 1651 The name of the molecule plus the .pdb extension will be used 1652 sort --- Boolean flag to either sort or not the nodes before writing 1653 the PDB file (default=True)\n 1654 pdbRec --- List of the PDB Record to save in the PDB file. 1655 (default: ['ATOM', 'HETATM', 'CONECT']\n 1656 bondOrigin --- string or list specifying the origin of the bonds to save 1657 as CONECT records in the PDB file. Can be 'all' or a tuple\n 1658 1659 ssOrigin --- Flag to specify the origin of the secondary structure 1660 information to be saved in the HELIX, SHEET and TURN 1661 record. Can either be None, File or Stride.\n 1662 """ 1663 1664
1665 - def doit(self, nodes, filename=None, sort=True, pdbRec = ['ATOM', 'HETATM', 'CONECT'], 1666 bondOrigin='all', ssOrigin=None, transformed=False):
1667 nodes = self.vf.expandNodes(nodes) 1668 molecules = nodes.top.uniq() 1669 if len(molecules)==0: return 'ERROR' 1670 # Cannot save multiple molecules in one PDB file. They need to be merged into one molecule 1671 # first 1672 if len(molecules)>1: 1673 self.warningMsg("ERROR: Cannot create the PDBQ file, the current selection contains more than one molecule") 1674 return 'ERROR' 1675 mol = molecules[0] 1676 # Cannot save a PDBQ file if all the atoms donnot have a charge assigned. 1677 allAtoms = nodes.findType(Atom) 1678 try: 1679 allAtoms.charge 1680 except: 1681 try: 1682 allAtoms.charge=allAtoms.gast_charge 1683 except: 1684 self.warningMsg('ERROR: Cannot create the PDBQ file, all atoms in the current selection do not have a charge field. Use the commands in the editCommands module to either assign Kollman charges or compute Gasteiger charges') 1685 return 'ERROR' 1686 1687 if filename is None: 1688 filename = './%s.pdbq'%mol.name 1689 1690 if transformed: 1691 oldConf = mol.allAtoms[0].conformation 1692 self.setNewCoords(mol) 1693 1694 writer = PdbqWriter() 1695 writer.write(filename, nodes, sort=sort, records=pdbRec, 1696 bondOrigin=bondOrigin, ssOrigin=ssOrigin) 1697 1698 if transformed: 1699 mol.allAtoms.setConformation(oldConf)
1700 1701
1702 - def __call__(self, nodes, filename=None, sort=True, pdbRec = ['ATOM', 'HETATM', 'CONECT'], 1703 bondOrigin='all', ssOrigin=None, transformed=False, **kw):
1704 """None <- writePDBQ( nodes, filename=None, sort=True, 1705 pdbRec=['ATOM', 'HETATM', 'CONECT'], 1706 bondOrigin='all', ssOrigin=None, **kw) 1707 \nRequired Argument:\n 1708 nodes: TreeNodeSet holding the current selection 1709 1710 \nOptional Arguments:\n 1711 filename --- name of the PDB file (default=None). If None is given 1712 The name of the molecule plus the .pdb extension will be used\n 1713 sort --- Boolean flag to either sort or not the nodes before writing 1714 the PDB file (default=True)\n 1715 pdbRec --- List of the PDB Record to save in the PDB file. 1716 (default: ['ATOM', 'HETATM', 'CONECT']\n 1717 bondOrigin --- string or list specifying the origin of the bonds to save 1718 as CONECT records in the PDB file. Can be 'all' or a tuple\n 1719 1720 ssOrigin --- Flag to specify the origin of the secondary structure 1721 information to be saved in the HELIX, SHEET and TURN 1722 record. Can either be None, File or Stride.\n 1723 """ 1724 1725 kw['sort'] = sort 1726 kw['bondOrigin'] = bondOrigin 1727 kw['ssOrigin'] = ssOrigin 1728 kw['filename'] = filename 1729 kw['transformed'] = transformed 1730 apply(self.doitWrapper, (nodes,), kw)
1731 1732
1733 - def guiCallback(self):
1734 # Get the current selection 1735 nodes = self.vf.getSelection() 1736 if not len(nodes): return None 1737 molecules, nodes = self.vf.getNodesByMolecule(nodes) 1738 # Make sure that the current selection only belong to 1 molecule 1739 if len(molecules)>1: 1740 self.warningMsg("ERROR: Cannot create the PDBQ file.\n\ 1741 The current selection contains more than one molecule.") 1742 return 1743 self.mol = molecules[0] 1744 self.nodes = nodes[0] 1745 self.title = "Write PDBQ file" 1746 self.fileType = [('PDBQ file', '*.pdbq')] 1747 currentPath = os.getcwd() 1748 self.defaultFilename = os.path.join(currentPath,self.mol.name) + '.pdbq' 1749 val = self.showForm('saveOptions', force=1,cancelCfg={'text':'Cancel', 'command':self.dismiss_cb}, 1750 okCfg={'text':'OK', 'command':self.dismiss_cb}) 1751 if val: 1752 del val['avRec'] 1753 if val.has_key('filebrowse'): del val['filebrowse'] 1754 ebn = self.cmdForms['saveOptions'].descr.entryByName 1755 w = ebn['pdbRec']['widget'] 1756 val['pdbRec'] = w.get() 1757 if len(val['pdbRec'])==0: return 1758 apply(self.doitWrapper, (self.nodes,), val)
1759 1760 1761 1762 pdbqWriterGuiDescr = {'widgetType':'Menu', 'menyBarName':'menuRoot', 1763 'menuButtonName':'File', 1764 'menyEntryLabel':'Write PDBQ ...', 1765 'index':0} 1766 1767 PDBQWriterGUI = CommandGUI() 1768 PDBQWriterGUI.addMenuCommand('menuRoot', 'File', 'Write PDBQ', 1769 cascadeName='Save', index=4) 1770 1771 1772
1773 -class PDBQSWriter(PDBWriter):
1774 """Command to write PDBQS files using a PDBQS spec compliant writer 1775 \nPackage : Pmv 1776 \nModule : fileCommands 1777 \nClass : PDBQSWriter 1778 \nCommand : writePDBQS 1779 \nSynopsis:\n 1780 None <- writePDBQS( nodes, filename=None, sort=True, 1781 pdbRec=['ATOM', 'HETATM', 'CONECT'], 1782 bondOrigin='all', ssOrigin=None, **kw) 1783 \nRequired Argument:\n 1784 nodes --- TreeNodeSet holding the current selection 1785 \nOptional Arguments:\n 1786 filename --- name of the PDB file (default=None). If None is given 1787 The name of the molecule plus the .pdb extension will be used\n 1788 sort --- Boolean flag to either sort or not the nodes before writing 1789 the PDB file (default=True)\n 1790 pdbRec --- List of the PDB Record to save in the PDB file. 1791 (default: ['ATOM', 'HETATM', 'CONECT']\n 1792 bondOrigin --- string or list specifying the origin of the bonds to save 1793 as CONECT records in the PDB file. Can be 'all' or a tuple\n 1794 1795 ssOrigin --- Flag to specify the origin of the secondary structure 1796 information to be saved in the HELIX, SHEET and TURN 1797 record. Can either be None, File or Stride.\n 1798 """ 1799
1800 - def doit(self, nodes, filename=None, sort=True, pdbRec = ['ATOM', 'HETATM', 'CONECT'], 1801 bondOrigin='all', ssOrigin=None, transformed=False):
1802 nodes = self.vf.expandNodes(nodes) 1803 molecules = nodes.top.uniq() 1804 if len(molecules)==0: return 'ERROR' 1805 # Cannot save multiple molecules in one PDB file. They need to be merged into one molecule 1806 # first 1807 if len(molecules)>1: 1808 self.warningMsg("ERROR: Cannot create the PDBQS file, the current selection contains more than one molecule") 1809 return 'ERROR' 1810 mol = molecules[0] 1811 # Cannot save a PDBQ file if all the atoms donnot have a charge assigned. 1812 allAtoms = nodes.findType(Atom) 1813 try: 1814 allAtoms.charge 1815 except: 1816 try: 1817 allAtoms.charge=allAtoms.gast_charge 1818 except: 1819 self.warningMsg('ERROR: Cannot create the PDBQS file, all atoms in the current selection do not have a charge field. Use the commands in the editCommands module to either assign Kollman charges or compute Gasteiger charges') 1820 return 'ERROR' 1821 1822 try: 1823 allAtoms.AtSolPar 1824 allAtoms.AtVol 1825 except: 1826 self.warningMsg('ERROR: Cannot create the PDBQS file, all atoms do not have a solvation fields') 1827 return 'ERROR' 1828 1829 if filename is None: 1830 filename = './%s.pdbqs'%mol.name 1831 if transformed: 1832 oldConf = mol.allAtoms[0].conformation 1833 self.setNewCoords(mol) 1834 1835 writer = PdbqsWriter() 1836 writer.write(filename, nodes, sort=sort, records=pdbRec, 1837 bondOrigin=bondOrigin, ssOrigin=ssOrigin) 1838 1839 if transformed: 1840 mol.allAtoms.setConformation(oldConf)
1841 1842
1843 - def __call__(self, nodes, filename=None, sort=True, pdbRec = ['ATOM', 'HETATM', 'CONECT'], 1844 bondOrigin='all', ssOrigin=None, transformed=False, **kw):
1845 """None <- writePDBQS( nodes, filename=None, sort=True, 1846 pdbRec=['ATOM', 'HETATM', 'CONECT'], 1847 bondOrigin='all', ssOrigin=None, **kw) 1848 \nRequired Argument:\n 1849 nodes --- TreeNodeSet holding the current selection 1850 1851 \nOptional Arguments:\n 1852 filename --- name of the PDB file (default=None). If None is given 1853 The name of the molecule plus the .pdb extension will be used\n 1854 sort --- Boolean flag to either sort or not the nodes before writing 1855 the PDB file (default=True)\n 1856 pdbRec --- List of the PDB Record to save in the PDB file. 1857 (default: ['ATOM', 'HETATM', 'CONECT']\n 1858 bondOrigin --- string or list specifying the origin of the bonds to save 1859 as CONECT records in the PDB file. Can be 'all' or a tuple\n 1860 1861 ssOrigin --- Flag to specify the origin of the secondary structure 1862 information to be saved in the HELIX, SHEET and TURN 1863 record. Can either be None, File or Stride. 1864 """ 1865 1866 kw['sort'] = sort 1867 kw['bondOrigin'] = bondOrigin 1868 kw['ssOrigin'] = ssOrigin 1869 kw['filename'] = filename 1870 kw['transformed'] = transformed 1871 apply(self.doitWrapper, (nodes,), kw)
1872 1873
1874 - def guiCallback(self):
1875 # Get the current selection 1876 nodes = self.vf.getSelection() 1877 if not len(nodes): return None 1878 molecules, nodes = self.vf.getNodesByMolecule(nodes) 1879 # Make sure that the current selection only belong to 1 molecule 1880 if len(molecules)>1: 1881 self.warningMsg("ERROR: Cannot create the PDBQS file.\n\ 1882 The current selection contains more than one molecule.") 1883 return 1884 self.mol = molecules[0] 1885 self.nodes = nodes[0] 1886 self.title = "Write PDBQS file" 1887 self.fileType = [('PDBQS file', '*.pdbqs')] 1888 currentPath = os.getcwd() 1889 self.defaultFilename = self.defaultFilename = os.path.join(currentPath,self.mol.name) + '.pdbqs' 1890 val = self.showForm('saveOptions', force=1,cancelCfg={'text':'Cancel', 'command':self.dismiss_cb}, 1891 okCfg={'text':'OK', 'command':self.dismiss_cb}) 1892 if val: 1893 del val['avRec'] 1894 if val.has_key('filebrowse'): del val['filebrowse'] 1895 ebn = self.cmdForms['saveOptions'].descr.entryByName 1896 w = ebn['pdbRec']['widget'] 1897 val['pdbRec'] = w.get() 1898 if len(val['pdbRec'])==0: return 1899 apply(self.doitWrapper, (self.nodes,), val)
1900 1901 1902 pdbqsWriterGuiDescr = {'widgetType':'Menu', 'menyBarName':'menuRoot', 1903 'menuButtonName':'File', 1904 'menyEntryLabel':'Write PDBS ...', 1905 'index':0} 1906 1907 PDBQSWriterGUI = CommandGUI() 1908 PDBQSWriterGUI.addMenuCommand('menuRoot', 'File', 'Write PDBQS', 1909 cascadeName='Save', index=5) 1910 1911
1912 -class PDBQTWriter(PDBWriter):
1913 """Command to write PDBQT files using a PDBQT spec compliant writer 1914 \nPackage : Pmv 1915 \nModule : fileCommands 1916 \nClass : PDBQTWriter 1917 \nCommand : write PDBQT 1918 \nSynopsis:\n 1919 None <--- writePDBQT( nodes, filename=None, sort=True, 1920 pdbRec=['ATOM', 'HETATM', 'CONECT'], 1921 bondOrigin='all', ssOrigin=None, **kw)\n 1922 \nRequired argument:\n 1923 nodes --- TreeNodeSet holding the current selection 1924 1925 \nOptional arguments:\n 1926 filename --- name of the PDB file (default=None). If None is given 1927 The name of the molecule plus the .pdb extension will be used\n 1928 sort --- Boolean flag to either sort or not the nodes before writing 1929 the PDB file (default=True)\n 1930 pdbRec --- List of the PDB Record to save in the PDB file. 1931 (default: ['ATOM', 'HETATM', 'CONECT']\n 1932 bondOrigin --- string or list specifying the origin of the bonds to save 1933 as CONECT records in the PDB file. Can be 'all' or a tuple\n 1934 1935 ssOrigin --- Flag to specify the origin of the secondary structure 1936 information to be saved in the HELIX, SHEET and TURN 1937 record. Can either be None, File or Stride. 1938 1939 """ 1940
1941 - def doit(self, nodes, filename=None, sort=True, pdbRec = ['ATOM', 'HETATM', 'CONECT'], 1942 bondOrigin='all', ssOrigin=None, transformed=False):
1943 nodes = self.vf.expandNodes(nodes) 1944 molecules = nodes.top.uniq() 1945 if len(molecules)==0: return 'ERROR' 1946 # Cannot save multiple molecules in one PDB file. They need to be merged into one molecule 1947 # first 1948 if len(molecules)>1: 1949 self.warningMsg("ERROR: Cannot create the PDBQT file, the current selection contains more than one molecule") 1950 return 'ERROR' 1951 mol = molecules[0] 1952 # Cannot save a PDBQ file if all the atoms donnot have a charge assigned. 1953 allAtoms = nodes.findType(Atom) 1954 try: 1955 allAtoms.charge 1956 except: 1957 try: 1958 allAtoms.charge=allAtoms.gast_charge 1959 except: 1960 self.warningMsg('ERROR: Cannot create the PDBQT file, all atoms in the current selection do not have a charge field. Use the commands in the editCommands module to either assign Kollman charges or compute Gasteiger charges') 1961 return 'ERROR' 1962 1963 try: 1964 allAtoms.autodock_element 1965 except: 1966 self.warningMsg('ERROR: Cannot create the PDBQT file, all atoms do not have an autodock_element field') 1967 return 'ERROR' 1968 1969 if filename is None: 1970 filename = './%s.pdbqt'%mol.name 1971 if transformed: 1972 oldConf = mol.allAtoms[0].conformation 1973 self.setNewCoords(mol) 1974 1975 writer = PdbqtWriter() 1976 writer.write(filename, nodes, sort=sort, records=pdbRec, 1977 bondOrigin=bondOrigin, ssOrigin=ssOrigin) 1978 1979 if transformed: 1980 mol.allAtoms.setConformation(oldConf)
1981 1982
1983 - def __call__(self, nodes, filename=None, sort=True, pdbRec = ['ATOM', 'HETATM', 'CONECT'], 1984 bondOrigin='all', ssOrigin=None, transformed=False, **kw):
1985 """None <- writePDBQT( nodes, filename=None, sort=True, 1986 pdbRec=['ATOM', 'HETATM', 'CONECT'], 1987 bondOrigin='all', ssOrigin=None, **kw)\n 1988 \nRequired Argument:\n 1989 nodes --- TreeNodeSet holding the current selection 1990 1991 \nOptional Arguments:\n 1992 filename --- name of the PDB file (default=None). If None is given 1993 The name of the molecule plus the .pdb extension will be used\n 1994 sort --- Boolean flag to either sort or not the nodes before writing 1995 the PDB file (default=True)\n 1996 pdbRec --- List of the PDB Record to save in the PDB file. 1997 (default: ['ATOM', 'HETATM', 'CONECT']\n 1998 bondOrigin --- string or list specifying the origin of the bonds to save 1999 as CONECT records in the PDB file. Can be 'all' or a tuple\n 2000 2001 ssOrigin --- Flag to specify the origin of the secondary structure 2002 information to be saved in the HELIX, SHEET and TURN 2003 record. Can either be None, File or Stride. 2004 """ 2005 2006 kw['sort'] = sort 2007 kw['bondOrigin'] = bondOrigin 2008 kw['ssOrigin'] = ssOrigin 2009 kw['filename'] = filename 2010 kw['transformed'] = transformed 2011 apply(self.doitWrapper, (nodes,), kw)
2012 2013
2014 - def guiCallback(self):
2015 # Get the current selection 2016 nodes = self.vf.getSelection() 2017 if not len(nodes): return None 2018 molecules, nodes = self.vf.getNodesByMolecule(nodes) 2019 # Make sure that the current selection only belong to 1 molecule 2020 if len(molecules)>1: 2021 self.warningMsg("ERROR: Cannot create the PDBQT file.\n\ 2022 The current selection contains more than one molecule.") 2023 return 2024 self.mol = molecules[0] 2025 self.nodes = nodes[0] 2026 self.title = "Write PDBQT file" 2027 self.fileType = [('PDBQT file', '*.pdbqt')] 2028 currentPath = os.getcwd() 2029 self.defaultFilename = self.defaultFilename = os.path.join(currentPath,self.mol.name) + '.pdbqt' 2030 val = self.showForm('saveOptions', force=1,cancelCfg={'text':'Cancel', 'command':self.dismiss_cb}, 2031 okCfg={'text':'OK', 'command':self.dismiss_cb}) 2032 if val: 2033 del val['avRec'] 2034 if val.has_key('filebrowse'): del val['filebrowse'] 2035 ebn = self.cmdForms['saveOptions'].descr.entryByName 2036 w = ebn['pdbRec']['widget'] 2037 val['pdbRec'] = w.get() 2038 if len(val['pdbRec'])==0: return 2039 apply(self.doitWrapper, (self.nodes,), val)
2040 2041 2042 pdbqtWriterGuiDescr = {'widgetType':'Menu', 'menyBarName':'menuRoot', 2043 'menuButtonName':'File', 2044 'menyEntryLabel':'Write PDBQT ...', 2045 'index':0} 2046 2047 PDBQTWriterGUI = CommandGUI() 2048 PDBQTWriterGUI.addMenuCommand('menuRoot', 'File', 'Write PDBQT', 2049 cascadeName='Save', index=6) 2050 2051
2052 -class SaveMMCIF(MVCommand):
2053 """This command writes macromolecular Crystallographic Information File (mmCIF). 2054 \nPackage : Pmv 2055 \nModule : fileCommands 2056 \nClass : SaveMMCIF 2057 \nCommand : saveMMCIF 2058 \nSynopsis:\n 2059 None<---saveMMCIF(filename, nodes) 2060 \nRequired Arguments:\n 2061 filename --- name of the mmcif file (default=None). If None is given 2062 The name of the molecule plus the .cif extension will be used\n 2063 nodes --- TreeNodeSet holding the current selection 2064 """ 2065
2066 - def doit(self, filename, nodes):
2067 nodes = self.vf.expandNodes(nodes) 2068 writer = MMCIFWriter() 2069 writer.write(filename, nodes)
2070
2071 - def __call__(self, filename, nodes,**kw):
2072 """None<---saveMMCIF(filename,nodes) 2073 \nfilename --- name of the mmcif file (default=None). If None is given 2074 The name of the molecule plus the .cif extension will be used\n 2075 \nnodes --- TreeNodeSet holding the current selection 2076 """ 2077 nodes = self.vf.expandNodes(nodes) 2078 apply(self.doitWrapper, (filename, nodes), kw)
2079
2080 - def guiCallback(self):
2081 filename = self.vf.askFileSave(types=[('MMCIF files', '*.cif')], 2082 title="Write MMCIF File:") 2083 if not filename is None: 2084 nodes = self.vf.getSelection() 2085 if not len(nodes) : return None 2086 2087 if len(nodes.top.uniq())>1: 2088 self.warningMsg("more than one molecule in selection") 2089 return 2090 2091 self.doitWrapper(filename, nodes)
2092 2093 SaveMMCIFGUI = CommandGUI() 2094 SaveMMCIFGUI.addMenuCommand('menuRoot', 'File', 'Write MMCIF', 2095 cascadeName='Save', index=7) 2096 2097
2098 -class STLWriter(MVCommand):
2099 """Command to write coords&normals of currently displayed geometries as 2100 ASCII STL files (STL = stereolithography, don't confuse with standard 2101 template library) 2102 \nPackage : Pmv 2103 \nModule : fileCommands 2104 \nClass : STLWriter 2105 \nCommand : writeSTL 2106 \nSynopsis:\n 2107 None<---Write STL ( filename, sphereQuality=2, 2108 cylinderQuality=10 ) 2109 """ 2110
2111 - def doit(self, filename, sphereQuality=2, 2112 cylinderQuality=10):
2113 """Write all displayed geoms of all displayed molecules in 2114 the STL format""" 2115 from DejaVu.DataOutput import OutputSTL 2116 STL = OutputSTL() 2117 stl = STL.getSTL(self.vf.GUI.VIEWER.rootObject, filename, 2118 sphereQuality=sphereQuality, 2119 cylinderQuality=cylinderQuality) 2120 2121 if stl is not None and len(stl) != 0: 2122 f = open(filename, 'w') 2123 map( lambda x,f=f: f.write(x), stl) 2124 f.close()
2125 2126
2127 - def __call__(self, filename, **kw):
2128 """None <--- Write STL ( filename, sphereQuality=2, 2129 cylinderQuality=10 )""" 2130 apply( self.doitWrapper, (filename,), kw )
2131 2132
2133 - def guiCallback(self):
2134 newfile = self.vf.askFileSave(types=[('STL files', '*.stl'),], 2135 title='Select STL files:') 2136 2137 if not newfile or newfile == '': 2138 return 2139 2140 from DejaVu.DataOutput import STLGUI 2141 opPanel = STLGUI(master=None, title='STL Options') 2142 opPanel.displayPanel(create=1) 2143 2144 if not opPanel.readyToRun: 2145 return 2146 2147 # get values from options panel 2148 di = opPanel.getValues() 2149 sq = di['sphereQuality'] 2150 cq = di['cylinderQuality'] 2151 2152 self.doitWrapper(newfile, sq, cq)
2153 2154 2155 stlWriterGuiDescr = {'widgetType':'Menu', 'menuBarName':'menuRoot', 2156 'menuButtonName':'File', 2157 'menuEntryLabel':'Write STL', 2158 } 2159 2160 STLWriterGUI = CommandGUI() 2161 STLWriterGUI.addMenuCommand('menuRoot', 'File', 'Write STL', 2162 cascadeName='Save', index=11,separatorBelow=1) 2163 2164
2165 -class VRML2Writer(MVCommand):
2166 """Command to save currently displayed geometries in VRML 2.0 format 2167 \nPackage : Pmv 2168 \nModule : fileCommands 2169 \nClass : VRML2Writer 2170 \nCommand : writeVRML2.0file 2171 \nSynopsis:\n 2172 None<---Write VRML 2.0 file (filename, saveNormals=0, 2173 colorPerVertex=True, useProto=0, sphereQuality=2, cylinderQuality=10 ) 2174 """
2175 - def onAddCmdToViewer(self):
2176 if self.vf.hasGui: 2177 from DejaVu.DataOutput import VRML2GUI 2178 self.opPanel = VRML2GUI(master=None, title='VRML2 Options')
2179
2180 - def __init__(self):
2181 MVCommand.__init__(self)
2182 2183 2184
2185 - def doit(self, filename, saveNormals=0, 2186 colorPerVertex=True, useProto=0, 2187 sphereQuality=2, cylinderQuality=10):
2188 2189 from DejaVu.DataOutput import OutputVRML2 2190 2191 V = OutputVRML2() 2192 2193 # add hook to progress bar 2194 if self.vf.hasGui: 2195 V.updateProgressBar = self.vf.GUI.updateProgressBar 2196 V.configureProgressBar = self.vf.GUI.configureProgressBar 2197 2198 2199 vrml2 = V.getVRML2(self.vf.GUI.VIEWER.rootObject, complete=1, 2200 normals=saveNormals, 2201 colorPerVertex=colorPerVertex, usePROTO=useProto, 2202 sphereQuality=sphereQuality, 2203 cylinderQuality=cylinderQuality) 2204 2205 if vrml2 is not None and len(vrml2) != 0: 2206 f = open(filename, 'w') 2207 map( lambda x,f=f: f.write(x), vrml2) 2208 f.close() 2209 del vrml2
2210 2211
2212 - def __call__(self, filename, saveNormals=0, 2213 colorPerVertex=True, useProto=0, 2214 sphereQuality=2, cylinderQuality=10, **kw):
2215 """Write VRML 2.0 file (filename, saveNormals=0, 2216 colorPerVertex=True, useProto=0, sphereQuality=2, cylinderQuality=10 )""" 2217 kw['saveNormals'] = saveNormals 2218 kw['colorPerVertex'] = colorPerVertex 2219 kw['useProto'] = useProto 2220 kw['sphereQuality'] = sphereQuality 2221 kw['cylinderQuality'] = cylinderQuality 2222 apply( self.doitWrapper, (filename,), kw)
2223 2224
2225 - def guiCallback(self):
2226 newfile = self.vf.askFileSave(types=[('VRML 2.0 files', '*.wrl'),], 2227 title='Select VRML 2.0 files:') 2228 2229 if newfile is None or newfile == '': 2230 return 2231 2232 2233 if not self.opPanel.readyToRun: 2234 self.opPanel.displayPanel(create=1) 2235 else: 2236 self.opPanel.displayPanel(create=0) 2237 2238 # get values from options panel 2239 di = self.opPanel.getValues() 2240 sn = di['saveNormals'] 2241 co = di['colorPerVertex'] 2242 if co == 1: 2243 co = True 2244 else: 2245 co = False 2246 up = di['usePROTO'] 2247 sq = di['sphereQuality'] 2248 cq = di['cylinderQuality'] 2249 kw = {'saveNormals':di['saveNormals'], 2250 'colorPerVertex':di['colorPerVertex'], 2251 'useProto':di['usePROTO'], 'sphereQuality':di['sphereQuality'], 2252 'cylinderQuality':di['cylinderQuality'], 'redraw':0} 2253 apply(self.doitWrapper, (newfile,), kw)
2254 #self.doitWrapper(newfile, sn, ni, co, up, sq, cq) 2255 2256 2257 vrml2WriterGuiDescr = {'widgetType':'Menu', 'menuBarName':'menuRoot', 2258 'menuButtonName':'File', 2259 'menuEntryLabel':'Write VRML 2.0', 2260 } 2261 2262 VRML2WriterGUI = CommandGUI() 2263 VRML2WriterGUI.addMenuCommand('menuRoot', 'File', 'Write VRML 2.0', 2264 cascadeName='Save', index=10, separatorAbove=1) 2265 2266 import urllib
2267 -class readFromWebCommand(MVCommand):
2268 """Command to read pdb from ftp://ftp.rcsb.org 2269 \nPackage : Pmv 2270 \nModule : fileCommands 2271 \nClass : readFromWebCommand 2272 \nCommand : readFromWeb 2273 \nSynopsis:\n 2274 mols <- readMOL2(keyword, **kw) 2275 \nRequired Arguments:\n PDB ID 2276 keyword --- PDB ID 2277 """ 2278 baseURI = "http://www.rcsb.org/pdb/download/downloadFile.do?fileFormat=pdb&compression=NO&structureId=" 2279 searchURI = "http://www.rcsb.org/pdb/search/navbarsearch.do?inputQuickSearch=" 2280 resultURI = 'http://www.rcsb.org/pdb/results/results.do' 2281 from mglutil.util.packageFilePath import getResourceFolderWithVersion 2282 rcFolder = getResourceFolderWithVersion() 2283 width = 440 #width of the GUI 2284 height = 200 #height of the GUI 2285 listmols=[]
2286 - def message_box(self):
2287 txt = "The file you requested does not exist\n" 2288 txt+= "Do you want to search again?" 2289 if askyesno(title = 'Invalid Input',message=txt): 2290 self.guiCallback()
2291
2292 - def find_list(self,keyword):
2293 """This function is to find out number of pages molecules are 2294 listed and get all molecule and information. """ 2295 if keyword: 2296 keyword = keyword.replace(' ','%20') 2297 uri = self.searchURI+keyword 2298 try: 2299 fURL = urllib.urlopen(uri) 2300 except Exception, inst: 2301 print inst 2302 return 2303 # if 'content-type' not in fURL.headers.keys(): 2304 # self.message_box() 2305 # return 2306 # if fURL.headers['content-type'] == 'text/html;charset=ISO-8859-1' or fURL.headers['content-type'] =="text/html; charset=iso-8859-1": 2307 m=[] 2308 self.listmols=[] 2309 self.information=[] 2310 newurl = fURL.geturl() 2311 #shows first hundred files 2312 cur_url = newurl.split(";")[-1] 2313 st = "startAt=0&resultsperpage=100" 2314 cURL = self.resultURI+";"+cur_url+"?"+st 2315 fURL = urllib.urlopen(cURL) 2316 fp = open("dataf" ,"w") 2317 fp.write(fURL.read()) 2318 fp.close() 2319 fp = open("dataf") 2320 lines =fp.readlines() 2321 fp.close() 2322 os.remove("dataf") 2323 ## file names 2324 for i in lines: 2325 if '<input type="checkbox" name=' in i: 2326 m.append(i) 2327 for j in m: 2328 h = eval(str(j.split(" ")[-1][:-2]).split("=")[-1]) 2329 self.listmols.append(h) 2330 2331 if len(self.listmols)==0: 2332 return 2333 ##information 2334 z=[] 2335 c=[] 2336 for i in lines: 2337 if 'href="/pdb/explore.do?structureId=' in i: 2338 z.append(i) 2339 for i in z: 2340 c.append(i.split(">")) 2341 for i in c: 2342 if len(i[-1])>6: 2343 self.information.append(i[-1][:-2])
2344
2345 - def doit(self,pdbID):
2346 2347 if pdbID: 2348 #pdbID 2349 dirnames = os.listdir(self.rcFolder) 2350 #checks in pdb cache before searching in rcsb.org. 2351 if "pdbcache" in dirnames: 2352 filenames = os.listdir(self.rcFolder+os.sep+'pdbcache') 2353 if pdbID+".pdb" in filenames: 2354 tmpFileName = self.rcFolder + os.sep +"pdbcache"+os.sep+pdbID+".pdb" 2355 mols = self.vf.readPDB(tmpFileName, log=0) 2356 return mols 2357 URI = self.baseURI + pdbID 2358 try: 2359 fURL = urllib.urlopen(URI) 2360 except Exception, inst: 2361 print inst 2362 return 2363 if fURL.headers['content-type'] == 'application/download': 2364 if "pdbcache" not in dirnames: 2365 curdir = os.getcwd() 2366 os.mkdir(self.rcFolder + os.sep +"pdbcache") 2367 tmpFileName = self.rcFolder + os.sep +"pdbcache"+os.sep+pdbID+".pdb" 2368 tmpFile = open(tmpFileName,'w') 2369 tmpFile.write(fURL.read()) 2370 tmpFile.close() 2371 mols = self.vf.readPDB(tmpFileName, log=0) 2372 self.vf.recentFiles.add(os.path.abspath(tmpFileName), 'readMolecule') 2373 return mols 2374 else: 2375 self.message_box()
2376 2377
2378 - def hide(self, event=None):
2379 if self.root: 2380 self.root.withdraw()
2381 2382
2383 - def buildFormDescr(self, formName):
2384 if formName == "FetchPDB": 2385 self.ifd = ifd = InputFormDescr(title="Fetch PDB") 2386 ifd.append({'name':"pdbID", 2387 'widgetType':Pmw.EntryField, 2388 'tooltip':'Enter either keyword or pdbID', 2389 'wcfg':{'labelpos':'w','label_text':"PDB ID", 2390 'entry_width':1, 2391 'validate':{'validator':'alphanumeric', 2392 'min':4, 'max':4, 'minstrict':False 2393 }, 2394 2395 }, 2396 'gridcfg':{'columnspan':2} 2397 }) 2398 ifd.append({'name':"keyword", 2399 'widgetType':Pmw.EntryField, 2400 'tooltip':'Enter either keyword or pdbID', 2401 'wcfg':{'labelpos':'w','label_text':"keyword", 2402 'entry_width':1, 2403 2404 }, 2405 'gridcfg':{'columnspan':2} 2406 2407 2408 }) 2409 if self.getPDBCachedir(): 2410 ifd.append({'name':"PDBCachelab", 2411 'widgetType':Tkinter.Label, 2412 'text': "PDBCache directory : \n'%s'" %self.getPDBCachedir(), 2413 'gridcfg':{'sticky':'w'}, 2414 }) 2415 2416 ifd.append({'name':'PDBCachedir', 2417 'widgetType':Tkinter.Button, 2418 'wcfg':{'text':'Clear', 2419 'command':self.clearPDBCache()}, 2420 'gridcfg':{'sticky':'we', 'row':2, 'column':1}}) 2421 2422 2423 2424 return ifd
2425
2426 - def guiCallback(self, **kw):
2427 if hasattr(self,"root"): 2428 if self.root!=None: 2429 self.root.withdraw() 2430 if not self.getPDBCachedir(): 2431 os.mkdir(self.rcFolder+os.sep+'pdbcache') 2432 val = self.showForm('FetchPDB', force=1, 2433 cancelCfg={'text':'Cancel', 2434 'command':self.dismiss_cb}, 2435 okCfg={'text':'OK', 2436 'command':self.