MayaChemTools

   1 package MolecularDescriptors::HydrogenBondsDescriptors;
   2 #
   3 # File: HydrogenBondsDescriptors.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 TextUtil ();
  31 use Atom;
  32 use Molecule;
  33 use MolecularDescriptors::MolecularDescriptors;
  34 
  35 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  36 
  37 @ISA = qw(MolecularDescriptors::MolecularDescriptors Exporter);
  38 @EXPORT = qw();
  39 @EXPORT_OK = qw(GetDescriptorNames);
  40 
  41 %EXPORT_TAGS = (all  => [@EXPORT, @EXPORT_OK]);
  42 
  43 # Setup class variables...
  44 my($ClassName, @DescriptorNames);
  45 _InitializeClass();
  46 
  47 # Overload Perl functions...
  48 use overload '""' => 'StringifyHydrogenBondsDescriptors';
  49 
  50 # Class constructor...
  51 sub new {
  52   my($Class, %NamesAndValues) = @_;
  53 
  54   # Initialize object...
  55   my $This = $Class->SUPER::new();
  56   bless $This, ref($Class) || $Class;
  57   $This->_InitializeHydrogenBondsDescriptors();
  58 
  59   $This->_InitializeHydrogenBondsDescriptorsProperties(%NamesAndValues);
  60 
  61   return $This;
  62 }
  63 
  64 # Initialize class ...
  65 sub _InitializeClass {
  66   #Class name...
  67   $ClassName = __PACKAGE__;
  68 
  69   # Descriptor names...
  70   @DescriptorNames = ('HydrogenBondDonors', 'HydrogenBondAcceptors');
  71 
  72 }
  73 
  74 # Get descriptor names as an array.
  75 #
  76 # This functionality can be either invoked as a class function or an
  77 # object method.
  78 #
  79 sub GetDescriptorNames {
  80   return @DescriptorNames;
  81 }
  82 
  83 # Initialize object data...
  84 #
  85 sub _InitializeHydrogenBondsDescriptors {
  86   my($This) = @_;
  87 
  88   # Type of MolecularDescriptor...
  89   $This->{Type} = 'HydrogenBonds';
  90 
  91   # The currrent release of MayaChemTools supports identification of two types of
  92   # hydrogen bond donor and acceptor atoms with these names:
  93   #
  94   # HBondsType1 or HydrogenBondsType1
  95   # HBondsType2 or HydrogenBondsType2
  96   #
  97   # The names of these hydrogen bond types are rather arbirary. However, their
  98   # definitions have specific meaning and are as follows:
  99   #
 100   # HydrogenBondsType1 [ Ref 60-61, Ref 65-66 ]:
 101   #   . Donor: NH, NH2, OH - Any N and O with available H
 102   #   . Acceptor: N[!H], O - Any N without available H and any O
 103   #
 104   # HydrogenBondsType2 [ Ref 91 ]:
 105   #   . Donor: NH, NH2, OH - N and O with availabe H
 106   #   . Acceptor: N, O - Add N and O
 107   #
 108   # Note:
 109   #   . HydrogenBondsType2 definition corresponds to Rule of 5.
 110   #
 111   $This->{HydrogenBondsType} = 'HBondsType2';
 112 
 113   # Intialize descriptor names and values...
 114   $This->_InitializeDescriptorNamesAndValues(@DescriptorNames);
 115 
 116   return $This;
 117 }
 118 
 119 # Initialize object properties...
 120 #
 121 sub _InitializeHydrogenBondsDescriptorsProperties {
 122   my($This, %NamesAndValues) = @_;
 123 
 124   my($Name, $Value, $MethodName);
 125   while (($Name, $Value) = each  %NamesAndValues) {
 126     $MethodName = "Set${Name}";
 127     $This->$MethodName($Value);
 128   }
 129 
 130   return $This;
 131 }
 132 
 133 # Set hydrogen bonds type...
 134 #
 135 sub SetHydrogenBondsType {
 136   my($This, $HydrogenBondsType) = @_;
 137 
 138   if ($HydrogenBondsType !~ /^(HBondsType1|HBondsType2|HydrogenBondsType1|HydrogenBondsType2)$/i) {
 139     croak "Error: ${ClassName}->SetHydrogenBondsType: Specified hydrogen bonds type, $HydrogenBondsType, is not supported. Valid values: HBondsType1, HBondsType2, HydrogenBondsType1, HydrogenBondsType2 ...\n ";
 140   }
 141 
 142   $This->{HydrogenBondsType} = $HydrogenBondsType;
 143 
 144   return $This;
 145 }
 146 
 147 # Calculate number of hydrogen bond donors and acceptors in a molecule...
 148 #
 149 sub GenerateDescriptors {
 150   my($This) = @_;
 151 
 152   # Initialize descriptor values...
 153   $This->_InitializeDescriptorValues();
 154 
 155   # Check availability of molecule...
 156   if (!$This->{Molecule}) {
 157     carp "Warning: ${ClassName}->GenerateDescriptors: $This->{Type} molecular descriptors generation didn't succeed: Molecule data is not available: Molecule object hasn't been set...";
 158     return undef;
 159   }
 160 
 161   # Calculate descriptor values...
 162   if (!$This->_CalculateDescriptorValues()) {
 163     carp "Warning: ${ClassName}->CalculateDescriptorValues: $This->{Type} molecular descriptors generation didn't succeed: Couldn't calculate number of hydrogen bond donor and accepror values...";
 164     return undef;
 165   }
 166 
 167   # Set final descriptor values...
 168   $This->_SetFinalDescriptorValues();
 169 
 170 }
 171 
 172 # Calculate number of hydrogen bond donors and acceptors...
 173 #
 174 sub _CalculateDescriptorValues {
 175   my($This) = @_;
 176   my($HydrogenBondDonors, $HydrogenBondAcceptors, $Atom);
 177 
 178   $HydrogenBondDonors = 0;
 179   $HydrogenBondAcceptors = 0;
 180 
 181   for $Atom ($This->{Molecule}->GetAtoms()) {
 182     if ($Atom->IsHydrogenBondDonor($This->{HydrogenBondsType})) {
 183       $HydrogenBondDonors++;
 184     }
 185     if ($Atom->IsHydrogenBondAcceptor($This->{HydrogenBondsType})) {
 186       $HydrogenBondAcceptors++;
 187     }
 188   }
 189 
 190   # Track the calculated values...
 191   $This->{HydrogenBondDonors} = $HydrogenBondDonors;
 192   $This->{HydrogenBondAcceptors} = $HydrogenBondAcceptors;
 193 
 194   return $This;
 195 }
 196 
 197 # Setup final descriptor values...
 198 #
 199 sub _SetFinalDescriptorValues {
 200   my($This) = @_;
 201 
 202   $This->{DescriptorsGenerated} = 1;
 203 
 204   $This->SetDescriptorValues($This->{HydrogenBondDonors}, $This->{HydrogenBondAcceptors});
 205 
 206   return $This;
 207 }
 208 
 209 # Return a string containg data for HydrogenBondsDescriptors object...
 210 #
 211 sub StringifyHydrogenBondsDescriptors {
 212   my($This) = @_;
 213   my($HydrogenBondsDescriptorsString);
 214 
 215   $HydrogenBondsDescriptorsString = "MolecularDescriptorType: $This->{Type}; HydrogenBondsType: $This->{HydrogenBondsType}; " . $This->_StringifyDescriptorNamesAndValues();
 216 
 217   return $HydrogenBondsDescriptorsString;
 218 }
 219 
 220 # Is it a HydrogenBondsDescriptors object?
 221 sub _IsHydrogenBondsDescriptors {
 222   my($Object) = @_;
 223 
 224   return (Scalar::Util::blessed($Object) && $Object->isa($ClassName)) ? 1 : 0;
 225 }
 226