def ImageRotation(self, bound, image, angle): ''' self.ArrayRotation() is 3D rotation self.ImageRotation() is 2D rotation Parameters ---------- bound: True / False image: Must be 2D array or 3D with .shape[2]==3 angle: [float] in degree angle>=0: anticlockwise angle <0: clockwise ''' angle %= 360 ang = angle - 360 if (angle > 180) else angle if (abs(ang) < 1e-4): return image import numpy as np from jizhipy.Basic import IsType, Raise import imutils image = np.array(image) if (len(image.shape) == 2): pass elif (len(image.shape) == 3 and image.shape[2] == 3): pass else: Raise( Exception, 'image must be 2D, or 3D with shape[2]==3, but now image.shape=' + str(image.shape)) if (bound): image = imutils.rotate_bound(image, -angle) else: image = imutils.rotate(image, angle) return image
def _Angle(self, kwargs, orderkwargs): ''' degree to rad, not call directly ''' from jizhipy.Basic import IsType import numpy as np from jizhipy.Array import Asarray N = len(orderkwargs) islist = [] raisestr = 'Shape miss-matching, ' for i in range(N): ok = orderkwargs[i] if (kwargs[ok] is None): kwargs[ok] = 0 islist.append(1 - IsType.isnum(kwargs[ok])) kwargs[ok] = Asarray(kwargs[ok]) * np.pi / 180 raisestr += ok + '.shape=' + str(kwargs[ok].shape) + ', ' try: for i in range(N): oki = orderkwargs[i] for j in range(N): okj = orderkwargs[j] if (i == j): continue kwargs[oki] = kwargs[oki] + kwargs[okj] * 0 # broadcast except: Raise(Exception, raisestr) if (np.array(islist).sum() == 0): islist = False else: islist = True return [kwargs, islist]
def _CoordInOut(self, coordin, coordout): ''' return registered coordin and coordout 'equatorial', 'galactic', 'ecliptic' ''' from jizhipy.Baise import Raise raisestr = "coordin='" + str(coordin) + "', coordout='" + str( coordout) + "' not in ['galactic', 'equatorial', 'ecliptic']" coordin, coordout = str(coordin).lower(), str(coordout).lower() if ('gal' == coordin[:3]): coordin = 'galactic' elif ('equ' == coordin[:3]): coordin = 'equatorial' elif ('ecl' == coordin[:3]): coordin = 'ecliptic' else: Raise(Exception, raisestr) if ('gal' == coordout[:3]): coordout = 'galactic' elif ('equ' == coordout[:3]): coordout = 'equatorial' elif ('ecl' == coordout[:3]): coordout = 'ecliptic' else: Raise(Exception, raisestr) return [coordin, coordout]
def ToHealpix(self, nside, RA, Dec=None, T=None, replace=True): ''' replace: =True : if there are several values in 1 pixel, use the lagest value to fill this pixel (for diffuse emission) =False : if there are several values in 1 pixel, fill this pixel with the sum of all values (for point sources) RA, Dec: in rad RA or lon : 0 ~ 2pi Dec or lat : -pi/2 ~ pi/2 if Dec=None and T=None : RA, Dec, T = RA[0], RA[1], RA[2] = RA (ROW) ''' import healpy as hp import numpy as np from jizhipy.Array import Asarray from jizhipy.Basic import Raise replace = bool(replace) hp.nside2resol(nside) if (Dec is None and T is None): RA, Dec, T = RA RA, Dec, T = 1 * Asarray(RA).flatten(), 1 * Asarray( Dec).flatten(), 1 * Asarray(T).flatten() size = max(RA.size, Dec.size, T.size) if ((RA.size not in [size, 1]) or (Dec.size not in [size, 1]) or (T.size not in [size, 1])): Raise( Exception, 'jizhipy.CoordTrans.ToHealpix(): RA.size=' + str(RA.size) + ', Dec.size=' + str(Dec.size) + ', T.size=' + str(T.size) + ' not in [' + str(size) + ',1]') if (RA.size == 1): RA = np.zeros(size) + RA[0] if (Dec.size == 1): Dec = np.zeros(size) + Dec[0] if (T.size == 1): T = np.zeros(size) + T[0] #---------------------------------------- if (replace): T = np.sort(T + 1j * np.arange(size)) n = T.imag.astype(int) T = T.real RA, Dec = RA[n], Dec[n] #---------------------------------------- hpmap = np.zeros(12 * nside**2) pix = hp.ang2pix(nside, np.pi / 2 - Dec, RA) if (replace): hpmap[pix] = T return hpmap #---------------------------------------- for i in range(pix.size): hpmap[pix[i]] += T[i] return hpmap
def _RAlDecb(self, RAl, Decb): ''' Make RAl and Decb can broadcast return: [RAl, Decb, islist] ''' from jizhipy.Basic import IsType from jizhipy.Array import Asarray if (IsType.isnum(RAl) and IsType.isnum(Decb)): islist = False else: islist = True RAl, Decb = Asarray(RAl), Asarray(Decb) try: RAl = RAl + Decb * 0 Decb = RAl * 0 + Decb except: Raise( Exception, 'RAl.shape=' + str(RAl.shape) + ', Decb.shape=' + str(Decb.shape) + ', can NOT broadcast') return [RAl, Decb, islist]
def thetaphi2xyz(self, thetaphi, Amp=1): ''' thetaphi: in rad, NOT degree Can be any shape, but must: theta, phi = thetaphi theta, phi can NOT have the same shape, but must can broadcast x = sin(theta) * cos(phi) y = sin(theta) * sin(phi) z = cos(theta) Amp: Must can broadcast with theta return: xyz = [x, y, z] x.shape = y.shape = z.shape = theta.shape = phi.shape ''' import numpy as np from jizhipy.Array import Asarray from jizhipy.Basic import Raise theta, phi = thetaphi theta, phi, Amp = Asarray2(theta, True), Asarray2(phi, True), Asarray2(Amp, True) try: x = Amp * np.sin(theta) * np.cos(phi) y = Amp * np.sin(theta) * np.sin(phi) z = Amp * np.cos(theta) * np.ones(phi.shape, phi.dtype) except: Raise( Exception, 'theta.shape=' + str(theta.shape) + ', phi.shape=' + str(phi.shape) + ', Amp.shape=' + str(Amp.shape) + ', can NOT broadcast') xyz = np.array([x, y, z]) del x, y, z return xyz
def _RotationMatrix(self, key, ang, islist): ''' return R, not call directly ''' from jizhipy.Array import ArrayAxis import numpy as np one = np.ones(ang.shape) zero = np.zeros(ang.shape) if (key == 'ax'): R = np.array([[one, zero, zero], [zero, np.cos(ang), np.sin(ang)], [zero, -np.sin(ang), np.cos(ang)]]) elif (key == 'ay'): R = np.array([[np.cos(ang), zero, -np.sin(ang)], [zero, one, zero], [np.sin(ang), zero, np.cos(ang)]]) elif (key == 'az'): R = np.array([[np.cos(ang), np.sin(ang), zero], [-np.sin(ang), np.cos(ang), zero], [zero, zero, one]]) else: Raise(Exception, "key in **kwargs not in ['ax', 'ay', 'az']") R = ArrayAxis(R, 0, -1, 'move') R = ArrayAxis(R, 0, -1, 'move') if (not islist): R = R[0] return R
def _xyzRotation(self, xyz, **kwargs): ''' (x,y,z) coordinates rotation with ax,ay,az= xyz: xyz can be any shape, but must: x, y, z = xyz x = sin(theta) * cos(phi) y = sin(theta) * sin(phi) z = cos(theta) **kwargs: See self.xyzRotationMatrix() ax=None: means NOT rotate this axis (1) xyzRotation(xyz, ay=1, ax=2, az=3) (2) ang = {'ay':1, 'ax':2, 'az':3, 'order':['ay','ax','az']} xyzRotation(xyz, **ang) return: Same shape and type as input xyz xyz_new.shape = xyz.shape+(3,) # (3,) for x,y,z ''' from jizhipy.Basic import OrderKwargs, Raise from jizhipy.Array import ArrayAxis, Asarray xyz = Asarray(xyz, True, float) shapexyz = xyz.shape if (shapexyz[0] != 3): Raise(Exception, 'xyz.shape=' + str(shapexyz) + ', shape[0] != 3') if (xyz.shape == (3, )): islistx = False else: islistx = True x, y, z = xyz #-------------------------------------------------- try: kwargs['order'] except: kwargs['order'] = OrderKwargs() if ('which' in kwargs.keys()): which = kwargs['which'] else: which = 'system' R = self.xyzRotationMatrix(which, **kwargs) shapeR = R.shape R = ArrayAxis(R, -2, 0, 'move') #@#@ if (R.shape == (3, 3)): islistr = False else: islistr = True Rx, Ry, Rz = R.T Rx, Ry, Rz = Rx.T, Ry.T, Rz.T #-------------------------------------------------- if (Rx.shape == (3, )): sR = Rx.shape + len(x.shape) * (1, ) Rx, Ry, Rz = Rx.reshape(sR), Ry.reshape(sR), Rz.reshape(sR) try: xyz = x * Rx + y * Ry + z * Rz except: Raise( Exception, 'x.shape=' + str(x.shape) + ', Rx.shape=' + str(Rx.shape) + ', can NOT broadcast') return xyz
def xyzRotationMatrix(self, which, **kwargs): ''' Right-hand rule: Your right thumb points along the +Z axis and the curl of your fingers represents a motion from +X to +Y to -X to -Y. When viewed from the top along -Z, the system is counter-clockwise. The angle along the fingers is positive. 'which': 'system' | 'point' Rotate coordinate system or point **kwargs: (1) kwargs={'ax':, 'ay':, 'az':, 'order':} Only allow keys 'ax', 'ay', 'az', 'order', all the keys are options 'order'=['ay', 'ax', ...] like Rotate about which axis with how many degree, 'order' is to determinate rotate which axis first, then which axis, .... (2) kwargs={'atheta':, 'aphi':, 'ang'} Only allow keys 'atheta', 'aphi', 'ang' ('atheta', 'aphi') reprecents the rotation axis (any axis), 'ang' is the rotation angle (right-handed) NOTE THAT atheta is theta, NOT lat Case (1) xyzRotationMatrix(ay, ax, az) OR xyzRotationMatrix(ax, ay, az, order=['ay','ax','az']) First rotate about Y-axis, second rotate about X-axis, third rotate about Z-axis ax: Rotation angle about X-axis, thumb points to +X ay: Rotation angle about Y-axis, thumb points to +Y az: Rotation angle about Z-axis, thumb points to +Z order: give the order manually, order=['az','ax','ay'] ax, ay, az: in degree, NOT rad Can be one or N-D array which can broadcast Case (2) xyzRotationMatrix(atheta, aphi, ang) Rotate about axis (atheta, aphi) with ang atheta, aphi, ang: all in degree Can be one or N-D array which can broadcast return: Rotation matrix R in np.array(), NOT np.matrix() new_xyz = R * old_xyz R.shape = ax.shape+(3,3) ''' from jizhipy.Basic import Raise, OrderKwargs # Check kwargs case1, case2 = False, False if ('ax' in kwargs.keys() or 'ay' in kwargs.keys() or 'az' in kwargs.keys()): case1 = True if ('atheta' in kwargs.keys() or 'aphi' in kwargs.keys() or 'ang' in kwargs.keys()): case2 = True if (case1 and case2): Raise( Exception, 'jizhipy.CoordTrans.xyzRotationMatrix(), have both (ax,ay,az,order) and (atheta,aphi,ang), NOT allow' ) if (case1): return self._xyzRotationMatrix1(**kwargs) elif (case2): return self._xyzRotationMatrix2(**kwargs)
def _Nside(self, nside): import numpy as np n = np.log(nside) / np.log(2) if (n != int(n)): Raise(Exception, 'nside=' + str(nside) + ' != 2**n') return int(round(nside))