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

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

various changes/fixes etc related to getting supporting subsetting by index

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.API.genSubset
8import csml.csmllibs.netCDFWriter
9import csmlutils
10
11
12import sys  #remove later
13
14def testmethod(self):
15    #print 'testmethod for gridseries feature'
16    return 'testmethod - gridseries'
17
18def getAllowedSubsettings(self):
19    return ['subsetToGridSeries']  #other operations
20
21def getDomain(self):
22    #returns domain as a dictionary of ordinates {name: [values], ...}
23    self.domain={}
24    self.gridnames={}
25    for gridOrd in self.value.gridSeriesDomain.coordTransformTable.gridOrdinates:
26        name=gridOrd.coordAxisLabel.CONTENT
27        self.gridnames[gridOrd.gridAxesSpanned.CONTENT]=name
28        if hasattr(gridOrd.coordAxisValues, 'insertedExtract'):
29            self.domain[name], fill, axisorder, units=gridOrd.coordAxisValues.insertedExtract.getData()
30        else:           
31            valList=[]
32            try:
33                vals=gridOrd.coordAxisValues.coordinateList.CONTENT
34                for val in vals.split(): 
35                    valList.append(eval(val))
36            except:
37                vals=gridOrd.coordAxisValues.timePositionList.CONTENT
38                for val in vals.split(): 
39                    valList.append(val)           
40            self.domain[name]=valList   
41    return self.domain
42
43def getUom(self):
44    uom=None
45    #returns the uom of the phenomenon.
46    try: 
47        uom=self.value.rangeSet.valueArray.valueComponent.quantityList.insertedExtract.uom.CONTENT
48    except AttributeError:
49        uom =None
50    return uom
51
52def _subsetGrid(self, csmlpath=None, ncpath=None,**kwargs):
53    '''this takes a selection from a gridseries object (be it a profile, a grid, whatever, it is still just a selection'''
54           
55    #set self.domain:
56    self.getDomain()     
57   
58    #if request doesn't match domain points find nearest neighbours
59    kwargs=csml.API.genSubset.checkNeighbours(self.domain, self.gridnames, **kwargs)
60    #get the CRS from a  the  catalogue
61    cat=csml.csmllibs.csmlcrs.CRSCatalogue()
62    crs=cat.getCRS(self.value.gridSeriesDomain.srsName, self.value.gridSeriesDomain.axisLabels) 
63   
64    #non-feature specific setup code, mainly handles the time dimension/calendar
65   
66    pathToSubsetNetCDF, kwargs, timeAxis, timeName, caltype, times=csml.API.genSubset.genericSubset(self, csmlpath, ncpath, self.domain, kwargs)
67     
68    ##Get names of variables in file and relate them to the subset selection
69    selection={}
70    frame=''
71    for gridOrd in self.value.gridSeriesDomain.coordTransformTable.gridOrdinates:
72        try:
73            selection[gridOrd.gridAxesSpanned.CONTENT]=kwargs[gridOrd.coordAxisLabel.CONTENT]
74        except KeyError:
75            allValues=tuple(self.domain[gridOrd.coordAxisLabel.CONTENT])
76        if hasattr(gridOrd.coordAxisValues, 'timePositionList'):
77            if hasattr(gridOrd.coordAxisValues, 'frame'):
78                frame=gridOrd.coordAxisValues.frame
79
80    try:
81        del selection[timeAxis] #NOTE: Haven't resolved the single CRS issue so cannot subset by time within an individual file for now
82    except KeyError:
83        pass
84    #TEST selection by index:
85    selection['lower']=(0,10,)
86    selection['upper']=(124,262)
87           
88    strTimes, axisorder, units, fulldata, fillvalue =csml.API.genSubset.getTheData(self, selection, times, timeName)
89    return pathToSubsetNetCDF, crs, frame, timeName, times, strTimes, caltype, axisorder,units, fulldata, fillvalue, kwargs
90   
91def subsetToGridSeries(self, csmlpath=None, ncpath=None,**kwargs):
92    #perform the subset (note this included nearest neighbour searching, so may return a different set of kwargs
93    pathToSubsetNetCDF, crs, frame, timeName, times, strTimes, caltype, axisorder,units, fulldata, fillvalue, kwargs=self._subsetGrid(csmlpath, ncpath,**kwargs) 
94    #Okay, got the data now. Need to write CSML feature and NetCDF files.
95    #Writing out the CSML feature
96   
97    # define domain/coverage  to use in 'value' attribute   
98    newdomain=csml.parser.GridSeriesDomain()
99    domainSubset, totalArraySize=csml.API.genSubset.subsetDomain(timeName,strTimes,self.domain, **kwargs)
100    cTT=csml.API.genSubset.getCoordTransformTable(domainSubset, crs, frame)
101    newdomain.id=csml.csmllibs.csmlextra.getRandomID()
102    newdomain.coordTransformTable=cTT
103    newdomain.srsName=self.value.gridSeriesDomain.srsName 
104    newdomain.axisLabels=self.value.gridSeriesDomain.axisLabels
105    newdomain.srsDimension=self.value.gridSeriesDomain.srsDimension
106    newdomain.dimension=self.value.gridSeriesDomain.dimension
107    env=csml.parser.GridEnvelope()
108    env.low=csml.parser.csString('0 0 0') #TODO
109    env.high=csml.parser.csString('0 0 0')
110    newdomain.limits=env
111    newdomain.aLabels=self.value.gridSeriesDomain.aLabels
112    rs=csml.parser.RangeSet()
113    sdid=csml.csmllibs.csmlextra.getRandomID()
114    descriptor=csml.parser.NetCDFExtract(id=sdid,fileName=csml.parser.csString(pathToSubsetNetCDF),variableName=self.name,arraySize=csml.parser.csString(totalArraySize))
115    rs=csml.parser.RangeSet()
116    va=csml.parser.ValueArray()
117    vc=csml.parser.MeasureOrNullList()
118    vc.href='#%s'%sdid
119    vc.arcrole="http://ndg.nerc.ac.uk/xlinkUsage/insert#QuantityList"
120    vc.role="http://ndg.nerc.ac.uk/fileFormat/csmlStorageDescriptor"
121    vc.show='embed'
122    try:
123        vc.uom=self.value.rangeSet.valueArray.valueComponent.uom
124    except:
125        vc.uom = 'unknown'  #TODO,
126    va.valueComponent=vc
127    va.id=csml.csmllibs.csmlextra.getRandomID()
128    rs.valueArray=va
129    #gridseries coverage
130    cvg=csml.parser.GridSeriesCoverage()
131    cvg.id=csml.csmllibs.csmlextra.getRandomID()
132    cvg.rangeSet=rs
133    cvg.gridSeriesDomain=newdomain   
134   
135    #parameter, as before subsetting.
136    param = self.parameter
137       
138    #create a stand alone gridseries feature containing this coverage
139    csmlWrap=csml.csmllibs.csmlfeaturewrap.CSMLWrapper()
140    subsettedFeature=csmlWrap.createGridSeriesFeature(value=cvg,parameter=param,featureID=csml.csmllibs.csmlextra.getRandomID(),name=self.name,description=self.description)
141 
142    ### write netcdf using NCWriter class (wraps cdms) ###
143    nc=csml.csmllibs.netCDFWriter.NCwriter(pathToSubsetNetCDF)
144    ords=cTT.gridOrdinates
145    axislist=[]
146    for a in axisorder:
147        axislist.append(self.gridnames[a])
148    nc.genWriteVar(self.id,ords, times, caltype, axislist, units, fulldata, fillvalue)
149    nc.closeFinishedFile()
150    print 'NetCDF file written to %s'%pathToSubsetNetCDF
151    return subsettedFeature, pathToSubsetNetCDF, descriptor
152   
153
154def subsetToProfileSeries(self, csmlpath=None, ncpath=None,**kwargs):
155    #TODO   !!!!!!!!! Need to perform some sort of testing on the kwargs to check it is a profileseries request.
156   
157   
158    #perform the subset (note this included nearest neighbour searching, so may return a different set of kwargs
159    pathToSubsetNetCDF, crs,frame, timeName, times, strTimes, caltype, axisorder,units, fulldata, fillvalue, kwargs=self._subsetGrid(csmlpath, ncpath,**kwargs) 
160    latName=crs.axes[crs.latAxis]
161    lonName=crs.axes[crs.lonAxis]
162    #Okay, got the data now. Need to write CSML feature and NetCDF files.
163    #Writing out the CSML feature
164   
165    # define domain/coverage  to use in 'value' attribute   
166    newdomain=csml.parser.ProfileSeriesDomain()
167   
168   
169    domainSubset, totalArraySize=csml.API.genSubset.subsetDomain(timeName,strTimes,self.domain, **kwargs)
170    cTT=csml.API.genSubset.getCoordTransformTable(domainSubset, crs, frame) 
171   
172    #Need to remove location (lat/lon) axes from the cTT
173    newGridOrds=[]
174    for gridOrd in cTT.gridOrdinates:
175        if gridOrd.coordAxisLabel.CONTENT not in  [latName,lonName]:
176            newGridOrds.append(gridOrd)
177    cTT.gridOrdinates=newGridOrds
178    axes=[]
179    for ord in newGridOrds:
180        axes.append(ord.coordAxisLabel.CONTENT)
181    cat = csml.csmllibs.csmlcrs.CRSCatalogue()
182    crsInfo=cat.determineCRS(knownCRSAxes=axes)   
183    crs=cat.getCRS(crsInfo[0].srsName)
184   
185    newdomain.coordTransformTable=cTT   
186    newdomain.id=csml.csmllibs.csmlextra.getRandomID()
187    #TODO need to remove 'location' from this srs
188    newdomain.srsName=crsInfo[0].srsName
189    axisLabels=csml.csmllibs.csmlextra.stringify(crsInfo[1].keys())
190    newdomain.axisLabels=axisLabels
191    newdomain.srsDimension=2
192    newdomain.dimension=2
193    env=csml.parser.GridEnvelope()
194    env.low=csml.parser.csString('0 0 0') #TODO
195    env.high=csml.parser.csString('0 0 0')
196    newdomain.limits=env
197    newdomain.aLabels=self.value.gridSeriesDomain.aLabels #todo 
198    rangeSet=csml.parser.RangeSet()
199    descid=csml.csmllibs.csmlextra.getRandomID()
200    descriptor=csml.parser.NetCDFExtract(id=descid,fileName=csml.parser.csString(pathToSubsetNetCDF),variableName=csml.parser.csString(self.id),arraySize=csml.parser.csString(totalArraySize))
201    rs=csml.parser.RangeSet()
202    va=csml.parser.ValueArray()
203    vc=csml.parser.MeasureOrNullList()
204    vc.href='#%s'%descid
205    vc.arcrole="http://ndg.nerc.ac.uk/xlinkUsage/insert#QuantityList"
206    vc.role="http://ndg.nerc.ac.uk/fileFormat/csmlStorageDescriptor"
207    vc.show='embed'
208    try:
209        vc.uom=self.value.rangeSet.valueArray.valueComponent.uom
210    except:
211        vc.uom = 'unknown'  #TODO,
212    va.valueComponent=vc
213    va.id=csml.csmllibs.csmlextra.getRandomID()
214    rs.valueArray=va
215    #profileseries coverage
216    cvg=csml.parser.ProfileSeriesCoverage()
217    cvg.id=csml.csmllibs.csmlextra.getRandomID()
218    cvg.rangeSet=rs
219    cvg.profileSeriesDomain=newdomain   
220    csmlWrap=csml.csmllibs.csmlfeaturewrap.CSMLWrapper()
221   
222    #parameter, as before subsetting.
223    param = self.parameter
224   
225    #create 'location' attribute:
226    if (latName, lonName) is not (None, None):
227        locStr ='%s %s'%(kwargs[latName], kwargs[lonName])
228        loc=csml.parser.csString(locStr)
229    else:
230        loc = csml.parser.csString('unknown location')
231       
232   
233    #create a stand alone gridseries feature containing this coverage
234    subsettedFeature=csmlWrap.createProfileSeriesFeature(value=cvg,parameter=param, location=loc, featureID=csml.csmllibs.csmlextra.getRandomID(),name=self.name,description=self.description)
235 
236   
237    ### write netcdf using NCWriter class (wraps cdms) ###
238    nc=csml.csmllibs.netCDFWriter.NCwriter(pathToSubsetNetCDF)
239    ords=cTT.gridOrdinates
240    axislist=[]
241       
242    for a in axisorder:
243        axislist.append(self.gridnames[a])
244    nc.genWriteVar(self.id,ords, times, caltype, axislist, units, fulldata, fillvalue, latitude=kwargs[latName], longitude=kwargs[lonName])
245    nc.closeFinishedFile()
246   
247    return subsettedFeature, pathToSubsetNetCDF, descriptor
248
249def subsetToProfile(self, csmlpath=None, ncpath=None,**kwargs):
250    #Two step process - subset GridSeries to ProfileSeries, then ProfileSeries to Profile
251    profileSeries, pSfile=self.subsetToProfileSeries(csmlpath=csmlpath, ncpath=ncpath, **kwargs)   
252    del kwargs['latitude']    #TODO - need to remove excess kwargs based on the domain of the temporary profileSeries feature
253    del kwargs['longitude']
254    subsettedFeature, pathToSubsetNetCDF=profileSeries.subsetToProfile(csmlpath=csmlpath, ncpath=ncpath, **kwargs)   
255    return subsettedFeature, pathToSubsetNetCDF
256
257def subsetToPointSeries(self, csmlpath=None, ncpath=None,**kwargs):
258    #Two step process - subset GridSeries to ProfileSeries, then ProfileSeries to PointSeries
259    profileSeries, pSfile=self.subsetToProfileSeries(csmlpath=csmlpath, ncpath=ncpath, **kwargs)   
260    del kwargs['latitude']    #TODO - need to remove excess kwargs based on the domain of the temporary profileSeries feature
261    del kwargs['longitude']
262    subsettedFeature, pathToSubsetNetCDF=profileSeries.subsetToPointSeries(csmlpath=csmlpath, ncpath=ncpath, **kwargs)   
263    return subsettedFeature, pathToSubsetNetCDF
Note: See TracBrowser for help on using the repository browser.