def GaussianFilter(per=None, times=None, std=None, Npix=None): ''' call jp.Gaussian.GaussianFilter() return: [gaussianfilter, std] Unit for std: pixel When use this std, x must pixel: np.arange(...) gaussianfilter.size = (per-1) * times + 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 (1) per, times Use per, times to generate gaussian filter then use Npix to reshape (2) sigma, Npix Use sigma, npix to generate gaussian filter ''' from jizhipy.Math import Gaussian import numpy as np if (per is not None or times is not None): gaussianfilter, std = _GaussianFilter(per, times) else: x = np.arange(Npix) x = x - x.mean() gaussianfilter = Gaussian.GaussianValue(x, 0, std) return [gaussianfilter, std]
def func(x, p): return Gaussian.GaussianValue1(x, 0, p[0])
def func(x, p): return Gaussian.GaussianValue(x, p[0], p[1])
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 K2Jy(T, freq, Dx=None, Dy=None, fwhmx=None, fwhmy=None): ''' Convert brightness temperature T(K) to flux density S(Jy) Tb = S*1e-26 * wavelength**2 / 2 / kB / solid_angle S = Tb * 2*bB * 1e26 * solid_angle / wavelength**2 T, freq, Dx, Dy, fwhmx, fwhmy: Can be any shape, but must can broadcast freq: None | MHz (1) None: solid_angle = 1.133 * fwhm**2 (2) in MHz: solid_angle = GaussianSolidAngle() fwhmx, fwhmy: in rad (1) Jy2K(S, None, D) (2) Jy2K(S, freq, D) (3) Jy2K(S, freq, Dx, Dy) (4) Jy2K(S, freq, fwhm) (4) Jy2K(S, freq, fwhmx, fwhmy) ''' import numpy as np from jizhipy.Math import Gaussian from jizhipy.Basic import Raise from jizhipy.Array import Asarray T, freq, Dx, Dy, fwhmx, fwhmy = Asarray2(T, True), Asarray2( freq, True), Asarray2(Dx, True), Asarray2(Dy, True), Asarray2( fwhmx, True), Asarray2(fwhmy, True) kB = 1.3806e-23 const = T * 2 * kB * 1e26 if (freq is None and Dx is not None): if (Dy is not None and Dy != Dx): Raise( Exception, 'Wrong parameters: Jy2K( S, None, Dx, Dy ). When use Dx and Dy, freq can NOT be None' ) S = const / Dx**2 * (1.133 * 1.029**2) return S #-------------------------------------------------- if (Dx is not None): fwhmx = 1.029 * 300 / freq / Dx if (Dy is not None): fwhmy = 1.029 * 300 / freq / Dy else: fwhmy = fwhmx elif (Dy is not None): fwhmy = 1.029 * 300 / freq / Dy fwhmx = fwhmy elif (fwhmx is not None): if (fwhmy is not None): fwhmy = Num(fwhmy, float) else: fwhmy = fwhmx elif (fwhmy is not None): fwhmx = fwhmy else: Raise(Exception, 'Dx=Dy=fwhmx=fwhmy = None') #-------------------------------------------------- solid_angle = Gaussian.GaussianSolidAngle(fwhmx, fwhmy) #-------------------------------------------------- S = const / (300. / freq)**2 * solid_angle return S
def Jy2K(S, freq, Dx=None, Dy=None, fwhmx=None, fwhmy=None, **kwargs): ''' Convert flux density S(Jy) to brightness temperature T(K) with Gaussian Beam with FWHM resolution Tb = S*1e-26 / 2 / kB * wavelength**2 / solid_angle Tb = S*1e-26 / 2 / kB / (1.133*1.029**2) * Dx**2 sigma = fwhm / (8ln2)**0.5 sigma \approx lambda/D /ksd, ksd=1.962~2.286, Reza=2 S, freq, Dx, Dy, fwhmx, fwhmy: Can be any shape, but must can broadcast freq: None | MHz (1) None: solid_angle = 1.133 * fwhm**2 (2) in MHz: solid_angle = GaussianSolidAngle() fwhmx, fwhmy: in rad (1) Jy2K(S, None, D) (2) Jy2K(S, freq, D) (3) Jy2K(S, freq, Dx, Dy) (4) Jy2K(S, freq, fwhm) (4) Jy2K(S, freq, fwhmx, fwhmy) ''' import numpy as np from jizhipy.Math import Gaussian from jizhipy.Basic import Raise from jizhipy.Array import Asarray if ('fwhm' in kwargs.keys()): fwhmx = kwargs['fwhm'] S, freq, Dx, Dy, fwhmx, fwhmy = Asarray2(S, True), Asarray2( freq, True), Asarray2(Dx, True), Asarray2(Dy, True), Asarray2( fwhmx, True), Asarray2(fwhmy, True) kB = 1.3806e-23 const = S * 1e-26 / 2 / kB if (freq is None and Dx is not None): if (Dy is not None and Dy != Dx): Raise( Exception, 'Wrong parameters: Jy2K( S, None, Dx, Dy ). When use Dx and Dy, freq can NOT be None' ) Tb = const * Dx**2 / (1.133 * 1.029**2) return Tb #-------------------------------------------------- if (Dx is not None): fwhmx = 1.029 * 300 / freq / Dx if (Dy is not None): fwhmy = 1.029 * 300 / freq / Dy else: fwhmy = fwhmx elif (Dy is not None): fwhmy = 1.029 * 300 / freq / Dy fwhmx = fwhmy elif (fwhmx is not None): if (fwhmy is not None): fwhmy = Num(fwhmy, float) else: fwhmy = fwhmx elif (fwhmy is not None): fwhmx = fwhmy else: Raise(Exception, 'Dx=Dy=fwhmx=fwhmy=None') #-------------------------------------------------- case = 2 if (case == 1): solid_angle = Gaussian.GaussianSolidAngle(fwhmx, fwhmy) elif (case == 2): solid_angle = 1.133 * fwhmx * fwhmy #-------------------------------------------------- Tb = const * (300. / freq)**2 / solid_angle return Tb