       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