def opt_zmatrix(output_string): """ get optimized z-matrix geometry from output """ # read the matrix from the beginning of the output syms, key_mat, name_mat = ar.zmatrix.matrix.read( output_string, start_ptt=app.maybe(app.SPACES).join( ['geometry', app.escape('='), app.escape('{'), '']), entry_start_ptt=app.maybe(','), entry_sep_ptt=',', last=False, case=False) # read the initial z-matrix values from the beginning out the output if len(syms) == 1: val_dct = {} else: val_dct = ar.zmatrix.setval.read( output_string, entry_start_ptt='SETTING', val_ptt=app.one_of_these([app.EXPONENTIAL_FLOAT_D, app.NUMBER]), last=False, case=False) names = sorted(set(numpy.ravel(name_mat)) - {None}) caps_names = list(map(str.upper, names)) name_dct = dict(zip(caps_names, names)) assert set(caps_names) <= set(val_dct) val_dct = { name_dct[caps_name]: val_dct[caps_name] for caps_name in caps_names } # read optimized z-matrix values from the end of the output opt_val_dct = ar.zmatrix.setval.read( output_string, start_ptt=app.padded('Optimized variables') + app.NEWLINE, entry_end_ptt=app.one_of_these(['ANGSTROM', 'DEGREE']), last=True, case=False) opt_val_dct = { name_dct[caps_name]: opt_val_dct[caps_name] for caps_name in opt_val_dct.keys() } assert set(opt_val_dct) <= set(val_dct) val_dct.update(opt_val_dct) # call the automol constructor zma = automol.zmatrix.from_data(syms, key_mat, name_mat, val_dct, one_indexed=True, angstrom=True, degree=True) return zma
def _mp2_energy(output_string): ene = ar.energy.read( output_string, app.one_of_these([ app.escape('MP2 TOTAL ENERGY:'), app.LINESPACES.join([ app.escape('Initial E(tot)'), '...']) ])) return ene
def _has_opt_convergence_message(output_string): """ does this output string have a convergence success message? """ pattern = ( app.escape('Optimization completed.') + app.LINE_FILL + app.NEWLINE + app.LINE_FILL + app.escape('-- Stationary point found.') ) return apf.has_match(pattern, output_string, case=False)
def _hf_energy(output_string): ene = ar.energy.read( output_string, app.one_of_these([ app.escape('E(RHF) ='), app.escape('E(UHF) ='), app.escape('E(ROHF) =') ])) return ene
def _ccsdt_energy(output_string): ene = ar.energy.read( output_string, app.one_of_these([ app.LINESPACES.join( [app.escape('!CCSDT STATE'), app.FLOAT, app.escape('Energy')]), ])) return ene
def _check_name_string(output_str): """ checks to see if the cfour program string is in the output """ pattern = (app.escape('* CFOUR Coupled-Cluster techniques ') + app.escape('for Computational Chemistry *')) prog_string = apf.has_match(pattern, output_str) return prog_string
def _doub_hyb_dft_energy(output_string): e_pattern = (app.escape('E') + app.maybe('2') + app.escape('(') + app.one_of_these([dft.upper() for dft in DOUB_HYB_DFT]) + app.escape(')')) dft_pattern = (e_pattern + app.SPACES + '=' + app.SPACES + app.EXPONENTIAL_FLOAT_D + app.SPACES + e_pattern + app.SPACES + '=') ene = ar.energy.read(output_string, start_ptt=dft_pattern) return ene
def _has_scf_convergence_message(output_string): """ does this output string have a convergence success message? """ scf_str1 = ( 'Initial convergence to {} achieved. Increase integral accuracy.' + app.LINE_FILL + app.NEWLINE + app.LINE_FILL + app.escape('SCF Done:') ).format(app.EXPONENTIAL_FLOAT_D) scf_str2 = app.escape('Rotation gradient small -- convergence achieved.') pattern = app.one_of_these([scf_str1, scf_str2]) return apf.has_match(pattern, output_string, case=False)
def test__geom(): """ test autoread.geom """ start_ptt = (app.padded(app.NEWLINE).join([ app.escape('Standard orientation:'), app.LINE, app.LINE, app.LINE, app.LINE, '' ])) nums, xyzs = autoread.geom.read( GEO1_STR, start_ptt=start_ptt, symb_ptt=app.UNSIGNED_INTEGER, line_start_ptt=app.UNSIGNED_INTEGER, line_sep_ptt=app.UNSIGNED_INTEGER, ) assert nums == (8, 8, 1, 1) assert xyzs == ((-0.0, 0.723527, -0.046053), (0.0, -0.723527, -0.046053), (0.876174, 0.838634, 0.368421), (-0.876174, -0.838634, 0.368421)) start_ptt = (app.padded(app.NEWLINE).join( [app.escape('Final (previous) structure:'), app.LINE, ''])) symbs, xyzs = autoread.geom.read(GEO2_STR, start_ptt=start_ptt) assert symbs == ('O', 'O', 'H', 'H') assert xyzs == ((0.0, 0.7028389815, 0.0245676525), (0.0, -0.7028389815, 0.0245676525), (-0.8761735478, 0.8179459165, -0.389906474), (0.8761735478, -0.8179459165, -0.389906474)) start_ptt = (app.padded(app.NEWLINE).join( [app.escape('ATOMIC COORDINATES'), app.LINE, app.LINE, app.LINE, ''])) symbs, xyzs = autoread.geom.read( GEO3_STR, start_ptt=start_ptt, line_start_ptt=app.UNSIGNED_INTEGER, line_sep_ptt=app.FLOAT, ) assert symbs == ('O', 'H', 'H') assert xyzs == ((0.0, 0.0, -0.109999068), (0.0, -1.635000492, 0.875999553), (0.0, 1.635000492, 0.875999553)) symbs, xyzs = autoread.geom.read_xyz(XYZ_STR) assert symbs == ('O', 'O', 'H', 'H') assert xyzs == ((0.0, 0.7028389815, 0.0245676525), (0.0, -0.7028389815, 0.0245676525), (-0.8761735478, 0.8179459165, -0.389906474), (0.8761735478, -0.8179459165, -0.389906474)) with pytest.raises(ValueError): symbs, xyzs = autoread.geom.read_xyz(BAD_XYZ_STR)
def _get_targets_section(input_string): """ grabs the section of text containing all of the targets """ pattern = (escape('$targets') + LINE_FILL + NEWLINE + capturing(one_or_more(WILDCARD, greedy=False)) + escape('$end')) section = first_capture(pattern, input_string) assert section is not None return section
def paren_block_ptt(key=None): """ Build a regex pattern to search for a keyword and its value, defined as key = (value) :param key: string for a specific key to find :type key: str :rtype: str """ keywrd = key if key is not None else app.one_or_more(app.NONSPACE) return (app.capturing(keywrd) + app.SPACES + app.escape('=') + app.SPACES + app.escape('(') + FULL_BLOCK_PTT + app.escape(')'))
def test__energy(): """ test autoread.energy """ ene = autoread.energy.read(ENE1_STR, app.escape('@RKS Final Energy:')) assert ene == -149.44268093948725 ene = autoread.energy.read(ENE1_STR, app.escape('@UKS Final Energy:')) assert ene is None ene = autoread.energy.read(ENE2_STR, app.escape('E(RB3LYP) =')) assert ene == -149.442473330
def low_p_parameters(rxn_dstr): """ low-pressure parameters """ pattern = ('LOW' + app.zero_or_more(app.SPACE) + app.escape('/') + app.SPACES + app.capturing(app.NUMBER) + app.SPACES + app.capturing(app.NUMBER) + app.SPACES + app.capturing(app.NUMBER) + app.zero_or_more(app.SPACE) + app.escape('/')) params = apf.first_capture(pattern, rxn_dstr) if params is not None: params = [float(val) for val in params] return params
def _get_lennard_jones_options_section(input_string): """ grabs the section of text containing all of the job keywords for lennard jones calculations """ pattern = (escape('$lennard_jones') + LINE_FILL + NEWLINE + capturing(one_or_more(WILDCARD, greedy=False)) + escape('$end')) section = first_capture(pattern, input_string) assert section is not None return section
def _ccsd_t_energy(output_string): ene = ar.energy.read( output_string, app.one_of_these([ app.escape('!CCSD(T) total energy') + app.maybe(':'), app.escape('!RHF-UCCSD(T) energy'), app.LINESPACES.join([ app.escape('!CCSD(T) STATE'), app.FLOAT, app.escape('Energy') ]), ])) return ene
def options_matrix_optimization(script_str, prefix, # geom, species_info, theory_level, geom, chg, mul, method, basis, prog, errors=(), options_mat=(), feedback=False, frozen_coordinates=(), freeze_dummy_atoms=True, **kwargs): """ try several sets of options to generate an output file :returns: the input string and the output string :rtype: (str, str) """ assert len(errors) == len(options_mat) subrun_fs = autofile.fs.subrun(prefix) max_macro_idx, _ = max(subrun_fs.leaf.existing(), default=(-1, -1)) macro_idx = max_macro_idx + 1 micro_idx = 0 read_geom_ = (elstruct.reader.opt_zmatrix_(prog) if automol.zmatrix.is_valid(geom) else elstruct.reader.opt_geometry_(prog)) if freeze_dummy_atoms and automol.zmatrix.is_valid(geom): frozen_coordinates = (tuple(frozen_coordinates) + automol.zmatrix.dummy_coordinate_names(geom)) kwargs_ = dict(kwargs) while True: subrun_fs.leaf.create([macro_idx, micro_idx]) path = subrun_fs.leaf.path([macro_idx, micro_idx]) with warnings.catch_warnings(): warnings.simplefilter('ignore') inp_str, out_str = elstruct.run.direct( elstruct.writer.optimization, script_str, path, # geom=geom, species_info, theory_level, # basis=basis, frozen_coordinates=frozen_coordinates, geom=geom, charge=chg, mult=mul, method=method, basis=basis, prog=prog, frozen_coordinates=frozen_coordinates, **kwargs_) error_vals = [elstruct.reader.has_error_message(prog, error, out_str) for error in errors] # Kill the while loop if we Molpro error signaling a hopeless point # When an MCSCF WF calculation fails to converge at some step in opt # it is not clear how to save the optimization, so we give up on opt fail_pattern = app.one_of_these([ app.escape('The problem occurs in Multi'), app.escape('The problem occurs in cipro') ]) if apf.has_match(fail_pattern, out_str, case=False):
def symb_block_ptt(symb, header): """ Read the string that has the global model information can also capture with the name if needed... {symb}{header} DATA {symb}end """ # Set the top and bottom of the end block pattern top_ptt = app.escape(symb) + app.capturing(header) bot_ptt = app.escape(symb) + 'end' return top_ptt + FULL_BLOCK_PTT + bot_ptt
def troe_parameters(rxn_dstr): """ troe parameters """ pattern = ('TROE' + app.zero_or_more(app.SPACE) + app.escape('/') + app.SPACES + app.capturing(app.NUMBER) + app.SPACES + app.capturing(app.NUMBER) + app.SPACES + app.capturing(app.NUMBER) + app.SPACES + app.maybe(app.capturing(app.NUMBER)) + app.zero_or_more(app.SPACE) + app.escape('/')) params = apf.first_capture(pattern, rxn_dstr) if params is not None: params = [float(val) for val in params] return params
def data_strings(block_str): """ thermo strings """ headline_pattern = (app.LINE_START + app.not_followed_by( app.one_of_these([app.DIGIT, app.PLUS, app.escape('=')])) + app.one_or_more(app.NONNEWLINE) + app.escape('1') + app.LINE_END) thm_strs = headlined_sections( string=block_str.strip(), headline_pattern=headline_pattern, ) return thm_strs
def gradient(output_string): """ read gradient from the output string """ head_ptt = ('Atom' + app.SPACES + app.escape('dE/dx') + app.SPACES + app.escape('dE/dy') + app.SPACES + app.escape('dE/dz')) grad = ar.matrix.read(output_string, start_ptt=app.padded(app.NEWLINE).join([ app.padded(head_ptt, app.NONNEWLINE), app.LINE, '' ]), line_start_ptt=app.UNSIGNED_INTEGER) assert numpy.shape(grad)[1] == 3 return grad
def test__setval(): """ test autoread.zmat.setval """ val_dct = autoread.setval.read(ZMA_VAL1_STR) assert val_dct == { 'A2': 96.772572, 'D3': 129.366995, 'R1': 1.4470582953, 'R2': 0.976073} start_ptt = app.padded(app.NEWLINE).join([ app.escape('! Optimized Parameters !'), app.LINE, app.LINE, app.LINE, app.LINE, '']) val_dct = autoread.setval.read( ZMA_VAL2_STR, start_ptt=start_ptt, entry_sep_ptt='', entry_start_ptt=app.escape('!'), sep_ptt=app.maybe(app.LINESPACES).join([ app.escape('-DE/DX ='), app.FLOAT, app.escape('!'), app.NEWLINE])) assert val_dct == { 'R1': 1.4057, 'R2': 0.9761, 'A2': 96.7726, 'D3': 129.367} val_dct = autoread.setval.read( ZMA_VAL3_STR, sep_ptt=app.one_of_these(['', app.NEWLINE])) assert val_dct == { 'R1': 2.73454, 'R2': 1.84451, 'A2': 96.7726, 'R3': 1.84451, 'A3': 96.7726, 'D3': 129.367} val_dct = autoread.setval.read( ZMA_VAL4_STR, entry_start_ptt='SETTING', val_ptt=app.one_of_these([app.EXPONENTIAL_FLOAT_D, app.NUMBER]), last=False, case=False) assert val_dct == { 'R1': 1.375861, 'R2': 1.058354, 'A2': 108.861981, 'R3': 1.058354, 'A3': 108.861981, 'D3': 120.321137, 'R4': 1.058354, 'A4': 108.861981, 'D4': 234.912696, 'R5': 0.952519, 'A5': 103.132403, 'D5': 297.938053, 'SPIN': '0.00000000D+00', 'CHARGE': '0.00000000D+00'} val_dct = autoread.setval.read( ZMA_VAL5_STR, start_ptt=app.padded('Optimized variables') + app.NEWLINE, entry_end_ptt=app.one_of_these(['ANGSTROM', 'DEGREE']), last=True, case=False) assert val_dct == { 'R1': 1.43218364, 'R2': 1.09538054, 'A2': 112.03775543, 'R3': 1.09538307, 'A3': 112.04463832, 'R4': 1.09084803, 'A4': 108.31761858, 'D4': 240.16203078, 'D5': 299.84441753}
def opt_zmatrix(output_string): """ get optimized z-matrix geometry from output """ # read the matrix from the beginning of the output syms, key_mat, name_mat = ar.zmatrix.matrix.read( output_string, start_ptt=app.padded(app.NEWLINE).join( [app.escape('Symbolic Z-matrix:'), app.LINE, '']), sym_ptt=ar.par.Pattern.ATOM_SYMBOL + app.maybe(app.UNSIGNED_INTEGER), key_ptt=app.one_of_these([app.UNSIGNED_INTEGER, app.VARIABLE_NAME]), line_end_ptt=app.maybe(app.UNSIGNED_INTEGER), last=False) # read the values from the end of the output if len(syms) == 1: val_dct = {} else: val_dct = ar.zmatrix.setval.read( output_string, start_ptt=app.padded(app.NEWLINE).join([ app.padded('Optimized Parameters', app.NONNEWLINE), app.LINE, app.LINE, app.LINE, app.LINE, '' ]), entry_sep_ptt='', entry_start_ptt=app.escape('!'), sep_ptt=app.maybe(app.LINESPACES).join([ app.escape('-DE/DX ='), app.FLOAT, app.escape('!'), app.NEWLINE ]), last=True) # for the case when variable names are used instead of integer keys: # (otherwise, does nothing) key_dct = dict(map(reversed, enumerate(syms))) key_dct[None] = 0 key_mat = [[ key_dct[val] + 1 if not isinstance(val, numbers.Real) else val for val in row ] for row in key_mat] sym_ptt = app.STRING_START + app.capturing(ar.par.Pattern.ATOM_SYMBOL) syms = [apf.first_capture(sym_ptt, sym) for sym in syms] # call the automol constructor zma = automol.zmatrix.from_data(syms, key_mat, name_mat, val_dct, one_indexed=True, angstrom=True, degree=True) return zma
def _has_opt_convergence_message(output_str): """ Assess whether the output file string contains the message signaling successful convergence of the geometry optimization. :param output_str: string of the program's output file :type output_str: str :rtype: bool """ pattern = (app.escape('Optimization completed.') + app.LINE_FILL + app.NEWLINE + app.LINE_FILL + app.escape('-- Stationary point found.')) return apf.has_match(pattern, output_str, case=False)
def has_normal_exit_message(output_str): """ Assess whether the output file string contains the normal program exit message. :param output_str: string of the program's output file :type output_str: str :rtype: bool """ pattern = app.padded(app.NEWLINE).join([ app.escape('Molpro calculation terminated'), app.escape('Variable memory released')]) return apf.has_match(pattern, output_str, case=False)
def _hf_energy(output_str): """ Reads the Hartree-Fock energy from the output file string. Returns the energy in Hartrees. :param output_str: string of the program's output file :type output_str: str :rtype: float """ ene = ar.energy.read( output_str, app.one_of_these([app.escape('E(SCF)='), app.escape('E(ROHF)=')])) return ene
def _dft_energy(output_str): """ Reads the energy from most density functional theory methods from the output file string. Returns the energy in Hartrees. :param output_str: string of the program's output file :type output_str: str :rtype: float """ e_pattern = app.escape('E(') + app.VARIABLE_NAME + app.escape(')') ene = ar.energy.read(output_str, start_ptt=app.LINESPACES.join( ['SCF Done:', e_pattern, '='])) return ene
def vibro_rot_alpha_matrix_reader(output_string): """ Get the Vibration-Rotation Alpha Matrix """ begin_string = 'Vibro-Rot alpha Matrix (in cm^-1)' end_string = app.escape('Q( ') + app.UNSIGNED_INTEGER + app.escape(')') vib_rot_mat = ar.matrix.read(output_string, start_ptt=app.padded(app.NEWLINE).join([ app.padded(app.escape(begin_string), app.NONNEWLINE), app.LINE, app.LINE, '' ]), line_start_ptt=end_string) return vib_rot_mat
def _has_scf_nonconvergence_error_message(output_str): """ Assess whether the output file string contains the message signaling the failure of the SCF procedure. :param output_str: string of the program's output file :type output_str: str :rtype: bool """ pattern = app.padded(app.NEWLINE).join([ app.escape('Convergence criterion not met.'), app.escape('SCF Done:') ]) return apf.has_match(pattern, output_str, case=False)
def _has_opt_nonconvergence_error_message(output_str): """ Assess whether the output file string contains the message signaling the failure of the geometry optimization. :param output_str: string of the program's output file :type output_str: str :rtype: bool """ pattern = app.padded(app.NEWLINE).join([ app.escape('Optimization stopped.'), app.escape('-- Number of steps exceeded,') ]) return apf.has_match(pattern, output_str, case=False)
def get_pes_info(rxn_str): """ Get PES info """ ptt = (app.escape('#') + app.SPACES + 'pes.subpes.channel' + app.SPACES + app.capturing(app.INTEGER + app.escape('.') + app.INTEGER + app.escape('.') + app.INTEGER)) cap = apf.first_capture(ptt, rxn_str) if cap is not None: pes_inf = tuple(int(x) - 1 for x in cap.strip().split('.')) else: pes_inf = None return pes_inf