<commit_before>package etomica.box;

import etomica.action.BoxInflate;
import etomica.api.IAtomLeaf;
import etomica.api.IAtomSet;
import etomica.api.IBoundary;
import etomica.api.IBox;
import etomica.api.IBoxEventManager;
import etomica.api.IMolecule;
import etomica.api.ISimulation;
import etomica.api.ISpecies;
import etomica.atom.AtomArrayList;
import etomica.space.Boundary;
import etomica.space.BoundaryRectangularPeriodic;
import etomica.space.ISpace;
import etomica.util.Arrays;
import etomica.util.Debug;

/**
 * A Box collects all atoms that interact with one another; atoms in different
 * boxs do not interact. These are the important features of a Box:
 * <p>
 * <ol>
 * <li>It holds a SpeciesMaster instance, which provides the root of a
 * hierarchy of atoms that represent the physical objects that interact.
 * <li>It holds a Boundary object, obtained from the governing Space, that
 * defines the volume of the box and the behavior of atoms as they move into or
 * across the boundary of the box.
 * <li>It maintains a list of listeners that are informed when significant
 * events happen in the box (such as a change in its boundary).
 * <li>Each Box has a unique index assigned when it is constructed.
 * The index assignment begins at 0 and is incremented after each Box
 * construction. This index is useful when collecting things in reference to the
 * box.
 * </ol>
 * A box is acted upon by an Integrator instance to move its atoms around and
 * generate configurations. Properties of a box are measured by MeterAbstract
 * instances which are simply DataSource objects that require a box to
 * generate their data. <br>
 * A simulation may involve more than one box. All Box instances are
 * registered with the simulation specified upon their construction, and
 * may be accessed via the simulation's getBoxs method.
 * 
 * @author <NAME>, <NAME>
 * @see Boundary
 */
public class Box implements java.io.Serializable, IBox {

    /**
     * Constructs box with default rectangular periodic boundary.
     */
    public Box(ISimulation sim, ISpace _space) {
        this(new BoundaryRectangularPeriodic(sim.getRandom(), _space), _space);
    }
    
    /**
     * Constructs box with the given boundary
     */
    public Box(IBoundary boundary, ISpace _space) {
    	this.space = _space;
        eventManager = new BoxEventManager();
        setBoundary(boundary);
        
        moleculeLists = new AtomArrayList[0];
        allMoleculeList = new AtomSetAllMolecules();
        allMoleculeList.setMoleculeLists(moleculeLists);
        leafList = new AtomArrayList();
        
        indexReservoir = new int[reservoirSize];
        maxIndex = -1;
        reservoirCount = 0;
    }
    
    public void setIndex(int newIndex) {
        index = newIndex;
    }

    public int getIndex() {
        return index;
    }
    
    public String toString() {
        return "Box"+getIndex();
    }
    
    public IMolecule addNewMolecule(ISpecies species) {
        IMolecule aNew = species.makeMolecule();
        addMolecule(aNew);
        return aNew;
    }

    public void addMolecule(IMolecule molecule) {
        int speciesIndex = molecule.getType().getIndex();
        if (Debug.ON) {
            for (int i=0; i<moleculeLists[speciesIndex].getAtomCount(); i++) {
                if (moleculeLists[speciesIndex].getAtom(i) == molecule) {
                    throw new RuntimeException("you bastard!");
                }
            }
        }
        molecule.setIndex(moleculeLists[speciesIndex].getAtomCount());
        moleculeLists[speciesIndex].add(molecule);
        allMoleculeList.setMoleculeLists(moleculeLists);

        IAtomSet childList = molecule.getChildList();
        int nLeafAtoms = leafList.getAtomCount();
        for (int iChild = 0; iChild < childList.getAtomCount(); iChild++) {
            IAtomLeaf childAtom = (IAtomLeaf)childList.getAtom(iChild);
            childAtom.setLeafIndex(nLeafAtoms);
            leafList.add(childAtom);
        }
        eventManager.fireEvent(new BoxAtomAddedEvent(this, molecule));

        if (Debug.ON) {
            for (int i=0; i<moleculeLists[speciesIndex].getAtomCount(); i++) {
                if (moleculeLists[speciesIndex].getAtom(i).getIndex() != i) {
                    throw new RuntimeException("oops "+molecule+" "+moleculeLists[speciesIndex].getAtom(i)+" "+i);
                }
            }
        }
    }

    public void removeMolecule(IMolecule molecule) {
        int moleculeIndex = molecule.getIndex();
        AtomArrayList moleculeList = moleculeLists[molecule.getType().getIndex()];
        if (Debug.ON && moleculeList.getAtom(moleculeIndex) != molecule) {
            throw new IllegalArgumentException("can't find "+molecule);
        }
        if (moleculeIndex < moleculeList.getAtomCount()-1) {
            moleculeList.removeAndReplace(moleculeIndex);
            IMolecule replacingMolecule = (IMolecule)moleculeList.getAtom(moleculeIndex);
            replacingMolecule.setIndex(moleculeIndex);<commit_msg>increment nLeafAtoms so that leaf atoms within the same molecule get different leaf indices.<commit_after>package etomica.box;

import etomica.action.BoxInflate;
import etomica.api.IAtomLeaf;
import etomica.api.IAtomSet;
import etomica.api.IBoundary;
import etomica.api.IBox;
import etomica.api.IBoxEventManager;
import etomica.api.IMolecule;
import etomica.api.ISimulation;
import etomica.api.ISpecies;
import etomica.atom.AtomArrayList;
import etomica.space.Boundary;
import etomica.space.BoundaryRectangularPeriodic;
import etomica.space.ISpace;
import etomica.util.Arrays;
import etomica.util.Debug;

/**
 * A Box collects all atoms that interact with one another; atoms in different
 * boxs do not interact. These are the important features of a Box:
 * <p>
 * <ol>
 * <li>It holds a SpeciesMaster instance, which provides the root of a
 * hierarchy of atoms that represent the physical objects that interact.
 * <li>It holds a Boundary object, obtained from the governing Space, that
 * defines the volume of the box and the behavior of atoms as they move into or
 * across the boundary of the box.
 * <li>It maintains a list of listeners that are informed when significant
 * events happen in the box (such as a change in its boundary).
 * <li>Each Box has a unique index assigned when it is constructed.
 * The index assignment begins at 0 and is incremented after each Box
 * construction. This index is useful when collecting things in reference to the
 * box.
 * </ol>
 * A box is acted upon by an Integrator instance to move its atoms around and
 * generate configurations. Properties of a box are measured by MeterAbstract
 * instances which are simply DataSource objects that require a box to
 * generate their data. <br>
 * A simulation may involve more than one box. All Box instances are
 * registered with the simulation specified upon their construction, and
 * may be accessed via the simulation's getBoxs method.
 * 
 * @author <NAME>, <NAME>
 * @see Boundary
 */
public class Box implements java.io.Serializable, IBox {

    /**
     * Constructs box with default rectangular periodic boundary.
     */
    public Box(ISimulation sim, ISpace _space) {
        this(new BoundaryRectangularPeriodic(sim.getRandom(), _space), _space);
    }
    
    /**
     * Constructs box with the given boundary
     */
    public Box(IBoundary boundary, ISpace _space) {
    	this.space = _space;
        eventManager = new BoxEventManager();
        setBoundary(boundary);
        
        moleculeLists = new AtomArrayList[0];
        allMoleculeList = new AtomSetAllMolecules();
        allMoleculeList.setMoleculeLists(moleculeLists);
        leafList = new AtomArrayList();
        
        indexReservoir = new int[reservoirSize];
        maxIndex = -1;
        reservoirCount = 0;
    }
    
    public void setIndex(int newIndex) {
        index = newIndex;
    }

    public int getIndex() {
        return index;
    }
    
    public String toString() {
        return "Box"+getIndex();
    }
    
    public IMolecule addNewMolecule(ISpecies species) {
        IMolecule aNew = species.makeMolecule();
        addMolecule(aNew);
        return aNew;
    }

    public void addMolecule(IMolecule molecule) {
        int speciesIndex = molecule.getType().getIndex();
        if (Debug.ON) {
            for (int i=0; i<moleculeLists[speciesIndex].getAtomCount(); i++) {
                if (moleculeLists[speciesIndex].getAtom(i) == molecule) {
                    throw new RuntimeException("you bastard!");
                }
            }
        }
        molecule.setIndex(moleculeLists[speciesIndex].getAtomCount());
        moleculeLists[speciesIndex].add(molecule);
        allMoleculeList.setMoleculeLists(moleculeLists);

        IAtomSet childList = molecule.getChildList();
        int nLeafAtoms = leafList.getAtomCount();
        for (int iChild = 0; iChild < childList.getAtomCount(); iChild++) {
            IAtomLeaf childAtom = (IAtomLeaf)childList.getAtom(iChild);
            childAtom.setLeafIndex(nLeafAtoms++);
            leafList.add(childAtom);
        }
        eventManager.fireEvent(new BoxAtomAddedEvent(this, molecule));

        if (Debug.ON) {
            for (int i=0; i<moleculeLists[speciesIndex].getAtomCount(); i++) {
                if (moleculeLists[speciesIndex].getAtom(i).getIndex() != i) {
                    throw new RuntimeException("oops "+molecule+" "+moleculeLists[speciesIndex].getAtom(i)+" "+i);
                }
            }
        }
    }

    public void removeMolecule(IMolecule molecule) {
        int moleculeIndex = molecule.getIndex();
        AtomArrayList moleculeList = moleculeLists[molecule.getType().getIndex()];
        if (Debug.ON && moleculeList.getAtom(moleculeIndex) != molecule) {
            throw new IllegalArgumentException("can't find "+molecule);
        }
        if (moleculeIndex < moleculeList.getAtomCount()-1) {
            moleculeList.removeAndReplace(moleculeIndex);
            IMolecule replacingMolecule = (IMolecule)moleculeList.getAtom(moleculeIndex);
            replacingMolecule.setIndex(moleculeIndex);
{'fraction_non_alphanumeric': 0.09028256374913853, 'fraction_numerical': 0.0015752682878802796, 'mean_word_length': 2.97573385518591, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3701012', 'n_tokens_mistral': 3027, 'n_tokens_neox': 2841, 'n_words': 846}