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