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
9 import copy
10 import inspect
11 import os
12 import re
13 import sys
14
15
16 from tkFileDialog import askopenfilename
17 from Tkinter import *
18
19
20 from Scientific import N as Num
21 from Scientific.IO.NetCDF import _NetCDFFile, NetCDFFile
22
23 from MMTK.Trajectory import Trajectory
24
25
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
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
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
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
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
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
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
183
184
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
198 self.parent.focus_set()
199 self.destroy()
200
201
203
204
205 self.inputFile = self.inputFileBrowser.getValue()
206 if not self.inputFile:
207 raise Error('Please enter a NetCDF input file.')
208
209
210 self.floatPrecision = self.floatPrecisionEntry.getValue()
211 if self.floatPrecision <= 0:
212 raise Error('The float precision must > 0.')
213
214
215 self.doublePrecision = self.doublePrecisionEntry.getValue()
216 if self.doublePrecision <= 0:
217 raise Error('The Double precision must > 0.')
218
219
220 self.outputFile = self.outputFileBrowser.getValue()
221 if not self.outputFile:
222 raise Error('Please enter an ASCII output file.')
223
224
225 if self.outputFile[-4:] != '.cdl':
226 self.outputFile += '.cdl'
227
228
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
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
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
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
276 filename = askopenfilename(parent = self,\
277 filetypes = [('NetCDF file','*.nc')],\
278 initialdir = PREFERENCES.outputfile_path)
279
280
281 if filename:
282 self.netcdf = NetCDFFile(filename, 'r')
283
284 self.displayNetCDFContents()
285
286
287 self.inputFileBrowser.setValue(filename)
288
289
290 self.outputFileBrowser.setValue(os.path.splitext(filename)[0] + '.cdl')
291
292 return 'break'
293
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
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