Mercurial > repos > deepakjadmin > mayatool3_test3
comparison mayachemtools/lib/Atom.pm @ 0:73ae111cf86f draft
Uploaded
author | deepakjadmin |
---|---|
date | Wed, 20 Jan 2016 11:55:01 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:73ae111cf86f |
---|---|
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 |