/**
   * Fixes Aromaticity of the molecule i.e. need to find rings and aromaticity again since added H's
   *
   * @param mol
   */
  @TestMethod("testFixAromaticity")
  public static void configure(IAtomContainer mol) {
    // need to find rings and aromaticity again since added H's

    IRingSet ringSet = null;
    try {
      AllRingsFinder arf = new AllRingsFinder();
      ringSet = arf.findAllRings(mol);
    } catch (Exception e) {
      e.printStackTrace();
    }

    try {
      // figure out which atoms are in aromatic rings:
      CDKHydrogenAdder cdk = CDKHydrogenAdder.getInstance(DefaultChemObjectBuilder.getInstance());
      cdk.addImplicitHydrogens(mol);
      ExtAtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(mol);

      CDKHueckelAromaticityDetector.detectAromaticity(mol);
      // figure out which rings are aromatic:
      RingSetManipulator.markAromaticRings(ringSet);
      // figure out which simple (non cycles) rings are aromatic:

      // only atoms in 6 membered rings are aromatic
      // determine largest ring that each atom is a part of

      for (int i = 0; i < mol.getAtomCount(); i++) {
        mol.getAtom(i).setFlag(CDKConstants.ISAROMATIC, false);
        jloop:
        for (int j = 0; j < ringSet.getAtomContainerCount(); j++) {
          // logger.debug(i+"\t"+j);
          IRing ring = (IRing) ringSet.getAtomContainer(j);
          if (!ring.getFlag(CDKConstants.ISAROMATIC)) {
            continue jloop;
          }
          boolean haveatom = ring.contains(mol.getAtom(i));
          // logger.debug("haveatom="+haveatom);
          if (haveatom && ring.getAtomCount() == 6) {
            mol.getAtom(i).setFlag(CDKConstants.ISAROMATIC, true);
          }
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  /**
   * Get all paths of lengths 0 to the specified length.
   *
   * <p>This method will find all paths upto length N starting from each atom in the molecule and
   * return the unique set of such paths.
   *
   * @param container The molecule to search
   * @return A map of path strings, keyed on themselves
   */
  private Integer[] findPaths(IAtomContainer container) {

    ShortestPathWalker walker = new ShortestPathWalker(container);
    // convert paths to hashes
    List<Integer> paths = new ArrayList<Integer>();
    int patternIndex = 0;

    for (String s : walker.paths()) {
      int toHashCode = s.hashCode();
      paths.add(patternIndex, toHashCode);
      patternIndex++;
    }

    /*
     * Add ring information
     */
    IRingSet sssr = Cycles.essential(container).toRingSet();
    RingSetManipulator.sort(sssr);
    for (Iterator<IAtomContainer> it = sssr.atomContainers().iterator(); it.hasNext(); ) {
      IAtomContainer ring = it.next();
      int toHashCode = String.valueOf(ring.getAtomCount()).hashCode();
      paths.add(patternIndex, toHashCode);
      patternIndex++;
    }
    /*
     * Check for the charges
     */
    List<String> l = new ArrayList<String>();
    for (Iterator<IAtom> it = container.atoms().iterator(); it.hasNext(); ) {
      IAtom atom = it.next();
      int charge = atom.getFormalCharge() == null ? 0 : atom.getFormalCharge();
      if (charge != 0) {
        l.add(atom.getSymbol().concat(String.valueOf(charge)));
      }
    }
    Collections.sort(l);
    int toHashCode = l.hashCode();
    paths.add(patternIndex, toHashCode);
    patternIndex++;

    l = new ArrayList<String>();
    /*
     * atom stereo parity
     */
    for (Iterator<IAtom> it = container.atoms().iterator(); it.hasNext(); ) {
      IAtom atom = it.next();
      int st = atom.getStereoParity() == null ? 0 : atom.getStereoParity();
      if (st != 0) {
        l.add(atom.getSymbol().concat(String.valueOf(st)));
      }
    }
    Collections.sort(l);
    toHashCode = l.hashCode();
    paths.add(patternIndex, toHashCode);
    patternIndex++;

    if (container.getSingleElectronCount() > 0) {
      StringBuilder radicalInformation = new StringBuilder();
      radicalInformation.append("RAD: ").append(String.valueOf(container.getSingleElectronCount()));
      paths.add(patternIndex, radicalInformation.toString().hashCode());
      patternIndex++;
    }
    if (container.getLonePairCount() > 0) {
      StringBuilder lpInformation = new StringBuilder();
      lpInformation.append("LP: ").append(String.valueOf(container.getLonePairCount()));
      paths.add(patternIndex, lpInformation.toString().hashCode());
      patternIndex++;
    }
    return paths.toArray(new Integer[paths.size()]);
  }
Example #3
0
  /**
   * Finds the Smallest Set of Smallest Rings.
   *
   * @param mol the molecule to be searched for rings
   * @return a RingSet containing the rings in molecule
   */
  public IRingSet findSSSR(IAtomContainer mol) {
    IBond brokenBond = null;
    IChemObjectBuilder builder = mol.getBuilder();
    IRingSet sssr = builder.newInstance(IRingSet.class);
    IAtomContainer molecule = builder.newInstance(IAtomContainer.class);
    molecule.add(mol);
    IAtom smallest;
    int smallestDegree, nodesToBreakCounter, degree;
    IAtom[] rememberNodes;
    IRing ring;

    // Two Vectors - as defined in the article. One to hold the
    // full set of atoms in the structure and on to store the numbers
    // of the nodes that have been trimmed away.
    // Furhter there is a Vector nodesN2 to store the number of N2 nodes
    List<IAtom> fullSet = new ArrayList<IAtom>();
    List<IAtom> trimSet = new ArrayList<IAtom>();
    List<IAtom> nodesN2 = new ArrayList<IAtom>();

    initPath(molecule);
    logger.debug("molecule.getAtomCount(): " + molecule.getAtomCount());
    // load fullSet with the numbers of our atoms
    for (int f = 0; f < molecule.getAtomCount(); f++) {
      fullSet.add(molecule.getAtom(f));
    }
    logger.debug("fullSet.size(): " + fullSet.size());

    do {
      // Add nodes of degree zero to trimset.
      // Also add nodes of degree 2 to nodesN2.
      // In the same run, check, which node has the lowest degree
      // greater than zero.
      smallestDegree = 7;
      smallest = null;
      nodesN2.clear();
      for (int f = 0; f < molecule.getAtomCount(); f++) {
        IAtom atom = molecule.getAtom(f);
        degree = molecule.getConnectedBondsCount(atom);
        if (degree == 0) {
          if (!trimSet.contains(atom)) {
            logger.debug("Atom of degree 0");
            trimSet.add(atom);
          }
        }
        if (degree == 2) {
          nodesN2.add(atom);
        }
        if (degree < smallestDegree && degree > 0) {
          smallest = atom;
          smallestDegree = degree;
        }
      }
      if (smallest == null) break;

      // If there are nodes of degree 1, trim them away
      if (smallestDegree == 1) {
        trimCounter++;
        trim(smallest, molecule);
        trimSet.add(smallest);
      }

      // if there are nodes of degree 2, find out of which rings
      // they are part of.
      else if (smallestDegree == 2) {
        rememberNodes = new IAtom[nodesN2.size()];
        nodesToBreakCounter = 0;
        for (int f = 0; f < nodesN2.size(); f++) {
          ring = getRing((IAtom) nodesN2.get(f), molecule);
          if (ring != null) {
            // check, if this ring already is in SSSR
            if (!RingSetManipulator.ringAlreadyInSet(ring, sssr)) {
              sssr.addAtomContainer(ring);
              rememberNodes[nodesToBreakCounter] = (IAtom) nodesN2.get(f);
              nodesToBreakCounter++;
            }
          }
        }
        if (nodesToBreakCounter == 0) {
          nodesToBreakCounter = 1;
          rememberNodes[0] = (IAtom) nodesN2.get(0);
        }
        for (int f = 0; f < nodesToBreakCounter; f++) {
          breakBond(rememberNodes[f], molecule);
        }
        if (brokenBond != null) {
          molecule.addBond(brokenBond);
          brokenBond = null;
        }
      }
      // if there are nodes of degree 3
      else if (smallestDegree == 3) {
        ring = getRing(smallest, molecule);
        if (ring != null) {

          // check, if this ring already is in SSSR
          if (!RingSetManipulator.ringAlreadyInSet(ring, sssr)) {
            sssr.addAtomContainer(ring);
          }
          brokenBond = checkEdges(ring, molecule);
          molecule.removeElectronContainer(brokenBond);
        }
      }
    } while (trimSet.size() < fullSet.size());
    logger.debug("fullSet.size(): " + fullSet.size());
    logger.debug("trimSet.size(): " + trimSet.size());
    logger.debug("trimCounter: " + trimCounter);
    //		molecule.setProperty(CDKConstants.SMALLEST_RINGS, sssr);
    return sssr;
  }