~ubuntu-branches/ubuntu/maverick/cdk/maverick

« back to all changes in this revision

Viewing changes to src/org/openscience/cdk/reaction/type/DisplacementChargeFromAcceptorReaction.java

  • Committer: Bazaar Package Importer
  • Author(s): Paul Cager
  • Date: 2008-04-09 21:17:53 UTC
  • Revision ID: james.westby@ubuntu.com-20080409211753-46lmjw5z8mx5pd8d
Tags: upstream-1.0.2
ImportĀ upstreamĀ versionĀ 1.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  $RCSfile$
 
3
 *  $Author: egonw $
 
4
 *  $Date: 2006-03-29 10:27:08 +0200 (Wed, 29 Mar 2006) $
 
5
 *  $Revision: 5855 $
 
6
 *
 
7
 *  Copyright (C) 2006-2007  Miguel Rojas <miguel.rojas@uni-koeln.de>
 
8
 *
 
9
 *  Contact: cdk-devel@lists.sourceforge.net
 
10
 *
 
11
 *  This program is free software; you can redistribute it and/or
 
12
 *  modify it under the terms of the GNU Lesser General Public License
 
13
 *  as published by the Free Software Foundation; either version 2.1
 
14
 *  of the License, or (at your option) any later version.
 
15
 *
 
16
 *  This program is distributed in the hope that it will be useful,
 
17
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
19
 *  GNU Lesser General Public License for more details.
 
20
 *
 
21
 *  You should have received a copy of the GNU Lesser General Public License
 
22
 *  along with this program; if not, write to the Free Software
 
23
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 
24
 */
 
25
package org.openscience.cdk.reaction.type;
 
26
 
 
27
 
 
28
import org.openscience.cdk.CDKConstants;
 
29
import org.openscience.cdk.DefaultChemObjectBuilder;
 
30
import org.openscience.cdk.LonePair;
 
31
import org.openscience.cdk.exception.CDKException;
 
32
import org.openscience.cdk.interfaces.*;
 
33
import org.openscience.cdk.reaction.IReactionProcess;
 
34
import org.openscience.cdk.reaction.ReactionSpecification;
 
35
import org.openscience.cdk.tools.LoggingTool;
 
36
import org.openscience.cdk.tools.manipulator.AtomContainerManipulator;
 
37
 
 
38
import java.util.Iterator;
 
39
 
 
40
/**
 
41
 * <p>IReactionProcess which participate in movement resonance. 
 
42
 * This reaction could be represented as two forms</p>
 
43
 * <pre>X=A => |[X-]-[A+]. X represents an acceptor atomType. 
 
44
 * It is a case specific of the method BreakingBondReaction</pre>
 
45
 * <pre>
 
46
 *  IMoleculeSet setOfReactants = DefaultChemObjectBuilder.getInstance().newMoleculeSet();
 
47
 *  setOfReactants.addMolecule(new Molecule());
 
48
 *  IReactionProcess type = new DisplacementChargeFromAcceptorReaction();
 
49
 *  Object[] params = {Boolean.FALSE};
 
50
    type.setParameters(params);
 
51
 *  IReactionSet setOfReactions = type.initiate(setOfReactants, null);
 
52
 *  </pre>
 
53
 * 
 
54
 * <p>We have the possibility to localize the reactive center. Good method if you
 
55
 * want to localize the reaction in a fixed point</p>
 
56
 * <pre>atoms[0].setFlag(CDKConstants.REACTIVE_CENTER,true);</pre>
 
57
 * <p>Moreover you must put the parameter Boolean.TRUE</p>
 
58
 * <p>If the reactive center is not localized then the reaction process will
 
59
 * try to find automatically the posible reactive center.</p>
 
60
 * 
 
61
 * 
 
62
 * @author         Miguel Rojas
 
63
 * 
 
64
 * @cdk.created    2006-05-05
 
65
 * @cdk.module     reaction
 
66
 * @cdk.set        reaction-types
 
67
 * 
 
68
 **/
 
69
public class DisplacementChargeFromAcceptorReaction implements IReactionProcess{
 
70
    private LoggingTool logger;
 
71
    private boolean hasActiveCenter;
 
72
    private static final int BONDTOFLAG1 = 8;
 
73
 
 
74
    /**
 
75
     * Constructor of the DisplacementChargeFromAcceptorReaction object
 
76
     *
 
77
     */
 
78
    public DisplacementChargeFromAcceptorReaction(){
 
79
        logger = new LoggingTool(this);
 
80
    }
 
81
    /**
 
82
     *  Gets the specification attribute of the DisplacementChargeFromAcceptorReaction object
 
83
     *
 
84
     *@return    The specification value
 
85
     */
 
86
    public ReactionSpecification getSpecification() {
 
87
        return new ReactionSpecification(
 
88
                "http://almost.cubic.uni-koeln.de/jrg/Members/mrc/reactionDict/reactionDict#DisplacementChargeFromAcceptorReaction",
 
89
                this.getClass().getName(),
 
90
                "$Id: DisplacementChargeReaction.java,v 1.6 2006/04/01 08:26:47 mrc Exp $",
 
91
                "The Chemistry Development Kit");
 
92
    }
 
93
 
 
94
    /**
 
95
     *  Sets the parameters attribute of the DisplacementChargeFromAcceptorReaction object
 
96
     *
 
97
     *@param  params            The parameter is if the molecule has already fixed the center active or not. It
 
98
     *                                                  should be set before to inize the reaction with a setFlag:  CDKConstants.REACTIVE_CENTER
 
99
     *@exception  CDKException  Description of the Exception
 
100
     */
 
101
    public void setParameters(Object[] params) throws CDKException {
 
102
        if (params.length > 1) {
 
103
            throw new CDKException("DisplacementChargeFromAcceptorReaction only expects one parameter");
 
104
        }
 
105
        if (!(params[0] instanceof Boolean)) {
 
106
            throw new CDKException("The parameter 1 must be of type boolean");
 
107
        }
 
108
        hasActiveCenter = ((Boolean) params[0]).booleanValue();
 
109
    }
 
110
 
 
111
 
 
112
    /**
 
113
     *  Gets the parameters attribute of the DisplacementChargeFromAcceptorReaction object
 
114
     *
 
115
     *@return    The parameters value
 
116
     */
 
117
    public Object[] getParameters() {
 
118
        Object[] params = new Object[1];
 
119
        params[0] = new Boolean (hasActiveCenter);
 
120
        return params;
 
121
    }
 
122
 
 
123
    /**
 
124
     *  Initiate process.
 
125
     *  It is needed to call the addExplicitHydrogensToSatisfyValency
 
126
     *  from the class tools.HydrogenAdder.
 
127
     *
 
128
     *@param  reactants         reactants of the reaction.
 
129
     *@param  agents            agents of the reaction (Must be in this case null).
 
130
     *
 
131
     *@exception  CDKException  Description of the Exception
 
132
     */
 
133
    public IReactionSet initiate(IMoleculeSet reactants, IMoleculeSet agents) throws CDKException{
 
134
 
 
135
        logger.debug("initiate reaction: DisplacementChargeFromAcceptorReaction");
 
136
 
 
137
        if (reactants.getMoleculeCount() != 1) {
 
138
            throw new CDKException("DisplacementChargeFromAcceptorReaction only expects one reactant");
 
139
        }
 
140
        if (agents != null) {
 
141
            throw new CDKException("DisplacementChargeFromAcceptorReaction don't expects agents");
 
142
        }
 
143
 
 
144
        IReactionSet setOfReactions = DefaultChemObjectBuilder.getInstance().newReactionSet();
 
145
        IMolecule reactant = reactants.getMolecule(0);
 
146
 
 
147
        /* if the parameter hasActiveCenter is not fixed yet, set the active centers*/
 
148
        if(!hasActiveCenter){
 
149
            setActiveCenters(reactant);
 
150
        }
 
151
 
 
152
        Iterator bonds = reactants.getMolecule(0).bonds();
 
153
        while (bonds.hasNext()) {
 
154
            IBond bond = (IBond) bonds.next();
 
155
 
 
156
            if(bond.getFlag(CDKConstants.REACTIVE_CENTER) && bond.getOrder() == 2.0){
 
157
                IAtom atom1 = bond.getAtom(0);
 
158
                IAtom atom2 = bond.getAtom(1);
 
159
                if((((atom1.getFormalCharge() == 0 && reactant.getConnectedSingleElectronsCount(atom1) == 0 && reactant.getConnectedLonePairsCount(atom1) > 0 && !atom1.getSymbol().equals("C")))
 
160
                        &&(atom2.getFormalCharge() == 0 && reactant.getConnectedSingleElectronsCount(atom2) == 0))
 
161
                        || (((atom2.getFormalCharge() == 0 && reactant.getConnectedSingleElectronsCount(atom2) == 0 && reactant.getConnectedLonePairsCount(atom2) > 0 && !atom2.getSymbol().equals("C")))
 
162
                        &&(atom1.getFormalCharge() == 0 && reactant.getConnectedSingleElectronsCount(atom1) == 0))){
 
163
 
 
164
                        cleanFlagBOND(reactants.getMolecule(0));
 
165
                        /* positions atoms and bonds */
 
166
                        int atom0P = reactant.getAtomNumber(bond.getAtom(0));
 
167
                        bond.setFlag(BONDTOFLAG1, true);
 
168
                        int atom1P = reactant.getAtomNumber(bond.getAtom(1));
 
169
 
 
170
                        /* action */
 
171
                        IAtomContainer acCloned;
 
172
                        try {
 
173
                            acCloned = (IAtomContainer)reactant.clone();
 
174
                        } catch (CloneNotSupportedException e) {
 
175
                            throw new CDKException("Could not clone reactant", e);
 
176
                        }
 
177
 
 
178
                        IBond bondClon = null;
 
179
                        for(int l = 0 ; l<acCloned.getBondCount();l++){
 
180
                            if(acCloned.getBond(l).getFlag(BONDTOFLAG1)){
 
181
                                double order = acCloned.getBond(l).getOrder();
 
182
                                acCloned.getBond(l).setOrder(order - 1);
 
183
                                bondClon = acCloned.getBond(l);
 
184
                                break;
 
185
                            }
 
186
                        }
 
187
 
 
188
                        IReaction reaction = DefaultChemObjectBuilder.getInstance().newReaction();
 
189
                        reaction.addReactant(reactant);
 
190
 
 
191
 
 
192
                        if(reactant.getConnectedLonePairsCount(atom1) > 0){
 
193
                            acCloned.getAtom(atom0P).setFormalCharge(-1);
 
194
                            acCloned.addLonePair(new LonePair(acCloned.getAtom(atom0P)));
 
195
 
 
196
                            acCloned.getAtom(atom1P).setFormalCharge(1);
 
197
                        }else{
 
198
                            acCloned.getAtom(atom0P).setFormalCharge(1);
 
199
 
 
200
                            acCloned.getAtom(atom1P).setFormalCharge(-1);
 
201
                            acCloned.addLonePair(new LonePair(acCloned.getAtom(atom1P)));
 
202
 
 
203
                        }
 
204
 
 
205
                            /* mapping */
 
206
                            IMapping mapping = DefaultChemObjectBuilder.getInstance().newMapping(bond, bondClon);
 
207
                            reaction.addMapping(mapping);
 
208
                            mapping = DefaultChemObjectBuilder.getInstance().newMapping(bond.getAtom(0), acCloned.getAtom(atom0P));
 
209
                            reaction.addMapping(mapping);
 
210
                            mapping = DefaultChemObjectBuilder.getInstance().newMapping(bond.getAtom(1), acCloned.getAtom(atom1P));
 
211
                            reaction.addMapping(mapping);
 
212
 
 
213
 
 
214
                            reaction.addProduct((IMolecule) acCloned);
 
215
                            setOfReactions.addReaction(reaction);
 
216
 
 
217
 
 
218
                            bond.setFlag(BONDTOFLAG1, false);
 
219
                        }
 
220
                }
 
221
        }
 
222
 
 
223
        return setOfReactions;
 
224
 
 
225
 
 
226
    }
 
227
    /**
 
228
     * set the active center for this molecule.
 
229
     * The active center will be those which correspond with A=B.
 
230
     * <pre>
 
231
     * A: Atom with lone pair electrons // TODO- not only the atoms with
 
232
     * lone electrons are acceptor atoms.
 
233
     * =: Double bond
 
234
     * B: Atom
 
235
     *  </pre>
 
236
     *
 
237
     * @param reactant The molecule to set the activity
 
238
     * @throws CDKException
 
239
     */
 
240
    private void setActiveCenters(IMolecule reactant) throws CDKException {
 
241
        Iterator bonds = reactant.bonds();
 
242
 
 
243
        if (AtomContainerManipulator.getTotalNegativeFormalCharge(reactant) != 0 || AtomContainerManipulator.getTotalPositiveFormalCharge(reactant) != 0)
 
244
            return;
 
245
 
 
246
        while (bonds.hasNext()) {
 
247
            IBond bond = (IBond) bonds.next();
 
248
            if (bond.getOrder() == 2.0) {
 
249
                IAtom atom1 = bond.getAtom(0);
 
250
                IAtom atom2 = bond.getAtom(1);/* TODO - not controll from lone pair electrons*/
 
251
                if ((((atom1.getFormalCharge() == 0 && reactant.getConnectedSingleElectronsCount(atom1) == 0 && reactant.getConnectedLonePairsCount(atom1) > 0 && !atom1.getSymbol().equals("C")))
 
252
                        && (atom2.getFormalCharge() == 0 && reactant.getConnectedSingleElectronsCount(atom2) == 0))
 
253
                        || (((atom2.getFormalCharge() == 0 && reactant.getConnectedSingleElectronsCount(atom2) == 0 && reactant.getConnectedLonePairsCount(atom2) > 0 && !atom2.getSymbol().equals("C")))
 
254
                        && (atom1.getFormalCharge() == 0 && reactant.getConnectedSingleElectronsCount(atom1) == 0))) {
 
255
                    atom1.setFlag(CDKConstants.REACTIVE_CENTER, true);
 
256
                    atom2.setFlag(CDKConstants.REACTIVE_CENTER, true);
 
257
                    bond.setFlag(CDKConstants.REACTIVE_CENTER, true);
 
258
                }
 
259
            }
 
260
        }
 
261
    }
 
262
    /**
 
263
     *  Gets the parameterNames attribute of the DisplacementChargeFromAcceptorReaction object
 
264
     *
 
265
     *@return    The parameterNames value
 
266
     */
 
267
    public String[] getParameterNames() {
 
268
        String[] params = new String[1];
 
269
        params[0] = "hasActiveCenter";
 
270
        return params;
 
271
    }
 
272
 
 
273
 
 
274
    /**
 
275
     *  Gets the parameterType attribute of the DisplacementChargeFromAcceptorReaction object
 
276
     *
 
277
     *@param  name  Description of the Parameter
 
278
     *@return       The parameterType value
 
279
     */
 
280
    public Object getParameterType(String name) {
 
281
        return Boolean.FALSE;
 
282
    }
 
283
    /**
 
284
     * clean the flags CDKConstants.REACTIVE_CENTER from the molecule
 
285
     * 
 
286
     * @param mol
 
287
     */
 
288
    public void cleanFlagBOND(IAtomContainer ac){
 
289
        for(int j = 0 ; j < ac.getBondCount(); j++){
 
290
            ac.getBond(j).setFlag(BONDTOFLAG1, false);
 
291
        }
 
292
    }
 
293
}