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