1 package MolecularDescriptors::Fsp3CarbonsDescriptors; 2 # 3 # File: Fsp3CarbonsDescriptors.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 MathUtil (); 32 use Atom; 33 use Molecule; 34 use MolecularDescriptors::MolecularDescriptors; 35 36 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); 37 38 @ISA = qw(MolecularDescriptors::MolecularDescriptors Exporter); 39 @EXPORT = qw(); 40 @EXPORT_OK = qw(GetDescriptorNames); 41 42 %EXPORT_TAGS = (all => [@EXPORT, @EXPORT_OK]); 43 44 # Setup class variables... 45 my($ClassName, @DescriptorNames); 46 _InitializeClass(); 47 48 # Overload Perl functions... 49 use overload '""' => 'StringifyFsp3CarbonsDescriptors'; 50 51 # Class constructor... 52 sub new { 53 my($Class, %NamesAndValues) = @_; 54 55 # Initialize object... 56 my $This = $Class->SUPER::new(); 57 bless $This, ref($Class) || $Class; 58 $This->_InitializeFsp3CarbonsDescriptors(); 59 60 $This->_InitializeFsp3CarbonsDescriptorsProperties(%NamesAndValues); 61 62 return $This; 63 } 64 65 # Initialize class ... 66 sub _InitializeClass { 67 #Class name... 68 $ClassName = __PACKAGE__; 69 70 # Descriptor names... 71 @DescriptorNames = ('Fsp3Carbons', 'Sp3Carbons'); 72 73 } 74 75 # Get descriptor names as an array. 76 # 77 # This functionality can be either invoked as a class function or an 78 # object method. 79 # 80 sub GetDescriptorNames { 81 return @DescriptorNames; 82 } 83 84 # Initialize object data... 85 # 86 sub _InitializeFsp3CarbonsDescriptors { 87 my($This) = @_; 88 89 # Type of MolecularDescriptor... 90 $This->{Type} = 'Fsp3Carbons'; 91 92 # Intialize descriptor names and values... 93 $This->_InitializeDescriptorNamesAndValues(@DescriptorNames); 94 95 return $This; 96 } 97 98 # Initialize object properties... 99 # 100 sub _InitializeFsp3CarbonsDescriptorsProperties { 101 my($This, %NamesAndValues) = @_; 102 103 my($Name, $Value, $MethodName); 104 while (($Name, $Value) = each %NamesAndValues) { 105 $MethodName = "Set${Name}"; 106 $This->$MethodName($Value); 107 } 108 109 return $This; 110 } 111 112 # Calculate fraction of SP3 carbons (Fsp3Carbons) [ Ref 115-116, Ref 119 ] in a molecule... 113 # 114 # It is defined as follows: 115 # 116 # Fsp3 = Number of SP3 carbons/Total number of carbons 117 # 118 sub GenerateDescriptors { 119 my($This) = @_; 120 121 # Initialize descriptor values... 122 $This->_InitializeDescriptorValues(); 123 124 # Check availability of molecule... 125 if (!$This->{Molecule}) { 126 carp "Warning: ${ClassName}->GenerateDescriptors: $This->{Type} molecular descriptors generation didn't succeed: Molecule data is not available: Molecule object hasn't been set..."; 127 return undef; 128 } 129 130 # Calculate descriptor values... 131 if (!$This->_CalculateDescriptorValues()) { 132 carp "Warning: ${ClassName}->GenerateDescriptors: $This->{Type} molecular descriptors generation didn't succeed: Couldn't calculate Fsp3Carbons values corresponding to assigned Fsp3Carbons atom types..."; 133 return undef; 134 } 135 136 # Set final descriptor values... 137 $This->_SetFinalDescriptorValues(); 138 139 return $This; 140 } 141 142 # Calculate Fsp3Carbons value... 143 # 144 sub _CalculateDescriptorValues { 145 my($This) = @_; 146 my($Atom, $AtomID, $TotalCarbons, $NumOfSp3Carbons, $Fsp3Carbons); 147 148 $TotalCarbons = 0; 149 $NumOfSp3Carbons = 0; 150 151 ATOM: for $Atom ($This->{Molecule}->GetAtoms()) { 152 if (!$Atom->IsCarbon()) { 153 next ATOM; 154 } 155 $TotalCarbons += 1; 156 157 if ($Atom->DoesAtomNeighborhoodMatch('C.T4.TSB4')) { 158 $NumOfSp3Carbons += 1; 159 } 160 } 161 162 $Fsp3Carbons = $NumOfSp3Carbons ? $NumOfSp3Carbons/$TotalCarbons : 0; 163 164 # Track values... 165 $This->{Fsp3Carbons} = MathUtil::round($Fsp3Carbons, 2); 166 $This->{Sp3Carbons} = $NumOfSp3Carbons; 167 168 return $This; 169 } 170 171 # Setup final descriptor values... 172 # 173 sub _SetFinalDescriptorValues { 174 my($This) = @_; 175 176 $This->{DescriptorsGenerated} = 1; 177 178 $This->SetDescriptorValues($This->{Fsp3Carbons}, $This->{Sp3Carbons}); 179 180 return $This; 181 } 182 183 # Return a string containg data for Fsp3CarbonsDescriptors object... 184 # 185 sub StringifyFsp3CarbonsDescriptors { 186 my($This) = @_; 187 my($Fsp3CarbonsDescriptorsString); 188 189 $Fsp3CarbonsDescriptorsString = "MolecularDescriptorType: $This->{Type}; " . $This->_StringifyDescriptorNamesAndValues(); 190 191 return $Fsp3CarbonsDescriptorsString; 192 } 193 194 # Is it a Fsp3CarbonsDescriptors object? 195 sub _IsFsp3CarbonsDescriptors { 196 my($Object) = @_; 197 198 return (Scalar::Util::blessed($Object) && $Object->isa($ClassName)) ? 1 : 0; 199 } 200