Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: joelib/util/IsomerismDetection.java


1   ///////////////////////////////////////////////////////////////////////////////
2   //  Filename: $RCSfile: IsomerismDetection.java,v $
3   //  Purpose:  Atom representation.
4   //  Language: Java
5   //  Compiler: JDK 1.4
6   //  Authors:  Joerg K. Wegner
7   //  Version:  $Revision: 1.6 $
8   //            $Date: 2003/08/22 15:56:21 $
9   //            $Author: wegner $
10  //
11  //  Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
12  //
13  //  This program is free software; you can redistribute it and/or modify
14  //  it under the terms of the GNU General Public License as published by
15  //  the Free Software Foundation version 2 of the License.
16  //
17  //  This program is distributed in the hope that it will be useful,
18  //  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  //  GNU General Public License for more details.
21  ///////////////////////////////////////////////////////////////////////////////
22  package joelib.util;
23  
24  import joelib.math.XYZVector;
25  
26  import joelib.molecule.JOEAtom;
27  import joelib.molecule.JOEBond;
28  
29  import joelib.util.iterator.NbrAtomIterator;
30  
31  import org.apache.log4j.Category;
32  
33  
34  /*==========================================================================*
35   * IMPORTS
36   *==========================================================================  */
37  /*==========================================================================*
38   * CLASS DECLARATION
39   *==========================================================================  */
40  
41  /**
42   * Helper class to detect E/Z isomerism.
43   *
44   * @author     wegnerj
45   * @license GPL
46   * @cvsversion    $Revision: 1.6 $, $Date: 2003/08/22 15:56:21 $
47   */
48  public class IsomerismDetection
49  {
50      //~ Static fields/initializers /////////////////////////////////////////////
51  
52      /*-------------------------------------------------------------------------*
53       * private static member variables
54       *-------------------------------------------------------------------------  */
55  
56      // Obtain a suitable logger.
57      private static Category logger = Category.getInstance(
58              "joelib.util.IsomerismDetection");
59  
60      /*-------------------------------------------------------------------------*
61       * public static member variables
62       *------------------------------------------------------------------------- */
63      public static final int EZ_ISOMERISM_UNDEFINED = 0;
64      public static final int CISTRANS_ISOMERISM_UNDEFINED = 0;
65      public static final int Z_ISOMERISM = 1;
66      public static final int E_ISOMERISM = 2;
67      public static final int CIS_ISOMERISM = 1;
68      public static final int TRANS_ISOMERISM = 2;
69  
70      //~ Constructors ///////////////////////////////////////////////////////////
71  
72      /*-------------------------------------------------------------------------*
73       * constructor
74       *-------------------------------------------------------------------------  */
75      public IsomerismDetection()
76      {
77          if (logger.isDebugEnabled())
78          {
79              logger.debug("Initialize " + this.getClass().getName());
80          }
81      }
82  
83      //~ Methods ////////////////////////////////////////////////////////////////
84  
85      /**
86       * Sets up/down informations for cis/trans isomerism of a double bond.<br>
87       * Cases:<br>
88       * E/trans -- bondUP/doubleBond/bondUP<br>
89       * Z/cis   -- bondDOWN/doubleBond/bondUP<br>
90       * <br>
91       * The method gets two heavy atoms with the highest atomic number and sets the corresponding
92       * up/down bond flags for cis/trans isomeres.
93       *
94       *
95       * @param bond the double bond
96       * @return ezType new cis/trans type for this double bond
97       * @see #EZ_ISOMERISM_UNDEFINED
98       * @see #Z_ISOMERISM
99       * @see #E_ISOMERISM
100      * @see #isCisTransBond(JOEBond)
101      * @see #getCisTransFrom2D3D(JOEBond)
102      */
103     public static void setCisTransBond(JOEBond bond, int ezType)
104     {
105         if (!bond.isDouble())
106         {
107             return;
108         }
109 
110         JOEAtom begin = bond.getBeginAtom();
111         JOEAtom end = bond.getEndAtom();
112 
113         begin.nbrAtomIterator();
114 
115         NbrAtomIterator nait = begin.nbrAtomIterator();
116         JOEBond tmpBond;
117         JOEBond beginBond = null;
118         JOEAtom nbrAtom;
119 
120         while (nait.hasNext())
121         {
122             nbrAtom = nait.nextNbrAtom();
123             tmpBond = nait.actualBond();
124 
125             if (nbrAtom != end)
126             {
127                 if ((beginBond == null) ||
128                         (nbrAtom.getAtomicNum() > begin.getAtomicNum()))
129                 {
130                     beginBond = tmpBond;
131                 }
132             }
133         }
134 
135         nait = end.nbrAtomIterator();
136 
137         JOEBond endBond = null;
138 
139         while (nait.hasNext())
140         {
141             nbrAtom = nait.nextNbrAtom();
142             tmpBond = nait.actualBond();
143 
144             if (nbrAtom != begin)
145             {
146                 if ((endBond == null) ||
147                         (nbrAtom.getAtomicNum() > end.getAtomicNum()))
148                 {
149                     endBond = tmpBond;
150                 }
151             }
152         }
153 
154         if ((beginBond == null) || (endBond == null))
155         {
156             return;
157         }
158 
159         if (ezType == Z_ISOMERISM)
160         {
161             beginBond.setDown();
162             endBond.setUp();
163         }
164         else if (ezType == E_ISOMERISM)
165         {
166             beginBond.setUp();
167             endBond.setUp();
168         }
169     }
170 
171     /*-------------------------------------------------------------------------*
172      * public static methods
173      *-------------------------------------------------------------------------  */
174 
175     /**
176      * Checks bonds for cis/trans isomerism using the SMILES flags up/down bond connected to a double bond.<br>
177      * Cases:<br>
178      * E/trans -- bondUP/doubleBond/bondUP<br>
179      * E/trans -- bondDOWN/doubleBond/bondDOWN<br>
180      * Z/cis   -- bondUP/doubleBond/bondDOWN<br>
181      * Z/cis   -- bondDOWN/doubleBond/bondUP<br>
182      * <br>
183      * This method does not check multiple definitions.
184      * If no up/down informations are available, the {@link #getCisTransFrom2D3D(JOEBond)} method is used
185      * also to get cis/trans informations.
186      * Single bond flags will be not set if a cis/trans double bond is detected.
187      *
188      * @param bond
189      * @return int Z_ISOMERISM for cis, E_ISOMERISM for trans and EZ_ISOMERISM_UNDEFINED for undefined isomerism
190      * @see #EZ_ISOMERISM_UNDEFINED
191      * @see #Z_ISOMERISM
192      * @see #E_ISOMERISM
193      * @see #getCisTransFrom2D3D(JOEBond)
194      */
195     public static int isCisTransBond(JOEBond bond)
196     {
197         return isCisTransBond(bond, false);
198     }
199 
200     /**
201      * Checks bonds for cis/trans isomerism using the SMILES flags up/down bond connected to a double bond.<br>
202      * Cases:<br>
203      * E/trans -- bondUP/doubleBond/bondUP<br>
204      * E/trans -- bondDOWN/doubleBond/bondDOWN<br>
205      * Z/cis   -- bondUP/doubleBond/bondDOWN<br>
206      * Z/cis   -- bondDOWN/doubleBond/bondUP<br>
207      * <br>
208      * This method does not check multiple definitions.
209      * If no up/down informations are available, the {@link #getCisTransFrom2D3D(JOEBond)} method is used
210      * also to get cis/trans informations.
211      *
212      *
213      * @param bond
214      * @param setSingleBondFlags set the single bond flags {@link JOEBond#JOE_TORUP_BOND}/{@link JOEBond#JOE_TORDOWN_BOND}, if <tt>true</tt> and a cis/trans bond is detected.
215      * @return int Z_ISOMERISM for cis, E_ISOMERISM for trans and EZ_ISOMERISM_UNDEFINED for undefined isomerism
216      * @see #EZ_ISOMERISM_UNDEFINED
217      * @see #Z_ISOMERISM
218      * @see #E_ISOMERISM
219      * @see #getCisTransFrom2D3D(JOEBond)
220      */
221     public static int isCisTransBond(JOEBond bond, boolean setSingleBondFlags)
222     {
223         if (!bond.isDouble())
224         {
225             return EZ_ISOMERISM_UNDEFINED;
226         }
227 
228         JOEAtom begin = bond.getBeginAtom();
229         JOEAtom end = bond.getEndAtom();
230 
231         begin.nbrAtomIterator();
232 
233         NbrAtomIterator nait = begin.nbrAtomIterator();
234         JOEBond tmpBond;
235         JOEBond beginBond = null;
236         JOEAtom nbrAtom;
237 
238         while (nait.hasNext())
239         {
240             nbrAtom = nait.nextNbrAtom();
241             tmpBond = nait.actualBond();
242 
243             if (((tmpBond.getFlags() & JOEBond.JOE_TORUP_BOND) != 0) ||
244                     ((tmpBond.getFlags() & JOEBond.JOE_TORDOWN_BOND) != 0))
245             {
246                 beginBond = tmpBond;
247 
248                 break;
249             }
250         }
251 
252         nait = end.nbrAtomIterator();
253 
254         JOEBond endBond = null;
255 
256         while (nait.hasNext())
257         {
258             nbrAtom = nait.nextNbrAtom();
259             tmpBond = nait.actualBond();
260 
261             if (((tmpBond.getFlags() & JOEBond.JOE_TORUP_BOND) != 0) ||
262                     ((tmpBond.getFlags() & JOEBond.JOE_TORDOWN_BOND) != 0))
263             {
264                 endBond = tmpBond;
265 
266                 break;
267             }
268         }
269 
270         if ((beginBond == null) || (endBond == null))
271         {
272             //try to resolve cis/trans isomerism from 2D/3D structure
273             int ez = getCisTransFrom2D3D(bond, setSingleBondFlags);
274 
275             return ez;
276         }
277 
278         if ((beginBond.isUp() && endBond.isUp()) ||
279                 (beginBond.isDown() && endBond.isDown()))
280         {
281             return E_ISOMERISM;
282         }
283 
284         if ((beginBond.isDown() && endBond.isUp()) ||
285                 (beginBond.isUp() && endBond.isDown()))
286         {
287             return Z_ISOMERISM;
288         }
289 
290         return EZ_ISOMERISM_UNDEFINED;
291     }
292 
293     /**
294      * Checks bonds for cis/trans isomerism using 2D/3D informations.
295      * Single bond flags will be not set if a cis/trans double bond is detected.
296      *
297      * @param bond
298      * @param setSingleBondFlags set the single bond flags {@link JOEBond#JOE_TORUP_BOND}/{@link JOEBond#JOE_TORDOWN_BOND}, if <tt>true</tt> and a cis/trans bond is detected.
299      * @return int Z_ISOMERISM for cis, E_ISOMERISM for trans and EZ_ISOMERISM_UNDEFINED for undefined isomerism
300      * @see #EZ_ISOMERISM_UNDEFINED
301      * @see #Z_ISOMERISM
302      * @see #E_ISOMERISM
303      * @see #isCisTransBond(JOEBond)
304      */
305     public static int getCisTransFrom2D3D(JOEBond bond)
306     {
307         return getCisTransFrom2D3D(bond);
308     }
309 
310     /**
311      * Checks bonds for cis/trans isomerism using 2D/3D informations.
312      *
313      * @param bond
314      * @param setSingleBondFlags set the single bond flags {@link JOEBond#JOE_TORUP_BOND}/{@link JOEBond#JOE_TORDOWN_BOND}, if <tt>true</tt> and a cis/trans bond is detected.
315      * @return int Z_ISOMERISM for cis, E_ISOMERISM for trans and EZ_ISOMERISM_UNDEFINED for undefined isomerism
316      * @see #EZ_ISOMERISM_UNDEFINED
317      * @see #Z_ISOMERISM
318      * @see #E_ISOMERISM
319      * @see #isCisTransBond(JOEBond)
320      */
321     public static int getCisTransFrom2D3D(JOEBond bond,
322         boolean setSingleBondFlags)
323     {
324         if (!bond.isDouble() && bond.isInRing())
325         {
326             return EZ_ISOMERISM_UNDEFINED;
327         }
328 
329         JOEAtom begin = bond.getBeginAtom();
330         JOEAtom end = bond.getEndAtom();
331 
332         //skip allenes
333         if ((begin.getHyb() == 1) || (end.getHyb() == 1))
334         {
335             return EZ_ISOMERISM_UNDEFINED;
336         }
337 
338         begin.nbrAtomIterator();
339 
340         NbrAtomIterator nait = begin.nbrAtomIterator();
341         JOEBond tmpBond;
342         JOEBond beginBond = null;
343         JOEAtom nbrAtom;
344         JOEAtom afterBeginAtom = null;
345         JOEAtom afterEndAtom = null;
346         boolean uniqueHeavyAtom = false;
347 
348         while (nait.hasNext())
349         {
350             nbrAtom = nait.nextNbrAtom();
351             tmpBond = nait.actualBond();
352 
353             if (nbrAtom != end)
354             {
355                 if (beginBond == null)
356                 {
357                     // skip hydrogens
358                     if (!nbrAtom.isHydrogen())
359                     {
360                         beginBond = tmpBond;
361                         afterBeginAtom = nbrAtom;
362                         uniqueHeavyAtom = true;
363                     }
364                 }
365                 else
366                 {
367                     // skip hydrogens
368                     if (!nbrAtom.isHydrogen())
369                     {
370                         if (nbrAtom.getAtomicNum() > begin.getAtomicNum())
371                         {
372                             beginBond = tmpBond;
373                             afterBeginAtom = nbrAtom;
374                             uniqueHeavyAtom = true;
375                         }
376                         else if (nbrAtom.getAtomicNum() == begin.getAtomicNum())
377                         {
378                             uniqueHeavyAtom = false;
379                         }
380                     }
381                 }
382             }
383         }
384 
385         //do not use multiple heavy atoms
386         if (uniqueHeavyAtom == false)
387         {
388             beginBond = null;
389             afterBeginAtom = null;
390         }
391 
392         nait = end.nbrAtomIterator();
393 
394         JOEBond endBond = null;
395 
396         while (nait.hasNext())
397         {
398             nbrAtom = nait.nextNbrAtom();
399             tmpBond = nait.actualBond();
400 
401             if (nbrAtom != begin)
402             {
403                 if (endBond == null)
404                 {
405                     // skip hydrogens
406                     if (!nbrAtom.isHydrogen())
407                     {
408                         endBond = tmpBond;
409                         afterEndAtom = nbrAtom;
410                         uniqueHeavyAtom = true;
411                     }
412                 }
413                 else
414                 {
415                     // skip hydrogens
416                     if (!nbrAtom.isHydrogen())
417                     {
418                         if (nbrAtom.getAtomicNum() > end.getAtomicNum())
419                         {
420                             endBond = tmpBond;
421                             afterEndAtom = nbrAtom;
422                             uniqueHeavyAtom = true;
423                         }
424                         else if (nbrAtom.getAtomicNum() == end.getAtomicNum())
425                         {
426                             uniqueHeavyAtom = false;
427                         }
428                     }
429                 }
430             }
431         }
432 
433         //do not use multiple heavy atoms
434         if (uniqueHeavyAtom == false)
435         {
436             endBond = null;
437             afterEndAtom = null;
438         }
439 
440         // one side of the double bond is not really cis/trans !
441         if ((beginBond == null) || (endBond == null))
442         {
443             return EZ_ISOMERISM_UNDEFINED;
444         }
445 
446         if (Math.abs(XYZVector.calcTorsionAngle(afterBeginAtom.getVector(),
447                         begin.getVector(), end.getVector(),
448                         afterEndAtom.getVector())) > 10.0)
449         {
450             if (setSingleBondFlags)
451             {
452                 beginBond.setUp();
453                 endBond.setUp();
454             }
455 
456             return E_ISOMERISM;
457         }
458         else
459         {
460             if (setSingleBondFlags)
461             {
462                 beginBond.setDown();
463                 endBond.setUp();
464             }
465 
466             return Z_ISOMERISM;
467         }
468     }
469 }
470 ///////////////////////////////////////////////////////////////////////////////
471 //  END OF FILE.
472 ///////////////////////////////////////////////////////////////////////////////