@@ -5087,28 +5087,49 @@ def shiftgrid(lon0,datain,lonsin,start=True,cyclic=360.0):
5087
5087
dataout [...,i0_shift :] = datain [...,start_idx :i0 + start_idx ]
5088
5088
return dataout ,lonsout
5089
5089
5090
- def addcyclic (arrin , lonsin ):
5090
+ def addcyclic (* arr , ** kwargs ):
5091
5091
"""
5092
- ``arrout, lonsout = addcyclic(arrin, lonsin)``
5093
- adds cyclic (wraparound) point in longitude to ``arrin`` and ``lonsin``,
5094
- assumes longitude is the right-most dimension of ``arrin``.
5092
+ Adds cyclic (wraparound) points in longitude to one or several arrays,
5093
+ the last array being longitudes in degrees. E.g.
5094
+
5095
+ ``data1out, data2out, lonsout = addcyclic(data1,data2,lons)``
5096
+
5097
+ ============== ====================================================
5098
+ Keywords Description
5099
+ ============== ====================================================
5100
+ axis the dimension longitude is in (default right-most)
5101
+ cyclic width of periodic domain (default 360)
5102
+ ============== ====================================================
5095
5103
"""
5096
- nlons = arrin .shape [- 1 ]
5097
- newshape = list (arrin .shape )
5098
- newshape [- 1 ] += 1
5099
- if ma .isMA (arrin ):
5100
- arrout = ma .zeros (newshape ,arrin .dtype )
5101
- else :
5102
- arrout = np .zeros (newshape ,arrin .dtype )
5103
- arrout [...,0 :nlons ] = arrin [:]
5104
- arrout [...,nlons ] = arrin [...,0 ]
5105
- if ma .isMA (lonsin ):
5106
- lonsout = ma .zeros (nlons + 1 ,lonsin .dtype )
5104
+ # get (default) keyword arguments
5105
+ axis = kwargs .get ('axis' ,- 1 )
5106
+ cyclic = kwargs .get ('cyclic' ,360 )
5107
+ # define functions
5108
+ def _addcyclic (a ):
5109
+ """addcyclic function for a single data array"""
5110
+ npsel = np .ma if np .ma .is_masked (a ) else np
5111
+ slicer = [slice (None )] * np .ndim (a )
5112
+ try :
5113
+ slicer [axis ] = slice (0 , 1 )
5114
+ except IndexError :
5115
+ raise ValueError ('The specified axis does not correspond to an '
5116
+ 'array dimension.' )
5117
+ return npsel .concatenate ((a ,a [slicer ]),axis = axis )
5118
+ def _addcyclic_lon (a ):
5119
+ """addcyclic function for a single longitude array"""
5120
+ # select the right numpy functions
5121
+ npsel = np .ma if np .ma .is_masked (a ) else np
5122
+ # get cyclic longitudes
5123
+ clon = (np .take (a ,[0 ],axis = axis )
5124
+ + cyclic * np .sign (np .diff (np .take (a ,[0 ,- 1 ],axis = axis ),axis = axis )))
5125
+ # ensure the values do not exceed cyclic
5126
+ clonmod = npsel .where (clon <= cyclic ,clon ,np .mod (clon ,cyclic ))
5127
+ return npsel .concatenate ((a ,clonmod ),axis = axis )
5128
+ # process array(s)
5129
+ if len (arr ) == 1 :
5130
+ return _addcyclic_lon (arr [- 1 ])
5107
5131
else :
5108
- lonsout = np .zeros (nlons + 1 ,lonsin .dtype )
5109
- lonsout [0 :nlons ] = lonsin [:]
5110
- lonsout [nlons ] = lonsin [- 1 ] + lonsin [1 ]- lonsin [0 ]
5111
- return arrout ,lonsout
5132
+ return map (_addcyclic ,arr [:- 1 ]) + [_addcyclic_lon (arr [- 1 ])]
5112
5133
5113
5134
def _choosecorners (width ,height ,** kwargs ):
5114
5135
"""
0 commit comments