MayaChemTools

   1 package MACCSKeys;
   2 #
   3 # $RCSfile: MACCSKeys.pm,v $
   4 # $Date: 2011/12/26 21:54:09 $
   5 # $Revision: 1.26 $
   6 #
   7 # Author: Manish Sud <msud@san.rr.com>
   8 #
   9 # Copyright (C) 2004-2012 Manish Sud. All rights reserved.
  10 #
  11 # This file is part of MayaChemTools.
  12 #
  13 # MayaChemTools is free software; you can redistribute it and/or modify it under
  14 # the terms of the GNU Lesser General Public License as published by the Free
  15 # Software Foundation; either version 3 of the License, or (at your option) any
  16 # later version.
  17 #
  18 # MayaChemTools is distributed in the hope that it will be useful, but without
  19 # any warranty; without even the implied warranty of merchantability of fitness
  20 # for a particular purpose.  See the GNU Lesser General Public License for more
  21 # details.
  22 #
  23 # You should have received a copy of the GNU Lesser General Public License
  24 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or
  25 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330,
  26 # Boston, MA, 02111-1307, USA.
  27 #
  28 
  29 use strict;
  30 use Carp;
  31 use Exporter;
  32 use Fingerprints::Fingerprints;
  33 use TextUtil ();
  34 use Molecule;
  35 use PeriodicTable;
  36 
  37 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  38 
  39 @ISA = qw(Fingerprints Exporter);
  40 @EXPORT = qw();
  41 @EXPORT_OK = qw();
  42 
  43 %EXPORT_TAGS = (all  => [@EXPORT, @EXPORT_OK]);
  44 
  45 # Setup class variables...
  46 my($ClassName);
  47 _InitializeClass();
  48 
  49 # Overload Perl functions...
  50 use overload '""' => 'StringifyMACCSKeys';
  51 
  52 # Class constructor...
  53 sub new {
  54   my($Class, %NamesAndValues) = @_;
  55 
  56   # Initialize object...
  57   my $This = $Class->SUPER::new();
  58   bless $This, ref($Class) || $Class;
  59   $This->_InitializeMACCSKeys();
  60 
  61   $This->_InitializeMACCSKeysProperties(%NamesAndValues);
  62 
  63   return $This;
  64 }
  65 
  66 # Initialize object data...
  67 #
  68 sub _InitializeMACCSKeys {
  69   my($This) = @_;
  70 
  71   # Type of fingerprint to generate:
  72   #
  73   # MACCSKeyBits - A bit vector indicating presence/absence of keys
  74   # MACCSKeyCount - A vector containing count of keys
  75   #
  76   $This->{Type} = '';
  77   $This->{KeyBits} = '';
  78 
  79   # Size of key set: 166 or 322...
  80   $This->{Size} = '';
  81 }
  82 
  83 # Initialize class ...
  84 sub _InitializeClass {
  85   #Class name...
  86   $ClassName = __PACKAGE__;
  87 }
  88 
  89 # Initialize object properties....
  90 sub _InitializeMACCSKeysProperties {
  91   my($This, %NamesAndValues) = @_;
  92 
  93   my($Name, $Value, $MethodName);
  94   while (($Name, $Value) = each  %NamesAndValues) {
  95     $MethodName = "Set${Name}";
  96     $This->$MethodName($Value);
  97   }
  98 
  99   # Make sure molecule object was specified...
 100   if (!exists $NamesAndValues{Molecule}) {
 101     croak "Error: ${ClassName}->New: Object can't be instantiated without specifying molecule...";
 102   }
 103 
 104   # Make sure type and size were specified...
 105   if (!exists $NamesAndValues{Type}) {
 106     croak "Error: ${ClassName}->New: Object can't be instantiated without specifying type...";
 107   }
 108   if (!exists $NamesAndValues{Size}) {
 109     croak "Error: ${ClassName}->New: Object can't be instantiated without specifying size...";
 110   }
 111 
 112   # Make sure approriate size is specified...
 113   if ($NamesAndValues{Size} !~ /^(166|322)$/) {
 114     croak "Error: ${ClassName}->New: The current release of MayaChemTools doesn't support MDL MACCS $NamesAndValues{Size} keys...";
 115   }
 116 
 117   if ($This->{Type} =~ /^MACCSKeyBits$/i) {
 118     $This->_InitializeMACCSKeyBits();
 119   }
 120   elsif ($This->{Type} =~ /^MACCSKeyCount$/i) {
 121     $This->_InitializeMACCSKeyCounts();
 122   }
 123   else {
 124     croak "Error: ${ClassName}->_InitializeMACCSKeysProperties: Unknown MACCS keys type: $This->{Type}; Supported type keys: MACCSKeyBits or MACCSKeyCount......";
 125   }
 126 
 127   return $This;
 128 }
 129 
 130 # Initialize MACCS key bits...
 131 #
 132 sub _InitializeMACCSKeyBits {
 133   my($This) = @_;
 134 
 135   $This->{KeyBits} = 1;
 136 
 137   # Vector type...
 138   $This->{VectorType} = 'FingerprintsBitVector';
 139 
 140   $This->_InitializeFingerprintsBitVector();
 141 
 142   return $This;
 143 }
 144 
 145 # Initialize MACCS key counts...
 146 #
 147 sub _InitializeMACCSKeyCounts {
 148   my($This) = @_;
 149 
 150   $This->{KeyBits} = 0;
 151 
 152   # Vector type and type of values...
 153   $This->{VectorType} = 'FingerprintsVector';
 154   $This->{FingerprintsVectorType} = 'OrderedNumericalValues';
 155 
 156   $This->_InitializeFingerprintsVector();
 157 
 158   # Initialize values to zero...
 159   my(@Values);
 160   @Values = (0) x $This->{Size};
 161   $This->{FingerprintsVector}->AddValues(\@Values);
 162 
 163   return $This;
 164 }
 165 
 166 # Set type...
 167 #
 168 sub SetType {
 169   my($This, $Type) = @_;
 170 
 171   if ($This->{Type}) {
 172     croak "Error: ${ClassName}->SetType: Can't change type:  It's already set...";
 173   }
 174 
 175   if ($Type =~ /^MACCSKeyBits$/i) {
 176     $This->{Type} = 'MACCSKeyBits';;
 177     $This->{KeyBits} = 1;
 178   }
 179   elsif ($Type =~ /^MACCSKeyCount$/i) {
 180     $This->{Type} = 'MACCSKeyCount';;
 181     $This->{KeyBits} = 0;
 182   }
 183   else {
 184     croak "Error: ${ClassName}->SetType: Unknown type MACCS keys: $Type; Supported type keys: MACCSKeyBits or MACCSKeyCount...";
 185   }
 186   return $This;
 187 }
 188 
 189 # Set size...
 190 #
 191 sub SetSize {
 192   my($This, $Value) = @_;
 193 
 194   if ($This->{Size}) {
 195     croak "Error: ${ClassName}->SetSize: Can't change size:  It's already set...";
 196   }
 197   if (!TextUtil::IsPositiveInteger($Value)) {
 198     croak "Error: ${ClassName}->SetSize: Size value, $Value, is not valid:  It must be a positive integer...";
 199   }
 200   if ($Value !~ /^(166|322)/i) {
 201     croak "Error: ${ClassName}->Size: The current release of MayaChemTools doesn't support MDL MACCS $Value keys...";
 202   }
 203   $This->{Size} = $Value;
 204 
 205   return $This;
 206 }
 207 
 208 # Generate description...
 209 #
 210 sub GetDescription {
 211   my($This) = @_;
 212 
 213   # Is description explicity set?
 214   if (exists $This->{Description}) {
 215     return $This->{Description};
 216   }
 217 
 218   return "$This->{Type}";
 219 }
 220 
 221 # Generate MDL MACCS keys..
 222 #
 223 sub GenerateMACCSKeys {
 224   my($This) = @_;
 225 
 226   # Cache appropriate molecule data...
 227   $This->_SetupMoleculeDataCache();
 228 
 229   if ($This->{Size} == 166) {
 230     $This->_GenerateMACCS166Keys();
 231   }
 232   elsif ($This->{Size} == 322) {
 233     $This->_GenerateMACCS322Keys();
 234   }
 235   else {
 236     croak "Error: ${ClassName}->GenerateMACCSKeys: The current release of MayaChemTools doesn't support MDL MACCS  $This->{Size} keys...";
 237   }
 238 
 239   $This->{FingerprintsGenerated} = 1;
 240 
 241   # Clear cached molecule data...
 242   $This->_ClearMoleculeDataCache();
 243 
 244   return $This;
 245 }
 246 
 247 # Setup GenerateFingerprints method in order to be consistent with all other
 248 # fingerprints classes implemented in the current release of MayaChemTools...
 249 #
 250 sub GenerateFingerprints {
 251   my($This) = @_;
 252 
 253   return $This->GenerateMACCSKeys();
 254 }
 255 
 256 # Generate MDL MACCS 166 keys...
 257 #
 258 # Information on the 166 keys [ Ref. 45-47 ]:
 259 #
 260 # Atom symbols:
 261 #
 262 # A : Any valid perodic table element symbol
 263 # Q  : Hetro atoms; any non-C or non-H atom
 264 # X  : Halogens; F, Cl, Br, I
 265 # Z  : Others; other than H, C, N, O, Si, P, S, F, Cl, Br, I
 266 #
 267 # Bond types:
 268 #
 269 # -  : Single
 270 # =  : Double
 271 # T  : Triple
 272 # #  : Triple
 273 # ~  : Single or double query bond
 274 # %  : An aromatic query bond
 275 #
 276 # None : Any bond type; no explict bond specified
 277 #
 278 # $  : Ring bond; $ before a bond type specifies ring bond
 279 # !  : Chain or non-ring bond; ! before a bond type specifies chain bond
 280 #
 281 # @  : A ring linkage and the number following it specifies the
 282 #      atoms position in the line, thus @1 means linked back to the first atom in
 283 #      the list.
 284 #
 285 # Aromatic: Kekule or Arom5
 286 #
 287 # Kekule: Bonds in 6-membered rings with alternalte single/double bonds or perimeter
 288 #         bonds
 289 #
 290 # Arom5: Bonds in 5-membered rings with two double bonds and a hetro atom at
 291 #        the apex of the ring.
 292 #
 293 # Index Key Description
 294 # 1        ISOTOPE
 295 # 2        103 < ATOMIC NO. < 256
 296 # 3        GROUP IVA,VA,VIA PERIODS 4-6 (Ge...)
 297 # 4        ACTINIDE
 298 # 5        GROUP IIIB,IVB (Sc...)
 299 # 6        LANTHANIDE
 300 # 7        GROUP VB,VIB,VIIB (V...)
 301 # 8        QAAA@1
 302 # 9        GROUP VIII (Fe...)
 303 # 10        GROUP IIA (ALKALINE EARTH)
 304 # 11        4M RING
 305 # 12        GROUP IB,IIB (Cu...)
 306 # 13        ON(C)C
 307 # 14        S-S
 308 # 15        OC(O)O
 309 # 16        QAA@1
 310 # 17        CTC
 311 # 18        GROUP IIIA (B...)
 312 # 19        7M RING
 313 # 20        SI
 314 # 21        C=C(Q)Q
 315 # 22        3M RING
 316 # 23        NC(O)O
 317 # 24        N-O
 318 # 25        NC(N)N
 319 # 26        C$=C($A)$A
 320 # 27        I
 321 # 28        QCH2Q
 322 # 29        P
 323 # 30        CQ(C)(C)A
 324 # 31        QX
 325 # 32        CSN
 326 # 33        NS
 327 # 34        CH2=A
 328 # 35        GROUP IA (ALKALI METAL)
 329 # 36        S HETEROCYCLE
 330 # 37        NC(O)N
 331 # 38        NC(C)N
 332 # 39        OS(O)O
 333 # 40        S-O
 334 # 41        CTN
 335 # 42        F
 336 # 43        QHAQH
 337 # 44        OTHER
 338 # 45        C=CN
 339 # 46        BR
 340 # 47        SAN
 341 # 48        OQ(O)O
 342 # 49        CHARGE
 343 # 50        C=C(C)C
 344 # 51        CSO
 345 # 52        NN
 346 # 53        QHAAAQH
 347 # 54        QHAAQH
 348 # 55        OSO
 349 # 56        ON(O)C
 350 # 57        O HETEROCYCLE
 351 # 58        QSQ
 352 # 59        Snot%A%A
 353 # 60        S=O
 354 # 61        AS(A)A
 355 # 62        A$A!A$A
 356 # 63        N=O
 357 # 64        A$A!S
 358 # 65        C%N
 359 # 66        CC(C)(C)A
 360 # 67        QS
 361 # 68        QHQH (&...)
 362 # 69        QQH
 363 # 70        QNQ
 364 # 71        NO
 365 # 72        OAAO
 366 # 73        S=A
 367 # 74        CH3ACH3
 368 # 75        A!N$A
 369 # 76        C=C(A)A
 370 # 77        NAN
 371 # 78        C=N
 372 # 79        NAAN
 373 # 80        NAAAN
 374 # 81        SA(A)A
 375 # 82        ACH2QH
 376 # 83         QAAAA@1
 377 # 84        NH2
 378 # 85        CN(C)C
 379 # 86        CH2QCH2
 380 # 87        X!A$A
 381 # 88        S
 382 # 89        OAAAO
 383 # 90        QHAACH2A
 384 # 91        QHAAACH2A
 385 # 92        OC(N)C
 386 # 93        QCH3
 387 # 94        QN
 388 # 95        NAAO
 389 # 96        5M RING
 390 # 97        NAAAO
 391 # 98        QAAAAA@1
 392 # 99        C=C
 393 # 100        ACH2N
 394 # 101        8M RING
 395 # 102        QO
 396 # 103        CL
 397 # 104        QHACH2A
 398 # 105        A$A($A)$A
 399 # 106        QA(Q)Q
 400 # 107        XA(A)A
 401 # 108        CH3AAACH2A
 402 # 109        ACH2O
 403 # 110        NCO
 404 # 111        NACH2A
 405 # 112        AA(A)(A)A
 406 # 113        Onot%A%A
 407 # 114        CH3CH2A
 408 # 115        CH3ACH2A
 409 # 116        CH3AACH2A
 410 # 117        NAO
 411 # 118        ACH2CH2A > 1
 412 # 119        N=A
 413 # 120        HETEROCYCLIC ATOM > 1 (&...)
 414 # 121        N HETEROCYCLE
 415 # 122        AN(A)A
 416 # 123        OCO
 417 # 124        QQ
 418 # 125        AROMATIC RING > 1
 419 # 126        A!O!A
 420 # 127        A$A!O > 1 (&...)
 421 # 128        ACH2AAACH2A
 422 # 129        ACH2AACH2A
 423 # 130        QQ > 1 (&...)
 424 # 131        QH > 1
 425 # 132        OACH2A
 426 # 133        A$A!N
 427 # 134        X (HALOGEN)
 428 # 135        Nnot%A%A
 429 # 136        O=A > 1
 430 # 137        HETEROCYCLE
 431 # 138        QCH2A > 1 (&...)
 432 # 139        OH
 433 # 140        O > 3 (&...)
 434 # 141        CH3 > 2 (&...)
 435 # 142        N > 1
 436 # 143        A$A!O
 437 # 144        Anot%A%Anot%A
 438 # 145        6M RING > 1
 439 # 146        O > 2
 440 # 147        ACH2CH2A
 441 # 148        AQ(A)A
 442 # 149        CH3 > 1
 443 # 150        A!A$A!A
 444 # 151        NH
 445 # 152        OC(C)C
 446 # 153        QCH2A
 447 # 154        C=O
 448 # 155        A!CH2!A
 449 # 156        NA(A)A
 450 # 157        C-O
 451 # 158        C-N
 452 # 159        O > 1
 453 # 160        CH3
 454 # 161        N
 455 # 162        AROMATIC
 456 # 163        6M RING
 457 # 164        O
 458 # 165        RING
 459 # 166         FRAGMENTS
 460 #
 461 sub _GenerateMACCS166Keys {
 462   my($This) = @_;
 463   my($KeyNum, $KeyIndex, $MethodName, $KeyValue, $SkipPosCheck);
 464 
 465   $SkipPosCheck = 1;
 466 
 467   # Generate and set key values...
 468   KEYNUM: for $KeyNum (1 .. 166) {
 469     $MethodName = "_Generate166KeySetKey${KeyNum}";
 470     $KeyValue = $This->$MethodName();
 471 
 472     if (!$KeyValue) {
 473       next KEYNUM;
 474     }
 475     $KeyIndex = $KeyNum - 1;
 476     if ($This->{KeyBits}) {
 477       $This->{FingerprintsBitVector}->SetBit($KeyIndex, $SkipPosCheck);
 478     }
 479     else {
 480       $This->{FingerprintsVector}->SetValue($KeyIndex, $KeyValue, $SkipPosCheck);
 481     }
 482   }
 483 
 484   # Add key labels for MACCSKeyCount...
 485   if (!$This->{KeyBits}) {
 486     $This->_SetMACCSKeyCountValueIDs();
 487   }
 488 
 489   return $This;
 490 }
 491 
 492 # Generate MDL MACCS 322 keys...
 493 #
 494 # MDL MACCS 322 key set is defined in tables 1, 2 and 3 by: Joseph L. Durant; Burton A. Leland;
 495 # Douglas R. Henry; James G. Nourse. Reoptimization of MDL Keys for Use in Drug Discovery [ Ref. 46 ].
 496 #
 497 # Atom symbols:
 498 #
 499 # A : Any valid perodic table element symbol
 500 # Q  : Hetro atoms; any non-C or non-H atom
 501 # X  : Others; other than H, C, N, O, Si, P, S, F, Cl, Br, I
 502 # Z is neither defined nor used
 503 #
 504 # Atom symbol, X, used for 322 keys [ Ref 46 ] doesn't refer to Halogens as it does for 166 keys. In
 505 # order to keep the definition of 322 keys consistent with the published definitions, the symbol X is
 506 # used to imply "others" atoms, but it's internally mapped to symbol X as defined for 166 keys
 507 # during the generation of key values.
 508 #
 509 # The keys include:
 510 #
 511 # o 26 atom properties of type P, as listed in Table 1
 512 # o 32 one-atom environments, as listed in Table 3
 513 # o 264 atom-bond-atom combinations listed in Table 4
 514 #
 515 # Total number of keys in three tables: 322
 516 #
 517 # Removal of two rare properties in Table 1 number 21 and 22 results in a 320 keyset.
 518 #
 519 # Atom properties-based keys (26):
 520 #
 521 # Index Description
 522 # 1     A(AAA) or AA(A)A - atom with at least three neighbors
 523 # 2     Q - heteroatom
 524 # 3     Anot%not-A - atom involved in one or more multiple bonds, not aromatic
 525 # 4     A(AAAA) or AA(A)(A)A - atom with at least four neighbors
 526 # 5     A(QQ) or QA(Q) - atom with at least two heteroatom neighbors
 527 # 6     A(QQQ) or QA(Q)Q - atom with at least three heteroatom neighbors
 528 # 7     QH - heteroatom with at least one hydrogen attached
 529 # 8     CH2(AA) or ACH2A - carbon with at least two single bonds and at least two hydrogens attached
 530 # 9     CH3(A) or ACH3 - carbon with at least one single bond and at least three hydrogens attached
 531 # 10    Halogen
 532 # 11    A(-A-A-A) or A-A(-A)-A - atom has at least three single bonds
 533 # 12    AAAAAA@1 > 2 - atom is in at least two different six-membered rings
 534 # 13    A($A$A$A) or A$A($A)$A - atom has more than two ring bonds
 535 # 14    A$A!A$A - atom is at a ring/chain boundary. When a comparison is done
 536 #       with another atom the path passes through the chain bond.
 537 # 15    Anot%A%Anot%A - atom is at an aromatic/nonaromatic boundary. When a
 538 #       comparison is done with another atom the path
 539 #       passes through the aromatic bond.
 540 # 16    A!A!A  - atom with more than one chain bond
 541 # 17    A!A$A!A - atom is at a ring/chain boundary. When a comparison is done
 542 #       with another atom the path passes through the ring bond.
 543 # 18    A%Anot%A%A - atom is at an aromatic/nonaromatic boundary. When a
 544 #       comparison is done with another atom the
 545 #       path passes through the nonaromatic bond.
 546 # 19    HETEROCYCLE - atom is a heteroatom in a ring.
 547 # 20    rare properties: atom with five or more neighbors, atom in
 548 #       four or more rings, or atom types other than
 549 #       H, C, N, O, S, F, Cl, Br, or I
 550 # 21    rare properties: atom has a charge, is an isotope, has two or
 551 #       more multiple bonds, or has a triple bond.
 552 # 22    N - nitrogen
 553 # 23    S - sulfur
 554 # 24    O - oxygen
 555 # 25    A(AA)A(A)A(AA) - atom has two neighbors, each with three or more neighbors
 556 #       (including the central atom).
 557 # 26    CHACH2 - atom has two hydrocarbon (CH2) neighbors
 558 #
 559 #
 560 # Atomic environments properties-based keys (32):
 561 #
 562 # Index Key Description
 563 # 27    C(CC)
 564 # 28    C(CCC)
 565 # 29    C(CN)
 566 # 30    C(CCN)
 567 # 31    C(NN)
 568 # 32    C(NNC)
 569 # 33    C(NNN)
 570 # 34    C(CO)
 571 # 35    C(CCO)
 572 # 36    C(NO)
 573 # 37    C(NCO)
 574 # 38    C(NNO)
 575 # 39    C(OO)
 576 # 40    C(COO)
 577 # 41    C(NOO)
 578 # 42    C(OOO)
 579 # 43    Q(CC)
 580 # 44    Q(CCC)
 581 # 45    Q(CN)
 582 # 46    Q(CCN)
 583 # 47    Q(NN)
 584 # 48    Q(CNN)
 585 # 49    Q(NNN)
 586 # 50    Q(CO)
 587 # 51    Q(CCO)
 588 # 52    Q(NO)
 589 # 53    Q(CNO)
 590 # 54    Q(NNO)
 591 # 55    Q(OO)
 592 # 56    Q(COO)
 593 # 57    Q(NOO)
 594 # 58    Q(OOO)
 595 #
 596 # Note: The first symbol is the central atom, with atoms bonded to the
 597 # central atom listed in parentheses. Q is any non-C, non-H atom. If
 598 # only two atoms are in parentheses, there is no implication concerning
 599 # the other atoms bonded to the central atom.
 600 #
 601 # Atom-Bond-Atom properties-based keys: (264)
 602 #
 603 # Index Key Description
 604 # 59    C-C
 605 # 60    C-N
 606 # 61    C-O
 607 # 62    C-S
 608 # 63    C-Cl
 609 # 64    C-P
 610 # 65    C-F
 611 # 66    C-Br
 612 # 67    C-Si
 613 # 68    C-I
 614 # 69    C-X
 615 # 70    N-N
 616 # 71    N-O
 617 # 72    N-S
 618 # 73    N-Cl
 619 # 74    N-P
 620 # 75    N-F
 621 # 76    N-Br
 622 # 77    N-Si
 623 # 78    N-I
 624 # 79    N-X
 625 # 80    O-O
 626 # 81    O-S
 627 # 82    O-Cl
 628 # 83    O-P
 629 # 84    O-F
 630 # 85    O-Br
 631 # 86    O-Si
 632 # 87    O-I
 633 # 88    O-X
 634 # 89    S-S
 635 # 90    S-Cl
 636 # 91    S-P
 637 # 92    S-F
 638 # 93    S-Br
 639 # 94    S-Si
 640 # 95    S-I
 641 # 96    S-X
 642 # 97    Cl-Cl
 643 # 98    Cl-P
 644 # 99    Cl-F
 645 # 100   Cl-Br
 646 # 101   Cl-Si
 647 # 102   Cl-I
 648 # 103   Cl-X
 649 # 104   P-P
 650 # 105   P-F
 651 # 106   P-Br
 652 # 107   P-Si
 653 # 108   P-I
 654 # 109   P-X
 655 # 110   F-F
 656 # 111   F-Br
 657 # 112   F-Si
 658 # 113   F-I
 659 # 114   F-X
 660 # 115   Br-Br
 661 # 116   Br-Si
 662 # 117   Br-I
 663 # 118   Br-X
 664 # 119   Si-Si
 665 # 120   Si-I
 666 # 121   Si-X
 667 # 122   I-I
 668 # 123   I-X
 669 # 124   X-X
 670 # 125   C=C
 671 # 126   C=N
 672 # 127   C=O
 673 # 128   C=S
 674 # 129   C=Cl
 675 # 130   C=P
 676 # 131   C=F
 677 # 132   C=Br
 678 # 133   C=Si
 679 # 134   C=I
 680 # 135   C=X
 681 # 136   N=N
 682 # 137   N=O
 683 # 138   N=S
 684 # 139   N=Cl
 685 # 140   N=P
 686 # 141   N=F
 687 # 142   N=Br
 688 # 143   N=Si
 689 # 144   N=I
 690 # 145   N=X
 691 # 146   O=O
 692 # 147   O=S
 693 # 148   O=Cl
 694 # 149   O=P
 695 # 150   O=F
 696 # 151   O=Br
 697 # 152   O=Si
 698 # 153   O=I
 699 # 154   O=X
 700 # 155   S=S
 701 # 156   S=Cl
 702 # 157   S=P
 703 # 158   S=F
 704 # 159   S=Br
 705 # 160   S=Si
 706 # 161   S=I
 707 # 162   S=X
 708 # 163   Cl=Cl
 709 # 164   Cl=P
 710 # 165   Cl=F
 711 # 166   Cl=Br
 712 # 167   Cl=Si
 713 # 168   Cl=I
 714 # 169   Cl=X
 715 # 170   P=P
 716 # 171   P=F
 717 # 172   P=Br
 718 # 173   P=Si
 719 # 174   P=I
 720 # 175   P=X
 721 # 176   F=F
 722 # 177   F=Br
 723 # 178   F=Si
 724 # 179   F=I
 725 # 180   F=X
 726 # 181   Br=Br
 727 # 182   Br=Si
 728 # 183   Br=I
 729 # 184   Br=X
 730 # 185   Si=Si
 731 # 186   Si=I
 732 # 187   Si=X
 733 # 188   I=I
 734 # 189   I=X
 735 # 190   X=X
 736 # 191   C#C
 737 # 192   C#N
 738 # 193   C#O
 739 # 194   C#S
 740 # 195   C#Cl
 741 # 196   C#P
 742 # 197   C#F
 743 # 198   C#Br
 744 # 199   C#Si
 745 # 200   C#I
 746 # 201   C#X
 747 # 202   N#N
 748 # 203   N#O
 749 # 204   N#S
 750 # 205   N#Cl
 751 # 206   N#P
 752 # 207   N#F
 753 # 208   N#Br
 754 # 209   N#Si
 755 # 210   N#I
 756 # 211   N#X
 757 # 212   O#O
 758 # 213   O#S
 759 # 214   O#Cl
 760 # 215   O#P
 761 # 216   O#F
 762 # 217   O#Br
 763 # 218   O#Si
 764 # 219   O#I
 765 # 220   O#X
 766 # 221   S#S
 767 # 222   S#Cl
 768 # 223   S#P
 769 # 224   S#F
 770 # 225   S#Br
 771 # 226   S#Si
 772 # 227   S#I
 773 # 228   S#X
 774 # 229   Cl#Cl
 775 # 230   Cl#P
 776 # 231   Cl#F
 777 # 232   Cl#Br
 778 # 233   Cl#Si
 779 # 234   Cl#I
 780 # 235   Cl#X
 781 # 236   P#P
 782 # 237   P#F
 783 # 238   P#Br
 784 # 239   P#Si
 785 # 240   P#I
 786 # 241   P#X
 787 # 242   F#F
 788 # 243   F#Br
 789 # 244   F#Si
 790 # 245   F#I
 791 # 246   F#X
 792 # 247   Br#Br
 793 # 248   Br#Si
 794 # 249   Br#I
 795 # 250   Br#X
 796 # 251   Si#Si
 797 # 252   Si#I
 798 # 253   Si#X
 799 # 254   I#I
 800 # 255   I#X
 801 # 256   X#X
 802 # 257   C$C
 803 # 258   C$N
 804 # 259   C$O
 805 # 260   C$S
 806 # 261   C$Cl
 807 # 262   C$P
 808 # 263   C$F
 809 # 264   C$Br
 810 # 265   C$Si
 811 # 266   C$I
 812 # 267   C$X
 813 # 268   N$N
 814 # 269   N$O
 815 # 270   N$S
 816 # 271   N$Cl
 817 # 272   N$P
 818 # 273   N$F
 819 # 274   N$Br
 820 # 275   N$Si
 821 # 276   N$I
 822 # 277   N$X
 823 # 278   O$O
 824 # 279   O$S
 825 # 280   O$Cl
 826 # 281   O$P
 827 # 282   O$F
 828 # 283   O$Br
 829 # 284   O$Si
 830 # 285   O$I
 831 # 286   O$X
 832 # 287   S$S
 833 # 288   S$Cl
 834 # 289   S$P
 835 # 290   S$F
 836 # 291   S$Br
 837 # 292   S$Si
 838 # 293   S$I
 839 # 294   S$X
 840 # 295   Cl$Cl
 841 # 296   Cl$P
 842 # 297   Cl$F
 843 # 298   Cl$Br
 844 # 299   Cl$Si
 845 # 300   Cl$I
 846 # 301   Cl$X
 847 # 302   P$P
 848 # 303   P$F
 849 # 304   P$Br
 850 # 305   P$Si
 851 # 306   P$I
 852 # 307   P$X
 853 # 308   F$F
 854 # 309   F$Br
 855 # 310   F$Si
 856 # 311   F$I
 857 # 312   F$X
 858 # 313   Br$Br
 859 # 314   Br$Si
 860 # 315   Br$I
 861 # 316   Br$X
 862 # 317   Si$Si
 863 # 318   Si$I
 864 # 319   Si$X
 865 # 320   I$I
 866 # 321   I$X
 867 # 322   X$X
 868 #
 869 # Note: Instead of using '%' as rind bond as mentioned in the article [ Ref. 46 ], MayaChemTools
 870 # used '$' as a symbol for ring bond to follow conventions used for MACCS 166 keys; the symbol '%'
 871 # is used to indicate an aromatic query bond.
 872 #
 873 sub _GenerateMACCS322Keys {
 874   my($This) = @_;
 875   my($KeyNum, $KeyIndex, $MethodName, $KeyValue, $SkipPosCheck);
 876 
 877   $SkipPosCheck = 1;
 878 
 879   # Generate and set key values...
 880   KEYNUM: for $KeyNum (1 .. 322) {
 881     $MethodName = "_Generate322KeySetKey${KeyNum}";
 882     $KeyValue = $This->$MethodName();
 883 
 884     if (!$KeyValue) {
 885       next KEYNUM;
 886     }
 887     $KeyIndex = $KeyNum - 1;
 888     if ($This->{KeyBits}) {
 889       $This->{FingerprintsBitVector}->SetBit($KeyIndex, $SkipPosCheck);
 890     }
 891     else {
 892       $This->{FingerprintsVector}->SetValue($KeyIndex, $KeyValue, $SkipPosCheck);
 893     }
 894   }
 895 
 896   # Add key labels for MACCSKeyCount...
 897   if (!$This->{KeyBits}) {
 898     $This->_SetMACCSKeyCountValueIDs();
 899   }
 900   return $This;
 901 }
 902 
 903 # Set MACCS key count value IDs for fingerprint vector. The value IDs labels format
 904 # is: Key<KeyNum>.
 905 #
 906 # By default, no value IDs are set for fingerprint vector values.
 907 #
 908 sub _SetMACCSKeyCountValueIDs {
 909   my($This) = @_;
 910 
 911   if (!$This->{FingerprintsVector}) {
 912     return;
 913   }
 914   my(@ValueIDs);
 915 
 916   @ValueIDs = map { "Key$_"; } (1 .. $This->{Size});
 917   $This->{FingerprintsVector}->AddValueIDs(\@ValueIDs);
 918 
 919   return $This;
 920 }
 921 
 922 ##################################
 923 #
 924 #  Implementation of MDL MACCS 166 keys...
 925 #
 926 ##################################
 927 
 928 # Generate key 1 value as 1/0 indicating its presence/absence or count of its
 929 # presence in a molecule.
 930 #
 931 # Key 1 description: ISOTOPE
 932 #
 933 sub _Generate166KeySetKey1 {
 934   my($This) = @_;
 935   my($Atom, $KeyValue);
 936 
 937   $KeyValue = 0;
 938   ATOM: for $Atom (@{$This->{Atoms}}) {
 939     if ($Atom->IsIsotope()) {
 940       if ($This->{KeyBits}) {
 941         $KeyValue = 1;
 942         last ATOM;
 943       }
 944       $KeyValue++;
 945     }
 946   }
 947   return $KeyValue;
 948 }
 949 
 950 # Generate key 2 value as 1/0 indicating its presence/absence or count of its
 951 # presence in a molecule.
 952 #
 953 # Key 2 description: 103 < ATOMIC NO. < 256
 954 #
 955 sub _Generate166KeySetKey2 {
 956   my($This) = @_;
 957   my($Atom, $AtomicNumber, $KeyValue);
 958 
 959   $KeyValue = 0;
 960   ATOM: for $Atom (@{$This->{Atoms}}) {
 961     $AtomicNumber = $Atom->GetAtomicNumber();
 962     if ($AtomicNumber > 103 && $AtomicNumber < 256) {
 963       if ($This->{KeyBits}) {
 964         $KeyValue = 1;
 965         last ATOM;
 966       }
 967       $KeyValue++;
 968     }
 969   }
 970   return $KeyValue;
 971 }
 972 
 973 # Generate key 3 value as 1/0 indicating its presence/absence or count of its
 974 # presence in a molecule.
 975 #
 976 # Key 3 description: GROUP IVA,VA,VIA (GroupNumber: 14, 15, 16) PERIODS 4-6 (Ge...)
 977 #
 978 sub _Generate166KeySetKey3 {
 979   my($This) = @_;
 980   my($Atom, $KeyValue, $AtomicNumber, $GroupNumber, $PeriodNumber);
 981 
 982   $KeyValue = 0;
 983   ATOM: for $Atom (@{$This->{Atoms}}) {
 984     $AtomicNumber = $Atom->GetAtomicNumber();
 985     if ($AtomicNumber) {
 986       $GroupNumber = PeriodicTable::GetElementGroupNumber($AtomicNumber);
 987       $PeriodNumber = PeriodicTable::GetElementPeriodNumber($AtomicNumber);
 988       if ($PeriodNumber =~ /^(4|5|6)$/ && $GroupNumber =~ /^(14|15|16)$/) {
 989         if ($This->{KeyBits}) {
 990           $KeyValue = 1;
 991           last ATOM;
 992         }
 993         $KeyValue++;
 994       }
 995     }
 996   }
 997   return $KeyValue;
 998 }
 999 
1000 # Generate key 4 value as 1/0 indicating its presence/absence or count of its
1001 # presence in a molecule.
1002 #
1003 # Key 4 description: ACTINIDE
1004 #
1005 sub _Generate166KeySetKey4 {
1006   my($This) = @_;
1007   my($Atom, $AtomicNumber, $KeyValue);
1008 
1009   $KeyValue = 0;
1010   ATOM: for $Atom (@{$This->{Atoms}}) {
1011     $AtomicNumber = $Atom->GetAtomicNumber();
1012     if ($AtomicNumber >= 89 && $AtomicNumber <= 103) {
1013       if ($This->{KeyBits}) {
1014         $KeyValue = 1;
1015         last ATOM;
1016       }
1017       $KeyValue++;
1018     }
1019   }
1020   return $KeyValue;
1021 }
1022 
1023 # Generate key 5 value as 1/0 indicating its presence/absence or count of its
1024 # presence in a molecule.
1025 #
1026 # Key 5 description: GROUP IIIB,IVB (Sc...)
1027 #
1028 sub _Generate166KeySetKey5 {
1029   my($This) = @_;
1030   my($Atom, $KeyValue, $AtomicNumber, $GroupNumber);
1031 
1032   $KeyValue = 0;
1033   ATOM: for $Atom (@{$This->{Atoms}}) {
1034     $AtomicNumber = $Atom->GetAtomicNumber();
1035     if ($AtomicNumber) {
1036       $GroupNumber = PeriodicTable::GetElementGroupNumber($AtomicNumber);
1037       if ($GroupNumber =~ /^(3|4)$/) {
1038         if ($This->{KeyBits}) {
1039           $KeyValue = 1;
1040           last ATOM;
1041         }
1042         $KeyValue++;
1043       }
1044     }
1045   }
1046   return $KeyValue;
1047 }
1048 
1049 # Generate key 6 value as 1/0 indicating its presence/absence or count of its
1050 # presence in a molecule.
1051 #
1052 # Key 6 description: LANTHANIDE
1053 #
1054 sub _Generate166KeySetKey6 {
1055   my($This) = @_;
1056   my($Atom, $AtomicNumber, $KeyValue);
1057 
1058   $KeyValue = 0;
1059   ATOM: for $Atom (@{$This->{Atoms}}) {
1060     $AtomicNumber = $Atom->GetAtomicNumber();
1061     if ($AtomicNumber >= 57 && $AtomicNumber <= 71) {
1062       if ($This->{KeyBits}) {
1063         $KeyValue = 1;
1064         last ATOM;
1065       }
1066       $KeyValue++;
1067     }
1068   }
1069   return $KeyValue;
1070 }
1071 
1072 # Generate key 7 value as 1/0 indicating its presence/absence or count of its
1073 # presence in a molecule.
1074 #
1075 # Key 7 description: GROUP VB,VIB,VIIB (V...)
1076 #
1077 sub _Generate166KeySetKey7 {
1078   my($This) = @_;
1079   my($Atom, $KeyValue, $AtomicNumber, $GroupNumber);
1080 
1081   $KeyValue = 0;
1082   ATOM: for $Atom (@{$This->{Atoms}}) {
1083     $AtomicNumber = $Atom->GetAtomicNumber();
1084     if ($AtomicNumber) {
1085       $GroupNumber = PeriodicTable::GetElementGroupNumber($AtomicNumber);
1086       if ($GroupNumber =~ /^(5|6|7)$/) {
1087         if ($This->{KeyBits}) {
1088           $KeyValue = 1;
1089           last ATOM;
1090         }
1091         $KeyValue++;
1092       }
1093     }
1094   }
1095   return $KeyValue;
1096 }
1097 
1098 # Generate key 8 value as 1/0 indicating its presence/absence or count of its
1099 # presence in a molecule.
1100 #
1101 # Key 8 description: QAAA@1
1102 #
1103 sub _Generate166KeySetKey8 {
1104   my($This) = @_;
1105   my($Atom, $KeyValue, $RingSize);
1106 
1107   $RingSize = 4;
1108   $KeyValue = 0;
1109   ATOM: for $Atom (@{$This->{Atoms}}) {
1110     if ($This->_IsHetroAtom($Atom) && $Atom->IsInRingOfSize($RingSize)) {
1111       if ($This->{KeyBits}) {
1112         $KeyValue = 1;
1113         last ATOM;
1114       }
1115       $KeyValue++;
1116     }
1117   }
1118   return $KeyValue;
1119 }
1120 
1121 # Generate key 9 value as 1/0 indicating its presence/absence or count of its
1122 # presence in a molecule.
1123 #
1124 # Key 9 description: GROUP VIII (Fe...)
1125 #
1126 sub _Generate166KeySetKey9 {
1127   my($This) = @_;
1128   my($Atom, $KeyValue, $AtomicNumber, $GroupNumber);
1129 
1130   $KeyValue = 0;
1131   ATOM: for $Atom (@{$This->{Atoms}}) {
1132     $AtomicNumber = $Atom->GetAtomicNumber();
1133     if ($AtomicNumber) {
1134       $GroupNumber = PeriodicTable::GetElementGroupNumber($AtomicNumber);
1135       if ($GroupNumber =~ /^(8|9|10)$/) {
1136         if ($This->{KeyBits}) {
1137           $KeyValue = 1;
1138           last ATOM;
1139         }
1140         $KeyValue++;
1141       }
1142     }
1143   }
1144   return $KeyValue;
1145 }
1146 
1147 # Generate key 10 value as 1/0 indicating its presence/absence or count of its
1148 # presence in a molecule.
1149 #
1150 # Key 10 description: GROUP IIA (ALKALINE EARTH)
1151 #
1152 sub _Generate166KeySetKey10 {
1153   my($This) = @_;
1154   my($Atom, $KeyValue, $AtomicNumber, $GroupNumber);
1155 
1156   $KeyValue = 0;
1157   ATOM: for $Atom (@{$This->{Atoms}}) {
1158     $AtomicNumber = $Atom->GetAtomicNumber();
1159     if ($AtomicNumber) {
1160       $GroupNumber = PeriodicTable::GetElementGroupNumber($AtomicNumber);
1161       if ($GroupNumber =~ /^2$/) {
1162         if ($This->{KeyBits}) {
1163           $KeyValue = 1;
1164           last ATOM;
1165         }
1166         $KeyValue++;
1167       }
1168     }
1169   }
1170   return $KeyValue;
1171 }
1172 
1173 # Generate key 11 value as 1/0 indicating its presence/absence or count of its
1174 # presence in a molecule.
1175 #
1176 # Key 11 description: 4M RING
1177 #
1178 sub _Generate166KeySetKey11 {
1179   my($This) = @_;
1180   my($Molecule, $KeyValue, $RingSize, $NumOfRings);
1181 
1182   $RingSize = 4;
1183   $Molecule = $This->GetMolecule();
1184   $NumOfRings = $Molecule->GetNumOfRingsWithSize($RingSize);
1185 
1186   if ($This->{KeyBits}) {
1187     $KeyValue = $NumOfRings ? 1 : 0;
1188   }
1189   else {
1190     $KeyValue = $NumOfRings;
1191   }
1192   return $KeyValue;
1193 }
1194 
1195 # Generate key 12 value as 1/0 indicating its presence/absence or count of its
1196 # presence in a molecule.
1197 #
1198 # Key 12 description: GROUP IB,IIB (Cu...)
1199 #
1200 sub _Generate166KeySetKey12 {
1201   my($This) = @_;
1202   my($Atom, $KeyValue, $AtomicNumber, $GroupNumber);
1203 
1204   $KeyValue = 0;
1205   ATOM: for $Atom (@{$This->{Atoms}}) {
1206     $AtomicNumber = $Atom->GetAtomicNumber();
1207     if ($AtomicNumber) {
1208       $GroupNumber = PeriodicTable::GetElementGroupNumber($AtomicNumber);
1209       if ($GroupNumber =~ /^(11|12)$/) {
1210         if ($This->{KeyBits}) {
1211           $KeyValue = 1;
1212           last ATOM;
1213         }
1214         $KeyValue++;
1215       }
1216     }
1217   }
1218   return $KeyValue;
1219 }
1220 
1221 # Generate key 13 value as 1/0 indicating its presence/absence or count of its
1222 # presence in a molecule.
1223 #
1224 # Key 13 description: ON(C)C
1225 #
1226 sub _Generate166KeySetKey13 {
1227   my($This) = @_;
1228   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1229 
1230   $CentralAtomSymbol = 'N';
1231   @NbrAtomSymbols = ('O', 'C', 'C');
1232   @NbrBondSymbols = (undef, undef, undef);
1233 
1234   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1235 }
1236 
1237 # Generate key 14 value as 1/0 indicating its presence/absence or count of its
1238 # presence in a molecule.
1239 #
1240 # Key 14 description: S-S
1241 #
1242 sub _Generate166KeySetKey14 {
1243   my($This) = @_;
1244   my($BondOrder) = 1;
1245 
1246   return $This->_DetectBondKeys('S', 'S', $BondOrder);
1247 }
1248 
1249 # Generate key 15 value as 1/0 indicating its presence/absence or count of its
1250 # presence in a molecule.
1251 #
1252 # Key 15 description: OC(O)O
1253 #
1254 sub _Generate166KeySetKey15 {
1255   my($This) = @_;
1256   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1257 
1258   $CentralAtomSymbol = 'C';
1259   @NbrAtomSymbols = ('O', 'O', 'O');
1260   @NbrBondSymbols = (undef, undef, undef);
1261 
1262   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1263 }
1264 
1265 # Generate key 16 value as 1/0 indicating its presence/absence or count of its
1266 # presence in a molecule.
1267 #
1268 # Key 16 description: QAA@1
1269 #
1270 sub _Generate166KeySetKey16 {
1271   my($This) = @_;
1272   my($Atom, $KeyValue, $RingSize);
1273 
1274   $RingSize = 3;
1275   $KeyValue = 0;
1276   ATOM: for $Atom (@{$This->{Atoms}}) {
1277     if ($This->_IsHetroAtom($Atom) && $Atom->IsInRingOfSize($RingSize)) {
1278       if ($This->{KeyBits}) {
1279         $KeyValue = 1;
1280         last ATOM;
1281       }
1282       $KeyValue++;
1283     }
1284   }
1285   return $KeyValue;
1286 }
1287 
1288 # Generate key 17 value as 1/0 indicating its presence/absence or count of its
1289 # presence in a molecule.
1290 #
1291 # Key 17 description: CTC
1292 #
1293 sub _Generate166KeySetKey17 {
1294   my($This) = @_;
1295   my($BondOrder) = 3;
1296 
1297   return $This->_DetectBondKeys('C', 'C', $BondOrder);
1298 }
1299 
1300 # Generate key 18 value as 1/0 indicating its presence/absence or count of its
1301 # presence in a molecule.
1302 #
1303 # Key 18 description: GROUP IIIA (B...)
1304 #
1305 sub _Generate166KeySetKey18 {
1306   my($This) = @_;
1307   my($Atom, $KeyValue, $AtomicNumber, $GroupNumber);
1308 
1309   $KeyValue = 0;
1310   ATOM: for $Atom (@{$This->{Atoms}}) {
1311     $AtomicNumber = $Atom->GetAtomicNumber();
1312     if ($AtomicNumber) {
1313       $GroupNumber = PeriodicTable::GetElementGroupNumber($AtomicNumber);
1314       if ($GroupNumber =~ /^13$/) {
1315         if ($This->{KeyBits}) {
1316           $KeyValue = 1;
1317           last ATOM;
1318         }
1319         $KeyValue++;
1320       }
1321     }
1322   }
1323   return $KeyValue;
1324 }
1325 
1326 # Generate key 19 value as 1/0 indicating its presence/absence or count of its
1327 # presence in a molecule.
1328 #
1329 # Key 19 description: 7M RING
1330 #
1331 sub _Generate166KeySetKey19 {
1332   my($This) = @_;
1333   my($Molecule, $KeyValue, $RingSize, $NumOfRings);
1334 
1335   $RingSize = 7;
1336   $Molecule = $This->GetMolecule();
1337   $NumOfRings = $Molecule->GetNumOfRingsWithSize($RingSize);
1338 
1339   $KeyValue = 0;
1340   if ($NumOfRings) {
1341     $KeyValue = ($This->{KeyBits}) ? 1 : $NumOfRings;
1342   }
1343   return $KeyValue;
1344 }
1345 
1346 # Generate key 20 value as 1/0 indicating its presence/absence or count of its
1347 # presence in a molecule.
1348 #
1349 # Key 20 description: SI
1350 #
1351 sub _Generate166KeySetKey20 {
1352   my($This) = @_;
1353 
1354   return $This->_DetectAtomKeys('Si');
1355 }
1356 
1357 # Generate key 21 value as 1/0 indicating its presence/absence or count of its
1358 # presence in a molecule.
1359 #
1360 # Key 21 description: C=C(Q)Q
1361 #
1362 sub _Generate166KeySetKey21 {
1363   my($This) = @_;
1364   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1365 
1366   $CentralAtomSymbol = 'C';
1367   @NbrAtomSymbols = ('C', 'Q', 'Q');
1368   @NbrBondSymbols = ('=', undef, undef);
1369 
1370   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1371 }
1372 
1373 # Generate key 22 value as 1/0 indicating its presence/absence or count of its
1374 # presence in a molecule.
1375 #
1376 # Key 22 description: 3M RING
1377 #
1378 sub _Generate166KeySetKey22 {
1379   my($This) = @_;
1380   my($Molecule, $KeyValue, $RingSize, $NumOfRings);
1381 
1382   $RingSize = 3;
1383   $Molecule = $This->GetMolecule();
1384   $NumOfRings = $Molecule->GetNumOfRingsWithSize($RingSize);
1385 
1386   if ($This->{KeyBits}) {
1387     $KeyValue = $NumOfRings ? 1 : 0;
1388   }
1389   else {
1390     $KeyValue = $NumOfRings;
1391   }
1392   return $KeyValue;
1393 }
1394 
1395 # Generate key 23 value as 1/0 indicating its presence/absence or count of its
1396 # presence in a molecule.
1397 #
1398 # Key 23 description: NC(O)O
1399 #
1400 sub _Generate166KeySetKey23 {
1401   my($This) = @_;
1402   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1403 
1404   $CentralAtomSymbol = 'C';
1405   @NbrAtomSymbols = ('N', 'O', 'O');
1406   @NbrBondSymbols = (undef, undef, undef);
1407 
1408   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1409 }
1410 
1411 # Generate key 24 value as 1/0 indicating its presence/absence or count of its
1412 # presence in a molecule.
1413 #
1414 # Key 24 description: N-O
1415 #
1416 sub _Generate166KeySetKey24 {
1417   my($This) = @_;
1418   my($BondOrder) = 1;
1419 
1420   return $This->_DetectBondKeys('N', 'O', $BondOrder);
1421 }
1422 
1423 # Generate key 25 value as 1/0 indicating its presence/absence or count of its
1424 # presence in a molecule.
1425 #
1426 # Key 25 description: NC(N)N
1427 #
1428 sub _Generate166KeySetKey25 {
1429   my($This) = @_;
1430   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1431 
1432   $CentralAtomSymbol = 'C';
1433   @NbrAtomSymbols = ('N', 'N', 'N');
1434   @NbrBondSymbols = (undef, undef, undef);
1435 
1436   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1437 }
1438 
1439 # Generate key 26 value as 1/0 indicating its presence/absence or count of its
1440 # presence in a molecule.
1441 #
1442 # Key 26 description: C$=C($A)$A
1443 #
1444 sub _Generate166KeySetKey26 {
1445   my($This) = @_;
1446   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1447 
1448   $CentralAtomSymbol = 'C';
1449   @NbrAtomSymbols = ('C', 'A', 'A');
1450   @NbrBondSymbols = ('$=', '$', '$');
1451 
1452   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1453 }
1454 
1455 # Generate key 27 value as 1/0 indicating its presence/absence or count of its
1456 # presence in a molecule.
1457 #
1458 # Key 27 description: I
1459 #
1460 sub _Generate166KeySetKey27 {
1461   my($This) = @_;
1462 
1463   return $This->_DetectAtomKeys('I');
1464 }
1465 
1466 # Generate key 28 value as 1/0 indicating its presence/absence or count of its
1467 # presence in a molecule.
1468 #
1469 # Key 28 description: QCH2Q
1470 #
1471 sub _Generate166KeySetKey28 {
1472   my($This) = @_;
1473   my($CentralAtomSymbol, $CentralAtomMinHydrogenCount, $MinKeyCount, @NbrAtomSymbols, @NbrBondSymbols);
1474 
1475   $CentralAtomSymbol = 'C';
1476   @NbrAtomSymbols = ('Q', 'Q');
1477   @NbrBondSymbols = (undef, undef);
1478   $MinKeyCount = undef;
1479   $CentralAtomMinHydrogenCount = 2;
1480 
1481   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols, $MinKeyCount, $CentralAtomMinHydrogenCount);
1482 }
1483 
1484 # Generate key 29 value as 1/0 indicating its presence/absence or count of its
1485 # presence in a molecule.
1486 #
1487 # Key 29 description: P
1488 #
1489 sub _Generate166KeySetKey29 {
1490   my($This) = @_;
1491 
1492   return $This->_DetectAtomKeys('P');
1493 }
1494 
1495 # Generate key 30 value as 1/0 indicating its presence/absence or count of its
1496 # presence in a molecule.
1497 #
1498 # Key 30 description: CQ(C)(C)A
1499 #
1500 sub _Generate166KeySetKey30 {
1501   my($This) = @_;
1502   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1503 
1504   $CentralAtomSymbol = 'Q';
1505   @NbrAtomSymbols = ('C', 'C', 'C', 'A');
1506   @NbrBondSymbols = (undef, undef, undef, undef);
1507 
1508   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1509 }
1510 
1511 # Generate key 31 value as 1/0 indicating its presence/absence or count of its
1512 # presence in a molecule.
1513 #
1514 # Key 31 description: QX
1515 #
1516 sub _Generate166KeySetKey31 {
1517   my($This) = @_;
1518 
1519   return $This->_DetectBondKeys('Q', 'X');
1520 }
1521 
1522 # Generate key 32 value as 1/0 indicating its presence/absence or count of its
1523 # presence in a molecule.
1524 #
1525 # Key 32 description: CSN
1526 #
1527 sub _Generate166KeySetKey32 {
1528   my($This) = @_;
1529   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1530 
1531   $CentralAtomSymbol = 'S';
1532   @NbrAtomSymbols = ('C', 'N');
1533   @NbrBondSymbols = (undef, undef);
1534 
1535   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1536 }
1537 
1538 # Generate key 33 value as 1/0 indicating its presence/absence or count of its
1539 # presence in a molecule.
1540 #
1541 # Key 33 description: NS
1542 #
1543 sub _Generate166KeySetKey33 {
1544   my($This) = @_;
1545 
1546   return $This->_DetectBondKeys('N', 'S');
1547 }
1548 
1549 # Generate key 34 value as 1/0 indicating its presence/absence or count of its
1550 # presence in a molecule.
1551 #
1552 # Key 34 description: CH2=A
1553 #
1554 sub _Generate166KeySetKey34 {
1555   my($This) = @_;
1556   my($CentralAtomSymbol, $CentralAtomMinHydrogenCount, $MinKeyCount, @NbrAtomSymbols, @NbrBondSymbols);
1557 
1558   $CentralAtomSymbol = 'C';
1559   @NbrAtomSymbols = ('A');
1560   @NbrBondSymbols = ('=');
1561   $MinKeyCount = undef;
1562   $CentralAtomMinHydrogenCount = 2;
1563 
1564   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols, $MinKeyCount, $CentralAtomMinHydrogenCount);
1565 }
1566 
1567 # Generate key 35 value as 1/0 indicating its presence/absence or count of its
1568 # presence in a molecule.
1569 #
1570 # Key 35 description: GROUP IA (ALKALI METAL)
1571 #
1572 sub _Generate166KeySetKey35 {
1573   my($This) = @_;
1574   my($Atom, $KeyValue, $AtomicNumber, $GroupNumber);
1575 
1576   $KeyValue = 0;
1577   ATOM: for $Atom (@{$This->{Atoms}}) {
1578     $AtomicNumber = $Atom->GetAtomicNumber();
1579     if ($AtomicNumber) {
1580       $GroupNumber = PeriodicTable::GetElementGroupNumber($AtomicNumber);
1581       if ($GroupNumber =~ /^1$/) {
1582         if ($This->{KeyBits}) {
1583           $KeyValue = 1;
1584           last ATOM;
1585         }
1586         $KeyValue++;
1587       }
1588     }
1589   }
1590   return $KeyValue;
1591 }
1592 
1593 # Generate key 36 value as 1/0 indicating its presence/absence or count of its
1594 # presence in a molecule.
1595 #
1596 # Key 36 description: S HETEROCYCLE
1597 #
1598 sub _Generate166KeySetKey36 {
1599   my($This) = @_;
1600   my($MinKeyCount, $IsInRing) = (1, 1);
1601 
1602   return $This->_DetectAtomKeys('S', $MinKeyCount, $IsInRing);
1603 }
1604 
1605 # Generate key 37 value as 1/0 indicating its presence/absence or count of its
1606 # presence in a molecule.
1607 #
1608 # Key 37 description: NC(O)N
1609 #
1610 sub _Generate166KeySetKey37 {
1611   my($This) = @_;
1612   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1613 
1614   $CentralAtomSymbol = 'C';
1615   @NbrAtomSymbols = ('N', 'O', 'N');
1616   @NbrBondSymbols = (undef, undef, undef);
1617 
1618   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1619 }
1620 
1621 # Generate key 38 value as 1/0 indicating its presence/absence or count of its
1622 # presence in a molecule.
1623 #
1624 # Key 38 description: NC(C)N
1625 #
1626 sub _Generate166KeySetKey38 {
1627   my($This) = @_;
1628   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1629 
1630   $CentralAtomSymbol = 'C';
1631   @NbrAtomSymbols = ('N', 'C', 'N');
1632   @NbrBondSymbols = (undef, undef, undef);
1633 
1634   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1635 }
1636 
1637 # Generate key 39 value as 1/0 indicating its presence/absence or count of its
1638 # presence in a molecule.
1639 #
1640 # Key 39 description: OS(O)O
1641 #
1642 sub _Generate166KeySetKey39 {
1643   my($This) = @_;
1644   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1645 
1646   $CentralAtomSymbol = 'S';
1647   @NbrAtomSymbols = ('O', 'O', 'O');
1648   @NbrBondSymbols = (undef, undef, undef);
1649 
1650   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1651 }
1652 
1653 # Generate key 40 value as 1/0 indicating its presence/absence or count of its
1654 # presence in a molecule.
1655 #
1656 # Key 40 description: S-O
1657 #
1658 sub _Generate166KeySetKey40 {
1659   my($This) = @_;
1660   my($BondOrder) = 1;
1661 
1662   return $This->_DetectBondKeys('S', 'O', $BondOrder);
1663 }
1664 
1665 # Generate key 41 value as 1/0 indicating its presence/absence or count of its
1666 # presence in a molecule.
1667 #
1668 # Key 41 description: CTN
1669 #
1670 sub _Generate166KeySetKey41 {
1671   my($This) = @_;
1672   my($BondOrder) = 3;
1673 
1674   return $This->_DetectBondKeys('C', 'N', $BondOrder);
1675 }
1676 
1677 # Generate key 42 value as 1/0 indicating its presence/absence or count of its
1678 # presence in a molecule.
1679 #
1680 # Key 42 description: F
1681 #
1682 sub _Generate166KeySetKey42 {
1683   my($This) = @_;
1684 
1685   return $This->_DetectAtomKeys('F');
1686 }
1687 
1688 # Generate key 43 value as 1/0 indicating its presence/absence or count of its
1689 # presence in a molecule.
1690 #
1691 # Key 43 description: QHAQH
1692 #
1693 sub _Generate166KeySetKey43 {
1694   my($This) = @_;
1695   my($CentralAtomSymbol, $CentralAtomMinHydrogenCount, $MinKeyCount, @NbrAtomSymbols, @NbrBondSymbols, @NbrAtomMinHydrogenCount);
1696 
1697   $CentralAtomSymbol = 'A';
1698   $CentralAtomMinHydrogenCount = undef;
1699 
1700   @NbrAtomSymbols = ('Q', 'Q');
1701   @NbrBondSymbols = (undef, undef);
1702   @NbrAtomMinHydrogenCount = (1, 1);
1703 
1704   $MinKeyCount = undef;
1705 
1706   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols, $MinKeyCount, $CentralAtomMinHydrogenCount, \@NbrAtomMinHydrogenCount);
1707 }
1708 
1709 # Generate key 44 value as 1/0 indicating its presence/absence or count of its
1710 # presence in a molecule.
1711 #
1712 # Key 44 description: OTHER
1713 #
1714 sub _Generate166KeySetKey44 {
1715   my($This) = @_;
1716 
1717   return $This->_DetectAtomKeys('Z');
1718 }
1719 
1720 # Generate key 45 value as 1/0 indicating its presence/absence or count of its
1721 # presence in a molecule.
1722 #
1723 # Key 45 description: C=CN
1724 #
1725 sub _Generate166KeySetKey45 {
1726   my($This) = @_;
1727   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1728 
1729   $CentralAtomSymbol = 'C';
1730   @NbrAtomSymbols = ('C', 'N');
1731   @NbrBondSymbols = ('=', undef);
1732 
1733   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1734 }
1735 
1736 # Generate key 46 value as 1/0 indicating its presence/absence or count of its
1737 # presence in a molecule.
1738 #
1739 # Key 46 description: BR
1740 #
1741 sub _Generate166KeySetKey46 {
1742   my($This) = @_;
1743 
1744   return $This->_DetectAtomKeys('Br');
1745 }
1746 
1747 # Generate key 47 value as 1/0 indicating its presence/absence or count of its
1748 # presence in a molecule.
1749 #
1750 # Key 47 description: SAN
1751 #
1752 sub _Generate166KeySetKey47 {
1753   my($This) = @_;
1754   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1755 
1756   $CentralAtomSymbol = 'A';
1757   @NbrAtomSymbols = ('S', 'N');
1758   @NbrBondSymbols = (undef, undef);
1759 
1760   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1761 }
1762 
1763 # Generate key 48 value as 1/0 indicating its presence/absence or count of its
1764 # presence in a molecule.
1765 #
1766 # Key 48 description: OQ(O)O
1767 #
1768 sub _Generate166KeySetKey48 {
1769   my($This) = @_;
1770   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1771 
1772   $CentralAtomSymbol = 'Q';
1773   @NbrAtomSymbols = ('O', 'O', 'O');
1774   @NbrBondSymbols = (undef, undef, undef);
1775 
1776   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1777 }
1778 
1779 # Generate key 49 value as 1/0 indicating its presence/absence or count of its
1780 # presence in a molecule.
1781 #
1782 # Key 49 description: CHARGE
1783 #
1784 sub _Generate166KeySetKey49 {
1785   my($This) = @_;
1786   my($Molecule, $KeyValue);
1787 
1788   $Molecule = $This->GetMolecule();
1789   $KeyValue = $Molecule->GetFormalCharge() ? 1 : 0;
1790 
1791   return $KeyValue;
1792 }
1793 
1794 # Generate key 50 value as 1/0 indicating its presence/absence or count of its
1795 # presence in a molecule.
1796 #
1797 # Key 50 description: C=C(C)C
1798 #
1799 sub _Generate166KeySetKey50 {
1800   my($This) = @_;
1801   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1802 
1803   $CentralAtomSymbol = 'C';
1804   @NbrAtomSymbols = ('C', 'C', 'C');
1805   @NbrBondSymbols = ('=', undef, undef);
1806 
1807   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1808 }
1809 
1810 # Generate key 51 value as 1/0 indicating its presence/absence or count of its
1811 # presence in a molecule.
1812 #
1813 # Key 51 description: CSO
1814 #
1815 sub _Generate166KeySetKey51 {
1816   my($This) = @_;
1817   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1818 
1819   $CentralAtomSymbol = 'S';
1820   @NbrAtomSymbols = ('C', 'O');
1821   @NbrBondSymbols = (undef, undef);
1822 
1823   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1824 }
1825 
1826 # Generate key 52 value as 1/0 indicating its presence/absence or count of its
1827 # presence in a molecule.
1828 #
1829 # Key 52 description: NN
1830 #
1831 sub _Generate166KeySetKey52 {
1832   my($This) = @_;
1833 
1834   return $This->_DetectBondKeys('N', 'N');
1835 }
1836 
1837 # Generate key 53 value as 1/0 indicating its presence/absence or count of its
1838 # presence in a molecule.
1839 #
1840 # Key 53 description: QHAAAQH
1841 #
1842 sub _Generate166KeySetKey53 {
1843   my($This) = @_;
1844   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols, @CentralAtomsMinHydrogenCount);
1845 
1846   @CentralAtomsSymbols = ('Q', 'A', 'A', 'A', 'Q');
1847   @CentralAtomsBondSymbols = (undef, undef, undef, undef);
1848   @CentralAtomsMinHydrogenCount = (1, undef, undef, undef, 1);
1849 
1850   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols, \@CentralAtomsMinHydrogenCount);
1851 }
1852 
1853 # Generate key 54 value as 1/0 indicating its presence/absence or count of its
1854 # presence in a molecule.
1855 #
1856 # Key 54 description: QHAAQH
1857 #
1858 sub _Generate166KeySetKey54 {
1859   my($This) = @_;
1860   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols, @CentralAtomsMinHydrogenCount);
1861 
1862   @CentralAtomsSymbols = ('Q', 'A', 'A', 'Q');
1863   @CentralAtomsBondSymbols = (undef, undef, undef);
1864   @CentralAtomsMinHydrogenCount = (1, undef, undef, 1);
1865 
1866   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols, \@CentralAtomsMinHydrogenCount);
1867 }
1868 
1869 # Generate key 55 value as 1/0 indicating its presence/absence or count of its
1870 # presence in a molecule.
1871 #
1872 # Key 55 description: OSO
1873 #
1874 sub _Generate166KeySetKey55 {
1875   my($This) = @_;
1876   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1877 
1878   $CentralAtomSymbol = 'S';
1879   @NbrAtomSymbols = ('O', 'O');
1880   @NbrBondSymbols = (undef, undef);
1881 
1882   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1883 }
1884 
1885 # Generate key 56 value as 1/0 indicating its presence/absence or count of its
1886 # presence in a molecule.
1887 #
1888 # Key 56 description: ON(O)C
1889 #
1890 sub _Generate166KeySetKey56 {
1891   my($This) = @_;
1892   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1893 
1894   $CentralAtomSymbol = 'N';
1895   @NbrAtomSymbols = ('O', 'O', 'C');
1896   @NbrBondSymbols = (undef, undef, undef);
1897 
1898   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1899 }
1900 
1901 # Generate key 57 value as 1/0 indicating its presence/absence or count of its
1902 # presence in a molecule.
1903 #
1904 # Key 57 description: O HETEROCYCLE
1905 #
1906 sub _Generate166KeySetKey57 {
1907   my($This) = @_;
1908   my($MinKeyCount, $IsInRing) = (undef, 1);
1909 
1910   return $This->_DetectAtomKeys('O', $MinKeyCount, $IsInRing);
1911 }
1912 
1913 # Generate key 58 value as 1/0 indicating its presence/absence or count of its
1914 # presence in a molecule.
1915 #
1916 # Key 58 description: QSQ
1917 #
1918 sub _Generate166KeySetKey58 {
1919   my($This) = @_;
1920   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1921 
1922   $CentralAtomSymbol = 'S';
1923   @NbrAtomSymbols = ('Q', 'Q');
1924   @NbrBondSymbols = (undef, undef);
1925 
1926   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1927 }
1928 
1929 # Generate key 59 value as 1/0 indicating its presence/absence or count of its
1930 # presence in a molecule.
1931 #
1932 # Key 59 description: Snot%A%A
1933 #
1934 sub _Generate166KeySetKey59 {
1935   my($This) = @_;
1936   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1937 
1938   $CentralAtomSymbol = 'A';
1939   @NbrAtomSymbols = ('S', 'A');
1940   @NbrBondSymbols = ('not%', '%');
1941 
1942   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1943 }
1944 
1945 # Generate key 60 value as 1/0 indicating its presence/absence or count of its
1946 # presence in a molecule.
1947 #
1948 # Key 60 description: S=O
1949 #
1950 sub _Generate166KeySetKey60 {
1951   my($This) = @_;
1952   my($BondOrder) = 2;
1953 
1954   return $This->_DetectBondKeys('S', 'O', $BondOrder);
1955 }
1956 
1957 # Generate key 61 value as 1/0 indicating its presence/absence or count of its
1958 # presence in a molecule.
1959 #
1960 # Key 61 description: AS(A)A
1961 #
1962 sub _Generate166KeySetKey61 {
1963   my($This) = @_;
1964   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
1965 
1966   $CentralAtomSymbol = 'S';
1967   @NbrAtomSymbols = ('A', 'A', 'A');
1968   @NbrBondSymbols = (undef, undef, undef);
1969 
1970   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
1971 }
1972 
1973 # Generate key 62 value as 1/0 indicating its presence/absence or count of its
1974 # presence in a molecule.
1975 #
1976 # Key 62 description: A$A!A$A
1977 #
1978 sub _Generate166KeySetKey62 {
1979   my($This) = @_;
1980   my($BondAtomSymbol1, $BondAtomSymbol2, $BondSymbol, @NbrAtomsSymbols, @NbrAtomsBondSymbols);
1981 
1982   ($BondAtomSymbol1, $BondAtomSymbol2) = ('A', 'A');
1983   $BondSymbol = '!';
1984 
1985   @NbrAtomsSymbols = (['A'], ['A']);
1986   @NbrAtomsBondSymbols = (['$'], ['$']);
1987   return $This->_DetectBondNeighborhoodKeys($BondAtomSymbol1, $BondAtomSymbol2, $BondSymbol, \@NbrAtomsSymbols, \@NbrAtomsBondSymbols);
1988 }
1989 
1990 # Generate key 63 value as 1/0 indicating its presence/absence or count of its
1991 # presence in a molecule.
1992 #
1993 # Key 63 description: N=O
1994 #
1995 sub _Generate166KeySetKey63 {
1996   my($This) = @_;
1997   my($BondOrder) = 2;
1998 
1999   return $This->_DetectBondKeys('N', 'O', $BondOrder);
2000 }
2001 
2002 # Generate key 64 value as 1/0 indicating its presence/absence or count of its
2003 # presence in a molecule.
2004 #
2005 # Key 64 description: A$A!S
2006 #
2007 sub _Generate166KeySetKey64 {
2008   my($This) = @_;
2009   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2010 
2011   $CentralAtomSymbol = 'A';
2012   @NbrAtomSymbols = ('A', 'S');
2013   @NbrBondSymbols = ('$', '!');
2014 
2015   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2016 }
2017 
2018 # Generate key 65 value as 1/0 indicating its presence/absence or count of its
2019 # presence in a molecule.
2020 #
2021 # Key 65 description: C%N
2022 #
2023 sub _Generate166KeySetKey65 {
2024   my($This) = @_;
2025   my($BondSymbol) = '%';
2026 
2027   return $This->_DetectBondKeys('C', 'N', $BondSymbol);
2028 }
2029 
2030 # Generate key 66 value as 1/0 indicating its presence/absence or count of its
2031 # presence in a molecule.
2032 #
2033 # Key 66 description: CC(C)(C)A
2034 #
2035 sub _Generate166KeySetKey66 {
2036   my($This) = @_;
2037   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2038 
2039   $CentralAtomSymbol = 'C';
2040   @NbrAtomSymbols = ('C', 'C', 'C', 'A');
2041   @NbrBondSymbols = (undef, undef, undef, undef);
2042 
2043   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2044 }
2045 
2046 # Generate key 67 value as 1/0 indicating its presence/absence or count of its
2047 # presence in a molecule.
2048 #
2049 # Key 67 description: QS
2050 #
2051 sub _Generate166KeySetKey67 {
2052   my($This) = @_;
2053 
2054   return $This->_DetectBondKeys('Q', 'S');
2055 }
2056 
2057 # Generate key 68 value as 1/0 indicating its presence/absence or count of its
2058 # presence in a molecule.
2059 #
2060 # Key 68 description: QHQH (&...)
2061 #
2062 sub _Generate166KeySetKey68 {
2063   my($This) = @_;
2064   my($AtomSymbol1, $AtomSymbol2, $BondSymbol) = ('Q', 'Q', undef);
2065   my($MinKeyCount) = undef;
2066   my($Atom1MinHydrogenCount, $Atom2MinHydrogenCount) = (1, 1);
2067 
2068   return $This->_DetectBondKeys($AtomSymbol1, $AtomSymbol2, $BondSymbol, $MinKeyCount, $Atom1MinHydrogenCount, $Atom2MinHydrogenCount);
2069 }
2070 
2071 # Generate key 69 value as 1/0 indicating its presence/absence or count of its
2072 # presence in a molecule.
2073 #
2074 # Key 69 description: QQH
2075 #
2076 sub _Generate166KeySetKey69 {
2077   my($This) = @_;
2078   my($AtomSymbol1, $AtomSymbol2, $BondSymbol) = ('Q', 'Q', undef);
2079   my($MinKeyCount) = undef;
2080   my($Atom1MinHydrogenCount, $Atom2MinHydrogenCount) = (undef, 1);
2081 
2082   return $This->_DetectBondKeys($AtomSymbol1, $AtomSymbol2, $BondSymbol, $MinKeyCount, $Atom1MinHydrogenCount, $Atom2MinHydrogenCount);
2083 }
2084 
2085 # Generate key 70 value as 1/0 indicating its presence/absence or count of its
2086 # presence in a molecule.
2087 #
2088 # Key 70 description: QNQ
2089 #
2090 sub _Generate166KeySetKey70 {
2091   my($This) = @_;
2092   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2093 
2094   $CentralAtomSymbol = 'N';
2095   @NbrAtomSymbols = ('Q', 'Q');
2096   @NbrBondSymbols = (undef, undef);
2097 
2098   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2099 }
2100 
2101 # Generate key 71 value as 1/0 indicating its presence/absence or count of its
2102 # presence in a molecule.
2103 #
2104 # Key 71 description: NO
2105 #
2106 sub _Generate166KeySetKey71 {
2107   my($This) = @_;
2108 
2109   return $This->_DetectBondKeys('N', 'O');
2110 }
2111 
2112 # Generate key 72 value as 1/0 indicating its presence/absence or count of its
2113 # presence in a molecule.
2114 #
2115 # Key 72 description: OAAO
2116 #
2117 sub _Generate166KeySetKey72 {
2118   my($This) = @_;
2119   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols);
2120 
2121   @CentralAtomsSymbols = ('O', 'A', 'A', 'O');
2122   @CentralAtomsBondSymbols = (undef, undef, undef);
2123 
2124   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols);
2125 }
2126 
2127 # Generate key 73 value as 1/0 indicating its presence/absence or count of its
2128 # presence in a molecule.
2129 #
2130 # Key 73 description: S=A
2131 #
2132 sub _Generate166KeySetKey73 {
2133   my($This) = @_;
2134   my($BondOrder) = 2;
2135 
2136   return $This->_DetectBondKeys('S', 'A', $BondOrder);
2137 }
2138 
2139 # Generate key 74 value as 1/0 indicating its presence/absence or count of its
2140 # presence in a molecule.
2141 #
2142 # Key 74 description: CH3ACH3
2143 #
2144 sub _Generate166KeySetKey74 {
2145   my($This) = @_;
2146   my($CentralAtomSymbol, $CentralAtomMinHydrogenCount, $MinKeyCount, @NbrAtomSymbols, @NbrBondSymbols, @NbrAtomMinHydrogenCount);
2147 
2148   $CentralAtomSymbol = 'A';
2149   $CentralAtomMinHydrogenCount = undef;
2150 
2151   @NbrAtomSymbols = ('C', 'C');
2152   @NbrBondSymbols = (undef, undef);
2153   @NbrAtomMinHydrogenCount = (3, 3);
2154 
2155   $MinKeyCount = undef;
2156 
2157   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols, $MinKeyCount, $CentralAtomMinHydrogenCount, \@NbrAtomMinHydrogenCount);
2158 }
2159 
2160 # Generate key 75 value as 1/0 indicating its presence/absence or count of its
2161 # presence in a molecule.
2162 #
2163 # Key 75 description: A!N$A
2164 #
2165 sub _Generate166KeySetKey75 {
2166   my($This) = @_;
2167   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2168 
2169   $CentralAtomSymbol = 'N';
2170   @NbrAtomSymbols = ('A', 'A');
2171   @NbrBondSymbols = ('!', '$');
2172 
2173   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2174 }
2175 
2176 # Generate key 76 value as 1/0 indicating its presence/absence or count of its
2177 # presence in a molecule.
2178 #
2179 # Key 76 description: C=C(A)A
2180 #
2181 sub _Generate166KeySetKey76 {
2182   my($This) = @_;
2183   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2184 
2185   $CentralAtomSymbol = 'C';
2186   @NbrAtomSymbols = ('C', 'A', 'A');
2187   @NbrBondSymbols = ('=', undef, undef);
2188 
2189   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2190 }
2191 
2192 # Generate key 77 value as 1/0 indicating its presence/absence or count of its
2193 # presence in a molecule.
2194 #
2195 # Key 77 description: NAN
2196 #
2197 sub _Generate166KeySetKey77 {
2198   my($This) = @_;
2199   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2200 
2201   $CentralAtomSymbol = 'A';
2202   @NbrAtomSymbols = ('N', 'N');
2203   @NbrBondSymbols = (undef, undef);
2204 
2205   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2206 }
2207 
2208 # Generate key 78 value as 1/0 indicating its presence/absence or count of its
2209 # presence in a molecule.
2210 #
2211 # Key 78 description: C=N
2212 #
2213 sub _Generate166KeySetKey78 {
2214   my($This) = @_;
2215   my($BondOrder) = 2;
2216 
2217   return $This->_DetectBondKeys('C', 'N', $BondOrder);
2218 }
2219 
2220 # Generate key 79 value as 1/0 indicating its presence/absence or count of its
2221 # presence in a molecule.
2222 #
2223 # Key 79 description: NAAN
2224 #
2225 sub _Generate166KeySetKey79 {
2226   my($This) = @_;
2227   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols);
2228 
2229   @CentralAtomsSymbols = ('N', 'A', 'A', 'N');
2230   @CentralAtomsBondSymbols = (undef, undef, undef);
2231 
2232   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols);
2233 }
2234 
2235 # Generate key 80 value as 1/0 indicating its presence/absence or count of its
2236 # presence in a molecule.
2237 #
2238 # Key 80 description: NAAAN
2239 #
2240 sub _Generate166KeySetKey80 {
2241   my($This) = @_;
2242   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols);
2243 
2244   @CentralAtomsSymbols = ('N', 'A', 'A', 'A', 'N');
2245   @CentralAtomsBondSymbols = (undef, undef, undef, undef);
2246 
2247   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols);
2248 }
2249 
2250 # Generate key 81 value as 1/0 indicating its presence/absence or count of its
2251 # presence in a molecule.
2252 #
2253 # Key 81 description: SA(A)A
2254 #
2255 sub _Generate166KeySetKey81 {
2256   my($This) = @_;
2257   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2258 
2259   $CentralAtomSymbol = 'A';
2260   @NbrAtomSymbols = ('S', 'A', 'A');
2261   @NbrBondSymbols = (undef, undef, undef);
2262 
2263   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2264 }
2265 
2266 # Generate key 82 value as 1/0 indicating its presence/absence or count of its
2267 # presence in a molecule.
2268 #
2269 # Key 82 description: ACH2QH
2270 #
2271 sub _Generate166KeySetKey82 {
2272   my($This) = @_;
2273   my($CentralAtomSymbol, $CentralAtomMinHydrogenCount, $MinKeyCount, @NbrAtomSymbols, @NbrBondSymbols, @NbrAtomMinHydrogenCount);
2274 
2275   $CentralAtomSymbol = 'C';
2276   $CentralAtomMinHydrogenCount = 2;
2277 
2278   @NbrAtomSymbols = ('A', 'Q');
2279   @NbrBondSymbols = (undef, undef);
2280   @NbrAtomMinHydrogenCount = (undef, 1);
2281 
2282   $MinKeyCount = undef;
2283 
2284   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols, $MinKeyCount, $CentralAtomMinHydrogenCount, \@NbrAtomMinHydrogenCount);
2285 }
2286 
2287 # Generate key 83 value as 1/0 indicating its presence/absence or count of its
2288 # presence in a molecule.
2289 #
2290 # Key 83 description: QAAAA@1
2291 #
2292 sub _Generate166KeySetKey83 {
2293   my($This) = @_;
2294   my($Atom, $KeyValue, $RingSize);
2295 
2296   $RingSize = 5;
2297   $KeyValue = 0;
2298   ATOM: for $Atom (@{$This->{Atoms}}) {
2299     if ($This->_IsHetroAtom($Atom) && $Atom->IsInRingOfSize($RingSize)) {
2300       if ($This->{KeyBits}) {
2301         $KeyValue = 1;
2302         last ATOM;
2303       }
2304       $KeyValue++;
2305     }
2306   }
2307   return $KeyValue;
2308 }
2309 
2310 # Generate key 84 value as 1/0 indicating its presence/absence or count of its
2311 # presence in a molecule.
2312 #
2313 # Key 84 description: NH2
2314 #
2315 sub _Generate166KeySetKey84 {
2316   my($This) = @_;
2317   my($MinKeyCount, $IsInRing, $MinHydrogenCount) = (undef, undef, 2);
2318 
2319   return $This->_DetectAtomKeys('N', $MinKeyCount, $IsInRing, $MinHydrogenCount);
2320 }
2321 
2322 # Generate key 85 value as 1/0 indicating its presence/absence or count of its
2323 # presence in a molecule.
2324 #
2325 # Key 85 description: CN(C)C
2326 #
2327 sub _Generate166KeySetKey85 {
2328   my($This) = @_;
2329   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2330 
2331   $CentralAtomSymbol = 'N';
2332   @NbrAtomSymbols = ('C', 'C', 'C');
2333   @NbrBondSymbols = (undef, undef, undef);
2334 
2335   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2336 }
2337 
2338 # Generate key 86 value as 1/0 indicating its presence/absence or count of its
2339 # presence in a molecule.
2340 #
2341 # Key 86 description: CH2QCH2
2342 #
2343 sub _Generate166KeySetKey86 {
2344   my($This) = @_;
2345   my($CentralAtomSymbol, $CentralAtomMinHydrogenCount, $MinKeyCount, @NbrAtomSymbols, @NbrBondSymbols, @NbrAtomMinHydrogenCount);
2346 
2347   $CentralAtomSymbol = 'Q';
2348   $CentralAtomMinHydrogenCount = undef;
2349 
2350   @NbrAtomSymbols = ('C', 'C');
2351   @NbrBondSymbols = (undef, undef);
2352   @NbrAtomMinHydrogenCount = (2, 2);
2353 
2354   $MinKeyCount = undef;
2355 
2356   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols, $MinKeyCount, $CentralAtomMinHydrogenCount, \@NbrAtomMinHydrogenCount);
2357 }
2358 
2359 # Generate key 87 value as 1/0 indicating its presence/absence or count of its
2360 # presence in a molecule.
2361 #
2362 # Key 87 description: X!A$A
2363 #
2364 sub _Generate166KeySetKey87 {
2365   my($This) = @_;
2366   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2367 
2368   $CentralAtomSymbol = 'A';
2369   @NbrAtomSymbols = ('X', 'A');
2370   @NbrBondSymbols = ('!', '$');
2371 
2372   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2373 }
2374 
2375 # Generate key 88 value as 1/0 indicating its presence/absence or count of its
2376 # presence in a molecule.
2377 #
2378 # Key 88 description: S
2379 #
2380 sub _Generate166KeySetKey88 {
2381   my($This) = @_;
2382 
2383   return $This->_DetectAtomKeys('S');
2384 }
2385 
2386 # Generate key 89 value as 1/0 indicating its presence/absence or count of its
2387 # presence in a molecule.
2388 #
2389 # Key 89 description: OAAAO
2390 #
2391 sub _Generate166KeySetKey89 {
2392   my($This) = @_;
2393   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols);
2394 
2395   @CentralAtomsSymbols = ('O', 'A', 'A', 'A', 'O');
2396   @CentralAtomsBondSymbols = (undef, undef, undef, undef);
2397 
2398   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols);
2399 }
2400 
2401 # Generate key 90 value as 1/0 indicating its presence/absence or count of its
2402 # presence in a molecule.
2403 #
2404 # Key 90 description: QHAACH2A
2405 #
2406 sub _Generate166KeySetKey90 {
2407   my($This) = @_;
2408   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols, @CentralAtomsMinHydrogenCount);
2409 
2410   @CentralAtomsSymbols = ('Q', 'A', 'A', 'C', 'A');
2411   @CentralAtomsBondSymbols = (undef, undef, undef, undef);
2412   @CentralAtomsMinHydrogenCount = (1, undef, undef, 2, undef);
2413 
2414   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols, \@CentralAtomsMinHydrogenCount);
2415 }
2416 
2417 # Generate key 91 value as 1/0 indicating its presence/absence or count of its
2418 # presence in a molecule.
2419 #
2420 # Key 91 description: QHAAACH2A
2421 #
2422 sub _Generate166KeySetKey91 {
2423   my($This) = @_;
2424   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols, @CentralAtomsMinHydrogenCount);
2425 
2426   @CentralAtomsSymbols = ('Q', 'A', 'A', 'A', 'C', 'A');
2427   @CentralAtomsBondSymbols = (undef, undef, undef, undef, undef);
2428   @CentralAtomsMinHydrogenCount = (1, undef, undef, undef, 2, undef);
2429 
2430   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols, \@CentralAtomsMinHydrogenCount);
2431 }
2432 
2433 # Generate key 92 value as 1/0 indicating its presence/absence or count of its
2434 # presence in a molecule.
2435 #
2436 # Key 92 description: OC(N)C
2437 #
2438 sub _Generate166KeySetKey92 {
2439   my($This) = @_;
2440   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2441 
2442   $CentralAtomSymbol = 'C';
2443   @NbrAtomSymbols = ('O', 'N', 'C');
2444   @NbrBondSymbols = (undef, undef, undef);
2445 
2446   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2447 }
2448 
2449 # Generate key 93 value as 1/0 indicating its presence/absence or count of its
2450 # presence in a molecule.
2451 #
2452 # Key 93 description: QCH3
2453 #
2454 sub _Generate166KeySetKey93 {
2455   my($This) = @_;
2456   my($AtomSymbol1, $AtomSymbol2, $BondSymbol) = ('Q', 'C', undef);
2457   my($MinKeyCount) = undef;
2458   my($Atom1MinHydrogenCount, $Atom2MinHydrogenCount) = (undef, 3);
2459 
2460   return $This->_DetectBondKeys($AtomSymbol1, $AtomSymbol2, $BondSymbol, $MinKeyCount, $Atom1MinHydrogenCount, $Atom2MinHydrogenCount);
2461 }
2462 
2463 # Generate key 94 value as 1/0 indicating its presence/absence or count of its
2464 # presence in a molecule.
2465 #
2466 # Key 94 description: QN
2467 #
2468 sub _Generate166KeySetKey94 {
2469   my($This) = @_;
2470 
2471   return $This->_DetectBondKeys('Q', 'N');
2472 }
2473 
2474 # Generate key 95 value as 1/0 indicating its presence/absence or count of its
2475 # presence in a molecule.
2476 #
2477 # Key 95 description: NAAO
2478 #
2479 sub _Generate166KeySetKey95 {
2480   my($This) = @_;
2481   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols);
2482 
2483   @CentralAtomsSymbols = ('N', 'A', 'A', 'O');
2484   @CentralAtomsBondSymbols = (undef, undef, undef);
2485 
2486   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols);
2487 }
2488 
2489 # Generate key 96 value as 1/0 indicating its presence/absence or count of its
2490 # presence in a molecule.
2491 #
2492 # Key 96 description: 5M RING
2493 #
2494 sub _Generate166KeySetKey96 {
2495   my($This) = @_;
2496   my($Molecule, $KeyValue, $RingSize, $NumOfRings);
2497 
2498   $RingSize = 5;
2499   $Molecule = $This->GetMolecule();
2500   $NumOfRings = $Molecule->GetNumOfRingsWithSize($RingSize);
2501 
2502   if ($This->{KeyBits}) {
2503     $KeyValue = $NumOfRings ? 1 : 0;
2504   }
2505   else {
2506     $KeyValue = $NumOfRings;
2507   }
2508   return $KeyValue;
2509 }
2510 
2511 # Generate key 97 value as 1/0 indicating its presence/absence or count of its
2512 # presence in a molecule.
2513 #
2514 # Key 97 description: NAAAO
2515 #
2516 sub _Generate166KeySetKey97 {
2517   my($This) = @_;
2518   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols);
2519 
2520   @CentralAtomsSymbols = ('N', 'A', 'A', 'A', 'O');
2521   @CentralAtomsBondSymbols = (undef, undef, undef, undef);
2522 
2523   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols);
2524 }
2525 
2526 # Generate key 98 value as 1/0 indicating its presence/absence or count of its
2527 # presence in a molecule.
2528 #
2529 # Key 98 description: QAAAAA@1
2530 #
2531 sub _Generate166KeySetKey98 {
2532   my($This) = @_;
2533   my($Atom, $KeyValue, $RingSize);
2534 
2535   $RingSize = 6;
2536   $KeyValue = 0;
2537   ATOM: for $Atom (@{$This->{Atoms}}) {
2538     if ($This->_IsHetroAtom($Atom) && $Atom->IsInRingOfSize($RingSize)) {
2539       if ($This->{KeyBits}) {
2540         $KeyValue = 1;
2541         last ATOM;
2542       }
2543       $KeyValue++;
2544     }
2545   }
2546   return $KeyValue;
2547 }
2548 
2549 # Generate key 99 value as 1/0 indicating its presence/absence or count of its
2550 # presence in a molecule.
2551 #
2552 # Key 99 description: C=C
2553 #
2554 sub _Generate166KeySetKey99 {
2555   my($This) = @_;
2556   my($BondOrder) = 2;
2557 
2558   return $This->_DetectBondKeys('C', 'C', $BondOrder);
2559 }
2560 
2561 # Generate key 100 value as 1/0 indicating its presence/absence or count of its
2562 # presence in a molecule.
2563 #
2564 # Key 100 description: ACH2N
2565 #
2566 sub _Generate166KeySetKey100 {
2567   my($This) = @_;
2568   my($CentralAtomSymbol, $CentralAtomMinHydrogenCount, $MinKeyCount, @NbrAtomSymbols, @NbrBondSymbols);
2569 
2570   $CentralAtomSymbol = 'C';
2571   $CentralAtomMinHydrogenCount = 2;
2572 
2573   @NbrAtomSymbols = ('A', 'N');
2574   @NbrBondSymbols = (undef, undef);
2575 
2576   $MinKeyCount = undef;
2577 
2578   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols, $MinKeyCount, $CentralAtomMinHydrogenCount);
2579 }
2580 
2581 # Generate key 101 value as 1/0 indicating its presence/absence or count of its
2582 # presence in a molecule.
2583 #
2584 # Key 101 description: 8M RING
2585 #
2586 sub _Generate166KeySetKey101 {
2587   my($This) = @_;
2588   my($Molecule, $KeyValue, $RingSize, $NumOfRings);
2589 
2590   $RingSize = 8;
2591   $Molecule = $This->GetMolecule();
2592   $NumOfRings = $Molecule->GetNumOfRingsWithSize($RingSize);
2593 
2594   if ($This->{KeyBits}) {
2595     $KeyValue = $NumOfRings ? 1 : 0;
2596   }
2597   else {
2598     $KeyValue = $NumOfRings;
2599   }
2600   return $KeyValue;
2601 }
2602 
2603 # Generate key 102 value as 1/0 indicating its presence/absence or count of its
2604 # presence in a molecule.
2605 #
2606 # Key 102 description: QO
2607 #
2608 sub _Generate166KeySetKey102 {
2609   my($This) = @_;
2610 
2611   return $This->_DetectBondKeys('Q', 'O');
2612 }
2613 
2614 # Generate key 103 value as 1/0 indicating its presence/absence or count of its
2615 # presence in a molecule.
2616 #
2617 # Key 103 description: CL
2618 #
2619 sub _Generate166KeySetKey103 {
2620   my($This) = @_;
2621 
2622   return $This->_DetectAtomKeys('Cl');
2623 }
2624 
2625 # Generate key 104 value as 1/0 indicating its presence/absence or count of its
2626 # presence in a molecule.
2627 #
2628 # Key 104 description: QHACH2A
2629 #
2630 sub _Generate166KeySetKey104 {
2631   my($This) = @_;
2632   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols, @CentralAtomsMinHydrogenCount);
2633 
2634   @CentralAtomsSymbols = ('Q', 'A', 'C', 'A');
2635   @CentralAtomsBondSymbols = (undef, undef, undef);
2636   @CentralAtomsMinHydrogenCount = (1, undef, 2, undef);
2637 
2638   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols, \@CentralAtomsMinHydrogenCount);
2639 }
2640 
2641 # Generate key 105 value as 1/0 indicating its presence/absence or count of its
2642 # presence in a molecule.
2643 #
2644 # Key 105 description: A$A($A)$A
2645 #
2646 sub _Generate166KeySetKey105 {
2647   my($This) = @_;
2648   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2649 
2650   $CentralAtomSymbol = 'A';
2651   @NbrAtomSymbols = ('A', 'A', 'A');
2652   @NbrBondSymbols = ('$', '$', '$');
2653 
2654   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2655 }
2656 
2657 # Generate key 106 value as 1/0 indicating its presence/absence or count of its
2658 # presence in a molecule.
2659 #
2660 # Key 106 description: QA(Q)Q
2661 #
2662 sub _Generate166KeySetKey106 {
2663   my($This) = @_;
2664   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2665 
2666   $CentralAtomSymbol = 'A';
2667   @NbrAtomSymbols = ('Q', 'Q', 'Q');
2668   @NbrBondSymbols = (undef, undef, undef);
2669 
2670   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2671 }
2672 
2673 # Generate key 107 value as 1/0 indicating its presence/absence or count of its
2674 # presence in a molecule.
2675 #
2676 # Key 107 description: XA(A)A
2677 #
2678 sub _Generate166KeySetKey107 {
2679   my($This) = @_;
2680   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2681 
2682   $CentralAtomSymbol = 'A';
2683   @NbrAtomSymbols = ('X', 'A', 'A');
2684   @NbrBondSymbols = (undef, undef, undef);
2685 
2686   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2687 }
2688 
2689 # Generate key 108 value as 1/0 indicating its presence/absence or count of its
2690 # presence in a molecule.
2691 #
2692 # Key 108 description: CH3AAACH2A
2693 #
2694 sub _Generate166KeySetKey108 {
2695   my($This) = @_;
2696   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols, @CentralAtomsMinHydrogenCount);
2697 
2698   @CentralAtomsSymbols = ('C', 'A', 'A', 'A', 'C', 'A');
2699   @CentralAtomsBondSymbols = (undef, undef, undef, undef, undef);
2700   @CentralAtomsMinHydrogenCount = (3, undef, undef, undef, 1, undef);
2701 
2702   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols, \@CentralAtomsMinHydrogenCount);
2703 }
2704 
2705 # Generate key 109 value as 1/0 indicating its presence/absence or count of its
2706 # presence in a molecule.
2707 #
2708 # Key 109 description: ACH2O
2709 #
2710 sub _Generate166KeySetKey109 {
2711   my($This) = @_;
2712   my($CentralAtomSymbol, $CentralAtomMinHydrogenCount, $MinKeyCount, @NbrAtomSymbols, @NbrBondSymbols);
2713 
2714   $CentralAtomSymbol = 'C';
2715   $CentralAtomMinHydrogenCount = 2;
2716 
2717   @NbrAtomSymbols = ('A', 'O');
2718   @NbrBondSymbols = (undef, undef);
2719 
2720   $MinKeyCount = undef;
2721 
2722   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols, $MinKeyCount, $CentralAtomMinHydrogenCount);
2723 }
2724 
2725 # Generate key 110 value as 1/0 indicating its presence/absence or count of its
2726 # presence in a molecule.
2727 #
2728 # Key 110 description: NCO
2729 #
2730 sub _Generate166KeySetKey110 {
2731   my($This) = @_;
2732   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2733 
2734   $CentralAtomSymbol = 'C';
2735   @NbrAtomSymbols = ('N', 'O');
2736   @NbrBondSymbols = (undef, undef);
2737 
2738   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2739 }
2740 
2741 # Generate key 111 value as 1/0 indicating its presence/absence or count of its
2742 # presence in a molecule.
2743 #
2744 # Key 111 description: NACH2A
2745 #
2746 sub _Generate166KeySetKey111 {
2747   my($This) = @_;
2748   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols, @CentralAtomsMinHydrogenCount);
2749 
2750   @CentralAtomsSymbols = ('N', 'A', 'C', 'A');
2751   @CentralAtomsBondSymbols = (undef, undef, undef);
2752   @CentralAtomsMinHydrogenCount = (undef, undef, 2, undef);
2753 
2754   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols, \@CentralAtomsMinHydrogenCount);
2755 }
2756 
2757 # Generate key 112 value as 1/0 indicating its presence/absence or count of its
2758 # presence in a molecule.
2759 #
2760 # Key 112 description: AA(A)(A)A
2761 #
2762 sub _Generate166KeySetKey112 {
2763   my($This) = @_;
2764   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2765 
2766   $CentralAtomSymbol = 'A';
2767   @NbrAtomSymbols = ('A', 'A', 'A', 'A');
2768   @NbrBondSymbols = (undef, undef, undef, undef);
2769 
2770   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2771 }
2772 
2773 # Generate key 113 value as 1/0 indicating its presence/absence or count of its
2774 # presence in a molecule.
2775 #
2776 # Key 113 description: Onot%A%A
2777 #
2778 sub _Generate166KeySetKey113 {
2779   my($This) = @_;
2780   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2781 
2782   $CentralAtomSymbol = 'A';
2783   @NbrAtomSymbols = ('O', 'A');
2784   @NbrBondSymbols = ('not%', '%');
2785 
2786   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2787 }
2788 
2789 # Generate key 114 value as 1/0 indicating its presence/absence or count of its
2790 # presence in a molecule.
2791 #
2792 # Key 114 description: CH3CH2A
2793 #
2794 sub _Generate166KeySetKey114 {
2795   my($This) = @_;
2796   my($CentralAtomSymbol, $CentralAtomMinHydrogenCount, $MinKeyCount, @NbrAtomSymbols, @NbrBondSymbols, @NbrAtomMinHydrogenCount);
2797 
2798   $CentralAtomSymbol = 'C';
2799   $CentralAtomMinHydrogenCount = 2;
2800 
2801   @NbrAtomSymbols = ('C', 'A');
2802   @NbrBondSymbols = (undef, undef);
2803   @NbrAtomMinHydrogenCount = (3, undef);
2804 
2805   $MinKeyCount = undef;
2806 
2807   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols, $MinKeyCount, $CentralAtomMinHydrogenCount, \@NbrAtomMinHydrogenCount);
2808 }
2809 
2810 # Generate key 115 value as 1/0 indicating its presence/absence or count of its
2811 # presence in a molecule.
2812 #
2813 # Key 115 description: CH3ACH2A
2814 #
2815 sub _Generate166KeySetKey115 {
2816   my($This) = @_;
2817   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols, @CentralAtomsMinHydrogenCount);
2818 
2819   @CentralAtomsSymbols = ('C', 'A', 'C', 'A');
2820   @CentralAtomsBondSymbols = (undef, undef, undef);
2821   @CentralAtomsMinHydrogenCount = (3, undef, 2, undef);
2822 
2823   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols, \@CentralAtomsMinHydrogenCount);
2824 }
2825 
2826 # Generate key 116 value as 1/0 indicating its presence/absence or count of its
2827 # presence in a molecule.
2828 #
2829 # Key 116 description: CH3AACH2A
2830 #
2831 sub _Generate166KeySetKey116 {
2832   my($This) = @_;
2833   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols, @CentralAtomsMinHydrogenCount);
2834 
2835   @CentralAtomsSymbols = ('C', 'A', 'A', 'C', 'A');
2836   @CentralAtomsBondSymbols = (undef, undef, undef, undef);
2837   @CentralAtomsMinHydrogenCount = (3, undef, undef, 2, undef);
2838 
2839   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols, \@CentralAtomsMinHydrogenCount);
2840 }
2841 
2842 # Generate key 117 value as 1/0 indicating its presence/absence or count of its
2843 # presence in a molecule.
2844 #
2845 # Key 117 description: NAO
2846 #
2847 sub _Generate166KeySetKey117 {
2848   my($This) = @_;
2849   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2850 
2851   $CentralAtomSymbol = 'A';
2852   @NbrAtomSymbols = ('N', 'O');
2853   @NbrBondSymbols = (undef, undef);
2854 
2855   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2856 }
2857 
2858 # Generate key 118 value as 1/0 indicating its presence/absence or count of its
2859 # presence in a molecule.
2860 #
2861 # Key 118 description: ACH2CH2A > 1
2862 #
2863 sub _Generate166KeySetKey118 {
2864   my($This) = @_;
2865   my($MinKeyCount, @CentralAtomsSymbols, @CentralAtomsBondSymbols, @CentralAtomsMinHydrogenCount);
2866 
2867   $MinKeyCount = 2;
2868   @CentralAtomsSymbols = ('A', 'C', 'C', 'A');
2869   @CentralAtomsBondSymbols = (undef, undef, undef);
2870   @CentralAtomsMinHydrogenCount = (undef, 2, 2, undef);
2871 
2872   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols, \@CentralAtomsMinHydrogenCount, $MinKeyCount);
2873 }
2874 
2875 # Generate key 119 value as 1/0 indicating its presence/absence or count of its
2876 # presence in a molecule.
2877 #
2878 # Key 119 description: N=A
2879 #
2880 sub _Generate166KeySetKey119 {
2881   my($This) = @_;
2882   my($BondOrder) = 2;
2883 
2884   return $This->_DetectBondKeys('N', 'A', $BondOrder);
2885 }
2886 
2887 # Generate key 120 value as 1/0 indicating its presence/absence or count of its
2888 # presence in a molecule.
2889 #
2890 # Key 120 description: HETEROCYCLIC ATOM > 1 (&...)
2891 #
2892 sub _Generate166KeySetKey120 {
2893   my($This) = @_;
2894   my($MinKeyCount, $IsInRing) = (2, 1);
2895 
2896   return $This->_DetectAtomKeys('Q', $MinKeyCount, $IsInRing);
2897 }
2898 
2899 # Generate key 121 value as 1/0 indicating its presence/absence or count of its
2900 # presence in a molecule.
2901 #
2902 # Key 121 description: N HETEROCYCLE
2903 #
2904 sub _Generate166KeySetKey121 {
2905   my($This) = @_;
2906   my($MinKeyCount, $IsInRing) = (undef, 1);
2907 
2908   return $This->_DetectAtomKeys('N', $MinKeyCount, $IsInRing);
2909 }
2910 
2911 # Generate key 122 value as 1/0 indicating its presence/absence or count of its
2912 # presence in a molecule.
2913 #
2914 # Key 122 description: AN(A)A
2915 #
2916 sub _Generate166KeySetKey122 {
2917   my($This) = @_;
2918   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2919 
2920   $CentralAtomSymbol = 'N';
2921   @NbrAtomSymbols = ('A', 'A', 'A');
2922   @NbrBondSymbols = (undef, undef, undef);
2923 
2924   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2925 }
2926 
2927 # Generate key 123 value as 1/0 indicating its presence/absence or count of its
2928 # presence in a molecule.
2929 #
2930 # Key 123 description: OCO
2931 #
2932 sub _Generate166KeySetKey123 {
2933   my($This) = @_;
2934   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2935 
2936   $CentralAtomSymbol = 'C';
2937   @NbrAtomSymbols = ('O', 'O');
2938   @NbrBondSymbols = (undef, undef);
2939 
2940   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2941 }
2942 
2943 # Generate key 124 value as 1/0 indicating its presence/absence or count of its
2944 # presence in a molecule.
2945 #
2946 # Key 124 description: QQ
2947 #
2948 sub _Generate166KeySetKey124 {
2949   my($This) = @_;
2950 
2951   return $This->_DetectBondKeys('Q', 'Q');
2952 }
2953 
2954 # Generate key 125 value as 1/0 indicating its presence/absence or count of its
2955 # presence in a molecule.
2956 #
2957 # Key 125 description: AROMATIC RING > 1
2958 #
2959 sub _Generate166KeySetKey125 {
2960   my($This) = @_;
2961   my($Molecule, $NumOfAromaticRings, $KeyValue);
2962 
2963   $Molecule = $This->GetMolecule();
2964   $NumOfAromaticRings = $Molecule->GetNumOfAromaticRings();
2965 
2966   if ($This->{KeyBits}) {
2967     $KeyValue = ($NumOfAromaticRings > 1) ? 1 : 0;
2968   }
2969   else {
2970     $KeyValue = $NumOfAromaticRings;
2971   }
2972   return $KeyValue;
2973 }
2974 
2975 # Generate key 126 value as 1/0 indicating its presence/absence or count of its
2976 # presence in a molecule.
2977 #
2978 # Key 126 description: A!O!A
2979 #
2980 sub _Generate166KeySetKey126 {
2981   my($This) = @_;
2982   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
2983 
2984   $CentralAtomSymbol = 'O';
2985   @NbrAtomSymbols = ('A', 'A');
2986   @NbrBondSymbols = ('!', '!');
2987 
2988   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
2989 }
2990 
2991 # Generate key 127 value as 1/0 indicating its presence/absence or count of its
2992 # presence in a molecule.
2993 #
2994 # Key 127 description: A$A!O > 1 (&...)
2995 #
2996 sub _Generate166KeySetKey127 {
2997   my($This) = @_;
2998   my($CentralAtomSymbol, $MinKeyCount, @NbrAtomSymbols, @NbrBondSymbols);
2999 
3000   $CentralAtomSymbol = 'A';
3001   @NbrAtomSymbols = ('A', 'O');
3002   @NbrBondSymbols = ('$', '!');
3003   $MinKeyCount = 2;
3004 
3005   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols, $MinKeyCount);
3006 }
3007 
3008 # Generate key 128 value as 1/0 indicating its presence/absence or count of its
3009 # presence in a molecule.
3010 #
3011 # Key 128 description: ACH2AAACH2A
3012 #
3013 sub _Generate166KeySetKey128 {
3014   my($This) = @_;
3015   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols, @CentralAtomsMinHydrogenCount);
3016 
3017   @CentralAtomsSymbols = ('A', 'C', 'A', 'A', 'A', 'C', 'A');
3018   @CentralAtomsBondSymbols = (undef, undef, undef, undef, undef, undef);
3019   @CentralAtomsMinHydrogenCount = (undef, 2, undef, undef, undef, 2, undef);
3020 
3021   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols, \@CentralAtomsMinHydrogenCount);
3022 }
3023 
3024 # Generate key 129 value as 1/0 indicating its presence/absence or count of its
3025 # presence in a molecule.
3026 #
3027 # Key 129 description: ACH2AACH2A
3028 #
3029 sub _Generate166KeySetKey129 {
3030   my($This) = @_;
3031   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols, @CentralAtomsMinHydrogenCount);
3032 
3033   @CentralAtomsSymbols = ('A', 'C', 'A', 'A', 'C', 'A');
3034   @CentralAtomsBondSymbols = (undef, undef, undef, undef, undef);
3035   @CentralAtomsMinHydrogenCount = (undef, 2, undef, undef, 2, undef);
3036 
3037   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols, \@CentralAtomsMinHydrogenCount);
3038 }
3039 
3040 # Generate key 130 value as 1/0 indicating its presence/absence or count of its
3041 # presence in a molecule.
3042 #
3043 # Key 130 description: QQ > 1 (&...)
3044 #
3045 sub _Generate166KeySetKey130 {
3046   my($This) = @_;
3047   my($BondOrder, $MinKeyCount) = (undef, 2);
3048 
3049   return $This->_DetectBondKeys('Q', 'Q', $BondOrder, $MinKeyCount);
3050 }
3051 
3052 # Generate key 131 value as 1/0 indicating its presence/absence or count of its
3053 # presence in a molecule.
3054 #
3055 # Key 131 description: QH > 1
3056 #
3057 sub _Generate166KeySetKey131 {
3058   my($This) = @_;
3059   my($MinKeyCount, $IsInRing, $MinHydrogenCount) = (2, undef, 1);
3060 
3061   return $This->_DetectAtomKeys('Q', $MinKeyCount, $IsInRing, $MinHydrogenCount);
3062 }
3063 
3064 # Generate key 132 value as 1/0 indicating its presence/absence or count of its
3065 # presence in a molecule.
3066 #
3067 # Key 132 description: OACH2A
3068 #
3069 sub _Generate166KeySetKey132 {
3070   my($This) = @_;
3071   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols, @CentralAtomsMinHydrogenCount);
3072 
3073   @CentralAtomsSymbols = ('O', 'A', 'C', 'A');
3074   @CentralAtomsBondSymbols = (undef, undef, undef);
3075   @CentralAtomsMinHydrogenCount = (undef, undef, 2, undef);
3076 
3077   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols, \@CentralAtomsMinHydrogenCount);
3078 }
3079 
3080 # Generate key 133 value as 1/0 indicating its presence/absence or count of its
3081 # presence in a molecule.
3082 #
3083 # Key 133 description: A$A!N
3084 #
3085 sub _Generate166KeySetKey133 {
3086   my($This) = @_;
3087   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
3088 
3089   $CentralAtomSymbol = 'A';
3090   @NbrAtomSymbols = ('A', 'N');
3091   @NbrBondSymbols = ('$', '!');
3092 
3093   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
3094 }
3095 
3096 # Generate key 134 value as 1/0 indicating its presence/absence or count of its
3097 # presence in a molecule.
3098 #
3099 # Key 134 description: X (HALOGEN)
3100 #
3101 sub _Generate166KeySetKey134 {
3102   my($This) = @_;
3103 
3104   return $This->_DetectAtomKeys('X');
3105 }
3106 
3107 # Generate key 135 value as 1/0 indicating its presence/absence or count of its
3108 # presence in a molecule.
3109 #
3110 # Key 135 description: Nnot%A%A
3111 #
3112 sub _Generate166KeySetKey135 {
3113   my($This) = @_;
3114   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
3115 
3116   $CentralAtomSymbol = 'A';
3117   @NbrAtomSymbols = ('N', 'A');
3118   @NbrBondSymbols = ('not%', '%');
3119 
3120   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
3121 }
3122 
3123 # Generate key 136 value as 1/0 indicating its presence/absence or count of its
3124 # presence in a molecule.
3125 #
3126 # Key 136 description: O=A > 1
3127 #
3128 sub _Generate166KeySetKey136 {
3129   my($This) = @_;
3130   my($BondOrder, $MinKeyCount) = (2, 2);
3131 
3132   return $This->_DetectBondKeys('O', 'A', $BondOrder, $MinKeyCount);
3133 }
3134 
3135 # Generate key 137 value as 1/0 indicating its presence/absence or count of its
3136 # presence in a molecule.
3137 #
3138 # Key 137 description: HETEROCYCLE
3139 #
3140 sub _Generate166KeySetKey137 {
3141   my($This) = @_;
3142   my($MinKeyCount, $IsInRing) = (1, 1);
3143 
3144   return $This->_DetectAtomKeys('Q', $MinKeyCount, $IsInRing);
3145 }
3146 
3147 # Generate key 138 value as 1/0 indicating its presence/absence or count of its
3148 # presence in a molecule.
3149 #
3150 # Key 138 description: QCH2A > 1 (&...)
3151 #
3152 sub _Generate166KeySetKey138 {
3153   my($This) = @_;
3154   my($CentralAtomSymbol, $CentralAtomMinHydrogenCount, $MinKeyCount, @NbrAtomSymbols, @NbrBondSymbols);
3155 
3156   $CentralAtomSymbol = 'C';
3157   @NbrAtomSymbols = ('Q', 'A');
3158   @NbrBondSymbols = (undef, undef);
3159   $MinKeyCount = 2;
3160   $CentralAtomMinHydrogenCount = 2;
3161 
3162   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols, $MinKeyCount, $CentralAtomMinHydrogenCount);
3163 }
3164 
3165 # Generate key 139 value as 1/0 indicating its presence/absence or count of its
3166 # presence in a molecule.
3167 #
3168 # Key 139 description: OH
3169 #
3170 sub _Generate166KeySetKey139 {
3171   my($This) = @_;
3172   my($MinKeyCount, $IsInRing, $MinHydrogenCount) = (undef, undef, 1);
3173 
3174   return $This->_DetectAtomKeys('O', $MinKeyCount, $IsInRing, $MinHydrogenCount);
3175 }
3176 
3177 # Generate key 140 value as 1/0 indicating its presence/absence or count of its
3178 # presence in a molecule.
3179 #
3180 # Key 140 description: O > 3 (&...)
3181 #
3182 sub _Generate166KeySetKey140 {
3183   my($This) = @_;
3184   my($MinKeyCount) = 4;
3185 
3186   return $This->_DetectAtomKeys('O', $MinKeyCount);
3187 }
3188 
3189 # Generate key 141 value as 1/0 indicating its presence/absence or count of its
3190 # presence in a molecule.
3191 #
3192 # Key 141 description: CH3 > 2 (&...)
3193 #
3194 sub _Generate166KeySetKey141 {
3195   my($This) = @_;
3196   my($MinKeyCount, $IsInRing, $MinHydrogenCount) = (3, undef, 3);
3197 
3198   return $This->_DetectAtomKeys('C', $MinKeyCount, $IsInRing, $MinHydrogenCount);
3199 }
3200 
3201 # Generate key 142 value as 1/0 indicating its presence/absence or count of its
3202 # presence in a molecule.
3203 #
3204 # Key 142 description: N > 1
3205 #
3206 sub _Generate166KeySetKey142 {
3207   my($This) = @_;
3208   my($MinKeyCount) = 2;
3209 
3210   return $This->_DetectAtomKeys('N', $MinKeyCount);
3211 }
3212 
3213 # Generate key 143 value as 1/0 indicating its presence/absence or count of its
3214 # presence in a molecule.
3215 #
3216 # Key 143 description: A$A!O
3217 #
3218 sub _Generate166KeySetKey143 {
3219   my($This) = @_;
3220   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
3221 
3222   $CentralAtomSymbol = 'A';
3223   @NbrAtomSymbols = ('A', 'O');
3224   @NbrBondSymbols = ('$', '!');
3225 
3226   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
3227 }
3228 
3229 # Generate key 144 value as 1/0 indicating its presence/absence or count of its
3230 # presence in a molecule.
3231 #
3232 # Key 144 description: Anot%A%Anot%A
3233 #
3234 sub _Generate166KeySetKey144 {
3235   my($This) = @_;
3236   my($BondAtomSymbol1, $BondAtomSymbol2, $BondSymbol, @NbrAtomsSymbols, @NbrAtomsBondSymbols);
3237 
3238   ($BondAtomSymbol1, $BondAtomSymbol2) = ('A', 'A');
3239   $BondSymbol = '%';
3240 
3241   @NbrAtomsSymbols = (['A'], ['A']);
3242   @NbrAtomsBondSymbols = (['not%'], ['not%']);
3243   return $This->_DetectBondNeighborhoodKeys($BondAtomSymbol1, $BondAtomSymbol2, $BondSymbol, \@NbrAtomsSymbols, \@NbrAtomsBondSymbols);
3244 }
3245 
3246 # Generate key 145 value as 1/0 indicating its presence/absence or count of its
3247 # presence in a molecule.
3248 #
3249 # Key 145 description: 6M RING > 1
3250 #
3251 sub _Generate166KeySetKey145 {
3252   my($This) = @_;
3253   my($Molecule, $KeyValue, $RingSize, $NumOfRings);
3254 
3255   $RingSize = 6;
3256   $Molecule = $This->GetMolecule();
3257   $NumOfRings = $Molecule->GetNumOfRingsWithSize($RingSize);
3258 
3259   if ($This->{KeyBits}) {
3260     $KeyValue = ($NumOfRings > 1) ? 1 : 0;
3261   }
3262   else {
3263     $KeyValue = $NumOfRings;
3264   }
3265   return $KeyValue;
3266 }
3267 
3268 # Generate key 146 value as 1/0 indicating its presence/absence or count of its
3269 # presence in a molecule.
3270 #
3271 # Key 146 description: O > 2
3272 #
3273 sub _Generate166KeySetKey146 {
3274   my($This) = @_;
3275   my($MinKeyCount) = 3;
3276 
3277   return $This->_DetectAtomKeys('O', $MinKeyCount);
3278 }
3279 
3280 # Generate key 147 value as 1/0 indicating its presence/absence or count of its
3281 # presence in a molecule.
3282 #
3283 # Key 147 description: ACH2CH2A
3284 #
3285 sub _Generate166KeySetKey147 {
3286   my($This) = @_;
3287   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols, @CentralAtomsMinHydrogenCount);
3288 
3289   @CentralAtomsSymbols = ('A', 'C', 'C', 'A');
3290   @CentralAtomsBondSymbols = (undef, undef, undef);
3291   @CentralAtomsMinHydrogenCount = (undef, 2, 2, undef);
3292 
3293   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols, \@CentralAtomsMinHydrogenCount);
3294 }
3295 
3296 # Generate key 148 value as 1/0 indicating its presence/absence or count of its
3297 # presence in a molecule.
3298 #
3299 # Key 148 description: AQ(A)A
3300 #
3301 sub _Generate166KeySetKey148 {
3302   my($This) = @_;
3303   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
3304 
3305   $CentralAtomSymbol = 'Q';
3306   @NbrAtomSymbols = ('A', 'A', 'A');
3307   @NbrBondSymbols = (undef, undef, undef);
3308 
3309   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
3310 }
3311 
3312 # Generate key 149 value as 1/0 indicating its presence/absence or count of its
3313 # presence in a molecule.
3314 #
3315 # Key 149 description: CH3 > 1
3316 #
3317 sub _Generate166KeySetKey149 {
3318   my($This) = @_;
3319   my($MinKeyCount, $IsInRing, $MinHydrogenCount) = (2, undef, 3);
3320 
3321   return $This->_DetectAtomKeys('C', $MinKeyCount, $IsInRing, $MinHydrogenCount);
3322 }
3323 
3324 # Generate key 150 value as 1/0 indicating its presence/absence or count of its
3325 # presence in a molecule.
3326 #
3327 # Key 150 description: A!A$A!A
3328 #
3329 sub _Generate166KeySetKey150 {
3330   my($This) = @_;
3331   my(@CentralAtomsSymbols, @CentralAtomsBondSymbols);
3332 
3333   @CentralAtomsSymbols = ('A', 'A', 'A', 'A');
3334   @CentralAtomsBondSymbols = ('!', '$', '!');
3335 
3336   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols);
3337 }
3338 
3339 # Generate key 151 value as 1/0 indicating its presence/absence or count of its
3340 # presence in a molecule.
3341 #
3342 # Key 151 description: NH
3343 #
3344 sub _Generate166KeySetKey151 {
3345   my($This) = @_;
3346   my($MinKeyCount, $IsInRing, $MinHydrogenCount) = (undef, undef, 1);
3347 
3348   return $This->_DetectAtomKeys('N', $MinKeyCount, $IsInRing, $MinHydrogenCount);
3349 }
3350 
3351 # Generate key 152 value as 1/0 indicating its presence/absence or count of its
3352 # presence in a molecule.
3353 #
3354 # Key 152 description: OC(C)C
3355 #
3356 sub _Generate166KeySetKey152 {
3357   my($This) = @_;
3358   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
3359 
3360   $CentralAtomSymbol = 'C';
3361   @NbrAtomSymbols = ('O', 'C', 'C');
3362   @NbrBondSymbols = (undef, undef, undef);
3363 
3364   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
3365 }
3366 
3367 # Generate key 153 value as 1/0 indicating its presence/absence or count of its
3368 # presence in a molecule.
3369 #
3370 # Key 153 description: QCH2A
3371 #
3372 sub _Generate166KeySetKey153 {
3373   my($This) = @_;
3374   my($CentralAtomSymbol, $CentralAtomMinHydrogenCount, $MinKeyCount, @NbrAtomSymbols, @NbrBondSymbols);
3375 
3376   $CentralAtomSymbol = 'C';
3377   @NbrAtomSymbols = ('Q', 'A');
3378   @NbrBondSymbols = (undef, undef);
3379   $MinKeyCount = undef;
3380   $CentralAtomMinHydrogenCount = 2;
3381 
3382   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols, $MinKeyCount, $CentralAtomMinHydrogenCount);
3383 }
3384 
3385 # Generate key 154 value as 1/0 indicating its presence/absence or count of its
3386 # presence in a molecule.
3387 #
3388 # Key 154 description: C=O
3389 #
3390 sub _Generate166KeySetKey154 {
3391   my($This) = @_;
3392   my($BondOrder) = 2;
3393 
3394   return $This->_DetectBondKeys('C', 'O', $BondOrder);
3395 }
3396 
3397 # Generate key 155 value as 1/0 indicating its presence/absence or count of its
3398 # presence in a molecule.
3399 #
3400 # Key 155 description: A!CH2!A
3401 #
3402 sub _Generate166KeySetKey155 {
3403   my($This) = @_;
3404   my($CentralAtomSymbol, $CentralAtomMinHydrogenCount, $MinKeyCount, @NbrAtomSymbols, @NbrBondSymbols);
3405 
3406   $CentralAtomSymbol = 'C';
3407   @NbrAtomSymbols = ('A', 'A');
3408   @NbrBondSymbols = ('!', '!');
3409   $MinKeyCount = undef;
3410   $CentralAtomMinHydrogenCount = 2;
3411 
3412   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols, $MinKeyCount, $CentralAtomMinHydrogenCount);
3413 }
3414 
3415 # Generate key 156 value as 1/0 indicating its presence/absence or count of its
3416 # presence in a molecule.
3417 #
3418 # Key 156 description: NA(A)A
3419 #
3420 sub _Generate166KeySetKey156 {
3421   my($This) = @_;
3422   my($MinKeyCount, @CentralAtomsSymbols, @CentralAtomsBondSymbols, @CentralAtomsMinHydrogenCount, @CentralAtomNbrsAtomSymbols, @CentralAtomNbrsBondSymbols);
3423 
3424   @CentralAtomsSymbols = ('N', 'A', 'A');
3425   @CentralAtomsBondSymbols = (undef, undef);
3426   @CentralAtomsMinHydrogenCount = (undef, undef, undef);
3427 
3428   @CentralAtomNbrsAtomSymbols = (undef, ['A'], undef);
3429   @CentralAtomNbrsBondSymbols = (undef, undef, undef);
3430   $MinKeyCount = undef;
3431 
3432   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, \@CentralAtomsBondSymbols, \@CentralAtomsMinHydrogenCount, $MinKeyCount, \@CentralAtomNbrsAtomSymbols, \@CentralAtomNbrsBondSymbols);
3433 }
3434 
3435 # Generate key 157 value as 1/0 indicating its presence/absence or count of its
3436 # presence in a molecule.
3437 #
3438 # Key 157 description: C-O
3439 #
3440 sub _Generate166KeySetKey157 {
3441   my($This) = @_;
3442   my($BondOrder) = 1;
3443 
3444   return $This->_DetectBondKeys('C', 'O', $BondOrder);
3445 }
3446 
3447 # Generate key 158 value as 1/0 indicating its presence/absence or count of its
3448 # presence in a molecule.
3449 #
3450 # Key 158 description: C-N
3451 #
3452 sub _Generate166KeySetKey158 {
3453   my($This) = @_;
3454   my($BondOrder) = 1;
3455 
3456   return $This->_DetectBondKeys('C', 'N', $BondOrder);
3457 }
3458 
3459 # Generate key 159 value as 1/0 indicating its presence/absence or count of its
3460 # presence in a molecule.
3461 #
3462 # Key 159 description: O > 1
3463 #
3464 sub _Generate166KeySetKey159 {
3465   my($This) = @_;
3466   my($MinKeyCount) = 2;
3467 
3468   return $This->_DetectAtomKeys('O', $MinKeyCount);
3469 }
3470 
3471 # Generate key 160 value as 1/0 indicating its presence/absence or count of its
3472 # presence in a molecule.
3473 #
3474 # Key 160 description: CH3
3475 #
3476 sub _Generate166KeySetKey160 {
3477   my($This) = @_;
3478   my($MinKeyCount, $IsInRing, $MinHydrogenCount) = (undef, undef, 3);
3479 
3480   return $This->_DetectAtomKeys('C', $MinKeyCount, $IsInRing, $MinHydrogenCount);
3481 }
3482 
3483 # Generate key 161 value as 1/0 indicating its presence/absence or count of its
3484 # presence in a molecule.
3485 #
3486 # Key 161 description: N
3487 #
3488 sub _Generate166KeySetKey161 {
3489   my($This) = @_;
3490 
3491   return $This->_DetectAtomKeys('N');
3492 }
3493 
3494 # Generate key 162 value as 1/0 indicating its presence/absence or count of its
3495 # presence in a molecule.
3496 #
3497 # Key 162 description: AROMATIC
3498 #
3499 sub _Generate166KeySetKey162 {
3500   my($This) = @_;
3501   my($Atom, $Molecule, $KeyValue);
3502 
3503   # Check molecule aromatic property...
3504   $Molecule = $This->GetMolecule();
3505   if ($Molecule->IsAromatic()) {
3506     return 1;
3507   }
3508 
3509   # Check aromatic property of each atom...
3510   $KeyValue = 1;
3511   ATOM: for $Atom (@{$This->{Atoms}}) {
3512       if (!$Atom->IsAromatic()) {
3513         $KeyValue = 0;
3514         last ATOM;
3515       }
3516   }
3517   return $KeyValue;
3518 }
3519 
3520 # Generate key 163 value as 1/0 indicating its presence/absence or count of its
3521 # presence in a molecule.
3522 #
3523 # Key 163 description: 6M RING
3524 #
3525 sub _Generate166KeySetKey163 {
3526   my($This) = @_;
3527   my($Molecule, $KeyValue, $RingSize, $NumOfRings);
3528 
3529   $RingSize = 6;
3530   $Molecule = $This->GetMolecule();
3531   $NumOfRings = $Molecule->GetNumOfRingsWithSize($RingSize);
3532 
3533   if ($This->{KeyBits}) {
3534     $KeyValue = $NumOfRings ? 1 : 0;
3535   }
3536   else {
3537     $KeyValue = $NumOfRings;
3538   }
3539   return $KeyValue;
3540 }
3541 
3542 # Generate key 164 value as 1/0 indicating its presence/absence or count of its
3543 # presence in a molecule.
3544 #
3545 # Key 164 description: O
3546 #
3547 sub _Generate166KeySetKey164 {
3548   my($This) = @_;
3549 
3550   return $This->_DetectAtomKeys('O');
3551 }
3552 
3553 # Generate key 165 value as 1/0 indicating its presence/absence or count of its
3554 # presence in a molecule.
3555 #
3556 # Key 165 description: RING
3557 #
3558 sub _Generate166KeySetKey165 {
3559   my($This) = @_;
3560   my($Molecule, $KeyValue, $NumOfRings);
3561 
3562   $Molecule = $This->GetMolecule();
3563   $NumOfRings = $Molecule->GetNumOfRings();
3564 
3565   if ($This->{KeyBits}) {
3566     $KeyValue = $NumOfRings ? 1 : 0;
3567   }
3568   else {
3569     $KeyValue = $NumOfRings;
3570   }
3571   return $KeyValue;
3572 }
3573 
3574 # Generate key 166 value as 1/0 indicating its presence/absence or count of its
3575 # presence in a molecule.
3576 #
3577 # Key 166 description: FRAGMENTS
3578 #
3579 sub _Generate166KeySetKey166 {
3580   my($This) = @_;
3581   my($Molecule, $KeyValue, $NumOfComponents);
3582 
3583   $Molecule = $This->GetMolecule();
3584   $NumOfComponents = $Molecule->GetNumOfConnectedComponents();
3585 
3586   if ($This->{KeyBits}) {
3587     $KeyValue = ($NumOfComponents > 1) ? 1 : 0;
3588   }
3589   else {
3590     $KeyValue = $NumOfComponents;
3591   }
3592   return $KeyValue;
3593 }
3594 
3595 ##################################
3596 #
3597 #  Implementation of MDL MACCS 322 keys...
3598 #
3599 ##################################
3600 
3601 # Generate 322 keyset key 1 value as 1/0 indicating its presence/absence or
3602 # count of its presence in a molecule.
3603 #
3604 # Key 1 description: A(AAA) or AA(A)A - atom with at least three neighbors
3605 #
3606 sub _Generate322KeySetKey1 {
3607   my($This) = @_;
3608   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
3609 
3610   $CentralAtomSymbol = 'A';
3611   @NbrAtomSymbols = ('A', 'A', 'A');
3612   @NbrBondSymbols = (undef, undef, undef);
3613 
3614   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
3615 }
3616 
3617 # Generate 322 keyset key 2 value as 1/0 indicating its presence/absence or
3618 # count of its presence in a molecule.
3619 #
3620 # Key 2 description: Q - heteroatom
3621 #
3622 sub _Generate322KeySetKey2 {
3623   my($This) = @_;
3624 
3625   return $This->_DetectAtomKeys('Q');
3626 }
3627 
3628 # Generate 322 keyset key 3 value as 1/0 indicating its presence/absence or
3629 # count of its presence in a molecule.
3630 #
3631 # Key 3 description: Anot%not-A - atom involved in one or more multiple bonds, not aromatic
3632 #
3633 sub _Generate322KeySetKey3 {
3634   my($This) = @_;
3635   my($BondSymbol) = 'not%not-';
3636 
3637   return $This->_DetectBondKeys('A', 'A', $BondSymbol);
3638 }
3639 
3640 # Generate 322 keyset key 4 value as 1/0 indicating its presence/absence or
3641 # count of its presence in a molecule.
3642 #
3643 # Key 4 description:      A(AAAA) or AA(A)(A)A - atom with at least four neighbors
3644 #
3645 sub _Generate322KeySetKey4 {
3646   my($This) = @_;
3647   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
3648 
3649   $CentralAtomSymbol = 'A';
3650   @NbrAtomSymbols = ('A', 'A', 'A', 'A');
3651   @NbrBondSymbols = (undef, undef, undef, undef);
3652 
3653   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
3654 }
3655 
3656 # Generate 322 keyset key 5 value as 1/0 indicating its presence/absence or
3657 # count of its presence in a molecule.
3658 #
3659 # Key 5 description: A(QQ) or QA(Q) - atom with at least two heteroatom neighbors
3660 #
3661 sub _Generate322KeySetKey5 {
3662   my($This) = @_;
3663   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
3664 
3665   $CentralAtomSymbol = 'A';
3666   @NbrAtomSymbols = ('Q', 'Q');
3667   @NbrBondSymbols = (undef, undef);
3668 
3669   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
3670 }
3671 
3672 # Generate 322 keyset key 6 value as 1/0 indicating its presence/absence or
3673 # count of its presence in a molecule.
3674 #
3675 # Key 6 description: A(QQQ) or QA(Q)Q - atom with at least three heteroatom neighbors
3676 #
3677 sub _Generate322KeySetKey6 {
3678   my($This) = @_;
3679   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
3680 
3681   $CentralAtomSymbol = 'A';
3682   @NbrAtomSymbols = ('Q', 'Q', 'Q');
3683   @NbrBondSymbols = (undef, undef, undef);
3684 
3685   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
3686 }
3687 
3688 # Generate 322 keyset key 7 value as 1/0 indicating its presence/absence or
3689 # count of its presence in a molecule.
3690 #
3691 # Key 7 description:      QH - heteroatom with at least one hydrogen attached
3692 #
3693 sub _Generate322KeySetKey7 {
3694   my($This) = @_;
3695   my($MinKeyCount, $IsInRing, $MinHydrogenCount) = (undef, undef, 1);
3696 
3697   return $This->_DetectAtomKeys('Q', $MinKeyCount, $IsInRing, $MinHydrogenCount);
3698 }
3699 
3700 # Generate 322 keyset key 8 value as 1/0 indicating its presence/absence or
3701 # count of its presence in a molecule.
3702 #
3703 # Key 8 description: CH2(AA) or ACH2A - carbon with at least two single bonds and at least two hydrogens attached
3704 #
3705 sub _Generate322KeySetKey8 {
3706   my($This) = @_;
3707   my($CentralAtomSymbol, $CentralAtomMinHydrogenCount, $MinKeyCount, @NbrAtomSymbols, @NbrBondSymbols);
3708 
3709   $CentralAtomSymbol = 'C';
3710   @NbrAtomSymbols = ('A', 'A');
3711   @NbrBondSymbols = (undef, undef);
3712   $MinKeyCount = undef;
3713   $CentralAtomMinHydrogenCount = 2;
3714 
3715   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols, $MinKeyCount, $CentralAtomMinHydrogenCount);
3716 }
3717 
3718 # Generate 322 keyset key 9 value as 1/0 indicating its presence/absence or
3719 # count of its presence in a molecule.
3720 #
3721 # Key 9 description: CH3(A) or ACH3 - carbon with at least one single bond and at least three hydrogens attached
3722 #
3723 sub _Generate322KeySetKey9 {
3724   my($This) = @_;
3725   my($CentralAtomSymbol, $CentralAtomMinHydrogenCount, $MinKeyCount, @NbrAtomSymbols, @NbrBondSymbols);
3726 
3727   $CentralAtomSymbol = 'C';
3728   @NbrAtomSymbols = ('A');
3729   @NbrBondSymbols = (undef);
3730   $MinKeyCount = undef;
3731   $CentralAtomMinHydrogenCount = 3;
3732 
3733   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols, $MinKeyCount, $CentralAtomMinHydrogenCount);
3734 }
3735 
3736 # Generate 322 keyset key 10 value as 1/0 indicating its presence/absence or
3737 # count of its presence in a molecule.
3738 #
3739 # Key 10 description: Halogen
3740 #
3741 sub _Generate322KeySetKey10 {
3742   my($This) = @_;
3743 
3744   return $This->_DetectAtomKeys('X');
3745 }
3746 
3747 # Generate 322 keyset key 11 value as 1/0 indicating its presence/absence or
3748 # count of its presence in a molecule.
3749 #
3750 # Key 11 description: A(-A-A-A) or A-A(-A)-A - atom has at least three single bonds
3751 #
3752 sub _Generate322KeySetKey11 {
3753   my($This) = @_;
3754   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
3755 
3756   $CentralAtomSymbol = 'A';
3757   @NbrAtomSymbols = ('A', 'A', 'A');
3758   @NbrBondSymbols = ('-', '-', '-');
3759 
3760   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
3761 }
3762 
3763 # Generate 322 keyset key 12 value as 1/0 indicating its presence/absence or
3764 # count of its presence in a molecule.
3765 #
3766 # Key 12 description: AAAAAA@1 >= 2 - atom is in at least two different six-membered rings
3767 #
3768 sub _Generate322KeySetKey12 {
3769   my($This) = @_;
3770   my($Atom, $KeyValue, $RingSize, $NumOfRings);
3771 
3772   $RingSize = 6;
3773   $KeyValue = 0;
3774 
3775   ATOM: for $Atom (@{$This->{Atoms}}) {
3776     if (!$This->_IsAtom($Atom)) {
3777       next ATOM;
3778     }
3779     $NumOfRings = $Atom->GetNumOfRingsWithSize($RingSize);
3780     if ($NumOfRings >= 2) {
3781       $KeyValue++;
3782       if ($This->{KeyBits}) {
3783         $KeyValue = 1;
3784         last ATOM;
3785       }
3786     }
3787   }
3788   return $KeyValue;
3789 }
3790 
3791 # Generate 322 keyset key 13 value as 1/0 indicating its presence/absence or
3792 # count of its presence in a molecule.
3793 #
3794 # Key 13 description: A($A$A$A) or A$A($A)$A - atom has more than two ring bonds (at least three ring bonds)
3795 #
3796 sub _Generate322KeySetKey13 {
3797   my($This) = @_;
3798   my($CentralAtomSymbol, $MinKeyCount, @NbrAtomSymbols, @NbrBondSymbols);
3799 
3800   $CentralAtomSymbol = 'A';
3801   @NbrAtomSymbols = ('A', 'A', 'A');
3802   @NbrBondSymbols = ('$', '$', '$');
3803 
3804   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
3805 }
3806 
3807 # Generate 322 keyset key 14 value as 1/0 indicating its presence/absence or
3808 # count of its presence in a molecule.
3809 #
3810 # Key 14 description: A$A!A$A - atom is at a ring/chain boundary. When a comparison is
3811 #                     done with another atom the path passes through the chain bond.
3812 #
3813 sub _Generate322KeySetKey14 {
3814   my($This) = @_;
3815   my($BondAtomSymbol1, $BondAtomSymbol2, $BondSymbol, @NbrAtomsSymbols, @NbrAtomsBondSymbols);
3816 
3817   ($BondAtomSymbol1, $BondAtomSymbol2) = ('A', 'A');
3818   $BondSymbol = '!';
3819 
3820   @NbrAtomsSymbols = (['A'], ['A']);
3821   @NbrAtomsBondSymbols = (['$'], ['$']);
3822   return $This->_DetectBondNeighborhoodKeys($BondAtomSymbol1, $BondAtomSymbol2, $BondSymbol, \@NbrAtomsSymbols, \@NbrAtomsBondSymbols);
3823 }
3824 
3825 # Generate 322 keyset key 15 value as 1/0 indicating its presence/absence or
3826 # count of its presence in a molecule.
3827 #
3828 # Key 15 description:  Anot%A%Anot%A - atom is at an aromatic/nonaromatic boundary.
3829 #                      When a comparison is done with another atom the path passes through the aromatic bond.
3830 #
3831 sub _Generate322KeySetKey15 {
3832   my($This) = @_;
3833   my($BondAtomSymbol1, $BondAtomSymbol2, $BondSymbol, @NbrAtomsSymbols, @NbrAtomsBondSymbols);
3834 
3835   ($BondAtomSymbol1, $BondAtomSymbol2) = ('A', 'A');
3836   $BondSymbol = '%';
3837 
3838   @NbrAtomsSymbols = (['A'], ['A']);
3839   @NbrAtomsBondSymbols = (['not%'], ['not%']);
3840   return $This->_DetectBondNeighborhoodKeys($BondAtomSymbol1, $BondAtomSymbol2, $BondSymbol, \@NbrAtomsSymbols, \@NbrAtomsBondSymbols);
3841 }
3842 
3843 # Generate 322 keyset key 16 value as 1/0 indicating its presence/absence or
3844 # count of its presence in a molecule.
3845 #
3846 # Key 16 description:     A!A!A  - atom with more than one chain bond
3847 #
3848 sub _Generate322KeySetKey16 {
3849   my($This) = @_;
3850   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
3851 
3852   $CentralAtomSymbol = 'A';
3853   @NbrAtomSymbols = ('A', 'A');
3854   @NbrBondSymbols = ('!', '!');
3855 
3856   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
3857 }
3858 
3859 # Generate 322 keyset key 17 value as 1/0 indicating its presence/absence or
3860 # count of its presence in a molecule.
3861 #
3862 # Key 17 description: A!A$A!A - atom is at a ring/chain boundary. When a comparison
3863 #                     is done  with another atom the path passes through the ring bond.
3864 #
3865 sub _Generate322KeySetKey17 {
3866   my($This) = @_;
3867   my($BondAtomSymbol1, $BondAtomSymbol2, $BondSymbol, @NbrAtomsSymbols, @NbrAtomsBondSymbols);
3868 
3869   ($BondAtomSymbol1, $BondAtomSymbol2) = ('A', 'A');
3870   $BondSymbol = '$';
3871 
3872   @NbrAtomsSymbols = (['A'], ['A']);
3873   @NbrAtomsBondSymbols = (['!'], ['!']);
3874   return $This->_DetectBondNeighborhoodKeys($BondAtomSymbol1, $BondAtomSymbol2, $BondSymbol, \@NbrAtomsSymbols, \@NbrAtomsBondSymbols);
3875 }
3876 
3877 # Generate 322 keyset key 18 value as 1/0 indicating its presence/absence or
3878 # count of its presence in a molecule.
3879 #
3880 # Key 18 description: A%Anot%A%A - atom is at an aromatic/nonaromatic boundary.
3881 #                     When a comparison is done with another atom the path passes through
3882 #                     the nonaromatic bond
3883 #
3884 sub _Generate322KeySetKey18 {
3885   my($This) = @_;
3886   my($BondAtomSymbol1, $BondAtomSymbol2, $BondSymbol, @NbrAtomsSymbols, @NbrAtomsBondSymbols);
3887 
3888   ($BondAtomSymbol1, $BondAtomSymbol2) = ('A', 'A');
3889   $BondSymbol = 'not%';
3890 
3891   @NbrAtomsSymbols = (['A'], ['A']);
3892   @NbrAtomsBondSymbols = (['%'], ['%']);
3893   return $This->_DetectBondNeighborhoodKeys($BondAtomSymbol1, $BondAtomSymbol2, $BondSymbol, \@NbrAtomsSymbols, \@NbrAtomsBondSymbols);
3894 }
3895 
3896 # Generate 322 keyset key 19 value as 1/0 indicating its presence/absence or
3897 # count of its presence in a molecule.
3898 #
3899 # Key 19 description: HETEROCYCLE - atom is a heteroatom in a ring.
3900 #
3901 sub _Generate322KeySetKey19 {
3902   my($This) = @_;
3903   my($MinKeyCount, $IsInRing) = (undef, 1);
3904 
3905   return $This->_DetectAtomKeys('Q', $MinKeyCount, $IsInRing);
3906 }
3907 
3908 # Generate 322 keyset key 20 value as 1/0 indicating its presence/absence or
3909 # count of its presence in a molecule.
3910 #
3911 # Key 20 description: rare properties: atom with five or more neighbors, atom in four
3912 #                     or more rings, or atom types other than  H, C, N, O, S, F, Cl, Br, or I
3913 #
3914 sub _Generate322KeySetKey20 {
3915   my($This) = @_;
3916   my($Atom, $KeyValue);
3917 
3918   $KeyValue = 0;
3919   ATOM: for $Atom (@{$This->{Atoms}}) {
3920     if (!($Atom->GetAtomicNumber() !~ /^(1|6|7|8|9|16|17|35|53)$/) || ($Atom->GetNumOfRings() >= 4) || ($Atom->GetNumOfNeighbors() >= 5) ) {
3921       next ATOM;
3922     }
3923     $KeyValue++;
3924     if ($This->{KeyBits}) {
3925       $KeyValue = 1;
3926       last ATOM;
3927     }
3928   }
3929   return $KeyValue;
3930 }
3931 
3932 # Generate 322 keyset key 21 value as 1/0 indicating its presence/absence or
3933 # count of its presence in a molecule.
3934 #
3935 # Key 21 description: rare properties: atom has a charge, is an isotope, has
3936 #                     two or more multiple bonds, or has a triple bond.
3937 #
3938 sub _Generate322KeySetKey21 {
3939   my($This) = @_;
3940   my($Atom, $KeyValue);
3941 
3942   $KeyValue = 0;
3943   ATOM: for $Atom (@{$This->{Atoms}}) {
3944     if ( !($Atom->IsIsotope() || $Atom->GetFormalCharge()) ) {
3945       # Look for multiple and triple bonds...
3946       my($Bond, $NumOfTripleBonds, $NumOfMultipleBonds);
3947 
3948       ($NumOfTripleBonds, $NumOfMultipleBonds) = (0, 0);
3949       BOND: for $Bond ($Atom->GetBonds()) {
3950         if ($Bond->IsSingle()) { next BOND; }
3951         if ($Bond->IsDouble()) { $NumOfMultipleBonds++; next BOND; }
3952         if ($Bond->IsTriple()) { $NumOfTripleBonds++; next BOND; }
3953       }
3954       if ( !($NumOfTripleBonds || ($NumOfMultipleBonds >= 2)) ) {
3955         next ATOM;
3956       }
3957     }
3958     $KeyValue++;
3959     if ($This->{KeyBits}) {
3960       $KeyValue = 1;
3961       last ATOM;
3962     }
3963   }
3964   return $KeyValue;
3965 }
3966 
3967 # Generate 322 keyset key 22 value as 1/0 indicating its presence/absence or
3968 # count of its presence in a molecule.
3969 #
3970 # Key 22 description:  N - nitrogen
3971 #
3972 sub _Generate322KeySetKey22 {
3973   my($This) = @_;
3974 
3975   return $This->_DetectAtomKeys('N');
3976 }
3977 
3978 # Generate 322 keyset key 23 value as 1/0 indicating its presence/absence or
3979 # count of its presence in a molecule.
3980 #
3981 # Key 23 description: S - sulfur
3982 #
3983 sub _Generate322KeySetKey23 {
3984   my($This) = @_;
3985 
3986   return $This->_DetectAtomKeys('S');
3987 }
3988 
3989 # Generate 322 keyset key 24 value as 1/0 indicating its presence/absence or
3990 # count of its presence in a molecule.
3991 #
3992 # Key 24 description: O - oxygen
3993 #
3994 sub _Generate322KeySetKey24 {
3995   my($This) = @_;
3996 
3997   return $This->_DetectAtomKeys('O');
3998 }
3999 
4000 # Generate 322 keyset key 25 value as 1/0 indicating its presence/absence or
4001 # count of its presence in a molecule.
4002 #
4003 # Key 25 description: A(AA)A(A)A(AA) - atom has two neighbors, each with
4004 #                     three or more neighbors (including the central atom).
4005 #
4006 sub _Generate322KeySetKey25 {
4007   my($This) = @_;
4008   my($MinKeyCount, @CentralAtomsSymbols, @NbrAtomsSymbols);
4009 
4010   @CentralAtomsSymbols = ('A', 'A', 'A');
4011   @NbrAtomsSymbols = (['A', 'A'], ['A'], ['A', 'A']);
4012 
4013   return $This->_DetectExtendedAtomNeighborhoodKeys(\@CentralAtomsSymbols, undef, undef, undef, \@NbrAtomsSymbols);
4014 }
4015 
4016 # Generate 322 keyset key 26 value as 1/0 indicating its presence/absence or
4017 # count of its presence in a molecule.
4018 #
4019 # Key 26 description:     CH2ACH2 - atom has two hydrocarbon (CH2) neighbors
4020 #
4021 sub _Generate322KeySetKey26 {
4022   my($This) = @_;
4023   my($CentralAtomSymbol, $CentralAtomMinHydrogenCount, $MinKeyCount, @NbrAtomSymbols, @NbrBondSymbols, @NbrAtomMinHydrogenCount);
4024 
4025   $CentralAtomSymbol = 'A';
4026   $CentralAtomMinHydrogenCount = undef;
4027 
4028   @NbrAtomSymbols = ('C', 'C');
4029   @NbrBondSymbols = (undef, undef);
4030   @NbrAtomMinHydrogenCount = (2, 2);
4031 
4032   $MinKeyCount = undef;
4033 
4034   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols, $MinKeyCount, $CentralAtomMinHydrogenCount, \@NbrAtomMinHydrogenCount);
4035 }
4036 
4037 # Generate 322 keyset key 27 value as 1/0 indicating its presence/absence or
4038 # count of its presence in a molecule.
4039 #
4040 # Key 27 description: C(CC)
4041 #
4042 sub _Generate322KeySetKey27 {
4043   my($This) = @_;
4044   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4045 
4046   $CentralAtomSymbol = 'C';
4047   @NbrAtomSymbols = ('C', 'C');
4048   @NbrBondSymbols = (undef, undef);
4049 
4050   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4051 }
4052 
4053 # Generate 322 keyset key 28 value as 1/0 indicating its presence/absence or
4054 # count of its presence in a molecule.
4055 #
4056 # Key 28 description: C(CCC)
4057 #
4058 sub _Generate322KeySetKey28 {
4059   my($This) = @_;
4060   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4061 
4062   $CentralAtomSymbol = 'C';
4063   @NbrAtomSymbols = ('C', 'C', 'C');
4064   @NbrBondSymbols = (undef, undef, undef);
4065 
4066   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4067 }
4068 
4069 # Generate 322 keyset key 29 value as 1/0 indicating its presence/absence or
4070 # count of its presence in a molecule.
4071 #
4072 # Key 29 description: C(CN)
4073 #
4074 sub _Generate322KeySetKey29 {
4075   my($This) = @_;
4076   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4077 
4078   $CentralAtomSymbol = 'C';
4079   @NbrAtomSymbols = ('C', 'N');
4080   @NbrBondSymbols = (undef, undef);
4081 
4082   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4083 }
4084 
4085 # Generate 322 keyset key 30 value as 1/0 indicating its presence/absence or
4086 # count of its presence in a molecule.
4087 #
4088 # Key 30 description: C(CCN)
4089 #
4090 sub _Generate322KeySetKey30 {
4091   my($This) = @_;
4092   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4093 
4094   $CentralAtomSymbol = 'C';
4095   @NbrAtomSymbols = ('C', 'C', 'N');
4096   @NbrBondSymbols = (undef, undef, undef);
4097 
4098   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4099 }
4100 
4101 # Generate 322 keyset key 31 value as 1/0 indicating its presence/absence or
4102 # count of its presence in a molecule.
4103 #
4104 # Key 31 description: C(NN)
4105 #
4106 sub _Generate322KeySetKey31 {
4107   my($This) = @_;
4108   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4109 
4110   $CentralAtomSymbol = 'C';
4111   @NbrAtomSymbols = ('N', 'N');
4112   @NbrBondSymbols = (undef, undef);
4113 
4114   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4115 }
4116 
4117 # Generate 322 keyset key 32 value as 1/0 indicating its presence/absence or
4118 # count of its presence in a molecule.
4119 #
4120 # Key 32 description: C(NNC)
4121 #
4122 sub _Generate322KeySetKey32 {
4123   my($This) = @_;
4124   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4125 
4126   $CentralAtomSymbol = 'C';
4127   @NbrAtomSymbols = ('N', 'N', 'C');
4128   @NbrBondSymbols = (undef, undef, undef);
4129 
4130   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4131 }
4132 
4133 # Generate 322 keyset key 33 value as 1/0 indicating its presence/absence or
4134 # count of its presence in a molecule.
4135 #
4136 # Key 33 description: C(NNN)
4137 #
4138 sub _Generate322KeySetKey33 {
4139   my($This) = @_;
4140   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4141 
4142   $CentralAtomSymbol = 'C';
4143   @NbrAtomSymbols = ('N', 'N', 'N');
4144   @NbrBondSymbols = (undef, undef, undef);
4145 
4146   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4147 }
4148 
4149 # Generate 322 keyset key 34 value as 1/0 indicating its presence/absence or
4150 # count of its presence in a molecule.
4151 #
4152 # Key 34 description: C(CO)
4153 #
4154 sub _Generate322KeySetKey34 {
4155   my($This) = @_;
4156   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4157 
4158   $CentralAtomSymbol = 'C';
4159   @NbrAtomSymbols = ('C', 'O');
4160   @NbrBondSymbols = (undef, undef);
4161 
4162   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4163 }
4164 
4165 # Generate 322 keyset key 35 value as 1/0 indicating its presence/absence or
4166 # count of its presence in a molecule.
4167 #
4168 # Key 35 description: C(CCO)
4169 #
4170 sub _Generate322KeySetKey35 {
4171   my($This) = @_;
4172   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4173 
4174   $CentralAtomSymbol = 'C';
4175   @NbrAtomSymbols = ('C', 'C', 'O');
4176   @NbrBondSymbols = (undef, undef, undef);
4177 
4178   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4179 }
4180 
4181 # Generate 322 keyset key 36 value as 1/0 indicating its presence/absence or
4182 # count of its presence in a molecule.
4183 #
4184 # Key 36 description: C(NO)
4185 #
4186 sub _Generate322KeySetKey36 {
4187   my($This) = @_;
4188   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4189 
4190   $CentralAtomSymbol = 'C';
4191   @NbrAtomSymbols = ('N', 'O');
4192   @NbrBondSymbols = (undef, undef);
4193 
4194   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4195 }
4196 
4197 # Generate 322 keyset key 37 value as 1/0 indicating its presence/absence or
4198 # count of its presence in a molecule.
4199 #
4200 # Key 37 description: C(NCO)
4201 #
4202 sub _Generate322KeySetKey37 {
4203   my($This) = @_;
4204   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4205 
4206   $CentralAtomSymbol = 'C';
4207   @NbrAtomSymbols = ('N', 'C', 'O');
4208   @NbrBondSymbols = (undef, undef, undef);
4209 
4210   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4211 }
4212 
4213 # Generate 322 keyset key 38 value as 1/0 indicating its presence/absence or
4214 # count of its presence in a molecule.
4215 #
4216 # Key 38 description: C(NNO)
4217 #
4218 sub _Generate322KeySetKey38 {
4219   my($This) = @_;
4220   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4221 
4222   $CentralAtomSymbol = 'C';
4223   @NbrAtomSymbols = ('N', 'N', 'O');
4224   @NbrBondSymbols = (undef, undef, undef);
4225 
4226   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4227 }
4228 
4229 # Generate 322 keyset key 39 value as 1/0 indicating its presence/absence or
4230 # count of its presence in a molecule.
4231 #
4232 # Key 39 description: C(OO)
4233 #
4234 sub _Generate322KeySetKey39 {
4235   my($This) = @_;
4236   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4237 
4238   $CentralAtomSymbol = 'C';
4239   @NbrAtomSymbols = ('O', 'O');
4240   @NbrBondSymbols = (undef, undef);
4241 
4242   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4243 }
4244 
4245 # Generate 322 keyset key 40 value as 1/0 indicating its presence/absence or
4246 # count of its presence in a molecule.
4247 #
4248 # Key 40 description: C(COO)
4249 #
4250 sub _Generate322KeySetKey40 {
4251   my($This) = @_;
4252   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4253 
4254   $CentralAtomSymbol = 'C';
4255   @NbrAtomSymbols = ('C', 'O', 'O');
4256   @NbrBondSymbols = (undef, undef, undef);
4257 
4258   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4259 }
4260 
4261 # Generate 322 keyset key 41 value as 1/0 indicating its presence/absence or
4262 # count of its presence in a molecule.
4263 #
4264 # Key 41 description: C(NOO)
4265 #
4266 sub _Generate322KeySetKey41 {
4267   my($This) = @_;
4268   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4269 
4270   $CentralAtomSymbol = 'C';
4271   @NbrAtomSymbols = ('N', 'O', 'O');
4272   @NbrBondSymbols = (undef, undef, undef);
4273 
4274   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4275 }
4276 
4277 # Generate 322 keyset key 42 value as 1/0 indicating its presence/absence or
4278 # count of its presence in a molecule.
4279 #
4280 # Key 42 description: C(OOO)
4281 #
4282 sub _Generate322KeySetKey42 {
4283   my($This) = @_;
4284   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4285 
4286   $CentralAtomSymbol = 'C';
4287   @NbrAtomSymbols = ('O', 'O', 'O');
4288   @NbrBondSymbols = (undef, undef, undef);
4289 
4290   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4291 }
4292 
4293 # Generate 322 keyset key 43 value as 1/0 indicating its presence/absence or
4294 # count of its presence in a molecule.
4295 #
4296 # Key 43 description: Q(CC)
4297 #
4298 sub _Generate322KeySetKey43 {
4299   my($This) = @_;
4300   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4301 
4302   $CentralAtomSymbol = 'Q';
4303   @NbrAtomSymbols = ('C', 'C');
4304   @NbrBondSymbols = (undef, undef);
4305 
4306   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4307 }
4308 
4309 # Generate 322 keyset key 44 value as 1/0 indicating its presence/absence or
4310 # count of its presence in a molecule.
4311 #
4312 # Key 44 description: Q(CCC)
4313 #
4314 sub _Generate322KeySetKey44 {
4315   my($This) = @_;
4316   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4317 
4318   $CentralAtomSymbol = 'Q';
4319   @NbrAtomSymbols = ('C', 'C', 'C');
4320   @NbrBondSymbols = (undef, undef, undef);
4321 
4322   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4323 }
4324 
4325 # Generate 322 keyset key 45 value as 1/0 indicating its presence/absence or
4326 # count of its presence in a molecule.
4327 #
4328 # Key 45 description: Q(CN)
4329 #
4330 sub _Generate322KeySetKey45 {
4331   my($This) = @_;
4332   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4333 
4334   $CentralAtomSymbol = 'Q';
4335   @NbrAtomSymbols = ('C', 'N');
4336   @NbrBondSymbols = (undef, undef);
4337 
4338   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4339 }
4340 
4341 # Generate 322 keyset key 46 value as 1/0 indicating its presence/absence or
4342 # count of its presence in a molecule.
4343 #
4344 # Key 46 description: Q(CCN)
4345 #
4346 sub _Generate322KeySetKey46 {
4347   my($This) = @_;
4348   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4349 
4350   $CentralAtomSymbol = 'Q';
4351   @NbrAtomSymbols = ('C', 'C', 'N');
4352   @NbrBondSymbols = (undef, undef, undef);
4353 
4354   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4355 }
4356 
4357 # Generate 322 keyset key 47 value as 1/0 indicating its presence/absence or
4358 # count of its presence in a molecule.
4359 #
4360 # Key 47 description: Q(NN)
4361 #
4362 sub _Generate322KeySetKey47 {
4363   my($This) = @_;
4364   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4365 
4366   $CentralAtomSymbol = 'Q';
4367   @NbrAtomSymbols = ('N', 'N');
4368   @NbrBondSymbols = (undef, undef);
4369 
4370   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4371 }
4372 
4373 # Generate 322 keyset key 48 value as 1/0 indicating its presence/absence or
4374 # count of its presence in a molecule.
4375 #
4376 # Key 48 description: Q(CNN)
4377 #
4378 sub _Generate322KeySetKey48 {
4379   my($This) = @_;
4380   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4381 
4382   $CentralAtomSymbol = 'Q';
4383   @NbrAtomSymbols = ('C', 'N', 'N');
4384   @NbrBondSymbols = (undef, undef, undef);
4385 
4386   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4387 }
4388 
4389 # Generate 322 keyset key 49 value as 1/0 indicating its presence/absence or
4390 # count of its presence in a molecule.
4391 #
4392 # Key 49 description: Q(NNN)
4393 #
4394 sub _Generate322KeySetKey49 {
4395   my($This) = @_;
4396   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4397 
4398   $CentralAtomSymbol = 'Q';
4399   @NbrAtomSymbols = ('N', 'N', 'N');
4400   @NbrBondSymbols = (undef, undef, undef);
4401 
4402   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4403 }
4404 
4405 # Generate 322 keyset key 50 value as 1/0 indicating its presence/absence or
4406 # count of its presence in a molecule.
4407 #
4408 # Key 50 description: Q(CO)
4409 #
4410 sub _Generate322KeySetKey50 {
4411   my($This) = @_;
4412   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4413 
4414   $CentralAtomSymbol = 'Q';
4415   @NbrAtomSymbols = ('C', 'O');
4416   @NbrBondSymbols = (undef, undef);
4417 
4418   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4419 }
4420 
4421 # Generate 322 keyset key 51 value as 1/0 indicating its presence/absence or
4422 # count of its presence in a molecule.
4423 #
4424 # Key 51 description: Q(CCO)
4425 #
4426 sub _Generate322KeySetKey51 {
4427   my($This) = @_;
4428   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4429 
4430   $CentralAtomSymbol = 'Q';
4431   @NbrAtomSymbols = ('C', 'C', 'O');
4432   @NbrBondSymbols = (undef, undef, undef);
4433 
4434   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4435 }
4436 
4437 # Generate 322 keyset key 52 value as 1/0 indicating its presence/absence or
4438 # count of its presence in a molecule.
4439 #
4440 # Key 52 description: Q(NO)
4441 #
4442 sub _Generate322KeySetKey52 {
4443   my($This) = @_;
4444   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4445 
4446   $CentralAtomSymbol = 'Q';
4447   @NbrAtomSymbols = ('N', 'O');
4448   @NbrBondSymbols = (undef, undef);
4449 
4450   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4451 }
4452 
4453 # Generate 322 keyset key 53 value as 1/0 indicating its presence/absence or
4454 # count of its presence in a molecule.
4455 #
4456 # Key 53 description: Q(CNO)
4457 #
4458 sub _Generate322KeySetKey53 {
4459   my($This) = @_;
4460   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4461 
4462   $CentralAtomSymbol = 'Q';
4463   @NbrAtomSymbols = ('C', 'N', 'O');
4464   @NbrBondSymbols = (undef, undef, undef);
4465 
4466   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4467 }
4468 
4469 # Generate 322 keyset key 54 value as 1/0 indicating its presence/absence or
4470 # count of its presence in a molecule.
4471 #
4472 # Key 54 description: Q(NNO)
4473 #
4474 sub _Generate322KeySetKey54 {
4475   my($This) = @_;
4476   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4477 
4478   $CentralAtomSymbol = 'Q';
4479   @NbrAtomSymbols = ('N', 'N', 'O');
4480   @NbrBondSymbols = (undef, undef, undef);
4481 
4482   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4483 }
4484 
4485 # Generate 322 keyset key 55 value as 1/0 indicating its presence/absence or
4486 # count of its presence in a molecule.
4487 #
4488 # Key 55 description: Q(OO)
4489 #
4490 sub _Generate322KeySetKey55 {
4491   my($This) = @_;
4492   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4493 
4494   $CentralAtomSymbol = 'Q';
4495   @NbrAtomSymbols = ('O', 'O');
4496   @NbrBondSymbols = (undef, undef);
4497 
4498   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4499 }
4500 
4501 # Generate 322 keyset key 56 value as 1/0 indicating its presence/absence or
4502 # count of its presence in a molecule.
4503 #
4504 # Key 56 description: Q(COO)
4505 #
4506 sub _Generate322KeySetKey56 {
4507   my($This) = @_;
4508   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4509 
4510   $CentralAtomSymbol = 'Q';
4511   @NbrAtomSymbols = ('C', 'O', 'O');
4512   @NbrBondSymbols = (undef, undef, undef);
4513 
4514   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4515 }
4516 
4517 # Generate 322 keyset key 57 value as 1/0 indicating its presence/absence or
4518 # count of its presence in a molecule.
4519 #
4520 # Key 57 description: Q(NOO)
4521 #
4522 sub _Generate322KeySetKey57 {
4523   my($This) = @_;
4524   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4525 
4526   $CentralAtomSymbol = 'Q';
4527   @NbrAtomSymbols = ('N', 'O', 'O');
4528   @NbrBondSymbols = (undef, undef, undef);
4529 
4530   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4531 }
4532 
4533 # Generate 322 keyset key 58 value as 1/0 indicating its presence/absence or
4534 # count of its presence in a molecule.
4535 #
4536 # Key 58 description: Q(OOO)
4537 #
4538 sub _Generate322KeySetKey58 {
4539   my($This) = @_;
4540   my($CentralAtomSymbol, @NbrAtomSymbols, @NbrBondSymbols);
4541 
4542   $CentralAtomSymbol = 'Q';
4543   @NbrAtomSymbols = ('O', 'O', 'O');
4544   @NbrBondSymbols = (undef, undef, undef);
4545 
4546   return $This->_DetectAtomNeighborhoodKeys($CentralAtomSymbol, \@NbrAtomSymbols, \@NbrBondSymbols);
4547 }
4548 
4549 # Generate 322 keyset key 59 value as 1/0 indicating its presence/absence or
4550 # count of its presence in a molecule.
4551 #
4552 # Key 59 description: C-C
4553 #
4554 sub _Generate322KeySetKey59 {
4555   my($This) = @_;
4556   my($BondSymbol) = '-';
4557 
4558   return $This->_DetectBondKeys('C', 'C', $BondSymbol);
4559 }
4560 
4561 # Generate 322 keyset key 60 value as 1/0 indicating its presence/absence or
4562 # count of its presence in a molecule.
4563 #
4564 # Key 60 description: C-N
4565 #
4566 sub _Generate322KeySetKey60 {
4567   my($This) = @_;
4568   my($BondSymbol) = '-';
4569 
4570   return $This->_DetectBondKeys('C', 'N', $BondSymbol);
4571 }
4572 
4573 # Generate 322 keyset key 61 value as 1/0 indicating its presence/absence or
4574 # count of its presence in a molecule.
4575 #
4576 # Key 61 description: C-O
4577 #
4578 sub _Generate322KeySetKey61 {
4579   my($This) = @_;
4580   my($BondSymbol) = '-';
4581 
4582   return $This->_DetectBondKeys('C', 'O', $BondSymbol);
4583 }
4584 
4585 # Generate 322 keyset key 62 value as 1/0 indicating its presence/absence or
4586 # count of its presence in a molecule.
4587 #
4588 # Key 62 description: C-S
4589 #
4590 sub _Generate322KeySetKey62 {
4591   my($This) = @_;
4592   my($BondSymbol) = '-';
4593 
4594   return $This->_DetectBondKeys('C', 'S', $BondSymbol);
4595 }
4596 
4597 # Generate 322 keyset key 63 value as 1/0 indicating its presence/absence or
4598 # count of its presence in a molecule.
4599 #
4600 # Key 63 description: C-Cl
4601 #
4602 sub _Generate322KeySetKey63 {
4603   my($This) = @_;
4604   my($BondSymbol) = '-';
4605 
4606   return $This->_DetectBondKeys('C', 'Cl', $BondSymbol);
4607 }
4608 
4609 # Generate 322 keyset key 64 value as 1/0 indicating its presence/absence or
4610 # count of its presence in a molecule.
4611 #
4612 # Key 64 description: C-P
4613 #
4614 sub _Generate322KeySetKey64 {
4615   my($This) = @_;
4616   my($BondSymbol) = '-';
4617 
4618   return $This->_DetectBondKeys('C', 'P', $BondSymbol);
4619 }
4620 
4621 # Generate 322 keyset key 65 value as 1/0 indicating its presence/absence or
4622 # count of its presence in a molecule.
4623 #
4624 # Key 65 description: C-F
4625 #
4626 sub _Generate322KeySetKey65 {
4627   my($This) = @_;
4628   my($BondSymbol) = '-';
4629 
4630   return $This->_DetectBondKeys('C', 'F', $BondSymbol);
4631 }
4632 
4633 # Generate 322 keyset key 66 value as 1/0 indicating its presence/absence or
4634 # count of its presence in a molecule.
4635 #
4636 # Key 66 description: C-Br
4637 #
4638 sub _Generate322KeySetKey66 {
4639   my($This) = @_;
4640   my($BondSymbol) = '-';
4641 
4642   return $This->_DetectBondKeys('C', 'Br', $BondSymbol);
4643 }
4644 
4645 # Generate 322 keyset key 67 value as 1/0 indicating its presence/absence or
4646 # count of its presence in a molecule.
4647 #
4648 # Key 67 description: C-Si
4649 #
4650 sub _Generate322KeySetKey67 {
4651   my($This) = @_;
4652   my($BondSymbol) = '-';
4653 
4654   return $This->_DetectBondKeys('C', 'Si', $BondSymbol);
4655 }
4656 
4657 # Generate 322 keyset key 68 value as 1/0 indicating its presence/absence or
4658 # count of its presence in a molecule.
4659 #
4660 # Key 68 description: C-I
4661 #
4662 sub _Generate322KeySetKey68 {
4663   my($This) = @_;
4664   my($BondSymbol) = '-';
4665 
4666   return $This->_DetectBondKeys('C', 'I', $BondSymbol);
4667 }
4668 
4669 # Generate 322 keyset key 69 value as 1/0 indicating its presence/absence or
4670 # count of its presence in a molecule.
4671 #
4672 # Key 69 description: C-X
4673 #
4674 sub _Generate322KeySetKey69 {
4675   my($This) = @_;
4676   my($BondSymbol) = '-';
4677 
4678   return $This->_DetectBondKeys('C', 'Z', $BondSymbol);
4679 }
4680 
4681 # Generate 322 keyset key 70 value as 1/0 indicating its presence/absence or
4682 # count of its presence in a molecule.
4683 #
4684 # Key 70 description: N-N
4685 #
4686 sub _Generate322KeySetKey70 {
4687   my($This) = @_;
4688   my($BondSymbol) = '-';
4689 
4690   return $This->_DetectBondKeys('N', 'N', $BondSymbol);
4691 }
4692 
4693 # Generate 322 keyset key 71 value as 1/0 indicating its presence/absence or
4694 # count of its presence in a molecule.
4695 #
4696 # Key 71 description: N-O
4697 #
4698 sub _Generate322KeySetKey71 {
4699   my($This) = @_;
4700   my($BondSymbol) = '-';
4701 
4702   return $This->_DetectBondKeys('N', 'O', $BondSymbol);
4703 }
4704 
4705 # Generate 322 keyset key 72 value as 1/0 indicating its presence/absence or
4706 # count of its presence in a molecule.
4707 #
4708 # Key 72 description: N-S
4709 #
4710 sub _Generate322KeySetKey72 {
4711   my($This) = @_;
4712   my($BondSymbol) = '-';
4713 
4714   return $This->_DetectBondKeys('N', 'S', $BondSymbol);
4715 }
4716 
4717 # Generate 322 keyset key 73 value as 1/0 indicating its presence/absence or
4718 # count of its presence in a molecule.
4719 #
4720 # Key 73 description: N-Cl
4721 #
4722 sub _Generate322KeySetKey73 {
4723   my($This) = @_;
4724   my($BondSymbol) = '-';
4725 
4726   return $This->_DetectBondKeys('N', 'Cl', $BondSymbol);
4727 }
4728 
4729 # Generate 322 keyset key 74 value as 1/0 indicating its presence/absence or
4730 # count of its presence in a molecule.
4731 #
4732 # Key 74 description: N-P
4733 #
4734 sub _Generate322KeySetKey74 {
4735   my($This) = @_;
4736   my($BondSymbol) = '-';
4737 
4738   return $This->_DetectBondKeys('N', 'P', $BondSymbol);
4739 }
4740 
4741 # Generate 322 keyset key 75 value as 1/0 indicating its presence/absence or
4742 # count of its presence in a molecule.
4743 #
4744 # Key 75 description: N-F
4745 #
4746 sub _Generate322KeySetKey75 {
4747   my($This) = @_;
4748   my($BondSymbol) = '-';
4749 
4750   return $This->_DetectBondKeys('N', 'F', $BondSymbol);
4751 }
4752 
4753 # Generate 322 keyset key 76 value as 1/0 indicating its presence/absence or
4754 # count of its presence in a molecule.
4755 #
4756 # Key 76 description: N-Br
4757 #
4758 sub _Generate322KeySetKey76 {
4759   my($This) = @_;
4760   my($BondSymbol) = '-';
4761 
4762   return $This->_DetectBondKeys('N', 'Br', $BondSymbol);
4763 }
4764 
4765 # Generate 322 keyset key 77 value as 1/0 indicating its presence/absence or
4766 # count of its presence in a molecule.
4767 #
4768 # Key 77 description: N-Si
4769 #
4770 sub _Generate322KeySetKey77 {
4771   my($This) = @_;
4772   my($BondSymbol) = '-';
4773 
4774   return $This->_DetectBondKeys('N', 'Si', $BondSymbol);
4775 }
4776 
4777 # Generate 322 keyset key 78 value as 1/0 indicating its presence/absence or
4778 # count of its presence in a molecule.
4779 #
4780 # Key 78 description: N-I
4781 #
4782 sub _Generate322KeySetKey78 {
4783   my($This) = @_;
4784   my($BondSymbol) = '-';
4785 
4786   return $This->_DetectBondKeys('N', 'I', $BondSymbol);
4787 }
4788 
4789 # Generate 322 keyset key 79 value as 1/0 indicating its presence/absence or
4790 # count of its presence in a molecule.
4791 #
4792 # Key 79 description: N-X
4793 #
4794 sub _Generate322KeySetKey79 {
4795   my($This) = @_;
4796   my($BondSymbol) = '-';
4797 
4798   return $This->_DetectBondKeys('N', 'Z', $BondSymbol);
4799 }
4800 
4801 # Generate 322 keyset key 80 value as 1/0 indicating its presence/absence or
4802 # count of its presence in a molecule.
4803 #
4804 # Key 80 description: O-O
4805 #
4806 sub _Generate322KeySetKey80 {
4807   my($This) = @_;
4808   my($BondSymbol) = '-';
4809 
4810   return $This->_DetectBondKeys('O', 'O', $BondSymbol);
4811 }
4812 
4813 # Generate 322 keyset key 81 value as 1/0 indicating its presence/absence or
4814 # count of its presence in a molecule.
4815 #
4816 # Key 81 description: O-S
4817 #
4818 sub _Generate322KeySetKey81 {
4819   my($This) = @_;
4820   my($BondSymbol) = '-';
4821 
4822   return $This->_DetectBondKeys('O', 'S', $BondSymbol);
4823 }
4824 
4825 # Generate 322 keyset key 82 value as 1/0 indicating its presence/absence or
4826 # count of its presence in a molecule.
4827 #
4828 # Key 82 description: O-Cl
4829 #
4830 sub _Generate322KeySetKey82 {
4831   my($This) = @_;
4832   my($BondSymbol) = '-';
4833 
4834   return $This->_DetectBondKeys('O', 'Cl', $BondSymbol);
4835 }
4836 
4837 # Generate 322 keyset key 83 value as 1/0 indicating its presence/absence or
4838 # count of its presence in a molecule.
4839 #
4840 # Key 83 description: O-P
4841 #
4842 sub _Generate322KeySetKey83 {
4843   my($This) = @_;
4844   my($BondSymbol) = '-';
4845 
4846   return $This->_DetectBondKeys('O', 'P', $BondSymbol);
4847 }
4848 
4849 # Generate 322 keyset key 84 value as 1/0 indicating its presence/absence or
4850 # count of its presence in a molecule.
4851 #
4852 # Key 84 description: O-F
4853 #
4854 sub _Generate322KeySetKey84 {
4855   my($This) = @_;
4856   my($BondSymbol) = '-';
4857 
4858   return $This->_DetectBondKeys('O', 'F', $BondSymbol);
4859 }
4860 
4861 # Generate 322 keyset key 85 value as 1/0 indicating its presence/absence or
4862 # count of its presence in a molecule.
4863 #
4864 # Key 85 description: O-Br
4865 #
4866 sub _Generate322KeySetKey85 {
4867   my($This) = @_;
4868   my($BondSymbol) = '-';
4869 
4870   return $This->_DetectBondKeys('O', 'Br', $BondSymbol);
4871 }
4872 
4873 # Generate 322 keyset key 86 value as 1/0 indicating its presence/absence or
4874 # count of its presence in a molecule.
4875 #
4876 # Key 86 description: O-Si
4877 #
4878 sub _Generate322KeySetKey86 {
4879   my($This) = @_;
4880   my($BondSymbol) = '-';
4881 
4882   return $This->_DetectBondKeys('O', 'Si', $BondSymbol);
4883 }
4884 
4885 # Generate 322 keyset key 87 value as 1/0 indicating its presence/absence or
4886 # count of its presence in a molecule.
4887 #
4888 # Key 87 description: O-I
4889 #
4890 sub _Generate322KeySetKey87 {
4891   my($This) = @_;
4892   my($BondSymbol) = '-';
4893 
4894   return $This->_DetectBondKeys('O', 'I', $BondSymbol);
4895 }
4896 
4897 # Generate 322 keyset key 88 value as 1/0 indicating its presence/absence or
4898 # count of its presence in a molecule.
4899 #
4900 # Key 88 description: O-X
4901 #
4902 sub _Generate322KeySetKey88 {
4903   my($This) = @_;
4904   my($BondSymbol) = '-';
4905 
4906   return $This->_DetectBondKeys('O', 'Z', $BondSymbol);
4907 }
4908 
4909 # Generate 322 keyset key 89 value as 1/0 indicating its presence/absence or
4910 # count of its presence in a molecule.
4911 #
4912 # Key 89 description: S-S
4913 #
4914 sub _Generate322KeySetKey89 {
4915   my($This) = @_;
4916   my($BondSymbol) = '-';
4917 
4918   return $This->_DetectBondKeys('S', 'S', $BondSymbol);
4919 }
4920 
4921 # Generate 322 keyset key 90 value as 1/0 indicating its presence/absence or
4922 # count of its presence in a molecule.
4923 #
4924 # Key 90 description: S-Cl
4925 #
4926 sub _Generate322KeySetKey90 {
4927   my($This) = @_;
4928   my($BondSymbol) = '-';
4929 
4930   return $This->_DetectBondKeys('S', 'Cl', $BondSymbol);
4931 }
4932 
4933 # Generate 322 keyset key 91 value as 1/0 indicating its presence/absence or
4934 # count of its presence in a molecule.
4935 #
4936 # Key 91 description: S-P
4937 #
4938 sub _Generate322KeySetKey91 {
4939   my($This) = @_;
4940   my($BondSymbol) = '-';
4941 
4942   return $This->_DetectBondKeys('S', 'P', $BondSymbol);
4943 }
4944 
4945 # Generate 322 keyset key 92 value as 1/0 indicating its presence/absence or
4946 # count of its presence in a molecule.
4947 #
4948 # Key 92 description: S-F
4949 #
4950 sub _Generate322KeySetKey92 {
4951   my($This) = @_;
4952   my($BondSymbol) = '-';
4953 
4954   return $This->_DetectBondKeys('S', 'F', $BondSymbol);
4955 }
4956 
4957 # Generate 322 keyset key 93 value as 1/0 indicating its presence/absence or
4958 # count of its presence in a molecule.
4959 #
4960 # Key 93 description: S-Br
4961 #
4962 sub _Generate322KeySetKey93 {
4963   my($This) = @_;
4964   my($BondSymbol) = '-';
4965 
4966   return $This->_DetectBondKeys('S', 'Br', $BondSymbol);
4967 }
4968 
4969 # Generate 322 keyset key 94 value as 1/0 indicating its presence/absence or
4970 # count of its presence in a molecule.
4971 #
4972 # Key 94 description: S-Si
4973 #
4974 sub _Generate322KeySetKey94 {
4975   my($This) = @_;
4976   my($BondSymbol) = '-';
4977 
4978   return $This->_DetectBondKeys('S', 'Si', $BondSymbol);
4979 }
4980 
4981 # Generate 322 keyset key 95 value as 1/0 indicating its presence/absence or
4982 # count of its presence in a molecule.
4983 #
4984 # Key 95 description: S-I
4985 #
4986 sub _Generate322KeySetKey95 {
4987   my($This) = @_;
4988   my($BondSymbol) = '-';
4989 
4990   return $This->_DetectBondKeys('S', 'I', $BondSymbol);
4991 }
4992 
4993 # Generate 322 keyset key 96 value as 1/0 indicating its presence/absence or
4994 # count of its presence in a molecule.
4995 #
4996 # Key 96 description: S-X
4997 #
4998 sub _Generate322KeySetKey96 {
4999   my($This) = @_;
5000   my($BondSymbol) = '-';
5001 
5002   return $This->_DetectBondKeys('S', 'Z', $BondSymbol);
5003 }
5004 
5005 # Generate 322 keyset key 97 value as 1/0 indicating its presence/absence or
5006 # count of its presence in a molecule.
5007 #
5008 # Key 97 description: Cl-Cl
5009 #
5010 sub _Generate322KeySetKey97 {
5011   my($This) = @_;
5012   my($BondSymbol) = '-';
5013 
5014   return $This->_DetectBondKeys('Cl', 'Cl', $BondSymbol);
5015 }
5016 
5017 # Generate 322 keyset key 98 value as 1/0 indicating its presence/absence or
5018 # count of its presence in a molecule.
5019 #
5020 # Key 98 description: Cl-P
5021 #
5022 sub _Generate322KeySetKey98 {
5023   my($This) = @_;
5024   my($BondSymbol) = '-';
5025 
5026   return $This->_DetectBondKeys('Cl', 'P', $BondSymbol);
5027 }
5028 
5029 # Generate 322 keyset key 99 value as 1/0 indicating its presence/absence or
5030 # count of its presence in a molecule.
5031 #
5032 # Key 99 description: Cl-F
5033 #
5034 sub _Generate322KeySetKey99 {
5035   my($This) = @_;
5036   my($BondSymbol) = '-';
5037 
5038   return $This->_DetectBondKeys('Cl', 'F', $BondSymbol);
5039 }
5040 
5041 # Generate 322 keyset key 100 value as 1/0 indicating its presence/absence or
5042 # count of its presence in a molecule.
5043 #
5044 # Key 100 description: Cl-Br
5045 #
5046 sub _Generate322KeySetKey100 {
5047   my($This) = @_;
5048   my($BondSymbol) = '-';
5049 
5050   return $This->_DetectBondKeys('Cl', 'Br', $BondSymbol);
5051 }
5052 
5053 # Generate 322 keyset key 101 value as 1/0 indicating its presence/absence or
5054 # count of its presence in a molecule.
5055 #
5056 # Key 101 description: Cl-Si
5057 #
5058 sub _Generate322KeySetKey101 {
5059   my($This) = @_;
5060   my($BondSymbol) = '-';
5061 
5062   return $This->_DetectBondKeys('Cl', 'Si', $BondSymbol);
5063 }
5064 
5065 # Generate 322 keyset key 102 value as 1/0 indicating its presence/absence or
5066 # count of its presence in a molecule.
5067 #
5068 # Key 102 description: Cl-I
5069 #
5070 sub _Generate322KeySetKey102 {
5071   my($This) = @_;
5072   my($BondSymbol) = '-';
5073 
5074   return $This->_DetectBondKeys('Cl', 'I', $BondSymbol);
5075 }
5076 
5077 # Generate 322 keyset key 103 value as 1/0 indicating its presence/absence or
5078 # count of its presence in a molecule.
5079 #
5080 # Key 103 description: Cl-X
5081 #
5082 sub _Generate322KeySetKey103 {
5083   my($This) = @_;
5084   my($BondSymbol) = '-';
5085 
5086   return $This->_DetectBondKeys('Cl', 'Z', $BondSymbol);
5087 }
5088 
5089 # Generate 322 keyset key 104 value as 1/0 indicating its presence/absence or
5090 # count of its presence in a molecule.
5091 #
5092 # Key 104 description: P-P
5093 #
5094 sub _Generate322KeySetKey104 {
5095   my($This) = @_;
5096   my($BondSymbol) = '-';
5097 
5098   return $This->_DetectBondKeys('P', 'P', $BondSymbol);
5099 }
5100 
5101 # Generate 322 keyset key 105 value as 1/0 indicating its presence/absence or
5102 # count of its presence in a molecule.
5103 #
5104 # Key 105 description: P-F
5105 #
5106 sub _Generate322KeySetKey105 {
5107   my($This) = @_;
5108   my($BondSymbol) = '-';
5109 
5110   return $This->_DetectBondKeys('P'