source: TI02-CSML/trunk/Scanner/csmllibs/csmldataiface.py @ 1466

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI02-CSML/trunk/Scanner/csmllibs/csmldataiface.py@1466
Revision 1466, 12.8 KB checked in by domlowe, 15 years ago (diff)

changes to allow time values to use different reference systems within the same feature

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#!/usr/bin/env python
2
3#**************************************************************************************
4#csmldataIface.py
5#contains classes for interfacing with various files
6#currently supports cdunif (NetCDF, PP, Grib(untested)) And Nappy (NASAAmes)
7#use by instantiating the factory class: DataInterface
8#v0.00 30th November 2005
9#Dominic Lowe, BADC
10#**************************************************************************************
11
12
13import cdms 
14import nappy 
15import string
16import sys
17
18class DataInterface(object):
19        #Use DataInterface and setInterfaceType to instantiate the correct
20        #subclass for data
21        def __init__(self):
22                self.iface ='None'
23               
24        def setInterfaceType(self,interfaceType):
25                # function returns approprate data interface
26                #set interfaceType: should correspond to available datainterface subclasses
27                self.iface =interfaceType
28                if self.iface == 'nappy':
29                        return NappyInterface()
30                elif self.iface == 'cdunif':
31                        return cdunifInterface()
32               
33               
34        def getUnknownInterfaceType(self, filename):
35                #if the interface type is not known at the time of instantiation, then use
36                #this function to examine the file and return the correct interface (if it exists).
37                fileExtension = str(filename)[-3:]
38                if fileExtension == '.nc':
39                        return cdunifInterface()
40                if fileExtension == '.qxf':
41                        return cdunifInterface()
42                elif fileExtension == '.pp':
43                        return cdunifInterface()
44                elif fileExtension == 'ctl':
45                        return cdunifInterface()
46                else:
47                        try:
48                                nappy.readFFI(filename) in [1001,1010,1020,2010,2110,2160,2310,3010,4010]
49                                return NappyInterface()
50                        except:
51                                print "Could not establish file type"
52                                print "See csmldataiface.py"
53                       
54       
55                                                       
56class AbstractDI(object):               
57        #Abstract data interface class
58        #does nothing, but contains templates for methods required for a data interface class
59        #individual interfaces (e.g NappyInterface) should override these methods
60
61        def __init__(self):
62                self.extractType=''
63                self.extractPrefix = ''
64                                       
65        def openFile(self, filename):
66                #opens file
67                self.file=''
68               
69        def closeFile(self):
70                #closes file
71                self.file.close()
72                       
73               
74               
75class NappyInterface(AbstractDI):       
76        # Data Interface for Nappy (NASA Ames Processing in Python)
77   
78        def __init__(self):
79                self.extractType='NASAAmesExtract'
80                self.extractPrefix = '_naextract_'
81                                         
82        def openFile(self, filename):
83                #print 'opening NA file: ' + str(filename)
84                self.file=nappy.openNAFile(filename)
85                #print 'reading data....'
86                #self.file.readData()
87                #print 'nappyopen ' + filename
88
89        def getListOfAxes(self):
90                axes=self.file.XNAME
91                #print 'before units stripped' + str(axes)
92                axes=self.stripunits(axes)
93                #print 'after units stripped' + str(axes)
94                return axes
95
96        def setAxis(self,axis):
97                axes = self.getListOfAxes()
98                self.axisstub=axes.index(axis)
99
100        def getAxisAttribute(self, att):
101                        #need to do something here...? maybe
102                pass
103                return attValue
104
105        def getTimeUnits(self):
106                axes = self.getListOfAxes()
107                for axis in axes:
108                        if string.find(string.upper(axis),'SECONDS SINCE') != -1:
109                                #found possible time axis.
110                                if axis[-3:]=='UTC':
111                                    units =string.lower(axis[:-4]) #hack!
112                                    units=units.replace('/','-') #try and clean it up
113                                else:
114                                    units=string.lower(axis)
115                                break
116                        elif string.find(string.upper(axis),'HOURS SINCE') != -1:
117                                #found possible time axis.
118                                units =(str(axis))
119                                break
120                        elif string.find(string.upper(axis),'DAYS SINCE') != -1:
121                                #found possible time axis.
122                                units =(str(axis))
123                                break
124                       
125                #revisit with udunits python library?
126                return units
127
128
129        def getDataForAxis(self):
130
131                if self.file.X == None:
132                        #print 'reading data....'
133                        self.file.readData()
134
135                if type(self.file.X[1])==list:
136                #if len(self.file.X) > 0:
137                        data = self.file.X[self.axisstub]
138                else:
139                        data =self.file.X
140                return data
141
142        def getSizeOfAxis(self,axis):
143
144                #check this function is okay
145                #is time always the first dimension in NA??
146                axes = self.getListOfAxes()
147                axisPosition=axes.index(axis)
148                #print "axis position" + str( axisPosition)
149                #print "NX" + str(self.file.NX)
150                try :
151                        axisSize=self.file.NX[axisPosition-1]
152                except:
153                        axisSize ='Unknown axis size'
154                return axisSize
155
156        def getListofVariables(self):
157                variableList=self.stripunits(self.file.VNAME)
158                return variableList
159
160        def setVariable(self,varname):
161                vlist=self.getListofVariables()
162                self.varstub=vlist.index(varname)
163
164        def getVariableAxes(self):
165                #hmm, now with Nasa Ames the Axis will be the same for all variables.
166                #so just use the getListOfAxes function again
167                #I think... check this!
168                varAxesList=self.getListOfAxes()
169                return varAxesList
170
171        def getVariableAttribute(self,attName):
172                if attName =='units':
173                        #strip the units (attribute) from the variable
174                        unitslist=self.getUnits(self.file.VNAME)
175                        attribValue = unitslist[self.varstub]
176                        try:
177                                attribValue = unitslist[self.varstub]
178                        except:
179                                attribValue = 'unknown'
180                else:
181                        attribValue = 'unknown'
182                return attribValue
183
184        def getDataForVar(self):
185            #NOTE TO SELF:
186            #Review this function (and in fact all of nasa ames data interface...)
187                if self.file.V == None:
188                        #print 'reading data....'
189                        self.file.readData()
190
191                try:
192                    if type(self.file.V[1])==list:
193                        data = self.file.V[self.varstub]
194                #else:
195                #       data =self.file.X
196                #       print data
197                    return data
198                except:
199                    data = self.file.X
200                   # print data
201                    return data
202
203        def getArraySizeOfVar(self):
204        #iterates through all dimensions in variable to get array size i.e a 3x3x3 array would have a size of 27
205
206                dimlist=self.file.NX
207                varsize =1
208                for item in dimlist:
209                        varsize = varsize * item
210                        #print "VARSISZE" + str(varsize)
211                return varsize
212
213        def getShapeOfVar(self):
214            #this should return a list.
215            varShape = []
216            for item in self.file.NX:
217                varShape.append(item)
218            return varShape
219
220        def getLowLimits(self):
221                lowlims = ""
222                for i in range (0, len(self.file.NX)):
223                        #for now, assume low limit is always of form 1 1 1 ..
224                        lowlims =lowlims + str(1)  +' '
225                return lowlims
226
227        def getHighLimits(self):
228                highlims = ""
229                for i in range (0, len(self.file.NX)):
230                        dimValue = self.file.NX[i]
231                        highlims =highlims  + str(dimValue) +' '
232                return highlims
233
234
235        def stripunits(self,listtostrip):
236                #strips units of measure from list
237                #eg ['Universal time (hours)', 'Altitude (km)', 'Latitude (degrees)', 'Longitude (degrees)']
238                #becomes ['Universal time', 'Altitude', 'Latitude', 'Longitude']
239                cleanlist = []
240                for item in listtostrip:
241                        openbracket=string.find(item,'(')
242                        if openbracket != -1:
243                                #if brackets exist, strip units.
244                                item=item[:openbracket-1]
245                        cleanlist.append(item)
246                return cleanlist
247
248        def getUnits(self,listwithunits):
249                #gets units from list
250                #eg ['Universal time (hours)', 'Altitude (km)', 'Latitude (degrees)', 'Longitude (degrees)']
251                #becomes ['hours', 'km', 'degrees', 'degrees']
252                unitlist=[]
253                for item in listwithunits:
254                        openbracket=string.find(item,'(')
255                        item = item[openbracket+1:-1]
256                        unitlist.append(item)
257                return unitlist
258
259        def getTimes(self):
260                #This function attempts to determine the time axis and read the time data
261                #it may well not manage it.
262                axes = self.getListOfAxes()
263                for axis in axes:
264                        if string.find(string.upper(axis),'TIME') != -1:
265                                #found possible time axis.
266                                self.setAxis(axis)
267                                times=self.getDataForAxis()
268                                break
269                        elif string.find(string.upper(axis),'SECONDS SINCE') != -1:
270                                #found possible time axis.
271                                self.setAxis(axis)
272                                times=self.getDataForAxis()
273                                break
274                        elif string.find(string.upper(axis),'HOURS SINCE') != -1:
275                                #found possible time axis.
276                                self.setAxis(axis)
277                                times=self.getDataForAxis()
278                                break
279                        elif string.find(string.upper(axis),'DAYS SINCE') != -1:
280                                #found possible time axis.
281                                self.setAxis(axis)
282                                times=self.getDataForAxis()
283                                break
284                return times
285
286
287
288class cdunifInterface(AbstractDI):
289    #Data Interface for cdunif (netcdf & pp formats & grib (not tested with grib)
290
291    def __init__(self):
292        #these are just temporary values until we can determine whether the
293        #file is netcdf pp or grib
294        self.extractType='cdunifExtract'
295        self.extractPrefix = '_cdunifextract_'
296
297    def openFile(self, filename):
298        self.file=cdms.open(filename)
299        #print 'cdunifopen ' + filename
300
301        #now we have the file name can properly determine extractType/Prefix
302        fileExtension = str(filename)[-3:]
303        if fileExtension == '.nc':
304            self.extractType = 'NetCDFExtract'
305            self.extractPrefix = '_ncextract_'
306        elif fileExtension == '.qxf':
307            self.extractType = 'NetCDFExtract'
308            self.extractPrefix = '_ncextract_'
309        elif fileExtension == '.pp':
310            self.extractType  = 'PPExtract'
311            self.extractPrefix = '_ppextract_'
312        elif fileExtension == 'ctl':
313            self.extractType = 'GRIBExtract'
314            self.extractPrefix = '_gribextract_'
315
316    def getListOfAxes(self):
317        axes=self.file.dimensions.keys()
318        return axes
319
320    def getSizeOfAxis(self,axis):
321        axisSize=self.file.dimensions[axis]
322        return axisSize
323
324    def getListofVariables(self):
325        variableList=self.file.variables.keys()
326        return variableList
327
328    def setAxis(self,axis):
329        self.axisobj=self.file.getAxis(axis)
330
331    def getAxisAttribute(self, att):
332        attValue=self.axisobj.attributes[att]
333        return attValue
334
335    def getTimeUnits(self):
336        #this does the same as getAxisAttribute, but is a separate function as different formats handle time differently.
337        return self.getAxisAttribute('units')
338
339    def getDataForAxis(self):
340        data = self.axisobj.getValue()
341        return data
342
343    def setVariable(self,varname):
344        self.varobj=self.file.variables[varname]
345
346    def getVariableAxes(self):
347        varAxesList=self.varobj.getAxisIds()
348        return varAxesList
349
350    def getVariableAttribute(self,attName):
351
352        #atts=self.varobj.getattributes(attName)
353        #print atts
354        if attName == 'long_name':
355            try:
356                attribValue = self.varobj.long_name
357            except:
358                attribValue=''
359        elif attName == 'units':
360            try:
361                attribValue = self.varobj.units
362            except:
363                attribValue=''
364
365        return attribValue
366
367    def getDataForVar(self):
368        data = self.varobj.getValue()
369        return data
370
371    def getSubsetOfDataForVar(self, **kwargs):
372        #takes keyword args defining subset eg
373        #subset=getSubsetOfDataForVar(latitude=(0.,10.0), longitude=(90, 100.0))
374        for key in kwargs:
375            if key == 'longitude':   #this test needs to be more robust...
376                print kwargs[key]
377                if kwargs[key][0] > kwargs[key][1]:
378                    #subsetting greenwich meridian around 0
379                    lonMin = kwargs[key][0]
380                    lonMax =kwargs[key][1]
381                    kwargs[key]=(0.0, lonMax)
382                    sel=cdms.selectors.Selector(**kwargs)
383                    subset1=self.file(self.varobj.name,sel)
384                    kwargs[key]=(lonMin,359.9999)
385                    sel=cdms.selectors.Selector(**kwargs)
386                    subset2=self.file(self.varobj.name,sel)
387                    #concatenate arrays along longitude
388                    longitudeAxis=subset1.getAxisIndex('longitude') # this needs to be more robust test.
389                    subset = cdms.MV.concatenate([subset1,subset2],axis=longitudeAxis)
390                else:
391                    sel=cdms.selectors.Selector(**kwargs)
392                    subset=self.file(self.varobj.name,sel)
393        data = subset
394        return data
395
396    def getArraySizeOfVar(self):
397    #iterates through all dimensions in variable to get array size i.e a 3x3x3 array would have a size of 27
398        var = self.varobj
399        size = var.shape
400        varsize = 1
401        for item in size:
402            varsize = item *varsize
403        return varsize
404
405    def getShapeOfVar(self):
406        varShape = []
407        for item in self.varobj.shape:
408            varShape.append(item)
409        return varShape
410
411    def getLowLimits(self):
412        dimNames = self.varobj.getAxisIds()
413        lowlims = ""
414        for i in range (1, len(dimNames)):
415            #for now, assume low limit is always of form 1 1 1 ..
416            lowlims =lowlims + str(1)  +' '
417        return lowlims
418
419    def getHighLimits(self):
420        dimNames = self.varobj.getAxisIds()
421        highlims = ""
422        for i in range (1, len(dimNames)):
423            dimValue = self.file.dimensions[dimNames[i]]
424            highlims =highlims  + str(dimValue) +' '
425        return highlims
426       
427   
428
429       
Note: See TracBrowser for help on using the repository browser.