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