MayaChemTools

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