MomentOfInertiaDescriptor extends AbstractMolecularDescriptor implements IMolecularDescriptor { @Override public DescriptorValue calculate(IAtomContainer container) { if (!GeometryUtil.has3DCoordinates(container)) return getDummyDescriptorValue(new CDKException("Molecule must have 3D coordinates")); IAtomContainer clone; IsotopeFactory factory; try { clone = (IAtomContainer) container.clone(); factory = Isotopes.getInstance(); factory.configureAtoms(clone); } catch (CloneNotSupportedException | IOException e) { logger.debug(e); return getDummyDescriptorValue(e); } DoubleArrayResult retval = new DoubleArrayResult(7); double ccf = 1.000138; double eps = 1e-5; double[][] imat = new double[3][3]; Point3d centerOfMass = GeometryUtil.get3DCentreOfMass(clone); double xdif; double ydif; double zdif; double xsq; double ysq; double zsq; for (int i = 0; i < clone.getAtomCount(); i++) { IAtom currentAtom = clone.getAtom(i); Double mass = factory.getMajorIsotope(currentAtom.getSymbol()).getExactMass(); if (mass == null) mass = factory.getNaturalMass(currentAtom); xdif = currentAtom.getPoint3d().x - centerOfMass.x; ydif = currentAtom.getPoint3d().y - centerOfMass.y; zdif = currentAtom.getPoint3d().z - centerOfMass.z; xsq = xdif * xdif; ysq = ydif * ydif; zsq = zdif * zdif; imat[0][0] += mass * (ysq + zsq); imat[1][1] += mass * (xsq + zsq); imat[2][2] += mass * (xsq + ysq); imat[1][0] += -1 * mass * ydif * xdif; imat[0][1] = imat[1][0]; imat[2][0] += -1 * mass * xdif * zdif; imat[0][2] = imat[2][0]; imat[2][1] += -1 * mass * ydif * zdif; imat[1][2] = imat[2][1]; } Matrix tmp = new Matrix(imat); EigenvalueDecomposition eigenDecomp = tmp.eig(); double[] eval = eigenDecomp.getRealEigenvalues(); retval.add(eval[2]); retval.add(eval[1]); retval.add(eval[0]); double etmp = eval[0]; eval[0] = eval[2]; eval[2] = etmp; if (Math.abs(eval[1]) > 1e-3) retval.add(eval[0] / eval[1]); else retval.add(1000); if (Math.abs(eval[2]) > 1e-3) { retval.add(eval[0] / eval[2]); retval.add(eval[1] / eval[2]); } else { retval.add(1000); retval.add(1000); } double pri; IMolecularFormula formula = MolecularFormulaManipulator.getMolecularFormula(clone); if (Math.abs(eval[2]) > eps) pri = Math.pow(eval[0] * eval[1] * eval[2], 1.0 / 3.0); else pri = Math.sqrt(eval[0] * ccf / MolecularFormulaManipulator.getTotalExactMass(formula)); retval.add(Math.sqrt(Math.PI * 2 * pri * ccf / MolecularFormulaManipulator.getTotalExactMass(formula))); return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), retval, getDescriptorNames()); }  @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 testMOIFromSmiles() throws InvalidSmilesException { SmilesParser sp = new SmilesParser(DefaultChemObjectBuilder.getInstance()); IAtomContainer mol = sp.parseSmiles("CCCC"); DescriptorValue value = descriptor.calculate(mol); Assert.assertNotNull("The Exception should be non-null since we don't have 3D coords", value.getException()); }
@Test public void testMomentOfInertia1() throws ClassNotFoundException, CDKException, java.lang.Exception { String filename = "data/hin/gravindex.hin"; InputStream ins = this.getClass().getClassLoader().getResourceAsStream(filename); ISimpleChemObjectReader reader = new HINReader(ins); ChemFile content = (ChemFile) reader.read((ChemObject) new ChemFile()); List cList = ChemFileManipulator.getAllAtomContainers(content); IAtomContainer ac = (IAtomContainer) cList.get(0); DoubleArrayResult retval = (DoubleArrayResult) descriptor.calculate(ac).getValue(); Assert.assertEquals(1820.692519, retval.get(0), 0.00001); Assert.assertEquals(1274.532522, retval.get(1), 0.00001); Assert.assertEquals(979.210423, retval.get(2), 0.00001); Assert.assertEquals(1.428517, retval.get(3), 0.00001); Assert.assertEquals(1.859347, retval.get(4), 0.00001); Assert.assertEquals(1.301592, retval.get(5), 0.00001); Assert.assertEquals(5.411195, retval.get(6), 0.00001); }
@Test public void testMomentOfInertia2() throws ClassNotFoundException, CDKException, java.lang.Exception { String filename = "data/hin/momi2.hin"; InputStream ins = this.getClass().getClassLoader().getResourceAsStream(filename); ISimpleChemObjectReader reader = new HINReader(ins); ChemFile content = (ChemFile) reader.read((ChemObject) new ChemFile()); List cList = ChemFileManipulator.getAllAtomContainers(content); IAtomContainer ac = (IAtomContainer) cList.get(0); DoubleArrayResult retval = (DoubleArrayResult) descriptor.calculate(ac).getValue(); Assert.assertEquals(10068.419360, retval.get(0), 0.00001); Assert.assertEquals(9731.078356, retval.get(1), 0.00001); Assert.assertEquals(773.612799, retval.get(2), 0.00001); Assert.assertEquals(1.034666, retval.get(3), 0.00001); Assert.assertEquals(13.014804, retval.get(4), 0.00001); Assert.assertEquals(12.578745, retval.get(5), 0.00001); Assert.assertEquals(8.2966226, retval.get(6), 0.00001); }