Mercurial > repos > deepakjadmin > mayatool3_test1
comparison lib/Atom.pm @ 1:2abf0d43254d draft
Uploaded
| author | deepakjadmin |
|---|---|
| date | Wed, 20 Jan 2016 09:10:43 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:1791cb0984a7 | 1:2abf0d43254d |
|---|---|
| 1 package Atom; | |
| 2 # | |
| 3 # $RCSfile: Atom.pm,v $ | |
| 4 # $Date: 2015/02/28 20:47:02 $ | |
| 5 # $Revision: 1.62 $ | |
| 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 Storable (); | |
| 33 use Scalar::Util (); | |
| 34 use ObjectProperty; | |
| 35 use PeriodicTable; | |
| 36 use Vector; | |
| 37 use MathUtil; | |
| 38 use Text::ParseWords; | |
| 39 use TextUtil; | |
| 40 use FileUtil; | |
| 41 | |
| 42 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); | |
| 43 | |
| 44 @ISA = qw(ObjectProperty Exporter); | |
| 45 @EXPORT = qw(); | |
| 46 @EXPORT_OK = qw(); | |
| 47 | |
| 48 %EXPORT_TAGS = (all => [@EXPORT, @EXPORT_OK]); | |
| 49 | |
| 50 # Setup class variables... | |
| 51 my($ClassName, $ObjectID, %MDLValenceModelDataMap, %DaylightValenceModelDataMap); | |
| 52 _InitializeClass(); | |
| 53 | |
| 54 # Overload Perl functions... | |
| 55 use overload '""' => 'StringifyAtom'; | |
| 56 | |
| 57 # Class constructor... | |
| 58 sub new { | |
| 59 my($Class, %NamesAndValues) = @_; | |
| 60 | |
| 61 # Initialize object... | |
| 62 my $This = {}; | |
| 63 bless $This, ref($Class) || $Class; | |
| 64 $This->_InitializeAtom(); | |
| 65 | |
| 66 $This->_InitializeAtomProperties(%NamesAndValues); | |
| 67 | |
| 68 return $This; | |
| 69 } | |
| 70 | |
| 71 # Initialize object data... | |
| 72 sub _InitializeAtom { | |
| 73 my($This) = @_; | |
| 74 my($ObjectID) = _GetNewObjectID(); | |
| 75 | |
| 76 # All other property names and values along with all Set/Get<PropertyName> methods | |
| 77 # are implemented on-demand using ObjectProperty class. | |
| 78 $This->{ID} = $ObjectID; | |
| 79 $This->{Name} = "Atom ${ObjectID}"; | |
| 80 $This->{AtomSymbol} = ''; | |
| 81 $This->{AtomicNumber} = 0; | |
| 82 $This->{XYZ} = Vector::ZeroVector; | |
| 83 } | |
| 84 | |
| 85 # Initialize atom properties... | |
| 86 sub _InitializeAtomProperties { | |
| 87 my($This, %NamesAndValues) = @_; | |
| 88 | |
| 89 my($Name, $Value, $MethodName); | |
| 90 while (($Name, $Value) = each %NamesAndValues) { | |
| 91 $MethodName = "Set${Name}"; | |
| 92 $This->$MethodName($Value); | |
| 93 } | |
| 94 if (!exists $NamesAndValues{'AtomSymbol'}) { | |
| 95 carp "Warning: ${ClassName}->new: Atom object instantiated without setting atom symbol..."; | |
| 96 } | |
| 97 | |
| 98 return $This; | |
| 99 } | |
| 100 | |
| 101 # Initialize class ... | |
| 102 sub _InitializeClass { | |
| 103 #Class name... | |
| 104 $ClassName = __PACKAGE__; | |
| 105 | |
| 106 # ID to keep track of objects... | |
| 107 $ObjectID = 0; | |
| 108 | |
| 109 # Load atom class data... | |
| 110 _LoadAtomClassData(); | |
| 111 } | |
| 112 | |
| 113 # Setup an explicit SetID method to block setting of ID by AUTOLOAD function... | |
| 114 sub SetID { | |
| 115 my($This, $Value) = @_; | |
| 116 | |
| 117 carp "Warning: ${ClassName}->SetID: Object ID can't be changed: it's used for internal tracking..."; | |
| 118 | |
| 119 return $This; | |
| 120 } | |
| 121 | |
| 122 # Setup an explicit SetMolecule method to block setting of ID by AUTOLOAD function... | |
| 123 sub SetMolecule { | |
| 124 my($This, $Value) = @_; | |
| 125 | |
| 126 carp "Warning: ${ClassName}->SetMolecule: Molecule property can't be changed: it's used for internal tracking..."; | |
| 127 | |
| 128 return $This; | |
| 129 } | |
| 130 | |
| 131 # Assign atom to molecule... | |
| 132 sub _SetMolecule { | |
| 133 my($This, $Molecule) = @_; | |
| 134 | |
| 135 $This->{Molecule} = $Molecule; | |
| 136 | |
| 137 # Weaken the reference to disable increment of reference count; otherwise, | |
| 138 # it it becomes a circular reference and destruction of Molecule object doesn't | |
| 139 # get initiated which in turn disables destruction of atom object. | |
| 140 # | |
| 141 Scalar::Util::weaken($This->{Molecule}); | |
| 142 | |
| 143 return $This; | |
| 144 } | |
| 145 | |
| 146 # Setup atom symbol and atomic number for the element... | |
| 147 # | |
| 148 # Possible atom symbol values: | |
| 149 # . An element symbol or some other type of atom: L - Atom list; LP - Lone pair; R# - R group; | |
| 150 # A, Q, * - unknown atom; or something else? | |
| 151 # | |
| 152 # Default mass number corresponds to the most abundant natural isotope unless it's explicity | |
| 153 # set using "MassNumber" property. | |
| 154 # | |
| 155 sub SetAtomSymbol { | |
| 156 my($This, $AtomSymbol) = @_; | |
| 157 my($AtomicNumber); | |
| 158 | |
| 159 $This->{AtomSymbol} = $AtomSymbol; | |
| 160 | |
| 161 $AtomicNumber = PeriodicTable::GetElementAtomicNumber($AtomSymbol); | |
| 162 $This->{AtomicNumber} = (defined $AtomicNumber) ? $AtomicNumber : 0; | |
| 163 | |
| 164 return $This; | |
| 165 } | |
| 166 | |
| 167 # Setup atom symbol and atomic number for the element... | |
| 168 sub SetAtomicNumber { | |
| 169 my($This, $AtomicNumber) = @_; | |
| 170 my($AtomSymbol); | |
| 171 | |
| 172 $AtomSymbol = PeriodicTable::GetElementAtomSymbol($AtomicNumber); | |
| 173 if (!defined $AtomSymbol) { | |
| 174 carp "Warning: ${ClassName}->SetAtomicNumber: Didn't set atomic number: Invalid atomic number, $AtomicNumber, specified..."; | |
| 175 return; | |
| 176 } | |
| 177 $This->{AtomicNumber} = $AtomicNumber; | |
| 178 $This->{AtomSymbol} = $AtomSymbol; | |
| 179 | |
| 180 return $This; | |
| 181 } | |
| 182 | |
| 183 # Set atom as stereo center... | |
| 184 # | |
| 185 sub SetStereoCenter { | |
| 186 my($This, $StereoCenter) = @_; | |
| 187 | |
| 188 $This->SetProperty('StereoCenter', $StereoCenter); | |
| 189 | |
| 190 return $This; | |
| 191 } | |
| 192 | |
| 193 # Is it a stereo center? | |
| 194 # | |
| 195 sub IsStereoCenter { | |
| 196 my($This) = @_; | |
| 197 my($StereoCenter); | |
| 198 | |
| 199 $StereoCenter = $This->GetProperty('StereoCenter'); | |
| 200 | |
| 201 return (defined($StereoCenter) && $StereoCenter) ? 1 : 0; | |
| 202 } | |
| 203 | |
| 204 # Set atom stereochemistry. | |
| 205 # | |
| 206 # Supported values are: R, S. | |
| 207 # | |
| 208 # Notes: | |
| 209 # | |
| 210 # . After the ligands around a central stereocenter has been ranked using CIP priority scheme and | |
| 211 # the lowest ranked ligand lies behind the center atom, then R and S values correspond to: | |
| 212 # | |
| 213 # R: Clockwise arrangement of remaining ligands around the central atom going from highest to lowest ranked ligand | |
| 214 # S: CounterClockwise arrangement of remaining ligands around the central atom going from highest to lowest ranked ligand | |
| 215 # | |
| 216 # . Assignment of any other arbitray values besides R and S is also allowed; however, a warning is printed. | |
| 217 # | |
| 218 sub SetStereochemistry { | |
| 219 my($This, $Stereochemistry) = @_; | |
| 220 | |
| 221 if ($Stereochemistry !~ /^(R|S)$/i) { | |
| 222 carp "Warning: ${ClassName}->SetStereochemistry: Assigning non-supported Stereochemistry value of $Stereochemistry. Supported values: R, S..."; | |
| 223 } | |
| 224 | |
| 225 $This->SetProperty('StereoCenter', 1); | |
| 226 $This->SetProperty('Stereochemistry', $Stereochemistry); | |
| 227 | |
| 228 return $This; | |
| 229 } | |
| 230 | |
| 231 # Setup mass number for atom... | |
| 232 sub SetMassNumber { | |
| 233 my($This, $MassNumber) = @_; | |
| 234 my($AtomicNumber, $AtomSymbol); | |
| 235 | |
| 236 $AtomicNumber = $This->{AtomicNumber}; | |
| 237 $AtomSymbol = $This->{AtomSymbol}; | |
| 238 if (!$AtomicNumber) { | |
| 239 carp "Warning: ${ClassName}->SetMassNumber: Didn't set mass number: Non standard atom with atomic number, $AtomicNumber, and atomic symbol, $AtomSymbol..."; | |
| 240 return; | |
| 241 } | |
| 242 if (!PeriodicTable::IsElementNaturalIsotopeMassNumber($AtomicNumber, $MassNumber)) { | |
| 243 carp "Warning: ${ClassName}->SetMassNumber: Unknown mass number, $MassNumber, specified for atom with atomic number, $AtomicNumber, and atomic symbol, $AtomSymbol. Don't forget to Set ExactMass property explicitly; otherwise, GetExactMass method would return mass of most abundant isotope..."; | |
| 244 } | |
| 245 $This->SetProperty('MassNumber', $MassNumber); | |
| 246 | |
| 247 return $This; | |
| 248 } | |
| 249 | |
| 250 # Get mass number... | |
| 251 # | |
| 252 sub GetMassNumber { | |
| 253 my($This) = @_; | |
| 254 | |
| 255 # Is mass number explicity set? | |
| 256 if ($This->HasProperty('MassNumber')) { | |
| 257 return $This->GetProperty('MassNumber'); | |
| 258 } | |
| 259 | |
| 260 # Is it an element symbol? | |
| 261 my($AtomicNumber) = $This->{AtomicNumber}; | |
| 262 if (!$AtomicNumber) { | |
| 263 return 0; | |
| 264 } | |
| 265 | |
| 266 # Return most abundant mass number... | |
| 267 return PeriodicTable::GetElementMostAbundantNaturalIsotopeMassNumber($AtomicNumber); | |
| 268 } | |
| 269 | |
| 270 # Get atomic weight: | |
| 271 # . Explicitly set by the caller | |
| 272 # . Using atomic number | |
| 273 # | |
| 274 sub GetAtomicWeight { | |
| 275 my($This) = @_; | |
| 276 | |
| 277 # Is atomic weight explicity set? | |
| 278 if ($This->HasProperty('AtomicWeight')) { | |
| 279 return $This->GetProperty('AtomicWeight'); | |
| 280 } | |
| 281 | |
| 282 # Is it an element symbol? | |
| 283 my($AtomicNumber) = $This->{AtomicNumber}; | |
| 284 if (!$AtomicNumber) { | |
| 285 return 0; | |
| 286 } | |
| 287 | |
| 288 # Return its atomic weight... | |
| 289 return PeriodicTable::GetElementAtomicWeight($AtomicNumber); | |
| 290 } | |
| 291 | |
| 292 # Get exact mass weight: | |
| 293 # . Explicitly set by the caller | |
| 294 # . Using atomic number and mass number explicity set by the caller | |
| 295 # . Using atomic number and most abundant isotope | |
| 296 # | |
| 297 sub GetExactMass { | |
| 298 my($This) = @_; | |
| 299 | |
| 300 # Is exact mass explicity set? | |
| 301 if ($This->HasProperty('ExactMass')) { | |
| 302 return $This->GetProperty('ExactMass'); | |
| 303 } | |
| 304 | |
| 305 # Is it an element symbol? | |
| 306 my($AtomicNumber) = $This->{AtomicNumber}; | |
| 307 if (!$AtomicNumber) { | |
| 308 return 0; | |
| 309 } | |
| 310 | |
| 311 # Is mass number explicitly set? | |
| 312 if ($This->HasProperty('MassNumber')) { | |
| 313 my($MassNumber) = $This->GetProperty('MassNumber'); | |
| 314 if (PeriodicTable::IsElementNaturalIsotopeMassNumber($AtomicNumber, $MassNumber)) { | |
| 315 return PeriodicTable::GetElementNaturalIsotopeMass($AtomicNumber, $MassNumber); | |
| 316 } | |
| 317 } | |
| 318 | |
| 319 # Return most abundant isotope mass... | |
| 320 return PeriodicTable::GetElementMostAbundantNaturalIsotopeMass($AtomicNumber); | |
| 321 } | |
| 322 | |
| 323 # Get formal charge: | |
| 324 # . Explicitly set by the caller | |
| 325 # . Or return zero insetad of undef | |
| 326 # | |
| 327 sub GetFormalCharge { | |
| 328 my($This) = @_; | |
| 329 my($FormalCharge); | |
| 330 | |
| 331 $FormalCharge = 0; | |
| 332 if ($This->HasProperty('FormalCharge')) { | |
| 333 $FormalCharge = $This->GetProperty('FormalCharge'); | |
| 334 } | |
| 335 | |
| 336 return defined($FormalCharge) ? $FormalCharge : 0; | |
| 337 } | |
| 338 | |
| 339 # Get spin multiplicity: | |
| 340 # . Explicitly set by the caller | |
| 341 # . From FreeRadicalElectrons value explicitly set by the caller | |
| 342 # . Or return zero insetad of undef | |
| 343 # | |
| 344 sub GetSpinMultiplicity { | |
| 345 my($This) = @_; | |
| 346 my($SpinMultiplicity); | |
| 347 | |
| 348 $SpinMultiplicity = 0; | |
| 349 if ($This->HasProperty('SpinMultiplicity')) { | |
| 350 $SpinMultiplicity = $This->GetProperty('SpinMultiplicity'); | |
| 351 return defined($SpinMultiplicity) ? $SpinMultiplicity : 0; | |
| 352 } | |
| 353 | |
| 354 if ($This->HasProperty('FreeRadicalElectrons')) { | |
| 355 my($FreeRadicalElectrons); | |
| 356 $FreeRadicalElectrons = $This->GetProperty('FreeRadicalElectrons'); | |
| 357 | |
| 358 SPINMULTIPLICITY: { | |
| 359 if ($FreeRadicalElectrons == 1) { $SpinMultiplicity = 2; last SPINMULTIPLICITY;} | |
| 360 if ($FreeRadicalElectrons == 2) { $SpinMultiplicity = 1; last SPINMULTIPLICITY;} | |
| 361 carp "Warning: ${ClassName}->GetSpinMultiplicity: It's not possible to determine spin multiplicity from the specified free radical electrons value, $FreeRadicalElectrons. It has been set to 0..."; | |
| 362 $SpinMultiplicity = 0; | |
| 363 } | |
| 364 } | |
| 365 | |
| 366 return $SpinMultiplicity; | |
| 367 } | |
| 368 | |
| 369 # Get number of free radical electrons: | |
| 370 # . Explicitly set by the caller | |
| 371 # . From SpinMultiplicity value explicitly set by the caller | |
| 372 # . Or return zero insetad of undef | |
| 373 # | |
| 374 # Notes: | |
| 375 # . For atoms with explicit assignment of SpinMultiplicity property values corresponding to | |
| 376 # Singlet (two unpaired electrons corresponding to one spin state), Doublet (free radical; an unpaired | |
| 377 # electron corresponding to two spin states), and Triplet (two unparied electrons corresponding to | |
| 378 # three spin states; divalent carbon atoms (carbenes)), FreeRadicalElectrons are calculated as follows: | |
| 379 # | |
| 380 # SpinMultiplicity: Doublet(2); FreeRadicalElectrons: 1 | |
| 381 # SpinMultiplicity: Singlet(1)/Triplet(3); FreeRadicalElectrons: 2 | |
| 382 # | |
| 383 sub GetFreeRadicalElectrons { | |
| 384 my($This) = @_; | |
| 385 my($FreeRadicalElectrons); | |
| 386 | |
| 387 $FreeRadicalElectrons = 0; | |
| 388 | |
| 389 if ($This->HasProperty('FreeRadicalElectrons')) { | |
| 390 $FreeRadicalElectrons = $This->GetProperty('FreeRadicalElectrons'); | |
| 391 return defined($FreeRadicalElectrons) ? $FreeRadicalElectrons : 0; | |
| 392 } | |
| 393 | |
| 394 if ($This->HasProperty('SpinMultiplicity')) { | |
| 395 my($SpinMultiplicity); | |
| 396 $SpinMultiplicity = $This->GetProperty('SpinMultiplicity'); | |
| 397 | |
| 398 SPINMULTIPLICITY: { | |
| 399 if ($SpinMultiplicity == 1) { $FreeRadicalElectrons = 2; last SPINMULTIPLICITY;} | |
| 400 if ($SpinMultiplicity == 2) { $FreeRadicalElectrons = 1; last SPINMULTIPLICITY;} | |
| 401 if ($SpinMultiplicity == 3) { $FreeRadicalElectrons = 2; last SPINMULTIPLICITY;} | |
| 402 carp "Warning: ${ClassName}->GetFreeRadicalElectrons: It's not possible to determine free radical electrons from the specified spin multiplicity value, $FreeRadicalElectrons. It has been set to 0..."; | |
| 403 $FreeRadicalElectrons = 0; | |
| 404 } | |
| 405 } | |
| 406 | |
| 407 return $FreeRadicalElectrons; | |
| 408 } | |
| 409 | |
| 410 # Set atom coordinates using: | |
| 411 # . An array reference with three values | |
| 412 # . An array containg three values | |
| 413 # . A 3D vector | |
| 414 # | |
| 415 sub SetXYZ { | |
| 416 my($This, @Values) = @_; | |
| 417 | |
| 418 if (!@Values) { | |
| 419 carp "Warning: ${ClassName}->SetXYZ: No values specified..."; | |
| 420 return; | |
| 421 } | |
| 422 | |
| 423 $This->{XYZ}->SetXYZ(@Values); | |
| 424 return $This; | |
| 425 } | |
| 426 | |
| 427 # Set X value... | |
| 428 sub SetX { | |
| 429 my($This, $Value) = @_; | |
| 430 | |
| 431 if (!defined $Value) { | |
| 432 carp "Warning: ${ClassName}->SetX: Undefined X value..."; | |
| 433 return; | |
| 434 } | |
| 435 $This->{XYZ}->SetX($Value); | |
| 436 return $This; | |
| 437 } | |
| 438 | |
| 439 # Set Y value... | |
| 440 sub SetY { | |
| 441 my($This, $Value) = @_; | |
| 442 | |
| 443 if (!defined $Value) { | |
| 444 carp "Warning: ${ClassName}->SetY: Undefined Y value..."; | |
| 445 return; | |
| 446 } | |
| 447 $This->{XYZ}->SetY($Value); | |
| 448 return $This; | |
| 449 } | |
| 450 | |
| 451 # Set Z value... | |
| 452 sub SetZ { | |
| 453 my($This, $Value) = @_; | |
| 454 | |
| 455 if (!defined $Value) { | |
| 456 carp "Warning: ${ClassName}->SetZ: Undefined Z value..."; | |
| 457 return; | |
| 458 } | |
| 459 $This->{XYZ}->SetZ($Value); | |
| 460 return $This; | |
| 461 } | |
| 462 | |
| 463 # Return XYZ as: | |
| 464 # . Reference to an array | |
| 465 # . An array | |
| 466 # | |
| 467 sub GetXYZ { | |
| 468 my($This) = @_; | |
| 469 | |
| 470 return $This->{XYZ}->GetXYZ(); | |
| 471 } | |
| 472 | |
| 473 # Return XYZ as a vector object... | |
| 474 # | |
| 475 sub GetXYZVector { | |
| 476 my($This) = @_; | |
| 477 | |
| 478 return $This->{XYZ}; | |
| 479 } | |
| 480 | |
| 481 # Get X value... | |
| 482 sub GetX { | |
| 483 my($This) = @_; | |
| 484 | |
| 485 return $This->{XYZ}->GetX(); | |
| 486 } | |
| 487 | |
| 488 # Get Y value... | |
| 489 sub GetY { | |
| 490 my($This) = @_; | |
| 491 | |
| 492 return $This->{XYZ}->GetY(); | |
| 493 } | |
| 494 | |
| 495 # Get Z value... | |
| 496 sub GetZ { | |
| 497 my($This) = @_; | |
| 498 | |
| 499 return $This->{XYZ}->GetZ(); | |
| 500 } | |
| 501 | |
| 502 # Delete atom... | |
| 503 sub DeleteAtom { | |
| 504 my($This) = @_; | |
| 505 | |
| 506 # Is this atom in a molecule? | |
| 507 if (!$This->HasProperty('Molecule')) { | |
| 508 # Nothing to do... | |
| 509 return $This; | |
| 510 } | |
| 511 my($Molecule) = $This->GetProperty('Molecule'); | |
| 512 | |
| 513 return $Molecule->_DeleteAtom($This); | |
| 514 } | |
| 515 | |
| 516 # Get atom neighbor objects as array. In scalar conetxt, return number of neighbors... | |
| 517 sub GetNeighbors { | |
| 518 my($This, @ExcludeNeighbors) = @_; | |
| 519 | |
| 520 # Is this atom in a molecule? | |
| 521 if (!$This->HasProperty('Molecule')) { | |
| 522 return undef; | |
| 523 } | |
| 524 my($Molecule) = $This->GetProperty('Molecule'); | |
| 525 | |
| 526 if (@ExcludeNeighbors) { | |
| 527 return $This->_GetAtomNeighbors(@ExcludeNeighbors); | |
| 528 } | |
| 529 else { | |
| 530 return $This->_GetAtomNeighbors(); | |
| 531 } | |
| 532 } | |
| 533 | |
| 534 # Get atom neighbor objects as array. In scalar conetxt, return number of neighbors... | |
| 535 sub _GetAtomNeighbors { | |
| 536 my($This, @ExcludeNeighbors) = @_; | |
| 537 my($Molecule) = $This->GetProperty('Molecule'); | |
| 538 | |
| 539 if (!@ExcludeNeighbors) { | |
| 540 return $Molecule->_GetAtomNeighbors($This); | |
| 541 } | |
| 542 | |
| 543 # Setup a map for neigbhors to exclude... | |
| 544 my($ExcludeNeighbor, $ExcludeNeighborID, %ExcludeNeighborsIDsMap); | |
| 545 | |
| 546 %ExcludeNeighborsIDsMap = (); | |
| 547 for $ExcludeNeighbor (@ExcludeNeighbors) { | |
| 548 $ExcludeNeighborID = $ExcludeNeighbor->GetID(); | |
| 549 $ExcludeNeighborsIDsMap{$ExcludeNeighborID} = $ExcludeNeighborID; | |
| 550 } | |
| 551 | |
| 552 # Generate a filtered neighbors list... | |
| 553 my($Neighbor, $NeighborID, @FilteredAtomNeighbors); | |
| 554 @FilteredAtomNeighbors = (); | |
| 555 NEIGHBOR: for $Neighbor ($Molecule->_GetAtomNeighbors($This)) { | |
| 556 $NeighborID = $Neighbor->GetID(); | |
| 557 if (exists $ExcludeNeighborsIDsMap{$NeighborID}) { | |
| 558 next NEIGHBOR; | |
| 559 } | |
| 560 push @FilteredAtomNeighbors, $Neighbor; | |
| 561 } | |
| 562 | |
| 563 return wantarray ? @FilteredAtomNeighbors : scalar @FilteredAtomNeighbors; | |
| 564 } | |
| 565 | |
| 566 # Get specific atom neighbor objects as array. In scalar conetxt, return number of neighbors. | |
| 567 # | |
| 568 # Notes: | |
| 569 # . AtomSpecification correspond to any valid AtomicInvariant based atomic specifications | |
| 570 # as implemented in DoesAtomNeighborhoodMatch method. | |
| 571 # . Multiple atom specifications can be used in a string delimited by comma. | |
| 572 # | |
| 573 sub GetNeighborsUsingAtomSpecification { | |
| 574 my($This, $AtomSpecification, @ExcludeNeighbors) = @_; | |
| 575 my(@AtomNeighbors); | |
| 576 | |
| 577 @AtomNeighbors = (); | |
| 578 @AtomNeighbors = $This->GetNeighbors(@ExcludeNeighbors); | |
| 579 | |
| 580 # Does atom has any neighbors and do they need to be filtered? | |
| 581 if (!(@AtomNeighbors && defined($AtomSpecification) && $AtomSpecification)) { | |
| 582 return wantarray ? @AtomNeighbors : scalar @AtomNeighbors; | |
| 583 } | |
| 584 | |
| 585 # Filter neighbors using atom specification... | |
| 586 my($AtomNeighbor, @FilteredAtomNeighbors); | |
| 587 | |
| 588 @FilteredAtomNeighbors = (); | |
| 589 NEIGHBOR: for $AtomNeighbor (@AtomNeighbors) { | |
| 590 if (!$AtomNeighbor->_DoesAtomSpecificationMatch($AtomSpecification)) { | |
| 591 next NEIGHBOR; | |
| 592 } | |
| 593 push @FilteredAtomNeighbors, $AtomNeighbor; | |
| 594 } | |
| 595 | |
| 596 return wantarray ? @FilteredAtomNeighbors : scalar @FilteredAtomNeighbors; | |
| 597 } | |
| 598 | |
| 599 | |
| 600 # Get non-hydrogen atom neighbor objects as array. In scalar context, return number of neighbors... | |
| 601 sub GetHeavyAtomNeighbors { | |
| 602 my($This) = @_; | |
| 603 | |
| 604 return $This->GetNonHydrogenAtomNeighbors(); | |
| 605 } | |
| 606 | |
| 607 # Get non-hydrogen atom neighbor objects as array. In scalar context, return number of neighbors... | |
| 608 sub GetNonHydrogenAtomNeighbors { | |
| 609 my($This) = @_; | |
| 610 | |
| 611 # Is this atom in a molecule? | |
| 612 if (!$This->HasProperty('Molecule')) { | |
| 613 return undef; | |
| 614 } | |
| 615 my($NonHydrogenAtomsOnly, $HydrogenAtomsOnly) = (1, 0); | |
| 616 | |
| 617 return $This->_GetFilteredAtomNeighbors($NonHydrogenAtomsOnly, $HydrogenAtomsOnly); | |
| 618 } | |
| 619 | |
| 620 # Get hydrogen atom neighbor objects as array. In scalar context, return numbe of neighbors... | |
| 621 sub GetHydrogenAtomNeighbors { | |
| 622 my($This) = @_; | |
| 623 | |
| 624 # Is this atom in a molecule? | |
| 625 if (!$This->HasProperty('Molecule')) { | |
| 626 return undef; | |
| 627 } | |
| 628 my($NonHydrogenAtomsOnly, $HydrogenAtomsOnly) = (0, 1); | |
| 629 | |
| 630 return $This->_GetFilteredAtomNeighbors($NonHydrogenAtomsOnly, $HydrogenAtomsOnly); | |
| 631 } | |
| 632 | |
| 633 # Get non-hydrogen neighbor of hydrogen atom... | |
| 634 # | |
| 635 sub GetNonHydrogenNeighborOfHydrogenAtom { | |
| 636 my($This) = @_; | |
| 637 | |
| 638 # Is it Hydrogen? | |
| 639 if (!$This->IsHydrogen()) { | |
| 640 return undef; | |
| 641 } | |
| 642 my(@Neighbors); | |
| 643 | |
| 644 @Neighbors = $This->GetNonHydrogenAtomNeighbors(); | |
| 645 | |
| 646 return (@Neighbors == 1) ? $Neighbors[0] : undef; | |
| 647 } | |
| 648 | |
| 649 # Get filtered atom atom neighbors | |
| 650 sub _GetFilteredAtomNeighbors { | |
| 651 my($This, $NonHydrogenAtomsOnly, $HydrogenAtomsOnly) = @_; | |
| 652 | |
| 653 # Check flags... | |
| 654 if (!defined $NonHydrogenAtomsOnly) { | |
| 655 $NonHydrogenAtomsOnly = 0; | |
| 656 } | |
| 657 if (!defined $HydrogenAtomsOnly) { | |
| 658 $HydrogenAtomsOnly = 0; | |
| 659 } | |
| 660 my($Neighbor, @FilteredAtomNeighbors); | |
| 661 | |
| 662 @FilteredAtomNeighbors = (); | |
| 663 NEIGHBOR: for $Neighbor ($This->GetNeighbors()) { | |
| 664 if ($NonHydrogenAtomsOnly && $Neighbor->IsHydrogen()) { | |
| 665 next NEIGHBOR; | |
| 666 } | |
| 667 if ($HydrogenAtomsOnly && (!$Neighbor->IsHydrogen())) { | |
| 668 next NEIGHBOR; | |
| 669 } | |
| 670 push @FilteredAtomNeighbors, $Neighbor; | |
| 671 } | |
| 672 | |
| 673 return wantarray ? @FilteredAtomNeighbors : scalar @FilteredAtomNeighbors; | |
| 674 } | |
| 675 | |
| 676 # Get number of neighbors... | |
| 677 # | |
| 678 sub GetNumOfNeighbors { | |
| 679 my($This) = @_; | |
| 680 my($NumOfNeighbors); | |
| 681 | |
| 682 $NumOfNeighbors = $This->GetNeighbors(); | |
| 683 | |
| 684 return (defined $NumOfNeighbors) ? $NumOfNeighbors : undef; | |
| 685 } | |
| 686 | |
| 687 # Get number of neighbors which are non-hydrogen atoms... | |
| 688 sub GetNumOfHeavyAtomNeighbors { | |
| 689 my($This) = @_; | |
| 690 | |
| 691 return $This->GetNumOfNonHydrogenAtomNeighbors(); | |
| 692 } | |
| 693 | |
| 694 # Get number of neighbors which are non-hydrogen atoms... | |
| 695 sub GetNumOfNonHydrogenAtomNeighbors { | |
| 696 my($This) = @_; | |
| 697 my($NumOfNeighbors); | |
| 698 | |
| 699 $NumOfNeighbors = $This->GetNonHydrogenAtomNeighbors(); | |
| 700 | |
| 701 return (defined $NumOfNeighbors) ? $NumOfNeighbors : undef; | |
| 702 } | |
| 703 | |
| 704 # Get number of neighbors which are hydrogen atoms... | |
| 705 sub GetNumOfHydrogenAtomNeighbors { | |
| 706 my($This) = @_; | |
| 707 my($NumOfNeighbors); | |
| 708 | |
| 709 $NumOfNeighbors = $This->GetHydrogenAtomNeighbors(); | |
| 710 | |
| 711 return (defined $NumOfNeighbors) ? $NumOfNeighbors : undef; | |
| 712 } | |
| 713 | |
| 714 # Get bond objects as array. In scalar context, return number of bonds... | |
| 715 sub GetBonds { | |
| 716 my($This) = @_; | |
| 717 | |
| 718 # Is this atom in a molecule? | |
| 719 if (!$This->HasProperty('Molecule')) { | |
| 720 return undef; | |
| 721 } | |
| 722 my($Molecule) = $This->GetProperty('Molecule'); | |
| 723 | |
| 724 return $Molecule->_GetAtomBonds($This); | |
| 725 } | |
| 726 | |
| 727 # Get bond to specified atom... | |
| 728 sub GetBondToAtom { | |
| 729 my($This, $Other) = @_; | |
| 730 | |
| 731 # Is this atom in a molecule? | |
| 732 if (!$This->HasProperty('Molecule')) { | |
| 733 return undef; | |
| 734 } | |
| 735 my($Molecule) = $This->GetProperty('Molecule'); | |
| 736 | |
| 737 return $Molecule->_GetBondToAtom($This, $Other); | |
| 738 } | |
| 739 | |
| 740 # It it bonded to a specified atom? | |
| 741 sub IsBondedToAtom { | |
| 742 my($This, $Other) = @_; | |
| 743 | |
| 744 # Is this atom in a molecule? | |
| 745 if (!$This->HasProperty('Molecule')) { | |
| 746 return undef; | |
| 747 } | |
| 748 my($Molecule) = $This->GetProperty('Molecule'); | |
| 749 | |
| 750 return $Molecule->_IsBondedToAtom($This, $Other); | |
| 751 } | |
| 752 | |
| 753 # Get bond objects to non-hydrogen atoms as array. In scalar context, return number of bonds... | |
| 754 sub GetBondsToHeavyAtoms { | |
| 755 my($This) = @_; | |
| 756 | |
| 757 return $This->GetBondsToNonHydrogenAtoms(); | |
| 758 } | |
| 759 | |
| 760 # Get bond objects to non-hydrogen atoms as array. In scalar context, return number of bonds... | |
| 761 sub GetBondsToNonHydrogenAtoms { | |
| 762 my($This) = @_; | |
| 763 | |
| 764 # Is this atom in a molecule? | |
| 765 if (!$This->HasProperty('Molecule')) { | |
| 766 return undef; | |
| 767 } | |
| 768 my($BondsToNonHydrogenAtomsOnly, $BondsToHydrogenAtomsOnly) = (1, 0); | |
| 769 | |
| 770 return $This->_GetFilteredBonds($BondsToNonHydrogenAtomsOnly, $BondsToHydrogenAtomsOnly); | |
| 771 } | |
| 772 | |
| 773 # Get bond objects to hydrogen atoms as array. In scalar context, return number of bonds... | |
| 774 sub GetBondsToHydrogenAtoms { | |
| 775 my($This) = @_; | |
| 776 | |
| 777 # Is this atom in a molecule? | |
| 778 if (!$This->HasProperty('Molecule')) { | |
| 779 return undef; | |
| 780 } | |
| 781 my($BondsToNonHydrogenAtomsOnly, $BondsToHydrogenAtomsOnly) = (0, 1); | |
| 782 | |
| 783 return $This->_GetFilteredBonds($BondsToNonHydrogenAtomsOnly, $BondsToHydrogenAtomsOnly); | |
| 784 } | |
| 785 | |
| 786 # Get filtered bonds... | |
| 787 sub _GetFilteredBonds { | |
| 788 my($This, $BondsToNonHydrogenAtomsOnly, $BondsToHydrogenAtomsOnly) = @_; | |
| 789 | |
| 790 # Check flags... | |
| 791 if (!defined $BondsToNonHydrogenAtomsOnly) { | |
| 792 $BondsToNonHydrogenAtomsOnly = 0; | |
| 793 } | |
| 794 if (!defined $BondsToHydrogenAtomsOnly) { | |
| 795 $BondsToHydrogenAtomsOnly = 0; | |
| 796 } | |
| 797 | |
| 798 my($Bond, $BondedAtom, @FilteredBonds); | |
| 799 | |
| 800 @FilteredBonds = (); | |
| 801 BOND: for $Bond ($This->GetBonds()) { | |
| 802 $BondedAtom = $Bond->GetBondedAtom($This); | |
| 803 if ($BondsToNonHydrogenAtomsOnly && $BondedAtom->IsHydrogen()) { | |
| 804 next BOND; | |
| 805 } | |
| 806 if ($BondsToHydrogenAtomsOnly && (!$BondedAtom->IsHydrogen())) { | |
| 807 next BOND; | |
| 808 } | |
| 809 push @FilteredBonds, $Bond; | |
| 810 } | |
| 811 | |
| 812 return wantarray ? @FilteredBonds : (scalar @FilteredBonds); | |
| 813 } | |
| 814 | |
| 815 # Get number of bonds... | |
| 816 # | |
| 817 sub GetNumOfBonds { | |
| 818 my($This) = @_; | |
| 819 my($NumOfBonds); | |
| 820 | |
| 821 $NumOfBonds = $This->GetBonds(); | |
| 822 | |
| 823 return (defined $NumOfBonds) ? ($NumOfBonds) : undef; | |
| 824 } | |
| 825 | |
| 826 # Get number of bonds to non-hydrogen atoms... | |
| 827 sub GetNumOfBondsToHeavyAtoms { | |
| 828 my($This) = @_; | |
| 829 | |
| 830 return $This->GetNumOfBondsToNonHydrogenAtoms(); | |
| 831 } | |
| 832 | |
| 833 # Get number of bonds to non-hydrogen atoms... | |
| 834 sub GetNumOfBondsToNonHydrogenAtoms { | |
| 835 my($This) = @_; | |
| 836 my($NumOfBonds); | |
| 837 | |
| 838 $NumOfBonds = $This->GetBondsToNonHydrogenAtoms(); | |
| 839 | |
| 840 return (defined $NumOfBonds) ? ($NumOfBonds) : undef; | |
| 841 } | |
| 842 | |
| 843 # Get number of single bonds to heavy atoms... | |
| 844 sub GetNumOfSingleBondsToHeavyAtoms { | |
| 845 my($This) = @_; | |
| 846 | |
| 847 return $This->GetNumOfSingleBondsToNonHydrogenAtoms(); | |
| 848 } | |
| 849 | |
| 850 # Get number of single bonds to non-hydrogen atoms... | |
| 851 sub GetNumOfSingleBondsToNonHydrogenAtoms { | |
| 852 my($This) = @_; | |
| 853 | |
| 854 # Is this atom in a molecule? | |
| 855 if (!$This->HasProperty('Molecule')) { | |
| 856 return undef; | |
| 857 } | |
| 858 return $This->_GetNumOfBondsWithSpecifiedBondOrderToNonHydrogenAtoms(1); | |
| 859 } | |
| 860 | |
| 861 # Get number of double bonds to heavy atoms... | |
| 862 sub GetNumOfDoubleBondsToHeavyAtoms { | |
| 863 my($This) = @_; | |
| 864 | |
| 865 return $This->GetNumOfDoubleBondsToNonHydrogenAtoms(); | |
| 866 } | |
| 867 | |
| 868 # Get number of double bonds to non-hydrogen atoms... | |
| 869 sub GetNumOfDoubleBondsToNonHydrogenAtoms { | |
| 870 my($This) = @_; | |
| 871 | |
| 872 # Is this atom in a molecule? | |
| 873 if (!$This->HasProperty('Molecule')) { | |
| 874 return undef; | |
| 875 } | |
| 876 return $This->_GetNumOfBondsWithSpecifiedBondOrderToNonHydrogenAtoms(2); | |
| 877 } | |
| 878 | |
| 879 # Get number of triple bonds to heavy atoms... | |
| 880 sub GetNumOfTripleBondsToHeavyAtoms { | |
| 881 my($This) = @_; | |
| 882 | |
| 883 return $This->GetNumOfTripleBondsToNonHydrogenAtoms(); | |
| 884 } | |
| 885 | |
| 886 # Get number of triple bonds to non-hydrogen atoms... | |
| 887 sub GetNumOfTripleBondsToNonHydrogenAtoms { | |
| 888 my($This) = @_; | |
| 889 | |
| 890 # Is this atom in a molecule? | |
| 891 if (!$This->HasProperty('Molecule')) { | |
| 892 return undef; | |
| 893 } | |
| 894 return $This->_GetNumOfBondsWithSpecifiedBondOrderToNonHydrogenAtoms(3); | |
| 895 } | |
| 896 | |
| 897 # Get number of bonds of specified bond order to non-hydrogen atoms... | |
| 898 sub _GetNumOfBondsWithSpecifiedBondOrderToNonHydrogenAtoms { | |
| 899 my($This, $SpecifiedBondOrder) = @_; | |
| 900 my($NumOfBonds, $Bond, $BondOrder, @Bonds); | |
| 901 | |
| 902 $NumOfBonds = 0; | |
| 903 @Bonds = $This->GetBondsToNonHydrogenAtoms(); | |
| 904 for $Bond (@Bonds) { | |
| 905 $BondOrder = $Bond->GetBondOrder(); | |
| 906 if ($SpecifiedBondOrder == $BondOrder) { | |
| 907 $NumOfBonds++; | |
| 908 } | |
| 909 } | |
| 910 return $NumOfBonds; | |
| 911 } | |
| 912 | |
| 913 # Get number of aromatic bonds to heavy atoms... | |
| 914 sub GetNumOfAromaticBondsToHeavyAtoms { | |
| 915 my($This) = @_; | |
| 916 | |
| 917 return $This->GetNumOfAromaticBondsToNonHydrogenAtoms(); | |
| 918 } | |
| 919 | |
| 920 # Get number of aromatic bonds to non-hydrogen atoms... | |
| 921 sub GetNumOfAromaticBondsToNonHydrogenAtoms { | |
| 922 my($This) = @_; | |
| 923 my($NumOfBonds, $Bond, @Bonds); | |
| 924 | |
| 925 # Is this atom in a molecule? | |
| 926 if (!$This->HasProperty('Molecule')) { | |
| 927 return undef; | |
| 928 } | |
| 929 | |
| 930 $NumOfBonds = 0; | |
| 931 @Bonds = $This->GetBondsToNonHydrogenAtoms(); | |
| 932 for $Bond (@Bonds) { | |
| 933 if ($Bond->IsAromatic()) { $NumOfBonds++; } | |
| 934 } | |
| 935 return $NumOfBonds; | |
| 936 } | |
| 937 | |
| 938 # Get number of different bond types to non-hydrogen atoms... | |
| 939 # | |
| 940 sub GetNumOfBondTypesToHeavyAtoms { | |
| 941 my($This, $CountAromaticBonds) = @_; | |
| 942 | |
| 943 return $This->GetNumOfBondTypesToNonHydrogenAtoms($CountAromaticBonds); | |
| 944 } | |
| 945 | |
| 946 # Get number of single, double, triple, and aromatic bonds from an atom to all other | |
| 947 # non-hydrogen atoms. Value of CountAtomaticBonds parameter controls whether | |
| 948 # number of aromatic bonds is returned; default is not to count aromatic bonds. During | |
| 949 # counting of aromatic bonds, the bond marked aromatic is not included in the count | |
| 950 # of other bond types. | |
| 951 # | |
| 952 sub GetNumOfBondTypesToNonHydrogenAtoms { | |
| 953 my($This, $CountAromaticBonds) = @_; | |
| 954 my($NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds, $NumOfAromaticBonds, $None, $Bond, @Bonds); | |
| 955 | |
| 956 $CountAromaticBonds = defined($CountAromaticBonds) ? $CountAromaticBonds : 0; | |
| 957 | |
| 958 ($NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds) = ('0') x 3; | |
| 959 $NumOfAromaticBonds = $CountAromaticBonds ? 0 : undef; | |
| 960 | |
| 961 # Is this atom in a molecule? | |
| 962 if (!$This->HasProperty('Molecule')) { | |
| 963 return ($NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds, $NumOfAromaticBonds); | |
| 964 } | |
| 965 | |
| 966 @Bonds = $This->GetBondsToNonHydrogenAtoms(); | |
| 967 | |
| 968 for $Bond (@Bonds) { | |
| 969 BONDTYPE: { | |
| 970 if ($CountAromaticBonds) { | |
| 971 if ($Bond->IsAromatic()) { $NumOfAromaticBonds++; last BONDTYPE; } | |
| 972 } | |
| 973 if ($Bond->IsSingle()) { $NumOfSingleBonds++; last BONDTYPE; } | |
| 974 if ($Bond->IsDouble()) { $NumOfDoubleBonds++; last BONDTYPE; } | |
| 975 if ($Bond->IsTriple()) { $NumOfTripleBonds++; last BONDTYPE; } | |
| 976 $None = 1; | |
| 977 } | |
| 978 } | |
| 979 return ($NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds, $NumOfAromaticBonds); | |
| 980 } | |
| 981 | |
| 982 # Get number of sigma and pi bonds to heavy atoms... | |
| 983 # | |
| 984 sub GetNumOfSigmaAndPiBondsToHeavyAtoms { | |
| 985 my($This) = @_; | |
| 986 | |
| 987 return $This->GetNumOfSigmaAndPiBondsToNonHydrogenAtoms(); | |
| 988 } | |
| 989 | |
| 990 # Get number of sigma and pi bonds from an atom to all other non-hydrogen atoms. | |
| 991 # Sigma and pi bonds are counted using the following methodology: a single bond | |
| 992 # correspond to one sigma bond; a double bond contributes one to sigma bond count | |
| 993 # and one to pi bond count; a triple bond contributes one to sigma bond count and | |
| 994 # two to pi bond count. | |
| 995 # | |
| 996 sub GetNumOfSigmaAndPiBondsToNonHydrogenAtoms { | |
| 997 my($This) = @_; | |
| 998 my($NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds, $NumOfSigmaBonds, $NumOfPiBonds); | |
| 999 | |
| 1000 ($NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds) = $This->GetNumOfBondTypesToNonHydrogenAtoms(); | |
| 1001 | |
| 1002 $NumOfSigmaBonds = $NumOfSingleBonds + $NumOfDoubleBonds + $NumOfTripleBonds; | |
| 1003 $NumOfPiBonds = $NumOfDoubleBonds + 2*$NumOfTripleBonds; | |
| 1004 | |
| 1005 return ($NumOfSigmaBonds, $NumOfPiBonds); | |
| 1006 } | |
| 1007 | |
| 1008 # Get information related to atoms for all heavy atoms attached to an atom.. | |
| 1009 # | |
| 1010 sub GetHeavyAtomNeighborsAtomInformation { | |
| 1011 my($This) = @_; | |
| 1012 | |
| 1013 return $This->GetNonHydrogenAtomNeighborsAtomInformation(); | |
| 1014 } | |
| 1015 | |
| 1016 # Get information related to atoms for all non-hydrogen atoms attached to an atom.. | |
| 1017 # | |
| 1018 # The following values are returned: | |
| 1019 # . Number of non-hydrogen atom neighbors | |
| 1020 # . A reference to an array containing atom objects correpsonding to non-hydrogen | |
| 1021 # atom neighbors | |
| 1022 # . Number of different types of non-hydrogen atom neighbors | |
| 1023 # . A reference to a hash containing atom symbol as key with value corresponding | |
| 1024 # to its count for non-hydrogen atom neighbors | |
| 1025 # | |
| 1026 sub GetNonHydrogenAtomNeighborsAtomInformation { | |
| 1027 my($This) = @_; | |
| 1028 | |
| 1029 # Is this atom in a molecule? | |
| 1030 if (!$This->HasProperty('Molecule')) { | |
| 1031 return (undef, undef, undef, undef); | |
| 1032 } | |
| 1033 my($AtomSymbol, $AtomNeighbor, $NumOfAtomNeighbors, $NumOfAtomNeighborsType, @AtomNeighbors, %AtomNeighborsTypeMap); | |
| 1034 | |
| 1035 $NumOfAtomNeighbors = 0; @AtomNeighbors = (); | |
| 1036 $NumOfAtomNeighborsType = 0; %AtomNeighborsTypeMap = (); | |
| 1037 | |
| 1038 @AtomNeighbors = $This->GetNonHydrogenAtomNeighbors(); | |
| 1039 $NumOfAtomNeighbors = scalar @AtomNeighbors; | |
| 1040 | |
| 1041 for $AtomNeighbor (@AtomNeighbors) { | |
| 1042 $AtomSymbol = $AtomNeighbor->{AtomSymbol}; | |
| 1043 if (exists $AtomNeighborsTypeMap{$AtomSymbol}) { | |
| 1044 $AtomNeighborsTypeMap{$AtomSymbol} += 1; | |
| 1045 } | |
| 1046 else { | |
| 1047 $AtomNeighborsTypeMap{$AtomSymbol} = 1; | |
| 1048 $NumOfAtomNeighborsType++; | |
| 1049 } | |
| 1050 } | |
| 1051 | |
| 1052 return ($NumOfAtomNeighbors, \@AtomNeighbors, $NumOfAtomNeighborsType, \%AtomNeighborsTypeMap); | |
| 1053 } | |
| 1054 | |
| 1055 # Get information related to bonds for all heavy atoms attached to an atom.. | |
| 1056 # | |
| 1057 sub GetHeavyAtomNeighborsBondformation { | |
| 1058 my($This) = @_; | |
| 1059 | |
| 1060 return $This->GetNonHydrogenAtomNeighborsBondInformation(); | |
| 1061 } | |
| 1062 | |
| 1063 # Get information related to bonds for all non-hydrogen atoms attached to an atom.. | |
| 1064 # | |
| 1065 # The following values are returned: | |
| 1066 # . Number of bonds to non-hydrogen atom neighbors | |
| 1067 # . A reference to an array containing bond objects correpsonding to non-hydrogen | |
| 1068 # atom neighbors | |
| 1069 # . A reference to a hash containing bond type as key with value corresponding | |
| 1070 # to its count for non-hydrogen atom neighbors. Bond types are: Single, Double or Triple | |
| 1071 # . A reference to a hash containing atom symbol as key pointing to bond type as second | |
| 1072 # key with values correponding to count of bond types for atom symbol for non-hydrogen | |
| 1073 # atom neighbors | |
| 1074 # . A reference to a hash containing atom symbol as key pointing to bond type as second | |
| 1075 # key with values correponding to atom objects array involved in corresponding bond type for | |
| 1076 # atom symbol for non-hydrogen atom neighbors | |
| 1077 # | |
| 1078 sub GetNonHydrogenAtomNeighborsBondInformation { | |
| 1079 my($This) = @_; | |
| 1080 | |
| 1081 # Is this atom in a molecule? | |
| 1082 if (!$This->HasProperty('Molecule')) { | |
| 1083 return (undef, undef, undef, undef, undef); | |
| 1084 } | |
| 1085 my($BondedAtom, $BondedAtomSymbol, $BondType, $None, $Bond, $NumOfBonds, @Bonds, %BondTypeCountMap, %AtomsBondTypesCountMap, %AtomsBondTypeAtomsMap); | |
| 1086 | |
| 1087 $NumOfBonds = 0; @Bonds = (); | |
| 1088 %BondTypeCountMap = (); | |
| 1089 %AtomsBondTypesCountMap = (); %AtomsBondTypeAtomsMap = (); | |
| 1090 | |
| 1091 $BondTypeCountMap{Single} = 0; | |
| 1092 $BondTypeCountMap{Double} = 0; | |
| 1093 $BondTypeCountMap{Triple} = 0; | |
| 1094 | |
| 1095 @Bonds = $This->GetBondsToNonHydrogenAtoms(); | |
| 1096 $NumOfBonds = scalar @Bonds; | |
| 1097 | |
| 1098 BOND: for $Bond (@Bonds) { | |
| 1099 $BondType = $Bond->IsSingle() ? "Single" : ($Bond->IsDouble() ? "Double" : ($Bond->IsTriple() ? "Triple" : "")); | |
| 1100 if (!$BondType) { | |
| 1101 next BOND; | |
| 1102 } | |
| 1103 | |
| 1104 # Track bond types... | |
| 1105 if (exists $BondTypeCountMap{$BondType}) { | |
| 1106 $BondTypeCountMap{$BondType} += 1; | |
| 1107 } | |
| 1108 else { | |
| 1109 $BondTypeCountMap{$BondType} = 1; | |
| 1110 } | |
| 1111 | |
| 1112 $BondedAtom = $Bond->GetBondedAtom($This); | |
| 1113 $BondedAtomSymbol = $BondedAtom->{AtomSymbol}; | |
| 1114 | |
| 1115 # Track bond types count for atom types involved in specific bond types... | |
| 1116 if (!exists $AtomsBondTypesCountMap{$BondedAtomSymbol}) { | |
| 1117 %{$AtomsBondTypesCountMap{$BondedAtomSymbol}} = (); | |
| 1118 } | |
| 1119 if (exists $AtomsBondTypesCountMap{$BondedAtomSymbol}{$BondType}) { | |
| 1120 $AtomsBondTypesCountMap{$BondedAtomSymbol}{$BondType} += 1; | |
| 1121 } | |
| 1122 else { | |
| 1123 $AtomsBondTypesCountMap{$BondedAtomSymbol}{$BondType} = 1; | |
| 1124 } | |
| 1125 | |
| 1126 # Track atoms involved in specific bond types for specific atom types... | |
| 1127 if (!exists $AtomsBondTypeAtomsMap{$BondedAtomSymbol}) { | |
| 1128 %{$AtomsBondTypeAtomsMap{$BondedAtomSymbol}} = (); | |
| 1129 } | |
| 1130 if (!exists $AtomsBondTypeAtomsMap{$BondedAtomSymbol}{$BondType}) { | |
| 1131 @{$AtomsBondTypeAtomsMap{$BondedAtomSymbol}{$BondType}} = (); | |
| 1132 } | |
| 1133 push @{$AtomsBondTypeAtomsMap{$BondedAtomSymbol}{$BondType}}, $BondedAtom; | |
| 1134 } | |
| 1135 | |
| 1136 return ($NumOfBonds, \@Bonds, \%BondTypeCountMap, \%AtomsBondTypesCountMap, \%AtomsBondTypeAtomsMap); | |
| 1137 } | |
| 1138 | |
| 1139 # Get number of bonds to hydrogen atoms... | |
| 1140 sub GetNumOfBondsToHydrogenAtoms { | |
| 1141 my($This) = @_; | |
| 1142 my($NumOfBonds); | |
| 1143 | |
| 1144 $NumOfBonds = $This->GetBondsToHydrogenAtoms(); | |
| 1145 | |
| 1146 return (defined $NumOfBonds) ? ($NumOfBonds) : undef; | |
| 1147 } | |
| 1148 | |
| 1149 # Get sum of bond orders to all bonded atoms... | |
| 1150 # | |
| 1151 sub GetSumOfBondOrders { | |
| 1152 my($This) = @_; | |
| 1153 | |
| 1154 # Is this atom in a molecule? | |
| 1155 if (!$This->HasProperty('Molecule')) { | |
| 1156 return undef; | |
| 1157 } | |
| 1158 | |
| 1159 return $This->_GetSumOfBondOrders(); | |
| 1160 } | |
| 1161 | |
| 1162 # Get sum of bond orders to non-hydrogen atoms only... | |
| 1163 # | |
| 1164 sub GetSumOfBondOrdersToHeavyAtoms { | |
| 1165 my($This) = @_; | |
| 1166 | |
| 1167 return $This->GetSumOfBondOrdersToNonHydrogenAtoms(); | |
| 1168 } | |
| 1169 | |
| 1170 # Get sum of bond orders to non-hydrogen atoms only... | |
| 1171 # | |
| 1172 sub GetSumOfBondOrdersToNonHydrogenAtoms { | |
| 1173 my($This) = @_; | |
| 1174 | |
| 1175 # Is this atom in a molecule? | |
| 1176 if (!$This->HasProperty('Molecule')) { | |
| 1177 return undef; | |
| 1178 } | |
| 1179 my($ToNonHydrogenAtomsOnly, $ToHydrogenAtomsOnly) = (1, 0); | |
| 1180 | |
| 1181 return $This->_GetSumOfBondOrders($ToNonHydrogenAtomsOnly, $ToHydrogenAtomsOnly); | |
| 1182 } | |
| 1183 | |
| 1184 # Get sum of bond orders to hydrogen atoms only... | |
| 1185 # | |
| 1186 sub GetSumOfBondOrdersToHydrogenAtoms { | |
| 1187 my($This) = @_; | |
| 1188 | |
| 1189 # Is this atom in a molecule? | |
| 1190 if (!$This->HasProperty('Molecule')) { | |
| 1191 return undef; | |
| 1192 } | |
| 1193 my($ToNonHydrogenAtomsOnly, $ToHydrogenAtomsOnly) = (0, 1); | |
| 1194 | |
| 1195 return $This->_GetSumOfBondOrders($ToNonHydrogenAtomsOnly, $ToHydrogenAtomsOnly); | |
| 1196 } | |
| 1197 | |
| 1198 # Get sum of bond orders to all bonded atoms, non-hydrogen or hydrogen bonded atoms... | |
| 1199 # | |
| 1200 sub _GetSumOfBondOrders { | |
| 1201 my($This, $ToNonHydrogenAtomsOnly, $ToHydrogenAtomsOnly) = @_; | |
| 1202 | |
| 1203 # Check flags... | |
| 1204 if (!defined $ToNonHydrogenAtomsOnly) { | |
| 1205 $ToNonHydrogenAtomsOnly = 0; | |
| 1206 } | |
| 1207 if (!defined $ToHydrogenAtomsOnly) { | |
| 1208 $ToHydrogenAtomsOnly = 0; | |
| 1209 } | |
| 1210 my($Bond, $SumOfBondOrders, @Bonds); | |
| 1211 @Bonds = (); | |
| 1212 | |
| 1213 if ($ToNonHydrogenAtomsOnly) { | |
| 1214 @Bonds = $This->GetBondsToNonHydrogenAtoms(); | |
| 1215 } | |
| 1216 elsif ($ToHydrogenAtomsOnly) { | |
| 1217 @Bonds = $This->GetBondsToHydrogenAtoms(); | |
| 1218 } | |
| 1219 else { | |
| 1220 # All bonds... | |
| 1221 @Bonds = $This->GetBonds(); | |
| 1222 } | |
| 1223 | |
| 1224 $SumOfBondOrders = 0; | |
| 1225 for $Bond (@Bonds) { | |
| 1226 $SumOfBondOrders += $Bond->GetBondOrder(); | |
| 1227 } | |
| 1228 | |
| 1229 if ($SumOfBondOrders =~ /\./) { | |
| 1230 # | |
| 1231 # Change any fractional bond order to next largest integer... | |
| 1232 # | |
| 1233 # As long as aromatic bond orders in a ring are correctly using using 4n + 2 Huckel rule | |
| 1234 # (BondOrder: 1.5) or explicity set as Kekule bonds (alternate single/double), | |
| 1235 # SumOfBondOrders should add up to an integer. | |
| 1236 # | |
| 1237 $SumOfBondOrders = ceil($SumOfBondOrders); | |
| 1238 } | |
| 1239 | |
| 1240 return $SumOfBondOrders; | |
| 1241 } | |
| 1242 | |
| 1243 # Get largest bond order to any bonded atoms... | |
| 1244 # | |
| 1245 sub GetLargestBondOrder { | |
| 1246 my($This) = @_; | |
| 1247 | |
| 1248 # Is this atom in a molecule? | |
| 1249 if (!$This->HasProperty('Molecule')) { | |
| 1250 return undef; | |
| 1251 } | |
| 1252 | |
| 1253 return $This->_GetLargestBondOrder(); | |
| 1254 } | |
| 1255 | |
| 1256 # Get largest bond order to bonded non-hydrogen atoms... | |
| 1257 # | |
| 1258 sub GetLargestBondOrderToHeavyAtoms { | |
| 1259 my($This) = @_; | |
| 1260 | |
| 1261 return $This->GetLargestBondOrderToNonHydrogenAtoms(); | |
| 1262 } | |
| 1263 | |
| 1264 # Get largest bond order to bonded non-hydrogen atoms... | |
| 1265 # | |
| 1266 sub GetLargestBondOrderToNonHydrogenAtoms { | |
| 1267 my($This) = @_; | |
| 1268 | |
| 1269 # Is this atom in a molecule? | |
| 1270 if (!$This->HasProperty('Molecule')) { | |
| 1271 return undef; | |
| 1272 } | |
| 1273 | |
| 1274 my($ToNonHydrogenAtomsOnly) = (1); | |
| 1275 | |
| 1276 return $This->_GetLargestBondOrder($ToNonHydrogenAtomsOnly); | |
| 1277 } | |
| 1278 | |
| 1279 # Get largest bond order to all bonded atoms, non-hydrogen or hydrogen bonded atoms... | |
| 1280 # | |
| 1281 sub _GetLargestBondOrder { | |
| 1282 my($This, $ToNonHydrogenAtomsOnly, $ToHydrogenAtomsOnly) = @_; | |
| 1283 | |
| 1284 # Check flags... | |
| 1285 if (!defined $ToNonHydrogenAtomsOnly) { | |
| 1286 $ToNonHydrogenAtomsOnly = 0; | |
| 1287 } | |
| 1288 if (!defined $ToHydrogenAtomsOnly) { | |
| 1289 $ToHydrogenAtomsOnly = 0; | |
| 1290 } | |
| 1291 my($Bond, $LargestBondOrder, $BondOrder, @Bonds); | |
| 1292 @Bonds = (); | |
| 1293 | |
| 1294 if ($ToNonHydrogenAtomsOnly) { | |
| 1295 @Bonds = $This->GetBondsToNonHydrogenAtoms(); | |
| 1296 } | |
| 1297 elsif ($ToHydrogenAtomsOnly) { | |
| 1298 @Bonds = $This->GetBondsToHydrogenAtoms(); | |
| 1299 } | |
| 1300 else { | |
| 1301 # All bonds... | |
| 1302 @Bonds = $This->GetBonds(); | |
| 1303 } | |
| 1304 | |
| 1305 $LargestBondOrder = 0; | |
| 1306 for $Bond (@Bonds) { | |
| 1307 $BondOrder = $Bond->GetBondOrder(); | |
| 1308 if ($BondOrder > $LargestBondOrder) { | |
| 1309 $LargestBondOrder = $BondOrder; | |
| 1310 } | |
| 1311 } | |
| 1312 | |
| 1313 return $LargestBondOrder; | |
| 1314 } | |
| 1315 | |
| 1316 # Get number of implicit hydrogen for atom... | |
| 1317 # | |
| 1318 sub GetImplicitHydrogens { | |
| 1319 my($This) = @_; | |
| 1320 | |
| 1321 return $This->GetNumOfImplicitHydrogens(); | |
| 1322 } | |
| 1323 | |
| 1324 # Get number of implicit hydrogen for atom... | |
| 1325 # | |
| 1326 sub GetNumOfImplicitHydrogens { | |
| 1327 my($This) = @_; | |
| 1328 | |
| 1329 # Is this atom in a molecule? | |
| 1330 if (!$This->HasProperty('Molecule')) { | |
| 1331 return undef; | |
| 1332 } | |
| 1333 | |
| 1334 # Is ImplicitHydrogens property explicitly set? | |
| 1335 if ($This->HasProperty('ImplicitHydrogens')) { | |
| 1336 return $This->GetProperty('ImplicitHydrogens'); | |
| 1337 } | |
| 1338 | |
| 1339 # Is it an element symbol? | |
| 1340 if (!$This->{AtomicNumber}) { | |
| 1341 return 0; | |
| 1342 } | |
| 1343 | |
| 1344 my($ImplicitHydrogens, $PotentialTotalValence, $SumOfBondOrders); | |
| 1345 | |
| 1346 $ImplicitHydrogens = 0; | |
| 1347 $SumOfBondOrders = $This->GetSumOfBondOrders(); | |
| 1348 $PotentialTotalValence = $This->GetPotentialTotalCommonValence(); | |
| 1349 | |
| 1350 if (defined($PotentialTotalValence) && defined($SumOfBondOrders)) { | |
| 1351 # Subtract sum of bond orders to non-hydrogen and hydrogen atom neighbors... | |
| 1352 $ImplicitHydrogens = $PotentialTotalValence - $SumOfBondOrders; | |
| 1353 } | |
| 1354 | |
| 1355 return $ImplicitHydrogens > 0 ? $ImplicitHydrogens : 0; | |
| 1356 } | |
| 1357 | |
| 1358 # Get number of bonds available to form additional bonds with heavy atoms, excluding | |
| 1359 # any implicit bonds to hydrogens set using ImplicitHydrogens property. | |
| 1360 # | |
| 1361 # It's different from number of implicit or missing hydrogens, both of which are equivalent. | |
| 1362 # | |
| 1363 # For example, in a SMILES string, [nH] ring atom corresponds to an aromatic nitrogen. | |
| 1364 # Although the hydrogen specified for n is treated internally as implicit hydrogen and shows | |
| 1365 # up in missing hydrogen count, it's not available to participate in double bonds to additional | |
| 1366 # heavy atoms. | |
| 1367 # | |
| 1368 sub GetNumOfBondsAvailableForHeavyAtoms { | |
| 1369 my($This) = @_; | |
| 1370 | |
| 1371 return $This->GetNumOfBondsAvailableForNonHydrogenAtoms(); | |
| 1372 } | |
| 1373 | |
| 1374 # It's another name for GetNumOfBondsAvailableForHeavyAtoms | |
| 1375 # | |
| 1376 sub GetNumOfBondsAvailableForNonHydrogenAtoms { | |
| 1377 my($This) = @_; | |
| 1378 my($NumOfAvailableBonds, $PotentialTotalValence, $SumOfBondOrders); | |
| 1379 | |
| 1380 $NumOfAvailableBonds = 0; | |
| 1381 | |
| 1382 $SumOfBondOrders = $This->GetSumOfBondOrders(); | |
| 1383 $PotentialTotalValence = $This->GetPotentialTotalCommonValence(); | |
| 1384 | |
| 1385 if (defined($PotentialTotalValence) && defined($SumOfBondOrders)) { | |
| 1386 # Subtract sum of bond orders to non-hydrogen and hydrogen atom neighbors... | |
| 1387 $NumOfAvailableBonds = $PotentialTotalValence - $SumOfBondOrders; | |
| 1388 } | |
| 1389 | |
| 1390 if ($This->HasProperty('ImplicitHydrogens')) { | |
| 1391 $NumOfAvailableBonds -= $This->GetProperty('ImplicitHydrogens'); | |
| 1392 } | |
| 1393 | |
| 1394 return $NumOfAvailableBonds > 0 ? $NumOfAvailableBonds : 0; | |
| 1395 } | |
| 1396 | |
| 1397 # Disable setting of explicit hydrogens property... | |
| 1398 sub SetExplicitHydrogens { | |
| 1399 my($This, $Value) = @_; | |
| 1400 | |
| 1401 carp "Warning: ${ClassName}->SetExplicitHydrogens: Setting of explicit hydrogens is not supported..."; | |
| 1402 | |
| 1403 return $This; | |
| 1404 } | |
| 1405 | |
| 1406 # Get number of explicit hydrogens for atom... | |
| 1407 # | |
| 1408 sub GetExplicitHydrogens { | |
| 1409 my($This) = @_; | |
| 1410 | |
| 1411 return $This->GetNumOfExplicitHydrogens(); | |
| 1412 } | |
| 1413 | |
| 1414 # Get number of explicit hydrogens for atom... | |
| 1415 # | |
| 1416 sub GetNumOfExplicitHydrogens { | |
| 1417 my($This) = @_; | |
| 1418 my($HydrogenAtomNbrs); | |
| 1419 | |
| 1420 # Is this atom in a molecule? | |
| 1421 if (!$This->HasProperty('Molecule')) { | |
| 1422 return undef; | |
| 1423 } | |
| 1424 | |
| 1425 $HydrogenAtomNbrs = $This->GetNumOfHydrogenAtomNeighbors(); | |
| 1426 | |
| 1427 return defined $HydrogenAtomNbrs ? $HydrogenAtomNbrs : 0; | |
| 1428 } | |
| 1429 | |
| 1430 # Get num of missing hydrogens... | |
| 1431 # | |
| 1432 sub GetMissingHydrogens { | |
| 1433 my($This) = @_; | |
| 1434 | |
| 1435 return $This->GetNumOfMissingHydrogens(); | |
| 1436 } | |
| 1437 | |
| 1438 # Get num of missing hydrogens... | |
| 1439 # | |
| 1440 sub GetNumOfMissingHydrogens { | |
| 1441 my($This) = @_; | |
| 1442 | |
| 1443 # Is this atom in a molecule? | |
| 1444 if (!$This->HasProperty('Molecule')) { | |
| 1445 return undef; | |
| 1446 } | |
| 1447 | |
| 1448 return $This->GetNumOfImplicitHydrogens(); | |
| 1449 } | |
| 1450 | |
| 1451 # Get total number of hydrogens... | |
| 1452 # | |
| 1453 sub GetHydrogens { | |
| 1454 my($This) = @_; | |
| 1455 | |
| 1456 return $This->GetNumOfHydrogens(); | |
| 1457 } | |
| 1458 | |
| 1459 # Get total number of hydrogens... | |
| 1460 # | |
| 1461 sub GetNumOfHydrogens { | |
| 1462 my($This) = @_; | |
| 1463 | |
| 1464 # Is this atom in a molecule? | |
| 1465 if (!$This->HasProperty('Molecule')) { | |
| 1466 return undef; | |
| 1467 } | |
| 1468 | |
| 1469 return $This->GetNumOfImplicitHydrogens() + $This->GetNumOfExplicitHydrogens(); | |
| 1470 } | |
| 1471 | |
| 1472 # Valence corresponds to the number of electrons used by an atom in bonding: | |
| 1473 # | |
| 1474 # Valence = ValenceElectrons - ValenceFreeElectrons = BondingElectrons | |
| 1475 # | |
| 1476 # Single, double, triple bonds with bond orders of 1, 2 and 3 correspond to contribution of | |
| 1477 # 1, 2, and 3 bonding electrons. So Valence can be computed using: | |
| 1478 # | |
| 1479 # Valence = SumOfBondOrders + NumOfMissingHydrogens + FormalCharge | |
| 1480 # | |
| 1481 # where positive and negative values of FormalCharge increase and decrease the number | |
| 1482 # of bonding electrons respectively. | |
| 1483 # | |
| 1484 # The current release of MayaChemTools supports the following three valence models, which | |
| 1485 # are used during calculation of implicit hydrogens: MDLValenceModel, DaylightValenceModel, | |
| 1486 # InternalValenceModel or MayaChemToolsValenceModel. | |
| 1487 # | |
| 1488 # Notes: | |
| 1489 # . This doesn't always corresponds to explicit valence. | |
| 1490 # . Missing hydrogens are included in the valence. | |
| 1491 # . For neutral molecules, valence and sum of bond order are equal. | |
| 1492 # . For molecules containing only single bonds, SumOfBondOrders and NumOfBonds are equal. | |
| 1493 # . Free radical electrons lead to the decrease in valence. For atoms with explicit assignment | |
| 1494 # of SpinMultiplicity property values corresponding to Singlet (two unparied electrons | |
| 1495 # corresponding to one spin state), Doublet (free radical; an unpaired electron corresponding | |
| 1496 # to two spin states), and Triplet (two unparied electrons corresponding to three spin states; | |
| 1497 # divalent carbon atoms (carbenes)), FreeRadicalElectrons are calculated as follows: | |
| 1498 # | |
| 1499 # SpinMultiplicity: Doublet(2); FreeRadicalElectrons: 1 (one valence electron not available for bonding) | |
| 1500 # SpinMultiplicity: Singlet(1)/Triplet(3); FreeRadicalElectrons: 2 (two valence electrons not available for bonding) | |
| 1501 # | |
| 1502 sub GetValence { | |
| 1503 my($This) = @_; | |
| 1504 | |
| 1505 # Is this atom in a molecule? | |
| 1506 if (!$This->HasProperty('Molecule')) { | |
| 1507 return undef; | |
| 1508 } | |
| 1509 | |
| 1510 # Is Valence property explicitly set? | |
| 1511 if ($This->HasProperty('Valence')) { | |
| 1512 return $This->GetProperty('Valence'); | |
| 1513 } | |
| 1514 my($Valence); | |
| 1515 | |
| 1516 $Valence = $This->GetSumOfBondOrders() + $This->GetNumOfMissingHydrogens() + $This->GetFormalCharge(); | |
| 1517 | |
| 1518 return $Valence > 0 ? $Valence : 0; | |
| 1519 } | |
| 1520 | |
| 1521 # Get free non-bodning valence electrons left on atom after taking into account | |
| 1522 # sum of bond orders, missing hydrogens and formal charged on the atom. Free | |
| 1523 # radical electrons are included in the valence free electrons count by default. | |
| 1524 # | |
| 1525 # Valence corresponds to number of electrons used by atom in bonding: | |
| 1526 # | |
| 1527 # Valence = ValenceElectrons - ValenceFreeElectrons | |
| 1528 # | |
| 1529 # Additionally, valence can also be calculated by: | |
| 1530 # | |
| 1531 # Valence = SumOfBondOrders + NumOfMissingHydrogens + FormalCharge | |
| 1532 # | |
| 1533 # Valence and SumOfBondOrders are equal for neutral molecules. | |
| 1534 # | |
| 1535 # From two formulas for Valence described above, non-bonding free electrons | |
| 1536 # left can be computed by: | |
| 1537 # | |
| 1538 # ValenceFreeElectrons = ValenceElectrons - Valence | |
| 1539 # = ValenceElectrons - SumOfBondOrders - | |
| 1540 # NumOfMissingHydrogens - FormalCharge | |
| 1541 # | |
| 1542 # . Notes: | |
| 1543 # . Missing hydrogens are excluded from the valence free electrons. | |
| 1544 # . Any free radical electrons are considered part of the valence free electrons | |
| 1545 # by default. | |
| 1546 # | |
| 1547 # Examples: | |
| 1548 # | |
| 1549 # o NH3: ValenceFreeElectrons = 5 - 3 = 5 - 3 - 0 - 0 = 2 | |
| 1550 # o NH2: ValenceFreeElectrons = 5 - 3 = 5 - 2 - 1 - 0 = 2 | |
| 1551 # o NH4+; ValenceFreeElectrons = 5 - 5 = 5 - 4 - 0 - 1 = 0 | |
| 1552 # o NH3+; ValenceFreeElectrons = 5 - 5 = 5 - 3 - 1 - 1 = 0 | |
| 1553 # o C(=O)O- : ValenceFreeElectrons on O- = 6 - 0 = 6 - 1 - 0 - (-1) = 6 | |
| 1554 # o C(=O)O- : ValenceFreeElectrons on =O = 6 - 2 = 6 - 2 - 0 - 0 = 4 | |
| 1555 # | |
| 1556 # | |
| 1557 sub GetValenceFreeElectrons { | |
| 1558 my($This, $ExcludeFreeRadicalElectrons) = @_; | |
| 1559 | |
| 1560 # Is this atom in a molecule? | |
| 1561 if (!$This->HasProperty('Molecule')) { | |
| 1562 return undef; | |
| 1563 } | |
| 1564 | |
| 1565 # Is ValenceFreeElectrons property explicitly set? | |
| 1566 if ($This->HasProperty('ValenceFreeElectrons')) { | |
| 1567 return $This->GetProperty('ValenceFreeElectrons'); | |
| 1568 } | |
| 1569 | |
| 1570 if (!$This->{AtomicNumber}) { | |
| 1571 return 0; | |
| 1572 } | |
| 1573 | |
| 1574 my($ValenceFreeElectrons); | |
| 1575 | |
| 1576 $ValenceFreeElectrons = $This->GetValenceElectrons() - $This->GetValence(); | |
| 1577 if ($ExcludeFreeRadicalElectrons) { | |
| 1578 $ValenceFreeElectrons -= $This->GetFreeRadicalElectrons(); | |
| 1579 } | |
| 1580 | |
| 1581 return $ValenceFreeElectrons > 0 ? $ValenceFreeElectrons : 0; | |
| 1582 } | |
| 1583 | |
| 1584 # Get potential total common valence for calculating the number of implicit hydrogens | |
| 1585 # using the specified common valence model or default internal model for a molecule... | |
| 1586 # | |
| 1587 sub GetPotentialTotalCommonValence { | |
| 1588 my($This) = @_; | |
| 1589 | |
| 1590 # Is this atom in a molecule? | |
| 1591 if (!$This->HasProperty('Molecule')) { | |
| 1592 return undef; | |
| 1593 } | |
| 1594 my($PotentialTotalValence, $ValenceModel); | |
| 1595 | |
| 1596 $PotentialTotalValence = 0; | |
| 1597 $ValenceModel = $This->GetProperty('Molecule')->GetValenceModel(); | |
| 1598 | |
| 1599 VALENCEMODEL: { | |
| 1600 if ($ValenceModel =~ /^MDLValenceModel$/i) { | |
| 1601 $PotentialTotalValence = $This->_GetPotentialTotalCommonValenceUsingMDLValenceModel(); | |
| 1602 last VALENCEMODEL; | |
| 1603 } | |
| 1604 if ($ValenceModel =~ /^DaylightValenceModel$/i) { | |
| 1605 $PotentialTotalValence = $This->_GetPotentialTotalCommonValenceUsingDaylightValenceModel(); | |
| 1606 last VALENCEMODEL; | |
| 1607 } | |
| 1608 if ($ValenceModel !~ /^(InternalValenceModel|MayaChemToolsValenceModel)$/i) { | |
| 1609 carp "Warning: ${ClassName}->GetPotentialTotalCommonValence: The current release of MayaChemTools doesn't support the specified valence model $ValenceModel. Supported valence models: MDLValenceModel, DaylightValenceModel, InternalValenceModel. Using internal valence model..."; | |
| 1610 } | |
| 1611 # Use internal valence model as the default valence model... | |
| 1612 $PotentialTotalValence = $This->_GetPotentialTotalCommonValenceUsingInternalValenceModel(); | |
| 1613 } | |
| 1614 | |
| 1615 return $PotentialTotalValence; | |
| 1616 } | |
| 1617 | |
| 1618 # Get potential total common valence using data for MDL valence model available in file, | |
| 1619 # lib/data/MDLValenceModelData.csv, distributed with the package... | |
| 1620 # | |
| 1621 sub _GetPotentialTotalCommonValenceUsingMDLValenceModel { | |
| 1622 my($This) = @_; | |
| 1623 | |
| 1624 return $This->_GetPotentialTotalCommonValenceUsingValenceModelData(\%MDLValenceModelDataMap); | |
| 1625 | |
| 1626 } | |
| 1627 | |
| 1628 # Get potential total common valence using data for Daylight valence model available in file, | |
| 1629 # lib/data/DaylightValenceModelData.csv, distributed with the release... | |
| 1630 # | |
| 1631 sub _GetPotentialTotalCommonValenceUsingDaylightValenceModel { | |
| 1632 my($This) = @_; | |
| 1633 | |
| 1634 return $This->_GetPotentialTotalCommonValenceUsingValenceModelData(\%DaylightValenceModelDataMap); | |
| 1635 } | |
| 1636 | |
| 1637 # Get potential total common valence using data for a specific valence model... | |
| 1638 # | |
| 1639 sub _GetPotentialTotalCommonValenceUsingValenceModelData { | |
| 1640 my($This, $ValenceModelDataRef) = @_; | |
| 1641 my($AtomicNumber, $FormalCharge); | |
| 1642 | |
| 1643 $AtomicNumber = $This->{AtomicNumber}; | |
| 1644 if (!$AtomicNumber) { | |
| 1645 return 0; | |
| 1646 } | |
| 1647 | |
| 1648 $FormalCharge = $This->GetFormalCharge(); | |
| 1649 | |
| 1650 # Is any valence model data available for atomic number and formal charge? | |
| 1651 if (!exists $ValenceModelDataRef->{$AtomicNumber}) { | |
| 1652 return 0; | |
| 1653 } | |
| 1654 if (!exists $ValenceModelDataRef->{$AtomicNumber}{$FormalCharge}) { | |
| 1655 return 0; | |
| 1656 } | |
| 1657 | |
| 1658 my($PotentialTotalValence, $SumOfBondOrders, $CurrentEffectiveValence, $AvailableCommonValence); | |
| 1659 | |
| 1660 $SumOfBondOrders = $This->GetSumOfBondOrders(); | |
| 1661 if (!defined $SumOfBondOrders) { | |
| 1662 $SumOfBondOrders = 0; | |
| 1663 } | |
| 1664 $CurrentEffectiveValence = $SumOfBondOrders + $This->GetFreeRadicalElectrons(); | |
| 1665 | |
| 1666 $PotentialTotalValence = 0; | |
| 1667 VALENCE: for $AvailableCommonValence (@{$ValenceModelDataRef->{$AtomicNumber}{$FormalCharge}{CommonValences}}) { | |
| 1668 if ($CurrentEffectiveValence <= $AvailableCommonValence) { | |
| 1669 $PotentialTotalValence = $AvailableCommonValence; | |
| 1670 last VALENCE; | |
| 1671 } | |
| 1672 } | |
| 1673 | |
| 1674 return $PotentialTotalValence; | |
| 1675 } | |
| 1676 | |
| 1677 # | |
| 1678 # For elements with one one common valence, potential total common valence used | |
| 1679 # during the calculation for number of implicit hydrogens during InternalValenceMode | |
| 1680 # corresponds to: | |
| 1681 # | |
| 1682 # CommonValence + FormalCharge - FreeRadicalElectrons | |
| 1683 # | |
| 1684 # For elements with multiple common valences, each common valence is used to | |
| 1685 # calculate total potential common valence as shown above, and the first total potential | |
| 1686 # common valence gerater than the sum of bond orderes is selected as the final total | |
| 1687 # common valence. | |
| 1688 # | |
| 1689 # Group numbers > 14 - Group numbers 15 (N), 16 (O), 17 (F), 18 (He) | |
| 1690 # | |
| 1691 # Formal charge sign is not adjusted. Positive and negative values result in the | |
| 1692 # increase and decrease of valence. | |
| 1693 # | |
| 1694 # Group 14 containing C, Si, Ge, Sn, Pb... | |
| 1695 # | |
| 1696 # Formal charge sign is reversed for positive values. Both positive and negative | |
| 1697 # values result in the decrease of valence. | |
| 1698 # | |
| 1699 # Group 13 containing B, Al, Ga, In, Tl... | |
| 1700 # | |
| 1701 # Formal charge sign is always reversed. Positive and negative values result in the | |
| 1702 # decrease and increase of valence. | |
| 1703 # | |
| 1704 # Groups 1 (H) through 12 (Zn)... | |
| 1705 # | |
| 1706 # Formal charge sign is reversed for positive values. Both positive and negative | |
| 1707 # values result in the decrease of valence. | |
| 1708 # | |
| 1709 # Lanthanides and actinides... | |
| 1710 # | |
| 1711 # Formal charge sign is reversed for positive values. Both positive and negative | |
| 1712 # values result in the decrease of valence. | |
| 1713 # | |
| 1714 # Notes: | |
| 1715 # . CommonValence and HighestCommonValence available from PeriodicTable module | |
| 1716 # are equivalent to most common and highest sum of bond orders for an element. For | |
| 1717 # neutral atoms involved only in single bonds, it corresponds to highest number of | |
| 1718 # allowed bonds for the atom. | |
| 1719 # . FormalCharge sign is reversed for electropositive elements with positive formal charge | |
| 1720 # during common valence calculations. Electropositive elements, metals and transition elements, | |
| 1721 # have usually plus formal charge and it leads to decrease in common valence; the negative | |
| 1722 # formal charge should result in the decrease of common valence. | |
| 1723 # . For carbon, both plus/minus formal charge cause decrease in common valence | |
| 1724 # . For elements on the right of carbon in periodic table, electronegative elements, plus formal | |
| 1725 # charge causes common valence to increase and minus formal charge cause it to decrease. | |
| 1726 # | |
| 1727 sub _GetPotentialTotalCommonValenceUsingInternalValenceModel { | |
| 1728 my($This) = @_; | |
| 1729 my($AtomicNumber, $CommonValences); | |
| 1730 | |
| 1731 $AtomicNumber = $This->{AtomicNumber}; | |
| 1732 if (!$AtomicNumber) { | |
| 1733 return 0; | |
| 1734 } | |
| 1735 | |
| 1736 $CommonValences = PeriodicTable::GetElementCommonValences($AtomicNumber); | |
| 1737 if (!$CommonValences) { | |
| 1738 return 0; | |
| 1739 } | |
| 1740 | |
| 1741 my($PotentialTotalValence, $AdjustedFormalCharge, $FreeRadicalElectrons, $SumOfBondOrders, $AvailableCommonValence, @AvailableCommonValences); | |
| 1742 | |
| 1743 $AdjustedFormalCharge = $This->_GetFormalChargeAdjustedForInternalValenceModel(); | |
| 1744 $FreeRadicalElectrons = $This->GetFreeRadicalElectrons(); | |
| 1745 | |
| 1746 $SumOfBondOrders = $This->GetSumOfBondOrders(); | |
| 1747 if (!defined $SumOfBondOrders) { | |
| 1748 $SumOfBondOrders = 0; | |
| 1749 } | |
| 1750 | |
| 1751 @AvailableCommonValences = split /\,/, $CommonValences; | |
| 1752 | |
| 1753 if (@AvailableCommonValences == 1) { | |
| 1754 # Calculate potential total valence using the only available common valence... | |
| 1755 $PotentialTotalValence = $AvailableCommonValences[0] + $AdjustedFormalCharge - $FreeRadicalElectrons; | |
| 1756 } | |
| 1757 else { | |
| 1758 # Calculate potential total valence using common valence from a list of available valences | |
| 1759 # that makes it higher than sum of bond orders or using the highest common valence... | |
| 1760 VALENCE: for $AvailableCommonValence (@AvailableCommonValences) { | |
| 1761 $PotentialTotalValence = $AvailableCommonValence + $AdjustedFormalCharge - $FreeRadicalElectrons; | |
| 1762 | |
| 1763 if ($PotentialTotalValence < 0 || $PotentialTotalValence >= $SumOfBondOrders) { | |
| 1764 last VALENCE; | |
| 1765 } | |
| 1766 } | |
| 1767 } | |
| 1768 | |
| 1769 return $PotentialTotalValence > 0 ? $PotentialTotalValence : 0; | |
| 1770 } | |
| 1771 | |
| 1772 # Adjust sign of the formal charge for potential total common valence calculation | |
| 1773 # used during internal valence model to figure out number of implicit hydrogens. | |
| 1774 # | |
| 1775 sub _GetFormalChargeAdjustedForInternalValenceModel { | |
| 1776 my($This) = @_; | |
| 1777 my($FormalCharge, $GroupNumber, $SwitchSign); | |
| 1778 | |
| 1779 $FormalCharge = $This->GetFormalCharge(); | |
| 1780 if ($FormalCharge == 0) { | |
| 1781 return 0; | |
| 1782 } | |
| 1783 | |
| 1784 $GroupNumber = $This->GetGroupNumber(); | |
| 1785 if (!defined $GroupNumber) { | |
| 1786 return $FormalCharge; | |
| 1787 } | |
| 1788 | |
| 1789 # Group numbers > 14 - Group numbers 15 (N), 16 (O), 17 (F), 18 (He) | |
| 1790 # | |
| 1791 # Formal charge sign is not adjusted. Positive and negative values result in the | |
| 1792 # increase and decrease of valence. | |
| 1793 # | |
| 1794 # Group 14 containing C, Si, Ge, Sn, Pb... | |
| 1795 # | |
| 1796 # Formal charge sign is reversed for positive values. Both positive and negative | |
| 1797 # values result in the decrease of valence. | |
| 1798 # | |
| 1799 # Group 13 containing B, Al, Ga, In, Tl... | |
| 1800 # | |
| 1801 # Formal charge sign is always reversed. Positive and negative values result in the | |
| 1802 # decrease and increase of valence. | |
| 1803 # | |
| 1804 # Groups 1 (H) through 12 (Zn)... | |
| 1805 # | |
| 1806 # Formal charge sign is reversed for positive values. Both positive and negative | |
| 1807 # values result in the decrease of valence. | |
| 1808 # | |
| 1809 # Lanthanides and actinides... | |
| 1810 # | |
| 1811 # Formal charge sign is reversed for positive values. Both positive and negative | |
| 1812 # values result in the decrease of valence. | |
| 1813 # | |
| 1814 | |
| 1815 $SwitchSign = 0; | |
| 1816 if (length $GroupNumber) { | |
| 1817 GROUPNUMBER: { | |
| 1818 if ($GroupNumber > 14) { | |
| 1819 # Groups on the right side of C group in the periodic table... | |
| 1820 $SwitchSign = 0; | |
| 1821 last GROUPNUMBER; | |
| 1822 } | |
| 1823 if ($GroupNumber == 14) { | |
| 1824 # Group containing C, Si, Ge, Sn, Pb... | |
| 1825 $SwitchSign = ($FormalCharge > 0) ? 1 : 0; | |
| 1826 last GROUPNUMBER; | |
| 1827 } | |
| 1828 if ($GroupNumber == 13) { | |
| 1829 # Group containing B, Al, Ga, In, Tl... | |
| 1830 $SwitchSign = 1; | |
| 1831 last GROUPNUMBER; | |
| 1832 } | |
| 1833 # Groups 1 (H) through 12 (Zn)... | |
| 1834 if ($GroupNumber >=1 && $GroupNumber <= 12) { | |
| 1835 # Groups 1 (H) through 12 (Zn)... | |
| 1836 $SwitchSign = ($FormalCharge > 0) ? 1 : 0; | |
| 1837 last GROUPNUMBER; | |
| 1838 } | |
| 1839 } | |
| 1840 } | |
| 1841 else { | |
| 1842 # Lanthanides and actinides... | |
| 1843 $SwitchSign = ($FormalCharge > 0) ? 1 : 0; | |
| 1844 } | |
| 1845 | |
| 1846 if ($SwitchSign) { | |
| 1847 $FormalCharge *= -1.0; | |
| 1848 } | |
| 1849 | |
| 1850 return $FormalCharge; | |
| 1851 } | |
| 1852 | |
| 1853 # Get lowest common valence... | |
| 1854 sub GetLowestCommonValence { | |
| 1855 my($This) = @_; | |
| 1856 | |
| 1857 # Is LowestCommonValence property explicitly set? | |
| 1858 if ($This->HasProperty('LowestCommonValence')) { | |
| 1859 return $This->GetProperty('LowestCommonValence'); | |
| 1860 } | |
| 1861 my($AtomicNumber, $LowestCommonValence); | |
| 1862 | |
| 1863 $AtomicNumber = $This->{AtomicNumber}; | |
| 1864 if (!$AtomicNumber) { | |
| 1865 return 0; | |
| 1866 } | |
| 1867 # Any need to differentiate between internal and other valence models... | |
| 1868 | |
| 1869 # LowestCommonValence is not set for all elements... | |
| 1870 $LowestCommonValence = PeriodicTable::GetElementLowestCommonValence($AtomicNumber); | |
| 1871 if (!$LowestCommonValence) { | |
| 1872 $LowestCommonValence = undef; | |
| 1873 } | |
| 1874 | |
| 1875 return $LowestCommonValence; | |
| 1876 } | |
| 1877 | |
| 1878 # Get highest common valence... | |
| 1879 sub GetHighestCommonValence { | |
| 1880 my($This) = @_; | |
| 1881 | |
| 1882 # Is HighestCommonValence property explicitly set? | |
| 1883 if ($This->HasProperty('HighestCommonValence')) { | |
| 1884 return $This->GetProperty('HighestCommonValence'); | |
| 1885 } | |
| 1886 my($AtomicNumber, $HighestCommonValence); | |
| 1887 | |
| 1888 $AtomicNumber = $This->{AtomicNumber}; | |
| 1889 if (!$AtomicNumber) { | |
| 1890 return 0; | |
| 1891 } | |
| 1892 | |
| 1893 # Any need to differentiate between internal and other valence models... | |
| 1894 | |
| 1895 # HighestCommonValence is not set for all elements... | |
| 1896 $HighestCommonValence = PeriodicTable::GetElementHighestCommonValence($AtomicNumber); | |
| 1897 if (!$HighestCommonValence) { | |
| 1898 $HighestCommonValence = undef; | |
| 1899 } | |
| 1900 | |
| 1901 return $HighestCommonValence; | |
| 1902 } | |
| 1903 | |
| 1904 # Get valence electrons... | |
| 1905 sub GetValenceElectrons { | |
| 1906 my($This) = @_; | |
| 1907 | |
| 1908 # Is ValenceElectrons property explicitly set? | |
| 1909 if ($This->HasProperty('ValenceElectrons')) { | |
| 1910 return $This->GetProperty('ValenceElectrons'); | |
| 1911 } | |
| 1912 my($AtomicNumber, $ValenceElectrons); | |
| 1913 | |
| 1914 $AtomicNumber = $This->{AtomicNumber}; | |
| 1915 if (!$AtomicNumber) { | |
| 1916 return 0; | |
| 1917 } | |
| 1918 | |
| 1919 $ValenceElectrons = PeriodicTable::GetElementValenceElectrons($AtomicNumber); | |
| 1920 | |
| 1921 return $ValenceElectrons; | |
| 1922 } | |
| 1923 | |
| 1924 # Add hydrogens to specified atom in molecule and return number of hydrogens added: | |
| 1925 # | |
| 1926 # o HydrogensToAdd = ImplicitHydrogenCount - ExplicitHydrogenCount | |
| 1927 # | |
| 1928 # o XYZ are set to ZeroVector | |
| 1929 # | |
| 1930 sub AddHydrogens { | |
| 1931 my($This, $HydrogenPositionsWarning) = @_; | |
| 1932 | |
| 1933 # Is this atom in a molecule? | |
| 1934 if (!$This->HasProperty('Molecule')) { | |
| 1935 return undef; | |
| 1936 } | |
| 1937 if (!defined $HydrogenPositionsWarning) { | |
| 1938 $HydrogenPositionsWarning = 1; | |
| 1939 } | |
| 1940 if ($HydrogenPositionsWarning) { | |
| 1941 carp "Warning: ${ClassName}->AddHydrogens: The current release of MayaChemTools doesn't assign any hydrogen positions..."; | |
| 1942 } | |
| 1943 | |
| 1944 # Is it an element symbol? | |
| 1945 if (!$This->{AtomicNumber}) { | |
| 1946 return 0; | |
| 1947 } | |
| 1948 | |
| 1949 my($Molecule, $HydrogensAdded, $HydrogensToAdd); | |
| 1950 | |
| 1951 $Molecule = $This->GetProperty('Molecule'); | |
| 1952 $HydrogensAdded = 0; | |
| 1953 $HydrogensToAdd = $This->GetNumOfMissingHydrogens(); | |
| 1954 if ($HydrogensToAdd <= 0) { | |
| 1955 return $HydrogensAdded; | |
| 1956 } | |
| 1957 | |
| 1958 my($Count, $Hydrogen); | |
| 1959 | |
| 1960 for $Count (1 .. $HydrogensToAdd) { | |
| 1961 $HydrogensAdded++; | |
| 1962 | |
| 1963 $Hydrogen = $Molecule->NewAtom('AtomSymbol' => 'H', 'XYZ' => [0, 0, 0]); | |
| 1964 $Molecule->NewBond('Atoms' => [$This, $Hydrogen], 'BondOrder' => 1); | |
| 1965 } | |
| 1966 | |
| 1967 return $HydrogensAdded; | |
| 1968 } | |
| 1969 | |
| 1970 # Delete hydrogens attached to atom in molecule and return total number of hydrogens deleted... | |
| 1971 sub DeleteHydrogens { | |
| 1972 my($This) = @_; | |
| 1973 | |
| 1974 # Is this atom in a molecule? | |
| 1975 if (!$This->HasProperty('Molecule')) { | |
| 1976 return undef; | |
| 1977 } | |
| 1978 | |
| 1979 # Is it an element symbol? | |
| 1980 if (!$This->{AtomicNumber}) { | |
| 1981 return 0; | |
| 1982 } | |
| 1983 | |
| 1984 my($Molecule, $Neighbor, $HydrogensDeleted, @Neighbors); | |
| 1985 | |
| 1986 $Molecule = $This->GetProperty('Molecule'); | |
| 1987 $HydrogensDeleted = 0; | |
| 1988 @Neighbors = $This->GetNeighbors(); | |
| 1989 | |
| 1990 NEIGHBOR: for $Neighbor (@Neighbors) { | |
| 1991 if (!$Neighbor->IsHydrogen()) { | |
| 1992 next NEIGHBOR; | |
| 1993 } | |
| 1994 $Molecule->_DeleteAtom($Neighbor); | |
| 1995 $HydrogensDeleted++; | |
| 1996 } | |
| 1997 | |
| 1998 return $HydrogensDeleted; | |
| 1999 } | |
| 2000 | |
| 2001 # Copy atom and all its associated data... | |
| 2002 sub Copy { | |
| 2003 my($This) = @_; | |
| 2004 my($Atom); | |
| 2005 | |
| 2006 $Atom = Storable::dclone($This); | |
| 2007 | |
| 2008 return $Atom; | |
| 2009 } | |
| 2010 | |
| 2011 # Get atomic invariant value... | |
| 2012 # | |
| 2013 sub GetAtomicInvariantValue { | |
| 2014 my($This, $AtomicInvariant) = @_; | |
| 2015 my($Value); | |
| 2016 | |
| 2017 $Value = ""; | |
| 2018 | |
| 2019 ATOMICVARIANT: { | |
| 2020 if ($AtomicInvariant =~ /^(AS|AtomSymbol|ElementSymbol)$/i) { | |
| 2021 $Value = $This->GetAtomSymbol(); | |
| 2022 last ATOMICVARIANT; | |
| 2023 } | |
| 2024 if ($AtomicInvariant =~ /^(X|NumOfNonHydrogenAtomNeighbors|NumOfHeavyAtomNeighbors)$/i) { | |
| 2025 $Value = $This->GetNumOfNonHydrogenAtomNeighbors(); | |
| 2026 last ATOMICVARIANT; | |
| 2027 } | |
| 2028 if ($AtomicInvariant =~ /^(BO|SumOfBondOrdersToNonHydrogenAtoms|SumOfBondOrdersToHeavyAtoms)$/i) { | |
| 2029 $Value = $This->GetSumOfBondOrdersToNonHydrogenAtoms(); | |
| 2030 last ATOMICVARIANT; | |
| 2031 } | |
| 2032 if ($AtomicInvariant =~ /^(LBO|LargestBondOrderToNonHydrogenAtoms|LargestBondOrderToHeavyAtoms)$/i) { | |
| 2033 $Value = $This->GetLargestBondOrderToNonHydrogenAtoms(); | |
| 2034 last ATOMICVARIANT; | |
| 2035 } | |
| 2036 if ($AtomicInvariant =~ /^(H|NumOfImplicitAndExplicitHydrogens)$/i) { | |
| 2037 $Value = $This->GetNumOfHydrogens(); | |
| 2038 last ATOMICVARIANT; | |
| 2039 } | |
| 2040 if ($AtomicInvariant =~ /^(SB|NumOfSingleBondsToNonHydrogenAtoms|NumOfSingleBondsToHeavyAtoms)$/i) { | |
| 2041 $Value = $This->GetNumOfSingleBondsToNonHydrogenAtoms(); | |
| 2042 last ATOMICVARIANT; | |
| 2043 } | |
| 2044 if ($AtomicInvariant =~ /^(DB|NumOfDoubleBondsToNonHydrogenAtoms|NumOfDoubleBondsToHeavyAtoms)$/i) { | |
| 2045 $Value = $This->GetNumOfDoubleBondsToNonHydrogenAtoms(); | |
| 2046 last ATOMICVARIANT; | |
| 2047 } | |
| 2048 if ($AtomicInvariant =~ /^(TB|NumOfTripleBondsToNonHydrogenAtoms|NumOfTripleBondsToHeavyAtoms)$/i) { | |
| 2049 $Value = $This->GetNumOfTripleBondsToNonHydrogenAtoms(); | |
| 2050 last ATOMICVARIANT; | |
| 2051 } | |
| 2052 if ($AtomicInvariant =~ /^(AB|NumOfAromaticBondsToNonHydrogenAtoms|NumOfAromaticBondsToHeavyAtoms)$/i) { | |
| 2053 $Value = $This->GetNumOfAromaticBondsToNonHydrogenAtoms(); | |
| 2054 last ATOMICVARIANT; | |
| 2055 } | |
| 2056 if ($AtomicInvariant =~ /^(FC|FormalCharge)$/i) { | |
| 2057 $Value = $This->GetFormalCharge(); | |
| 2058 $Value = defined $Value ? $Value : 0; | |
| 2059 last ATOMICVARIANT; | |
| 2060 } | |
| 2061 if ($AtomicInvariant =~ /^(T|TotalNumOfAtomNeighbors)$/i) { | |
| 2062 $Value = $This->GetNumOfNonHydrogenAtomNeighbors() + $This->GetNumOfHydrogens(); | |
| 2063 last ATOMICVARIANT; | |
| 2064 } | |
| 2065 if ($AtomicInvariant =~ /^(TSB|TotalNumOfSingleBonds)$/i) { | |
| 2066 $Value = $This->GetNumOfSingleBondsToNonHydrogenAtoms() + $This->GetNumOfHydrogens(); | |
| 2067 last ATOMICVARIANT; | |
| 2068 } | |
| 2069 if ($AtomicInvariant =~ /^(Ar|Aromatic)$/i) { | |
| 2070 $Value = $This->IsAromatic() ? 1 : 0; | |
| 2071 last ATOMICVARIANT; | |
| 2072 } | |
| 2073 if ($AtomicInvariant =~ /^(RA|RingAtom)$/i) { | |
| 2074 $Value = $This->IsInRing() ? 1 : 0; | |
| 2075 last ATOMICVARIANT; | |
| 2076 } | |
| 2077 if ($AtomicInvariant =~ /^(Str|Stereochemistry)$/i) { | |
| 2078 $Value = $This->GetStereochemistry(); | |
| 2079 $Value= (defined($Value) && ($Value =~ /^(R|S)$/i)) ? $Value : ''; | |
| 2080 last ATOMICVARIANT; | |
| 2081 } | |
| 2082 if ($AtomicInvariant =~ /^(AN|AtomicNumber)$/i) { | |
| 2083 $Value = $This->GetAtomicNumber(); | |
| 2084 last ATOMICVARIANT; | |
| 2085 } | |
| 2086 if ($AtomicInvariant =~ /^(AM|AtomicMass)$/i) { | |
| 2087 $Value = round($This->GetExactMass(), 4) + 0; | |
| 2088 last ATOMICVARIANT; | |
| 2089 } | |
| 2090 if ($AtomicInvariant =~ /^(MN|MassNumber)$/i) { | |
| 2091 $Value = $This->GetMassNumber(); | |
| 2092 last ATOMICVARIANT; | |
| 2093 } | |
| 2094 if ($AtomicInvariant =~ /^(SM|SpinMultiplicity)$/i) { | |
| 2095 $Value = $This->GetSpinMultiplicity(); | |
| 2096 $Value = defined $Value ? $Value : ''; | |
| 2097 last ATOMICVARIANT; | |
| 2098 } | |
| 2099 $Value = ""; | |
| 2100 carp "Warning: ${ClassName}->GetAtomicInvariantValue: Unknown atomic invariant $AtomicInvariant..."; | |
| 2101 } | |
| 2102 | |
| 2103 return $Value; | |
| 2104 } | |
| 2105 | |
| 2106 # Get period number of the atom.. | |
| 2107 # | |
| 2108 sub GetPeriodNumber { | |
| 2109 my($This) = @_; | |
| 2110 | |
| 2111 # Is PeriodNumber property explicitly set? | |
| 2112 if ($This->HasProperty('PeriodNumber')) { | |
| 2113 return $This->GetProperty('PeriodNumber'); | |
| 2114 } | |
| 2115 my($AtomicNumber, $PeriodNumber); | |
| 2116 | |
| 2117 $AtomicNumber = $This->{AtomicNumber}; | |
| 2118 if (!$AtomicNumber) { | |
| 2119 return 0; | |
| 2120 } | |
| 2121 | |
| 2122 $PeriodNumber = PeriodicTable::GetElementPeriodNumber($AtomicNumber); | |
| 2123 | |
| 2124 return $PeriodNumber; | |
| 2125 } | |
| 2126 | |
| 2127 # Get group number of the atom.. | |
| 2128 # | |
| 2129 sub GetGroupNumber { | |
| 2130 my($This) = @_; | |
| 2131 | |
| 2132 # Is GroupNumber property explicitly set? | |
| 2133 if ($This->HasProperty('GroupNumber')) { | |
| 2134 return $This->GetProperty('GroupNumber'); | |
| 2135 } | |
| 2136 my($AtomicNumber, $GroupNumber); | |
| 2137 | |
| 2138 $AtomicNumber = $This->{AtomicNumber}; | |
| 2139 if (!$AtomicNumber) { | |
| 2140 return 0; | |
| 2141 } | |
| 2142 | |
| 2143 $GroupNumber = PeriodicTable::GetElementGroupNumber($AtomicNumber); | |
| 2144 | |
| 2145 return $GroupNumber; | |
| 2146 } | |
| 2147 | |
| 2148 # Is it a specified topological pharmacophore atom type? | |
| 2149 # | |
| 2150 sub IsTopologicalPharmacophoreType { | |
| 2151 my($This, $Type) = @_; | |
| 2152 | |
| 2153 return $This->_IsFunctionalClassType($Type); | |
| 2154 } | |
| 2155 | |
| 2156 # Is it a specified functional class atom type? | |
| 2157 # | |
| 2158 sub IsFunctionalClassType { | |
| 2159 my($This, $Type) = @_; | |
| 2160 | |
| 2161 return $This->_IsFunctionalClassType($Type); | |
| 2162 } | |
| 2163 | |
| 2164 # Is it a specified functional/topological pharmacophore atom type? | |
| 2165 # | |
| 2166 sub _IsFunctionalClassType { | |
| 2167 my($This, $Type) = @_; | |
| 2168 my($Value); | |
| 2169 | |
| 2170 $Value = 0; | |
| 2171 | |
| 2172 TYPE: { | |
| 2173 if ($Type =~ /^(HBD|HydrogenBondDonor)$/i) { | |
| 2174 $Value = $This->IsHydrogenBondDonor(); | |
| 2175 last TYPE; | |
| 2176 } | |
| 2177 if ($Type =~ /^(HBA|HydrogenBondAcceptor)$/i) { | |
| 2178 $Value = $This->IsHydrogenBondAcceptor(); | |
| 2179 last TYPE; | |
| 2180 } | |
| 2181 if ($Type =~ /^(PI|PositivelyIonizable)$/i) { | |
| 2182 $Value = $This->IsPositivelyIonizable(); | |
| 2183 last TYPE; | |
| 2184 } | |
| 2185 if ($Type =~ /^(NI|NegativelyIonizable)$/i) { | |
| 2186 $Value = $This->IsNegativelyIonizable(); | |
| 2187 last TYPE; | |
| 2188 } | |
| 2189 if ($Type =~ /^(H|Hydrophobic)$/i) { | |
| 2190 $Value = $This->IsHydrophobic(); | |
| 2191 last TYPE; | |
| 2192 } | |
| 2193 if ($Type =~ /^(Ar|Aromatic)$/i) { | |
| 2194 $Value = $This->IsAromatic(); | |
| 2195 last TYPE; | |
| 2196 } | |
| 2197 if ($Type =~ /^(Hal|Halogen)$/i) { | |
| 2198 $Value = $This->IsHalogen(); | |
| 2199 last TYPE; | |
| 2200 } | |
| 2201 if ($Type =~ /^(RA|RingAtom)$/i) { | |
| 2202 $Value = $This->IsInRing(); | |
| 2203 last TYPE; | |
| 2204 } | |
| 2205 if ($Type =~ /^(CA|ChainAtom)$/i) { | |
| 2206 $Value = $This->IsNotInRing(); | |
| 2207 last TYPE; | |
| 2208 } | |
| 2209 $Value = 0; | |
| 2210 carp "Warning: ${ClassName}->_IsType: Unknown functional/pharmacohore type $Type..."; | |
| 2211 } | |
| 2212 return $Value; | |
| 2213 } | |
| 2214 | |
| 2215 # Is it a Hydrogen atom? | |
| 2216 sub IsHydrogen { | |
| 2217 my($This) = @_; | |
| 2218 | |
| 2219 return ($This->{AtomicNumber} == 1) ? 1 : 0; | |
| 2220 } | |
| 2221 | |
| 2222 # Is it a Carbon atom? | |
| 2223 sub IsCarbon { | |
| 2224 my($This) = @_; | |
| 2225 | |
| 2226 return ($This->{AtomicNumber} == 6) ? 1 : 0; | |
| 2227 } | |
| 2228 | |
| 2229 # Is it a Nitrogen atom? | |
| 2230 sub IsNitrogen { | |
| 2231 my($This) = @_; | |
| 2232 | |
| 2233 return ($This->{AtomicNumber} == 7) ? 1 : 0; | |
| 2234 } | |
| 2235 | |
| 2236 # Is it a Oxygen atom? | |
| 2237 sub IsOxygen { | |
| 2238 my($This) = @_; | |
| 2239 | |
| 2240 return ($This->{AtomicNumber} == 8) ? 1 : 0; | |
| 2241 } | |
| 2242 | |
| 2243 # Is it a Fluorine atom? | |
| 2244 sub IsFluorine { | |
| 2245 my($This) = @_; | |
| 2246 | |
| 2247 return ($This->{AtomicNumber} == 9) ? 1 : 0; | |
| 2248 } | |
| 2249 | |
| 2250 # Is it a Silicon atom? | |
| 2251 sub IsSilicon { | |
| 2252 my($This) = @_; | |
| 2253 | |
| 2254 return ($This->{AtomicNumber} == 14) ? 1 : 0; | |
| 2255 } | |
| 2256 | |
| 2257 # Is it a Phosphorus atom? | |
| 2258 sub IsPhosphorus { | |
| 2259 my($This) = @_; | |
| 2260 | |
| 2261 return ($This->{AtomicNumber} == 15) ? 1 : 0; | |
| 2262 } | |
| 2263 | |
| 2264 # Is it a Sulphur atom? | |
| 2265 sub IsSulphur { | |
| 2266 my($This) = @_; | |
| 2267 | |
| 2268 return $This->IsSulfur(); | |
| 2269 } | |
| 2270 | |
| 2271 # Is it a Sulfur atom? | |
| 2272 sub IsSulfur { | |
| 2273 my($This) = @_; | |
| 2274 | |
| 2275 return ($This->{AtomicNumber} == 16) ? 1 : 0; | |
| 2276 } | |
| 2277 | |
| 2278 # Is it a Chlorine atom? | |
| 2279 sub IsChlorine { | |
| 2280 my($This) = @_; | |
| 2281 | |
| 2282 return ($This->{AtomicNumber} == 17) ? 1 : 0; | |
| 2283 } | |
| 2284 | |
| 2285 # Is it a Arsenic atom? | |
| 2286 sub IsArsenic { | |
| 2287 my($This) = @_; | |
| 2288 | |
| 2289 return ($This->{AtomicNumber} == 33) ? 1 : 0; | |
| 2290 } | |
| 2291 | |
| 2292 # Is it a Selenium atom? | |
| 2293 sub IsSelenium { | |
| 2294 my($This) = @_; | |
| 2295 | |
| 2296 return ($This->{AtomicNumber} == 34) ? 1 : 0; | |
| 2297 } | |
| 2298 | |
| 2299 # Is it a Bromine atom? | |
| 2300 sub IsBromine { | |
| 2301 my($This) = @_; | |
| 2302 | |
| 2303 return ($This->{AtomicNumber} == 35) ? 1 : 0; | |
| 2304 } | |
| 2305 | |
| 2306 # Is it a Tellurium atom? | |
| 2307 sub IsTellurium { | |
| 2308 my($This) = @_; | |
| 2309 | |
| 2310 return ($This->{AtomicNumber} == 52) ? 1 : 0; | |
| 2311 } | |
| 2312 | |
| 2313 # Is it a Iodine atom? | |
| 2314 sub IsIodine { | |
| 2315 my($This) = @_; | |
| 2316 | |
| 2317 return ($This->{AtomicNumber} == 53) ? 1 : 0; | |
| 2318 } | |
| 2319 | |
| 2320 # Is it a hetro atom? (N, O, F, P, S, Cl, Br, I) | |
| 2321 sub IsHeteroAtom { | |
| 2322 my($This) = @_; | |
| 2323 | |
| 2324 return ($This->{AtomicNumber} =~ /^(7|8|9|15|16|17|35|53)$/) ? 1 : 0; | |
| 2325 } | |
| 2326 | |
| 2327 # Is it a halogen atom? (F, Cl, Br, I) | |
| 2328 sub IsHalogen { | |
| 2329 my($This) = @_; | |
| 2330 | |
| 2331 return ($This->{AtomicNumber} =~ /^(9|17|35|53)$/) ? 1 : 0; | |
| 2332 } | |
| 2333 | |
| 2334 # Is it classified as metallic? | |
| 2335 sub IsMetallic { | |
| 2336 my($This) = @_; | |
| 2337 my($Classification); | |
| 2338 | |
| 2339 $Classification = PeriodicTable::GetElementClassification($This->{AtomicNumber}); | |
| 2340 | |
| 2341 return ($Classification =~ /^Metallic$/i) ? 1 : 0; | |
| 2342 } | |
| 2343 | |
| 2344 # Is it a non carbon or hydrogen atom? (C, H) | |
| 2345 sub IsNonCarbonOrHydrogen { | |
| 2346 my($This) = @_; | |
| 2347 | |
| 2348 return ($This->{AtomicNumber} =~ /^(1|6)$/) ? 0 : 1; | |
| 2349 } | |
| 2350 | |
| 2351 # Is it a polar atom? ( N, O, P, S) | |
| 2352 sub IsPolarAtom { | |
| 2353 my($This) = @_; | |
| 2354 | |
| 2355 return ($This->{AtomicNumber} =~ /^(7|8|15|16)$/) ? 1 : 0; | |
| 2356 } | |
| 2357 | |
| 2358 # Is it an isotope? | |
| 2359 sub IsIsotope { | |
| 2360 my($This) = @_; | |
| 2361 | |
| 2362 my($AtomicNumber) = $This->{AtomicNumber}; | |
| 2363 if (!$AtomicNumber) { | |
| 2364 return 0; | |
| 2365 } | |
| 2366 | |
| 2367 if (!$This->HasProperty('MassNumber')) { | |
| 2368 return 0; | |
| 2369 } | |
| 2370 my($MassNumber, $MostAbundantMassNumber); | |
| 2371 | |
| 2372 $MassNumber = $This->GetProperty('MassNumber'); | |
| 2373 $MostAbundantMassNumber = PeriodicTable::GetElementMostAbundantNaturalIsotopeMassNumber($AtomicNumber); | |
| 2374 | |
| 2375 return ($MassNumber == $MostAbundantMassNumber) ? 0 : 1; | |
| 2376 } | |
| 2377 | |
| 2378 # Is it a terminal atom? | |
| 2379 sub IsTerminal { | |
| 2380 my($This) = @_; | |
| 2381 | |
| 2382 # Is this atom in a molecule? | |
| 2383 if (!$This->HasProperty('Molecule')) { | |
| 2384 return undef; | |
| 2385 } | |
| 2386 | |
| 2387 return ($This->GetNumOfNonHydrogenAtomNeighbors() <= 1) ? 1 : 0 | |
| 2388 | |
| 2389 } | |
| 2390 | |
| 2391 # Is aromatic property set for the atom? | |
| 2392 sub IsAromatic { | |
| 2393 my($This) = @_; | |
| 2394 my($Aromatic); | |
| 2395 | |
| 2396 $Aromatic = $This->GetAromatic(); | |
| 2397 | |
| 2398 return (defined($Aromatic) && $Aromatic) ? 1 : 0; | |
| 2399 } | |
| 2400 | |
| 2401 # Is this a hydrogen atom and attached to one of these atoms: N, O, P, S | |
| 2402 sub IsPolarHydrogen { | |
| 2403 my($This) = @_; | |
| 2404 | |
| 2405 if (!$This->IsHydrogen()) { | |
| 2406 return 0; | |
| 2407 } | |
| 2408 | |
| 2409 my(@Bonds); | |
| 2410 @Bonds = $This->GetBonds(); | |
| 2411 if (@Bonds > 1) { | |
| 2412 return 0; | |
| 2413 } | |
| 2414 | |
| 2415 my($Bond, $BondedAtom); | |
| 2416 ($Bond) = @Bonds; | |
| 2417 $BondedAtom = $Bond->GetBondedAtom($This); | |
| 2418 | |
| 2419 return $BondedAtom->IsPolarAtom() ? 1 : 0; | |
| 2420 } | |
| 2421 | |
| 2422 # Is it a hydrogen bond donor atom? | |
| 2423 # | |
| 2424 sub IsHBondDonor { | |
| 2425 my($This, $HydrogenBondsType) = @_; | |
| 2426 | |
| 2427 return $This->IsHydrogenBondDonor($HydrogenBondsType); | |
| 2428 } | |
| 2429 | |
| 2430 # The currrent release of MayaChemTools supports identification of two types of | |
| 2431 # hydrogen bond donor and acceptor atoms with these names: | |
| 2432 # | |
| 2433 # HBondsType1 or HydrogenBondsType1 | |
| 2434 # HBondsType2 or HydrogenBondsType2 | |
| 2435 # | |
| 2436 # The names of these hydrogen bond types are rather arbitrary. However, their | |
| 2437 # definitions have specific meaning and are as follows: | |
| 2438 # | |
| 2439 # HydrogenBondsType1 [ Ref 60-61, Ref 65-66 ]: | |
| 2440 # . Donor: NH, NH2, NH3, OH - Any N and O with available H | |
| 2441 # . Acceptor: N[!H], O - Any N without available H and any O | |
| 2442 # | |
| 2443 # HydrogenBondsType2 [ Ref 91 ]: | |
| 2444 # . Donor: NH, NH2, NH3, OH - Any N and O with availabe H | |
| 2445 # . Acceptor: N, O - Any N and O | |
| 2446 # | |
| 2447 # Note: | |
| 2448 # . HydrogenBondsType2 definition corresponds to Rule of 5. | |
| 2449 # | |
| 2450 | |
| 2451 # Is it a hydrogen bond donor atom? | |
| 2452 # | |
| 2453 # The currrent release of MayaChemTools supports identification of two types of | |
| 2454 sub IsHydrogenBondDonor { | |
| 2455 my($This, $HydrogenBondsType) = @_; | |
| 2456 my($Status); | |
| 2457 | |
| 2458 $HydrogenBondsType = defined $HydrogenBondsType ? $HydrogenBondsType : 'HBondsType1'; | |
| 2459 $Status = 0; | |
| 2460 | |
| 2461 HYDROGENBONDSTYPE: { | |
| 2462 | |
| 2463 if ($HydrogenBondsType =~ /^(HBondsType1|HydrogenBondsType1)$/i) { | |
| 2464 $Status = $This->_IsHydrogenBondDonorOfType1(); | |
| 2465 last HYDROGENBONDSTYPE; | |
| 2466 } | |
| 2467 | |
| 2468 if ($HydrogenBondsType =~ /^(HBondsType2|HydrogenBondsType2)$/i) { | |
| 2469 $Status = $This->_IsHydrogenBondDonorOfType2(); | |
| 2470 last HYDROGENBONDSTYPE; | |
| 2471 } | |
| 2472 | |
| 2473 $Status = 0; | |
| 2474 carp "Warning: ${ClassName}->IsHydrogenBondDonor: The current release of MayaChemTools doesn't support specified value, $HydrogenBondsType, for HydrogenBondsType. Valid values: HBondsType1, HydrogenBondsType1, HBondsType2 HydrogenBondsType2 ..."; | |
| 2475 } | |
| 2476 | |
| 2477 return $Status; | |
| 2478 } | |
| 2479 | |
| 2480 # Is it a MayaChemTools HBondType1 hydrogen bond donor atom? | |
| 2481 # | |
| 2482 sub _IsHydrogenBondDonorOfType1 { | |
| 2483 my($This) = @_; | |
| 2484 | |
| 2485 return $This->_IsHydrogenBondDonorOfType1OrType2(); | |
| 2486 } | |
| 2487 | |
| 2488 # Is it a MayaChemTools HBondType2 hydrogen bond donor atom? | |
| 2489 # | |
| 2490 sub _IsHydrogenBondDonorOfType2 { | |
| 2491 my($This) = @_; | |
| 2492 | |
| 2493 return $This->_IsHydrogenBondDonorOfType1OrType2(); | |
| 2494 } | |
| 2495 | |
| 2496 # Is it a hydrogen bond donor atom of MayaChemTools Type1 or Type2? | |
| 2497 # | |
| 2498 # HydrogenBondDonor definition [ Ref 60-61, Ref 65-66, Ref 91 ]: NH, NH2, OH | |
| 2499 # | |
| 2500 # In other words: | |
| 2501 # . NH, NH2 - Nitrogen atom with available hydrogen | |
| 2502 # . OH - Oxygen atom with avilable hydrogen | |
| 2503 # | |
| 2504 sub _IsHydrogenBondDonorOfType1OrType2 { | |
| 2505 my($This) = @_; | |
| 2506 | |
| 2507 # Is this atom in a molecule? | |
| 2508 if (!$This->HasProperty('Molecule')) { | |
| 2509 return 0; | |
| 2510 } | |
| 2511 | |
| 2512 # Is it N or O? | |
| 2513 if ($This->{AtomicNumber} !~ /^(7|8)$/) { | |
| 2514 return 0; | |
| 2515 } | |
| 2516 | |
| 2517 # Any explicitly attached hydrogens? | |
| 2518 if ($This->GetExplicitHydrogens()) { | |
| 2519 return 1; | |
| 2520 } | |
| 2521 | |
| 2522 # Any missing hydrogens? | |
| 2523 return $This->GetNumOfMissingHydrogens() ? 1 : 0; | |
| 2524 } | |
| 2525 | |
| 2526 # Is it a hydrogen bond acceptor atom? | |
| 2527 # | |
| 2528 sub IsHBondAcceptor { | |
| 2529 my($This, $HydrogenBondsType) = @_; | |
| 2530 | |
| 2531 return $This->IsHydrogenBondAcceptor($HydrogenBondsType); | |
| 2532 } | |
| 2533 | |
| 2534 # Is it a hydrogen bond acceptor atom? | |
| 2535 # | |
| 2536 sub IsHydrogenBondAcceptor { | |
| 2537 my($This, $HydrogenBondsType) = @_; | |
| 2538 my($Status); | |
| 2539 | |
| 2540 $HydrogenBondsType = defined $HydrogenBondsType ? $HydrogenBondsType : 'HBondsType1'; | |
| 2541 $Status = 0; | |
| 2542 | |
| 2543 HYDROGENBONDSTYPE: { | |
| 2544 | |
| 2545 if ($HydrogenBondsType =~ /^(HBondsType1|HydrogenBondsType1)$/i) { | |
| 2546 $Status = $This->_IsHydrogenBondAcceptorOfType1(); | |
| 2547 last HYDROGENBONDSTYPE; | |
| 2548 } | |
| 2549 | |
| 2550 if ($HydrogenBondsType =~ /^(HBondsType2|HydrogenBondsType2)$/i) { | |
| 2551 $Status = $This->_IsHydrogenBondAcceptorOfType2(); | |
| 2552 last HYDROGENBONDSTYPE; | |
| 2553 } | |
| 2554 | |
| 2555 $Status = 0; | |
| 2556 carp "Warning: ${ClassName}->IsHydrogenBondAcceptor: The current release of MayaChemTools doesn't support specified value, $HydrogenBondsType, for HydrogenBondsType. Valid values: HBondsType1, HydrogenBondsType1, HBondsType2 HydrogenBondsType2 ..."; | |
| 2557 } | |
| 2558 | |
| 2559 return $Status; | |
| 2560 } | |
| 2561 | |
| 2562 # Is it a MayaChemTools HBondType1 hydrogen bond acceptor atom? | |
| 2563 # | |
| 2564 # HydrogenBondAcceptor definition [ Ref 60-61, Ref 65-66 ]: N[!H], O | |
| 2565 # | |
| 2566 # In other words: | |
| 2567 # . N[!H] - Nitrogen atom with no hydrogen | |
| 2568 # . O - Oxygen atom | |
| 2569 # | |
| 2570 sub _IsHydrogenBondAcceptorOfType1 { | |
| 2571 my($This) = @_; | |
| 2572 | |
| 2573 # Is this atom in a molecule? | |
| 2574 if (!$This->HasProperty('Molecule')) { | |
| 2575 return 0; | |
| 2576 } | |
| 2577 | |
| 2578 # Is it N or O? | |
| 2579 if ($This->{AtomicNumber} !~ /^(7|8)$/) { | |
| 2580 return 0; | |
| 2581 } | |
| 2582 | |
| 2583 # Is it O? | |
| 2584 if ($This->{AtomicNumber} == 8 ) { | |
| 2585 return 1; | |
| 2586 } | |
| 2587 | |
| 2588 # Any explicitly attached hydrogens? | |
| 2589 if ($This->GetExplicitHydrogens()) { | |
| 2590 return 0; | |
| 2591 } | |
| 2592 | |
| 2593 # Any missing hydrogens? | |
| 2594 return $This->GetNumOfMissingHydrogens() ? 0 : 1; | |
| 2595 } | |
| 2596 | |
| 2597 # Is it a MayaChemTools HBondType2 hydrogen bond acceptor atom? | |
| 2598 # | |
| 2599 # HydrogenBondAcceptor definition [ Ref 91 ]: N, O | |
| 2600 # | |
| 2601 # In other words: | |
| 2602 # . Any Nitrogen or Oxygen atom | |
| 2603 # | |
| 2604 # Note: | |
| 2605 # . HydrogenBondsType2 definition corresponds to Rule of 5. | |
| 2606 # | |
| 2607 sub _IsHydrogenBondAcceptorOfType2 { | |
| 2608 my($This) = @_; | |
| 2609 | |
| 2610 # Is this atom in a molecule? | |
| 2611 if (!$This->HasProperty('Molecule')) { | |
| 2612 return 0; | |
| 2613 } | |
| 2614 | |
| 2615 return ($This->{AtomicNumber} =~ /^(7|8)$/) ? 1 : 0; | |
| 2616 } | |
| 2617 | |
| 2618 # Is it a positively ionizable atom? | |
| 2619 # | |
| 2620 # PositivelyIonizable defintion [ Ref 60-61, Ref 65-66 ]: +, NH2 | |
| 2621 # | |
| 2622 # In other words: | |
| 2623 # . Any atom with positve formal charge | |
| 2624 # . NH2 - Nitogen atom in amino group | |
| 2625 # | |
| 2626 sub IsPositivelyIonizable { | |
| 2627 my($This) = @_; | |
| 2628 my($FormalCharge); | |
| 2629 | |
| 2630 # Is this atom in a molecule? | |
| 2631 if (!$This->HasProperty('Molecule')) { | |
| 2632 return 0; | |
| 2633 } | |
| 2634 | |
| 2635 # Any explicit positive formal charge? | |
| 2636 $FormalCharge = $This->GetFormalCharge(); | |
| 2637 if (defined($FormalCharge) && $FormalCharge > 0) { | |
| 2638 return 1; | |
| 2639 } | |
| 2640 | |
| 2641 # Is it N? | |
| 2642 if ($This->{AtomicNumber} != 7 ) { | |
| 2643 return 0; | |
| 2644 } | |
| 2645 | |
| 2646 return ($This->GetNumOfHydrogens() == 2) ? 1 : 0; | |
| 2647 } | |
| 2648 | |
| 2649 # Is it a negatively ionizable atom? | |
| 2650 # | |
| 2651 # NegativelyIonizable definition [ Ref 60-61, Ref 65-66 ]: -, C(=O)OH, S(=O)OH, P(=O)OH | |
| 2652 # | |
| 2653 # In other words: | |
| 2654 # . Any atom with negative formal charge | |
| 2655 # . Carbon atom in C(=O)OH group | |
| 2656 # . Phosphorous in P(=O)OH group | |
| 2657 # . Sulfur atom in S(=O)OH group | |
| 2658 # | |
| 2659 sub IsNegativelyIonizable { | |
| 2660 my($This) = @_; | |
| 2661 my($FormalCharge); | |
| 2662 | |
| 2663 # Is this atom in a molecule? | |
| 2664 if (!$This->HasProperty('Molecule')) { | |
| 2665 return 0; | |
| 2666 } | |
| 2667 | |
| 2668 # Any explicit negative formal charge? | |
| 2669 $FormalCharge = $This->GetFormalCharge(); | |
| 2670 if (defined($FormalCharge) && $FormalCharge < 0) { | |
| 2671 return 1; | |
| 2672 } | |
| 2673 | |
| 2674 # Is it C, P or S? | |
| 2675 if ($This->{AtomicNumber} !~ /^(6|15|16)$/ ) { | |
| 2676 return 0; | |
| 2677 } | |
| 2678 | |
| 2679 # Collect oxygens connected to C, P or S with single or double bonds and not connected to | |
| 2680 # any other heavy atom... | |
| 2681 my($Neighbor, $NeighborOxygenBondOrder, $NumOfNeighborOxygensWithSingleBonds, $NumOfNeighborOxygensWithDoubleBonds); | |
| 2682 | |
| 2683 $NumOfNeighborOxygensWithSingleBonds = 0; $NumOfNeighborOxygensWithDoubleBonds = 0; | |
| 2684 | |
| 2685 NEIGHBOR: for $Neighbor ($This->GetNeighbors()) { | |
| 2686 # Is it an oxygen? | |
| 2687 if ($Neighbor->{AtomicNumber} != 8) { | |
| 2688 next NEIGHBOR; | |
| 2689 } | |
| 2690 # Is oxygent connected to only heavy atom? | |
| 2691 if ($Neighbor->GetNumOfHeavyAtomNeighbors() != 1) { | |
| 2692 next NEIGHBOR; | |
| 2693 } | |
| 2694 $NeighborOxygenBondOrder = $This->GetBondToAtom($Neighbor)->GetBondOrder(); | |
| 2695 | |
| 2696 if ($NeighborOxygenBondOrder == 2) { | |
| 2697 $NumOfNeighborOxygensWithDoubleBonds++; | |
| 2698 } | |
| 2699 elsif ($NeighborOxygenBondOrder == 1) { | |
| 2700 $NumOfNeighborOxygensWithSingleBonds++; | |
| 2701 } | |
| 2702 } | |
| 2703 return ($NumOfNeighborOxygensWithDoubleBonds >= 1 && $NumOfNeighborOxygensWithSingleBonds >= 1) ? 1 : 0; | |
| 2704 } | |
| 2705 | |
| 2706 # Is it a liphophilic atom? | |
| 2707 # | |
| 2708 # Lipophilic definition [ Ref 60-61, Ref 65-66 ]: C(C)(C)(C)(C), Cl, Br, I, S(C)(C) | |
| 2709 # | |
| 2710 # In other words: | |
| 2711 # . C(C)(C)(C)(C) - Carbon atom connected to only other carbons | |
| 2712 # . Chlorine, Bromine or Iodine atom | |
| 2713 # . S(C)(C) - Sulfur connected to two carbons | |
| 2714 # | |
| 2715 sub IsLipophilic { | |
| 2716 my($This) = @_; | |
| 2717 | |
| 2718 # Is this atom in a molecule? | |
| 2719 if (!$This->HasProperty('Molecule')) { | |
| 2720 return 0; | |
| 2721 } | |
| 2722 | |
| 2723 # Is it Cl, Br, I? | |
| 2724 if ($This->{AtomicNumber} =~ /^(17|35|53)$/) { | |
| 2725 return 1; | |
| 2726 } | |
| 2727 | |
| 2728 # Is it C, S? | |
| 2729 if ($This->{AtomicNumber} !~ /^(6|16)$/) { | |
| 2730 return 0; | |
| 2731 } | |
| 2732 | |
| 2733 # Are all heavy atom neighbors Carbons? | |
| 2734 my($HeavyAtomNeighbor, @HeavyAtomNeighbors); | |
| 2735 @HeavyAtomNeighbors = (); | |
| 2736 @HeavyAtomNeighbors = $This->GetHeavyAtomNeighbors(); | |
| 2737 | |
| 2738 for $HeavyAtomNeighbor (@HeavyAtomNeighbors) { | |
| 2739 if ($HeavyAtomNeighbor->{AtomicNumber} != 6) { | |
| 2740 return 0; | |
| 2741 } | |
| 2742 } | |
| 2743 | |
| 2744 # Does sulfur has two carbon neighbors? | |
| 2745 if ($This->{AtomicNumber} == 16) { | |
| 2746 if (@HeavyAtomNeighbors != 2) { | |
| 2747 return 0; | |
| 2748 } | |
| 2749 } | |
| 2750 return 1; | |
| 2751 } | |
| 2752 | |
| 2753 # Is it hydrophobic? | |
| 2754 # | |
| 2755 sub IsHydrophobic { | |
| 2756 my($This) = @_; | |
| 2757 | |
| 2758 return $This->IsLipophilic(); | |
| 2759 } | |
| 2760 | |
| 2761 # Is it a Nitrogen atom in Guadinium group? | |
| 2762 # | |
| 2763 sub IsGuadiniumNitrogen { | |
| 2764 my($This) = @_; | |
| 2765 | |
| 2766 # Is it Nitrogen? | |
| 2767 if (!$This->IsNitrogen()) { | |
| 2768 return 0; | |
| 2769 } | |
| 2770 | |
| 2771 # Is it connected to a Guadinium Carbon? | |
| 2772 my($AtomNeighbor); | |
| 2773 | |
| 2774 for $AtomNeighbor ($This->GetNonHydrogenAtomNeighbors()) { | |
| 2775 if ($AtomNeighbor->IsGuadiniumCarbon()) { | |
| 2776 return 1; | |
| 2777 } | |
| 2778 } | |
| 2779 | |
| 2780 return 0; | |
| 2781 } | |
| 2782 | |
| 2783 # Is it a Carbon atom in Guadinium group? | |
| 2784 # | |
| 2785 # Guadinium group definition: | |
| 2786 # | |
| 2787 # R2N-C(=NR)-(NR2) or R2N-C(=NR2+)-(NR2) | |
| 2788 # | |
| 2789 # where: | |
| 2790 # . R = Hydrogens or group of atoms attached through Carbon | |
| 2791 # . Only one of the three Nitrogens has a double bond to Carbon and has optional | |
| 2792 # formal charge allowing it to be neutral or charged state | |
| 2793 # | |
| 2794 sub IsGuadiniumCarbon { | |
| 2795 my($This) = @_; | |
| 2796 | |
| 2797 # Is it Carbon? | |
| 2798 if (!$This->IsCarbon()) { | |
| 2799 return 0; | |
| 2800 } | |
| 2801 | |
| 2802 # Match atom neighborhood... | |
| 2803 my($CentralAtomSpec, @NbrAtomSpecsRef, @NbrBondSpecsRef, @NbrOfNbrAtomSpecsRef); | |
| 2804 | |
| 2805 $CentralAtomSpec = 'C.X3.BO4'; | |
| 2806 @NbrAtomSpecsRef = ('N.FC0', 'N.FC0', 'N.FC0,N.FC+1'); | |
| 2807 @NbrBondSpecsRef = ('-', '-', '='); | |
| 2808 @NbrOfNbrAtomSpecsRef = ('C,H', 'C,H', 'C,H'); | |
| 2809 | |
| 2810 if ($This->DoesAtomNeighborhoodMatch($CentralAtomSpec, \@NbrAtomSpecsRef, \@NbrBondSpecsRef, \@NbrOfNbrAtomSpecsRef)) { | |
| 2811 return 1; | |
| 2812 } | |
| 2813 | |
| 2814 return 0; | |
| 2815 } | |
| 2816 | |
| 2817 # Is it a Nitrogen atom in Amide group? | |
| 2818 # | |
| 2819 sub IsAmideNitrogen { | |
| 2820 my($This) = @_; | |
| 2821 | |
| 2822 # Is it Nitrogen? | |
| 2823 if (!$This->IsNitrogen()) { | |
| 2824 return 0; | |
| 2825 } | |
| 2826 | |
| 2827 # Is it connected to a Amide Carbon? | |
| 2828 my($AtomNeighbor); | |
| 2829 | |
| 2830 for $AtomNeighbor ($This->GetNonHydrogenAtomNeighbors()) { | |
| 2831 if ($AtomNeighbor->IsAmideCarbon()) { | |
| 2832 return 1; | |
| 2833 } | |
| 2834 } | |
| 2835 | |
| 2836 return 0; | |
| 2837 } | |
| 2838 | |
| 2839 # Is it a Carbon atom in Amide group? | |
| 2840 # | |
| 2841 # Amide group definition: R-C(=O)-N(-R')-R'' | |
| 2842 # | |
| 2843 # where: | |
| 2844 # . R = Hydrogen or groups of atoms attached through Carbon | |
| 2845 # . R' = Hydrogens or groups of atoms attached through Carbon or hetro atoms | |
| 2846 # . R'' = Hydrogens or groups of atoms attached through Carbon or hetro atoms | |
| 2847 # | |
| 2848 sub IsAmideCarbon { | |
| 2849 my($This) = @_; | |
| 2850 | |
| 2851 # Is this atom in a molecule? | |
| 2852 if (!$This->HasProperty('Molecule')) { | |
| 2853 return 0; | |
| 2854 } | |
| 2855 | |
| 2856 # Is it Carbon? | |
| 2857 if (!$This->IsCarbon()) { | |
| 2858 return 0; | |
| 2859 } | |
| 2860 | |
| 2861 # Match atom neighborhood... | |
| 2862 my($CentralAtomSpec, @NbrAtomSpecsRef, @NbrBondSpecsRef, @NbrOfNbrAtomSpecsRef); | |
| 2863 | |
| 2864 $CentralAtomSpec = 'C.X3.BO4,C.X2.BO3'; | |
| 2865 @NbrAtomSpecsRef = ('C,H', 'O', 'N'); | |
| 2866 @NbrBondSpecsRef = ('-', '=', '-'); | |
| 2867 @NbrOfNbrAtomSpecsRef = ('C,H', 'C', 'C,H,N,O,S,P,F,Cl,Br,I'); | |
| 2868 | |
| 2869 if ($This->DoesAtomNeighborhoodMatch($CentralAtomSpec, \@NbrAtomSpecsRef, \@NbrBondSpecsRef, \@NbrOfNbrAtomSpecsRef)) { | |
| 2870 return 1; | |
| 2871 } | |
| 2872 | |
| 2873 return 0; | |
| 2874 } | |
| 2875 | |
| 2876 # Is it a Oxygen atom in Carboxylate group? | |
| 2877 # | |
| 2878 sub IsCarboxylateOxygen { | |
| 2879 my($This) = @_; | |
| 2880 | |
| 2881 return $This->_MatchCarboxylateAndOrCarboxylOxygen('Carboxylate'); | |
| 2882 } | |
| 2883 | |
| 2884 # Is it a Carbon atom in Carboxylate group? | |
| 2885 # | |
| 2886 # Carboxyl group definition: R-C(=O)-O- | |
| 2887 # | |
| 2888 sub IsCarboxylateCarbon { | |
| 2889 my($This) = @_; | |
| 2890 | |
| 2891 return $This->_MatchCarboxylateAndOrCarboxylCarbon('Carboxylate'); | |
| 2892 } | |
| 2893 | |
| 2894 # Is it a Oxygen atom in Carboxyl group? | |
| 2895 # | |
| 2896 sub IsCarboxylOxygen { | |
| 2897 my($This) = @_; | |
| 2898 | |
| 2899 return $This->_MatchCarboxylateAndOrCarboxylOxygen('Carboxyl'); | |
| 2900 } | |
| 2901 | |
| 2902 # Is it a Carbon atom in Carboxyl group? | |
| 2903 # | |
| 2904 # Carboxyl group definition: R-C(=O)-OH | |
| 2905 # | |
| 2906 sub IsCarboxylCarbon { | |
| 2907 my($This) = @_; | |
| 2908 | |
| 2909 return $This->_MatchCarboxylateAndOrCarboxylCarbon('Carboxyl'); | |
| 2910 } | |
| 2911 | |
| 2912 # Match Carboxylate and/or Carboxyl oxygen... | |
| 2913 # | |
| 2914 sub _MatchCarboxylateAndOrCarboxylOxygen { | |
| 2915 my($This, $Mode) = @_; | |
| 2916 | |
| 2917 # Is it Oxygen? | |
| 2918 if (!$This->IsOxygen()) { | |
| 2919 return 0; | |
| 2920 } | |
| 2921 | |
| 2922 # Is it connected to a Carboxylate Carbon? | |
| 2923 my($AtomNeighbor); | |
| 2924 | |
| 2925 for $AtomNeighbor ($This->GetNonHydrogenAtomNeighbors()) { | |
| 2926 if ($AtomNeighbor->_MatchCarboxylateAndOrCarboxylCarbon($Mode)) { | |
| 2927 return 1; | |
| 2928 } | |
| 2929 } | |
| 2930 | |
| 2931 return 0; | |
| 2932 } | |
| 2933 | |
| 2934 # Match Carboxylate and Carboxyl Carbon | |
| 2935 # | |
| 2936 # Carboxylate group definition: R-C(=O)-O- | |
| 2937 # Carboxyl group definition: R-C(=O)-OH | |
| 2938 # | |
| 2939 # where: | |
| 2940 # . R = Hydrogens or groups of atoms attached through Carbon | |
| 2941 # | |
| 2942 sub _MatchCarboxylateAndOrCarboxylCarbon { | |
| 2943 my($This, $Mode) = @_; | |
| 2944 | |
| 2945 # Is this atom in a molecule? | |
| 2946 if (!$This->HasProperty('Molecule')) { | |
| 2947 return 0; | |
| 2948 } | |
| 2949 | |
| 2950 # Is it Carbon? | |
| 2951 if (!$This->IsCarbon()) { | |
| 2952 return 0; | |
| 2953 } | |
| 2954 | |
| 2955 # Match atom neighborhood... | |
| 2956 my($CentralAtomSpec, @NbrAtomSpecsRef, @NbrBondSpecsRef, @NbrOfNbrAtomSpecsRef); | |
| 2957 | |
| 2958 $CentralAtomSpec = 'C.X3.BO4,C.X2.BO3'; | |
| 2959 MODE: { | |
| 2960 if ($Mode =~ /^Carboxylate$/i) { | |
| 2961 @NbrAtomSpecsRef = ('C,H', 'O', 'O.X1.FC-1'); | |
| 2962 last MODE; | |
| 2963 } | |
| 2964 if ($Mode =~ /^Carboxyl$/i) { | |
| 2965 @NbrAtomSpecsRef = ('C,H', 'O', 'O.X1.FC0'); | |
| 2966 last MODE; | |
| 2967 } | |
| 2968 if ($Mode =~ /^CarboxylateOrCarboxyl$/i) { | |
| 2969 @NbrAtomSpecsRef = ('C,H', 'O', 'O.X1.FC-1,O.X1.FC0'); | |
| 2970 last MODE; | |
| 2971 } | |
| 2972 carp "Warning: ${ClassName}->_MatchCarboxylateAndCarboxylCarbon.: Unknown mode $Mode..."; | |
| 2973 return 0; | |
| 2974 } | |
| 2975 @NbrBondSpecsRef = ('-', '=', '-'); | |
| 2976 @NbrOfNbrAtomSpecsRef = ('C,H', 'C', 'C'); | |
| 2977 | |
| 2978 if ($This->DoesAtomNeighborhoodMatch($CentralAtomSpec, \@NbrAtomSpecsRef, \@NbrBondSpecsRef, \@NbrOfNbrAtomSpecsRef)) { | |
| 2979 return 1; | |
| 2980 } | |
| 2981 | |
| 2982 return 0; | |
| 2983 } | |
| 2984 | |
| 2985 # Is it a Oxygen atom in Phosphate group? | |
| 2986 # | |
| 2987 sub IsPhosphateOxygen { | |
| 2988 my($This) = @_; | |
| 2989 | |
| 2990 # Is it Oxygen? | |
| 2991 if (!$This->IsOxygen()) { | |
| 2992 return 0; | |
| 2993 } | |
| 2994 | |
| 2995 # Is it connected to a Phosphate Phosphorus? | |
| 2996 my($AtomNeighbor); | |
| 2997 | |
| 2998 for $AtomNeighbor ($This->GetNonHydrogenAtomNeighbors()) { | |
| 2999 if ($AtomNeighbor->IsPhosphatePhosphorus()) { | |
| 3000 return 1; | |
| 3001 } | |
| 3002 } | |
| 3003 | |
| 3004 return 0; | |
| 3005 } | |
| 3006 | |
| 3007 # Is it a Phosphorus atom in Phosphate group? | |
| 3008 # | |
| 3009 # Phosphate group definition: AO-(O=)P(-OA)-OA | |
| 3010 # | |
| 3011 # where: | |
| 3012 # . A = Any Groups of atoms including hydrogens | |
| 3013 # | |
| 3014 sub IsPhosphatePhosphorus { | |
| 3015 my($This) = @_; | |
| 3016 | |
| 3017 # Is this atom in a molecule? | |
| 3018 if (!$This->HasProperty('Molecule')) { | |
| 3019 return 0; | |
| 3020 } | |
| 3021 | |
| 3022 # Is it Phosphorus? | |
| 3023 if (!$This->IsPhosphorus()) { | |
| 3024 return 0; | |
| 3025 } | |
| 3026 | |
| 3027 # Match atom neighborhood... | |
| 3028 my($CentralAtomSpec, @NbrAtomSpecsRef, @NbrBondSpecsRef, @NbrOfNbrAtomSpecsRef); | |
| 3029 | |
| 3030 $CentralAtomSpec = 'P.X4.BO5'; | |
| 3031 @NbrAtomSpecsRef = ('O', 'O', 'O', 'O'); | |
| 3032 @NbrBondSpecsRef = ('-', '=', '-', '-'); | |
| 3033 @NbrOfNbrAtomSpecsRef = (undef, undef, undef, undef); | |
| 3034 | |
| 3035 if ($This->DoesAtomNeighborhoodMatch($CentralAtomSpec, \@NbrAtomSpecsRef, \@NbrBondSpecsRef, \@NbrOfNbrAtomSpecsRef)) { | |
| 3036 return 1; | |
| 3037 } | |
| 3038 | |
| 3039 return 0; | |
| 3040 } | |
| 3041 | |
| 3042 | |
| 3043 # Match central atom and its neighborhood using specified atom and bonds specifications... | |
| 3044 # | |
| 3045 # Let: | |
| 3046 # AS = Atom symbol corresponding to element symbol, atomic number (#n) or any | |
| 3047 # atom (A) | |
| 3048 # | |
| 3049 # X<n> = Number of non-hydrogen atom neighbors or heavy atoms attached to atom | |
| 3050 # T<n> = Total number of atom neighbors including implcit and explicit hydrogens | |
| 3051 # BO<n> = Sum of bond orders to non-hydrogen atom neighbors or heavy atoms attached to atom | |
| 3052 # LBO<n> = Largest bond order of non-hydrogen atom neighbors or heavy atoms attached to atom | |
| 3053 # SB<n> = Number of single bonds to non-hydrogen atom neighbors or heavy atoms attached to atom | |
| 3054 # TSB<n> = Total number of single bonds to atom neighbors including implcit and explicit hydrogens | |
| 3055 # DB<n> = Number of double bonds to non-hydrogen atom neighbors or heavy atoms attached to atom | |
| 3056 # TB<n> = Number of triple bonds to non-hydrogen atom neighbors or heavy atoms attached to atom | |
| 3057 # H<n> = Number of implicit and explicit hydrogens for atom | |
| 3058 # Ar = Aromatic annotation indicating whether atom is aromatic | |
| 3059 # RA or RA<n> = Ring atom annotation indicating whether atom is a ring | |
| 3060 # TR<n> = Total number of rings containing atom | |
| 3061 # FC<+n/-n> = Formal charge assigned to atom | |
| 3062 # MN<n> = Mass number indicating isotope other than most abundant isotope | |
| 3063 # SM<n> = Spin multiplicity of atom. Possible values: 1 (singlet), 2 (doublet) or 3 (triplet) | |
| 3064 # | |
| 3065 # Then: | |
| 3066 # | |
| 3067 # Atom specification corresponds to: | |
| 3068 # | |
| 3069 # AS.X<n>.T<n>.BO<n>.LBO<n>.<SB><n>.TSB<n>.<DB><n>.<TB><n>.H<n>.Ar.RA<n>.TR<n>FC<+n/-n>.MN<n>.SM<n> | |
| 3070 # | |
| 3071 # Except for AS which is a required atomic invariant in atom specification, all other atomic invariants are | |
| 3072 # optional. For an atom specification to match an atom, the values of all specified atomic invariants must | |
| 3073 # match. Exclamation in from of atomic invariant can be used to negate its effect during the match. | |
| 3074 # | |
| 3075 # A comma delimited atom specification string is used to match any one of the specifed atom specification. | |
| 3076 # | |
| 3077 # Notes: | |
| 3078 # . During atom specification match to an atom, the first atomic invariant is always assumed to | |
| 3079 # atom symbol. | |
| 3080 # . Atom match specfication is based on AtomicInvariantAtomTypes implemented in | |
| 3081 # AotmTypes::AtomicInvariantAtomType.pm module | |
| 3082 # | |
| 3083 # Examples: | |
| 3084 # . ('N', 'N', 'N') | |
| 3085 # . ('N.FC0', 'N.FC0', 'N,N.FC+1.H1') | |
| 3086 # . ('N.H2', 'N.H2', 'N.H1') | |
| 3087 # . ('C,N', '!N', '!H') | |
| 3088 # . ('C,N', 'N.Ar', 'N.R5') | |
| 3089 # | |
| 3090 # Let: | |
| 3091 # -|1|s|Single = Single bond | |
| 3092 # =|2|d|Double = Double bond | |
| 3093 # #|3|t|Triple = Triple bond | |
| 3094 # :|1.5|a|Ar|Aromatic = Aromatic bond | |
| 3095 # | |
| 3096 # @|RB|Ring = Ring bond | |
| 3097 # ~|*|Any = Any bond | |
| 3098 # | |
| 3099 # Then: | |
| 3100 # | |
| 3101 # Bond specification corresponds to: | |
| 3102 # | |
| 3103 # -.: | |
| 3104 # =.@ | |
| 3105 # Double.Aromatic | |
| 3106 # | |
| 3107 # For a bond specification to match bond between two atoms, the values of all specified bond symbols must | |
| 3108 # match. Exclamation in from of bond symbol can be used to negate its effect during the match. | |
| 3109 # | |
| 3110 # A comma delimited bond specification string is used to match any one of the specifed atom specification. | |
| 3111 # | |
| 3112 sub DoesAtomNeighborhoodMatch { | |
| 3113 my($CentralAtom, $CentralAtomSpec, $NbrAtomSpecsRef, $NbrBondSpecsRef, $NbrOfNbrAtomSpecsRef) = @_; | |
| 3114 my($NumOfNbrAtomSpecs, $NumOfNbrBondSpecs, $NumOfNbrOfNbrAtomSpecs); | |
| 3115 | |
| 3116 # Is this atom in a molecule? | |
| 3117 if (!$CentralAtom->HasProperty('Molecule')) { | |
| 3118 return 0; | |
| 3119 } | |
| 3120 | |
| 3121 $NumOfNbrAtomSpecs = defined $NbrAtomSpecsRef ? scalar @{$NbrAtomSpecsRef} : 0; | |
| 3122 $NumOfNbrBondSpecs = defined $NbrBondSpecsRef ? scalar @{$NbrBondSpecsRef} : 0; | |
| 3123 $NumOfNbrOfNbrAtomSpecs = defined $NbrOfNbrAtomSpecsRef ? scalar @{$NbrOfNbrAtomSpecsRef} : 0; | |
| 3124 | |
| 3125 # Validate number of specifications... | |
| 3126 if ($NumOfNbrBondSpecs && ($NumOfNbrAtomSpecs != $NumOfNbrBondSpecs)) { | |
| 3127 carp "Warning: ${ClassName}->DoesAtomNeighborhoodMatch: Number of specified central atom, $NumOfNbrAtomSpecs, and bond, $NumOfNbrBondSpecs, specifications must be same; No neighborhood match performed ..."; | |
| 3128 return 0; | |
| 3129 } | |
| 3130 | |
| 3131 if ($NumOfNbrOfNbrAtomSpecs && ($NumOfNbrOfNbrAtomSpecs != $NumOfNbrAtomSpecs)) { | |
| 3132 carp "Warning: ${ClassName}->DoesAtomNeighborhoodMatch: Number of specified central atom, $NumOfNbrAtomSpecs, and neighbor of neighbor atoms specifications, $NumOfNbrOfNbrAtomSpecs, must be same; No neighborhood match performed ..."; | |
| 3133 return 0; | |
| 3134 } | |
| 3135 | |
| 3136 # Sort atom and bond specifications in terms of being most specific to least specific.. | |
| 3137 ($NbrAtomSpecsRef, $NbrBondSpecsRef, $NbrOfNbrAtomSpecsRef) = $CentralAtom->_SortSpecificationsForAtomNeighborhoodMatch($NbrAtomSpecsRef, $NbrBondSpecsRef, $NbrOfNbrAtomSpecsRef); | |
| 3138 | |
| 3139 # Does central atom specification match? | |
| 3140 if (!$CentralAtom->_DoesAtomSpecificationMatch($CentralAtomSpec)) { | |
| 3141 return 0; | |
| 3142 } | |
| 3143 | |
| 3144 # No neighbors to match... | |
| 3145 if (!$NumOfNbrAtomSpecs) { | |
| 3146 return 1; | |
| 3147 } | |
| 3148 | |
| 3149 # Match neighbors... | |
| 3150 my($NbrSpecsMatched, $NbrSpecCount, $NbrSpecMatchCount, %NbrSpecAlreadyMatchedMap); | |
| 3151 | |
| 3152 $NbrSpecCount = $NumOfNbrAtomSpecs; | |
| 3153 $NbrSpecMatchCount = 0; | |
| 3154 | |
| 3155 %NbrSpecAlreadyMatchedMap = (); | |
| 3156 ($NbrSpecsMatched, $NbrSpecMatchCount) = $CentralAtom->_MatchAtomNeighborhoodUsingAtomBondSpecs($NbrSpecCount, $NbrSpecMatchCount, \%NbrSpecAlreadyMatchedMap, $NbrAtomSpecsRef, $NbrBondSpecsRef, $NbrOfNbrAtomSpecsRef); | |
| 3157 | |
| 3158 if ($NbrSpecsMatched) { | |
| 3159 # It's match... | |
| 3160 return 1; | |
| 3161 } | |
| 3162 | |
| 3163 # Match central atom's missing hydrogens with any unmatched atom | |
| 3164 # and bond specifications... | |
| 3165 # | |
| 3166 ($NbrSpecsMatched, $NbrSpecMatchCount) = $CentralAtom->_MatchAtomNeighborhoodUsingMissingHydrogens($NbrSpecCount, $NbrSpecMatchCount, \%NbrSpecAlreadyMatchedMap, $NbrAtomSpecsRef, $NbrBondSpecsRef, $NbrOfNbrAtomSpecsRef); | |
| 3167 | |
| 3168 if ($NbrSpecsMatched) { | |
| 3169 # It's match... | |
| 3170 return 1; | |
| 3171 } | |
| 3172 | |
| 3173 # No match... | |
| 3174 return 0; | |
| 3175 } | |
| 3176 | |
| 3177 # Match central atom neighborhood atom and bond specifications... | |
| 3178 # | |
| 3179 sub _MatchAtomNeighborhoodUsingAtomBondSpecs { | |
| 3180 my($CentralAtom, $NbrSpecCount, $NbrSpecMatchCount, $NbrSpecAlreadyMatchedRef, $NbrAtomSpecsRef, $NbrBondSpecsRef, $NbrOfNbrAtomSpecsRef) = @_; | |
| 3181 my($Index, $NbrAtom, $NbrAtomSpec, $NbrBondSpec, $NbrOfNbrAtom, $NbrOfNbrAtomSpec, $MatchNbrOfNbrAtomSpecs, $NbrSpecsMatched); | |
| 3182 | |
| 3183 $MatchNbrOfNbrAtomSpecs = (defined $NbrOfNbrAtomSpecsRef && scalar @{$NbrOfNbrAtomSpecsRef}) ? 1 : 0; | |
| 3184 | |
| 3185 $NbrSpecsMatched = 0; | |
| 3186 | |
| 3187 # Match central atom's immediate neighbors atom and bond specifications... | |
| 3188 NBRATOM: for $NbrAtom ($CentralAtom->GetNeighbors()) { | |
| 3189 NBRATOMSPEC: for $Index (0 .. ($NbrSpecCount - 1)) { | |
| 3190 if (exists $NbrSpecAlreadyMatchedRef->{$Index}) { | |
| 3191 next NBRATOMSPEC; | |
| 3192 } | |
| 3193 $NbrAtomSpec = $NbrAtomSpecsRef->[$Index]; | |
| 3194 $NbrBondSpec = $NbrBondSpecsRef->[$Index]; | |
| 3195 | |
| 3196 $NbrOfNbrAtomSpec = $MatchNbrOfNbrAtomSpecs ? $NbrOfNbrAtomSpecsRef->[$Index] : undef; | |
| 3197 | |
| 3198 # Match neighbor atom specification... | |
| 3199 if (!$NbrAtom->_DoesAtomSpecificationMatch($NbrAtomSpec)) { | |
| 3200 next NBRATOMSPEC; | |
| 3201 } | |
| 3202 | |
| 3203 # Match central atom to neighbor atom bond specification... | |
| 3204 if (!$CentralAtom->_DoesBondSpecificationMatch($NbrAtom, $NbrBondSpec)) { | |
| 3205 next NBRATOMSPEC; | |
| 3206 } | |
| 3207 | |
| 3208 # Match any neighbor of neighbor atom specifications... | |
| 3209 if (defined $NbrOfNbrAtomSpec) { | |
| 3210 # Go over the neighbors of central atom skipping the central atom... | |
| 3211 for $NbrOfNbrAtom ($NbrAtom->GetNeighbors($CentralAtom)) { | |
| 3212 if (!$NbrOfNbrAtom->_DoesAtomSpecificationMatch($NbrOfNbrAtomSpec)) { | |
| 3213 next NBRATOMSPEC; | |
| 3214 } | |
| 3215 } | |
| 3216 } | |
| 3217 | |
| 3218 # It's a match for a neighbor atom specification... | |
| 3219 $NbrSpecAlreadyMatchedRef->{$Index} = $Index; | |
| 3220 $NbrSpecMatchCount++; | |
| 3221 | |
| 3222 if ($NbrSpecMatchCount == $NbrSpecCount) { | |
| 3223 # It's match... | |
| 3224 $NbrSpecsMatched = 1; | |
| 3225 last NBRATOM; | |
| 3226 } | |
| 3227 # Match next neighbor atom... | |
| 3228 next NBRATOM; | |
| 3229 } | |
| 3230 } | |
| 3231 return ($NbrSpecsMatched, $NbrSpecMatchCount); | |
| 3232 } | |
| 3233 | |
| 3234 # Match central atom's missing hydrogens with any unmatched atom and bond | |
| 3235 # specifications... | |
| 3236 # | |
| 3237 sub _MatchAtomNeighborhoodUsingMissingHydrogens { | |
| 3238 my($CentralAtom, $NbrSpecCount, $NbrSpecMatchCount, $NbrSpecAlreadyMatchedRef, $NbrAtomSpecsRef, $NbrBondSpecsRef, $NbrOfNbrAtomSpecsRef) = @_; | |
| 3239 my($Index, $NbrAtom, $NbrAtomSpec, $NbrBondSpec, $NumOfMissingHydrogens, $MissingHydrogensIndex, $NbrSpecsMatched, $AtomSpecMatched, $AtomSpec, $AtomSymbol); | |
| 3240 | |
| 3241 $NbrSpecsMatched = 0; | |
| 3242 | |
| 3243 $NumOfMissingHydrogens = $CentralAtom->GetNumOfMissingHydrogens(); | |
| 3244 if (($NbrSpecCount - $NbrSpecMatchCount) > $NumOfMissingHydrogens) { | |
| 3245 # It won't match... | |
| 3246 return ($NbrSpecsMatched, $NbrSpecMatchCount); | |
| 3247 } | |
| 3248 | |
| 3249 MISSINGHYDROGENNBR: for $MissingHydrogensIndex (0 .. ($NumOfMissingHydrogens - 1)) { | |
| 3250 NBRATOMSPEC: for $Index (0 .. ($NbrSpecCount - 1)) { | |
| 3251 if (exists $NbrSpecAlreadyMatchedRef->{$Index}) { | |
| 3252 next NBRATOMSPEC; | |
| 3253 } | |
| 3254 $NbrAtomSpec = $NbrAtomSpecsRef->[$Index]; | |
| 3255 $NbrBondSpec = $NbrBondSpecsRef->[$Index]; | |
| 3256 | |
| 3257 $NbrAtomSpec =~ s/ //g; | |
| 3258 | |
| 3259 # Match neighbor atom specification hydrogen atom symbol... | |
| 3260 $AtomSpecMatched = 0; | |
| 3261 ATOMSPEC: for $AtomSpec (split /\,/, $NbrAtomSpec) { | |
| 3262 ($AtomSymbol) = split /\./, $AtomSpec; | |
| 3263 if ($AtomSymbol =~ /^(H|A|\*)$/i) { | |
| 3264 $AtomSpecMatched = 1; | |
| 3265 last ATOMSPEC; | |
| 3266 } | |
| 3267 } | |
| 3268 if (!$AtomSpecMatched) { | |
| 3269 next NBRATOMSPEC; | |
| 3270 } | |
| 3271 | |
| 3272 # Match neighbor atom bond specification to singal bond... | |
| 3273 if (defined $NbrBondSpec) { | |
| 3274 $NbrBondSpec =~ s/ //g; | |
| 3275 if ($NbrBondSpec !~ /^(-|1|s|Single|\~|\*|Any)/i) { | |
| 3276 next NBRATOMSPEC; | |
| 3277 } | |
| 3278 } | |
| 3279 | |
| 3280 # It's a match for a neighbor atom specification... | |
| 3281 $NbrSpecAlreadyMatchedRef->{$Index} = $Index; | |
| 3282 $NbrSpecMatchCount++; | |
| 3283 | |
| 3284 if ($NbrSpecMatchCount == $NbrSpecCount) { | |
| 3285 # It's match... | |
| 3286 $NbrSpecsMatched = 1; | |
| 3287 last MISSINGHYDROGENNBR; | |
| 3288 } | |
| 3289 # Match next missing hydrogen neighbor... | |
| 3290 next MISSINGHYDROGENNBR; | |
| 3291 } | |
| 3292 } | |
| 3293 | |
| 3294 return ($NbrSpecsMatched, $NbrSpecMatchCount); | |
| 3295 } | |
| 3296 | |
| 3297 # Sort atom and bond specifications base on neighbor atom specifications going | |
| 3298 # from most to least specific atom specifications. | |
| 3299 # | |
| 3300 # Atom specifications are sorted at the following two levels: | |
| 3301 # | |
| 3302 # o By atom specification count with in each specification going from most specific | |
| 3303 # to least specific, where count is determined by the number of "," in each | |
| 3304 # specification. Wild card containing specifications are considered least specific | |
| 3305 # and end up at the end of the sorted list. | |
| 3306 # o By atomic invariant count with in each sorted list going from most specific to | |
| 3307 # least specific, where count is determined by the number of "." in each atom | |
| 3308 # specification. | |
| 3309 # | |
| 3310 #A single atom specification, | |
| 3311 # without any commas in atom specification, is is considered most specific... | |
| 3312 # | |
| 3313 sub _SortSpecificationsForAtomNeighborhoodMatch { | |
| 3314 my($This, $NbrAtomSpecsRef, $NbrBondSpecsRef, $NbrOfNbrAtomSpecsRef) = @_; | |
| 3315 my($Index, $NeedToSort, $NumOfNbrAtomSpecs, $NbrAtomSpecCount, $NbrAtomSpecAtomicInvarintCount, $NbrAtomSpecToMatch, $NbrAtomSpec, $FirstAtomicInvariant, $WildCardInNbrAtomSpec, @NbrAtomSpecs, @NbrAtomSpecAtomicInvariants, @SortedNbrAtomSpecs, @SortedNbrBondSpecs, @SortedNbrOfNbrAtomSpecs, %NbrAtomSpecDataMap); | |
| 3316 | |
| 3317 $NumOfNbrAtomSpecs = defined $NbrAtomSpecsRef ? scalar @{$NbrAtomSpecsRef} : 0; | |
| 3318 | |
| 3319 # Figure out whether sorting is necessary... | |
| 3320 $NeedToSort = 0; | |
| 3321 if ($NumOfNbrAtomSpecs > 1) { | |
| 3322 ATOMSPEC: for $NbrAtomSpecToMatch (@{$NbrAtomSpecsRef}) { | |
| 3323 if ($NbrAtomSpecToMatch =~ /(,|\.|A|\*)/i) { | |
| 3324 $NeedToSort = 1; | |
| 3325 last ATOMSPEC; | |
| 3326 } | |
| 3327 } | |
| 3328 } | |
| 3329 if (!$NeedToSort) { | |
| 3330 # Nothing to do... | |
| 3331 return ($NbrAtomSpecsRef, $NbrBondSpecsRef, $NbrOfNbrAtomSpecsRef); | |
| 3332 } | |
| 3333 | |
| 3334 %NbrAtomSpecDataMap = (); | |
| 3335 | |
| 3336 for $Index (0 .. ($NumOfNbrAtomSpecs - 1)) { | |
| 3337 $NbrAtomSpecToMatch = $NbrAtomSpecsRef->[$Index]; | |
| 3338 $NbrAtomSpecToMatch =~ s/ //g; | |
| 3339 | |
| 3340 @NbrAtomSpecs = split /\,/, $NbrAtomSpecToMatch; | |
| 3341 $NbrAtomSpecCount = scalar @NbrAtomSpecs; | |
| 3342 | |
| 3343 # Does neighbor specification contains a wild card in atom symbol specification? | |
| 3344 # | |
| 3345 if ($NbrAtomSpecToMatch =~ /(A|\*)/i) { | |
| 3346 $WildCardInNbrAtomSpec = 0; | |
| 3347 NBRATOMSPEC: for $NbrAtomSpec (@NbrAtomSpecs) { | |
| 3348 ($FirstAtomicInvariant) = split /\./, $NbrAtomSpec; | |
| 3349 if ($FirstAtomicInvariant =~ /^!/) { | |
| 3350 $FirstAtomicInvariant =~ s/^!//; | |
| 3351 } | |
| 3352 $WildCardInNbrAtomSpec = $This->_IsWildCardAtomSymbolAtomicInvariant($FirstAtomicInvariant); | |
| 3353 if ($WildCardInNbrAtomSpec) { | |
| 3354 last NBRATOMSPEC; | |
| 3355 } | |
| 3356 } | |
| 3357 if ($WildCardInNbrAtomSpec) { | |
| 3358 # Set NbrAtomSpecCount arbitrarily high to make the spec containing wild | |
| 3359 # card last on the sorted list while maintaining its original order in the list... | |
| 3360 $NbrAtomSpecCount = 999; | |
| 3361 } | |
| 3362 } | |
| 3363 | |
| 3364 if (!exists $NbrAtomSpecDataMap{$NbrAtomSpecCount}) { | |
| 3365 %{$NbrAtomSpecDataMap{$NbrAtomSpecCount}} = (); | |
| 3366 } | |
| 3367 | |
| 3368 # Use first NbrAtomSpec available in @NbrAtomSpecs to determine atomic invariant count | |
| 3369 # with in each NbrAtomSpecToMatch, as @NbrAtomSpecs derived from $NbrAtomSpecToMatch | |
| 3370 # simply corresponds to a list of possible matches... | |
| 3371 # | |
| 3372 ($NbrAtomSpec) = @NbrAtomSpecs; | |
| 3373 @NbrAtomSpecAtomicInvariants = split /\./, $NbrAtomSpec; | |
| 3374 $NbrAtomSpecAtomicInvarintCount = scalar @NbrAtomSpecAtomicInvariants; | |
| 3375 | |
| 3376 if (!exists $NbrAtomSpecDataMap{$NbrAtomSpecCount}{$NbrAtomSpecAtomicInvarintCount}) { | |
| 3377 @{$NbrAtomSpecDataMap{$NbrAtomSpecCount}{$NbrAtomSpecAtomicInvarintCount}} = (); | |
| 3378 } | |
| 3379 push @{$NbrAtomSpecDataMap{$NbrAtomSpecCount}{$NbrAtomSpecAtomicInvarintCount}}, $Index; | |
| 3380 | |
| 3381 } | |
| 3382 | |
| 3383 @SortedNbrAtomSpecs = (); @SortedNbrBondSpecs = (); | |
| 3384 @SortedNbrOfNbrAtomSpecs = (); | |
| 3385 | |
| 3386 for $NbrAtomSpecCount ( sort { $a <=> $b } keys %NbrAtomSpecDataMap) { | |
| 3387 for $NbrAtomSpecAtomicInvarintCount ( sort { $b <=> $a } keys %{$NbrAtomSpecDataMap{$NbrAtomSpecCount}}) { | |
| 3388 for $Index (@{$NbrAtomSpecDataMap{$NbrAtomSpecCount}{$NbrAtomSpecAtomicInvarintCount}}) { | |
| 3389 push @SortedNbrAtomSpecs, $NbrAtomSpecsRef->[$Index]; | |
| 3390 if (defined $NbrBondSpecsRef) { | |
| 3391 push @SortedNbrBondSpecs, $NbrBondSpecsRef->[$Index]; | |
| 3392 } | |
| 3393 if (defined $NbrOfNbrAtomSpecsRef) { | |
| 3394 push @SortedNbrOfNbrAtomSpecs, $NbrOfNbrAtomSpecsRef->[$Index]; | |
| 3395 } | |
| 3396 } | |
| 3397 } | |
| 3398 } | |
| 3399 | |
| 3400 return (\@SortedNbrAtomSpecs, defined $NbrBondSpecsRef ? \@SortedNbrBondSpecs : undef, defined $NbrOfNbrAtomSpecsRef ? \@SortedNbrOfNbrAtomSpecs : undef); | |
| 3401 } | |
| 3402 | |
| 3403 # Check whether atom matches supported atom specification... | |
| 3404 # | |
| 3405 sub _DoesAtomSpecificationMatch { | |
| 3406 my($This, $AtomSpecificationToMatch) = @_; | |
| 3407 my($AtomSpecification, $AtomicInvariant, $AtomSpecificationMatched, $AtomicInvariantMatched, $FirstMatch); | |
| 3408 | |
| 3409 # Anything to match... | |
| 3410 if (!(defined($AtomSpecificationToMatch) && $AtomSpecificationToMatch)) { | |
| 3411 return 1; | |
| 3412 } | |
| 3413 | |
| 3414 # Take out any spaces... | |
| 3415 $AtomSpecificationToMatch =~ s/ //g; | |
| 3416 | |
| 3417 # Match specified atom specifications. For multiple atom specifications in a comma delimited string, | |
| 3418 # only one atom specification needs to match for a successful match. It's up to the caller to make | |
| 3419 # sure that the specificaton list is ordered from least to most specific atom specification... | |
| 3420 # | |
| 3421 for $AtomSpecification (split /\,/, $AtomSpecificationToMatch) { | |
| 3422 $AtomSpecificationMatched = 1; | |
| 3423 $FirstMatch = 1; | |
| 3424 | |
| 3425 # Match all atom symbol atomic invariants... | |
| 3426 ATOMICINVARIANT: for $AtomicInvariant (split /\./, $AtomSpecification) { | |
| 3427 if ($FirstMatch) { | |
| 3428 # Match atom symbol atomic invariant... | |
| 3429 $FirstMatch = 0; | |
| 3430 $AtomicInvariantMatched = $This->_MatchAtomSymbolAtomicInvariant($AtomicInvariant); | |
| 3431 } | |
| 3432 else { | |
| 3433 # Match non atom symbol atomic invariant... | |
| 3434 $AtomicInvariantMatched = $This->_MatchNonAtomSymbolAtomicInvariant($AtomicInvariant); | |
| 3435 } | |
| 3436 | |
| 3437 if (!$AtomicInvariantMatched) { | |
| 3438 # No need to match other atomic invariants... | |
| 3439 $AtomSpecificationMatched = 0; | |
| 3440 last ATOMICINVARIANT; | |
| 3441 } | |
| 3442 } | |
| 3443 | |
| 3444 if ($AtomSpecificationMatched) { | |
| 3445 # No need to match other atom specifications... | |
| 3446 return 1; | |
| 3447 } | |
| 3448 } | |
| 3449 | |
| 3450 # Nothing matched... | |
| 3451 return 0; | |
| 3452 } | |
| 3453 | |
| 3454 # Check whether atom matches atom symbol atomic invariant... | |
| 3455 # | |
| 3456 sub _MatchAtomSymbolAtomicInvariant { | |
| 3457 my($This, $AtomicInvariant) = @_; | |
| 3458 my($NegateMatch, $Status, $AtomicNumber); | |
| 3459 | |
| 3460 $Status = 0; | |
| 3461 $NegateMatch = 0; | |
| 3462 | |
| 3463 # Does match needs to be negated? | |
| 3464 if ($AtomicInvariant =~ /^!/) { | |
| 3465 $NegateMatch = 1; | |
| 3466 $AtomicInvariant =~ s/^!//; | |
| 3467 } | |
| 3468 | |
| 3469 ATOMICINVARIANT: { | |
| 3470 # Any atom match... | |
| 3471 if ($This->_IsWildCardAtomSymbolAtomicInvariant($AtomicInvariant)) { | |
| 3472 $Status = 1; | |
| 3473 last ATOMICINVARIANT; | |
| 3474 } | |
| 3475 | |
| 3476 # Atomic number match... | |
| 3477 if ($AtomicInvariant =~ /^#/) { | |
| 3478 $AtomicNumber = $AtomicInvariant; $AtomicNumber =~ s/^#//; | |
| 3479 $Status = ($This->{AtomicNumber} == $AtomicNumber) ? 1 : 0; | |
| 3480 last ATOMICINVARIANT; | |
| 3481 } | |
| 3482 | |
| 3483 # Atom symbol match... | |
| 3484 $Status = ($This->{AtomSymbol} =~ /^$AtomicInvariant$/i) ? 1 : 0; | |
| 3485 } | |
| 3486 | |
| 3487 if ($NegateMatch) { | |
| 3488 $Status = $Status ? 0 : 1; | |
| 3489 } | |
| 3490 | |
| 3491 return $Status; | |
| 3492 } | |
| 3493 | |
| 3494 # Is it a wild card atom symbol atomic invariant? | |
| 3495 # | |
| 3496 sub _IsWildCardAtomSymbolAtomicInvariant { | |
| 3497 my($This, $AtomicInvariant) = @_; | |
| 3498 | |
| 3499 return ($AtomicInvariant =~ /^(A|\*)$/i) ? 1 : 0; | |
| 3500 } | |
| 3501 | |
| 3502 # Check whether atom matches non atom symbol atomic invariants... | |
| 3503 # | |
| 3504 sub _MatchNonAtomSymbolAtomicInvariant { | |
| 3505 my($This, $AtomicInvariant) = @_; | |
| 3506 my($NegateMatch, $Status, $Name, $Value, $UnknownName); | |
| 3507 | |
| 3508 ($Status, $NegateMatch, $UnknownName) = ('0') x 3; | |
| 3509 | |
| 3510 # Does match needs to be negated? | |
| 3511 if ($AtomicInvariant =~ /^!/) { | |
| 3512 $NegateMatch = 1; | |
| 3513 $AtomicInvariant =~ s/^!//; | |
| 3514 } | |
| 3515 | |
| 3516 # Extract atomic invariant name and any value... | |
| 3517 if ($AtomicInvariant =~ /[0-9\*]+/) { | |
| 3518 ($Name, $Value) = $AtomicInvariant =~ /^([a-zA-Z]+)([0-9\-\+\*\>\<\=]+)$/; | |
| 3519 } | |
| 3520 else { | |
| 3521 ($Name, $Value) = ($AtomicInvariant, undef); | |
| 3522 } | |
| 3523 | |
| 3524 NAME: { | |
| 3525 # Match number of non-hydrogen atom neighbors | |
| 3526 if ($Name =~ /^X$/i) { | |
| 3527 $Status = (defined($Value) && $This->GetNumOfNonHydrogenAtomNeighbors() == $Value) ? 1 : 0; | |
| 3528 last NAME; | |
| 3529 } | |
| 3530 | |
| 3531 # Match total number of atom neighbors including missing hydrogens... | |
| 3532 if ($Name =~ /^T$/i) { | |
| 3533 $Status = (defined($Value) && ($This->GetNumOfNonHydrogenAtomNeighbors() + $This->GetNumOfHydrogens()) == $Value) ? 1 : 0; | |
| 3534 last NAME; | |
| 3535 } | |
| 3536 | |
| 3537 # Match formal charge... | |
| 3538 if ($Name =~ /^FC$/i) { | |
| 3539 my $FormalCharge = $This->GetFormalCharge(); | |
| 3540 $Status = $This->_MatchNonAtomSymbolAtomicInvariantValue($FormalCharge, $Value); | |
| 3541 last NAME; | |
| 3542 } | |
| 3543 | |
| 3544 # Match aromatic annotation indicating whether atom is aromatic... | |
| 3545 if ($Name =~ /^Ar$/i) { | |
| 3546 $Status = $This->IsAromatic() ? 1 : 0; | |
| 3547 last NAME; | |
| 3548 } | |
| 3549 | |
| 3550 # Match number of implicit and explicit hydrogens... | |
| 3551 if ($Name =~ /^H$/i) { | |
| 3552 $Status = (defined($Value) && ($This->GetNumOfHydrogens() == $Value)) ? 1 : 0; | |
| 3553 last NAME; | |
| 3554 } | |
| 3555 | |
| 3556 # Match ring atom annotation indicating whether atom is in ring... | |
| 3557 if ($Name =~ /^RA$/i) { | |
| 3558 $Status = defined($Value) ? $This->IsInRingOfSize($Value) : ($This->IsInRing() ? 1 : 0); | |
| 3559 last NAME; | |
| 3560 } | |
| 3561 | |
| 3562 # Match number of rings for atom.. | |
| 3563 if ($Name =~ /^TR$/i) { | |
| 3564 $Status = (defined($Value) && ($Value == $This->GetNumOfRings())) ? 1 : 0; | |
| 3565 last NAME; | |
| 3566 } | |
| 3567 | |
| 3568 # Match sum of bond orders to non-hydrogen atom neighbors... | |
| 3569 if ($Name =~ /^BO$/i) { | |
| 3570 $Status = (defined($Value) && $This->GetSumOfBondOrdersToNonHydrogenAtoms() == $Value) ? 1 : 0; | |
| 3571 last NAME; | |
| 3572 } | |
| 3573 | |
| 3574 # Match largest bond order of non-hydrogen atom neighbors... | |
| 3575 if ($Name =~ /^LBO$/i) { | |
| 3576 $Status = (defined($Value) && $This->GetLargestBondOrderToNonHydrogenAtoms() == $Value) ? 1 : 0; | |
| 3577 last NAME; | |
| 3578 } | |
| 3579 | |
| 3580 # Match number of single bonds to non-hydrogen atom neighbors... | |
| 3581 if ($Name =~ /^SB$/i) { | |
| 3582 $Status = (defined($Value) && $This->GetNumOfSingleBondsToNonHydrogenAtoms() == $Value) ? 1 : 0; | |
| 3583 last NAME; | |
| 3584 } | |
| 3585 | |
| 3586 # Match total number of single bonds to atom neighbors including missing and explicit hydrogens... | |
| 3587 if ($Name =~ /^TSB$/i) { | |
| 3588 $Status = (defined($Value) && ($This->GetNumOfSingleBondsToNonHydrogenAtoms() + $This->GetNumOfHydrogens()) == $Value) ? 1 : 0; | |
| 3589 last NAME; | |
| 3590 } | |
| 3591 | |
| 3592 # Match number of double bonds to non-hydrogen atom neighbors... | |
| 3593 if ($Name =~ /^DB$/i) { | |
| 3594 $Status = (defined($Value) && $This->GetNumOfDoubleBondsToNonHydrogenAtoms() == $Value) ? 1 : 0; | |
| 3595 last NAME; | |
| 3596 } | |
| 3597 | |
| 3598 # Match number of triple bonds to non-hydrogen atom neighbors... | |
| 3599 if ($Name =~ /^TB$/i) { | |
| 3600 $Status = (defined($Value) && $This->GetNumOfTripleBondsToNonHydrogenAtoms() == $Value) ? 1 : 0; | |
| 3601 last NAME; | |
| 3602 } | |
| 3603 | |
| 3604 # Match number of aromatic bonds to non-hydrogen atom neighbors... | |
| 3605 if ($Name =~ /^AB$/i) { | |
| 3606 $Status = (defined($Value) && $This->GetNumOfAromaticBondsToNonHydrogenAtoms() == $Value) ? 1 : 0; | |
| 3607 last NAME; | |
| 3608 } | |
| 3609 | |
| 3610 | |
| 3611 # Match mass number indicating isotope other than most abundant isotope... | |
| 3612 if ($Name =~ /^MN$/i) { | |
| 3613 $Status = (defined($Value) && $This->GetMassNumber() == $Value) ? 1 : 0; | |
| 3614 last NAME; | |
| 3615 } | |
| 3616 | |
| 3617 # Match spin multiplicity... | |
| 3618 if ($Name =~ /^SM$/i) { | |
| 3619 my $SpinMultiplicity = $This->GetSpinMultiplicity(); | |
| 3620 if (!defined $SpinMultiplicity) { $SpinMultiplicity = 0; } | |
| 3621 $Status = (defined($Value) && defined($SpinMultiplicity) && $Value == $SpinMultiplicity) ? 1 : 0; | |
| 3622 last NAME; | |
| 3623 } | |
| 3624 | |
| 3625 $UnknownName = 1; | |
| 3626 carp "Warning: ${ClassName}->_MatchNonAtomSymbolAtomicInvariant: Unknown atomic invariant $AtomicInvariant..."; | |
| 3627 } | |
| 3628 | |
| 3629 if (!$UnknownName) { | |
| 3630 if ($NegateMatch) { | |
| 3631 $Status = $Status ? 0 : 1; | |
| 3632 } | |
| 3633 } | |
| 3634 | |
| 3635 return $Status; | |
| 3636 } | |
| 3637 | |
| 3638 # Match atomic invariant value... | |
| 3639 # | |
| 3640 # Specified value format: | |
| 3641 # . +* : Any positive value | |
| 3642 # . -* : Any negative value | |
| 3643 # . >ValidNumber or >=ValidNumber | |
| 3644 # . <ValidNumber or <=ValidNumber | |
| 3645 # . Any valid number | |
| 3646 # | |
| 3647 sub _MatchNonAtomSymbolAtomicInvariantValue { | |
| 3648 my($This, $TargetValue, $SpecifiedValue) = @_; | |
| 3649 my($Status); | |
| 3650 | |
| 3651 $Status = 0; | |
| 3652 | |
| 3653 if (!(defined($TargetValue) && defined($SpecifiedValue))) { | |
| 3654 return $Status; | |
| 3655 } | |
| 3656 | |
| 3657 VALUE: { | |
| 3658 if ($SpecifiedValue =~ /^\+\*/) { | |
| 3659 $Status = ($TargetValue > 0) ? 1 : 0; | |
| 3660 last VALUE; | |
| 3661 } | |
| 3662 if ($SpecifiedValue =~ /^\-\*/) { | |
| 3663 $Status = ($TargetValue < 0) ? 1 : 0; | |
| 3664 last VALUE; | |
| 3665 } | |
| 3666 if ($SpecifiedValue =~ /^>/) { | |
| 3667 if ($SpecifiedValue =~ /^>=/) { | |
| 3668 $SpecifiedValue =~ s/^>=//; | |
| 3669 $Status = ($SpecifiedValue >= $TargetValue) ? 1 : 0; | |
| 3670 } | |
| 3671 else { | |
| 3672 $SpecifiedValue =~ s/^>//; | |
| 3673 $Status = ($SpecifiedValue > $TargetValue) ? 1 : 0; | |
| 3674 } | |
| 3675 last VALUE; | |
| 3676 } | |
| 3677 if ($SpecifiedValue =~ /^</) { | |
| 3678 if ($SpecifiedValue =~ /^<=/) { | |
| 3679 $SpecifiedValue =~ s/^<=//; | |
| 3680 $Status = ($SpecifiedValue <= $TargetValue) ? 1 : 0; | |
| 3681 } | |
| 3682 else { | |
| 3683 $SpecifiedValue =~ s/^<//; | |
| 3684 $Status = ($SpecifiedValue < $TargetValue) ? 1 : 0; | |
| 3685 } | |
| 3686 last VALUE; | |
| 3687 } | |
| 3688 # Default is do perform an equality match... | |
| 3689 $Status = ($SpecifiedValue == $TargetValue) ? 1 : 0; | |
| 3690 } | |
| 3691 | |
| 3692 return $Status; | |
| 3693 } | |
| 3694 | |
| 3695 # Check whether atoms match bond specifications... | |
| 3696 # | |
| 3697 sub _DoesBondSpecificationMatch { | |
| 3698 my($This, $BondedAtom, $BondSpecificationToMatch) = @_; | |
| 3699 my($BondSpecification, $BondSymbolSpecification, $BondSpecificationMatched); | |
| 3700 | |
| 3701 # Anything to match... | |
| 3702 if (!(defined($BondSpecificationToMatch) && $BondSpecificationToMatch)) { | |
| 3703 return 1; | |
| 3704 } | |
| 3705 | |
| 3706 # Take out any spaces... | |
| 3707 $BondSpecificationToMatch =~ s/ //g; | |
| 3708 | |
| 3709 # Match specified bond specifications. For multiple bond specifications in a comma delimited string, | |
| 3710 # only one bond specification needs to match for a successful match... | |
| 3711 # | |
| 3712 for $BondSpecification (split /\,/, $BondSpecificationToMatch) { | |
| 3713 $BondSpecificationMatched = 1; | |
| 3714 | |
| 3715 # Match all specified bond symbol specifications... | |
| 3716 BONDSYMBOL: for $BondSymbolSpecification (split /\./, $BondSpecification) { | |
| 3717 if (!$This->_MatchBondSymbolSpecification($BondedAtom, $BondSymbolSpecification)) { | |
| 3718 # No need to match other bond symbol specifications... | |
| 3719 $BondSpecificationMatched = 0; | |
| 3720 last BONDSYMBOL; | |
| 3721 } | |
| 3722 } | |
| 3723 if ($BondSpecificationMatched) { | |
| 3724 # No need to try matching other bond specifications... | |
| 3725 return 1; | |
| 3726 } | |
| 3727 } | |
| 3728 | |
| 3729 # Nothing matched... | |
| 3730 return 0; | |
| 3731 } | |
| 3732 | |
| 3733 # Check whether atoms match bond symbol specification... | |
| 3734 # | |
| 3735 sub _MatchBondSymbolSpecification { | |
| 3736 my($This, $BondedAtom, $BondSymbolSpecification) = @_; | |
| 3737 my($NegateMatch, $Status, $Bond, $BondSymbol, $UnknownBondSymbol); | |
| 3738 | |
| 3739 ($Status, $NegateMatch, $UnknownBondSymbol) = ('0') x 3; | |
| 3740 | |
| 3741 # Does match needs to be negated? | |
| 3742 if ($BondSymbolSpecification =~ /^!/) { | |
| 3743 $NegateMatch = 1; | |
| 3744 $BondSymbolSpecification =~ s/^!//; | |
| 3745 } | |
| 3746 $BondSymbol = $BondSymbolSpecification; | |
| 3747 $Bond = $This->GetBondToAtom($BondedAtom); | |
| 3748 | |
| 3749 BONDSYMBOL: { | |
| 3750 if ($BondSymbol =~ /^(-|1|s|Single)$/i) { $Status = $Bond->IsSingle() ? 1 : 0; last BONDSYMBOL; } | |
| 3751 if ($BondSymbol =~ /^(=|2|d|Double)$/i) { $Status = $Bond->IsDouble() ? 1 : 0; last BONDSYMBOL; } | |
| 3752 if ($BondSymbol =~ /^(#|3|t|Triple)$/i) { $Status = $Bond->IsTriple() ? 1 : 0; last BONDSYMBOL; } | |
| 3753 if ($BondSymbol =~ /^(:|a|Ar|Aromatic)$/i) { $Status = $Bond->IsAromatic() ? 1 : 0; last BONDSYMBOL; } | |
| 3754 | |
| 3755 if ($BondSymbol =~ /^(\@|RB|Ring)$/i) { $Status = $Bond->IsInRing() ? 1 : 0; last BONDSYMBOL; } | |
| 3756 | |
| 3757 if ($BondSymbol =~ /^(\~|\*|Any)$/i) { $Status = 1; last BONDSYMBOL; } | |
| 3758 | |
| 3759 $UnknownBondSymbol = 1; | |
| 3760 carp "Warning: ${ClassName}->_MatchBondSpecification: Unknown bond specification $BondSymbolSpecification..."; | |
| 3761 } | |
| 3762 | |
| 3763 if (!$UnknownBondSymbol) { | |
| 3764 if ($NegateMatch) { | |
| 3765 $Status = $Status ? 0 : 1; | |
| 3766 } | |
| 3767 } | |
| 3768 | |
| 3769 return $Status; | |
| 3770 } | |
| 3771 | |
| 3772 # Is it a saturated atom? | |
| 3773 # | |
| 3774 sub IsSaturated { | |
| 3775 my($This) = @_; | |
| 3776 | |
| 3777 return !$This->IsUnsaturated(); | |
| 3778 } | |
| 3779 | |
| 3780 # Is it an unsaturated atom containing at least one non-single bond? | |
| 3781 # | |
| 3782 sub IsUnsaturated { | |
| 3783 my($This) = @_; | |
| 3784 my($NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds, $NumOfAromaticBonds); | |
| 3785 | |
| 3786 ($NumOfSingleBonds, $NumOfDoubleBonds, $NumOfTripleBonds, $NumOfAromaticBonds) = $This->GetNumOfBondTypesToNonHydrogenAtoms(); | |
| 3787 | |
| 3788 return ($NumOfDoubleBonds || $NumOfTripleBonds || $NumOfAromaticBonds) ? 1 : 0; | |
| 3789 } | |
| 3790 | |
| 3791 # Is atom in a ring? | |
| 3792 # | |
| 3793 sub IsInRing { | |
| 3794 my($This) = @_; | |
| 3795 | |
| 3796 # Is this atom in a molecule? | |
| 3797 if (!$This->HasProperty('Molecule')) { | |
| 3798 return undef; | |
| 3799 } | |
| 3800 my($Molecule); | |
| 3801 $Molecule = $This->GetProperty('Molecule'); | |
| 3802 | |
| 3803 return $Molecule->_IsAtomInRing($This); | |
| 3804 } | |
| 3805 | |
| 3806 # Is atom not in a ring? | |
| 3807 # | |
| 3808 sub IsNotInRing { | |
| 3809 my($This) = @_; | |
| 3810 | |
| 3811 # Is this atom in a molecule? | |
| 3812 if (!$This->HasProperty('Molecule')) { | |
| 3813 return undef; | |
| 3814 } | |
| 3815 my($Molecule); | |
| 3816 $Molecule = $This->GetProperty('Molecule'); | |
| 3817 | |
| 3818 return $Molecule->_IsAtomNotInRing($This); | |
| 3819 } | |
| 3820 | |
| 3821 # Is atom only in one ring? | |
| 3822 # | |
| 3823 sub IsOnlyInOneRing { | |
| 3824 my($This) = @_; | |
| 3825 | |
| 3826 # Is this atom in a molecule? | |
| 3827 if (!$This->HasProperty('Molecule')) { | |
| 3828 return undef; | |
| 3829 } | |
| 3830 my($Molecule); | |
| 3831 $Molecule = $This->GetProperty('Molecule'); | |
| 3832 | |
| 3833 return $Molecule->_IsAtomInOnlyOneRing($This); | |
| 3834 } | |
| 3835 | |
| 3836 # Is atom in a ring of specific size? | |
| 3837 # | |
| 3838 sub IsInRingOfSize { | |
| 3839 my($This, $RingSize) = @_; | |
| 3840 | |
| 3841 # Is this atom in a molecule? | |
| 3842 if (!$This->HasProperty('Molecule')) { | |
| 3843 return undef; | |
| 3844 } | |
| 3845 my($Molecule); | |
| 3846 $Molecule = $This->GetProperty('Molecule'); | |
| 3847 | |
| 3848 return $Molecule->_IsAtomInRingOfSize($This, $RingSize); | |
| 3849 } | |
| 3850 | |
| 3851 # Get size of smallest ring containing the atom... | |
| 3852 # | |
| 3853 sub GetSizeOfSmallestRing { | |
| 3854 my($This) = @_; | |
| 3855 | |
| 3856 # Is this atom in a molecule? | |
| 3857 if (!$This->HasProperty('Molecule')) { | |
| 3858 return undef; | |
| 3859 } | |
| 3860 my($Molecule); | |
| 3861 $Molecule = $This->GetProperty('Molecule'); | |
| 3862 | |
| 3863 return $Molecule->_GetSizeOfSmallestAtomRing($This); | |
| 3864 } | |
| 3865 | |
| 3866 # Get size of largest ring containing the atom... | |
| 3867 # | |
| 3868 sub GetSizeOfLargestRing { | |
| 3869 my($This) = @_; | |
| 3870 | |
| 3871 # Is this atom in a molecule? | |
| 3872 if (!$This->HasProperty('Molecule')) { | |
| 3873 return undef; | |
| 3874 } | |
| 3875 my($Molecule); | |
| 3876 $Molecule = $This->GetProperty('Molecule'); | |
| 3877 | |
| 3878 return $Molecule->_GetSizeOfLargestAtomRing($This); | |
| 3879 } | |
| 3880 | |
| 3881 # Get number of rings containing the atom... | |
| 3882 # | |
| 3883 sub GetNumOfRings { | |
| 3884 my($This) = @_; | |
| 3885 | |
| 3886 # Is this atom in a molecule? | |
| 3887 if (!$This->HasProperty('Molecule')) { | |
| 3888 return undef; | |
| 3889 } | |
| 3890 my($Molecule); | |
| 3891 $Molecule = $This->GetProperty('Molecule'); | |
| 3892 | |
| 3893 return $Molecule->_GetNumOfAtomRings($This); | |
| 3894 } | |
| 3895 | |
| 3896 # Get number of rings with odd size containing the atom... | |
| 3897 # | |
| 3898 sub GetNumOfRingsWithOddSize { | |
| 3899 my($This) = @_; | |
| 3900 | |
| 3901 # Is this atom in a molecule? | |
| 3902 if (!$This->HasProperty('Molecule')) { | |
| 3903 return undef; | |
| 3904 } | |
| 3905 my($Molecule); | |
| 3906 $Molecule = $This->GetProperty('Molecule'); | |
| 3907 | |
| 3908 return $Molecule->_GetNumOfAtomRingsWithOddSize($This); | |
| 3909 } | |
| 3910 | |
| 3911 # Get number of rings with even size containing the atom... | |
| 3912 # | |
| 3913 sub GetNumOfRingsWithEvenSize { | |
| 3914 my($This) = @_; | |
| 3915 | |
| 3916 # Is this atom in a molecule? | |
| 3917 if (!$This->HasProperty('Molecule')) { | |
| 3918 return undef; | |
| 3919 } | |
| 3920 my($Molecule); | |
| 3921 $Molecule = $This->GetProperty('Molecule'); | |
| 3922 | |
| 3923 return $Molecule->_GetNumOfAtomRingsWithEvenSize($This); | |
| 3924 } | |
| 3925 | |
| 3926 # Get number of rings with specified size containing the atom... | |
| 3927 # | |
| 3928 sub GetNumOfRingsWithSize { | |
| 3929 my($This, $RingSize) = @_; | |
| 3930 | |
| 3931 # Is this atom in a molecule? | |
| 3932 if (!$This->HasProperty('Molecule')) { | |
| 3933 return undef; | |
| 3934 } | |
| 3935 my($Molecule); | |
| 3936 $Molecule = $This->GetProperty('Molecule'); | |
| 3937 | |
| 3938 return $Molecule->_GetNumOfAtomRingsWithSize($This, $RingSize); | |
| 3939 | |
| 3940 } | |
| 3941 | |
| 3942 # Get number of rings with size less than specified containing the atom... | |
| 3943 # | |
| 3944 sub GetNumOfRingsWithSizeLessThan { | |
| 3945 my($This, $RingSize) = @_; | |
| 3946 | |
| 3947 # Is this atom in a molecule? | |
| 3948 if (!$This->HasProperty('Molecule')) { | |
| 3949 return undef; | |
| 3950 } | |
| 3951 my($Molecule); | |
| 3952 $Molecule = $This->GetProperty('Molecule'); | |
| 3953 | |
| 3954 return $Molecule->_GetNumOfAtomRingsWithSizeLessThan($This, $RingSize); | |
| 3955 } | |
| 3956 | |
| 3957 # Get number of rings with size greater than specified size containing the atom... | |
| 3958 # | |
| 3959 sub GetNumOfRingsWithSizeGreaterThan { | |
| 3960 my($This, $RingSize) = @_; | |
| 3961 | |
| 3962 # Is this atom in a molecule? | |
| 3963 if (!$This->HasProperty('Molecule')) { | |
| 3964 return undef; | |
| 3965 } | |
| 3966 my($Molecule); | |
| 3967 $Molecule = $This->GetProperty('Molecule'); | |
| 3968 | |
| 3969 return $Molecule->_GetNumOfAtomRingsWithSizeGreaterThan($This, $RingSize); | |
| 3970 } | |
| 3971 | |
| 3972 # Get all rings an array of references to arrays containing ring atoms... | |
| 3973 # | |
| 3974 sub GetRings { | |
| 3975 my($This) = @_; | |
| 3976 | |
| 3977 # Is this atom in a molecule? | |
| 3978 if (!$This->HasProperty('Molecule')) { | |
| 3979 return undef; | |
| 3980 } | |
| 3981 my($Molecule); | |
| 3982 $Molecule = $This->GetProperty('Molecule'); | |
| 3983 | |
| 3984 return $Molecule->_GetAtomRings($This); | |
| 3985 } | |
| 3986 | |
| 3987 # Get smallest ring as an array containing ring atoms... | |
| 3988 # | |
| 3989 sub GetSmallestRing { | |
| 3990 my($This) = @_; | |
| 3991 | |
| 3992 # Is this atom in a molecule? | |
| 3993 if (!$This->HasProperty('Molecule')) { | |
| 3994 return undef; | |
| 3995 } | |
| 3996 my($Molecule); | |
| 3997 $Molecule = $This->GetProperty('Molecule'); | |
| 3998 | |
| 3999 return $Molecule->_GetSmallestAtomRing($This); | |
| 4000 } | |
| 4001 | |
| 4002 # Get largest ring as an array containing ring atoms... | |
| 4003 # | |
| 4004 sub GetLargestRing { | |
| 4005 my($This) = @_; | |
| 4006 | |
| 4007 # Is this atom in a molecule? | |
| 4008 if (!$This->HasProperty('Molecule')) { | |
| 4009 return undef; | |
| 4010 } | |
| 4011 my($Molecule); | |
| 4012 $Molecule = $This->GetProperty('Molecule'); | |
| 4013 | |
| 4014 return $Molecule->_GetLargestAtomRing($This); | |
| 4015 } | |
| 4016 | |
| 4017 # Get odd size rings an array of references to arrays containing ring atoms... | |
| 4018 # | |
| 4019 sub GetRingsWithOddSize { | |
| 4020 my($This) = @_; | |
| 4021 | |
| 4022 # Is this atom in a molecule? | |
| 4023 if (!$This->HasProperty('Molecule')) { | |
| 4024 return undef; | |
| 4025 } | |
| 4026 my($Molecule); | |
| 4027 $Molecule = $This->GetProperty('Molecule'); | |
| 4028 | |
| 4029 return $Molecule->_GetAtomRingsWithOddSize($This); | |
| 4030 } | |
| 4031 | |
| 4032 # Get even size rings an array of references to arrays containing ring atoms... | |
| 4033 # | |
| 4034 sub GetRingsWithEvenSize { | |
| 4035 my($This) = @_; | |
| 4036 | |
| 4037 # Is this atom in a molecule? | |
| 4038 if (!$This->HasProperty('Molecule')) { | |
| 4039 return undef; | |
| 4040 } | |
| 4041 my($Molecule); | |
| 4042 $Molecule = $This->GetProperty('Molecule'); | |
| 4043 | |
| 4044 return $Molecule->_GetAtomRingsWithEvenSize($This); | |
| 4045 } | |
| 4046 | |
| 4047 # Get rings with specified size as an array of references to arrays containing ring atoms... | |
| 4048 # | |
| 4049 sub GetRingsWithSize { | |
| 4050 my($This, $RingSize) = @_; | |
| 4051 | |
| 4052 # Is this atom in a molecule? | |
| 4053 if (!$This->HasProperty('Molecule')) { | |
| 4054 return undef; | |
| 4055 } | |
| 4056 my($Molecule); | |
| 4057 $Molecule = $This->GetProperty('Molecule'); | |
| 4058 | |
| 4059 return $Molecule->_GetAtomRingsWithSize($This, $RingSize); | |
| 4060 } | |
| 4061 | |
| 4062 # Get rings with size less than specfied size as an array of references to arrays containing ring atoms... | |
| 4063 # | |
| 4064 sub GetRingsWithSizeLessThan { | |
| 4065 my($This, $RingSize) = @_; | |
| 4066 | |
| 4067 # Is this atom in a molecule? | |
| 4068 if (!$This->HasProperty('Molecule')) { | |
| 4069 return undef; | |
| 4070 } | |
| 4071 my($Molecule); | |
| 4072 $Molecule = $This->GetProperty('Molecule'); | |
| 4073 | |
| 4074 return $Molecule->_GetAtomRingsWithSizeLessThan($This, $RingSize); | |
| 4075 } | |
| 4076 | |
| 4077 # Get rings with size greater than specfied size as an array of references to arrays containing ring atoms... | |
| 4078 # | |
| 4079 sub GetRingsWithSizeGreaterThan { | |
| 4080 my($This, $RingSize) = @_; | |
| 4081 | |
| 4082 # Is this atom in a molecule? | |
| 4083 if (!$This->HasProperty('Molecule')) { | |
| 4084 return undef; | |
| 4085 } | |
| 4086 my($Molecule); | |
| 4087 $Molecule = $This->GetProperty('Molecule'); | |
| 4088 | |
| 4089 return $Molecule->_GetAtomRingsWithSizeGreaterThan($This, $RingSize); | |
| 4090 } | |
| 4091 | |
| 4092 # Get next object ID... | |
| 4093 sub _GetNewObjectID { | |
| 4094 $ObjectID++; | |
| 4095 return $ObjectID; | |
| 4096 } | |
| 4097 | |
| 4098 # Return a string containing vertices, edges and other properties... | |
| 4099 sub StringifyAtom { | |
| 4100 my($This) = @_; | |
| 4101 my($AtomString, $ID, $Name, $AtomSymbol, $AtomicNumber, $XYZVector, $AtomicWeight, $ExactMass, $NumOfNeighbors, $NumOfBonds, $Valence, $MissingHydrogens, $TotalHydrogens, $ImplicitHydrogens, $ExplicitHydrogens, $FormalCharge, $Charge, $SpinMultiplicity, $FreeRadicalElectrons, $StereoCenter, $StereoCenterStatus, $StereoChemistry, $StereochemistryString, $RingAtom, $NumOfRings, $AromaticAtom); | |
| 4102 | |
| 4103 $ID = $This->GetID(); | |
| 4104 $Name = $This->GetName(); | |
| 4105 $AtomSymbol = $This->GetAtomSymbol(); | |
| 4106 $AtomicNumber = $This->GetAtomicNumber(); | |
| 4107 $XYZVector = $This->GetXYZVector(); | |
| 4108 | |
| 4109 $AtomicWeight = $This->GetAtomicWeight(); | |
| 4110 if (!defined $AtomicWeight) { | |
| 4111 $AtomicWeight = 'undefined'; | |
| 4112 } | |
| 4113 $ExactMass = $This->GetExactMass(); | |
| 4114 if (!defined $ExactMass) { | |
| 4115 $ExactMass = 'undefined'; | |
| 4116 } | |
| 4117 $NumOfNeighbors = $This->GetNumOfNeighbors(); | |
| 4118 if (!defined $NumOfNeighbors) { | |
| 4119 $NumOfNeighbors = 'undefined'; | |
| 4120 } | |
| 4121 $NumOfBonds = $This->GetNumOfBonds(); | |
| 4122 if (!defined $NumOfBonds) { | |
| 4123 $NumOfBonds = 'undefined'; | |
| 4124 } | |
| 4125 $Valence = $This->GetValence(); | |
| 4126 if (!defined $Valence) { | |
| 4127 $Valence = 'undefined'; | |
| 4128 } | |
| 4129 | |
| 4130 $MissingHydrogens = $This->GetNumOfMissingHydrogens(); | |
| 4131 if (!defined $MissingHydrogens) { | |
| 4132 $MissingHydrogens = 'undefined'; | |
| 4133 } | |
| 4134 $TotalHydrogens = $This->GetNumOfHydrogens(); | |
| 4135 if (!defined $TotalHydrogens) { | |
| 4136 $TotalHydrogens = 'undefined'; | |
| 4137 } | |
| 4138 $ImplicitHydrogens = $This->GetNumOfImplicitHydrogens(); | |
| 4139 if (!defined $ImplicitHydrogens) { | |
| 4140 $ImplicitHydrogens = 'undefined'; | |
| 4141 } | |
| 4142 $ExplicitHydrogens = $This->GetNumOfExplicitHydrogens(); | |
| 4143 if (!defined $ExplicitHydrogens) { | |
| 4144 $ExplicitHydrogens = 'undefined'; | |
| 4145 } | |
| 4146 | |
| 4147 $FormalCharge = $This->GetFormalCharge(); | |
| 4148 if (!defined $FormalCharge) { | |
| 4149 $FormalCharge = 'undefined'; | |
| 4150 } | |
| 4151 $Charge = $This->GetCharge(); | |
| 4152 if (!defined $Charge) { | |
| 4153 $Charge = 'undefined'; | |
| 4154 } | |
| 4155 | |
| 4156 $SpinMultiplicity = $This->GetSpinMultiplicity(); | |
| 4157 if (!defined $SpinMultiplicity) { | |
| 4158 $SpinMultiplicity = 'undefined'; | |
| 4159 } | |
| 4160 $FreeRadicalElectrons = $This->GetFreeRadicalElectrons(); | |
| 4161 if (!defined $FreeRadicalElectrons) { | |
| 4162 $FreeRadicalElectrons = 'undefined'; | |
| 4163 } | |
| 4164 | |
| 4165 $RingAtom = $This->IsInRing(); | |
| 4166 if (defined $RingAtom) { | |
| 4167 $RingAtom = $RingAtom ? 'Yes' : 'No'; | |
| 4168 $NumOfRings = $This->GetNumOfRings(); | |
| 4169 } | |
| 4170 else { | |
| 4171 $RingAtom = 'undefined'; | |
| 4172 $NumOfRings = 'undefined'; | |
| 4173 } | |
| 4174 | |
| 4175 $AromaticAtom = $This->GetAromatic(); | |
| 4176 if (defined $AromaticAtom) { | |
| 4177 $AromaticAtom = $AromaticAtom ? 'Yes' : 'No'; | |
| 4178 } | |
| 4179 else { | |
| 4180 $AromaticAtom = 'undefined'; | |
| 4181 } | |
| 4182 | |
| 4183 $StereochemistryString = ''; | |
| 4184 $StereoCenter = $This->GetStereoCenter(); | |
| 4185 if (defined $StereoCenter) { | |
| 4186 $StereoCenterStatus = $This->IsStereoCenter() ? 'Yes' : 'No'; | |
| 4187 $StereoChemistry = $This->GetStereochemistry(); | |
| 4188 if (!defined $StereoChemistry) { | |
| 4189 $StereoChemistry = 'undefined'; | |
| 4190 } | |
| 4191 $StereochemistryString = "StereoCenter: $StereoCenterStatus; Stereochemistry: $StereoChemistry"; | |
| 4192 } | |
| 4193 | |
| 4194 $AtomString = "Atom: ID: $ID; Name: \"$Name\"; AtomSymbol: \"$AtomSymbol\"; AtomicNumber: $AtomicNumber; XYZ: $XYZVector; AtomicWeight: $AtomicWeight; ExactMass: $ExactMass; NumOfNeighbors: $NumOfNeighbors; NumOfBonds: $NumOfBonds; Valence: $Valence; MissingHydrogens: $MissingHydrogens; TotalHydrogens: $TotalHydrogens; ImplicitHydrogens: $ImplicitHydrogens; ExplicitHydrogens: $ExplicitHydrogens; FormalCharge: $FormalCharge; Charge: $Charge; SpinMultiplicity: $SpinMultiplicity; FreeRadicalElectrons: $FreeRadicalElectrons; RingAtom: $RingAtom; NumOfAtomRings: $NumOfRings; AromaticAtom: $AromaticAtom"; | |
| 4195 | |
| 4196 if ($StereochemistryString) { | |
| 4197 $AtomString .= "; $StereochemistryString"; | |
| 4198 } | |
| 4199 | |
| 4200 return $AtomString; | |
| 4201 } | |
| 4202 | |
| 4203 # Load appropriate atom data files from <MayaChemTools>/lib directory used by various | |
| 4204 # object methods in the current class... | |
| 4205 # | |
| 4206 sub _LoadAtomClassData { | |
| 4207 my($MayaChemToolsLibDir); | |
| 4208 | |
| 4209 $MayaChemToolsLibDir = GetMayaChemToolsLibDirName(); | |
| 4210 | |
| 4211 _LoadAtomValenceModelData($MayaChemToolsLibDir); | |
| 4212 | |
| 4213 } | |
| 4214 | |
| 4215 # | |
| 4216 # Load data for supported valence models... | |
| 4217 # | |
| 4218 sub _LoadAtomValenceModelData { | |
| 4219 my($MayaChemToolsLibDir) = @_; | |
| 4220 my($MDLValenceModelDataFile, $DaylightValenceModelDataFile); | |
| 4221 | |
| 4222 %MDLValenceModelDataMap = (); | |
| 4223 %DaylightValenceModelDataMap = (); | |
| 4224 | |
| 4225 $MDLValenceModelDataFile = $MayaChemToolsLibDir . "/data/MDLValenceModelData.csv"; | |
| 4226 $DaylightValenceModelDataFile = $MayaChemToolsLibDir . "/data/DaylightValenceModelData.csv"; | |
| 4227 | |
| 4228 if (! -e "$MDLValenceModelDataFile") { | |
| 4229 croak "Error: ${ClassName}::_LoadAtomValenceModelData: MayaChemTools package file, $MDLValenceModelDataFile, is missing: Possible installation problems..."; | |
| 4230 } | |
| 4231 | |
| 4232 if (! -e "$DaylightValenceModelDataFile") { | |
| 4233 croak "Error: ${ClassName}::_LoadAtomValenceModelData: MayaChemTools package file, $DaylightValenceModelDataFile, is missing: Possible installation problems..."; | |
| 4234 } | |
| 4235 | |
| 4236 _LoadValenceModelDataFile($MDLValenceModelDataFile, \%MDLValenceModelDataMap); | |
| 4237 _LoadValenceModelDataFile($DaylightValenceModelDataFile, \%DaylightValenceModelDataMap); | |
| 4238 | |
| 4239 } | |
| 4240 | |
| 4241 # | |
| 4242 # Load valence model data file... | |
| 4243 # | |
| 4244 sub _LoadValenceModelDataFile { | |
| 4245 my($DataFile, $DataMapRef) = @_; | |
| 4246 | |
| 4247 # File format: | |
| 4248 # | |
| 4249 # "AtomicNumber","ElementSymbol","FormalCharge","CommomValences" | |
| 4250 # | |
| 4251 my($InDelim, $Line, $NumOfCols, @ColLabels, @LineWords); | |
| 4252 | |
| 4253 $InDelim = "\,"; | |
| 4254 open DATAFILE, "$DataFile" or croak "Couldn't open $DataFile: $! ..."; | |
| 4255 | |
| 4256 # Skip lines up to column labels... | |
| 4257 LINE: while ($Line = GetTextLine(\*DATAFILE)) { | |
| 4258 if ($Line !~ /^#/) { | |
| 4259 last LINE; | |
| 4260 } | |
| 4261 } | |
| 4262 @ColLabels= quotewords($InDelim, 0, $Line); | |
| 4263 $NumOfCols = @ColLabels; | |
| 4264 | |
| 4265 my($AtomicNumber, $ElementSymbol, $FormalCharge, $CommonValences); | |
| 4266 | |
| 4267 # Process element data... | |
| 4268 LINE: while ($Line = GetTextLine(\*DATAFILE)) { | |
| 4269 if ($Line =~ /^#/) { | |
| 4270 next LINE; | |
| 4271 } | |
| 4272 @LineWords = (); | |
| 4273 @LineWords = quotewords($InDelim, 0, $Line); | |
| 4274 if (@LineWords != $NumOfCols) { | |
| 4275 croak "Error: ${ClassName}::_LoadValenceModelDataFile: The number of data fields, @LineWords, in $DataFile must be $NumOfCols.\nLine: $Line..."; | |
| 4276 } | |
| 4277 | |
| 4278 ($AtomicNumber, $ElementSymbol, $FormalCharge, $CommonValences) = @LineWords; | |
| 4279 | |
| 4280 if (exists $DataMapRef->{$AtomicNumber}) { | |
| 4281 # Additional data for an element... | |
| 4282 if (exists $DataMapRef->{$AtomicNumber}{$FormalCharge}) { | |
| 4283 # Duplicate data entries for an element... | |
| 4284 carp "Warning: ${ClassName}::_LoadValenceModelDataFile: Ignoring valence data for element with atomic number $AtomicNumber and formal charge $FormalCharge in data file $DataFile: It has already been loaded.\nLine: $Line..."; | |
| 4285 next LINE; | |
| 4286 } | |
| 4287 } | |
| 4288 else { | |
| 4289 # Data for a new element... | |
| 4290 %{$DataMapRef->{$AtomicNumber}} = (); | |
| 4291 } | |
| 4292 | |
| 4293 %{$DataMapRef->{$AtomicNumber}{$FormalCharge}} = (); | |
| 4294 $DataMapRef->{$AtomicNumber}{$FormalCharge}{ElementSymbol} = $ElementSymbol; | |
| 4295 | |
| 4296 @{$DataMapRef->{$AtomicNumber}{$FormalCharge}{CommonValences}} = (); | |
| 4297 @{$DataMapRef->{$AtomicNumber}{$FormalCharge}{CommonValences}} = sort { $a <=> $b } split /\,/, $CommonValences; | |
| 4298 } | |
| 4299 close DATAFILE; | |
| 4300 } | |
| 4301 | |
| 4302 1; | |
| 4303 | |
| 4304 __END__ | |
| 4305 | |
| 4306 =head1 NAME | |
| 4307 | |
| 4308 Atom | |
| 4309 | |
| 4310 =head1 SYNOPSIS | |
| 4311 | |
| 4312 use Atom; | |
| 4313 | |
| 4314 =head1 DESCRIPTION | |
| 4315 | |
| 4316 B<Atom> class provides the following methods: | |
| 4317 | |
| 4318 new, AddHydrogens, Copy, DeleteAtom, DeleteHydrogens, DoesAtomNeighborhoodMatch, | |
| 4319 GetAtomicInvariantValue, GetAtomicWeight, GetBondToAtom, GetBonds, | |
| 4320 GetBondsToHeavyAtoms, GetBondsToHydrogenAtoms, GetBondsToNonHydrogenAtoms, | |
| 4321 GetExactMass, GetExplicitHydrogens, GetFormalCharge, GetFreeRadicalElectrons, | |
| 4322 GetGroupNumber, GetHeavyAtomNeighbors, GetHeavyAtomNeighborsAtomInformation, | |
| 4323 GetHeavyAtomNeighborsBondformation, GetHighestCommonValence, | |
| 4324 GetHydrogenAtomNeighbors, GetHydrogens, GetImplicitHydrogens, GetLargestBondOrder, | |
| 4325 GetLargestBondOrderToHeavyAtoms, GetLargestBondOrderToNonHydrogenAtoms, | |
| 4326 GetLargestRing, GetLowestCommonValence, GetMassNumber, GetMissingHydrogens, | |
| 4327 GetNeighbors, GetNeighborsUsingAtomSpecification, GetNonHydrogenAtomNeighbors, | |
| 4328 GetNonHydrogenAtomNeighborsAtomInformation, | |
| 4329 GetNonHydrogenAtomNeighborsBondInformation, GetNonHydrogenNeighborOfHydrogenAtom, | |
| 4330 GetNumOfAromaticBondsToHeavyAtoms, GetNumOfAromaticBondsToNonHydrogenAtoms, | |
| 4331 GetNumOfBondTypesToHeavyAtoms, GetNumOfBondTypesToNonHydrogenAtoms, GetNumOfBonds, | |
| 4332 GetNumOfBondsToHeavyAtoms, GetNumOfBondsToHydrogenAtoms, | |
| 4333 GetNumOfBondsToNonHydrogenAtoms, GetNumOfDoubleBondsToHeavyAtoms, | |
| 4334 GetNumOfBondsAvailableForHeavyAtoms, GetNumOfBondsAvailableForNonHydrogenAtoms, | |
| 4335 GetNumOfDoubleBondsToNonHydrogenAtoms, GetNumOfExplicitHydrogens, | |
| 4336 GetNumOfHeavyAtomNeighbors, GetNumOfHydrogenAtomNeighbors, GetNumOfHydrogens, | |
| 4337 GetNumOfImplicitHydrogens, GetNumOfMissingHydrogens, GetNumOfNeighbors, | |
| 4338 GetNumOfNonHydrogenAtomNeighbors, GetNumOfRings, GetNumOfRingsWithEvenSize, | |
| 4339 GetNumOfRingsWithOddSize, GetNumOfRingsWithSize, GetNumOfRingsWithSizeGreaterThan, | |
| 4340 GetNumOfRingsWithSizeLessThan, GetNumOfSigmaAndPiBondsToHeavyAtoms, | |
| 4341 GetNumOfSigmaAndPiBondsToNonHydrogenAtoms, GetNumOfSingleBondsToHeavyAtoms, | |
| 4342 GetNumOfSingleBondsToNonHydrogenAtoms, GetNumOfTripleBondsToHeavyAtoms, | |
| 4343 GetNumOfTripleBondsToNonHydrogenAtoms, GetPeriodNumber, | |
| 4344 GetPotentialTotalCommonValence, GetRings, GetRingsWithEvenSize, | |
| 4345 GetRingsWithOddSize, GetRingsWithSize, GetRingsWithSizeGreaterThan, | |
| 4346 GetRingsWithSizeLessThan, GetSizeOfLargestRing, GetSizeOfSmallestRing, | |
| 4347 GetSmallestRing, GetSpinMultiplicity, GetSumOfBondOrders, | |
| 4348 GetSumOfBondOrdersToHeavyAtoms, GetSumOfBondOrdersToHydrogenAtoms, | |
| 4349 GetSumOfBondOrdersToNonHydrogenAtoms, GetValence, GetValenceElectrons, | |
| 4350 GetValenceFreeElectrons, GetX, GetXYZ, GetXYZVector, GetY, GetZ, IsAmideCarbon, | |
| 4351 IsAmideNitrogen, IsAromatic, IsArsenic, IsBondedToAtom, IsBromine, IsCarbon, IsCarboxylCarbon, | |
| 4352 IsCarboxylOxygen, IsCarboxylateCarbon, IsCarboxylateOxygen, IsChlorine, | |
| 4353 IsFluorine, IsFunctionalClassType, IsGuadiniumCarbon, IsGuadiniumNitrogen, | |
| 4354 IsHBondAcceptor, IsHBondDonor, IsHalogen, IsHeteroAtom, IsHydrogen, | |
| 4355 IsHydrogenBondAcceptor, IsHydrogenBondDonor, IsHydrophobic, IsInRing, | |
| 4356 IsInRingOfSize, IsIodine, IsIsotope, IsLipophilic, IsMetallic, | |
| 4357 IsNegativelyIonizable, IsNitrogen, IsNonCarbonOrHydrogen, IsNotInRing, | |
| 4358 IsOnlyInOneRing, IsOxygen, IsPhosphateOxygen, IsPhosphatePhosphorus, IsPhosphorus, | |
| 4359 IsPolarAtom, IsPolarHydrogen, IsPositivelyIonizable, IsSaturated, IsSelenium, | |
| 4360 IsSilicon, IsStereoCenter, IsSulfur, IsSulphur, IsTellurium, IsTerminal, | |
| 4361 IsTopologicalPharmacophoreType, IsUnsaturated, SetAtomSymbol, SetAtomicNumber, | |
| 4362 SetExplicitHydrogens, SetMassNumber, SetStereoCenter, SetStereochemistry, | |
| 4363 SetX, SetXYZ, SetY, SetZ, StringifyAtom | |
| 4364 | |
| 4365 B<Atom> class is derived from B<ObjectProperty> base class which provides methods not explicitly | |
| 4366 defined in B<Atom> or B<ObjectProperty> class using Perl's AUTOLOAD functionality. These methods | |
| 4367 are generated on-the-fly for a specified object property: | |
| 4368 | |
| 4369 Set<PropertyName>(<PropertyValue>); | |
| 4370 $PropertyValue = Get<PropertyName>(); | |
| 4371 Delete<PropertyName>(); | |
| 4372 | |
| 4373 =head2 METHODS | |
| 4374 | |
| 4375 =over 4 | |
| 4376 | |
| 4377 =item B<new> | |
| 4378 | |
| 4379 $NewAtom = new Atom([%PropertyNameAndValues]); | |
| 4380 | |
| 4381 Using specified I<Atom> property names and values hash, B<new> method creates a new object | |
| 4382 and returns a reference to newly created B<Atom> object. By default, following properties are | |
| 4383 initialized: | |
| 4384 | |
| 4385 ID = SequentialObjectID | |
| 4386 Name = "Atom <SequentialObjectID>" | |
| 4387 AtomSymbol = "" | |
| 4388 AtomicNumber = 0 | |
| 4389 XYZ = ZeroVector | |
| 4390 | |
| 4391 Except for I<ID> property, all other default properties and other additional properties can | |
| 4392 be set during invocation of this method. | |
| 4393 | |
| 4394 Examples: | |
| 4395 | |
| 4396 $Atom = new Atom(); | |
| 4397 $CarbonAtom = new Atom('AtomSymbol' => 'C', 'XYZ' => (0.0, 1.0, | |
| 4398 0.0)); | |
| 4399 $OxygenAtom = new Atom('AtomName' => 'Oxygen', AtomSymbol' => 'O', | |
| 4400 'XYZ' => (1.0, 1.0, 1.0)); | |
| 4401 | |
| 4402 =item B<AddHydrogens> | |
| 4403 | |
| 4404 $NumOfHydrogensAdded = $Atom->AddHydrogens(); | |
| 4405 | |
| 4406 Adds hydrogens to an B<Atom> present in a B<Molecule> object and returns | |
| 4407 the number of added hydrogens. The current release of MayaChemTools doesn't | |
| 4408 assign hydrogen positions. | |
| 4409 | |
| 4410 =item B<Copy> | |
| 4411 | |
| 4412 $AtomCopy = $Atom->Copy(); | |
| 4413 | |
| 4414 Copy I<Atom> and its associated data using B<Storable::dclone> and return a new | |
| 4415 B<Atom> object. | |
| 4416 | |
| 4417 =item B<DeleteAtom> | |
| 4418 | |
| 4419 $Atom->DeleteAtom(); | |
| 4420 | |
| 4421 Delete I<Atom> from a molecule. | |
| 4422 | |
| 4423 =item B<DoesAtomNeighborhoodMatch> | |
| 4424 | |
| 4425 $Status = $Atom->DoesAtomNeighborhoodMatch($CentralAtomSpec); | |
| 4426 $Status = $Atom->DoesAtomNeighborhoodMatch($CentralAtomSpec, | |
| 4427 $NbrAtomSpecsRef); | |
| 4428 $Status = $Atom->DoesAtomNeighborhoodMatch($CentralAtomSpec, | |
| 4429 $NbrAtomSpecsRef, $AllowedNbrBondSpecsRef); | |
| 4430 $Status = $Atom->DoesAtomNeighborhoodMatch($CentralAtomSpec, | |
| 4431 $NbrAtomSpecsRef, $NbrBondSpecsRef, | |
| 4432 $AllowedNbrOfNbrAtomSpecsRef); | |
| 4433 | |
| 4434 Returns 1 or 0 based on whether atom matches central atom and its neighborhood | |
| 4435 using specified atom and bonds specifications. Neighborhood atom and bond specifications | |
| 4436 are specified as array references containing neighbor atom and bond specifications. | |
| 4437 | |
| 4438 Let: | |
| 4439 | |
| 4440 AS = Atom symbol corresponding to element symbol, atomic number (#n) | |
| 4441 or any atom (A) | |
| 4442 | |
| 4443 X<n> = Number of non-hydrogen atom neighbors or heavy atoms | |
| 4444 attached to atom | |
| 4445 T<n> = Total number of atom neighbors including implicit and explicit | |
| 4446 hydrogens | |
| 4447 BO<n> = Sum of bond orders to non-hydrogen atom neighbors or heavy | |
| 4448 atoms attached to atom | |
| 4449 LBO<n> = Largest bond order of non-hydrogen atom neighbors or heavy | |
| 4450 atoms attached to atom | |
| 4451 SB<n> = Number of single bonds to non-hydrogen atom neighbors or | |
| 4452 heavy atoms attached to atom | |
| 4453 TSB<n> = Total number of single bonds to atom neighbors including implicit | |
| 4454 and explicit hydrogens | |
| 4455 DB<n> = Number of double bonds to non-hydrogen atom neighbors or | |
| 4456 heavy atoms attached to atom | |
| 4457 TB<n> = Number of triple bonds to non-hydrogen atom neighbors or | |
| 4458 heavy atoms attached to atom | |
| 4459 AB<n> = Number of aromatic bonds to non-hydrogen atom neighbors or | |
| 4460 heavy atoms attached to atom | |
| 4461 H<n> = Number of implicit and explicit hydrogens for atom | |
| 4462 Ar = Aromatic annotation indicating whether atom is aromatic | |
| 4463 RA or RA<n> = Ring atom annotation indicating whether atom | |
| 4464 is a ring | |
| 4465 TR<n> = Total number of rings containing atom | |
| 4466 FC<+n/-n> = Formal charge assigned to atom | |
| 4467 MN<n> = Mass number indicating isotope other than most abundant isotope | |
| 4468 SM<n> = Spin multiplicity of atom. Possible values: 1 (singlet), | |
| 4469 2 (doublet) or 3 (triplet) | |
| 4470 | |
| 4471 Then, atom specification corresponds to: | |
| 4472 | |
| 4473 AS.X<n>.T<n>.BO<n>.LBO<n>.<SB><n>.TSB<n>.<DB><n>.<TB><n>.AB<n>.H<n>.Ar. | |
| 4474 RA<n>.TR<n>FC<+n/-n>.MN<n>.SM<n> | |
| 4475 | |
| 4476 Except for AS which is a required atomic invariant in atom specification, all other atomic invariants are | |
| 4477 optional. For an atom specification to match an atom, the values of all specified atomic invariants must | |
| 4478 match. Exclamation in from of atomic invariant can be used to negate its effect during the match. | |
| 4479 | |
| 4480 For I<FC> value matching, the following value operators are also supported: | |
| 4481 | |
| 4482 o +* : Any positive value | |
| 4483 o -* : Any negative value | |
| 4484 o > ValidNumber or >= ValidNumber | |
| 4485 o < ValidNumber or <= ValidNumber | |
| 4486 | |
| 4487 A comma delimited atom specification string is used to match any one of the specified atom specification. | |
| 4488 | |
| 4489 Notes: | |
| 4490 | |
| 4491 o During atom specification match to an atom, the first atomic invariant is always assumed to | |
| 4492 atom symbol. | |
| 4493 | |
| 4494 Examples: | |
| 4495 | |
| 4496 o ('N', 'N', 'N') | |
| 4497 o ('N.FC0', 'N.FC0', 'N,N.FC+1.H1') | |
| 4498 o ('N.H2', 'N.H2', 'N.H1') | |
| 4499 o ('C,N', '!N', '!H') | |
| 4500 o ('C,N', 'N.Ar', 'N.R5') | |
| 4501 | |
| 4502 Let: | |
| 4503 | |
| 4504 -|1|s|Single = Single bond | |
| 4505 =|2|d|Double = Double bond | |
| 4506 #|3|t|Triple = Triple bond | |
| 4507 :|1.5|a|Ar|Aromatic = Aromatic bond | |
| 4508 | |
| 4509 @|RB|Ring = Ring bond | |
| 4510 ~|*|Any = Any bond | |
| 4511 | |
| 4512 Then, bond specification corresponds to: | |
| 4513 | |
| 4514 -.: | |
| 4515 =.@ | |
| 4516 Double.Aromatic | |
| 4517 | |
| 4518 For a bond specification to match bond between two atoms, the values of all specified bond symbols must | |
| 4519 match. Exclamation in from of bond symbol can be used to negate its effect during the match. | |
| 4520 | |
| 4521 A comma delimited bond specification string is used to match any one of the specified atom specification. | |
| 4522 | |
| 4523 Notes: | |
| 4524 | |
| 4525 o During atom neighborhood match for central atom neighborhood atom and bond specifications, | |
| 4526 implicit or missing hydrogens are automatically checked for any matches to unmatched | |
| 4527 specifications. | |
| 4528 | |
| 4529 Examples: | |
| 4530 | |
| 4531 | |
| 4532 Aromatic carbon in a 5 membered ring: | |
| 4533 $Atom->DoesAtomNeighborhoodMatch('C.Ar.RA5'); | |
| 4534 | |
| 4535 AcetylenicCarbon: $Atom->DoesAtomNeighborhoodMatch('C.T2.TB1'); or | |
| 4536 $Atom->DoesAtomNeighborhoodMatch('C.T2.TB1', | |
| 4537 ['*', '*'], ['#', '-']); | |
| 4538 | |
| 4539 GuadiniumCarbon: $Atom->DoesAtomNeighborhoodMatch('C.X3.BO4', | |
| 4540 ['N.FC0', 'N.FC0', 'N.FC0,N.FC+1'], | |
| 4541 ['-', '-', '='], | |
| 4542 ['C,H', 'C,H', 'C,H']); | |
| 4543 | |
| 4544 AmideCarbon: $Atom->DoesAtomNeighborhoodMatch('C.X3.BO4,C.X2.BO3', | |
| 4545 ['C,H', 'O', 'N'], | |
| 4546 ['-', '=', '-'], | |
| 4547 ['C,H', 'C', 'C,H,N,O,S,P,F,Cl,Br,I']); | |
| 4548 | |
| 4549 CarboxylCarbon: $Atom->DoesAtomNeighborhoodMatch('C.X3.BO4,C.X2.BO3', | |
| 4550 ['C,H', 'O', 'O.X1.FC0'], | |
| 4551 ['-', '=', '-'], | |
| 4552 ['C,H', 'C', 'C']); | |
| 4553 | |
| 4554 CarboxylateCarbon: $Atom->DoesAtomNeighborhoodMatch('C.X3.BO4,C.X2.BO3', | |
| 4555 ['C,H', 'O', 'O.X1.FC-1'], | |
| 4556 ['-', '=', '-'], | |
| 4557 ['C,H', 'C', 'C']); | |
| 4558 | |
| 4559 | |
| 4560 =item B<DeleteHydrogens> | |
| 4561 | |
| 4562 $NumOfHydrogensDeleted = $Atom->AddHydrogens(); | |
| 4563 | |
| 4564 Delete hydrogens from an B<Atom> present in a B<Molecule> object and returns | |
| 4565 the number of deleted hydrogens. | |
| 4566 | |
| 4567 =item B<GetAtomicInvariantValue> | |
| 4568 | |
| 4569 $Value = $Atom->GetAtomicInvariantValue($AtomicInvariant); | |
| 4570 | |
| 4571 Returns atomic invariant value for a specified I<AtomicInvariant>. The current release | |
| 4572 of MayaChemTools supports following abbreviations and descriptive names for | |
| 4573 I<AtomicInvarints>: | |
| 4574 | |
| 4575 AS : Atom or element symbol | |
| 4576 X : NumOfNonHydrogenAtomNeighbors or NumOfHeavyAtomNeighbors | |
| 4577 T : TotalNumOfAtomNeighbors | |
| 4578 BO : SumOfBondOrdersToNonHydrogenAtoms or SumOfBondOrdersToHeavyAtoms | |
| 4579 LBO : LargestBondOrderToNonHydrogenAtoms or LargestBondOrderToHeavyAtoms | |
| 4580 SB : NumOfSingleBondsToNonHydrogenAtoms or NumOfSingleBondsToHeavyAtoms | |
| 4581 TSB : TotalNumOfSingleBonds | |
| 4582 DB : NumOfDoubleBondsToNonHydrogenAtoms or NumOfDoubleBondsToHeavyAtoms | |
| 4583 TB : NumOfTripleBondsToNonHydrogenAtoms or NumOfTripleBondsToHeavyAtoms | |
| 4584 AB : NumOfAromaticBondsToNonHydrogenAtoms or NumOfAromaticBondsToHeavyAtoms | |
| 4585 H : NumOfImplicitAndExplicitHydrogens | |
| 4586 Ar : Aromatic | |
| 4587 Str : Stereochemistry | |
| 4588 RA : RingAtom | |
| 4589 FC : FormalCharge | |
| 4590 AN : AtomicNumber | |
| 4591 AM : AtomicMass | |
| 4592 MN : MassNumber | |
| 4593 SM : SpinMultiplicity | |
| 4594 | |
| 4595 =item B<GetAtomicWeight> | |
| 4596 | |
| 4597 $Value = $Aom->GetAtomicWeight(); | |
| 4598 | |
| 4599 Returns atomic weight of an B<Atom> which corresponds to either explicity set I<AtomicWeight> | |
| 4600 atom property or atomic weight of the corresponding element in the periodic table available by | |
| 4601 B<PeriodicTable> module. | |
| 4602 | |
| 4603 =item B<GetBondToAtom> | |
| 4604 | |
| 4605 $Bond = $Atom->GetBondToAtom($OtherAtom); | |
| 4606 | |
| 4607 Returns a B<Bond> object corresponding to bond between I<Atom> and I<OtherAtom> in | |
| 4608 a molecule. | |
| 4609 | |
| 4610 =item B<GetBonds> | |
| 4611 | |
| 4612 @Bonds = $Aoto->GetBonds(); | |
| 4613 | |
| 4614 Returns an array of B<Bond> objects corresponding to all bonds from I<Atom> to other | |
| 4615 bonded atoms in a molecule. | |
| 4616 | |
| 4617 =item B<GetBondsToHeavyAtoms> | |
| 4618 | |
| 4619 @Bonds = $Atom->GetBondsToHeavyAtoms(); | |
| 4620 | |
| 4621 Returns an array of B<Bond> objects corresponding to bonds from I<Atom> to other bonded | |
| 4622 non-hydrogen atoms in a molecule. | |
| 4623 | |
| 4624 =item B<GetBondsToHydrogenAtoms> | |
| 4625 | |
| 4626 @Bonds = $Atom->GetBondsToHydrogenAtoms(); | |
| 4627 | |
| 4628 Returns an array of B<Bond> objects corresponding to bonds from I<Atom> to any other | |
| 4629 hydrogen atom in a molecule. | |
| 4630 | |
| 4631 =item B<GetBondsToNonHydrogenAtoms> | |
| 4632 | |
| 4633 @Bonds = $Atom->GetBondsToNonHydrogenAtoms(); | |
| 4634 | |
| 4635 Returns an array of B<Bond> objects corresponding to bonds from I<Atom> to other bonded | |
| 4636 non-hydrogen atoms in a molecule. | |
| 4637 | |
| 4638 =item B<GetExactMass> | |
| 4639 | |
| 4640 $ExactMass = $Atom->GetExactMass(); | |
| 4641 | |
| 4642 Returns exact mass of an I<Atom> which correspond to one of these three values: explicity set | |
| 4643 I<ExactMass> property; mass of natural isotope for an explicty set value of I<MassNumber>; most | |
| 4644 abundant natural isotope mass for I<Atom> with valid atomic number value available by | |
| 4645 B<PerodicTable> module. | |
| 4646 | |
| 4647 =item B<GetExplicitHydrogens> | |
| 4648 | |
| 4649 $NumOfExplicitHydrogens = $Atom->GetExplicitHydrogens(); | |
| 4650 | |
| 4651 Returns number of hydrogens explicity bonded to an I<Atom> in a molecule. | |
| 4652 | |
| 4653 =item B<GetFormalCharge> | |
| 4654 | |
| 4655 $FormalCharge = $Atom->GetFormalCharge(); | |
| 4656 | |
| 4657 Returns formal charge of an I<Atom> in a molecule. | |
| 4658 | |
| 4659 =item B<GetFreeRadicalElectrons> | |
| 4660 | |
| 4661 $FreeRadicalElectrons = $Atom->GetFreeRadicalElectrons(); | |
| 4662 | |
| 4663 Returns number of free radical electrons corresponding to to one of these | |
| 4664 three values: I<FreeRadicalElectrons> property; I<SpinMultiplicity> property; value | |
| 4665 of 0. | |
| 4666 | |
| 4667 For atoms with explicit assignment of I<SpinMultiplicity> atom property values, | |
| 4668 | |
| 4669 Singlet - two unparied electrons corresponding to one spin state | |
| 4670 Doublet - free radical; an unpaired electron corresponding to two | |
| 4671 spin states | |
| 4672 Triplet - two unparied electrons corresponding to three spin states | |
| 4673 (divalent carbon atoms: carbenes) | |
| 4674 | |
| 4675 B<FreeRadicalElectrons> are calculated as follows: | |
| 4676 | |
| 4677 Doublet: 1 (one valence electron not available for bonding) | |
| 4678 Singlet: 2 (two valence electrons not available for bonding) | |
| 4679 Triplet: 2 (two valence electrons not available for bonding) | |
| 4680 | |
| 4681 =item B<GetGroupNumber> | |
| 4682 | |
| 4683 $GroupNumber = $Atom->GetGroupNumber(); | |
| 4684 | |
| 4685 Returns group number of an I<Atom> in a molecule with a valid atomic number. | |
| 4686 | |
| 4687 =item B<GetHeavyAtomNeighbors> | |
| 4688 | |
| 4689 $NumOfHeavyAtoms = $Atom->GetHeavyAtomNeighbors(); | |
| 4690 @HeavyAtoms = $Atom->GetHeavyAtomNeighbors(); | |
| 4691 | |
| 4692 Return number of heavy atoms or an array of B<Atom> objects corresponding to heavy atoms | |
| 4693 bonded to an I<Atom> in a molecule. | |
| 4694 | |
| 4695 =item B<GetHeavyAtomNeighborsAtomInformation> | |
| 4696 | |
| 4697 ($NumOfAtomNeighbors, $AtomNeighborsRef, | |
| 4698 $NumOfAtomNeighborsType, $AtomNeighborsTypeMapRef) = $Atom-> | |
| 4699 GetHeavyAtomNeighborsAtomInformation(); | |
| 4700 | |
| 4701 Returns atoms information for all non-hydrogen atoms attached to an I<Atom> | |
| 4702 in a molecule. | |
| 4703 | |
| 4704 The following values are returned: | |
| 4705 | |
| 4706 o Number of non-hydrogen atom neighbors | |
| 4707 o A reference to an array containing atom objects corresponding to | |
| 4708 non-hydrogen atom neighbors | |
| 4709 o Number of different types of non-hydrogen atom neighbors | |
| 4710 o A reference to a hash containing atom symbol as key with value | |
| 4711 corresponding to its count for non-hydrogen atom neighbors | |
| 4712 | |
| 4713 =item B<GetHeavyAtomNeighborsBondformation> | |
| 4714 | |
| 4715 ($NumOfBonds, $BondTypeCountMapRef, | |
| 4716 $AtomsBondTypesCountMapRef, | |
| 4717 $AtomsBondTypeAtomsMap) = $Atom-> | |
| 4718 GetHeavyAtomNeighborsBondformation(); | |
| 4719 | |
| 4720 Returns bonds information for all non-hydrogen atoms attached to an I<Atom> | |
| 4721 in a molecule. | |
| 4722 | |
| 4723 The following values are returned: | |
| 4724 | |
| 4725 o Number of bonds to non-hydrogen atom neighbors | |
| 4726 o A reference to an array containing bond objects corresponding to | |
| 4727 non-hydrogen atom neighbors | |
| 4728 o A reference to a hash containing bond type as key with value | |
| 4729 corresponding to its count for non-hydrogen atom neighbors. Bond | |
| 4730 types are: Single, Double or Triple | |
| 4731 o A reference to a hash containing atom symbol as key pointing to bond | |
| 4732 type as second key with values corresponding to count of bond types for atom | |
| 4733 symbol for non-hydrogen atom neighbors | |
| 4734 o A reference to a hash containing atom symbol as key pointing to bond | |
| 4735 type as second key with values corresponding to atom objects array involved | |
| 4736 in corresponding bond type for atom symbol for non-hydrogen atom neighbors | |
| 4737 | |
| 4738 =item B<GetHighestCommonValence> | |
| 4739 | |
| 4740 $HighestCommonValence = $Atom->GetHighestCommonValence(); | |
| 4741 | |
| 4742 Returns highest common valence of an I<Atom> which corresponds to either explicity set | |
| 4743 I<HighestCommonValence> atom property or highest common valence of the corresponding | |
| 4744 element in the periodic table available by B<PerodicTable> module. | |
| 4745 | |
| 4746 =item B<GetHydrogens> | |
| 4747 | |
| 4748 $NumOfHydrogens = $Atom->GetHydrogens(); | |
| 4749 | |
| 4750 Returns total number of hydrogens for an I<Atom> in a molecule including both hydrogen atom | |
| 4751 neighbors and implicit hydrogens. | |
| 4752 | |
| 4753 =item B<GetHydrogenAtomNeighbors> | |
| 4754 | |
| 4755 $NumOfHydrogenAtomNeighbors = $Atom->GetHydrogenAtomNeighbors(); | |
| 4756 @HydrogenAtomNeighbors = $Atom->GetHydrogenAtomNeighbors(); | |
| 4757 | |
| 4758 Return number of hydrogen atoms or an array of I<Atom> objects corresponding to hydrogen | |
| 4759 atoms bonded to an I<Atom> in a molecule. | |
| 4760 | |
| 4761 =item B<GetImplicitHydrogens> | |
| 4762 | |
| 4763 $NumOfImplicitHydrogens = $Atom->GetImplicitHydrogens(); | |
| 4764 | |
| 4765 Returns number of implicit hydrogens for an I<Atom> in a molecule. This value either | |
| 4766 corresponds to explicitly set I<ImplicitHydrogens> atom property or calculated as the | |
| 4767 difference between the value of potential total valence and sum of bond orders to | |
| 4768 both hydrogen and non-hydrogen atom neighbors. | |
| 4769 | |
| 4770 =item B<GetPotentialTotalCommonValence> | |
| 4771 | |
| 4772 $PotentialTotalValence = $Atom->GetPotentialTotalCommonValence(); | |
| 4773 | |
| 4774 Returns potential total common valence of an I<Atom> in a molecule corresponding | |
| 4775 to a specific valence model set for the molecule using its B<SetValenceModel> method | |
| 4776 or default internal valence model. It is used during the calculation of missing or | |
| 4777 implicit hydrogens. | |
| 4778 | |
| 4779 The current release of MayaChemTools supports three valence models: I<MDLValenceModel, | |
| 4780 DaylightValenceModel, InternalValenceModel or MayaChemToolsValenceModel>. | |
| 4781 | |
| 4782 For I<MDLValenceModel> and I<DaylightValenceModel>, the following data files, distributed | |
| 4783 with the package, are used to calculate potential total valence: | |
| 4784 | |
| 4785 lib/data/MDLValenceModelData.csv | |
| 4786 lib/data/DaylightValenceModelData.csv | |
| 4787 | |
| 4788 The calculation of potential total common valence for these two models is performed as | |
| 4789 follows: Calculate current effective total valence of the I<Atom> by adding up the bond | |
| 4790 order of its neighbors and number of free radical electrons; Find available common valence | |
| 4791 for the I<Atom>, corresponding to any specified formal charge, higher than the effective | |
| 4792 total valence, and return it as I<PotentialTotalValence>. | |
| 4793 | |
| 4794 The calculation of potential total common valence For I<InternalValenceModel> or | |
| 4795 I<MayaChenToolsValenceModel> doesn't uses B<PeriodicTable> module to retrieve values | |
| 4796 for common valence, which in turn reads in PeriodicTableElements.csv file distributed with | |
| 4797 the package. | |
| 4798 | |
| 4799 For elements with one one common valence, potential total common valence corresponds | |
| 4800 to: | |
| 4801 | |
| 4802 CommonValence + FormalCharge - FreeRadicalElectrons | |
| 4803 | |
| 4804 For elements with multiple common valences, each common valence is used to | |
| 4805 calculate total potential common valence as shown above, and the first total potential | |
| 4806 common valence greater than the sum of bond orders to all neighbors is selected as | |
| 4807 the final total common valence. | |
| 4808 | |
| 4809 FormalCharge sign is reversed for electropositive elements with positive formal charge | |
| 4810 during common valence calculations. Electropositive elements, metals and transition elements, | |
| 4811 have usually plus formal charge and it leads to decrease in common valence; the negative | |
| 4812 formal charge should result in the decrease of common valence. | |
| 4813 | |
| 4814 The sign of formal charge is adjusted as follows. | |
| 4815 | |
| 4816 Group numbers > 14 - Group numbers 15 (N), 16 (O), 17 (F), 18 (He): | |
| 4817 | |
| 4818 Formal charge sign is not adjusted. Positive and negative values result in the | |
| 4819 increase and decrease of valence. | |
| 4820 | |
| 4821 Group 14 containing C, Si, Ge, Sn, Pb...: | |
| 4822 | |
| 4823 Formal charge sign is reversed for positive values. Both positive and negative | |
| 4824 values result in the decrease of valence. | |
| 4825 | |
| 4826 Group 13 containing B, Al, Ga, In, Tl...: | |
| 4827 | |
| 4828 Formal charge sign is always reversed. Positive and negative values result in the | |
| 4829 decrease and increase of valence. | |
| 4830 | |
| 4831 Groups 1 (H) through 12 (Zn)...: | |
| 4832 | |
| 4833 Formal charge sign is reversed for positive values. Both positive and negative | |
| 4834 values result in the decrease of valence. | |
| 4835 | |
| 4836 Lanthanides and actinides: | |
| 4837 | |
| 4838 Formal charge sign is reversed for positive values. Both positive and negative | |
| 4839 values result in the decrease of valence. | |
| 4840 | |
| 4841 =item B<GetLargestBondOrder> | |
| 4842 | |
| 4843 $LargestBO =$Atom->GetLargestBondOrder(); | |
| 4844 | |
| 4845 Returns largest bond order for an I<Atom> among the bonds to other atoms in a molecule. | |
| 4846 | |
| 4847 =item B<GetLargestBondOrderToHeavyAtoms> | |
| 4848 | |
| 4849 $LargestBO =$Atom->GetLargestBondOrderToHeavyAtoms(); | |
| 4850 | |
| 4851 Returns largest bond order for an I<Atom> among the bonds to other heavy atoms in a molecule. | |
| 4852 | |
| 4853 =item B<GetLargestBondOrderToNonHydrogenAtoms> | |
| 4854 | |
| 4855 $LargestBO =$Atom->GetLargestBondOrderToNonHydrogenAtoms(); | |
| 4856 | |
| 4857 Returns largest bond order for an I<Atom> among the bonds to other non-hydrogen atoms | |
| 4858 in a molecule. | |
| 4859 | |
| 4860 =item B<GetLargestRing> | |
| 4861 | |
| 4862 @RingAtoms = $Atom->GetLargestRing(); | |
| 4863 | |
| 4864 Returns an array of ring I<Atom> objects corresponding to the largest ring containing I<Atom> | |
| 4865 in a molecule. | |
| 4866 | |
| 4867 =item B<GetLowestCommonValence> | |
| 4868 | |
| 4869 $LowestCommonValence = $Atom->GetLowestCommonValence(); | |
| 4870 | |
| 4871 Returns lowest common valence of an I<Atom> which corresponds to either explicity set | |
| 4872 I<LowestCommonValence> atom property or highest common valence of the corresponding | |
| 4873 element in the periodic table available by B<PerodicTable> module. | |
| 4874 | |
| 4875 =item B<GetMassNumber> | |
| 4876 | |
| 4877 $MassNumber = $Aom->GetMassNumber(); | |
| 4878 | |
| 4879 Returns atomic weight of an B<Atom> which corresponds to either explicity set I<MassNumber> | |
| 4880 atom property or mass number of the most abundant natural isotope of the corresponding element | |
| 4881 in the periodic table available by B<PeriodicTable> module. | |
| 4882 | |
| 4883 =item B<GetMissingHydrogens> | |
| 4884 | |
| 4885 $NumOfMissingHydrogens = $Atom->GetMissingHydrogens(); | |
| 4886 | |
| 4887 Returns number of missing hydrogens for an I<Atom> in a molecule. This value either | |
| 4888 corresponds to explicitly set I<ImplicitHydrogens> atom property or calculated as the | |
| 4889 difference between the value of potential total valence and sum of bond orders to | |
| 4890 both hydrogen and non-hydrogen atom neighbors. | |
| 4891 | |
| 4892 =item B<GetNeighbors> | |
| 4893 | |
| 4894 $NumOfNeighbors = $Atom->GetNeighbors(); | |
| 4895 @Neighbors = $Atom->GetNeighbors(); | |
| 4896 | |
| 4897 Returns number of neighbor atoms or an array of I<Atom> objects corresponding to all | |
| 4898 atoms bonded to an I<Atom> in a molecule. | |
| 4899 | |
| 4900 =item B<GetNeighborsUsingAtomSpecification> | |
| 4901 | |
| 4902 @AtomNeighbors = $Atom->GetNeighborsUsingAtomSpecification($AtomSpec); | |
| 4903 $NumOfNeighbors = $Atom->GetNeighborsUsingAtomSpecification($AtomSpec); | |
| 4904 | |
| 4905 @AtomNeighbors = $Atom->GetNeighborsUsingAtomSpecification($AtomSpec, | |
| 4906 @ExcludeNeighbors); | |
| 4907 | |
| 4908 Returns number of neighbor atoms or an array of I<Atom> objects matching atom | |
| 4909 specification corresponding to atom neighbors of an I<Atom> in a molecule. Optionally, | |
| 4910 I<Atom> neighbors can be excluded from the neighbors list using I<ExcludeNeighbors>. | |
| 4911 | |
| 4912 Notes: | |
| 4913 | |
| 4914 o AtomSpecification correspond to any valid AtomicInvariant based atomic specifications | |
| 4915 as supported by DoesAtomNeighborhoodMatch method | |
| 4916 o Multiple atom specifications can be used in a string delimited by comma | |
| 4917 | |
| 4918 =item B<GetNonHydrogenAtomNeighbors> | |
| 4919 | |
| 4920 $NumOfNeighbors = $Atom->GetNonHydrogenAtomNeighbors(); | |
| 4921 @Neighbors = $Atom->GetNonHydrogenAtomNeighbors(); | |
| 4922 | |
| 4923 Returns number of non-hydrogen atoms or an array of B<Atom> objects corresponding to non-hydrogen | |
| 4924 atoms bonded to an I<Atom> in a molecule. | |
| 4925 | |
| 4926 =item B<GetNonHydrogenAtomNeighborsAtomInformation> | |
| 4927 | |
| 4928 ($NumOfAtomNeighbors, $AtomNeighborsRef, | |
| 4929 $NumOfAtomNeighborsType, $AtomNeighborsTypeMapRef) = $Atom-> | |
| 4930 GetNonHydrogenAtomNeighborsAtomInformation(); | |
| 4931 | |
| 4932 Returns atoms information for all non-hydrogen atoms attached to an I<Atom> | |
| 4933 in a molecule. | |
| 4934 | |
| 4935 The following values are returned: | |
| 4936 | |
| 4937 o Number of non-hydrogen atom neighbors | |
| 4938 o A reference to an array containing atom objects corresponding to | |
| 4939 non-hydrogen atom neighbors | |
| 4940 o Number of different types of non-hydrogen atom neighbors | |
| 4941 o A reference to a hash containing atom symbol as key with value | |
| 4942 corresponding to its count for non-hydrogen atom neighbors | |
| 4943 | |
| 4944 | |
| 4945 =item B<GetNonHydrogenAtomNeighborsBondInformation> | |
| 4946 | |
| 4947 ($NumOfBonds, $BondTypeCountMapRef, | |
| 4948 $AtomsBondTypesCountMapRef, | |
| 4949 $AtomsBondTypeAtomsMap) = $Atom-> | |
| 4950 GetNonHydrogenAtomNeighborsBondInformation(); | |
| 4951 | |
| 4952 Returns bonds information for all non-hydrogen atoms attached to an I<Atom> | |
| 4953 in a molecule. | |
| 4954 | |
| 4955 The following values are returned: | |
| 4956 | |
| 4957 o Number of bonds to non-hydrogen atom neighbors | |
| 4958 o A reference to an array containing bond objects corresponding to | |
| 4959 non-hydrogen atom neighbors | |
| 4960 o A reference to a hash containing bond type as key with value | |
| 4961 corresponding to its count for non-hydrogen atom neighbors. Bond | |
| 4962 types are: Single, Double or Triple | |
| 4963 o A reference to a hash containing atom symbol as key pointing to bond | |
| 4964 type as second key with values corresponding to count of bond types for atom | |
| 4965 symbol for non-hydrogen atom neighbors | |
| 4966 o A reference to a hash containing atom symbol as key pointing to bond | |
| 4967 type as second key with values corresponding to atom objects array involved | |
| 4968 in corresponding bond type for atom symbol for non-hydrogen atom neighbors | |
| 4969 | |
| 4970 =item B<GetNonHydrogenNeighborOfHydrogenAtom> | |
| 4971 | |
| 4972 $Atom = $Atom->GetNonHydrogenNeighborOfHydrogenAtom(); | |
| 4973 | |
| 4974 Returns non-hydrogen or heavy atom neighbor of a hydrogen atom in a molecule.. | |
| 4975 | |
| 4976 =item B<GetNumOfAromaticBondsToHeavyAtoms> | |
| 4977 | |
| 4978 $NumOfBonds = $Atom->GetNumOfAromaticBondsToHeavyAtoms(); | |
| 4979 | |
| 4980 Returns number of aromatic bonds from an I<Atom> to other non-hydrogen or heavy atoms in | |
| 4981 a molecule. | |
| 4982 | |
| 4983 =item B<GetNumOfAromaticBondsToNonHydrogenAtoms> | |
| 4984 | |
| 4985 $NumOfBonds = $Atom->GetNumOfAromaticBondsToNonHydrogenAtoms(); | |
| 4986 | |
| 4987 Returns number of aromatic bonds from an I<Atom> to other non-hydrogen or heavy atoms in | |
| 4988 a molecule. | |
| 4989 | |
| 4990 =item B<GetNumOfBonds> | |
| 4991 | |
| 4992 $NumOfBonds = $Atom->GetNumOfBonds(); | |
| 4993 | |
| 4994 Returns number of bonds from an I<Atom> to other atoms in a molecule. | |
| 4995 | |
| 4996 =item B<GetNumOfBondsAvailableForHeavyAtoms> | |
| 4997 | |
| 4998 $NumOfBonds = $Atom->GetNumOfBondsAvailableForHeavyAtoms(); | |
| 4999 | |
| 5000 Get number of bonds available to form additional bonds with heavy atoms, excluding | |
| 5001 any implicit bonds to hydrogens set using I<ImplicitHydrogens> property. | |
| 5002 | |
| 5003 It's different from number of implicit or missing hydrogens, both of which are equivalent. | |
| 5004 | |
| 5005 For example, in a SMILES string, [nH] ring atom corresponds to an aromatic nitrogen. | |
| 5006 Although the hydrogen specified for n is treated internally as implicit hydrogen and shows | |
| 5007 up in missing hydrogen count, it's not available to participate in double bonds to additional | |
| 5008 heavy atoms. | |
| 5009 | |
| 5010 =item B<GetNumOfBondsAvailableForNonHydrogenAtoms> | |
| 5011 | |
| 5012 $NumOfBonds = $Atom->GetNumOfBondsAvailableForNonHydrogenAtoms(); | |
| 5013 | |
| 5014 Get number of bonds available to form additional bonds with heavy atoms, excluding | |
| 5015 any implicit bonds to hydrogens set using ImplicitHydrogens property. | |
| 5016 | |
| 5017 =item B<GetNumOfBondsToHeavyAtoms> | |
| 5018 | |
| 5019 $NumOfBondsToHeavyAtoms = $Atom->GetNumOfBondsToHeavyAtoms(); | |
| 5020 | |
| 5021 Returns number of bonds from an I<Atom> to other heavy atoms in a molecule. | |
| 5022 | |
| 5023 =item B<GetNumOfBondsToHydrogenAtoms> | |
| 5024 | |
| 5025 $NumOfBonds = $Atom->GetNumOfBondsToHydrogenAtoms(); | |
| 5026 | |
| 5027 Returns number of bonds from an I<Atom> to other hydrogen atoms in a molecule. | |
| 5028 | |
| 5029 =item B<GetNumOfBondsToNonHydrogenAtoms> | |
| 5030 | |
| 5031 $NumOfBonds = $Atom->GetNumOfBondsToNonHydrogenAtoms(); | |
| 5032 | |
| 5033 Returns number of bonds from an I<Atom> to other non-hydrogen atoms in a molecule. | |
| 5034 | |
| 5035 =item B<GetNumOfBondTypesToHeavyAtoms> | |
| 5036 | |
| 5037 ($NumOfSingleBonds, $NumOfDoubleBonds, | |
| 5038 $NumOfTripleBonds, $NumOfAromaticBonds) = $Atom-> | |
| 5039 GetNumOfBondTypesToHeavyAtoms($CountAromaticBonds); | |
| 5040 | |
| 5041 Get number of single, double, triple, and aromatic bonds from an I<Atom> to all other | |
| 5042 non-hydrogen atoms in a molecule. | |
| 5043 | |
| 5044 Value of I<CountAtomaticBonds> parameter controls whether number of aromatic | |
| 5045 bonds is returned; default is not to count aromatic bonds. During counting of | |
| 5046 aromatic bonds, the bond marked aromatic is not included in the count | |
| 5047 of other bond types. | |
| 5048 | |
| 5049 =item B<GetNumOfBondTypesToNonHydrogenAtoms> | |
| 5050 | |
| 5051 ($NumOfSingleBonds, $NumOfDoubleBonds, | |
| 5052 $NumOfTripleBonds, $NumOfAromaticBonds) = $Atom-> | |
| 5053 GetNumOfBondTypesToNonHydrogenAtoms($CountAromaticBonds); | |
| 5054 | |
| 5055 Get number of single, double, triple, and aromatic bonds from an I<Atom> to all other | |
| 5056 non-hydrogen atoms in a molecule. | |
| 5057 | |
| 5058 Value of I<CountAtomaticBonds> parameter controls whether number of aromatic | |
| 5059 bonds is returned; default is not to count aromatic bonds. During counting of | |
| 5060 aromatic bonds, the bond marked aromatic is not included in the count | |
| 5061 of other bond types. | |
| 5062 | |
| 5063 =item B<GetNumOfDoubleBondsToHeavyAtoms> | |
| 5064 | |
| 5065 $NumOfDoubleBonds = $Atom->GetNumOfDoubleBondsToHeavyAtoms(); | |
| 5066 | |
| 5067 Returns number of double bonds from an I<Atom> to other heavy atoms or non-hydrogen | |
| 5068 atoms in a molecule. | |
| 5069 | |
| 5070 =item B<GetNumOfDoubleBondsToNonHydrogenAtoms> | |
| 5071 | |
| 5072 $NumOfDoubleBonds =$Atom->GetNumOfDoubleBondsToNonHydrogenAtoms(); | |
| 5073 | |
| 5074 Returns number of double bonds from an I<Atom> to other heavy atoms or non-hydrogen | |
| 5075 atoms in a molecule. | |
| 5076 | |
| 5077 =item B<GetNumOfHeavyAtomNeighbors> | |
| 5078 | |
| 5079 $NumOfNeighbors = $Atom->GetNumOfHeavyAtomNeighbors(); | |
| 5080 | |
| 5081 Returns number heavy atom neighbors for an I<Atom> in a molecule. | |
| 5082 | |
| 5083 =item B<GetNumOfHydrogenAtomNeighbors> | |
| 5084 | |
| 5085 $NumOfNeighbors = $Atom->GetNumOfHydrogenAtomNeighbors(); | |
| 5086 | |
| 5087 Returns number hydrogens atom neighbors for an I<Atom> in a molecule. | |
| 5088 | |
| 5089 =item B<GetNumOfMissingHydrogens> | |
| 5090 | |
| 5091 $NumOfMissingHydrogens = $Atom->GetNumOfMissingHydrogens(); | |
| 5092 | |
| 5093 Returns number of implicit hydrogens for an I<Atom> in a molecule. This value either | |
| 5094 corresponds to explicitly set I<ImplicitHydrogens> atom property or calculated as the | |
| 5095 difference between the value of potential total valence and sum of bond orders to | |
| 5096 both hydrogen and non-hydrogen atom neighbors. | |
| 5097 | |
| 5098 =item B<GetNumOfExplicitHydrogens> | |
| 5099 | |
| 5100 $NumOfExplicitHydrogens = $Atom->GetNumOfExplicitHydrogens(); | |
| 5101 | |
| 5102 Returns number hydrogens atom neighbors for an I<Atom> in a molecule. | |
| 5103 | |
| 5104 =item B<GetNumOfHydrogens> | |
| 5105 | |
| 5106 $NumOfHydrogens = $Atom->GetNumOfHydrogens(); | |
| 5107 | |
| 5108 Returns total number of hydrogens for an I<Atom> in a molecule including both hydrogen atom | |
| 5109 neighbors and implicit hydrogens. | |
| 5110 | |
| 5111 =item B<GetNumOfImplicitHydrogens> | |
| 5112 | |
| 5113 $NumOfImplicitHydrogens = $Atom->GetNumOfImplicitHydrogens(); | |
| 5114 | |
| 5115 Returns number of implicit hydrogens for an I<Atom> in a molecule. This value either | |
| 5116 corresponds to explicitly set I<ImplicitHydrogens> atom property or calculated as the | |
| 5117 difference between the value of potential total valence and sum of bond orders to | |
| 5118 both hydrogen and non-hydrogen atom neighbors. | |
| 5119 | |
| 5120 =item B<GetNumOfNeighbors> | |
| 5121 | |
| 5122 $NumOfNeighbors = $Atom->GetNumOfNeighbors(); | |
| 5123 | |
| 5124 Returns number atom neighbors for an I<Atom> in a molecule. | |
| 5125 | |
| 5126 =item B<GetNumOfNonHydrogenAtomNeighbors> | |
| 5127 | |
| 5128 $NumNeighbors = $This->GetNumOfNonHydrogenAtomNeighbors(); | |
| 5129 | |
| 5130 Returns number non-hydrogens atom neighbors for an I<Atom> in a molecule. | |
| 5131 | |
| 5132 =item B<GetNumOfRings> | |
| 5133 | |
| 5134 $NumOfRings = $Atom->GetNumOfRings(); | |
| 5135 | |
| 5136 Returns number of rings containing I<Atom> in a molecule. | |
| 5137 | |
| 5138 =item B<GetNumOfRingsWithEvenSize> | |
| 5139 | |
| 5140 $NumOfRings = $Atom->GetNumOfRingsWithEvenSize(); | |
| 5141 | |
| 5142 Returns number of rings with even size containing I<Atom> in a molecule. | |
| 5143 | |
| 5144 =item B<GetNumOfRingsWithOddSize> | |
| 5145 | |
| 5146 $NumOfRings = $Atom->GetNumOfRingsWithOddSize(); | |
| 5147 | |
| 5148 Returns number of rings with odd size containing I<Atom> in a molecule. | |
| 5149 | |
| 5150 =item B<GetNumOfRingsWithSize> | |
| 5151 | |
| 5152 $NumOfRings = $Atom->GetNumOfRingsWithSize($RingSize); | |
| 5153 | |
| 5154 Returns number of rings with specific I<RingSize> containing I<Atom> in a molecule. | |
| 5155 | |
| 5156 =item B<GetNumOfRingsWithSizeGreaterThan> | |
| 5157 | |
| 5158 $NumOfRings = $Atom->GetNumOfRingsWithSizeGreaterThan($RingSize); | |
| 5159 | |
| 5160 Returns number of rings with size greater than specific I<RingSize> containing I<Atom> | |
| 5161 in a molecule. | |
| 5162 | |
| 5163 =item B<GetNumOfRingsWithSizeLessThan> | |
| 5164 | |
| 5165 $NumOfRings = $Atom->GetNumOfRingsWithSizeLessThan($RingSize); | |
| 5166 | |
| 5167 Returns number of rings with size less than specific I<RingSize> containing I<Atom> in a molecule. | |
| 5168 | |
| 5169 =item B<GetNumOfSigmaAndPiBondsToHeavyAtoms> | |
| 5170 | |
| 5171 ($NumOfSigmaBonds, $NumOfPiBonds) = $Atom-> | |
| 5172 GetNumOfSigmaAndPiBondsToHeavyAtoms(); | |
| 5173 | |
| 5174 Get number of sigma and pi bonds from an I<Atom> to all other non-hydrogen | |
| 5175 atoms in a molecule. | |
| 5176 | |
| 5177 Sigma and pi bonds are counted using the following methodology: a single bond | |
| 5178 correspond to one sigma bond; a double bond contributes one to sigma bond count | |
| 5179 and one to pi bond count; a triple bond contributes one to sigma bond count and | |
| 5180 two to pi bond count. | |
| 5181 | |
| 5182 | |
| 5183 =item B<GetNumOfSigmaAndPiBondsToNonHydrogenAtoms> | |
| 5184 | |
| 5185 ($NumOfSigmaBonds, $NumOfPiBonds) = $Atom-> | |
| 5186 GetNumOfSigmaAndPiBondsToNonHydrogenAtoms(); | |
| 5187 | |
| 5188 Get number of sigma and pi bonds from an I<Atom> to all other non-hydrogen | |
| 5189 atoms in a molecule. | |
| 5190 | |
| 5191 Sigma and pi bonds are counted using the following methodology: a single bond | |
| 5192 correspond to one sigma bond; a double bond contributes one to sigma bond count | |
| 5193 and one to pi bond count; a triple bond contributes one to sigma bond count and | |
| 5194 two to pi bond count. | |
| 5195 | |
| 5196 =item B<GetNumOfSingleBondsToNonHydrogenAtoms> | |
| 5197 | |
| 5198 $NumOfSingleBonds =$Atom->GetNumOfSingleBondsToNonHydrogenAtoms(); | |
| 5199 | |
| 5200 Returns number of single bonds from an I<Atom> to other heavy atoms or non-hydrogen | |
| 5201 atoms in a molecule. | |
| 5202 | |
| 5203 =item B<GetNumOfSingleBondsToHeavyAtoms> | |
| 5204 | |
| 5205 $NumOfSingleBonds = $Atom->GetNumOfSingleBondsToHeavyAtoms(); | |
| 5206 | |
| 5207 Returns number of single bonds from an I<Atom> to other heavy atoms or non-hydrogen | |
| 5208 atoms in a molecule. | |
| 5209 | |
| 5210 =item B<GetNumOfTripleBondsToNonHydrogenAtoms> | |
| 5211 | |
| 5212 $NumOfTripleBonds =$Atom->GetNumOfTripleBondsToNonHydrogenAtoms(); | |
| 5213 | |
| 5214 Returns number of triple bonds from an I<Atom> to other heavy atoms or non-hydrogen | |
| 5215 atoms in a molecule. | |
| 5216 | |
| 5217 =item B<GetNumOfTripleBondsToHeavyAtoms> | |
| 5218 | |
| 5219 $NumOfTripleBonds = $Atom->GetNumOfTripleBondsToHeavyAtoms(); | |
| 5220 | |
| 5221 Returns number of triple bonds from an I<Atom> to other heavy atoms or non-hydrogen | |
| 5222 atoms in a molecule. | |
| 5223 | |
| 5224 =item B<GetPeriodNumber> | |
| 5225 | |
| 5226 $PeriodNumber = $Atom->GetPeriodNumber(); | |
| 5227 | |
| 5228 Returns periodic table period number for an I<Atom> in a molecule with a valid atomic number . | |
| 5229 | |
| 5230 =item B<GetRings> | |
| 5231 | |
| 5232 @Rings = $Aotm->GetRings(); | |
| 5233 | |
| 5234 Returns an array of references to arrays containing ring atoms corressponding to all rings containing | |
| 5235 I<Atom> in a molecule. | |
| 5236 | |
| 5237 =item B<GetRingsWithEvenSize> | |
| 5238 | |
| 5239 @Rings = $Aotm->GetRingsWithEvenSize(); | |
| 5240 | |
| 5241 Returns an array of references to arrays containing ring atoms corressponding to all rings with even size | |
| 5242 containing I<Atom> in a molecule. | |
| 5243 | |
| 5244 =item B<GetRingsWithOddSize> | |
| 5245 | |
| 5246 @Rings = $Aotm->GetRingsWithOddSize(); | |
| 5247 | |
| 5248 Returns an array of references to arrays containing ring atoms corressponding to all rings with odd size | |
| 5249 containing I<Atom> in a molecule. | |
| 5250 | |
| 5251 =item B<GetRingsWithSize> | |
| 5252 | |
| 5253 @Rings = $Aotm->GetRingsWithSize($RingSize); | |
| 5254 | |
| 5255 Returns an array of references to arrays containing ring atoms corressponding to all rings with specific | |
| 5256 I<RingSize >containing I<Atom> in a molecule. | |
| 5257 | |
| 5258 =item B<GetRingsWithSizeGreaterThan> | |
| 5259 | |
| 5260 @Rings = $Aotm->GetRingsWithSizeGreaterThan($RingSize); | |
| 5261 | |
| 5262 Returns an array of references to arrays containing ring atoms corressponding to all rings with size | |
| 5263 greater than specific I<RingSize >containing I<Atom> in a molecule. | |
| 5264 | |
| 5265 =item B<GetRingsWithSizeLessThan> | |
| 5266 | |
| 5267 @Rings = $Aotm->GetRingsWithSizeLessThan($RingSize); | |
| 5268 | |
| 5269 Returns an array of references to arrays containing ring atoms corressponding to all rings with size | |
| 5270 less than specific I<RingSize >containing I<Atom> in a molecule. | |
| 5271 | |
| 5272 =item B<GetSizeOfLargestRing> | |
| 5273 | |
| 5274 $Size = $Atom->GetSizeOfLargestRing(); | |
| 5275 | |
| 5276 Returns size of the largest ring containing I<Atom> in a molecule. | |
| 5277 | |
| 5278 =item B<GetSizeOfSmallestRing> | |
| 5279 | |
| 5280 $Size = $Atom->GetSizeOfSmallestRing(); | |
| 5281 | |
| 5282 Returns size of the smallest ring containing I<Atom> in a molecule. | |
| 5283 | |
| 5284 =item B<GetSmallestRing> | |
| 5285 | |
| 5286 @RingAtoms = $Atom->GetSmallestRing(); | |
| 5287 | |
| 5288 Returns an array of ring I<Atom> objects corresponding to the largest ring containing I<Atom> | |
| 5289 in a molecule. | |
| 5290 | |
| 5291 =item B<GetSpinMultiplicity> | |
| 5292 | |
| 5293 $SpinMultiplicity = $Atom->GetSpinMultiplicity(); | |
| 5294 | |
| 5295 Returns spin multiplicity of an I<Atom> corresponding to one of these three | |
| 5296 values: explicitly set B<SpinMultiplicity> property value; calculated from | |
| 5297 B<FreeRadicalElectrons> property; value of 0. | |
| 5298 | |
| 5299 The B<SpinMultiplicity> is calculate from I<FreeRadicalElectrons> property as | |
| 5300 follows: | |
| 5301 | |
| 5302 FreeRadicalElectrons: 1; SpinMultiplicity: 2 | |
| 5303 FreeRadicalElectrons: 2; SpinMultiplicity: 1 | |
| 5304 FreeRadicalElectrons: other; SpinMultiplicity: 0 | |
| 5305 | |
| 5306 =item B<GetSumOfBondOrders> | |
| 5307 | |
| 5308 $SumBondOrders = $Atom->GetSumOfBondOrders(); | |
| 5309 | |
| 5310 Returns sum of bond orders corresponding to all atoms bonded to an I<Atom> in a molecule. | |
| 5311 | |
| 5312 =item B<GetSumOfBondOrdersToHeavyAtoms> | |
| 5313 | |
| 5314 $SumBondOrders = $Atom->GetSumOfBondOrdersToHeavyAtoms(); | |
| 5315 | |
| 5316 Returns sum of bond orders corresponding to all heavy atoms bonded to an I<Atom> in a molecule. | |
| 5317 | |
| 5318 =item B<GetSumOfBondOrdersToHydrogenAtoms> | |
| 5319 | |
| 5320 $SumBondOrders = $Atom->GetSumOfBondOrdersToHydrogenAtoms(); | |
| 5321 | |
| 5322 Returns sum of bond orders corresponding to all hydrogen atoms bonded to an I<Atom> in a molecule. | |
| 5323 | |
| 5324 =item B<GetSumOfBondOrdersToNonHydrogenAtoms> | |
| 5325 | |
| 5326 $SumBondOrders = $Atom->GetSumOfBondOrdersToNonHydrogenAtoms(); | |
| 5327 | |
| 5328 Returns sum of bond orders corresponding to all non-hydrogen atoms bonded to an I<Atom> | |
| 5329 in a molecule. | |
| 5330 | |
| 5331 =item B<GetValence> | |
| 5332 | |
| 5333 $Valence = $Atom->GetValence(); | |
| 5334 | |
| 5335 Returns valence of an I<Atom> in a molecule. Valence corresponds to number of electrons used | |
| 5336 by an atom in bonding: | |
| 5337 | |
| 5338 Valence = ValenceElectrons - ValenceFreeElectrons = BondingElectrons | |
| 5339 | |
| 5340 Single, double and triple bonds with bond orders of 1, 2, and 3 correspond to | |
| 5341 contribution of 1, 2, and 3 bonding electrons. So: | |
| 5342 | |
| 5343 Valence = SumOfBondOrders + NumOfMissingHydrogens + FormalCharge | |
| 5344 | |
| 5345 where positive and negative values of FormalCharge increase and decrease the number of bonding | |
| 5346 electrons, respectively. | |
| 5347 | |
| 5348 The current release of MayaChemTools supports the following three valence models, which | |
| 5349 are used during calculation of implicit hydrogens: MDLValenceModel, DaylightValenceModel, | |
| 5350 InternalValenceModel or MayaChemToolsValenceModel. | |
| 5351 | |
| 5352 Notes: | |
| 5353 | |
| 5354 . Missing hydrogens are included in the valence. | |
| 5355 . For neutral molecules, valence and sum of bond orders are equal. | |
| 5356 . For molecules containing only single bonds, SumOfBondOrders and | |
| 5357 NumOfBonds are equal. | |
| 5358 . Free radical electrons lead to the decrease in valence. For atoms with | |
| 5359 explicit assignment of SpinMultiplicity property values corresponding to | |
| 5360 Singlet (two unparied electrons corresponding to one spin state), Doublet | |
| 5361 (free radical; an unpaired electron corresponding to two spin states), | |
| 5362 and Triplet (two unparied electrons corresponding to three spin states; | |
| 5363 divalent carbon atoms (carbenes)), FreeRadicalElectrons are calculated as follows: | |
| 5364 | |
| 5365 SpinMultiplicity: Doublet(2); FreeRadicalElectrons: 1 (one valence | |
| 5366 electron not available for bonding) | |
| 5367 SpinMultiplicity: Singlet(1)/Triplet(3); FreeRadicalElectrons: 2 (two | |
| 5368 valence electrons not available for bonding) | |
| 5369 | |
| 5370 =item B<GetValenceElectrons> | |
| 5371 | |
| 5372 $ValenceElectrons = $Atom->GetValenceElectrons(); | |
| 5373 | |
| 5374 Returns valence electrons for an B<Atom> which corresponds to either explicity set I<ValenceElectrons> | |
| 5375 atom property or valence electrons for the corresponding element in the periodic table available by | |
| 5376 B<PeriodicTable> module. | |
| 5377 | |
| 5378 =item B<GetValenceFreeElectrons> | |
| 5379 | |
| 5380 $ValenceFreeElectrons = $Atom->GetValenceFreeElectrons(); | |
| 5381 $ValenceFreeElectrons = $Atom->GetValenceFreeElectrons( | |
| 5382 $ExcludeFreeRadicalElectrons); | |
| 5383 | |
| 5384 Returns valence frees electrons for an B<Atom> in a molecule. It corresponds to: | |
| 5385 | |
| 5386 ValenceElectrons - Valence | |
| 5387 or | |
| 5388 ValenceElectrons - NumOfMissingHydrogens - SumOfBondOrders - FormalCharge | |
| 5389 | |
| 5390 Free radical electrons are included in the valence free electrons count by default. | |
| 5391 | |
| 5392 Examples: | |
| 5393 | |
| 5394 NH3: ValenceFreeElectrons = 5 - 3 = 5 - 3 - 0 - 0 = 2 | |
| 5395 NH2: ValenceFreeElectrons = 5 - 3 = 5 - 2 - 1 - 0 = 2 | |
| 5396 NH4+; ValenceFreeElectrons = 5 - 5 = 5 - 4 - 0 - 1 = 0 | |
| 5397 NH3+; ValenceFreeElectrons = 5 - 5 = 5 - 3 - 1 - 1 = 0 | |
| 5398 C(=O)O- : ValenceFreeElectrons on O- = 6 - 0 = 6 - 1 - 0 - (-1) = 6 | |
| 5399 C(=O)O- : ValenceFreeElectrons on =O = 6 - 2 = 6 - 2 - 0 - 0 = 4 | |
| 5400 | |
| 5401 =item B<GetX> | |
| 5402 | |
| 5403 $X = $Atom->GetX(); | |
| 5404 | |
| 5405 Returns value of X-coordinate for an I<Atom>. | |
| 5406 | |
| 5407 =item B<GetXYZ> | |
| 5408 | |
| 5409 @XYZ = $Atom->GetXYZ(); | |
| 5410 $XYZRef = $Atom->GetXYZ(); | |
| 5411 | |
| 5412 Returns an array or a reference to an array containing values for I<Atom> coordinates. | |
| 5413 | |
| 5414 =item B<GetXYZVector> | |
| 5415 | |
| 5416 $XYZVector = $Atom->GetXYZVector(); | |
| 5417 | |
| 5418 Returns a I<Vector> object containing values for I<Atom> coordinates | |
| 5419 | |
| 5420 =item B<GetY> | |
| 5421 | |
| 5422 $Y = $Atom->GetY(); | |
| 5423 | |
| 5424 Returns value of Y-coordinate for an I<Atom>. | |
| 5425 | |
| 5426 =item B<GetZ> | |
| 5427 | |
| 5428 $Z = $Atom->GetZ(); | |
| 5429 | |
| 5430 Returns value of Z-coordinate for an I<Atom>. | |
| 5431 | |
| 5432 =item B<IsAmideCarbon> | |
| 5433 | |
| 5434 $Status = $Atom->IsAmideCarbon(); | |
| 5435 | |
| 5436 Returns 1 or 0 based on whether it's amide carbon I<Atom>. | |
| 5437 | |
| 5438 An amide group is defineds as: | |
| 5439 | |
| 5440 R-C(=O)-N(-R')-R'' | |
| 5441 | |
| 5442 where: | |
| 5443 | |
| 5444 o R = Hydrogen or groups of atoms attached through carbon | |
| 5445 o R' = Hydrogens or groups of atoms attached through carbon or | |
| 5446 hetro atoms | |
| 5447 o R'' = Hydrogens or groups of atoms attached through carbon or | |
| 5448 hetro atoms | |
| 5449 | |
| 5450 =item B<IsAmideNitrogen> | |
| 5451 | |
| 5452 $Status = $Atom->IsAmideNitrogen(); | |
| 5453 | |
| 5454 Returns 1 or 0 based on whether it's amide nitrogen I<Atom>. | |
| 5455 | |
| 5456 =item B<IsAromatic> | |
| 5457 | |
| 5458 $Status = $Atom->IsAromatic(); | |
| 5459 | |
| 5460 Returns 1 or 0 based on whether it's an aromatic I<Atom>. | |
| 5461 | |
| 5462 =item B<IsArsenic> | |
| 5463 | |
| 5464 $Status = $Atom->IsArsenic(); | |
| 5465 | |
| 5466 Returns 1 or 0 based on whether it's an arsenic I<Atom>. | |
| 5467 | |
| 5468 =item B<IsBondedToAtom> | |
| 5469 | |
| 5470 $Status = $Atom->IsBondedToAtom($OtherAtom); | |
| 5471 | |
| 5472 Returns 1 or 0 based on whether I<Atom> is bonded to I<OtherAtom>. | |
| 5473 | |
| 5474 =item B<IsBromine> | |
| 5475 | |
| 5476 $Status = $Atom->IsBromine(); | |
| 5477 | |
| 5478 Returns 1 or 0 based on whether it's a bromine I<Atom>. | |
| 5479 | |
| 5480 =item B<IsCarbon> | |
| 5481 | |
| 5482 $Status = $Atom->IsCarbon(); | |
| 5483 | |
| 5484 Returns 1 or 0 based on whether it's a carbon I<Atom>. | |
| 5485 | |
| 5486 =item B<IsCarboxylCarbon> | |
| 5487 | |
| 5488 $Status = $Atom->IsCarboxylCarbon(); | |
| 5489 | |
| 5490 Returns 1 or 0 based on whether it's a carboxyl carbon atom in carboxyl group: | |
| 5491 R-C(=O)-OH. | |
| 5492 | |
| 5493 =item B<IsCarboxylOxygen> | |
| 5494 | |
| 5495 $Status = $Atom->IsCarboxylOxygen(); | |
| 5496 | |
| 5497 Returns 1 or 0 based on whether it's a carboxyl oxygen atom in carboxyl group: | |
| 5498 R-C(=O)-OH. | |
| 5499 | |
| 5500 =item B<IsCarboxylateCarbon> | |
| 5501 | |
| 5502 $Status = $Atom->IsCarboxylateCarbon(); | |
| 5503 | |
| 5504 Returns 1 or 0 based on whether it's a carboxylate carbon atom in carboxyl group: | |
| 5505 R-C(=O)-O-. | |
| 5506 | |
| 5507 =item B<IsCarboxylateOxygen> | |
| 5508 | |
| 5509 $Status = $Atom->IsCarboxylateOxygen(); | |
| 5510 | |
| 5511 Returns 1 or 0 based on whether it's a carboxylate oxygen atom in carboxyl group: | |
| 5512 R-C(=O)-O-. | |
| 5513 | |
| 5514 =item B<IsChlorine> | |
| 5515 | |
| 5516 $Status = $Atom->IsChlorine(); | |
| 5517 | |
| 5518 Returns 1 or 0 based on whether it's a chlorine I<Atom>. | |
| 5519 | |
| 5520 =item B<IsFluorine> | |
| 5521 | |
| 5522 $Status = $Atom->IsFluorine(); | |
| 5523 | |
| 5524 Returns 1 or 0 based on whether it's a fluorine I<Atom>. | |
| 5525 | |
| 5526 =item B<IsFunctionalClassType> | |
| 5527 | |
| 5528 $Status =$Atom->IsFunctionalClassType($Type); | |
| 5529 | |
| 5530 Returns 1 or 0 based on whether it's a specified functional class I<Type>. | |
| 5531 | |
| 5532 The current release of MayaChemTools supports following abbreviations and descriptive | |
| 5533 names for I<FunctionalClassType>: | |
| 5534 | |
| 5535 HBD: HydrogenBondDonor | |
| 5536 HBA: HydrogenBondAcceptor | |
| 5537 PI : PositivelyIonizable | |
| 5538 NI : NegativelyIonizable | |
| 5539 Ar : Aromatic | |
| 5540 Hal : Halogen | |
| 5541 H : Hydrophobic | |
| 5542 RA : RingAtom | |
| 5543 CA : ChainAtom | |
| 5544 | |
| 5545 The following definitions are used to determine functional class types: [ Ref 60-61, Ref 65-66 ]: | |
| 5546 | |
| 5547 HydrogenBondDonor: NH, NH2, OH | |
| 5548 HydrogenBondAcceptor: N[!H], O | |
| 5549 PositivelyIonizable: +, NH2 | |
| 5550 NegativelyIonizable: -, C(=O)OH, S(=O)OH, P(=O)OH | |
| 5551 | |
| 5552 =item B<IsGuadiniumCarbon> | |
| 5553 | |
| 5554 $Status = $Atom->IsGuadiniumCarbon(); | |
| 5555 | |
| 5556 Returns 1 or 0 based on whether it's a guadinium carbon in guadinium group by | |
| 5557 checking its neighbors for a nitrogen in guadinium group. | |
| 5558 | |
| 5559 =item B<IsGuadiniumNitrogen> | |
| 5560 | |
| 5561 $Status = $Atom->IsGuadiniumNitrogen(); | |
| 5562 | |
| 5563 Returns 1 or 0 based on whether it's a guadinium nitrogen in guadinium group. | |
| 5564 | |
| 5565 A guadinium group is defined as: | |
| 5566 | |
| 5567 R2N-C(=NR)-(NR2) or R2N-C(=NR2+)-(NR2) | |
| 5568 | |
| 5569 where: | |
| 5570 | |
| 5571 o R = Hydrogens or group of atoms attached through carbon | |
| 5572 o Only one of the three nitrogens has a double bond to carbon | |
| 5573 and has optional formal charge allowing it to be neutral or charged state | |
| 5574 | |
| 5575 =item B<IsHBondAcceptor> | |
| 5576 | |
| 5577 $Status =$Atom->IsHBondAcceptor(); | |
| 5578 $Status =$Atom->IsHBondAcceptor($HydrogenBondsType); | |
| 5579 | |
| 5580 Returns 1 or 0 based on whether it's a hydrogen bond acceptor I<Atom>. | |
| 5581 | |
| 5582 =item B<IsHBondDonor> | |
| 5583 | |
| 5584 $Status =$Atom->IsHBondDonor(); | |
| 5585 $Status =$Atom->IsHBondDonor($HydrogenBondsType); | |
| 5586 | |
| 5587 Returns 1 or 0 based on whether it's a hydrogen bond donor I<Atom>. | |
| 5588 | |
| 5589 =item B<IsHydrogenBondAcceptor> | |
| 5590 | |
| 5591 $Status =$Atom->IsHydrogenBondAcceptor(); | |
| 5592 $Status =$Atom->IsHydrogenBondAcceptor($HydrogenBondsType); | |
| 5593 | |
| 5594 Returns 1 or 0 based on whether it's a hydrogen bond acceptor I<Atom>. | |
| 5595 | |
| 5596 =item B<IsHydrogenBondDonor> | |
| 5597 | |
| 5598 $Status =$Atom->IsHydrogenBondDonor(); | |
| 5599 $Status =$Atom->IsHydrogenBondDonor($HydrogenBondsType); | |
| 5600 | |
| 5601 Returns 1 or 0 based on whether it's a hydrogen bond donor I<Atom>. | |
| 5602 | |
| 5603 The current release of MayaChemTools supports identification of two types of hydrogen bond | |
| 5604 donor and acceptor atoms with these names: | |
| 5605 | |
| 5606 HBondsType1 or HydrogenBondsType1 | |
| 5607 HBondsType2 or HydrogenBondsType2 | |
| 5608 | |
| 5609 The names of these hydrogen bond types are rather arbitrary. However, their definitions have | |
| 5610 specific meaning and are as follows: | |
| 5611 | |
| 5612 HydrogenBondsType1 [ Ref 60-61, Ref 65-66 ]: | |
| 5613 | |
| 5614 Donor: NH, NH2, OH - Any N and O with available H | |
| 5615 Acceptor: N[!H], O - Any N without available H and any O | |
| 5616 | |
| 5617 HydrogenBondsType2 [ Ref 91 ]: | |
| 5618 | |
| 5619 Donor: NH, NH2, OH - N and O with available H | |
| 5620 Acceptor: N, O - And N and O | |
| 5621 | |
| 5622 By default, I<HydrogenBondsType1> is used to calculate number hydrogen bond donor | |
| 5623 and acceptor atoms. I<HydrogenBondsType2> corresponds to B<RuleOf5> definition | |
| 5624 of hydrogen bond donors and acceptors. | |
| 5625 | |
| 5626 =item B<IsHalogen> | |
| 5627 | |
| 5628 $Status =$Atom->IsHalogen(); | |
| 5629 | |
| 5630 Returns 1 or 0 based on whether it's a halogen I<Atom>. | |
| 5631 | |
| 5632 =item B<IsHeteroAtom> | |
| 5633 | |
| 5634 $Status = $Atom->IsHeteroAtom(); | |
| 5635 | |
| 5636 Returns 0 or 1 based on whether it's a hetro I<Atom>. Following atoms are considered hetro atoms: | |
| 5637 B<N, O, F, P, S, Cl, Br, I>. | |
| 5638 | |
| 5639 =item B<IsHydrogen> | |
| 5640 | |
| 5641 $Status = $Atom->IsHydrogen(); | |
| 5642 | |
| 5643 Returns 1 or 0 based on whether it's a hydrogen I<Atom>. | |
| 5644 | |
| 5645 =item B<IsHydrophobic> | |
| 5646 | |
| 5647 $Status =$Atom->IsHydrophobic(); | |
| 5648 | |
| 5649 Returns 1 or 0 based on whether it's a hydrophobic I<Atom>. | |
| 5650 | |
| 5651 =item B<IsInRing> | |
| 5652 | |
| 5653 $Status = $Atom->IsInRing(); | |
| 5654 | |
| 5655 Returns 1 or 0 based on whether I<Atom> is present in a ring. | |
| 5656 | |
| 5657 =item B<IsInRingOfSize> | |
| 5658 | |
| 5659 $Status = $Atom->IsInRingOfSize($Size); | |
| 5660 | |
| 5661 Returns 1 or 0 based on whether I<Atom> is present in a ring of specific I<Size>. | |
| 5662 | |
| 5663 =item B<IsIodine> | |
| 5664 | |
| 5665 $Status = $Atom->IsIodine(); | |
| 5666 | |
| 5667 Returns 1 or 0 based on whether it's an iodine I<Atom>. | |
| 5668 | |
| 5669 =item B<IsIsotope> | |
| 5670 | |
| 5671 $Status =$Atom->IsIsotope(); | |
| 5672 | |
| 5673 Returns 1 or 0 based on whether it's an isotope I<Atom>. | |
| 5674 | |
| 5675 =item B<IsLipophilic> | |
| 5676 | |
| 5677 $Status =$Atom->IsLipophilic(); | |
| 5678 | |
| 5679 Returns 1 or 0 based on whether it's a lipophilic I<Atom>. | |
| 5680 | |
| 5681 =item B<IsMetallic> | |
| 5682 | |
| 5683 $Status = $Atom->IsMetallic(); | |
| 5684 | |
| 5685 Returns 1 or 0 based on whether it's a metallic I<Atom>. | |
| 5686 | |
| 5687 =item B<IsNegativelyIonizable> | |
| 5688 | |
| 5689 $Status =$Atom->IsNegativelyIonizable(); | |
| 5690 | |
| 5691 Returns 1 or 0 based on whether it's a negatively ionizable atom I<Atom>. | |
| 5692 | |
| 5693 =item B<IsNitrogen> | |
| 5694 | |
| 5695 $Status = $Atom->IsNitrogen(); | |
| 5696 | |
| 5697 Returns 1 or 0 based on whether it's a nitrogen I<Atom>. | |
| 5698 | |
| 5699 =item B<IsNonCarbonOrHydrogen> | |
| 5700 | |
| 5701 $Status =$Atom->IsNonCarbonOrHydrogen(); | |
| 5702 | |
| 5703 Returns 1 or 0 based on whether it's not a carbon or hydrogen I<Atom>. | |
| 5704 | |
| 5705 =item B<IsNotInRing> | |
| 5706 | |
| 5707 $Status = $Atom->IsNotInRing(); | |
| 5708 | |
| 5709 Returns 1 or 0 based on whether I<Atom> is not present in a ring. | |
| 5710 | |
| 5711 =item B<IsOnlyInOneRing> | |
| 5712 | |
| 5713 $Status = $Atom->IsOnlyInOneRing(); | |
| 5714 | |
| 5715 Returns 1 or 0 based on whether I<Atom> is only present in one ring. | |
| 5716 | |
| 5717 =item B<IsOxygen> | |
| 5718 | |
| 5719 $Status = $Atom->IsOxygen(); | |
| 5720 | |
| 5721 Returns 0 or 1 based on whether it's an oxygen I<Atom>. | |
| 5722 | |
| 5723 =item B<IsPhosphorus> | |
| 5724 | |
| 5725 $Status = $Atom->IsPhosphorus(); | |
| 5726 | |
| 5727 Returns 0 or 1 based on whether it's a phosphorus I<Atom>. | |
| 5728 | |
| 5729 =item B<IsPhosphateOxygen> | |
| 5730 | |
| 5731 $Status = $Atom->IsPhosphateOxygen(); | |
| 5732 | |
| 5733 Returns 1 or 0 based on whether it's a phosphate oxygen in phosphate group. | |
| 5734 | |
| 5735 A phosphate group is defined as: | |
| 5736 | |
| 5737 AO-(O=)P(-OA)-OA | |
| 5738 | |
| 5739 Where: | |
| 5740 | |
| 5741 A - Any group of atoms including hydrogens | |
| 5742 | |
| 5743 =item B<IsPhosphatePhosphorus> | |
| 5744 | |
| 5745 $Status = $Atom->IsPhosphatePhosphorus(); | |
| 5746 | |
| 5747 Returns 1 or 0 based on whether it's a phosphate phosphorus in phosphate group. | |
| 5748 | |
| 5749 =item B<IsPolarAtom> | |
| 5750 | |
| 5751 $Status = $Atom->IsPolarAtom(); | |
| 5752 | |
| 5753 Returns 0 or 1 based on whether it's a polar I<Atom>. Following atoms are considered polar atoms: | |
| 5754 B<N, O, P, S>. | |
| 5755 | |
| 5756 =item B<IsPolarHydrogen> | |
| 5757 | |
| 5758 $Status = $Atom->IsPolarHydrogen(); | |
| 5759 | |
| 5760 Returns 0 or 1 based on whether it's a hydrogen I<Atom> bonded to a polar atom. | |
| 5761 | |
| 5762 =item B<IsPositivelyIonizable> | |
| 5763 | |
| 5764 $Status =$Atom->IsPositivelyIonizable(); | |
| 5765 | |
| 5766 Returns 1 or 0 based on whether it's a positively ionizable I<Atom>. | |
| 5767 | |
| 5768 =item B<IsSaturated> | |
| 5769 | |
| 5770 $Status = $Atom->IsSaturated(); | |
| 5771 | |
| 5772 Returns 1 or 0 based on whether it's a saturated I<Atom>. An atom attached | |
| 5773 to other atoms with only single bonds is considered a saturated atom. | |
| 5774 | |
| 5775 =item B<IsSelenium> | |
| 5776 | |
| 5777 $Status = $Atom->IsSelenium(); | |
| 5778 | |
| 5779 Returns 0 or 1 based on whether it's a selenium I<Atom>. | |
| 5780 | |
| 5781 =item B<IsStereoCenter> | |
| 5782 | |
| 5783 $Status = $Atom->IsStereoCenter(); | |
| 5784 | |
| 5785 Returns 0 or 1 based on whether it's marked as a stero center I<Atom> by explicit setting | |
| 5786 of I<StereoCenter> atom propert to value of I<1>. | |
| 5787 | |
| 5788 =item B<IsSilicon> | |
| 5789 | |
| 5790 $Status = $Atom->IsSilicon(); | |
| 5791 | |
| 5792 Returns 0 or 1 based on whether it's a silicon I<Atom>. | |
| 5793 | |
| 5794 =item B<IsSulfur> | |
| 5795 | |
| 5796 $Status = $Atom->IsSulfur(); | |
| 5797 | |
| 5798 Returns 0 or 1 based on whether it's a sulfur I<Atom>. | |
| 5799 | |
| 5800 =item B<IsSulphur> | |
| 5801 | |
| 5802 $Status = $Atom->IsSulphur(); | |
| 5803 | |
| 5804 Returns 0 or 1 based on whether it's a sulfur I<Atom>. | |
| 5805 | |
| 5806 =item B<IsTellurium> | |
| 5807 | |
| 5808 $Status = $Atom->IsTellurium(); | |
| 5809 | |
| 5810 Returns 0 or 1 based on whether it's a tellurium I<Atom>. | |
| 5811 | |
| 5812 =item B<IsTerminal> | |
| 5813 | |
| 5814 $Status = $Atom->IsTerminal(); | |
| 5815 | |
| 5816 Returns 0 or 1 based on whether it's a terminal I<Atom> attached to no | |
| 5817 more than one non-hydrogen atom. | |
| 5818 | |
| 5819 =item B<IsUnsaturated> | |
| 5820 | |
| 5821 $Status = $Atom->IsUnsaturated(); | |
| 5822 | |
| 5823 Returns 1 or 0 based on whether it's as unsaturated I<Atom>. An atom attached | |
| 5824 to other atoms with at least one non-single bond is considered an unsaturated atom. | |
| 5825 | |
| 5826 =item B<IsTopologicalPharmacophoreType> | |
| 5827 | |
| 5828 $Status =$Atom->IsTopologicalPharmacophoreType(); | |
| 5829 | |
| 5830 Returns 1 or 0 based on whether it's any of the supportyed topological pharmacophore | |
| 5831 I<Atom> type. See I<IsFunctionalClassType> for a list of supported types. | |
| 5832 | |
| 5833 =item B<SetAtomSymbol> | |
| 5834 | |
| 5835 $Atom->SetAtomSymbol($AtomicSymbol); | |
| 5836 | |
| 5837 Sets atom symbol for I<Atom> and returns I<Atom> object. The appropriate atomic number is also | |
| 5838 set automatically. | |
| 5839 | |
| 5840 =item B<SetAtomicNumber> | |
| 5841 | |
| 5842 $Atom->SetAtomicNumber($AtomicNumber); | |
| 5843 | |
| 5844 Sets atomic number for I<Atom> and returns I<Atom> object. The appropriate atom symbol is also | |
| 5845 set automatically. | |
| 5846 | |
| 5847 =item B<SetMassNumber> | |
| 5848 | |
| 5849 $Atom->SetMassNumber($MassNumber); | |
| 5850 | |
| 5851 Sets mass number for I<Atom> and returns I<Atom> object. | |
| 5852 | |
| 5853 =item B<SetStereoCenter> | |
| 5854 | |
| 5855 $Atom->SetStereoCenter($StereoCenter); | |
| 5856 | |
| 5857 Sets stereo center for I<Atom> and returns I<Atom> object. | |
| 5858 | |
| 5859 =item B<SetStereochemistry> | |
| 5860 | |
| 5861 $Atom->SetStereochemistry($Stereochemistry); | |
| 5862 | |
| 5863 Sets stereo chemistry for I<Atom> and returns I<Atom> object. | |
| 5864 | |
| 5865 =item B<SetX> | |
| 5866 | |
| 5867 $Atom->SetX($Value); | |
| 5868 | |
| 5869 Sets X-coordinate value for I<Atom> and returns I<Atom> object. | |
| 5870 | |
| 5871 =item B<SetXYZ> | |
| 5872 | |
| 5873 $Atom->SetXYZ(@XYZValues); | |
| 5874 $Atom->SetXYZ($XYZValuesRef); | |
| 5875 $Atom->SetXYZ($XYZVector); | |
| 5876 | |
| 5877 Sets I<Atom> coordinates using an array, reference to an array or a I<Vector> object and | |
| 5878 returns I<Atom> object. | |
| 5879 | |
| 5880 =item B<SetY> | |
| 5881 | |
| 5882 $Atom->SetY($Value); | |
| 5883 | |
| 5884 Sets Y-coordinate value for I<Atom> and returns I<Atom> object. | |
| 5885 | |
| 5886 =item B<SetZ> | |
| 5887 | |
| 5888 $Atom->SetZ($Value); | |
| 5889 | |
| 5890 Sets Z-coordinate value for I<Atom> and returns I<Atom> object. | |
| 5891 | |
| 5892 =item B<StringifyAtom> | |
| 5893 | |
| 5894 $AtomString = $Atom->StringifyAtom(); | |
| 5895 | |
| 5896 Returns a string containing information about I<Atom> object. | |
| 5897 | |
| 5898 =back | |
| 5899 | |
| 5900 =head1 AUTHOR | |
| 5901 | |
| 5902 Manish Sud <msud@san.rr.com> | |
| 5903 | |
| 5904 =head1 SEE ALSO | |
| 5905 | |
| 5906 Bond.pm, Molecule.pm, MoleculeFileIO.pm | |
| 5907 | |
| 5908 =head1 COPYRIGHT | |
| 5909 | |
| 5910 Copyright (C) 2015 Manish Sud. All rights reserved. | |
| 5911 | |
| 5912 This file is part of MayaChemTools. | |
| 5913 | |
| 5914 MayaChemTools is free software; you can redistribute it and/or modify it under | |
| 5915 the terms of the GNU Lesser General Public License as published by the Free | |
| 5916 Software Foundation; either version 3 of the License, or (at your option) | |
| 5917 any later version. | |
| 5918 | |
| 5919 =cut |
