MayaChemTools

   1 package MolecularDescriptors::MolecularDescriptors;
   2 #
   3 # File: MolecularDescriptors.pm
   4 # Author: Manish Sud <msud@san.rr.com>
   5 #
   6 # Copyright (C) 2024 Manish Sud. All rights reserved.
   7 #
   8 # This file is part of MayaChemTools.
   9 #
  10 # MayaChemTools is free software; you can redistribute it and/or modify it under
  11 # the terms of the GNU Lesser General Public License as published by the Free
  12 # Software Foundation; either version 3 of the License, or (at your option) any
  13 # later version.
  14 #
  15 # MayaChemTools is distributed in the hope that it will be useful, but without
  16 # any warranty; without even the implied warranty of merchantability of fitness
  17 # for a particular purpose.  See the GNU Lesser General Public License for more
  18 # details.
  19 #
  20 # You should have received a copy of the GNU Lesser General Public License
  21 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or
  22 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330,
  23 # Boston, MA, 02111-1307, USA.
  24 #
  25 
  26 use strict;
  27 use Carp;
  28 use Exporter;
  29 use Scalar::Util ();
  30 use ObjectProperty;
  31 use TextUtil ();
  32 
  33 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  34 
  35 @ISA = qw(ObjectProperty Exporter);
  36 @EXPORT = qw();
  37 @EXPORT_OK = qw();
  38 
  39 %EXPORT_TAGS = (all  => [@EXPORT, @EXPORT_OK]);
  40 
  41 # Setup class variables...
  42 my($ClassName);
  43 _InitializeClass();
  44 
  45 # Class constructor...
  46 sub new {
  47   my($Class, %NamesAndValues) = @_;
  48 
  49   # Initialize object...
  50   my $This = {};
  51   bless $This, ref($Class) || $Class;
  52   $This->_InitializeMolecularDescriptors();
  53 
  54   $This->_InitializeMolecularDescriptorsProperties(%NamesAndValues);
  55 
  56   return $This;
  57 }
  58 
  59 # Initialize object data...
  60 #
  61 sub _InitializeMolecularDescriptors {
  62   my($This) = @_;
  63 
  64   # Molecule object...
  65   $This->{Molecule} = '';
  66 
  67   # Type of molecular descriptors...
  68   $This->{Type} = '';
  69 
  70   # Names and calculated value of molecular descriptors...
  71   #
  72   # The specific descriptor class, derived from this base class, populate descriptor names and values
  73   # arrays...
  74   #
  75   @{$This->{DescriptorNames}} = ();
  76   @{$This->{DescriptorValues}} = ();
  77 
  78   # Marks successful generation of descriptors...
  79   $This->{DescriptorsGenerated} = 0;
  80 
  81 }
  82 
  83 # Initialize class ...
  84 sub _InitializeClass {
  85   #Class name...
  86   $ClassName = __PACKAGE__;
  87 }
  88 
  89 
  90 # Initialize object properties....
  91 sub _InitializeMolecularDescriptorsProperties {
  92   my($This, %NamesAndValues) = @_;
  93 
  94   my($Name, $Value, $MethodName);
  95   while (($Name, $Value) = each  %NamesAndValues) {
  96     $MethodName = "Set${Name}";
  97     $This->$MethodName($Value);
  98   }
  99 
 100   return $This;
 101 }
 102 
 103 # Initialize descriptor names and values...
 104 #
 105 sub _InitializeDescriptorNamesAndValues {
 106   my($This, @Names) = @_;
 107 
 108   @{$This->{DescriptorNames}} = @Names;
 109 
 110   $This->_InitializeDescriptorValues();
 111 
 112   return $This;
 113 }
 114 
 115 # Initialize descriptor values...
 116 #
 117 sub _InitializeDescriptorValues {
 118   my($This) = @_;
 119 
 120   $This->{DescriptorsGenerated} = 0;
 121 
 122   @{$This->{DescriptorValues}} = ();
 123 
 124   return $This;
 125 }
 126 
 127 # Set molecule object...
 128 #
 129 sub SetMolecule {
 130   my($This, $Molecule) = @_;
 131 
 132   $This->{Molecule} = $Molecule;
 133 
 134   # Weaken the reference to disable increment of reference count...
 135   Scalar::Util::weaken($This->{Molecule});
 136 
 137   return $This;
 138 }
 139 
 140 # Set type and make sure it's not already set...
 141 #
 142 sub SetType {
 143   my($This, $Type) = @_;
 144 
 145   if ($This->{Type}) {
 146     croak "Error: ${ClassName}->SetType: Can't change MolecularDescriptors type:  It's already set...";
 147   }
 148   $This->{Type} = $Type;
 149 
 150   return $This;
 151 }
 152 
 153 # Get molecular descriptor names as an array...
 154 #
 155 sub GetDescriptorNames {
 156   my($This) = @_;
 157 
 158   return @{$This->{DescriptorNames}};
 159 }
 160 
 161 # Set descriptor names...
 162 #
 163 sub SetDescriptorNames {
 164   my($This, @Names) = @_;
 165 
 166   @{$This->{DescriptorNames}} = @Names;
 167 
 168   return $This;
 169 }
 170 
 171 # Add descriptor names...
 172 #
 173 sub AddDescriptorNames {
 174   my($This, @Names) = @_;
 175 
 176   push @{$This->{DescriptorNames}}, @Names;
 177 
 178   return $This;
 179 }
 180 
 181 # Set descriptor values...
 182 #
 183 sub SetDescriptorValues {
 184   my($This, @Values) = @_;
 185 
 186   @{$This->{DescriptorValues}} = @Values;
 187 
 188   return $This;
 189 }
 190 
 191 # Add descriptor values...
 192 #
 193 sub AddDescriptorValues {
 194   my($This, @Values) = @_;
 195 
 196   push @{$This->{DescriptorValues}}, @Values;
 197 
 198   return $This;
 199 }
 200 
 201 # Is descriptors generation successful?
 202 #
 203 # Notes:
 204 #   . The specific molecular descriptor class generation class sets the value of
 205 #     DescriptorsCalculated  to 1 after the successful generation of descriptors;
 206 #     otherwise, it's set to 0.
 207 #
 208 sub IsDescriptorsGenerationSuccessful {
 209   my($This) = @_;
 210 
 211   return $This->{DescriptorsGenerated} ? 1 : 0;
 212 }
 213 
 214 # Get all descriptor values as an array...
 215 #
 216 sub GetDescriptorValues {
 217   my($This) = @_;
 218 
 219   if ($This->{DescriptorsGenerated}) {
 220     return wantarray ? @{$This->{DescriptorValues}} : scalar @{$This->{DescriptorValues}};
 221   }
 222   else {
 223     my(@DescriptorValues);
 224 
 225     @DescriptorValues = ('None') x scalar @{$This->{DescriptorNames}};
 226 
 227     return wantarray ? @DescriptorValues : scalar @DescriptorValues;
 228   }
 229 }
 230 
 231 # Get descriptor value for a specified descriptor name...
 232 #
 233 sub GetDescriptorValueByName {
 234   my($This, $Name) = @_;
 235   my(%NamesAndValues);
 236 
 237   %NamesAndValues = $This->GetDescriptorNamesAndValues();
 238 
 239   return exists $NamesAndValues{$Name} ? $NamesAndValues{$Name} : 'None';
 240 
 241 }
 242 
 243 # Get calculated molecular descriptor names sand values as a to a hash with names
 244 # and values as key/value pairs...
 245 #
 246 sub GetDescriptorNamesAndValues {
 247   my($This) = @_;
 248   my(%NamesAndValues);
 249 
 250   %NamesAndValues = ();
 251   @NamesAndValues{ @{$This->{DescriptorNames}} } = $This->GetDescriptorValues();
 252 
 253   return %NamesAndValues;
 254 }
 255 
 256 # Return a string containing descriptor names and values...
 257 #
 258 sub _StringifyDescriptorNamesAndValues {
 259   my($This) = @_;
 260   my($NamesAndValuesString, $Name, $Value, @NamesAndValuesInfo, %NamesAndValues);
 261 
 262   @NamesAndValuesInfo = ();
 263   %NamesAndValues = $This->GetDescriptorNamesAndValues();
 264 
 265   for $Name (@{$This->{DescriptorNames}}) {
 266     $Value = $NamesAndValues{$Name};
 267     $Value = (TextUtil::IsEmpty($Value) || $Value =~ /^None$/i) ? 'None' : $Value;
 268     push @NamesAndValuesInfo, "$Name - $Value";
 269   }
 270   if (@NamesAndValuesInfo) {
 271     $NamesAndValuesString = "Names - Values: <" . TextUtil::JoinWords(\@NamesAndValuesInfo, ", ", 0) . ">";
 272   }
 273   else {
 274     $NamesAndValuesString = "Names - Values: < None>";
 275   }
 276   return $NamesAndValuesString;
 277 }
 278