/** Converts a Bond to a MSML Bond element */
  protected BondType convertBond(IBond bond, String parentID, ArrayList<String> hashes) {
    BondType bondElement = new BondType();
    String bondID = parentID + PREFIX_BOND + bond.hashCode();
    bondElement.setId(bondID);
    int atom1 = hashes.indexOf(Integer.toString(bond.getAtom(0).hashCode())) + 1;
    int atom2 = hashes.indexOf(Integer.toString(bond.getAtom(1).hashCode())) + 1;
    // bondElement.setCustomId("" + bond.getID());
    // atom name
    // bondElement.setTitle(bond.getID());
    /*
     * System.out.println(bond.getAtom(0).getSymbol()); System.out.println(bond.getAtom(1).getSymbol());
     */

    String a1 = "a" + atom1;
    String a2 = "a" + atom2;
    List<String> atomrefs = bondElement.getAtomRefs2();
    atomrefs.add(a1); // add first atom in bond
    atomrefs.add(a2); // add second atom in bond
    if (bond.getOrder() != null) {
      bondElement.setOrder(bond.getOrder().toString());
    }
    /*
     * if (bond.getStereo() != null){ bondElement.setStereo(bond.getStereo().toString()); //no stereo property as of
     * now }
     */

    return bondElement;
  }
Ejemplo n.º 2
0
  /**
   * Returns a CIP-expanded array of side chains of a ligand. If the ligand atom is only connected
   * to the chiral atom, the method will return an empty list. The expansion involves the CIP rules,
   * so that a double bonded oxygen will be represented twice in the list.
   *
   * @param ligand the {@link ILigand} for which to return the ILigands
   * @return a {@link ILigand} array with the side chains of the ligand atom
   */
  @TestMethod("testGetLigandLigands")
  public static ILigand[] getLigandLigands(ILigand ligand) {
    if (ligand instanceof TerminalLigand) return new ILigand[0];

    IAtomContainer container = ligand.getAtomContainer();
    IAtom ligandAtom = ligand.getLigandAtom();
    IAtom centralAtom = ligand.getCentralAtom();
    VisitedAtoms visitedAtoms = ligand.getVisitedAtoms();
    List<IBond> bonds = container.getConnectedBondsList(ligandAtom);
    // duplicate ligands according to bond order, following the CIP rules
    List<ILigand> ligands = new ArrayList<ILigand>();
    for (IBond bond : bonds) {
      if (bond.contains(centralAtom)) {
        if (Order.SINGLE == bond.getOrder()) continue;
        int duplication = getDuplication(bond.getOrder()) - 1;
        if (duplication > 0) {
          for (int i = 1; i <= duplication; i++) {
            ligands.add(new TerminalLigand(container, visitedAtoms, ligandAtom, centralAtom));
          }
        }
      } else {
        int duplication = getDuplication(bond.getOrder());
        IAtom connectedAtom = bond.getConnectedAtom(ligandAtom);
        if (visitedAtoms.isVisited(connectedAtom)) {
          ligands.add(new TerminalLigand(container, visitedAtoms, ligandAtom, connectedAtom));
        } else {
          ligands.add(new Ligand(container, visitedAtoms, ligandAtom, connectedAtom));
        }
        for (int i = 2; i <= duplication; i++) {
          ligands.add(new TerminalLigand(container, visitedAtoms, ligandAtom, connectedAtom));
        }
      }
    }
    return ligands.toArray(new ILigand[0]);
  }
Ejemplo n.º 3
0
 /**
  * Return true if a bond is matched between query and target
  *
  * @param targetBond
  * @return
  */
 private boolean isBondTypeMatch(IBond targetBond) {
   if ((queryBond.getFlag(CDKConstants.ISAROMATIC) == targetBond.getFlag(CDKConstants.ISAROMATIC))
       && (queryBond.getOrder() == targetBond.getOrder())) {
     return true;
   } else if (queryBond.getFlag(CDKConstants.ISAROMATIC)
       && targetBond.getFlag(CDKConstants.ISAROMATIC)) {
     return true;
   }
   return false;
 }
Ejemplo n.º 4
0
  @Test
  public void testBond5() throws Exception {
    String cmlString =
        "<molecule id='m1'><atomArray atomID='a1 a2 a3'/><bondArray atomRef1='a1 a1' atomRef2='a2 a3' order='1 1'/></molecule>";

    IChemFile chemFile = parseCMLString(cmlString);
    IMolecule mol = checkForSingleMoleculeFile(chemFile);

    Assert.assertEquals(3, mol.getAtomCount());
    Assert.assertEquals(2, mol.getBondCount());
    org.openscience.cdk.interfaces.IBond bond = mol.getBond(0);
    Assert.assertEquals(2, bond.getAtomCount());
    Assert.assertEquals(IBond.Order.SINGLE, bond.getOrder());
    bond = mol.getBond(1);
    Assert.assertEquals(2, bond.getAtomCount());
    Assert.assertEquals(IBond.Order.SINGLE, bond.getOrder());
  }
  /**
   * set the active center for this molecule. The active center will be those which correspond with
   * [A*]-B=C .
   *
   * <pre>
   * A: Atom with single electron
   * -: Single bond
   * B: Atom
   * =: Double bond
   * C: Atom
   *  </pre>
   *
   * @param reactant The molecule to set the activity
   * @throws CDKException
   */
  private void setActiveCenters(IAtomContainer reactant) throws CDKException {
    if (AtomContainerManipulator.getTotalNegativeFormalCharge(reactant)
        != 0 /*|| AtomContainerManipulator.getTotalPositiveFormalCharge(reactant) != 0*/) return;
    Iterator<IAtom> atoms = reactant.atoms().iterator();
    while (atoms.hasNext()) {
      IAtom atomi = atoms.next();
      if (reactant.getConnectedSingleElectronsCount(atomi) == 1) {

        Iterator<IBond> bondis = reactant.getConnectedBondsList(atomi).iterator();

        while (bondis.hasNext()) {
          IBond bondi = bondis.next();

          if (bondi.getOrder() == IBond.Order.SINGLE) {

            IAtom atomj = bondi.getConnectedAtom(atomi);
            if ((atomj.getFormalCharge() == CDKConstants.UNSET ? 0 : atomj.getFormalCharge()) == 0
                && reactant.getConnectedSingleElectronsCount(atomj) == 0) {

              Iterator<IBond> bondjs = reactant.getConnectedBondsList(atomj).iterator();
              while (bondjs.hasNext()) {
                IBond bondj = bondjs.next();

                if (bondj.equals(bondi)) continue;

                if (bondj.getOrder() == IBond.Order.DOUBLE) {

                  IAtom atomk = bondj.getConnectedAtom(atomj);
                  if ((atomk.getFormalCharge() == CDKConstants.UNSET ? 0 : atomk.getFormalCharge())
                          == 0
                      && reactant.getConnectedSingleElectronsCount(atomk) == 0) {

                    atomi.setFlag(CDKConstants.REACTIVE_CENTER, true);
                    atomj.setFlag(CDKConstants.REACTIVE_CENTER, true);
                    atomk.setFlag(CDKConstants.REACTIVE_CENTER, true);
                    bondi.setFlag(CDKConstants.REACTIVE_CENTER, true);
                    bondj.setFlag(CDKConstants.REACTIVE_CENTER, true);
                  }
                }
              }
            }
          }
        }
      }
    }
  }
Ejemplo n.º 6
0
  /**
   * Initiate process. It is needed to call the addExplicitHydrogensToSatisfyValency from the class
   * tools.HydrogenAdder.
   *
   * @param reactants reactants of the reaction
   * @param agents agents of the reaction (Must be in this case null)
   * @exception CDKException Description of the Exception
   */
  @TestMethod("testInitiate_IMoleculeSet_IMoleculeSet")
  public IReactionSet initiate(IMoleculeSet reactants, IMoleculeSet agents) throws CDKException {

    logger.debug("initiate reaction: HeterolyticCleavagePBReaction");

    if (reactants.getMoleculeCount() != 1) {
      throw new CDKException("HeterolyticCleavagePBReaction only expects one reactant");
    }
    if (agents != null) {
      throw new CDKException("HeterolyticCleavagePBReaction don't expects agents");
    }

    IReactionSet setOfReactions =
        DefaultChemObjectBuilder.getInstance().newInstance(IReactionSet.class);
    IMolecule reactant = reactants.getMolecule(0);

    /* if the parameter hasActiveCenter is not fixed yet, set the active centers*/
    IParameterReact ipr = super.getParameterClass(SetReactionCenter.class);
    if (ipr != null && !ipr.isSetParameter()) setActiveCenters(reactant);

    Iterator<IBond> bondis = reactant.bonds().iterator();
    while (bondis.hasNext()) {
      IBond bondi = bondis.next();
      IAtom atom1 = bondi.getAtom(0);
      IAtom atom2 = bondi.getAtom(1);
      if (bondi.getFlag(CDKConstants.REACTIVE_CENTER)
          && bondi.getOrder() != IBond.Order.SINGLE
          && atom1.getFlag(CDKConstants.REACTIVE_CENTER)
          && atom2.getFlag(CDKConstants.REACTIVE_CENTER)
          && (atom1.getFormalCharge() == CDKConstants.UNSET ? 0 : atom1.getFormalCharge()) == 0
          && (atom2.getFormalCharge() == CDKConstants.UNSET ? 0 : atom2.getFormalCharge()) == 0
          && reactant.getConnectedSingleElectronsCount(atom1) == 0
          && reactant.getConnectedSingleElectronsCount(atom2) == 0) {

        /**/
        for (int j = 0; j < 2; j++) {

          ArrayList<IAtom> atomList = new ArrayList<IAtom>();
          if (j == 0) {
            atomList.add(atom1);
            atomList.add(atom2);
          } else {
            atomList.add(atom2);
            atomList.add(atom1);
          }
          ArrayList<IBond> bondList = new ArrayList<IBond>();
          bondList.add(bondi);

          IMoleculeSet moleculeSet = reactant.getBuilder().newInstance(IMoleculeSet.class);
          moleculeSet.addMolecule(reactant);
          IReaction reaction = mechanism.initiate(moleculeSet, atomList, bondList);
          if (reaction == null) continue;
          else setOfReactions.addReaction(reaction);
        }
      }
    }
    return setOfReactions;
  }
Ejemplo n.º 7
0
 @Override
 public int seed(IAtomContainer molecule, IAtom atom, BitSet mask) {
   double sum = 0;
   for (IBond bond : molecule.getConnectedBondsList(atom)) {
     if (mask.get(molecule.getAtomNumber(bond.getConnectedAtom(atom))))
       sum += order(bond.getOrder());
   }
   return ((Double) sum).hashCode();
 }
Ejemplo n.º 8
0
 private int getAttachedMultipleBondCount(IAtom atom, IAtomContainer atomContainer) {
   int count = 0;
   for (IBond bond : atomContainer.getConnectedBondsList(atom)) {
     if (bond.getOrder() == IBond.Order.SINGLE) {
       continue;
     }
     ++count;
   }
   return count;
 }
Ejemplo n.º 9
0
 /**
  * Determines if the isolatedRingSystem has attached double bonds, which are not part of the ring
  * system itself, and not part of any other ring system. Exceptions: a N.sp2.3 nitrogen with a
  * double ring to an oxygen outwards.
  */
 private static boolean isRingSystemSproutedWithNonRingDoubleBonds(
     IAtomContainer fullContainer, IAtomContainer isolatedRingSystem) {
   Iterator<IAtom> atoms = isolatedRingSystem.atoms().iterator();
   while (atoms.hasNext()) {
     IAtom atom = atoms.next();
     Iterator<IBond> neighborBonds = fullContainer.getConnectedBondsList(atom).iterator();
     while (neighborBonds.hasNext()) {
       IBond neighborBond = neighborBonds.next();
       if (!neighborBond.getFlag(CDKConstants.ISINRING)
               && neighborBond.getOrder() == CDKConstants.BONDORDER_DOUBLE
           || neighborBond.getOrder() == CDKConstants.BONDORDER_TRIPLE) {
         if (!("N.sp2.3".equals(atom.getAtomTypeName())
             && "O.sp2".equals(neighborBond.getConnectedAtom(atom).getAtomTypeName())))
           return true;
       }
     }
   }
   return false;
 }
  /**
   * set the active center for this molecule. The active center will be those which correspond with
   * A-B-[C*].
   *
   * <pre>
   * A: Atom
   * -: bond
   * B: Atom
   * -: bond
   * C: Atom with single electron
   *  </pre>
   *
   * @param reactant The molecule to set the activity
   * @throws CDKException
   */
  private void setActiveCenters(IMolecule reactant) throws CDKException {

    Iterator<IAtom> atoms = reactant.atoms().iterator();
    while (atoms.hasNext()) {
      IAtom atomi = atoms.next();
      if (reactant.getConnectedSingleElectronsCount(atomi) == 1 && atomi.getFormalCharge() == 1) {

        Iterator<IBond> bondis = reactant.getConnectedBondsList(atomi).iterator();

        while (bondis.hasNext()) {
          IBond bondi = bondis.next();

          if (bondi.getOrder() == IBond.Order.SINGLE) {

            IAtom atomj = bondi.getConnectedAtom(atomi);
            if (atomj.getFormalCharge() == 0) {

              Iterator<IBond> bondjs = reactant.getConnectedBondsList(atomj).iterator();
              while (bondjs.hasNext()) {
                IBond bondj = bondjs.next();

                if (bondj.equals(bondi)) continue;

                if (bondj.getOrder() == IBond.Order.SINGLE) {

                  IAtom atomk = bondj.getConnectedAtom(atomj);
                  if (atomk.getSymbol().equals("C") && atomk.getFormalCharge() == 0) {
                    atomi.setFlag(CDKConstants.REACTIVE_CENTER, true);
                    atomj.setFlag(CDKConstants.REACTIVE_CENTER, true);
                    atomk.setFlag(CDKConstants.REACTIVE_CENTER, true);
                    bondi.setFlag(CDKConstants.REACTIVE_CENTER, true);
                    bondj.setFlag(CDKConstants.REACTIVE_CENTER, true);
                  }
                }
              }
            }
          }
        }
      }
    }
  }
Ejemplo n.º 11
0
  @Test
  public void testBondAromatic2() throws Exception {
    String cmlString =
        "<molecule id='m1'><atomArray atomID='a1 a2'/><bondArray><bond atomRefs='a1 a2' order='2'><bondType dictRef='cdk:aromaticBond'/></bond></bondArray></molecule>";
    IChemFile chemFile = parseCMLString(cmlString);
    IMolecule mol = checkForSingleMoleculeFile(chemFile);

    Assert.assertEquals(2, mol.getAtomCount());
    Assert.assertEquals(1, mol.getBondCount());
    org.openscience.cdk.interfaces.IBond bond = mol.getBond(0);
    Assert.assertEquals(CDKConstants.BONDORDER_DOUBLE, bond.getOrder());
    Assert.assertTrue(bond.getFlag(CDKConstants.ISAROMATIC));
  }
Ejemplo n.º 12
0
 private boolean getIfACarbonIsDoubleBondedToAnOxygen(Molecule mol, IAtom carbonAtom) {
   boolean isDoubleBondedToOxygen = false;
   List<IAtom> neighToCarbon = mol.getConnectedAtomsList(carbonAtom);
   IBond tmpBond;
   int counter = 0;
   for (int nei = 0; nei < neighToCarbon.size(); nei++) {
     IAtom neighbour = neighToCarbon.get(nei);
     if (neighbour.getSymbol().equals("O")) {
       tmpBond = mol.getBond(neighbour, carbonAtom);
       if (tmpBond.getOrder() == IBond.Order.DOUBLE) counter += 1;
     }
   }
   if (counter > 0) isDoubleBondedToOxygen = true;
   return isDoubleBondedToOxygen;
 }
Ejemplo n.º 13
0
 /**
  * set the active center for this molecule. The active center will be those which correspond with
  * A-B. If the bond is simple, it will be broken forming two fragments
  *
  * <pre>
  * A: Atom
  * #/=/-: bond
  * B: Atom
  *  </pre>
  *
  * @param reactant The molecule to set the activity
  * @throws CDKException
  */
 private void setActiveCenters(IMolecule reactant) throws CDKException {
   Iterator<IBond> bonds = reactant.bonds().iterator();
   while (bonds.hasNext()) {
     IBond bond = bonds.next();
     IAtom atom1 = bond.getAtom(0);
     IAtom atom2 = bond.getAtom(1);
     if (bond.getOrder() != IBond.Order.SINGLE
         && (atom1.getFormalCharge() == CDKConstants.UNSET ? 0 : atom1.getFormalCharge()) == 0
         && (atom2.getFormalCharge() == CDKConstants.UNSET ? 0 : atom2.getFormalCharge()) == 0
         && reactant.getConnectedSingleElectronsCount(atom1) == 0
         && reactant.getConnectedSingleElectronsCount(atom2) == 0) {
       atom1.setFlag(CDKConstants.REACTIVE_CENTER, true);
       atom2.setFlag(CDKConstants.REACTIVE_CENTER, true);
       bond.setFlag(CDKConstants.REACTIVE_CENTER, true);
     }
   }
 }
Ejemplo n.º 14
0
  @Test(timeout = 1000)
  public void testPyrrole_Silent() throws Exception {
    String smiles = "c2ccc3n([H])c1ccccc1c3(c2)";
    SmilesParser smilesParser = new SmilesParser(SilentChemObjectBuilder.getInstance());
    IAtomContainer molecule = smilesParser.parseSmiles(smiles);

    molecule = fbot.kekuliseAromaticRings(molecule);
    Assert.assertNotNull(molecule);

    molecule = (IAtomContainer) AtomContainerManipulator.removeHydrogens(molecule);
    int doubleBondCount = 0;
    for (int i = 0; i < molecule.getBondCount(); i++) {
      IBond bond = molecule.getBond(i);
      Assert.assertTrue(bond.getFlag(CDKConstants.ISAROMATIC));
      if (bond.getOrder() == Order.DOUBLE) doubleBondCount++;
    }
    Assert.assertEquals(6, doubleBondCount);
  }
Ejemplo n.º 15
0
  protected void process(
      IAtomContainer target,
      List<Integer> unmapped_atoms_molB,
      int mappingSize,
      List<Integer> i_bond_setB,
      List<String> c_bond_setB,
      List<Integer> mapped_atoms,
      int counter) {

    int unmapped_numB = unmapped_atoms_molB.size();
    boolean bond_considered = false;
    boolean normal_bond = true;

    for (int atomIndex = 0; atomIndex < target.getBondCount(); atomIndex++) {

      Integer indexI = target.getAtomNumber(target.getBond(atomIndex).getAtom(0));
      Integer indexJ = target.getAtomNumber(target.getBond(atomIndex).getAtom(1));
      IBond bond = target.getBond(atomIndex);
      Integer order = (bond.getOrder().ordinal() + 1);

      for (int b = 0; b < unmapped_numB; b++) {
        if (unmapped_atoms_molB.get(b).equals(indexI)) {
          normal_bond =
              unMappedAtomsEqualsIndexI(
                  target, mappingSize, atomIndex, counter, mapped_atoms, indexI, indexJ, order);
          bond_considered = true;
        } else if (unmapped_atoms_molB.get(b) == indexJ) {
          normal_bond =
              unMappedAtomsEqualsIndexJ(
                  target, mappingSize, atomIndex, counter, mapped_atoms, indexI, indexJ, order);
          bond_considered = true;
        }

        if (normal_bond && bond_considered) {
          markNormalBonds(atomIndex, i_bond_setB, c_bond_setB, indexI, indexJ, order);
          normal_bond = true;
          break;
        }
      }
      bond_considered = false;
    }
  }
Ejemplo n.º 16
0
  @Test
  public void testLargeRingSystem() throws Exception {
    String smiles = "O=C1Oc6ccccc6(C(O)C1C5c2ccccc2CC(c3ccc(cc3)c4ccccc4)C5)";
    SmilesParser smilesParser = new SmilesParser(DefaultChemObjectBuilder.getInstance());
    IAtomContainer molecule = smilesParser.parseSmiles(smiles);

    molecule = fbot.kekuliseAromaticRings(molecule);
    Assert.assertNotNull(molecule);

    molecule = (IAtomContainer) AtomContainerManipulator.removeHydrogens(molecule);
    Assert.assertEquals(34, molecule.getAtomCount());

    // we should have 14 double bonds
    int doubleBondCount = 0;
    for (int i = 0; i < molecule.getBondCount(); i++) {
      IBond bond = molecule.getBond(i);
      if (bond.getOrder() == Order.DOUBLE) doubleBondCount++;
    }
    Assert.assertEquals(13, doubleBondCount);
  }
Ejemplo n.º 17
0
  /** @cdk.bug 3506770 */
  @Test
  public void testLargeBioclipseUseCase() throws Exception {
    String smiles =
        "COc1ccc2[C@@H]3[C@H](COc2c1)C(C)(C)OC4=C3C(=O)C(=O)C5=C4OC(C)(C)[C@@H]6COc7cc(OC)ccc7[C@H]56";
    SmilesParser smilesParser = new SmilesParser(DefaultChemObjectBuilder.getInstance());
    IAtomContainer molecule = smilesParser.parseSmiles(smiles);

    molecule = fbot.kekuliseAromaticRings(molecule);
    Assert.assertNotNull(molecule);

    molecule = (IAtomContainer) AtomContainerManipulator.removeHydrogens(molecule);
    Assert.assertEquals(40, molecule.getAtomCount());

    // we should have 14 double bonds
    int doubleBondCount = 0;
    for (int i = 0; i < molecule.getBondCount(); i++) {
      IBond bond = molecule.getBond(i);
      if (bond.getOrder() == Order.DOUBLE) doubleBondCount++;
    }
    Assert.assertEquals(10, doubleBondCount);
  }
Ejemplo n.º 18
0
  /**
   * This method calculate the number of bonds of a given type in an atomContainer
   *
   * @param container AtomContainer
   * @return The number of bonds of a certain type.
   */
  @Override
  public DescriptorValue calculate(IAtomContainer container) {
    if (order.equals("")) {
      int bondCount = 0;
      for (IBond bond : container.bonds()) {
        boolean hasHydrogen = false;
        for (int i = 0; i < bond.getAtomCount(); i++) {
          if (bond.getAtom(i).getSymbol().equals("H")) {
            hasHydrogen = true;
            break;
          }
        }
        if (!hasHydrogen) bondCount++;
      }
      return new DescriptorValue(
          getSpecification(),
          getParameterNames(),
          getParameters(),
          new IntegerResult(bondCount),
          getDescriptorNames(),
          null);
    }

    int bondCount = 0;
    for (IBond bond : container.bonds()) {
      if (bondMatch(bond.getOrder(), order)) {
        bondCount += 1;
      }
    }

    return new DescriptorValue(
        getSpecification(),
        getParameterNames(),
        getParameters(),
        new IntegerResult(bondCount),
        getDescriptorNames());
  }
Ejemplo n.º 19
0
 /**
  * Helper method determines if a bond is defined (not null) and whether it is a sigma (single)
  * bond with no stereo attribute (wedge/hatch).
  *
  * @param bond the bond to test
  * @return the bond is a planar sigma bond
  */
 private static boolean isPlanarSigmaBond(IBond bond) {
   return bond != null
       && IBond.Order.SINGLE.equals(bond.getOrder())
       && IBond.Stereo.NONE.equals(bond.getStereo());
 }
 /**
  * Determine whether the bond order is 'double'.
  *
  * @param bond a bond
  * @return the bond is a double bond.
  */
 private static boolean isDoubleBond(IBond bond) {
   return IBond.Order.DOUBLE.equals(bond.getOrder());
 }
  /**
   * Initiate process. It is needed to call the addExplicitHydrogensToSatisfyValency from the class
   * tools.HydrogenAdder.
   *
   * @exception CDKException Description of the Exception
   * @param reactants reactants of the reaction.
   * @param agents agents of the reaction (Must be in this case null).
   */
  @TestMethod("testInitiate_IAtomContainerSet_IAtomContainerSet")
  public IReactionSet initiate(IAtomContainerSet reactants, IAtomContainerSet agents)
      throws CDKException {

    logger.debug("initiate reaction: RearrangementRadicalReaction");

    if (reactants.getAtomContainerCount() != 1) {
      throw new CDKException("RearrangementRadicalReaction only expects one reactant");
    }
    if (agents != null) {
      throw new CDKException("RearrangementRadicalReaction don't expects agents");
    }

    IReactionSet setOfReactions =
        DefaultChemObjectBuilder.getInstance().newInstance(IReactionSet.class);
    IAtomContainer reactant = reactants.getAtomContainer(0);

    /* if the parameter hasActiveCenter is not fixed yet, set the active centers*/
    IParameterReact ipr = super.getParameterClass(SetReactionCenter.class);
    if (ipr != null && !ipr.isSetParameter()) setActiveCenters(reactant);

    Iterator<IAtom> atoms = reactants.getAtomContainer(0).atoms().iterator();
    while (atoms.hasNext()) {
      IAtom atomi = atoms.next();
      if (atomi.getFlag(CDKConstants.REACTIVE_CENTER)
          && reactant.getConnectedSingleElectronsCount(atomi) == 1) {

        Iterator<IBond> bondis = reactant.getConnectedBondsList(atomi).iterator();

        while (bondis.hasNext()) {
          IBond bondi = bondis.next();

          if (bondi.getFlag(CDKConstants.REACTIVE_CENTER)
              && bondi.getOrder() == IBond.Order.SINGLE) {

            IAtom atomj = bondi.getConnectedAtom(atomi);
            if (atomi.getFlag(CDKConstants.REACTIVE_CENTER)
                && (atomj.getFormalCharge() == CDKConstants.UNSET ? 0 : atomj.getFormalCharge())
                    == 0
                && reactant.getConnectedSingleElectronsCount(atomj) == 0) {

              Iterator<IBond> bondjs = reactant.getConnectedBondsList(atomj).iterator();
              while (bondjs.hasNext()) {
                IBond bondj = bondjs.next();

                if (bondj.equals(bondi)) continue;

                if (bondj.getFlag(CDKConstants.REACTIVE_CENTER)
                    && bondj.getOrder() == IBond.Order.DOUBLE) {

                  IAtom atomk = bondj.getConnectedAtom(atomj);
                  if (atomk.getFlag(CDKConstants.REACTIVE_CENTER)
                      && (atomk.getFormalCharge() == CDKConstants.UNSET
                              ? 0
                              : atomk.getFormalCharge())
                          == 0
                      && reactant.getConnectedSingleElectronsCount(atomk) == 0) {

                    ArrayList<IAtom> atomList = new ArrayList<IAtom>();
                    atomList.add(atomi);
                    atomList.add(atomj);
                    atomList.add(atomk);
                    ArrayList<IBond> bondList = new ArrayList<IBond>();
                    bondList.add(bondi);
                    bondList.add(bondj);

                    IAtomContainerSet moleculeSet =
                        reactant.getBuilder().newInstance(IAtomContainerSet.class);
                    moleculeSet.addAtomContainer(reactant);
                    IReaction reaction = mechanism.initiate(moleculeSet, atomList, bondList);
                    if (reaction == null) continue;
                    else setOfReactions.addReaction(reaction);
                  }
                }
              }
            }
          }
        }
      }
    }
    return setOfReactions;
  }
  /**
   * Choose any possible quadruple of the set of atoms in ac and establish all of the possible
   * bonding schemes according to Faulon's equations.
   */
  public static List sample(IMolecule ac) {
    logger.debug("RandomGenerator->mutate() Start");
    List structures = new ArrayList();

    int nrOfAtoms = ac.getAtomCount();
    double a11 = 0, a12 = 0, a22 = 0, a21 = 0;
    double b11 = 0, lowerborder = 0, upperborder = 0;
    double b12 = 0;
    double b21 = 0;
    double b22 = 0;
    double[] cmax = new double[4];
    double[] cmin = new double[4];
    IAtomContainer newAc = null;

    IAtom ax1 = null, ax2 = null, ay1 = null, ay2 = null;
    IBond b1 = null, b2 = null, b3 = null, b4 = null;
    // int[] choices = new int[3];
    /* We need at least two non-zero bonds in order to be successful */
    int nonZeroBondsCounter = 0;
    for (int x1 = 0; x1 < nrOfAtoms; x1++) {
      for (int x2 = x1 + 1; x2 < nrOfAtoms; x2++) {
        for (int y1 = x2 + 1; y1 < nrOfAtoms; y1++) {
          for (int y2 = y1 + 1; y2 < nrOfAtoms; y2++) {
            nonZeroBondsCounter = 0;
            ax1 = ac.getAtom(x1);
            ay1 = ac.getAtom(y1);
            ax2 = ac.getAtom(x2);
            ay2 = ac.getAtom(y2);

            /* Get four bonds for these four atoms */

            b1 = ac.getBond(ax1, ay1);
            if (b1 != null) {
              a11 = BondManipulator.destroyBondOrder(b1.getOrder());
              nonZeroBondsCounter++;
            } else {
              a11 = 0;
            }

            b2 = ac.getBond(ax1, ay2);
            if (b2 != null) {
              a12 = BondManipulator.destroyBondOrder(b2.getOrder());
              nonZeroBondsCounter++;
            } else {
              a12 = 0;
            }

            b3 = ac.getBond(ax2, ay1);
            if (b3 != null) {
              a21 = BondManipulator.destroyBondOrder(b3.getOrder());
              nonZeroBondsCounter++;
            } else {
              a21 = 0;
            }

            b4 = ac.getBond(ax2, ay2);
            if (b4 != null) {
              a22 = BondManipulator.destroyBondOrder(b4.getOrder());
              nonZeroBondsCounter++;
            } else {
              a22 = 0;
            }
            if (nonZeroBondsCounter > 1) {
              /* Compute the range for b11 (see Faulons formulae for details) */

              cmax[0] = 0;
              cmax[1] = a11 - a22;
              cmax[2] = a11 + a12 - 3;
              cmax[3] = a11 + a21 - 3;
              cmin[0] = 3;
              cmin[1] = a11 + a12;
              cmin[2] = a11 + a21;
              cmin[3] = a11 - a22 + 3;
              lowerborder = MathTools.max(cmax);
              upperborder = MathTools.min(cmin);
              for (b11 = lowerborder; b11 <= upperborder; b11++) {
                if (b11 != a11) {

                  b12 = a11 + a12 - b11;
                  b21 = a11 + a21 - b11;
                  b22 = a22 - a11 + b11;
                  logger.debug("Trying atom combination : " + x1 + ":" + x2 + ":" + y1 + ":" + y2);
                  try {
                    newAc = (IAtomContainer) ac.clone();
                    change(newAc, x1, y1, x2, y2, b11, b12, b21, b22);
                    if (ConnectivityChecker.isConnected(newAc)) {
                      structures.add(newAc);
                    } else {
                      logger.debug("not connected");
                    }
                  } catch (CloneNotSupportedException e) {
                    logger.error("Cloning exception: " + e.getMessage());
                    logger.debug(e);
                  }
                }
              }
            }
          }
        }
      }
    }
    return structures;
  }
Ejemplo n.º 23
0
  /**
   * Read an IAtomContainer from a file in MDL sd format
   *
   * @return The Molecule that was read from the MDL file.
   */
  private IAtomContainer readAtomContainer(IAtomContainer molecule) throws CDKException {
    logger.debug("Reading new molecule");
    IAtomContainer outputContainer = null;
    int linecount = 0;
    int atoms = 0;
    int bonds = 0;
    int atom1 = 0;
    int atom2 = 0;
    int order = 0;
    IBond.Stereo stereo = (IBond.Stereo) CDKConstants.UNSET;
    int RGroupCounter = 1;
    int Rnumber = 0;
    String[] rGroup = null;
    double x = 0.0;
    double y = 0.0;
    double z = 0.0;
    double totalX = 0.0;
    double totalY = 0.0;
    double totalZ = 0.0;
    String title = null;
    String remark = null;
    // int[][] conMat = new int[0][0];
    // String help;
    IAtom atom;
    String line = "";
    // A map to keep track of R# atoms so that RGP line can be parsed
    Map<Integer, IPseudoAtom> rAtoms = new HashMap<Integer, IPseudoAtom>();

    try {
      IsotopeFactory isotopeFactory = Isotopes.getInstance();

      logger.info("Reading header");
      line = input.readLine();
      linecount++;
      if (line == null) {
        return null;
      }
      logger.debug("Line " + linecount + ": " + line);

      if (line.startsWith("$$$$")) {
        logger.debug("File is empty, returning empty molecule");
        return molecule;
      }
      if (line.length() > 0) {
        title = line;
      }
      line = input.readLine();
      linecount++;
      logger.debug("Line " + linecount + ": " + line);
      line = input.readLine();
      linecount++;
      logger.debug("Line " + linecount + ": " + line);
      if (line.length() > 0) {
        remark = line;
      }

      logger.info("Reading rest of file");
      line = input.readLine();
      linecount++;
      logger.debug("Line " + linecount + ": " + line);

      // if the line is empty we hav a problem - either a malformed
      // molecule entry or just extra new lines at the end of the file
      if (line.length() == 0) {
        // read till the next $$$$ or EOF
        while (true) {
          line = input.readLine();
          linecount++;
          if (line == null) {
            return null;
          }
          if (line.startsWith("$$$$")) {
            return molecule; // an empty molecule
          }
        }
      }

      // check the CT block version
      if (line.contains("V3000") || line.contains("v3000")) {
        handleError("This file must be read with the MDLV3000Reader.");
      } else if (!line.contains("V2000") && !line.contains("v2000")) {
        handleError("This file must be read with the MDLReader.");
      }

      atoms = Integer.parseInt(line.substring(0, 3).trim());
      List<IAtom> atomList = new ArrayList<IAtom>();

      logger.debug("Atomcount: " + atoms);
      bonds = Integer.parseInt(line.substring(3, 6).trim());
      logger.debug("Bondcount: " + bonds);
      List<IBond> bondList = new ArrayList<IBond>();

      // used for applying the MDL valence model
      int[] explicitValence = new int[atoms];

      // read ATOM block
      logger.info("Reading atom block");
      atomsByLinePosition = new ArrayList<IAtom>();
      atomsByLinePosition.add(null); // 0 is not a valid position
      int atomBlockLineNumber = 0;
      for (int f = 0; f < atoms; f++) {
        line = input.readLine();
        linecount++;
        atomBlockLineNumber++;
        Matcher trailingSpaceMatcher = TRAILING_SPACE.matcher(line);
        if (trailingSpaceMatcher.find()) {
          handleError(
              "Trailing space found",
              linecount,
              trailingSpaceMatcher.start(),
              trailingSpaceMatcher.end());
          line = trailingSpaceMatcher.replaceAll("");
        }
        x = Double.parseDouble(line.substring(0, 10).trim());
        y = Double.parseDouble(line.substring(10, 20).trim());
        z = Double.parseDouble(line.substring(20, 30).trim());
        // *all* values should be zero, not just the sum
        totalX += Math.abs(x);
        totalY += Math.abs(y);
        totalZ += Math.abs(z);
        logger.debug("Coordinates: " + x + "; " + y + "; " + z);
        String element = line.substring(31, Math.min(line.length(), 34)).trim();
        if (line.length() < 34) {
          handleError(
              "Element atom type does not follow V2000 format type should of length three"
                  + " and padded with space if required",
              linecount,
              31,
              34);
        }

        logger.debug("Atom type: ", element);
        if (isotopeFactory.isElement(element)) {
          atom = isotopeFactory.configure(molecule.getBuilder().newInstance(IAtom.class, element));
        } else if ("A".equals(element)) {
          atom = molecule.getBuilder().newInstance(IPseudoAtom.class, element);
        } else if ("Q".equals(element)) {
          atom = molecule.getBuilder().newInstance(IPseudoAtom.class, element);
        } else if ("*".equals(element)) {
          atom = molecule.getBuilder().newInstance(IPseudoAtom.class, element);
        } else if ("LP".equals(element)) {
          atom = molecule.getBuilder().newInstance(IPseudoAtom.class, element);
        } else if ("L".equals(element)) {
          atom = molecule.getBuilder().newInstance(IPseudoAtom.class, element);
        } else if (element.equals("R") || (element.length() > 0 && element.charAt(0) == 'R')) {
          logger.debug("Atom ", element, " is not an regular element. Creating a PseudoAtom.");
          // check if the element is R
          rGroup = element.split("^R");
          atom = null;
          if (rGroup.length > 1) {
            try {
              Rnumber = Integer.valueOf(rGroup[(rGroup.length - 1)]);
              RGroupCounter = Rnumber;
              element = "R" + Rnumber;
              atom = molecule.getBuilder().newInstance(IPseudoAtom.class, element);

            } catch (Exception ex) {
              // This happens for atoms labeled "R#".
              // The Rnumber may be set later on, using RGP line
              atom = molecule.getBuilder().newInstance(IPseudoAtom.class, "R");
              rAtoms.put(atomBlockLineNumber, (IPseudoAtom) atom);
            }
          } else {
            atom = molecule.getBuilder().newInstance(IPseudoAtom.class, element);
          }
        } else {
          handleError(
              "Invalid element type. Must be an existing " + "element, or one in: A, Q, L, LP, *.",
              linecount,
              32,
              35);
          atom = molecule.getBuilder().newInstance(IPseudoAtom.class, element);
          atom.setSymbol(element);
        }

        // store as 3D for now, convert to 2D (if totalZ == 0.0) later
        atom.setPoint3d(new Point3d(x, y, z));

        // parse further fields
        if (line.length() >= 36) {
          String massDiffString = line.substring(34, 36).trim();
          logger.debug("Mass difference: ", massDiffString);
          if (!(atom instanceof IPseudoAtom)) {
            try {
              int massDiff = Integer.parseInt(massDiffString);
              if (massDiff != 0) {
                IIsotope major = Isotopes.getInstance().getMajorIsotope(element);
                atom.setMassNumber(major.getMassNumber() + massDiff);
              }
            } catch (Exception exception) {
              handleError("Could not parse mass difference field.", linecount, 35, 37, exception);
            }
          } else {
            logger.error("Cannot set mass difference for a non-element!");
          }
        } else {
          handleError("Mass difference is missing", linecount, 34, 36);
        }

        // set the stereo partiy
        Integer parity = line.length() > 41 ? Character.digit(line.charAt(41), 10) : 0;
        atom.setStereoParity(parity);

        if (line.length() >= 51) {
          String valenceString = removeNonDigits(line.substring(48, 51));
          logger.debug("Valence: ", valenceString);
          if (!(atom instanceof IPseudoAtom)) {
            try {
              int valence = Integer.parseInt(valenceString);
              if (valence != 0) {
                // 15 is defined as 0 in mol files
                if (valence == 15) atom.setValency(0);
                else atom.setValency(valence);
              }
            } catch (Exception exception) {
              handleError(
                  "Could not parse valence information field", linecount, 49, 52, exception);
            }
          } else {
            logger.error("Cannot set valence information for a non-element!");
          }
        }

        if (line.length() >= 39) {
          String chargeCodeString = line.substring(36, 39).trim();
          logger.debug("Atom charge code: ", chargeCodeString);
          int chargeCode = Integer.parseInt(chargeCodeString);
          if (chargeCode == 0) {
            // uncharged species
          } else if (chargeCode == 1) {
            atom.setFormalCharge(+3);
          } else if (chargeCode == 2) {
            atom.setFormalCharge(+2);
          } else if (chargeCode == 3) {
            atom.setFormalCharge(+1);
          } else if (chargeCode == 4) {
          } else if (chargeCode == 5) {
            atom.setFormalCharge(-1);
          } else if (chargeCode == 6) {
            atom.setFormalCharge(-2);
          } else if (chargeCode == 7) {
            atom.setFormalCharge(-3);
          }
        } else {
          handleError("Atom charge is missing", linecount, 36, 39);
        }

        try {
          // read the mmm field as position 61-63
          String reactionAtomIDString = line.substring(60, 63).trim();
          logger.debug("Parsing mapping id: ", reactionAtomIDString);
          try {
            int reactionAtomID = Integer.parseInt(reactionAtomIDString);
            if (reactionAtomID != 0) {
              atom.setProperty(CDKConstants.ATOM_ATOM_MAPPING, reactionAtomID);
            }
          } catch (Exception exception) {
            logger.error("Mapping number ", reactionAtomIDString, " is not an integer.");
            logger.debug(exception);
          }
        } catch (Exception exception) {
          // older mol files don't have all these fields...
          logger.warn("A few fields are missing. Older MDL MOL file?");
        }

        // shk3: This reads shifts from after the molecule. I don't think this is an official
        // format, but I saw it frequently 80=>78 for alk
        if (line.length() >= 78) {
          double shift = Double.parseDouble(line.substring(69, 80).trim());
          atom.setProperty("first shift", shift);
        }
        if (line.length() >= 87) {
          double shift = Double.parseDouble(line.substring(79, 87).trim());
          atom.setProperty("second shift", shift);
        }
        atomList.add(atom);
        atomsByLinePosition.add(atom);
      }

      // convert to 2D, if totalZ == 0
      if (totalX == 0.0 && totalY == 0.0 && totalZ == 0.0) {
        logger.info("All coordinates are 0.0");
        if (atomList.size() == 1) {
          atomList.get(0).setPoint2d(new Point2d(x, y));
        } else {
          for (IAtom atomToUpdate : atomList) {
            atomToUpdate.setPoint3d(null);
          }
        }
      } else if (totalZ == 0.0 && !forceReadAs3DCoords.isSet()) {
        logger.info("Total 3D Z is 0.0, interpreting it as a 2D structure");
        for (IAtom atomToUpdate : atomList) {
          Point3d p3d = atomToUpdate.getPoint3d();
          if (p3d != null) {
            atomToUpdate.setPoint2d(new Point2d(p3d.x, p3d.y));
            atomToUpdate.setPoint3d(null);
          }
        }
      }

      // read BOND block
      logger.info("Reading bond block");
      int queryBondCount = 0;
      for (int f = 0; f < bonds; f++) {
        line = input.readLine();
        linecount++;
        atom1 = Integer.parseInt(line.substring(0, 3).trim());
        atom2 = Integer.parseInt(line.substring(3, 6).trim());
        order = Integer.parseInt(line.substring(6, 9).trim());
        if (line.length() >= 12) {
          int mdlStereo =
              line.length() > 12
                  ? Integer.parseInt(line.substring(9, 12).trim())
                  : Integer.parseInt(line.substring(9).trim());
          if (mdlStereo == 1) {
            // MDL up bond
            stereo = IBond.Stereo.UP;
          } else if (mdlStereo == 6) {
            // MDL down bond
            stereo = IBond.Stereo.DOWN;
          } else if (mdlStereo == 0) {
            if (order == 2) {
              // double bond stereo defined by coordinates
              stereo = IBond.Stereo.E_Z_BY_COORDINATES;
            } else {
              // bond has no stereochemistry
              stereo = IBond.Stereo.NONE;
            }
          } else if (mdlStereo == 3 && order == 2) {
            // unknown E/Z stereochemistry
            stereo = IBond.Stereo.E_OR_Z;
          } else if (mdlStereo == 4) {
            // MDL bond undefined
            stereo = IBond.Stereo.UP_OR_DOWN;
          }
        } else {
          handleError("Missing expected stereo field at line: ", linecount, 10, 12);
        }
        if (logger.isDebugEnabled()) {
          logger.debug("Bond: " + atom1 + " - " + atom2 + "; order " + order);
        }
        // interpret CTfile's special bond orders
        IAtom a1 = atomList.get(atom1 - 1);
        IAtom a2 = atomList.get(atom2 - 1);
        IBond newBond = null;
        if (order >= 1 && order <= 3) {
          IBond.Order cdkOrder = IBond.Order.SINGLE;
          if (order == 2) cdkOrder = IBond.Order.DOUBLE;
          if (order == 3) cdkOrder = IBond.Order.TRIPLE;
          if (stereo != null) {
            newBond = molecule.getBuilder().newInstance(IBond.class, a1, a2, cdkOrder, stereo);
          } else {
            newBond = molecule.getBuilder().newInstance(IBond.class, a1, a2, cdkOrder);
          }
        } else if (order == 4) {
          // aromatic bond
          if (stereo != null) {
            newBond =
                molecule.getBuilder().newInstance(IBond.class, a1, a2, IBond.Order.UNSET, stereo);
          } else {
            newBond = molecule.getBuilder().newInstance(IBond.class, a1, a2, IBond.Order.UNSET);
          }
          // mark both atoms and the bond as aromatic and raise the SINGLE_OR_DOUBLE-flag
          newBond.setFlag(CDKConstants.SINGLE_OR_DOUBLE, true);
          newBond.setFlag(CDKConstants.ISAROMATIC, true);
          a1.setFlag(CDKConstants.ISAROMATIC, true);
          a2.setFlag(CDKConstants.ISAROMATIC, true);
        } else {
          queryBondCount++;
          newBond = new CTFileQueryBond(molecule.getBuilder());
          IAtom[] bondAtoms = {a1, a2};
          newBond.setAtoms(bondAtoms);
          newBond.setOrder(null);
          CTFileQueryBond.Type queryBondType = null;
          switch (order) {
            case 5:
              queryBondType = CTFileQueryBond.Type.SINGLE_OR_DOUBLE;
              break;
            case 6:
              queryBondType = CTFileQueryBond.Type.SINGLE_OR_AROMATIC;
              break;
            case 7:
              queryBondType = CTFileQueryBond.Type.DOUBLE_OR_AROMATIC;
              break;
            case 8:
              queryBondType = CTFileQueryBond.Type.ANY;
              break;
          }
          ((CTFileQueryBond) newBond).setType(queryBondType);
          newBond.setStereo(stereo);
        }
        bondList.add((newBond));

        // add the bond order to the explicit valence for each atom
        if (newBond.getOrder() != null && newBond.getOrder() != IBond.Order.UNSET) {
          explicitValence[atom1 - 1] += newBond.getOrder().numeric();
          explicitValence[atom2 - 1] += newBond.getOrder().numeric();
        } else {
          explicitValence[atom1 - 1] = Integer.MIN_VALUE;
          explicitValence[atom2 - 1] = Integer.MIN_VALUE;
        }
      }

      if (queryBondCount == 0) outputContainer = molecule;
      else {
        outputContainer = new QueryAtomContainer(molecule.getBuilder());
      }

      outputContainer.setProperty(CDKConstants.TITLE, title);
      outputContainer.setProperty(CDKConstants.REMARK, remark);
      for (IAtom at : atomList) {
        outputContainer.addAtom(at);
      }
      for (IBond bnd : bondList) {
        outputContainer.addBond(bnd);
      }

      // read PROPERTY block
      logger.info("Reading property block");
      while (true) {
        line = input.readLine();
        linecount++;
        if (line == null) {
          handleError("The expected property block is missing!", linecount, 0, 0);
        }
        if (line.startsWith("M  END")) break;

        boolean lineRead = false;
        if (line.startsWith("M  CHG")) {
          // FIXME: if this is encountered for the first time, all
          // atom charges should be set to zero first!
          int infoCount = Integer.parseInt(line.substring(6, 9).trim());
          StringTokenizer st = new StringTokenizer(line.substring(9));
          for (int i = 1; i <= infoCount; i++) {
            String token = st.nextToken();
            int atomNumber = Integer.parseInt(token.trim());
            token = st.nextToken();
            int charge = Integer.parseInt(token.trim());
            outputContainer.getAtom(atomNumber - 1).setFormalCharge(charge);
          }
        } else if (line.matches("A\\s{1,4}\\d+")) {
          // Reads the pseudo atom property from the mol file

          // The atom number of the to replaced atom
          int aliasAtomNumber =
              Integer.parseInt(line.replaceFirst("A\\s{1,4}", "")) - RGroupCounter;
          line = input.readLine();
          linecount++;
          String[] aliasArray = line.split("\\\\");
          // name of the alias atom like R1 or R2 etc.
          String alias = "";
          for (int i = 0; i < aliasArray.length; i++) {
            alias += aliasArray[i];
          }
          IAtom aliasAtom = outputContainer.getAtom(aliasAtomNumber);

          // skip if already a pseudoatom
          if (aliasAtom instanceof IPseudoAtom) {
            ((IPseudoAtom) aliasAtom).setLabel(alias);
            continue;
          }

          IAtom newPseudoAtom = molecule.getBuilder().newInstance(IPseudoAtom.class, alias);
          if (aliasAtom.getPoint2d() != null) {
            newPseudoAtom.setPoint2d(aliasAtom.getPoint2d());
          }
          if (aliasAtom.getPoint3d() != null) {
            newPseudoAtom.setPoint3d(aliasAtom.getPoint3d());
          }
          outputContainer.addAtom(newPseudoAtom);
          List<IBond> bondsOfAliasAtom = outputContainer.getConnectedBondsList(aliasAtom);

          for (int i = 0; i < bondsOfAliasAtom.size(); i++) {
            IBond bondOfAliasAtom = bondsOfAliasAtom.get(i);
            IAtom connectedToAliasAtom = bondOfAliasAtom.getConnectedAtom(aliasAtom);
            IBond newBond = bondOfAliasAtom.getBuilder().newInstance(IBond.class);
            newBond.setAtoms(new IAtom[] {connectedToAliasAtom, newPseudoAtom});
            newBond.setOrder(bondOfAliasAtom.getOrder());
            outputContainer.addBond(newBond);
            outputContainer.removeBond(aliasAtom, connectedToAliasAtom);
          }
          outputContainer.removeAtom(aliasAtom);
          RGroupCounter++;

        } else if (line.startsWith("M  ISO")) {
          try {
            String countString = line.substring(6, 10).trim();
            int infoCount = Integer.parseInt(countString);
            StringTokenizer st = new StringTokenizer(line.substring(10));
            for (int i = 1; i <= infoCount; i++) {
              int atomNumber = Integer.parseInt(st.nextToken().trim());
              int absMass = Integer.parseInt(st.nextToken().trim());
              if (absMass != 0) {
                IAtom isotope = outputContainer.getAtom(atomNumber - 1);
                isotope.setMassNumber(absMass);
              }
            }
          } catch (NumberFormatException exception) {
            String error =
                "Error ("
                    + exception.getMessage()
                    + ") while parsing line "
                    + linecount
                    + ": "
                    + line
                    + " in property block.";
            logger.error(error);
            handleError(
                "NumberFormatException in isotope information.", linecount, 7, 11, exception);
          }
        } else if (line.startsWith("M  RAD")) {
          try {
            String countString = line.substring(6, 9).trim();
            int infoCount = Integer.parseInt(countString);
            StringTokenizer st = new StringTokenizer(line.substring(9));
            for (int i = 1; i <= infoCount; i++) {
              int atomNumber = Integer.parseInt(st.nextToken().trim());
              int spinMultiplicity = Integer.parseInt(st.nextToken().trim());
              MDLV2000Writer.SPIN_MULTIPLICITY spin = MDLV2000Writer.SPIN_MULTIPLICITY.NONE;
              if (spinMultiplicity > 0) {
                IAtom radical = outputContainer.getAtom(atomNumber - 1);
                switch (spinMultiplicity) {
                  case 1:
                    spin = MDLV2000Writer.SPIN_MULTIPLICITY.DOUBLET;
                    break;
                  case 2:
                    spin = MDLV2000Writer.SPIN_MULTIPLICITY.SINGLET;
                    break;
                  case 3:
                    spin = MDLV2000Writer.SPIN_MULTIPLICITY.TRIPLET;
                    break;
                  default:
                    logger.debug("Invalid spin multiplicity found: " + spinMultiplicity);
                    break;
                }
                for (int j = 0; j < spin.getSingleElectrons(); j++) {
                  outputContainer.addSingleElectron(
                      molecule.getBuilder().newInstance(ISingleElectron.class, radical));
                }
              }
            }
          } catch (NumberFormatException exception) {
            String error =
                "Error ("
                    + exception.getMessage()
                    + ") while parsing line "
                    + linecount
                    + ": "
                    + line
                    + " in property block.";
            logger.error(error);
            handleError(
                "NumberFormatException in radical information", linecount, 7, 10, exception);
          }
        } else if (line.startsWith("G  ")) {
          try {
            String atomNumberString = line.substring(3, 6).trim();
            int atomNumber = Integer.parseInt(atomNumberString);
            // String whatIsThisString = line.substring(6,9).trim();

            String atomName = input.readLine();

            // convert Atom into a PseudoAtom
            IAtom prevAtom = outputContainer.getAtom(atomNumber - 1);
            IPseudoAtom pseudoAtom = molecule.getBuilder().newInstance(IPseudoAtom.class, atomName);
            if (prevAtom.getPoint2d() != null) {
              pseudoAtom.setPoint2d(prevAtom.getPoint2d());
            }
            if (prevAtom.getPoint3d() != null) {
              pseudoAtom.setPoint3d(prevAtom.getPoint3d());
            }
            AtomContainerManipulator.replaceAtomByAtom(molecule, prevAtom, pseudoAtom);
          } catch (NumberFormatException exception) {
            String error =
                "Error ("
                    + exception.toString()
                    + ") while parsing line "
                    + linecount
                    + ": "
                    + line
                    + " in property block.";
            logger.error(error);
            handleError("NumberFormatException in group information", linecount, 4, 7, exception);
          }
        } else if (line.startsWith("M  RGP")) {
          StringTokenizer st = new StringTokenizer(line);
          // Ignore first 3 tokens (overhead).
          st.nextToken();
          st.nextToken();
          st.nextToken();
          // Process the R group numbers as defined in RGP line.
          while (st.hasMoreTokens()) {
            Integer position = new Integer(st.nextToken());
            Rnumber = new Integer(st.nextToken());
            IPseudoAtom pseudoAtom = rAtoms.get(position);
            if (pseudoAtom != null) {
              pseudoAtom.setLabel("R" + Rnumber);
            }
          }
        }
        if (line.startsWith("V  ")) {
          Integer atomNumber = new Integer(line.substring(3, 6).trim());
          IAtom atomWithComment = outputContainer.getAtom(atomNumber - 1);
          atomWithComment.setProperty(CDKConstants.COMMENT, line.substring(7));
        }

        if (!lineRead) {
          logger.warn("Skipping line in property block: ", line);
        }
      }

      if (interpretHydrogenIsotopes.isSet()) {
        fixHydrogenIsotopes(molecule, isotopeFactory);
      }

      // note: apply the valence model last so that all fixes (i.e. hydrogen
      // isotopes) are in place
      for (int i = 0; i < atoms; i++) {
        applyMDLValenceModel(outputContainer.getAtom(i), explicitValence[i]);
      }

    } catch (CDKException exception) {
      String error =
          "Error while parsing line " + linecount + ": " + line + " -> " + exception.getMessage();
      logger.error(error);
      logger.debug(exception);
      throw exception;
    } catch (Exception exception) {
      exception.printStackTrace();
      String error =
          "Error while parsing line " + linecount + ": " + line + " -> " + exception.getMessage();
      logger.error(error);
      logger.debug(exception);
      handleError("Error while parsing line: " + line, linecount, 0, 0, exception);
    }
    return outputContainer;
  }
  /**
   * Get the container which is found resonance from a IMolecule. It is based on looking if the
   * order of the bond changes.
   *
   * @param molecule The IMolecule to analyze
   * @return The different containers
   */
  @TestMethod("testGetContainers_IMolecule")
  public IAtomContainerSet getContainers(IMolecule molecule) {
    IAtomContainerSet setOfCont = molecule.getBuilder().newAtomContainerSet();
    IMoleculeSet setOfMol = getStructures(molecule);

    if (setOfMol.getMoleculeCount() == 0) return setOfCont;

    /*extraction of all bonds which has been produced a changes of order*/
    List<IBond> bondList = new ArrayList<IBond>();
    for (int i = 1; i < setOfMol.getMoleculeCount(); i++) {
      IMolecule mol = setOfMol.getMolecule(i);
      for (int j = 0; j < mol.getBondCount(); j++) {
        IBond bond = molecule.getBond(j);
        if (!mol.getBond(j).getOrder().equals(bond.getOrder())) {
          if (!bondList.contains(bond)) bondList.add(bond);
        }
      }
    }

    if (bondList.size() == 0) return null;

    int[] flagBelonging = new int[bondList.size()];
    for (int i = 0; i < flagBelonging.length; i++) flagBelonging[i] = 0;
    int[] position = new int[bondList.size()];
    int maxGroup = 1;

    /*Analysis if the bond are linked together*/
    List<IBond> newBondList = new ArrayList<IBond>();
    newBondList.add(bondList.get(0));

    int pos = 0;
    for (int i = 0; i < newBondList.size(); i++) {

      if (i == 0) flagBelonging[i] = maxGroup;
      else {
        if (flagBelonging[position[i]] == 0) {
          maxGroup++;
          flagBelonging[position[i]] = maxGroup;
        }
      }

      IBond bondA = newBondList.get(i);
      for (int ato = 0; ato < 2; ato++) {
        IAtom atomA1 = bondA.getAtom(ato);
        List<IBond> bondA1s = molecule.getConnectedBondsList(atomA1);
        for (int j = 0; j < bondA1s.size(); j++) {
          IBond bondB = bondA1s.get(j);
          if (!newBondList.contains(bondB))
            for (int k = 0; k < bondList.size(); k++)
              if (bondList.get(k).equals(bondB))
                if (flagBelonging[k] == 0) {
                  flagBelonging[k] = maxGroup;
                  pos++;
                  newBondList.add(bondB);
                  position[pos] = k;
                }
        }
      }
      // if it is final size and not all are added
      if (newBondList.size() - 1 == i)
        for (int k = 0; k < bondList.size(); k++)
          if (!newBondList.contains(bondList.get(k))) {
            newBondList.add(bondList.get(k));
            position[i + 1] = k;
            break;
          }
    }
    /*creating containers according groups*/
    for (int i = 0; i < maxGroup; i++) {
      IAtomContainer container = molecule.getBuilder().newAtomContainer();
      for (int j = 0; j < bondList.size(); j++) {
        if (flagBelonging[j] != i + 1) continue;
        IBond bond = bondList.get(j);
        IAtom atomA1 = bond.getAtom(0);
        IAtom atomA2 = bond.getAtom(1);
        if (!container.contains(atomA1)) container.addAtom(atomA1);
        if (!container.contains(atomA2)) container.addAtom(atomA2);
        container.addBond(bond);
      }
      setOfCont.addAtomContainer(container);
    }
    return setOfCont;
  }
Ejemplo n.º 25
0
  @Test
  public void unionMolecules() throws IOException, CDKException {
    SmilesParser sp = new SmilesParser(DefaultChemObjectBuilder.getInstance());
    IAtomContainer mol1 = sp.parseSmiles("OOC1=CC=CC=C1");
    IAtomContainer mol2 = sp.parseSmiles("c1ccc(cc1)c2ccccc2");
    int i = 0;
    for (IAtom atom1 : mol1.atoms()) {
      atom1.setID(String.valueOf((i++)));
    }
    int j = 0;
    for (IAtom atom2 : mol2.atoms()) {
      atom2.setID(String.valueOf((j++)));
    }

    MoleculeSanityCheck.aromatizeMolecule(mol1);
    MoleculeSanityCheck.aromatizeMolecule(mol2);

    Isomorphism isomorphism = new Isomorphism(mol1, mol2, Algorithm.DEFAULT, true, false, false);
    isomorphism.setChemFilters(false, false, false);

    int combinations = 1;

    List<String> acSet = new ArrayList<String>();

    if (isomorphism.getFirstAtomMapping() != null) {

      for (AtomAtomMapping mapping : isomorphism.getAllAtomMapping()) {

        IAtomContainer union = new AtomContainer();

        for (IAtom atom : mol1.atoms()) {
          union.addAtom(atom);
        }

        for (IBond bond : mol1.bonds()) {
          union.addBond(bond);
        }

        for (IBond bond : mol2.bonds()) {
          IAtom a1 = bond.getAtom(0);
          IAtom a2 = bond.getAtom(1);

          if (!mapping.getMappingsByAtoms().containsValue(a1)
              && !mapping.getMappingsByAtoms().containsValue(a2)) {
            if (!union.contains(a1)) {
              union.addAtom(a1);
            }
            if (!union.contains(a2)) {
              union.addAtom(a2);
            }
            union.addBond(bond);
          } else if (mapping.getMappingsByAtoms().containsValue(a1)
              && !mapping.getMappingsByAtoms().containsValue(a2)) {
            if (!union.contains(a2)) {
              union.addAtom(a2);
            }
            union.addBond(
                new Bond(
                    a2,
                    getKey(a1, mapping.getMappingsByAtoms()),
                    bond.getOrder(),
                    bond.getStereo()));
          } else if (!mapping.getMappingsByAtoms().containsValue(a1)
              && mapping.getMappingsByAtoms().containsValue(a2)) {
            if (!union.contains(a1)) {
              union.addAtom(a1);
            }
            union.addBond(
                new Bond(
                    a1,
                    getKey(a2, mapping.getMappingsByAtoms()),
                    bond.getOrder(),
                    bond.getStereo()));
          }
        }
        /*check if this combination is chemically valid*/
        if (isChemicallyValid(union)) {
          String molSMILES = getSMILES(union).toString();
          if (!acSet.contains(molSMILES)) {
            acSet.add(molSMILES);
          }
        }
      }
    }

    //        for (String container : acSet) {
    // System.out.println("\n-------------" + " Combination " + combinations++ +
    // "--------------------");
    // System.out.println("Query SMILES " + getSMILES(mol1).toString() + ", count " +
    // mol1.getAtomCount());
    // System.out.println("Target SMILES " + getSMILES(mol2).toString() + ", count " +
    // mol2.getAtomCount());
    // System.out.println("Union SMILES " + container + ", count " +
    // sp.parseSmiles(container).getAtomCount());
    //        }
  }
Ejemplo n.º 26
0
  @TestMethod(value = "testCalculate_IAtomContainer")
  public DescriptorValue calculate(
      IAtom atom, IAtomContainer atomContainer, IRingSet precalculatedringset) {
    IAtomContainer varAtomContainer;
    try {
      varAtomContainer = (IAtomContainer) atomContainer.clone();
    } catch (CloneNotSupportedException e) {
      return getDummyDescriptorValue(e);
    }

    int atomPosition = atomContainer.getAtomNumber(atom);
    IAtom clonedAtom = varAtomContainer.getAtom(atomPosition);

    DoubleArrayResult rdfProtonCalculatedValues = new DoubleArrayResult(gsr_desc_length);
    if (!atom.getSymbol().equals("H")) {
      return getDummyDescriptorValue(new CDKException("Invalid atom specified"));
    }

    ///////////////////////// FIRST SECTION OF MAIN METHOD: DEFINITION OF MAIN VARIABLES
    ///////////////////////// AND AROMATICITY AND PI-SYSTEM AND RINGS DETECTION

    Molecule mol = new Molecule(varAtomContainer);
    if (varAtomContainer != acold) {
      acold = varAtomContainer;
      // DETECTION OF pi SYSTEMS
      varAtomContainerSet = ConjugatedPiSystemsDetector.detect(mol);
      if (precalculatedringset == null)
        try {
          varRingSet = (new AllRingsFinder()).findAllRings(varAtomContainer);
        } catch (CDKException e) {
          return getDummyDescriptorValue(e);
        }
      else varRingSet = precalculatedringset;
      try {
        GasteigerMarsiliPartialCharges peoe = new GasteigerMarsiliPartialCharges();
        peoe.assignGasteigerMarsiliSigmaPartialCharges(mol, true);
      } catch (Exception ex1) {
        return getDummyDescriptorValue(ex1);
      }
    }
    if (checkAromaticity) {
      try {
        AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(varAtomContainer);
        CDKHueckelAromaticityDetector.detectAromaticity(varAtomContainer);
      } catch (CDKException e) {
        return getDummyDescriptorValue(e);
      }
    }
    IRingSet rsAtom;
    Ring ring;
    IRingSet ringsWithThisBond;
    // SET ISINRING FLAGS FOR BONDS
    Iterator<IBond> bondsInContainer = varAtomContainer.bonds().iterator();
    while (bondsInContainer.hasNext()) {
      IBond bond = bondsInContainer.next();
      ringsWithThisBond = varRingSet.getRings(bond);
      if (ringsWithThisBond.getAtomContainerCount() > 0) {
        bond.setFlag(CDKConstants.ISINRING, true);
      }
    }

    // SET ISINRING FLAGS FOR ATOMS
    IRingSet ringsWithThisAtom;

    for (int w = 0; w < varAtomContainer.getAtomCount(); w++) {
      ringsWithThisAtom = varRingSet.getRings(varAtomContainer.getAtom(w));
      if (ringsWithThisAtom.getAtomContainerCount() > 0) {
        varAtomContainer.getAtom(w).setFlag(CDKConstants.ISINRING, true);
      }
    }

    IAtomContainer detected = varAtomContainerSet.getAtomContainer(0);

    // neighboors[0] is the atom joined to the target proton:
    List<IAtom> neighboors = mol.getConnectedAtomsList(clonedAtom);
    IAtom neighbour0 = neighboors.get(0);

    // 2', 3', 4', 5', 6', and 7' atoms up to the target are detected:
    List<IAtom> atomsInSecondSphere = mol.getConnectedAtomsList(neighbour0);
    List<IAtom> atomsInThirdSphere;
    List<IAtom> atomsInFourthSphere;
    List<IAtom> atomsInFifthSphere;
    List<IAtom> atomsInSixthSphere;
    List<IAtom> atomsInSeventhSphere;

    // SOME LISTS ARE CREATED FOR STORING OF INTERESTING ATOMS AND BONDS DURING DETECTION
    ArrayList<Integer> singles = new ArrayList<Integer>(); // list of any bond not rotatable
    ArrayList<Integer> doubles = new ArrayList<Integer>(); // list with only double bonds
    ArrayList<Integer> atoms = new ArrayList<Integer>(); // list with all the atoms in spheres
    // atoms.add( Integer.valueOf( mol.getAtomNumber(neighboors[0]) ) );
    ArrayList<Integer> bondsInCycloex =
        new ArrayList<Integer>(); // list for bonds in cycloexane-like rings

    // 2', 3', 4', 5', 6', and 7' bonds up to the target are detected:
    IBond secondBond; // (remember that first bond is proton bond)
    IBond thirdBond; //
    IBond fourthBond; //
    IBond fifthBond; //
    IBond sixthBond; //
    IBond seventhBond; //

    // definition of some variables used in the main FOR loop for detection of interesting atoms and
    // bonds:
    boolean theBondIsInA6MemberedRing; // this is like a flag for bonds which are in cycloexane-like
    // rings (rings with more than 4 at.)
    IBond.Order bondOrder;
    int bondNumber;
    int sphere;

    // THIS MAIN FOR LOOP DETECT RIGID BONDS IN 7 SPHERES:
    for (IAtom curAtomSecond : atomsInSecondSphere) {
      secondBond = mol.getBond(neighbour0, curAtomSecond);
      if (mol.getAtomNumber(curAtomSecond) != atomPosition
          && getIfBondIsNotRotatable(mol, secondBond, detected)) {
        sphere = 2;
        bondOrder = secondBond.getOrder();
        bondNumber = mol.getBondNumber(secondBond);
        theBondIsInA6MemberedRing = false;
        checkAndStore(
            bondNumber,
            bondOrder,
            singles,
            doubles,
            bondsInCycloex,
            mol.getAtomNumber(curAtomSecond),
            atoms,
            sphere,
            theBondIsInA6MemberedRing);
        atomsInThirdSphere = mol.getConnectedAtomsList(curAtomSecond);
        if (atomsInThirdSphere.size() > 0) {
          for (IAtom curAtomThird : atomsInThirdSphere) {
            thirdBond = mol.getBond(curAtomThird, curAtomSecond);
            // IF THE ATOMS IS IN THE THIRD SPHERE AND IN A CYCLOEXANE-LIKE RING, IT IS STORED IN
            // THE PROPER LIST:
            if (mol.getAtomNumber(curAtomThird) != atomPosition
                && getIfBondIsNotRotatable(mol, thirdBond, detected)) {
              sphere = 3;
              bondOrder = thirdBond.getOrder();
              bondNumber = mol.getBondNumber(thirdBond);
              theBondIsInA6MemberedRing = false;

              // if the bond is in a cyclohexane-like ring (a ring with 5 or more atoms, not
              // aromatic)
              // the boolean "theBondIsInA6MemberedRing" is set to true
              if (!thirdBond.getFlag(CDKConstants.ISAROMATIC)) {
                if (!curAtomThird.equals(neighbour0)) {
                  rsAtom = varRingSet.getRings(thirdBond);
                  for (int f = 0; f < rsAtom.getAtomContainerCount(); f++) {
                    ring = (Ring) rsAtom.getAtomContainer(f);
                    if (ring.getRingSize() > 4 && ring.contains(thirdBond)) {
                      theBondIsInA6MemberedRing = true;
                    }
                  }
                }
              }
              checkAndStore(
                  bondNumber,
                  bondOrder,
                  singles,
                  doubles,
                  bondsInCycloex,
                  mol.getAtomNumber(curAtomThird),
                  atoms,
                  sphere,
                  theBondIsInA6MemberedRing);
              theBondIsInA6MemberedRing = false;
              atomsInFourthSphere = mol.getConnectedAtomsList(curAtomThird);
              if (atomsInFourthSphere.size() > 0) {
                for (IAtom curAtomFourth : atomsInFourthSphere) {
                  fourthBond = mol.getBond(curAtomThird, curAtomFourth);
                  if (mol.getAtomNumber(curAtomFourth) != atomPosition
                      && getIfBondIsNotRotatable(mol, fourthBond, detected)) {
                    sphere = 4;
                    bondOrder = fourthBond.getOrder();
                    bondNumber = mol.getBondNumber(fourthBond);
                    theBondIsInA6MemberedRing = false;
                    checkAndStore(
                        bondNumber,
                        bondOrder,
                        singles,
                        doubles,
                        bondsInCycloex,
                        mol.getAtomNumber(curAtomFourth),
                        atoms,
                        sphere,
                        theBondIsInA6MemberedRing);
                    atomsInFifthSphere = mol.getConnectedAtomsList(curAtomFourth);
                    if (atomsInFifthSphere.size() > 0) {
                      for (IAtom curAtomFifth : atomsInFifthSphere) {
                        fifthBond = mol.getBond(curAtomFifth, curAtomFourth);
                        if (mol.getAtomNumber(curAtomFifth) != atomPosition
                            && getIfBondIsNotRotatable(mol, fifthBond, detected)) {
                          sphere = 5;
                          bondOrder = fifthBond.getOrder();
                          bondNumber = mol.getBondNumber(fifthBond);
                          theBondIsInA6MemberedRing = false;
                          checkAndStore(
                              bondNumber,
                              bondOrder,
                              singles,
                              doubles,
                              bondsInCycloex,
                              mol.getAtomNumber(curAtomFifth),
                              atoms,
                              sphere,
                              theBondIsInA6MemberedRing);
                          atomsInSixthSphere = mol.getConnectedAtomsList(curAtomFifth);
                          if (atomsInSixthSphere.size() > 0) {
                            for (IAtom curAtomSixth : atomsInSixthSphere) {
                              sixthBond = mol.getBond(curAtomFifth, curAtomSixth);
                              if (mol.getAtomNumber(curAtomSixth) != atomPosition
                                  && getIfBondIsNotRotatable(mol, sixthBond, detected)) {
                                sphere = 6;
                                bondOrder = sixthBond.getOrder();
                                bondNumber = mol.getBondNumber(sixthBond);
                                theBondIsInA6MemberedRing = false;
                                checkAndStore(
                                    bondNumber,
                                    bondOrder,
                                    singles,
                                    doubles,
                                    bondsInCycloex,
                                    mol.getAtomNumber(curAtomSixth),
                                    atoms,
                                    sphere,
                                    theBondIsInA6MemberedRing);
                                atomsInSeventhSphere = mol.getConnectedAtomsList(curAtomSixth);
                                if (atomsInSeventhSphere.size() > 0) {
                                  for (IAtom curAtomSeventh : atomsInSeventhSphere) {
                                    seventhBond = mol.getBond(curAtomSeventh, curAtomSixth);
                                    if (mol.getAtomNumber(curAtomSeventh) != atomPosition
                                        && getIfBondIsNotRotatable(mol, seventhBond, detected)) {
                                      sphere = 7;
                                      bondOrder = seventhBond.getOrder();
                                      bondNumber = mol.getBondNumber(seventhBond);
                                      theBondIsInA6MemberedRing = false;
                                      checkAndStore(
                                          bondNumber,
                                          bondOrder,
                                          singles,
                                          doubles,
                                          bondsInCycloex,
                                          mol.getAtomNumber(curAtomSeventh),
                                          atoms,
                                          sphere,
                                          theBondIsInA6MemberedRing);
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }

    // Variables
    double[] values; // for storage of results of other methods
    double distance;
    double sum;
    double smooth = -20;
    double partial;
    int position;
    double limitInf;
    double limitSup;
    double step;

    //////////////////////// THE FOUTH DESCRIPTOR IS gS(r), WHICH TAKES INTO ACCOUNT SINGLE BONDS IN
    // RIGID SYSTEMS

    Vector3d a_a = new Vector3d();
    Vector3d a_b = new Vector3d();
    Vector3d b_a = new Vector3d();
    Vector3d b_b = new Vector3d();
    Point3d middlePoint = new Point3d();
    double angle = 0;

    if (singles.size() > 0) {
      double dist0;
      double dist1;
      IAtom singleBondAtom0;
      IAtom singleBondAtom1;
      distance = 0;
      position = 0;
      IBond theSingleBond = null;
      limitInf = 0;
      limitSup = Math.PI / 2;
      step = (limitSup - limitInf) / 7;
      smooth = -1.15;
      int counter = 0;
      for (double ghs = 0; ghs < limitSup; ghs = ghs + step) {
        sum = 0;
        for (int sing = 0; sing < singles.size(); sing++) {
          angle = 0;
          partial = 0;
          Integer thisSingleBond = singles.get(sing);
          position = thisSingleBond;
          theSingleBond = mol.getBond(position);
          middlePoint = theSingleBond.get3DCenter();
          singleBondAtom0 = theSingleBond.getAtom(0);
          singleBondAtom1 = theSingleBond.getAtom(1);
          dist0 = calculateDistanceBetweenTwoAtoms(singleBondAtom0, atom);
          dist1 = calculateDistanceBetweenTwoAtoms(singleBondAtom1, atom);

          a_a.set(middlePoint.x, middlePoint.y, middlePoint.z);
          if (dist1 > dist0)
            a_b.set(
                singleBondAtom0.getPoint3d().x,
                singleBondAtom0.getPoint3d().y,
                singleBondAtom0.getPoint3d().z);
          else
            a_b.set(
                singleBondAtom1.getPoint3d().x,
                singleBondAtom1.getPoint3d().y,
                singleBondAtom1.getPoint3d().z);
          b_a.set(middlePoint.x, middlePoint.y, middlePoint.z);
          b_b.set(atom.getPoint3d().x, atom.getPoint3d().y, atom.getPoint3d().z);

          values = calculateDistanceBetweenAtomAndBond(atom, theSingleBond);

          angle = calculateAngleBetweenTwoLines(a_a, a_b, b_a, b_b);
          // System.out.println("ANGLe: "+angle+ " "+ mol.getAtomNumber(atomsInSingleBond[0]) +" "
          // +mol.getAtomNumber(atomsInSingleBond[1]));

          partial =
              (1 / (Math.pow(values[0], 2))) * Math.exp(smooth * (Math.pow((ghs - angle), 2)));
          sum += partial;
        }
        // gSr_function.add(new Double(sum));
        rdfProtonCalculatedValues.add(sum);
        logger.debug("RDF gSr prob.: " + sum + " at distance " + ghs);
        counter++;
      }
    } else {
      return getDummyDescriptorValue(new CDKException("Some error occurred. Please report"));
    }
    return new DescriptorValue(
        getSpecification(),
        getParameterNames(),
        getParameters(),
        rdfProtonCalculatedValues,
        getDescriptorNames());
  }