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

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

fixes to object property pattern and validation errors. last commit before new egg

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