root/cdat/trunk/Packages/browser/Lib/gui_read_Struct.py

Revision 7340, 12.6 kB (checked in by doutriaux1, 1 month ago)

hopefully fixed the MISuse of sys.prefix for things install in cdat which can be installed somewhere else

Line 
1 # Adapted for numpy/ma/cdms2 by convertcdms.py
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     ## first if format has not been entered!
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     ## Now test on format
52     fsz=struct.calcsize(format)
53
54     if len(s)!=fsz:
55         ## pbm with sizes, not good....
56         if len(ids)>1 and len(shape)==1: ## Ok 1 shape multiple vars!
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==[]: ## Ok let's try to repeat
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: # everything failed if format smaller than s, thne let's hope it's garbage a the end
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 ) # Keep widget on top of its 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         ## Big or Little Endian Button
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         ## Variables format
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         ## datatype
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         ## Number of elements or shape
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         ## Variable id once into the Defined variable
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         ## Variables separator
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()
Note: See TracBrowser for help on using the browser.