@@ -5087,28 +5087,49 @@ def shiftgrid(lon0,datain,lonsin,start=True,cyclic=360.0):
50875087 dataout [...,i0_shift :] = datain [...,start_idx :i0 + start_idx ]
50885088 return dataout ,lonsout
50895089
5090- def addcyclic (arrin , lonsin ):
5090+ def addcyclic (* arr , ** kwargs ):
50915091 """
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+ ============== ====================================================
50955103 """
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 ])
51075131 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 ])]
51125133
51135134def _choosecorners (width ,height ,** kwargs ):
51145135 """
0 commit comments