4
* $Date: 2006-03-29 10:27:08 +0200 (Wed, 29 Mar 2006) $
7
* Copyright (C) 2006-2007 Miguel Rojas <miguel.rojas@uni-koeln.de>
9
* Contact: cdk-devel@lists.sourceforge.net
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.
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.
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.
25
package org.openscience.cdk.reaction.type;
28
import java.util.List;
30
import org.openscience.cdk.CDKConstants;
31
import org.openscience.cdk.DefaultChemObjectBuilder;
32
import org.openscience.cdk.LonePair;
33
import org.openscience.cdk.exception.CDKException;
34
import org.openscience.cdk.interfaces.IAtom;
35
import org.openscience.cdk.interfaces.IAtomContainer;
36
import org.openscience.cdk.interfaces.IBond;
37
import org.openscience.cdk.interfaces.ILonePair;
38
import org.openscience.cdk.interfaces.IMapping;
39
import org.openscience.cdk.interfaces.IMolecule;
40
import org.openscience.cdk.interfaces.IMoleculeSet;
41
import org.openscience.cdk.interfaces.IReaction;
42
import org.openscience.cdk.interfaces.IReactionSet;
43
import org.openscience.cdk.reaction.IReactionProcess;
44
import org.openscience.cdk.reaction.ReactionSpecification;
45
import org.openscience.cdk.tools.LoggingTool;
46
import org.openscience.cdk.tools.manipulator.AtomContainerManipulator;
49
* <p>IReactionProcess which participate in movement resonance.
50
* This reaction could be represented as </p>
51
* <pre>X-A=B => [X+]=A-|[B-]. X represents a donor atomType which contains
52
* lone pair electrons</pre>
55
* IMoleculeSet setOfReactants = DefaultChemObjectBuilder.getInstance().newMoleculeSet();
56
* setOfReactants.addMolecule(new Molecule());
57
* IReactionProcess type = new DisplacementChargeFromDonorReaction();
58
* Object[] params = {Boolean.FALSE};
59
type.setParameters(params);
60
* IReactionSet setOfReactions = type.initiate(setOfReactants, null);
63
* <p>We have the possibility to localize the reactive center. Good method if you
64
* want to localize the reaction in a fixed point</p>
65
* <pre>atoms[0].setFlag(CDKConstants.REACTIVE_CENTER,true);</pre>
66
* <p>Moreover you must put the parameter Boolean.TRUE</p>
67
* <p>If the reactive center is not localized then the reaction process will
68
* try to find automatically the posible reactive center.</p>
71
* @author Miguel Rojas
73
* @cdk.created 2006-05-05
74
* @cdk.module reaction
75
* @cdk.set reaction-types
78
public class DisplacementChargeFromDonorReaction implements IReactionProcess{
79
private LoggingTool logger;
80
private boolean hasActiveCenter;
81
private static final int BONDTOFLAG1 = 8;
82
private static final int BONDTOFLAG2 = 9;
85
* Constructor of the DisplacementChargeFromDonorReaction object
88
public DisplacementChargeFromDonorReaction(){
89
logger = new LoggingTool(this);
92
* Gets the specification attribute of the DisplacementChargeFromDonorReaction object
94
*@return The specification value
96
public ReactionSpecification getSpecification() {
97
return new ReactionSpecification(
98
"http://almost.cubic.uni-koeln.de/jrg/Members/mrc/reactionDict/reactionDict#DisplacementChargeFromDonorReaction",
99
this.getClass().getName(),
100
"$Id: DisplacementChargeFromDonorReaction.java,v 1.6 2006/04/01 08:26:47 mrc Exp $",
101
"The Chemistry Development Kit");
105
* Sets the parameters attribute of the DisplacementChargeFromDonorReaction object
107
*@param params The parameter is if the molecule has already fixed the center active or not. It
108
* should be set before to inize the reaction with a setFlag: CDKConstants.REACTIVE_CENTER
109
*@exception CDKException Description of the Exception
111
public void setParameters(Object[] params) throws CDKException {
112
if (params.length > 1) {
113
throw new CDKException("DisplacementChargeFromDonorReaction only expects one parameter");
115
if (!(params[0] instanceof Boolean)) {
116
throw new CDKException("The parameter 1 must be of type boolean");
118
hasActiveCenter = ((Boolean) params[0]).booleanValue();
123
* Gets the parameters attribute of the DisplacementChargeFromDonorReaction object
125
*@return The parameters value
127
public Object[] getParameters() {
128
Object[] params = new Object[1];
129
params[0] = new Boolean (hasActiveCenter);
135
* It is needed to call the addExplicitHydrogensToSatisfyValency
136
* from the class tools.HydrogenAdder.
138
*@param reactants reactants of the reaction.
139
*@param agents agents of the reaction (Must be in this case null).
141
*@exception CDKException Description of the Exception
143
public IReactionSet initiate(IMoleculeSet reactants, IMoleculeSet agents) throws CDKException{
145
logger.debug("initiate reaction: DisplacementChargeFromDonorReaction");
147
if (reactants.getMoleculeCount() != 1) {
148
throw new CDKException("DisplacementChargeFromDonorReaction only expects one reactant");
150
if (agents != null) {
151
throw new CDKException("DisplacementChargeFromDonorReaction don't expects agents");
154
IReactionSet setOfReactions = DefaultChemObjectBuilder.getInstance().newReactionSet();
155
IMolecule reactant = reactants.getMolecule(0);
157
/* if the parameter hasActiveCenter is not fixed yet, set the active centers*/
158
if(!hasActiveCenter){
159
setActiveCenters(reactant);
165
for (int i = 0 ; i < reactant.getAtomCount() ; i++){
166
atomi = reactant.getAtom(i);
167
if(atomi.getFlag(CDKConstants.REACTIVE_CENTER)&& reactant.getConnectedLonePairsCount(atomi) > 0){
168
IReaction reaction = DefaultChemObjectBuilder.getInstance().newReaction();
169
reaction.addReactant(reactant);
171
java.util.List bonds = reactant.getConnectedBondsList(atomi);
173
for(int j = 0 ; j < bonds.size() ; j++){
174
bondj = (IBond)bonds.get(j);
175
if(bondj.getFlag(CDKConstants.REACTIVE_CENTER)&& bondj.getOrder() == 1.0){
176
IAtom atom = bondj.getConnectedAtom(reactant.getAtom(i));
177
java.util.List bondsI = reactant.getConnectedBondsList(atom);
178
for(int k = 0 ; k < bondsI.size() ; k++){
179
bondk = (IBond)bondsI.get(k);
180
if(bondk.getFlag(CDKConstants.REACTIVE_CENTER) && bondk.getOrder() == 2.0){
182
cleanFlagBOND(reactants.getMolecule(0));
183
/* positions atoms and bonds */
184
int atom0P = reactant.getAtomNumber(atomi);
185
bondj.setFlag(BONDTOFLAG1, true);
186
bondk.setFlag(BONDTOFLAG2, true);
187
int atom1P = reactant.getAtomNumber(atom);
188
int atom2P = reactant.getAtomNumber(bondk.getConnectedAtom(atom));
191
IAtomContainer acCloned;
193
acCloned = (IAtomContainer)reactant.clone();
194
} catch (CloneNotSupportedException e) {
195
throw new CDKException("Could not clone IMolecule!", e);
198
int charge = acCloned.getAtom(atom0P).getFormalCharge();
199
acCloned.getAtom(atom0P).setFormalCharge(charge+1);
200
List selectron = acCloned.getConnectedLonePairsList(acCloned.getAtom(atom0P));
201
acCloned.removeLonePair((ILonePair)selectron.get(selectron.size() -1));
203
IBond bondjClon = null, bondkClon = null;
204
for(int l = 0 ; l<acCloned.getBondCount();l++){
205
if(acCloned.getBond(l).getFlag(BONDTOFLAG1)){
206
double order = acCloned.getBond(l).getOrder();
207
acCloned.getBond(l).setOrder(order + 1);
208
bondjClon = acCloned.getBond(l);
209
} else if(acCloned.getBond(l).getFlag(BONDTOFLAG2)){
210
double order = acCloned.getBond(l).getOrder();
211
acCloned.getBond(l).setOrder(order - 1);
212
bondkClon = acCloned.getBond(l);
216
charge = acCloned.getAtom(atom2P).getFormalCharge();
217
acCloned.getAtom(atom2P).setFormalCharge(charge-1);
218
acCloned.addLonePair(new LonePair(acCloned.getAtom(atom2P)));
221
IMapping mapping = DefaultChemObjectBuilder.getInstance().newMapping(atomi, acCloned.getAtom(atom0P));
222
reaction.addMapping(mapping);
223
mapping = DefaultChemObjectBuilder.getInstance().newMapping(atom, acCloned.getAtom(atom1P));
224
reaction.addMapping(mapping);
225
mapping = DefaultChemObjectBuilder.getInstance().newMapping(bondk.getConnectedAtom(atom), acCloned.getAtom(atom2P));
226
reaction.addMapping(mapping);
227
mapping = DefaultChemObjectBuilder.getInstance().newMapping(bondj, bondjClon);
228
reaction.addMapping(mapping);
229
mapping = DefaultChemObjectBuilder.getInstance().newMapping(bondk, bondkClon);
230
reaction.addMapping(mapping);
232
reaction.addProduct((IMolecule) acCloned);
233
setOfReactions.addReaction(reaction);
236
bondj.setFlag(BONDTOFLAG1, false);
237
bondk.setFlag(BONDTOFLAG2, false);
244
return setOfReactions;
247
* set the active center for this molecule.
248
* The active center will be those which correspond with X-A=B.
250
* A: Atom with lone pair electrons
257
* @param reactant The molecule to set the activity
258
* @throws CDKException
260
private void setActiveCenters(IMolecule reactant) throws CDKException {
261
if(AtomContainerManipulator.getTotalNegativeFormalCharge(reactant) != 0 || AtomContainerManipulator.getTotalPositiveFormalCharge(reactant) != 0)
267
for(int i = 0 ; i < reactant.getAtomCount() ; i++) {
268
atomi = reactant.getAtom(i);
269
if(reactant.getConnectedLonePairsCount(atomi) > 0 ){
270
// not possible is the atom-X has already double bond
271
java.util.List bondsSe = reactant.getConnectedBondsList(atomi);
272
for(int j = 0 ; j < bondsSe.size() ; j++)
273
if(((IBond)bondsSe.get(j)).getOrder() == 2)
275
java.util.List bonds = reactant.getConnectedBondsList(atomi);
276
for(int j = 0 ; j < bonds.size() ; j++){
277
bondj = (IBond)bonds.get(j);
278
if(bondj.getOrder() == 1.0){
279
IAtom atom = bondj.getConnectedAtom(reactant.getAtom(i));
280
java.util.List bondsI = reactant.getConnectedBondsList(atom);
281
for(int k = 0 ; k < bondsI.size() ; k++){
282
bondk = (IBond)bondsI.get(k);
283
if(bondk.getOrder() == 2.0){
284
atomi.setFlag(CDKConstants.REACTIVE_CENTER,true);
285
atom.setFlag(CDKConstants.REACTIVE_CENTER,true);
286
bondk.getConnectedAtom(atom).setFlag(CDKConstants.REACTIVE_CENTER,true);
287
bondj.setFlag(CDKConstants.REACTIVE_CENTER,true);
288
bondk.setFlag(CDKConstants.REACTIVE_CENTER,true);
297
* Gets the parameterNames attribute of the DisplacementChargeFromDonorReaction object
299
*@return The parameterNames value
301
public String[] getParameterNames() {
302
String[] params = new String[1];
303
params[0] = "hasActiveCenter";
309
* Gets the parameterType attribute of the DisplacementChargeFromDonorReaction object
311
*@param name Description of the Parameter
312
*@return The parameterType value
314
public Object getParameterType(String name) {
315
return new Boolean(false);
318
* clean the flags CDKConstants.REACTIVE_CENTER from the molecule
322
public void cleanFlagBOND(IAtomContainer ac){
323
for(int j = 0 ; j < ac.getBondCount(); j++){
324
ac.getBond(j).setFlag(BONDTOFLAG1, false);
325
ac.getBond(j).setFlag(BONDTOFLAG2, false);