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

Source Code for Module nMOLDYN.GUI.NetCDFToASCIIConversionDialog

  1  """This modules implements I{File-->Convert NetCDF to ASCII} dialog. 
  2   
  3  Classes: 
  4      * NetCDFToASCIIConversionDialog: creates I{File-->Convert NetCDF to ASCII} dialog used to  
  5        convert a file in NetCDF format to a file in ASCII format. 
  6  """ 
  7   
  8  # The python distribution modules 
  9  import copy 
 10  import inspect 
 11  import os 
 12  import re 
 13  import sys 
 14   
 15  # The Tcl/Tk modules 
 16  from tkFileDialog import askopenfilename 
 17  from Tkinter import * 
 18   
 19  # The ScientificPython modules 
 20  from Scientific import N as Num 
 21  from Scientific.IO.NetCDF import _NetCDFFile, NetCDFFile 
 22   
 23  from MMTK.Trajectory import Trajectory 
 24   
 25  # The nMOLDYN modules 
 26  from nMOLDYN.Core.Error import Error 
 27  from nMOLDYN.Core.IOFiles import convertNetCDFToASCII 
 28  from nMOLDYN.Core.Logger import LogMessage 
 29  from nMOLDYN.Core.Preferences import PREFERENCES 
 30  from nMOLDYN.GUI.Widgets import * 
 31   
32 -class NetCDFToASCIIConversionDialog(Toplevel):
33 """Sets up a dialog that allows the conversion of any numeric variables present in a 34 NetCDF file into an ASCII file. 35 """ 36
37 - def __init__(self, parent, title = None, netcdf = 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 self.transient(parent) 48 49 if title: 50 self.title(title) 51 52 self.parent = parent 53 54 try: 55 if isinstance(netcdf, _NetCDFFile): 56 self.netcdf = netcdf 57 self.netcdf_filename = re.findall('<open netCDF file \'(.*)\',.*', str(netcdf))[0] 58 59 elif isinstance(netcdf, Trajectory): 60 self.netcdf = NetCDFFile(netcdf.filename, 'r') 61 self.netcdf_filename = netcdf.filename 62 63 else: 64 raise 65 66 except: 67 self.netcdf = None 68 self.netcdf_filename = None 69 70 body = Frame(self) 71 self.initial_focus = self.body(body) 72 body.grid(row = 0, column = 0, sticky = EW) 73 74 self.buttonbox() 75 76 self.grab_set() 77 78 if not self.initial_focus: 79 self.initial_focus = self 80 81 self.protocol("WM_DELETE_WINDOW", self.cancel) 82 83 self.resizable(width = NO, height = NO) 84 85 self.geometry("+%d+%d" % (parent.winfo_rootx()+50, parent.winfo_rooty()+50)) 86 87 self.initial_focus.focus_set() 88 89 self.wait_window(self)
90
91 - def body(self, master):
92 """ 93 Create dialog body. Return widget that should have initial focus. 94 """ 95 96 settingsFrame = LabelFrame(master, text = 'Settings', bd = 2, relief = GROOVE) 97 settingsFrame.grid(row = 0, column = 0, sticky = EW, padx = 3, pady = 3) 98 settingsFrame.grid_columnconfigure(0, weight = 1) 99 100 # The combo widget for the file browser. 101 self.inputFileBrowser = ComboFileBrowser(settingsFrame,\ 102 frameLabel = "NetCDF input file",\ 103 tagName = 'convert_netcdf_to_ascii_netcdf_input_file',\ 104 contents = '',\ 105 save = False,\ 106 command = self.openNetCDFFile,\ 107 filetypes = [("NetCDF file", ".nc"),]) 108 self.inputFileBrowser.entry.bind('<Return>', self.openNetCDFFile) 109 self.inputFileBrowser.grid(row = 0, column = 0, sticky = EW, padx = 2, pady = 2) 110 self.inputFileBrowser.grid_columnconfigure(0, weight = 1) 111 112 self.variablesInfo = ComboText(settingsFrame,\ 113 frameLabel = 'Available variables',\ 114 tagName = 'convert_netcdf_to_ascii_available_variables') 115 self.variablesInfo.grid(row = 1, column = 0, columnspan = 2, sticky = EW, padx = 2, pady = 2) 116 self.variablesInfo.grid_columnconfigure(0, weight = 1) 117 self.variablesInfo.text.config({'height' : 10, 'width' : 68}) 118 119 self.variablesInfo.text.window_create('1.0',\ 120 window = Label(self.variablesInfo.text, 121 text = 'Select',\ 122 width = 13,\ 123 bg = 'Grey')) 124 125 self.variablesInfo.text.window_create('1.1',\ 126 window = Label(self.variablesInfo.text, 127 text = 'NetCDF Variable',\ 128 width = 50,\ 129 anchor = W,\ 130 bg = 'white')) 131 132 # The combo widget for the float precision. 133 self.floatPrecisionEntry = ComboIntegerEntry(settingsFrame,\ 134 frameLabel = 'Float precision',\ 135 tagName = 'convert_netcdf_to_ascii_float_precision',\ 136 contents = 9) 137 self.floatPrecisionEntry.grid(row = 2, column = 0, sticky = EW, padx = 2, pady = 2) 138 self.floatPrecisionEntry.grid_columnconfigure(0, weight = 1) 139 140 # The combo widget for the double precision. 141 self.doublePrecisionEntry = ComboIntegerEntry(settingsFrame,\ 142 frameLabel = 'Double precision',\ 143 tagName = 'convert_netcdf_to_ascii_double_precision',\ 144 contents = 17) 145 self.doublePrecisionEntry.grid(row = 3, column = 0, sticky = EW, padx = 2, pady = 2) 146 self.doublePrecisionEntry.grid_columnconfigure(0, weight = 1) 147 148 # The combo widget for the file browser. 149 self.outputFileBrowser = ComboFileBrowser(settingsFrame,\ 150 frameLabel = "ASCII/CDL output file",\ 151 tagName = 'convert_netcdf_to_ascii_ascii_output_file',\ 152 contents = '',\ 153 filetypes = [("CDL file", ".cdl"),],\ 154 save = True) 155 self.outputFileBrowser.grid(row = 4, column = 0, sticky = EW, padx = 2, pady = 2) 156 self.outputFileBrowser.grid_columnconfigure(0, weight = 1) 157 158 if self.netcdf is not None: 159 # The control variables are updated with the informations coming from the loaded trajectory. 160 self.inputFileBrowser.setValue(self.netcdf_filename) 161 self.displayNetCDFContents() 162 self.outputFileBrowser.setValue(os.path.splitext(self.netcdf_filename)[0] + '.cdl') 163 else: 164 self.outputFileBrowser.setValue('ASCII.cdl')
165
166 - def buttonbox(self):
167 """ 168 Add standard button box. 169 """ 170 171 # The frame that contains the 'Cancel' and 'OK' buttons. 172 box = LabelFrame(self, text = 'Actions', bd = 2, relief = GROOVE) 173 box.grid(row = 1, column = 0, sticky = EW, padx = 3, pady = 3) 174 box.grid_columnconfigure(0, weight = 1) 175 176 w = Button(box, text = "Cancel", width=10, command = self.cancel) 177 w.grid(row = 0, column = 0, sticky = E) 178 w = Button(box, text = "OK", width=10, command = self.ok, default=ACTIVE) 179 w.grid(row = 0, column = 1, sticky = E) 180 181 self.bind("<Return>", self.ok) 182 self.bind("<Escape>", self.cancel)
183 184 # Standard button semantics.
185 - def ok(self, event = None):
186 187 if not self.validate(): 188 self.initial_focus.focus_set() 189 return 190 191 self.update_idletasks() 192 193 self.apply()
194
195 - def cancel(self, event=None):
196 197 # Put focus back to the parent window 198 self.parent.focus_set() 199 self.destroy()
200 201 # Command hooks
202 - def validate(self):
203 204 # An input file must have been set. 205 self.inputFile = self.inputFileBrowser.getValue() 206 if not self.inputFile: 207 raise Error('Please enter a NetCDF input file.') 208 209 # The float precision entry is checked and stored. 210 self.floatPrecision = self.floatPrecisionEntry.getValue() 211 if self.floatPrecision <= 0: 212 raise Error('The float precision must > 0.') 213 214 # The double precision entry is checked and stored. 215 self.doublePrecision = self.doublePrecisionEntry.getValue() 216 if self.doublePrecision <= 0: 217 raise Error('The Double precision must > 0.') 218 219 # An output file must have been set. 220 self.outputFile = self.outputFileBrowser.getValue() 221 if not self.outputFile: 222 raise Error('Please enter an ASCII output file.') 223 224 # The extension '.cdl' is appended to the output file name if necessary. 225 if self.outputFile[-4:] != '.cdl': 226 self.outputFile += '.cdl' 227 228 # The selected variables are stored. 229 self.selectedVariables = [] 230 for k, v in self.variables.items(): 231 if v.get(): 232 self.selectedVariables.append(k) 233 234 if not self.selectedVariables: 235 raise Error('No NetCDF variables selected for conversion.') 236 237 return True
238 239 # Command hooks
240 - def apply(self):
241 """ 242 This method is called when the user clicks on the OK button of the conversion dialog. It performs the 243 conversion from the loaded NetCDF file to the selected ASCII/CDL file. 244 """ 245 246 convertNetCDFToASCII(inputFile = self.inputFile,\ 247 outputFile = self.outputFile,\ 248 variables = self.selectedVariables,\ 249 floatPrecision = self.floatPrecision,\ 250 doublePrecision = self.doublePrecision) 251 252 LogMessage('info', 'Conversion successful', ['gui'])
253 254
255 - def openNetCDFFile(self, event = None):
256 """ 257 This method opens a NetCDF file and updates the dialog with the data read from that file. 258 Arguments: 259 -event: Tkinter event. 260 """ 261 262 self.variablesInfo.text.config(state = NORMAL) 263 self.variablesInfo.text.delete('2.0', END) 264 self.variablesInfo.text.config(state = DISABLED) 265 266 # Case where the user enters a file name directly in the entry widget without using the browser. 267 if event is not None: 268 if event.widget == self.inputFileBrowser.entry: 269 filename = self.inputFileBrowser.getValue() 270 else: 271 return 272 273 else: 274 275 # The name of the NetCDF file to load. 276 filename = askopenfilename(parent = self,\ 277 filetypes = [('NetCDF file','*.nc')],\ 278 initialdir = PREFERENCES.outputfile_path) 279 280 # The file must exist otherwise do nothing. 281 if filename: 282 self.netcdf = NetCDFFile(filename, 'r') 283 284 self.displayNetCDFContents() 285 286 # The filebrowser entry is updated with the loaded filename. 287 self.inputFileBrowser.setValue(filename) 288 289 # A default filename for the output ASCII file is built. 290 self.outputFileBrowser.setValue(os.path.splitext(filename)[0] + '.cdl') 291 292 return 'break'
293
294 - def selectVariable(self):
295 296 for k, v in self.variables.items(): 297 if v.get(): 298 self.textVariables[k].set('selected') 299 300 else: 301 self.textVariables[k].set('unselected')
302 303
304 - def displayNetCDFContents(self):
305 """ 306 This method display the variables found in the NetCDF file. 307 """ 308 309 self.variables = {} 310 self.textVariables = {} 311 312 self.variablesInfo.text.config(state = NORMAL) 313 self.variablesInfo.text.delete('2.0', END) 314 self.variablesInfo.text.config(state = DISABLED) 315 316 comp = 0 317 for varName in sorted(self.netcdf.variables.keys()): 318 self.variables[varName] = BooleanVar() 319 self.variables[varName].set(True) 320 321 self.textVariables[varName] = StringVar() 322 self.textVariables[varName].set('selected') 323 324 self.variablesInfo.insert(END, '\n') 325 326 self.variablesInfo.text.window_create(str(comp + 2)+'.0',\ 327 window = Checkbutton(self.variablesInfo.text,\ 328 variable = self.variables[varName],\ 329 textvariable = self.textVariables[varName],\ 330 command = self.selectVariable,\ 331 anchor = W,\ 332 justify = LEFT,\ 333 bd = 1,\ 334 width = 10,\ 335 bg = 'Grey')) 336 337 self.variablesInfo.text.window_create(str(comp + 2)+'.1',\ 338 window = Label(self.variablesInfo.text,\ 339 text = varName,\ 340 width = 50,\ 341 anchor = W,\ 342 bg = 'white')) 343 comp += 1
344