<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Point Particles
Step1:  While this would work for defining a single molecule or very small system, this would not be efficient for large systems.  Instead, the clone and translate operator can be used to facilitate automation. Below, we simply define a single prototype particle (lj_proto), which we then copy and translate about the system. 
Note, mBuild provides two different translate operations, "translate" and "translate_to".   "translate" moves a particle by adding the vector the original position, whereas "translate_to" move a particle to the specified location in space.  Note, "translate_to" maintains the internal spatial relationships of a collection of particles by first shifting the center of mass of the collection of particles to the origin, then translating to the specified location.  Since the lj_proto particle in this example starts at the origin, these two commands produce identical behavior.
Step2:  To simplify this process, mBuild provides several build-in patterning tools, where for example,  Grid3DPattern can be used to perform this same operation.  Grid3DPattern generates a set of points, from 0 to 1, which get stored in the variable "pattern".  We need only loop over the points in pattern, cloning, translating, and adding to the system.  Note, because Grid3DPattern defines points between 0 and 1, they must be scaled based on the desired system size, i.e., pattern.scale(2).
Step3:  Larger systems can therefore be easily generated by toggling the values given to Grid3DPattern.  Other patterns can also be generated using the same basic code, such as a 2D grid pattern
Step4:  Points on a sphere can be generated using SpherePattern. Points on a disk using DisKPattern, etc. 
Note to show both simultaneously, we shift the x-coordinate of Particles in the sphere by -1 (i.e., pos[0]-=1.0) and +1 for the disk (i.e, pos[0]+=1.0).
Step5:  We can also take advantage of the hierachical nature of mBuild to accomplish the same task more cleanly.  Below we  create a component that corresponds to the sphere (class SphereLJ), and one that corresponds to the disk (class DiskLJ), and then instantiate and shift each of these individually in the MonoLJ component.
Step6:  Again, since mBuild is hierarchical, the pattern functions can be used to generate large systems of any arbitary component.  For example, we can replicate the SphereLJ component on a regular array.
Step7:  Several functions exist for rotating compounds. For example, the spin command allows a compound to be rotated, in place, about a specific axis (i.e., it considers the origin for the rotation to lie at the compound's center of mass).
Step8:  Configurations can be dumped to file using the save command; this takes advantage of MDTraj and supports a range of file formats (see http
<ASSISTANT_TASK:>
Python Code:
import mbuild as mb
class MonoLJ(mb.Compound):
    def __init__(self):
        super(MonoLJ, self).__init__()
        lj_particle1 = mb.Particle(name='LJ', pos=[0, 0, 0])
        self.add(lj_particle1)
        lj_particle2 = mb.Particle(name='LJ', pos=[1, 0, 0])
        self.add(lj_particle2)
        lj_particle3 = mb.Particle(name='LJ', pos=[0, 1, 0])
        self.add(lj_particle3)
        lj_particle4 = mb.Particle(name='LJ', pos=[0, 0, 1])
        self.add(lj_particle4)
        lj_particle5 = mb.Particle(name='LJ', pos=[1, 0, 1])
        self.add(lj_particle5)
        lj_particle6 = mb.Particle(name='LJ', pos=[1, 1, 0])
        self.add(lj_particle6)
        lj_particle7 = mb.Particle(name='LJ', pos=[0, 1, 1])
        self.add(lj_particle7)
        
        lj_particle8 = mb.Particle(name='LJ', pos=[1, 1, 1])
        self.add(lj_particle8)
monoLJ = MonoLJ()
monoLJ.visualize()
Explanation: Point Particles: Basic system initialization
Note: mBuild expects all distance units to be in nanometers.
This tutorial focuses on the usage of basic system initialization operations, as applied to simple point particle systems (i.e., generic Lennard-Jones particles rather than specific atoms). 
The code below defines several point particles in a cubic arrangement. Note, the color and radius associated with a Particle name can be set and passed to the visualize command.  Colors are passed in hex format (see http://www.color-hex.com/color/bfbfbf).
End of explanation
import mbuild as mb
class MonoLJ(mb.Compound):
    def __init__(self):
        super(MonoLJ, self).__init__()
        lj_proto = mb.Particle(name='LJ', pos=[0, 0, 0])
        for i in range(0,2):
            for j in range(0,2):
                for k in range(0,2):
                    lj_particle = mb.clone(lj_proto)
                    pos = [i,j,k]
                    mb.translate(lj_particle, pos)
                    self.add(lj_particle)
monoLJ = MonoLJ()
monoLJ.visualize()
Explanation: While this would work for defining a single molecule or very small system, this would not be efficient for large systems.  Instead, the clone and translate operator can be used to facilitate automation. Below, we simply define a single prototype particle (lj_proto), which we then copy and translate about the system. 
Note, mBuild provides two different translate operations, "translate" and "translate_to".   "translate" moves a particle by adding the vector the original position, whereas "translate_to" move a particle to the specified location in space.  Note, "translate_to" maintains the internal spatial relationships of a collection of particles by first shifting the center of mass of the collection of particles to the origin, then translating to the specified location.  Since the lj_proto particle in this example starts at the origin, these two commands produce identical behavior.
End of explanation
import mbuild as mb
class MonoLJ(mb.Compound):
    def __init__(self):
        super(MonoLJ, self).__init__()
        lj_proto = mb.Particle(name='LJ', pos=[0, 0, 0])
        pattern = mb.Grid3DPattern(2, 2, 2)
        pattern.scale(2)
        for pos in pattern:
            lj_particle = mb.clone(lj_proto)
            mb.translate(lj_particle, pos)
            self.add(lj_particle)
monoLJ = MonoLJ()
monoLJ.visualize()
Explanation: To simplify this process, mBuild provides several build-in patterning tools, where for example,  Grid3DPattern can be used to perform this same operation.  Grid3DPattern generates a set of points, from 0 to 1, which get stored in the variable "pattern".  We need only loop over the points in pattern, cloning, translating, and adding to the system.  Note, because Grid3DPattern defines points between 0 and 1, they must be scaled based on the desired system size, i.e., pattern.scale(2).
End of explanation
import mbuild as mb
class MonoLJ(mb.Compound):
    def __init__(self):
        super(MonoLJ, self).__init__()
        lj_proto = mb.Particle(name='LJ', pos=[0, 0, 0])
        pattern = mb.Grid2DPattern(5, 5)
        pattern.scale(5)
        for pos in pattern:
            lj_particle = mb.clone(lj_proto)
            mb.translate(lj_particle, pos)
            self.add(lj_particle)
monoLJ = MonoLJ()
monoLJ.visualize()
Explanation: Larger systems can therefore be easily generated by toggling the values given to Grid3DPattern.  Other patterns can also be generated using the same basic code, such as a 2D grid pattern:
End of explanation
import mbuild as mb
class MonoLJ(mb.Compound):
    def __init__(self):
        super(MonoLJ, self).__init__()
        lj_proto = mb.Particle(name='LJ', pos=[0, 0, 0])
        
        pattern_sphere = mb.SpherePattern(200)
        pattern_sphere.scale(0.5)
        
        for pos in pattern_sphere:
            lj_particle = mb.clone(lj_proto)
            pos[0]-=1.0
            mb.translate(lj_particle, pos)
            self.add(lj_particle)
        
        pattern_disk = mb.DiskPattern(200)
        pattern_disk.scale(0.5)
        for pos in pattern_disk:
            lj_particle = mb.clone(lj_proto)
            pos[0]+=1.0
            mb.translate(lj_particle, pos)
            self.add(lj_particle)
monoLJ = MonoLJ()
monoLJ.visualize()
Explanation: Points on a sphere can be generated using SpherePattern. Points on a disk using DisKPattern, etc. 
Note to show both simultaneously, we shift the x-coordinate of Particles in the sphere by -1 (i.e., pos[0]-=1.0) and +1 for the disk (i.e, pos[0]+=1.0).
End of explanation
import mbuild as mb
class SphereLJ(mb.Compound):
    def __init__(self):
        super(SphereLJ, self).__init__()
        lj_proto = mb.Particle(name='LJ', pos=[0, 0, 0])
        
        pattern_sphere = mb.SpherePattern(200)
        pattern_sphere.scale(0.5)
        
        for pos in pattern_sphere:
            lj_particle = mb.clone(lj_proto)
            mb.translate(lj_particle, pos)
            self.add(lj_particle)
class DiskLJ(mb.Compound):
    def __init__(self):
        super(DiskLJ, self).__init__()
        lj_proto = mb.Particle(name='LJ', pos=[0, 0, 0])
        pattern_disk = mb.DiskPattern(200)
        pattern_disk.scale(0.5)
        for pos in pattern_disk:
            lj_particle = mb.clone(lj_proto)
            mb.translate(lj_particle, pos)
            self.add(lj_particle)
class MonoLJ(mb.Compound):
    def __init__(self):
        super(MonoLJ, self).__init__()
        
        sphere = SphereLJ();
        pos=[-1, 0, 0]
        mb.translate(sphere, pos)
        self.add(sphere)
        disk = DiskLJ();
        pos=[1, 0, 0]
        mb.translate(disk, pos)
        self.add(disk)
monoLJ = MonoLJ()
monoLJ.visualize()
Explanation: We can also take advantage of the hierachical nature of mBuild to accomplish the same task more cleanly.  Below we  create a component that corresponds to the sphere (class SphereLJ), and one that corresponds to the disk (class DiskLJ), and then instantiate and shift each of these individually in the MonoLJ component.
End of explanation
import mbuild as mb
class SphereLJ(mb.Compound):
    def __init__(self):
        super(SphereLJ, self).__init__()
        lj_proto = mb.Particle(name='LJ', pos=[0, 0, 0])
        
        pattern_sphere = mb.SpherePattern(13)
        pattern_sphere.scale(0.5)
        
        for pos in pattern_sphere:
            lj_particle = mb.clone(lj_proto)
            mb.translate(lj_particle, pos)
            self.add(lj_particle)
class MonoLJ(mb.Compound):
    def __init__(self):
        super(MonoLJ, self).__init__()
        sphere = SphereLJ();
        pattern = mb.Grid3DPattern(3, 3, 3)
        pattern.scale(10)
        for pos in pattern:
            lj_sphere = mb.clone(sphere)
            mb.translate_to(lj_sphere, pos)
            #shift the particle so the center of mass
            #of the system is at the origin
            mb.translate(lj_sphere, [-5,-5,-5])
            self.add(lj_sphere)
monoLJ = MonoLJ()
monoLJ.visualize()
Explanation: Again, since mBuild is hierarchical, the pattern functions can be used to generate large systems of any arbitary component.  For example, we can replicate the SphereLJ component on a regular array.
End of explanation
import mbuild as mb
import random
from numpy import pi
class CubeLJ(mb.Compound):
    def __init__(self):
        super(CubeLJ, self).__init__()
        lj_proto = mb.Particle(name='LJ', pos=[0, 0, 0])
        
        pattern = mb.Grid3DPattern(2, 2, 2)
        pattern.scale(1)
        for pos in pattern:
            lj_particle = mb.clone(lj_proto)
            mb.translate(lj_particle, pos)
            self.add(lj_particle)
            
class MonoLJ(mb.Compound):
    def __init__(self):
        super(MonoLJ, self).__init__()
        cube_proto = CubeLJ();
        pattern = mb.Grid3DPattern(3, 3, 3)
        pattern.scale(10)
        rnd = random.Random()
        rnd.seed(123)
        
        for pos in pattern:
            lj_cube = mb.clone(cube_proto)
            mb.translate_to(lj_cube, pos)
            #shift the particle so the center of mass
            #of the system is at the origin
            mb.translate(lj_cube, [-5,-5,-5])
            mb.spin_x(lj_cube, rnd.uniform(0, 2 * pi))
            mb.spin_y(lj_cube, rnd.uniform(0, 2 * pi))
            mb.spin_z(lj_cube, rnd.uniform(0, 2 * pi))
            self.add(lj_cube)
monoLJ = MonoLJ()
monoLJ.visualize()
Explanation: Several functions exist for rotating compounds. For example, the spin command allows a compound to be rotated, in place, about a specific axis (i.e., it considers the origin for the rotation to lie at the compound's center of mass).
End of explanation
#save as xyz file
monoLJ.save('output.xyz')
#save as mol2
monoLJ.save('output.mol2')
Explanation: Configurations can be dumped to file using the save command; this takes advantage of MDTraj and supports a range of file formats (see http://MDTraj.org).
End of explanation
<END_TASK>