def obtain_jobinfo(xyzfile, frame=-1, txt=False): init_mol = read_geometry_to_mol(xyzfile, frame=frame, txt=txt) natoms = init_mol.natoms metal_ind = init_mol.findMetal()[0] liglist, ligdents, ligcons = ligand_breakdown(init_mol, flag_loose=False, BondedOct=False) # print(liglist) # print(ligdents) # print(ligcons) ### Old version # _, _, _, _, _, _, ax_con, eq_con, _ = ligand_assign(init_mol, liglist, # ligdents, ligcons) # print("ax_con: ", ax_con) # print("eq_con: ", eq_con) # ax_con = np.squeeze(np.array(ax_con).reshape(2, -1)) # eq_con = np.squeeze(np.array(eq_con).reshape(4, -1)) _, _, _, _, _, _, _ax_con, _eq_con, _ = ligand_assign_consistent(init_mol, liglist, ligdents, ligcons) print(("ax_con: ", _ax_con)) print(("eq_con: ", _eq_con)) job_info = {} info_list = ['ax_con', 'eq_con', 'ax_con_sym', 'eq_con_sym', 'catoms', 'natoms', 'metal_ind'] eq_con, ax_con = [], [] for x in _eq_con: eq_con += x for x in _ax_con: ax_con += x ax_con_sym = [init_mol.atoms[x].sym for x in ax_con] eq_con_sym = [init_mol.atoms[x].sym for x in eq_con] catoms = [x for x in eq_con] + [x for x in ax_con] for info in info_list: job_info.update({info: locals()[info]}) return job_info
def find_mc_eq_ax_autocorrelation_oct(mol, prop, loud, depth, name=False, oct=True, func=autocorrelation_catoms, modifier=False): # For octahedral complexes only. # Calculate mc/ax, mc/eq deltametrics. liglist, ligdents, ligcons = ligand_breakdown(mol) ax_ligand_list, eq_ligand_list, ax_natoms_list, eq_natoms_list, ax_con_int_list, eq_con_int_list, ax_con_list, eq_con_list, built_ligand_list = ligand_assign( mol, liglist, ligdents, ligcons, loud, name=False) ## shape reduce ax_con_list = [x[0] for x in ax_con_list] eq_con_list = [x[0] for x in eq_con_list] ax_ligand_ac_mc = metal_only_autocorrelation(mol, prop, depth, catoms=ax_con_list, func=func, modifier=modifier) eq_ligand_ac_mc = metal_only_autocorrelation(mol, prop, depth, catoms=eq_con_list, func=func, modifier=modifier) ax_ligand_ac_mc = np.divide(ax_ligand_ac_mc, len(ax_con_list)) eq_ligand_ac_mc = np.divide(eq_ligand_ac_mc, len(eq_con_list)) return ax_ligand_ac_mc, eq_ligand_ac_mc
def getOctBondDistances(mol): ## This function gets ## ax and equitorial ## min and max bond lengths liglist, ligdents, ligcons = ligand_breakdown(mol) ax_ligand_list, eq_ligand_list, ax_natoms_list, eq_natoms_list, ax_con_int_list, eq_con_int_list, ax_con_list, eq_con_list, built_ligand_list = ligand_assign_consistent( mol, liglist, ligdents, ligcons, False, False) ax_dist = list() eq_dist = list() for ax_ligs in ax_con_list: tempList = list() for conatms in ax_ligs: tempList.append( distance( mol.getAtom(mol.findMetal()[0]).coords(), mol.getAtom(conatms).coords())) ax_dist.append(tempList) for eq_ligs in eq_con_list: tempList = list() for conatms in eq_ligs: tempList.append( distance( mol.getAtom(mol.findMetal()[0]).coords(), mol.getAtom(conatms).coords())) eq_dist.append(tempList) return ax_dist, eq_dist
def find_ligand_deltametrics_oct(mol, prop, loud, depth, name=False, oct=True, custom_ligand_dict=False): ## custom_ligand_dict.keys() must be eq_ligands_list, ax_ligand_list ## ax_con_int_list ,eq_con_int_list ## with types: eq/ax_ligand_list list of mol3D ## eq/ax_con_int_list list of list/tuple of int e.g, [[1,2] [1,2]] ## this function takes a ## octahedral complex ## and returns deltametrics for ## the axial an equatorial ligands if not custom_ligand_dict: liglist, ligdents, ligcons = ligand_breakdown(mol) ax_ligand_list, eq_ligand_list, ax_natoms_list, eq_natoms_list, ax_con_int_list, eq_con_int_list, ax_con_list, eq_con_list, built_ligand_list = ligand_assign( mol, liglist, ligdents, ligcons, loud, name=False) else: ax_ligand_list = custom_ligand_dict["ax_ligand_list"] eq_ligand_list = custom_ligand_dict["eq_ligand_list"] ax_con_int_list = custom_ligand_dict["ax_con_int_list"] eq_con_int_list = custom_ligand_dict["eq_con_int_list"] ## count ligands n_ax = len(ax_ligand_list) n_eq = len(eq_ligand_list) ## get partial ligand AC ax_ligand_ac_con = [] eq_ligand_ac_con = [] for i in range(0, n_ax): if not list(ax_ligand_ac_con): ax_ligand_ac_con = atom_only_deltametric(ax_ligand_list[i].mol, prop, depth, ax_con_int_list[i]) else: ax_ligand_ac_con += atom_only_deltametric(ax_ligand_list[i].mol, prop, depth, ax_con_int_list[i]) ax_ligand_ac_con = np.divide(ax_ligand_ac_con, n_ax) for i in range(0, n_eq): if not list(eq_ligand_ac_con): eq_ligand_ac_con = atom_only_deltametric(eq_ligand_list[i].mol, prop, depth, eq_con_int_list[i]) else: eq_ligand_ac_con += atom_only_deltametric(eq_ligand_list[i].mol, prop, depth, eq_con_int_list[i]) eq_ligand_ac_con = np.divide(eq_ligand_ac_con, n_eq) return ax_ligand_ac_con, eq_ligand_ac_con
def getLigFormulae(mol): ## This function gets ## ax and equitorial ## ligand names for octahedral complexes axnames = [] eqnames = [] liglist, ligdents, ligcons = ligand_breakdown(mol) ax_ligand_list, eq_ligand_list, ax_natoms_list, eq_natoms_list, ax_con_int_list, eq_con_int_list, ax_con_list, eq_con_list, built_ligand_list = ligand_assign( mol, liglist, ligdents, ligcons, False, False) for axl in ax_ligand_list: axnames.append(axl.mol.make_formula()) for eql in eq_ligand_list: eqnames.append(eql.mol.make_formula()) return axnames, eqnames
def obtain_jobinfo(xyzfile): init_mol = read_geometry_to_mol(xyzfile) natoms = init_mol.natoms metal_ind = init_mol.findMetal()[0] liglist, ligdents, ligcons = ligand_breakdown(init_mol, flag_loose=False, BondedOct=False) _, _, _, _, _, _, ax_con, eq_con, _ = ligand_assign(init_mol, liglist, ligdents, ligcons) job_info = {} info_list = ['ax_con', 'eq_con', 'ax_con_sym', 'eq_con_sym', 'catoms', 'natoms', 'metal_ind'] ax_con = np.squeeze(np.array(ax_con).reshape(2, -1)) eq_con = np.squeeze(np.array(eq_con).reshape(4, -1)) ax_con_sym = [init_mol.atoms[x].sym for x in ax_con] eq_con_sym = [init_mol.atoms[x].sym for x in eq_con] catoms = [x for x in eq_con] + [x for x in ax_con] for info in info_list: job_info.update({info: locals()[info]}) return job_info
def prep_ligand_breakown(outfile_path): # Given a path to the outfile of a finished run, this preps the files for rigid ligand dissociation energies of all ligands # Returns a list of the PATH(s) to the jobscript(s) to start the rigid ligand calculations home = os.getcwd() outfile_path = tools.convert_to_absolute_path(outfile_path) results = manager_io.read_outfile(outfile_path) if not results['finished']: raise Exception( 'This calculation does not appear to be complete! Aborting...') infile_dict = manager_io.read_infile(outfile_path) charge = int(infile_dict['charge']) spinmult = int(infile_dict['spinmult']) base = os.path.split(outfile_path)[0] name = os.path.split(outfile_path)[-1][:-4] breakdown_folder = os.path.join(base, name + '_dissociation') if os.path.isdir(breakdown_folder): return ['Ligand dissociation directory already exists'] optimxyz = os.path.join(base, 'scr', 'optim.xyz') tools.extract_optimized_geo(optimxyz) mol = mol3D() mol.readfromxyz(os.path.join(base, 'scr', 'optimized.xyz')) ligand_idxs, _, _ = ligand_breakdown(mol, silent=True) ligand_syms = [] for ii in ligand_idxs: ligand_syms.append([mol.getAtom(i).symbol() for i in ii]) ligand_names = name_ligands(ligand_syms) if not os.path.isdir(breakdown_folder): os.mkdir(breakdown_folder) os.chdir(breakdown_folder) jobscripts = [] for ligand in zip(ligand_names, ligand_idxs): # Assign charges to use during the breakdown for special cases...oxygen, hydroxide, peroxide, and acac # All other ligands are currently assigned charge 0 ligand_charges = {'O1': -2, 'H1O1': -1, 'H1O2': -1, 'C5H7O2': -1} if ligand[0] in list(ligand_charges.keys()): ligand_charge = ligand_charges[ligand[0]] else: ligand_charge = 0 metal_charge = charge - ligand_charge # Assign spin, which always remains with the metal except for when an O2 leaves if spinmult == 1: # If the whole complex is restricted, it's components must be restricted as well ligand_spin, metal_spin = 1, 1 else: ligand_spinmults = {'O2': 3} if ligand[0] in list(ligand_spinmults.keys()): ligand_spin = ligand_spinmults[ligand[0]] else: ligand_spin = 1 metal_spin = spinmult - ligand_spin + 1 # Derived from spinmult = (2S+1) where S=1/2 per electron # Create the necessary files for the metal complex single point local_name = name + '_rm_' + ligand[0] if os.path.isdir('rm_' + ligand[0]): pass else: os.mkdir('rm_' + ligand[0]) os.chdir('rm_' + ligand[0]) local_mol = mol3D() local_mol.copymol3D(mol) local_mol.deleteatoms(ligand[1]) local_mol.writexyz(local_name + '.xyz') local_infile_dict = copy.copy(infile_dict) local_infile_dict['name'] = local_name local_infile_dict['charge'], local_infile_dict[ 'spinmult'] = metal_charge, metal_spin local_infile_dict['run_type'] = 'energy' local_infile_dict['constraints'], local_infile_dict[ 'convergence_thresholds'] = False, False manager_io.write_input(local_infile_dict) manager_io.write_jobscript(local_name, time_limit='12:00:00', sleep=True) jobscripts.append(local_name + '.in') os.chdir('..') # Create the necessary files for the dissociated ligand single point local_name = name + '_kp_' + ligand[0] if os.path.isdir('kp_' + ligand[0]): pass else: os.mkdir('kp_' + ligand[0]) os.chdir('kp_' + ligand[0]) local_mol = mol3D() local_mol.copymol3D(mol) deletion_indices = list( set(range(local_mol.natoms)) - set(ligand[1])) local_mol.deleteatoms(deletion_indices) local_mol.writexyz(local_name + '.xyz') local_infile_dict = copy.copy(infile_dict) local_infile_dict['name'] = local_name local_infile_dict['charge'], local_infile_dict[ 'spinmult'] = ligand_charge, ligand_spin local_infile_dict['run_type'] = 'energy' local_infile_dict['constraints'], local_infile_dict[ 'convergence_thresholds'] = False, False manager_io.write_input(local_infile_dict) manager_io.write_jobscript(local_name, time_limit='12:00:00', sleep=True) jobscripts.append(local_name + '.in') os.chdir('..') os.chdir(home) return jobscripts
def find_ligand_autocorrelations_oct(mol, prop, loud, depth, name=False, oct=True, custom_ligand_dict=False): ## this function takes a ## symmetric (axial == axial, ## equatorial == equatorial) ## octahedral complex ## and returns autocorrelations for ## the axial an equatorial ligands ## custom_ligand_dict allows the user to skip the breakdown ## in cases where 3D geo is not correct/formed ## custom_ligand_dict.keys() must be eq_ligands_list, ax_ligand_list ## ax_con_int_list ,eq_con_int_list ## with types: eq/ax_ligand_list list of mol3D ## eq/ax_con_int_list list of list/tuple of int e.g, [[1,2] [1,2]] if not custom_ligand_dict: liglist, ligdents, ligcons = ligand_breakdown(mol) ax_ligand_list, eq_ligand_list, ax_natoms_list, eq_natoms_list, ax_con_int_list, eq_con_int_list, ax_con_list, eq_con_list, built_ligand_list = ligand_assign( mol, liglist, ligdents, ligcons, loud, name=False) else: ax_ligand_list = custom_ligand_dict["ax_ligand_list"] eq_ligand_list = custom_ligand_dict["eq_ligand_list"] ax_con_int_list = custom_ligand_dict["ax_con_int_list"] eq_con_int_list = custom_ligand_dict["eq_con_int_list"] ## count ligands n_ax = len(ax_ligand_list) n_eq = len(eq_ligand_list) ## get full ligand AC ax_ligand_ac_full = [] eq_ligand_ac_full = [] for i in range(0, n_ax): if not list(ax_ligand_ac_full): ax_ligand_ac_full = full_autocorrelation(ax_ligand_list[i].mol, prop, depth) else: ax_ligand_ac_full += full_autocorrelation(ax_ligand_list[i].mol, prop, depth) ax_ligand_ac_full = np.divide(ax_ligand_ac_full, n_ax) for i in range(0, n_eq): if not list(eq_ligand_ac_full): eq_ligand_ac_full = full_autocorrelation(eq_ligand_list[i].mol, prop, depth) else: eq_ligand_ac_full += full_autocorrelation(eq_ligand_list[i].mol, prop, depth) eq_ligand_ac_full = np.divide(eq_ligand_ac_full, n_eq) ## get partial ligand AC ax_ligand_ac_con = [] eq_ligand_ac_con = [] for i in range(0, n_ax): if not list(ax_ligand_ac_con): ax_ligand_ac_con = atom_only_autocorrelation( ax_ligand_list[i].mol, prop, depth, ax_con_int_list[i]) else: ax_ligand_ac_con += atom_only_autocorrelation( ax_ligand_list[i].mol, prop, depth, ax_con_int_list[i]) ax_ligand_ac_con = np.divide(ax_ligand_ac_con, n_ax) for i in range(0, n_eq): if not list(eq_ligand_ac_con): eq_ligand_ac_con = atom_only_autocorrelation( eq_ligand_list[i].mol, prop, depth, eq_con_int_list[i]) else: eq_ligand_ac_con += atom_only_autocorrelation( eq_ligand_list[i].mol, prop, depth, eq_con_int_list[i]) eq_ligand_ac_con = np.divide(eq_ligand_ac_con, n_eq) # ax_ligand_ac_con = atom_only_autocorrelation(ax_ligand.mol,prop,depth,ax_con_int) # eq_ligand_ac_con = atom_only_autocorrelation(eq_ligand.mol,prop,depth,eq_con_int) return ax_ligand_ac_full, eq_ligand_ac_full, ax_ligand_ac_con, eq_ligand_ac_con
def generate_all_ligand_misc(mol, loud, custom_ligand_dict=False, force_legacy=False): # custom_ligand_dict.keys() must be eq_ligands_list, ax_ligand_list ## ax_con_int_list ,eq_con_int_list # with types: eq/ax_ligand_list list of mol3D # eq/ax_con_int_list list of list/tuple of int e.g, [[1,2] [1,2]] # use force_legacy to get kier indices/MCDL result_ax = list() result_eq = list() if force_legacy: colnames = ['dent', 'maxDEN', 'ki', 'tki', 'charge'] else: colnames = ['dent', 'charge'] if not custom_ligand_dict: liglist, ligdents, ligcons = ligand_breakdown(mol) ax_ligand_list, eq_ligand_list, ax_natoms_list, eq_natoms_list, ax_con_int_list, eq_con_int_list, ax_con_list, eq_con_list, built_ligand_list = ligand_assign( mol, liglist, ligdents, ligcons, loud, name=False) else: ax_ligand_list = custom_ligand_dict["ax_ligand_list"] eq_ligand_list = custom_ligand_dict["eq_ligand_list"] ax_con_int_list = custom_ligand_dict["ax_con_int_list"] eq_con_int_list = custom_ligand_dict["eq_con_int_list"] # count ligands n_ax = len(ax_ligand_list) n_eq = len(eq_ligand_list) # allocate result_ax_dent = False result_eq_dent = False result_ax_maxdelen = False result_eq_maxdelen = False result_ax_ki = False result_eq_ki = False result_ax_tki = False result_eq_tki = False result_ax_charge = False result_eq_charge = False # loop over axial ligands if n_ax > 0: for i in range(0, n_ax): ax_ligand_list[i].mol.convert2OBMol() if not (i == 0): result_ax_dent += ax_ligand_list[i].dent if force_legacy: result_ax_maxdelen += get_lig_EN( ax_ligand_list[i].mol, ax_con_int_list[i]) result_ax_ki += kier(ax_ligand_list[i].mol) result_ax_tki += get_truncated_kier( ax_ligand_list[i].mol, ax_con_int_list[i]) result_ax_charge += ax_ligand_list[i].mol.OBMol.GetTotalCharge() else: result_ax_dent = ax_ligand_list[i].dent if force_legacy: result_ax_maxdelen = get_lig_EN( ax_ligand_list[i].mol, ax_con_int_list[i]) result_ax_ki = kier(ax_ligand_list[i].mol) result_ax_tki = get_truncated_kier( ax_ligand_list[i].mol, ax_con_int_list[i]) result_ax_charge = ax_ligand_list[i].mol.OBMol.GetTotalCharge() # average axial results result_ax_dent = np.divide(result_ax_dent, n_ax) if force_legacy: result_ax_maxdelen = np.divide(result_ax_maxdelen, n_ax) result_ax_ki = np.divide(result_ax_ki, n_ax) result_ax_tki = np.divide(result_ax_tki, n_ax) result_ax_charge = np.divide(result_ax_charge, n_ax) # loop over eq ligands if n_eq > 0: for i in range(0, n_eq): eq_ligand_list[i].mol.convert2OBMol() if not (i == 0): result_eq_dent += eq_ligand_list[i].dent if force_legacy: result_eq_maxdelen += get_lig_EN( eq_ligand_list[i].mol, eq_con_int_list[i]) result_eq_ki += kier(eq_ligand_list[i].mol) result_eq_tki += get_truncated_kier( eq_ligand_list[i].mol, eq_con_int_list[i]) result_eq_charge += eq_ligand_list[i].mol.OBMol.GetTotalCharge() else: result_eq_dent = eq_ligand_list[i].dent if force_legacy: result_eq_maxdelen = get_lig_EN( eq_ligand_list[i].mol, eq_con_int_list[i]) result_eq_ki = kier(eq_ligand_list[i].mol) result_eq_tki = get_truncated_kier( eq_ligand_list[i].mol, eq_con_int_list[i]) result_eq_charge = eq_ligand_list[i].mol.OBMol.GetTotalCharge() # average eq results result_eq_dent = np.divide(result_eq_dent, n_eq) if force_legacy: result_eq_maxdelen = np.divide(result_eq_maxdelen, n_eq) result_eq_ki = np.divide(result_eq_ki, n_eq) result_eq_tki = np.divide(result_eq_tki, n_eq) result_eq_charge = np.divide(result_eq_charge, n_eq) # save the results result_ax.append(result_ax_dent) if force_legacy: result_ax.append(result_ax_maxdelen) result_ax.append(result_ax_ki) result_ax.append(result_ax_tki) result_ax.append(result_ax_charge) result_eq.append(result_eq_dent) if force_legacy: result_eq.append(result_eq_maxdelen) result_eq.append(result_eq_ki) result_eq.append(result_eq_tki) result_eq.append(result_eq_charge) results_dictionary = {'colnames': colnames, 'result_ax': result_ax, 'result_eq': result_eq} return results_dictionary
def match_lig_list(file_in, file_init_geo, catoms_arr, flag_loose, flag_lbd=True, debug=False, depth=3, BondedOct=False): flag_match = True my_mol = create_mol_with_xyz(_file_in=file_in) init_mol = create_mol_with_xyz(_file_in=file_init_geo) if flag_lbd: # Also do ligand breakdown for opt geo my_mol_trunc = obtain_truncation_metal(my_mol, depth) init_mol_trunc = obtain_truncation_metal(init_mol, depth) my_mol_trunc.createMolecularGraph() init_mol_trunc.createMolecularGraph() init_mol_trunc.writexyz('init_trunc_tmp.xyz') my_mol_trunc.writexyz('mymol_trunc_tmp.xyz') liglist_init, ligdents_init, ligcons_init = ligand_breakdown( init_mol_trunc) liglist, ligdents, ligcons = ligand_breakdown(my_mol_trunc) liglist_atom = [[my_mol_trunc.getAtom(x).symbol() for x in ele] for ele in liglist] liglist_init_atom = [[init_mol_trunc.getAtom(x).symbol() for x in ele] for ele in liglist_init] if debug: print(('!!!!:', [x.symbol() for x in init_mol_trunc.getAtoms()])) print(('liglist_init, ligdents_init, ligcons_init', liglist_init, ligdents_init, ligcons_init)) # print('liglist, ligdents, ligcons', liglist, ligdents, ligcons) else: # ceate/use the liglist, ligdents, ligcons of initial geo as we just wanna track them down # _start = time.clock() if debug: print('Just inherit the ligand list from init structure.') liglist_init, ligdents_init, ligcons_init = ligand_breakdown( init_mol, flag_loose=flag_loose, BondedOct=BondedOct) # _elapsed = (time.clock() - _start) # print('time on lig_breakdoen:', _elapsed) liglist, ligdents, ligcons = liglist_init[:], ligdents_init[:], ligcons_init[:] liglist_atom = [[my_mol.getAtom(x).symbol() for x in ele] for ele in liglist] liglist_init_atom = [[init_mol.getAtom(x).symbol() for x in ele] for ele in liglist_init] if debug: print(('ligand_list opt in symbols:', liglist_atom)) print(('ligand_list init in symbols: ', liglist_init_atom)) liglist_shifted = [] for ele in liglist_init_atom: # posi = liglist_atom.index(ele) # liglist_shifted.append(liglist[posi]) # liglist_atom.pop(posi) try: _flag = False for idx, _ele in enumerate(liglist_atom): if set(ele) == set(_ele) and len(ele) == len(_ele): if debug: print(('fragment in liglist_init', ele)) print(('fragment in liglist', _ele)) posi = idx _flag = True liglist_shifted.append(liglist[posi]) liglist_atom.pop(posi) liglist.pop(posi) if not _flag: if debug: print('Ligands cannot match!') flag_match = False except: print('Ligands cannot match!') flag_match = False if debug: print(('!!!!!returns', liglist_shifted, liglist_init)) return liglist_shifted, liglist_init, flag_match