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
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
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())
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
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
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)
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
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
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
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
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