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

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

bug fixed in profile subset

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