1 /*
2  * Copyright (c) 2013 European Bioinformatics Institute (EMBL-EBI)
3  *                    John May <jwmay@users.sf.net>
4  *
5  * Contact: cdk-devel@lists.sourceforge.net
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation; either version 2.1 of the License, or (at
10  * your option) any later version. All we ask is that proper credit is given
11  * for our work, which includes - but is not limited to - adding the above
12  * copyright notice to the beginning of your source code files, and to any
13  * copyright notice that you may distribute with programs based on this work.
14  *
15  * This program is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
18  * License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 U
23  */
24 
25 package org.openscience.cdk.aromaticity;
26 
27 import org.openscience.cdk.interfaces.IAtomContainer;
28 import org.openscience.cdk.ringsearch.RingSearch;
29 
30 /**
31  * Defines an electron donation model for perceiving aromatic systems. The model
32  * defines which atoms are allowed and how many electron it contributes. There
33  * are currently several models available.
34  *
35  * <ul>
36  *     <li>{@link #cdk()}/{@link #cdkAllowingExocyclic()} - uses the information
37  *     form the preset CDK atom types to determine how many electrons each atom
38  *     should contribute. The model can either allow or exclude contributions
39  *     from exocyclic pi bonds. This model requires that atom types have be
40  *     perceived.
41  * </li>
42  *     <li>
43  *      {@link #piBonds()} - a simple model only allowing cyclic pi bonds to
44  *      contribute. This model only requires that bond orders are set.
45  *     </li>
46  *     <li>
47  *      {@link #daylight()} - a model similar to that used by Daylight for SMILES.
48  *      This model does not require atom types to be defined but every atom should
49  *      have it's hydrogen count set.
50  *     </li>
51  * </ul>
52  *
53  * To obtain an instance of the model simply invoke the named method.
54  * <blockquote><pre>
55  * ElectronDonation model = ElectronDonation.cdk();
56  * </pre></blockquote>
57  *
58  * @author John May
59  * @cdk.module standard
60  * @cdk.githash
61  */
62 public abstract class ElectronDonation {
63 
64     /**
65      * Determine the number 'p' electron contributed by each atom in the
66      * provided {@code container}. A value of '0' indicates the atom can
67      * contribute but that it contributes no electrons. A value of '-1'
68      * indicates the atom should not contribute at all.
69      *
70      * @param container  molecule
71      * @param ringSearch ring information
72      * @return electron contribution of each atom (-1=none)
73      */
contribution(IAtomContainer container, RingSearch ringSearch)74     abstract int[] contribution(IAtomContainer container, RingSearch ringSearch);
75 
76     /**
77      * Use the preset CDK atom types to determine the electron contribution of
78      * atoms. If an atom type has not been perceived or hybridisation is unset a
79      * runtime exception is thrown.  The model accepts cyclic atoms which
80      * are {@link org.openscience.cdk.interfaces.IAtom.Hybridization#SP2} or
81      * {@link org.openscience.cdk.interfaces.IAtom.Hybridization#PLANAR3}
82      * hybridised. The {@link org.openscience.cdk.CDKConstants#PI_BOND_COUNT} and
83      * {@link org.openscience.cdk.CDKConstants#LONE_PAIR_COUNT} to determine how
84      * many electrons an atom type can contribute. Generally these values are
85      * not automatically configured and so several atom types are cached
86      * for lookup: <ul> <li>N.planar3: 2 electrons </li>
87      * <li>N.minus.planar3: 2 electrons </li> <li>N.amide: 2 electrons </li>
88      * <li>S.2: 2 electrons </li> <li>S.planar3: 2 electrons </li>
89      * <li>C.minus.planar: 2 electrons </li> <li>O.planar3: 2 electrons </li>
90      * <li>N.sp2.3: 1 electron </li> <li>C.sp2: 1 electron </li> </ul>
91      *
92      * Exocyclic pi bonds are not allowed to contribute.
93      *
94      * @return electron donation model to use for aromaticity perception
95      * @see org.openscience.cdk.interfaces.IAtom#getAtomTypeName()
96      */
cdk()97     public static ElectronDonation cdk() {
98         return new AtomTypeModel(false);
99     }
100 
101     /**
102      * Use the preset CDK atom types to determine the electron contribution of
103      * atoms. If an atom type has not been perceived or hybridisation is unset a
104      * runtime exception is thrown.  The model accepts cyclic atoms which
105      * are {@link org.openscience.cdk.interfaces.IAtom.Hybridization#SP2} or
106      * {@link org.openscience.cdk.interfaces.IAtom.Hybridization#PLANAR3}
107      * hybridised. The {@link org.openscience.cdk.CDKConstants#PI_BOND_COUNT} and
108      * {@link org.openscience.cdk.CDKConstants#LONE_PAIR_COUNT} to determine how
109      * many electrons an atom type can contribute. Generally these values are
110      * not automatically configured and so several atom types are cached
111      * for lookup: <ul> <li>N.planar3: 2 electrons </li>
112      * <li>N.minus.planar3: 2 electrons </li> <li>N.amide: 2 electrons </li>
113      * <li>S.2: 2 electrons </li> <li>S.planar3: 2 electrons </li>
114      * <li>C.minus.planar: 2 electrons </li> <li>O.planar3: 2 electrons </li>
115      * <li>N.sp2.3: 1 electron </li> <li>C.sp2: 1 electron </li> </ul>
116      *
117      * Exocyclic pi bonds are not allowed to contribute.
118      *
119      * @return electron donation model to use for aromaticity perception
120      * @see org.openscience.cdk.interfaces.IAtom#getAtomTypeName()
121      */
cdkAllowingExocyclic()122     public static ElectronDonation cdkAllowingExocyclic() {
123         return new AtomTypeModel(true);
124     }
125 
126     /**
127      * A very simple aromaticity model which only allows atoms adjacent to
128      * cyclic pi bonds. Lone pairs are not consider and as such molecules like
129      * furan and pyrrole are non-aromatic. The model is useful for storing
130      * aromaticity in MDL and Mol2 file formats where aromatic systems involving
131      * a lone pair can not be properly represented.
132      *
133      * @return electron donation model to use for aromaticity perception
134      */
piBonds()135     public static ElectronDonation piBonds() {
136         return new PiBondModel();
137     }
138 
139     /**
140      * Electron donation model closely mirroring the Daylight model for use in
141      * generating SMILES. The model was interpreted from various resources and
142      * as such may not match exactly. If you find an inconsistency please add a
143      * request for enhancement to the patch tracker. One known limitation is
144      * that this model does not currently consider unknown/pseudo atoms '*'.
145      *
146      *
147      * The model makes a couple of assumptions which it will not correct for.
148      * Checked assumptions cause the model to throw a runtime exception. <ul>
149      * <li>there should be no valence errors (unchecked)</li> <li>every atom has
150      * a set implicit hydrogen count (checked)</li> <li>every bond has defined
151      * order, single, double etc (checked)</li> <li>atomic number of non-pseudo
152      * atoms is set (checked)</li> </ul>
153      *
154      * The aromaticity model in SMILES was designed to simplify canonicalisation
155      * and express symmetry in a molecule. The contributed electrons can be
156      * summarised as follows (refer to code for exact specification): <ul>
157      * <li>carbon, nitrogen, oxygen, phosphorus, sulphur, arsenic and selenium
158      * are allow to be aromatic</li> <li>atoms should be Sp2 hybridised - not
159      * actually computed</li> <li>atoms adjacent to a single cyclic pi bond
160      * contribute 1 electron</li> <li>neutral or negatively charged atoms with a
161      * lone pair contribute 2 electrons</li> <li>exocyclic pi bonds are allowed
162      * but if the exocyclic atom is more electronegative it consumes an
163      * electron. As an example ketone groups contribute '0'
164      * electrons.</li></ul>
165      */
daylight()166     public static ElectronDonation daylight() {
167         return new DaylightModel();
168     }
169 }
170