1 package AtomTypes::EStateAtomTypes; 2 # 3 # File: EStateAtomTypes.pm 4 # Author: Manish Sud <msud@san.rr.com> 5 # 6 # Copyright (C) 2024 Manish Sud. All rights reserved. 7 # 8 # This file is part of MayaChemTools. 9 # 10 # MayaChemTools is free software; you can redistribute it and/or modify it under 11 # the terms of the GNU Lesser General Public License as published by the Free 12 # Software Foundation; either version 3 of the License, or (at your option) any 13 # later version. 14 # 15 # MayaChemTools is distributed in the hope that it will be useful, but without 16 # any warranty; without even the implied warranty of merchantability of fitness 17 # for a particular purpose. See the GNU Lesser General Public License for more 18 # details. 19 # 20 # You should have received a copy of the GNU Lesser General Public License 21 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or 22 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330, 23 # Boston, MA, 02111-1307, USA. 24 # 25 26 use strict; 27 use Carp; 28 use Exporter; 29 use Scalar::Util (); 30 use AtomTypes::AtomTypes; 31 use Molecule; 32 33 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); 34 35 @ISA = qw(AtomTypes::AtomTypes Exporter); 36 @EXPORT = qw(GetEStateAtomTypesData GetAllPossibleEStateAtomTypes GetAllPossibleEStateNonHydrogenAtomTypes); 37 @EXPORT_OK = qw(); 38 39 %EXPORT_TAGS = (all => [@EXPORT, @EXPORT_OK]); 40 41 # Setup class variables... 42 my($ClassName, %EStateAtomTypesDataMap); 43 _InitializeClass(); 44 45 # Overload Perl functions... 46 use overload '""' => 'StringifyEStateAtomTypes'; 47 48 # Class constructor... 49 sub new { 50 my($Class, %NamesAndValues) = @_; 51 52 # Initialize object... 53 my $This = $Class->SUPER::new(); 54 bless $This, ref($Class) || $Class; 55 $This->_InitializeEStateAtomTypes(); 56 57 $This->_InitializeEStateAtomTypesProperties(%NamesAndValues); 58 59 return $This; 60 } 61 62 # Initialize class ... 63 sub _InitializeClass { 64 #Class name... 65 $ClassName = __PACKAGE__; 66 67 # Initialize the data hash. It'll be loaded on demand later... 68 %EStateAtomTypesDataMap = (); 69 } 70 71 # Initialize object data... 72 # 73 sub _InitializeEStateAtomTypes { 74 my($This) = @_; 75 76 # Type of AtomTypes... 77 $This->{Type} = 'EState'; 78 79 # By default, EState atom types are also assigned to hydrogens... 80 $This->{IgnoreHydrogens} = 0; 81 82 return $This; 83 } 84 85 # Initialize object properties... 86 # 87 sub _InitializeEStateAtomTypesProperties { 88 my($This, %NamesAndValues) = @_; 89 90 my($Name, $Value, $MethodName); 91 while (($Name, $Value) = each %NamesAndValues) { 92 $MethodName = "Set${Name}"; 93 $This->$MethodName($Value); 94 } 95 96 # Make sure molecule object was specified... 97 if (!exists $NamesAndValues{Molecule}) { 98 croak "Error: ${ClassName}->New: Object can't be instantiated without specifying molecule..."; 99 } 100 101 return $This; 102 } 103 104 # Get EState atom types and associated data loaded from EState data file as 105 # a reference to hash with the following hash data format: 106 # 107 # @{$EStateAtomTypesDataMap{AtomTypes}} - Array of all possible atom types for all atoms 108 # @{$EStateAtomTypesDataMap{NonHydrogenAtomTypes}} - Array of all possible atom types for non-hydrogen atoms 109 # @{$EStateAtomTypesDataMap->{ColLabels}} - Array of column labels 110 # %{$EStateAtomTypesDataMap->{DataCol<Num>}} - Hash keys pair: <DataCol<Num>, AtomType> 111 # 112 # This functionality can be either invoked as a class function or an 113 # object method. 114 # 115 sub GetEStateAtomTypesData { 116 117 # Make sure data is loaded... 118 _CheckAndLoadEStateAtomTypesData(); 119 120 return \%EStateAtomTypesDataMap; 121 } 122 123 # Get all possible E-state atom types corresponding to hydrogen and non-hydrogen 124 # atoms as an array reference... 125 # 126 # This functionality can be either invoked as a class function or an 127 # object method. 128 # 129 sub GetAllPossibleEStateAtomTypes { 130 return _GetAllPossibleEStateAtomTypes(); 131 } 132 133 # Get all possible E-state atom types corresponding to non-hydrogen atoms 134 # as an array reference... 135 # 136 # This functionality can be either invoked as a class function or an 137 # object method. 138 # 139 sub GetAllPossibleEStateNonHydrogenAtomTypes { 140 my($NonHydrogensOnly); 141 142 $NonHydrogensOnly = 1; 143 return _GetAllPossibleEStateAtomTypes($NonHydrogensOnly); 144 } 145 146 # Get all possible E-state atom types as an array reference... 147 # 148 sub _GetAllPossibleEStateAtomTypes { 149 my($NonHydrogensOnly) = @_; 150 my($EStateAtomTypesDataRef); 151 152 $NonHydrogensOnly = defined $NonHydrogensOnly ? $NonHydrogensOnly : 0; 153 154 $EStateAtomTypesDataRef = GetEStateAtomTypesData(); 155 156 return $NonHydrogensOnly ? \@{$EStateAtomTypesDataRef->{NonHydrogenAtomTypes}}: \@{$EStateAtomTypesDataRef->{AtomTypes}}; 157 } 158 159 # Assign electrotopological state (E-state) [ Ref 75-78 ] atom types to all atoms... 160 # 161 # E-state atom types for various different atom groups [Appendix Table 1 in Ref 76, Appendix III 162 # in Ref 77 ] are defined using central atom environments indicating its topological and valence state 163 # along with bonded hydrogens. 164 # 165 # The current release of MayaChemTools implements an extended E-state atom assignment 166 # methodology which is able to assign atom types to any valid non-hydrogen atom in any 167 # atom group instead of a fixed set of E-state atom types [ Ref 77]. 168 # 169 # Let: 170 # As = Atom symbol corresponding to element symbol 171 # 172 # H<n> = Number of implicit and explicit hydrogens for atom 173 # 174 # s = Single bond to non-hydrogen atom neighbors or heavy atoms attached to atom 175 # s<x> = Symbol s repeated x times to indicate multiple single bonds 176 # 177 # d = Double bond to non-hydrogen atom neighbors or heavy atoms attached to atom 178 # d<x> = Symbol d repeated x times to indicate multiple double bonds 179 # 180 # t = Triple bond to non-hydrogen atom neighbors or heavy atoms attached to atom 181 # t<x> = Symbol t repeated x times to indicate multiple triple bonds 182 # 183 # a = Aromatic to bond non-hydrogen atom neighbors or heavy atoms attached to atom 184 # t<x> = Symbol a repeated x times to indicate multiple aromatic bonds 185 # 186 # p = Plus or positive formal charge 187 # m = Minus or negative formal charge 188 # 189 # Then: 190 # 191 # AtomType specification corresponds to: 192 # 193 # t<x>d<x>a<x>s<x>AsH<n>p or t<x>d<x>a<x>s<x>AsH<n>m 194 # 195 # Notes: 196 # . p and n with values of 0 are not shown. 197 # . s, d, t, and a bond symbol with values of zero are not shown. 198 # . s and d bonds which are also aromatic don't contribute to the count of single and 199 # double bonds; instead, aromatic bond count reflect these bonds. 200 # . The E-state atom type assignment scheme implemented in the current release of 201 # MayaChemToools package supports assignment of atom types to all the periodic tab'e 202 # element. 203 # 204 # Hydrogen E-state [ Ref 76-77 ] atom type definitions: 205 # 206 # HGroup AtomType 207 # 208 # -OH HsOH 209 # -SH HsSH 210 # 211 # -NH2 HsNH2 212 # >NH HssNH 213 # =NH HdNH 214 # :NH: HaaNH 215 # -NH3+ HsNH3p 216 # >NH2+ HssNH2p 217 # >NH-+ HsssNHp 218 # 219 # #CH HtCH 220 # =CH2 HdCH2 - H attached to a terminal vinyl group 221 # =CH- HdsCH - H attached a non-terminal vinyl group 222 # :CH: HaaCH 223 # 224 # >CHF HCHF 225 # -CH2F HCH2F 226 # >CHCl HCHCl 227 # -CH2Cl HCH2Cl 228 # 229 # CHn (saturated) HCsats - H attached to sp3 carbon attached to saturated carbon(s) 230 # CHn (unsatd.) HCsatu - H attached to sp3 carbon attached to unsaturated carbon(s) 231 # 232 # CHn (aromatic) Havin - H attached to a non-terminal vinyl group, =CH-, attached to an aromatic carbon 233 # 234 # CHn Hother - H attached to any other type of C, N, O or S 235 # AHn Hmisc - H not attached to C, N, O or S 236 # 237 # Notes: 238 # . - : Single bond; = : Double bond; # : Triple bond 239 # . Hother atom type capture Hydrogen atom groups not explicitly defined. 240 # . HGroup doesn't explicitly corresponds to functional groups 241 # . -OH group could be a hydroxyl group or part of carboxylic acid group and so on 242 # . -NH2 group could be primary amine or part of an amide group and so on 243 # 244 sub AssignAtomTypes { 245 my($This) = @_; 246 my($Atom); 247 248 ATOM: for $Atom ($This->GetMolecule()->GetAtoms()) { 249 if ($Atom->IsHydrogen()) { 250 if (!$This->{IgnoreHydrogens}) { 251 $This->_AssignAtomTypeToHydrogenAtom($Atom); 252 } 253 next ATOM; 254 } 255 256 # Handle non-hydrogen atoms.. 257 $This->_AssignAtomTypeToNonHydrogenAtom($Atom); 258 } 259 return $This; 260 } 261 262 # Assign E-State atom type to non-hydrogen atom... 263 # 264 sub _AssignAtomTypeToNonHydrogenAtom { 265 my($This, $Atom) = @_; 266 my($AtomType); 267 268 $AtomType = $This->_GetAtomTypeForNonHydrogenAtom($Atom); 269 $This->SetAtomType($Atom, $AtomType); 270 271 return $This; 272 } 273 274 # Get E-State atom type for non-hydrogen atom... 275 # 276 sub _GetAtomTypeForNonHydrogenAtom { 277 my($This, $Atom) = @_; 278 my($AtomType, $AtomSymbol, $NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds, $NumOfAromaticBonds, $CountAromaticBonds, $NumOfHydrogens, $FormalCharge, @EStateAtomInvariants); 279 280 @EStateAtomInvariants = (); 281 282 $AtomSymbol = $Atom->GetAtomicInvariantValue('AS'); 283 $NumOfHydrogens = $Atom->GetAtomicInvariantValue('H'); 284 $FormalCharge = $Atom->GetAtomicInvariantValue('FC'); 285 286 $CountAromaticBonds = 1; 287 ($NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds, $NumOfAromaticBonds) = $Atom->GetNumOfBondTypesToNonHydrogenAtoms($CountAromaticBonds); 288 289 # Set up E-state atom invariants symbols... 290 if ($NumOfTripleBonds > 0) { 291 push @EStateAtomInvariants, "t" x $NumOfTripleBonds; 292 } 293 if ($NumOfDoubleBonds > 0) { 294 push @EStateAtomInvariants, "d" x $NumOfDoubleBonds; 295 } 296 if ($NumOfAromaticBonds > 0) { 297 push @EStateAtomInvariants, "a" x $NumOfAromaticBonds; 298 } 299 if ($NumOfSingleBonds > 0) { 300 push @EStateAtomInvariants, "s" x $NumOfSingleBonds; 301 } 302 push @EStateAtomInvariants, $AtomSymbol; 303 if ($NumOfHydrogens > 0) { 304 push @EStateAtomInvariants, ($NumOfHydrogens > 1) ? "H${NumOfHydrogens}" : "H"; 305 } 306 if ($FormalCharge > 0) { 307 push @EStateAtomInvariants, "p"; 308 } 309 elsif ($FormalCharge < 0) { 310 push @EStateAtomInvariants, "m"; 311 } 312 313 $AtomType = TextUtil::JoinWords(\@EStateAtomInvariants, "", 0); 314 315 return $AtomType; 316 } 317 318 # Assign E-State atom type to hydrogen atom... 319 # 320 sub _AssignAtomTypeToHydrogenAtom { 321 my($This, $Atom) = @_; 322 my($AtomType); 323 324 $AtomType = $This->_GetAtomTypeForHydrogenAtom($Atom); 325 $This->SetAtomType($Atom, $AtomType); 326 327 return $This; 328 } 329 330 # Get E-State atom type for hydrogen atom... 331 # 332 sub _GetAtomTypeForHydrogenAtom { 333 my($This, $Atom) = @_; 334 my($AtomType, $AtomNeighbor); 335 336 $AtomType = "Hmisc"; 337 338 # Get non-hydrogen atom neighbor... 339 $AtomNeighbor = $Atom->GetNonHydrogenNeighborOfHydrogenAtom(); 340 if (!$AtomNeighbor) { 341 return $AtomType; 342 } 343 344 ATOMNEIGHBOR: { 345 if ($AtomNeighbor->IsCarbon()) { 346 $AtomType = $This->_GetAtomTypeForHydrogenAttachedToCarbon($AtomNeighbor); 347 last ATOMNEIGHBOR; 348 } 349 if ($AtomNeighbor->IsNitrogen()) { 350 $AtomType = $This->_GetAtomTypeForHydrogenAttachedToNitrogen($AtomNeighbor); 351 last ATOMNEIGHBOR; 352 } 353 if ($AtomNeighbor->IsOxygen()) { 354 $AtomType = $This->_GetAtomTypeForHydrogenAttachedToOxygen($AtomNeighbor); 355 last ATOMNEIGHBOR; 356 } 357 if ($AtomNeighbor->IsSulfur()) { 358 $AtomType = $This->_GetAtomTypeForHydrogenAttachedToSulfur($AtomNeighbor); 359 last ATOMNEIGHBOR; 360 } 361 $AtomType = "Hmisc"; 362 } 363 return $AtomType; 364 } 365 366 # Get E-state atom type for Hydrogen attached to Carbon... 367 # 368 # HGroup AtomType 369 # 370 # #CH HtCH 371 # =CH2 HdCH2 - H attached to a terminal vinyl group 372 # =CH- HdsCH - H attached a non-terminal vinyl group 373 # :CH: HaaCH 374 # 375 # >CHF HCHF 376 # -CH2F HCH2F 377 # >CHCl HCHCl 378 # -CH2Cl HCH2Cl 379 # 380 # CHn (saturated) HCsats - H attached to sp3 carbon attached to saturated carbon(s) 381 # CHn (unsatd.) HCsatu - H attached to sp3 carbon attached to unsaturated carbon(s) 382 # 383 # CHn (aromatic) Havin - H attached to a non-terminal vinyl group, =CH-, attached to an aromatic carbon 384 # 385 # 386 sub _GetAtomTypeForHydrogenAttachedToCarbon { 387 my($This, $CarbonAtom) = @_; 388 my($AtomType, $AtomNeighbor, $NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds, $NumOfAromaticBonds, $CountAromaticBonds, $NumOfHydrogens, $NumOfFluorines, $NumOfChlorines); 389 390 $AtomType = "Hother"; 391 392 $NumOfHydrogens = $CarbonAtom->GetAtomicInvariantValue('H'); 393 394 $CountAromaticBonds = 1; 395 ($NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds, $NumOfAromaticBonds) = $CarbonAtom->GetNumOfBondTypesToNonHydrogenAtoms($CountAromaticBonds); 396 397 ($NumOfFluorines, $NumOfChlorines) = $This->_GetNumOfFluorineAndChlorineNeighbors($CarbonAtom); 398 399 ATOMTYPE: { 400 if ($NumOfHydrogens == 1 && $NumOfSingleBonds == 0 && $NumOfDoubleBonds == 0 && $NumOfTripleBonds == 1 && $NumOfAromaticBonds == 0) { 401 $AtomType = "HtCH"; 402 last ATOMTYPE; 403 } 404 if ($NumOfHydrogens == 2 && $NumOfSingleBonds == 0 && $NumOfDoubleBonds == 1 && $NumOfTripleBonds == 0 && $NumOfAromaticBonds == 0) { 405 $AtomType = "HdCH2"; 406 last ATOMTYPE; 407 } 408 if ($NumOfHydrogens == 1 && $NumOfSingleBonds == 1 && $NumOfDoubleBonds == 1 && $NumOfTripleBonds == 0 && $NumOfAromaticBonds == 0) { 409 if ($This->_IsAttachedToAromaticCarbon($CarbonAtom)) { 410 $AtomType = "Havin"; 411 } 412 else { 413 $AtomType = "HdsCH"; 414 } 415 last ATOMTYPE; 416 } 417 if ($NumOfHydrogens == 1 && $NumOfSingleBonds == 0 && $NumOfDoubleBonds == 0 && $NumOfTripleBonds == 0 && $NumOfAromaticBonds == 2) { 418 $AtomType = "HaaCH"; 419 last ATOMTYPE; 420 } 421 422 if ($NumOfFluorines == 1 && $NumOfHydrogens == 1 && $NumOfSingleBonds == 3 && $NumOfDoubleBonds == 0 && $NumOfTripleBonds == 0 && $NumOfAromaticBonds == 0) { 423 $AtomType = "HCHF"; 424 last ATOMTYPE; 425 } 426 if ($NumOfFluorines == 1 && $NumOfHydrogens == 2 && $NumOfSingleBonds == 2 && $NumOfDoubleBonds == 0 && $NumOfTripleBonds == 0 && $NumOfAromaticBonds == 0) { 427 $AtomType = "HCH2F"; 428 last ATOMTYPE; 429 } 430 if ($NumOfChlorines == 1 && $NumOfHydrogens == 1 && $NumOfSingleBonds == 3 && $NumOfDoubleBonds == 0 && $NumOfTripleBonds == 0 && $NumOfAromaticBonds == 0) { 431 $AtomType = "HCHCl"; 432 last ATOMTYPE; 433 } 434 if ($NumOfChlorines == 1 && $NumOfHydrogens == 2 && $NumOfSingleBonds == 2 && $NumOfDoubleBonds == 0 && $NumOfTripleBonds == 0 && $NumOfAromaticBonds == 0) { 435 $AtomType = "HCH2Cl"; 436 last ATOMTYPE; 437 } 438 if ($NumOfDoubleBonds == 0 && $NumOfTripleBonds == 0 && $NumOfAromaticBonds == 0) { 439 # H attached to sp3 carbon... 440 $AtomType = $This->_GetAtomTypeForHydrogenAttachedToSaturatedOrUnsaturatedCarbons($CarbonAtom); 441 last ATOMTYPE; 442 } 443 $AtomType = "Hother"; 444 } 445 446 return $AtomType; 447 } 448 449 # Get number of fluorines and chlorines atached to an atom... 450 # 451 sub _GetNumOfFluorineAndChlorineNeighbors { 452 my($This, $Atom) = @_; 453 my($NumOfFluorines, $NumOfChlorines, $AtomNeighbor); 454 455 $NumOfFluorines = 0; $NumOfChlorines = 0; 456 ATOMNEIGHBOR: for $AtomNeighbor ($Atom->GetNonHydrogenAtomNeighbors()) { 457 if ($AtomNeighbor->IsFluorine()) { 458 $NumOfFluorines++; 459 next ATOMNEIGHBOR; 460 } 461 if ($AtomNeighbor->IsChlorine()) { 462 $NumOfChlorines++; 463 next ATOMNEIGHBOR; 464 } 465 } 466 return ($NumOfFluorines, $NumOfChlorines); 467 } 468 469 # Get atom type of hydrogen atom attached to a sp3 carbon attached to saturated or 470 # unsaturated carbons... 471 # 472 # HGroup AtomType 473 # 474 # CHn (saturated) HCsats - H attached to sp3 carbon attached to saturated carbon(s) 475 # CHn (unsatd.) HCsatu - H attached to sp3 carbon attached to unsaturated carbon(s) 476 # 477 sub _GetAtomTypeForHydrogenAttachedToSaturatedOrUnsaturatedCarbons { 478 my($This, $CarbonAtom) = @_; 479 my($AtomType, $AtomNeighbor, @AtomNeighbors); 480 481 $AtomType = "Hother"; 482 @AtomNeighbors = $CarbonAtom->GetNonHydrogenAtomNeighbors(); 483 484 # Make sure all neighbors are carbon atoms... 485 for $AtomNeighbor (@AtomNeighbors) { 486 if (!$AtomNeighbor->IsCarbon()) { 487 return $AtomType; 488 } 489 } 490 491 $AtomType = "HCsats"; 492 ATOMNEIGHBOR: for $AtomNeighbor ($CarbonAtom->GetNonHydrogenAtomNeighbors()) { 493 if ($AtomNeighbor->IsUnsaturated()) { 494 $AtomType = "HCsatu"; 495 last ATOMNEIGHBOR; 496 } 497 } 498 499 return $AtomType; 500 } 501 502 # Is vinyl carbon attached to an aromatic carbon? 503 # 504 sub _IsAttachedToAromaticCarbon { 505 my($This, $CarbonAtom) = @_; 506 my($Status, $AtomNeighbor, @AtomNeighbors); 507 508 $Status = 0; 509 510 @AtomNeighbors = $CarbonAtom->GetNonHydrogenAtomNeighbors(); 511 ATOMNEIGHBOR: for $AtomNeighbor (@AtomNeighbors) { 512 if ($AtomNeighbor->IsCarbon() && $AtomNeighbor->IsAromatic()) { 513 $Status = 1; 514 last ATOMNEIGHBOR; 515 } 516 } 517 return $Status; 518 } 519 520 521 # Get E-state atom type for Hydrogen attached to Nitrogen... 522 # 523 # HGroup AtomType 524 # 525 # -NH2 HsNH2 526 # >NH HssNH 527 # =NH HdNH 528 # :NH: HaaNH 529 # -NH3+ HsNH3p 530 # >NH2+ HssNH2p 531 # >NH-+ HsssNHp 532 # 533 sub _GetAtomTypeForHydrogenAttachedToNitrogen { 534 my($This, $NitrogenAtom) = @_; 535 my($AtomType, $NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds, $NumOfAromaticBonds, $CountAromaticBonds, $NumOfHydrogens, $FormalCharge); 536 537 $AtomType = "Hother"; 538 539 $NumOfHydrogens = $NitrogenAtom->GetAtomicInvariantValue('H'); 540 $FormalCharge = $NitrogenAtom->GetAtomicInvariantValue('FC'); 541 542 $CountAromaticBonds = 1; 543 ($NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds, $NumOfAromaticBonds) = $NitrogenAtom->GetNumOfBondTypesToNonHydrogenAtoms($CountAromaticBonds); 544 545 if (!($NumOfTripleBonds == 0)) { 546 return $AtomType; 547 } 548 549 ATOMTYPE: { 550 if ($FormalCharge == 0) { 551 if ($NumOfHydrogens == 2 && $NumOfSingleBonds == 1 && $NumOfDoubleBonds == 0 && $NumOfAromaticBonds == 0) { 552 $AtomType = "HsNH2"; 553 last ATOMTYPE; 554 } 555 if ($NumOfHydrogens == 1 && $NumOfSingleBonds == 2 && $NumOfDoubleBonds == 0 && $NumOfAromaticBonds == 0) { 556 $AtomType = "HssNH"; 557 last ATOMTYPE; 558 } 559 if ($NumOfHydrogens == 1 && $NumOfSingleBonds == 0 && $NumOfDoubleBonds == 1 && $NumOfAromaticBonds == 0) { 560 $AtomType = "HdNH"; 561 last ATOMTYPE; 562 } 563 if ($NumOfHydrogens == 1 && $NumOfSingleBonds == 0 && $NumOfDoubleBonds == 0 && $NumOfAromaticBonds == 2) { 564 $AtomType = "HaaNH"; 565 last ATOMTYPE; 566 } 567 $AtomType = "Hother"; 568 last ATOMTYPE; 569 } 570 if ($FormalCharge == 1) { 571 if ($NumOfHydrogens == 3 && $NumOfSingleBonds == 1 && $NumOfDoubleBonds == 0 && $NumOfAromaticBonds == 0) { 572 $AtomType = "HsNH3p"; 573 last ATOMTYPE; 574 } 575 if ( $NumOfHydrogens == 2 && $NumOfSingleBonds == 2 && $NumOfDoubleBonds == 0 && $NumOfAromaticBonds == 0) { 576 $AtomType = "HssNH2p"; 577 last ATOMTYPE; 578 } 579 if ($NumOfHydrogens == 1 && $NumOfSingleBonds == 3 && $NumOfDoubleBonds == 0 && $NumOfAromaticBonds == 0) { 580 $AtomType = "HsssNHp"; 581 last ATOMTYPE; 582 } 583 $AtomType = "Hother"; 584 last ATOMTYPE; 585 } 586 $AtomType = "Hother"; 587 } 588 589 return $AtomType; 590 } 591 592 # Get E-state atom type for Hydrogen attached to Oxygen... 593 # 594 # HGroup AtomType 595 # 596 # -OH HsOH 597 # 598 sub _GetAtomTypeForHydrogenAttachedToOxygen { 599 my($This, $OxygenAtom) = @_; 600 my($NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds, $NumOfAromaticBonds, $CountAromaticBonds, $NumOfHydrogens); 601 602 $NumOfHydrogens = $OxygenAtom->GetAtomicInvariantValue('H'); 603 604 $CountAromaticBonds = 1; 605 ($NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds, $NumOfAromaticBonds) = $OxygenAtom->GetNumOfBondTypesToNonHydrogenAtoms($CountAromaticBonds); 606 607 return ($NumOfSingleBonds == 1 && $NumOfHydrogens == 1 && $NumOfDoubleBonds == 0 && $NumOfTripleBonds == 0 && $NumOfAromaticBonds == 0) ? "HsOH" : "Hother"; 608 } 609 610 # Get E-state atom type for Hydrogen attached to Sulfur... 611 # 612 # HGroup AtomType 613 # 614 # -SH HsSH 615 # 616 sub _GetAtomTypeForHydrogenAttachedToSulfur { 617 my($This, $SulfurAtom) = @_; 618 my($NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds, $NumOfAromaticBonds, $CountAromaticBonds, $NumOfHydrogens); 619 620 $NumOfHydrogens = $SulfurAtom->GetAtomicInvariantValue('H'); 621 622 $CountAromaticBonds = 1; 623 ($NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds, $NumOfAromaticBonds) = $SulfurAtom->GetNumOfBondTypesToNonHydrogenAtoms($CountAromaticBonds); 624 625 return ($NumOfSingleBonds == 1 && $NumOfHydrogens == 1 && $NumOfDoubleBonds == 0 && $NumOfTripleBonds == 0 && $NumOfAromaticBonds == 0) ? "HsSH" : "Hother"; 626 } 627 628 # Return a string containg data for EStateAtomTypes object... 629 # 630 sub StringifyEStateAtomTypes { 631 my($This) = @_; 632 my($AtomTypesString); 633 634 # Type of AtomTypes... 635 $AtomTypesString = "AtomTypes: $This->{Type}; IgnoreHydrogens: " . ($This->{IgnoreHydrogens} ? "Yes" : "No"); 636 637 # Setup atom types information... 638 my($AtomID, $AtomType, @AtomTypesInfo, %AssignedAtomTypes); 639 640 @AtomTypesInfo = (); 641 %AssignedAtomTypes = $This->GetAtomTypes(); 642 643 for $AtomID (sort { $a <=> $b } keys %AssignedAtomTypes) { 644 $AtomType = $AssignedAtomTypes{$AtomID} ? $AssignedAtomTypes{$AtomID} : 'None'; 645 push @AtomTypesInfo, "$AtomID:$AtomType"; 646 } 647 $AtomTypesString .= "; AtomIDs:AtomTypes: <" . TextUtil::JoinWords(\@AtomTypesInfo, ", ", 0) . ">"; 648 649 return $AtomTypesString; 650 } 651 652 # Is it a EStateAtomTypes object? 653 sub _IsEStateAtomTypes { 654 my($Object) = @_; 655 656 return (Scalar::Util::blessed($Object) && $Object->isa($ClassName)) ? 1 : 0; 657 } 658 659 # Check and load EState atom types data... 660 # 661 sub _CheckAndLoadEStateAtomTypesData { 662 663 # Is it already loaded? 664 if (exists $EStateAtomTypesDataMap{AtomTypes}) { 665 return; 666 } 667 668 _LoadEStateAtomTypesData(); 669 } 670 671 # Load EState atom types data from the file assuming first column to be atom type symbol.. 672 # 673 # Format: 674 # 675 # "AtomType","AtomGroup" 676 # "sLi","-Li" 677 # "ssBe","-Be-" 678 # "ssssBem",">Be<-2" 679 # 680 sub _LoadEStateAtomTypesData { 681 my($AtomTypesDataFile, $MayaChemToolsLibDir); 682 683 $MayaChemToolsLibDir = FileUtil::GetMayaChemToolsLibDirName(); 684 685 $AtomTypesDataFile = "$MayaChemToolsLibDir" . "/data/EStateAtomTypes.csv"; 686 if (! -e "$AtomTypesDataFile") { 687 croak "Error: MayaChemTools package file, $AtomTypesDataFile, is missing: Possible installation problems..."; 688 } 689 690 %EStateAtomTypesDataMap = (); 691 AtomTypes::AtomTypes::LoadAtomTypesData($AtomTypesDataFile, \%EStateAtomTypesDataMap); 692 } 693