BCUTDescriptor extends AbstractMolecularDescriptor implements IMolecularDescriptor { @Override public DescriptorValue calculate(IAtomContainer container) { int counter; IAtomContainer molecule; try { molecule = container.clone(); } catch (CloneNotSupportedException e) { logger.debug("Error during clone"); return getDummyDescriptorValue(new CDKException("Error occurred during clone " + e)); } try { AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(molecule); CDKHydrogenAdder hAdder = CDKHydrogenAdder.getInstance(molecule.getBuilder()); hAdder.addImplicitHydrogens(molecule); AtomContainerManipulator.convertImplicitToExplicitHydrogens(molecule); } catch (Exception e) { return getDummyDescriptorValue(new CDKException("Could not add hydrogens: " + e.getMessage(), e)); } if (this.checkAromaticity) { try { AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(molecule); } catch (CDKException e) { return getDummyDescriptorValue(new CDKException("Error in atom typing: " + e.getMessage(), e)); } try { Aromaticity.cdkLegacy().apply(molecule); } catch (CDKException e) { return getDummyDescriptorValue(new CDKException("Error in aromaticity perception: " + e.getMessage())); } } int nheavy = 0; for (int i = 0; i < molecule.getAtomCount(); i++) { if (molecule.getAtom(i).getAtomicNumber() != IElement.H) nheavy++; } if (nheavy == 0) return getDummyDescriptorValue(new CDKException("No heavy atoms in the molecule")); double[] diagvalue = new double[nheavy]; counter = 0; try { for (int i = 0; i < molecule.getAtomCount(); i++) { if (molecule.getAtom(i).getAtomicNumber() == IElement.H) continue; diagvalue[counter] = Isotopes.getInstance().getMajorIsotope(molecule.getAtom(i).getSymbol()) .getExactMass(); counter++; } } catch (Exception e) { return getDummyDescriptorValue(new CDKException("Could not calculate weight: " + e.getMessage(), e)); } double[][] burdenMatrix = BurdenMatrix.evalMatrix(molecule, diagvalue); if (hasUndefined(burdenMatrix)) return getDummyDescriptorValue(new CDKException("Burden matrix has undefined values")); Matrix matrix = new Matrix(burdenMatrix); EigenvalueDecomposition eigenDecomposition = new EigenvalueDecomposition(matrix); double[] eval1 = eigenDecomposition.getRealEigenvalues(); LonePairElectronChecker lpcheck = new LonePairElectronChecker(); GasteigerMarsiliPartialCharges peoe; try { lpcheck.saturate(molecule); double[] charges = new double[molecule.getAtomCount()]; peoe = new GasteigerMarsiliPartialCharges(); peoe.assignGasteigerMarsiliSigmaPartialCharges(molecule, true); for (int i = 0; i < molecule.getAtomCount(); i++) charges[i] += molecule.getAtom(i).getCharge(); for (int i = 0; i < molecule.getAtomCount(); i++) { molecule.getAtom(i).setCharge(charges[i]); } } catch (Exception e) { return getDummyDescriptorValue(new CDKException("Could not calculate partial charges: " + e.getMessage(), e)); } counter = 0; for (int i = 0; i < molecule.getAtomCount(); i++) { if (molecule.getAtom(i).getAtomicNumber() == IElement.H) continue; diagvalue[counter] = molecule.getAtom(i).getCharge(); counter++; } burdenMatrix = BurdenMatrix.evalMatrix(molecule, diagvalue); if (hasUndefined(burdenMatrix)) return getDummyDescriptorValue(new CDKException("Burden matrix has undefined values")); matrix = new Matrix(burdenMatrix); eigenDecomposition = new EigenvalueDecomposition(matrix); double[] eval2 = eigenDecomposition.getRealEigenvalues(); int[][] topoDistance = PathTools.computeFloydAPSP(AdjacencyMatrix.getMatrix(molecule)); Polarizability pol = new Polarizability(); counter = 0; for (int i = 0; i < molecule.getAtomCount(); i++) { if (molecule.getAtom(i).getAtomicNumber() == IElement.H) continue; diagvalue[counter] = pol.calculateGHEffectiveAtomPolarizability(molecule, molecule.getAtom(i), false, topoDistance); counter++; } burdenMatrix = BurdenMatrix.evalMatrix(molecule, diagvalue); if (hasUndefined(burdenMatrix)) return getDummyDescriptorValue(new CDKException("Burden matrix has undefined values")); matrix = new Matrix(burdenMatrix); eigenDecomposition = new EigenvalueDecomposition(matrix); double[] eval3 = eigenDecomposition.getRealEigenvalues(); int lnlow, lnhigh, enlow, enhigh; if (nlow > nheavy) { lnlow = nheavy; enlow = nlow - nheavy; } else { lnlow = nlow; enlow = 0; } if (nhigh > nheavy) { lnhigh = nheavy; enhigh = nhigh - nheavy; } else { lnhigh = nhigh; enhigh = 0; } DoubleArrayResult retval = new DoubleArrayResult((lnlow + enlow + lnhigh + enhigh) * 3); for (int i = 0; i < lnlow; i++) retval.add(eval1[i]); for (int i = 0; i < enlow; i++) retval.add(Double.NaN); for (int i = 0; i < lnhigh; i++) retval.add(eval1[eval1.length - i - 1]); for (int i = 0; i < enhigh; i++) retval.add(Double.NaN); for (int i = 0; i < lnlow; i++) retval.add(eval2[i]); for (int i = 0; i < enlow; i++) retval.add(Double.NaN); for (int i = 0; i < lnhigh; i++) retval.add(eval2[eval2.length - i - 1]); for (int i = 0; i < enhigh; i++) retval.add(Double.NaN); for (int i = 0; i < lnlow; i++) retval.add(eval3[i]); for (int i = 0; i < enlow; i++) retval.add(Double.NaN); for (int i = 0; i < lnhigh; i++) retval.add(eval3[eval3.length - i - 1]); for (int i = 0; i < enhigh; i++) retval.add(Double.NaN); return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), retval, getDescriptorNames()); } BCUTDescriptor(); @Override DescriptorSpecification getSpecification(); @Override void setParameters(Object[] params); @Override Object[] getParameters(); @Override String[] getDescriptorNames(); @Override String[] getParameterNames(); @Override Object getParameterType(String name); @Override DescriptorValue calculate(IAtomContainer container); @Override IDescriptorResult getDescriptorResultType();  }
@Test public void testAromaticity() throws Exception { setDescriptor(BCUTDescriptor.class); String smiles1 = "c1ccccc1"; String smiles2 = "C1=CC=CC=C1"; SmilesParser sp = new SmilesParser(DefaultChemObjectBuilder.getInstance()); IAtomContainer mol1 = sp.parseSmiles(smiles1); IAtomContainer mol2 = sp.parseSmiles(smiles2); addExplicitHydrogens(mol1); addExplicitHydrogens(mol2); AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(mol1); AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(mol2); Aromaticity.cdkLegacy().apply(mol1); Aromaticity.cdkLegacy().apply(mol2); DoubleArrayResult result1 = (DoubleArrayResult) descriptor.calculate(mol1).getValue(); DoubleArrayResult result2 = (DoubleArrayResult) descriptor.calculate(mol2).getValue(); Assert.assertEquals(result1.length(), result2.length()); for (int i = 0; i < result1.length(); i++) { Assert.assertEquals("element " + i + " does not match", result1.get(i), result2.get(i), 0.01); } }
@Test public void testHAddition() throws Exception { SmilesParser sp = new SmilesParser(DefaultChemObjectBuilder.getInstance()); IAtomContainer mol = sp.parseSmiles("C=1C=CC(=CC1)CNC2=CC=C(C=C2N(=O)=O)S(=O)(=O)C(Cl)(Cl)Br"); DoubleArrayResult result1 = (DoubleArrayResult) descriptor.calculate(mol).getValue(); for (int i = 0; i < result1.length(); i++) Assert.assertTrue(result1.get(i) != Double.NaN); }
@Test public void testUndefinedValues() throws Exception { String filename = "data/mdl/burden_undefined.sdf"; InputStream ins = this.getClass().getClassLoader().getResourceAsStream(filename); ISimpleChemObjectReader reader = new MDLV2000Reader(ins); ChemFile content = reader.read(new ChemFile()); List cList = ChemFileManipulator.getAllAtomContainers(content); IAtomContainer ac = (IAtomContainer) cList.get(0); Assert.assertNotNull(ac); AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(ac); addExplicitHydrogens(ac); Aromaticity.cdkLegacy().apply(ac); Exception e = descriptor.calculate(ac).getException(); Assert.assertNotNull(e); Assert.assertEquals("Could not calculate partial charges: Partial charge not-supported for element: 'As'.", e.getMessage()); }