示例#1
0
def active_space(info_obj, typ='ts'):
    """ Determine the active space for the multireference MEP scan
    """

    def _active_space(ich, mul):
        """ Determine the active sapce for an InChI string
        """
        if ich in act_space.DCT:
            num_act_orb = act_space.DCT[ich][0]
            num_act_elc = act_space.DCT[ich][1]
            num_states = act_space.DCT[ich][2]
        else:
            num_act_orb = (mul - 1)
            num_act_elc = (mul - 1)
            num_states = 1

        return num_act_orb, num_act_elc, num_states

    if typ == 'spc':
        ich = sinfo.value(info_obj, 'inchi')
        mul = sinfo.value(info_obj, 'mult')
        num_act_orb, num_act_elec, num_states = _active_space(ich, mul)
    elif typ == 'ts':
        rct_ichs = rinfo.value(info_obj, 'inchi')[0]
        rct_muls = rinfo.value(info_obj, 'mult')[0]

        num_act_orb, num_act_elec, num_states = 0, 0, 1
        for ich, mul in zip(rct_ichs, rct_muls):
            norb, nelec, nstat = _active_space(ich, mul)
            num_act_orb += norb
            num_act_elec += nelec
            num_states *= nstat

    return num_act_orb, num_act_elec, num_states
示例#2
0
def ts_dct_sing_chnl(pes_idx,
                     reaction,
                     spc_dct,
                     run_prefix,
                     save_prefix,
                     thy_info=None,
                     ini_thy_info=None):
    """ build dct for single reaction
    """

    # Unpack the reaction object
    chnl_idx, (reacs, prods) = reaction

    rxn_info = rinfo.from_dct(reacs, prods, spc_dct)
    print('  Preparing for reaction {} = {}'.format('+'.join(reacs),
                                                    '+'.join(prods)))

    # Set the reacs and prods for the desired direction
    reacs, prods = rxnid.set_reaction_direction(reacs,
                                                prods,
                                                rxn_info,
                                                thy_info,
                                                ini_thy_info,
                                                save_prefix,
                                                direction='forw')

    # Obtain the reaction object for the reaction
    zma_locs = (0, )
    zrxns, zmas, rclasses = rxnid.build_reaction(rxn_info, ini_thy_info,
                                                 zma_locs, save_prefix)

    # Could reverse the spc dct
    if zrxns is not None:
        ts_dct = {}
        for idx, (zrxn, zma, cls) in enumerate(zip(zrxns, zmas, rclasses)):
            tsname = 'ts_{:g}_{:g}_{:g}'.format(pes_idx + 1, chnl_idx + 1, idx)
            ts_dct[tsname] = {
                'zrxn': zrxn,
                'zma': zma,
                'reacs': reacs,
                'prods': prods,
                'rxn_info': rxn_info,
                'inchi': '',
                'charge': rinfo.value(rxn_info, 'charge'),
                'mult': rinfo.value(rxn_info, 'tsmult'),
                'elec_levels': ((0.0, rinfo.value(rxn_info, 'tsmult')), ),
                'hind_inc': 30.0 * phycon.DEG2RAD,
                # 'sym_factor': 1.0,  # remove later
                'class': cls,
                'rxn_fs': reaction_fs(run_prefix, save_prefix, rxn_info)
            }
    else:
        ts_dct = {}
        print('Skipping reaction as class not given/identified')

    # Add the ts dct to the spc dct here?

    return ts_dct
示例#3
0
def _mod_class(class_typ, rxn_info):
    """ Create the object containing the full description of the
        reaction class, including its type, spin state, and whether
        it is a radical-radical combination.

        :param class_typ: reaction class type
        :type class_typ: str
        :param rxn_info: ???
        :tpye rxn_info: ???
    """

    # Set the spin of the reaction to high/low
    _fake_class = (class_typ, '', '', False)
    if automol.par.need_spin_designation(_fake_class):
        ts_mul = rinfo.value(rxn_info, 'tsmult')
        high_mul = rinfo.ts_mult(rxn_info, rxn_mul='high')
        _spin = 'high-spin' if ts_mul == high_mul else 'low-spin'
    else:
        _spin = ''

    # Determine if it iss intersystem crossing
    # rxn_muls = rinfo.value(rxn_info, 'mult')
    # is_isc = automol.reac.intersystem_crossing(rxn_muls)

    return automol.par.reaction_class_from_data(
        class_typ, _spin, rinfo.radrad(rxn_info), False)
示例#4
0
def _id_reaction(rxn_info):
    """ Identify the reaction and build the object

        :param rxn_info: reaction info object
        :type rxn_info: mechanalyzer.inf.rxn object
        :rtype: (tuple(automol.Reaction object), tuple(automol.zmat object))
    """

    rxn_ichs = rinfo.value(rxn_info, 'inchi')
    rct_ichs, prd_ichs = rxn_ichs[0], rxn_ichs[1]

    zrxn_objs = automol.reac.rxn_objs_from_inchi(rct_ichs,
                                                 prd_ichs,
                                                 indexing='zma')
    # zrxns = tuple(obj[0] for obj in zrxn_objs)
    # zmas = tuple(obj[1] for obj in zrxn_objs)
    zrxns, zmas = [], []
    # for objs in zrxn_objs:
    #     zrxn, zma, _, _ = objs
    #     zrxns.append(zrxn)
    #     zmas.append(zma)
    #     print('zrxn, zma in id:', zrxn, automol.zmat.string(zma))
    # for now just use first zma until we are properly producing extra zmas
    if zrxn_objs:
        zrxns.append(zrxn_objs[0][0])
        zmas.append(zrxn_objs[0][1])

    return zrxns, zmas
示例#5
0
def skip_task(tsk, spc_dct, spc_name, thy_dct, es_keyword_dct, save_prefix):
    """ Determine if an electronic structure task should be skipped based on
        various parameters.

        :param spc_dct: species dictionary
        :type spc_dct: dictionary
        :param spc_name: name of species
        :type spc_name: string
        :rtype: bool
    """

    # Initialize skip to be false
    skip = False

    # Set theory info needed to find information
    ini_method_dct = thy_dct.get(es_keyword_dct['inplvl'])
    ini_thy_info = tinfo.from_dct(ini_method_dct)

    # Perform checks
    if 'ts' in spc_name:
        # Skip all tasks except find_ts
        # if rad-rad TS
        if tsk not in ('find_ts', 'rpath_scan'):  # generalize to other rpath
            rxn_info = spc_dct[spc_name]['rxn_info']
            ts_mul = rinfo.value(rxn_info, 'tsmult')
            high_ts_mul = rinfo.ts_mult(rxn_info, rxn_mul='high')
            if rinfo.radrad(rxn_info) and ts_mul != high_ts_mul:
                skip = True
                ioprinter.info_message(
                    f'Skipping task because {spc_name}',
                    'is a low-spin radical radical reaction')
    else:
        spc_natoms = len(automol.inchi.geometry(spc_dct[spc_name]['inchi']))
        if spc_natoms == 1:
            # Skip all tasks except init_geom and conf_energy
            # if species is an atom
            if tsk not in ('init_geom', 'conf_energy'):
                skip = True
                ioprinter.info_message('Skipping task for an atom...',
                                       newline=1)
        else:
            # Skip all tasks except ini_geom
            # if (non-TS) species is unstable (zrxn found (i.e. is not None))
            if tsk != 'init_geom':
                instab, path = filesys.read.instability_transformation(
                    spc_dct, spc_name, ini_thy_info, save_prefix)

                skip = (instab is not None)
                if skip:
                    ioprinter.info_message(
                        f'Found instability file at path {path}', newline=1)
                    ioprinter.info_message(
                        'Skipping task for unstable species...', newline=1)

    return skip
示例#6
0
def _id_reaction(rxn_info, thy_info, save_prefix):
    """ Identify the reaction and build the object

        :param rxn_info: reaction info object
        :type rxn_info: mechanalyzer.inf.rxn object
        :rtype: (tuple(automol.Reaction object), tuple(automol.zmat object))
    """

    # Check the save filesystem for the reactant and product geometries
    rct_geos, prd_geos, rct_paths, prd_paths = reagent_geometries(
        rxn_info, thy_info, save_prefix)

    # Identify reactants and products from geoms or InChIs, depending
    # We automatically assess and add stereo to the reaction object, as needed
    if any(rct_geos) and any(prd_geos):
        print('    Reaction ID from geometries from SAVE filesys')
        for i, path in enumerate(rct_paths):
            print(f'     - reactant {i+1}: {path}')
        for i, path in enumerate(prd_paths):
            print(f'     - product {i+1}: {path}')
        zrxn_objs = automol.reac.rxn_objs_from_geometry(
            rct_geos, prd_geos, indexing='zma', stereo=False)
            # rct_geos, prd_geos, indexing='zma', stereo=True)
    else:
        print('    Reaction ID from geometries from input InChIs')
        rxn_ichs = rinfo.value(rxn_info, 'inchi')
        rct_ichs, prd_ichs = rxn_ichs[0], rxn_ichs[1]

        zrxn_objs = automol.reac.rxn_objs_from_inchi(
            rct_ichs, prd_ichs, indexing='zma', stereo=False)
            # rct_ichs, prd_ichs, indexing='zma', stereo=True)

    # Loop over the found reaction objects
    if zrxn_objs is not None:
        zrxns, zmas = (), ()
        for obj_set in zrxn_objs:
            zrxn, zma, _, _ = obj_set
            zrxns += (zrxn,)
            zmas += (zma,)
    else:
        zrxns, zmas = None, None

    return zrxns, zmas
示例#7
0
def _mod_class(class_typ, rxn_info):
    """ Create the object containing the full description of the
        reaction class, including its type, spin state, and whether
        it is a radical-radical combination.

        :param class_typ: reaction class type
        :type class_typ: str
        :param rxn_info: ???
        :tpye rxn_info: ???
    """

    # Set the spin of the reaction to high/low
    if automol.par.need_spin_designation(class_typ):
        ts_mul = rinfo.value(rxn_info, 'tsmult')
        high_mul = rinfo.ts_mult(rxn_info, rxn_mul='high')
        _spin = 'high-spin' if ts_mul == high_mul else 'low-spin'
    else:
        _spin = ''

    return automol.par.reaction_class_from_data(class_typ, _spin,
                                                rinfo.radrad(rxn_info))
示例#8
0
def remove_radrad_ts(obj_queue, spc_dct):
    """ Remove TSs who have no information from the queue and
        include them in the missing data lists
    """

    ioprinter.info_message(
        'Removing low-spin radical-radical TS from queue...\n')

    new_queue = ()
    for obj in obj_queue:
        if 'ts_' in obj:
            rxn_info = spc_dct[obj]['rxn_info']
            ts_mul = rinfo.value(rxn_info, 'tsmult')
            high_ts_mul = rinfo.ts_mult(rxn_info, rxn_mul='high')
            if rinfo.radrad(rxn_info) and ts_mul != high_ts_mul:
                ioprinter.info_message(f'Removing {obj} from queue.')
            else:
                new_queue += (obj, )
        else:
            new_queue += (obj, )

    return new_queue
示例#9
0
def skip_task(spc_dct, spc_name):
    """ Should this task be skipped?
    :param spc_dct: species dictionary
    :type spc_dct: dictionary
    :param spc_name: name of species
    :type spc_name: string

    :rtype skip: boolean
    """
    skip = False

    # It should be skipped if its radical radical
    if 'ts' in spc_name:
        rxn_info = spc_dct[spc_name]['rxn_info']
        ts_mul = rinfo.value(rxn_info, 'tsmult')
        high_ts_mul = rinfo.ts_mult(rxn_info, rxn_mul='high')
        if rinfo.radrad(rxn_info) and ts_mul != high_ts_mul:
            skip = True
            ioprinter.info_message(
                'Skipping task because {} is a low-spin radical radical reaction'
                .format(spc_name))
    return skip
示例#10
0
def _mod_class(cls, rxn_info):
    """ append additional info to the class
    """

    full_cls_str = ''

    # Determine the string for radical radical reactions
    radrad = rinfo.radrad(rxn_info)
    radrad_str = 'radical-radical' if radrad else ''
    full_cls_str += radrad_str

    # Set the spin of the reaction to high/low
    if 'addition' in cls or 'absraction' in cls:
        ts_mul = rinfo.value(rxn_info, 'tsmult')
        high_mul = rinfo.ts_mult(rxn_info, rxn_mul='high')
        spin_str = 'high-spin' if ts_mul == high_mul else 'low-spin'
        full_cls_str += ' ' + spin_str
    else:
        spin_str = ''

    # Add the class label
    full_cls_str += ' ' + cls

    return full_cls_str
示例#11
0
def ts_dct_sing_chnl(pes_idx,
                     reaction,
                     spc_dct,
                     run_prefix,
                     save_prefix,
                     thy_info=None,
                     ini_thy_info=None,
                     id_missing=True,
                     re_id=False):
    """ build dct for single reaction
    """

    # Unpack the reaction object
    chnl_idx, (reacs, prods) = reaction

    rxn_info = rinfo.from_dct(reacs, prods, spc_dct)
    rct_str, prd_str = '+'.join(reacs), '+'.join(prods)
    print(f'\n  Preparing for reaction {rct_str} = {prd_str}')

    # Set the reacs and prods for the desired direction
    reacs, prods = rxnid.set_reaction_direction(reacs,
                                                prods,
                                                rxn_info,
                                                thy_info,
                                                ini_thy_info,
                                                save_prefix,
                                                direction='forw')

    # Obtain the reaction object for the reaction
    zma_locs = (0, )
    # is there a better way to get this hbond param out of spc_dct and does
    # it matter in getting the mincofs to build the reaction if we bother
    # to include it?
    # hbond_cutoffs = spc_dct[reacs[0]]['hbond_cutoffs']
    zrxns, zmas, rclasses, status = rxnid.build_reaction(rxn_info,
                                                         ini_thy_info,
                                                         zma_locs,
                                                         save_prefix,
                                                         id_missing=id_missing,
                                                         re_id=re_id)
    # , hbond_cutoffs=hbond_cutoffs)

    # Could reverse the spc dct
    if status not in ('MISSING-SKIP', 'MISSING-ADD'):
        ts_dct = {}
        for idx, (zrxn, zma, cls) in enumerate(zip(zrxns, zmas, rclasses)):
            tsname = f'ts_{pes_idx+1:d}_{chnl_idx+1:d}_{idx:d}'
            ts_dct[tsname] = {
                'zrxn': zrxn,
                'zma': zma,
                'reacs': reacs,
                'prods': prods,
                'rxn_info': rxn_info,
                'inchi': '',
                'charge': rinfo.ts_chg(rxn_info),
                'mult': rinfo.value(rxn_info, 'tsmult'),
                'elec_levels': ((0.0, rinfo.value(rxn_info, 'tsmult')), ),
                'hind_inc': 30.0 * phycon.DEG2RAD,
                'hbond_cutoffs': (4.55, 1.92),
                'class': cls,
                'rxn_fs': reaction_fs(run_prefix, save_prefix, rxn_info)
            }
    elif status == 'MISSING-ADD':
        tsname = f'ts_{pes_idx+1:d}_{chnl_idx+1:d}_0'
        ts_dct = {}
        ts_dct[tsname] = {'missdata': ini_thy_info}
    elif status == 'MISSING-SKIP':
        ts_dct = {}
        print('Skipping reaction as class not given/identified')

    return ts_dct