source: TI02-CSML/trunk/csml/API/ops_PointSeriesFeature.py @ 3296

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI02-CSML/trunk/csml/API/ops_PointSeriesFeature.py@3296
Revision 3296, 8.5 KB checked in by domlowe, 12 years ago (diff)

fixing example parser and point series subsetting of inline content

Line 
1''' ops_PointSeriesFeature  contains operations for PointSeriesFeatures. These methods are attached to PointSeriesFeature instances at runtime.'''
2import csml,sys
3import cdms, MV, MA
4
5def testmethod(self):
6    ''' testmethod for gridseries feature'''
7    print 'testmethod for pointSeries feature'
8    return 'testmethod pointSeries'
9
10def getAllowedSubsettings(self):
11    '''get the allowed operations
12    @return:    list of operations'''
13    return ['subsetToPointSeries']
14   
15def getDomain(self):
16    ''' returns domain as a dictionary of ordinates {name: [values], ...} '''
17    self.domain={}
18    valList=[]
19    for val in self.value.pointSeriesDomain.timePositionList.CONTENT.split():
20        valList.append(val)
21    self.domain['time']=valList
22    [lat,lon]=self.location.CONTENT.split()
23    self.domain['longitude']=lon
24    self.domain['latitude']=lat
25
26    return self.domain   
27   
28def getLongitudeAxis(self):
29    ''' get the index of the longitude axis'''
30    return 'longitude' #dummy value not used, subsetting is by time only
31
32def getLatitudeAxis(self):
33    ''' get the index of the latitude axis'''
34    return 'latitude' #dummy value not used,  subsetting is by time only
35
36def getTimeAxis(self):
37    ''' get the index of the time axis'''
38    return 'times'
39   
40def subsetToPointSeries(self, outputdir=None, ncname='pointseries.nc' ,times=None):
41    '''Subset a PointSeriesFeature to a PointSeriesFeature. Performs the subset (note this includes nearest neighbour searching, so may return a different set of kwargs.
42   
43    @param outputdir:    name of directory to write data files to
44    @param ncname:     name of netcdf file to write out
45    @param times:       selection by times
46    @return:     subsettedFeature (PointSeriesFeature instance)  pathToSubsetNetCDF (filepath), descriptor (array descriptor instance)'''
47    if outputdir is not None:
48        self.outputdir=outputdir
49    elif csml.API.csmlContainer.globalContainer.OUTPUTDIR is not None:
50        self.outputdir=csml.API.csmlContainer.globalContainer.OUTPUTDIR
51     
52    if self.outputdir is not None:
53        pathToSubsetNetCDF=self.outputdir + '/' +ncname
54    else: 
55        pathToSubsetNetCDF=ncname
56    if self.outputdir is not None:
57        csml.csmllibs.csmlextra.checkDirExists(self.outputdir)
58 
59    if type(times) is str:
60        selection = tuple(csml.csmllibs.csmlextra.listify(times))
61    else:
62        selection = times 
63    tlist=[]   
64    for val in self.value.pointSeriesDomain.timePositionList.CONTENT.split():
65        tlist.append(val)
66   
67    indices=[]
68    if  len(selection) ==2:       
69        selectedTimes=[]
70        for domaintime in tlist:
71            if selection[0] == domaintime:
72                minIndex=tlist.index(domaintime)
73                selectedTimes.append(domaintime)
74            if domaintime > selection[0]:
75                if domaintime < selection[1]:
76                    selectedTimes.append(domaintime)         
77            if selection[1] == domaintime:
78                maxIndex=tlist.index(domaintime)
79                selectedTimes.append(domaintime)         
80                break   
81                   
82    elif len(selection)==1:   #point only
83        for domaintime in tlist:
84            if selection[0] == domaintime:
85               
86                minIndex=tlist.index(domaintime)
87                maxIndex=minIndex
88                selectedTimes=selection
89                break
90   
91   
92   
93    #fileList=[]
94       
95    if self.value.rangeSet.quantityList.CONTENT:
96        #inline
97        data=self.value.rangeSet.quantityList.CONTENT.split()[minIndex:maxIndex+1]
98        fillvalue=None
99        units=self.value.rangeSet.quantityList.uom
100    else:
101        #file extract
102        if hasattr(self.value.rangeSet, 'valueArray'):
103            fextract=self.value.rangeSet.valueArray.valueComponent.insertedExtract.components
104            uom = self.value.rangeSet.valueArray.valueComponent.insertedExtract.uom
105        else:
106            fextract=self.value.rangeSet.arrayDescriptor.components
107            uom = self.value.rangeSet.arrayDescriptor.uom
108        #for f in fextract.fileList.fileNames.CONTENT.split():
109            #fileList.append(f)
110       
111        data, fillvalue=fextract.getDataFromChunks(minIndex, maxIndex)
112       
113        units=[uom.CONTENT]
114   
115    #Now write out the CSML Feature:
116    #create a PointSeriesCoverage
117    cvg=csml.parser.PointSeriesCoverage()
118    cvg.id=csml.csmllibs.csmlextra.getRandomID()
119   
120    #create a TimeSeriesDomain (appropriate domain for a PointSeriesFeature
121    ptsd=csml.parser.TimeSeries()
122    ptsd.id=csml.csmllibs.csmlextra.getRandomID()
123    #create (and populate) a TimePositionList. Using keyword arguements for conciseness.
124    ptsd.timePositionList=csml.parser.TimePositionList(CONTENT=csml.csmllibs.csmlextra.stringify(selectedTimes))
125       
126    sdid=csml.csmllibs.csmlextra.getRandomID() # for the storage descriptor
127    #create a RangeSet
128    rs=csml.parser.RangeSet()
129    va=csml.parser.ValueArray()
130    vc=csml.parser.MeasureOrNullList()
131    vc.href='#%s'%sdid
132    vc.arcrole="http://ndg.nerc.ac.uk/xlinkUsage/insert#QuantityList"
133    vc.role="http://ndg.nerc.ac.uk/fileFormat/csmlStorageDescriptor"
134    vc.show='embed'
135    try:
136        vc.uom=self.value.rangeSet.valueArray.valueComponent.uom
137    except:
138        vc.uom = 'unknown'  #TODO,
139    va.valueComponent=vc
140    va.id=csml.csmllibs.csmlextra.getRandomID()
141    rs.valueArray=va
142   
143   
144    #Add the domain and rangeSet as attributes of the coverage
145    cvg.pointSeriesDomain=ptsd
146    cvg.rangeSet=rs
147   
148    totalArraySize=10
149    if hasattr(self, 'name'):
150        varname=self.name
151    else:
152        varname=self.id
153    descriptor=csml.parser.NetCDFExtract(id=sdid,fileName=csml.parser.csString(ncname),variableName=csml.parser.csString(varname),arraySize=csml.parser.csString(totalArraySize))
154
155    #the parameter of the feature is of type Phenomenon, here href creates "xlink:href=..."
156    param=self.parameter
157   
158     
159    #create a stand alone pointseries feature containing this coverage
160    csmlWrap=csml.csmllibs.csmlfeaturewrap.CSMLWrapper()
161    subsettedFeature=csmlWrap.createPointSeriesFeature(value=cvg,parameter=param,location=self.location,featureID=self.id,description=self.description)
162     
163   
164    #Now write out the NetCDF File:   
165    nc=cdms.open(pathToSubsetNetCDF,'w')
166    var=MV.array(data)
167    var.id=varname
168    var.name=varname
169    var.units=units[0] # hopefully there is just one unit in this list..
170    setattr(var, 'missing_value' ,fillvalue)
171   
172    floatTimes=[]
173   
174    tOne=csml.csmllibs.csmltime.getCDtime(selection[0])
175    tbase=csml.csmllibs.csmltime.getBaseUnits(tOne)
176    for time in selectedTimes:
177        time=csml.csmllibs.csmltime.getCDtime(time).torel(tbase)
178        floatTimes.append(time.value)
179    timeAx=cdms.createAxis(floatTimes)
180    timeAx.designateTime()
181    timeAx.id='time'
182    timeAx.units=tbase 
183    var.setAxis(0,timeAx)     
184    nc.write(var)
185    nc.close()   
186    print 'NetCDF file written to %s'%pathToSubsetNetCDF
187    return subsettedFeature, pathToSubsetNetCDF, descriptor
188   
189   
190def subsetToPoint(self, outputdir=None, ncname='point.nc',time=None):
191    '''Subset a PointSeriesFeature to a PointFeature. Performs the subset (note this includes nearest neighbour searching, so may return a different set of kwargs.
192       
193    @param outputdir:    name of directory to write data files to
194    @param ncname:     name of netcdf file to write out
195    @param time:       selection by single time
196    @return:     subsettedFeature (PointFeature instance)  pathToSubsetNetCDF (filepath), descriptor (array descriptor instance)'''
197    if outputdir is not None:
198        self.outputdir=outputdir
199    elif csml.API.csmlContainer.globalContainer.OUTPUTDIR is not None:
200        self.outputdir=csml.API.csmlContainer.globalContainer.OUTPUTDIR
201    pseriesFeature, pathToSubsetNetCDF, descriptor=self.subsetToPointSeries(self.outputdir, ncname,time)         
202    #now need to take this point series feature containing one time and rewrite it as a point feature.
203    pointFeature=csml.parser.PointFeature()
204    pointFeature.location=pseriesFeature.location
205    pointFeature.parameter=pseriesFeature.parameter
206    pointFeature.description=pseriesFeature.description
207    cvg=csml.parser.PointCoverage()
208    domain=csml.parser.PointDomain()
209    domain.id=csml.csmllibs.csmlextra.getRandomID()
210    domain.pointMember=csml.parser.csString(pseriesFeature.location.CONTENT)
211    #create (and populate) a TimePositionList. Using keyword arguements for conciseness.
212    cvg.pointDomain=domain
213    pointFeature.value=cvg
214    pointFeature.time=csml.parser.csString(time)
215    return pointFeature, pathToSubsetNetCDF, descriptor
Note: See TracBrowser for help on using the repository browser.