1 package Fingerprints; 2 # 3 # $RCSfile: Fingerprints.pm,v $ 4 # $Date: 2008/04/25 00:01:05 $ 5 # $Revision: 1.11 $ 6 # 7 # Author: Manish Sud <msud@san.rr.com> 8 # 9 # Copyright (C) 2004-2008 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 use 5.006; 29 use strict; 30 use Carp; 31 use Exporter; 32 use ObjectProperty; 33 use Fingerprints::FingerprintsBitVector; 34 use MathUtil; 35 use TextUtil (); 36 37 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); 38 39 $VERSION = '1.00'; 40 @ISA = qw(ObjectProperty Exporter); 41 @EXPORT = qw(); 42 @EXPORT_OK = qw(); 43 44 %EXPORT_TAGS = (all => [@EXPORT, @EXPORT_OK]); 45 46 # Setup class variables... 47 my($ClassName); 48 _InitializeClass(); 49 50 # Class constructor... 51 sub new { 52 my($Class, %NamesAndValues) = @_; 53 54 # Initialize object... 55 my $This = {}; 56 bless $This, ref($Class) || $Class; 57 $This->_InitializeFingerprints(); 58 59 $This->_InitializeFingerprintsProperties(%NamesAndValues); 60 61 return $This; 62 } 63 64 # Initialize object data... 65 # 66 sub _InitializeFingerprints { 67 my($This) = @_; 68 69 # Molecule object... 70 $This->{Molecule} = ''; 71 72 # Type of fingerprints... 73 $This->{Type} = ''; 74 75 # Size of fingerprints... 76 $This->{Size} = ''; 77 $This->{MinSize} = ''; 78 $This->{MaxSize} = ''; 79 80 # Bit vector used to store bit-based fingerprints... 81 $This->{FingerprintsBitVector} = ''; 82 } 83 84 # Initialize class ... 85 sub _InitializeClass { 86 #Class name... 87 $ClassName = __PACKAGE__; 88 } 89 90 91 # Initialize object properties.... 92 sub _InitializeFingerprintsProperties { 93 my($This, %NamesAndValues) = @_; 94 95 my($Name, $Value, $MethodName); 96 while (($Name, $Value) = each %NamesAndValues) { 97 $MethodName = "Set${Name}"; 98 $This->$MethodName($Value); 99 } 100 101 return $This; 102 } 103 104 # Initialize fingerprint bit vector... 105 sub _InitializeFingerprintsBitVector { 106 my($This) = @_; 107 108 if ($This->{Size}) { 109 $This->{FingerprintsBitVector} = new FingerprintsBitVector($This->{Size}); 110 } 111 112 return $This; 113 } 114 115 # Set molecule object and make sure it's not already set... 116 # 117 sub SetMolecule { 118 my($This, $Molecule) = @_; 119 120 if ($This->{Molecule}) { 121 croak "Error: ${ClassName}->SetMolecule: Can't change molecule object: It's already set..."; 122 } 123 $This->{Molecule} = $Molecule; 124 125 return $This; 126 } 127 128 # Set type and make sure it's not already set... 129 # 130 sub SetType { 131 my($This, $Type) = @_; 132 133 if ($This->{Type}) { 134 croak "Error: ${ClassName}->SetType: Can't set fingerprint type to $Type: It's already set to $This->{Type}..."; 135 } 136 $This->{Type} = $Type; 137 138 return $This; 139 } 140 141 # Set size... 142 # 143 sub SetSize { 144 my($This, $Size) = @_; 145 146 if ($This->{MinSize} && $Size < $This->{MinSize}) { 147 croak "Error: ${ClassName}->SetSize: Fingerprint size value, $Size, is not valid : It must be >= $This->{MinSize}..."; 148 } 149 if ($This->{MaxSize} && $Size > $This->{MaxSize}) { 150 croak "Error: ${ClassName}->SetSize: Fingerprint size value, $Size, is not valid: It must be <= $This->{MaxSize}..."; 151 } 152 153 $This->{Size} = $Size; 154 155 return $This; 156 } 157 158 # Set FingerprintsBitVector object and make sure it's not already set... 159 # 160 sub SetFingerprintsBitVector { 161 my($This, $FingerprintsBitVector) = @_; 162 163 if ($This->{FingerprintsBitVector}) { 164 croak "Error: ${ClassName}->SetFingerprintsBitVector: Can't change FingerprintsBitVector object: It's already set..."; 165 } 166 $This->{FingerprintsBitVector} = $FingerprintsBitVector; 167 168 return $This; 169 } 170 171 172 # Fold fingerprints by recursively reducing its size by half untill bit density is greater than or equal to 173 # specified bit density... 174 # 175 sub FoldFingerprintsByBitDensity { 176 my($This, $BitDensity) = @_; 177 178 if (!($BitDensity >= 0 && $BitDensity <= 1)) { 179 croak "Error: ${ClassName}->FoldFingerprintsByBitDensity: Specified bit density, $BitDensity, is not valid: It must be > 0 && <= 1 ..."; 180 } 181 182 return $This->_FoldFingerprintsBitVector('ByDensity', $BitDensity); 183 } 184 185 # Fold fingerprints by recursively reducing its size by half untill size is less than or equal to 186 # specified size... 187 # 188 sub FoldFingerprintsBySize { 189 my($This, $Size, $CheckSizeValue) = @_; 190 191 if (!defined $CheckSizeValue) { 192 $CheckSizeValue = 1; 193 } 194 195 if ($CheckSizeValue) { 196 if (!TextUtil::IsPositiveInteger($Size)) { 197 croak "Error: ${ClassName}->FoldFingerprintsBySize: Specified size, $Size, is not valid: It must be a positive integer"; 198 } 199 if (!($Size >= $This->{MinSize} && $Size < $This->{Size})) { 200 croak "Error: ${ClassName}->FoldFingerprintsBySize: Specified size, $Size, is not valid: It must be greater than or equal to minimum size of $This->{MinSize} and less than current size of $This->{Size}..."; 201 } 202 if (!TextUtil::IsNumberPowerOfNumber($Size, 2)) { 203 croak "Error: ${ClassName}->FoldFingerprintsBySize: Specified size value, $Size, must be power of 2..."; 204 } 205 } 206 207 return $This->_FoldFingerprintsBitVector('BySize', $Size); 208 } 209 210 # Fold fingerprints bit vector using specified size of bit density... 211 # 212 sub _FoldFingerprintsBitVector { 213 my($This, $Mode, $Value) = @_; 214 215 if (!$This->{FingerprintsBitVector}) { 216 return $This; 217 } 218 my($FingerprintsBitVector, $FoldedFingerprintsBitVector); 219 220 $FoldedFingerprintsBitVector = ''; 221 $FingerprintsBitVector = $This->{FingerprintsBitVector}; 222 MODE: { 223 if ($Mode =~ /^BySize$/i) { $FoldedFingerprintsBitVector = $FingerprintsBitVector->FoldFingerprintsBitVectorBySize($Value); last MODE; } 224 if ($Mode =~ /^ByDensity$/i) { $FoldedFingerprintsBitVector = $FingerprintsBitVector->FoldFingerprintsBitVectorByDensity($Value); last MODE; } 225 $FoldedFingerprintsBitVector = ''; 226 } 227 if ($FoldedFingerprintsBitVector) { 228 $This->{FingerprintsBitVector} = $FoldedFingerprintsBitVector; 229 $This->{Size} = $FoldedFingerprintsBitVector->GetSize(); 230 } 231 return $This; 232 } 233 234 # Get fingerprints as a binary ascii string containing 0s and 1s... 235 # 236 sub GetFingerprintBitsAsBinaryString { 237 my($This) = @_; 238 239 return $This->_GetFingerprintBitsAsString('Binary'); 240 } 241 242 # Get fingerprints as a hexadecimal string... 243 # 244 sub GetFingerprintBitsAsHexadecimalString { 245 my($This) = @_; 246 247 return $This->_GetFingerprintBitsAsString('Hexadecimal'); 248 } 249 250 # Get fingerprints as a raw binary string containing packed bit values for each 251 # byte... 252 # 253 sub GetFingerprintBitsAsRawBinaryString { 254 my($This) = @_; 255 256 return $This->_GetFingerprintBitsAsString('RawBinary'); 257 } 258 259 # Get fingerprint bits as a string... 260 # 261 sub _GetFingerprintBitsAsString { 262 my($This, $Format) = @_; 263 264 if (!$This->{FingerprintsBitVector}) { 265 return undef; 266 } 267 FORMAT : { 268 if ($Format =~ /^(Binary|Bin)$/i) { return $This->{FingerprintsBitVector}->GetBitsAsBinaryString(); last FORMAT; } 269 if ($Format =~ /^(Hexadecimal|Hex)$/i) { return $This->{FingerprintsBitVector}->GetBitsAsHexadecimalString(); last FORMAT; } 270 if ($Format =~ /^(RawBinary|RawBin)$/i) { return $This->{FingerprintsBitVector}->GetBitsAsRawBinaryString(); last FORMAT; } 271 croak "Error: ${ClassName}->_GetFingerprintBitsAsString: Specified bit vector string format, $Format, is not supported. Value values: Binary, Hexdecimal, Hex, RawBinary..."; 272 } 273 return undef; 274 } 275