source: TI02-CSML/trunk/csml/API/ops_GridSeriesFeature.py @ 1956

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI02-CSML/trunk/csml/API/ops_GridSeriesFeature.py@1985
Revision 1956, 9.5 KB checked in by domlowe, 13 years ago (diff)

added stub methods to AbstractDI class

Line 
1''' ops_GridSeriesFeature  contains operations for GridSeriesFeatures'''
2
3import csml.parser
4import csml.csmllibs.csmltime
5import csml.csmllibs.csmldocument
6import csml.API.ops_AbstractFeature
7import csml.csmllibs.netCDFWriter
8import csmlutils
9
10import sys  #remove later
11
12def testmethod(self):
13    #print 'testmethod for gridseries feature'
14    return 'testmethod - gridseries'
15
16def getAllowedSubsettings(self):
17    return ['subsetToGridSeries']  #other operations
18
19def getDomain(self):
20    #returns domain as a dictionary of ordinates {name: [values], ...}
21    self.domain={}
22    for gridOrd in self.value.gridSeriesDomain.coordTransformTable.gridOrdinates:
23        name=gridOrd.coordAxisLabel.CONTENT
24        if isinstance(gridOrd.coordAxisValues, csml.parser.FileExtract):
25            #not tested with file extracts yet: (01/01/07)
26            self.domain[name]=gridOrd.coordAxisValues.getData()
27        else:
28            vals=gridOrd.coordAxisValues.coordinateList.CONTENT
29            valList=[]
30            for val in vals.split(','):  #remove commas
31                valList.append(val)
32            self.domain[name]=valList
33    return self.domain
34
35def subsetToGridSeries(self, csmlpath=None, ncpath=None,**kwargs):
36    #pathToSubsetCSML = container.csmlpath
37    if ncpath is not None:
38        pathToSubsetNetCDF=ncpath
39    else:
40        pathToSubsetNetCDF='temp.nc'
41   
42    self.getDomain()
43    #deal with longitude requests
44    #if the request is in -ve,+ve eg (-30,30) but the data is in (0,360) need to handle this by changing the args.
45    kwargs=csmlutils.fixLongitude(self.domain,kwargs)
46    #deal with times
47    timeAxis=self._identifyTimeAxis(self.domain.keys())
48    self.times=kwargs[timeAxis]
49    self.files=[]
50    strTimes=''
51    fulldata=[]
52   
53    #set the reference system for the time axis
54   
55    for gridOrd in self.value.gridSeriesDomain.coordTransformTable.gridOrdinates:
56        if gridOrd.coordAxisLabel.CONTENT==timeAxis:
57            try:
58                caltype=gridOrd.coordAxisValues.frame.split(':',1)[0]
59                calunits=gridOrd.coordAxisValues.frame.split(':',1)[1]
60                csml.csmllibs.csmltime.setcdtimeCalendar(caltype)
61                calset=True
62            except:pass
63    if calset!=True:
64        csml.csmllibs.csmltime.setcdtimeCalendar(csml.csmllibs.csmltime.cdtime.DefaultCalendar)   
65    try:
66        caltype=self.domain.domainReference.frame.split(':',1)[0]
67        calunits=self.domain.domainReference.frame.split(':',1)[1]
68        csml.csmllibs.csmltime.setcdtimeCalendar(caltype)
69    except:
70        csml.csmllibs.csmltime.setcdtimeCalendar(csml.csmllibs.csmltime.cdtime.DefaultCalendar)
71   
72   
73    if len(self.times) == 2:
74        #then this is a range of times (t1, tn)
75        try:
76            tone=ops_AbstractFeature.__getCDtime(self.times[0])
77        except:
78            tone=self.times[0]
79        try:
80            ttwo=ops_AbstractFeature.__getCDtime(self.times[1])
81        except:
82            ttwo=self.times[1]
83        self.times=[]
84        if hasattr(self, 'domain'):
85            pass
86        else:
87            self.getDomain()
88        for time in self.domain[timeAxis][0].split():
89            timeok=csml.API.ops_AbstractFeature.__compareTimes(tone,time,ttwo)
90            if timeok ==1:
91                self.times.append(time)
92    if hasattr(self.value.rangeSet, 'aggregatedArray'):
93        #handle aggregatedArray
94        numFiles=len(csmlutils.listify(self.value.rangeSet.aggregatedArray.components)[0].fileName.CONTENT.split())
95        timeToFileRatio=len(self.domain[timeAxis][0].split())/numFiles
96        #to keep track of files that have already been fetched. eg. if multiple times are in a single file only need to get data from that file once...
97        filesFetched=[]
98        #get data:
99        selection={}
100        for kw in kwargs:
101                    if kw != timeAxis:
102                        selection[kw]=kwargs[kw]
103        for time in self.times:
104            listPosition=self.domain[timeAxis][0].split().index(time)
105            strTimes= strTimes + ' ' + time
106            for comp in csmlutils.listify(self.value.rangeSet.aggregatedArray.components): 
107                filePos=(listPosition)/timeToFileRatio
108                if filePos in filesFetched:
109                    continue #already got data from this file, try next time
110                print comp
111                print dir(comp)
112                data=comp.getData(fileposition=filePos, **selection)
113                self.files.append(comp.fileName.CONTENT.split()[filePos])
114                if fulldata ==[]:
115                    fulldata = data.tolist()
116                else:
117                    for item in data.tolist():
118                        fulldata.append(item)
119                filesFetched.append(filePos)
120            axisorder = data.getAxisIds()  #will need later!
121            for comp in csmlutils.listify(self.value.rangeSet.aggregatedArray.components):
122                filePos=(listPosition)/timeToFileRatio
123                if filePos in filesFetched:
124                    continue #already got data from this file, try next time
125                data=comp.getData(fileposition=filePos, **selection)
126                self.files.append(comp.fileName.CONTENT.split()[filePos])
127                if fulldata ==[]:
128                    fulldata = data.tolist()
129                else:
130                    for item in data.tolist():
131                        fulldata.append(item)
132                filesFetched.append(filePos)
133            axisorder = data.getAxisIds()  #will need later!
134
135    elif hasattr(self.value.rangeSet, 'datablock'): #not tested
136        pass
137
138 
139
140    ### define domain and rangeSet to use for feature in csml document####
141    #TODO - rewrite this section for version 2 parser ###
142   
143    #domain=csml.parser.GridSeriesDomain()
144    #domain.domainReference=csml.parser.TimePositionList(timePositions=strTimes)
145    #grid=csml.parser.Grid()
146    ##dc = self.getDomainComplement()
147    ordinates= []
148    i=0
149    valueStore=[]  # use the values again later to generate netcdf
150    arraySize=0
151    totalArraySize=1
152    for key in self.domain.keys():
153        arraySize=0
154        i=i+1
155        god=csml.parser.GridOrdinateDescription()
156        god.gridAxesSpanned='dim%s'%i
157        god.sequenceRule='+x+y+z'
158        god.definesAxis=key
159        straxisValues=''
160        #now deal with each argument:
161           
162        print "KWARGS"
163        print kwargs
164        print  "DOM"
165        print self.domain
166        if key in kwargs:
167            if kwargs[key][0] < kwargs[key][1]:   
168                for val in self.domain[key]:
169                    if val is not '':
170                        if float(val) >= kwargs[key][0]:
171                            if float(val) <= kwargs[key] [1]:
172                                arraySize=arraySize+1
173                                straxisValues=straxisValues+ str(val) + ', '
174            else:#this if deals with selections such as longitude (330,30) where the lower limit is 'greater' than the upper limit in a mathematical sense.
175                    for val in self.domain[key]:
176                        if val is not '':
177                            if val >= kwargs[key][0]:
178                                arraySize=arraySize+1
179                                straxisValues=straxisValues+ str(val) + ', '
180                    for val in self.domain[key]:
181                        if val is not '':
182                            if val <= kwargs[key] [1]:
183                                arraySize=arraySize+1
184                                straxisValues=straxisValues+ str(val) + ', '
185        else: # this dimension has not been subsetted at all
186            for val in self.domain[key]:
187                if val is not '':
188                    arraySize=arraySize+1
189                    straxisValues=straxisValues+ str(val) + ', '       
190        totalArraySize=totalArraySize*arraySize
191        god.axisValues=straxisValues[:-2]
192        ordinates.append(god)
193    #totalArraySize=totalArraySize*len(self.times)
194    #grid.ordinates=ordinates
195    #domain.domainComplement=grid
196    #rangeSet=csml.parser.RangeSet()
197    #rangeSet.arrayDescriptor=csml.parser.NetCDFExtract(id=self.id,fileName=pathToSubsetNetCDF,variableName=self.id,arraySize=[arraySize])
198
199    #csmlWrap=csml.csmllibs.csmlfeaturewrap.CSMLWrapper()
200    #subsettedFeature=csmlWrap.createGridSeriesFeature(domain,rangeSet,datasetID="A",featureID="B",description="C")
201    ##container.appendFeature(subsettedFeature)
202
203    ### write netcdf using NCWriter class (wraps cdms) ###
204    nc=csml.csmllibs.netCDFWriter.NCwriter(pathToSubsetNetCDF)
205    floatTimes=[]
206    for time in self.times:
207        time=csml.API.ops_AbstractFeature.__getCDtime(time).torel(calunits)
208        floatTimes.append(time.value)
209    nc.addAxis('t',floatTimes,isTime=1,units=calunits,calendar=caltype)
210    for ordinate in ordinates:
211        lon,lat=None,None
212        if ordinate.definesAxis=='longitude':
213            lon=1
214        if ordinate.definesAxis=='latitude':
215            lat=1
216        #convert to list
217        vals=[]
218        for val in ordinate.axisValues.split(','):
219            vals.append(float(val))
220        nc.addAxis(ordinate.definesAxis,vals,isLon=lon,isLat=lat,units='')#to do, units attribute for CF compliance
221    if len(ordinates)==3:
222        axes=['t',axisorder[1],axisorder[2],axisorder[3]]
223    elif len(grid.ordinates)==2:
224        axes=['t',axisorder[1],axisorder[2]]
225    nc.addVariable(fulldata,self.id, axes,units='') #to do, units attribute for CF compliance
226    nc.closeFinishedFile()
227    return subsettedFeature, pathToSubsetNetCDF
228    #container.attachNetCDFFile(nc)
229    #MUST be supplied with a CSMLContainer object to store the subsetted feature in
230    return subsettedFeature, pathToSubsetNetCDF
Note: See TracBrowser for help on using the repository browser.