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