MDLValence { static IAtomContainer apply(IAtomContainer container) { int n = container.getAtomCount(); int[] valences = new int[n]; Map<IAtom, Integer> atomToIndex = Maps.newHashMapWithExpectedSize(n); for (IAtom atom : container.atoms()) atomToIndex.put(atom, atomToIndex.size()); for (IBond bond : container.bonds()) { int u = atomToIndex.get(bond.getBegin()); int v = atomToIndex.get(bond.getEnd()); int bondOrder = bond.getOrder().numeric(); valences[u] += bondOrder; valences[v] += bondOrder; } for (int i = 0; i < n; i++) { IAtom atom = container.getAtom(i); Integer charge = atom.getFormalCharge(); Integer element = atom.getAtomicNumber(); if (element == null) continue; charge = charge == null ? 0 : charge; int explicit = valences[i]; if (atom.getValency() != null) { atom.setImplicitHydrogenCount(atom.getValency() - explicit); } else { int implicit = implicitValence(element, charge, valences[i]); atom.setImplicitHydrogenCount(implicit - explicit); atom.setValency(implicit); } } return container; } private  MDLValence();   }
@Test public void sodium_metal() { IAtomContainer container = new AtomContainer(); IAtom atom = new Atom("Na"); atom.setValency(0); container.addAtom(atom); MDLValence.apply(container); assertThat(atom.getValency(), is(0)); assertThat(atom.getImplicitHydrogenCount(), is(0)); }
@Test public void sodium_hydride() { IAtomContainer container = new AtomContainer(); IAtom atom = new Atom("Na"); atom.setValency(1); container.addAtom(atom); MDLValence.apply(container); assertThat(atom.getValency(), is(1)); assertThat(atom.getImplicitHydrogenCount(), is(1)); }
@Test public void sodium_implicit() { IAtomContainer container = new AtomContainer(); IAtom atom = new Atom("Na"); container.addAtom(atom); MDLValence.apply(container); assertThat(atom.getValency(), is(1)); assertThat(atom.getImplicitHydrogenCount(), is(1)); }
@Test public void bismuth() { IAtomContainer container = new AtomContainer(); IAtom bi1 = new Atom("Bi"); IAtom h2 = new Atom("H"); bi1.setFormalCharge(+2); container.addAtom(bi1); container.addAtom(h2); container.addBond(0, 1, IBond.Order.SINGLE); MDLValence.apply(container); assertThat(bi1.getValency(), is(3)); assertThat(h2.getValency(), is(1)); assertThat(bi1.getImplicitHydrogenCount(), is(2)); assertThat(h2.getImplicitHydrogenCount(), is(0)); }
@Test public void tin_ii() { IAtomContainer container = new AtomContainer(); IAtom atom = new Atom("Sn"); atom.setValency(2); container.addAtom(atom); MDLValence.apply(container); assertThat(atom.getValency(), is(2)); assertThat(atom.getImplicitHydrogenCount(), is(2)); }
@Test public void tin_iv() { IAtomContainer container = new AtomContainer(); IAtom atom = new Atom("Sn"); atom.setValency(4); IAtom hydrogen = new Atom("H"); container.addAtom(atom); container.addAtom(hydrogen); container.addBond(0, 1, IBond.Order.SINGLE); MDLValence.apply(container); assertThat(atom.getValency(), is(4)); assertThat(atom.getImplicitHydrogenCount(), is(3)); }
@Test public void carbon_neutral() { IAtomContainer container = new AtomContainer(); IAtom atom = new Atom("C"); container.addAtom(atom); MDLValence.apply(container); assertThat(atom.getValency(), is(4)); assertThat(atom.getImplicitHydrogenCount(), is(4)); }
@Test public void carbon_cation() { IAtomContainer container = new AtomContainer(); IAtom atom = new Atom("C"); atom.setFormalCharge(-1); container.addAtom(atom); MDLValence.apply(container); assertThat(atom.getValency(), is(3)); assertThat(atom.getImplicitHydrogenCount(), is(3)); }
@Test public void carbon_cation_doubleBonded() { IAtomContainer container = new AtomContainer(); IAtom c1 = new Atom("C"); IAtom c2 = new Atom("C"); c1.setFormalCharge(-1); container.addAtom(c1); container.addAtom(c2); container.addBond(0, 1, IBond.Order.DOUBLE); MDLValence.apply(container); assertThat(c1.getValency(), is(3)); assertThat(c1.getImplicitHydrogenCount(), is(1)); assertThat(c2.getValency(), is(4)); assertThat(c2.getImplicitHydrogenCount(), is(2)); }
@Test public void carbon_anion() { IAtomContainer container = new AtomContainer(); IAtom atom = new Atom("C"); atom.setFormalCharge(+1); container.addAtom(atom); MDLValence.apply(container); assertThat(atom.getValency(), is(3)); assertThat(atom.getImplicitHydrogenCount(), is(3)); }
@Test public void bismuth_isImplicit() { IAtomContainer container = new AtomContainer(); IAtom bi1 = new Atom("Bi"); IAtom h2 = new Atom("H"); bi1.setFormalCharge(+2); container.addAtom(bi1); container.addAtom(h2); container.addBond(0, 1, IBond.Order.SINGLE); MDLValence.apply(container); assertThat(bi1.getValency(), is(3)); assertThat(h2.getValency(), is(1)); assertThat(bi1.getImplicitHydrogenCount(), is(2)); assertThat(h2.getImplicitHydrogenCount(), is(0)); }