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

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

added fix to check ordering of output axes, fixes latitude reversal problem

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        elif isLat is not None:
31            ax.designateLatitude()
32        elif isTime is not None:
33            ax.designateTime()
34        for key in kwargs:
35            setattr(ax, key,kwargs[key])
36        self.axes.append(ax)
37       
38   
39    def getAxis(self, axID):
40        for axis in self.axes:
41            if axis.id == axID:
42                return axis
43   
44   
45   
46    def addTimeVariable(self,timeval): 
47        dataarray=MV.array(timeval)
48        #dataarray.id='time'
49        #dataarray.name ='time'
50        ax=self.getAxis('time')
51        dataarray.setAxis(0,ax)           
52        self.nc.write(dataarray)
53       
54       
55    def addVariable(self,data, variableName,axesList, fillvalue,  **kwargs):       
56        #creates a new variable containing data with named attributes from **kwargs       
57             
58        dataarray=MV.array(data)     
59        dataarray.id=variableName
60        dataarray.name=variableName
61        for key in kwargs:
62            setattr(dataarray, key,kwargs[key])
63        axisCount=0
64     
65        #depending on whether time is modelled in the underlying data as a dimension or not the shapes may not match
66        if len(dataarray.shape) < len(axesList): 
67            #take time out and create a separate variable
68            newaxesList=[]
69            for a in axesList:
70                if a != 'time':
71                    newaxesList.append(a)
72            axesList=newaxesList
73        if hasattr(self, 'axes'):   
74            for axis in axesList:
75                for ax in self.axes:
76                    if ax.id == axis:
77                        dataarray.setAxis(axisCount,ax)                       
78                        axisCount = axisCount +1     
79        setattr(dataarray, 'missing_value' ,fillvalue)
80        self.nc.write(dataarray)
81
82    def genWriteVar(self,varid, ordinates, times, caltype, axisorder, unitlist, fulldata, fillvalue, **kwargs):
83        #**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.     
84        axesdone=[]
85        floatTimes=[]
86        #determine base units for times:
87        tOne=csml.csmllibs.csmltime.getCDtime(times[0])
88        tbase=csml.csmllibs.csmltime.getBaseUnits(tOne)
89        for time in times:
90            time=csml.csmllibs.csmltime.getCDtime(time).torel(tbase)
91            floatTimes.append(time.value)
92        self.addAxis('time',floatTimes,isTime=1,units=tbase,calendar=caltype)
93 
94        axesdone.append('time')
95        if ordinates is not None:
96            for ord in enumerate(ordinates):
97                vals=[]
98                lon,lat=None,None
99                if ord[1].coordAxisLabel.CONTENT=='time':
100                    continue
101                else:
102                    for val in ord[1].coordAxisValues.coordinateList.CONTENT.split():
103                        if val != ' ':
104                            vals.append(eval(val)) 
105                if ord[1].coordAxisLabel.CONTENT=='longitude':
106                    lon=1
107                    name='longitude'
108                elif ord[1].coordAxisLabel.CONTENT=='latitude':
109                    lat=1
110                    name='latitude'
111                else:
112                    name=ord[1].coordAxisLabel.CONTENT
113                for ax in enumerate(axisorder):
114                    if ax[1]==name:
115                        position=ax[0]
116                axesdone.append(name)
117                self.addAxis(name,vals,isLon=lon,isLat=lat,units=unitlist[position])#to do, units attribute for CF compliance
118       
119        if kwargs is not None:   
120            for kw in kwargs:
121                lon,lat=None,None
122                if kw=='longitude':
123                    lon=1
124                elif kw == 'latitude':
125                    lat=1
126                name = kw
127                for ax in enumerate(axisorder):
128                    if ax[1]==name:
129                        position=ax[0]
130                vals=(kwargs[kw],)
131                self.addAxis(name,vals,isLon=lon,isLat=lat,units=unitlist[position])
132                axesdone.append(name)       
133        self.addVariable(fulldata,varid, axisorder, fillvalue, units=unitlist[-1] ) #to do, units attribute for CF compliance
134
135        for ax in self.axes:
136            if ax.id =='time':
137                if self.nc.variables.has_key('time') is False:
138                    self.addTimeVariable(floatTimes)
139       
140       
141    def closeFinishedFile(self):
142        #returns finished (hopefully) NetCDF file
143        self.nc.close()
Note: See TracBrowser for help on using the repository browser.