1
2
3
4
5
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
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
421 """Base class for all the classes in this module
422 \nPackage : Pmv
423 \nModule : bondsCommands
424 \nClass : MoleculeLoader
425 """
427 MVCommand.__init__(self)
428 self.fileTypes = [('all', '*')]
429 self.fileBrowserTitle = "Read File"
430 self.lastDir = "."
431
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
444
445
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
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
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
503
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
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
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
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
580 if self.fileExt == ".pdb":
581
582 mols = self.vf.readPDB(filename,ask=ask, topCommand=0)
583 elif self.fileExt == ".pdbq":
584
585 mols = self.vf.readPDBQ(filename, ask=ask,topCommand=0)
586 elif self.fileExt == ".pdbqs":
587
588 mols = self.vf.readPDBQS(filename,ask=ask, topCommand=0)
589 elif self.fileExt == ".pdbqt":
590
591 mols = self.vf.readPDBQT(filename,ask=ask, topCommand=0)
592 elif self.fileExt == ".pqr":
593
594 mols = self.vf.readPQR(filename,ask=ask, topCommand=0)
595 elif self.fileExt == ".mol2":
596
597 mols = self.vf.readMOL2(filename,ask=ask, topCommand=0)
598 elif self.fileExt == ".cif":
599
600 mols = self.vf.readMMCIF(filename, ask=ask, topCommand=0)
601 elif self.fileExt == ".gro":
602
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
614
615 MoleculeReaderGUI.addMenuCommand('menuRoot', 'File', 'Read Molecule',
616 index=0)
617
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
633 if not hasattr(self.vf,'readMolecule'):
634 self.vf.loadCommand('fileCommands', ['readMolecule'], 'Pmv',
635 topCommand=0)
636
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
645
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
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
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
687
688
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
703 if not hasattr(self.vf,'readMolecule'):
704 self.vf.loadCommand('fileCommands', ['readMolecule'], 'Pmv',
705 topCommand=0)
706
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
715
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
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
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
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
766 if not hasattr(self.vf,'readMolecule'):
767 self.vf.loadCommand('fileCommands', ['readMolecule'], 'Pmv',
768 topCommand=0)
769
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
778
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
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
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
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
829 if not hasattr(self.vf,'readMolecule'):
830 self.vf.loadCommand('fileCommands', ['readMolecule'], 'Pmv',
831 topCommand=0)
832
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
841
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
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
879
880
881
882
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
897 if not hasattr(self.vf,'readMolecule'):
898 self.vf.loadCommand('fileCommands', ['readMolecule'], 'Pmv',
899 topCommand=0)
900
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
909
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
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
948
949
950
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
965 if not hasattr(self.vf,'readMolecule'):
966 self.vf.loadCommand('fileCommands', ['readMolecule'], 'Pmv',
967 topCommand=0)
968
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
977
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
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
1016
1017
1018
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
1033 if not hasattr(self.vf,'readMolecule'):
1034 self.vf.loadCommand('fileCommands', ['readMolecule'], 'Pmv',
1035 topCommand=0)
1036
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
1045
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
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
1080
1081
1082
1083
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
1099 if not hasattr(self.vf,'readMolecule'):
1100 self.vf.loadCommand('fileCommands', ['readMolecule'], 'Pmv',
1101 topCommand=0)
1102
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
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
1143
1144
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 """
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
1204 """ set the current conformation to be 1"""
1205 allAtoms = mol.allAtoms
1206
1207 mg = mol.geomContainer.masterGeom
1208
1209
1210 matrix = mg.GetMatrix(mg)
1211
1212
1213
1214 trMatrix = Numeric.transpose(matrix)
1215
1216 allAtoms.setConformation(0)
1217 coords = allAtoms.coords
1218
1219 hCoords = Numeric.concatenate((coords,Numeric.ones( (len(coords), 1), 'd')), 1)
1220
1221
1222 tCoords = Numeric.matrixmultiply(hCoords, trMatrix)
1223
1224 confNum = len(allAtoms[0]._coords)
1225 if hasattr(mol, 'transformedCoordsIndex'):
1226
1227 allAtoms.updateCoords(tCoords[:,:3].tolist(), \
1228 mol.transformedCoordsIndex)
1229 else:
1230
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
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
1277 f = self.cmdForms['saveOptions']
1278 f.releaseFocus()
1279 nf = self.showForm("PDBHelp", modal=0, blocking=0)
1280
1281
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
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
1501
1502
1504
1505 nodes = self.vf.getSelection()
1506 if not len(nodes): return None
1507 molecules, nodes = self.vf.getNodesByMolecule(nodes)
1508
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
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):
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
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
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
1671
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
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
1734
1735 nodes = self.vf.getSelection()
1736 if not len(nodes): return None
1737 molecules, nodes = self.vf.getNodesByMolecule(nodes)
1738
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
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
1806
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
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
1875
1876 nodes = self.vf.getSelection()
1877 if not len(nodes): return None
1878 molecules, nodes = self.vf.getNodesByMolecule(nodes)
1879
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
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
1947
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
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
2015
2016 nodes = self.vf.getSelection()
2017 if not len(nodes): return None
2018 molecules, nodes = self.vf.getNodesByMolecule(nodes)
2019
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
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):
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
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
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
2128 """None <--- Write STL ( filename, sphereQuality=2,
2129 cylinderQuality=10 )"""
2130 apply( self.doitWrapper, (filename,), kw )
2131
2132
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
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
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 """
2176 if self.vf.hasGui:
2177 from DejaVu.DataOutput import VRML2GUI
2178 self.opPanel = VRML2GUI(master=None, title='VRML2 Options')
2179
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
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
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
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
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
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
2284 height = 200
2285 listmols=[]
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
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
2304
2305
2306
2307 m=[]
2308 self.listmols=[]
2309 self.information=[]
2310 newurl = fURL.geturl()
2311
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
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
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
2349 dirnames = os.listdir(self.rcFolder)
2350
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
2425
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.