1 |
|
---|
2 |
import string |
---|
3 |
import MV2 as MV |
---|
4 |
import tkFileDialog |
---|
5 |
import Pmw |
---|
6 |
import os |
---|
7 |
import gui_control |
---|
8 |
import Tkinter |
---|
9 |
import sys |
---|
10 |
import gui_user_menus |
---|
11 |
import gui_busy |
---|
12 |
import gui_message |
---|
13 |
import struct |
---|
14 |
import cdms2 |
---|
15 |
|
---|
16 |
|
---|
17 |
def make_var(lap,id=None,shape=None): |
---|
18 |
lap=MV.array(lap) |
---|
19 |
if shape is not None: |
---|
20 |
lap=MV.reshape(lap,shape) |
---|
21 |
if id is not None: |
---|
22 |
lap.id=id |
---|
23 |
return lap |
---|
24 |
|
---|
25 |
def read( file ,format="", endian='@', datatype='f', ids=[], shape=[], separator=""): |
---|
26 |
|
---|
27 |
f=open(file) |
---|
28 |
s=f.read() |
---|
29 |
f.close() |
---|
30 |
|
---|
31 |
|
---|
32 |
if format=="": |
---|
33 |
if shape==[]: |
---|
34 |
format=str(len(s)/struct.calcsize(datatype))+datatype |
---|
35 |
s=s[:struct.calcsize(format)] |
---|
36 |
if format=="": |
---|
37 |
if len(ids)>1 and len(shape)!=len(ids): |
---|
38 |
if len(shape)==1: |
---|
39 |
shape=shape*len(ids) |
---|
40 |
else: |
---|
41 |
raise "Error shapes and ids are not compatible" |
---|
42 |
format="" |
---|
43 |
for sh in shape: |
---|
44 |
n=1 |
---|
45 |
for S in sh: n=n*S |
---|
46 |
if format!="": |
---|
47 |
format=format+separator+str(n)+datatype |
---|
48 |
else: |
---|
49 |
format=format+str(n)+datatype |
---|
50 |
|
---|
51 |
|
---|
52 |
fsz=struct.calcsize(format) |
---|
53 |
|
---|
54 |
if len(s)!=fsz: |
---|
55 |
|
---|
56 |
if len(ids)>1 and len(shape)==1: |
---|
57 |
shape=shape*len(ids) |
---|
58 |
format2='' |
---|
59 |
for i in range(len(ids)): |
---|
60 |
if format2!="": |
---|
61 |
format2=format2+separator+format |
---|
62 |
else: |
---|
63 |
format2+=format |
---|
64 |
if len(s)==struct.calcsize(format2): |
---|
65 |
format=format2 |
---|
66 |
elif len(shape)==1 and ids==[]: |
---|
67 |
format2='' |
---|
68 |
sz=0 |
---|
69 |
n=0 |
---|
70 |
while sz<len(s): |
---|
71 |
n+=1 |
---|
72 |
sz=struct.calcsize(format2) |
---|
73 |
if format2!='' : |
---|
74 |
format2=format2+separator+format |
---|
75 |
else: |
---|
76 |
format2+=format |
---|
77 |
if sz==len(s): |
---|
78 |
format=format2 |
---|
79 |
shape=shape*n |
---|
80 |
else: |
---|
81 |
if len(s)<fsz: |
---|
82 |
s=s[:fsz] |
---|
83 |
else: |
---|
84 |
raise "Error coudln't read your data !" |
---|
85 |
|
---|
86 |
if not format[0] in ['@','=','<','>','!']: |
---|
87 |
format=endian+format |
---|
88 |
|
---|
89 |
|
---|
90 |
s=struct.unpack(format,s) |
---|
91 |
vars=[] |
---|
92 |
if shape!=[]: |
---|
93 |
i=0 |
---|
94 |
for sh in shape: |
---|
95 |
n=1 |
---|
96 |
for S in sh: n*=S |
---|
97 |
v=MV.array(s[:n]) |
---|
98 |
v=MV.reshape(v,sh) |
---|
99 |
if ids!=[]: |
---|
100 |
v.id=ids[i] |
---|
101 |
s=s[n:] |
---|
102 |
vars.append(v) |
---|
103 |
i+=1 |
---|
104 |
else: |
---|
105 |
v=MV.array(s) |
---|
106 |
if ids!=[]: |
---|
107 |
v.id=ids[0] |
---|
108 |
vars.append(v) |
---|
109 |
|
---|
110 |
if len(vars)>1: |
---|
111 |
return vars |
---|
112 |
else: |
---|
113 |
return vars[0] |
---|
114 |
|
---|
115 |
|
---|
116 |
class read_bin_popup: |
---|
117 |
def evt_icon_open_file(self, parent, dirfilename=None, event=None): |
---|
118 |
datatypes = [ |
---|
119 |
("All files", "*") |
---|
120 |
] |
---|
121 |
|
---|
122 |
dialog_icon = tkFileDialog.Open(master=parent, |
---|
123 |
filetypes=datatypes, title = 'File Select') |
---|
124 |
dirfilename=dialog_icon.show(initialdir=os.getcwd()) |
---|
125 |
self.file.setentry(dirfilename) |
---|
126 |
|
---|
127 |
def __init__(self, Self,parent): |
---|
128 |
self.parent = parent |
---|
129 |
self.Self=Self |
---|
130 |
self.dialog = Pmw.Dialog( parent, |
---|
131 |
title = "Reading a Binary File", |
---|
132 |
buttons = ('OK', 'Dismiss'), |
---|
133 |
defaultbutton = 'OK', |
---|
134 |
command = gui_control.Command(self.execute, parent) ) |
---|
135 |
|
---|
136 |
if parent.menu.popup_window_settings_flg == 1: |
---|
137 |
self.dialog.transient( self.parent ) |
---|
138 |
|
---|
139 |
d=self.dialog.interior() |
---|
140 |
frame=Tkinter.Frame(d) |
---|
141 |
frame.pack(fill='x',pady=5) |
---|
142 |
file=Tkinter.Label(frame,text='File:') |
---|
143 |
file.pack(fill='x',pady=5,side='left') |
---|
144 |
self.canvas_openicon = Tkinter.Canvas(frame, bd=0, highlightthickness=0, |
---|
145 |
width = 27, height = 27) |
---|
146 |
self.canvas_openicon.pack( side='left', fill='x', pady=5 ) |
---|
147 |
parent.balloon.bind( self.canvas_openicon, |
---|
148 |
"Display 'File Select' browser for 'Directory' and 'File' selection." ) |
---|
149 |
self.img = Tkinter.PhotoImage( file = os.path.join(cdms2.__path__[0],'..','..','..','..', 'bin', 'open.gif') ) |
---|
150 |
self.canvas_openicon.create_image(0,0, anchor=Tkinter.NW, image=self.img ) |
---|
151 |
self.canvas_openicon.bind( '<1>', gui_control.Command( self.evt_icon_open_file, parent, None )) |
---|
152 |
self.file=Pmw.EntryField(frame,labelpos='w', |
---|
153 |
label_text='', |
---|
154 |
entry_background = 'white', |
---|
155 |
entry_foreground = 'black', |
---|
156 |
entry_width = 20, |
---|
157 |
) |
---|
158 |
self.file.pack( side='left',fill = 'x', pady=5 ) |
---|
159 |
self.parent.balloon.bind( self.file, "Browse to get the file to read" ) |
---|
160 |
|
---|
161 |
|
---|
162 |
endian=['Native (@)','Native (=)','Little-Endian (<)', 'Big-Endian (>)',] |
---|
163 |
self.endian=Pmw.OptionMenu(d, |
---|
164 |
labelpos='w', |
---|
165 |
label_text='Endian:', |
---|
166 |
items=endian, |
---|
167 |
initialitem='Native (@)', |
---|
168 |
) |
---|
169 |
self.endian.pack( pady=5,fill='x') |
---|
170 |
self.parent.balloon.bind( self.endian, "The Endian in which the File as been written, Big or Little" ) |
---|
171 |
|
---|
172 |
|
---|
173 |
self.format=Pmw.EntryField(d,labelpos='w', |
---|
174 |
label_text='Format:', |
---|
175 |
entry_background = 'white', |
---|
176 |
entry_foreground = 'black', |
---|
177 |
entry_width = 20, |
---|
178 |
) |
---|
179 |
self.format.pack( fill ='x', pady=5 ) |
---|
180 |
self.parent.balloon.bind( self.format, "The format of each variables" ) |
---|
181 |
self.format.setentry('') |
---|
182 |
|
---|
183 |
|
---|
184 |
datatypes=['char','signed char','unsigned char','short','unsigned short','int','unsigned int','long','unsigned long','float','double'] |
---|
185 |
self.datatype=Pmw.OptionMenu(d, |
---|
186 |
labelpos='w', |
---|
187 |
label_text='Datatype:', |
---|
188 |
items=datatypes, |
---|
189 |
initialitem='float', |
---|
190 |
) |
---|
191 |
|
---|
192 |
self.datatype.pack(fill='x',pady=5) |
---|
193 |
self.parent.balloon.bind( self.datatype, "Datatype in the file (only if all data are from same type)\nEntering anything in Format will override this" ) |
---|
194 |
|
---|
195 |
|
---|
196 |
self.shape=Pmw.EntryField(d,labelpos='w', |
---|
197 |
label_text='Shape:', |
---|
198 |
entry_background = 'white', |
---|
199 |
entry_foreground = 'black', |
---|
200 |
entry_width = 20, |
---|
201 |
) |
---|
202 |
self.shape.pack( fill = 'x', pady=5 ) |
---|
203 |
self.parent.balloon.bind( self.shape, |
---|
204 |
"The variables shape or number of elements in the file\nDimensions are spaces or comma separated)\nMultiple shapes can be entered must be in format (n1,n2,n3..), (m1,m2,m3,...)\nIf only one shape and multiple ids, then it is assumed shape is identical for all variables\nIf Format is filled then shape(s) and Format must match, otherwise format will prevail and a 1D array will be returned", |
---|
205 |
) |
---|
206 |
|
---|
207 |
|
---|
208 |
self.id=Pmw.EntryField(d,labelpos='w', |
---|
209 |
label_text='Id:', |
---|
210 |
entry_background = 'white', |
---|
211 |
entry_foreground = 'black', |
---|
212 |
entry_width = 20, |
---|
213 |
) |
---|
214 |
self.id.pack( fill = 'x', pady=5 ) |
---|
215 |
self.parent.balloon.bind( self.id, "The variables id(s) (space or comma separated)" ) |
---|
216 |
|
---|
217 |
|
---|
218 |
self.vs=Pmw.EntryField(d,labelpos='w', |
---|
219 |
label_text='Variables separators:', |
---|
220 |
entry_background = 'white', |
---|
221 |
entry_foreground = 'black', |
---|
222 |
entry_width = 20, |
---|
223 |
) |
---|
224 |
self.vs.pack( fill = 'x', pady=5 ) |
---|
225 |
self.parent.balloon.bind( self.vs, "The string sequence that separates variables\nWill be inserted between each variable format" ) |
---|
226 |
self.vs.setentry('') |
---|
227 |
|
---|
228 |
|
---|
229 |
entries = ( self.endian, self.format, self.datatype, self.shape, self.id, self.vs) |
---|
230 |
Pmw.alignlabels(entries) |
---|
231 |
|
---|
232 |
def execute(self, parent,button): |
---|
233 |
if button=='OK': |
---|
234 |
gui_busy.busyStart( self, parent ) |
---|
235 |
try: |
---|
236 |
file=self.file.get() |
---|
237 |
while file=="": |
---|
238 |
file=self.evt_icon_open_file(self.parent,None) |
---|
239 |
file=self.file.get() |
---|
240 |
e=self.endian.index(self.endian.getvalue()) |
---|
241 |
endians=['@','=','<','>'] |
---|
242 |
e=endians[e] |
---|
243 |
f=self.format.get() |
---|
244 |
try: |
---|
245 |
struct.calcsize(f) |
---|
246 |
except: |
---|
247 |
Pmw.Dialog(self.parent, |
---|
248 |
title = "Wrong Format !", |
---|
249 |
buttons = ('OK',), |
---|
250 |
) |
---|
251 |
gui_busy.busyEnd( self, parent ) |
---|
252 |
return |
---|
253 |
|
---|
254 |
id=self.id.get() |
---|
255 |
if id=="": |
---|
256 |
id=[] |
---|
257 |
else: |
---|
258 |
id=id.split(',') |
---|
259 |
id=string.join(id) |
---|
260 |
id=id.split() |
---|
261 |
sh=self.shape.get() |
---|
262 |
if sh=="": |
---|
263 |
sh=[] |
---|
264 |
else: |
---|
265 |
sh=sh.strip() |
---|
266 |
if sh[0]=='(': |
---|
267 |
sh=eval(sh) |
---|
268 |
else: |
---|
269 |
sh=sh.split(',') |
---|
270 |
sh=string.join(sh) |
---|
271 |
sh=sh.split('(') |
---|
272 |
sh=string.join(sh) |
---|
273 |
sh=sh.split(')') |
---|
274 |
sh=string.join(sh) |
---|
275 |
sh2=sh.split() |
---|
276 |
sh=[] |
---|
277 |
for s in sh2: |
---|
278 |
sh.append(eval(s)) |
---|
279 |
sh=[list(sh),] |
---|
280 |
|
---|
281 |
datatype=self.datatype.index(self.datatype.getvalue()) |
---|
282 |
dtp=['c','b','B','h','H','i','I','l','L','f','d'] |
---|
283 |
datatype=dtp[datatype] |
---|
284 |
|
---|
285 |
vs=self.vs.get() |
---|
286 |
try: |
---|
287 |
struct.calcsize(vs) |
---|
288 |
except: |
---|
289 |
Pmw.Dialog(self.parent, |
---|
290 |
title = "Wrong Format for Variable Separators !", |
---|
291 |
buttons = ('OK',), |
---|
292 |
) |
---|
293 |
gui_busy.busyEnd( self, parent ) |
---|
294 |
return |
---|
295 |
|
---|
296 |
vars=read( file ,format=f, endian=e, datatype=datatype, ids=id, shape=sh,separator=vs) |
---|
297 |
gui_control.record_command( parent, "\n# PCMDI's read Binary Tool\nimport browser", 1 ) |
---|
298 |
ids='' |
---|
299 |
ids_lst='' |
---|
300 |
if isinstance(vars,list): |
---|
301 |
for v in vars: |
---|
302 |
v.id = self.Self.return_unique_name( v.id) |
---|
303 |
ids+=v.id+', ' |
---|
304 |
ids_lst+=repr(v.id)+', ' |
---|
305 |
gui_user_menus.user_menus_put( v.id, v ) |
---|
306 |
else: |
---|
307 |
v=vars |
---|
308 |
v.id = self.Self.return_unique_name( vars.id) |
---|
309 |
ids+=v.id+', ' |
---|
310 |
ids_lst+=repr(v.id)+', ' |
---|
311 |
gui_user_menus.user_menus_put( v.id, v ) |
---|
312 |
|
---|
313 |
gui_control.record_command( parent, "%s = browser.gui_read_Struct.read(%s, format=%s, endian=%s, datatype=%s, ids= %s, shape=%s, separator=%s)" % (ids[:-2], repr(file), repr(f), repr(e), repr(datatype), '[ '+ids_lst[:-2]+' ]', str(sh), repr(vs)), 1 ) |
---|
314 |
|
---|
315 |
gui_busy.busyEnd( self, parent ) |
---|
316 |
except Exception, err: |
---|
317 |
gui_busy.busyEnd( self, parent ) |
---|
318 |
gui_message.error( "The 'Binary Read Tool' could not complete its function\nError:\n"+str(err)) |
---|
319 |
|
---|
320 |
self.dialog.destroy() |
---|