MayaChemTools

   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