def parse_ecp(string, symb=None): if symb is not None: symb = _std_symbol(symb) raw_data = string.splitlines() for i, dat in enumerate(raw_data): dat0 = dat.split(None, 1) if dat0 and dat0[0] == symb: break if i + 1 == len(raw_data): raise BasisNotFoundError('ECP not found for %s' % symb) seg = [] for dat in raw_data[i:]: dat = dat.strip().upper() if dat: # remove empty lines if ((dat[0].isalpha() and dat.split(None, 1)[0] != symb.upper())): break else: seg.append(dat) else: seg = string.splitlines() ecptxt = [] for dat in seg: x = dat.split('#')[0].strip().upper() if (x and not x.startswith('END') and not x.startswith('ECP')): ecptxt.append(x) return _parse_ecp(ecptxt)
def _parse(raw_basis, optimize=True): basis_add = [] for line in raw_basis: dat = line.strip() if not dat or dat.startswith('#'): continue elif dat[0].isalpha(): key = dat.split()[1] if key == 'SP': basis_add.append([0]) basis_add.append([1]) else: basis_add.append([MAPSPDF[key]]) else: try: line = [float(x) for x in dat.replace('D', 'e').split()] except Exception as e: raise BasisNotFoundError( '\n' + str(e) + '\nor the required basis file not existed.') if key == '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 optimize: basis_sorted = optimize_contraction(basis_sorted) basis_sorted = remove_zero(basis_sorted) return basis_sorted
def parse(string, symb=None, optimize=True): '''Parse the basis text which is in NWChem format. Return an internal basis format which can be assigned to attribute :attr:`Mole.basis` Empty lines, or the lines started with #, or the lines of "BASIS SET" and "END" will be ignored are ignored. Args: string : A string in NWChem basis format. Empty links and the lines of "BASIS SET" and "END" will be ignored Kwargs: optimize : Optimize basis contraction. Convert the segment contracted basis to the general contracted basis. Examples: >>> mol = gto.Mole() >>> mol.basis = {'O': gto.basis.parse(""" ... #BASIS SET: (6s,3p) -> [2s,1p] ... C S ... 71.6168370 0.15432897 ... 13.0450960 0.53532814 ... 3.5305122 0.44463454 ... C SP ... 2.9412494 -0.09996723 0.15591627 ... 0.6834831 0.39951283 0.60768372 ... 0.2222899 0.70011547 0.39195739 ... """)} >>> gto.basis.parse(""" ... He S ... 13.6267000 0.1752300 ... 1.9993500 0.8934830 ... 0.3829930 0.0000000 ... He S ... 13.6267000 0.0000000 ... 1.9993500 0.0000000 ... 0.3829930 1.0000000 ... """, optimize=True) [[0, [13.6267, 0.17523, 0.0], [1.99935, 0.893483, 0.0], [0.382993, 0.0, 1.0]]] ''' if symb is not None: symb = _std_symbol(symb) string = _search_basis_block(re.split(BASIS_SET_DELIMITER, string), symb) if not string: raise BasisNotFoundError('Basis not found for %s' % symb) raw_basis = [] for dat in string.splitlines(): dat = dat.split('#')[0].strip() # Use # to start comments dat_upper = dat.upper() if (dat and not dat_upper.startswith('END') and not dat_upper.startswith('BASIS')): raw_basis.append(dat) return _parse(raw_basis, optimize)
def search_seg(basisfile, symb): with open(basisfile, 'r') as fin: # ignore head dat = fin.readline().lstrip(' ') while dat.startswith('#'): dat = fin.readline().lstrip(' ') # searching while dat: if dat[:-1].rstrip(' ') == symb: seg = [] fin.readline() # pass the "back to top" mark while (dat and not dat.startswith('back to top')): seg.append(dat) dat = fin.readline().lstrip(' ') return seg[:-1] dat = fin.readline().lstrip(' ') raise BasisNotFoundError('Basis not found for %s in %s' % (symb, basisfile))
def _parse(raw_basis, optimize=True): basis_parsed = [[] for l in range(MAXL)] key = None for line in raw_basis: dat = line.strip() if not dat or dat.startswith('#'): continue elif dat[0].isalpha(): key = dat.split()[1].upper() if key == 'SP': basis_parsed[0].append([0]) basis_parsed[1].append([1]) else: l = MAPSPDF[key] current_basis = [l] basis_parsed[l].append(current_basis) else: dat = dat.replace('D','e').split() try: dat = [float(x) for x in dat] except ValueError: if DISABLE_EVAL: raise ValueError('Failed to parse basis %s' % line) else: dat = list(eval(','.join(dat))) except Exception as e: raise BasisNotFoundError('\n' + str(e) + '\nor the required basis file not existed.') if key is None: raise RuntimeError('Failed to parse basis') elif key == 'SP': basis_parsed[0][-1].append([dat[0], dat[1]]) basis_parsed[1][-1].append([dat[0], dat[2]]) else: current_basis.append(dat) basis_sorted = [b for bs in basis_parsed for b in bs] if optimize: basis_sorted = optimize_contraction(basis_sorted) basis_sorted = remove_zero(basis_sorted) return basis_sorted
def load(filename_or_basisname, symb, optimize=OPTIMIZE_CONTRACTION): '''Convert the basis of the given symbol to internal format Args: filename_or_basisname : str Case insensitive basis set name. Special characters will be removed. or a string of "path/to/file" which stores the basis functions symb : str Atomic symbol, Special characters will be removed. Examples: Load STO 3G basis of carbon to oxygen atom >>> mol = gto.Mole() >>> mol.basis = {'O': load('sto-3g', 'C')} ''' symb = ''.join([i for i in symb if i.isalpha()]) if os.path.isfile(filename_or_basisname): # read basis from given file try: return parse_nwchem.load(filename_or_basisname, symb, optimize) except BasisNotFoundError: with open(filename_or_basisname, 'r') as fin: return parse_nwchem.parse(fin.read(), symb) name = _format_basis_name(filename_or_basisname) if '@' in name: split_name = name.split('@') assert len(split_name) == 2 name = split_name[0] contr_scheme = _convert_contraction(split_name[1]) else: contr_scheme = 'Full' if not (name in ALIAS or _is_pople_basis(name)): try: return parse_nwchem.parse(filename_or_basisname, symb) except BasisNotFoundError: try: return parse_nwchem.parse(filename_or_basisname) except IndexError: raise BasisNotFoundError('Invalid basis name %s' % filename_or_basisname) except IndexError: raise BasisNotFoundError(filename_or_basisname) if name in ALIAS: basmod = ALIAS[name] elif _is_pople_basis(name): basmod = _parse_pople_basis(name, symb) else: raise BasisNotFoundError(filename_or_basisname) if 'dat' in basmod: b = parse_nwchem.load(join(_BASIS_DIR, basmod), symb, optimize) elif isinstance(basmod, (tuple, list)) and isinstance(basmod[0], str): b = [] for f in basmod: b += parse_nwchem.load(join(_BASIS_DIR, f), symb, optimize) else: if sys.version_info < (2, 7): fp, pathname, description = imp.find_module(basmod, __path__) mod = imp.load_module(name, fp, pathname, description) b = mod.__getattribute__(symb) fp.close() else: mod = importlib.import_module('.' + basmod, __package__) b = mod.__getattribute__(symb) if contr_scheme != 'Full': b = _truncate(b, contr_scheme, symb, split_name) return b