Package nMOLDYN :: Package GUI :: Module PDBSnapshotGeneratorDialog
[hide private]
[frames] | no frames]

Source Code for Module nMOLDYN.GUI.PDBSnapshotGeneratorDialog

  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  # The python distribution modules 
  9  import os 
 10  import re 
 11  import sys 
 12  from tempfile import mkdtemp 
 13   
 14  # The Tcl/Tk modules 
 15  from tkFileDialog import askopenfilename 
 16  from Tkinter import * 
 17   
 18  # The ScientificPython modules 
 19  from Scientific import N as Num 
 20   
 21  # The MMTK distribution modules 
 22  from MMTK.PDB import PDBOutputFile 
 23  from MMTK.Trajectory import Trajectory 
 24   
 25  # The nMOLDYN modules 
 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   
31 -class PDBSnapshotGeneratorDialog(Toplevel):
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 # If a trajectory has been loaded in nMOLDYN for simulation purposes (e.g. MSD ...) then it is proposed by default for 56 # visualization. 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 # The combo widget for the file browser. 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 # The combo widget for the first step setting. 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 # The PDB output file browser. 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 # If a trajectory has been loaded in nMOLDYN for simulation purposes (e.g. MSD ...) then it is proposed by default for 122 # visualization. 123 if self.trajectory is not None: 124 # The control variables are updated with the informations coming from the loaded trajectory. 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
133 - def buttonbox(self):
134 """ 135 Add standard button box. 136 """ 137 138 # The frame that contains the 'Cancel' and 'OK' buttons. 139 box = LabelFrame(self, text = 'Actions', bd = 2, relief = GROOVE) 140 box.grid(row = 1, column = 0, sticky = EW, padx = 3, pady = 3) 141 box.grid_columnconfigure(0, weight = 1) 142 143 w = Button(box, text = "Cancel", width=10, command = self.cancel) 144 w.grid(row = 0, column = 0, sticky = E) 145 w = Button(box, text = "OK", width=10, command = self.ok, default=ACTIVE) 146 w.grid(row = 0, column = 1, sticky = E) 147 148 self.bind("<Return>", self.ok) 149 self.bind("<Escape>", self.cancel)
150 151 # Standard button semantics.
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 # Put focus back to the parent window 165 self.parent.focus_set() 166 self.destroy()
167 168 # Command hooks
169 - def validate(self):
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 # A frame selection must have been set. 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 # The entry can be an integer. 188 if isinstance(self.selectedFrames, int): 189 self.selectedFrames = [self.selectedFrames] 190 191 # The entry can be a list or a tuple. 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 # Check that every selected step is valid. 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 # A PDB output file name must have been set. 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
218 - def apply(self):
219 220 try: 221 # pid = the pid number for the job 222 pid = os.getpid() 223 suffix = '.'.join(['',str(pid),'pdb','nmoldyn']) 224 225 # This just creates a unique temporary directory. 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 # This MMTK function write a PDB file given a trajectory and a selected frame index. 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
249 - def openTrajectory(self, event = None):
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 # Case where the user enters a file name directly in the entry widget without using the browser. 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 # The name of the NetCDF file to load. 265 filename = askopenfilename(parent = self,\ 266 filetypes = [('NetCDF file','*.nc')],\ 267 initialdir = PREFERENCES.trajfile_path) 268 269 # The file must exist. 270 if filename: 271 try: 272 # The trajectory is loaded. 273 self.trajectory = Trajectory(None, filename, 'r') 274 except IOError: 275 raise Error('Can not read the trajectory.') 276 else: 277 # The control variables are updated with the informations about the loaded trajectory. 278 self.fileBrowser.setValue(filename) 279 self.selectedStepEntry.setValue('1') 280 281 return 'break'
282