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 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 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 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)