       1 package MolecularDescriptors::WeightAndMassDescriptors;
       2 #
       3 # $RCSfile: WeightAndMassDescriptors.pm,v $
       4 # $Date: 2015/02/28 20:49:20 $
       5 # $Revision: 1.10 $
       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 '""' => 'StringifyWeightAndMassDescriptors';
      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->_InitializeWeightAndMassDescriptors();
      62
      63   $This->_InitializeWeightAndMassDescriptorsProperties(%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 = ('MolecularWeight', 'ExactMass');
      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 _InitializeWeightAndMassDescriptors {
      90   my($This) = @_;
      91
      92   # Type of MolecularDescriptor...
      93   $This->{Type} = 'WeightAndMass';
      94
      95   # Precision for molecular weight and exact mass values...
      96   $This->{WeightPrecision} = 2;
      97   $This->{MassPrecision} = 4;
      98
      99   # Intialize descriptor names and values...
     100   $This->_InitializeDescriptorNamesAndValues(@DescriptorNames);
     101
     102   return $This;
     103 }
     104
     105 # Initialize object properties...
     106 #
     107 sub _InitializeWeightAndMassDescriptorsProperties {
     108   my($This, %NamesAndValues) = @_;
     109
     110   my($Name, $Value, $MethodName);
     111   while (($Name, $Value) = each  %NamesAndValues) {
     112     $MethodName = "Set${Name}";
     113     $This->$MethodName($Value);
     114   }
     115
     116   return $This;
     117 }
     118
     119 # Set weight precision for moelcular weight...
     120 #
     121 sub SetWeightPrecision {
     122   my($This, $Value) = @_;
     123
     124   if (!TextUtil::IsInteger($Value)) {
     125     croak "Error: ${ClassName}->SetWeightPrecision: WeightPrecision value, $Value, is not valid:  It must be a an integer...";
     126   }
     127   $This->{WeightPrecision} = $Value;
     128
     129   return $This;
     130 }
     131
     132 # Set mass precision for exact weight...
     133 #
     134 sub SetMassPrecision {
     135   my($This, $Value) = @_;
     136
     137   if (!TextUtil::IsInteger($Value)) {
     138     croak "Error: ${ClassName}->SetMassPrecision: MassPrecision value, $Value, is not valid:  It must be a an integer...";
     139   }
     140   $This->{MassPrecision} = $Value;
     141
     142   return $This;
     143 }
     144
     145 # Generate molecular weight and exact mass values...
     146 #
     147 sub GenerateDescriptors {
     148   my($This) = @_;
     149
     150   # Initialize descriptor values...
     151   $This->_InitializeDescriptorValues();
     152
     153   # Check availability of molecule...
     154   if (!$This->{Molecule}) {
     155     carp "Warning: ${ClassName}->GenerateDescriptors: $This->{Type} molecular descriptors generation didn't succeed: Molecule data is not available: Molecule object hasn't been set...";
     156     return undef;
     157   }
     158
     159   # Calculate descriptor values...
     160   if (!$This->_CalculateDescriptorValues()) {
     161     carp "Warning: ${ClassName}->GenerateDescriptors: $This->{Type} molecular descriptors generation didn't succeed...";
     162     return undef;
     163   }
     164
     165   # Set final descriptor values...
     166   $This->_SetFinalDescriptorValues();
     167
     168   return $This;
     169 }
     170
     171 # Calculate molecular weight and exact mass values..
     172 #
     173 sub _CalculateDescriptorValues {
     174   my($This) = @_;
     175   my($MolecularWeight, $ExactMass);
     176
     177   $MolecularWeight = $This->{Molecule}->GetMolecularWeight();
     178   $ExactMass = $This->{Molecule}->GetExactMass();
     179
     180   # Track values...
     181   $This->{MolecularWeight} = MathUtil::round($MolecularWeight, $This->{WeightPrecision});
     182   $This->{ExactMass} = MathUtil::round($ExactMass, $This->{MassPrecision});
     183
     184   return $This;
     185 }
     186
     187 # Setup final descriptor values...
     188 #
     189 sub _SetFinalDescriptorValues {
     190   my($This) = @_;
     191
     192   $This->{DescriptorsGenerated} = 1;
     193
     194   $This->SetDescriptorValues($This->{MolecularWeight}, $This->{ExactMass});
     195
     196   return $This;
     197 }
     198
     199 # Return a string containg data for WeightAndMassDescriptors object...
     200 #
     201 sub StringifyWeightAndMassDescriptors {
     202   my($This) = @_;
     203   my($TheString);
     204
     205   $TheString = "MolecularDescriptorType: $This->{Type}; " . $This->_StringifyDescriptorNamesAndValues();
     206
     207   return $TheString;
     208 }
     209
     210 # Is it a WeightAndMassDescriptors object?
     211 sub _IsWeightAndMassDescriptors {
     212   my($Object) = @_;
     213
     214   return (Scalar::Util::blessed($Object) && $Object->isa($ClassName)) ? 1 : 0;
     215 }
     216