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.hash;
26 
27 import org.openscience.cdk.interfaces.IAtom;
28 import org.openscience.cdk.interfaces.IAtomContainer;
29 import org.openscience.cdk.interfaces.IPseudoAtom;
30 
31 import java.util.BitSet;
32 
33 /**
34  * Defines a method of suppressing certain atoms from an {@link IAtomContainer}
35  * when computing the hash codes for the molecule or its atoms.
36  *
37  * @author John May
38  * @cdk.module hash
39  */
40 abstract class AtomSuppression {
41 
42     /**
43      * Returns a new instance indicating which atoms are suppressed for this
44      * suppression method.
45      *
46      * @param container molecule with 0 or more atoms
47      * @return the vertices (atom index) which should be suppressed
48      */
suppress(IAtomContainer container)49     abstract Suppressed suppress(IAtomContainer container);
50 
51     /** Default implementation - don't suppress anything. */
52     private static final class Unsuppressed extends AtomSuppression {
53 
54         @Override
suppress(IAtomContainer container)55         Suppressed suppress(IAtomContainer container) {
56             return Suppressed.none();
57         }
58     }
59 
60     /**
61      * Suppresses any explicit hydrogen regardless of whether the atom is a
62      * hydrogen ion or isotope.
63      */
64     private static final class AnyHydrogens extends AtomSuppression {
65 
66         /**{@inheritDoc} */
67         @Override
suppress(IAtomContainer container)68         Suppressed suppress(IAtomContainer container) {
69             BitSet hydrogens = new BitSet();
70             for (int i = 0; i < container.getAtomCount(); i++) {
71                 IAtom atom = container.getAtom(i);
72                 hydrogens.set(i, "H".equals(atom.getSymbol()));
73             }
74             return Suppressed.fromBitSet(hydrogens);
75         }
76     }
77 
78     /** Suppresses any pseudo atom. */
79     private static final class AnyPseudos extends AtomSuppression {
80 
81         /**{@inheritDoc} */
82         @Override
suppress(IAtomContainer container)83         Suppressed suppress(IAtomContainer container) {
84             BitSet hydrogens = new BitSet();
85             for (int i = 0; i < container.getAtomCount(); i++) {
86                 IAtom atom = container.getAtom(i);
87                 hydrogens.set(i, atom instanceof IPseudoAtom);
88             }
89             return Suppressed.fromBitSet(hydrogens);
90         }
91     }
92 
93     /** internal reference for factory. */
94     private static final AtomSuppression unsuppressed = new Unsuppressed();
95     /** internal reference for factory. */
96     private static final AtomSuppression anyHydrogens = new AnyHydrogens();
97     /** internal reference for factory. */
98     private static final AtomSuppression anyPseudos   = new AnyPseudos();
99 
100     /**
101      * Do not suppress any atoms.
102      *
103      * @return a suppression which wont' suppress anything.
104      */
unsuppressed()105     static AtomSuppression unsuppressed() {
106         return unsuppressed;
107     }
108 
109     /**
110      * Suppress all hydrogens even if they are charged or an isotope.
111      *
112      * @return a suppression which will mark 'all' explicit hydrogens
113      */
anyHydrogens()114     static AtomSuppression anyHydrogens() {
115         return anyHydrogens;
116     }
117 
118     /**
119      * Suppress all pseudo atoms regardless of what their label is.
120      *
121      * @return a suppression which will mark 'all' pseudo atoms
122      */
anyPseudos()123     static AtomSuppression anyPseudos() {
124         return anyPseudos;
125     }
126 }
127