Esempio n. 1
0
def aggregate(seeds,
              monomer,
              aggregate_size=2,
              hm_orientations=8,
              method=None):
    """
    Input: a list of seed molecules, a monomer Molecule objects
    """
    if check_stop_signal():
        print("Function: aggregate")
        return StopIteration

    if hm_orientations == 'auto':
        number_of_orientations = 8
    else:
        number_of_orientations = hm_orientations

    starting_directory = os.getcwd()
    print("Starting Aggregation in\n {}".format(starting_directory))
    for aggregation_counter in range(2, aggregate_size + 2):
        aggregate_id = "{:03d}".format(aggregation_counter)
        aggregate_home = 'aggregate_' + aggregate_id
        file_manager.make_directories(aggregate_home)
        os.chdir(aggregate_home)

        print(" Starting aggregation cycle: {}".format(aggregation_counter))
        seeds = add_one(aggregate_id, seeds, monomer, number_of_orientations,
                        method)
        print(" Aggregation cycle: {} completed\n".format(aggregation_counter))

        if hm_orientations == 'auto' and number_of_orientations <= 256:
            number_of_orientations *= 2
        os.chdir(starting_directory)
    return
Esempio n. 2
0
def optimise(molecule,
             method,
             gamma=0.0,
             max_cycles=350,
             convergence='normal',
             restart='False',
             custom_keyword=None):
    cwd = os.getcwd()
    if molecule.name == '':
        molecule.name = 'opt'
    job_dir = 'job_' + molecule.name
    file_manager.make_directories(job_dir)
    os.chdir(job_dir)

    software = method['software']
    if software == 'xtb':
        from interface import xtb
        geometry = xtb.Xtb(molecule, method)
    elif software == 'xtb_turbo':
        if gamma == 0.0:
            from interface import xtb
            geometry = xtb.Xtb(molecule, method)
        else:
            from interface import xtbturbo
            geometry = xtbturbo.XtbTurbo(molecule, method)
    elif software == 'turbomole':
        from interface import turbomole
        geometry = turbomole.Turbomole(molecule, method)
    elif software == "mopac":
        from interface import mopac
        geometry = mopac.Mopac(molecule, method)
    elif software == "orca":
        from interface import orca
        geometry = orca.Orca(molecule, method, custom_keyword=custom_keyword)
    elif software == 'obabel':
        from interface import babel
        geometry = babel.OBabel(molecule)
    elif software == 'psi4':
        from interface import psi4
        geometry = psi4.Psi4(molecule, method)
    else:
        print(software, "is not implemented yet")
        return NotImplementedError

    optimize_status = geometry.optimize(gamma=gamma,
                                        max_cycles=max_cycles,
                                        convergence=convergence)
    if optimize_status is True\
            or optimize_status == 'converged'\
            or optimize_status == 'CycleExceeded':
        molecule.energy = geometry.energy
        molecule.coordinates = geometry.optimized_coordinates
        optimiser_logger.info("Energy: %15.6f", geometry.energy)
    else:
        molecule.energy = None
        molecule.coordinates = None

    os.chdir(cwd)
    return optimize_status
Esempio n. 3
0
def add_one(aggregate_id, seeds, monomer, hm_orientations, method):
    """
    :type aggregate_id str
    :type seeds list of Molecules
    :type monomer Molecule.Molecule
    :type hm_orientations int how many orientations
    :type method dict containing charge, multiplicity, software
    """
    if check_stop_signal():
        print("Function: add_one")
        return StopIteration
    print('  There are', len(seeds), 'seed molecules')
    cwd = os.getcwd()

    dict_of_optimized_molecules = {}
    for seed_count, each_seed in enumerate(seeds):
        if check_stop_signal():
            print("Function: add_one")
            return
        print('   Seed: {}'.format(seed_count))
        seed_id = "{:03d}".format(seed_count)
        seeds_home = 'seed_' + seed_id
        file_manager.make_directories(seeds_home)
        os.chdir(seeds_home)
        each_seed.mol_to_xyz('seed.xyz')
        monomer.mol_to_xyz('monomer.xyz')
        mol_id = '{0}_{1}'.format(seed_id, aggregate_id)

        all_orientations = tabu.generate_orientations(mol_id,
                                                      seeds[seed_count],
                                                      monomer, hm_orientations)
        for name, molecule in sorted(all_orientations.items(),
                                     key=operator.itemgetter(0)):
            o_status = optimise(molecule, method)
            if o_status is True:
                print("      E(%10s): %12.7f" % (name, molecule.energy))
                dict_of_optimized_molecules[name] = molecule
            else:
                print('    Optimisation failed:', name, 'will be discarded')
        os.chdir(cwd)
    if len(dict_of_optimized_molecules) < 2:
        return list(dict_of_optimized_molecules.values())
    print("  Clustering")
    selected_seeds = clustering.choose_geometries(dict_of_optimized_molecules)
    file_manager.make_directories('selected')
    for each_file in selected_seeds.values():
        xyz_file = 'seed_' + each_file.name[
            4:7] + '/result_' + each_file.name + '.xyz'
        shutil.copy(xyz_file, 'selected/')
    return list(selected_seeds.values())
Esempio n. 4
0
def react(reactant_a,
          reactant_b,
          gamma_min=100,
          gamma_max=1000,
          hm_orientations=8,
          method=None):
    cwd = os.getcwd()
    software = method['software']
    print_header(gamma_max, gamma_min, hm_orientations, software)
    # prepare job directories
    product_dir = cwd + '/products'
    file_manager.make_directories(product_dir)
    file_manager.make_directories('trial_geometries')
    os.chdir('trial_geometries')

    all_orientations = tabu.generate_orientations('geom', reactant_a,
                                                  reactant_b, hm_orientations)

    os.chdir(cwd)

    gamma_list = np.linspace(gamma_min, gamma_max, num=10, dtype=float)
    orientations_to_optimize = all_orientations.copy()

    for gamma in gamma_list:
        print('  Current gamma :', gamma)
        gamma_id = "%04d" % (int(gamma))
        gamma_home = cwd + '/gamma_' + gamma_id
        file_manager.make_directories(gamma_home)
        os.chdir(gamma_home)

        optimized_molecules = optimize_all(gamma_id, gamma,
                                           orientations_to_optimize,
                                           product_dir, method)

        print("      ", len(optimized_molecules),
              "geometries from this gamma cycle")
        orientations_to_optimize = clustering.choose_geometries(
            optimized_molecules)
        if len(orientations_to_optimize) == 0:
            print("No orientations to optimized for the next gamma cycle.")
            break
        print("      ", len(orientations_to_optimize),
              "geometries in the next gamma cycle")
        print("number of products found from gamma:", gamma, " = ",
              len(table_of_product_inchi_strings))
        for key, value in orientations_to_optimize.items():
            print("the key for next gamma cycle:", key)
    print("\n\n\n\n")
    os.chdir(cwd)
    return
Esempio n. 5
0
def add_one1(aggregate_id1, aggregate_id2, seeds1, seeds2, hm_orientations,
             method):
    """

    """
    seeds2 = seeds2[0]
    if check_stop_signal():
        aggregator_logger.info("Function: add_one")
        return StopIteration

    aggregator_logger.info('  There are {} seed molecules'.format(len(seeds1)))
    cwd = os.getcwd()

    list_of_optimized_molecules = []
    for seed_count, each_seed in enumerate(seeds1):
        if check_stop_signal():
            print("Function: add_one")
            return
        print('   Seed: {}'.format(seed_count))
        seed_id = "{:03d}".format(seed_count)
        seeds_home = 'seed_' + seed_id
        file_manager.make_directories(seeds_home)
        os.chdir(seeds_home)
        each_seed.mol_to_xyz('seed.xyz')
        seeds2.mol_to_xyz('monomer.xyz')
        mol_id = '{0}_{1}_{2}'.format(seed_id, aggregate_id1, aggregate_id2)

        all_orientations = tabu.generate_orientations(mol_id,
                                                      seeds1[seed_count],
                                                      seeds2, hm_orientations)
        not_converged = all_orientations[:]
        converged = []
        for i in range(10):
            aggregator_logger.info(
                "Round %d of block optimizations with %d molecules" %
                (i + 1, len(not_converged)))
            if len(not_converged) == 0:
                break
            status_list = [
                optimise(each_mol, method, max_cycles=350, convergence='loose')
                for each_mol in not_converged
            ]
            converged = [
                n for n, s in zip(not_converged, status_list) if s is True
            ]
            list_of_optimized_molecules.extend(converged)
            not_converged = [
                n for n, s in zip(not_converged, status_list)
                if s == 'CycleExceeded'
            ]
            not_converged = clustering.remove_similar(not_converged)

        os.chdir(cwd)
    print(list_of_optimized_molecules)
    if len(list_of_optimized_molecules) < 2:
        return list_of_optimized_molecules
    print("  Clustering")
    selected_seeds = clustering.choose_geometries(list_of_optimized_molecules)
    file_manager.make_directories('selected')
    for each_file in selected_seeds:
        status = optimise(each_file,
                          method,
                          max_cycles=350,
                          convergence='normal')
        if status is True:
            xyz_file = 'seed_' + each_file.name[
                4:
                7] + '/job_' + each_file.name + '/result_' + each_file.name + '.xyz'
            shutil.copy(xyz_file, 'selected/')
        else:
            selected_seeds.remove(each_file)
    return selected_seeds
Esempio n. 6
0
def aggregate(seeds1, seeds2, aggregate_size1, aggregate_size2,
              hm_orientations, method):
    """
    Input: a list of seed molecules, a monomer Molecule objects
    """
    if check_stop_signal():
        print("Function: aggregate")
        return StopIteration

    if hm_orientations == 'auto':
        number_of_orientations = 8
    else:
        number_of_orientations = int(hm_orientations)
    if (os.path.exists('Bag') == False):
        os.mkdir('Bag')
    os.chdir('Bag')
    starting_directory = os.getcwd()

    print("Starting Aggregation in\n {}".format(starting_directory))
    seed_init1 = seeds1
    seed_init2 = seeds2
    seed_in1 = seeds1
    seed_in2 = seeds2
    for aggregation_counter1 in range(1, aggregate_size1 + 1):
        for aggregation_counter2 in range(1, aggregate_size2 + 1):
            print(seeds1)
            print(seeds2)

            if (aggregation_counter1 > 1 and aggregation_counter2 == 1):
                pass
            else:
                aggregate_id1 = "{:02d}".format(aggregation_counter1)
                aggregate_id2 = "{:02d}".format(aggregation_counter2)
                aggregate_home = 'aggregate_' + aggregate_id1 + '_' + aggregate_id2
                file_manager.make_directories(aggregate_home)
                os.chdir(aggregate_home)

                print(" Starting aggregation cycle: {}".format(
                    aggregation_counter1))

                seeds1 = add_one1(aggregate_id1, aggregate_id2, seeds1,
                                  seed_init2, number_of_orientations, method)

                print(" Aggregation cycle: {} completed\n".format(
                    aggregation_counter1))

            if (aggregation_counter2 == 1):
                os.chdir(starting_directory)
                aggregate_id1 = "{:02d}".format(aggregation_counter1 + 1)
                aggregate_id2 = "{:02d}".format(aggregation_counter2)
                aggregate_home = 'aggregate_' + aggregate_id1 + '_' + aggregate_id2
                file_manager.make_directories(aggregate_home)
                os.chdir(aggregate_home)
                seed_in1 = seeds1
                seed_in1 = add_one1(aggregate_id1, aggregate_id2, seed_in1,
                                    seed_init1, number_of_orientations, method)

            if (aggregation_counter2 == aggregate_size2):
                seeds1 = seed_in1
            if hm_orientations == 'auto' and number_of_orientations <= 256:
                number_of_orientations *= 2
            os.chdir(starting_directory)
Esempio n. 7
0
    def optimize(self, cycle=10000, gamma=0.0):
        cwd = os.getcwd()
        file_manager.make_directories(self.job_dir)
        for f in [
                'auxbasis', 'basis', 'control', 'coord', 'mos', 'alpha',
                'beta', 'define.inp', 'define.log', 'fragment'
        ]:
            if os.path.exists(f):
                shutil.move(f, self.job_dir)
        os.chdir(self.job_dir)
        if not os.path.exists('control'):
            print("TURBOMOLE input file (control) not found, stoping")
            sys.exit()
        if gamma > 0.0:
            print("      gamma", gamma)
            if not os.path.isfile('fragment'):
                print("fragment file is not found")
                sys.exit()

        c = 0
        energy_program = "xtb coord"
        gradient_program = "xtb coord -grad"
        update_coord = "statpt"
        status = True
        outfile = 'job.start'
        # initial energy
        self.run_xtb(energy_program, outfile)
        if self.check_scf_convergance() is False:
            print('SF Failure. Check files in', os.getcwd())
            os.chdir(cwd)
            return False
        converged = False
        outfile = "xtb.log"

        while c <= cycle and not converged:
            print("{:4d} {:15.6f}".format(c, self.energy))
            sys.stdout.flush()

            self.run_xtb(gradient_program, outfile)

            if gamma > 0.0:
                status = restraints.isotropic(force=gamma)
                if status is False:
                    print("problem with afir restraints")
                    os.chdir(cwd)
                    return False

            self.run_xtb(update_coord, outfile)
            self.run_turbomole_convgrep(outfile)
            converged = self.check_geometry_convergence(outfile)

            if converged:
                print("\nConverged, at cycle", c)

            self.run_xtb(energy_program, outfile)
            if self.check_scf_convergance() is False:
                print('SF Failure. Check files in', os.getcwd())
                os.chdir(cwd)
                return False
            c += 1
        print()

        if converged:
            interface.babel.write_xyz(self.atoms_list,
                                      self.optimized_coordinates,
                                      self.result_xyz_file,
                                      job_name=self.job_name)
            shutil.copy(self.result_xyz_file, cwd)
            status = True
        elif c > cycle:
            print("cycle exceeded")
            status = 'cycle_exceeded'
        os.chdir(cwd)
        print(os.getcwd())
        sys.stdout.flush()
        return status
Esempio n. 8
0
    def optimize(self, ri="on", cycle=10000, gamma=0.0):
        cwd = os.getcwd()
        job_dir = 'job_' + self.job_name
        file_manager.make_directories(job_dir)
        for f in [
                'auxbasis', 'basis', 'control', 'coord', 'mos', 'alpha',
                'beta', 'define.inp', 'define.log', 'fragment'
        ]:
            if os.path.exists(f):
                shutil.move(f, job_dir)
        os.chdir(job_dir)
        if not os.path.exists('control'):
            print("TURBOMOLE input file (control) not found, stopping")
            sys.exit()
        if gamma > 0.0:
            print("      gamma", gamma)
            if not os.path.isfile('fragment'):
                print("fragment file is not found")
                sys.exit()

        c = 0
        if ri == "on":
            energy_program = "ridft"
            gradient_program = "rdgrad"
        else:
            energy_program = "dscf"
            gradient_program = "grad"
        update_coord = "statpt"
        status = True
        outfile = 'job.start'
        # initial energy
        if self.run_turbomole_module(energy_program, outfile) \
                or self.check_status_from_log(outfile, energy_program) \
                or self.check_dscf():
            os.chdir(cwd)
            return False
        converged = False

        while c <= cycle and not converged:
            if c == 50:
                print("{:4d} {:15.6f}".format(c, self.get_coords()))
            sys.stdout.flush()
            outfile = "job.last"
            if self.run_turbomole_module(gradient_program, outfile) \
                    or self.check_status_from_log(outfile, gradient_program):
                os.chdir(cwd)
                return False

            if gamma > 0.0:
                if restraints.isotropic(force=gamma) is False:
                    print("problem with afir restraints")
                    os.chdir(cwd)
                    return False

            if self.run_turbomole_module(update_coord, outfile):
                print("problem with statpt")
                os.chdir(cwd)
                return False

            self.run_convgrep(outfile)
            converged = self.check_convergence(outfile)

            if converged:
                print("\nConverged, at cycle", c)

            if self.run_turbomole_module(energy_program, outfile) \
                    or self.check_status_from_log(outfile, energy_program) \
                    or self.check_dscf():
                os.chdir(cwd)
                return False
            c += 1
        print()

        if converged:
            self.energy = self.get_energy()
            self.optimized_coordinates = self.get_coords()
            interface.babel.write_xyz(self.atoms_list,
                                      self.optimized_coordinates,
                                      self.result_xyz_file,
                                      self.job_name,
                                      energy=self.energy)
            shutil.copy(self.result_xyz_file, cwd)
            status = True
        elif c > cycle:
            print("cycle exceeded")
            status = False
        os.chdir(cwd)
        print(os.getcwd())
        sys.stdout.flush()
        return status
Esempio n. 9
0
def optimize_all(gamma_id, gamma, orientations_to_optimize, product_dir,
                 method):
    cwd = os.getcwd()
    table_of_optimized_molecules = {}
    for job_key, this_molecule in sorted(orientations_to_optimize.items(),
                                         key=operator.itemgetter(0)):
        print('   Orientation:', job_key)
        o_key = u"_{}".format(job_key[-8:])
        orientations_home = 'orientation' + o_key
        file_manager.make_directories(orientations_home)
        os.chdir(orientations_home)
        na, nb = [len(i) for i in this_molecule.fragments]
        fragment.make_fragment_file(na, nb)
        job_name = gamma_id + o_key
        this_molecule.name = job_name
        print('    Optimizing', this_molecule.name, ':')
        start_xyz_file_name = 'trial_' + this_molecule.name + '.xyz'
        this_molecule.mol_to_xyz(start_xyz_file_name)
        start_inchi = interface.babel.make_inchi_string_from_xyz(
            start_xyz_file_name)
        start_smile = interface.babel.make_smile_string_from_xyz(
            start_xyz_file_name)
        status = optimise(this_molecule, method, gamma=gamma)
        this_molecule.name = job_name
        print('     job completed')
        if status is True or status == 'converged' or status == 'cycle_exceeded':
            print("      E(%s): %12.7f" % (job_name, this_molecule.energy))
            if this_molecule.is_bonded() is True:
                print(
                    "      The fragments have close contracts. Going for relaxation"
                )
                this_molecule.mol_to_xyz('trial_relax.xyz')
                this_molecule.name = 'relax'
                status = optimise(this_molecule, method)
                this_molecule.name = job_name
                if status is True:
                    current_inchi = interface.babel.make_inchi_string_from_xyz(
                        'result_relax.xyz')
                    current_smile = interface.babel.make_smile_string_from_xyz(
                        'result_relax.xyz')
                    print('      geometry relaxed')
                    print(
                        "Checking for product formation with SMILE and InChi strings"
                    )
                    print("Start SMILE:", start_smile, "Current SMILE:",
                          current_smile)
                    print("Start InChi:", start_inchi, "Current InChi:",
                          current_inchi)

                    if start_inchi != current_inchi or start_smile != current_smile:
                        table_of_product_molecules[job_name] = this_molecule
                        print(
                            "       The geometry is different from the stating structure."
                        )
                        print("       Checking if this is a (new) products")
                        if current_inchi not in table_of_product_inchi_strings.values(
                        ):
                            if current_smile not in table_of_product_smile_strings.values(
                            ):
                                print("        New Product! Saving")
                                table_of_product_inchi_strings[
                                    job_name] = current_inchi
                                table_of_product_smile_strings[
                                    job_name] = current_smile
                                table_of_product_molecules[
                                    job_name] = this_molecule
                                table_of_product_keys_inchis[
                                    job_name] = current_inchi
                                shutil.copy(
                                    'result_relax.xyz',
                                    product_dir + '/' + job_name + '.xyz')
                                os.chdir(cwd)
                                continue
                            else:
                                print("SMILE matches")
                                os.chdir(cwd)
                                continue
                        else:
                            print("InChi matches")
                            os.chdir(cwd)
                            continue
                    else:
                        table_of_optimized_molecules[job_name] = this_molecule
                        print(
                            job_name,
                            'is added to the table to optimize with higher gamma'
                        )
            else:
                table_of_optimized_molecules[job_name] = this_molecule
                print(job_name, 'no close contacts found')
                print(job_name,
                      'is added to the table to optimize with higher gamma')
        os.chdir(cwd)
        sys.stdout.flush()
    return table_of_optimized_molecules
Esempio n. 10
0
def optimize_all(gamma_id, gamma, orientations_to_optimize, product_dir,
                 method):
    cwd = os.getcwd()
    table_of_optimized_molecules = []
    for this_molecule in orientations_to_optimize:
        job_key = this_molecule.name
        reactor_logger.info('   Orientation: {}'.format(job_key))
        o_key = "_{}".format(job_key[-8:])
        orientations_home = 'orientation' + o_key
        file_manager.make_directories(orientations_home)
        os.chdir(orientations_home)
        job_name = gamma_id + o_key
        this_molecule.name = job_name
        reactor_logger.info('Optimizing {}'.format(this_molecule.name))
        start_xyz_file_name = 'trial_' + this_molecule.name + '.xyz'
        this_molecule.mol_to_xyz(start_xyz_file_name)
        start_inchi = interface.babel.make_inchi_string_from_xyz(
            start_xyz_file_name)
        start_smile = interface.babel.make_smile_string_from_xyz(
            start_xyz_file_name)
        status = optimise(this_molecule, method, gamma=gamma)
        before_relax = copy.copy(this_molecule)
        this_molecule.name = job_name
        reactor_logger.info('... completed')
        if status is True or status == 'converged' or status == 'cycle_exceeded':
            reactor_logger.info("      E({}): {:12.7f}".format(
                job_name, this_molecule.energy))
            if this_molecule.is_bonded():
                reactor_logger.info(
                    "The fragments have close contracts. Going for relaxation")
                this_molecule.mol_to_xyz('trial_relax.xyz')
                this_molecule.name = 'relax'
                status = optimise(this_molecule, method)
                this_molecule.name = job_name
                if status is True or status == 'converged':
                    this_molecule.mol_to_xyz('result_relax.xyz')
                    current_inchi = interface.babel.make_inchi_string_from_xyz(
                        'result_relax.xyz')
                    current_smile = interface.babel.make_smile_string_from_xyz(
                        'result_relax.xyz')
                    reactor_logger.info('geometry relaxed')
                    reactor_logger.info(
                        "Checking for product formation with SMILE and InChi strings"
                    )
                    reactor_logger.info(
                        "Start SMILE: {} Current SMILE: {}".format(
                            start_smile, current_smile))
                    reactor_logger.info(
                        "Start InChi: {} Current InChi: {}".format(
                            start_inchi, current_inchi))

                    if start_inchi != current_inchi or start_smile != current_smile:
                        saved_products[job_name] = this_molecule
                        reactor_logger.info("       The geometry is different "
                                            "from the stating structure.")
                        reactor_logger.info(
                            "       Checking if this is a (new)"
                            " products")
                        if current_inchi not in saved_inchi_strings.values() and \
                                current_smile not in saved_smile_strings.values():
                            reactor_logger.info("        New Product! Saving")
                            saved_inchi_strings[job_name] = current_inchi
                            saved_smile_strings[job_name] = current_smile
                            saved_products[job_name] = this_molecule
                            shutil.copy('result_relax.xyz',
                                        product_dir + '/' + job_name + '.xyz')
                            os.chdir(cwd)
                            continue
                        else:
                            reactor_logger.info("Both strings matches with "
                                                "those of already saved "
                                                "products. Discarded")
                            os.chdir(cwd)
                            continue
                    else:
                        table_of_optimized_molecules.append(before_relax)
                        reactor_logger.info('{} is added to the table to '
                                            'optimize with higher '
                                            'gamma'.format(job_name))
                elif status == 'cycle_exceeded':
                    table_of_optimized_molecules.append(before_relax)
                    reactor_logger.info('{} is added to the table to optimize '
                                        'with higher gamma'.format(job_name))
            else:
                table_of_optimized_molecules.append(this_molecule)
                reactor_logger.info('        no close contacts found')
                reactor_logger.info(
                    '       {} is added to the table to '
                    'optimize with higher gamma'.format(job_name))
        os.chdir(cwd)
        sys.stdout.flush()
    return table_of_optimized_molecules
Esempio n. 11
0
def react(reactant_a, reactant_b, gamma_min, gamma_max, hm_orientations,
          method, site, proximity_factor):
    """Run reactor module.  This is the outer loop
    generates all the orientations
    loop over all the gamma values
      optimize all orientations in each gamma
      after eliminating the products or failed geometries
    """
    cwd = os.getcwd()
    reactor_logger.debug('Current working directory: {}'.format(cwd))
    software = method['software']
    print_header(gamma_max, gamma_min, hm_orientations, software)
    # prepare job directories
    product_dir = cwd + '/products'
    reactor_logger.debug('Product directory: {}'.format(product_dir))
    file_manager.make_directories(product_dir)
    file_manager.make_directories('trial_geometries')
    os.chdir('trial_geometries')

    if site is None:
        all_orientations = tabu.generate_orientations('geom', reactant_a,
                                                      reactant_b,
                                                      hm_orientations)
    else:
        all_orientations = tabu.generate_guess_for_bonding(
            'geom', reactant_a, reactant_b, site[0], site[1], hm_orientations)

    os.chdir(cwd)

    gamma_list = np.linspace(gamma_min, gamma_max, num=10, dtype=float)
    orientations_to_optimize = all_orientations[:]

    for gamma in gamma_list:
        reactor_logger.info('  Current gamma : {}'.format(gamma))
        gamma_id = "%04d" % (int(gamma))
        gamma_home = cwd + '/gamma_' + gamma_id
        file_manager.make_directories(gamma_home)
        os.chdir(gamma_home)

        optimized_molecules = optimize_all(gamma_id, gamma,
                                           orientations_to_optimize,
                                           product_dir, method)

        reactor_logger.info("      {} geometries from this gamma cycle".format(
            len(optimized_molecules)))
        if len(optimized_molecules) == 0:
            reactor_logger.info(
                "No orientations to be optimized for the next gamma cycle.")
            return
        if len(optimized_molecules) == 1:
            orientations_to_optimize = optimized_molecules[:]
        else:
            orientations_to_optimize = clustering.remove_similar(
                optimized_molecules)
        reactor_logger.info(
            "Number of products found from gamma:{} = {}".format(
                gamma, len(saved_inchi_strings)))
        reactor_logger.info(
            "{} geometries are considered for the next gamma cycle".format(
                len(orientations_to_optimize)))
        reactor_logger.debug("the keys of the molecules for next gamma cycle")
        for this_orientation in orientations_to_optimize:
            reactor_logger.debug("{}".format(this_orientation.name))
    os.chdir(cwd)
    return