From: <js...@us...> - 2009-10-17 13:02:46
|
Revision: 7890 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7890&view=rev Author: jswhit Date: 2009-10-17 13:02:30 +0000 (Sat, 17 Oct 2009) Log Message: ----------- remove restriction that cyclic point be included in shiftgrid function (patch from Eric Bruning). Add unit tests for shiftgrid in test.py Modified Paths: -------------- trunk/toolkits/basemap/Changelog trunk/toolkits/basemap/README trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py trunk/toolkits/basemap/lib/mpl_toolkits/basemap/test.py Modified: trunk/toolkits/basemap/Changelog =================================================================== --- trunk/toolkits/basemap/Changelog 2009-10-16 17:31:42 UTC (rev 7889) +++ trunk/toolkits/basemap/Changelog 2009-10-17 13:02:30 UTC (rev 7890) @@ -1,4 +1,6 @@ version 0.99.5 (not yet released) + * shiftgrid no longer requires a cyclic point to be present + (patch from Eric Bruning). * fix date2index bugs. * update date2index function with a bug-fix from netcdf4-python. * in contourf method, mask data outside map projection region Modified: trunk/toolkits/basemap/README =================================================================== --- trunk/toolkits/basemap/README 2009-10-16 17:31:42 UTC (rev 7889) +++ trunk/toolkits/basemap/README 2009-10-17 13:02:30 UTC (rev 7890) @@ -140,5 +140,6 @@ Chris Murphy Pierre Gerard-Marchant Christoph Gohlke +Eric Bruning for valuable contributions. Modified: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py =================================================================== --- trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py 2009-10-16 17:31:42 UTC (rev 7889) +++ trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py 2009-10-17 13:02:30 UTC (rev 7890) @@ -3677,10 +3677,9 @@ dataout = np.where(xymask,masked,dataout) return dataout -def shiftgrid(lon0,datain,lonsin,start=True): +def shiftgrid(lon0,datain,lonsin,start=True,cyclic=360.0): """ Shift global lat/lon grid east or west. - assumes wraparound (or cyclic point) is included. .. tabularcolumns:: |l|L| @@ -3702,15 +3701,21 @@ start if True, lon0 represents the starting longitude of the new grid. if False, lon0 is the ending longitude. Default True. + cyclic width of periodic domain (default 360) ============== ==================================================== returns ``dataout,lonsout`` (data and longitudes on shifted grid). """ - if np.fabs(lonsin[-1]-lonsin[0]-360.) > 1.e-4: - raise ValueError, 'cyclic point not included' + if np.fabs(lonsin[-1]-lonsin[0]-cyclic) > 1.e-4: + # Use all data instead of raise ValueError, 'cyclic point not included' + start_idx = 0 + else: + # If cyclic, remove the duplicate point + start_idx = 1 if lon0 < lonsin[0] or lon0 > lonsin[-1]: raise ValueError, 'lon0 outside of range of lonsin' i0 = np.argmin(np.fabs(lonsin-lon0)) + i0_shift = len(lonsin)-i0 if hasattr(datain,'mask'): dataout = ma.zeros(datain.shape,datain.dtype) else: @@ -3720,15 +3725,15 @@ else: lonsout = np.zeros(lonsin.shape,lonsin.dtype) if start: - lonsout[0:len(lonsin)-i0] = lonsin[i0:] + lonsout[0:i0_shift] = lonsin[i0:] else: - lonsout[0:len(lonsin)-i0] = lonsin[i0:]-360. - dataout[:,0:len(lonsin)-i0] = datain[:,i0:] + lonsout[0:i0_shift] = lonsin[i0:]-cyclic + dataout[:,0:i0_shift] = datain[:,i0:] if start: - lonsout[len(lonsin)-i0:] = lonsin[1:i0+1]+360. + lonsout[i0_shift:] = lonsin[start_idx:i0+start_idx]+cyclic else: - lonsout[len(lonsin)-i0:] = lonsin[1:i0+1] - dataout[:,len(lonsin)-i0:] = datain[:,1:i0+1] + lonsout[i0_shift:] = lonsin[start_idx:i0+start_idx] + dataout[:,i0_shift:] = datain[:,start_idx:i0+start_idx] return dataout,lonsout def addcyclic(arrin,lonsin): Modified: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/test.py =================================================================== --- trunk/toolkits/basemap/lib/mpl_toolkits/basemap/test.py 2009-10-16 17:31:42 UTC (rev 7889) +++ trunk/toolkits/basemap/lib/mpl_toolkits/basemap/test.py 2009-10-17 13:02:30 UTC (rev 7890) @@ -1,10 +1,12 @@ -from mpl_toolkits.basemap import Basemap +from mpl_toolkits.basemap import Basemap, shiftgrid import numpy as np # beginnings of a test suite. -from numpy.testing import NumpyTestCase,assert_almost_equal -class TestRotateVector(NumpyTestCase): +from numpy.testing import TestCase,assert_almost_equal + +class TestRotateVector(TestCase): + def make_array(self): lat = np.array([0, 45, 75, 90]) lon = np.array([0,90,180,270]) @@ -17,7 +19,6 @@ B = Basemap() u,v,lat,lon=self.make_array() ru, rv = B.rotate_vector(u,v, lon, lat) - # Check that the vectors are identical. assert_almost_equal(ru, u) assert_almost_equal(rv, v) @@ -37,20 +38,74 @@ B=Basemap(projection='npstere', boundinglat=50., lon_0=0.) u,v,lat,lon=self.make_array() v = np.ones((len(lat), len(lon))) - ru, rv = B.rotate_vector(u,v, lon, lat) - assert_almost_equal(ru[2, :],[1,-1,-1,1], 6) assert_almost_equal(rv[2, :],[1,1,-1,-1], 6) +class TestShiftGrid(TestCase): + + def make_data_cyc(self): + loncyc = np.array([0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300,\ + 330, 360],dtype=np.float) + gridcyc = np.array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\ + 11, 0]],dtype=np.float) + lonoutcyc = np.array([-180, -150, -120, -90, -60, -30, 0, 30,60,90,\ + 120, 150, 180],dtype=np.float) + gridoutcyc = np.array([[ 6, 7, 8, 9, 10, 11, 0, 1, 2,3,\ + 4, 5, 6]],dtype=np.float) + return loncyc, gridcyc, lonoutcyc, gridoutcyc + + def make_data_nocyc(self): + lonnocyc = np.array([0, 30, 60, 90, 120, 150, 180, 210, 240, 270,\ + 300, 330],dtype=np.float) + gridnocyc = np.array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\ + 10, 11]],dtype=np.float) + lonoutnocyc = np.array([-180, -150, -120, -90, -60, -30, 0, 30, 60,\ + 90, 120, 150],dtype=np.float) + gridoutnocyc = np.array([[ 6, 7, 8, 9, 10, 11, 0, 1, 2,\ + 3, 4, 5]],dtype=np.float) + return lonnocyc, gridnocyc, lonoutnocyc, gridoutnocyc + + def make_data_nocyc2(self): + lonnocyc2 = np.array([15, 45, 75, 105, 135, 165, 195, 225, 255, 285,\ + 315, 345],dtype=np.float) + gridnocyc2 = np.array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\ + 10, 11]],dtype=np.float) + lonoutnocyc2 = np.array([-165, -135, -105, -75, -45, -15, 15,45,75,\ + 105, 135, 165],dtype=np.float) + gridoutnocyc2 = np.array([[ 6, 7, 8, 9, 10, 11, 0, 1, 2,\ + 3, 4, 5]],dtype=np.float) + return lonnocyc2, gridnocyc2, lonoutnocyc2, gridoutnocyc2 + + def test_cyc(self): + lonin, gridin, lonout, gridout = self.make_data_cyc() + grid, lon = shiftgrid(lonin[len(lonin)/2], gridin, lonin, start=False) + assert (lon==lonout).all() + assert (grid==gridout).all() + + def test_no_cyc(self): + lonin, gridin, lonout, gridout = self.make_data_nocyc() + grid, lon = shiftgrid(lonin[len(lonin)/2], gridin, lonin, start=False) + assert (lon==lonout).all() + assert (grid==gridout).all() + + def test_no_cyc2(self): + lonin, gridin, lonout, gridout = self.make_data_nocyc2() + grid, lon = shiftgrid(lonin[len(lonin)/2], gridin, lonin, start=False) + assert (lon==lonout).all() + assert (grid==gridout).all() + + def test(): """ Run some tests. """ import unittest - suite = unittest.makeSuite(TestRotateVector,'test') + rotatevector_suite = unittest.makeSuite(TestRotateVector,'test') + shiftgrid_suite = unittest.makeSuite(TestShiftGrid,'test') runner = unittest.TextTestRunner() - runner.run(suite) + runner.run(rotatevector_suite) + runner.run(shiftgrid_suite) if __name__ == '__main__': test() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |