Source code for CDTK.Tools.Inputfile
#* **************************************************************************
#*
#* CDTK, Chemical Dynamics Toolkit
#* A modular system for chemical dynamics applications and more
#*
#* Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016
#* Oriol Vendrell, DESY, <oriol.vendrell@desy.de>
#*
#* Copyright (C) 2017, 2018, 2019
#* Ralph Welsch, DESY, <ralph.welsch@desy.de>
#*
#* Copyright (C) 2020, 2021, 2022, 2023
#* Ludger Inhester, DESY, ludger.inhester@cfel.de
#*
#* This file is part of CDTK.
#*
#* CDTK is free software: you can redistribute it and/or modify
#* it under the terms of the GNU General Public License as published by
#* the Free Software Foundation, either version 3 of the License, or
#* (at your option) any later version.
#*
#* This program is distributed in the hope that it will be useful,
#* but WITHOUT ANY WARRANTY; without even the implied warranty of
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#* GNU General Public License for more details.
#*
#* You should have received a copy of the GNU General Public License
#* along with this program. If not, see <http://www.gnu.org/licenses/>.
#*
#* **************************************************************************
import sys
[docs]
class Inputfile(object):
"""
Read and store the contents of an input file
"""
def __init__(self,fname=None,**args):
self.filename = fname
self.sections = {}
self._readfile()
def _readfile(self,**args):
if self.filename is None:
raise ValueError('Inputfile: no file to read')
else:
self._openfile()
self._read_sections()
for sect in self._sections:
name = sect[0]
if name[0:4] == 'cart' or name[0:4] == 'nmco': # process Cartesian geometry
process_func = self._process_cart
else:
try:
process_func = getattr(self,'_process_'+name)
except:
process_func = self._process_default
self.sections[name] = process_func(sect[1:])
def _openfile(self,**args):
try:
self.fileunit = open(self.filename,'r')
except:
sys.stderr.write('\n Inputfile: could not open ' + self.filename)
sys.exit(1)
def _read_sections(self):
self.fileunit.seek(0)
self._sections = []
line = self.fileunit.readline()
while line:
if line[0] == '#':
line = self.fileunit.readline()
continue
if line.split() == []: # detects empty lines
line = self.fileunit.readline()
continue
if line[0] == '$':
sec = _cleanstr(line[1:]).lower()
if sec != 'end':
self._sections.append([sec]+self._section_list())
line = self.fileunit.readline()
def _section_list(self):
seclist = []
line = self.fileunit.readline()
while line:
if line[0] == '#':
line = self.fileunit.readline()
continue
if line.split() == []: # detects empty lines
line = self.fileunit.readline()
continue
if line[0] == '$':
sec = _cleanstr(line[1:]).lower()
if sec == 'end':
return seclist
else:
raise ValueError('$end forgotten at end of section?')
seclist.append(line)
line = self.fileunit.readline()
raise ValueError('$end forgotten at end of section?')
def _process_default(self,seclist):
dsection = {}
for line in seclist:
ls = line.split('=')
keyword = ls[0].strip().lower()
try:
value = ls[1].split()
except:
value = None
if value:
vlist = []
for v in value:
vlist.append(v.strip())
value = vlist
dsection[keyword] = value
return dsection
def _process_cart(self,seclist):
dsection = {}
atomlist = []
coordinates = []
for line in seclist:
ls = line.split()
atomlist.append(ls[0])
for x in ls[1:]:
coordinates.append( float(x) )
dsection['atomlist'] = atomlist
dsection['coordinates'] = coordinates
return dsection
def _process_secname(self,seclist):
# modify this function to read a specific input section.
# The section must be called "secname", where secname is a
# name of your choice.
# Alternatively one can specialize this class through inheritance.
dsection = {}
for line in seclist:
ls = line.split('=')
keyword = _cleanstr(ls[0]).lower()
try:
value = _cleanstr(ls[1])
except:
value = None
dsection[keyword] = value
return dsection
def _cleanstr(s):
"""
remove blanks around 1st word in string
"""
return s.split()[0]