1 package AtomicDescriptors::AtomicDescriptors; 2 # 3 # $RCSfile: AtomicDescriptors.pm,v $ 4 # $Date: 2015/02/28 20:47:48 $ 5 # $Revision: 1.17 $ 6 # 7 # Author: Manish Sud <msud@san.rr.com> 8 # 9 # Copyright (C) 2015 Manish Sud. All rights reserved. 10 # 11 # This file is part of MayaChemTools. 12 # 13 # MayaChemTools is free software; you can redistribute it and/or modify it under 14 # the terms of the GNU Lesser General Public License as published by the Free 15 # Software Foundation; either version 3 of the License, or (at your option) any 16 # later version. 17 # 18 # MayaChemTools is distributed in the hope that it will be useful, but without 19 # any warranty; without even the implied warranty of merchantability of fitness 20 # for a particular purpose. See the GNU Lesser General Public License for more 21 # details. 22 # 23 # You should have received a copy of the GNU Lesser General Public License 24 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or 25 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330, 26 # Boston, MA, 02111-1307, USA. 27 # 28 29 use strict; 30 use Carp; 31 use Exporter; 32 use Scalar::Util (); 33 use ObjectProperty; 34 use TextUtil (); 35 36 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); 37 38 @ISA = qw(ObjectProperty Exporter); 39 @EXPORT = qw(); 40 @EXPORT_OK = qw(); 41 42 %EXPORT_TAGS = (all => [@EXPORT, @EXPORT_OK]); 43 44 # Setup class variables... 45 my($ClassName); 46 _InitializeClass(); 47 48 # Class constructor... 49 sub new { 50 my($Class, %PropertyNamesAndValues) = @_; 51 52 # Initialize object... 53 my $This = {}; 54 bless $This, ref($Class) || $Class; 55 $This->_InitializeAtomicDescriptors(); 56 57 $This->_InitializeAtomicDescriptorsProperties(%PropertyNamesAndValues); 58 59 return $This; 60 } 61 62 # Initialize object data... 63 # 64 sub _InitializeAtomicDescriptors { 65 my($This) = @_; 66 67 # Molecule object... 68 $This->{Molecule} = ''; 69 70 # Type of atomic descriptors... 71 $This->{Type} = ''; 72 73 # By default, atomic decriptor values are also calculated for hydrogens... 74 $This->{IgnoreHydrogens} = 0; 75 76 # Calculated atomic descriptor values hash. Instead of assigning the calculated values to Atom 77 # objects, these values are stored in the current object in a hash with atom ID and atomic descriptor 78 # values as key/value pairs. 79 # 80 # Unlike molecular descriptors, no descriptor names are assigned to individual atomic descriptor 81 # values. 82 # 83 %{$This->{DescriptorValues}} = (); 84 } 85 86 # Initialize class ... 87 sub _InitializeClass { 88 #Class name... 89 $ClassName = __PACKAGE__; 90 } 91 92 # Initialize object properties.... 93 sub _InitializeAtomicDescriptorsProperties { 94 my($This, %PropertiesNamesAndValues) = @_; 95 96 my($Name, $Value, $MethodName); 97 while (($Name, $Value) = each %PropertiesNamesAndValues) { 98 $MethodName = "Set${Name}"; 99 $This->$MethodName($Value); 100 } 101 102 return $This; 103 } 104 105 # Initialize descriptor values for all atoms in a molecule... 106 # 107 sub _InitializeDescriptorValues { 108 my($This) = @_; 109 110 if (!$This->{Molecule}) { 111 return $This; 112 } 113 114 # Assign 'None' to all atomic descriptor values... 115 # 116 my($Atom, $AtomID); 117 118 ATOM: for $Atom ($This->{Molecule}->GetAtoms()) { 119 $AtomID = $Atom->GetID(); 120 $This->{DescriptorValues}{$AtomID} = 'None'; 121 } 122 123 return $This; 124 } 125 126 # Set molecule object and make sure it's not already set... 127 # 128 sub SetMolecule { 129 my($This, $Molecule) = @_; 130 131 if ($This->{Molecule}) { 132 croak "Error: ${ClassName}->SetMolecule: Can't change molecule object: It's already set..."; 133 } 134 $This->{Molecule} = $Molecule; 135 136 # Weaken the reference to disable increment of reference count... 137 Scalar::Util::weaken($This->{Molecule}); 138 139 return $This; 140 } 141 142 # Set type and make sure it's not already set... 143 # 144 sub SetType { 145 my($This, $Type) = @_; 146 147 if ($This->{Type}) { 148 croak "Error: ${ClassName}->SetType: Can't change AtomicDescriptors type: It's already set..."; 149 } 150 $This->{Type} = $Type; 151 152 return $This; 153 } 154 155 # Set specific atomic descriptor value... 156 # 157 sub SetDescriptorValue { 158 my($This, $Atom, $AtomicDescriptor) = @_; 159 my($AtomID); 160 161 $AtomID = $Atom->GetID(); 162 $This->{DescriptorValues}{$AtomID} = $AtomicDescriptor; 163 164 return $This; 165 } 166 167 # Get specific atomic descriptor value... 168 # 169 sub GetDescriptorValue { 170 my($This, $Atom) = @_; 171 my($AtomID); 172 173 $AtomID = $Atom->GetID(); 174 175 return exists $This->{DescriptorValues}{$AtomID} ? $This->{DescriptorValues}{$AtomID} : 'None'; 176 } 177 178 # Get calculated atomic descriptor values as a hash with atom ID and atomic descriptor 179 # values as key/value pairs... 180 # 181 sub GetDescriptorValues { 182 my($This) = @_; 183 184 return %{$This->{DescriptorValues}}; 185 } 186 187 # Are all atomic descriptor values successfully calculated? 188 # 189 # Notes: 190 # . Dynamic checking of calculated descriptor values for atoms eliminates the need 191 # to check and synchronize valid descriptor values during SetDescriptorValue. 192 # 193 sub IsDescriptorsGenerationSuccessful { 194 my($This) = @_; 195 my($Atom, $DescriptorValue, @Atoms); 196 197 ATOM: for $Atom ($This->{Molecule}->GetAtoms()) { 198 if ($This->{IgnoreHydrogens} && $Atom->IsHydrogen()) { 199 next ATOM; 200 } 201 $DescriptorValue = $This->GetDescriptorValue($Atom); 202 if ($DescriptorValue =~ /^None$/i) { 203 return 0; 204 } 205 } 206 207 return 1; 208 } 209