Ejemplo n.º 1
0
def an_spherical(q, xq, E_1, E_2, E_0, R, N):
        
    PHI = zeros(len(q))
    for K in range(len(q)):
        rho = sqrt(sum(xq[K]**2))
        zenit = arccos(xq[K,2]/rho)
        azim  = arctan2(xq[K,1],xq[K,0])

        phi = 0.+0.*1j
        for n in range(N):
            for m in range(-n,n+1):
                sph1 = special.sph_harm(m,n,zenit,azim)
                cons1 = rho**n/(E_1*E_0*R**(2*n+1))*(E_1-E_2)*(n+1)/(E_1*n+E_2*(n+1))
                cons2 = 4*pi/(2*n+1)

                for k in range(len(q)):
                    rho_k   = sqrt(sum(xq[k]**2))
                    zenit_k = arccos(xq[k,2]/rho_k)
                    azim_k  = arctan2(xq[k,1],xq[k,0])
                    sph2 = conj(special.sph_harm(m,n,zenit_k,azim_k))
                    phi += cons1*cons2*q[K]*rho_k**n*sph1*sph2
        
        PHI[K] = real(phi)/(4*pi)

    return PHI
Ejemplo n.º 2
0
def make2DGammaPlot(params,n=2,index0=[1,-1,0],poleaxis=[1,1,0],number_of_points=50):
    """
    this is to make the gamma plot cross section using the fitted broken bond
    model
    """
    
    thetas = numpy.linspace(0,2*numpy.pi,number_of_points)
    angles = []
    energies = []    
    phis = [] 

    for theta in thetas:
        phi = scipy.optimize.fsolve(dotProduct,0.8,args=(theta,index0))[0]
        phis.append(phi)
        #print theta, phi    
        nvector = [sin(theta)*cos(phi),sin(theta)*sin(phi),cos(theta)]
        [h,k,l] = nvector
        energy = fitFunction(nvector,params)
        #energies.append(energy)
        angle = numpy.arccos(numpy.dot(poleaxis,[h,k,l])/(numpy.sqrt((h**2+k**2+l**2)*numpy.dot(poleaxis,poleaxis))))    
        if numpy.dot(numpy.cross([h,k,l],poleaxis),index0) < 0:
            angle = -1.0*angle
        #angles.append(angle)
        #print angle
        # plot with poleaxis pointing in +y direction
        exp_r = abs(0.2200912656713*sph_harm(0, 0,theta,phi) + 0.0032670284794418564*sph_harm(0, 4, theta, phi) + 0.00195264*(sph_harm(-4,4,theta,phi)+sph_harm(4,4,theta,phi))- 0.0023674865858444084*sph_harm(0, 6, theta, phi)+0.00442926*(sph_harm(4,6,theta,phi)+sph_harm(-4,6,theta,phi))-0.00211574*sph_harm(0,8,theta,phi)-0.000795321*(sph_harm(-4,8,theta,phi)+sph_harm(4,8,theta,phi))-0.0012122*(sph_harm(-8,8,theta,phi)+sph_harm(8,8,theta,phi)))
        pylab.plot(energy*sin(angle),energy*cos(angle),'r.')
        pylab.plot(exp_r*sin(angle),exp_r*cos(angle),'b.')
Ejemplo n.º 3
0
def combine_ylm_num(l,m1,m2,a,b,phimax=np.pi,thetamax=2*np.pi,num_points=100):    
    '''returns numerical spherical harmonics as [x,y,z],s where x,y,z are cartesian coordinates and s is realvalue of spherical harmonic or orbital\n
    plot in the following way\n\n
    
    Y,s=Y_lm_num(1,1)\n
    colormap = cm.ScalarMappable( cmap=pl.get_cmap("cool"))
    
    fig = pl.figure(1,figsize=(10,10))\n 
    ax = fig.gca(projection='3d')\n
    surf = ax.plot_surface(*Y, rstride=2, cstride=2, facecolors=colormap.to_rgba(s), \n
                           linewidth=0.5, antialiased=False)\n
    
    lim=0.15 \n
    ax.set_xlabel('x') \n
    ax.set_ylabel('y') \n
    ax.set_zlabel('z') \n
    ax.set_xlim(-lim,lim) \n
    ax.set_ylim(-lim,lim) \n
    ax.set_zlim(-lim,lim) \n
    ax.set_aspect("equal")'''
    
    phi = np.linspace(0, phimax, num_points)
    theta = np.linspace(0, thetamax, num_points)
    phi, theta = np.meshgrid(phi, theta)
    s=1/np.sqrt(2)*np.real(a*sph_harm(m1,l,theta,phi)+b*sph_harm(m2,l,theta,phi))
    r=np.abs(s)**2
    x = r*np.sin(phi) * np.cos(theta)
    y = r*np.sin(phi) * np.sin(theta)
    z = r*np.cos(phi)
    return [x,y,z],s
Ejemplo n.º 4
0
def Ylm(l, m, theta, phi):
    """
    The definition we use in our code is the one of Greengard. Namely, we have
    the following expression for Ylm(t,p)::
                                               |m|
        Ylm(t, p) = sqrt((l-|m|)! / (l+|m|)!).P  (cos(t)).exp(i.m.p)
                                               l
    The spherical harmonics defined in scipy is (scipy calls "theta" what we
    consider to be phi and vice-versa)::
         S
        Ylm(p, t) = sqrt(2l+1 / 4.pi).Ylm(t, p) if m >= 0
         S
        Ylm(p, t) = (-1)**m.sqrt(2l+1 / 4.pi).Ylm(t, p) if m < 0
    """

    from scipy.special import sph_harm

    assert l >= 0
    assert abs(m) <= l

    prefactor = np.sqrt(4.*np.pi / (2.*l+1.))

    if m >= 0:
        return prefactor * sph_harm(m, l, phi, theta)
    else:
        return prefactor * np.conjugate(sph_harm(abs(m), l, phi, theta))
Ejemplo n.º 5
0
def harmonic(m, l, coor):
    '''Produce m,l spherical harmonic at coarse and fine coordinates'''
    Harmonic = namedtuple('Harmonic', 'fine coarse')
    return Harmonic(
        special.sph_harm(m, l, coor.fine.theta, coor.fine.phi).real,
        special.sph_harm(m, l, coor.coarse.theta, coor.coarse.phi).real
    )
	def SphericalHarmonics_sum(x,contrib):
		"Compute the sum of spherical harmonicsExpect input (theta1, phi1,theta2,phi2) and ((A,l1,m1,l2,m2),...)"
		ampl = 0
		for i in range(contrib.shape[0]):
			#print("A , m1 : ", contrib[i,0], contrib[i,2])
			ampl += contrib[i,0]*sph_harm(contrib[i,1],contrib[i,2],x[0],x[1])*sph_harm(contrib[i,3],contrib[i,4],x[2],x[3])
		#print("ampl : ",ampl)
		prob = np.real(ampl* np.conjugate(ampl))
		return prob
Ejemplo n.º 7
0
def get_coeffs_lm_baselines_from_origin(calfile,l,m,freqs = n.array([.1,]),savefolderpath=None):
    """
    This function calculates the coefficients in front of the lm spherical
    harmonic for the antenna array described in the calfile. The coefficients 
    are determined by the integral of A(l,m)Y(l,m)exp[-i2pi(ul+vm)]dldm.

    However, this function only loops over the baselines of the antennas with
    respect to the origin. 
    """
    aa = a.cal.get_aa(calfile, n.array([.150])) #get antenna array
    im = a.img.Img(size=200, res=.5) #make an image of the sky to get sky coords
    tx,ty,tz = im.get_top(center=(200,200)) #get coords of the zenith?
    valid = n.logical_not(tx.mask)
    tx,ty,tz = tx.flatten(),ty.flatten(),tz.flatten()
    theta = n.arctan(ty/tx) # using math convention of theta=[0,2pi], phi=[0,pi]
    phi = n.arccos(n.sqrt(1-tx*tx-ty*ty))
    #n.set_printoptions(threshold='nan')
    #print theta,phi
    #quit()

    #beam response for an antenna pointing at (tx,ty,tz) with a polarization in x direction
    #amp = A(theta) in notes
    amp = aa[0].bm_response((tx,ty,tz),pol='x')**2 
    na = len(aa.ants) # number of antennas
    #coefficient array: rows baselines; cols frequencies
    coeffs = n.zeros([(na*na-na)/2,len(freqs)],dtype=n.complex)
    # compute normalization for spherical harmonics
    Ynorm = special.sph_harm(0,0,0,0)
    # loop through all baselines
    baselines = n.zeros([(na*na-na)/2,3])
    ll=0
    for jj in range(1,na):
        bx,by,bz = aa.get_baseline(0,jj,'z') 
        #the baseline for antennas 0 and jj 
        print 0,jj,[bx,by,bz]
        baselines[ll] = [bx,by,bz]
        kk=0
        for fq in freqs: #loop over frequencies
            phs = n.exp(-2j*n.pi*fq * (bx*tx+by*ty+bz*tz)) #fringe pattern
            Y = n.array(special.sph_harm(m,l,theta,phi))/Ynorm #using math convention of theta=[0,2pi], phi=[0,pi]
            Y.shape = phs.shape = amp.shape = im.uv.shape
            amp = n.where(valid, amp, 0)
            phs = n.where(valid, phs, 0)                
            Y = n.where(valid, Y, 0) 
            # n.set_printoptions(threshold='nan')
            # print Y
            # quit() 
            dc_response = n.sum(amp*Y*phs)/n.sum(amp) #this integrates the amplitude * fringe pattern; units mK?
            print 'dc = ',dc_response
            jy_response = n.real(dc_response * 100 / C.pspec.jy2T(fq)) # jy2T converts flux density in jansky to temp in mK
            print '\t',fq, dc_response, jy_response
            coeffs[ll,kk] = dc_response
            kk+=1
        ll+=1
    if savefolderpath!=None: n.savez_compressed('{0}{1}_data_l_{1}_m_{2}'.format(savefolderpath,calfile,l,m),baselines=baselines,frequencies=freqs,coeffs=coeffs)
    return baselines,freqs,coeffs
Ejemplo n.º 8
0
	      def integrand(mu,phi):
	        theta = np.arccos(mu)
                if ((m1 >= 0) and (m2>=0)):
                   return np.sin(theta) * np.sin(phi) * c1*sph_harm(m1, n1, phi, theta).real * c2*sph_harm(m2, n2, phi, theta).real
                elif ((m1 >= 0) and (m2<0)):
                   return np.sin(theta) * np.sin(phi) * c1*sph_harm(m1, n1, phi, theta).real * c2*sph_harm(-m2, n2, phi, theta).imag
                elif ((m1 < 0) and (m2>=0)):
                   return np.sin(theta) * np.sin(phi) * c1*sph_harm(-m1, n1, phi, theta).imag * c2*sph_harm(m2, n2, phi, theta).real
                elif ((m1 < 0) and (m2<0)):
                   return np.sin(theta) * np.sin(phi) * c1*sph_harm(-m1, n1, phi, theta).imag * c2*sph_harm(-m2, n2, phi, theta).imag
Ejemplo n.º 9
0
    def sph_harm_set(self):
        """
        Calculate the spherical harmonics, provided n parameters (corresponding
        to nc = (L+1) * (L+2)/2 with L being the maximal harmonic degree for
        the set of bvecs of the object

        Note
        ----

        1. This was written according to the documentation of mrtrix's
        'csdeconv'. The following is taken from there:  

          Note that this program makes use of implied symmetries in the
          diffusion profile. First, the fact the relative signal profile is
          real implies that it has conjugate symmetry, i.e. Y(l,-m) = Y(l,m)*
          (where * denotes the complex conjugate). Second, the diffusion
          profile should be antipodally symmetric (i.e. S(x) = S(-x)), implying
          that all odd l components should be zero. Therefore, this program
          only computes the even elements.

          Note that the spherical harmonics equations used here differ slightly
          from those conventionally used, in that the (-1)^m factor has been
          omitted. This should be taken into account in all subsequent
          calculations.

          Each volume in the output image corresponds to a different spherical
          harmonic component, according to the following convention: [0]    
          Y(0,0)  [1] Im {Y(2,2)} [2] Im {Y(2,1)} [3]     Y(2,0) [4] Re
          {Y(2,1)} [5] Re {Y(2,2)}  [6] Im {Y(4,4)} [7] Im {Y(4,3)} etc... 

          
        2. Take heed that it seems that scipy's sph_harm actually has the
        order/degree in reverse order than the convention used by mrtrix, so
        that needs to be taken into account in the calculation below

        """

        # Convert to spherical coordinates:
        r, theta, phi = geo.cart2sphere(self.bvecs[0, self.b_idx], self.bvecs[1, self.b_idx], self.bvecs[2, self.b_idx])

        # Preallocate:
        b = np.empty((self.model_coeffs.shape[-1], theta.shape[0]))

        i = 0
        # Only even order are taken:
        for order in np.arange(0, self.L + 1, 2):  # Go to L, inclusive!
            for degree in np.arange(-order, order + 1):
                # In negative degrees, take the imaginary part:
                if degree < 0:
                    b[i, :] = np.imag(sph_harm(-1 * degree, order, phi, theta))
                else:
                    b[i, :] = np.real(sph_harm(degree, order, phi, theta))
                i = i + 1
        return b
Ejemplo n.º 10
0
		    def integrandZ(mu,phi):
		       theta = np.arccos(mu)
		       if ((m1 >= 0) and (m2>=0)):
			   return abs(np.sin(theta) * np.sin(phi)) * c1*sph_harm(m1, n1, phi, theta).real * c2*sph_harm(m2, n2, phi, theta).real
			   #return abs(np.sqrt(1-mu**2) * np.cos(phi)) * c1*sph_harm(m1, n1, phi, theta).real * c2*sph_harm(m2, n2, phi, theta).real
		       elif ((m1 >= 0) and (m2<0)):
			   return abs(np.sin(theta) * np.sin(phi)) * c1*sph_harm(m1, n1, phi, theta).real * c2*sph_harm(-m2, n2, phi, theta).imag
		       elif ((m1 < 0) and (m2>=0)):
			   return abs(np.sin(theta) * np.sin(phi)) * c1*sph_harm(-m1, n1, phi, theta).imag * c2*sph_harm(m2, n2, phi, theta).real
		       elif ((m1 < 0) and (m2<0)):
			   return abs(np.sin(theta) * np.sin(phi)) * c1*sph_harm(-m1, n1, phi, theta).imag * c2*sph_harm(-m2, n2, phi, theta).imag
Ejemplo n.º 11
0
    def populate_instance_response_matrix(self,truncated_nmax=None, truncated_nmin=None,truncated_lmax=None, truncated_lmin=None, usedefault=1):
        """
        Populate the R matrix for the default range of l and n, or
        or over the range specified above
        """

        if usedefault == 1:
            truncated_nmax = self.truncated_nmax
            truncated_nmin = self.truncated_nmin
            truncated_lmax = self.truncated_lmax
            truncated_lmin = self.truncated_lmin
            lms = self.lms
            kfilter = self.kfilter    
        else:
            low_k_cutoff = truncated_nmin*self.Deltak
            high_k_cutoff = truncated_nmax*self.Deltak
            self.set_instance_k_filter(truncated_nmax=truncated_nmax,truncated_nmin=truncated_nmin)    
            lms = [(l, m) for l in range(truncated_lmin,truncated_lmax+1) for m in range(-l, l+1)]
        
        
        # Initialize R matrix:
        NY = (truncated_lmax + 1)**2-(truncated_lmin)**2
        # Find the indices of the non-zero elements of the filter
        ind = np.where(self.kfilter>0)
        # The n index spans 2x that length, 1st half for the cos coefficients, 2nd half
        #    for the sin coefficients
        NN = 2*len(ind[1])
        R_long = np.zeros([NY,NN], dtype=np.complex128)

        # In case we need n1, n2, n3 at some point...:
        #    n1, n2, n3 = self.kx[ind]/self.Deltak , self.ky[ind]/self.Deltak, self.kz[ind]/self.Deltak
        k, theta, phi = self.k[ind], np.arctan2(self.ky[ind],self.kx[ind]), np.arccos(self.kz[ind]/self.k[ind])
        # We need to fix the 'nan' theta element that came from having ky=0
        theta[np.isnan(theta)] = np.pi/2.0
        
        # Get ready to loop over y
        y = 0
        A = [sph_jn(truncated_lmax,ki)[0] for ki in k]        
        # Loop over y, computing elements of R_yn 
        for i in lms:        
            l = i[0]
            m = i[1]
            trigpart = np.cos(np.pi*l/2.0)
            B = np.asarray([A[ki][l] for ki in range(len(k))])
            R_long[y,:NN/2] = 4.0 * np.pi * sph_harm(m,l,theta,phi).reshape(NN/2)*B.reshape(NN/2) * trigpart

            trigpart = np.sin(np.pi*l/2.0)
            R_long[y,NN/2:] = 4.0 * np.pi * sph_harm(m,l,theta,phi).reshape(NN/2)*B.reshape(NN/2)* trigpart
                
            y = y+1
        
        self.R = np.zeros([NY,len(ind[1])], dtype=np.complex128)
        self.R = np.append(R_long[:,0:len(ind[1])/2], R_long[:,len(ind[1]):3*len(ind[1])/2], axis=1)
        return
Ejemplo n.º 12
0
def real_sph_harm(mm, ll, phi, theta):
    if mm>0:
        ans = (1./math.sqrt(2)) * \
                (ss.sph_harm(mm, ll, phi, theta) + \
                ((-1)**mm) * ss.sph_harm(-mm, ll, phi, theta))
    elif mm==0:
        ans = ss.sph_harm(0, ll, phi, theta)
    elif mm<0:
        ans = (1./(math.sqrt(2)*complex(0.,1))) * \
                (ss.sph_harm(-mm, ll, phi, theta) - \
                ((-1)**mm) * ss.sph_harm(mm, ll, phi, theta))

    return ans.real
Ejemplo n.º 13
0
def zdlm(l,m,x2):
	if l < m:
		print 'Error:\nabs(m) must be equal or less than l'
		return None
	else:
		# Kinematics
		q2 = ((2*np.pi/L)**2)*x2
		cm_energy = np.sqrt(q2 + m1**2) + np.sqrt(q2 + m2**2)
		lab_energy = np.sqrt(cm_energy**2+lab_moment**2)
		alpha = 1.0/2.0*(1.0+(np.square(m1)-np.square(m2))/np.square(cm_energy))
		gamma = 1.0 # lab_energy/cm_energy

		first_term = sum(np.exp(-r2_array+x2)*(1.0/(r2_array-x2))*(r2_array**(l/2.0))*special.sph_harm(m,l,r_azimuthal,r_polar))

		print first_term

		# Calculate the second term
		if l == 0:
			second_term = special.sph_harm(0,0,0.0,0.0)*gamma*np.power(np.pi,3.0/2.0)
			second_term_bracket = 2 * x2 * integrate.quad(integr_second_term,0,1, args = (x2))[0] - 2 * np.exp(x2)
			second_term *= second_term_bracket
		else:
			second_term = 0

		print second_term


		# Calculate the third term
		wd = np.inner(w_arr,d)
		t1 = np.exp(I*2*np.pi*alpha*wd)
		t2 = np.power(gw2_array,l/2.0)
		t3 = special.sph_harm(m,l,gw_azimuthal,gw_polar)
		coef_third_term = t1*t2*t3

		third_term_r = integrate.quad(integr_third_term_r,0,1, args = (l,gw2_array,x2,coef_third_term))[0]

		third_term_i = integrate.quad(integr_third_term_i,0,1, args = (l,gw2_array,x2,coef_third_term))[0]

		third_term = gamma*np.power(I,l)* (third_term_r + I*third_term_i)

		print third_term

		total = first_term + second_term + third_term

		return total

# for i in xrange(len(x2_forplot)):
# 	y_forplot[i] = zdlm(0,0,x2_forplot[i])
# 	print i
    def __call__(self, coords):
        from scipy.special import sph_harm

        theta, phi = cart_to_polar_angles(coords)
        if self.m == 0:
            return (sph_harm(self.m, self.l, phi, theta)).real

        vplus = sph_harm(abs(self.m), self.l, phi, theta)
        vminus = sph_harm(-abs(self.m), self.l, phi, theta)
        value = np.sqrt(1/2.0) * (self._posneg*vplus + vminus)

        if self.m < 0:
            return -value.imag
        else:
            return value.real
def real_spherical_harmonic( theta, phi, l, m):
    assert( m <= l )
    assert( l >= 0. )

    if m==0:
        val = sph_harm(m, l, phi, theta)
        return val.real
    elif m < 0:
        val = 1.0j/np.sqrt(2.) * (sph_harm(m,l,phi, theta) 
              - np.power(-1., m ) * sph_harm(-m, l, phi, theta) )
        return val.real
    elif m > 0:
        val = 1.0/np.sqrt(2.) * (sph_harm(-m,l,phi, theta) 
              + np.power(-1., m ) * sph_harm(m, l, phi, theta) )
        return val.real
Ejemplo n.º 16
0
def spherical_harmonic_real_scipy(l, m, theta, phi):
    """ real spherical harmonics of degree l and order m """
    # note that the definition of `sph_harm` has a different convention for the
    # usage of the variables phi and theta
    if m > 0:
        return (sph_harm(m, l, phi, theta) +
                (-1)**m * sph_harm(-m, l, phi, theta)
                ).real / math.sqrt(2)
        
    elif m == 0:
        return sph_harm(0, l, phi, theta).real
    
    else:  # m < 0
        return ((sph_harm(-m, l, phi, theta) -
                 (-1)**m * sph_harm(m, l, phi, theta)
                 ) / csqrt(-2)).real
Ejemplo n.º 17
0
def spH():
    for l in range(4):
        m=0
           
        for theta in np.arange(0,2*math.pi,0.01):
            for phi in np.arange(0,math.pi,0.01):
                print l ,m, theta, phi, sph_harm(m,l,theta,phi)
Ejemplo n.º 18
0
def coefficients(x, y, z, mass, n, l, m):
    """
    Input:
    ------
    x: Array of particles x-coordiante
    y: Array of particles y-coordiante
    z: Array of particles z-coordinate
    mass: Array with the mass particles
    n: n
    l: l
    m: m
    r_s: halo scale length
    Output:
    -------
    var(a): A float number with the variance
    of the coefficient (S_nlm, T_nlm) evaluated at n,l,m.
    """

    r = np.sqrt(x**2.0+y**2.0+z**2.0)/r_s
    N = len(r)
    theta = np.arccos(z/(r*r_s))
    phi = np.arctan2(y,x)
    Y_lm = special.sph_harm(m,l,0,theta) # scipy notation m,l
    phi_nl = phi_nl_f(r, n, l)
    Psi = phi_nl*Y_lm*mass
    if m==0:
        dm0=1.0
    else:
        dm0=0.0
    Anl = Anl_f(n,l)
    Snlm=(2.-dm0)*Anl*np.sum(Psi.real*np.cos(m*phi))
    Tnlm=(2.-dm0)*Anl*np.sum(Psi.real*np.sin(m*phi))

    return Snlm, Tnlm
Ejemplo n.º 19
0
 def multi(self,inorm=0, isym=1):
     """
     calculates the coefficients A_lm for themulti pole expansion
     """
     print "using l_max=",self.lmax
     bnorm=1.0
     for l in range(0,self.lmax+1,2):
         temp=list()
         for m in range(l+1):
             #Do the calculation
             
             summ=0
             #print "-----------------"
             for val in self.grid:
                 temp2=sfunc.sph_harm(m,l,val[1],val[0])
                 summ+=temp2.conjugate()*val[3]*val[5] #Y*_lm(theta,phi)*g(thea,phi)*sin(theta)dphi*dtheta
                 
             if(l==0 and m==0):
                 bnorm=summ
                 print"normalization factor= ",bnorm
             
             temp.append([l,m,summ,summ/bnorm])
             #print temp[m]
         self.alm.append(temp)
     self.writeCoeff("PYcoeff.dat")
     print "calcualted coefficients"
     print "-------------------------------------------"
Ejemplo n.º 20
0
def harm_P(l, m, beta, alpha):
    """
    Associated Legendre polynomial

    Arguments
    =========
    l     =
    m     =
    beta  =
    alpha =
    """
    import numpy as np
    P_lm = np.zeros((len(beta), len(alpha)), dtype='complex')
    from scipy.special import sph_harm

    mt, lt, bt, at = [], [], [], []
    for i in range(len(beta)):
        for j in range(len(alpha)):
            mt.append(m); lt.append(l)
            bt.append(beta[i]); at.append(alpha[j])
    dat = sph_harm(mt, lt, bt, at)

    k = 0
    for i in range(len(beta)):
        for j in range(len(alpha)):
            P_lm[i,j] = dat[k]
            k = k + 1
    return P_lm
Ejemplo n.º 21
0
def GetLegendrePoly(conf, theta, phi):
	"""
	leg = GetLegendrePoly(conf, theta, phi)

	Calculates the Legendre polynomials for all {l,m}, and the angles in theta.

	Parametres
	----------
	conf : Config object.
	theta : 1D double array, containing the theta grid.
	phi : 1D double array, containing the phi grid.

	Returns
	-------
	leg : 3D double array, containing legendre polinomials evaluated for different l, m and thetas.
	"""
	index_iterator = conf.AngularRepresentation.index_iterator
	nr_lm = (index_iterator.lmax+1)**2

	leg = zeros([nr_lm, len(theta), len(phi)], dtype=complex)
	print "Legendre ..."
	for i, lm in enumerate(index_iterator.__iter__()):
		if mod(i,nr_lm/10)==0:
			print i * 100. / nr_lm, "%"
		for j, my_theta in enumerate(theta):
			leg[i,j,:] = sph_harm(lm.m, lm.l, phi, my_theta)

	return leg
Ejemplo n.º 22
0
 def testExpansionYlmpow(self):
     """Test the expansion of Ylm into powers"""
     for (phi, theta) in [(self.phi + dp, self.theta + dt)
                          for dp in (0., 0.25 * np.pi, 0.5 * np.pi, 0.75 * np.pi)
                          for dt in (0., 0.5 * np.pi, np.pi, 1.5 * np.pi)]:
         utest, umagn = T3D.powexp(np.array([np.sin(phi) * np.cos(theta),
                                             np.sin(phi) * np.sin(theta),
                                             np.cos(phi)]))
         self.assertAlmostEqual(umagn, 1)
         Ylm0 = np.zeros(T3D.NYlm, dtype=complex)
         # Ylm as power expansions
         for lm in range(T3D.NYlm):
             l, m = T3D.ind2Ylm[lm, 0], T3D.ind2Ylm[lm, 1]
             Ylm0[lm] = sph_harm(m, l, theta, phi)
             Ylmexp = np.dot(T3D.Ylmpow[lm], utest)
             self.assertAlmostEqual(Ylm0[lm], Ylmexp,
                                    msg="Failure for Ylmpow " 
                 "l={} m={}; theta={}, phi={}\n{} != {}".format(l, m, theta, phi, Ylm0[lm], Ylmexp))
         # power expansions in Ylm's
         for p in range(T3D.NYlm):
             pYlm = np.dot(T3D.powYlm[p], Ylm0)
             self.assertAlmostEqual(utest[p], pYlm,
                                    msg="Failure for powYlm " 
                 "{}; theta={}, phi={}\n{} != {}".format(T3D.ind2pow[p], theta, phi, utest[p], pYlm))
         # projection (note that Lproj is not symmetric): so this test ensures that v.u and (proj.v).u
         # give the same value
         uproj = np.tensordot(T3D.Lproj[-1], utest, axes=(0, 0))
         for p in range(T3D.NYlm):
             self.assertAlmostEqual(utest[p], uproj[p],
                                    msg="Projection failure for " 
                 "{}\n{} != {}".format(T3D.ind2pow[p], uproj[p], utest[p]))
Ejemplo n.º 23
0
    def Y_lm(self, theta, phi):
        """ The angular part of the wavefunction, Y_lm(theta, phi).

            quantum numbers:
                l, m
        """
        return sph_harm(self.m, self.l, phi, theta)
Ejemplo n.º 24
0
 def test(theta, m, lmax):
     Plm = compute_normalized_associated_legendre(m, theta, lmax)
     Plm_p = sph_harm(m, np.arange(m, lmax + 1), 0, theta)[None, :]
     if not np.allclose(Plm_p, Plm):
         print Plm_p
         print Plm
     return ok_, np.allclose(Plm_p, Plm)
Ejemplo n.º 25
0
def sph_harm(m, n, az, el):
    """Compute spherical harmonics

    Parameters
    ----------
    m : (int)
        Order of the spherical harmonic. abs(m) <= n

    n : (int)
        Degree of the harmonic, sometimes called l. n >= 0

    az: (float)
        Azimuthal (longitudinal) coordinate [0, 2pi], also called Theta.

    el : (float)
        Elevation (colatitudinal) coordinate [0, pi], also called Phi.

    Returns
    -------
    y_mn : (complex float)
        Complex spherical harmonic of order m and degree n,
        sampled at theta = az, phi = el
    """

    return scy.sph_harm(m, n, az, el)
Ejemplo n.º 26
0
def real_sph_harm(ll, mm, phi, theta):
    """
    The real-valued spherical harmonics
    (adapted from van Haasteren's piccard code)
    """

    if mm > 0:
        ans = (1.0 / math.sqrt(2)) * (ss.sph_harm(mm, ll, phi, theta) + ((-1) ** mm) * ss.sph_harm(-mm, ll, phi, theta))
    elif mm == 0:
        ans = ss.sph_harm(0, ll, phi, theta)
    elif mm < 0:
        ans = (1.0 / (math.sqrt(2) * complex(0.0, 1))) * (
            ss.sph_harm(-mm, ll, phi, theta) - ((-1) ** mm) * ss.sph_harm(mm, ll, phi, theta)
        )

    return ans.real
Ejemplo n.º 27
0
def test_spherical_conversions():
    """Test spherical harmonic conversions."""
    # Test our real<->complex conversion functions
    az, pol = np.meshgrid(np.linspace(0, 2 * np.pi, 30),
                          np.linspace(0, np.pi, 20))
    for degree in range(1, int_order):
        for order in range(0, degree + 1):
            sph = sph_harm(order, degree, az, pol)
            # ensure that we satisfy the conjugation property
            assert_allclose(_sh_negate(sph, order),
                            sph_harm(-order, degree, az, pol))
            # ensure our conversion functions work
            sph_real_pos = _sh_complex_to_real(sph, order)
            sph_real_neg = _sh_complex_to_real(sph, -order)
            sph_2 = _sh_real_to_complex([sph_real_pos, sph_real_neg], order)
            assert_allclose(sph, sph_2, atol=1e-7)
Ejemplo n.º 28
0
def powerSpectrum(records, lmax=40):
    import scipy.special as spe
    print '~'*50
    print records
    print '~'*50

    key = 'bParts'
    power = np.zeros(shape=(lmax, len(records)))
    for iRecord, rec in enumerate(records):
        es    = [rec[key][ii][1] for ii in range(rec['nParts'])]
        cosTs = [rec[key][ii][2] for ii in range(rec['nParts'])]
        phis  = [rec[key][ii][3] for ii in range(rec['nParts'])]
    
        thetas = np.arccos(cosTs)
        phis   = np.array(phis)
        es     = np.array(es)
        #es    /= np.sum(es*es)
        es    /= math.sqrt(np.sum(es*es))

        for ll in range(lmax):
            for mm in range(-ll, ll+1):
    #note scipy takes opposite unit names from Physics
    #phi (in scipy) is angle from z-axis
                flm = np.sum(                 spe.sph_harm(mm, ll, phis, thetas) * es)
                #flm = np.sum(np.sin(thetas) * spe.sph_harm(mm, ll, phis, thetas) * es)
                power[ll,iRecord] += np.abs(flm + np.conj(flm))



    power = np.sqrt(power)
    return power
Ejemplo n.º 29
0
def real_sph_harm(mm, ll, phi, theta):
    """
    The real-valued spherical harmonics.
    """
    if mm>0:
        ans = (1./math.sqrt(2)) * \
                (ss.sph_harm(mm, ll, phi, theta) + \
                ((-1)**mm) * ss.sph_harm(-mm, ll, phi, theta))
    elif mm==0:
        ans = ss.sph_harm(0, ll, phi, theta)
    elif mm<0:
        ans = (1./(math.sqrt(2)*complex(0.,1))) * \
                (ss.sph_harm(-mm, ll, phi, theta) - \
                ((-1)**mm) * ss.sph_harm(mm, ll, phi, theta))

    return ans.real
Ejemplo n.º 30
0
def angular_function(j, theta, phi):
    """
    Returns the values of the spherical harmonics function at given 
    positions specified by colatitude and aximuthal angles.

    Parameters
    ----------
    j : int
        The spherical harmonic index.
    theta : array-like, shape (K, )
        The colatitude angles.
    phi : array-like, shape (K, )
        The azimuth angles.

    Returns
    -------
    f : array-like, shape (K, )
        The value of the function at given positions.
    """
    l = sh_degree(j)
    m = sh_order(j)
    # We follow here reverse convention about theta and phi w.r.t scipy.
    sh = sph_harm(np.abs(m), l, phi, theta)
    if m < 0:
        return np.sqrt(2) * sh.real
    if m == 0:
        return sh.real
    if m > 0:
        return np.sqrt(2) * sh.imag
Ejemplo n.º 31
0
def inverseSphericalHarmonicTransform(coeffs, envmap_height=512, format_='latlong', reduction_type='right'):
    """
    Recovers an EnvironmentMap from a list of coefficients.
    """
    degrees = np.asscalar(np.sqrt(coeffs.shape[0]).astype('int')) - 1

    coeffs = addRedundantCoeffs(coeffs, reduction_type)[..., np.newaxis]

    ch = coeffs.shape[1] if len(coeffs.shape) > 0 else 1
    retval = EnvironmentMap(envmap_height, format_)
    retval.data = np.zeros((retval.data.shape[0], retval.data.shape[1], ch), dtype=np.float32)

    x, y, z, valid = retval.worldCoordinates()
    theta = np.arctan2(x, -z)
    phi = np.arccos(y)

    for l in range(degrees + 1):
        for col, m in enumerate(range(-l, l + 1)):
            Y = sph_harm(m, l, theta, phi)
            for c in range(ch):
                retval.data[..., c] += (coeffs[l**2+col, c]*Y).real

    return retval
Ejemplo n.º 32
0
def sph_c(xyz, l, m=None):
    '''
    Complex spherial harmonics including the Condon-Shortley phase.

    https://en.wikipedia.org/wiki/Table_of_spherical_harmonics#Spherical_harmonics

    input:
       xyz: cartesian coordinate of shape [n, 3]
    '''
    xyz = np.asarray(xyz, dtype=float)
    if xyz.ndim == 1:
        xyz = xyz[None, :]
    if m:
        assert -l <= m <= l, "'m' must be in the range of [{},{}]".format(-l, l)

    r, phi, theta = cart2sph(xyz)
    N = xyz.shape[0]
    ylm = [sph_harm(M, l, phi, theta) for M in range(-l, l+1)]

    if m is None:
        return np.array(ylm, dtype=complex).T
    else:
        return np.array(ylm, dtype=complex).T[:, m+l]
Ejemplo n.º 33
0
def shd_nm(channels, n, m):
    """
    Calculate the n-the order, m-th degree SHD coefficients for the given Eigenmike em32 channels

    :param channels: 32 channels of audio from Eigenmike em32
    :param n: SHD coefficient order
    :param m: SHD coefficient degree
    :return: Non-equalised SHD coefficients (p_nm) for the given em32 recording
    """
    em32 = mc.EigenmikeEM32()
    estr = em32.returnAsStruct()
    wts = estr['weights']
    ths = estr['thetas']
    phs = estr['phis']
    pnm = np.zeros(np.shape(channels[0])) * 1j
    for ind in range(32):
        cq = channels[ind]
        wq = wts[ind]
        tq = ths[ind]
        pq = phs[ind]
        Ynm = spec.sph_harm(m, n, pq, tq)
        pnm += wq * cq * np.conj(Ynm)
    return pnm
Ejemplo n.º 34
0
def real_sph_harmonic(j, m, theta, phi):
    """
    Evaluate a real spherical harmonic

    :param j: The order of the spherical harmonic. These must satisfy |m| < j.
    :param m: The degree of the spherical harmonic. These must satisfy |m| < j.
    :param theta: The spherical coordinates of the points at which we want to evaluate the real spherical harmonic.
        `theta` is the latitude between 0 and pi
    :param phi: The spherical coordinates of the points at which we want to evaluate the real spherical harmonic.
        `phi` is the longitude, between 0 and 2*pi
    :return: The real spherical harmonics evaluated at the points (theta, phi).
    """
    abs_m = abs(m)

    y = sph_harm(abs_m, j, phi, theta)
    if m < 0:
        y = np.sqrt(2) * np.imag(y)
    elif m > 0:
        y = np.sqrt(2) * np.real(y)
    else:
        y = np.real(y)

    return y
Ejemplo n.º 35
0
def sph_harm_array(N, theta, phi, sh_type='real'):

    # Q = np.max(phi.shape)*theta.shape[np.argmin(phi.shape)]
    # find number of angles
    if isinstance(theta, float) or isinstance(theta, int):
        Q = 1
    else:
        Q = len(theta)

    Y_mn = np.zeros([Q, (N+1)**2], dtype=complex)

    for i in range((N+1)**2):

        # trick from ambiX paper
        n = np.floor(np.sqrt(i))
        m = i - (n**2) - n

        Y_mn[:,i] = sp.sph_harm(m, n, theta, phi).reshape(1,-1)

    if sh_type == 'real':
        Y_mn = np.real((C(N) @ Y_mn.T).T)

    return np.array(Y_mn)
Ejemplo n.º 36
0
def sphericalHarmonicTransform(envmap, degrees=None, reduction_type='right'):
    """
    Performs a Spherical Harmonics Transform of `envmap` up to `degree`.
    """
    ch = envmap.data.shape[2] if len(envmap.data.shape) > 2 else 1

    if degrees is None:
        degrees = np.ceil(np.maximum(envmap.shape) / 2.)

    retval = np.zeros(((degrees + 1)**2, ch), dtype=np.complex)

    f = envmap.data * envmap.solidAngles()[:, :, np.newaxis]

    x, y, z, valid = envmap.worldCoordinates()
    theta = np.arctan2(x, -z)
    phi = np.arccos(y)

    for l in tqdm(range(degrees + 1)):
        for col, m in enumerate(range(-l, l + 1)):
            Y = sph_harm(m, l, theta, phi)
            for c in range(ch):
                retval[l**2 + col, c] = np.nansum(Y * f[:, :, c])
    return removeRedundantCoeffs(retval, reduction_type)
Ejemplo n.º 37
0
    def analyse(self, values):
        """Perform a spherical harmonic transform given a grid and a set of values

        Arguments:
        values -- set of complex scalar function values associated with grid points
        """
        if self._shtns:
            desired_shape = self._shtns.spat_shape[::-1]
            return self._shtns.analys_cplx(
                np.array(
                    values,
                    dtype=np.complex128).reshape(desired_shape).transpose())
        coefficients = np.zeros((self.l_max + 1) * (self.l_max + 1),
                                dtype=np.complex128)
        lm = 0
        grid = self.grid
        for l in range(0, self.l_max + 1):
            for m in range(-l, l + 1):
                vals = np.conj(sph_harm(m, l, grid[:, 0], grid[:, 1]))
                vals *= values
                coefficients[lm] = integrate_values(grid, vals)
                lm += 1
        return coefficients
Ejemplo n.º 38
0
def _steinhardt_pars(vecs, l_channels, compute_W=False, weights=None):
    """Compute the Steinhardt bond order parameters (Q and optionally W)"""

    Qlm = []
    Q = np.zeros(len(l_channels))
    W = np.zeros(len(l_channels))

    # Translate vectors in polar form
    vecs = np.array(vecs) / np.linalg.norm(vecs, axis=1)[:, None]
    pols = np.array(
        [np.arccos(vecs[:, 2]),
         np.arctan2(vecs[:, 1], vecs[:, 0])]).T

    # What about weights?
    if weights is None:
        weights = np.ones(vecs.shape[0]) / len(vecs)

    for i, l in enumerate(l_channels):
        mvals = np.arange(-l, l + 1)
        Qlm.append(
            np.sum(sph_harm(mvals[None, :], l, pols[:, 1, None],
                            pols[:, 0, None]) * weights[:, None],
                   axis=0))
        Qsum = np.sum(np.conj(Qlm[i]) * Qlm[i])
        Q[i] = np.abs(np.sqrt(Qsum * 4 * np.pi / (2 * l + 1.0)))
        if compute_W:
            m1, m2, m3 = _valid_triples(l).T
            ls = np.array([l] * len(m1))
            w3j = wigner_3j(ls, m1, ls, m2, ls, m3)
            W[i] = np.abs(
                np.sum(w3j * Qlm[i][m1 + l] * Qlm[i][m2 + l] * Qlm[i][m3 + l])
                / (Qsum)**1.5)

    if not compute_W:
        return Q
    else:
        return Q, W
    def Plot(self):
        #Clear figure
        plt.clf()
        #Read in m and l
        m = int(self.Entm.get())
        l = int(self.Entl.get())
        #Define phi and theta
        theta = np.linspace(0, np.pi, 101)
        phi = np.linspace(0, 2 * np.pi, 101)
        theta, phi = np.meshgrid(theta, phi)
        #Calculate scalar spherical harmonic
        Y = scp.sph_harm(m, l, phi, theta)

        if self.ComplexPartBox.get() == 'Real':
            Y = Y.real
        elif self.ComplexPartBox.get() == 'Imag':
            Y = Y.imag
        elif self.ComplexPartBox.get() == 'Mod':
            Y = np.sqrt(Y.real**2 + Y.imag**2)
        #Normalize to between 0 - 1
        Y_norm = (Y - Y.min()) / (Y.max() - Y.min())
        #Convert to Cartesian
        x = np.sin(theta) * np.cos(phi)
        y = np.sin(theta) * np.sin(phi)
        z = np.cos(theta)
        #Setup plot for 3D surface
        ax = self.Fig.gca(projection='3d')
        ax.plot_surface(x,
                        y,
                        z,
                        rstride=1,
                        cstride=1,
                        facecolors=cm.seismic(Y_norm))
        #Plot
        ax.set_axis_off()
        plt.gcf().canvas.draw()
Ejemplo n.º 40
0
    def __init__(self, sh_order, gradients, lb_lambda=0.006):
        super(Signal2SH, self).__init__()
        self.sh_order = sh_order
        self.lb_lambda = lb_lambda
        self.num_gradients = gradients.shape[0]
        self.num_coefficients = int(
            (self.sh_order + 1) * (self.sh_order / 2 + 1))

        b = np.zeros((self.num_gradients, self.num_coefficients))
        l = np.zeros((self.num_coefficients, self.num_coefficients))
        for id_gradient in range(self.num_gradients):
            id_column = 0
            for id_order in range(0, self.sh_order + 1, 2):
                for id_degree in range(-id_order, id_order + 1):
                    gradients_phi, gradients_theta, gradients_z = cart2sph(
                        gradients[id_gradient, 0], gradients[id_gradient, 1],
                        gradients[id_gradient, 2])
                    y = sci.sph_harm(np.abs(id_degree), id_order,
                                     gradients_phi, gradients_theta)

                    if id_degree < 0:
                        b[id_gradient, id_column] = np.real(y) * np.sqrt(2)
                    elif id_degree == 0:
                        b[id_gradient, id_column] = np.real(y)
                    elif id_degree > 0:
                        b[id_gradient, id_column] = np.imag(y) * np.sqrt(2)

                    l[id_column,
                      id_column] = self.lb_lambda * id_order**2 * (id_order +
                                                                   1)**2
                    id_column += 1

        b_inv = np.linalg.pinv(np.matmul(b.transpose(), b) + l)
        self.Signal2SHMat = torch.nn.Parameter(torch.from_numpy(
            np.matmul(b_inv, b.transpose()).transpose()).float(),
                                               requires_grad=False)
Ejemplo n.º 41
0
def spherical_harm(m, l, theta, phi):
    r""" Calculate the spherical harmonics using :math:`Y_l^m(\theta, \varphi)` with :math:`\mathbf R\to \{r, \theta, \varphi\}`.

    .. math::
        Y^m_l(\theta,\varphi) = (-1)^m\sqrt{\frac{2l+1}{4\pi} \frac{(l-m)!}{(l+m)!}}
             e^{i m \theta} P^m_l(\cos(\varphi))

    which is the spherical harmonics with the Condon-Shortley phase.

    Parameters
    ----------
    m : int
       order of the spherical harmonics
    l : int
       degree of the spherical harmonics
    theta : array_like
       angle in :math:`x-y` plane (azimuthal)
    phi : array_like
       angle from :math:`z` axis (polar)
    """
    # Probably same as:
    #return (-1) ** m * ( (2*l+1)/(4*pi) * factorial(l-m) / factorial(l+m) ) ** 0.5 \
    #    * lpmv(m, l, cos(theta)) * exp(1j * m * phi)
    return sph_harm(m, l, theta, phi) * (-1) ** m
Ejemplo n.º 42
0
def WaveFunction(x, y, z, n, l, m):

    # theta is azimuthal angle and phi is polar angle
    r, phi, theta = CoordinateConverter(x, y, z)
    # a is the Bohr radius in angstroms

    a = .529

    spherical = special.sph_harm(m, n, theta, phi)

    LaguerreOrder = 2 * l + 1
    LaguerrePoint = (2 * r) / (n * a)
    laguerre = special.assoc_laguerre(LaguerreOrder, LaguerrePoint)
    radial = sqrt(
        (2 / (n * a))**3 *
        (float(factorial(n - l - 1)) /
         (float(2 * n * (factorial(n + l))**3)))) * exp(-r /
                                                        (n * a)) * ((2 * r) /
                                                                    (n * a))**l

    value = radial * laguerre * spherical
    probability = abs(value)**2

    return probability
Ejemplo n.º 43
0
def spherical_harmonics(m, n, theta, phi):
    r""" Compute spherical harmonics

    This may take scalar or array arguments. The inputs will be broadcasted
    against each other.

    Parameters
    ----------
    m : int ``|m| <= n``
        The order of the harmonic.
    n : int ``>= 0``
        The degree of the harmonic.
    theta : float [0, 2*pi]
        The azimuthal (longitudinal) coordinate.
    phi : float [0, pi]
        The polar (colatitudinal) coordinate.

    Returns
    -------
    y_mn : complex float
        The harmonic $Y^m_n$ sampled at `theta` and `phi`.

    Notes
    -----
    This is a faster implementation of scipy.special.sph_harm for
    scipy version < 0.15.0.

    """
    if SCIPY_15_PLUS:
        return sph_harm(m, n, theta, phi)
    x = np.cos(phi)
    val = lpmv(m, n, x).astype(complex)
    val *= np.sqrt((2 * n + 1) / 4.0 / np.pi)
    val *= np.exp(0.5 * (gammaln(n - m + 1) - gammaln(n + m + 1)))
    val = val * np.exp(1j * m * theta)
    return val
Ejemplo n.º 44
0
from scipy.special import sph_harm
import numpy as np

x = 1
y = 1
z = 1

rxy2 = x * x + y * y
rxy = np.sqrt(rxy2)
r2 = rxy2 + z * z
r = np.sqrt(r2)
sinTheta = rxy / r
cosTheta = z / r
sinPsi = x / rxy
cosPsi = y / rxy
print("Y6m:")
for i in range(-6, 7):
    print(sph_harm(i, 6, np.arccos(cosPsi), np.arccos(cosTheta)))

print("Y4m:")
for i in range(-4, 5):
    print(sph_harm(i, 4, np.arccos(cosPsi), np.arccos(cosTheta)))
Ejemplo n.º 45
0
r = 0.3
pi = np.pi
cos = np.cos
sin = np.sin
phi, theta = np.mgrid[0:pi:101j, 0:2 * pi:101j]

x = r * sin(phi) * cos(theta)
y = r * sin(phi) * sin(theta)
z = r * cos(phi)

mlab.figure(1, bgcolor=(1, 1, 1), fgcolor=(0, 0, 0), size=(400, 300))
mlab.clf()
# Represent spherical harmonics on the surface of the sphere
for n in range(1, 6):
    for m in range(n):
        s = sph_harm(m, n, theta, phi).real

        mlab.mesh(x - m, y - n, z, scalars=s, colormap='jet')

        s[s < 0] *= 0.97

        s /= s.max()
        mlab.mesh(s * x - m,
                  s * y - n,
                  s * z + 1.3,
                  scalars=s,
                  colormap='Spectral')

mlab.view(90, 70, 6.2, (-1.3, -2.9, 0.25))
mlab.show()
Ejemplo n.º 46
0
    def populate_instance_response_matrix(self,
                                          truncated_nmax=None,
                                          truncated_nmin=None,
                                          truncated_lmax=None,
                                          truncated_lmin=None,
                                          usedefault=1):
        """
        Populate the R matrix for the default range of l and n, or
        or over the range specified above
        """

        if usedefault == 1:
            truncated_nmax = self.truncated_nmax
            truncated_nmin = self.truncated_nmin
            truncated_lmax = self.truncated_lmax
            truncated_lmin = self.truncated_lmin
            lms = self.lms
            kfilter = self.kfilter
        else:
            low_k_cutoff = truncated_nmin * self.Deltak
            high_k_cutoff = truncated_nmax * self.Deltak
            self.set_instance_k_filter(truncated_nmax=truncated_nmax,
                                       truncated_nmin=truncated_nmin)
            lms = [(l, m) for l in range(truncated_lmin, truncated_lmax + 1)
                   for m in range(-l, l + 1)]

        # Initialize R matrix:
        NY = (truncated_lmax + 1)**2 - (truncated_lmin)**2
        # Find the indices of the non-zero elements of the filter
        ind = np.where(self.kfilter > 0)
        # The n index spans 2x that length, 1st half for the cos coefficients, 2nd half
        #    for the sin coefficients
        NN = 2 * len(ind[1])
        R_long = np.zeros([NY, NN], dtype=np.complex128)

        # In case we need n1, n2, n3 at some point...:
        #    n1, n2, n3 = self.kx[ind]/self.Deltak , self.ky[ind]/self.Deltak, self.kz[ind]/self.Deltak
        k, theta, phi = self.k[ind], np.arctan2(
            self.ky[ind], self.kx[ind]), np.arccos(self.kz[ind] / self.k[ind])
        # We need to fix the 'nan' theta element that came from having ky=0
        theta[np.isnan(theta)] = np.pi / 2.0

        # Get ready to loop over y
        y = 0
        A = [sph_jn(truncated_lmax, ki)[0] for ki in k]
        # Loop over y, computing elements of R_yn
        for i in lms:
            l = i[0]
            m = i[1]
            trigpart = np.cos(np.pi * l / 2.0)
            B = np.asarray([A[ki][l] for ki in range(len(k))])
            R_long[y, :NN /
                   2] = 4.0 * np.pi * sph_harm(m, l, theta, phi).reshape(
                       NN / 2) * B.reshape(NN / 2) * trigpart

            trigpart = np.sin(np.pi * l / 2.0)
            R_long[y,
                   NN / 2:] = 4.0 * np.pi * sph_harm(m, l, theta, phi).reshape(
                       NN / 2) * B.reshape(NN / 2) * trigpart

            y = y + 1

        self.R = np.zeros([NY, len(ind[1])], dtype=np.complex128)
        self.R = np.append(R_long[:, 0:len(ind[1]) / 2],
                           R_long[:, len(ind[1]):3 * len(ind[1]) / 2],
                           axis=1)
        return
Ejemplo n.º 47
0
def gen_uniform_sample_sph_harm(n_samples, alpha, l, m, NSIDE = 4, savetofile = False, fname ='none'):
    """
    generate a user-defined random number of points on the celestial sphere distributed 
    according to spherical harmonics parameterized by l, m and alpha

    Parameters
    ----------
    n_samples : int
            the number of samples to generate
    alpha: float, array
            the weight to apply to spherical harmonic i
    l: int, array
            the l value for spherical harmonic i
    m: int, array
            the m value for spherical harmonic i, limited by l   
    NSIDE: int, must be a power of 2 and no greater than 8
            for healpix     
    savetofile: Bool
            save to file in current directory, true or false
    fname: string
            filename to save as, 'none' if savetofile = False
            
    Returns
    -------
    numpy ndarray
        table of RA and DEC in radians sampled from the desired linear combination of spherical harmonics
    """

    x = np.linspace(-np.pi, np.pi, 100)
    y = np.linspace(-np.pi/2, np.pi/2, 100)
    X, Y = np.meshgrid(x, y)

    # Spherical coordinate arrays derived from x, y
    # Necessary conversions to get Mollweide right
    phi = x.copy()    # physical copy
    phi[x < 0] = 2 * np.pi + x[x<0]
    theta = np.pi/2 - y
    PHI, THETA = np.meshgrid(phi, theta)

    SH_SP = np.zeros((100,100))

    assert len(alpha) == len(l) == len(m)

    for i in range(len(alpha)):
        sp_temp = alpha[i]*sph_harm(m[i],l[i], PHI, THETA).real
        SH_SP = SH_SP+sp_temp

    #turn the spherical harmonic map into a healpix map
    hpmap = make_map_vec(THETA, PHI, abs(SH_SP))

    theta_out = []
    phi_out = []

    while len(theta_out)<n_samples:

    #generate an ra and dec - should be an underlying uniform distribution
        u = np.random.uniform(0,1)
        v = np.random.uniform(0,1)
        ph = 2*np.pi*u
        th = np.arccos(2*v-1)

        #calculate the hp index of this theta and phi, and get it's value
        idx = hp.ang2pix(NSIDE, th, ph)
        pix_val = hpmap[idx]

        q = np.random.uniform(min(hpmap), max(hpmap))
        print(q)

        if pix_val>q:
            theta_out.append(th-np.pi/2)
            phi_out.append(ph)
        else:
            pass

    c = SkyCoord(ra=phi_out*units.radian, dec=theta_out*units.radian, frame='icrs')
    ra = c.ra
    #the sky is weird so wrap the angles at 180 degrees
    ra = ra.wrap_at(180*units.degree)
    dec = c.dec
    out = np.column_stack([ra.radian, dec.radian])

    if savetofile==True:
        if fname == 'none':
            raise ValueError('invalid file name')
        else:
            np.savetxt(fname, out)
    else:
        print('generated {} sky direction samples'.format(n_samples))
        
    return out
Ejemplo n.º 48
0
def compute_alpha(data, l, r_cut, qq_cut):
    """ 
  Computes alpha for all particles in data.  
  
  Parameters: 
    data (DataCollection): Ovito class with pipeline computation result.
    l (int): Spherical Harmonics order for Steinhardt parameter.
    r_cut (float): radial cutoff for neighbor finder.
    qq_cut (float): cutoff for product of Steinhardt vectors.
        
  Returns: 
    ndarray: value of alpha for each particle.
  """
    natoms = data.particles.count  # Total number of atoms.

    # Compute total number of neighbors of each atom.
    finder = CutoffNeighborFinder(cutoff=r_cut, data_collection=data)
    N_neigh = zeros(natoms, dtype=int)
    for iatom in range(natoms):
        for neigh in finder.find(iatom):
            N_neigh[iatom] += 1
    N_neigh_total = sum(N_neigh)

    # Unroll neighbor distances.
    r_ij = zeros((N_neigh_total, 3))  # Distance vectors to neighbors.
    d_ij = zeros(N_neigh_total)  # Distance to neighbors.
    neigh_list = zeros(N_neigh_total, dtype=int)  # ID of neighbors.
    ineigh = 0  # Neighbor counter.
    for iatom in range(natoms):
        for neigh in finder.find(iatom):
            r_ij[ineigh] = array(neigh.delta)
            d_ij[ineigh] = neigh.distance
            neigh_list[ineigh] = neigh.index
            ineigh += 1

    # Compute spherical harmonics for all neighbors of each atom.
    phi = arctan2(r_ij[:, 1], r_ij[:, 0])
    theta = arccos(r_ij[:, 2] / d_ij)
    Y = zeros((2 * l + 1, N_neigh_total), dtype=complex)
    for m in range(-l, l + 1):
        Y[m + l] = sph_harm(m, l, phi, theta)

    # Construct Steinhard vector by summing spherical harmonics.
    q = zeros((natoms, 2 * l + 1), dtype=complex)
    ineigh = 0
    for iatom in range(natoms):
        q[iatom] = sum(Y[:, ineigh:ineigh + N_neigh[iatom]], axis=1)
        ineigh += N_neigh[iatom]

    # Normalization.
    for m in range(2 * l + 1):
        q[:, m] /= N_neigh
    q = (q.T / norm(q, axis=1)).T

    # Classify bonds as crystal-like or not and compute alpha.
    alpha = zeros(natoms)  # Crystal-like fraction of bonds per atom.
    ineigh = 0
    for iatom in range(natoms):
        for jatom in neigh_list[ineigh:ineigh + N_neigh[iatom]]:
            qq = dot(q[iatom], conjugate(q[jatom])).real  # Im[qq] always 0.
            if qq > qq_cut: alpha[iatom] += 1.0
            ineigh += 1
    alpha /= N_neigh

    return alpha
Ejemplo n.º 49
0
import pygmt
import numpy as np
from scipy.special import sph_harm
from numpy.random import random_sample

#come up with n random points on a sphere
n=10000
x = random_sample(n)-0.5
y = random_sample(n)-0.5
z = random_sample(n)-0.5
lats = np.arccos( z/np.sqrt(x*x+y*y+z*z))
lons = np.arctan2( y, x )+np.pi

#evaluate a spherical harmonic on that sphere
vals = sph_harm(4,9, lons, lats).real
vals = vals/np.amax(vals)

lons = lons*180.0/np.pi
lats = 90.0-lats*180.0/np.pi

#recover the spherical harmonic with contouring
fig = pygmt.GMT_Figure("output.ps", figure_range='g', projection='G-75/41/7i', verbosity=2)
dataset = fig.blockmean('-I5/5 -Rg', [lons,lats,vals])
grid = fig.surface('-I5/5 -Rg', dataset)
c = fig.grd2cpt('-Chot', grid, output=None)
fig.grdimage('-E100i', grid, cpt=c)
fig.grdcontour('-Wthick,black -C0.2', grid)
fig.psxy('-Sp.1c', [lons,lats,vals])

fig.close()
Ejemplo n.º 50
0
def getLBP3DImage(inputImage, inputMask, **kwargs):
  """
  Compute and return the Local Binary Pattern (LBP) in 3D using spherical harmonics.
  If ``force2D`` is set to true (= feature extraction in 2D) a warning is logged.

  LBP is only calculated for voxels segmented in the mask

  Following settings are possible:

    - ``lbp3DLevels`` [2]: integer, specifies the the number of levels in spherical harmonics to use.
    - ``lbp3DIcosphereRadius`` [1]: Float, specifies the radius in which the neighbours should be sampled
    - ``lbp3DIcosphereSubdivision`` [1]: Integer, specifies the number of subdivisions to apply in the icosphere

  :return: Yields LBP filtered image for each level, 'lbp-3D-m<level>' and ``kwargs`` (customized settings).
           Additionally yields the kurtosis image, 'lbp-3D-k' and ``kwargs``.

  .. note::
    LBP can often return only a very small number of different gray levels. A customized bin width is often needed.
  .. warning::
    Requires package ``scipy`` and ``trimesh`` to function. If not available, this filter logs a warning and does not
    yield an image.

  References:

  - Banerjee, J, Moelker, A, Niessen, W.J, & van Walsum, T.W. (2013), "3D LBP-based rotationally invariant region
    description." In: Park JI., Kim J. (eds) Computer Vision - ACCV 2012 Workshops. ACCV 2012. Lecture Notes in Computer
    Science, vol 7728. Springer, Berlin, Heidelberg. doi:10.1007/978-3-642-37410-4_3
  """
  global logger
  try:
    from scipy.stats import kurtosis
    from scipy.ndimage.interpolation import map_coordinates
    from scipy.special import sph_harm
    from trimesh.creation import icosphere
  except ImportError:
    logger.warning('Could not load required package "scipy" or "trimesh", cannot implement filter LBP 3D')
    return

  # Warn the user if features are extracted in 2D, as this function calculates LBP in 3D
  if kwargs.get('force2D', False):
    logger.warning('Calculating Local Binary Pattern in 3D, but extracting features in 2D. Use with caution!')

  label = kwargs.get('label', 1)

  lbp_levels = kwargs.get('lbp3DLevels', 2)
  lbp_icosphereRadius = kwargs.get('lbp3DIcosphereRadius', 1)
  lbp_icosphereSubdivision = kwargs.get('lbp3DIcosphereSubdivision', 1)

  im_arr = sitk.GetArrayFromImage(inputImage)
  ma_arr = sitk.GetArrayFromImage(inputMask)

  # Variables used in the shape comments:
  # Np Number of voxels
  # Nv Number of vertices

  # Vertices icosahedron for spherical sampling
  coords_icosahedron = numpy.array(icosphere(lbp_icosphereSubdivision, lbp_icosphereRadius).vertices)  # shape(Nv, 3)

  # Corresponding polar coordinates
  theta = numpy.arccos(numpy.true_divide(coords_icosahedron[:, 2], lbp_icosphereRadius))
  phi = numpy.arctan2(coords_icosahedron[:, 1], coords_icosahedron[:, 0])

  # Corresponding spherical harmonics coefficients Y_{m, n, theta, phi}
  Y = sph_harm(0, 0, theta, phi)  # shape(Nv,)
  n_ix = numpy.array(0)

  for n in range(1, lbp_levels):
    for m in range(-n, n + 1):
      n_ix = numpy.append(n_ix, n)
      Y = numpy.column_stack((Y, sph_harm(m, n, theta, phi)))
  # shape (Nv, x) where x is the number of iterations in the above loops + 1

  # Get labelled coordinates
  ROI_coords = numpy.where(ma_arr == label)  # shape(3, Np)

  # Interpolate f (samples on the spheres across the entire volume)
  coords = numpy.array(ROI_coords).T[None, :, :] + coords_icosahedron[:, None, :]  # shape(Nv, Np, 3)
  f = map_coordinates(im_arr, coords.T, order=3)  # Shape(Np, Nv)  Note that 'Np' and 'Nv' are swapped due to .T

  # Compute spherical Kurtosis
  k = kurtosis(f, axis=1)  # shape(Np,)

  # Apply sign function
  f_centroids = im_arr[ROI_coords]  # Shape(Np,)
  f = numpy.greater_equal(f, f_centroids[:, None]).astype(int)  # Shape(Np, Nv)

  # Compute c_{m,n} coefficients
  c = numpy.multiply(f[:, :, None], Y[None, :, :])  # Shape(Np, Nv, x)
  c = c.sum(axis=1)  # Shape(Np, x)

  # Integrate over m
  f = numpy.multiply(c[:, None, n_ix == 0], Y[None, :, n_ix == 0])  # Shape (Np, Nv, 1)
  for n in range(1, lbp_levels):
    f = numpy.concatenate((f,
                           numpy.sum(numpy.multiply(c[:, None, n_ix == n], Y[None, :, n_ix == n]),
                                     axis=2, keepdims=True)
                           ),
                          axis=2)
  # Shape f (Np, Nv, levels)

  # Compute L2-Norm
  f = numpy.sqrt(numpy.sum(f ** 2, axis=1))  # shape(Np, levels)

  # Keep only Real Part
  f = numpy.real(f)  # shape(Np, levels)
  k = numpy.real(k)  # shape(Np,)

  # Yield the derived images for each level
  result = numpy.ndarray(im_arr.shape)
  for l_idx in range(lbp_levels):
    result[ROI_coords] = f[:, l_idx]

    # Create a SimpleITK image
    im = sitk.GetImageFromArray(result)
    im.CopyInformation(inputImage)

    yield im, 'lbp-3D-m%d' % (l_idx + 1), kwargs

  # Yield Kurtosis
  result[ROI_coords] = k

  # Create a SimpleITK image
  im = sitk.GetImageFromArray(result)
  im.CopyInformation(inputImage)

  yield im, 'lbp-3D-k', kwargs
Ejemplo n.º 51
0
def vect2Ylm(v, l):
    """Projects vectors v on the base of spherical harmonics of degree l."""
    spherical = cart2sph(v)
    return sph_harm(
        np.arange(l + 1)[:, None], l, spherical[:, 2][None, :],
        spherical[:, 1][None, :])
Ejemplo n.º 52
0
from scipy import special
import pylab as p
import matplotlib.axes3d as p3

phi = linspace(0, 2 * pi, 50)
theta = linspace(-pi / 2, pi / 2, 200)

ax = []
ay = []
az = []
R = 1.0
for t in theta:
    polar = float(t)
    for k in phi:
        azim = float(k)
        sph = special.sph_harm(0, 5, azim, polar)  # Y(m,l,phi,theta)
        modulation = 0.2 * abs(sph)
        r = R * (1 + modulation)
        x = r * cos(polar) * cos(azim)
        y = r * cos(polar) * sin(azim)
        z = r * sin(polar)
        #		print z
        #		print x,y,z
        ax.append(x)
        ay.append(y)
        az.append(z)
fig = p.figure()
f = p3.Axes3D(fig)
f.set_xlabel('X')
f.set_ylabel('Y')
f.set_zlabel('Z')
def csh(l, m, theta, phi, normalization='quantum', condon_shortley=True):
    """
    Compute Complex Spherical Harmonics (CSH) Y_l^m(theta, phi).
    Unlike the scipy.special.sph_harm function, we use the common convention that
    theta is the polar angle (0 to pi) and phi is the azimuthal angle (0 to 2pi).

    The spherical harmonic 'backbone' is:
    Y_l^m(theta, phi) = P_l^m(cos(theta)) exp(i m phi)
    where P_l^m is the associated Legendre function as defined in the scipy library (scipy.special.sph_harm).

    Various normalization factors can be multiplied with this function.
    -> seismology: sqrt( ((2 l + 1) * (l - m)!) / (4 pi * (l + m)!) )
    -> quantum: (-1)^2 sqrt( ((2 l + 1) * (l - m)!) / (4 pi * (l + m)!) )
    -> unnormalized: 1
    -> geodesy: sqrt( ((2 l + 1) * (l - m)!) / (l + m)! )
    -> nfft: sqrt( (l - m)! / (l + m)! )

    The 'quantum' and 'seismology' CSH are normalized so that
    <Y_l^m, Y_l'^m'>
    =
    int_S^2 Y_l^m(theta, phi) Y_l'^m'* dOmega
    =
    delta(l, l') delta(m, m')
    where dOmega is the volume element for the sphere S^2:
    dOmega = sin(theta) dtheta dphi
    The 'geodesy' convention have unit power, meaning the norm is equal to the surface area of the unit sphere (4 pi)
    <Y_l^m, Y_l'^m'> = 4pi delta(l, l') delta(m, m')

    On each of these normalizations, one can optionally include a Condon-Shortley phase factor:
    (-1)^m   (if m > 0)
    1        (otherwise)
    Note that this is the definition of Condon-Shortley according to wikipedia [1], but other sources call a
    phase factor of (-1)^m a Condon-Shortley phase (without mentioning the condition m > 0).

    References:
    [1] http://en.wikipedia.org/wiki/Spherical_harmonics#Conventions

    :param l: non-negative integer; the degree of the CSH.
    :param m: integer, -l <= m <= l; the order of the CSH.
    :param theta: the colatitude / polar angle,
    ranging from 0 (North Pole, (X,Y,Z)=(0,0,1)) to pi (South Pole, (X,Y,Z)=(0,0,-1)).
    :param phi: the longitude / azimuthal angle, ranging from 0 to 2 pi.
    :param normalization: how to normalize the CSH:
    'seismology', 'quantum', 'geodesy', 'unnormalized', 'nfft'.
    :return: the value of the complex spherical harmonic Y^l_m(theta, phi)
    """
    if normalization == 'quantum':
        # y = ((-1) ** m) * sph_harm(m, l, theta=phi, phi=theta)
        y = ((-1) ** m) * sph_harm(m, l, phi, theta)
    elif normalization == 'seismology':
        # y = sph_harm(m, l, theta=phi, phi=theta)
        y = sph_harm(m, l, phi, theta)
    elif normalization == 'geodesy':
        # y = np.sqrt(4 * np.pi) * sph_harm(m, l, theta=phi, phi=theta)
        y = np.sqrt(4 * np.pi) * sph_harm(m, l, phi, theta)
    elif normalization == 'unnormalized':
        # y = sph_harm(m, l, theta=phi, phi=theta) / np.sqrt((2 * l + 1) * factorial(l - m) /
        #                                                    (4 * np.pi * factorial(l + m)))
        y = sph_harm(m, l, phi, theta) / np.sqrt((2 * l + 1) * factorial(l - m) /
                                                           (4 * np.pi * factorial(l + m)))
    elif normalization == 'nfft':
        # y = sph_harm(m, l, theta=phi, phi=theta) / np.sqrt((2 * l + 1) / (4 * np.pi))
        y = sph_harm(m, l, phi, theta) / np.sqrt((2 * l + 1) / (4 * np.pi))
    else:
        raise ValueError('Unknown normalization convention:' + str(normalization))

    if condon_shortley:
        # The sph_harm function already includes CS phase
        return y
    else:
        # Cancel the CS phase in sph_harm (i.e. multiply by -1 when m is both odd and greater than 0)
        return y * ((-1) ** (m * (m > 0)))
Ejemplo n.º 54
0
def pairSphereHarms(a, b, l):
    theta, phi = sphang(a, b)
    print theta, phi
    return special.sph_harm(np.array(range(-l, l + 1)), l, theta, phi)
Ejemplo n.º 55
0
def main():
    # make environment
    fw_t = open("time_log",mode="w")
    t1 = time.time()
  
    pot_region,bound_rad,radius,region,nr,gridpx,gridpy,gridpz,x,y,z,xx,yy,zz,a,b,rofi,pot_type,pot_bottom,pot_show_f,si_method,radial_pot_show_f,new_radial_pot_show_f,node_open,node_close,LMAX = make_environment()

    # make potential
    V = makepotential(xx,yy,zz,pot_region,pot_type=pot_type,pot_bottom=pot_bottom,pot_show_f=pot_show_f)

    # surface integral
    V_radial = surfaceintegral(x,y,z,rofi,V,si_method=si_method,radial_pot_show_f=radial_pot_show_f)

    V_radial_new = make_V_radial_new(V_radial,rofi,pot_region,bound_rad,new_radial_pot_show_f=new_radial_pot_show_f)

    vofi = np.array (V_radial_new)  # select method of surface integral

    # make basis
    node = node_open + node_close
    nstates = node * LMAX**2

    all_basis = make_basis(LMAX,node_open,node_close,nr,a,b,rofi,vofi)
 
    #make spherical matrix element
    Smat = np.zeros((LMAX,LMAX,node,node),dtype = np.float64)
    hsmat = np.zeros((LMAX,LMAX,node,node),dtype = np.float64)
    lmat = np.zeros((LMAX,LMAX,node,node), dtype = np.float64)
    qmat = np.zeros((LMAX,LMAX,node,node), dtype = np.float64)

    for l1 in range (LMAX):
        for l2 in range (LMAX):
            if l1 != l2 :
                continue
            for n1 in range (node):
                for n2 in range (node):
                    if all_basis[l1][n1].l != l1 or all_basis[l2][n2].l != l2:
                        print("error: L is differnt")
                        sys.exit()
                    Smat[l1][l2][n1][n2] = integrate(all_basis[l1][n1].g[:nr] * all_basis[l2][n2].g[:nr],rofi,nr)
                    hsmat[l1][l2][n1][n2] = Smat[l1][l2][n1][n2] * all_basis[l2][n2].e
                    lmat[l1][l2][n1][n2] = all_basis[l1][n1].val * all_basis[l2][n2].slo
                    qmat[l1][l2][n1][n2] = all_basis[l1][n1].val * all_basis[l2][n2].val
    print("\nSmat")
    print(Smat)
    print ("\nhsmat")
    print (hsmat)
    print ("\nlmat")
    print (lmat)
    print ("\nqmat")
    print (qmat)

    hs_L = np.zeros((LMAX,LMAX,node,node))
    """
    for l1 in range(LMAX):
        for n1 in range(node):
            for l2 in range(LMAX):
                for n2 in range(node):
                    print("{:>8.4f}".format(lmat[l1][l2][n1][n2]),end="")
            print("")
    print("")
    """
    print("hs_L")
    for l1 in range(LMAX):
        for n1 in range(node):
            for l2 in range(LMAX):
                for n2 in range(node):
                    hs_L[l1][l2][n1][n2] = hsmat[l1][l2][n1][n2] + lmat[l1][l2][n1][n2]
                    print("{:>8.4f}".format(hs_L[l1][l2][n1][n2]),end="")
            print("")
    

    t2 = time.time()
    fw_t.write("make environment, make basis and calculate spherical matrix element\n")
    fw_t.write("time = {:>11.8}s\n".format(t2-t1))
    t1 = time.time()


    #make not spherical potential
    my_radial_interfunc = interpolate.interp1d(rofi, V_radial_new)

    V_ang = np.where(np.sqrt(xx * xx + yy * yy + zz * zz) < rofi[-1] , V - my_radial_interfunc(np.sqrt(xx **2 + yy **2 + zz **2)),0. )
    """
    for i in range(gridpx):
        for j in range(gridpy):
            for k in range(gridpz):
                print(V_ang[i][j][k],end="  ")
            print("")
        print("\n")
    sys.exit()
    """

    #WARING!!!!!!!!!!!!!!!!!!!!!!
    """
    Fujikata rewrote ~/.local/lib/python3.6/site-packages/scipy/interpolate/interpolate.py line 690~702
    To avoid exit with error "A value in x_new is below the interpolation range."
    """
    #!!!!!!!!!!!!!!!!!!!!!!!!!!!

    """
    with open ("V_ang.dat",mode = "w") as fw_a:
        for i in range(len(V_ang)):
            fw_a.write("{:>13.8f}".format(xx[50][i][50]))
            fw_a.write("{:>13.8f}\n".format(V_ang[i][50][50]))
    """

    #mayavi.mlab.plot3d(xx,yy,V_ang)
#    mlab.contour3d(V_ang,color = (1,1,1),opacity = 0.1)
#    obj = mlab.volume_slice(V_ang)
#    mlab.show()

    ngrid = 10
    fw_u = open("umat_gauss.dat",mode="w")

    umat = np.zeros((node,node,LMAX,LMAX,2 * LMAX + 1,2 * LMAX + 1), dtype = np.complex64)


    igridpx = ngrid
    igridpy = ngrid
    igridpz = ngrid

    gauss_px,gauss_wx = np.polynomial.legendre.leggauss(igridpx)
    gauss_py,gauss_wy = np.polynomial.legendre.leggauss(igridpy)
    gauss_pz,gauss_wz = np.polynomial.legendre.leggauss(igridpz)

    ix,iy,iz = gauss_px * pot_region[0],gauss_py * pot_region[1],gauss_pz * pot_region[2]
    ixx,iyy,izz = np.meshgrid(ix,iy,iz)

    gauss_weight = np.zeros((igridpx,igridpy,igridpz))
    for i in range(igridpx):
        for j in range(igridpy):
            for k in range(igridpz):
                gauss_weight[i][j][k] = gauss_wx[i] * gauss_wy[j] * gauss_wz[k]

    #my_V_ang_inter_func = RegularGridInterpolator((x, y, z), V_ang)
    #V_ang_i = my_V_ang_inter_func((ixx,iyy,izz))

    V_ang_i = np.zeros((igridpx,igridpy,igridpz))
    V_ang_i = -1. - my_radial_interfunc(np.sqrt(ixx * ixx + iyy * iyy + izz * izz))



    #mlab.contour3d(V_ang_i,color = (1,1,1),opacity = 0.1)
    #obj = mlab.volume_slice(V_ang_i)
    #mlab.show()

    dis = np.sqrt(ixx **2 + iyy **2 + izz **2)
    dis2 = ixx **2 + iyy **2 + izz **2
    theta = np.where( dis != 0., np.arccos(izz / dis), 0.)
    phi = np.where( iyy**2 + ixx **2 != 0 , np.where(iyy >= 0, np.arccos(ixx / np.sqrt(ixx **2 + iyy **2)), np.pi + np.arccos(ixx / np.sqrt(ixx **2 + iyy **2))), 0.)
    #phi = np.where( iyy != 0. , phi, 0.)
    #phi = np.where(iyy > 0, phi,-phi)
#    region_t = np.where(dis < rofi[-1],1,0)
    sph_harm_mat = np.zeros((LMAX,2 * LMAX + 1, igridpx,igridpy,igridpz),dtype = np.complex64)
    for l1 in range (LMAX):
        for m1 in range (-l1,l1 + 1):
            sph_harm_mat[l1][m1] = np.where(dis != 0., sph_harm(m1,l1,phi,theta),0.)
    g_ln_mat = np.zeros((node,LMAX,igridpx,igridpy,igridpz),dtype = np.float64)
    for n1 in range (node):
        for l1 in range (LMAX):
            my_radial_g_inter_func = interpolate.interp1d(rofi,all_basis[l1][n1].g[:nr])
            g_ln_mat[n1][l1] = my_radial_g_inter_func(np.sqrt(ixx **2 + iyy **2 + izz **2))


    for n1 in range (node):
        for n2 in range (node):
            for l1 in range (LMAX):
                for l2 in range (LMAX):
                    if all_basis[l1][n1].l != l1 or all_basis[l2][n2].l != l2:
                        print("error: L is differnt")
                        sys.exit()
                    # to avoid nan in region where it can not interpolate ie: dis > rofi
                    g_V_g = np.where(dis < rofi[-1], g_ln_mat[n1][l1] * V_ang_i * g_ln_mat[n2][l2], 0.)
                    for m1 in range (-l1,l1+1):
                        for m2 in range (-l2,l2+1):
                            #print("n1 = {} n2 = {} l1 = {} l2 = {} m1 = {} m2 = {}".format(n1,n2,l1,l2,m1,m2))
                            umat[n1][n2][l1][l2][m1][m2] = np.sum(np.where( dis2 != 0., sph_harm_mat[l1][m1].conjugate() * g_V_g * sph_harm_mat[l2][m2] / dis2 * gauss_weight, 0.)) * pot_region[0] * pot_region[1] * pot_region[2] 
                            #print(umat[n1][n2][l1][l2][m1][m2])
    count = 0
    for l1 in range (LMAX):
        for l2 in range (LMAX):
            for m1 in range (-l1,l1+1):
                for m2 in range (-l2,l2+1):
                    for n1 in range (node):
                        for n2 in range (node):
                            fw_u.write(str(count))
                            fw_u.write("{:>15.8f}{:>15.8f}\n".format(umat[n1][n2][l1][l2][m1][m2].real,umat[n1][n2][l1][l2][m1][m2].imag))
                            count += 1


    fw_u.close()

    t2 = time.time()
    fw_t.write("calculate U-matrix\n")
    fw_t.write("grid = {:<5} time ={:>11.8}s\n".format(ngrid,t2 - t1))
    t1 = time.time()


    
    ham_mat = np.zeros((nstates * nstates),dtype = np.float64)
    qmetric_mat = np.zeros((nstates * nstates),dtype = np.float64)
    for l1 in range(LMAX):
        for m1 in range (-l1,l1+1):
            for n1 in range(node):
                for l2 in range(LMAX):
                    for m2 in range(-l2,l2+1):
                        for n2 in range(node):
                            if l1 == l2 and m1 == m2 :
                                ham_mat[l1 **2 * node * LMAX**2 * node + (l1 + m1) * node * LMAX**2 * node + n1 * LMAX**2 * node + l2 **2 * node + (l2 + m2) * node + n2] += hs_L[l1][l2][n1][n2]
                                qmetric_mat[l1 **2 * node * LMAX**2 * node + (l1 + m1) * node * LMAX**2 * node + n1 * LMAX**2 * node + l2 **2 * node + (l2 + m2) * node + n2] = qmat[l1][l2][n1][n2]
                            ham_mat[l1 **2 * node * LMAX**2 * node + (l1 + m1) * node * LMAX**2 * node + n1 * LMAX**2 * node + l2 **2 * node + (l2 + m2) * node + n2] += umat[n1][n2][l1][l2][m1][m2].real

    lambda_mat = np.zeros(nstates * nstates,dtype = np.float64)
    alphalong = np.zeros(nstates)
    betalong = np.zeros(nstates)
    alpha = np.zeros(LMAX**2)
    beta = np.zeros(LMAX**2)
    reveclong = np.zeros(nstates * nstates)
    revec = np.zeros((LMAX**2,nstates))

    for e_num in range(1,2):
        E = e_num * 1
        lambda_mat = np.zeros(nstates * nstates,dtype = np.float64)
        lambda_mat -= ham_mat
        """
        for i in range(nstates):
            lambda_mat[i + i * nstates] += E
        """
        count = 0
        fw_lam = open("lambda.dat",mode="w")

        for l1 in range(LMAX):
            for m1 in range (-l1,l1+1):
                for n1 in range(node):
                    for l2 in range(LMAX):
                        for m2 in range(-l2,l2+1):
                            for n2 in range(node):
                                if l1 == l2 and m1 == m2 :
                                    lambda_mat[l1 **2 * node * LMAX**2 * node + (l1 + m1) * node * LMAX**2 * node + n1 * LMAX**2 * node + l2 **2 * node + (l2 + m2) * node + n2] += Smat[l1][l2][n1][n2] * E
                                fw_lam.write(str(count))
                                fw_lam.write("{:>15.8f}\n".format(lambda_mat[l1 **2 * node * LMAX**2 * node + (l1 + m1) * node * LMAX**2 * node + n1 * LMAX**2 * node + l2 **2 * node + (l2 + m2) * node + n2]))
                                count += 1
        fw_lam.close()
 
        
        info = solve_genev(nstates,lambda_mat,qmetric_mat,alphalong,betalong,reveclong)

        print("info = ",info)
        print("alphalong")
        print(alphalong)
        print("betalong")
        print(betalong)
        #print(revec)
        
        k = 0
        jk = np.zeros(nstates,dtype=np.int32) 
        for i in range(nstates):
            if abs(betalong[i]) > BETAZERO :
                jk[k] = i
                k += 1

        if k != LMAX**2:
            print(" main PANIC: solution of genev has rank k != nchannels ")
            sys.exit()

        for k in range(LMAX**2):
            j = jk[k]
            alpha[k] = alphalong[j]
            beta[k]  = betalong[j]
            revec[k] = reveclong[j * nstates : (j + 1) * nstates]




        fw_revec = open("revec.dat",mode="w")
        print("revec")
        for j in range(nstates):
            fw_revec.write("{:>4}".format(j))
            for i in range(LMAX**2):
                fw_revec.write("{:>13.8f}".format(revec[i][j]))
                print("{:>11.6f}".format(revec[i][j]),end="")
            print("")
            fw_revec.write("\n")
        print("")
        fw_revec.close()

        t2 = time.time()
        fw_t.write("solve eigenvalue progrem\n")
        fw_t.write("time = {:>11.8}s\n".format(t2-t1))
        fw_t.close()
Ejemplo n.º 56
0
def sphCalc(Lmax, Lmin=0, res=None, angs=None, XFlag=True):
    '''
    Calculate set of spherical harmonics Ylm(theta,phi) on a grid.

    Parameters
    ----------
    Lmax : int
        Maximum L for the set. Ylm calculated for Lmin:Lmax, all m.
    Lmin : int, optional, default 0
        Min L for the set. Ylm calculated for Lmin:Lmax, all m.
    res : int, optional, default None
        (Theta, Phi) grid resolution, outputs will be of dim [res,res].
    angs : list of 2D np.arrays, [thetea, phi], optional, default None
        If passed, use these grids for calculation
    XFlag : bool, optional, default True
        Flag for output. If true, output is Xarray. If false, np.arrays

    Note that either res OR angs needs to be passed.

    Outputs
    -------
    - if XFlag -
    YlmX
        3D Xarray, dims (lm,theta,phi)
    - else -
    Ylm, lm
        3D np.array of values, dims (lm,theta,phi), plus list of lm pairs

    Methods
    -------
    Currently set for scipy.special.sph_harm as calculation routine.

    Example
    -------
    >>> YlmX = sphCalc(2, res = 50)

    '''

    # Set coords based on inputs
    # TODO: better code here (try/fail?)
    if angs is None and res:
        theta, phi = np.meshgrid(np.linspace(0, 2 * np.pi, res),
                                 np.linspace(0, np.pi, res))
    elif res is None and angs:
        theta = angs[0]
        phi = angs[1]
    else:
        print('Need to pass either res or angs.')
        return False

    # Loop over lm and calculate
    lm = []
    Ylm = []
    for l in np.arange(Lmin, Lmax + 1):
        for m in np.arange(-l, l + 1):
            lm.append([l, m])
            Ylm.append(sph_harm(m, l, theta, phi))

    # Return as Xarray or np arrays.
    if XFlag:
        # Set indexes
        QNs = pd.MultiIndex.from_arrays(np.asarray(lm).T, names=['l', 'm'])
        YlmX = xr.DataArray(np.asarray(Ylm),
                            coords=[('LM', QNs), ('Theta', theta[0, :]),
                                    ('Phi', phi[:, 0])])
        return YlmX
    else:
        return np.asarray(Ylm), np.asarray(lm)
Ejemplo n.º 57
0
def sph_harm_(m, n, theta, phi):
    y = sph_harm(m, n, theta, phi)
    return (y.real, y.imag)
# In[105]:

U_tilde(ks_mesh, pp + theta_mesh, Lk, 0, 1, 1, 0).shape

# In[106]:

sph_harmY(1, 1, ([2, 3, 6]), 7)

# In[107]:

for i in range(0, len(theta_mesh)):
    print sph_harmY(1, 1, theta_mesh[i], phi_mesh[i])

# In[108]:

sph_harm(1, 1, phi_mesh, theta_mesh)

##### sph_harm does not produce a matrix over theta and phi as we would like, but instead takes corresponding element from theta array and the phi array. To get around this, precalculate and store the spherical harmonics. This will also speed up the program compared to calculating spherical harmonics each time on fly. As has been previously established, calculation of spherical harmonics is time intensive.

# In[109]:

sph_harm_theta_phi = np.zeros((6, 11, 10, 10), dtype='complex128')

# In[110]:

sph_harm_1 = np.zeros(10)

# In[111]:

sph_harm_1[:] = sph_harm(1, 1, phi_mesh, theta_mesh[1])
Ejemplo n.º 59
0
#!/bin/python
#spherical_harmonics.py

import scipy as sci
import scipy.special as sp
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm, colors

# Graphically represent spherical harmonics
l = 4
m = 2
theta, phi = 0.6, 0.75  # Some arbitrary values of angles in radians
Y42 = sp.sph_harm(m, l, phi, theta)
PHI, THETA = np.mgrid[0:2 * np.pi:200j,
                      0:np.pi:100j]  #arrays of angular variables
R = np.abs(sp.sph_harm(m, l, PHI,
                       THETA))  #Array with the absolute values of Ylm
#Now we convert to cartesian coordinates
# for the 3D representation
X = R * np.sin(THETA) * np.cos(PHI)
Y = R * np.sin(THETA) * np.sin(PHI)
Z = R * np.cos(THETA)

N = R / R.max(
)  # Normalize R for the plot colors to cover the entire range of colormap.
fig, ax = plt.subplots(subplot_kw=dict(projection='3d'), figsize=(12, 10))
im = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, facecolors=cm.jet(N))
ax.set_title(r'$|Y^2_ 4|$', fontsize=20)
def sph_harmY(l, m, theta, phi):
    if abs(m) <= abs(l):
        return sph_harm(m, l, phi, theta)
    else:
        return 0.0