MayaChemTools

   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