       1 package MoleculeFileIO;
       2 #
       3 # $RCSfile: MoleculeFileIO.pm,v $
       4 # $Date: 2015/02/28 20:47:18 $
       5 # $Revision: 1.32 $
       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 FileIO::SDFileIO;
      34 use FileIO::MDLMolFileIO;
      35
      36 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
      37
      38 @ISA = qw(Exporter);
      39 @EXPORT = qw();
      40 @EXPORT_OK = qw(IsSupportedMoleculeFileFormat);
      41
      42 %EXPORT_TAGS = (all  => [@EXPORT, @EXPORT_OK]);
      43
      44 # Setup class variables...
      45 my($ClassName);
      46 _InitializeClass();
      47
      48 # Class constructor...
      49 sub new {
      50   my($Class, %NamesAndValues) = @_;
      51
      52   # Initialize object...
      53   my $This = {};
      54   bless $This, ref($Class) || $Class;
      55   $This->_InitializeMoleculeFileIO();
      56
      57   $This->_InitializeMoleculeFileIOProperties(%NamesAndValues);
      58
      59   return $This;
      60 }
      61
      62 # Initialize object data...
      63 #
      64 sub _InitializeMoleculeFileIO {
      65   my($This) = @_;
      66
      67   # Reference to specific FileIO object...
      68   $This->{FileIORef} = '';
      69
      70   return $This;
      71 }
      72
      73 # Initialize class ...
      74 sub _InitializeClass {
      75   #Class name...
      76   $ClassName = __PACKAGE__;
      77
      78 }
      79
      80 # Initialize object properties......
      81 #
      82 sub _InitializeMoleculeFileIOProperties {
      83   my($This, %NamesAndValues) = @_;
      84
      85   if (!exists $NamesAndValues{Name}) {
      86     croak "Error: ${ClassName}->New: Object can't be instantiated without specifying file name...";
      87   }
      88
      89   if (!exists $NamesAndValues{Mode}) {
      90     $NamesAndValues{Mode} = 'Read';
      91   }
      92
      93   # Make sure its a supported format and intialize FileIO object reference...
      94   $This->_SetFileIORef(%NamesAndValues);
      95
      96   return $This;
      97 }
      98
      99 # Setup FileIO object reference...
     100 sub _SetFileIORef {
     101   my($This, %NamesAndValues) = @_;
     102   my($Name, $Status, $Format, $IOPackageName);
     103
     104   $Name = $NamesAndValues{Name};
     105
     106   ($Status, $Format, $IOPackageName) = $This->IsSupportedMoleculeFileFormat($Name);
     107   if (!$Status) {
     108     croak "Error: ${ClassName}->New: Object can't be instantiated: File format, $Name, is not supported: Currently supported file formats are: SDF, MDLMol...";
     109   }
     110
     111   $This->{FileIORef} = ${IOPackageName}->new(%NamesAndValues);
     112
     113   return $This;
     114 }
     115
     116 # Is it a supported file format?
     117 #
     118 # In scalar context only status is returned; otherwise, file format and file IO package name is also
     119 # returned.
     120 #
     121 # Note:
     122 #   . To support additional file formats, this is the only method which needs to be changed.
     123 #
     124 #   . Currently supported file formats are:
     125 #
     126 #      SDF         .sdf, .sd
     127 #      MDLMol   .mol
     128 #
     129 sub IsSupportedMoleculeFileFormat {
     130   my($FirstParameter, $SecondParameter) = @_;
     131   my($This, $Name);
     132
     133   if ((@_ == 2) && (_IsMoleculeFileIO($FirstParameter))) {
     134     ($This, $Name) = ($FirstParameter, $SecondParameter);
     135   }
     136   else {
     137     ($Name) = ($FirstParameter);
     138   }
     139   my($Status, $Format, $IOPackageName);
     140
     141   $Status = 0; $Format = 'NotSupported'; $IOPackageName = 'Unknown';
     142
     143   FORMAT: {
     144     if (FileIO::SDFileIO::IsSDFile($Name)) { $Status = 1; $Format = 'SDF'; $IOPackageName = 'FileIO::SDFileIO'; last FORMAT; }
     145     if (FileIO::MDLMolFileIO::IsMDLMolFile($Name)) { $Status = 1; $Format = 'MDLMol'; $IOPackageName = 'FileIO::MDLMolFileIO'; last FORMAT; }
     146     $Status = 0; $Format = 'NotSupported'; $IOPackageName = 'Unknown';
     147   }
     148
     149   return wantarray ? ($Status, $Format, $IOPackageName) : $Status;
     150 }
     151
     152 # Prohibit file ref change...
     153 #
     154 sub SetFileIORef {
     155   my($This, $Value) = @_;
     156
     157   carp "Warning: ${ClassName}->SetFileIORef: Explicit setting of file ref is not supported...";
     158
     159   return $This;
     160 }
     161
     162 # Prohibit file name change...
     163 #
     164 sub SetName {
     165   my($This, $Name) = @_;
     166
     167   carp "Warning: ${ClassName}->SetName: Explicit setting of file name is not supported: It must be set during object instantiation...";
     168
     169   return $This;
     170 }
     171
     172 # Prohibit file mode change...
     173 #
     174 sub SetMode {
     175   my($This, $Mode) = @_;
     176
     177   carp "Warning: ${ClassName}->SetMode: Explicit setting of file mode is not supported: It must be set during object instantiation...";
     178
     179   return $This;
     180 }
     181
     182 # Open file in a specific mode; default mode is Read only.
     183 # Supported mode values are: Read, Write, Append, <, >, >>, r, w, a
     184 #
     185 sub Open {
     186   my($This, $Mode) = @_;
     187
     188   return $This->{FileIORef}->Open($Mode);
     189 }
     190
     191 # close file...
     192 sub Close {
     193   my($This) = @_;
     194
     195   return $This->{FileIORef}->Close();
     196 }
     197
     198 # Read molecule string from file and return a molecule object...
     199 sub ReadMolecule {
     200   my($This) = @_;
     201
     202   return $This->{FileIORef}->ReadMolecule();
     203 }
     204
     205 # Retrieve molecule string from file...
     206 sub ReadMoleculeString {
     207   my($This) = @_;
     208
     209   return $This->{FileIORef}->ReadMoleculeString();
     210 }
     211
     212 # Write molecule using molecule object...
     213 sub WriteMolecule {
     214   my($This, $Molecule) = @_;
     215
     216   return $This->{FileIORef}->WriteMolecule($Molecule);
     217 }
     218
     219 # Is it a MoleculeFileIO object?
     220 sub _IsMoleculeFileIO {
     221   my($Object) = @_;
     222
     223   return (Scalar::Util::blessed($Object) && $Object->isa($ClassName)) ? 1 : 0;
     224 }
     225