1 """This modules implements I{File-->Frame snapshot} dialog.
2
3 Classes:
4 * PDBSnapshotGeneratorDialog: creates I{File-->Frame snapshot} dialog used to
5 extract a PDB file from one or several trajectory frame(s).
6 """
7
8
9 import os
10 import re
11 import sys
12 from tempfile import mkdtemp
13
14
15 from tkFileDialog import askopenfilename
16 from Tkinter import *
17
18
19 from Scientific import N as Num
20
21
22 from MMTK.PDB import PDBOutputFile
23 from MMTK.Trajectory import Trajectory
24
25
26 from nMOLDYN.Core.Error import Error
27 from nMOLDYN.Core.Logger import LogMessage
28 from nMOLDYN.Core.Preferences import PREFERENCES
29 from nMOLDYN.GUI.Widgets import *
30
32 """Sets up a dialog used to export one or several trajectory frames into a PDB file.
33
34 @note: if a trajectory has been previously loaded in nMOLDYN this will be the one proposed for extraction
35 by default. Otherwise, the user can still choose a trajectory to visualize from the dialog.
36 """
37 - def __init__(self, parent, title = None, trajectory = None):
38 """The constructor.
39
40 @param parent: the parent widget.
41
42 @param title: a string specifying the title of the dialog.
43 @type title: string
44 """
45
46 Toplevel.__init__(self, parent)
47
48 self.transient(parent)
49
50 if title:
51 self.title(title)
52
53 self.parent = parent
54
55
56
57 if isinstance(trajectory, Trajectory):
58 self.trajectory = trajectory
59
60 else:
61 self.trajectory = None
62
63 body = Frame(self)
64 self.initial_focus = self.body(body)
65 body.grid(row = 0, column = 0, sticky = EW)
66
67 self.buttonbox()
68
69 self.grab_set()
70
71 if not self.initial_focus:
72 self.initial_focus = self
73
74 self.protocol("WM_DELETE_WINDOW", self.cancel)
75
76 self.resizable(width = NO, height = NO)
77
78 self.geometry("+%d+%d" % (parent.winfo_rootx()+50, parent.winfo_rooty()+50))
79
80 self.initial_focus.focus_set()
81
82 self.wait_window(self)
83
84 - def body(self, master):
85 """
86 Create dialog body. Return widget that should have initial focus.
87 """
88
89 settingsFrame = LabelFrame(master, text = 'Settings', bd = 2, relief = GROOVE)
90 settingsFrame.grid(row = 0, column = 0, sticky = EW, padx = 3, pady = 3)
91 settingsFrame.grid_columnconfigure(0, weight = 1)
92
93
94 self.fileBrowser = ComboFileBrowser(settingsFrame,\
95 frameLabel = "MMTK trajectory file",\
96 tagName = 'frame_snapshot_mmtk_trajectory_file',\
97 contents = '',\
98 save = False,\
99 command = self.openTrajectory)
100 self.fileBrowser.grid(row = 0, column = 0, padx = 2, pady = 2, sticky = EW)
101 self.fileBrowser.grid_columnconfigure(0, weight = 1)
102 self.fileBrowser.entry.bind('<Return>', self.openTrajectory)
103
104
105 self.selectedStepEntry = ComboStringEntry(settingsFrame,\
106 frameLabel = 'Selected frames',\
107 tagName = 'frame_snapshot_selected_frames',\
108 contents = '1')
109 self.selectedStepEntry.grid(row = 1, column = 0, sticky = EW, padx = 2, pady = 2)
110 self.selectedStepEntry.grid_columnconfigure(0, weight = 1)
111
112
113 self.pdbFileBrowser = ComboFileBrowser(settingsFrame,\
114 frameLabel = "PDB output file",\
115 tagName = 'frame_snapshot_pdb_output_file',\
116 contents = '',\
117 save = True)
118 self.pdbFileBrowser.grid(row = 2, column = 0, padx = 2, pady = 2, sticky = EW)
119 self.pdbFileBrowser.grid_columnconfigure(0, weight = 1)
120
121
122
123 if self.trajectory is not None:
124
125 self.fileBrowser.setValue(self.trajectory.filename)
126 self.selectedStepEntry.setValue('1')
127 self.pdbFileBrowser.setValue(os.path.splitext(self.trajectory.filename)[0] + '_Frame.pdb')
128 else:
129 self.pdbFileBrowser.setValue('Frame.pdb')
130
131 return None
132
150
151
152 - def ok(self, event = None):
153
154 if not self.validate():
155 self.initial_focus.focus_set()
156 return
157
158 self.update_idletasks()
159
160 self.apply()
161
162 - def cancel(self, event=None):
163
164
165 self.parent.focus_set()
166 self.destroy()
167
168
170
171 if not self.trajectory:
172 raise Error('No MMTK trajectory file loaded for extraction.')
173
174 if self.trajectory.filename != self.fileBrowser.getValue():
175 raise Error('Mismatch between the loaded trajectory and the displayed MMTK trajectory file name.\
176 You should validate that file by pressing Return on its corresponding entry.')
177
178
179 if not self.selectedStepEntry.getValue():
180 self.selectedFrames = '1'
181 LogMessage('warning', 'No frame selected. Frame 1 will be extracted by default.', ['gui'])
182 else:
183 self.selectedFrames = self.selectedStepEntry.getValue().strip()
184
185 try:
186 self.selectedFrames = eval(self.selectedFrames)
187
188 if isinstance(self.selectedFrames, int):
189 self.selectedFrames = [self.selectedFrames]
190
191
192 elif isinstance(self.selectedFrames, (list,tuple)):
193 pass
194
195 except:
196 try:
197 temp = []
198 self.selectedFrames = [temp.extend(range(int(v[0]),int(v[1])+1,int(v[2]))) for v in re.findall('(\d+):(\d+):(\d+)',self.selectedFrames)]
199 self.selectedFrames = temp
200 except:
201 raise Error('Wrong format for frame selection.')
202
203
204 for s in self.selectedFrames:
205 if not isinstance(s, int):
206 raise Error('Wrong entry for frame selection.')
207
208 if (s <= 0) or (s > len(self.trajectory)):
209 raise Error('Some selected frame number are not within [1,%d].' % len(self.trajectory))
210
211
212 self.pdbFile = self.pdbFileBrowser.getValue()
213 if not self.pdbFile:
214 raise Error('Please enter a PDB output file.')
215
216 return True
217
219
220 try:
221
222 pid = os.getpid()
223 suffix = '.'.join(['',str(pid),'pdb','nmoldyn'])
224
225
226 dirName = mkdtemp(suffix)
227
228 outputFile = open(self.pdbFile,'w')
229
230 for f in self.selectedFrames:
231 pdbFrame = os.path.join(dirName,''.join(['Frame',str(f),'.pdb']))
232
233 PDBOutputFile(pdbFrame).write(self.trajectory.universe, self.trajectory.configuration[f-1])
234
235 pdbFile = open(pdbFrame,'r')
236 data = pdbFile.read()
237 pdbFile.close()
238 os.unlink(pdbFrame)
239 outputFile.write('REMARK Frame %d\n' % (f,))
240 outputFile.write(data)
241
242 outputFile.close()
243
244 LogMessage('info', 'Frame extraction successful', ['gui'])
245
246 except:
247 raise Error('Error when extracting PDB frame.')
248
250 """
251 Ths method is called when the user clicks on the 'Browse' button of the trajectory visualization dialog.
252 It opens a file browser. After the file selection some of the dialog widgets are updated with the informations
253 coming from the loaded trajectory.
254 """
255
256
257 if event is not None:
258 if event.widget == self.fileBrowser.entry:
259 filename = self.fileBrowser.getValue()
260 else:
261 return
262
263 else:
264
265 filename = askopenfilename(parent = self,\
266 filetypes = [('NetCDF file','*.nc')],\
267 initialdir = PREFERENCES.trajfile_path)
268
269
270 if filename:
271 try:
272
273 self.trajectory = Trajectory(None, filename, 'r')
274 except IOError:
275 raise Error('Can not read the trajectory.')
276 else:
277
278 self.fileBrowser.setValue(filename)
279 self.selectedStepEntry.setValue('1')
280
281 return 'break'
282