source: TI02-CSML/branches/CSML2/API/ops_GridSeriesFeature.py @ 1902

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI02-CSML/branches/CSML2/API/ops_GridSeriesFeature.py@1902
Revision 1902, 7.2 KB checked in by domlowe, 13 years ago (diff)

beginning to refactor API module

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
8
9
10def testmethod(self):
11    #print 'testmethod for gridseries feature'
12    return 'testmethod - gridseries'
13
14def getAllowedSubsettings(self):
15    return ['subsetToGridSeries']  #other operations
16
17def getDomain(self):
18    #need some sort of domain
19    pass
20
21def subsetToGridSeries(self,   csmlpath=None, ncpath=None,**kwargs):
22    #pathToSubsetCSML = container.csmlpath
23    if ncpath is not None:
24        pathToSubsetNetCDF=ncpath
25    else:
26        pathToSubsetNetCDF='temp.nc'
27   
28    #deal with longitude requests
29    #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.
30    dc = self.getDomainComplement()
31    for key in dc.keys():
32        if key == 'longitude': #how do we test if it is longitude properly?
33            for val in dc[key]:
34                if val < 0:
35                    pass
36                else:
37                    if kwargs[key][0] < 0:
38                        kwargs[key]=(kwargs[key][0]+360,kwargs[key][1])
39                    if kwargs[key][1] < 0:
40                        kwargs[key]=(kwargs[key][0],kwargs[key][1]+360)
41         
42    domainref = getDomainReference(self)
43    self.times=timeSubset
44    self.files=[]
45    strTimes=''
46    fulldata=[]
47    if len(self.times) == 2:
48        try:
49            tone=ops_AbstractFeature.__getCDtime(self.times[0])
50        except:
51            tone=self.times[0]
52        try:
53            ttwo=ops_AbstractFeature.__getCDtime(self.times[1])
54        except:
55            ttwo=self.times[1]
56        dr=getDomainReference(self)
57        self.times=[]
58        for time in dr['t'].split():
59            timeok=csml.API.ops_AbstractFeature.__compareTimes(tone,time,ttwo)
60            if timeok ==1:
61                self.times.append(time)
62   
63    #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...
64    numFiles=len(self.rangeSet.aggregatedArray.component[0].fileName.split())
65    timeToFileRatio=len(domainref['t'].split())/numFiles
66    filesFetched=[]
67    #get data:
68    for time in self.times:
69        listPosition=domainref['t'].split().index(time)
70        strTimes= strTimes + ' ' + time
71        timedim=self.rangeSet.aggregatedArray.component[0].variableName
72        for comp in self.rangeSet.aggregatedArray.component:
73            filePos=(listPosition)/timeToFileRatio
74            if filePos in filesFetched:
75                continue #already got data from this file, try next time
76            data=comp.getData(fileposition=filePos, times=self.times, **kwargs)
77            self.files.append(comp.fileName.split()[filePos])
78            if fulldata ==[]:
79               fulldata = data.tolist()
80            else:
81                for item in data.tolist():
82                    fulldata.append(item)
83            filesFetched.append(filePos)
84        axisorder = data.getAxisIds()  #will need later!
85    try:
86        caltype=self.domain.domainReference.frame.split(':',1)[0]
87        calunits=self.domain.domainReference.frame.split(':',1)[1]
88        csml.csmllibs.csmltime.setcdtimeCalendar(caltype)
89    except:
90        csml.csmllibs.csmltime.setcdtimeCalendar(csml.csmllibs.csmltime.cdtime.DefaultCalendar)
91    ### define domain and rangeSet to use for feature in csml document####
92    domain=csml.parser.GridSeriesDomain()
93    domain.domainReference=csml.parser.TimePositionList(timePositions=strTimes)
94    grid=csml.parser.Grid()
95    #dc = self.getDomainComplement()
96    ordinates= []
97    i=0
98    valueStore=[]  # use the values again later to generate netcdf
99    arraySize=0
100    totalArraySize=1
101    for key in dc.keys():
102        arraySize=0
103        i=i+1
104        god=csml.parser.GridOrdinateDescription()
105        god.gridAxesSpanned='dim%s'%i
106        god.sequenceRule='+x+y+z'
107        god.definesAxis=key
108        straxisValues=''
109        #now deal with each argument:
110       
111        if key in kwargs:
112            if kwargs[key][0] < kwargs[key][1]:   
113                for val in dc[key]:
114                    if val is not '':
115                        if float(val) >= kwargs[key][0]:
116                            if float(val) <= kwargs[key] [1]:
117                                arraySize=arraySize+1
118                                straxisValues=straxisValues+ str(val) + ', '
119            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.
120                    for val in dc[key]:
121                        if val is not '':
122                            if val >= kwargs[key][0]:
123                                arraySize=arraySize+1
124                                straxisValues=straxisValues+ str(val) + ', '
125                    for val in dc[key]:
126                        if val is not '':
127                            if val <= kwargs[key] [1]:
128                                arraySize=arraySize+1
129                                straxisValues=straxisValues+ str(val) + ', '
130        else: # this dimension has not been subsetted at all
131            for val in dc[key]:
132                if val is not '':
133                    arraySize=arraySize+1
134                    straxisValues=straxisValues+ str(val) + ', '       
135        totalArraySize=totalArraySize*arraySize
136        god.axisValues=straxisValues[:-2]
137        ordinates.append(god)
138    totalArraySize=totalArraySize*len(self.times)
139    grid.ordinates=ordinates
140    domain.domainComplement=grid
141    rangeSet=csml.parser.RangeSet()
142    rangeSet.arrayDescriptor=csml.parser.NetCDFExtract(id=self.id,fileName=pathToSubsetNetCDF,variableName=self.id,arraySize=[arraySize])
143
144    csmlWrap=csml.csmllibs.csmlfeaturewrap.CSMLWrapper()
145    subsettedFeature=csmlWrap.createGridSeriesFeature(domain,rangeSet,datasetID="A",featureID="B",description="C")
146    #container.appendFeature(subsettedFeature)
147
148    ### write netcdf using NCWriter class (wraps cdms) ###
149    nc=csml.csmllibs.netCDFWriter.NCwriter(pathToSubsetNetCDF)
150    floatTimes=[]
151    for time in self.times:
152        time=csml.API.ops_AbstractFeature.__getCDtime(time).torel(calunits)
153        floatTimes.append(time.value)
154    nc.addAxis('t',floatTimes,isTime=1,units=calunits,calendar=caltype)
155    for ordinate in ordinates:
156        lon,lat=None,None
157        if ordinate.definesAxis=='longitude':
158            lon=1
159        if ordinate.definesAxis=='latitude':
160            lat=1
161        #convert to list
162        vals=[]
163        for val in ordinate.axisValues.split(','):
164            vals.append(float(val))
165        nc.addAxis(ordinate.definesAxis,vals,isLon=lon,isLat=lat,units='')#to do, units attribute for CF compliance
166    if len(ordinates)==3:
167        axes=['t',axisorder[1],axisorder[2],axisorder[3]]
168    elif len(grid.ordinates)==2:
169        axes=['t',axisorder[1],axisorder[2]]
170    nc.addVariable(fulldata,self.id, axes,units='') #to do, units attribute for CF compliance
171    nc.closeFinishedFile()
172    return subsettedFeature, pathToSubsetNetCDF
173    #container.attachNetCDFFile(nc)
174    #MUST be supplied with a CSMLContainer object to store the subsetted feature in
175    return subsettedFeature, pathToSubsetNetCDF
Note: See TracBrowser for help on using the repository browser.