Source code for pyscf.gto.basis.parse_gaussian

#!/usr/bin/env python
# Copyright 2014-2020 The PySCF Developers. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author: Qiming Sun <osirpt.sun@gmail.com>
#

'''
Parsers for basis set in Gaussian program format
'''

__all__ = ['parse', 'load']

try:
    from pyscf.gto.basis.parse_nwchem import optimize_contraction
    from pyscf.gto.basis.parse_nwchem import remove_zero
except ImportError:
    optimize_contraction = lambda basis: basis
    remove_zero = lambda basis: basis
from pyscf.lib.exceptions import BasisNotFoundError

MAXL = 12
SPDF = 'SPDFGHIJKLMN'
MAPSPDF = {key: l for l, key in enumerate(SPDF)}

DELIMETER = '****'

[docs] def parse(string, optimize=True): '''Parse the basis text which is in NWChem format, return an internal basis format which can be assigned to :attr:`Mole.basis` Lines started with # are ignored. ''' raw_basis = [] for dat in string.splitlines(): x = dat.split('!', 1)[0].strip() if x and x != DELIMETER: raw_basis.append(x) return _parse(raw_basis, optimize)
[docs] def load(basisfile, symb, optimize=True): raw_basis = search_seg(basisfile, symb) #if not raw_basis: # raise BasisNotFoundError('Basis not found for %s in %s' % (symb, basisfile)) return _parse(raw_basis, optimize)
def search_seg(basisfile, symb): with open(basisfile, 'r') as fin: def _seek(test_str): raw_basis = [] dat = fin.readline() while dat: if test_str in dat: return True, raw_basis elif dat.strip(): # Skip empty lines raw_basis.append(dat) dat = fin.readline() return False, raw_basis has_delimeter, raw_basis = _seek(DELIMETER) if has_delimeter: dat = fin.readline() while dat: if dat.strip().split(' ', 1)[0].upper() == symb.upper(): raw_basis = _seek(DELIMETER)[1] break else: _seek(DELIMETER) dat = fin.readline() return raw_basis def _parse(raw_basis, optimize=True): basis_add = [] for line in raw_basis: dat = line.strip() if dat.startswith('!'): continue elif dat[0].isalpha(): key = dat.split() if len(key) == 2: # skip the line which has only two items. It's the line for # element symbol continue elif key[0] == 'SP': basis_add.append([0]) basis_add.append([1]) elif len(key[0])>2 and key[0][:2] in ['l=', 'L=']: # Angular momentum defined explicitly basis_add.append([int(key[0][2:])]) else: basis_add.append([MAPSPDF[key[0]]]) else: line = [float(x) for x in dat.replace('D','e').split()] if key[0] == 'SP': basis_add[-2].append([line[0], line[1]]) basis_add[-1].append([line[0], line[2]]) else: basis_add[-1].append(line) basis_sorted = [] for l in range(MAXL): basis_sorted.extend([b for b in basis_add if b[0] == l]) if not basis_sorted: raise BasisNotFoundError(f'Basis data not found in "{raw_basis}"') if optimize: basis_sorted = optimize_contraction(basis_sorted) basis_sorted = remove_zero(basis_sorted) return basis_sorted if __name__ == '__main__': print(load('def2-qzvp-jkfit.gbs', 'C'))