Example #1
0
def read_locs_harmonic_freqs(cnf_fs, cnf_locs, run_prefix, zrxn=None):
    """ Read the harmonic frequencies for a specific conformer
        Do the freqs obtain for two species for fake and pst?
    """

    if cnf_locs is not None:
        geo_exists = cnf_fs[-1].file.geometry.exists(cnf_locs)
        hess_exists = cnf_fs[-1].file.hessian.exists(cnf_locs)

        if not geo_exists:
            ioprinter.error_message(
                'No Reference geometry for harmonic frequencies at path',
                cnf_fs[-1].file.hessian.path(cnf_locs))
        if not hess_exists:
            ioprinter.error_message(
                'No Hessian available for harmonic frequencies at path',
                cnf_fs[-1].file.hessian.path(cnf_locs))
    else:
        geo_exists, hess_exists = False, False

    if geo_exists and hess_exists:
        # Obtain geom and freqs from filesys
        geo = cnf_fs[-1].file.geometry.read(cnf_locs)
        hess = cnf_fs[-1].file.hessian.read(cnf_locs)

        ioprinter.reading('Hessian', cnf_fs[-1].path(cnf_locs))

        # Build the run filesystem using locs
        fml_str = automol.geom.formula_string(geo)
        vib_path = job_path(run_prefix, 'PROJROT', 'FREQ', fml_str)

        # Obtain the frequencies
        ioprinter.info_message(
            'Calling ProjRot to diagonalize Hessian and get freqs...')
        script_str = autorun.SCRIPT_DCT['projrot']
        freqs, _, imag_freqs, _ = autorun.projrot.frequencies(
            script_str, vib_path, [geo], [[]], [hess])

        # Obtain the displacements
        norm_coord_str, _ = autorun.projrot.displacements(
            script_str, vib_path, [geo], [[]], [hess])

        # Calculate the zpve
        ioprinter.frequencies(freqs)
        zpe = (sum(freqs) / 2.0) * phycon.WAVEN2EH

        # Check imaginary frequencies and set freqs
        if zrxn is not None:
            if len(imag_freqs) > 1:
                ioprinter.warning_message('Saddle Point has more than',
                                          'one imaginary frequency')
            imag = imag_freqs[0]
        else:
            imag = None

        ret = (freqs, imag, zpe, norm_coord_str)
    else:
        ret = None

    return ret
Example #2
0
def _hess_freqs(geo, geo_save_fs, save_path, locs, run_prefix, overwrite):
    """ Calculate harmonic frequencies using Hessian
    """
    if _json_database(save_path):
        exists = geo_save_fs[-1].json.harmonic_frequencies.exists(locs)
    else:
        exists = geo_save_fs[-1].file.harmonic_frequencies.exists(locs)
    if not exists:
        ioprinter.info_message(
            'No harmonic frequencies found in save filesys...')
        _run = True
    elif overwrite:
        ioprinter.info_message(
            'User specified to overwrite frequencies with new run...')
        _run = True
    else:
        _run = False

    if _run:

        # Read the Hessian from the filesystem
        if _json_database(save_path):
            hess = geo_save_fs[-1].json.hessian.read(locs)
        else:
            hess = geo_save_fs[-1].file.hessian.read(locs)

        # Calculate and save the harmonic frequencies
        ioprinter.info_message(
            " - Calculating harmonic frequencies from Hessian...")
        script_str = autorun.SCRIPT_DCT['projrot']
        fml_str = automol.geom.formula_string(geo)
        vib_path = job_path(run_prefix, 'PROJROT', 'FREQ', fml_str)
        rt_freqs, _, rt_imags, _ = autorun.projrot.frequencies(
            script_str, vib_path, [geo], [[]], [hess])
        rt_imags = tuple(-1 * imag_freq for imag_freq in rt_imags)
        freqs = sorted(rt_imags + rt_freqs)
        ioprinter.frequencies(freqs)
        ioprinter.geometry(geo)
        if _json_database(save_path):
            geo_save_fs[-1].json.harmonic_frequencies.write(freqs, locs)
        else:
            geo_save_fs[-1].file.harmonic_frequencies.write(freqs, locs)
        ioprinter.save_frequencies(save_path)

    else:
        ioprinter.existing_path('Harmonic frequencies', save_path)
        freqs = geo_save_fs[-1].file.harmonic_frequencies.read(locs)
        ioprinter.frequencies(freqs)
Example #3
0
def read_locs_harmonic_freqs(cnf_fs,
                             harm_path,
                             cnf_locs,
                             run_prefix,
                             zrxn=None):
    """ Read the harmonic frequencies for a specific conformer
    """

    # probably should read freqs
    # Do the freqs obtain for two species for fake and pst
    if cnf_locs is not None:

        # Obtain geom and freqs from filesys
        geo = cnf_fs[-1].file.geometry.read(cnf_locs)
        hess = cnf_fs[-1].file.hessian.read(cnf_locs)
        ioprinter.reading('Hessian', cnf_fs[-1].path(cnf_locs))

        # Build the run filesystem using locs
        fml_str = automol.geom.formula_string(geo)
        vib_path = job_path(run_prefix, 'PROJROT', 'FREQ', fml_str)

        # Obtain the frequencies
        ioprinter.info_message(
            'Calling ProjRot to diagonalize Hessian and get freqs...')
        script_str = autorun.SCRIPT_DCT['projrot']
        freqs, _, imag_freqs, _ = autorun.projrot.frequencies(
            script_str, vib_path, [geo], [[]], [hess])

        # Calculate the zpve
        ioprinter.frequencies(freqs)
        zpe = (sum(freqs) / 2.0) * phycon.WAVEN2EH

        # Check imaginary frequencies and set freqs
        if zrxn is not None:
            if len(imag_freqs) > 1:
                ioprinter.warning_message('Saddle Point has more than',
                                          'one imaginary frequency')
            imag = imag_freqs[0]
        else:
            imag = None

    else:
        ioprinter.error_message(
            'Reference geometry is missing for harmonic frequencies')

    return freqs, imag, zpe
Example #4
0
def _assess_imags(freqs, ref_freqs, cnf_run_fs, cnf_save_fs, locs):
    """ Check if the frequencies signal a bad transition state
    """

    # Initialize success variable to be changed if needed
    success = True

    # Assume first (lowest) frequency is the imaginary mode
    imags = tuple(x for x in freqs if x < 0.0)
    imag_freq, ref_imag_freq = abs(imags[0]), abs(ref_freqs[0])

    print('\nChecking imaginary mode of potential saddle-point conformer '
          '(frequencies below)\n'
          f'versus reference imaginary mode {ref_imag_freq:.1f} cm-1.')
    ioprinter.frequencies(freqs)

    print('Checking if deviation from reference mode less than 100.0 cm-1')
    imag_diff = abs(imag_freq - ref_imag_freq)
    if imag_diff <= 100.0:
        print(f'  - Deviation = {imag_diff:.1f} cm-1. Small, likely fine.')
    else:
        print(f'  - Deviation = {imag_diff:1f} cm-1. Large, could be bad')
        print('  - Checking if value of mode greater than 150.0 cm-1')
        if imag_freq >= 150.0:
            print(f'    - Mode = {imag_freq:.1f} cm-1. Large, likely fine\n')
        else:
            print(f'    - Mode = {imag_freq:.1f} cm-1. Small, likely bad\n')
            success = False

    if success:
        print('Frequencies appear fine. Proceeding to save Hessian info.')
    else:
        cnf_run_path = cnf_run_fs[-1].path(locs)
        cnf_save_path = cnf_save_fs[-1].path(locs)
        shutil.rmtree(cnf_run_path)
        shutil.rmtree(cnf_save_path)
        print('Based on checks, saddle-point conformer likely bad. '
              'Removing conformer from both RUN and SAVE filesystem at\n'
              f'{cnf_run_path}\n'
              f'{cnf_save_path}\n')

    return success
Example #5
0
def conformer_tsk(job,
                  spc_dct,
                  spc_name,
                  thy_dct,
                  es_keyword_dct,
                  run_prefix,
                  save_prefix,
                  print_debug=False):
    """ Prepares and executes all electronic structure tasks that
        generate information for species and transition state conformers.
        This includes sampling and optimization procedures to generate
        conformer structures, as well as __ calculations using some
        saved conformer as input.

        :param job(subtask): calculatiion(s) to perform for conformer
        :type job: str
        :param spc_dct:
        :type spc_dct:
        :param spc_name: name of species
        :type spc_name: str
        :param thy_dct:
        :type thy_dct:
        :param es_keyword_dct: keyword-values for electronic structure task
        :type es_keyword_dct: dict[str:str]
        :param run_prefix: root-path to the run-filesystem
        :type run_prefix: str
        :param save_prefix: root-path to the save-filesystem
        :type save_prefix: str
    """

    saddle = bool('ts_' in spc_name)

    spc_dct_i = spc_dct[spc_name]

    # Set the spc_info
    if not saddle:
        spc_info = sinfo.from_dct(spc_dct_i)
    else:
        spc_info = rinfo.ts_info(spc_dct_i['rxn_info'])
    zrxn = spc_dct_i.get('zrxn', None)

    overwrite = es_keyword_dct['overwrite']
    retryfail = es_keyword_dct['retryfail']
    nprocs = 1
    # Modify the theory
    method_dct = thy_dct.get(es_keyword_dct['runlvl'])
    ini_method_dct = thy_dct.get(es_keyword_dct['inplvl'])
    thy_info = tinfo.from_dct(method_dct)
    ini_thy_info = tinfo.from_dct(ini_method_dct)
    mod_thy_info = tinfo.modify_orb_label(thy_info, spc_info)
    mod_ini_thy_info = tinfo.modify_orb_label(ini_thy_info, spc_info)

    # New filesystem objects
    _root = root_locs(spc_dct_i, saddle=saddle, name=spc_name)
    ini_cnf_run_fs, ini_cnf_save_fs = build_fs(run_prefix,
                                               save_prefix,
                                               'CONFORMER',
                                               thy_locs=mod_ini_thy_info[1:],
                                               **_root)
    cnf_run_fs, cnf_save_fs = build_fs(run_prefix,
                                       save_prefix,
                                       'CONFORMER',
                                       thy_locs=mod_thy_info[1:],
                                       **_root)

    if job == 'samp':

        # Build the ini zma filesys
        user_conf_ids = spc_dct_i.get('conf_id')
        if user_conf_ids is None:
            ini_loc_info = filesys.mincnf.min_energy_conformer_locators(
                ini_cnf_save_fs, mod_ini_thy_info)
            ini_locs, ini_min_cnf_path = ini_loc_info
        else:
            print(f'Using user specified conformer IDs: {user_conf_ids}')
            ini_locs = user_conf_ids

        if any(ini_locs):
            ini_zma_save_fs = autofile.fs.zmatrix(ini_min_cnf_path)

            # Set up the run scripts
            script_str, kwargs = qchem_params(method_dct,
                                              elstruct.Job.OPTIMIZATION)

            # Set variables if it is a saddle
            two_stage = saddle
            mc_nsamp = spc_dct_i['mc_nsamp']
            resave = es_keyword_dct['resave']

            # Read the geometry and zma from the ini file system
            geo = ini_cnf_save_fs[-1].file.geometry.read(ini_locs)
            zma = ini_zma_save_fs[-1].file.zmatrix.read([0])

            # Read the torsions from the ini file sys
            if ini_zma_save_fs[-1].file.torsions.exists([0]):
                tors_dct = ini_zma_save_fs[-1].file.torsions.read([0])
                rotors = automol.rotor.from_data(zma, tors_dct)
                tors_names = automol.rotor.names(rotors, flat=True)
            else:
                tors_names = ()

            geo_path = ini_cnf_save_fs[-1].path(ini_locs)
            ioprinter.initial_geom_path('Sampling started', geo_path)

            # Check runsystem for equal ring CONF make conf_fs
            # Else make new ring conf directory
            rid = conformer.rng_loc_for_geo(geo, cnf_save_fs)

            if rid is None:
                conformer.single_conformer(zma,
                                           spc_info,
                                           mod_thy_info,
                                           cnf_run_fs,
                                           cnf_save_fs,
                                           script_str,
                                           overwrite,
                                           retryfail=retryfail,
                                           zrxn=zrxn,
                                           **kwargs)

                rid = conformer.rng_loc_for_geo(geo, cnf_save_fs)

            # Run the sampling
            conformer.conformer_sampling(zma,
                                         spc_info,
                                         mod_thy_info,
                                         cnf_run_fs,
                                         cnf_save_fs,
                                         rid,
                                         script_str,
                                         overwrite,
                                         nsamp_par=mc_nsamp,
                                         tors_names=tors_names,
                                         zrxn=zrxn,
                                         two_stage=two_stage,
                                         retryfail=retryfail,
                                         resave=resave,
                                         repulsion_thresh=40.0,
                                         print_debug=print_debug,
                                         **kwargs)
        else:
            ioprinter.info_message('Missing conformers. Skipping task...')

    elif job == 'pucker':

        # Build the ini zma filesys
        ini_loc_info = filesys.mincnf.min_energy_conformer_locators(
            ini_cnf_save_fs, mod_ini_thy_info)
        ini_min_locs, ini_min_cnf_path = ini_loc_info
        ini_zma_save_fs = autofile.fs.zmatrix(ini_min_cnf_path)

        # Set up the run scripts
        script_str, kwargs = qchem_params(method_dct,
                                          elstruct.Job.OPTIMIZATION)

        # Set variables if it is a saddle
        two_stage = saddle
        mc_nsamp = spc_dct_i['mc_nsamp']

        # Read the geometry and zma from the ini file system
        geo = ini_cnf_save_fs[-1].file.geometry.read(ini_min_locs)
        zma = ini_zma_save_fs[-1].file.zmatrix.read([0])

        # Read the torsions from the ini file sys
        if ini_zma_save_fs[-1].file.ring_torsions.exists([0]):
            ring_tors_dct = ini_zma_save_fs[-1].file.ring_torsions.read([0])
        else:
            ring_tors_dct = {}

        geo_path = ini_cnf_save_fs[-1].path(ini_min_locs)
        ioprinter.initial_geom_path('Sampling started', geo_path)

        # Run the sampling
        conformer.ring_conformer_sampling(zma,
                                          spc_info,
                                          mod_thy_info,
                                          cnf_run_fs,
                                          cnf_save_fs,
                                          script_str,
                                          overwrite,
                                          nsamp_par=mc_nsamp,
                                          ring_tors_dct=ring_tors_dct,
                                          zrxn=zrxn,
                                          two_stage=two_stage,
                                          retryfail=retryfail,
                                          **kwargs)

    elif job == 'opt':

        cnf_range = es_keyword_dct['cnf_range']
        hbond_cutoffs = spc_dct_i['hbond_cutoffs']
        cnf_sort_info_lst = _sort_info_lst(es_keyword_dct['sort'], thy_dct,
                                           spc_info)

        # Set up the run scripts
        script_str, kwargs = qchem_params(method_dct,
                                          elstruct.Job.OPTIMIZATION)

        rng_cnf_locs_lst, _ = filesys.mincnf.conformer_locators(
            cnf_save_fs, mod_thy_info, cnf_range='all', nprocs=nprocs)

        ini_rng_cnf_locs_lst, _ = filesys.mincnf.conformer_locators(
            ini_cnf_save_fs,
            mod_ini_thy_info,
            cnf_range=cnf_range,
            sort_info_lst=cnf_sort_info_lst,
            hbond_cutoffs=hbond_cutoffs,
            print_enes=True,
            nprocs=nprocs)

        # Truncate the list of the ini confs
        uni_rng_locs_lst, uni_cnf_locs_lst = conformer.unique_fs_ring_confs(
            cnf_save_fs, rng_cnf_locs_lst, ini_cnf_save_fs,
            ini_rng_cnf_locs_lst)
        # ioprinter.debug_message(
        #    'uni lst that has no similar ring', uni_rng_locs_lst)
        # ioprinter.debug_message(
        #    'uni lst that has similar ring', uni_cnf_locs_lst)

        for locs in uni_rng_locs_lst:
            rid, cid = locs
            # Obtain the zma from ini loc
            ini_cnf_save_path = ini_cnf_save_fs[-1].path(locs)
            ini_zma_save_fs = autofile.fs.zmatrix(ini_cnf_save_path)
            zma = ini_zma_save_fs[-1].file.zmatrix.read((0, ))

            # Make the ring filesystem
            conformer.single_conformer(zma,
                                       spc_info,
                                       mod_thy_info,
                                       cnf_run_fs,
                                       cnf_save_fs,
                                       script_str,
                                       overwrite,
                                       retryfail=retryfail,
                                       zrxn=zrxn,
                                       use_locs=locs,
                                       **kwargs)

        for locs in uni_cnf_locs_lst:
            ini_locs, rid = locs
            # Obtain the zma from ini loc
            ini_cnf_save_path = ini_cnf_save_fs[-1].path(ini_locs)
            ini_zma_save_fs = autofile.fs.zmatrix(ini_cnf_save_path)
            zma = ini_zma_save_fs[-1].file.zmatrix.read((0, ))
            # obtain conformer filesys associated with ring at the runlevel
            cid = autofile.schema.generate_new_conformer_id()
            conformer.single_conformer(zma,
                                       spc_info,
                                       mod_thy_info,
                                       cnf_run_fs,
                                       cnf_save_fs,
                                       script_str,
                                       overwrite,
                                       retryfail=retryfail,
                                       zrxn=zrxn,
                                       use_locs=(rid, cid),
                                       **kwargs)

        # print all geometres within cnfrange
        rng_cnf_locs_lst, _ = filesys.mincnf.conformer_locators(
            cnf_save_fs,
            mod_thy_info,
            cnf_range=cnf_range,
            sort_info_lst=cnf_sort_info_lst,
            hbond_cutoffs=hbond_cutoffs,
            nprocs=nprocs)
        for locs in rng_cnf_locs_lst:
            geo = cnf_save_fs[-1].file.geometry.read(locs)
            ioprinter.geometry(geo)

    elif job in ('energy', 'grad', 'hess', 'vpt2', 'prop'):

        cnf_range = es_keyword_dct['cnf_range']
        hbond_cutoffs = spc_dct_i['hbond_cutoffs']
        cnf_sort_info_lst = _sort_info_lst(es_keyword_dct['sort'], thy_dct,
                                           spc_info)

        user_conf_ids = spc_dct_i.get('conf_id')
        if user_conf_ids is None:
            ini_rng_cnf_locs_lst, _ = filesys.mincnf.conformer_locators(
                ini_cnf_save_fs,
                mod_ini_thy_info,
                cnf_range=cnf_range,
                sort_info_lst=cnf_sort_info_lst,
                hbond_cutoffs=hbond_cutoffs,
                print_enes=True,
                nprocs=nprocs)
        else:
            print(f'Using user specified conformer IDs: {user_conf_ids}')
            ini_rng_cnf_locs_lst = (user_conf_ids, )

        # Check if locs exist, kill if it doesn't
        if not ini_rng_cnf_locs_lst:
            ioprinter.error_message('No min-energy conformer found for level:')

        else:

            # Set up the run scripts
            script_str, kwargs = qchem_params(method_dct)

            # Grab frequencies for the reference, print ref freqs
            if job == 'hess':
                if ini_cnf_save_fs[-1].file.harmonic_frequencies.exists(
                        ini_rng_cnf_locs_lst[0]):
                    frq = ini_cnf_save_fs[-1].file.harmonic_frequencies.read(
                        ini_rng_cnf_locs_lst[0])
                    ref_val = frq
                else:
                    ref_val = None
                if ref_val is not None and zrxn is not None:
                    ref_path = cnf_save_fs[-1].path(ini_rng_cnf_locs_lst[0])
                    print('Found reference frequencies for saddle-point '
                          f'checks for conformer at\n {ref_path}')
                    ioprinter.frequencies(ref_val)
            else:
                ref_val = None

            # Run the job over all the conformers requested by the user
            print('Going over all requested conformers for task...\n')
            for ini_locs in ini_rng_cnf_locs_lst:
                ini_cnf_run_fs[-1].create(ini_locs)
                geo_save_path = ini_cnf_save_fs[-1].path(ini_locs)
                ini_zma_save_fs = autofile.fs.zmatrix(geo_save_path)
                print('Running task for geometry at ', geo_save_path)
                geo = ini_cnf_save_fs[-1].file.geometry.read(ini_locs)
                zma = ini_zma_save_fs[-1].file.zmatrix.read((0, ))
                ES_TSKS[job](zma,
                             geo,
                             spc_info,
                             mod_thy_info,
                             ini_cnf_run_fs,
                             ini_cnf_save_fs,
                             ini_locs,
                             run_prefix,
                             script_str,
                             overwrite,
                             zrxn=zrxn,
                             retryfail=retryfail,
                             method_dct=method_dct,
                             ref_val=ref_val,
                             **kwargs)
                print('\n === FINISHED CONF ===\n')