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

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

fixing longitude subsetting for ddc data

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                #check for latitude reversal:
118                if lat ==1: 
119                  if len(vals) >1: 
120                    if vals[0] > vals[len(vals)-1]: 
121                      vals.reverse() 
122               
123                self.addAxis(name,vals,isLon=lon,isLat=lat,units=unitlist[position])#to do, units attribute for CF compliance
124       
125        if kwargs is not None:   
126            for kw in kwargs:
127                lon,lat=None,None
128                if kw=='longitude':
129                    lon=1
130                elif kw == 'latitude':
131                    lat=1
132                name = kw
133                for ax in enumerate(axisorder):
134                    if ax[1]==name:
135                        position=ax[0]
136                vals=(kwargs[kw],)
137                self.addAxis(name,vals,isLon=lon,isLat=lat,units=unitlist[position])
138                axesdone.append(name)       
139        self.addVariable(fulldata,varid, axisorder, fillvalue, units=unitlist[-1] ) #to do, units attribute for CF compliance
140
141        for ax in self.axes:
142            if ax.id =='time':
143                if self.nc.variables.has_key('time') is False:
144                    self.addTimeVariable(floatTimes)
145       
146       
147    def closeFinishedFile(self):
148        #returns finished (hopefully) NetCDF file
149        self.nc.close()
Note: See TracBrowser for help on using the repository browser.