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 ConfusionLimit( freq, fwhm=None, D=None, Q=3.35, Sobs=None ): ''' freq: MHz fwhm: rad D : meter Q : 3~5 Sobs: which flux density (Jy) do you want to observe Use to select k and gamma return: confusion limit sigma_c [Jy/beam] ''' import numpy as np from jizhipy.Basic import Raise if (Sobs is None) : Sobs = 1 if (Sobs <= 1e-4) : gamma, k = 1.57, 29500 elif (1e-4 < Sobs < 1e-3) : gamma, k = 2.23, 60.5 elif (Sobs > 1e-3) : gamma, k = 1.77, 1300 #-------------------------------------------------- if (fwhm is None and D is None) : Raise(Exception, 'One of [fwhm, D] must not be None') if (fwhm is None) : fwhm = 1.03*300/freq/D #-------------------------------------------------- sigmac1 = (Q**(3-gamma) * k * 1.133*(gamma-1)*fwhm**2 / (3-gamma))**(1./(gamma-1)) # http://www.cv.nrao.edu/course/astr534/Radiometers.html # At cm wavelengths, the rms confusion in a telescope beam with FHWM is observed to be sigmac2 = 1e-3 * 0.2 * (freq*1e-3)**(-0.7) * (fwhm*180/np.pi*60)**2 return np.array([sigmac1, sigmac2])
def SkyRegion(self, lon=None, lat=None, fwhm=None): ''' fwhm: [degree] fwhm==None: don't smooth the map lon, lat: [degree] lon: RA | l lat: Dec | b Must can be broadcast ''' import healpy as hp from jizhipy.Basic import Raise if (lon is not None and lat is not None): if (np.sum((lat < -90) + (lat > 90)) > 0): Raise(Exception, 'lat out of [-90, 90] degree') self.lonsky, self.latsky = lon, lat if (fwhm not in [0, None]): self.hpmap = np.array( hp.smoothing(self.hpmap, fwhm * np.pi / 180, verbose=False), self.hpmap.dtype) nside = hp.get_nside(self.hpmap) if (lon is not None and lat is not None): islist = False if (IsType.isnum(lon + lat)) else True lon, lat = lon + lat * 0, lon * 0 + lat # same shape lon %= 360 npix = hp.ang2pix(nside, np.pi / 2 - lat * np.pi / 180, lon * np.pi / 180) self.sky = self.hpmap[npix] if (not islist): self.sky = self.sky[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 Period(self, x=None, y=None, period=None, dmajor=None, fmt='%i', ax=None): ''' return [ticks, labels] x, y: list/ndarray is the x/y in plotting: plt.plot(x, y) period: one int value For o'clock, set period=24 hour For phase, set period=360 degree dmajor: Value of each major tick/label to be shown For o'clock, can set dmajor=12/6/... For phase, can set dmajpr=30/60/... ''' from jizhipy.Basic import Raise if (x is not None and y is not None): Raise( 'jizhipy.Plt.PeriodicAxes(): can NOT set x and y are NOT None at the same time' ) if (x is None and y is None): Raise('jizhipy.Plt.PeriodicAxes(): x = y = None') import matplotlib.pyplot as plt which = 'x' if (x is not None) else 'y' n = 1. * arr[0] / dmajor if (n == int(n)): n = int(n) else: n = 1 + int(n) x0 = n * dmajor x0 = np.arange(x0, arr[-1] + dmajor / 10., dmajor) x1 = list(x0 % period) for i in range(len(x1)): x1[i] = (fmt % x1[i]) ax0 = plt.gca() plt.sca(ax) if (which == 'x'): plt.xticks(x0, x1) elif (which == 'y'): plt.yticks(x0, x1) plt.sca(ax0) return [x0, x1]
def Linecolor(self, num, cmap='jet'): ''' Return is from Blue to Red num: (1) color name: in ['red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'purple', 'pink', 'brown', 'black', 'white'] return () of this color (2) int, number of colors: return () of colors (3) == 'png' : open 'jizhipy_Plt_LineColor.png' cmap: Use which cmap to generate the linecolor (1) None=>'gist_rainbow_r' | Name of cmap (see plt_color.cmap(None)) (2) <matplotlib.colors.LinearSegmentedColormap> (cmap instance) (3) cmap='my': use my cmap ''' from jizhipy.Basic import Raise, IsType, ShellCmd, Path import numpy as np #---------------------------------------- if (IsType.isstr(num)): num = num.lower() if ('png' in num): uname = ShellCmd('uname')[0].lower() figpath = Path.jizhipyPath( 'jizhipy_tool/jizhipy_Plt_Color_Linecolor.png') operate = 'eog ' if (uname == 'linux') else 'open ' ShellCmd(operate + figpath) return #---------------------------------------- if (num in self.mycolor.keys()): return self.mycolor[num] else: Raise(Exception, num + ' NOT in ' + str(self.mycolor.keys())) #---------------------------------------- if (IsType.isstr(cmap) and cmap == 'my'): _jet_data_my = np.array([(255, 0, 0), (255, 128, 0), (200, 200, 0), (0, 200, 0), (0, 250, 250), (0, 0, 255), (160, 0, 255)]) / 255. r, g, b = _jet_data_my.T from scipy.interpolate import interp1d r, g, b = np.array([r, g, b]) * ratio x = np.linspace(0, 1, r.size) fr = interp1d(x, r) fg = interp1d(x, g) fb = interp1d(x, b) x = np.linspace(0, 1, num) r, g, b = fr(x), fg(x), fb(x) color = [] for i in range(num): color += [(r[i], g[i], b[i])] return tuple(color) #---------------------------------------- else: cmap = self.Cmap(cmap) color = [cmap(x)[:3] for x in np.linspace(0., 1, num)] for i in range(len(color)): color[i] = (color[i][0], color[i][1], color[i][2]) return tuple(color)
def Save( self ) : ''' Save instance to .hdf5 ''' from jizhipy.Basic import Path, IsType, Raise import numpy as np import h5py self.outname = str(self.outname) if (self.outname[-5:] !='.hdf5') : self.outname += '.hdf5' Path.ExistsPath(self.outname, old=True) if (self.verbose) : print('jizhipy.ClassHdf5: Saveing to "'+self.outname+'"') fo = h5py.File(self.outname, 'w') if (self.value is None or self.keys is None): self.Values() fo['classinstance'] = str(type(self.classinstance)) for i in range(len(self.keys)) : if (self.values[i] is None) : fo[self.keys[i]] = '__None__' fo[self.keys[i]].attrs['type'] = 'is None, not str' #-------------------------------------------------- elif (IsType.isdtype(self.values[i])) : fo[self.keys[i]]=np.dtype(self.values[i]).name fo[self.keys[i]].attrs['type'] = 'numpy.dtype' #-------------------------------------------------- elif (IsType.ismatrix(self.values[i])) : fo[self.keys[i]] = np.array(self.values[i]) fo[self.keys[i]].attrs['type'] = 'numpy.matrix' #-------------------------------------------------- elif (IsType.ismaskedarray(self.values[i])) : fo[self.keys[i]] = self.values[i].data fo[self.keys[i]+'.mask'] = self.values[i].mask fo[self.keys[i]].attrs['type'] = 'numpy.MaskedArray .data' fo[self.keys[i]+'.mask'].attrs['type'] = 'numpy.MaskedArray .mask' #-------------------------------------------------- elif (IsType.isdict(self.values[i])) : self._OperaDict(self.values[i]) try : fo[self.keys[i]] =self.values[i].values() except : fo[self.keys[i]] = str(self.values[i].values()) fo[self.keys[i]+'.keys'] = self.values[i].keys() fo[self.keys[i]].attrs['type']='dict .values()' fo[self.keys[i]+'.keys'].attrs['type']='dict .keys()' self._OperaDict(self.values[i]) #-------------------------------------------------- else : # inside list and tuple, must not contain dict try : fo[self.keys[i]] = self.values[i] # convert to np.ndarray with same dtype, if contains string, will conver to string array except : strv = str([self.values[i]])[1:-1] Raise(Exception, "fo['"+self.keys[i]+"'] = "+strv) if (IsType.islist(self.values[i])) : fo[self.keys[i]].attrs['type'] = 'list' elif (IsType.istuple(self.values[i])) : fo[self.keys[i]].attrs['type'] = 'tuple' else : fo[self.keys[i]].attrs['type'] = 'numpy.array' #-------------------------------------------------- fo.flush() fo.close()
def AngleMean(self, angle1, angle2=None, axis=0): ''' return: angle.mean(axis) angle1: [rad] Any shape array angle2: (1) angle2=None: return the mean of angle1 (2) Can broadcast: angle1-angle2 return the mean of the difference of two angles (angle1-angle2) axis: average the angle along which axis ''' import numpy as np from jizhipy.Array import Asarray from jizhipy.Basic import Raise angle, axis = npfmt(angle1), int(axis) if (axis < 0): axis += len(angle.shape) if (axis > len(angle.shape)): Raise( Exception, 'axis=' + str(axis) + ' out of angle.shape=' + str(angle.shape)) if (angle2 is not None): angle2 = npfmt(angle2) try: angle2 = npfmt(angle2) + 0 * angle except: Raise( Exception, 'angle1.shape=' + str(angle.shape) + ', angle2.shape=' + str(angle2.shape) + ', can NOT broadcast') angle = np.exp(1j * angle) * np.exp(-1j * angle2) else: angle = np.exp(1j * angle) angle = angle.mean(axis) angle = np.angle(angle) angle = angle % (2 * np.pi) return angle
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 DopplerEffect( f0, df=None, dv=None ) : ''' In astronomy, when the object goes away/recede from us, it has a "positive" relative velocipy, while closing to use has a "negative" velocity +df => -dv +dv => -df (1) dv: [km/s] dv = vobs - vs Relative velocity of observer to the source (2) f0: [MHz] Original frequency of the source (3) f1: [MHz] Observed frequency by observer (4) df: [MHz] df = fobs - f0 Frequency differece of observed frequency to original frequency Case 1: DopplerEffect( f0, dv ), return df Case 2: DopplerEffect( f0, df ), return dv ''' import numpy as np from jizhipy.Array import Asarray from jizhipy.Basic import IsType, Raise from jizhipy.Astro import Const c = Const.c/1000. if (df is not None) : islist = False if(IsType.isnum(f0+df))else True f0, df = npfmt(f0), npfmt(df) f0 = f0 + df*0 df = f0*0 + df dv = -df * c / f0 if (not islist) : dv = dv[0] return dv elif (dv is not None) : islist = False if(IsType.isnum(f0+dv))else True f0, dv = npfmt(f0), npfmt(dv) f0 = f0 + dv*0 dv = f0*0 + dv df = -dv / c * f0 if (not islist) : df = df[0] return df else : Raise(Exception, 'df=None and dv=None')
def __Move(array, axis1, axis2): ''' My old function, insteaded by np.moveaxis() ''' shape = list(array.shape) s1, s2 = shape[axis1], shape[axis2] shape.pop(axis1) shape = shape[:axis2] + [s1] + shape[axis2:] a = np.zeros(shape, array.dtype) for i in range(s1): if (axis1 == 0): if (axis2 == 1): a[:, i] = array[i] elif (axis2 == 2): a[:, :, i] = array[i] elif (axis2 == 3): a[:, :, :, i] = array[i] elif (axis2 == 4): a[:, :, :, :, i] = array[i] elif (axis2 == 5): a[:, :, :, :, :, i] = array[i] elif (axis1 == 1): if (axis2 == 0): a[i] = array[:, i] elif (axis2 == 2): a[:, :, i] = array[:, i] elif (axis2 == 3): a[:, :, :, i] = array[:, i] elif (axis2 == 4): a[:, :, :, :, i] = array[:, i] elif (axis2 == 5): a[:, :, :, :, :, i] = array[:, i] elif (axis1 == 2): if (axis2 == 0): a[i] = array[:, :, i] elif (axis2 == 1): a[:, i] = array[:, :, i] elif (axis2 == 3): a[:, :, :, i] = array[:, :, i] elif (axis2 == 4): a[:, :, :, :, i] = array[:, :, i] elif (axis2 == 5): a[:, :, :, :, :, i] = array[:, :, i] elif (axis1 == 3): if (axis2 == 0): a[i] = array[:, :, :, i] elif (axis2 == 1): a[:, i] = array[:, :, :, i] elif (axis2 == 2): a[:, :, i] = array[:, :, :, i] elif (axis2 == 4): a[:, :, :, :, i] = array[:, :, :, i] elif (axis2 == 5): a[:, :, :, :, :, i] = array[:, :, :, i] elif (axis1 == 4): if (axis2 == 0): a[i] = array[:, :, :, :, i] elif (axis2 == 1): a[:, i] = array[:, :, :, :, i] elif (axis2 == 2): a[:, :, i] = array[:, :, :, :, i] elif (axis2 == 3): a[:, :, :, i] = array[:, :, :, :, i] elif (axis2 == 5): a[:, :, :, :, :, i] = array[:, :, :, :, i] elif (axis1 == 5): if (axis2 == 0): a[i] = array[:, :, :, :, :, i] elif (axis2 == 1): a[:, i] = array[:, :, :, :, :, i] elif (axis2 == 2): a[:, :, i] = array[:, :, :, :, :, i] elif (axis2 == 3): a[:, :, :, i] = array[:, :, :, :, :, i] elif (axis2 == 4): a[:, :, :, :, i] = array[:, :, :, :, :, i] else: Raise( Exception, 'ArrayAxis() can just handel 6-D array. For >= 7-D array, you can modify this function by yourself.' ) return a
def Distance( X, Y=None, metric='euclidean', p=2, pairwise=True ): ''' Y: if Y=None, return scipy.spatial.distance.pdist(X) pairwise: =True: use sklearn.metrics.pairwise_distances() or scipy.spatial.distance.cdist() the same as ((X[:,None]-Y[None,:])**2).sum(-1)**0.5 =False: ((X-Y)**2).sum(-1)**0.5 metric: ['braycurtis', 'canberra', 'chebyshev', 'cityblock', 'correlation', 'cosine', 'dice', 'euclidean', 'hamming', 'jaccard', 'kulsinski', 'mahalanobis', 'matching', 'minkowski', 'rogerstanimoto', 'russellrao', 'seuclidean', 'sokalmichener', 'sokalsneath', 'sqeuclidean', 'yule'] ''' import numpy as np import scipy.spatial from jizhipy.Basic import Raise #import sklearn.metrics X = np.array(X) if (Y is None): D = scipy.spatial.distance.pdist(X, metric=metric, p=p) return D Y = np.array(Y) if (not pairwise): # Broadcase X = X + 0*Y Y = Y + 0*X shape = X.shape if (X.shape != Y.shape): Raise(Exception, 'pairwise=False, must need X.shape==Y.shape, but now X.shape='+str(X.shape)+', Y.shape='+str(Y.shape)) if (len(shape) !=2): X = X.reshape(int(np.prod(shape[:-1])), shape[-1]) Y = Y.reshape(int(np.prod(shape[:-1])), shape[-1]) D, n, step = [], 0, 10000 while (n < len(X)): d = scipy.spatial.distance.cdist(X[n:n+step], Y[n:n+step], metric=metric, p=p) D.append(np.diag(d)) n += step D = np.concatenate(D) if (len(shape) !=2): D = D.reshape(shape[:-1]) return D else: D = scipy.spatial.distance.cdist(X, Y, metric=metric, p=p) return D
def Sample(array, axis, per=None, size=None): ''' Reduce the size of array array: Any shape, any dtype int/float/complex ndarray MaskedArray axis: Sampling along which axis? per, size: Use one of them (1) per, size=None: Sampling every per ponts (2) per=None, size: Sampled array.shape[axis] == size ''' import numpy as np from jizhipy.Basic import IsType, Raise from jizhipy.Array import ArrayAxis if (not IsType.isndarray(array) and not IsType.isnmaskedarray(array) and not IsType.ismatrix(array)): array = np.array(array) if (len(array.shape) == 1): axis = 0 elif (axis < 0): axis += len(array.shape) if (axis >= len(array.shape)): Raise(Exception, 'axis=' + str(axis) + ' out of array.shape=' + str(array.shape)) #---------------------------------------- if (per is None and size is None): return array #---------------------------------------- elif (per is None and array.shape[axis] >= size): return Smooth(array, axis, reduceshape=size) #---------------------------------------- elif (per is not None): per += 0 n = np.arange(0, array.shape[axis], per) else: size += 0 n = np.linspace(0, array.shape[axis] - 1, size) n = n.astype(int) #---------------------------------------- array = ArrayAxis(array, axis, 0) array = array[n] array = ArrayAxis(array, 0, axis) return array
def SetLevel(self, level, **kwargs): ''' self.level = 'DEBUG/INFO/...' self._level = 10/20/... Parameters ---------- level: [str] or [int] ''' import logging from jizhipy.Basic import Raise, IsType if (level is True): level ='INFO' elif (level is None): level =logging.getLogger().level elif (level ==0): level = False elif (level ==1): level = True if (not IsType.isnum(level)): if (level is not False): level, level0 = str(level).upper(), level if (level =='CRITICAL'): _level = logging.CRITICAL elif (level =='ERROR'): _level = logging.ERROR elif (level =='WARNING'): _level = logging.WARNING elif (level =='DEBUG'): _level = logging.DEBUG elif (level =='INFO'): _level = logging.INFO elif (level =='NOTSET'): _level = logging.NOTSET else: Raise(Exception, "level='"+str(level0)+"' not in ['CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG', 'NOTSET']") else: _level = False #---------------------------------------- else: if ( level<= 0): level, _level= 'NOTSET' , 0 elif ( 0<level<=10): level, _level= 'DEBUG' , 10 elif (10<level<=20): level, _level= 'INFO' , 20 elif (20<level<=30): level, _level= 'WARNING', 30 elif (30<level<=40): level, _level= 'ERROR' , 40 elif (40<level<=50): level, _level= 'CRITICAL',50 elif (50<level ): level, _level= False, False #---------------------------------------- if ('verbose' in kwargs.keys() and kwargs['verbose'] is True): pass else: self.level, self._level = level, _level return (level, _level)
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 _UnitCheck(self, unitin=None, unitout=None): ''' return [unitin, unitout, k_in2out] ''' from jizhipy.Basic import Raise doraise = [] if (unitin is None): try: unitin = self.unitin except: pass else: unitin = str(unitin) if (unitin.lower() == 'k'): unitin = 'K' elif (unitin.lower() == 'mk'): unitin = 'mK' elif (unitin.lower() == 'uk'): unitin = 'uK' else: doraise.append('in') #-------------------------------------------------- if (unitout is None): try: unitout = self.unit except: pass else: unitout = str(unitout) if (unitout.lower() == 'k'): unitout = 'K' elif (unitout.lower() == 'mk'): unitout = 'mK' elif (unitout.lower() == 'uk'): unitout = 'uK' else: doraise.append('out') #-------------------------------------------------- printstr = '' if ('in' in doraise): printstr += "unitin = '" + unitinin + "', " if ('out' in doraise): printstr += "unitout = '" + unitout + "', " if (printstr != ''): Raise(Exception, printstr[:-2] + " not in ['K', 'mK', 'uK']") #-------------------------------------------------- if (unitin is None or unitout is None): k_in2out = 1 elif (unitin == 'K' and unitout == 'K'): k_in2out = 1 elif (unitin == 'K' and unitout == 'mK'): k_in2out = 1e3 elif (unitin == 'K' and unitout == 'uK'): k_in2out = 1e6 elif (unitin == 'mK' and unitout == 'K'): k_in2out = 1e-3 elif (unitin == 'mK' and unitout == 'mK'): k_in2out = 1 elif (unitin == 'mK' and unitout == 'uK'): k_in2out = 1e3 elif (unitin == 'uK' and unitout == 'K'): k_in2out = 1e-6 elif (unitin == 'uK' and unitout == 'mK'): k_in2out = 1e-3 elif (unitin == 'uK' and unitout == 'uK'): k_in2out = 1 return [unitin, unitout, k_in2out]
def Pinv(array, leastsq=False): ''' return: pseudo-inverse (np.ndarray format) ''' import scipy.linalg as spla from jizhipy.Basic import Raise import numpy as np if (len(array.shape) != 2): Raise( Exception, 'jizhipy.Pinv(): len(array.shape) = ' + str(len(array.shape)) + ' != 2') if (not leastsq): return spla.pinv2(array) else: At = np.matrix(np.conj(array.T)) b = At * np.matrix(array) b = np.matrix(spla.inv(b)) * At return b
def _OrderingCheck(self, orderingin=None, orderingout=None): ''' ''' from jizhipy.Basic import Raise doraise = [] if (orderingin is None): try: orderingin = self.orderingin except: pass else: orderingin = str(orderingin) if (orderingin.upper() not in ['RING', 'NESTED', 'NEST']): doraise.append('in') else: orderingin = orderingin.upper() if ('NEST' in orderingin): orderingin = 'NESTED' #-------------------------------------------------- if (orderingout is None): try: orderingout = self.ordering except: pass else: orderingout = str(orderingout) if (orderingout.upper() not in ['RING', 'NESTED', 'NEST']): doraise.append('out') else: orderingout = orderingout.upper() if ('NEST' in orderingout): orderingout = 'NESTED' #-------------------------------------------------- printstr = '' if ('in' in doraise): printstr += "orderingin = '" + orderingin + "', " if ('out' in doraise): printstr += "orderingout = '" + orderingout + "', " if (printstr != ''): Raise(Exception, printstr[:-2] + " not in ['RING', 'NESTED']") #-------------------------------------------------- if (orderingin is None): nestin = None elif (orderingin == 'RING'): nestin = False else: nestin = True if (orderingout is None): nestout = None elif (orderingout == 'RING'): nestout = False else: nestout = True return [orderingin, nestin, orderingout, nestout]
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 _GaussianFilter(per, times, method=2): ''' a(n) = S(n) - S(n-1) S(n) = a(n) + a(n-1) + a(n-2) + ... + a(2) + a(1) per: per >=2, can be odd or even times: times >=1 method: method = 1 : non-normalized method = 2 : normalized: 1/(sigma*(2*pi)**0.5) return: gaussianfilter.size = (per-1) * times + 1 ''' import numpy as np from jizhipy.Basic import Raise per, times = np.array([per, times]).round().astype(int) if (per < 2 or times < 1): Raise( Warning, 'GaussianFilter(per, times), per=' + str(per) + ', times=' + str(times) + ', return gaussianfilter=[1]') return np.array([1]) if (method == 1): a0 = np.ones(per) elif (method == 2): a0 = np.ones(per) / per for n in range(2, times + 1): n1 = (per - 1) * n + 1 a1 = np.zeros([per, n1]) for i in range(per): a1[i, i:i + a0.size] = a0 if (method == 1): a0 = a1.sum(0) elif (method == 2): a0 = a1.sum(0) / per # if (method == 1) : gaussianfilter = a0 / (1.*per)**times gaussianfilter = a0 std = 1. / ((2 * np.pi)**0.5 * gaussianfilter.max()) return [gaussianfilter, std]
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 _CoordsysCheck(self, coordsysin=None, coordsysout=None): ''' ''' from jizhipy.Basic import Raise doraise = [] if (coordsysin is None): try: coordsysin = self.coordsysin except: pass else: coordsysin = str(coordsysin) if (coordsysin.lower() not in ['galactic', 'equatorial']): doraise.append('in') else: coordsysin = coordsysin.lower() #-------------------------------------------------- if (coordsysout is None): try: coordsysout = self.coordsys except: pass else: coordsysout = str(coordsysout) if (coordsysout.lower() not in ['galactic', 'equatorial']): doraise.append('out') else: coordsysout = coordsysout.lower() #-------------------------------------------------- printstr = '' if ('in' in doraise): printstr += "coordsysin = '" + coordsysin + "', " if ('out' in doraise): printstr += "coordsysout = '" + coordsysout + "', " if (printstr != ''): Raise(Exception, printstr[:-2] + " not in ['galactic', 'equatorial']") else: return [coordsysin, coordsysout]
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 _SigmaR( self, dimension, std_a, sigma_a, std_b, sigma_g=None, r=None ) : ''' std_a: standard deviation of data a: a.std() sigma_a: unit: pixel resolution of the input data sigma_in = fwhm_in / (8 ln2)**0.5 *** a can be signal convolved by beam, sigma_a~sigma_beam, OR pure noise, sigma_a=0=None std_b: standard deviation of Gaussian-Noise b: b.std() *** b must be pure noise, therefore NOT sigma_b *** r is signal to noise ratio (SNR) (case 1) sigma_g != None and r == None: use sigma_g to smooth a then obtain a1 use sigma_g to smooth b then obtain b1 return: SNR=a1.std()/b1.std() (case 2) r != None and sigma_g == None: want r = a1.std()/b1.std() need how large sigma_g (return) (case 3) r == None and sigma_g == None: return [r_limit, sigma_g_limit] ''' import numpy as np from jizhipy.Basic import Raise # case 1 if (sigma_g is not None) : stda = self._ReduceSTD(dimension, std_a, sigma_a, sigma_g) stdb = self._ReduceSTD(dimension, std_b, None, sigma_g) r = stda / stdb return r #---------------------------------------- else : def wei3( x ) : x = ('%.9f' % x).split('.') if (len(x[0]) >= 3) : x = x[0] elif (len(x[0]) == 2) : x = x[0]+'.'+x[1][0] else : if (x[0] != '0') : x = x[0]+'.'+x[1][:2] else : for i in range(len(x[1])) : if (x[1][i] != '0') : break x = '0.' + i*'0' + x[1][i:i+3] return x #---------------------------------------- if (str(dimension).lower() == '1d') : n0 = (np.pi * sigma_a)**0.5 * std_a / std_b n0 *= 0.9 # r_limit relim = True if(r is None)else False if (r is None) : r = n0 elif (r > n0) : n0str = wei3(n0) Raise(Warning, 'input n='+('%.1f' % n)+' reaches n_limit='+n0str, top=True) r = n0 up = r**4 * std_b**4 * sigma_a**2 down0 = np.pi**2 * std_a**4 * sigma_a**2 down1 = r**4 * std_b**4 sigma_g = (up / (down0 - down1))**0.5 if (relim) : return [n0, sigma_g] else : return sigma_g #---------------------------------------- elif (str(dimension).lower() == '2d') : n0 = 2 * np.pi**0.5 * sigma_a * std_a / std_b n0 *= 0.9 relim = True if(r is None)else False if (r is None) : r = n0 elif (r > n0) : n0str = wei3(n0) Raise(Warning, 'input n='+('%.1f' % n)+' reaches n_limit='+n0str, top=True) r = n0 up = r**2 * std_b**2 * sigma_a**2 down0 = 4*np.pi * std_a**2 * sigma_a**2 down1 = r**2 * std_b**2 sigma_g = (up / (down0 - down1))**0.5 if (relim) : return [n0, sigma_g] else : return sigma_g
def LogNormalValue( self, x, mean, std ) : from jizhipy.Basic import Raise import numpy as np if (x.min() < 0) : Raise(Exception, 'x.min() < 0') y = 1/(2*np.pi)**0.5 /std /x *np.exp(-(np.log(x)-mean)**2 /(2*std**2)) return y
def ConjugateSymmetrize( array ) : ''' This function is used to symmetrize the array which will be used to do the inverse Fourier transform. array is a N dimension array (real matrix or complex matrix), N can just be 1,2,3 ''' from jizhipy.Basic import Raise shape = np.array(array.shape) % 2 if (shape.max() != 0) : Raise(Exception, 'Length of each dimension of input array must be even') func = len(array.shape) if (func > 3) : Raise(Exception, 'dimension of array must be 1D or 2D or 3D') def conjugate_symmetrize_axis( a ) : a = np.append(a[:a.size/2+1], a[1:a.size/2][::-1].conjugate()) a[a.size/2] = 0 return a def conjugate_symmetrize_plane( a ) : # x and y axis x = a[0,:] y = a[:,0] a[0,:] = conjugate_symmetrize_axis( x ) a[:,0] = conjugate_symmetrize_axis( y ) # xy plane exclude x and y axis xy = a[1:y.size/2+1,1:] a[1:,1:] = np.append(xy, xy[:-1][::-1,::-1].conjugate(), 0) # vertical medium axis axisp = a[y.size/2] a[y.size/2] = conjugate_symmetrize_axis( axisp ) return a def conjugate_symmetrize_solid( a ) : # x, y, z axis x = a[0,0,:] y = a[0,:,0] z = a[:,0,0] a[0,0,:] = conjugate_symmetrize_axis( x ) a[0,:,0] = conjugate_symmetrize_axis( y ) a[:,0,0] = conjugate_symmetrize_axis( z ) # xy, xz, yz planes xy = a[0] xz = a[:,0] yz = a[:,:,0] a[0] = conjugate_symmetrize_plane( xy ) a[:,0] = conjugate_symmetrize_plane( xz ) a[:,:,0] = conjugate_symmetrize_plane( yz ) # solid xyz = a[1:len(a)/2+1,1:,1:] a[1:,1:,1:] = np.append( xyz, xyz[:-1][::-1,::-1,::-1].conjugate(), 0 ) # medium plane mplane = a[len(a)/2] a[len(a)/2] = conjugate_symmetrize_plane( mplane ) return a if ( func == 1 ) : array = conjugate_symmetrize_axis( array ) array[0] = 0 elif ( func == 2 ) : array = conjugate_symmetrize_plane( array ) array[0,0] = 0 elif ( func == 3 ) : array = conjugate_symmetrize_solid( array ) array[0,0,0] = 0 return array
def RandomShuffle(self, a, axis=None, kFold=None): ''' Parameters ---------- a: (1) int: a = range(a) (2) ndarray with any shape, any dtype axis: [int], shuffle along which axis? axis=None: shuffle a.flatten() (all elements) kFold: None: don't split =[int]: split into xx pieces except (a is n-D array and axis=None) Returns ---------- randomly shuffle all elements ''' if (axis is not None): axis = int(axis) if (kFold is not None): kFold = int(kFold) import numpy as np from jizhipy.Basic import IsType, Raise if (IsType.isint(a)): a = np.arange(a) else: a = np.array(a) shape = a.shape if (len(shape) == 1): axis = None if (axis is not None): if (axis < 0): axis += len(shape) if (axis >= len(shape)): Raise( Exception, 'a.shape=' + str(shape) + ', but axis=' + str(axis) + ' exceeds the dimension') b = np.arange(shape[axis]) else: b = np.arange(a.size) if (len(shape) > 1 and axis is None and kFold is not None): Raise( Exception, 'when a.shape=' + str(shape) + ' is n-D array and axis=None, can NOT use kFold') #---------------------------------------- b = np.random.random(b.size) + 1j * b b = np.sort(b).imag.astype(int) #---------------------------------------- if (kFold is None): b = [b] else: c, n = [], np.linspace(0, len(b), kFold + 1).astype(int) for i in range(len(n) - 1): c.append(b[n[i]:n[i + 1]]) n = np.random.random(len(c)) + 1j * np.arange(len(c)) n = np.sort(n).imag.astype(int) b = [] for i in n: b.append(c[i]) #---------------------------------------- if (len(shape) > 1 and axis is None): return a.flatten()[b[0]].reshape(shape) if (len(shape) > 1 and axis is not None and axis != 0): tranaxis = range(len(shape)) tranaxis[0], tranaxis[axis] = axis, 0 a = np.transpose(a, tranaxis) for i in range(len(b)): b[i] = a[b[i]] if (axis is not None and axis != 0): b[i] = np.transpose(b[i], tranaxis) if (kFold is None): b = b[0] return b
def _setTick(self, xy, which=None, fmt=None, direction=None, length=None, width=None, color=None, left=True, right=False, bottom=True, top=False, ax=None): ''' Set Tick by hand plt.xticks(), plt.yticks() xy: 'x' | 'y' | 'both' which: (case 1): list to be shown / xylabel ndarray (case 2): ==None: return xlabel or/and ylabel fmt: 'str' like '%i', '%.3f', '%6.3f' 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 ''' import matplotlib.pyplot as plt from jizhipy.Basic import IsType, Raise import numpy as np from jizhipy.Optimize import Sample, Interp1d xy = self._gxy(xy) ax = self._gca(ax) ax0 = plt.gca() plt.sca(ax) if (len(ax.lines) != 0): xdata, ydata = ax.lines[-1].get_data() else: xdata = ax.collections[-1]._coordinates[0, :, 0] ydata = ax.collections[-1]._coordinates[:, 0, 1] if (which is None): xydata = [] if ('x' in xy): xydata.append(xdata.copy()) if ('y' in xy): xydata.append(ydata.copy()) if (len(xydata) == 1): xydata = xydata[0] return xydata #---------------------------------------- which = np.array(which) if (len(which.shape) == 1): which = which[None, :] if ('xy' in xy and len(which) == 1): xy = 'x' #---------------------------------------- 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 ('x' in xy): loc = plt.xticks()[0] xlabel = which[0] if (loc.size != xlabel.size): if (xdata.size != xlabel.size): # Raise(Exception, 'xdata.size='+str(xdata.size)+' != xlabel.size='+str(xlabel.size)) xlabel = Sample(xlabel, 0, size=xdata.size) n = Interp1d(xdata, np.arange(xdata.size), loc) xlabel = Interp1d(np.arange(xlabel.size), xlabel, n) if (fmt is not None): try: fmt % 0 except: fmt = '%.1f' xlabel = list(xlabel) for i in range(len(xlabel)): xlabel[i] = fmt % xlabel[i] plt.xticks(loc, xlabel) ax.tick_params(axis='x', which='major', **kwargs) #---------------------------------------- if ('y' in xy): loc = plt.yticks()[0] ylabel = which[-1] if (loc.size != ylabel.size): if (ydata.size != ylabel.size): Raise( Exception, 'ydata.size=' + str(ydata.size) + ' != ylabel.size=' + str(ylabel.size)) ylabel = Sample(ylabel, 0, size=ydata.size) n = Interp1d(ydata, np.arange(ydata.size), loc) ylabel = Interp1d(np.arange(ylabel.size), ylabel, n) if (fmt is not None): try: fmt % 0 except: fmt = '%.1f' ylabel = list(ylabel) for i in range(len(ylabel)): ylabel[i] = fmt % ylabel[i] plt.yticks(loc, ylabel) ax.tick_params(axis='y', which='major', **kwargs) plt.sca(ax0)
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 SyntheticBeam(self, comm=None, per=30, verbose=False): ''' per: to speed up the calculate SyntheticBeam = |\sum_{i=1}^{Nfeed} \exp{1j \vec{k} \vec{r}_i} B_i }|^2 self.k.shape = (3, N_incident_direction) self.feedpos.shape = (3, Nfeed) self.beam.shape = (Nfeed, N_incident_direction) kr.shape = (Nfeed, N_incident_direction) ''' import numpy as np from jizhipy.Process import ProgressBar, MPI from jizhipy.Basic import Raise, IsType if (comm is not None) : rank, Nprocess, host, info = MPI.Comm(comm) else : rank = 0 #---------------------------------------- onebeam = True if ('beam' not in self.__dict__.keys() or IsType.isnum(self.beam)) : beam = 1 elif (len(self.beam)==1) : beam = self.beam[0] else : onebeam = False #---------------------------------------- #---------------------------------------- try : R, isbl = self.feedpos+0, False except : try : R, isbl = self.baseline+0, True except : Raise(Exception, 'self.feedpos and self.baseline are NOT valid') k = self.k[:,None] R = R.reshape( R.shape + (1,)*len(k.shape[2:]) ) #---------------------------------------- if (isbl) : Bsyn_sqrt = np.zeros(k.shape[2:]) else : Bsyn_sqrt = np.zeros(k.shape[2:], complex) n = np.arange(0, R.shape[1], per) n = np.append(n, [R.shape[1]]) Nfor = n.size - 1 if (verbose) : progressbar = ProgressBar('jizhipy.Beam.SyntheticBeam:', Nfor) for i in range(Nfor) : if (verbose) : progressbar.Progress() n1, n2 = n[i], n[i+1] kr = (k*R[:,n1:n2]).sum(0) if (not isbl) : if (onebeam) : Bsyn_sqrt_i = np.exp(1j*kr) else: Bsyn_sqrt_i = np.exp(1j*kr) *beam[n1:n2] else : if (onebeam) : Bsyn_sqrt_i = 2*np.cos(kr) else : Bsyn_sqrt_i = 2*np.cos(kr) *beam[n1:n2] Bsyn_sqrt += Bsyn_sqrt_i.sum(0) if (onebeam) : Bsyn_sqrt *= beam #---------------------------------------- if (comm is None) : if (not isbl) : self.synbeam = abs(Bsyn_sqrt)**2 else : self.synbeam = Bsyn_sqrt self.synbeam /= self.synbeam.max() # normalsized return #---------------------------------------- Bsyn_sqrt = MPI.Gather(Bsyn_sqrt[None,:], comm, 0, 0) if (rank == 0) : Bsyn_sqrt = Bsyn_sqrt.sum(0) if (not isbl) : self.synbeam = abs(Bsyn_sqrt)**2 else : self.synbeam = Bsyn_sqrt self.synbeam /= self.synbeam.max() else : self.synbeam = None self.synbeam = MPI.Bcast(self.synbeam, comm, 0) return self.synbeam