MayaChemTools

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