def demo1(l_box, l_pos, l_ang, verts, title="System Visualization"): # create box fbox = box.Box(Lx=l_box["Lx"], Ly=l_box["Ly"], is2D=True) side_length = max(fbox.Lx, fbox.Ly) l_min = -side_length / 2.0 l_min *= 1.1 l_max = -l_min # take local vertices and rotate, translate into # system coordinates patches = local_to_global(verts, l_pos[:, 0:2], l_ang) # plot p = figure(title=title, x_range=(l_min, l_max), y_range=(l_min, l_max), height=300, width=300) p.patches(xs=patches[:, :, 0].tolist(), ys=patches[:, :, 1].tolist(), fill_color=(42, 126, 187), line_color="black", line_width=1.5) # , # legend="hexagons") # box display p.patches(xs=[[-fbox.Lx / 2, fbox.Lx / 2, fbox.Lx / 2, -fbox.Lx / 2]], ys=[[-fbox.Ly / 2, -fbox.Ly / 2, fbox.Ly / 2, fbox.Ly / 2]], fill_color=(0, 0, 0, 0), line_color="black", line_width=2) # p.legend.location='bottom_center' # p.legend.orientation='horizontal' default_bokeh(p) # show(p) return p
def test_WrapMultipleImages(self): box = bx.Box(2, 2, 2, 1, 0, 0) testpoints = np.array([[10, -5, -5], [0, 0.5, 0]], dtype=np.float32) box.wrap(testpoints) npt.assert_almost_equal(testpoints[0,0], -2, decimal=2, err_msg="WrapFail")
def test_dict(self): box = bx.Box(2, 2, 2, 1, 0.5, 0.1) class BoxTuple(object): def __init__(self, box_dict): self.__dict__.update(box_dict) box2 = bx.Box.from_box(BoxTuple(box.to_dict())) self.assertEqual(box, box2)
def test_unwrap(self): box = bx.Box(2, 2, 2, 1, 0, 0) testpoints = np.array([[0, -1, -1], [0, 0.5, 0]], dtype=np.float32) imgs = np.array([[1,0,0], [1,1,0]], dtype=np.int32) box.unwrap(testpoints, imgs) npt.assert_almost_equal(testpoints[0,0], 2, decimal=2, err_msg="WrapFail")
def test_TiltFactor(self): box = bx.Box(2, 2, 2, 1, 0, 0); tiltxy = box.getTiltFactorXY() tiltxz = box.getTiltFactorXZ() tiltyz = box.getTiltFactorYZ() npt.assert_almost_equal(tiltxy, 1, decimal=2, err_msg="TiltXYfail") npt.assert_almost_equal(tiltxz, 0, decimal=2, err_msg="TiltXZfail") npt.assert_almost_equal(tiltyz, 0, decimal=2, err_msg="TiltYZfail")
def test_BoxLength(self): box = bx.Box(2, 2, 2, 1, 0, 0) Lx = box.getLx() Ly = box.getLy() Lz = box.getLz() npt.assert_almost_equal(Lx, 2, decimal=2, err_msg="LxFail") npt.assert_almost_equal(Ly, 2, decimal=2, err_msg="LyFail") npt.assert_almost_equal(Lz, 2, decimal=2, err_msg="LzFail")
def plot_ld(self, frame_idx, ld, title="Local Density Visualization", linked_plot=None): l_box = self.box_data[frame_idx] l_pos = self.pos_data[frame_idx] l_quat = self.quat_data[frame_idx] l_ang = 2 * np.arctan2(np.copy(l_quat[:, 3]), np.copy(l_quat[:, 0])) fbox = box.Box(Lx=l_box["Lx"], Ly=l_box["Ly"], is2D=True) side_length = max(fbox.Lx, fbox.Ly) l_min = -side_length / 2.0 l_min *= 1.1 l_max = -l_min if linked_plot is not None: x_range = linked_plot.x_range y_range = linked_plot.y_range else: x_range = (l_min, l_max) y_range = (l_min, l_max) # create array of transformed positions patches = local_to_global(verts, l_pos[:, 0:2], l_ang) # create an array of angles relative to the average # a = np.angle(psi_k) - np.angle(avg_psi_k) a = ld # turn into an rgb array of tuples # handle the matplotlib colormap myNorm = mplColors.Normalize(vmin=0.5, vmax=0.8) color = [tuple(cm.RdYlBu(myNorm(x))[:3]) for x in a] # bokeh (as of this version) requires hex colors, so convert rgb to hex hex_color = [ "#{:02x}{:02x}{:02x}".format(clamp(int(255 * r)), clamp(int(255 * g)), clamp(int(255 * b))) for (r, g, b) in color ] # plot p = figure(title=title, x_range=x_range, y_range=y_range, height=300, width=300) p.patches( xs=patches[:, :, 0].tolist(), ys=patches[:, :, 1].tolist(), fill_color=hex_color, line_color="black", ) default_bokeh(p) self.p = p return p
def test_throws(self): L = 10 with self.assertRaises(RuntimeError): fbox = box.Box.cube(L) locality.LinkCell(fbox, L / 1.9999) fbox = box.Box(L, 2 * L, 2 * L) locality.LinkCell(fbox, L / 2.0001) with self.assertRaises(RuntimeError): locality.LinkCell(fbox, L / 1.9999)
def plot_frame(self, frame_idx, title="System Visualization", linked_plot=None): l_box = self.box_data[frame_idx] l_pos = self.pos_data[frame_idx] l_quat = self.quat_data[frame_idx] l_ang = 2 * np.arctan2(np.copy(l_quat[:, 3]), np.copy(l_quat[:, 0])) fbox = box.Box(Lx=l_box["Lx"], Ly=l_box["Ly"], is2D=True) side_length = max(fbox.Lx, fbox.Ly) l_min = -side_length / 2.0 l_min *= 1.1 l_max = -l_min # take local vertices and rotate, translate into # system coordinates patches = local_to_global(verts, l_pos[:, 0:2], l_ang) if linked_plot is not None: x_range = linked_plot.x_range y_range = linked_plot.y_range else: x_range = (l_min, l_max) y_range = (l_min, l_max) # plot p = figure(title=title, x_range=x_range, y_range=y_range, height=300, width=300) p.patches( xs=patches[:, :, 0].tolist(), ys=patches[:, :, 1].tolist(), fill_color=(42, 126, 187), line_color="black", line_width=1.5, ) # , # legend="hexagons") # box display p.patches( xs=[[-fbox.Lx / 2, fbox.Lx / 2, fbox.Lx / 2, -fbox.Lx / 2]], ys=[[-fbox.Ly / 2, -fbox.Ly / 2, fbox.Ly / 2, fbox.Ly / 2]], fill_color=(0, 0, 0, 0), line_color="black", line_width=2, ) # p.legend.location='bottom_center' # p.legend.orientation='horizontal' default_bokeh(p) # show(p) self.p = p return p
def plot_hexatic( self, frame_idx, psi_k, avg_psi_k, title="Hexatic Visualization", linked_plot=None, ): l_box = self.box_data[frame_idx] l_pos = self.pos_data[frame_idx] l_quat = self.quat_data[frame_idx] l_ang = 2 * np.arctan2(np.copy(l_quat[:, 3]), np.copy(l_quat[:, 0])) fbox = box.Box(Lx=l_box["Lx"], Ly=l_box["Ly"], is2D=True) side_length = max(fbox.Lx, fbox.Ly) l_min = -side_length / 2.0 l_min *= 1.1 l_max = -l_min if linked_plot is not None: x_range = linked_plot.x_range y_range = linked_plot.y_range else: x_range = (l_min, l_max) y_range = (l_min, l_max) # create array of transformed positions patches = local_to_global(verts, l_pos[:, 0:2], l_ang) # create an array of angles relative to the average a = np.angle(psi_k) - np.angle(avg_psi_k) # turn into an rgb array of tuples color = [tuple(cubeellipse(x)) for x in a] # bokeh (as of this version) requires hex colors, so convert rgb to hex hex_color = [ f"#{clamp(r):02x}{clamp(g):02x}{clamp(b):02x}" for (r, g, b) in color ] # plot p = figure(title=title, x_range=x_range, y_range=y_range, height=300, width=300) p.patches( xs=patches[:, :, 0].tolist(), ys=patches[:, :, 1].tolist(), fill_color=hex_color, line_color="black", ) default_bokeh(p) self.p = p return p
def test_cluster_registration(self): xyz = np.load("sc_N54.npy") xyz = np.array(xyz, dtype=np.float32) rcut = 4 kn = 6 threshold = 0.005 #define rotation matrix, rotate along z axis by pi/24 degree rotationAngle = np.pi / 24.0 R = np.array([[np.cos(rotationAngle), -np.sin(rotationAngle), 0], [np.sin(rotationAngle), np.cos(rotationAngle), 0], [0, 0, 1]], float) #rotate particles that y>0, introduce grain boundary for i in range(len(xyz)): if xyz[i, 1] < 0.0: xyz[i] = R.dot(xyz[i]) L = np.max(xyz) * 3.0 fbox = box.Box(L, L, L, 0, 0, 0) match = MatchEnv(fbox, rcut, kn) match.cluster(xyz, threshold, hard_r=False, registration=True, global_search=True) clusters = match.getClusters() #get environment for each particle tot_env = match.getTotEnvironment() #particles with index 22 and 31 have opposite y positions, they should have the same local environment npt.assert_equal(clusters[22], clusters[31], err_msg="two points do not have similar environment") #particle 22 and particle 31's local environments should match returnResult = match.isSimilar(tot_env[22], tot_env[31], 0.005, registration=True) npt.assert_equal(len(returnResult[1]), kn, err_msg="two environments are not similar")
def plot_orientation(self, frame_idx, title="Orientation Visualization", linked_plot=None): l_box = self.box_data[frame_idx] l_pos = self.pos_data[frame_idx] l_quat = self.quat_data[frame_idx] l_ang = 2 * np.arctan2(np.copy(l_quat[:, 3]), np.copy(l_quat[:, 0])) fbox = box.Box(Lx=l_box["Lx"], Ly=l_box["Ly"], is2D=True) side_length = max(fbox.Lx, fbox.Ly) l_min = -side_length / 2.0 l_min *= 1.1 l_max = -l_min if linked_plot is not None: x_range = linked_plot.x_range y_range = linked_plot.y_range else: x_range = (l_min, l_max) y_range = (l_min, l_max) # create array of transformed positions patches = local_to_global(verts, l_pos[:, 0:2], l_ang) # turn into an rgb array of tuples theta = l_ang * 6.0 color = [tuple(cubeellipse(x, lam=0.5, h=2.0)) for x in theta] # bokeh (as of this version) requires hex colors, so convert rgb to hex hex_color = [ "#{0:02x}{1:02x}{2:02x}".format(clamp(r), clamp(g), clamp(b)) for (r, g, b) in color ] # plot p = figure(title=title, x_range=x_range, y_range=y_range, height=300, width=300) p.patches(xs=patches[:, :, 0].tolist(), ys=patches[:, :, 1].tolist(), fill_color=hex_color, line_color="black") default_bokeh(p) self.p = p return p
def __init__(self, system, groups, log, activation_energy, sec_bond_weight): Bonding.__init__(self, system=system, groups=groups, log=log, activation_energy=activation_energy, sec_bond_weight=sec_bond_weight) # create freud nearest neighbor object # set number of neighbors self.n_neigh = 6 # create freud nearest neighbors object self.nn = locality.NearestNeighbors(rmax=self.cut_off_dist, n_neigh=self.n_neigh, strict_cut=True) snapshot = self.system.take_snapshot() self.fbox = box.Box(Lx=snapshot.box.Lx, Ly=snapshot.box.Ly, Lz=snapshot.box.Lz)
def test_correct_bond(self): # generate the bonding map nr = 10 nt1 = 100 nt2 = 50 testArray = np.zeros(shape=(nr, nt2, nt1), dtype=np.uint32) rmax = 3.0 dr = rmax / float(nr) dt2 = 2.0 * np.pi / float(nt2) dt1 = 2.0 * np.pi / float(nt1) # make sure the radius for each bin is generated correctly posList = np.array([[0.0, 0.0, 0.0], [1.0, 1.0, 0.0]], dtype=np.float32) anglist = np.zeros(shape=(2), dtype=np.float32) # calculate the bin deltaX = posList[1,0] - posList[0,0] deltaY = posList[1,1] - posList[0,1] delta = np.array([deltaX, deltaY], dtype=np.float32) r = np.sqrt(np.dot(delta, delta)) theta1 = anglist[0] - np.arctan2(deltaY, deltaX) theta2 = anglist[1] - np.arctan2(-deltaY, -deltaX) theta1 = theta1 if (theta1 > 0) else theta1 + 2.0*np.pi theta1 = theta1 if (theta1 < 2.0*np.pi) else theta1 - 2.0*np.pi theta2 = theta2 if (theta2 > 0) else theta2 + 2.0*np.pi theta2 = theta2 if (theta2 < 2.0*np.pi) else theta2 - 2.0*np.pi binR = int(numpy.floor(r / dr)) binT1 = int(numpy.floor(theta1 / dt1)) binT2 = int(numpy.floor(theta2 / dt2)) testArray[binR,binT2,binT1] = 5 deltaX = posList[0,0] - posList[1,0] deltaY = posList[0,1] - posList[1,1] delta = np.array([deltaX, deltaY], dtype=np.float32) r = np.sqrt(np.dot(delta, delta)) theta1 = anglist[0] - np.arctan2(deltaY, deltaX) theta2 = anglist[1] - np.arctan2(-deltaY, -deltaX) theta1 = theta1 if (theta1 > 0) else theta1 + 2.0*np.pi theta1 = theta1 if (theta1 < 2.0*np.pi) else theta1 - 2.0*np.pi theta2 = theta2 if (theta2 > 0) else theta2 + 2.0*np.pi theta2 = theta2 if (theta2 < 2.0*np.pi) else theta2 - 2.0*np.pi binR = int(numpy.floor(r / dr)) binT1 = int(numpy.floor(theta1 / dt1)) binT2 = int(numpy.floor(theta2 / dt2)) testArray[binR,binT2,binT1] = 5 # create object bondList = np.array([0, 5], dtype=np.uint32) EB = bond.BondingR12(rmax, testArray, bondList) # create the box f_box = box.Box(Lx=5.0*rmax, Ly=5.0*rmax, is2D=True) # run the computation EB.compute(f_box, posList, anglist, posList, anglist) # check to make sure that the point is in the correct bin bonds = EB.getBonds() npt.assert_equal(bonds[0,1], 1) npt.assert_equal(bonds[1,1], 0)
def freud_box(self, frame): l_box = self.box_data[frame] fbox = box.Box(Lx=l_box["Lx"], Ly=l_box["Ly"], is2D=True) return fbox
def plot_neighbors(self, frame_idx, n_list, num_particles, n_neigh, title="Nearest Neighbor Visualization", linked_plot=None): l_box = self.box_data[frame_idx] l_pos = self.pos_data[frame_idx] l_quat = self.quat_data[frame_idx] l_ang = 2 * np.arctan2(np.copy(l_quat[:, 3]), np.copy(l_quat[:, 0])) fbox = box.Box(Lx=l_box["Lx"], Ly=l_box["Ly"], is2D=True) side_length = max(fbox.Lx, fbox.Ly) l_min = -side_length / 2.0 l_min *= 1.1 l_max = -l_min if linked_plot is not None: x_range = linked_plot.x_range y_range = linked_plot.y_range else: x_range = (l_min, l_max) y_range = (l_min, l_max) # now for array manipulation magic # create an integer array of the same shape as the neighbor list array int_arr = np.ones(shape=n_list.shape, dtype=np.int32) # "search" for non-indexed particles (missing neighbors) # while it would be most accurate to use the UINTMAX value # provided by nn.getUINTMAX(), but this works just as well int_arr[n_list > (num_particles - 1)] = 0 # sum along particle index axis to # determine the number of neighbors per particle n_neighbors = np.sum(int_arr, axis=1) # find the complement (if desired) to # find number of missing neighbors per particle n_deficits = n_neigh - n_neighbors p = figure(title=title, x_range=x_range, y_range=y_range, height=300, width=300) for k in np.unique(n_neighbors): # find particles with k neighbors c_idxs = np.copy(np.where(n_neighbors == k)[0]) center_pos = np.zeros(shape=(len(c_idxs), 3), dtype=np.float32) center_ang = np.zeros(shape=(len(c_idxs)), dtype=np.float32) center_pos = l_pos[c_idxs] center_ang = l_ang[c_idxs] c_patches = local_to_global(verts, center_pos[:, 0:2], center_ang) center_color = np.array( [c_dict[k] for _ in range(center_pos.shape[0])]) p.patches(xs=c_patches[:, :, 0].tolist(), ys=c_patches[:, :, 1].tolist(), fill_color=center_color.tolist(), line_color="black", legend="k={}".format(k)) p.patches(xs=[[-fbox.Lx / 2, fbox.Lx / 2, fbox.Lx / 2, -fbox.Lx / 2]], ys=[[-fbox.Ly / 2, -fbox.Ly / 2, fbox.Ly / 2, fbox.Ly / 2]], fill_color=(0, 0, 0, 0), line_color="black", line_width=2) p.legend.location = 'bottom_center' p.legend.orientation = 'horizontal' default_bokeh(p) self.p = p return p
def plot_single_neighbor(self, frame_idx, pidx, n_list, num_particles, title="Nearest Neighbor Visualization", linked_plot=None): l_box = self.box_data[frame_idx] l_pos = self.pos_data[frame_idx] l_quat = self.quat_data[frame_idx] l_ang = 2 * np.arctan2(np.copy(l_quat[:, 3]), np.copy(l_quat[:, 0])) fbox = box.Box(Lx=l_box["Lx"], Ly=l_box["Ly"], is2D=True) side_length = max(fbox.Lx, fbox.Ly) l_min = -side_length / 2.0 l_min *= 1.1 l_max = -l_min if linked_plot is not None: x_range = linked_plot.x_range y_range = linked_plot.y_range else: x_range = (l_min, l_max) y_range = (l_min, l_max) n_idxs = n_list[pidx] # clip padded values n_idxs = n_idxs[np.where(n_idxs < num_particles)] n_neigh = len(n_idxs) # get position, orientation for the central particle center_pos = np.zeros(shape=(1, 3), dtype=np.float32) center_ang = np.zeros(shape=(1), dtype=np.float32) center_pos[:] = l_pos[pidx] center_ang[:] = l_ang[pidx] # get the positions, orientations for the neighbor particles neigh_pos = np.zeros(shape=(n_neigh, 3), dtype=np.float32) neigh_ang = np.zeros(shape=(n_neigh), dtype=np.float32) neigh_pos[:] = l_pos[n_idxs] neigh_ang[:] = l_ang[n_idxs] # render in bokeh # create array of transformed positions # all particles patches = local_to_global(verts, l_pos[:, 0:2], l_ang) # center particle c_patches = local_to_global(verts, center_pos[:, 0:2], center_ang) # neighbor particles n_patches = local_to_global(verts, neigh_pos[:, 0:2], neigh_ang) # turn into list of colors # bokeh (as of this version) requires hex colors, so convert rgb to hex center_color = np.array( [c_list[0] for _ in range(center_pos.shape[0])]) neigh_color = np.array([c_list[1] for _ in range(neigh_pos.shape[0])]) # plot p = figure(title=title, x_range=x_range, y_range=y_range, height=300, width=300) p.patches(xs=patches[:, :, 0].tolist(), ys=patches[:, :, 1].tolist(), fill_color=(0, 0, 0, 0.1), line_color="black") p.patches(xs=n_patches[:, :, 0].tolist(), ys=n_patches[:, :, 1].tolist(), fill_color=neigh_color.tolist(), line_color="black", legend="neighbors") p.patches(xs=c_patches[:, :, 0].tolist(), ys=c_patches[:, :, 1].tolist(), fill_color=center_color.tolist(), line_color="black", legend="centers") # box display p.patches(xs=[[-fbox.Lx / 2, fbox.Lx / 2, fbox.Lx / 2, -fbox.Lx / 2]], ys=[[-fbox.Ly / 2, -fbox.Ly / 2, fbox.Ly / 2, fbox.Ly / 2]], fill_color=(0, 0, 0, 0), line_color="black", line_width=2) p.legend.location = 'bottom_center' p.legend.orientation = 'horizontal' default_bokeh(p) self.p = p return p
def test_matrix(self): box = bx.Box(2, 2, 2, 1, 0.5, 0.1) box2 = box.from_matrix(box.to_matrix()) self.assertTrue(np.isclose(box.to_matrix(), box2.to_matrix()).all())
def test_from_box(self): box = bx.Box(2, 2, 2, 1, 0.5, 0.1) box2 = bx.Box.from_box(box) self.assertEqual(box, box)
def test_tuple(self): box = bx.Box(2, 2, 2, 1, 0.5, 0.1) box2 = bx.Box.from_box(box.to_tuple()) self.assertEqual(box, box)
def test_str(self): box = bx.Box(2, 2, 2, 1, 0.5, 0.1) box2 = bx.Box(2, 2, 2, 1, 0.5, 0.1) self.assertEqual(str(box), str(box2))
def test_equal(self): box = bx.Box(2, 2, 2, 1, 0.5, 0.1) box2 = bx.Box(2, 2, 2, 1, 0, 0) self.assertEqual(box, box) self.assertNotEqual(box, box2)
def test_BoxVolume(self): box = bx.Box(2, 2, 2, 1, 0, 0) volume = box.getVolume() npt.assert_almost_equal(volume, 8, decimal=2, err_msg="VolumnFail")
def test_WrapSingleParticle(self): box = bx.Box(2, 2, 2, 1, 0, 0) testpoints = np.array([0, -1, -1], dtype=np.float32) box.wrap(testpoints) npt.assert_almost_equal(testpoints[0], -2, decimal=2, err_msg="WrapFail")