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