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

Quick Search    Search Deep

Source code: joelib/desc/types/SSKey3DS.java


1   ///////////////////////////////////////////////////////////////////////////////
2   //  Filename: $RCSfile: SSKey3DS.java,v $
3   //  Purpose:  Pharmacophore fingerprint.
4   //  Language: Java
5   //  Compiler: JDK 1.4
6   //  Authors:  Joerg K. Wegner
7   //  Version:  $Revision: 1.9 $
8   //            $Date: 2003/12/03 18:15:32 $
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.desc.types;
23  
24  import joelib.desc.DescDescription;
25  import joelib.desc.DescResult;
26  import joelib.desc.Descriptor;
27  import joelib.desc.DescriptorException;
28  import joelib.desc.DescriptorFactory;
29  import joelib.desc.DescriptorHelper;
30  import joelib.desc.DescriptorInfo;
31  import joelib.desc.ResultFactory;
32  
33  import joelib.desc.result.BitResult;
34  import joelib.desc.result.DoubleResult;
35  import joelib.desc.result.IntResult;
36  
37  import joelib.molecule.JOEAtom;
38  import joelib.molecule.JOEBond;
39  import joelib.molecule.JOEMol;
40  
41  import joelib.ring.JOERing;
42  
43  import joelib.smarts.JOESmartsPattern;
44  
45  import joelib.util.JOEBitVec;
46  import joelib.util.JOEProperty;
47  
48  import joelib.util.iterator.AtomIterator;
49  import joelib.util.iterator.BondIterator;
50  
51  /*==========================================================================*
52   * IMPORTS
53   *==========================================================================*/
54  import java.util.Hashtable;
55  import java.util.Map;
56  import java.util.Vector;
57  
58  import org.apache.log4j.Category;
59  
60  
61  /*==========================================================================*
62   * CLASS DECLARATION
63   *==========================================================================*/
64  
65  /**
66   * Pharmacophore fingerprint.
67   *
68   * @author     wegnerj
69   * @license    GPL
70   * @cvsversion    $Revision: 1.9 $, $Date: 2003/12/03 18:15:32 $
71   * @cite gxsb00
72   */
73  public class SSKey3DS implements Descriptor
74  {
75      //~ Static fields/initializers /////////////////////////////////////////////
76  
77      /*-------------------------------------------------------------------------*
78       * public static member variables
79       *------------------------------------------------------------------------- */
80  
81      /**
82       *  Obtain a suitable logger.
83       */
84      private static Category logger = Category.getInstance(
85              "joelib.desc.types.SSKey3DS");
86      private static Hashtable smartsPatterns = null;
87      public static final String DESC_KEY = "Pharmacophore_fingerprint_1";
88  
89      //~ Instance fields ////////////////////////////////////////////////////////
90  
91      /*-------------------------------------------------------------------------*
92       * private variables
93       *-------------------------------------------------------------------------*/
94      private DescriptorInfo descInfo;
95      private String aromaticBondsName = "Number_of_aromatic_bonds";
96      private String fracRotBondsName = "Fraction_of_rotatable_bonds";
97      private String hbaDescriptorName = "Number_of_HBA_1";
98      private String hbdDescriptorName = "Number_of_HBD_2";
99  
100     //~ Constructors ///////////////////////////////////////////////////////////
101 
102     /*-------------------------------------------------------------------------*
103      * constructor
104      *-------------------------------------------------------------------------  */
105 
106     /**
107      *  Constructor for the KierShape2 object
108      */
109     public SSKey3DS()
110     {
111         if (logger.isDebugEnabled())
112         {
113             logger.debug("Initialize " + this.getClass().getName());
114         }
115 
116         descInfo = DescriptorHelper.generateDescInfo(DESC_KEY, this.getClass(),
117                 DescriptorInfo.TYPE_NO_COORDINATES, null,
118                 "joelib.desc.result.BitResult");
119 
120         if (smartsPatterns == null)
121         {
122             smartsPatterns = getFingerprintPatterns();
123         }
124     }
125 
126     //~ Methods ////////////////////////////////////////////////////////////////
127 
128     /*-------------------------------------------------------------------------*
129      * public methods
130      *-------------------------------------------------------------------------  */
131 
132     /**
133      *  Description of the Method
134      *
135      * @return    Description of the Return Value
136      */
137     public DescriptorInfo getDescInfo()
138     {
139         return descInfo;
140     }
141 
142     /**
143      *  Sets the descriptionFile attribute of the Descriptor object
144      *
145      * @param  _descInfo  The new descInfo value
146      */
147 
148     //  public void setDescInfo(DescriptorInfo _descInfo)
149     //  {
150     //    descInfo = _descInfo;
151     //  }
152 
153     /**
154      *  Gets the description attribute of the Descriptor object
155      *
156      * @return    The description value
157      */
158     public DescDescription getDescription()
159     {
160         return new DescDescription(descInfo.getDescriptionFile());
161     }
162 
163     public JOEProperty[] acceptedProperties()
164     {
165         return null;
166     }
167 
168     /**
169      *  Description of the Method
170      *
171      * @param  mol                      Description of the Parameter
172      * @return                          Description of the Return Value
173      * @exception  DescriptorException  Description of the Exception
174      */
175     public DescResult calculate(JOEMol mol) throws DescriptorException
176     {
177         DescResult result = ResultFactory.instance().getDescResult(descInfo.getName());
178 
179         return calculate(mol, result, null);
180     }
181 
182     /**
183      *  Description of the Method
184      *
185      * @param  mol                      Description of the Parameter
186      * @param  initData                 Description of the Parameter
187      * @return                          Description of the Return Value
188      * @exception  DescriptorException  Description of the Exception
189      */
190     public DescResult calculate(JOEMol mol, Map properties)
191         throws DescriptorException
192     {
193         DescResult result = ResultFactory.instance().getDescResult(descInfo.getName());
194 
195         return calculate(mol, result, properties);
196     }
197 
198     /**
199      *  Description of the Method
200      *
201      * @param  mol                      Description of the Parameter
202      * @param  descResult               Description of the Parameter
203      * @return                          Description of the Return Value
204      * @exception  DescriptorException  Description of the Exception
205      */
206     public DescResult calculate(JOEMol mol, DescResult descResult)
207         throws DescriptorException
208     {
209         return calculate(mol, descResult, null);
210     }
211 
212     /**
213      *  Description of the Method
214      *
215      * @param  mol                      Description of the Parameter
216      * @param  initData                 Description of the Parameter
217      * @param  descResult               Description of the Parameter
218      * @return                          Description of the Return Value
219      * @exception  DescriptorException  Description of the Exception
220      */
221     public DescResult calculate(JOEMol mol, DescResult descResult,
222         Map properties) throws DescriptorException
223     {
224         if (!(descResult instanceof BitResult))
225         {
226             logger.error(descInfo.getName() + " result should be of type " +
227                 BitResult.class.getName() + " but it's of type " +
228                 descResult.getClass().toString());
229         }
230 
231         if (mol.empty())
232         {
233             JOEBitVec fp = new JOEBitVec(54);
234             BitResult result = (BitResult) descResult;
235             result.value = fp;
236             result.maxBitSize = 54;
237             logger.warn("Empty molecule '" + mol.getTitle() +
238                 "'. No bits were set.");
239 
240             return result;
241         }
242 
243         Descriptor hbd = null;
244         Descriptor hba = null;
245         Descriptor fracRotBonds = null;
246         Descriptor aromaticBonds = null;
247 
248         try
249         {
250             hbd = DescriptorFactory.getDescriptor(hbdDescriptorName);
251             hba = DescriptorFactory.getDescriptor(hbaDescriptorName);
252             fracRotBonds = DescriptorFactory.getDescriptor(fracRotBondsName);
253             aromaticBonds = DescriptorFactory.getDescriptor(aromaticBondsName);
254         }
255          catch (DescriptorException ex)
256         {
257             ex.printStackTrace();
258 
259             return null;
260         }
261 
262         IntResult hbdResult = null;
263         IntResult hbaResult = null;
264         IntResult aroResult = null;
265         DoubleResult frbResult = null;
266 
267         try
268         {
269             //calculate hydrogen bond donors
270             hbdResult = (IntResult) hbd.calculate(mol);
271 
272             if (hbdResult == null)
273             {
274                 logger.error("Hydrogen bond donors " + hbdDescriptorName +
275                     " can't be calculated.");
276 
277                 return null;
278             }
279 
280             //calculate hydrogen bond acceptors
281             hbaResult = (IntResult) hba.calculate(mol);
282 
283             if (hbaResult == null)
284             {
285                 logger.error("Hydrogen bond acceptors " + hbaDescriptorName +
286                     " can't be calculated.");
287 
288                 return null;
289             }
290 
291             //calculate fraction of rotatable bonds
292             frbResult = (DoubleResult) fracRotBonds.calculate(mol);
293 
294             if (frbResult == null)
295             {
296                 logger.error("Fraction of rotatable bonds " + fracRotBondsName +
297                     " can't be calculated.");
298 
299                 return null;
300             }
301 
302             //calculate number of aromatic bonds
303             aroResult = (IntResult) aromaticBonds.calculate(mol);
304 
305             if (aroResult == null)
306             {
307                 logger.error("Number of aromatic bonds " + aromaticBondsName +
308                     " can't be calculated.");
309 
310                 return null;
311             }
312         }
313          catch (DescriptorException ex)
314         {
315             ex.printStackTrace();
316         }
317 
318         JOEBitVec fp = new JOEBitVec(54);
319 
320         /////////////////////////////
321         // FRB
322         /////////////////////////////
323         if (frbResult.value > 0.0)
324         {
325             //1:  Fraction of rotatable bonds: 0.0 < x <= 0.1 (0)
326             fp.set(0);
327         }
328 
329         if (frbResult.value > 0.1)
330         {
331             //2:  Fraction of rotatable bonds: 0.1 < x <= 0.2
332             fp.set(1);
333         }
334 
335         if (frbResult.value > 0.2)
336         {
337             //3:  Fraction of rotatable bonds: 0.2 < x <= 0.3
338             fp.set(2);
339         }
340 
341         if (frbResult.value > 0.3)
342         {
343             //4:  Fraction of rotatable bonds: 0.3 < x <= 0.4
344             fp.set(3);
345         }
346 
347         if (frbResult.value > 0.4)
348         {
349             //5:  Fraction of rotatable bonds:       x > 0.4
350             fp.set(4);
351         }
352 
353         ////////////////////////////
354         // ARB
355         ////////////////////////////
356         if (aroResult.getInt()>= 2)
357         {
358             //6:  Aromatic bonds in molecule:  2 - 7  (0-1)
359             fp.set(5);
360         }
361 
362         if (aroResult.getInt() >= 8)
363         {
364             //7:  Aromatic bonds in molecule:  8 -15
365             fp.set(6);
366         }
367 
368         if (aroResult.getInt() >= 16)
369         {
370             //8:  Aromatic bonds in molecule:  16-19
371             fp.set(7);
372         }
373 
374         if (aroResult.getInt() >= 20)
375         {
376             //9:  Aromatic bonds in molecule:  20-25
377             fp.set(8);
378         }
379 
380         if (aroResult.getInt() >= 26)
381         {
382             //10: Aromatic bonds in molecule:  26-31
383             fp.set(9);
384         }
385 
386         if (aroResult.getInt() >= 32)
387         {
388             //11: Aromatic bonds in molecule:  32-37
389             fp.set(10);
390         }
391 
392         if (aroResult.getInt() >= 38)
393         {
394             //12: Aromatic bonds in molecule:  >= 38
395             fp.set(11);
396         }
397 
398         //////////////////////////////
399         // SSKeys
400         //////////////////////////////
401         if (hasHeteroCycle(mol))
402         {
403             //13: heterocycle
404             fp.set(12);
405         }
406 
407         if (hasSMARTSPattern(mol, "13"))
408         {
409             //14: aromatic OH
410             fp.set(13);
411         }
412 
413         if (hasSMARTSPattern(mol, "14"))
414         {
415             //15: aliphatic OH
416             fp.set(14);
417         }
418 
419         if (hasSMARTSPattern(mol, "15"))
420         {
421             //16: aliphatic secondary amine
422             fp.set(15);
423         }
424 
425         if (hasSMARTSPattern(mol, "16"))
426         {
427             //17: aliphatic tertiary amine
428             fp.set(16);
429         }
430 
431         if (hasSMARTSPattern(mol, "17"))
432         {
433             //18: phenyl ring
434             fp.set(17);
435         }
436 
437         if (hasNRing(mol))
438         {
439             //19: Nitrogen-containing ring
440             fp.set(18);
441         }
442 
443         if (hasSMARTSPattern(mol, "19"))
444         {
445             //20: -SO2
446             fp.set(19);
447         }
448 
449         if (hasSMARTSPattern(mol, "20"))
450         {
451             //21: -SO
452             fp.set(20);
453         }
454 
455         if (hasSMARTSPattern(mol, "21"))
456         {
457             //22: ester
458             fp.set(21);
459         }
460 
461         if (hasSMARTSPattern(mol, "22"))
462         {
463             //23: amide
464             fp.set(22);
465         }
466 
467         if (hasNonAromatic5Ring(mol))
468         {
469             //24: 5-membered non-aromatic ring
470             fp.set(23);
471         }
472 
473         if (hasAromatic5Ring(mol))
474         {
475             //25: 5-membered aromatic ring
476             fp.set(24);
477         }
478 
479         if (hasRingGreater9(mol))
480         {
481             //26: 9-membered or larger (fused) ring
482             fp.set(25);
483         }
484 
485         if (hasSMARTSPattern(mol, "26"))
486         {
487             //27: fused ring system
488             fp.set(26);
489         }
490 
491         if (hasSMARTSPattern(mol, "27"))
492         {
493             //28: fused aromatic ring system
494             fp.set(27);
495         }
496 
497         if (hasSMARTSPattern(mol, "28"))
498         {
499             //29: -OSO
500             fp.set(28);
501         }
502 
503         if (hasHalogen(mol))
504         {
505             //30: halogen atom
506             fp.set(29);
507         }
508 
509         if (hasSMARTSPattern(mol, "30"))
510         {
511             //31: Nitrogen attached to alpha-carbon of aromatic system
512             fp.set(30);
513         }
514 
515         if (hasSMARTSPattern(mol, "31"))
516         {
517             //32: -NO2
518             fp.set(31);
519         }
520 
521         if (hasSMARTSPattern(mol, "32"))
522         {
523             //33: rings separated by 2-3 non-ring atoms
524             fp.set(32);
525         }
526 
527         if (hasSMARTSPattern(mol, "33"))
528         {
529             //34: rings separated by 4-5 non-ring atoms
530             fp.set(33);
531         }
532 
533         if (hasSMARTSPattern(mol, "34"))
534         {
535             //35: NN
536             fp.set(34);
537         }
538 
539         if (hasSMARTSPattern(mol, "35"))
540         {
541             //36: C attached to 3 carbons and a hetero atom
542             fp.set(35);
543         }
544 
545         if (hasSMARTSPattern(mol, "36"))
546         {
547             //37: oxygen separated by 2 atoms
548             fp.set(36);
549         }
550 
551         if (hasSMARTSPattern(mol, "37"))
552         {
553             //38: methyl attached to hetero atom
554             fp.set(37);
555         }
556 
557         if (hasDoubleBond(mol))
558         {
559             //39: double bond
560             fp.set(38);
561         }
562 
563         if (hasSMARTSPattern(mol, "39"))
564         {
565             //40: Non-H atom linked to 3 heteroatoms
566             fp.set(39);
567         }
568 
569         if (hasSMARTSPattern(mol, "40"))
570         {
571             //41: Quaternary atom
572             fp.set(40);
573         }
574 
575         if (hasSMARTSPattern(mol, "41"))
576         {
577             //42: 2 methylenes separated by 2 atoms
578             fp.set(41);
579         }
580 
581         if (hasSMARTSPattern(mol, "42"))
582         {
583             //43: non-ring oxygen attached to aromatic system
584             fp.set(42);
585         }
586 
587         if (hasSMARTSPattern(mol, "43"))
588         {
589             //44: 2 non-C,H atoms separated by 2 atoms
590             fp.set(43);
591         }
592 
593         ///////////////////////////////
594         // HBA
595         ///////////////////////////////
596         if (hbaResult.getInt() >= 1)
597         {
598             //45: HBA=1 (0)
599             fp.set(44);
600         }
601 
602         if (hbaResult.getInt() >= 2)
603         {
604             //46: HBA=2
605             fp.set(45);
606         }
607 
608         if (hbaResult.getInt() >= 3)
609         {
610             //47: HBA=3
611             fp.set(46);
612         }
613 
614         if (hbaResult.getInt() >= 4)
615         {
616             //48: HBA=4
617             fp.set(47);
618         }
619 
620         if (hbaResult.getInt() >= 5)
621         {
622             //49: HBA=5
623             fp.set(48);
624         }
625 
626         if (hbaResult.getInt() >= 6)
627         {
628             //50: HBA=6
629             fp.set(49);
630         }
631 
632         if (hbaResult.getInt() >= 7)
633         {
634             //51: HBA=7
635             fp.set(50);
636         }
637 
638         if (hbaResult.getInt() >= 8)
639         {
640             //52: HBA=8
641             fp.set(51);
642         }
643 
644         if (hbaResult.getInt() >= 9)
645         {
646             //53: HBA=9
647             fp.set(52);
648         }
649 
650         if (hbaResult.getInt() >= 10)
651         {
652             //54: HBA>=10
653             fp.set(53);
654         }
655 
656         BitResult result = (BitResult) descResult;
657         result.value = fp;
658         result.maxBitSize = 54;
659 
660         return result;
661     }
662 
663     /**
664      *  Description of the Method
665      */
666     public void clear()
667     {
668     }
669 
670     /**
671      *  Description of the Method
672      *
673      * @param  initData  Description of the Parameter
674      * @return           Description of the Return Value
675      */
676     public boolean initialize(Map properties)
677     {
678         return true;
679     }
680 
681     /**
682     * Test the implementation of this descriptor.
683     *
684     * @return <tt>true</tt> if the implementation is correct
685     */
686     public boolean testDescriptor()
687     {
688         return true;
689     }
690 
691     private static Hashtable getFingerprintPatterns()
692     {
693         Hashtable smarts = new Hashtable();
694 
695         initSingleSMARTS(smarts, "13", "[OX2;H1;$(O-a)]");
696         initSingleSMARTS(smarts, "14", "[OX2;H1;$(O-C)]");
697         initSingleSMARTS(smarts, "15", "[NX3;H1;$(N(~C)~C)]");
698         initSingleSMARTS(smarts, "16", "[NQ3;H0;$(N(~C)(~C)~C)]");
699         initSingleSMARTS(smarts, "17", "[Cc1ccccc1]");
700         initSingleSMARTS(smarts, "19", "[#16Q4;$(S(=O)(=O))]-*");
701         initSingleSMARTS(smarts, "20", "[#16Q2;$(S~O);!$(S(~O)~O)]-*");
702         initSingleSMARTS(smarts, "21", "C([OQ2])=O");
703         initSingleSMARTS(smarts, "22", "C([NX3])=O");
704         initSingleSMARTS(smarts, "26", "[!a;R2]");
705         initSingleSMARTS(smarts, "27", "[a;R2]");
706         initSingleSMARTS(smarts, "28", "[#16Q2;$(S(~O)~O)]-*");
707         initSingleSMARTS(smarts, "30", "cC~N");
708         initSingleSMARTS(smarts, "31", "[#7Q3;$(N(~O)~O)]-*");
709         initSingleSMARTS(smarts, "32",
710             "[$([*;R][*;!R][*;!R][*;R]),$([*;R][*;!R][*;!R][*;!R][*;R])]");
711         initSingleSMARTS(smarts, "33",
712             "[$([*;R][*;!R][*;!R][*;!R][*;!R][*;R]),$([*;R][*;!R][*;!R][*;!R][*;!R][*;!R][*;R])]");
713         initSingleSMARTS(smarts, "34", "[NN]");
714         initSingleSMARTS(smarts, "35", "C([#6])([#6])[#6][*;!C;!H]");
715         initSingleSMARTS(smarts, "36", "[#8]**[#8]");
716         initSingleSMARTS(smarts, "37", "[C;H3][*;!C;!H]");
717         initSingleSMARTS(smarts, "39",
718             "[*X3;!H]([*;!$([#6]);!H])([*;!$([#6]);!H])[*;!$([#6]);!H]");
719         initSingleSMARTS(smarts, "40", "[*X4]");
720         initSingleSMARTS(smarts, "41", "*=C~*~*~C=*");
721         initSingleSMARTS(smarts, "42", "[O;R0]~a");
722         initSingleSMARTS(smarts, "43", "[!#6;!H]~*~*~[!#6;!H]");
723 
724         return smarts;
725     }
726 
727     /**
728      *  Description of the Method
729      *
730      * @param  mol  Description of the Parameter
731      * @return      Description of the Return Value
732      */
733     private boolean hasAromatic5Ring(JOEMol mol)
734     {
735         Vector sssRings = mol.getSSSR();
736         JOERing ring;
737 
738         for (int i = 0; i < sssRings.size(); i++)
739         {
740             ring = (JOERing) sssRings.get(i);
741 
742             if (ring.size() == 5)
743             {
744                 if (ring.isAromatic())
745                 {
746                     return true;
747                 }
748             }
749         }
750 
751         return false;
752     }
753 
754     /**
755      *  Description of the Method
756      *
757      * @param  mol  Description of the Parameter
758      * @return      Description of the Return Value
759      */
760     private boolean hasDoubleBond(JOEMol mol)
761     {
762         BondIterator bit = mol.bondIterator();
763         JOEBond bond;
764 
765         while (bit.hasNext())
766         {
767             bond = bit.nextBond();
768 
769             if (bond.getBondOrder() == 2)
770             {
771                 return true;
772             }
773         }
774 
775         return false;
776     }
777 
778     /**
779      *  Description of the Method
780      *
781      * @return    Description of the Return Value
782      */
783     private boolean hasHalogen(JOEMol mol)
784     {
785         JOEAtom atom;
786         AtomIterator ait = mol.atomIterator();
787         int atomicNum;
788 
789         while (ait.hasNext())
790         {
791             atom = ait.nextAtom();
792             atomicNum = atom.getAtomicNum();
793 
794             if (atom.isHalogen())
795             {
796                 return true;
797             }
798         }
799 
800         return false;
801     }
802 
803     /*-------------------------------------------------------------------------*
804      * private methods
805      *-------------------------------------------------------------------------  */
806 
807     /**
808      *  Description of the Method
809      *
810      * @param  mol  Description of the Parameter
811      * @return      Description of the Return Value
812      */
813     private boolean hasHeteroCycle(JOEMol mol)
814     {
815         Vector sssRings = mol.getSSSR();
816         JOERing ring;
817 
818         for (int i = 0; i < sssRings.size(); i++)
819         {
820             ring = (JOERing) sssRings.get(i);
821 
822             if (ring.isHetero())
823             {
824                 return true;
825             }
826         }
827 
828         return false;
829     }
830 
831     /**
832      *  Description of the Method
833      *
834      * @param  mol  Description of the Parameter
835      * @return      Description of the Return Value
836      */
837     private boolean hasNRing(JOEMol mol)
838     {
839         Vector sssRings = mol.getSSSR();
840         JOERing ring;
841         int[] atomIDs;
842 
843         for (int i = 0; i < sssRings.size(); i++)
844         {
845             ring = (JOERing) sssRings.get(i);
846             atomIDs = ring.getAtoms();
847 
848             for (int j = 0; j < atomIDs.length; j++)
849             {
850                 if ((mol.getAtom(atomIDs[j])).getAtomicNum() == 7)
851                 {
852                     return true;
853                 }
854             }
855         }
856 
857         return false;
858     }
859 
860     /**
861      *  Description of the Method
862      *
863      * @param  mol  Description of the Parameter
864      * @return      Description of the Return Value
865      */
866     private boolean hasNonAromatic5Ring(JOEMol mol)
867     {
868         Vector sssRings = mol.getSSSR();
869         JOERing ring;
870 
871         for (int i = 0; i < sssRings.size(); i++)
872         {
873             ring = (JOERing) sssRings.get(i);
874 
875             if (ring.size() == 5)
876             {
877                 if (!ring.isAromatic())
878                 {
879                     return true;
880                 }
881             }
882         }
883 
884         return false;
885     }
886 
887     /**
888      *  Description of the Method
889      *
890      * @param  mol  Description of the Parameter
891      * @return      Description of the Return Value
892      */
893     private boolean hasRingGreater9(JOEMol mol)
894     {
895         Vector sssRings = mol.getSSSR();
896         JOERing ring;
897 
898         for (int i = 0; i < sssRings.size(); i++)
899         {
900             ring = (JOERing) sssRings.get(i);
901 
902             if (ring.size() > 9)
903             {
904                 return true;
905             }
906         }
907 
908         return false;
909     }
910 
911     /**
912      *  Description of the Method
913      *
914      * @param  mol           Description of the Parameter
915      * @param  smartPattern  Description of the Parameter
916      * @return               Description of the Return Value
917      */
918     private boolean hasSMARTSPattern(JOEMol mol, String id)
919     {
920         JOESmartsPattern smarts = (JOESmartsPattern) smartsPatterns.get(id);
921 
922         if (smarts == null)
923         {
924             logger.error("ID '" + id + "' is missing in " +
925                 SSKey3DS.class.getName());
926 
927             return false;
928         }
929 
930         smarts.match(mol);
931 
932         if (smarts.numMatches() > 0)
933         {
934             return true;
935         }
936 
937         return false;
938     }
939 
940     private static void initSingleSMARTS(Hashtable table, String id,
941         String smartPattern)
942     {
943         JOESmartsPattern smarts = new JOESmartsPattern();
944 
945         if (!smarts.init(smartPattern))
946         {
947             logger.error("Invalid SMARTS pattern (id:" + id + ") '" +
948                 smartPattern + "' defined in " + SSKey3DS.class.getName());
949 
950             return;
951         }
952 
953         table.put(id, smarts);
954     }
955 }
956 ///////////////////////////////////////////////////////////////////////////////
957 //  END OF FILE.
958 ///////////////////////////////////////////////////////////////////////////////