source: TI02-CSML/trunk/parser/csmlio.py @ 928

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI02-CSML/trunk/parser/csmlio.py@928
Revision 928, 12.2 KB checked in by domlowe, 13 years ago (diff)

fixing path in csmlio.py

Line 
1#csmlio.py
2#Contains Parser wrapper'functions to enable reading of data
3
4from  Parser import *
5import nappy
6import cdms
7import parser_extra
8from xml.dom.minidom import parseString
9import elementtree.ElementTree as etree
10
11#import the DataInterface module from the Scanner, assumes it is in a sibling directory to the one containing csmlio.py
12#TODO - how best to organise modules...
13import os
14currentPath=os.getcwd()
15parentPath=os.sep.join(currentPath.split(os.sep)[:-1])
16parserPath=parentPath + '/Scanner/csmllibs'
17sys.path.append(parserPath) #append the parser path to sys.path
18try:
19    import csmldataiface
20except:
21    print 'Could not import CSML Data Interface module. Make sure the Parser code is in ../parser directory on the same level as ../Scanner directory.'
22    sys.exit()
23
24
25class CSMLinterface:
26    #Wrapper class containing methods to read/write from/to CSML
27    #Uses parser.
28    def __init__(self):
29        self.dataset=None
30        self.currentFeature=None
31        self.currentArrayDescriptor = None
32        #this is a fix to the  ElementTree namespace problem that namespaces are usually represented as ns0, ns1, ns2 etc.
33        etree._namespace_map.update({
34        'http://www.opengis.net/om': 'om',  'http://www.opengis.net/gml': 'gml','http://ndg.nerc.ac.uk/csml' : 'csml', 'http://www.w3.org/1999/xlink':'xlink'})
35   
36    def __setFeature(self,featureID):
37        #given a featureID, set the currentFeature if it is not already set
38        #this is used to check the correct feature is always set.   
39            for member in self.dataset.featureCollection.members:
40                if member.id == featureID:
41                    self.currentFeature = member
42
43    def __setArrayDescriptor(self,fileExtractID):
44        #given a fileExtractID, set the currentArrayDescriptor if it is not already set
45        if self.currentArrayDescriptor is None:
46            for arrayDescriptor in self.dataset.arrayDescriptors:
47                if arrayDescriptor.id == fileExtractID:
48                    self.currentArrayDescriptor=arrayDescriptor
49        if self.currentArrayDescriptor.id != fileExtractID:
50            for arrayDescriptor in self.dataset.arrayDescriptors:
51                if arrayDescriptor.id == fileExtractID:
52                    self.currentArrayDescriptor=arrayDescriptor
53
54    def parse(self,csmldoc):
55        #takes incoming csml document and parses it.
56        tree = ElementTree(file=csmldoc)
57        self.dataset=Dataset()
58        self.dataset.fromXML(tree.getroot())
59        self.dataset =parser_extra.ParserPostProcessor(self.dataset).resolveReferences()
60        #self.currentFeature holds a feature object
61        self.currentFeature = None
62       
63    def getDatasetObj(self):
64        #if you want to bypass this wrapper layer, call this method and it will
65        #return a Parser.Dataset object, which you can interrogate...
66        return self.dataset
67
68    def getCSMLasString(self):
69        #returns csml document as a string
70        strCSML=self.dataset.toXML()
71        #strCSML= parseString(tostring(strCSML)).toprettyxml()
72        #strCSML= parser_extra.removeInlineNS(strCSML)
73        return strCSML
74
75    def getFeatureList(self):
76        #returns a list of feature ids
77        self.featureList = []
78        for member in self.dataset.featureCollection.members:
79             self.featureList.append(member.id)
80        return self.featureList
81       
82    def getFeatureType(self,featureID):
83        self.__setFeature(featureID)
84        if isinstance(self.currentFeature, PointFeature):
85            featureType = 'PointFeature'
86        elif isinstance(self.currentFeature, PointSeriesFeature):
87            featureType = 'PointSeriesFeature'
88        elif isinstance(self.currentFeature, ProfileFeature):
89            featureType = 'ProfileFeature'
90        elif isinstance(self.currentFeature, ProfileSeriesFeature):
91            featureType = 'ProfileSeriesFeature'
92        elif isinstance(self.currentFeature, GridFeature):
93            featureType = 'GridFeature'
94        elif isinstance(self.currentFeature, GridSeriesFeature):
95            featureType = 'GridSeriesFeature'
96        elif isinstance(self.currentFeature, TrajectoryFeature):
97            featureType = 'TrajectoryFeature'
98        else:
99             featureType = 'Unknown feature'
100        return featureType
101   
102    def getFeatureDescription(self,featureID):
103        #returns gml:description (== long name) of feature
104        #returns empty string if not available
105        self.__setFeature(featureID)
106        if hasattr(self.currentFeature, 'description'):
107            desc = self.currentFeature.description
108        else:
109            desc =""
110        return desc
111       
112    def getFileExtractList(self):
113        fileExtractList=[]
114        for arrayDescriptor in self.dataset.arrayDescriptors:
115            fileExtractList.append(arrayDescriptor.id)
116        return fileExtractList
117   
118    def subsetList(self, fileExtractID, valueList, minValue, maxValue):
119        #This is a simple list subsetter. Given a List of values (which may have been extracted from a NetCDF/NASAAmes file
120        #or may have been taken from inline CSML, it doesn't matter) this function returns a subset based on max and min values.
121        #There is inefficiency here as you have to read in the whole  'axis' before subsetting       
122        # Also It assumes monotonically varying axis (although a non-monotonically varying axis 'might' work depending on it's shape)
123        #find position of minValue in list:
124#         self.__setArrayDescriptor(fileExtractID)
125#         
126        #find position of maxValue in list:
127        pass
128        #slice list:
129       
130        return subset
131       
132   
133
134   
135    def getDataForExtract(self, fileExtractID):
136        #getDataForExtract, given the gml:id of a file extract, returns the (full) data for that extract
137        self.__setArrayDescriptor(fileExtractID)
138        file = self.currentArrayDescriptor.fileName
139        variable = self.currentArrayDescriptor.variableName
140        DI = csmldataiface.DataInterface()
141        DI=DI.getUnknownInterfaceType(file)       
142        DI.openFile(file)
143        DI.setAxis(variable)
144        fulldata = DI.getDataForAxis()
145        DI.closeFile()
146        print fulldata
147        return fulldata
148       
149    def getDataForVariable(self,file, variable, **kwargs):
150        #given a filename and a variable name, get values for that variable from data interface
151        DI = csmldataiface.DataInterface()
152        DI=DI.getUnknownInterfaceType(file)       
153        DI.openFile(file)
154        DI.setVariable(variable)
155       
156       
157        if kwargs:
158            data = DI.getSubsetOfDataForVar(**kwargs)
159        else:
160            data = DI.getDataForVar()
161        return data
162       
163    def getDataForFeature(self, featureID, timeSubset,  **kwargs):
164        #getDataForFeature, given the gml:id of a file extract, returns the (full) data for that feature
165        #i.e. the rangeSet
166        #Needs to use the rangeSet, domainReference and domainComplement to work out how to
167        #extract the data from file
168        self.__setFeature(featureID)
169        if timeSubset:
170            pass
171        else:
172            timeSubset=None
173        #The RangeSet can be one of:
174        #QuantityList
175        #DataBlock
176        #ArrayDescriptor
177        #AggregatedArray
178        print self.currentFeature.rangeSet
179        if hasattr(self.currentFeature.rangeSet, 'quantityList'):
180            print self.currentFeature.rangeSet.quantityList
181        elif hasattr(self.currentFeature.rangeSet, 'dataBlock'):
182            print self.currentFeature.rangeSet.dataBlock
183        elif hasattr(self.currentFeature.rangeSet, 'arrayDescriptor'):
184            print self.currentFeature.rangeSet.arrayDescriptor
185        elif hasattr(self.currentFeature.rangeSet, 'aggregatedArray'):
186            print self.currentFeature.rangeSet.aggregatedArray
187            fulldata=None
188            if timeSubset == None:
189                for comp in self.currentFeature.rangeSet.aggregatedArray.component:
190                    var = comp.variableName
191                    for file in comp.fileName.split():
192                        data = self.getDataForVariable(file, var)
193                        print file + '  ' + var
194                        if fulldata is None:
195                            fulldata = data.tolist()
196                        else:
197                            #print data
198                            for item in data.tolist():
199                                fulldata.append(item)
200                            #print fulldata
201                            print 'length' + str(len(fulldata))
202                            #note, for now treat masked arrays as lists
203            else:
204                #handle the time subset: (assumes domain reference is time...)
205                domainref = self.getDomainReference(featureID)
206                filelog=[]
207                for time in timeSubset:
208                    listPosition=domainref['t'].split().index(time)
209                    for comp in self.currentFeature.rangeSet.aggregatedArray.component:
210                        var = comp.variableName
211                        print comp.fileName.split()
212                        data = self.getDataForVariable(comp.fileName.split()[listPosition], var, **kwargs)
213                        filelog.append(comp.fileName.split()[listPosition])
214                        #print comp.fileName.split()[listPosition] + '  ' + var
215                        if fulldata is None:
216                            fulldata = data.tolist()
217                        else:
218                            #print data
219                            for item in data.tolist():
220                                fulldata.append(item)
221                            #print fulldata
222                            print 'length' + str(len(fulldata))
223                print 'FILES:' +str(filelog)
224        return fulldata
225   
226    def getTimeSlice(self, featureID, time1, time2):
227         DI = csmldataiface.DataInterface()
228         DI=DI.getUnknownInterfaceType(file)       
229         DI.openFile(file)
230         DI.setVariable(variable)
231         return timeslicedata
232                       
233    def getDomainReference(self, featureID):
234        #This will return a list containing one or more ordinates:
235        #currently in form [Name, values]
236        self.__setFeature(featureID)
237        #domainReference could be one of:
238        #Trajectory
239        #OrientedTrajectory
240        #TimePositionList
241        if isinstance(self.currentFeature.domain.domainReference,TimePositionList):
242#             time = []
243#             time.append('t')
244#             time.append(self.currentFeature.domain.domainReference.timePositions)
245#             domainref.append(time)
246           
247            time = {}
248            time['t'] = self.currentFeature.domain.domainReference.timePositions
249            domainref  = time
250           
251        #Position
252        #OrientedPosition
253        #TimeInstant
254        return domainref
255   
256    def getDomainComplement(self, featureID):
257        #This will return a list containing one or more ordinates:
258        #currently in form [Name, values]
259        domaincomp ={}
260        self.__setFeature(featureID)
261        dc = self.currentFeature.domain.domainComplement
262       
263        #domainComplement could be one of:
264        #Null
265        #DirectPositionList
266        #Grid
267        if isinstance(dc, Grid):
268       
269            for ordinate in dc.ordinates:
270                domaincomp[ordinate.definesAxis]=self.getDataForExtract(ordinate.axisValues.id)
271#                 newaxis = []
272#                 newaxis.append(ordinate.definesAxis)
273#                 data = self.getData(ordinate.axisValues.id) # axisValues has already been resolved to the fileExtract so the gml:id can be passed straight to getData()
274#                 newaxis.append(data)
275#                 domaincomp.append(newaxis)
276        return domaincomp
277   
278    def getDomain(self, featureID):
279        #returns both the domain reference axes and domain compliment axes in a single domain dictionary
280        #axes are in no particular order
281        domain = {}
282        dc=self.getDomainComplement(featureID)
283        dr=self.getDomainReference(featureID)
284        for key in dc.keys():
285            domain[key]=dc[key]
286        for key in dr.keys():
287            domain[key]=dr[key]
288           
289        #domain.append(self.getDomainComplement(featureID))
290        #domain.append(self.getDomainReference(featureID))
291        return domain
Note: See TracBrowser for help on using the repository browser.