SmilesAromatic
Date: 2019-10-22

org.jmol.smiles

## Class SmilesAromatic

- java.lang.Object
- - org.jmol.smiles.SmilesAromatic

-     public class SmilesAromatic
      extends java.lang.Object

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `private static int[][]` | `OS_PI_COUNTS` Index to inner array is covalent bond count (b) + valence (v) + charge (c, carbon only) - 4.

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `SmilesAromatic()`

  - ### Method Summary

    All Methods Static Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `private static boolean` | `addNormal(javajs.util.V3 vTemp, javajs.util.V3 vMean, float maxDev)` adds a normal if similarity is within limits
    `(package private) static void` | `checkAromaticDefined(Node[] jmolAtoms, javajs.util.BS bsSelected, javajs.util.BS bsAromatic)` Set aromatic atoms based on predefined BOND_AROMATIC definitions.
    `private static void` | `checkBridges(javajs.util.Lst<?> lst, javajs.util.BS bsBad, javajs.util.Lst<?> lst2, javajs.util.BS bsBad2, javajs.util.BS bs)`
    `private static void` | `checkFusedRings(javajs.util.Lst<SmilesRing> rings, int[] eCounts, javajs.util.Lst<javajs.util.BS> lstAromatic)` Add fused rings based on the Hueckel 4n+2 rule.
    `private static int` | `checkHueckelAromatic(int nAtoms, Node[] jmolAtoms, javajs.util.BS bsAromatic, javajs.util.BS bsRing, int strictness, int[] eCounts)` For each atom in the ring, look up a unique combination of covalent bond count, valence, and charge for each atom and use that as a key into the PI_COUNTS array.
    `private static boolean` | `checkStandardDeviation(javajs.util.V3[] vNorms, javajs.util.V3 vMean, int n, float cutoff)` calculates a dot-product standard deviation and reports if it is below a cutoff
    `(package private) static void` | `finalizeAromatic(Node[] jmolAtoms, javajs.util.BS bsAromatic, javajs.util.Lst<javajs.util.BS> lstAromatic, javajs.util.Lst<SmilesRing> lstSP2, int[] eCounts, boolean isOpenNotStrict, boolean isStrict)` Iteratively trims a set of aromatic atoms that may be initially assigned to be aromatic but because their double bonds extend to non-aromatic atoms must be removed.
    `private static boolean` | `isSp2Ring(int n, Node[] atoms, javajs.util.BS bsSelected, javajs.util.BS bs, float cutoff, boolean checkExplicit, boolean allowSOxide)` 3D-SEARCH aromaticity test.
    `private static void` | `removeBridgingRings(javajs.util.Lst<javajs.util.BS> lstAromatic, javajs.util.Lst<SmilesRing> lstSP2)` check for any two rings with more than two common atoms and remove them from the pool
    `(package private) static void` | `setAromatic(int n, Node[] jmolAtoms, javajs.util.BS bsSelected, javajs.util.Lst<java.lang.Object> vR, javajs.util.BS bsAromatic, int strictness, boolean isOpenSMILES, boolean justCheckBonding, boolean checkExplicit, VTemp v, javajs.util.Lst<javajs.util.BS> vOK, javajs.util.Lst<SmilesRing> lstSP2, int[] eCounts, boolean doTestAromatic)` Main entry point.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### OS_PI_COUNTS

          private static final int[][] OS_PI_COUNTS

      Index to inner array is covalent bond count (b) + valence (v) + charge (c, carbon only) - 4. Special cases are listed here as -1. -2 indicates not considered aromatic (probably not possible). Many thanks to John May for the excellent visual guide that I have condensed here.

  - ### Constructor Detail

    - #### SmilesAromatic

          public SmilesAromatic()

  - ### Method Detail

    - #### setAromatic

          static void setAromatic(int n,
                                  Node[] jmolAtoms,
                                  javajs.util.BS bsSelected,
                                  javajs.util.Lst<java.lang.Object> vR,
                                  javajs.util.BS bsAromatic,
                                  int strictness,
                                  boolean isOpenSMILES,
                                  boolean justCheckBonding,
                                  boolean checkExplicit,
                                  VTemp v,
                                  javajs.util.Lst<javajs.util.BS> vOK,
                                  javajs.util.Lst<SmilesRing> lstSP2,
                                  int[] eCounts,
                                  boolean doTestAromatic)

      Main entry point. Note that unless bonds are pre-defined as aromatic, Jmol will first check for a flat ring configuration. This is 3D, after all.
      Parameters:
        `n` -
        `jmolAtoms` -
        `bsSelected` -
        `vR` -
        `bsAromatic` -
        `strictness` -
        `isOpenSMILES` -
        `justCheckBonding` -
        `checkExplicit` -
        `v` -
        `vOK` -
        `lstSP2` -
        `eCounts` -
        `doTestAromatic` -

    - #### checkAromaticDefined

          static void checkAromaticDefined(Node[] jmolAtoms,
                                           javajs.util.BS bsSelected,
                                           javajs.util.BS bsAromatic)

      Set aromatic atoms based on predefined BOND_AROMATIC definitions. Allows for totally customized creation of aromatic SMILES.
      Parameters:
        `jmolAtoms` -
        `bsSelected` -
        `bsAromatic` -

    - #### isSp2Ring

          private static final boolean isSp2Ring(int n,
                                                 Node[] atoms,
                                                 javajs.util.BS bsSelected,
                                                 javajs.util.BS bs,
                                                 float cutoff,
                                                 boolean checkExplicit,
                                                 boolean allowSOxide)

      3D-SEARCH aromaticity test. A simple and unambiguous test for aromaticity based on 3D geometry and connectivity only, not Hueckel theory.
      Parameters:
        `n` -
        `atoms` - a set of atoms with coordinate positions and associated bonds.
        `bs` - a bitset of atoms within the set of atoms, defining the ring
        `bsSelected` - must not be null
        `cutoff` - an arbitrary value to test the standard deviation against. 0.01 is appropriate here. Use Float.MAX_VALUE to just do bond connectivity check
        `checkExplicit` - check bonds that are explicit only - for XYZ and QM calcs
        `allowSOxide` - set TRUE to skip S atoms
      Returns:
        true if standard deviation of vNorm.dot.vMean is less than cutoff

    - #### addNormal

          private static final boolean addNormal(javajs.util.V3 vTemp,
                                                 javajs.util.V3 vMean,
                                                 float maxDev)

      adds a normal if similarity is within limits
      Parameters:
        `vTemp` -
        `vMean` -
        `maxDev` -
      Returns:
        true if successful

    - #### checkStandardDeviation

          private static final boolean checkStandardDeviation(javajs.util.V3[] vNorms,
                                                              javajs.util.V3 vMean,
                                                              int n,
                                                              float cutoff)

      calculates a dot-product standard deviation and reports if it is below a cutoff
      Parameters:
        `vNorms` -
        `vMean` -
        `n` -
        `cutoff` -
      Returns:
        true if stddev < cutoff

    - #### checkHueckelAromatic

          private static int checkHueckelAromatic(int nAtoms,
                                                  Node[] jmolAtoms,
                                                  javajs.util.BS bsAromatic,
                                                  javajs.util.BS bsRing,
                                                  int strictness,
                                                  int[] eCounts)

      For each atom in the ring, look up a unique combination of covalent bond count, valence, and charge for each atom and use that as a key into the PI_COUNTS array. c=X is the only special case. Final trimming will be necesseary if isStrict == true.
      Parameters:
        `nAtoms` - this ring's size
        `jmolAtoms` - could also be constructed nodes from a SMILES string
        `bsAromatic` - at least nominally aromatic atoms
        `bsRing` - specific atoms of this ring
        `strictness` - 0 (not) 1 (OpenSMILES), 2 (MMFF94) standard organic chemist's Hueckel interpretation, not allowing c=O
        `eCounts` -
      Returns:
        -1 if absolutely not possible, 0 if possible but not 4n+2, 1 if 4n+2

    - #### finalizeAromatic

          static void finalizeAromatic(Node[] jmolAtoms,
                                       javajs.util.BS bsAromatic,
                                       javajs.util.Lst<javajs.util.BS> lstAromatic,
                                       javajs.util.Lst<SmilesRing> lstSP2,
                                       int[] eCounts,
                                       boolean isOpenNotStrict,
                                       boolean isStrict)

      Iteratively trims a set of aromatic atoms that may be initially assigned to be aromatic but because their double bonds extend to non-aromatic atoms must be removed. Checks to see that these atoms really have two adjacent aromatic atoms and are not connected to any nonaromatic atom by a double bond. Could be entered with one of /open/, /open strict/, or /strict/
      Parameters:
        `jmolAtoms` -
        `bsAromatic` -
        `lstAromatic` - all rings passing the sp2 test and (if strict) the Hueckel strict test
        `lstSP2` - all rings passing the sp2 test
        `eCounts` -
        `isOpenNotStrict` - /open/ option
        `isStrict` - remove noncyclic double bonds and do not allow bridging aromatic ring systems (/strict/ option)

    - #### removeBridgingRings

          private static void removeBridgingRings(javajs.util.Lst<javajs.util.BS> lstAromatic,
                                                  javajs.util.Lst<SmilesRing> lstSP2)

      check for any two rings with more than two common atoms and remove them from the pool
      Parameters:
        `lstAromatic` -
        `lstSP2` -

    - #### checkBridges

          private static void checkBridges(javajs.util.Lst<?> lst,
                                           javajs.util.BS bsBad,
                                           javajs.util.Lst<?> lst2,
                                           javajs.util.BS bsBad2,
                                           javajs.util.BS bs)

    - #### checkFusedRings

          private static void checkFusedRings(javajs.util.Lst<SmilesRing> rings,
                                              int[] eCounts,
                                              javajs.util.Lst<javajs.util.BS> lstAromatic)

      Add fused rings based on the Hueckel 4n+2 rule. Note that this may be reverted later if in a STRICT setting, because in at this point in some cases we will have double bonds to exocyclic nonaromatic atoms. We are being careful here to only group FUSED rings -- that is rings that have only one bond in common.
      Parameters:
        `rings` -
        `eCounts` -
        `lstAromatic` - list to be appended to