All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openscience.cdk.io.MDLValence Maven / Gradle / Ivy

There is a newer version: 2.10
Show newest version
/*
 * Copyright (c) 2013 European Bioinformatics Institute (EMBL-EBI)
 *                    John May 
 *
 * Contact: [email protected]
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or (at
 * your option) any later version. All we ask is that proper credit is given
 * for our work, which includes - but is not limited to - adding the above
 * copyright notice to the beginning of your source code files, and to any
 * copyright notice that you may distribute with programs based on this work.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 U
 *
 * Additionally the 'MDLValence' method has the following licence/copyright.
 *
 * Copyright (C) 2012 NextMove Software
 *
 * @@ All Rights Reserved @@ This file is part of the RDKit. The contents
 * are covered by the terms of the BSD license which is included in the file
 * license.txt, found at the root of the RDKit source tree.
 */

package org.openscience.cdk.io;

import com.google.common.collect.Maps;
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.interfaces.IBond;

import java.util.Map;

/**
 * Adds implicit hydrogens and specifies valency using the MDL valence model.
 *
 * @author John May
 * @cdk.module io
 * @see Explicit
 *      and Implicit Hydrogens: taking liberties with valence
 */
final class MDLValence {

    private MDLValence() {}

    /**
     * Apply the MDL valence model to the provided atom container.
     *
     * @param container an atom container loaded from an MDL format
     * @return the container (for convenience)
     */
    static IAtomContainer apply(IAtomContainer container) {

        int n = container.getAtomCount();

        int[] valences = new int[n];

        Map atomToIndex = Maps.newHashMapWithExpectedSize(n);
        for (IAtom atom : container.atoms())
            atomToIndex.put(atom, atomToIndex.size());

        // compute the bond order sums
        for (IBond bond : container.bonds()) {
            int u = atomToIndex.get(bond.getAtom(0));
            int v = atomToIndex.get(bond.getAtom(1));

            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;

            // unset = 0 in this case
            charge = charge == null ? 0 : charge;

            int explicit = valences[i];

            // if there was a valence read from the mol file use that otherwise
            // use the default value from the valence model to set the correct
            // number of implied hydrogens
            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;
    }

    /**
     * Given an element (atomic number) its charge and the explicit valence
     * (bond order sum) return the implicit valence for that atom. This valence
     * is from the MDL valence model which was decoded by NextMove Software and
     * licenced as below.
     *
     * 
$Id: MDLValence.h 2288 2012-11-26 03:39:27Z glandrum $ * * Copyright (C) 2012 NextMove Software * * @@ All Rights Reserved @@ This file is part of the RDKit. The contents * are covered by the terms of the BSD license which is included in the file * license.txt, found at the root of the RDKit source tree.
* @see Explicit * and Implicit Hydrogens taking liberties with valence */ static int implicitValence(int elem, int q, int val) { switch (elem) { case 1: // H case 3: // Li case 11: // Na case 19: // K case 37: // Rb case 55: // Cs case 87: // Fr if (q == 0 && val <= 1) return 1; break; case 4: // Be case 12: // Mg case 20: // Ca case 38: // Sr case 56: // Ba case 88: // Ra switch (q) { case 0: if (val <= 2) return 2; break; case 1: if (val <= 1) return 1; break; } break; case 5: // B switch (q) { case -4: if (val <= 1) return 1; break; case -3: if (val <= 2) return 2; break; case -2: if (val <= 3) return 3; if (val <= 5) return 5; break; case -1: if (val <= 4) return 4; break; case 0: if (val <= 3) return 3; break; case 1: if (val <= 2) return 2; break; case 2: if (val <= 1) return 1; break; } break; case 6: // C switch (q) { case -3: if (val <= 1) return 1; break; case -2: if (val <= 2) return 2; break; case -1: if (val <= 3) return 3; if (val <= 5) return 5; break; case 0: if (val <= 4) return 4; break; case 1: if (val <= 3) return 3; break; case 2: if (val <= 2) return 2; break; case 3: if (val <= 1) return 1; break; } break; case 7: // N switch (q) { case -2: if (val <= 1) return 1; break; case -1: if (val <= 2) return 2; break; case 0: if (val <= 3) return 3; if (val <= 5) return 5; break; case 1: if (val <= 4) return 4; break; case 2: if (val <= 3) return 3; break; case 3: if (val <= 2) return 2; break; case 4: if (val <= 1) return 1; break; } break; case 8: // O switch (q) { case -1: if (val <= 1) return 1; break; case 0: if (val <= 2) return 2; break; case 1: if (val <= 3) return 3; if (val <= 5) return 5; break; case 2: if (val <= 4) return 4; break; case 3: if (val <= 3) return 3; break; case 4: if (val <= 2) return 2; break; case 5: if (val <= 1) return 1; break; } break; case 9: // F switch (q) { case 0: if (val <= 1) return 1; break; case 1: if (val <= 2) return 2; break; case 2: if (val <= 3) return 3; if (val <= 5) return 5; break; case 3: if (val <= 4) return 4; break; case 4: if (val <= 3) return 3; break; case 5: if (val <= 2) return 2; break; case 6: if (val <= 1) return 1; break; } break; case 13: // Al switch (q) { case -4: if (val <= 1) return 1; if (val <= 3) return 3; if (val <= 5) return 5; if (val <= 7) return 7; break; case -3: if (val <= 2) return 2; if (val <= 4) return 4; if (val <= 6) return 6; break; case -2: if (val <= 3) return 3; if (val <= 5) return 5; break; case -1: if (val <= 4) return 4; break; case 0: if (val <= 3) return 3; break; case 1: if (val <= 2) return 2; break; case 2: if (val <= 1) return 1; break; } break; case 14: // Si switch (q) { case -3: if (val <= 1) return 1; if (val <= 3) return 3; if (val <= 5) return 5; if (val <= 7) return 7; break; case -2: if (val <= 2) return 2; if (val <= 4) return 4; if (val <= 6) return 6; break; case -1: if (val <= 3) return 3; if (val <= 5) return 5; break; case 0: if (val <= 4) return 4; break; case 1: if (val <= 3) return 3; break; case 2: if (val <= 2) return 2; break; case 3: if (val <= 1) return 1; break; } break; case 15: // P switch (q) { case -2: if (val <= 1) return 1; if (val <= 3) return 3; if (val <= 5) return 5; if (val <= 7) return 7; break; case -1: if (val <= 2) return 2; if (val <= 4) return 4; if (val <= 6) return 6; break; case 0: if (val <= 3) return 3; if (val <= 5) return 5; break; case 1: if (val <= 4) return 4; break; case 2: if (val <= 3) return 3; break; case 3: if (val <= 2) return 2; break; case 4: if (val <= 1) return 1; break; } break; case 16: // S switch (q) { case -1: if (val <= 1) return 1; if (val <= 3) return 3; if (val <= 5) return 5; if (val <= 7) return 7; break; case 0: if (val <= 2) return 2; if (val <= 4) return 4; if (val <= 6) return 6; break; case 1: if (val <= 3) return 3; if (val <= 5) return 5; break; case 2: if (val <= 4) return 4; break; case 3: if (val <= 3) return 3; break; case 4: if (val <= 2) return 2; break; case 5: if (val <= 1) return 1; break; } break; case 17: // Cl switch (q) { case 0: if (val <= 1) return 1; if (val <= 3) return 3; if (val <= 5) return 5; if (val <= 7) return 7; break; case 1: if (val <= 2) return 2; if (val <= 4) return 4; if (val <= 6) return 6; break; case 2: if (val <= 3) return 3; if (val <= 5) return 5; break; case 3: if (val <= 4) return 4; break; case 4: if (val <= 3) return 3; break; case 5: if (val <= 2) return 2; break; case 6: if (val <= 1) return 1; break; } break; case 31: // Ga switch (q) { case -4: if (val <= 1) return 1; if (val <= 3) return 3; if (val <= 5) return 5; if (val <= 7) return 7; break; case -3: if (val <= 2) return 2; if (val <= 4) return 4; if (val <= 6) return 6; break; case -2: if (val <= 3) return 3; if (val <= 5) return 5; break; case -1: if (val <= 4) return 4; break; case 0: if (val <= 3) return 3; break; case 2: if (val <= 1) return 1; break; } break; case 32: // Ge switch (q) { case -3: if (val <= 1) return 1; if (val <= 3) return 3; if (val <= 5) return 5; if (val <= 7) return 7; break; case -2: if (val <= 2) return 2; if (val <= 4) return 4; if (val <= 6) return 6; break; case -1: if (val <= 3) return 3; if (val <= 5) return 5; break; case 0: if (val <= 4) return 4; break; case 1: if (val <= 3) return 3; break; case 3: if (val <= 1) return 1; break; } break; case 33: // As switch (q) { case -2: if (val <= 1) return 1; if (val <= 3) return 3; if (val <= 5) return 5; if (val <= 7) return 7; break; case -1: if (val <= 2) return 2; if (val <= 4) return 4; if (val <= 6) return 6; break; case 0: if (val <= 3) return 3; if (val <= 5) return 5; break; case 1: if (val <= 4) return 4; break; case 2: if (val <= 3) return 3; break; case 4: if (val <= 1) return 1; break; } break; case 34: // Se switch (q) { case -1: if (val <= 1) return 1; if (val <= 3) return 3; if (val <= 5) return 5; if (val <= 7) return 7; break; case 0: if (val <= 2) return 2; if (val <= 4) return 4; if (val <= 6) return 6; break; case 1: if (val <= 3) return 3; if (val <= 5) return 5; break; case 2: if (val <= 4) return 4; break; case 3: if (val <= 3) return 3; break; case 5: if (val <= 1) return 1; break; } break; case 35: // Br switch (q) { case 0: if (val <= 1) return 1; if (val <= 3) return 3; if (val <= 5) return 5; if (val <= 7) return 7; break; case 1: if (val <= 2) return 2; if (val <= 4) return 4; if (val <= 6) return 6; break; case 2: if (val <= 3) return 3; if (val <= 5) return 5; break; case 3: if (val <= 4) return 4; break; case 4: if (val <= 3) return 3; break; case 6: if (val <= 1) return 1; break; } break; case 49: // In switch (q) { case -4: if (val <= 1) return 1; if (val <= 3) return 3; if (val <= 5) return 5; if (val <= 7) return 7; break; case -3: if (val <= 2) return 2; if (val <= 4) return 4; if (val <= 6) return 6; break; case -2: if (val <= 3) return 3; if (val <= 5) return 5; break; case -1: if (val <= 2) return 2; if (val <= 4) return 4; break; case 0: if (val <= 3) return 3; break; case 2: if (val <= 1) return 1; break; } break; case 50: // Sn case 82: // Pb switch (q) { case -3: if (val <= 1) return 1; if (val <= 3) return 3; if (val <= 5) return 5; if (val <= 7) return 7; break; case -2: if (val <= 2) return 2; if (val <= 4) return 4; if (val <= 6) return 6; break; case -1: if (val <= 3) return 3; if (val <= 5) return 5; break; case 0: if (val <= 2) return 2; if (val <= 4) return 4; break; case 1: if (val <= 3) return 3; break; case 3: if (val <= 1) return 1; break; } break; case 51: // Sb case 83: // Bi switch (q) { case -2: if (val <= 1) return 1; if (val <= 3) return 3; if (val <= 5) return 5; if (val <= 7) return 7; break; case -1: if (val <= 2) return 2; if (val <= 4) return 4; if (val <= 6) return 6; break; case 0: if (val <= 3) return 3; if (val <= 5) return 5; break; case 1: if (val <= 2) return 2; if (val <= 4) return 4; break; case 2: if (val <= 3) return 3; break; case 4: if (val <= 1) return 1; break; } break; case 52: // Te case 84: // Po switch (q) { case -1: if (val <= 1) return 1; if (val <= 3) return 3; if (val <= 5) return 5; if (val <= 7) return 7; break; case 0: if (val <= 2) return 2; if (val <= 4) return 4; if (val <= 6) return 6; break; case 1: if (val <= 3) return 3; if (val <= 5) return 5; break; case 2: if (val <= 2) return 2; if (val <= 4) return 4; break; case 3: if (val <= 3) return 3; break; case 5: if (val <= 1) return 1; break; } break; case 53: // I case 85: // At switch (q) { case 0: if (val <= 1) return 1; if (val <= 3) return 3; if (val <= 5) return 5; if (val <= 7) return 7; break; case 1: if (val <= 2) return 2; if (val <= 4) return 4; if (val <= 6) return 6; break; case 2: if (val <= 3) return 3; if (val <= 5) return 5; break; case 3: if (val <= 2) return 2; if (val <= 4) return 4; break; case 4: if (val <= 3) return 3; break; case 6: if (val <= 1) return 1; break; } break; case 81: // Tl switch (q) { case -4: if (val <= 1) return 1; if (val <= 3) return 3; if (val <= 5) return 5; if (val <= 7) return 7; break; case -3: if (val <= 2) return 2; if (val <= 4) return 4; if (val <= 6) return 6; break; case -2: if (val <= 3) return 3; if (val <= 5) return 5; break; case -1: if (val <= 2) return 2; if (val <= 4) return 4; break; case 0: if (val <= 1) return 1; if (val <= 3) return 3; break; } break; } return val; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy