def _compass_from_lattice( lattice, origin=(0, 0, 0), scale=0.7, offset=0.15, compass_style="corner", **kwargs, ): # TODO: add along lattice """ Get the display components of the compass :param lattice: the pymatgen Lattice object that contains the primitive lattice vectors :param origin: the reference position to place the compass :param scale: scale all the geometric objects that makes up the compass the lattice vectors are normalized before the scaling so everything should be the same size :param offset: shift the compass from the origin by a ratio of the diagonal of the cell relative the size :return: list of cystal_toolkit.helper.scene objects that makes up the compass """ o = -np.array(origin) o = o - offset * (lattice.matrix[0] + lattice.matrix[1] + lattice.matrix[2]) a = lattice.matrix[0] / np.linalg.norm(lattice.matrix[0]) * scale b = lattice.matrix[1] / np.linalg.norm(lattice.matrix[1]) * scale c = lattice.matrix[2] / np.linalg.norm(lattice.matrix[2]) * scale a_arrow = [[o, o + a]] b_arrow = [[o, o + b]] c_arrow = [[o, o + c]] o_sphere = Spheres(positions=[o], color="black", radius=0.1 * scale) return [ Arrows( a_arrow, color="red", radius=0.7 * scale, headLength=2.3 * scale, headWidth=1.4 * scale, **kwargs, ), Arrows( b_arrow, color="blue", radius=0.7 * scale, headLength=2.3 * scale, headWidth=1.4 * scale, **kwargs, ), Arrows( c_arrow, color="green", radius=0.7 * scale, headLength=2.3 * scale, headWidth=1.4 * scale, **kwargs, ), o_sphere, ]
def get_site_scene( self, connected_sites: List[ConnectedSite] = None, # connected_site_metadata: None, # connected_sites_to_draw, connected_sites_not_drawn: List[ConnectedSite] = None, hide_incomplete_edges: bool = False, incomplete_edge_length_scale: Optional[float] = 1.0, connected_sites_colors: Optional[List[str]] = None, connected_sites_not_drawn_colors: Optional[List[str]] = None, origin: Optional[List[float]] = None, draw_polyhedra: bool = True, explicitly_calculate_polyhedra_hull: bool = False, bond_radius: float = 0.1, draw_magmoms: bool = True, magmom_scale: float = 1.0, legend: Optional[Legend] = None, ) -> Scene: """ Args: connected_sites: connected_sites_not_drawn: hide_incomplete_edges: incomplete_edge_length_scale: connected_sites_colors: connected_sites_not_drawn_colors: origin: explicitly_calculate_polyhedra_hull: legend: Returns: """ atoms = [] bonds = [] polyhedron = [] magmoms = [] legend = legend or Legend(self) # for disordered structures is_ordered = self.is_ordered phiStart, phiEnd = None, None occu_start = 0.0 position = self.coords.tolist() radii = [legend.get_radius(sp, site=self) for sp in self.species.keys()] max_radius = float(min(radii)) for idx, (sp, occu) in enumerate(self.species.items()): if isinstance(sp, DummySpecie): cube = Cubes( positions=[position], color=legend.get_color(sp, site=self), width=0.4 ) atoms.append(cube) else: color = legend.get_color(sp, site=self) radius = legend.get_radius(sp, site=self) # TODO: make optional/default to None # in disordered structures, we fractionally color-code spheres, # drawing a sphere segment from phi_end to phi_start # (think a sphere pie chart) if not is_ordered: phi_frac_end = occu_start + occu phi_frac_start = occu_start occu_start = phi_frac_end phiStart = phi_frac_start * np.pi * 2 phiEnd = phi_frac_end * np.pi * 2 name = str(sp) if occu != 1.0: name += " ({}% occupancy)".format(occu) name += f" ({position[0]:.3f}, {position[1]:.3f}, {position[2]:.3f})" if self.properties: for k, v in self.properties.items(): name += f" ({k} = {v})" sphere = Spheres( positions=[position], color=color, radius=radius, phiStart=phiStart, phiEnd=phiEnd, clickable=True, tooltip=name, ) atoms.append(sphere) # Add magmoms if draw_magmoms: if magmom := self.properties.get("magmom"): # enforce type magmom = np.array(Magmom(magmom).get_moment()) magmom = 2 * magmom_scale * max_radius * magmom tail = np.array(position) - 0.5 * np.array(magmom) head = np.array(position) + 0.5 * np.array(magmom) arrow = Arrows( positionPairs=[[tail, head]], color="red", radius=0.20, headLength=0.5, headWidth=0.4, clickable=True, ) magmoms.append(arrow)
def _axes_from_lattice(self, origin=None, scale=1, offset=0, **kwargs): """ Get the display components of the compass :param lattice: the pymatgen Lattice object that contains the primitive lattice vectors :param origin: the reference position to place the compass :param scale: scale all the geometric objects that makes up the compass the lattice vectors are normalized before the scaling so everything should be the same size :param offset: shift the compass from the origin by a ratio of the diagonal of the cell relative the size :param **kwargs: keyword args to pass to the Arrows initializer :return: Scene object """ origin = origin or [0, 0, 0] o = np.array(origin) # o = -self.get_cartesian_coords([0.5, 0.5, 0.5]) # o = o - offset * (self.matrix[0] + self.matrix[1] + self.matrix[2]) a = self.matrix[0] / np.linalg.norm(self.matrix[0]) * scale b = self.matrix[1] / np.linalg.norm(self.matrix[1]) * scale c = self.matrix[2] / np.linalg.norm(self.matrix[2]) * scale a_arrow = [[o, o + a]] b_arrow = [[o, o + b]] c_arrow = [[o, o + c]] radius_scale = 0.07 head_scale = 0.24 head_width = 0.14 o_sphere = Spheres(positions=[o], color="white", radius=2 * radius_scale * scale) return Scene( name="axes", contents=[ Arrows( a_arrow, color="red", radius=radius_scale * scale, headLength=head_scale * scale, headWidth=head_width * scale, **kwargs, ), Arrows( b_arrow, color="green", radius=radius_scale * scale, headLength=head_scale * scale, headWidth=head_width * scale, **kwargs, ), Arrows( c_arrow, color="blue", radius=radius_scale * scale, headLength=head_scale * scale, headWidth=head_width * scale, **kwargs, ), o_sphere, ], origin=origin, )