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

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

more changes to allow preservation of netcdf attributes. Not complete, but not broken

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