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 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
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 RandomVariable(self, shape, x, pdf, norm=True): ''' Invert operation of ProbabilityDensity() Provide probability density, return random variable shape: The shape of generated random variable pdf==fx, norm: fx: isfunc | isndarray (1) isfunc: fx = def f(x), f(x) is the probability density function (2) isndarray: fx.size = x.size norm: True | False fx must be 1. fx >= 0 2. \int_{-\inf}^{+\inf} fx dx = 1 Only if norm=False, not normal it, otherwise, always normal it. x: isndarray, must be 1D Use fx and x to obtain the inverse function of the cumulative distribution function, x = F^{-1}(y) return: 1D ndarray with shape, random variable ''' import numpy as np from jizhipy.Array import Asarray from jizhipy.Basic import IsType, Raise from jizhipy.Optimize import Interp1d #--------------------------------------------- x = Asarray(x).flatten() if (not IsType.isfunc(fx)): fx = Asarray(fx).flatten() if (x.size != fx.size): Raise(Exception, 'fx.size=' + str(fx.size) + ' != x.size=' + str(x.size)) else: fx = fx(x) fx *= 57533.4 #--------------------------------------------- # sort x from small to large x = np.sort(x + 1j * fx) fx, x = x.imag, x.real #--------------------------------------------- dx = x[1:] - x[:-1] dx = np.append(dx, dx[-1:]) #--------------------------------------------- # Normal fx if (norm is not False): fxmin = fx.min() if (fxmin < 0): fx -= fxmin fx /= (fx.sum() * dx) #--------------------------------------------- # Cumulative distribution function fx = fx.cumsum() * dx #--------------------------------------------- # Inverse function F_1 = Interp1d(fx, x, None) #--------------------------------------------- # Uniform random with shape x = np.random.random(shape) #--------------------------------------------- # Random variable with f(x) b = F_1(x) return b
def Bins(self, array, nbins, weight=None, wmax2a=None, nsigma=None): ''' nbins: (1) ==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 (2) ==int_number: ** Then use weight and wmax2a Give the total number of the bins, in this case, x.size=bins+1, xc.size=bins nsigma: float | None When generate the bins, won't use the whole range of array, set nsigma, will use |array| <= nsigma*array.std() weight: ** Use this only when bins==int_number 'G?', 'K?' | None | ndarray with size=bins (1) ==None: each bin has the same weight => uniform bins (2) ==ndarray: give weights to each bins (3) =='G?': '?' should be an value, for example, 'G1', 'G2.3', 'G5.4', 'G12', use Gaussian weight, and obtain it from np.linspace(-?, +?, bins) =='K?': '?' should be an value, for example, 'K1', 'K2.3', 'K5.4', 'K12', use modified Bessel functions of the second kind, and obtain it from np.linspace(-?, +?, bins) wmax2a: Use it when weight is not None float | None (1) ==float: weight.max() corresponds to which bin, the bin which value wmax2a is in ''' import numpy as np from jizhipy.Basic import IsType from jizhipy.Array import Invalid, Asarray from jizhipy.Math import Gaussian #--------------------------------------------- array = Asarray(array) if (nsigma is not None): mean, sigma = array.mean(), array.std() array = array[(mean - nsigma * sigma <= array) * (array <= mean + nsigma * sigma)] amin, amax = array.min(), array.max() #--------------------------------------------- if (Asarray(nbins).size == 3): nbins, bmin, bmax = nbins else: bmin, bmax = amin, amax #--------------------------------------------- # First uniform bins bins = np.linspace(bmin, bmax, nbins + 1) bstep = bins[1] - bins[0] #--------------------------------------------- # weight if (weight is not None): if (IsType.isstr(weight)): w, v = str(weight[0]).lower(), abs(float(weight[1:])) if (v == 0): v = 1 x = np.linspace(-v, v, nbins) if (w == 'k'): import scipy.special as spsp weight = spsp.k0(abs(x)) weight = Invalid(weight) weight.data[weight.mask] = 2 * weight.max() else: # Gaussian weight = Gaussian.GaussianValue1(x, 0, 0.4) #-------------------- # wmax2a if (wmax2a is not None): nmax = int(round(np.where(weight == weight.max())[0].mean())) nb = abs(bins - wmax2a) nb = np.where(nb == nb.min())[0][0] for i in range(bins.size - 1): if (bins[i] <= wmax2a < bins[i + 1]): nb = i break d = abs(nmax - nb) if (nmax < nb): weight = np.append(weight[-d:], weight[:-d]) elif (nmax > nb): weight = np.append(weight[d:], weight[:d]) #-------------------- weight = weight[:nbins] if (weight.size < nbins): weight = np.concatenate([weight] + (nbins - weight.size) * [weight[-1:]]) weight = weight.max() - weight + weight.min() weight /= weight.sum() weight = weight.cumsum() #-------------------- c = bins[0] + (bmax - bmin) * weight bins[1:-1] = c[:-1] #-------------------- bins = list(bins) n = 1 while (n < len(bins)): if (bins[n] - bins[n - 1] < bstep / 20.): bins = bins[:n] + bins[n + 1:] else: n += 1 bins = Asarray(bins) #--------------------------------------------- return bins
def LM2Index(self, which, lmax, l, m, order=None, symmetry=True): ''' Usage: See MapMaking.py lmax: int, must be one l, m: Can be one or 1D array order: '2D': return 2D matrix with np.nan None: remove np.nan and return 1D(flatten) ndarray 'l': return 1D array ordered by l from small to large 'm': return 1D array ordered by m from small to large 'i': return 1D array ordered by index from small to large which == 'Alm' : if (self.fgsymm) : index = (m*lmax - m*(m-1)/2 + l) else : if (m >= 0) : index = (m*lmax - m*(m-1)/2 + l) else : m = -m index = (m-1)*self.lmax-m*(m-1)/2+l+self.offnm-1 which == 'AlmDS' : index = l*(l+1) + m return: [index, morder, lorder] '2D': index.shape=(l.size, m.size), lorder=l[:,None], morder=m[None,:] Others: 1D with index.size==lorder.size==morder.size ''' import numpy as np from jizhipy.Array import Asarray, Invalid, Sort from jizhipy.Basic import Raise l, m = Asarray(l).flatten(), Asarray(m).flatten() if (l[l > lmax].size > 0): Raise( Exception, 'l=[' + str(l.min()) + ', ..., ' + str(l.max()) + '] > lmax=' + str(lmax)) if (abs(m)[abs(m) > lmax].size > 0): Raise( Exception, 'm=[' + str(m.min()) + ', ..., ' + str(m.max()) + '] > lmax=' + str(lmax)) #-------------------------------------------------- #-------------------------------------------------- if (str(which).lower() == 'alm'): if (symmetry): index = lmax * m[None, :] - m[None, :] * (m[None, :] - 1) / 2. + l[:, None] else: morder = np.append( np.arange(m.size)[m >= 0], np.arange(m.size)[m < 0]) mpos, mneg = m[m >= 0], abs(m[m < 0]) indexpos = lmax * mpos[None, :] - mpos[None, :] * ( mpos[None, :] - 1) / 2. + l[:, None] indexneg = lmax * (mneg[None, :] - 1) - mneg[None, :] * ( mneg[None, :] - 1) / 2. + l[:, None] + self.offnm - 1 index = np.append(indexpos, indexneg, 1) indexpos = indexneg = mpos = mneg = 0 #@ index = index[:, morder] #-------------------------------------------------- elif (str(which).lower() == 'almds'): index = l[:, None] * (l[:, None] + 1) + m[None, :] + 0. #-------------------------------------------------- #-------------------------------------------------- for i in range(l.size): index[i, abs(m) > l[i]] = np.nan #-------------------------------------------------- if (order == '2D'): return [index, m[None, :], l[:, None]] #-------------------------------------------------- lorder = (index * 0 + 1) * l[:, None] morder = (index * 0 + 1) * m[None, :] lorder = Invalid(lorder, False).astype(int) morder = Invalid(morder, False).astype(int) index = Invalid(index, False).astype(int) #-------------------------------------------------- if (order is not None): if (str(order).lower() == 'i'): along = '[0,:]' elif (str(order).lower() == 'l'): along = '[1,:]' elif (str(order).lower() == 'm'): along = '[2,:]' index = np.array([index, lorder, morder]) index, lorder, morder = Sort(index, along) if (index.size == 1): index, lorder, morder = index[0], lorder[0], morder[0] return [index, morder, lorder]
def ColorfulLine( x, y, z=None, lcarray=None, edge=None, ax=None, **kwargs ) : ''' plot Multicolor line return ax z: for 3D line lcarray: color from blue to red, corresponding to lcarray.min() to lcarray.max() In principle, lcarray can be any array from small to large. In practice, generally set lcarray=x or lcarray=y or lcarray=z edge: int Split lcarray(also from blue to red) into 'edge' pieces, each piece has one color lcarray + edge: create color map **kwargs: Can set: marker, ms, mec, ls, lw, ...... ** mec=True: mec == color of marker | mec=False: maybe 'k' or marker color dependent on matplotlib setting Example: x = np.linspace(0, 8*np.pi, 1000) y = np.sin(x) ColorfulLine(x, y, lcarray=x, edge=10, marker='o') ''' import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np from jizhipy.Array import Asarray from jizhipy.Basic import Raise, IsType if (lcarray is None) : lcarray = x lcarray = Asarray(lcarray) #--------------------------------------------- if (edge is None) : edge = 100 if (IsType.isint(edge)) : if(edge >lcarray.size*4/5): edge=lcarray.size*4/5 edge = np.linspace(lcarray.min(), lcarray.max(), edge) # Check edge edge2 = [edge[0]] for i in range(len(edge)-1) : tf = (edge[i]<=lcarray)*(lcarray<=edge[i+1]) n = lcarray[tf].size if (n >= 2) : edge2.append(edge[i+1]) if (len(edge2) == 1) : edge2.append(lcarray.size) edge = Asarray(edge2) #--------------------------------------------- color = plt_color.line(len(edge)-1, 'my') if ('color' in kwargs) : kwargs.pop('color') if ('c' in kwargs) : kwargs.pop('c') x, y = Asarray(x), Asarray(y) if (lcarray.shape != x.shape) : Raise(Exception, 'jizhipy.Plot.ColorfulLine(): lcarray.shape='+str(lcarray.shape)+' != x.shape='+str(x.shape)) #--------------------------------------------- if ('marker' in kwargs.keys()) : if ('ls' not in kwargs.keys() and 'linestyle' not in kwargs.keys()) : kwargs['ls'] = '' if ('mec' in kwargs.keys() and kwargs['mec'] is True): mec = True kwargs.pop('mec') else : mec = False #--------------------------------------------- n = np.arange(x.size) if (z is None) : if (ax is None) : ax = plt.gca() for i in range(len(color)) : tf = n[(edge[i]<=lcarray)*(lcarray<=edge[i+1])] if (tf[0] != 0) : tf[0] -= 1 if (mec) : ax.plot(x[tf], y[tf], color=color[i], mec=color[i], **kwargs) else : ax.plot(x[tf], y[tf], color=color[i], **kwargs) #--------------------------------------------- else : if (IsType.isnum(z)) : z = z + 0*x if (ax is None) : ax = Axes3D(plt.gcf()) #-------------------- if ('viewinit' in kwargs.keys()) : try : elev, azim = kwargs['viewinit'] except : elev = azim = None ax.view_init(elev, azim) kwargs.pop('viewinit') #-------------------- for i in range(len(color)) : tf = n[(edge[i]<=lcarray)*(lcarray<=edge[i+1])] if (tf[0] != 0) : tf[0] -= 1 if (mec) : ax.plot(x[tf], y[tf], z[tf], color=color[i], mec=color[i], **kwargs) else : ax.plot(x[tf], y[tf], z[tf], color=color[i], **kwargs) return ax