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 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
def Pcolormesh(*args, **kwargs): ''' **kwargs: 'shape': 2D shape of image, must (<=500, <=500) Default shape=(500, 500) 'sample': True | False How to reduce the image? =True: Sample(), keep the noise level =False: Smooth(), depress the noise Default sample=True ''' import numpy as np from jizhipy.Array import Asarray from jizhipy.Basic import IsType from jizhipy.Optimize import Smooth, Sample import matplotlib.pyplot as plt args = list(args) args[0] = Asarray(args[0]) if (len(args[0].shape) == 1): args[1], args[2] = Asarray(args[1]), Asarray(args[2]) X, Y, C = args[:3] else: X, Y, C = None, None, args[0] #---------------------------------------- if ('shape' in kwargs.keys()): shape = kwargs['shape'] kwargs.pop('shape') if (IsType.isnum(shape)): shape = [shape, shape] shape = Asarray(shape, float) if (shape.max() > 500): # lower if (shape[0] > shape[1]): shape[1] *= 500. / shape[0] shape[0] = 500 else: shape[0] *= 500. / shape[1] shape[1] = 500 shape = Asarray(shape, int) else: shape = np.array([500, 500]) #---------------------------------------- if ('sample' in kwargs.keys()): issample = bool(kwargs['sample']) kwargs.pop('sample') else: issample = False if (issample): if (C.shape[0] > shape[0]): C = Sample(C, 0, size=shape[0]) if (C.shape[1] > shape[0]): C = Sample(C, 1, size=shape[1]) else: if (C.shape[0] > shape[0]): C = Smooth(C, 0, reduceshape=shape[0]) if (C.shape[1] > shape[0]): C = Smooth(C, 1, reduceshape=shape[1]) #---------------------------------------- if (X is not None): X = Sample(X, 0, size=C.shape[1]) Y = Sample(Y, 0, size=C.shape[0]) args[0], args[1], args[2] = X, Y, C else: args[0] = C #---------------------------------------- return plt.pcolormesh(*args, **kwargs)