1 package MolecularDescriptors::MolecularDescriptors; 2 # 3 # $RCSfile: MolecularDescriptors.pm,v $ 4 # $Date: 2015/02/28 20:49:20 $ 5 # $Revision: 1.14 $ 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, %NamesAndValues) = @_; 51 52 # Initialize object... 53 my $This = {}; 54 bless $This, ref($Class) || $Class; 55 $This->_InitializeMolecularDescriptors(); 56 57 $This->_InitializeMolecularDescriptorsProperties(%NamesAndValues); 58 59 return $This; 60 } 61 62 # Initialize object data... 63 # 64 sub _InitializeMolecularDescriptors { 65 my($This) = @_; 66 67 # Molecule object... 68 $This->{Molecule} = ''; 69 70 # Type of molecular descriptors... 71 $This->{Type} = ''; 72 73 # Names and calculated value of molecular descriptors... 74 # 75 # The specific descriptor class, derived from this base class, populate descriptor names and values 76 # arrays... 77 # 78 @{$This->{DescriptorNames}} = (); 79 @{$This->{DescriptorValues}} = (); 80 81 # Marks successful generation of descriptors... 82 $This->{DescriptorsGenerated} = 0; 83 84 } 85 86 # Initialize class ... 87 sub _InitializeClass { 88 #Class name... 89 $ClassName = __PACKAGE__; 90 } 91 92 93 # Initialize object properties.... 94 sub _InitializeMolecularDescriptorsProperties { 95 my($This, %NamesAndValues) = @_; 96 97 my($Name, $Value, $MethodName); 98 while (($Name, $Value) = each %NamesAndValues) { 99 $MethodName = "Set${Name}"; 100 $This->$MethodName($Value); 101 } 102 103 return $This; 104 } 105 106 # Initialize descriptor names and values... 107 # 108 sub _InitializeDescriptorNamesAndValues { 109 my($This, @Names) = @_; 110 111 @{$This->{DescriptorNames}} = @Names; 112 113 $This->_InitializeDescriptorValues(); 114 115 return $This; 116 } 117 118 # Initialize descriptor values... 119 # 120 sub _InitializeDescriptorValues { 121 my($This) = @_; 122 123 $This->{DescriptorsGenerated} = 0; 124 125 @{$This->{DescriptorValues}} = (); 126 127 return $This; 128 } 129 130 # Set molecule object... 131 # 132 sub SetMolecule { 133 my($This, $Molecule) = @_; 134 135 $This->{Molecule} = $Molecule; 136 137 # Weaken the reference to disable increment of reference count... 138 Scalar::Util::weaken($This->{Molecule}); 139 140 return $This; 141 } 142 143 # Set type and make sure it's not already set... 144 # 145 sub SetType { 146 my($This, $Type) = @_; 147 148 if ($This->{Type}) { 149 croak "Error: ${ClassName}->SetType: Can't change MolecularDescriptors type: It's already set..."; 150 } 151 $This->{Type} = $Type; 152 153 return $This; 154 } 155 156 # Get molecular descriptor names as an array... 157 # 158 sub GetDescriptorNames { 159 my($This) = @_; 160 161 return @{$This->{DescriptorNames}}; 162 } 163 164 # Set descriptor names... 165 # 166 sub SetDescriptorNames { 167 my($This, @Names) = @_; 168 169 @{$This->{DescriptorNames}} = @Names; 170 171 return $This; 172 } 173 174 # Add descriptor names... 175 # 176 sub AddDescriptorNames { 177 my($This, @Names) = @_; 178 179 push @{$This->{DescriptorNames}}, @Names; 180 181 return $This; 182 } 183 184 # Set descriptor values... 185 # 186 sub SetDescriptorValues { 187 my($This, @Values) = @_; 188 189 @{$This->{DescriptorValues}} = @Values; 190 191 return $This; 192 } 193 194 # Add descriptor values... 195 # 196 sub AddDescriptorValues { 197 my($This, @Values) = @_; 198 199 push @{$This->{DescriptorValues}}, @Values; 200 201 return $This; 202 } 203 204 # Is descriptors generation successful? 205 # 206 # Notes: 207 # . The specific molecular descriptor class generation class sets the value of 208 # DescriptorsCalculated to 1 after the successful generation of descriptors; 209 # otherwise, it's set to 0. 210 # 211 sub IsDescriptorsGenerationSuccessful { 212 my($This) = @_; 213 214 return $This->{DescriptorsGenerated} ? 1 : 0; 215 } 216 217 # Get all descriptor values as an array... 218 # 219 sub GetDescriptorValues { 220 my($This) = @_; 221 222 if ($This->{DescriptorsGenerated}) { 223 return wantarray ? @{$This->{DescriptorValues}} : scalar @{$This->{DescriptorValues}}; 224 } 225 else { 226 my(@DescriptorValues); 227 228 @DescriptorValues = ('None') x scalar @{$This->{DescriptorNames}}; 229 230 return wantarray ? @DescriptorValues : scalar @DescriptorValues; 231 } 232 } 233 234 # Get descriptor value for a specified descriptor name... 235 # 236 sub GetDescriptorValueByName { 237 my($This, $Name) = @_; 238 my(%NamesAndValues); 239 240 %NamesAndValues = $This->GetDescriptorNamesAndValues(); 241 242 return exists $NamesAndValues{$Name} ? $NamesAndValues{$Name} : 'None'; 243 244 } 245 246 # Get calculated molecular descriptor names sand values as a to a hash with names 247 # and values as key/value pairs... 248 # 249 sub GetDescriptorNamesAndValues { 250 my($This) = @_; 251 my(%NamesAndValues); 252 253 %NamesAndValues = (); 254 @NamesAndValues{ @{$This->{DescriptorNames}} } = $This->GetDescriptorValues(); 255 256 return %NamesAndValues; 257 } 258 259 # Return a string containing descriptor names and values... 260 # 261 sub _StringifyDescriptorNamesAndValues { 262 my($This) = @_; 263 my($NamesAndValuesString, $Name, $Value, @NamesAndValuesInfo, %NamesAndValues); 264 265 @NamesAndValuesInfo = (); 266 %NamesAndValues = $This->GetDescriptorNamesAndValues(); 267 268 for $Name (@{$This->{DescriptorNames}}) { 269 $Value = $NamesAndValues{$Name}; 270 $Value = (TextUtil::IsEmpty($Value) || $Value =~ /^None$/i) ? 'None' : $Value; 271 push @NamesAndValuesInfo, "$Name - $Value"; 272 } 273 if (@NamesAndValuesInfo) { 274 $NamesAndValuesString = "Names - Values: <" . TextUtil::JoinWords(\@NamesAndValuesInfo, ", ", 0) . ">"; 275 } 276 else { 277 $NamesAndValuesString = "Names - Values: < None>"; 278 } 279 return $NamesAndValuesString; 280 } 281