def fourier3D(coordinates,L,frequencies):


    # Note, that I do not perform the calculation below on the central particle
    # Messes with results!
    
    N = coordinates.shape[0]-1;
    
    if N == 0:
        return [0]
    
    # Note.  The first coordinates is the center particle.
    #Translate all coordinates so the center is the origin
    coordinates = coordinate_helper.pbc(coordinates[1:,:]-coordinates[0,:],L)

    #-- STEP 1 - Convert to spherical  coordinates
    # calculate the radial distance of all the coordinates
    r = np.linalg.norm(coordinates)                            #Radial
    phi = np.arctan2(coordinates[:,1],coordinates[:,0]) +np.pi #Azimuthal
    theta = np.arccos(coordinates[:,2]/r)                      #Inclination

    #-- STEP 2: compute Ylm(theta, phi) for each theta, phi

    # Using spherical harmonic function provided by scipy
    #http://docs.scipy.org/doc/scipy-0.16.0/reference/generated/scipy.special.sph_harm.html

    # scipy.special.sph_harm(m, l, azimuthal, polar) azimuthal in [0,2pi], polar in [0,pi]  (n == l)

    # NEED MORE WORK BELOW

    # In the original smac code, for a given frequency l, loops over the n particles, and over m values from -l to +l, and then applies a "q" invarinace that combines all the m values generated for all the particles.

    shape_descriptor= []
    for l in frequencies:

        components = np.zeros(shape=(coordinates.shape[0],2*l+1,2))
        
        for m in range(-l,l+1):
            w = 1.0
            ylm = sp.sph_harm(m,l,phi,theta)
            components[:,m,0] = w*ylm.real
            components[:,m,1] = w*ylm.imag


        # Summing over all the particles
        ylm_average = np.sum(components,axis=0)/components.shape[0]

        # Applying invariance
        # computes the "q" invariant for a 3d fourier coefficient
        sd = np.sqrt(4.0*np.pi/ylm.shape[1]*np.sum(ylm_average**2))
        shape_descriptor.append(sd)


    return shape_descriptor



    
Exemple #2
0
    def calculate(self, coordinates, L, N):

        # Calculate RDF  - Doing this Brute Force for now - no cell list
        
        # radial position of the bin
        x_i = np.array(range(self.maxbin))*self.dr
        hist = np.zeros(self.maxbin)

        # Convienent Lambdas
        makeint = lambda x: int(x)
        
        # Note that currently all distances are being calculated twice.
        # If I change this, need to double the weight of the count in the histogram
        for rollval in range(1,N):
        
            dd = np.array(map(sub, coordinates, np.roll(coordinates,rollval,axis=0)))  # Box Periodicity is not used right now
            
            dd = coordinate_helper.pbc(dd,L)

            rij = np.linalg.norm(dd, axis=1)
            
            # DEBUGGING
            mask = rij < 0.5
            if sum(mask) :
                print
                print coordinates[mask], np.roll(coordinates,rollval,axis=0)[mask], dd[mask]
            
            
            bin = map(makeint, rij/self.dr)

            for b in bin:
                if b < self.maxbin :
                    hist[b] += 1
    
    
        # Calculate the array of normalization factors
        delta = self.dr/2.
        # density
        number_density = float(N)/np.product(L)
        
        volume_shell = 4./3.*np.pi*np.power(x_i+delta, 3) - 4./3.*np.pi*np.power(x_i-delta, 3);
        
        # Correction for first shell
        volume_shell[0] += 4./3.*np.pi*np.power(-delta, 3);
        
        np_ideal_gas = number_density * volume_shell;
        normalization =  np_ideal_gas * N;

        hist /= normalization;

        self.x_i = x_i
        self.hist = hist
        return x_i,hist
Exemple #3
0
def fourier3D(coordinates, L, frequencies):

    # Note, that I do not perform the calculation below on the central particle
    # Messes with results!

    N = coordinates.shape[0] - 1

    if N == 0:
        return [0]

    # Note.  The first coordinates is the center particle.
    #Translate all coordinates so the center is the origin
    coordinates = coordinate_helper.pbc(coordinates[1:, :] - coordinates[0, :],
                                        L)

    #-- STEP 1 - Convert to spherical  coordinates
    # calculate the radial distance of all the coordinates
    r = np.linalg.norm(coordinates)  #Radial
    phi = np.arctan2(coordinates[:, 1], coordinates[:, 0]) + np.pi  #Azimuthal
    theta = np.arccos(coordinates[:, 2] / r)  #Inclination

    #-- STEP 2: compute Ylm(theta, phi) for each theta, phi

    # Using spherical harmonic function provided by scipy
    #http://docs.scipy.org/doc/scipy-0.16.0/reference/generated/scipy.special.sph_harm.html

    # scipy.special.sph_harm(m, l, azimuthal, polar) azimuthal in [0,2pi], polar in [0,pi]  (n == l)

    # NEED MORE WORK BELOW

    # In the original smac code, for a given frequency l, loops over the n particles, and over m values from -l to +l, and then applies a "q" invarinace that combines all the m values generated for all the particles.

    shape_descriptor = []
    for l in frequencies:

        components = np.zeros(shape=(coordinates.shape[0], 2 * l + 1, 2))

        for m in range(-l, l + 1):
            w = 1.0
            ylm = sp.sph_harm(m, l, phi, theta)
            components[:, m, 0] = w * ylm.real
            components[:, m, 1] = w * ylm.imag

        # Summing over all the particles
        ylm_average = np.sum(components, axis=0) / components.shape[0]

        # Applying invariance
        # computes the "q" invariant for a 3d fourier coefficient
        sd = np.sqrt(4.0 * np.pi / ylm.shape[1] * np.sum(ylm_average**2))
        shape_descriptor.append(sd)

    return shape_descriptor
def fourier2D(coordinates,L,frequencies):


    # Note, that I do not perform the calculation below on the central particle
    # Messes with results!
    
    N = coordinates.shape[0]-1;
    
    if N == 0:
        return [0]
    
    # Note.  The first coordinates is the center particle.
    #Translate all coordinates so the center is the origin
    coordinates = coordinate_helper.pbc(coordinates[1:,:]-coordinates[0,:],L)

    #RSQ is only calculated in SMAC to partition particles by shells.
    #We are not partitioning particles by shells
    #rsq = coordinate_helper.rsq(coordinates)
    
    # calculate theta of all particles (including center)
    theta = np.arctan2(coordinates[:,1],coordinates[:,0]) + np.pi
    
    shape_descriptor = []
    
    # For each frequency.. calculate a complex number which
    # is sum [np.cos(k*theta), -np.sin(k*theta)] for each theta
    # Applying weight of 1.0 to all
    for k in frequencies:
    
        components = np.zeros(shape=(coordinates.shape[0],2))

        #components += [np.cos(k*theta), -np.sin(k*theta)]
        # weights
        w=1.0
        components[:,0] += w*np.cos(k*theta)
        components[:,1] += -w*np.sin(k*theta)
    
        # c is a complex number
        c= np.sum(components,axis=0)
        
        # scale the components
        c /=float(N)
        
        
        #print c
        # because invariant (return magnitude of complex number)
        c = np.sqrt(np.sum(c*c))
    
        shape_descriptor.append(c)

    return shape_descriptor
Exemple #5
0
def fourier2D(coordinates, L, frequencies):

    # Note, that I do not perform the calculation below on the central particle
    # Messes with results!

    N = coordinates.shape[0] - 1

    if N == 0:
        return [0]

    # Note.  The first coordinates is the center particle.
    #Translate all coordinates so the center is the origin
    coordinates = coordinate_helper.pbc(coordinates[1:, :] - coordinates[0, :],
                                        L)

    #RSQ is only calculated in SMAC to partition particles by shells.
    #We are not partitioning particles by shells
    #rsq = coordinate_helper.rsq(coordinates)

    # calculate theta of all particles (including center)
    theta = np.arctan2(coordinates[:, 1], coordinates[:, 0]) + np.pi

    shape_descriptor = []

    # For each frequency.. calculate a complex number which
    # is sum [np.cos(k*theta), -np.sin(k*theta)] for each theta
    # Applying weight of 1.0 to all
    for k in frequencies:

        components = np.zeros(shape=(coordinates.shape[0], 2))

        #components += [np.cos(k*theta), -np.sin(k*theta)]
        # weights
        w = 1.0
        components[:, 0] += w * np.cos(k * theta)
        components[:, 1] += -w * np.sin(k * theta)

        # c is a complex number
        c = np.sum(components, axis=0)

        # scale the components
        c /= float(N)

        #print c
        # because invariant (return magnitude of complex number)
        c = np.sqrt(np.sum(c * c))

        shape_descriptor.append(c)

    return shape_descriptor
    def getClusters(self,rmax):

        clusters = []

        for i in range(self.N):
            
            mask_notme = [True]*(self.N)
            mask_notme[i] = False
            
            dd = self.coordinates - self.coordinates[i]
            dd = coordinate_helper.pbc(dd,self.L)
            rij = np.linalg.norm(dd, axis=1)

            mask = (rij < rmax) & mask_notme
            
            myparticles = self.coordinates[mask]
            
            tmp = np.zeros(shape=(myparticles.shape[0]+1, 3))
            tmp[0,:] =copy.copy(self.coordinates[i])
            tmp[1:,:]= copy.copy(myparticles)
            
            clusters.append(tmp)

        return clusters
    def getClusters(self, rmax):

        clusters = []

        for i in range(self.N):

            mask_notme = [True] * (self.N)
            mask_notme[i] = False

            dd = self.coordinates - self.coordinates[i]
            dd = coordinate_helper.pbc(dd, self.L)
            rij = np.linalg.norm(dd, axis=1)

            mask = (rij < rmax) & mask_notme

            myparticles = self.coordinates[mask]

            tmp = np.zeros(shape=(myparticles.shape[0] + 1, 3))
            tmp[0, :] = copy.copy(self.coordinates[i])
            tmp[1:, :] = copy.copy(myparticles)

            clusters.append(tmp)

        return clusters