예제 #1
0
def zero_point_vibrational_energies(output_str):
    """ Reads the zero-point energies for each of the
        hindered rotors from MESS output file string.

        :param output_str: string of lines of MESS output file
        :type output_str: str
        :return zpves: zero-point energy for each of the rotors
        :rtype: list(float)
    """

    # Patterns for the ZPVE of a rotor
    num_patterns = (app.EXPONENTIAL_FLOAT, app.FLOAT, app.INTEGER)
    pattern1 = (app.escape('minimum energy[kcal/mol]') +
                app.one_or_more(app.SPACE) + '=' + app.one_or_more(app.SPACE) +
                app.capturing(app.one_of_these(num_patterns)))

    pattern2 = (app.escape('ground energy [kcal/mol]') +
                app.one_or_more(app.SPACE) + '=' + app.one_or_more(app.SPACE) +
                app.capturing(app.one_of_these(num_patterns)))

    # Obtain each ZPVE from the output string
    tmp1 = tuple(-float(val) for val in apf.all_captures(pattern1, output_str))
    tmp2 = tuple(float(val) for val in apf.all_captures(pattern2, output_str))
    tors_zpves = [sum(tmp) for tmp in zip(tmp1, tmp2)]

    # Convert to Hartrees
    for i, _ in enumerate(tors_zpves):
        tors_zpves[i] *= phycon.KCAL2EH

    return tuple(tors_zpves)
예제 #2
0
def zpves(output_string):
    """ Reads the zero-point energies for each of the
        hindered rotors from MESS output file string.

        :param output_string: string of lines of MESS output file
        :type output_string: str
        :return zpves: zero-point energy for each of the rotors
        :rtype: list(float)
    """

    # Patterns for the ZPVE of a rotor
    num_patterns = (app.EXPONENTIAL_FLOAT, app.FLOAT)
    pattern1 = (app.escape('minimum energy[kcal/mol]') +
                app.one_or_more(app.SPACE) + '=' + app.one_or_more(app.SPACE) +
                app.capturing(app.one_of_these(num_patterns)))

    pattern2 = (app.escape('ground energy [kcal/mol]') +
                app.one_or_more(app.SPACE) + '=' + app.one_or_more(app.SPACE) +
                app.capturing(app.one_of_these(num_patterns)))

    # Obtain each ZPVE from the output string
    tmp1 = [-float(val) for val in apf.all_captures(pattern1, output_string)]
    tmp2 = [float(val) for val in apf.all_captures(pattern2, output_string)]
    tors_zpes = [sum(tmp) for tmp in zip(tmp1, tmp2)]
    # print('tors_zpes calc test:', tmp1, tmp2, tors_zpes)

    return tors_zpes
예제 #3
0
def anharmonic_frequencies_reader(output_string):
    """ Get the anharmonic vibrational frequencies
    """

    # block
    block = apf.last_capture(
        (app.escape('Fundamental Bands (DE w.r.t. Ground State)') +
         app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
         app.escape('Overtones (DE w.r.t. Ground State)')), output_string)

    pattern = (app.INTEGER + app.escape('(1)') + app.SPACE +
               app.maybe(app.one_or_more(app.LOWERCASE_LETTER)) +
               app.one_or_more(app.SPACE) + app.FLOAT +
               app.one_or_more(app.SPACE) + app.capturing(app.FLOAT) +
               app.one_or_more(app.SPACE) + app.FLOAT +
               app.one_or_more(app.SPACE) + app.FLOAT +
               app.one_or_more(app.SPACE) + app.FLOAT)
    pattern2 = (app.INTEGER + app.escape('(1)') + app.SPACE +
                app.maybe(app.one_or_more(app.LOWERCASE_LETTER)) +
                app.one_or_more(app.SPACE) + app.FLOAT +
                app.one_or_more(app.SPACE) + app.capturing(app.FLOAT) +
                app.one_or_more(app.SPACE) + app.one_or_more(app.escape('*')) +
                app.one_or_more(app.SPACE) + app.one_or_more(app.escape('*')) +
                app.one_or_more(app.SPACE) + app.FLOAT)

    # Get list of values
    anharm_freq = [float(val) for val in apf.all_captures(pattern, block)]
    if not anharm_freq:
        anharm_freq = [float(val) for val in apf.all_captures(pattern2, block)]

    return anharm_freq
예제 #4
0
def ratek_fit_info(rxn_dstr):
    """ Read the information describing features of the fits to the
        rate constants
    """

    # Read the temperatures and the Errors from the lines
    pressure_ptt = (
        'Pressure:' + app.SPACES +
        app.capturing(app.one_of_these([app.FLOAT, 'High']))
    )
    trange_ptt = (
        'Temps: ' + app.SPACES +
        app.capturing(app.INTEGER) + '-' + app.capturing(app.INTEGER) +
        app.SPACES + 'K'
    )
    mean_ptt = (
        'MeanAbsErr:' + app.SPACES +
        app.capturing(app.FLOAT) + app.escape('%') +
        ','
    )
    max_ptt = (
        'MaxErr:' + app.SPACES +
        app.capturing(app.FLOAT) + app.escape('%')
    )
    pressure_caps = apf.all_captures(pressure_ptt, rxn_dstr)
    trange_caps = apf.all_captures(trange_ptt, rxn_dstr)
    mean_caps = apf.all_captures(mean_ptt, rxn_dstr)
    max_caps = apf.all_captures(max_ptt, rxn_dstr)

    pressures = []
    for pressure in pressure_caps:
        if pressure != 'High':
            pressures.append(float(pressure))
        elif pressure == 'High':
            pressures.append(pressure)
    trange_vals = []
    for cap in trange_caps:
        temp1, temp2 = cap
        trange_vals.append([int(temp1), int(temp2)])
    if mean_caps is not None:
        mean_vals = [float(val) for val in mean_caps]
    else:
        mean_vals = []
    if max_caps is not None:
        max_vals = [float(val) for val in max_caps]
    else:
        max_vals = []

    # Build the inf_dct
    inf_dct = {}
    for idx, pressure in enumerate(pressures):
        inf_dct[pressure] = {'temps': trange_vals[idx]}
        if mean_vals:
            inf_dct[pressure].update({'mean_err': mean_vals[idx]})
        if max_vals:
            inf_dct[pressure].update({'max_err': max_vals[idx]})

    return inf_dct
예제 #5
0
def irc_path(output_str):
    """ Reads the coordinates and electronic energies (relative to saddple point)
        of the Intrinsic Reaction Coordinate.

        :param output_str: string of the program's output file
        :type output_str: str
        :rtype: tuple(automol geom data structure)
    """

    # coordinates
    block = apf.last_capture(
        (app.escape('@IRC              ****     IRC Steps     ****') +
         app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
         app.escape('---Fragment 1 Intrafragment Coordinates---')),
        output_str)

    pattern = (
        app.escape('@IRC') + app.SPACES + app.INTEGER + app.SPACES +
        app.FLOAT + app.SPACES +
        app.capturing(app.FLOAT) + app.SPACES +
        app.FLOAT + app.SPACES +
        app.LINE_FILL
    )

    captures = apf.all_captures(pattern, block)
    if captures is not None:
        # Remove duplicates that may appear because of Psi4 output printing
        unique_coords = []
        for coord in captures:
            if coord not in unique_coords:
                unique_coords.append(coord)
        coords = [float(coord) for coord in unique_coords]
    else:
        coords = None

    # energies
    block = apf.last_capture(
        (app.escape('@IRC            ****      IRC Report      ****') +
         app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
         app.escape('@IRC              ****     IRC Steps     ****')),
        output_str)

    pattern = (
        app.escape('@IRC') + app.SPACES + app.INTEGER + app.SPACES +
        app.capturing(app.FLOAT) + app.SPACES +
        app.FLOAT
    )

    captures = apf.all_captures(pattern, block)
    if captures is not None:
        energies = [float(capture) for capture in captures]
    else:
        energies = None

    return (coords, energies)
예제 #6
0
파일: _wells.py 프로젝트: Auto-Mech/autoio
def well_average_energy(log_str, well, temp):
    """ Obtain the average energy of each well from the output
        of MESS rate calculations.

        Returns the energies in hartrees.

        :param log_str: string of the MESS .log file
        :type log_str: str
        :param well: name of the well to get energy for
        :type well: str
        :param temp: temperature to get the energy for
        :type temp: float
        :rtype: dict[str: float]
    """

    # Loop through file to find the energy block with requested temp
    block_ptt = (
        'MasterEquation::set:  starts' +
        app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
        'MasterEquation::set:  done'
    )
    blocks = apf.all_captures(block_ptt, log_str)

    if blocks is not None:
        for i, block in enumerate(blocks):
            templine = block.splitlines()[1]
            blocktemp = float(templine.strip().split()[2])
            if numpy.isclose(blocktemp, temp, atol=0.01):
                block_idx = i
                break
    else:
        block_idx = None

    # If block with requested temp found, get energies
    ene_dct = None
    if block_idx is not None:
        ptt = (
            app.capturing(app.VARIABLE_NAME) + app.SPACE +
            'Well:' + app.SPACE +
            'average energy =' + app.SPACE +
            app.capturing(app.NUMBER) + app.SPACE +
            'kcal/mol'
        )
        caps = apf.all_captures(ptt, blocks[block_idx])
        ene_dct = dict(
            ((cap[0], float(cap[1])*phycon.KCAL2EH) for cap in caps)
        )
        ene = ene_dct[well]

    return ene
예제 #7
0
파일: surface.py 프로젝트: avcopan/elstruct
def irc_path(output_string):
    """ get the coordinates and energies relative to the saddle point
    """

    # coordinates 
    block = apf.last_capture(
        (app.escape('@IRC              ****     IRC Steps     ****') +
         app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
         app.escape('---Fragment 1 Intrafragment Coordinates---')),
        output_string)

    pattern = (
        app.escape('@IRC') + app.SPACES + app.INTEGER + app.SPACES +
        app.FLOAT + app.SPACES +
        app.capturing(app.FLOAT) + app.SPACES +
        app.FLOAT + app.SPACES +
        app.LINE_FILL
    )

    captures = apf.all_captures(pattern, block)
    if captures is not None:
        # Remove duplicates that may appear because of Psi4 output printing
        unique_coords = []
        for coord in captures:
            if coord not in unique_coords:
                unique_coords.append(coord)
        coords = [float(coord) for coord in unique_coords]
    else:
        coords = None

    # energies
    block = apf.last_capture(
        (app.escape('@IRC            ****      IRC Report      ****') +
         app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
         app.escape('@IRC              ****     IRC Steps     ****')),
        output_string)

    pattern = (
        app.escape('@IRC') + app.SPACES + app.INTEGER + app.SPACES +
        app.capturing(app.FLOAT) + app.SPACES +
        app.FLOAT
    )

    captures = apf.all_captures(pattern, block)
    if captures is not None:
        energies = [float(capture) for capture in captures]
    else:
        energies = None

    return (coords, energies)
예제 #8
0
def read_models_sections(job_path):
    """ species input
    """
    mod_str = ptt.read_inp_str(job_path, MODEL_INP, remove_comments='#')

    # Build a dictionary for the PES models
    pes_model_sections = apf.all_captures(ptt.end_section_wname2('pes_model'),
                                          mod_str)
    assert pes_model_sections is not None

    pes_model_methods = {}
    glob_pes_model_methods = {}
    for section in pes_model_sections:
        if section[0] == 'global':
            name = section[0]
            keyword_dct = build_pes_model_keyword_dct(section[1])
            glob_pes_model_methods = keyword_dct
            break
    pes_model_methods['global'] = glob_pes_model_methods
    for section in pes_model_sections:
        if section[0] != 'global':
            name = section[0]
            keyword_dct = build_pes_model_keyword_dct(section[1])
            pes_model_methods[name] = combine_glob_and_spc_dct(
                glob_pes_model_methods, keyword_dct)

    # Build a dictionary for the spc models
    spc_model_sections = apf.all_captures(ptt.end_section_wname2('spc_model'),
                                          mod_str)
    assert spc_model_sections is not None

    spc_model_methods = {}
    glob_spc_model_methods = {}
    for section in spc_model_sections:
        if section[0] == 'global':
            name = section[0]
            keyword_dct = build_spc_model_keyword_dct(section[1])
            glob_spc_model_methods = keyword_dct
            break
    spc_model_methods['global'] = glob_spc_model_methods
    for section in spc_model_sections:
        if section[0] != 'global':
            name = section[0]
            keyword_dct = build_spc_model_keyword_dct(section[1])
            spc_model_methods[name] = combine_glob_and_spc_dct(
                glob_spc_model_methods, keyword_dct)

    return pes_model_methods, spc_model_methods
예제 #9
0
def plog_parameters(rxn_dstr):
    """ gets parameters associated with plog strings
    """
    pattern = ('PLOG' + app.zero_or_more(app.SPACE) + app.escape('/') +
               app.zero_or_more(app.SPACE) + app.capturing(app.NUMBER) +
               app.one_or_more(app.SPACE) + app.capturing(app.NUMBER) +
               app.one_or_more(app.SPACE) + app.capturing(app.NUMBER) +
               app.one_or_more(app.SPACE) + app.capturing(app.NUMBER) +
               app.zero_or_more(app.SPACE) + app.escape('/'))
    params_lst = apf.all_captures(pattern, rxn_dstr)

    # Build dictionary of parameters, indexed by parameter
    if params_lst:
        params_dct = {}
        for params in params_lst:
            pressure = float(params[0])
            vals = list(map(float, params[1:]))
            params_dct[pressure] = vals
            # if pressure not in params_dct:
            #     params_dct[pressure] = [vals]
            # else:
            #     params_dct[pressure].append(vals)
    else:
        params_dct = None

    return params_dct
예제 #10
0
def plog_parameters(rxn_dstr):
    """ Parses the data string for a reaction in the reactions block
        for the lines containing the PLog fitting parameters,
        then reads the parameters from these lines.

        :param rxn_dstr: data string for species in reaction block
        :type rxn_dstr: str
        :return params: PLog fitting parameters
        :rtype: dict[pressure: params]
    """

    pattern = ('PLOG' + app.zero_or_more(app.SPACE) + app.escape('/') +
               app.zero_or_more(app.SPACE) + app.capturing(app.NUMBER) +
               app.one_or_more(app.SPACE) + app.capturing(app.NUMBER) +
               app.one_or_more(app.SPACE) + app.capturing(app.NUMBER) +
               app.one_or_more(app.SPACE) + app.capturing(app.NUMBER) +
               app.zero_or_more(app.SPACE) + app.escape('/'))
    params_lst = apf.all_captures(pattern, rxn_dstr)

    # Build dictionary of parameters, indexed by parameter
    if params_lst:
        params_dct = {}
        for params in params_lst:
            pressure = float(params[0])
            vals = list(map(float, params[1:]))
            if pressure not in params_dct:
                params_dct[pressure] = [vals]
            else:
                params_dct[pressure].append(vals)
    else:
        params_dct = None

    return params_dct
예제 #11
0
def check_defined_sections(input_string):
    """ verify all defined sections have been defined
    """
    pattern = (escape('$') + capturing(one_or_more(NONNEWLINE)))

    matches = all_captures(pattern, input_string)

    # See if each section has an paired end and is a supported keywords
    defined_sections = []
    for i, match in enumerate(matches):
        if (i+1) % 2 == 0:
            if match != 'end':
                raise ValueError
        else:
            defined_sections.append(match)

    # Check if sections are supported
    if not all(section in INPUT_SUPPORTED_SECTIONS
               for section in defined_sections):
        raise NotImplementedError

    # Check if elements of keywords
    if not all(section in defined_sections
               for section in INPUT_REQUIRED_SECTIONS):
        raise NotImplementedError
예제 #12
0
def matrix_keys_and_entries(mat_str,
                            symbol_pattern=SYMBOL_PATTERN,
                            key_pattern=KEY_PATTERN,
                            variable_pattern=VARIABLE_PATTERN):
    """ the keys and entries of a matrix block, as matrices

    (float entries are converted to floats)
    """
    column_patterns = matrix_line_column_key_entry_patterns(
        symbol_pattern, key_pattern, variable_pattern)
    key_cols = []
    entry_cols = []
    for col_idx, column_pattern in enumerate(column_patterns):
        caps = apf.all_captures(column_pattern, mat_str)
        keys, entries = zip(*caps) if caps else ([], [])
        keys = list(map(int, keys))
        entries = [
            float(entry) if apf.is_number(entry) else entry
            for entry in entries
        ]
        key_cols.append([None] * (col_idx + 1) + keys)
        entry_cols.append([None] * (col_idx + 1) + entries)

    key_mat = tuple(zip(*key_cols))
    entry_mat = tuple(zip(*entry_cols))
    return key_mat, entry_mat
예제 #13
0
 def _connected_formula(ich):
     fml_str = formula_string(ich)
     fml = {
         s: int(n) if n else 1
         for s, n in apf.all_captures(ptt, fml_str)
     }
     return fml
예제 #14
0
def read_spc_amech(job_path):
    """ Read an amech style input file for the species
    """

    # Read the AMech species string
    if os.path.exists(os.path.join(job_path, DAT_INP)):
        spc_amech_str = ptt.read_inp_str(
            job_path, DAT_INP, remove_comments='#')
        print('Found species.dat. Reading file...')
    else:
        spc_amech_str = ''
        print('No species.dat file...')

    # Build the keyword dcts
    amech_dct = {}
    if spc_amech_str:
        # Read each of the species sections and build the dcts
        spc_sections = apf.all_captures(
            ptt.end_section_wname2('spc'), spc_amech_str)
        if spc_sections:
            # Get the global species section
            for section in spc_sections:
                if section[0] == 'global':
                    # Build the global species section
                    keyword_dct = ptt.build_keyword_dct(section[1])
                    amech_dct['global'] = keyword_dct
                else:
                    # Build each species dct to overwrite global dct
                    name = section[0]
                    keyword_dct = ptt.build_keyword_dct(section[1])
                    amech_dct[name] = keyword_dct

    return amech_dct
예제 #15
0
def buffer_enhance_factors(rxn_dstr):
    """ get the factors of speed-up from bath gas
    """
    species_char = app.one_of_these([
        app.LETTER, app.DIGIT,
        app.escape('('),
        app.escape(')'), app.UNDERSCORE
    ])
    species_name = app.one_or_more(species_char)

    # Get the line that could have the bath gas buffer enhancements
    bath_line_pattern = (_first_line_pattern(rct_ptt=SPECIES_NAMES_PATTERN,
                                             prd_ptt=SPECIES_NAMES_PATTERN,
                                             coeff_ptt=COEFF_PATTERN) + '\n' +
                         app.capturing(app.LINE))
    bath_string = apf.first_capture(bath_line_pattern, rxn_dstr)

    # Check if this line has bath gas factors or is for something else
    # If factors in string, get factors
    bad_strings = ('DUPLICATE', 'LOW', 'TROE', 'CHEB', 'PLOG')
    if (any(string in bath_string for string in bad_strings)
            and bath_string.strip() != ''):
        factors = None
    else:
        bath_string = '\n'.join(bath_string.strip().split())
        factor_pattern = (app.capturing(species_name) + app.escape('/') +
                          app.capturing(app.NUMBER) + app.escape('/'))
        baths = apf.all_captures(factor_pattern, bath_string)
        factors = {}
        for bath in baths:
            factors[bath[0]] = float(bath[1])

    return factors
예제 #16
0
def grid_min_freqs(output_string):
    """ Reads the analytic frequencies for each of the
        hindered rotors from MESS output file string.

        Frequency corresponds to the minimum from the minimum on the grid
        of the user supplied hindered rotor potential in the input.

        :param output_string: string of lines of MESS output file
        :type output_string: str
        :return freqs: frequency for each of the rotors
        :rtype: list(float)
    """

    # Pattern for the frequency of a rotor
    pattern = (app.escape('first point frequency estimate =') +
               app.one_or_more(app.SPACE) + app.capturing(app.NUMBER) +
               app.one_or_more(app.SPACE) + app.escape('1/cm'))

    # Obtain each frequency from the output string
    tors_freqs = [
        float(val) for val in apf.all_captures(pattern, output_string)
    ]

    print('tors freqs test in grid_min_freq:', tors_freqs)

    return tors_freqs
예제 #17
0
def high_p_parameters(rxn_dstr, ea_units, a_units):
    """ Parses the data string for a reaction in the reactions block
        for the line containing the chemical equation in order to
        read the fitting parameters that are on the same line.

        :param rxn_dstr: data string for species in reaction block
        :type rxn_dstr: str
        :return params: Arrhenius fitting parameters for high-P rates
        :rtype: list(float)
    """

    pattern = _first_line_pattern(rct_ptt=SPECIES_NAMES_PATTERN,
                                  prd_ptt=SPECIES_NAMES_PATTERN,
                                  param_ptt=app.capturing(COEFF_PATTERN))

    string_lst = apf.all_captures(pattern, rxn_dstr)
    if string_lst:
        fake_params = []
        for string in string_lst:
            fake_params.append(list(ap_cast(string.split())))
            params = fake_params[0]

        # Convert the units of Ea and A
        ea_conv_factor = get_ea_conv_factor(rxn_dstr, ea_units)
        a_conv_factor = get_a_conv_factor(rxn_dstr, a_units)
        params[2] = params[2] * ea_conv_factor
        params[0] = params[0] * a_conv_factor

    else:
        params = None

    return params
예제 #18
0
def stereo_bonds(ich, iso=True, one_indexed=False):
    """ Parse the stereo bonds from the stereochemistry layer.

        :param ich: InChI string
        :type ich: str
        :param iso: Include isotope stereochemistry?
        :type iso: bool
        :param one_indexed: Return indices in one-indexing?
        :type one_indexed: bool
    """
    if len(split(ich)) > 1:
        raise NotImplementedError("Multicomponent InChIs not implemented."
                                  "Call inchi.split() first")

    bnd_ptt = '-'.join([app.capturing(app.UNSIGNED_INTEGER)] * 2)

    ste_dct = stereo_sublayers(ich)
    iso_dct = isotope_sublayers(ich)

    blyr = ''
    if 'b' in ste_dct:
        blyr += ste_dct['b']

    if iso and 'b' in iso_dct:
        blyr += ',' + iso_dct['b']

    bnds = ()
    if blyr:
        bnds = ap_cast(apf.all_captures(bnd_ptt, blyr))

    if not one_indexed:
        bnds = tuple((i - 1, j - 1) for i, j in bnds)
        bnds = bnds if bnds is not None else ()

    return bnds
예제 #19
0
def _read_irc_reaction_path_summary(output_str, read_val):
    """ Reads the values for the Intrinsic Reaction Path from the table.

        :param output_str: string of the program's output file
        :type output_str: str
        :param read_val: value to read from table
        :type read_val: str
        :rtype: tuple(automol geom data structure)
    """

    assert read_val in ('energy', 'coord')

    block = apf.last_capture(
        (app.escape('Summary of reaction path following') +
         app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
         app.escape('Total number of points:') + app.SPACES + app.INTEGER),
        output_str)

    if read_val == 'energy':
        pattern = (app.INTEGER + app.SPACES + app.capturing(app.FLOAT) +
                   app.SPACES + app.FLOAT)
    elif read_val == 'coord':
        pattern = (app.INTEGER + app.SPACES + app.FLOAT + app.SPACES +
                   app.capturing(app.FLOAT))

    captures = apf.all_captures(pattern, block)
    if captures is not None:
        values = [float(capture) for capture in captures]
    else:
        values = None

    return values
예제 #20
0
def quartic_force_constants(output_str):
    """ Reads the quartic force constants
        from the output file string. Returns the constants in _.
        Hartree*amu(2)*Bohr(-4)

        :param output_str: string of the program's output file
        :type output_str: str
        :rtype: tuple(tuple(float))
    """

    block = apf.last_capture(
        ('QUARTIC FORCE CONSTANTS IN NORMAL MODES' +
         app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
         'Input to Restart Anharmonic Calculations'), output_str)
    if block is None:
        block = apf.last_capture(
            ('QUARTIC FORCE CONSTANTS IN NORMAL MODES' +
             app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
             'Input for POLYMODE'), output_str)

    pattern = (app.capturing(app.INTEGER) + app.SPACES +
               app.capturing(app.INTEGER) + app.SPACES +
               app.capturing(app.INTEGER) + app.SPACES +
               app.capturing(app.INTEGER) + app.SPACES + app.FLOAT +
               app.SPACES + app.FLOAT + app.SPACES + app.capturing(app.FLOAT))

    caps = apf.all_captures(pattern, block)
    if caps:
        qfc_mat = _fc_mat(caps)
    else:
        qfc_mat = None

    return qfc_mat
예제 #21
0
def reaction_units(string, start_pattern, units_pattern):
    """ return a block delimited by start and end patterns
    """
    rxn_line_pattern = start_pattern + app.capturing(app.LINE_FILL)
    units_string = apf.first_capture(rxn_line_pattern, string)
    units_lst = apf.all_captures(units_pattern, units_string)

    ckin_ea_units = [
        'CAL/MOLE', 'KCAL/MOLE', 'JOULES/MOLE', 'KJOULES/MOLE', 'KELVINS'
    ]
    ckin_a_units = ['MOLES', 'MOLECULES']

    if units_lst:
        if any(unit in ckin_ea_units for unit in units_lst):
            for unit in ckin_ea_units:
                if unit in units_lst:
                    ea_unit = unit.lower()
        else:
            ea_unit = 'cal/mole'
        if any(unit in ckin_a_units for unit in units_lst):
            for unit in ckin_a_units:
                if unit in units_lst:
                    a_unit = unit.lower()
        else:
            a_unit = 'moles'
        units = (ea_unit, a_unit)
    else:
        units = ('cal/mole', 'moles')

    return units
예제 #22
0
def centrifugal_distortion_constants(output_str):
    """ Reads the VPT2-computed quartic centrifugal distortion constants
        from the output file string. Returns the constants in _.

        :param output_str: string of the program's output file
        :type output_str: str
        :rtype: tuple(tuple(float))
    """

    # Set patterns for all molecule types and symmetries
    block = apf.last_capture(
        ('Quartic Centrifugal Distortion Constants Tau Prime' +
         app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
         'Asymmetric Top Reduction'), output_str)
    if not block:
        block = apf.last_capture(
            ('Quartic Centrifugal Distortion Constants Tau Prime' +
             app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
             'Constants in the Symmetrically Reduced Hamiltonian'), output_str)
    if not block:
        block = apf.last_capture(
            ('Quartic Centrifugal Distortion Constants Tau Prime' +
             app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
             'Rotational l-type doubling constants'), output_str)

    # Read values
    pattern = ('TauP' + app.SPACE +
               app.capturing(app.one_or_more(app.LOWERCASE_LETTER)) +
               app.SPACES + app.capturing(app.EXPONENTIAL_FLOAT_D) +
               app.SPACES + app.EXPONENTIAL_FLOAT_D)

    cent_dist_const = [[lbl, float(val.replace('D', 'E'))]
                       for (lbl, val) in apf.all_captures(pattern, block)]

    return cent_dist_const
예제 #23
0
def cubic_force_constants(output_str):
    """ Reads the cubic force constants
        from the output file string. Returns the constants in _.
        Hartree*amu(-3/2)*Bohr(-3)

        :param output_str: string of the program's output file
        :type output_str: str
        :rtype: tuple(tuple(float))
    """

    block = apf.last_capture(
        ('CUBIC FORCE CONSTANTS IN NORMAL MODES' +
         app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
         'QUARTIC FORCE CONSTANTS IN NORMAL MODES'), output_str)

    pattern = (app.capturing(app.INTEGER) + app.SPACES +
               app.capturing(app.INTEGER) + app.SPACES +
               app.capturing(app.INTEGER) + app.SPACES + app.FLOAT +
               app.SPACES + app.FLOAT + app.SPACES + app.capturing(app.FLOAT))

    caps = apf.all_captures(pattern, block)
    if caps:
        cfc_mat = _fc_mat(caps)
    else:
        cfc_mat = None

    return cfc_mat
예제 #24
0
def high_coefficients(thm_dstr):
    """ get the high temperature thermo coefficients
    """
    capture_lst = apf.all_captures(app.EXPONENTIAL_FLOAT, thm_dstr)
    assert len(capture_lst) in (14, 15)
    cfts = tuple(map(float, capture_lst[:7]))
    return cfts
예제 #25
0
def cent_dist_const_reader(output_string):
    """ Get the quartic centrifugal distortion constants
    """

    # block
    block = apf.last_capture(
        ('Quartic Centrifugal Distortion Constants Tau Prime' +
         app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
         'Asymmetric Top Reduction'), output_string)
    if not block:
        block = apf.last_capture(
            ('Quartic Centrifugal Distortion Constants Tau Prime' +
             app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
             'Constants in the Symmetrically Reduced Hamiltonian'),
            output_string)
    if not block:
        block = apf.last_capture(
            ('Quartic Centrifugal Distortion Constants Tau Prime' +
             app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
             'Rotational l-type doubling constants'), output_string)

    # pattern
    pattern = ('TauP' + app.SPACE +
               app.capturing(app.one_or_more(app.LOWERCASE_LETTER)) +
               app.SPACES + app.capturing(app.EXPONENTIAL_FLOAT_D) +
               app.SPACES + app.EXPONENTIAL_FLOAT_D)

    # Get list of values
    cent_dist_const = [[lbl, float(val.replace('D', 'E'))]
                       for (lbl, val) in apf.all_captures(pattern, block)]

    return cent_dist_const
예제 #26
0
def irc_points(output_string):
    """ obtain the geometry, gradient, and hessian at each point along the irc
    """

    # Set pattern to find the end of each IRC optimization
    pattern = app.escape('@IRC  **** Point ' + app.INTEGER +
                         ' on IRC path is optimized ****')
    block = apf.last_capture(
        (pattern + app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
         app.escape('    Back-transformation to cartesian coordinates...')),
        output_string)

    # Set pattern for grabbing the geometry from the block
    geo_head_ptt = (app.escape('@IRC    Cartesian Geometry (in Angstrom)') +
                    app.LINE_FILL + '\n')

    # Grab all of the optimized geometries
    captures = apf.all_captures(pattern, block)
    if captures is not None:
        geoms = []
        for string in captures:
            syms, xyzs = ar.geom.read(string,
                                      start_ptt=geo_head_ptt,
                                      line_start_ptt=app.escape('@IRC'))
            geoms.append(automol.geom.from_data(syms, xyzs, angstrom=True))
    else:
        geoms = []

    # Set the gradients and hessians to empty lists since they MAY not be run
    grads, hessians = [], []

    return geoms, grads, hessians
예제 #27
0
파일: surface.py 프로젝트: avcopan/elstruct
def _read_irc_reaction_path_summary(output_string, read_val):
    """ get the desired values from the reaction path summary block
    """
    assert read_val in ('energy', 'coord')

    block = apf.last_capture(
        (app.escape('Summary of reaction path following') +
         app.capturing(app.one_or_more(app.WILDCARD, greedy=False)) +
         app.escape('Total number of points:') + app.SPACES + app.INTEGER),
        output_string)

    if read_val == 'energy':
        pattern = (app.INTEGER + app.SPACES + app.capturing(app.FLOAT) +
                   app.SPACES + app.FLOAT)
    elif read_val == 'coord':
        pattern = (app.INTEGER + app.SPACES + app.FLOAT + app.SPACES +
                   app.capturing(app.FLOAT))

    captures = apf.all_captures(pattern, block)
    if captures is not None:
        values = [float(capture) for capture in captures]
    else:
        values = None

    return values
예제 #28
0
def high_p(rxn_str, ea_units, a_units):
    """ Parses the data string for a reaction in the reactions block
        for the line containing the chemical equation in order to
        read the fitting parameters that are on the same line.

        :param rxn_str: raw Chemkin string for a single reaction
        :type rxn_str: str
        :param ea_units: units of activation energy
        :type ea_units: str
        :param a_units: units of rate constants; either 'moles' or 'molecules'
        :type a_units: str
        :return params: Arrhenius fitting parameters for high-P rates
        :rtype: list(list(float))
    """

    pattern = _first_line_pattern(rct_ptt=SPECIES_NAMES_PATTERN,
                                  prd_ptt=SPECIES_NAMES_PATTERN,
                                  param_ptt=app.capturing(COEFF_PATTERN))
    string_lst = apf.all_captures(pattern, rxn_str)
    if string_lst:
        fake_params = []
        for string in string_lst:
            fake_params.append(list(ap_cast(string.split())))
            params = fake_params[0]

        # Convert the units of Ea and A
        ea_conv_factor = get_ea_conv_factor(ea_units)
        a_conv_factor = get_a_conv_factor(rxn_str, a_units)
        params[2] = params[2] * ea_conv_factor
        params[0] = params[0] * a_conv_factor
        params = [params]  # convert to list inside a list
    else:
        params = None

    return params
예제 #29
0
def harmonic_frequencies(output_str):
    """ Reads the harmonic vibrational frequencies from
        the output file string. Returns the frequencies in cm-1.

        :param output_str: string of the program's output file
        :type output_str: str
        :rtype: tuple(float)
    """

    pattern = app.escape('Freq [cm^-1]') + app.capturing(app.LINE_FILL)

    captures = apf.all_captures(pattern, output_str)
    if captures is not None:
        freqs = ()
        for capture in captures:
            vals = capture.split()
            for val in vals:
                if 'i' not in val:
                    freqs += (float(val), )
                else:
                    freqs += (-1.0 * float(val.replace('i', '')), )
    else:
        freqs = None

    return freqs
예제 #30
0
def lennard_jones(output_string):
    """ reads the lennard jones params from the output
    """

    sigma_ptt = (app.SPACES + app.INTEGER + app.SPACES +
                 app.capturing(app.FLOAT) + app.SPACES + app.FLOAT)
    epsilon_ptt = (app.SPACES + app.INTEGER + app.SPACES + app.FLOAT +
                   app.SPACES + app.capturing(app.FLOAT))

    sigmas = apf.all_captures(sigma_ptt, output_string)
    epsilons = apf.all_captures(epsilon_ptt, output_string)
    if sigmas is not None:
        sigmas = [float(val) for val in sigmas]
    if epsilons is not None:
        epsilons = [float(val) for val in epsilons]

    return sigmas, epsilons