source: TI02-CSML/trunk/csml/csmllibs/netCDFWriter.py @ 3096

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

subsetting of profileseries, pointseries retested and fixed

Line 
1import cdms,MV
2import Numeric
3import csml
4import sys
5
6class NCwriter(object):
7    #This provides a simplified wrapper to CDMS to write a CF compliant NetCDF
8    def __init__(self, fileName):
9        #initiates a new NetCDF file
10        self.nc=cdms.open(fileName,'w')
11   
12    def setGlobalAttributes(self, **kwargs):
13        #sets global attributes
14        pass
15   
16    def addAxis(self,axisName, data,isLon=None,isLat=None,isTime=None,**kwargs):
17        #first ensure tuple does not contains a list
18        if type(data[0]) is list:
19            newdata=tuple(data[0])
20            data=newdata
21           
22        # Now create the axis   
23        dataarray=MV.array(data)
24        ax=cdms.createAxis(dataarray)
25        ax.id = axisName
26        if not hasattr(self,'axes'):
27            self.axes=[]
28        if isLon is not None:
29            ax.designateLongitude()
30            setattr(ax, 'standard_name', 'longitude')
31        elif isLat is not None:
32            ax.designateLatitude()
33            setattr(ax, 'standard_name', 'latitude')
34        elif isTime is not None:
35            ax.designateTime()
36            setattr(ax, 'standard_name', 'time')
37        for key in kwargs:
38            setattr(ax, key,kwargs[key])
39        self.axes.append(ax)
40       
41   
42    def getAxis(self, axID):
43        for axis in self.axes:
44            if axis.id == axID:
45                return axis
46   
47   
48   
49    def addTimeVariable(self,timeval): 
50        dataarray=MV.array(timeval)
51        #dataarray.id='time'
52        #dataarray.name ='time'
53        ax=self.getAxis('time')
54        dataarray.setAxis(0,ax)           
55        self.nc.write(dataarray)
56       
57       
58    def addVariable(self,data, variableName,axesList, fillvalue, stdname=None, **kwargs):       
59        #creates a new variable containing data with named attributes from **kwargs       
60        dataarray=MV.array(data)     
61        dataarray.id=variableName
62        dataarray.name=variableName
63        for key in kwargs:
64            setattr(dataarray, key,kwargs[key])
65        axisCount=0
66     
67        #depending on whether time is modelled in the underlying data as a dimension or not the shapes may not match
68        if len(dataarray.shape) < len(axesList): 
69            #take time out and create a separate variable
70            newaxesList=[]
71            for a in axesList:
72                if a != 'time':
73                    newaxesList.append(a)
74            axesList=newaxesList
75        if hasattr(self, 'axes'):   
76            for axis in axesList:
77                for ax in self.axes:
78                    if ax.id == axis:
79                        dataarray.setAxis(axisCount,ax)                       
80                        axisCount = axisCount +1     
81        #missing_value deprecated but in common use;
82        #setattr(dataarray, 'missing_value' ,fillvalue)
83        setattr(dataarray, '_FillValue' ,fillvalue)
84        if stdname:
85            setattr(dataarray, 'standard_name' ,stdname)
86        self.nc.write(dataarray)
87
88    def genWriteVar(self,varid, ordinates, times, caltype, axisorder, unitlist, stdname, fulldata, fillvalue, **kwargs):
89
90        #**kwargs may contain additional axes not contained in a GridCoordinatesTable - e.g latitude, longitude may be stored in other attribute not in the rectified grid.     
91        axesdone=[]
92        floatTimes=[]
93        #determine base units for times:
94        tOne=csml.csmllibs.csmltime.getCDtime(times[0])
95        tbase=csml.csmllibs.csmltime.getBaseUnits(tOne)
96        for time in times:
97            time=csml.csmllibs.csmltime.getCDtime(time).torel(tbase)
98            floatTimes.append(time.value)
99        self.addAxis('time',floatTimes,isTime=1,units=tbase,calendar=caltype)
100 
101        axesdone.append('time')
102        if ordinates is not None:
103            for ord in enumerate(ordinates):
104                vals=[]
105                lon,lat=None,None
106                if ord[1].coordAxisLabel.CONTENT=='time':
107                    continue
108                else:
109                    for val in ord[1].coordAxisValues.coordinateList.CONTENT.split():
110                        if val != ' ':
111                            vals.append(eval(val)) 
112                if ord[1].coordAxisLabel.CONTENT=='longitude':
113                    lon=1
114                    name='longitude'
115                elif ord[1].coordAxisLabel.CONTENT=='latitude':
116                    lat=1
117                    name='latitude'
118                else:
119                    name=ord[1].coordAxisLabel.CONTENT
120                for ax in enumerate(axisorder):
121                    if ax[1]==name:
122                        position=ax[0]
123                axesdone.append(name)
124                self.addAxis(name,vals,isLon=lon,isLat=lat,units=unitlist[position])#to do, units attribute for CF compliance
125       
126        if kwargs is not None:   
127            for kw in kwargs:
128                lon,lat=None,None
129                if kw=='longitude':
130                    lon=1
131                elif kw == 'latitude':
132                    lat=1
133                name = kw
134                for ax in enumerate(axisorder):
135                    if ax[1]==name:
136                        position=ax[0]
137                vals=(kwargs[kw],)
138                self.addAxis(name,vals,isLon=lon,isLat=lat,units=unitlist[position])
139                axesdone.append(name)       
140        self.addVariable(fulldata,varid, axisorder, fillvalue, units=unitlist[-1], stdname=stdname ) 
141
142        #for ax in self.axes: #don't think this is needed!
143            #if ax.id =='time':
144                #if self.nc.variables.has_key('time') is False:
145                    #self.addTimeVariable(floatTimes)
146       
147       
148    def closeFinishedFile(self):
149        #returns finished (hopefully) NetCDF file
150        self.nc.close()
Note: See TracBrowser for help on using the repository browser.