def Interp1d(xdata, ydata, xnew, kind='linear'): ''' 1D interpolation. Note that all array must be 1D Outside the xdata, will use Linear interpolation xdata: must be 1D, must real ydata: must be 1D, real | complex xnew: any shape ndarray (not need to be 1D) | None * ==None: return def func(x) => a function kind: 'linear' or 'cubic' ''' import numpy as np from jizhipy.Array import Asarray xdata, ydata = Asarray(xdata).flatten(), Asarray(ydata).flatten() if ('complex' in ydata.dtype.name): yr = _Interp1d(xdata, ydata.real, xnew, kind) yi = _Interp1d(xdata, ydata.imag, xnew, kind) ynew = yr + 1j * yi else: ynew = _Interp1d(xdata, ydata, xnew, kind) return ynew
def LABdo(freq): from jizhipy.Array import Asarray freq = Asarray(freq) fmin, fmax = freq.min(), freq.max() if (fmax < LABfreq[0]): return False elif (fmin > LABfreq[1]): return False else: return True
def Corrcoef(x, y, axis): ''' Different from np.corrcoef() ''' from jizhipy.Basic import Raise import numpy as np from jizhipy.Array import Asarray x, y = Asarray(x), Asarray(y) try: x + y except: Raise( Exception, 'x.shape=' + str(x.shape) + ', y.shape=' + str(y.shape) + ' can NOT broadcast') x = x + y * 0 y = y + x * 0 if (axis < 0): axis += len(x.shape) if (axis >= len(x.shape)): Raise(Exception, 'axis=' + str(axis) + ' exceeds x.shape=' + str(x.shape)) up = ((x - x.mean(axis, keepdims=True)) * (y - y.mean(axis, keepdims=True))).sum(axis) / x.shape[axis] down = x.std(axis) * y.std(axis) r = up / down return r
def _SymmetryBeam( self, which, fwhm, theta, normalized ): ''' Generate any-dimension beam theta, fwhm: in rad Can be any shape normalized: False | 'int' | 'sum' 'int' means 'integrate' False: max=1 'sum': beam.sum()==1 'int': (beam * dtheta).sum()==1 return: beam, ndarray beam.shape = fwhm.shape + theta.shape GaussianBeam = exp{-(theta/FWHM)^2/2/sigma^2}, its max=1, not normalized. Set theta=0.5*FWHM, compute exp{-(1/2)^2/2/sigma^2}=0.5(because the max=1, theta=0.5*FWHM will decreate to half power) and get sigma^2=1/(8ln2) \int{e^(-a*x^2)dx} = (pi/a)^0.5 So, for the normalized GaussianBeam_normalized = 1/FWHM * (4ln2/pi)^0.5 * exp(-4ln2 * theta^2 / FWHM^2) SincBeam = np.sinc(2.783/np.pi * theta**2 / fwhm**2) ''' import numpy as np from jizhipy.Array import Asarray from jizhipy.Basic import IsType islistfwhm = False if(IsType.isnum(fwhm))else True islisttheta = False if(IsType.isnum(theta))else True fwhm, theta = Asarray(fwhm), Asarray(theta) shapefwhm, shapetheta = fwhm.shape, theta.shape fwhm, theta = fwhm.flatten(), theta.flatten() #---------------------------------------- which = str(which).lower() if (which == 'gaussian') : b = np.exp(-4*np.log(2) * theta[None,:]**2 / fwhm[:,None]**2) elif (which == 'sinc') : b = np.sinc(2.783/np.pi * theta[None,:]**2 / fwhm[:,None]**2)**2 #---------------------------------------- if (normalized is not False) : if (normalized == 'int') : a = 1/fwhm[:,None] *(4*np.log(2)/np.pi)**0.5 b *= a # for 'int' elif (normalized == 'sum') : b /= b.sum(1)[:,None] #---------------------------------------- if (not islistfwhm and not islisttheta) : b = b[0,0] elif (not islistfwhm and islisttheta) : b = b.reshape(shapetheta) elif (islistfwhm and not islisttheta) : b = b.reshape(shapefwhm) else : b = b.reshape(shapefwhm + shapetheta) #---------------------------------------- return b
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 _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 Center2Edge( array ) : ''' array is the centers, return the edges array can be non-uniform ''' from jizhipy.Array import Asarray array = Asarray(array) if (len(array.shape) != 1) : Raise(Exception, 'array must be 1D') step = array[1:] - array[:-1] n = array.size if ((1.*step.max()-step.min())/step.max() < 0.01) : edge = np.zeros([n+1,]) + array[n-1]+step.mean()/2. edge[:n] = array - step.mean()/2. return edge else : edge = np.zeros([n-2, n+1]) m, j = n/2, 0 for m in range(1, n-1) : edge[j,m] = array[m] - (step[m]+step[m-1])/4. for i in range(m-1, -1, -1) : edge[j,i] = 2*array[i] - edge[j,i+1] for i in range(m+1, n+1) : edge[j,i] = 2*array[i-1] - edge[j,i-1] j = j + 1 return edge.mean(0)
def Ymap( self, ymap=None ) : ''' ymap: Input y map, must be 2D array/matrix. y.shape = (nfreq, npix), row nfreq is the number of frequencies, column npix is the number of pixels at its frequency. (1) y is ndarray (2) y is list, len(y)==nfreq ''' import numpy as np from jizhipy.Basic import Raise, SysFrame, IsType from jizhipy.Array import Asarray from jizhipy.Optimize import Smooth if (ymap is None) : if (SysFrame(0,2)[-3][-2]!='') : self.ymap = None if (self.verbose) : print(' self.y = None') return else : return self.ymap pstr = ' ' if ('ymap' not in self.__dict__.keys())else ' Change: ' if (IsType.islist(ymap) or IsType.istuple(ymap)) : if (not IsType.isnum(ymap[0])) : ymap, N = list(ymap), 1e15 for i in range(len(ymap)) : if (len(ymap) < N) : N = len(ymap) for i in range(len(ymap)) : ymap[i]=jp.Smooth(ymap[i], 0,reduceshape=N) self.ymap = Asarray(ymap, np.float64) # force bit64 if (len(self.ymap.shape) not in [1, 2]) : Raise(Exception, 'jizhipy.PCA: ymap must be 1D/2D, but now ymap.shape='+str(self.ymap.shape)) if (self.verbose) : print(pstr+'self.ymap.shape =', self.ymap.shape) return self.ymap
def AlmReduce(alm, lmax=None, mmax=None): ''' alm: l from 0 to lmax0 NOTE THAT input alm must be full: lmax==mmax lmax: lmax of the reduced alm Reduced alm's l from 0 to lmax mmax: mmax of the reduced alm Reduced alm's m from 0 to mmax if lmax=None: lmax=lmax0 if mmax=None: mmax=mmax0 ''' import numpy as np from jizhipy.Array import Asarray import healpy as hp lmax0 = hp.Alm.getlmax(alm.size) mmax0 = hp.Alm.getidx(lmax0, 1, 1) - 1 lmax = lmax0 if (lmax is None) else int(lmax) mmax = mmax0 if (mmax is None) else int(mmax) l, m = hp.Alm.getlm(lmax0) tf = (l <= lmax) * (m <= mmax) alm = Asarray(alm)[tf] return alm
def xyz2thetaphi(self, xyz): ''' xyz: Can be any shape, but must: x, y, z = xyz return: thetaphi = [theta, phi] in rad (NOT degree) theta.shape = phi.shape = x.shape theta: 0--np.pi phi: 0--2*np.pi ''' from jizhipy.Basic import Print, IsType import numpy as np x, y, z = xyz if (IsType.isnum(x)): islistx = False else: islistx = True if (IsType.isnum(y)): islisty = False else: islisty = True if (IsType.isnum(z)): islistz = False else: islistz = True islist = bool(islistx + islisty + islistz) x, y, z = Asarray(x), Asarray(y), Asarray(z) r = (x**2 + y**2 + z**2)**0.5 r[r == 0] = 1e-30 x, y, z = x / r, y / r, z / r #-------------------------------------------------- # theta from 0 to 180, sin(theta) >=0 theta = np.arccos(z) # 0 to 180 degree zero = (np.sin(theta) == 0) sign = np.sign(z[zero]) theta[zero] += 1e-30 del z # Print.WarningSet(False) x = x / np.sin(theta) y = y / np.sin(theta) # Print.WarningSet(True) x = x + 1j * y del y phi = np.angle(x) % (2 * np.pi) theta[zero] -= 1e-30 if (zero.sum() > 0): phi[zero] = np.pi / 2 - sign * np.pi / 2 if (not islist): theta, phi = theta[0], phi[0] return np.array([theta, phi]) % (2 * np.pi)
def Edge2Center( array ) : ''' array is the edges, return the centers array can be non-uniform. ''' from jizhipy.Array import Asarray array = Asarray(array) if (len(array.shape) != 1) : Raise(Exception, 'array must be 1D') step = array[1:] - array[:-1] return array[:-1] + step/2.
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 SciNot( array ) : ''' Scientific Notation. value can be scale(int/float), list/n-D array Return [a, n], value = a * 10**n ''' from jizhipy.Basic import IsType import numpy as np from jizhipy.Array import Asarray if (IsType.isint(array) or IsType.isfloat(array)) : islist = False else : islist = True array = Asarray(array) # Flatten shape = array.shape array = array.flatten() # Get the sign sign = np.sign(array) # sign(0)=0 # Convert to abs array = abs(array) # because sign(0)=0, convert 0 to 1 array[array==0] = 1 nlarge, nsmall = (array>=1), (array<1) # bool, not int # Use log10 to get the power index # >=1 if (nlarge.sum() > 0) : idxlarge = np.log10(array[nlarge]).astype(int) else : idxlarge = [] # <1 if (nsmall.sum() > 0) : scalesmall = int(round(np.log10(array[nsmall].min())))-2 array[nsmall] /= 10.**scalesmall idxsmall = np.log10(array[nsmall]).astype(int) + scalesmall array[nsmall] *= 10.**scalesmall else : idxsmall = [] # valid and idx idx = np.zeros(array.size, int) idx[nlarge], idx[nsmall] = idxlarge, idxsmall valid = sign * (array / 10.**idx) valid, idx = valid.reshape(shape), idx.reshape(shape) if (islist) : return (valid, idx) else : return (valid[0], idx[0])
def Bar(x, y, align='edge', *args, **kwargs): ''' matplotlib.pyplot.bar(x, y, ...) align: 'edge': x=>xe 'center': x=>xc ''' from jizhipy.Plot import Gca if ('ax' in kwargs.keys()): ax = kwargs['ax'] kwargs.pop('ax') else: ax = Gca() if (align == 'center'): ax.bar(x, y, align='center', *args, **kwargs) return ax from jizhipy.Array import Asarray xe, y = Asarray(x), Asarray(y) width = xe[1:] - xe[:-1] ax.bar(xe[:-1], y, width, align='edge', *args, **kwargs) return ax
def GaussianSolidAngle( self, fwhmx, fwhmy=None ) : ''' fwhmx, fwhmy: in rad Can be any shape, but must can broadcast return: solid_angle =GaussianSolidAngle(fwhmx, fwhmy) in sr ''' from jizhipy.Basic import IsType from jizhipy.Array import Asarray import numpy as np fwhmx, fwhmy = Asarray(fwhmx,True), Asarray(fwhmy,True) if (fwhmy is None) : fwhmy = fwhmx fwhmx = fwhmx + 0*fwhmy # broadcast fwhmy = 0*fwhmx + fwhmy isnum = IsType.isnum(fwhmx) + IsType.isnum(fwhmy) if (isnum == 2) : return self._GaussianSolidAngle(fwhmx, fwhmy) shape = fwhmx.shape fwhmx, fwhmy = fwhmx.flatten(), fwhmy.flatten() solid_angle = np.zeros(fwhmx.size) for i in range(fwhmx.size) : solid_angle[i] = self._GaussianSolidAngle(fwhmx[i], fwhmy[i]) return solid_angle.reshape(shape)
def __init__(self, Nstart=None, Nend=None, Nprocess=None, nsplit=None, thread=False, verbose=False): ''' (1) PoolFor( Nstart, Nend, Nprocess ) use Nstart, Nend, Nprocess to calculate nsplit split send in self.map_async() (2) PoolFor( nsplit ) use this nsplit split send in self.map_async() (3) PoolFor() don't split send in self.map_async(), send has been splitted when gived to self.map_async(splitted_send, bcast) send[0] for process-1 send[1] for process-2 ...... send[n] for process-n+1 ''' import numpy as np from jizhipy.Array import Asarray self.verbose, self.thread = bool(verbose), bool(thread) self.zero, self.splitsend = False, True if ((Nstart is None or Nend is None) and nsplit is None): self.splitsend = False return #-------------------------------------------------- if (nsplit is not None): Nprocess, NprocessTot, threads, cores, Ncpu, hyper, cpuinfo = NprocessCPU( len(nsplit)) #-------------------------------------------------- else: if (Nend - Nstart <= 0): Raise(Warning, 'Nend-Nstart=' + str(Nend - Nstart) + '<=0, return None') self.zero = True return Nprocess, NprocessTot, threads, cores, Ncpu, hyper, cpuinfo = NprocessCPU( Nprocess) if (Nend - Nstart < Nprocess): Nprocess = Nend - Nstart # nsplit nsplit = np.linspace(Nstart, Nend, Nprocess + 1).astype(int) nsplit = np.array([nsplit[:-1], nsplit[1:]]).T #-------------------------------------------------- self.Nprocess, self.nsplit = Nprocess, Asarray(nsplit) self.Nmax = (self.nsplit[:, 1] - self.nsplit[:, 0]).max()
def ArrayAxis(array, axis1, axis2, act='move'): ''' array: Any dimension array (real, complex, masked) axis1, axis2, act: act='move': old a[axis1] becomes new b[axis2] a.shape=(2,3,4,5,6) b = ArrayAxis(a, 3, 1, 'move') b.shape=(2,5,3,4,6) act='exchange' : exchange a[axis1] with a[axis2] a.shape=(2,3,4,5,6) b = ArrayAxis(a, 3, 1, 'exchange') b.shape=(2,5,4,3,6) ''' import numpy as np from jizhipy.Array import Asarray from jizhipy.Basic import Raise, IsType ismatrix = IsType.ismatrix(array) array = Asarray(array) shapeo = array.shape if (len(shapeo) <= 1): return array if (axis1 < 0): axis1 = len(shapeo) + axis1 if (axis2 < 0): axis2 = len(shapeo) + axis2 if (axis1 == axis2): return array if (axis1 >= len(shapeo) or axis2 >= len(shapeo)): Raise( Exception, 'axis1=' + str(axis1) + ', axis2=' + str(axis2) + ' out of array.shape=' + str(shapeo) + '=>' + str(len(shapeo)) + 'D') if (len(shapeo) == 2): return array.T if (len(shapeo) == 3 and ((axis1 == 0 and axis2 == 2) or (axis1 == 2 and axis2 == 0)) and act.lower() == 'exchange'): return array.T #-------------------------------------------------- axis = list(range(len(shapeo))) if (act.lower() == 'move'): axis.remove(axis1) axis = axis[:axis2] + [axis1] + axis[axis2:] elif (act.lower() == 'exchange'): axis[axis1] = axis2 axis[axis2] = axis1 array = np.transpose(array, axis) if (ismatrix): array = np.matrix(array) return array
def FeedBeam( self, *args, **kwargs ) : ''' each beam of feed OR combined beam of pair, depending on self.feedpos and self.baseline For baseline case, self.beam must be real, NOT complex *args: give fwhm: in [rad] (1) 1 value: all beam are the same args = (1, ) (2) fwhm.size = Nfeed: each feed has its fwhm args = (1, 2, 3, 4, ...) **kwargs: sqrt=True: return beam**0.5 Default : return power beam (1) FeedBeam(): Uniform beam (2) FeedBeam(fwhm): GaussianBeam, NOT SincBeam (3) FeedBeam(fwhm1, fwhm2): EllipticGaussianBeam self.beam (case 1) =1 (case 2) .shape = (1, N_incident_direction) (case 3) .shape = (Nfeed/Nbl, N_incident_direction) ''' import numpy as np from jizhipy.Array import Asarray from jizhipy.Basic import IsType, Raise from jizhipy.Astro import Beam if (len(args) == 0 or args[0] is None) : self.beam = 1 return if ('thetaphi' not in self.__dict__.keys()) : Raise(Exception, 'NOT exists self.thetaphi, set it by SyntheticBeam.WaveVector()') if (len(args) == 1) : fwhm1 = fwhm2 = Asarray(args[0]) else : fwhm1, fwhm2 = args[:2] self.beam = [] for i in range(len(fwhm1)) : self.beam.append( Beam.EllipticGaussianBeam(fwhm1[i], fwhm2[i], self.thetaphi[0], self.thetaphi[1]) ) self.beam = np.array(self.beam) if ('sqrt' in kwargs.keys() and kwargs['sqrt']) : self.beam = abs(self.beam)**0.5 return self.beam
def lcm(self, *args): ''' lcm: lowest common multiple ''' import numpy as np from jizhipy.Basic import Raise, IsType from jizhipy.Array import Asarray a = [] for i in range(len(args)): a.append(Asarray(args[i]).flatten()) a = np.concatenate(a) if (not IsType.isint(a[0])): Raise( Exception, 'jizhipy.CommonFactor.lcm(): input number must be "int", but now is "' + a.dtype.name + '"') a = a[a > 0] if (a.size == 0): return 1 elif (a.size == 1): return 1 b = a.prod() / a v = self.gcd(b) v = a.prod() / v return v
def Sort( array, along='[0,:]', l2s=False ) : ''' array: Can be any shape along: Must as format like '[n1,n2,:,n4]' Must have ':', use [2,:] instead of [2] array[n1,n2,:,n4] must 1D so that we can sort along this along=[:,2] : second column '[0,:]' => 0-row '[:,0]' => 0-column l2s: l2s=False: from small to large (default) l2s=True : from large to small ''' import numpy as np from jizhipy.Array import Asarray, ArrayAxis along = along[1:-1].split(',') axis = along.index(':') along.pop(axis) along = np.array(along, int) #-------------------------------------------------- array = Asarray(array) if (len(array.shape) == 1) : array = np.sort(array) if (l2s) : array = array[::-1] return array #-------------------------------------------------- if (array.shape[axis] == 1) : return array array = ArrayAxis(array, axis, -1, 'move') shape = array.shape #-------------------------------------------------- cumprod = np.cumprod((shape[1:-1]+(1,))[::-1])[::-1] along = (along*cumprod).sum() a = array.reshape(np.prod(shape[:-1]), shape[-1])[along] #-------------------------------------------------- a = a + 1j*np.arange(a.size) a = np.sort(a).imag.astype(int) if (l2s) : a = a[::-1] #-------------------------------------------------- array = ArrayAxis(array, -1, 0, 'move') array = array[a] array = ArrayAxis(array, 0, axis, 'move') return array
def ArraySplit( array, axis, which ) : ''' axis: split along which axis which: =='1G' | '1GB' ==int ''' import numpy as np from jizhipy.Array import Asarray, ArrayAxis, Repection from jizhipy.Basic import IsType array = Asarray(array) if (IsType.isint(which)) : mem, N = None, which elif (IsType.isstr(which)) : which = str(which).lower() if ((which[-1]=='g' and which[-2] in '0123456789')) : mem = float(which[:-1]) elif ((which[-2:]=='gb' and which[-3] in '0123456789')) : mem = float(which[:-2]) # GB else : array = ArrayAxis(array, axis, 0, 'move') array = array[None,:] array = ArrayAxis(array, 0, axis+1, 'move') return array #-------------------------------------------------- if (mem is not None) : bit, n = array.dtype.name, 0 while (bit[n] not in '0123456789') : n += 1 bit = float(bit[n:]) size = array.size memtot = size / 1e8 * 0.8 * bit/64 N = int(memtot / mem) + 1 m = np.linspace(0, array.shape[axis], N+1).astype(int) m = Repetition(m, renon=True) b = [] array = ArrayAxis(array, axis, 0, 'move') for i in range(len(m)-1) : a = ArrayAxis(array[m[i]:m[i+1]], 0, axis) b.append(a) return b
def gcd(self, *args): ''' gcd: greatest common divisor ''' import numpy as np from jizhipy.Basic import Raise, IsType from jizhipy.Array import Asarray a = [] for i in range(len(args)): a.append(Asarray(args[i]).flatten()) a = np.concatenate(a) if (not IsType.isint(a[0])): Raise( Exception, 'jizhipy.CommonFactor.gcd(): input number must be "int", but now is "' + a.dtype.name + '"') a = abs(a.astype(float)) a = a[a > 0] if (a.size == 0): return 1 elif (a.size == 1): return int(a[0]) vmin = int(a.min()) for v in range(vmin, 0, -1): b = a / v b = abs(b - b.astype(int)).sum() if (b < 1e-6): break return v
def EllipticGaussianBeam( self, fwhm1, fwhm2, theta, phi, normalized=False ) : ''' theta, phi, fwhm1, fwhm2: in rad theta.shape == phi.shape, can be any shape fwhm1.shape == fwhm2.shape, can be any shape ''' import numpy as np from jizhipy.Array import Asarray from jizhipy.Basic import Raise, IsType if (IsType.isnum(fwhm1)) : islistfwhm1 = False else : islistfwhm1 = True if (IsType.isnum(fwhm2)) : islistfwhm2 = False else : islistfwhm2 = True islistfwhm = bool(islistfwhm1 + islistfwhm2) if (IsType.isnum(theta)) : islisttheta = False else : islisttheta = True if (IsType.isnum(phi)) : islistphi = False else : islistphi = True islisttheta = bool(islisttheta + islistphi) fwhm1, fwhm2, theta, phi = Asarray(fwhm1), Asarray(fwhm2), Asarray(theta), Asarray(phi) shape1, shape2, shapet, shapep = fwhm1.shape, fwhm2.shape, theta.shape, phi.shape printstr = 'fwhm1.shape='+str(shape1)+', fwhm2.shape='+str(shape2)+', theta.shape='+str(shapet)+', phi.shape='+str(shapep) if (shape1 != shape2) : Raise(Exception, 'fwhm1.shape != fwhm2.shape. '+printstr) if (shapet != shapep) : Raise(Exception, 'theta.shape != phi.shape. '+printstr) #-------------------------------------------------- fwhm1, fwhm2, theta, phi = fwhm1.flatten(), fwhm2.flatten(), theta.flatten(), phi.flatten() b = np.exp(-4*np.log(2) * theta[None,:]**2 * ((np.cos(phi[None,:])/fwhm1[:,None])**2 + (np.sin(phi[None,:])/fwhm2[:,None])**2)) if (normalized) : a = 4*np.log(2) * ((np.cos(phi[None,:])/fwhm1[:,None])**2 + (np.sin(phi[None,:])/fwhm2[:,None])**2) b = b/(np.pi/a)**0.5 a = 0 #@ #-------------------------------------------------- if (not islistfwhm and not islisttheta) : b = b[0,0] elif (not islistfwhm and islisttheta) : b = b.reshape(shapet) elif (islistfwhm and not islisttheta) : b = b.reshape(shape1) else : b = b.reshape(shape1 + shapet) return b
def ProbabilityDensity(self, randomvariable, bins, weight=None, wmax2a=None, nsigma=6, density=True): ''' Return the probability density or number counting of array. Return: [xe, xc, y] xe is the edge of the bins. xc is the center of the bins. y is the probability density of each bin, randomvariable==array: Input array must be flatten() bins: (1) ==list/ndarray with .size>3: ** Then ignore brange, weight, wmax2a use this as the edge of the bins total number of the bins is bins.size-1 (x.size=bins.size, xc.size=bins.size-1) (2) ==list/ndarray with .size==3 ** nbins, bmin, bmax = bins nbins: number of bins bmin, bmax: min and max of bins, NOT use the whole bin (3) ==int_number: ** Then use weight and wmax2a Give the total number of the bins, in this case, x.size=bins+1, xc.size=bins weight: ** Use this only when bins==int_number 'G', 'K0' | None | ndarray with size=bins (1) ==None: each bin has the same weight => uniform bins (2) ==ndarray: give weights to each bins (3) =='G': use Gaussian weight =='K0': use modified Bessel functions of the second kind wmax2a: ** Use this only when bins==int_number and weight is not None float | None (1) ==None: means weight[0]=>bins[0], weight[1]=>bins[1], weight[i]=>bins[i] (2) ==float: uniform bin b = np.linspace(array.min(), array.max(), bins+1) value wmax2a is in nb-th bin: b[nb] <= wmax2a <= b[nb+1] weight.max() => weight[nmax] !!! Give weight[nmax] to the bin b[nb] (then reorder the weight array) nsigma: float | None (use all data) When generate the bins, won't use the whole range of array, set nsigma, will throw away the points beyond the mean density: If True, return the probability density = counting / total number / bin width If False, return the counting number of each bin Return: [xe, xc, y] xe is the edge of the bins. xc is the center of the bins. y is the probability density of each bin, ''' import numpy as np from jizhipy.Process import Edge2Center from jizhipy.Array import Asarray #--------------------------------------------- # nsigma # Throw away the points beyond the mean try: nsigma = float(nsigma) except: nsigma = None array = Asarray(randomvariable).flatten() sigma, mean = array.std(), array.mean() if (nsigma is not None): array = array[(mean - nsigma * sigma <= array) * (array <= mean + nsigma * sigma)] amin, amax = array.min(), array.max() #--------------------------------------------- if (Asarray(bins).size <= 3): bins = self.Bins(array, bins, weight, wmax2a, None) bins = Asarray(bins) #--------------------------------------------- bins = bins[bins >= amin] bins = bins[bins <= amax] tf0, tf1 = False, False if (abs(amin - bins[0]) > 1e-6): bins = np.append([amin], bins) tf0 = True if (abs(amax - bins[-1]) > 1e-6): bins = np.append(bins, [amax]) tf1 = True #--------------------------------------------- y, bins = np.histogram(array, bins=bins, density=density) if (tf0): y, bins = y[1:], bins[1:] if (tf1): y, bins = y[:-1], bins[:-1] x = Edge2Center(bins) return [bins, x, y]
def GaussianFilter( self, per=None, times=None, std=None, shape=None ) : ''' std(pixel) = fwhm(pixel) / (8*ln2)**0.5 return: [gaussianfilter, std] Unit for std: pixel When use this std, x must pixel: np.arange(...) return normalized beam.sum()=1 gf1, s1 = GaussianFilter(per, times) gf2, s2 = GaussianFilter(None, None, s1, gf1.size) gf3=GaussianValue(np.arange(gf1.size), gf1.size/2, s1) gf1==gf2==gf3, s1==s2 NOTE THAT must be GaussianFilter.sum()==1 can NOT be other value Case 1: per, times, shape (1) Use per, times to generate gaussianfilter gaussianfilter.size = (per-1) * times + 1 (2) Use shape to reshape gaussianfilter Case 2: std, shape Use std, shape to generate gaussianfilter First use case 1, otherwise use case 2 shape: (1) Use per, times, shape 1. shape in [None, '1D']: 1D with original size 2. shape isint: 1D with .size=shape 3. shape == '2D': 1D with original size^2 4. shape == (int, int, ...): N-D filter, std=(axis0, axis1, ...) (2) Use std, shape 1. shape isint: 1D with .size=shape 2. shape == (int, int, ...): N-D filter, std=(axis0, axis1, ...) ''' from jizhipy.Optimize import GaussianFilter, Smooth from jizhipy.Basic import IsType import numpy as np from jizhipy.Array import Asarray if (per is not None and times is not None) : case = 1 else : case = 2 if (shape is None) : shape = [''] elif (IsType.isstr(shape)) : shape = ['' for i in range(int(shape[:-1]))] else : shape = Asarray(shape, int).flatten() #------------------------------------ filt, sigma = [], [] for i in range(len(shape)) : if (case == 1) : f, s = GaussianFilter(per, times) if (shape[i] != '') : f = Smooth(f, 0, reduceshape=shape[i]) if (case == 2) : f, s =GaussianFilter(None, None, std, shape[i]) filt.append(f) sigma.append(s) #------------------------------------ nd = len(shape) if (nd == 1) : filt, std = filt[0], sigma[0] else : std = np.array(sigma) for i in range(nd) : shape = [1 for j in range(nd)] shape[i] = filt[i].size filt[i] = filt[i].reshape(shape) for i in range(1, nd) : filt[0] = filt[0]*filt[i] filt = filt[0] return [filt, std]
def map_async(self, func, send=None, bcast=None): ''' If use apply() or map(), we can stop the pool program with Ctrl-c. However, if use apply_async().get(xxx) or map_async().get(xxx), we can use Ctrl-c to stop the program at any time. iterable: iterable[0] = [(n1,n2), (Nprocess, rank, pid)] func: _DoMultiprocess() send: (1) None (2) list/tuple. For this case, send[0], send[1], ... are different array, will split send[i] into Nprocess pieces, NOT split send !!! (3) 2D-ndarray: send[i] for ranks a, b = iterable[1] | a = iterable[1][0] (one array, must give[0]) If is tuple/list, means each element is one array (note that must be 2D, and split along axis=0/row) If not tuple/list, means the send is an unity: send = Asarray(send) If is 2D array, will split along axis-0 (row) bcast: None or tuple or others/as a unity If is others, may bcast = (bcast,) Some data which will be broadcasted to each processes, such as the x and p0 in test_multiprocess_poolfor_class-func.py Must be tuple: (x, p0, ...) get: get=True: pool.map_async(func,iterable).get(10**9) get=False: pool.map_async(func,iterable) ''' if (self.zero): return import numpy as np from jizhipy.Array import Asarray if (self.splitsend): # Main here istuple = True if (type(send) != tuple and type(send) != list): send, istuple = (Asarray(send), ), False iterable, nsl = list(self.nsplit), self.nsplit for i in range(len(nsl)): iterable[i] = [[iterable[i], [self.Nmax, i]]] sendtmp = () for j in range(len(send)): if (send[j] is None): sendtmp += (None, ) else: sendtmp += (send[j][nsl[i][0]:nsl[i][1]], ) if (not istuple): sendtmp = sendtmp[0] iterable[i] += [sendtmp, bcast] #-------------------------------------------------- else: if (send is not None): self.Nprocess = len(send) iterable = [] Nmax = 0 for i in range(len(send)): try: if (len(send[i]) > Nmax): Nmax = len(send[i]) except: pass for i in range(len(send)): iterable.append([[[None, None], [Nmax, i]], send[i], bcast]) else: self.Nprocess = 1 iterable = [[[[None, None], [1, 0]], None, bcast]] #-------------------------------------------------- cpuinfo = NprocessCPU()[-1] if (self.verbose): print('Open ' + str(self.Nprocess) + ' processes \n' + cpuinfo) # if (not self.thread) : # import multiprocessing # pool = multiprocessing.Pool(self.Nprocess) # else : # from multiprocessing.pool import ThreadPool # pool = ThreadPool(self.Nprocess) import multiprocessing pool = multiprocessing.Pool(self.Nprocess) for i in range(len(iterable)): iterable[i][0][1].append(str(pool._pool[i].pid)) self.data = pool.map_async(func, iterable).get(10**9) pool.close() pool.join() return self.data
def Time(current=None, ephemtime=None, sec1970=None, timezone=None, which=None, datelist=None): ''' (1) Return local/system timezone (int) ** Time( timezone=True ) timezone >=0:east, <0:west (2) Convert ephemtime to sec1970 with timezone ** Time(ephemtime='2016/10/25 16:39:24.68', timezone=8) (3) Convert ephemtime from timezonein to timezoneout ** Time( ephemtime='2016/10/25 16:39:24.68', timezone=[8, 5] ) (4) Convert sec1970 to ephemtime with timezone ** Time( sec1970=1477411200.729252, timezone=8, which=) (5) Calculate time interval between two ephemtimes ** Time( ephemtime=['2016/10/25 16:39:24.68', '2016/11/25 18:49:54.37'], which=0/1 ) which=0: return h:m:s which=1: return second return (ephemtime2 - ephemtime1) (6) Return current-time with timezone WITH/WITHOUT Daylight Saving Time ** Time( current=0/1/2/3/4/5, timezone=8, daylight=True/False ) (7) Date list ['2010-10-01', '2010-11-01', ...] ** Time( datelist=['2010-10-01', how, length] ) how: 2 case: '+3d'/'-3d' | '+3D'/'-3D' '+3d': add 3 days '+3D': each months' date 3: 2018-01-03, 2018-02-03, 2018-03-03, 2018-04-03, ... ** Similar: '+3m', '-3m': month '+3y', '-3y': year '+3M', '-3M': each years' March how must be str, not list, default '+1d' length: int, the length of return list ** Time( datelist=['2004-02-25', '+1d', 10] ) ** Time( datelist=['2004-02-25', '+1D', 10] ) (8) Time() = time.time() ''' import numpy as np from jizhipy.Array import Asarray from jizhipy.Basic import IsType # (1) Time(timezone=True) if (timezone is True): return _Time('timezone') #---------------------------------------- elif (IsType.isstr(ephemtime)): # (2) Time(ephemtime='2019/02/15 18:54:29.7') if (timezone is None): return _Time(ephemtime) timezone = Asarray(timezone, int).flatten() if (timezone.size == 1): return _Time(ephemtime, timezone[0]) #---------------------------------------- # (3) Time(ephemtime='2019/02/15 18:54:29.7', timezone=[0,8]) else: return _Time(ephemtime, timezone[0], timezone[1]) #---------------------------------------- # (4) Time(sec1970=1550228069.8, timezone=?, which=0/1) # elif (sec1970 is not None and IsType.isnum(timezone)) : return _Time(sec1970, timezone, which) elif (sec1970 is not None): return _Time(sec1970, timezone, which) #---------------------------------------- # (5) elif (ephemtime is not None): return _Time(ephemtime[0], ephemtime[1], which) #---------------------------------------- # (6) elif (IsType.isnum(current)): daylight = False if (which is True) else True return _Time(current, timezone, daylight) #---------------------------------------- # (7) elif (datelist is not None): date, how, N = datelist[:3] date, how, N = str(date), str(how), int(N) datein = date if ('/' in date): s, date = '/', date.split('/') elif ('-' in date): s, date = '-', date.split('-') #---------------------------------------- def Case1(date, how, N): datelist = [] if ('y' in how): year = int(date[0]) + np.arange(1, N) * int(how[:-1]) for y in year: datelist.append(str(y) + s + date[1] + s + date[2]) elif ('m' in how): m = int(date[1]) + np.arange(1, N) * int(how[:-1]) year = m / 12 month = m % 12 tf = month == 0 month[tf] = 12 year[tf] -= 1 for i in range(len(m)): m = str(month[i]) if (len(m) == 1): m = '0' + m datelist.append( str(int(date[0]) + year[i]) + s + m + s + date[2]) elif ('d' in how): ephemtime = date[0] + '/' + date[1] + '/' + date[2] if (':' not in ephemtime): ephemtime += ' 12:00:00' second = 24 * 3600 * np.arange(1, N) * int(how[:-1]) sec1970 = _Time(ephemtime) + second for i in range(len(sec1970)): ephemtime = _Time(sec1970[i]).split(' ')[0] if (s == '/'): datelist.append(ephemtime) else: ephemtime = ephemtime.split('/') datelist.append(ephemtime[0] + s + ephemtime[1] + s + ephemtime[2]) return datelist #---------------------------------------- if (how[-1] in 'dmy'): return [datein] + Case1(date, how, N) else: if ('M' in how): date[1] = how[1:-1] if (len(date[1]) == 1): date[1] = '0' + date[1] return [datein] + Case1(date, how[0] + '1y', N) elif ('D' in how): if (':' not in date[2]): date[2] = how[1:-1] else: date[2] = how[1:-1] + date[2].split(' ')[1] if (len(date[2]) == 1): date[2] = '0' + date[2] return [datein] + Case1(date, how[0] + '1m', N) #---------------------------------------- else: import time return time.time()
def _fmtTick(self, xy, which, fmt=None, sep=None, direction=None, length=None, width=None, color=None, left=True, right=False, bottom=True, top=False, ax=None): ''' Set Tick automatically Tick means the vertical lines on x-axis and parallel lines on y-axis xy: 'x' | 'y' | 'both' which: 'major' | 'minor' | 'both' sep: separation of ticks pair [0.1, 0.05] for [major, minor] one value 0.1 for major fmt: (1) 'str' like '%i', '%.3f', '%6.3f' (2) ==None: use plt.?ticks(sep[?][0], sep[?][1]) according to xy direction: 'in' | 'out' | 'inout' length, width, color: of ticks' size (length=8, width=1) left, right, bottom, top: True/False | 'on'/'off' Turn on/off the ticks ax: (1) can be =='cbar' | 'colorbar' ''' from matplotlib.ticker import MultipleLocator, FormatStrFormatter import numpy as np from jizhipy.Array import Asarray import matplotlib.pyplot as plt from jizhipy.Basic import IsType if (fmt is not None): try: fmt % 0 except: fmt = '%.1f' ax = self._gca(ax) #--------------------------------------------- if (IsType.iscbar(ax)): vmin, vmax = ax.get_clim() sep = Asarray(sep)[0] amin = int(vmin / sep) * sep amax = int(vmax / sep + 1) * sep ticks = np.arange(amin, amax + sep / 2., sep) ticks = ticks[(vmin <= ticks) * (ticks <= vmax)] ticklabels = [] for i in range(ticks.size): ticklabels.append(fmt % ticks[i]) ax.set_ticks(ticks) ax.set_ticklabels(ticklabels) return #--------------------------------------------- xy = self._gxy(xy) if (IsType.isstr(which)): which = str(which).lower() if (which == 'both'): which = 'majorminor' kwargs = { 'direction': direction, 'left': left, 'right': right, 'bottom': bottom, 'top': top } if (color is not None): kwargs['color'] = color if (length is not None): kwargs['length'] = length if (width is not None): kwargs['width'] = width #--------------------------------------------- if (sep is not None and fmt is None): dopltticks = True if (xy == 'x'): sep = [sep] if (xy == 'y'): sep = [None, sep] else: dopltticks = False #--------------------------------------------- if ('major' in which): if (not dopltticks): try: sep = Asarray(sep, float)[:2] loc = sep[0] loc = MultipleLocator(loc) fmt = FormatStrFormatter(fmt) except: pass if ('x' in xy): if (not dopltticks): try: ax.xaxis.set_major_locator(loc) ax.xaxis.set_major_formatter(fmt) except: pass else: ax.set_xticks(sep[0][0]) ax.set_xticklabels(sep[0][1]) ax.tick_params(axis='x', which='major', **kwargs) if ('y' in xy): if (not dopltticks): try: ax.yaxis.set_major_locator(loc) ax.yaxis.set_major_formatter(fmt) except: pass else: ax.set_xticks(sep[1][0]) ax.set_xticklabels(sep[1][1]) ax.tick_params(axis='y', which='major', **kwargs) #--------------------------------------------- if ('minor' in which): if (length is not None): kwargs['length'] *= 0.6 # if(width is not None): kwargs['width'] =width if (not dopltticks): try: sep = Asarray(sep, float)[:2] loc = sep[1] if ('major' in which) else sep[0] loc = MultipleLocator(loc) # fmt = FormatStrFormatter(fmt) except: pass if ('x' in xy): if (not dopltticks): try: ax.xaxis.set_minor_locator(loc) # ax.xaxis.set_minor_formatter(fmt) except: pass ax.tick_params(axis='x', which='minor', **kwargs) if ('y' in xy): if (not dopltticks): try: ax.yaxis.set_minor_locator(loc) # ax.yaxis.set_minor_formatter(fmt) # this will show values on minor axis, we don't want it except: pass ax.tick_params(axis='y', which='minor', **kwargs)
def BeamMap( pointRA=None, pointDec=None, dwl=None, freq=None, uniform=False, Bmap0=None, dtype='float32', nside=None ) : ''' pointRA, pointDec: [degree] Where does the antenna point to? default points to (RA, Dec) = (0, 0) dwl: [meter] d - diameter: for dish: one value w - width, l - length: for cylinder: (w,l) freq: [MHz] Used to get FWHM uniform: True | False If ==True: return =1 map Bmap0: Use this Bmap0 as the basic and rotate it to (pointRA, pointDec) ''' import healpy as hp import numpy as np from jizhipy.Array import Asarray from jizhipy.Basic import Raise from jizhipy.Transform import CoordTrans try : dtype = np.dtype(dtype) except : dtype = np.dtype(None) if (nside is not None) : nside = int(round(nside)) elif (Bmap0 is not None) : nside = hp.get_nside(Bmap0) else : Raise(Exception, 'nside = None') #-------------------------------------------------- if (uniform) : Bmap = np.ones(12*nside**2, dtype) if (Bmap0 is not None) : Bmap *= Bmap0[Bmap0.size/2] return Bmap #-------------------------------------------------- if (Bmap0 is not None) : nside0 = hp.get_nside(Bmap0) if (nside0 != nside) : Bmap0 = hp.ud_grade(nside, Bmap0) Bmap0 = Bmap0.astype(dtype) #-------------------------------------------------- else : n = hp.ang2pix(nside, np.pi/2, 0) Bmap0 = np.zeros(12*nside**2, dtype) Bmap0[n] = 10000 D = Asarray(dwl)[0] fwhm = 1.03 * 300/freq / D Bmap0 = hp.smoothing(Bmap0, fwhm, verbose=False) Bmap0[Bmap0<0] = 0 Bmap0 /= Bmap0.sum() #-------------------------------------------------- if (pointRA is None) : pointRA = 0 if (pointDec is None) : pointDec = 0 if (abs(pointRA)<1e-4 and abs(pointDec)<1e-4) : return Bmap0 #-------------------------------------------------- theta, phi = hp.pix2ang(nside, np.arange(12*nside**2)) theta, phi = CoordTrans.thetaphiRotation([theta, phi], az=pointRA, ay=-pointDec) n = hp.ang2pix(nside, theta, phi) Bmap = Bmap0[n] return Bmap
def WaveVector( self, thetaphi=None, widthshape=None, freq=None ) : ''' \vec{k} = 2pi/lambda * (xk, yk, zk) (xk, yk, zk) = thetaphi2xyz(thetaphi) (1) WaveVector( thetaphi, freq ) : set self.k, self.thetaphi, self.freq (2) WaveVector( thetaphi ) : set self.thetaphi self.thetaphi.shape = (2, N_sky-direction) self.k.shape = (3, N_sky-direction) Generate thetaphi matrix: thetaphi, widthshape: use one of them (1) give thetaphi argument: thetaphi: thetaphi.shape = (2, N_sky-direction) 2: (theta, phi) in [rad] direction of incident on celestial shpere Ground experiment: is half celestial sphere Space experiment: is all celestial sphere (2) give widthshape argument: widthNpix = (thetawidth, shape) thetawidth: 1 value/float in [rad] shape: N | (N,) | (N1, N2) Call Beam.ThetaPhiMatrix(thetawidth, Npix) freq: [MHz], observation frequency must be 1 value If given, calculate \vec{k} k.shape = (3, N_sky-direction) 3: (xk, yk, zk), NOTE THAT have *2pi/lambda N_sky-direction: direction of the incident light NOTE THAT (xk, yk, zk) and thetaphi must be in the SAME coordinate system of self.feedpos !!! ''' import numpy as np from jizhipy.Transform import CoordTrans from jizhipy.Astro import Beam from jizhipy.Basic import IsType from jizhipy.Array import Asarray # self.thetaphi if (thetaphi is not None) : thetaphi = np.array(thetaphi) if (thetaphi.size == 2) : thetaphi = thetaphi.reshape(2, 1) else : thetawidth, shape = widthshape shape = Asarray(shape, int).flatten() self.width = float(thetawidth) self.shape = tuple(shape) if (shape.size == 1) : theta = np.linspace(-thetawidth/2., thetawidth/2., shape[0]) thetaphi = np.array([theta, 0*theta]) else : thetaphi = Beam.ThetaPhiMatrix(thetawidth, shape.max()) n = shape.max() - shape.min() n1, n2 = n/2, n-n/2 if (shape[0] < shape[1]) : thetaphi = thetaphi[:,n1:-n2] elif (shape[0] > shape[1]) : thetaphi = thetaphi[:,:,n1:-n2] self.thetaphi = thetaphi #---------------------------------------- if (freq is not None) : freq = float(freq) k = 2*np.pi / (300./freq) * CoordTrans.thetaphi2xyz(self.thetaphi) self.k, self.freq = k, freq