3.5.1. Reactant
***************

In addition to the elements, coordinates, and bonds of the reactant
and product molecules, ACErxn needs a lot of information about the
molecular system. This additional required data can be summarized as
follows:

1. What the smallest possible fragments of the system are. The bonds
   between the atoms in these fragments will never be broken.

2. The charges of these smallest possible fragments.

3. The stability of these smallest possible fragments. If a fragment
   is determined to be unstable, it will be required to undergo change
   in every elementary reaction of the network.

The above information can be guessed automatically by the ACErxn code
if the following information is provided by you.

1. Which atoms in the reactant molecules are active atoms (can partake
   in bond breaking/forming).

2. The charge of the reactant molecules.

3. If there are any bonds between active atoms that can never be
   broken.

The figure below depicts an example of smallest fragments obtained
from the reactant molecules and the active atoms. The molecules at the
top are the reactant molecules, and the yellow-encircled atoms are
active atoms.

   [image]

The Reactant class contains all the above information on the reactant
molecules required by "ACErxnJob".

class Reactant(reactants, active_atoms, charges=None, min_bond_order=0.3)

   Class holding all reactant and information, and the definitions of
   the smallest fragments. This object needs to be passed to the
   constructor of "ACErxnJob".

   List of constructor arguments:

   * "reactants" - list of PLAMS "Molecule" objects, one for each
     reactant molecule.

   * "active_atoms" - list of lists of atom indices. For each reactant
     molecule, the indices of the active atoms are specified.

   * "charges" - list of floats representing the charges of the
     reactant submolecules.

   ACErxn needs information about the smallest possible fragments in
   the system. The bonds between the atoms in these fragments will
   never be broken in any of the reaction intermediates. The following
   fragment information is required.

   1. Elements, coordinates, and bonds for each fragment.

   2. The charges of the fragments.

   3. The stability of the fragments. If a fragments is determined to
      be unstable, an elementary reaction is only valid if this
      fragment undergoes change.

   The above information can be guessed automatically with
   "guess_fragments()" from the input data in the constructor
   arguments. The guessed fragment data is then stored in instance
   variables. The user is strongly recommended to check and alter the
   fragments, their charges, and their stabilities, after calling
   guess_fragments(), since chemical intuition is invaluable for the
   outcome.

   * "molecule" -- A single PLAMS "Molecule" object holding the entire
     reactant as a concatenation of the fragment molecules.

   * "fragments" -- A list of PLAMS "Molecule" objects, one for each
     smallest fragment. The objects contain info about the fragment
     charge and stability.

   * "submolecules" -- A list of PLAMS "Molecule" objects, one for
     each reactant molecule.

   * "submolecule_indices" -- A list of lists of integers, linking the
     "submolecules" indices to the indices in the full "molecule"
     variable.

   Example of use:

      >>> from scm.plams import Molecule
      >>> from scm.acerxn import Reactant

      >>> reactant_filenames = ['reactant.xyz']
      >>> molcharges = [0]
      >>> active_atoms = [[0,12,13,15]]

      >>> # Create the reactant molecules
      >>> reactants = [Molecule(fn) for fn in reactant_filenames]

      >>> # Create the Reactant object
      >>> reactant = Reactant(reactants, active_atoms, molcharges)

      >>> # Guess the fragment information
      >>> reactant.guess_fragments()

      >>> # Check the fragment information
      >>> print ('%8s %5s %s'%('Fragment','Charge','Stability'))
      >>> for i,mol in enumerate(reactant.fragments) :
      >>>     print ('%8i %5.2f %s'%(i,mol.properties.charge, mol.properties.stable))

      >>> print ('Indices fragments in submolecules: ')
      >>> for i,mol in enumerate(reactant.fragments) :
      >>>         print ('%8i '%(i),reactant.get_fragment_indices(i))

   Result:

      Fragment Charge Stability
             0 -1.00 False
             1  0.00 True
             2  1.00 False
      Indices fragments in submolecules:
             0  (0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
             1  (0, [13, 14])
             2  (0, [15])

   __len__()

      Returns the length of thee sum of fragments

   guess_fragments(frozen_bonds=None, products=None)

      Converts the reactants to the smallest fragments used to
      construct the intermediates

      * "frozen_bonds" -- list of lists of tuples of two integers. The
        tuples represent a bond between active atoms in a submolecule
        that can never be broken [[(0,1),(1,2)], [[0,1]]].

      * "products"     -- list of lists of products Molecule objects.
        Used to verify the stability of the fragments (if they match
        one of the products, they must be stable.)

      Note:

        Cuts the reactant molecules at the active atoms, to create the
        fragments

   set_fragments(fragment_indices, charges, stabilities)

      Set user defined fragments

      * "fragment_indices" -- For each fragment the indices of each
        atom in the reactant molecules {0: [[0,1,2], [3,4,5]], 1:
        [[0,1,2]]} Here the first two fragments came out of the
        reactant 0, and the last fragment out of reactant 1

      * "charges"          -- For each reactant molecule the charges
        of the fragments cut out of it {0: [0.,0.], 1: [0.]}

      * "stabilities"      -- For each reactant molecule the
        stabilities of the fragments cut out of it {0: [False, False],
        1: [True]}

   get_fragment_indices(ifrag, fragments=None, submolecule_indices=None)

      Get the indices of the specified fragment in the reactant
      molecules

      * "ifrag" -- The index of the fragment molecule for which the
        reactant indices should be returned.

      Returns a tuple, with as the first element the index of the
      reactant submolecule, and as the second element a list of atom
      indices in the submolecule. (0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
      10, 11, 12])

   get_fragment_indices_sumoffragments(ifrag, fragments=None)

      Get the indices of the specified fragment in the sum-of-
      fragments

   get_active_atoms()

      Read the active atoms from the submolecules

   write(filename=None)

      Write the reactants as AMS system blocks

      * "filename" -- Optional: The filename of an output file to
        whichthe system blocks should be written.

      Returns a string containing the system blocks.

   write_reactant(ireactant, frozen_bonds=None)

      Write a reactant molecule as a single AMS input block

      * "ireactant" -- The index of the reactant for which an AMS
        input block should be written.

      Returns a string containing the system block.

   set_regions(ireactant, fragments=None, submolecule_indices=None)

      Sets the regions in each submolecule

      * "ireactant" -- The index of the reactant for which an AMS
        input block should be written.

   classmethod read(filename=None, text=None, guess=True)

      Read reactant object from set of system blocks for reactants

      * "filename" -- Optional argument containing a filename from
        which the system blocks should be read

      * "text" -- If no filename is provided, the system block is read
        from this string.

      * "guess" -- If the fragment info is not yet in the file, guess
        it.

   classmethod from_molecules(reactants, guess=True, products=None, electronegativity_depth=1)

      Create the object from a list of submolecules containing the
      required reactant information (active atoms, charges, frozen
      bonds) in the properties variables.

      * "reactants" -- List of PLAMS "Molecule" objects with the
        charge present in mol.properties.charge, the active atom info
        in mol.atoms[i].properties.suffix, and the frozen bond info in
        mol.bonds[i].properties.suffix.

      * "guess" -- Guess the fragment info.

      * "electronegativity_depth" -- How many atoms are included in
        determining the electronegativity of a single atom (only the
        element itself, or the elements of the first neighbors, etc.)

      Note:

        The reactants are read in this format with the acerxn function
        *settings_from_amsinput*.

   check_fragments(fragments=None)

      Check if the all fragment information has been generated.

      * "fragments" -- Optionally a lsit of external fragment objects
        (PLAMS "Molecule" objects) can be provided here. By default,
        the instance variable *self.fragments* is used.

   write_xyz(dirname='.')

      Writes the reactants into a single human readable (XYZ) file

      * "dirname" -- The path to the XYZ file to be written.

   to_ace_intermediate()

      Convert reactant object to internal ACE "Intermediate" object

      Note:

        This method is used by "ACErxnJob". It should never be
        necessary for the user to access an ACE "Intermediate" object.

   get_elements()

      Get the elements of the full reactant

   identify_identical_fragments_with_chargedifferences()

      Return groups of fragments with identical bonding, but a
      different charge

   _prepare_state()

      Separate the reactants into submolecules if needed

   _guess_atomic_charges(molecule)

      Set the atomic charges in a single submolecule

   _adjust_stabilities(fragmol, products=None)

      Adjust the guessed stabilities based on if they are present in
      the reactants, and possibly products

   _map_to_submolecules(atoms)

      Map a set of atom indices from the sum of fragments to the
      submolecules
