def grow_linear_step(chain, new_unit, dim, interv): combined_mol = mol3D() combined_mol.copymol3D(chain) add_mol = mol3D() add_mol.copymol3D(new_unit) add_mol = zero_dim(new_unit, dim) chain_inds = range(0, chain.natoms) print('chain_inds', chain_inds) basic_lengths = find_extents(chain) # print(basic_lengths) basic_dist = basic_lengths[dim] tv = [0, 0, 0] tv[dim] = basic_dist # add_mol.translate(tv) print('translating', tv) add_mol.translate(interv) add_mol.writexyz('precut.xyz') add_mol = remove_closest_h(add_mol, combined_mol) add_mol.writexyz('postcut.xyz') combined_mol = combined_mol.combine(add_mol) #combined_mol,en = chain_ffopt('',combined_mol,[]) combined_mol.writexyz('pre.xyz') combined_mol.writexyz('post.xyz') return combined_mol
def freeze_bottom_n_layers(super_cell, n): frozen_cell = mol3D() frozen_cell.copymol3D(super_cell) counter = 0 while counter < n: frozen_cell_new = freeze_under_layer(frozen_cell) frozen_cell = mol3D() frozen_cell.copymol3D(frozen_cell_new) counter += 1 return frozen_cell
def obtain_mol3d(self): new_mol = mol3D() this_mol = mol3D() this_mol.readfromxyz(self.geopath) if this_mol.natoms > 0: self.mol = this_mol self.natoms = this_mol.natoms self.health = True else: self.comments.append('geo file appears empty') self.health = False
def grow_linear_step(chain, new_unit, dim, interv, conatom, freezhead): combined_mol = mol3D() combined_mol.copymol3D(chain) combined_mol.convert2OBMol() add_mol = mol3D() add_mol.copymol3D(new_unit) add_mol.convert2OBMol() add_mol = zero_dim(new_unit, dim) chain_inds = range(0, chain.natoms) print('chain_inds', chain_inds) print('freezehead is ' + str(freezhead)) print('freezehead is ' + str(freezhead)) basic_lengths = find_extents(chain) print('extents are ' + str(basic_lengths)) basic_dist = basic_lengths[dim] tv = [0, 0, 0] tv[dim] = basic_dist print('translating', tv) add_mol.translate(interv) add_mol.writexyz('precut.xyz') #add_mol = remove_closest_h(add_mol,combined_mol) add_mol.writexyz('postcut.xyz') #combined_mol.printxyz() #add_mol.printxyz() combined_mol = combined_mol.combine(add_mol, bond_to_add=[(conatom, combined_mol.natoms, 1)]) #ffopt(ff,mol,connected,constopt,frozenats,frozenangles,mlbonds,nsteps,debug=False): combined_mol, en = ffopt('MMFF94', mol=combined_mol, connected=[], constopt=0, frozenats=range(0, freezhead + 1), frozenangles=[], mlbonds=[], nsteps=200, debug=False) combined_mol.convert2mol3D() combined_mol.writexyz('pre.xyz') combined_mol.writexyz('post.xyz') return combined_mol
def assemble_connectivity_from_parts(metal_mol, custom_ligand_dict): ## custom_ligand_dict.keys() must be eq_ligands_list, ax_ligand_list ## ax_con_int_list ,eq_con_int_list ## with types: eq/ax_ligand2_list list of mol3D ## eq/ax_con_int_list list of list/tuple of int e.g, [[1,2] [1,2]] blank_mol = mol3D() # start with the connectivity matrix of the whole comlpex n_total = 1+ sum(m.mol.natoms for m in custom_ligand_dict["eq_ligand_list"]) + \ sum(m.mol.natoms for m in custom_ligand_dict["ax_ligand_list"]) con_mat = np.zeros((n_total, n_total)) this_complex = mol3D() this_complex.copymol3D(metal_mol) live_row = 1 # metal goes in row 0 for i, class_lig in enumerate(custom_ligand_dict["eq_ligand_list"]): this_lig = class_lig.mol this_dim = this_lig.natoms this_con = custom_ligand_dict["eq_con_int_list"][i] this_lig.convert2OBMol() this_lig.createMolecularGraph() con_mat[live_row:live_row + this_dim, live_row:live_row + this_dim] = this_lig.graph for con_atoms in this_con: con_mat[0, live_row + con_atoms] = 1 con_mat[live_row + con_atoms, 0] = 1 live_row = live_row + this_dim this_complex.combine(this_lig, [], dirty=True) for i, class_lig in enumerate(custom_ligand_dict["ax_ligand_list"]): this_lig = class_lig.mol this_dim = this_lig.natoms this_con = custom_ligand_dict["ax_con_int_list"][i] this_lig.convert2OBMol() this_lig.createMolecularGraph() con_mat[live_row:live_row + this_dim, live_row:live_row + this_dim] = this_lig.graph for con_atoms in this_con: con_mat[0, live_row + con_atoms] = 1 con_mat[live_row + con_atoms, 0] = 1 live_row = live_row + this_dim this_complex.combine(this_lig, [], dirty=True) if not int(sum(con_mat[:, 0])) == 6: print('coordination number is ' + str(sum(con_mat[:, 0]))) print('error, not oct ') sys.exit() # overwrite the connectivity matrix this_complex.graph = con_mat return this_complex
def bind_load(userbind,bindcores): globs = globalvars() if '~' in userbind: homedir = os.path.expanduser("~") userbind = userbind.replace('~',homedir) emsg = False bind = mol3D() # initialize binding molecule bsmi = False # flag for smiles ### check if binding molecule exists in dictionary if userbind in bindcores.keys(): # load bind mol file (with hydrogens) # fbind = installdir+'Bind/'+bindcores[userbind][0] if globs.custom_path: fbind = globs.custom_path + "/Bind/" + bindcores[userbind][0] else: fbind = resource_filename(Requirement.parse("molSimplify"),"molSimplify/Bind/" +bindcores[userbind][0]) # check if bind xyz/mol file exists if not glob.glob(fbind): emsg = "We can't find the binding species structure file %s right now! Something is amiss. Exiting..\n" % fbind print emsg return False,False,emsg if ('.xyz' in fbind): bind.OBMol = bind.getOBMol(fbind,'xyzf') elif ('.mol' in fbind): bind.OBMol = bind.getOBMol(fbind,'molf') elif ('.smi' in fbind): bind.OBMol = bind.getOBMol(fbind,'smif') bind.charge = bind.OBMol.GetTotalCharge() ### load from file elif ('.mol' in userbind or '.xyz' in userbind or '.smi' in userbind): if glob.glob(userbind): ftype = userbind.split('.')[-1] # try and catch error if conversion doesn't work try: bind.OBMol = bind.getOBMol(userbind,ftype+'f') # convert from file bind.charge = bind.OBMol.GetTotalCharge() except IOError: emsg = 'Failed converting file ' +userbind+' to molecule..Check your file.\n' return False,emsg bind.ident = userbind.rsplit('/')[-1] bind.ident = bind.ident.split('.'+ftype)[0] else: emsg = 'Binding species file '+userbind+' does not exist. Exiting..\n' return False,emsg ### if not, try converting from SMILES else: # check for transition metals userbind = checkTMsmiles(userbind) # try and catch error if conversion doesn't work try: bind.OBMol = bind.getOBMol(userbind,'smi') # convert from smiles bind.charge = bind.OBMol.GetTotalCharge() bsmi = True bind.ident = 'smi' except IOError: emsg = "We tried converting the string '%s' to a molecule but it wasn't a valid SMILES string.\n" % userbind emsg += "Furthermore, we couldn't find the binding species structure: '%s' in the binding species dictionary. Try again!\n" % userbind print emsg return False,False,emsg return bind, bsmi, emsg
def check_top_layer_correct(super_cell, atom_type): # remove the layer on # top of the cell if # wrong material is exposed trimmed_cell = mol3D() trimmed_cell.copymol3D(super_cell) globs = globalvars() elements = globs.elementsbynum() print(('chekcing surface for ' + atom_type + '\n')) if not atom_type in elements: print("unkown surface type, unable to trim ") return trimmed_cell else: stop_flag = False counter = 0 # 3 tries max while not stop_flag: atom_type_surf = find_all_surface_atoms(trimmed_cell, tol=1e-3, type_of_atom=atom_type) top_surf = find_all_surface_atoms(trimmed_cell, tol=1e-3, type_of_atom=False) # print("top surf",top_surf) # print("atom top surf",atom_type_surf) if set(atom_type_surf) == set(top_surf): print('match') stop_flag = True else: counter += 1 trimmed_cell = shave_surface_layer(trimmed_cell, 1e-3) if counter == 3: print('unable to find target atom in 3 cuts') stop_flag = True return trimmed_cell
def shave__type(super_cell, dim, mode): ## dim = 0,1,2 # x,y,z # mode = 1 for max, -1 for min shaved_cell = mol3D() shaved_cell.copymol3D(super_cell) TOL = 1e-1 dim_ref = 1000 if (mode == -1): for i, atoms in enumerate(super_cell.getAtoms()): coords = atoms.coords() if (coords[dim] < dim_ref): dim_ref = coords[dim] del_list = list() for i, atoms in enumerate(super_cell.getAtoms()): coords = atoms.coords() if abs(coords[dim] - dim_ref) < TOL: del_list.append(i) if (mode == 1): extents = find_extents(super_cell) dim_max = extents[dim] del_list = list() for i, atoms in enumerate(super_cell.getAtoms()): coords = atoms.coords() if abs(coords[dim] - dim_max) < TOL: del_list.append(i) # return shaved_cell.deleteatoms(del_list) return shaved_cell
def substplaceff_mode3(core, substr, substreact, compreact, cpoint, args, connected, frozenats): enc = 0 # align substrate according to connection atom and shadow atom substr.alignmol(substr.getAtom(substreact), atom3D('H', cpoint)) # perform rotations Bcoords = core.getAtomCoords(compreact) adjsidx = substr.getBondedAtoms(substreact)[0] if substr.natoms > 1: # align ligand center of symmetry substr = align_lig_centersym(Bcoords, substr, substreact, core, False) if substr.natoms > 2: # check for linear molecule and align substr = check_rotate_linear_lig(Bcoords, substr, substreact) # check for symmetric molecule substr = check_rotate_symm_lig(Bcoords, substr, substreact, core) # rotate around M-L axis to minimize steric repulsion substr = rotate_MLaxis_minimize_steric(Bcoords, substr, substreact, core) # distort substrate molecule adjsidx = substr.getBondedAtoms(substreact)[0] XYBL = XYcoeff * (substr.getAtom(substreact).rad + substr.getAtom(adjsidx).rad) substr.BCM(adjsidx, substreact, XYBL) # combine molecules ts3D = mol3D() ts3D.copymol3D(core) ts3D = ts3D.combine(substr) ts3D.charge += substr.charge if 'a' in args.ffoption or args.substplaceff: ts3D, enc = ffopt(args.ff, ts3D, connected, 1, frozenats, False, [], 'Adaptive') return ts3D, enc
def obtain_truncation(self, con_atoms, hops): self.trunc_mol = mol3D() added_list = list() for connections in con_atoms: hopped = 0 active_set = [connections] while hopped < hops: hopped += 1 new_active_set = list() for this_atom in active_set: this_atoms_neighbors = self.master_mol.getBondedAtoms( this_atom) for bound_atoms in this_atoms_neighbors: if (bound_atoms in self.index_list) and (bound_atoms not in added_list): self.trunc_mol.addAtom( self.master_mol.getAtom(bound_atoms)) added_list.append(bound_atoms) [ new_active_set.append(element) for element in this_atoms_neighbors ] active_set = new_active_set return trunc_mol
def trim_H(mol,reference_point): trimmed_mol = mol3D() trimmed_mol.copymol3D(mol) min_ind = find_term_heavy(mol,reference_point) hydrogen_list = trimmed_mol.getHsbyIndex(min_ind) trimmed_mol.deleteatoms([hydrogen_list[0]]) return trimmed_mol
def obtain_truncation(mol, con_atoms, hops): ## this function truncates a ligand to a certain number of ## hops from the core # Inputs: # mol - mol3D class to truncate # con_atoms - index of atoms that connect to metal # hops - int, number of hops to truncate trunc_mol = mol3D() added_list = list() for connections in con_atoms: hopped = 0 active_set = [connections] while hopped < hops: hopped += 1 new_active_set = list() for this_atom in active_set: ## add all connection atoms if this_atom not in added_list: trunc_mol.addAtom(mol.getAtom(this_atom)) added_list.append(this_atom) ## prepare all atoms attached to this connection this_atoms_neighbors = mol.getBondedAtomsSmart(this_atom) for bound_atoms in this_atoms_neighbors: if (bound_atoms not in added_list): trunc_mol.addAtom(mol.getAtom(bound_atoms)) added_list.append(bound_atoms) [ new_active_set.append(element) for element in this_atoms_neighbors ] active_set = new_active_set return trunc_mol
def chain_ffopt(ff,mol,frozenats): ### FORCE FIELD OPTIMIZATION ## # INPUT # - ff: force field to use, available MMFF94, UFF< Ghemical, GAFF # - mol: mol3D to be ff optimized # - connected: indices of connection atoms to metal # - constopt: flag for constrained optimization # OUTPUT # - mol: force field optimized mol3D metals = range(21,31)+range(39,49)+range(72,81) ### check requested force field ffav = 'mmff94, uff, ghemical, gaff, mmff94s' # force fields if ff.lower() not in ffav: print 'Requested force field not available. Defaulting to MMFF94' ff = 'mmff94' ### convert mol3D to OBmol via xyz file, because AFTER/END option have coordinates backup_mol = mol3D() backup_mol.copymol3D(mol) # print('bck ' + str(backup_mol.getAtom(0).coords())) # print('mol_ibf ' + str(mol.getAtom(0).coords())) mol.writexyz('tmp.xyz') mol.OBmol = mol.getOBmol('tmp.xyz','xyzf') os.remove('tmp.xyz') ### initialize constraints constr = pybel.ob.OBFFConstraints() ### openbabel indexing starts at 1 ### !!! # convert metals to carbons for FF indmtls = [] mtlsnums = [] for iiat,atom in enumerate(mol.OBmol.atoms): if atom.atomicnum in metals: indmtls.append(iiat) mtlsnums.append(atom.atomicnum) atom.OBAtom.SetAtomicNum(19) for cat in frozenats: constr.AddAtomConstraint(cat+1) # indexing babel ### set up forcefield forcefield =pybel.ob.OBForceField.FindForceField(ff) obmol = mol.OBmol.OBMol forcefield.Setup(obmol,constr) ## force field optimize structure forcefield.ConjugateGradients(2500) forcefield.GetCoordinates(obmol) mol.OBmol = pybel.Molecule(obmol) # reset atomic number to metal for i,iiat in enumerate(indmtls): mol.OBmol.atoms[iiat].OBAtom.SetAtomicNum(mtlsnums[i]) mol.convert2mol3D() en = forcefield.Energy() # print(str(mol.OBmol.atoms[1].OBAtom.GetVector().GetZ())) # print(str(forcefield.Validate())) # print('mol_af ' + str(mol.getAtom(0).coords())) # print('ff delta = ' + str(backup_mol.rmsd(mol))) del forcefield, constr, obmol return mol,en
def change_basis(mol, old_basis,new_basis): new_mol = mol3D() new_mol.copymol3D(mol) point_coefficients = [get_basis_coefficients(at.coords(),old_basis) for at in new_mol.getAtoms()] new_points = [get_basis_coefficients(point,new_basis) for point in point_coefficients] for i,at in enumerate(new_mol.getAtoms()): at.setcoords(new_points[i]) return new_mol
def assemble_connectivity_from_parts(metal_mol, custom_ligand_dict): ## custom_ligand_dict.keys() must be eq_ligands_list, ax_ligand_list ## ax_con_int_list ,eq_con_int_list ## with types: eq/ax_ligand2_list list of mol3D ## eq/ax_con_int_list list of list/tuple of int e.g, [[1,2] [1,2]] blank_mol = mol3D() # start with the connectivity matrix of the whole comlpex n_total = 1+ sum(m.mol.natoms for m in custom_ligand_dict["eq_ligand_list"]) + \ sum(m.mol.natoms for m in custom_ligand_dict["ax_ligand_list"]) con_mat = np.zeros((n_total,n_total)) this_complex = mol3D() this_complex.copymol3D(metal_mol) live_row = 1 # metal goes in row 0 for i, class_lig in enumerate(custom_ligand_dict["eq_ligand_list"]): this_lig = class_lig.mol this_dim = this_lig.natoms this_con = custom_ligand_dict["eq_con_int_list"][i] this_lig.convert2OBMol() this_lig.createMolecularGraph() con_mat[live_row:live_row + this_dim,live_row:live_row + this_dim] = this_lig.graph for con_atoms in this_con: con_mat[0,live_row + con_atoms] = 1 con_mat[live_row + con_atoms,0] = 1 live_row = live_row + this_dim this_complex.combine(this_lig,[],dirty=True) for i, class_lig in enumerate(custom_ligand_dict["ax_ligand_list"]): this_lig = class_lig.mol this_dim = this_lig.natoms this_con = custom_ligand_dict["ax_con_int_list"][i] this_lig.convert2OBMol() this_lig.createMolecularGraph() con_mat[live_row:live_row + this_dim,live_row:live_row + this_dim] = this_lig.graph for con_atoms in this_con: con_mat[0,live_row + con_atoms] = 1 con_mat[live_row + con_atoms,0] = 1 live_row = live_row + this_dim this_complex.combine(this_lig,[],dirty=True) if not int(sum(con_mat[:,0])) ==6: print('coordination number is ' + str(sum(con_mat[:,0]))) print('error, not oct ') sys.exit() # overwrite the connectivity matrix this_complex.graph = con_mat return this_complex
def zero_x(mol): zeroed_mol = mol3D() zeroed_mol.copymol3D(mol) TOL = 1e-1 xmin = 1000; for i,atoms in enumerate(mol.getAtoms()): coords = atoms.coords() if (coords[0] < xmin): xmin = coords[0] zeroed_mol.translate([-1*xmin,0,0]) return zeroed_mol
def zero_z(mol): zeroed_mol = mol3D() zeroed_mol.copymol3D(mol) TOL = 1e-1 zmin = 1000; for i,atoms in enumerate(mol.getAtoms()): coords = atoms.coords() if (coords[2] < zmin): zmin = coords[2] zeroed_mol.translate([0,0,-1*zmin]) return zeroed_mol
def zero_y(mol): zeroed_mol = mol3D() zeroed_mol.copymol3D(mol) TOL = 1e-1 ymin = 1000; for i,atoms in enumerate(mol.getAtoms()): coords = atoms.coords() if (coords[1] < ymin): ymin = coords[1] zeroed_mol.translate([0,-1*ymin,0]) return zeroed_mol
def obtain_mol3d(self): this_mol = mol3D() this_ext_int_dict = dict() j = 0 for i in range(0, self.master_mol.natoms): if i in self.index_list: this_mol.addAtom(self.master_mol.getAtom(i)) this_ext_int_dict.update({i: j}) j += 1 # keep count of how many are added self.mol = this_mol self.ext_int_dict = this_ext_int_dict
def shave_surface_layer(super_cell, TOL=1e-1): shaved_cell = mol3D() shaved_cell.copymol3D(super_cell) extents = find_extents(super_cell) zmax = extents[2] del_list = list() for i, atoms in enumerate(super_cell.getAtoms()): coords = atoms.coords() if abs(coords[2] - zmax) < TOL: del_list.append(i) shaved_cell.deleteatoms(del_list) return shaved_cell
def grow_linear_step(chain,new_unit,dim,interv,conatom,freezhead): combined_mol = mol3D() combined_mol.copymol3D(chain) combined_mol.convert2OBMol() add_mol = mol3D() add_mol.copymol3D(new_unit) add_mol.convert2OBMol() add_mol = zero_dim(new_unit,dim) chain_inds = range(0,chain.natoms) print('chain_inds',chain_inds) print('freezehead is '+str(freezhead)) print('freezehead is '+str(freezhead)) basic_lengths = find_extents(chain) print('extents are ' + str(basic_lengths)) basic_dist = basic_lengths[dim] tv =[0,0,0] tv[dim] = basic_dist print('translating',tv) add_mol.translate(interv) add_mol.writexyz('precut.xyz') #add_mol = remove_closest_h(add_mol,combined_mol) add_mol.writexyz('postcut.xyz') #combined_mol.printxyz() #add_mol.printxyz() combined_mol = combined_mol.combine(add_mol,bond_to_add=[(conatom,combined_mol.natoms,1)]) #ffopt(ff,mol,connected,constopt,frozenats,frozenangles,mlbonds,nsteps,debug=False): combined_mol,en = ffopt('MMFF94',mol=combined_mol,connected=[],constopt=0, frozenats=range(0,freezhead+1),frozenangles=[], mlbonds=[],nsteps=200,debug=False) combined_mol.convert2mol3D() combined_mol.writexyz('pre.xyz') combined_mol.writexyz('post.xyz') return combined_mol
def fsym(xyzf): # setting properties xyz = mol3D() xyz.readfromxyz(xyzf) # getting idxs of interest midx = xyz.findMetal()[0] # monometallic complexes fidx_list = xyz.getBondedAtoms(midx) # list of idx of the first-coord sphere fsym_list = [] for idx in fidx_list: sym = xyz.getAtom(idx).sym fsym_list.append(sym) return fsym_list
def fvalency(xyzf): # setting properties xyz = mol3D() xyz.readfromxyz(xyzf) # getting idxs of interest midx = xyz.findMetal()[0] # monometallic complexes fidx_list = xyz.getBondedAtoms(midx) # list of idx of the first-coord sphere fvalency_list = [] for idx in fidx_list: valency = len(xyz.getBondedAtoms(idx)) - 1 fvalency_list.append(valency) return fvalency_list
def fcharge(xyzf,charge): # setting properties xyz = mol3D() xyz.readfromxyz(xyzf) xyz.calccharges(charge) # getting idxs of interest midx = xyz.findMetal()[0] # monometallic complexes fidx_list = xyz.getBondedAtoms(midx) # list of idx of the first-coord sphere fcharge_list = [] for idx in fidx_list: charge = xyz.partialcharges[idx] fcharge_list.append(float(charge)) return fcharge_list
def obtain_mol3d(self): this_mol = mol3D() this_ext_int_dict = dict() j = 0 ## the old routine where all atoms in the master_mol are gone through from 0 to natoms-1 # for i in range(0, self.master_mol.natoms): # if i in self.index_list: ## the new rountine where the indices are taken out directly. This way the order of atoms is preserved for i in self.index_list: this_mol.addAtom(self.master_mol.getAtom(i)) this_ext_int_dict.update({i: j}) j += 1 # keep count of how many are added self.mol = this_mol self.ext_int_dict = this_ext_int_dict
def fsym(xyzf): # setting properties xyz = mol3D() xyz.readfromxyz(xyzf) # getting idxs of interest midx = xyz.findMetal()[0] # monometallic complexes # list of idx of the first-coord sphere fidx_list = xyz.getBondedAtoms(midx) fsym_list = [] for idx in fidx_list: sym = xyz.getAtom(idx).sym fsym_list.append(sym) return fsym_list
def fvalency(xyzf): # setting properties xyz = mol3D() xyz.readfromxyz(xyzf) # getting idxs of interest midx = xyz.findMetal()[0] # monometallic complexes # list of idx of the first-coord sphere fidx_list = xyz.getBondedAtoms(midx) fvalency_list = [] for idx in fidx_list: valency = len(xyz.getBondedAtoms(idx)) - 1 fvalency_list.append(valency) return fvalency_list
def deltametrics(dir="../data/xyz/"): # begin parsing str_temp = dir + "/*.xyz" target_paths = sorted(glob.glob(str_temp)) results_delta = [] for geos in target_paths: this_mol = mol3D() # mol3D instance this_mol.readfromxyz(geos) # read geo # if metals present results_delta_temp = deltametrics(this_mol) results_delta.append(results_delta_temp["results"]) results_delta = np.array(results_delta) return results_delta
def shave_surface_layer(super_cell, TOL=1e-1): # dlist = fractionate_points_by_plane(super_cell,n) # points_below_plane(point,n,refd) shaved_cell = mol3D() shaved_cell.copymol3D(super_cell) extents = find_extents(super_cell) zmax = extents[2] del_list = list() for i, atoms in enumerate(super_cell.getAtoms()): coords = atoms.coords() if abs(coords[2] - zmax) < TOL: del_list.append(i) shaved_cell.deleteatoms(del_list) return shaved_cell
def substplacecheap(core,connPts,catom): corerem = mol3D() corerem.copymol3D(core) corerem.deleteatom(catom) # complex less O atom mdist = -1 cpoint = [0,0,0] for P in connPts: if corerem.mindisttopoint(P) < 1: # auto-reject if too close d0 = -2 else: d0 = distance(core.centermass(),P)+0.5*log(corerem.mindisttopoint(P)-1) if d0 > mdist: mdist = d0 cpoint = P return cpoint
def fcharge(xyzf, charge): # setting properties xyz = mol3D() xyz.readfromxyz(xyzf) xyz.calccharges(charge) # getting idxs of interest midx = xyz.findMetal()[0] # monometallic complexes # list of idx of the first-coord sphere fidx_list = xyz.getBondedAtoms(midx) fcharge_list = [] for idx in fidx_list: charge = xyz.partialcharges[idx] fcharge_list.append(float(charge)) return fcharge_list
def fdistance(xyzf): # setting properties xyz = mol3D() xyz.readfromxyz(xyzf) # getting idxs of interest midx = xyz.findMetal()[0] # monometallic complexes mcoord = xyz.getAtom(midx).coords() fidx_list = xyz.getBondedAtoms(midx) # list of idx of the first-coord sphere fdistance_list = [] for idx in fidx_list: fcoord = xyz.getAtom(idx).coords() d = distance(mcoord,fcoord) fdistance_list.append(float(d)) return fdistance_list
def remove_closest_h(mol,other_mol): new_mol = mol3D() new_mol.copymol3D(mol); min_distance = 1000 current_ind = 0 for Hatoms in mol.getHs(): this_H = mol.getAtom(Hatoms) for atoms in other_mol.getAtoms(): this_distance = mdistance(this_H.coords(),atoms.coords()) if this_distance < min_distance: min_distance = this_distance current_ind = Hatoms print(' the H ind to delete is ' +str(current_ind) + ' at ' + str(min_distance)) new_mol.deleteatoms([current_ind]) return new_mol
def kier(mol): copy_mol = mol3D() copy_mol.copymol3D(mol) copy_mol.deleteHs() A = create_graph(copy_mol) n = A.shape[0] twopath = A * A remove_diagonals(twopath) p2 = twopath.sum() / 2 if (p2 != 0): two_kappa = ((np.power(n, 3) - 5 * np.power(n, 2) + 8 * n - 4) / (np.power(p2, 2))) else: two_kappa = 0 return (two_kappa)
def fdistance(xyzf): # setting properties xyz = mol3D() xyz.readfromxyz(xyzf) # getting idxs of interest midx = xyz.findMetal()[0] # monometallic complexes mcoord = xyz.getAtom(midx).coords() # list of idx of the first-coord sphere fidx_list = xyz.getBondedAtoms(midx) fdistance_list = [] for idx in fidx_list: fcoord = xyz.getAtom(idx).coords() d = distance(mcoord, fcoord) fdistance_list.append(float(d)) return fdistance_list
def shave_under_layer(super_cell): shaved_cell = mol3D() shaved_cell.copymol3D(super_cell) TOL = 1e-1 zmin = 1000 for i, atoms in enumerate(super_cell.getAtoms()): coords = atoms.coords() if (coords[2] < zmin): zmin = coords[2] del_list = list() for i, atoms in enumerate(super_cell.getAtoms()): coords = atoms.coords() if abs(coords[2] - zmin) < TOL: del_list.append(i) shaved_cell.deleteatoms(del_list) return shaved_cell
def features(xyzf,charge): prop_list = all_prop(xyzf,charge) xyz = mol3D() xyz.readfromxyz(xyzf) midx = xyz.findMetal()[0] manto = xyz.getAtom(midx).atno a = np.array(prop_list) b = a.T[a[0].argsort()].T feature_list = b.tolist() feature_list[0] = [int(str(i).split('.')[0]) for i in feature_list[0]] feature = [] feature.append(manto) for i in range(len(feature_list)): for j in range(len(feature_list[i])): feature.append(feature_list[i][j]) return feature
def obtain_truncation(self, con_atoms, hops): self.trunc_mol = mol3D() added_list = list() for connections in con_atoms: hopped = 0 active_set = [connections] while hopped < hops: hopped += 1 new_active_set = list() for this_atom in active_set: this_atoms_neighbors = self.master_mol.getBondedAtomsSmart(this_atom) for bound_atoms in this_atoms_neighbors: if (bound_atoms in self.index_list) and (bound_atoms not in added_list): self.trunc_mol.addAtom(self.master_mol.getAtomSmart(bound_atoms)) added_list.append(bound_atoms) [new_active_set.append(element) for element in this_atoms_neighbors] active_set = new_active_set return trunc_mol
def scharge_ave(xyzf,charge): # setting properties xyz = mol3D() xyz.readfromxyz(xyzf) xyz.calccharges(charge) # getting idxs of interest midx = xyz.findMetal()[0] # monometallic complexes fidx_list = xyz.getBondedAtoms(midx) # list of idx of the first-coord sphere sidx_list = [xyz.getBondedAtoms(fidx) for fidx in fidx_list] scharge_ave_list = [] for i in range(len(sidx_list)): charge = 0 for j in range(len(sidx_list[i])): idx = sidx_list[i][j] if idx is not midx: charge =+ xyz.partialcharges[idx] charge_ave = charge/len(sidx_list[i]) scharge_ave_list.append(float(charge_ave)) return scharge_ave_list
def ligand_comp_org(file_in, file_init_geo, catoms_arr, flag_deleteH=True, flag_loose=False, flag_lbd=True, debug=False, depth=3, BondedOct=False): liglist, liglist_init, flag_match = match_lig_list(file_in, file_init_geo, catoms_arr, flag_loose, flag_lbd, debug=debug, depth=depth, BondedOct=BondedOct) if debug: print('lig_list:', liglist, len(liglist)) print('lig_list_init:', liglist_init, len(liglist_init)) if flag_lbd: mymol_xyz = 'mymol_trunc_tmp.xyz' initmol_xyz = 'init_trunc_tmp.xyz' else: mymol_xyz = file_in initmol_xyz = file_init_geo if flag_match: rmsd_arr, max_atom_dist_arr = [], [] for idx, lig in enumerate(liglist): lig_init = liglist_init[idx] if debug: print('----This is %d th piece of ligand.' % (idx + 1)) print('ligand is:', lig, lig_init) posi_shift = 2 ## Create mol3D without a tmp file. _start = time.clock() with open(mymol_xyz, 'r') as fo: foo = [] for ii, line in enumerate(fo): if (ii - posi_shift) in lig: if debug: print('line is', line) foo.append(line) tmp_mol = mol3D() tmp_mol = readfromtxt(tmp_mol, foo) with open(initmol_xyz, 'r') as fo: foo = [] for ii, line in enumerate(fo): if (ii - posi_shift) in lig_init: if debug: print('line is', line) foo.append(line) tmp_org_mol = mol3D() tmp_org_mol = readfromtxt(tmp_org_mol, foo) _elapsed = (time.clock() - _start) # print('-reading txt:', _elapsed) if debug: print('# atoms: %d, init: %d' % (tmp_mol.natoms, tmp_org_mol.natoms)) print('!!!!atoms:', [x.symbol() for x in tmp_mol.getAtoms()], [x.symbol() for x in tmp_org_mol.getAtoms()]) if flag_deleteH: tmp_mol.deleteHs() tmp_org_mol.deleteHs() mol0, U, d0, d1 = kabsch(tmp_org_mol, tmp_mol) rmsd = tmp_mol.rmsd(tmp_org_mol) rmsd_arr.append(rmsd) atom_dist_max = tmp_mol.maxatomdist(tmp_org_mol) max_atom_dist_arr.append(atom_dist_max) if debug: print('rmsd:', rmsd) print('atom_dist_max', atom_dist_max) rmsd_max = max(rmsd_arr) atom_dist_max = max(max_atom_dist_arr) else: rmsd_max, atom_dist_max = 'lig_mismatch', 'lig_mismatch' return rmsd_max, atom_dist_max
def create_mol_with_xyz(_file_in): my_mol = mol3D() my_mol.readfromxyz(_file_in) return my_mol
def fpriority(xyzf): # setting properties xyz = mol3D() xyz.readfromxyz(xyzf) # setting up variables fpriority_list = [] fidx_list = [] sidx_list = [] satno_list = [] ref_list = [] exit_signal = True # getting bond-order matrix xyz.convert2OBMol() BOMatrix = xyz.populateBOMatrix() # preping for the loop fidx_list.append(xyz.findMetal()) for i in range(len(fidx_list)): for fidx in fidx_list[i]: for sidx in xyz.getBondedAtoms(fidx): sidx_list.append([sidx]) for i in range(len(fidx_list)): for fidx in fidx_list[i]: for j in range(len(sidx_list)): for sidx in sidx_list[j]: BO = int(BOMatrix[fidx][sidx]) if BO == 0: BO = 1 satno_str = str(xyz.getAtom(sidx).atno) satno_list.append(int(BO * satno_str)) for satno in sorted(set(satno_list)): satnocount = satno_list.count(satno) if satnocount > 1: s_sel_list = [i for i,atno in enumerate(satno_list) if atno is satno] exit_signal = False for i in range(len(fidx_list)): for fidx in fidx_list[i]: ref_list.append(fidx) # starting the loop tidx_list = [] tatno_list = [] for i in range(len(sidx_list)): tidx_list.append([]) tatno_list.append([]) while not exit_signal: for i in s_sel_list: t_list = [] for sidx in sidx_list[i]: for tidx in xyz.getBondedAtoms(sidx): if tidx not in ref_list: t_list.append(tidx) tidx_list[i] = t_list # print(sidx_list) # print(tidx_list) for i in s_sel_list: for sidx in sidx_list[i]: atno_list = tatno_list[i] ls = [] for j in s_sel_list: for tidx in tidx_list[j]: BO = int(BOMatrix[sidx][tidx]) tatno_str = str(xyz.getAtom(tidx).atno) ls.append(BO * tatno_str) sorted(ls,reverse=True) for j in ls: atno_list.append(j) a = ''.join(atno_list) tatno_list[i] = [a] sidx_list = [] for i in range(len(tidx_list)): sidx_list.append(tidx_list[i]) for i in s_sel_list: for sidx in sidx_list[i]: ref_list.append(sidx) test_list = [] for i in range(len(sidx_list)): test_list.append([]) if tidx_list == test_list: exit_signal = True for i in range(len(satno_list)): atno_list = [] atno_list.append(str(satno_list[i])) if tatno_list[i] == []: atno_list.append('') else: atno_list.append(tatno_list[i][0]) a = '.'.join(atno_list) fpriority_list.append(float(a)) return fpriority_list
def chain_builder_supervisor(args,rundir): emsg = list() if not (args.chain) and not (isinstance(args.chain_units, (int))): emsg.append('Invalid input: need monomer AND number of units') print(args.chain) print(args.chain_units) print('loading monomer') monomer = mol3D() monomer.OBMol = monomer.getOBMol(args.chain,convtype='smistring') # monomer.OBMol.make3D('mmff94',0) monomer.convert2mol3D() # monomer.writexyz('mono_nozero.xyz') monomer =zero_1st(monomer) # monomer.writexyz('mono_zero_z.xyz') conatom = len(args.chain)-1 print('connection atom is '+monomer.getAtom(conatom).symbol()) old_pos = monomer.getAtom(conatom).coords() idist = 1.25*mdistance(old_pos,[0,0,0]) print('currently at located at ' + str(old_pos)) target = [0,0,-1*mdistance(old_pos,[0,0,0])] print('target located at ' + str(target) ) vec1 = vecdiff([0,0,0],old_pos) print('vecdiff is ' + str(vec1) ) vec2 = [0,0,1] thetaold = vecangle(vec1,vec2) print('thetaold is ' + str(thetaold) ) myu = np.cross(vec1,vec2) theta,u = rotation_params(target,[0,0,0],old_pos) print('rot params are ' + str([theta, u]) +' my way ' + str(thetaold) + ' my norm ' + str(myu)) monomer = rotate_around_axis(monomer,[0,0,0],u,theta) # rotate_around_axis(mol, Rp,u,theta): # Loops over PointRotateAxis(). # @param mol mol3D of molecule to be rotated # @param Rp Reference point along axis # @param u Direction vector of axis # @param theta Angle of rotation in DEGREES # @return mol3D of rotated molecule # monomer.writexyz('mono_rotate.xyz') new_coords = monomer.getAtom(conatom).coords() print('now located at ' + str(new_coords)) print('target located at ' + str(target)) print('\n\n\n') # monomer.writexyz('mono.xyz') interv = [0,0,idist] my_dim = mol3D() my_dim.copymol3D(monomer) # my_dim.writexyz('prestart.xyz') my_dim = trim_H(my_dim,monomer.getAtom(len(args.chain)-1).coords()) basic_lengths = find_extents(my_dim) basic_x = basic_lengths[0] basic_y = basic_lengths[1] # my_dim.writexyz('start.xyz') middle = mol3D() middle.copymol3D(monomer) print('connection atom is '+monomer.getAtom(len(args.chain)-1).symbol()) conatom = len(args.chain)-1 middle = trim_H(middle,monomer.getAtom(len(args.chain)-1).coords()) middle = trim_H(middle,[0,0,0]) print('loading end') end = mol3D() print(args.chain_head) if args.chain_head: end.OBMol = end.getOBMol(args.chain_head,convtype='smistring') else: end.OBMol = end.getOBMol(args.chain,convtype='smistring') #end.OBMol = end.getOBMol("CC1COC(=O)O1",convtype='smistring') # monomer.OBMol.make3D('mmff94',0) end.convert2mol3D() end.writexyz('endi.xyz') end =zero_1st(end) end.writexyz('end_zero_z.xyz') conatom_end = 0 print('end connection atom is '+end.getAtom(conatom_end).symbol()) end_pos = end.getAtom(conatom_end).coords() print('end target position is '+str(end_pos)) target_displacement= mdistance(end_pos,[0,0,0]) end.printxyz() if target_displacement>0.05: target_end = [0,0,-1*mdistance(end_pos,[0,0,0])] theta,u = rotation_params(target_end,[0,0,0],end_pos) end = rotate_around_axis(end,[0,0,0],u,theta) end = trim_H(end,[0,0,0]) end.printxyz() # middle.writexyz('middle.xyz') end.writexyz('end.xyz') repu = mol3D() repu.copymol3D(middle) interv0 = interv old_nat = my_dim.natoms for i in range(0,int(args.chain_units)-1): locked_atoms = my_dim.natoms -1 my_dim = grow_linear_step(my_dim,repu,0,interv,conatom,freezhead = locked_atoms) interv = [interv[i] + interv0[i] for i in [0,1,2]] print('con is '+ str(conatom)) print('old nat is '+ str(old_nat)) conatom = conatom + old_nat old_nat = repu.natoms +1 if not i%2: old_nat -=1 print('build start') locked_atoms = my_dim.natoms -1 my_dim = grow_linear_step(my_dim,end,0,interv,conatom-1,freezhead = locked_atoms) # my_dim.printxyz() my_dim.writexyz('poly.xyz') #my_dim,en = chain_ffopt('',my_dim,[]) my_dim,en = ffopt('MMFF94',my_dim,[],0,[],mlbonds=[],frozenangles=[],nsteps=200,debug=False) my_dim.writexyz('polyf.xyz') if emsg: print(emsg) return emsg
# Written by JP Janet for HJK Group
def decorate_ligand(args,ligand_to_decorate,decoration,decoration_index): # INPUT # - args: placeholder for input arguments # - ligand_to_decorate: mol3D ligand # - decoration: list of smiles/decorations # - decoration_index: list of ligand atoms to replace # OUTPUT # - new_ligand: built ligand # - complex3D: list of all mol3D ligands and core # - emsg: error messages #if args.debug: # print 'decorating ligand' lig = ligand_to_decorate ## reorder to ensure highest atom index ## removed first sort_order = [i[0] for i in sorted(enumerate(decoration_index), key=lambda x:x[1])] sort_order = sort_order[::-1] ## reverse decoration_index = [decoration_index[i] for i in sort_order] decoration=[decoration[i] for i in sort_order] if args.debug: print('decoration_index is ' + str(decoration_index)) licores = getlicores() lig,emsg = lig_load(lig,licores) lig.convert2mol3D() # convert to mol3D ## create new ligand merged_ligand = mol3D() merged_ligand.copymol3D(lig) for i,dec in enumerate(decoration): print('** decoration number ' +str(i)+ ' attaching ' + dec + ' at site '+str(decoration_index[i]) + '**\n') dec,emsg = lig_load(dec,licores) dec.convert2mol3D() # convert to mol3D if args.debug: print(i) print(decoration_index) print(merged_ligand.getAtom(decoration_index[i]).symbol()) print(merged_ligand.getAtom(decoration_index[i]).coords()) merged_ligand.writexyz('basic.xyz') #dec.writexyz('dec' + str(i) + '.xyz') Hs = dec.getHsbyIndex(0) if len(Hs) > 0: dec.deleteatom(Hs[0]) dec.charge = dec.charge - 1 #dec.writexyz('dec_noH' + str(i) + '.xyz') dec.alignmol(dec.getAtom(0),merged_ligand.getAtom(decoration_index[i])) r1 = dec.getAtom(0).coords() r2 = dec.centermass() # center of mass rrot = r1 decb = mol3D() decb.copymol3D(dec) #################################### # center of mass of local environment (to avoid bad placement of bulky ligands) auxmol = mol3D() for at in dec.getBondedAtoms(0): auxmol.addAtom(dec.getAtom(at)) if auxmol.natoms > 0: r2 = auxmol.centermass() # overwrite global with local centermass #################################### # rotate around axis and get both images theta,u = rotation_params(merged_ligand.centermass(),r1,r2) #print('u = ' + str(u) + ' theta = ' + str(theta)) dec = rotate_around_axis(dec,rrot,u,theta) if args.debug: dec.writexyz('dec_ARA' + str(i) + '.xyz') decb = rotate_around_axis(decb,rrot,u,theta-180) if args.debug: decb.writexyz('dec_ARB' + str(i) + '.xyz') d1 = distance(dec.centermass(),merged_ligand.centermass()) d2 = distance(decb.centermass(),merged_ligand.centermass()) dec = dec if (d2 < d1) else decb # pick best one ##################################### # check for linear molecule auxm = mol3D() for at in dec.getBondedAtoms(0): auxm.addAtom(dec.getAtom(at)) if auxm.natoms > 1: r0 = dec.getAtom(0).coords() r1 = auxm.getAtom(0).coords() r2 = auxm.getAtom(1).coords() if checkcolinear(r1,r0,r2): theta,urot = rotation_params(r1,merged_ligand.getAtom(decoration_index[i]).coords(),r2) theta = vecangle(vecdiff(r0,merged_ligand.getAtom(decoration_index[i]).coords()),urot) dec = rotate_around_axis(dec,r0,urot,theta) ## get the default distance between atoms in question connection_neighbours = merged_ligand.getAtom(merged_ligand.getBondedAtomsnotH(decoration_index[i])[0]) new_atom = dec.getAtom(0) target_distance = connection_neighbours.rad + new_atom.rad position_to_place = vecdiff(new_atom.coords(),connection_neighbours.coords()) old_dist= norm(position_to_place) missing = (target_distance - old_dist)/2 dec.translate([missing*position_to_place[j] for j in [0,1,2]]) r1 = dec.getAtom(0).coords() u = vecdiff(r1,merged_ligand.getAtom(decoration_index[i]).coords()) dtheta = 2 optmax = -9999 totiters = 0 decb = mol3D() decb.copymol3D(dec) # check for minimum distance between atoms and center of mass distance while totiters < 180: #print('totiters '+ str(totiters)) dec = rotate_around_axis(dec,r1,u,dtheta) d0 = dec.mindist(merged_ligand) # try to maximize minimum atoms distance d0cm = dec.distance(merged_ligand) # try to maximize center of mass distance iteropt = d0cm+d0 # optimization function if (iteropt > optmax): # if better conformation, keep decb = mol3D() decb.copymol3D(dec) optmax = iteropt #temp = mol3D() #temp.copymol3D(merged_ligand) #temp.combine(decb) #temp.writexyz('opt_iter_'+str(totiters)+'.xyz') #print('new max! ' + str(iteropt) ) totiters += 1 dec = decb if args.debug: dec.writexyz('dec_aligned' + str(i) + '.xyz') print('natoms before delete ' + str(merged_ligand.natoms)) print('obmol before delete at ' + str(decoration_index[i]) + ' is ' + str(merged_ligand.OBMol.NumAtoms())) ## store connectivity for deleted H BO_mat = merged_ligand.populateBOMatrix() row_deleted = BO_mat[decoration_index[i]] bonds_to_add = [] # find where to put the new bonds for j,els in enumerate(row_deleted): if els > 0: # if there is a bond with an atom number # before the deleted atom, all is fine # else, we subtract one as the row will be be removed if j < decoration_index[i]: bond_partner = j else: bond_partner = j -1 bonds_to_add.append((bond_partner,merged_ligand.natoms-1,els)) ## perfrom delete merged_ligand.deleteatom(decoration_index[i]) merged_ligand.convert2OBMol() if args.debug: merged_ligand.writexyz('merged del ' + str(i) + '.xyz') ## merge and bond merged_ligand.combine(dec,bond_to_add=bonds_to_add) merged_ligand.convert2OBMol() if args.debug: merged_ligand.writexyz('merged' + str(i) + '.xyz') merged_ligand.printxyz() print('************') merged_ligand.convert2OBMol() merged_ligand,emsg = molSimplify.Scripts.structgen.ffopt('MMFF94',merged_ligand,[],0,[],False,[],100) BO_mat = merged_ligand.populateBOMatrix() if args.debug: merged_ligand.writexyz('merged_relaxed.xyz') print(BO_mat) return(merged_ligand)
def zero_1st(mol): zeroed_mol = mol3D() zeroed_mol.copymol3D(mol) coord_to_zero = zeroed_mol.getAtom(0).coords() zeroed_mol.translate([-1*i for i in coord_to_zero]) return zeroed_mol