def get_boxed_structure(self, a, b, c, images=(1, 1, 1),
                            random_rotation=False, min_dist=1, cls=None,
                            offset=None, no_cross=False):
        """
        Creates a Structure from a Molecule by putting the Molecule in the
        center of a orthorhombic box. Useful for creating Structure for
        calculating molecules using periodic codes.

        Args:
            a (float): a-lattice parameter.
            b (float): b-lattice parameter.
            c (float): c-lattice parameter.
            images: No. of boxed images in each direction. Defaults to
                (1, 1, 1), meaning single molecule with 1 lattice parameter
                in each direction.
            random_rotation (bool): Whether to apply a random rotation to
                each molecule. This jumbles all the molecules so that they
                are not exact images of each other.
            min_dist (float): The minimum distance that atoms should be from
                each other. This is only used if random_rotation is True.
                The randomized rotations are searched such that no two atoms
                are less than min_dist from each other.
            cls: The Structure class to instantiate (defaults to pymatgen
                structure)
            offset: Translation to offset molecule from center of mass coords
            no_cross: Whether to forbid molecule coords from extending beyond
                boundary of box.

        Returns:
            Structure containing molecule in a box.
        """
        if offset is None:
            offset = np.array([0, 0, 0])

        coords = np.array(self.cart_coords)
        x_range = max(coords[:, 0]) - min(coords[:, 0])
        y_range = max(coords[:, 1]) - min(coords[:, 1])
        z_range = max(coords[:, 2]) - min(coords[:, 2])

        if a <= x_range or b <= y_range or c <= z_range:
            raise ValueError("Box is not big enough to contain Molecule.")
        lattice = Lattice.from_parameters(a * images[0], b * images[1],
                                          c * images[2],
                                          90, 90, 90)
        nimages = images[0] * images[1] * images[2]
        coords = []

        centered_coords = self.cart_coords - self.center_of_mass + offset

        for i, j, k in itertools.product(list(range(images[0])),
                                         list(range(images[1])),
                                         list(range(images[2]))):
            box_center = [(i + 0.5) * a, (j + 0.5) * b, (k + 0.5) * c]
            if random_rotation:
                while True:
                    op = SymmOp.from_origin_axis_angle(
                        (0, 0, 0), axis=np.random.rand(3),
                        angle=random.uniform(-180, 180))
                    m = op.rotation_matrix
                    new_coords = np.dot(m, centered_coords.T).T + box_center
                    if no_cross:
                        x_max, x_min = max(new_coords[:, 0]), min(new_coords[:, 0])
                        y_max, y_min = max(new_coords[:, 1]), min(new_coords[:, 1])
                        z_max, z_min = max(new_coords[:, 2]), min(new_coords[:, 2])
                        if x_max > a or x_min < 0 or y_max > b or y_min < 0 or z_max > c or z_min < 0:
                            raise ValueError("Molecule crosses boundary of box.")
                    if len(coords) == 0:
                        break
                    distances = lattice.get_all_distances(
                        lattice.get_fractional_coords(new_coords),
                        lattice.get_fractional_coords(coords))
                    if np.amin(distances) > min_dist:
                        break
            else:
                new_coords = centered_coords + box_center
                if no_cross:
                    x_max, x_min = max(new_coords[:, 0]), min(new_coords[:, 0])
                    y_max, y_min = max(new_coords[:, 1]), min(new_coords[:, 1])
                    z_max, z_min = max(new_coords[:, 2]), min(new_coords[:, 2])
                    if x_max > a or x_min < 0 or y_max > b or y_min < 0 or z_max > c or z_min < 0:
                        raise ValueError("Molecule crosses boundary of box.")
            coords.extend(new_coords)
        sprops = {k: v * nimages for k, v in self.site_properties.items()}

        if cls is None:
            cls = Structure

        return cls(lattice, self.species * nimages, coords,
                   coords_are_cartesian=True,
                   site_properties=sprops).get_sorted_structure()
def get_boxed_structure ( self , a , b , c , images = ( 1 , 1 , 1 ) , random_rotation = False , min_dist = 1 , cls = None , offset = None , no_cross = False ) : if offset is None : offset = np . array ( [ 0 , 0 , 0 ] ) coords = np . array ( self . cart_coords ) x_range = max ( coords [ : , 0 ] ) - min ( coords [ : , 0 ] ) y_range = max ( coords [ : , 1 ] ) - min ( coords [ : , 1 ] ) z_range = max ( coords [ : , 2 ] ) - min ( coords [ : , 2 ] ) if a <= x_range or b <= y_range or c <= z_range : raise ValueError ( "Box is not big enough to contain Molecule." ) lattice = Lattice . from_parameters ( a * images [ 0 ] , b * images [ 1 ] , c * images [ 2 ] , 90 , 90 , 90 ) nimages = images [ 0 ] * images [ 1 ] * images [ 2 ] coords = [ ] centered_coords = self . cart_coords - self . center_of_mass + offset for i , j , k in itertools . product ( list ( range ( images [ 0 ] ) ) , list ( range ( images [ 1 ] ) ) , list ( range ( images [ 2 ] ) ) ) : box_center = [ ( i + 0.5 ) * a , ( j + 0.5 ) * b , ( k + 0.5 ) * c ] if random_rotation : while True : op = SymmOp . from_origin_axis_angle ( ( 0 , 0 , 0 ) , axis = np . random . rand ( 3 ) , angle = random . uniform ( - 180 , 180 ) ) m = op . rotation_matrix new_coords = np . dot ( m , centered_coords . T ) . T + box_center if no_cross : x_max , x_min = max ( new_coords [ : , 0 ] ) , min ( new_coords [ : , 0 ] ) y_max , y_min = max ( new_coords [ : , 1 ] ) , min ( new_coords [ : , 1 ] ) z_max , z_min = max ( new_coords [ : , 2 ] ) , min ( new_coords [ : , 2 ] ) if x_max > a or x_min < 0 or y_max > b or y_min < 0 or z_max > c or z_min < 0 : raise ValueError ( "Molecule crosses boundary of box." ) if len ( coords ) == 0 : break distances = lattice . get_all_distances ( lattice . get_fractional_coords ( new_coords ) , lattice . get_fractional_coords ( coords ) ) if np . amin ( distances ) > min_dist : break else : new_coords = centered_coords + box_center if no_cross : x_max , x_min = max ( new_coords [ : , 0 ] ) , min ( new_coords [ : , 0 ] ) y_max , y_min = max ( new_coords [ : , 1 ] ) , min ( new_coords [ : , 1 ] ) z_max , z_min = max ( new_coords [ : , 2 ] ) , min ( new_coords [ : , 2 ] ) if x_max > a or x_min < 0 or y_max > b or y_min < 0 or z_max > c or z_min < 0 : raise ValueError ( "Molecule crosses boundary of box." ) coords . extend ( new_coords ) sprops = { k : v * nimages for k , v in self . site_properties . items ( ) } if cls is None : cls = Structure return cls ( lattice , self . species * nimages , coords , coords_are_cartesian = True , site_properties = sprops ) . get_sorted_structure ( )
Creates a Structure from a Molecule by putting the Molecule in the
        center of a orthorhombic box. Useful for creating Structure for
        calculating molecules using periodic codes.

        Args:
            a (float): a-lattice parameter.
            b (float): b-lattice parameter.
            c (float): c-lattice parameter.
            images: No. of boxed images in each direction. Defaults to
                (1, 1, 1), meaning single molecule with 1 lattice parameter
                in each direction.
            random_rotation (bool): Whether to apply a random rotation to
                each molecule. This jumbles all the molecules so that they
                are not exact images of each other.
            min_dist (float): The minimum distance that atoms should be from
                each other. This is only used if random_rotation is True.
                The randomized rotations are searched such that no two atoms
                are less than min_dist from each other.
            cls: The Structure class to instantiate (defaults to pymatgen
                structure)
            offset: Translation to offset molecule from center of mass coords
            no_cross: Whether to forbid molecule coords from extending beyond
                boundary of box.

        Returns:
            Structure containing molecule in a box.