1#!/usr/bin/env python 2# Copyright 2014-2018,2021 The PySCF Developers. All Rights Reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15# 16# Author: Timothy Berkelbach <tim.berkelbach@gmail.com> 17# 18 19''' 20parse CP2K format 21''' 22 23import re 24from pyscf.gto.basis import parse_nwchem 25from pyscf import __config__ 26 27DISABLE_EVAL = getattr(__config__, 'DISABLE_EVAL', False) 28 29MAXL = 8 30 31def parse(string, optimize=False): 32 '''Parse the basis text which is in CP2K format, return an internal 33 basis format which can be assigned to :attr:`Mole.basis` 34 Lines started with # are ignored. 35 ''' 36 bastxt = [] 37 for dat in string.splitlines(): 38 x = dat.split('#')[0].strip() 39 if (x and not x.startswith('END') and not x.startswith('BASIS')): 40 bastxt.append(x) 41 return _parse(bastxt, optimize) 42 43def load(basisfile, symb, optimize=False): 44 return _parse(search_seg(basisfile, symb), optimize) 45 46def _parse(blines, optimize=False): 47 header_ln = blines.pop(0) # noqa: F841 48 nsets = int(blines.pop(0)) 49 basis = [] 50 for n in range(nsets): 51 comp = [int(p) for p in blines.pop(0).split()] 52 lmin, lmax, nexps, ncontractions = comp[1], comp[2], comp[3], comp[4:] 53 basis_n = [[l] for l in range(lmin,lmax+1)] 54 for nexp in range(nexps): 55 line = blines.pop(0) 56 dat = line.split() 57 try: 58 bfun = [float(x) for x in dat] 59 except ValueError: 60 if DISABLE_EVAL: 61 raise ValueError('Failed to parse basis %s' % line) 62 else: 63 bfun = eval(','.join(dat)) 64 exp = bfun.pop(0) 65 for i,l in enumerate(range(lmin,lmax+1)): 66 cl = [exp] 67 for c in range(ncontractions[i]): 68 cl.append(bfun.pop(0)) 69 basis_n[i].append(tuple(cl)) 70 basis.extend(basis_n) 71 basis_sorted = [] 72 for l in range(MAXL): 73 basis_sorted.extend([b for b in basis if b[0] == l]) 74 75 if optimize: 76 basis_sorted = parse_nwchem.optimize_contraction(basis_sorted) 77 78 basis_sorted = parse_nwchem.remove_zero(basis_sorted) 79 return basis_sorted 80 81BASIS_SET_DELIMITER = re.compile('# *BASIS SET.*\n') 82def search_seg(basisfile, symb): 83 with open(basisfile, 'r') as fin: 84 fdata = re.split(BASIS_SET_DELIMITER, fin.read()) 85 for dat in fdata[1:]: 86 dat0 = dat.split(None, 1) 87 if dat0 and dat0[0] == symb: 88 # remove blank lines 89 return [x.strip() for x in dat.splitlines() 90 if x.strip() and 'END' not in x] 91 raise RuntimeError('Basis not found for %s in %s' % (symb, basisfile)) 92 93 94