1 package AtomTypes::TPSAAtomTypes; 2 # 3 # $RCSfile: TPSAAtomTypes.pm,v $ 4 # $Date: 2015/02/28 20:48:03 $ 5 # $Revision: 1.15 $ 6 # 7 # Author: Manish Sud <msud@san.rr.com> 8 # 9 # Copyright (C) 2015 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 Scalar::Util (); 33 use Text::ParseWords; 34 use AtomTypes::AtomTypes; 35 use Molecule; 36 37 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); 38 39 @ISA = qw(AtomTypes::AtomTypes Exporter); 40 @EXPORT = qw(GetTPSAAtomTypesData GetAllPossibleTPSAAtomTypes); 41 @EXPORT_OK = qw(); 42 43 %EXPORT_TAGS = (all => [@EXPORT, @EXPORT_OK]); 44 45 # Setup class variables... 46 my($ClassName, %TPSAAtomTypesDataMap); 47 _InitializeClass(); 48 49 # Overload Perl functions... 50 use overload '""' => 'StringifyTPSAAtomTypes'; 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->_InitializeTPSAAtomTypes(); 60 61 $This->_InitializeTPSAAtomTypesProperties(%NamesAndValues); 62 63 return $This; 64 } 65 66 # Initialize class ... 67 sub _InitializeClass { 68 #Class name... 69 $ClassName = __PACKAGE__; 70 71 # Initialize the data hash. It'll be loaded on demand later... 72 %TPSAAtomTypesDataMap = (); 73 } 74 75 # Initialize object data... 76 # 77 sub _InitializeTPSAAtomTypes { 78 my($This) = @_; 79 80 # Type of AtomTypes... 81 $This->{Type} = 'TPSA'; 82 83 # Besides polar atoms - N, O, P, S - no TPSA atom types are assigned to any other 84 # atoms. 85 # 86 # By default, TPSA atom types are not assigned to Phosphorus and Sulfur atoms. 87 # 88 $This->{IgnorePhosphorus} = 0; 89 $This->{IgnoreSulfur} = 0; 90 91 return $This; 92 } 93 94 # Initialize object properties... 95 # 96 sub _InitializeTPSAAtomTypesProperties { 97 my($This, %NamesAndValues) = @_; 98 99 my($Name, $Value, $MethodName); 100 while (($Name, $Value) = each %NamesAndValues) { 101 $MethodName = "Set${Name}"; 102 $This->$MethodName($Value); 103 } 104 105 # Make sure molecule object was specified... 106 if (!exists $NamesAndValues{Molecule}) { 107 croak "Error: ${ClassName}->New: Object can't be instantiated without specifying molecule..."; 108 } 109 110 return $This; 111 } 112 113 # Get TPSA atom types and associated data loaded from TPSA data file as 114 # a reference to hash with the following hash data format: 115 # 116 # @{$TPSAAtomTypesDataMap{AtomTypes}} - Array of all possible atom types for all atoms 117 # @{$TPSAAtomTypesDataMap->{ColLabels}} - Array of column labels 118 # %{$TPSAAtomTypesDataMap->{DataCol<Num>}} - Hash keys pair: <DataCol<Num>, AtomType> 119 # 120 # This functionality can be either invoked as a class function or an 121 # object method. 122 # 123 sub GetTPSAAtomTypesData { 124 125 # Make sure data is loaded... 126 _CheckAndLoadTPSAAtomTypesData(); 127 128 return \%TPSAAtomTypesDataMap; 129 } 130 131 # Get all possible TPSA atom types atoms as an array reference... 132 # 133 # This functionality can be either invoked as a class function or an 134 # object method. 135 # 136 sub GetAllPossibleTPSAAtomTypes { 137 return _GetAllPossibleTPSAAtomTypes(); 138 } 139 140 # Are all atoms types successfully assigned? 141 # 142 # Notes: 143 # . Dynamic checking of atom types assignment for atoms eliminates the need 144 # to check and synchronize valid atom types during SetAtomType. 145 # . Base class method is overrided to check atom assignment to nitrogen and 146 # oxygen atom with optional check for phosphorus and sulfur atoms. 147 # 148 sub IsAtomTypesAssignmentSuccessful { 149 my($This) = @_; 150 my($Atom, $AtomType); 151 152 ATOM: for $Atom ($This->{Molecule}->GetAtoms()) { 153 if (!($Atom->IsNitrogen() || $Atom->IsOxygen() || 154 ($Atom->IsPhosphorus() && !$This->{IgnorePhosphorus}) || 155 ($Atom->IsSulfur() && !$This->{IgnoreSulfur}))) { 156 next ATOM; 157 } 158 $AtomType = $This->GetAtomType($Atom); 159 if ($AtomType =~ /^None$/i) { 160 return 0; 161 } 162 } 163 164 return 1; 165 } 166 167 # Get all possible TPSA atom types as an array reference... 168 # 169 sub _GetAllPossibleTPSAAtomTypes { 170 my($TPSAAtomTypesDataRef); 171 172 $TPSAAtomTypesDataRef = GetTPSAAtomTypesData(); 173 174 return \@{$TPSAAtomTypesDataRef->{AtomTypes}}; 175 } 176 177 # Assign Topological Polar Surface Area (TPSA) atom types [ Ref 90-91 ] to Nitrogen and Oxygen 178 # atoms with optional assignment to Phosphorus and Sulfur atoms. 179 # 180 # Notes: 181 # o Number of atom type symbols for: 182 # o N: 27 183 # o O: 7 184 # o P: 5 185 # o S: 8 186 # 187 sub AssignAtomTypes { 188 my($This) = @_; 189 my($Atom, $AtomType); 190 191 ATOM: for $Atom ($This->GetMolecule()->GetAtoms()) { 192 $AtomType = $This->_GetAtomType($Atom); 193 $This->SetAtomType($Atom, $AtomType); 194 } 195 196 return $This; 197 } 198 199 # Get TPSA atom type for atom... 200 # 201 sub _GetAtomType { 202 my($This, $Atom) = @_; 203 my($AtomType); 204 205 $AtomType = 'None'; 206 207 ATOM: { 208 if ($Atom->IsNitrogen()) { 209 $AtomType = $This->_GetAtomTypeForNitrogen($Atom); 210 last ATOM; 211 } 212 213 if ($Atom->IsOxygen()) { 214 $AtomType = $This->_GetAtomTypeForOxygen($Atom); 215 last ATOM; 216 } 217 218 if ($Atom->IsPhosphorus() && !$This->{IgnorePhosphorus}) { 219 $AtomType = $This->_GetAtomTypeForPhosphorus($Atom); 220 last ATOM; 221 } 222 223 if ($Atom->IsSulfur() && !$This->{IgnoreSulfur}) { 224 $AtomType = $This->_GetAtomTypeForSulfur($Atom); 225 last ATOM; 226 } 227 $AtomType = 'None'; 228 } 229 230 return $AtomType; 231 } 232 233 234 # Get TPSA atom type for Nitrogen atom... 235 # 236 # 27 AtomTypeSymbols for element N: 237 # 238 # AtomTypeSymbol - SMARTS - Comments 239 # N1 - '[N](-*)(-*)-*' 240 # N2 - '[N](-*)=*' 241 # N3 - '[N]#*' 242 # N4 - '[N](-*)(=*)=*' - As in nitro group 243 # N5 - '[N](=*)#*' - Middle nitrogen in azide group 244 # N6 - '[N]1(-*)-*-*-1' - Atom in a 3 membered ring 245 # N7 - '[NH](-*)-*' 246 # N8 - '[NH]1-*-*-1' - Atom in a 3 membered ring 247 # N9 - '[NH]=*' 248 # N10 - '[NH2]-*' 249 # N11 - '[N+](-*)(-*)(-*)-*' 250 # N12 - '[N+](-*)(-*)=*' 251 # N13 - '[N+](-*)#*' - Nitrogen in isocyano group 252 # N14 - '[NH+](-*)(-*)-*' 253 # N15 - '[NH+](-*)=*' 254 # N16 - '[NH2+](-*)-*' 255 # N17 - '[NH2+]=*' 256 # N18 - '[NH3+]-*' 257 # N19 - '[n](:*):*' 258 # N20 - '[n](:*)(:*):*' 259 # N21 - '[n](-*)(:*):*' 260 # N22 - '[n](=*)(:*):*' - As in pyridine N-oxide 261 # N23 - '[nH](:*):*' 262 # N24 - '[n+](:*)(:*):*' 263 # N25 - '[n+](-*)(:*):*' 264 # N26 - '[nH+](:*):*' 265 # N - '[#7]' - Any other Nitrogen; Contribution: 30.5 - X*8.2 + H*1.5 or 0.0 for negative value 266 # 267 sub _GetAtomTypeForNitrogen { 268 my($This, $Atom) = @_; 269 my($AtomType, $NumOfSigmaBonds, $NumOfPiBonds); 270 271 $AtomType = 'None'; 272 273 ($NumOfSigmaBonds, $NumOfPiBonds) = ('0') x 2; 274 275 ($NumOfSigmaBonds, $NumOfPiBonds) = $Atom->GetNumOfSigmaAndPiBondsToNonHydrogenAtoms(); 276 $NumOfSigmaBonds += $Atom->GetAtomicInvariantValue('H'); 277 278 ATOMTYPE: { 279 280 # Aromatic Nitrogens... 281 if ($Atom->IsAromatic()) { 282 $AtomType = $This->_GetAtomTypeForAromaticNitrogen($Atom); 283 last ATOMTYPE; 284 } 285 286 # Only single bonds... 287 if ($NumOfPiBonds == 0) { 288 $AtomType = $This->_GetAtomTypeForNitrogenWithOnlySigmaBonds($Atom); 289 last ATOMTYPE; 290 } 291 292 # One double bond... 293 if ($NumOfPiBonds == 1) { 294 $AtomType = $This->_GetAtomTypeForNitrogenWithOnePiBond($Atom); 295 last ATOMTYPE; 296 } 297 298 # One triple bond or two double bonds... 299 if ($NumOfPiBonds == 2) { 300 $AtomType = $This->_GetAtomTypeForNitrogenWithTwoPiBonds($Atom); 301 last ATOMTYPE; 302 } 303 304 # One triple bond and a double bond... 305 if ($NumOfPiBonds == 3) { 306 $AtomType = $This->_GetAtomTypeForNitrogenWithThreePiBonds($Atom); 307 last ATOMTYPE; 308 } 309 310 $AtomType = 'N'; 311 } 312 return $AtomType; 313 } 314 315 # Get TPSA atom type for Oxygen atom... 316 # 317 # AtomTypeSymbol - SMARTS - Comments 318 # O1 - '[O](-*)-*' 319 # O2 - '[O]1-*-*-1' - Atom in a 3 membered ring 320 # O3 - '[O]=*' 321 # O4 - '[OH]-*' 322 # O5 - '[O-]-*' 323 # O6 - '[o](:*):*' 324 # O - '[#8]' - Any other Oxygen; Contribution: 28.5 - X*8.6 + H*1.5 or 0.0 for negative value 325 # 326 sub _GetAtomTypeForOxygen { 327 my($This, $Atom) = @_; 328 my($AtomType); 329 330 $AtomType = 'None'; 331 332 ATOMTYPE: { 333 334 # O6 - '[o](:*):*' 335 if ($This->_IsO6Oxygen($Atom)) { 336 $AtomType = 'O6'; 337 last ATOMTYPE; 338 } 339 340 # O3 - '[O]=*' 341 if ($This->_IsO3Oxygen($Atom)) { 342 $AtomType = 'O3'; 343 last ATOMTYPE; 344 } 345 346 # O4 - '[OH]-*' 347 if ($This->_IsO4Oxygen($Atom)) { 348 $AtomType = 'O4'; 349 last ATOMTYPE; 350 } 351 352 # O5 - '[O-]-*' 353 if ($This->_IsO5Oxygen($Atom)) { 354 $AtomType = 'O5'; 355 last ATOMTYPE; 356 } 357 358 # O2 - '[O]1-*-*-1' - Atom in a 3 membered ring 359 if ($This->_IsO2Oxygen($Atom)) { 360 $AtomType = 'O2'; 361 last ATOMTYPE; 362 } 363 364 # O1 - '[O](-*)-*' 365 if ($This->_IsO1Oxygen($Atom)) { 366 $AtomType = 'O1'; 367 last ATOMTYPE; 368 } 369 370 # Any other Oxygen... 371 $AtomType = 'O'; 372 } 373 374 return $AtomType; 375 } 376 377 # Get TPSA atom type for Phosphorus atom... 378 # 379 # 4 AtomTypeSymbols for element P: 380 # 381 # AtomTypeSymbol - SMARTS - Comments 382 # P1 - '[P](-*)(-*)-*' 383 # P2 - '[P](-*)=*' 384 # P3 - '[P](-*)(-*)(-*)=*' 385 # P4 - '[PH](-*)(-*)=*' 386 # P - '[#15]' - Any other Sulfur 387 # 388 sub _GetAtomTypeForPhosphorus { 389 my($This, $Atom) = @_; 390 my($AtomType); 391 392 $AtomType = 'None'; 393 394 ATOMTYPE: { 395 396 # P1 - '[P](-*)(-*)-*' 397 if ($This->_IsP1Phosphorus($Atom)) { 398 $AtomType = 'P1'; 399 last ATOMTYPE; 400 } 401 402 # P2 - '[P](-*)=*' 403 if ($This->_IsP2Phosphorus($Atom)) { 404 $AtomType = 'P2'; 405 last ATOMTYPE; 406 } 407 408 # P3 - '[P](-*)(-*)(-*)=*' 409 if ($This->_IsP3Phosphorus($Atom)) { 410 $AtomType = 'P3'; 411 last ATOMTYPE; 412 } 413 414 # P4 - '[PH](-*)(-*)=*' 415 if ($This->_IsP4Phosphorus($Atom)) { 416 $AtomType = 'P4'; 417 last ATOMTYPE; 418 } 419 420 # Any other Phosphorus... 421 $AtomType = 'P'; 422 } 423 424 return $AtomType; 425 } 426 427 # Get TPSA atom type for Sulfur atom... 428 # 429 # 7 AtomTypeSymbols for element S: 430 # 431 # AtomTypeSymbol - SMARTS - Comments 432 # S1 - '[S](-*)-*' 433 # S2 - '[S]=*' 434 # S3 - '[S](-*)(-*)=*' 435 # S4 - '[S](-*)(-*)(=*)=*' 436 # S5 - '[SH]-*' 437 # S6 - '[s](:*):*' 438 # S - '[#16]' - Any other Phosphorus 439 # 440 sub _GetAtomTypeForSulfur { 441 my($This, $Atom) = @_; 442 my($AtomType); 443 444 $AtomType = 'None'; 445 446 ATOMTYPE: { 447 448 # S6 - '[s](:*):*' 449 if ($This->_IsS6Sulfur($Atom)) { 450 $AtomType = 'S6'; 451 last ATOMTYPE; 452 } 453 454 # S4 - '[S](-*)(-*)(=*)=*' 455 if ($This->_IsS4Sulfur($Atom)) { 456 $AtomType = 'S4'; 457 last ATOMTYPE; 458 } 459 460 # S1 - '[S](-*)-*' 461 if ($This->_IsS1Sulfur($Atom)) { 462 $AtomType = 'S1'; 463 last ATOMTYPE; 464 } 465 466 # S2 - '[S]=*' 467 if ($This->_IsS2Sulfur($Atom)) { 468 $AtomType = 'S2'; 469 last ATOMTYPE; 470 } 471 472 # S3 - '[S](-*)(-*)=*' 473 if ($This->_IsS3Sulfur($Atom)) { 474 $AtomType = 'S3'; 475 last ATOMTYPE; 476 } 477 478 # S5 - '[SH]-*' 479 if ($This->_IsS5Sulfur($Atom)) { 480 $AtomType = 'S5'; 481 last ATOMTYPE; 482 } 483 484 # Any other Sulfur... 485 $AtomType = 'S'; 486 } 487 488 return $AtomType; 489 } 490 491 # Get TPSA atom type for aromatic Nitrogen... 492 # 493 sub _GetAtomTypeForAromaticNitrogen { 494 my($This, $Atom) = @_; 495 my($AtomType); 496 497 $AtomType = 'None'; 498 499 ATOMTYPE: { 500 501 # N19 - '[n](:*):*' 502 if ($This->_IsN19Nitrogen($Atom)) { 503 $AtomType = 'N19'; 504 last ATOMTYPE; 505 } 506 507 # N20 - '[n](:*)(:*):*' 508 if ($This->_IsN20Nitrogen($Atom)) { 509 $AtomType = 'N20'; 510 last ATOMTYPE; 511 } 512 513 # N21 - '[n](-*)(:*):*' 514 if ($This->_IsN21Nitrogen($Atom)) { 515 $AtomType = 'N21'; 516 last ATOMTYPE; 517 } 518 519 # N22 - '[n](=*)(:*):*' - As in pyridine N-oxide 520 if ($This->_IsN22Nitrogen($Atom)) { 521 $AtomType = 'N22'; 522 last ATOMTYPE; 523 } 524 525 # N23 - '[nH](:*):*' 526 if ($This->_IsN23Nitrogen($Atom)) { 527 $AtomType = 'N23'; 528 last ATOMTYPE; 529 } 530 531 # N24 - '[n+](:*)(:*):*' 532 if ($This->_IsN24Nitrogen($Atom)) { 533 $AtomType = 'N24'; 534 last ATOMTYPE; 535 } 536 537 # N25 - '[n+](-*)(:*):*' 538 if ($This->_IsN25Nitrogen($Atom)) { 539 $AtomType = 'N25'; 540 last ATOMTYPE; 541 } 542 543 # N26 - '[nH+](:*):*' 544 if ($This->_IsN26Nitrogen($Atom)) { 545 $AtomType = 'N26'; 546 last ATOMTYPE; 547 } 548 549 $AtomType = 'N'; 550 } 551 552 return $AtomType; 553 } 554 555 # Get TPSA atom type for Nitrogen with only sigma bonds... 556 # 557 sub _GetAtomTypeForNitrogenWithOnlySigmaBonds { 558 my($This, $Atom) = @_; 559 my($AtomType); 560 561 $AtomType = 'None'; 562 563 ATOMTYPE: { 564 565 # N6 - '[N]1(-*)-*-*-1' - Atom in a 3 membered ring 566 if ($This->_IsN6Nitrogen($Atom)) { 567 $AtomType = 'N6'; 568 last ATOMTYPE; 569 } 570 571 # N1 - '[N](-*)(-*)-*' 572 if ($This->_IsN1Nitrogen($Atom)) { 573 $AtomType = 'N1'; 574 last ATOMTYPE; 575 } 576 577 # N8 - '[NH]1-*-*-1' - Atom in a 3 membered ring 578 if ($This->_IsN8Nitrogen($Atom)) { 579 $AtomType = 'N8'; 580 last ATOMTYPE; 581 } 582 583 # N7 - '[NH](-*)-*' 584 if ($This->_IsN7Nitrogen($Atom)) { 585 $AtomType = 'N7'; 586 last ATOMTYPE; 587 } 588 589 # N10 - '[NH2]-*' 590 if ($This->_IsN10Nitrogen($Atom)) { 591 $AtomType = 'N10'; 592 last ATOMTYPE; 593 } 594 595 # N11 - '[N+](-*)(-*)(-*)-*' 596 if ($This->_IsN11Nitrogen($Atom)) { 597 $AtomType = 'N11'; 598 last ATOMTYPE; 599 } 600 601 # N14 - '[NH+](-*)(-*)-*' 602 if ($This->_IsN14Nitrogen($Atom)) { 603 $AtomType = 'N14'; 604 last ATOMTYPE; 605 } 606 607 # N16 - '[NH2+](-*)-*' 608 if ($This->_IsN16Nitrogen($Atom)) { 609 $AtomType = 'N16'; 610 last ATOMTYPE; 611 } 612 613 # N18 - '[NH3+]-*' 614 if ($This->_IsN18Nitrogen($Atom)) { 615 $AtomType = 'N18'; 616 last ATOMTYPE; 617 } 618 619 $AtomType = 'N'; 620 } 621 622 return $AtomType; 623 } 624 625 # Get TPSA atom type for Nitrogen with one pi bonds... 626 # 627 sub _GetAtomTypeForNitrogenWithOnePiBond { 628 my($This, $Atom) = @_; 629 my($AtomType); 630 631 $AtomType = 'None'; 632 633 ATOMTYPE: { 634 635 # N2 - '[N](-*)=*' 636 if ($This->_IsN2Nitrogen($Atom)) { 637 $AtomType = 'N2'; 638 last ATOMTYPE; 639 } 640 641 # N9 - '[NH]=*' 642 if ($This->_IsN9Nitrogen($Atom)) { 643 $AtomType = 'N9'; 644 last ATOMTYPE; 645 } 646 647 # N12 - '[N+](-*)(-*)=*' 648 if ($This->_IsN12Nitrogen($Atom)) { 649 $AtomType = 'N12'; 650 last ATOMTYPE; 651 } 652 653 # N15 - '[NH+](-*)=*' 654 if ($This->_IsN15Nitrogen($Atom)) { 655 $AtomType = 'N15'; 656 last ATOMTYPE; 657 } 658 659 # N17 - '[NH2+]=*' 660 if ($This->_IsN17Nitrogen($Atom)) { 661 $AtomType = 'N17'; 662 last ATOMTYPE; 663 } 664 665 $AtomType = 'N'; 666 } 667 668 return $AtomType; 669 } 670 671 # Get TPSA atom type for Nitrogen with two pi bonds... 672 # 673 sub _GetAtomTypeForNitrogenWithTwoPiBonds { 674 my($This, $Atom) = @_; 675 my($AtomType); 676 677 $AtomType = 'None'; 678 679 ATOMTYPE: { 680 681 # N3 - '[N]#*' 682 if ($This->_IsN3Nitrogen($Atom)) { 683 $AtomType = 'N3'; 684 last ATOMTYPE; 685 } 686 687 # N4 - '[N](-*)(=*)=*' - As in nitro group 688 if ($This->_IsN4Nitrogen($Atom)) { 689 $AtomType = 'N4'; 690 last ATOMTYPE; 691 } 692 693 # N13 - '[N+](-*)#*'- Nitrogen in isocyano group 694 if ($This->_IsN13Nitrogen($Atom)) { 695 $AtomType = 'N13'; 696 last ATOMTYPE; 697 } 698 699 $AtomType = 'N'; 700 } 701 702 return $AtomType; 703 } 704 705 # Get TPSA atom type for Nitrogen with three pi bonds... 706 # 707 sub _GetAtomTypeForNitrogenWithThreePiBonds { 708 my($This, $Atom) = @_; 709 my($AtomType); 710 711 $AtomType = 'None'; 712 713 ATOMTYPE: { 714 715 # N5 - '[N](=*)#*' - Middle nitrogen in azide group 716 if ($This->_IsN5Nitrogen($Atom)) { 717 $AtomType = 'N5'; 718 last ATOMTYPE; 719 } 720 721 $AtomType = 'N'; 722 } 723 724 return $AtomType; 725 } 726 727 # N1 - '[N](-*)(-*)-*' 728 # 729 sub _IsN1Nitrogen { 730 my($This, $Atom) = @_; 731 732 return $Atom->DoesAtomNeighborhoodMatch('N.!RA3.X3.SB3.H0.FC0') ? 1 : 0; 733 } 734 735 # N2 - '[N](-*)=*' 736 # 737 sub _IsN2Nitrogen { 738 my($This, $Atom) = @_; 739 740 return $Atom->DoesAtomNeighborhoodMatch('N.X2.SB1.DB1.H0.FC0') ? 1 : 0; 741 } 742 743 # N3 - '[N]#*' 744 # 745 sub _IsN3Nitrogen { 746 my($This, $Atom) = @_; 747 748 return $Atom->DoesAtomNeighborhoodMatch('N.X1.TB1.H0.FC0') ? 1 : 0; 749 } 750 751 # N4 - '[N](-*)(=*)=*' - As in nitro group 752 # 753 sub _IsN4Nitrogen { 754 my($This, $Atom) = @_; 755 756 return $Atom->DoesAtomNeighborhoodMatch('N.X3.SB1.DB2.H0.FC0') ? 1 : 0; 757 } 758 759 # N5 - '[N](=*)#*' - Middle nitrogen in azide group 760 # 761 sub _IsN5Nitrogen { 762 my($This, $Atom) = @_; 763 764 return $Atom->DoesAtomNeighborhoodMatch('N.X2.DB1.TB1.H0.FC0') ? 1 : 0; 765 } 766 767 # N6 - '[N]1(-*)-*-*-1' - Atom in a 3 membered ring 768 # 769 sub _IsN6Nitrogen { 770 my($This, $Atom) = @_; 771 772 return $Atom->DoesAtomNeighborhoodMatch('N.RA3.X3.SB3.H0.FC0') ? 1 : 0; 773 } 774 775 # N7 - '[NH](-*)-*' 776 # 777 sub _IsN7Nitrogen { 778 my($This, $Atom) = @_; 779 780 return $Atom->DoesAtomNeighborhoodMatch('N.!RA3.X2.SB2.H1.FC0') ? 1 : 0; 781 } 782 783 # N8 - '[NH]1-*-*-1' - Atom in a 3 membered ring 784 # 785 sub _IsN8Nitrogen { 786 my($This, $Atom) = @_; 787 788 return $Atom->DoesAtomNeighborhoodMatch('N.RA3.X2.SB2.H1.FC0') ? 1 : 0; 789 } 790 791 # N9 - '[NH]=*' 792 # 793 sub _IsN9Nitrogen { 794 my($This, $Atom) = @_; 795 796 return $Atom->DoesAtomNeighborhoodMatch('N.X1.DB1.H1.FC0') ? 1 : 0; 797 } 798 799 # N10 - '[NH2]-*' 800 # 801 sub _IsN10Nitrogen { 802 my($This, $Atom) = @_; 803 804 return $Atom->DoesAtomNeighborhoodMatch('N.X1.SB1.H2.FC0') ? 1 : 0; 805 } 806 807 # N11 - '[N+](-*)(-*)(-*)-*' 808 # 809 sub _IsN11Nitrogen { 810 my($This, $Atom) = @_; 811 812 return $Atom->DoesAtomNeighborhoodMatch('N.X4.SB4.H0.FC+1') ? 1 : 0; 813 } 814 815 # N12 - '[N+](-*)(-*)=*' 816 # 817 sub _IsN12Nitrogen { 818 my($This, $Atom) = @_; 819 820 return $Atom->DoesAtomNeighborhoodMatch('N.X3.SB2.DB1.H0.FC+1') ? 1 : 0; 821 } 822 823 # N13 - '[N+](-*)#*'- Nitrogen in isocyano group 824 # 825 sub _IsN13Nitrogen { 826 my($This, $Atom) = @_; 827 828 return $Atom->DoesAtomNeighborhoodMatch('N.X2.SB1.TB1.H0.FC+1') ? 1 : 0; 829 } 830 831 # N14 - '[NH+](-*)(-*)-*' 832 # 833 sub _IsN14Nitrogen { 834 my($This, $Atom) = @_; 835 836 return $Atom->DoesAtomNeighborhoodMatch('N.X3.SB3.H1.FC+1') ? 1 : 0; 837 } 838 839 # N15 - '[NH+](-*)=*' 840 # 841 sub _IsN15Nitrogen { 842 my($This, $Atom) = @_; 843 844 return $Atom->DoesAtomNeighborhoodMatch('N.X2.SB1.DB1.H1.FC+1') ? 1 : 0; 845 } 846 847 # N16 - '[NH2+](-*)-*' 848 # 849 sub _IsN16Nitrogen { 850 my($This, $Atom) = @_; 851 852 return $Atom->DoesAtomNeighborhoodMatch('N.X2.SB2.H2.FC+1') ? 1 : 0; 853 } 854 855 # N17 - '[NH2+]=*' 856 # 857 sub _IsN17Nitrogen { 858 my($This, $Atom) = @_; 859 860 return $Atom->DoesAtomNeighborhoodMatch('N.X1.DB1.H2.FC+1') ? 1 : 0; 861 } 862 863 # N18 - '[NH3+]-*' 864 # 865 sub _IsN18Nitrogen { 866 my($This, $Atom) = @_; 867 868 return $Atom->DoesAtomNeighborhoodMatch('N.X1.SB1.H3.FC+1') ? 1 : 0; 869 } 870 871 # N19 - '[n](:*):*' 872 # 873 sub _IsN19Nitrogen { 874 my($This, $Atom) = @_; 875 876 return $Atom->DoesAtomNeighborhoodMatch('N.Ar.X2.AB2.H0.FC0') ? 1 : 0; 877 } 878 879 # N20 - '[n](:*)(:*):*' 880 # 881 sub _IsN20Nitrogen { 882 my($This, $Atom) = @_; 883 884 return $Atom->DoesAtomNeighborhoodMatch('N.Ar.X3.AB3.H0.FC0') ? 1 : 0; 885 } 886 887 # N21 - '[n](-*)(:*):*' 888 # 889 sub _IsN21Nitrogen { 890 my($This, $Atom) = @_; 891 892 return $Atom->DoesAtomNeighborhoodMatch('N.Ar.X3.AB2.H0.FC0', ['*', '*', '*'], [':', ':', '-']) ? 1 : 0; 893 } 894 895 # N22 - '[n](=*)(:*):*' - As in pyridine N-oxide 896 # 897 sub _IsN22Nitrogen { 898 my($This, $Atom) = @_; 899 900 return $Atom->DoesAtomNeighborhoodMatch('N.Ar.X3.AB2.H0.FC0', ['*', '*', '*'], [':', ':', '=']) ? 1 : 0; 901 } 902 903 # N23 - '[nH](:*):*' 904 # 905 sub _IsN23Nitrogen { 906 my($This, $Atom) = @_; 907 908 return $Atom->DoesAtomNeighborhoodMatch('N.Ar.X2.AB2.H1.FC0') ? 1 : 0; 909 } 910 911 # N24 - '[n+](:*)(:*):*' 912 # 913 sub _IsN24Nitrogen { 914 my($This, $Atom) = @_; 915 916 return $Atom->DoesAtomNeighborhoodMatch('N.Ar.X3.AB3.H0.FC+1') ? 1 : 0; 917 } 918 919 # N25 - '[n+](-*)(:*):*' 920 # 921 sub _IsN25Nitrogen { 922 my($This, $Atom) = @_; 923 924 return $Atom->DoesAtomNeighborhoodMatch('N.Ar.X3.AB2.H0.FC+1', ['*', '*', '*'], [':', ':', '-']) ? 1 : 0; 925 } 926 927 # N26 - '[nH+](:*):*' 928 # 929 sub _IsN26Nitrogen { 930 my($This, $Atom) = @_; 931 932 return $Atom->DoesAtomNeighborhoodMatch('N.Ar.X2.AB2.H1.FC+1') ? 1 : 0; 933 } 934 935 # O1 - '[O](-*)-*' 936 # 937 sub _IsO1Oxygen { 938 my($This, $Atom) = @_; 939 940 return $Atom->DoesAtomNeighborhoodMatch('O.!RA.X2.SB2.H0.FC0') ? 1 : 0; 941 } 942 943 # O2 - '[O]1-*-*-1' - Atom in a 3 membered ring 944 # 945 sub _IsO2Oxygen { 946 my($This, $Atom) = @_; 947 948 return $Atom->DoesAtomNeighborhoodMatch('O.RA3.X2.SB2.H0.FC0') ? 1 : 0; 949 } 950 951 # O3 - '[O]=*' 952 # 953 sub _IsO3Oxygen { 954 my($This, $Atom) = @_; 955 956 return $Atom->DoesAtomNeighborhoodMatch('O.X1.DB1.H0.FC0') ? 1 : 0; 957 } 958 959 # O4 - '[OH]-*' 960 # 961 sub _IsO4Oxygen { 962 my($This, $Atom) = @_; 963 964 return $Atom->DoesAtomNeighborhoodMatch('O.X1.SB1.H1.FC0') ? 1 : 0; 965 } 966 967 # O5 - '[O-]-*' 968 # 969 sub _IsO5Oxygen { 970 my($This, $Atom) = @_; 971 972 return $Atom->DoesAtomNeighborhoodMatch('O.X1.SB1.H0.FC-1') ? 1 : 0; 973 } 974 975 # O6 - '[o](:*):*' 976 # 977 sub _IsO6Oxygen { 978 my($This, $Atom) = @_; 979 980 return $Atom->DoesAtomNeighborhoodMatch('O.Ar.X2.AB2.H0.FC0') ? 1 : 0; 981 } 982 983 # P1 - '[P](-*)(-*)-*' 984 # 985 sub _IsP1Phosphorus { 986 my($This, $Atom) = @_; 987 988 return $Atom->DoesAtomNeighborhoodMatch('P.X3.SB3.H0.FC0') ? 1 : 0; 989 } 990 991 # P2 - '[P](-*)=*' 992 # 993 sub _IsP2Phosphorus { 994 my($This, $Atom) = @_; 995 996 return $Atom->DoesAtomNeighborhoodMatch('P.X2.SB1.DB1.H0.FC0') ? 1 : 0; 997 } 998 999 # P3 - '[P](-*)(-*)(-*)=*' 1000 # 1001 sub _IsP3Phosphorus { 1002 my($This, $Atom) = @_; 1003 1004 return $Atom->DoesAtomNeighborhoodMatch('P.X4.SB3.DB1.H0.FC0') ? 1 : 0; 1005 } 1006 1007 # P4 - '[PH](-*)(-*)=*' 1008 # 1009 sub _IsP4Phosphorus { 1010 my($This, $Atom) = @_; 1011 1012 return $Atom->DoesAtomNeighborhoodMatch('P.X3.SB2.DB1.H1.FC0') ? 1 : 0; 1013 } 1014 1015 # S1 - '[S](-*)-*' 1016 # 1017 sub _IsS1Sulfur { 1018 my($This, $Atom) = @_; 1019 1020 return $Atom->DoesAtomNeighborhoodMatch('S.X2.SB2.H0.FC0') ? 1 : 0; 1021 } 1022 1023 # S2 - '[S]=*' 1024 # 1025 sub _IsS2Sulfur { 1026 my($This, $Atom) = @_; 1027 1028 return $Atom->DoesAtomNeighborhoodMatch('S.X1.DB1.H0.FC0') ? 1 : 0; 1029 } 1030 1031 # S3 - '[S](-*)(-*)=*' 1032 # 1033 sub _IsS3Sulfur { 1034 my($This, $Atom) = @_; 1035 1036 return $Atom->DoesAtomNeighborhoodMatch('S.X3.SB2.DB1.H0.FC0') ? 1 : 0; 1037 } 1038 1039 # S4 - '[S](-*)(-*)(=*)=*' 1040 # 1041 sub _IsS4Sulfur { 1042 my($This, $Atom) = @_; 1043 1044 return $Atom->DoesAtomNeighborhoodMatch('S.X4.SB2.DB2.H0.FC0') ? 1 : 0; 1045 } 1046 1047 # S5 - '[SH]-*' 1048 # 1049 sub _IsS5Sulfur { 1050 my($This, $Atom) = @_; 1051 1052 return $Atom->DoesAtomNeighborhoodMatch('S.X1.SB1.H1.FC0') ? 1 : 0; 1053 } 1054 1055 # S6 - '[s](:*):*' 1056 # 1057 sub _IsS6Sulfur { 1058 my($This, $Atom) = @_; 1059 1060 return $Atom->DoesAtomNeighborhoodMatch('S.Ar.X2.AB2.H0.FC0') ? 1 : 0; 1061 } 1062 1063 # Return a string containg data for TPSAAtomTypes object... 1064 # 1065 sub StringifyTPSAAtomTypes { 1066 my($This) = @_; 1067 my($AtomTypesString); 1068 1069 # Type of AtomTypes... 1070 $AtomTypesString = "AtomTypes: $This->{Type}; IgnorePhosphorus: " . ($This->{IgnorePhosphorus} ? "Yes" : "No") . "; IgnoreSulfur: " . ($This->{IgnoreSulfur} ? "Yes" : "No"); 1071 1072 # Setup atom types information... 1073 my($AtomID, $AtomType, @AtomTypesInfo, %AssignedAtomTypes); 1074 1075 @AtomTypesInfo = (); 1076 %AssignedAtomTypes = $This->GetAtomTypes(); 1077 1078 for $AtomID (sort { $a <=> $b } keys %AssignedAtomTypes) { 1079 $AtomType = $AssignedAtomTypes{$AtomID} ? $AssignedAtomTypes{$AtomID} : 'None'; 1080 push @AtomTypesInfo, "$AtomID:$AtomType"; 1081 } 1082 $AtomTypesString .= "; AtomIDs:AtomTypes: <" . TextUtil::JoinWords(\@AtomTypesInfo, ", ", 0) . ">"; 1083 1084 return $AtomTypesString; 1085 } 1086 1087 # Is it a TPSAAtomTypes object? 1088 sub _IsTPSAAtomTypes { 1089 my($Object) = @_; 1090 1091 return (Scalar::Util::blessed($Object) && $Object->isa($ClassName)) ? 1 : 0; 1092 } 1093 1094 # Check and load TPSA atom types data... 1095 # 1096 sub _CheckAndLoadTPSAAtomTypesData { 1097 1098 # Is it already loaded? 1099 if (exists $TPSAAtomTypesDataMap{AtomTypes}) { 1100 return; 1101 } 1102 1103 _LoadTPSAAtomTypesData(); 1104 } 1105 1106 # Load TPSA atom types data from the file assuming first column to be atom type symbol.. 1107 # 1108 # Format: 1109 # 1110 # "AtomType","SMARTS","TPSAContribution","Comments" 1111 # "N1","[N](-*)(-*)-*","3.24","" 1112 # "N2","[N](-*)=*","12.36","" 1113 # 1114 sub _LoadTPSAAtomTypesData { 1115 my($AtomTypesDataFile, $MayaChemToolsLibDir); 1116 1117 $MayaChemToolsLibDir = FileUtil::GetMayaChemToolsLibDirName(); 1118 1119 $AtomTypesDataFile = "$MayaChemToolsLibDir" . "/data/TPSAAtomTypes.csv"; 1120 if (! -e "$AtomTypesDataFile") { 1121 croak "Error: MayaChemTools package file, $AtomTypesDataFile, is missing: Possible installation problems..."; 1122 } 1123 1124 %TPSAAtomTypesDataMap = (); 1125 AtomTypes::AtomTypes::LoadAtomTypesData($AtomTypesDataFile, \%TPSAAtomTypesDataMap); 1126 } 1127