source: qesdi/geoplot/trunk/lib/geoplot/tests/unit/test_grid_builder_lat_lon_2.py @ 5826

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/qesdi/geoplot/trunk/lib/geoplot/tests/unit/test_grid_builder_lat_lon_2.py@5826
Revision 5826, 8.4 KB checked in by pnorton, 11 years ago (diff)

Improved geoplot's behaviour when dealing with variables with axis in the order of lon/lat instead of lat/lon.

Line 
1#/urs/bin/env python
2"""
3test_grid_builder_base.py
4"""
5import logging
6
7import nose
8import cdms2 as cdms
9import numpy
10from mock import Mock
11import mock
12
13
14
15def _is_magic(name):
16    if name == '__getslice__':
17        return False
18    return '__%s__' % name[2:-2] == name
19
20mock._is_magic = _is_magic
21
22import nose.tools as nt
23
24import geoplot.grid_builder_base
25from geoplot.grid_builder_lat_lon import GridBuilderLatLon
26from geoplot.grid import Grid
27
28
29class Test_GridBuidlerLatLon_ResizeVar(object):
30   
31    # Need to test the re-sizing of the axis works
32
33    def setUp(self):
34        self.lonVals = numpy.linspace(-6, 2, 17, endpoint=True)
35        self.latVals = numpy.linspace(-45, 60, 15, endpoint=True)
36
37        self.xLimits = (-4,-1.5)
38        self.yLimits = (-40, 53)
39       
40        self.subsetLonVals = numpy.linspace(-4, 1.5, 12, endpoint=True)
41        self.subsetLatVals = numpy.linspace(-45, 52.5, 14, endpoint=True)
42   
43    def buildMockSubsetVar(self):
44        #because mock dosen't mock magic methods creating transient axis
45        self.lonAxis = cdms.axis.TransientAxis(self.lonVals)
46        self.lonAxis.isCircular = lambda : True
47        #print self.lonAxis.isCircular()
48        self.latAxis = cdms.axis.TransientAxis(self.latVals)
49       
50
51        self.subsetLonAxis = cdms.axis.TransientAxis(self.subsetLonVals)
52        self.subsetLonAxis.isCircular = lambda : True
53        self.subsetLatAxis = cdms.axis.TransientAxis(self.subsetLatVals)
54       
55        self.mockVariable = _buildMockCDMSVariable(self.lonVals, self.latVals)
56        self.mockSubsetVar = _buildMockCDMSVariable(self.subsetLonVals, self.subsetLatVals)
57        self.mockVariable._return_value = self.mockSubsetVar       
58               
59    def test_001_checkSelectionIsMade(self):
60        self.buildMockSubsetVar()
61        gridBuilder = GridBuilderLatLon(self.mockVariable)
62       
63        subsetVar = gridBuilder._resizeVar(self.xLimits, self.yLimits)
64       
65        nt.assert_true(self.mockVariable.called)
66        nt.assert_equal(self.mockVariable.call_count, 1)
67        nt.assert_equal(self.mockVariable.call_args, ((), {
68                'longitude':(self.xLimits[0], self.xLimits[1], 'cce'), 
69                'latitude' :(self.yLimits[0], self.yLimits[1], 'cce')}))
70       
71        #check that the subset var is returned
72        nt.assert_equal(id(subsetVar), id(self.mockSubsetVar))
73   
74    def test_002_selectionChnagesForHighToLowLongitude(self):
75       
76        # reverse the values
77        self.lonVals = self.lonVals[::-1] 
78       
79        self.buildMockSubsetVar()
80       
81        gridBuilder = GridBuilderLatLon(self.mockVariable)
82        subsetVar = gridBuilder._resizeVar(self.xLimits, self.yLimits)
83
84        nt.assert_equal(self.mockVariable.call_args, ((), {
85                'longitude':(self.xLimits[1], self.xLimits[0], 'cce'), 
86                'latitude' :(self.yLimits[0], self.yLimits[1], 'cce')}))
87
88    def test_003_selectionChnagesForHighToLowLatitude(self):
89       
90        # reverse the values
91        self.latVals = self.latVals[::-1] 
92       
93        self.buildMockSubsetVar()
94       
95        gridBuilder = GridBuilderLatLon(self.mockVariable)
96        subsetVar = gridBuilder._resizeVar(self.xLimits, self.yLimits)
97
98        nt.assert_equal(self.mockVariable.call_args, ((), {
99                'longitude':(self.xLimits[0], self.xLimits[1], 'cce'), 
100                'latitude' :(self.yLimits[1], self.yLimits[0], 'cce')}))
101
102    def test_004_selectionChnagesForHighToLowLonAndLat(self):
103       
104        # reverse the values
105        self.latVals = self.latVals[::-1]
106        self.lonVals = self.lonVals[::-1] 
107       
108        self.buildMockSubsetVar()
109       
110        gridBuilder = GridBuilderLatLon(self.mockVariable)
111        subsetVar = gridBuilder._resizeVar(self.xLimits, self.yLimits)
112
113        nt.assert_equal(self.mockVariable.call_args, ((), {
114                'longitude':(self.xLimits[1], self.xLimits[0], 'cce'), 
115                'latitude' :(self.yLimits[1], self.yLimits[0], 'cce')}))
116
117    def test_005_returnsOriginalVariableOnException(self):
118        self.buildMockSubsetVar()
119       
120        self.mockVariable.side_effect = Exception("Subsetting Exception")
121       
122        gridBuilder = GridBuilderLatLon(self.mockVariable)
123       
124        subsetVar = gridBuilder._resizeVar(self.xLimits, self.yLimits)
125       
126        #check that the original var is returned
127        nt.assert_equal(id(subsetVar), id(self.mockVariable))
128       
129class Test_GridBuidlerLatLon_isAxisOrderLonLat(object):
130   
131    def setUp(self):
132        self.lonVals = numpy.linspace(-6, 2, 17, endpoint=True)
133        self.latVals = numpy.linspace(-45, 60, 15, endpoint=True)
134       
135    def test_001_findsLatLonOrder(self):
136        self.mockVariable = _buildMockCDMSVariable(self.lonVals, self.latVals, 
137                                                   orderLonLat=True)
138       
139        nt.assert_false(GridBuilderLatLon._areAxisInOrderYX(self.mockVariable))
140       
141    def test_002_findsLonLatOrder(self):
142        self.mockVariable = _buildMockCDMSVariable(self.lonVals, self.latVals, 
143                                                   orderLonLat=False)
144       
145        nt.assert_true(GridBuilderLatLon._areAxisInOrderYX(self.mockVariable))       
146
147class Test_GridBuidlerLatLon_buildGridValues(object):
148
149    #try and test that the values masked array built by the grid is correct
150
151    def setUp(self):
152        self.lonVals = numpy.linspace(-6, 2, 17, endpoint=True)
153        self.latVals = numpy.linspace(-45, 60, 15, endpoint=True)
154       
155    def buildMockVariable(self, orderLonLat, getMissing=None):
156       
157        self.mockVariable = _buildMockCDMSVariable(self.lonVals, self.latVals,
158                                                   orderLonLat=orderLonLat)
159        #the variable data is set up in the order of the axis
160        if orderLonLat:
161            variableData = numpy.zeros((len(self.lonVals), len(self.latVals)))
162        else:
163            variableData = numpy.zeros((len(self.latVals), len(self.lonVals)))
164       
165        self.mockVariable.getValue._return_value = variableData
166        self.mockVariable.getMissing._return_value = getMissing       
167
168    def test_001_buildsDataForLatLon(self):
169       
170        orderLonLat = False
171        self.buildMockVariable(orderLonLat)
172               
173        builder = GridBuilderLatLon(self.mockVariable)
174       
175        #assuming no subsetting was needed so just pass the variable used in the constructor
176        data = builder._buildGridValues(self.mockVariable)
177       
178        # the data should be in the order lat/lon (this is needed for imshow to work)
179        nt.assert_equal(data.shape, (len(self.latVals), len(self.lonVals)))       
180       
181    def test_001_buildsDataForLonLat(self):
182       
183        orderLonLat = True
184        self.buildMockVariable(orderLonLat)
185                     
186        builder = GridBuilderLatLon(self.mockVariable)
187       
188        #assuming no subsetting was needed so just pass the variable used in the constructor
189        data = builder._buildGridValues(self.mockVariable)
190       
191        # the data should be in the order lat/lon (this is needed for imshow to work)
192        nt.assert_equal(data.shape, (len(self.latVals), len(self.lonVals)))
193   
194
195def _buildMockCDMSVariable(lonVals, latVals, orderLonLat=False):
196    mockVariable = Mock(spec=cdms.tvariable.TransientVariable)
197
198    lonAxis = cdms.axis.TransientAxis(lonVals)
199    lonAxis.isCircular = lambda : True
200    latAxis = cdms.axis.TransientAxis(latVals)
201
202    mockVariable.getLongitude = Mock(return_value=lonAxis)
203    mockVariable.getLatitude = Mock(return_value=latAxis)
204           
205    if orderLonLat:
206        mockVariable.getAxisList._return_value = [lonAxis, latAxis]
207        mockVariable.getAxisIds._return_value = ['longitude','latitude']
208    else:
209        mockVariable.getAxisList._return_value = [latAxis, lonAxis]
210        mockVariable.getAxisIds._return_value = ['latitude','longitude']
211       
212    def getAxisIndex(axis):
213        assert axis in [lonAxis, latAxis]
214
215        if orderLonLat:
216            lonIndex, latIndex = 0,1
217        else:
218            lonIndex, latIndex = 1,0
219           
220        if axis == lonAxis:
221            return lonIndex
222        else:
223            return latIndex
224       
225    mockVariable.getAxisIndex = Mock(side_effect=getAxisIndex)
226       
227    mockVariable.getLevel = Mock(return_value=None)
228    mockVariable.getTime = Mock(return_value=None)
229    mockVariable.id = 'var'
230
231    mockVariable.reset_mock()
232    return mockVariable       
233       
234if __name__ == '__main__':
235
236    nose.runmodule()
Note: See TracBrowser for help on using the repository browser.