Source code for molSimplify.Informatics.lacRACAssemble

# Written JP Janet
# for HJK Group
# Dpt of Chemical Engineering, MIT

# #########################################################
# ####### Defines methods for assembling    ###############
# #######     RACs from lists of ligands    ###############
# #########################################################

# lac: ligand assign consistent

from __future__ import print_function
from molSimplify.Classes.ligand import (
    ligand_assign_consistent,
    ligand_assign_original,
    ligand_breakdown,
    )
from molSimplify.Informatics.autocorrelation import (
    append_descriptor_derivatives,
    append_descriptors,
    atom_only_autocorrelation_derivative,
    atom_only_deltametric_derivative,
    full_autocorrelation_derivative,
    generate_atomonly_autocorrelations,
    generate_atomonly_deltametrics,
    generate_full_complex_autocorrelation_derivatives,
    generate_full_complex_autocorrelations,
    generate_metal_autocorrelation_derivatives,
    generate_metal_autocorrelations,
    generate_metal_deltametric_derivatives,
    generate_metal_deltametrics,
    generate_metal_ox_autocorrelation_derivatives,
    generate_metal_ox_autocorrelations,
    generate_metal_ox_deltametric_derivatives,
    generate_metal_ox_deltametrics,
    )
import numpy as np


[docs]def get_descriptor_vector(this_complex, custom_ligand_dict=False, ox_modifier=False, NumB=False, Gval=False, lacRACs=True, loud=False, smiles_charge=False, eq_sym=False, use_dist=False, size_normalize=False, alleq=False, custom_property_dict={}, depth=3, non_trivial=False, ): """ Calculate and return all geo-based RACs for a given octahedral TM complex (featurize). Parameters ---------- this_complex : mol3D Transition metal complex to be featurized. custom_ligand_dict : bool, optional Custom ligand dictionary to evaluate for complex if passed, by default False. Skip the ligand breakdown steps - 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, and 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]] ox_modifier : bool, optional dict, used to modify prop vector (e.g., for adding ONLY used with ox_nuclear_charge ox or charge) {"Fe": 2, "Co": 3} etc., by default False. NumB : bool, optional Use Number of Bonds as an atomic property, by default False. Gval : bool, optional Use group number as an atomic property, by default False. lacRACs : bool, optional Use ligand_assign_consistent (lac) to assign ligands as equatorial and axial. If False, use ligand_assign_original (older), default True. loud : bool, optional Print debugging information, by default False. smiles_charge : bool, optional Use obmol conversion through smiles to assign ligand_misc_charges, by default False. eq_sym : bool, optional Enforce equatorial plane to have connecting atoms with same symbol. Default is False. use_dist : bool, optional Whether or not CD-RACs used. size_normalize : bool, optional Whether or not to normalize by the number of atoms. alleq : bool, optional Whether or not all ligands are equatorial. custom_property_dict : dict, optional Keys are custom property names (str), values are dictionaries mapping atom symbols (str, e.g., "H", "He") to the numerical property (float) for that atom. If provided, other property RACs (e.g., Z, S, T) will not be made. depth : int, optional The maximum depth of the RACs (how many bonds out the RACs go). For example, if set to 3, depths considered will be 0, 1, 2, and 3. non_trivial : bool, optional Flag to exclude difference RACs of I, and depth zero difference RACs. These RACs are always zero. By default False. Returns ------- descriptor_names : list of str Compiled list of descriptor names. descriptors : list of float Compiled list of descriptor values. """ if depth < 0: raise Exception('depth must be a non-negative integer.') metals = this_complex.findMetal() if len(metals) != 1: raise Exception('Molecule does not have the expected number of transition metals (1).') descriptor_names = [] descriptors = [] # Generate custom_ligand_dict if one not passed! if not custom_ligand_dict: liglist, ligdents, ligcons = ligand_breakdown(this_complex, BondedOct=True) # Complex is assumed to be octahedral if alleq: from molSimplify.Classes.ligand import ligand_assign_alleq ax_ligand_list, eq_ligand_list, ax_con_int_list, eq_con_int_list = ligand_assign_alleq( this_complex, liglist, ligdents, ligcons) else: if lacRACs: assignment_func = ligand_assign_consistent else: assignment_func = ligand_assign_original ax_ligand_list, eq_ligand_list, _, _, \ ax_con_int_list, eq_con_int_list, _, _, \ _ = assignment_func(this_complex, liglist, ligdents, ligcons, loud=loud, eq_sym_match=eq_sym) custom_ligand_dict = {'ax_ligand_list': ax_ligand_list, 'eq_ligand_list': eq_ligand_list, 'ax_con_int_list': ax_con_int_list, 'eq_con_int_list': eq_con_int_list} # misc descriptors results_dictionary = generate_all_ligand_misc(this_complex, loud=False, custom_ligand_dict=custom_ligand_dict, smiles_charge=smiles_charge) descriptor_names, descriptors = append_descriptors(descriptor_names, descriptors, results_dictionary['colnames'], results_dictionary['result_ax'], 'misc', 'ax') descriptor_names, descriptors = append_descriptors(descriptor_names, descriptors, results_dictionary['colnames'], results_dictionary['result_eq'], 'misc', 'eq') # full ACs results_dictionary = generate_full_complex_autocorrelations(this_complex, depth=depth, flag_name=False, modifier=ox_modifier, NumB=NumB, Gval=Gval, use_dist=use_dist, size_normalize=size_normalize, custom_property_dict=custom_property_dict) descriptor_names, descriptors = append_descriptors(descriptor_names, descriptors, results_dictionary['colnames'], results_dictionary['results'], 'f', 'all') # # ligand ACs results_dictionary = generate_all_ligand_autocorrelations_lac(this_complex, depth=depth, loud=False, flag_name=False, custom_ligand_dict=custom_ligand_dict, NumB=NumB, Gval=Gval, use_dist=use_dist, size_normalize=size_normalize, custom_property_dict=custom_property_dict) if not alleq: descriptor_names, descriptors = append_descriptors(descriptor_names, descriptors, results_dictionary['colnames'], results_dictionary['result_ax_full'], 'f', 'ax') descriptor_names, descriptors = append_descriptors(descriptor_names, descriptors, results_dictionary['colnames'], results_dictionary['result_eq_full'], 'f', 'eq') if not alleq: descriptor_names, descriptors = append_descriptors(descriptor_names, descriptors, results_dictionary['colnames'], results_dictionary['result_ax_con'], 'lc', 'ax') descriptor_names, descriptors = append_descriptors(descriptor_names, descriptors, results_dictionary['colnames'], results_dictionary['result_eq_con'], 'lc', 'eq') results_dictionary = generate_all_ligand_deltametrics_lac(this_complex, depth=depth, loud=False, custom_ligand_dict=custom_ligand_dict, NumB=NumB, Gval=Gval, use_dist=use_dist, size_normalize=size_normalize, custom_property_dict=custom_property_dict, non_trivial=non_trivial) if not alleq: descriptor_names, descriptors = append_descriptors(descriptor_names, descriptors, results_dictionary['colnames'], results_dictionary['result_ax_con'], 'D_lc', 'ax') descriptor_names, descriptors = append_descriptors(descriptor_names, descriptors, results_dictionary['colnames'], results_dictionary['result_eq_con'], 'D_lc', 'eq') # metal ACs results_dictionary = generate_metal_autocorrelations(this_complex, depth=depth, modifier=ox_modifier, NumB=NumB, Gval=Gval, use_dist=use_dist, size_normalize=size_normalize, custom_property_dict=custom_property_dict) descriptor_names, descriptors = append_descriptors(descriptor_names, descriptors, results_dictionary['colnames'], results_dictionary['results'], 'mc', 'all') results_dictionary = generate_metal_deltametrics(this_complex, depth=depth, modifier=ox_modifier, NumB=NumB, Gval=Gval, use_dist=use_dist, size_normalize=size_normalize, custom_property_dict=custom_property_dict, non_trivial=non_trivial) descriptor_names, descriptors = append_descriptors(descriptor_names, descriptors, results_dictionary['colnames'], results_dictionary['results'], 'D_mc', 'all') # ## ox-metal ACs, if ox available if ox_modifier: results_dictionary = generate_metal_ox_autocorrelations(ox_modifier, this_complex, depth=depth, use_dist=use_dist, size_normalize=size_normalize) descriptor_names, descriptors = append_descriptors(descriptor_names, descriptors, results_dictionary['colnames'], results_dictionary['results'], 'mc', 'all') results_dictionary = generate_metal_ox_deltametrics(ox_modifier, this_complex, depth=depth, use_dist=use_dist, size_normalize=size_normalize, non_trivial=non_trivial) descriptor_names, descriptors = append_descriptors(descriptor_names, descriptors, results_dictionary['colnames'], results_dictionary['results'], 'D_mc', 'all') return descriptor_names, descriptors
[docs]def get_descriptor_derivatives(this_complex, custom_ligand_dict=False, ox_modifier=False, lacRACs=True, depth=4, loud=False): """ Calculate and return all derivatives of RACs for a given octahedral complex. Parameters ---------- this_complex : mol3D Transition metal complex to be featurized. custom_ligand_dict : bool, optional Custom ligand dictionary to evaluate for complex if passed, by default False. Skip the ligand breakdown steps - 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, and 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]] ox_modifier : bool, optional dict, used to modify prop vector (e.g., for adding ONLY used with ox_nuclear_charge ox or charge) {"Fe":2, "Co": 3} etc., by default False. lacRACs : bool, optional Use ligand_assign_consistent (lac) to assign ligands as equatorial and axial. if False, use ligand_assign_original (older), default True. depth : int, optional Depth of RACs to calculate, by default 4. loud : bool, optional Print debugging information, by default False. Returns ------- descriptor_derivative_names : list Compiled list (matrix) of descriptor derivative names descriptor_derivatives : list Derivatives of RACs w.r.t atomic props (matrix) """ if not custom_ligand_dict: if lacRACs: assignment_func = ligand_assign_consistent else: assignment_func = ligand_assign_original liglist, ligdents, ligcons = ligand_breakdown(this_complex, BondedOct=True) # Complex is assumed to be octahedral (ax_ligand_list, eq_ligand_list, _, _, ax_con_int_list, eq_con_int_list, _, _, _) = assignment_func(this_complex, liglist, ligdents, ligcons, loud=loud) custom_ligand_dict = {'ax_ligand_list': ax_ligand_list, 'eq_ligand_list': eq_ligand_list, 'ax_con_int_list': ax_con_int_list, 'eq_con_int_list': eq_con_int_list} # cannot do misc descriptors ! descriptor_derivative_names = [] descriptor_derivatives = None # full ACs results_dictionary = generate_full_complex_autocorrelation_derivatives(this_complex, depth=depth, flag_name=False, modifier=ox_modifier) descriptor_derivative_names, descriptor_derivatives = append_descriptor_derivatives(descriptor_derivative_names, descriptor_derivatives, results_dictionary['colnames'], results_dictionary['results'], 'f', 'all') # ligand ACs results_dictionary = generate_all_ligand_autocorrelation_derivatives_lac(this_complex, depth=depth, loud=False, custom_ligand_dict=custom_ligand_dict) descriptor_derivative_names, descriptor_derivatives = append_descriptor_derivatives(descriptor_derivative_names, descriptor_derivatives, results_dictionary['colnames'], results_dictionary['result_ax_full'], 'f', 'ax') descriptor_derivative_names, descriptor_derivatives = append_descriptor_derivatives(descriptor_derivative_names, descriptor_derivatives, results_dictionary['colnames'], results_dictionary['result_eq_full'], 'f', 'eq') descriptor_derivative_names, descriptor_derivatives = append_descriptor_derivatives(descriptor_derivative_names, descriptor_derivatives, results_dictionary['colnames'], results_dictionary['result_ax_con'], 'lc', 'ax') descriptor_derivative_names, descriptor_derivatives = append_descriptor_derivatives(descriptor_derivative_names, descriptor_derivatives, results_dictionary['colnames'], results_dictionary['result_eq_con'], 'lc', 'eq') results_dictionary = generate_all_ligand_deltametric_derivatives_lac(this_complex, depth=depth, loud=False, custom_ligand_dict=custom_ligand_dict) descriptor_derivative_names, descriptor_derivatives = append_descriptor_derivatives(descriptor_derivative_names, descriptor_derivatives, results_dictionary['colnames'], results_dictionary['result_ax_con'], 'D_lc', 'ax') descriptor_derivative_names, descriptor_derivatives = append_descriptor_derivatives(descriptor_derivative_names, descriptor_derivatives, results_dictionary['colnames'], results_dictionary['result_eq_con'], 'D_lc', 'eq') # metal ACs results_dictionary = generate_metal_autocorrelation_derivatives(this_complex, depth=depth, modifier=ox_modifier) descriptor_derivative_names, descriptor_derivatives = append_descriptor_derivatives(descriptor_derivative_names, descriptor_derivatives, results_dictionary['colnames'], results_dictionary['results'], 'mc', 'all') results_dictionary = generate_metal_deltametric_derivatives(this_complex, depth=depth, modifier=ox_modifier) descriptor_derivative_names, descriptor_derivatives = append_descriptor_derivatives(descriptor_derivative_names, descriptor_derivatives, results_dictionary['colnames'], results_dictionary['results'], 'D_mc', 'all') # ## ox-metal ACs if ox_modifier: results_dictionary = generate_metal_ox_autocorrelation_derivatives(ox_modifier, this_complex, depth=depth) descriptor_derivative_names, descriptor_derivatives = append_descriptor_derivatives(descriptor_derivative_names, descriptor_derivatives, results_dictionary['colnames'], results_dictionary['results'], 'mc', 'all') results_dictionary = generate_metal_ox_deltametric_derivatives(ox_modifier, this_complex, depth=depth) descriptor_derivative_names, descriptor_derivatives = append_descriptor_derivatives(descriptor_derivative_names, descriptor_derivatives, results_dictionary['colnames'], results_dictionary['results'], 'D_mc', 'all') return descriptor_derivative_names, descriptor_derivatives
[docs]def generate_all_ligand_misc(mol, loud=False, custom_ligand_dict=False, smiles_charge=False): """ Get the ligand_misc_descriptors (axial vs. equatorial charge (from OBMol) and denticity). custom_ligand_dict.keys() must be eq_ligands_list, ax_ligand_list ax_con_int_list, eq_con_int_list Parameters ---------- mol : mol3D Molecule to get the ligand_misc descriptors from. loud : bool, optional Print debugging information, by default False. custom_ligand_dict : bool, optional custom_ligand_dictionary if passed, by default False. smiles_charge : bool, optional Whether or not to use the smiles charge assignment, default is False. Returns ------- results_dictionary : dict Labels and results of ligand_misc RACs - {'colnames': colnames, 'result_ax': result_ax, 'result_eq': result_eq}. Ax. vs eq. charge (from OBMol) and denticity. """ result_ax = list() result_eq = list() colnames = ['dent', 'charge'] if custom_ligand_dict: 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"] else: liglist, ligdents, ligcons = ligand_breakdown(mol, BondedOct=True) # Complex is assumed to be octahedral ax_ligand_list, eq_ligand_list, _, _, _, _, \ _, _, _ = ligand_assign_consistent( mol, liglist, ligdents, ligcons, loud=loud) # 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_charge = False result_eq_charge = False # loop over axial ligands if n_ax > 0: for i in range(0, n_ax): if mol.bo_dict: ax_ligand_list[i].mol.convert2OBMol2() else: ax_ligand_list[i].mol.convert2OBMol() if i == 0: result_ax_dent = ax_ligand_list[i].dent if smiles_charge: result_ax_charge = ax_ligand_list[i].mol.get_smilesOBmol_charge() else: result_ax_charge = ax_ligand_list[i].mol.OBMol.GetTotalCharge() else: result_ax_dent += ax_ligand_list[i].dent if smiles_charge: result_ax_charge += ax_ligand_list[i].mol.get_smilesOBmol_charge() else: result_ax_charge += ax_ligand_list[i].mol.OBMol.GetTotalCharge() # average axial results result_ax_dent = np.divide(result_ax_dent, 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): if mol.bo_dict: eq_ligand_list[i].mol.convert2OBMol2() else: eq_ligand_list[i].mol.convert2OBMol() if i == 0: result_eq_dent = eq_ligand_list[i].dent if smiles_charge: result_eq_charge = eq_ligand_list[i].mol.get_smilesOBmol_charge() else: result_eq_charge = eq_ligand_list[i].mol.OBMol.GetTotalCharge() else: result_eq_dent += eq_ligand_list[i].dent if smiles_charge: result_eq_charge += eq_ligand_list[i].mol.get_smilesOBmol_charge() else: result_eq_charge += eq_ligand_list[i].mol.OBMol.GetTotalCharge() # average eq results result_eq_dent = np.divide(result_eq_dent, n_eq) result_eq_charge = np.divide(result_eq_charge, n_eq) # save the results result_ax.append(result_ax_dent) result_ax.append(result_ax_charge) result_eq.append(result_eq_dent) result_eq.append(result_eq_charge) results_dictionary = {'colnames': colnames, 'result_ax': result_ax, 'result_eq': result_eq} return results_dictionary
[docs]def generate_all_ligand_autocorrelations_lac(mol, loud=False, depth=4, flag_name=False, custom_ligand_dict=False, NumB=False, Gval=False, use_dist=False, size_normalize=False, custom_property_dict={}): """ Utility for generating all ligand-based product autocorrelations for a complex. Parameters ---------- mol : mol3D Molecule to get lc-RACs for. loud : bool, optional Print debugging information, by default False. depth : int, optional Depth of RACs to calculate, by default 4. flag_name : bool, optional Shift RAC names slightly, by default False. custom_ligand_dict : bool, optional Dict of ligands if passed - see generate_descriptor_vector, by default False. NumB : bool, optional Use number of bonds as descriptor property, by default False. Gval : bool, optional Use G value as descriptor property, by default False. use_dist : bool, optional Weigh autocorrelation by physical distance of scope atom from start atom, by default False. size_normalize : bool, optional Whether or not to normalize by the number of atoms. custom_property_dict : dict, optional Keys are custom property names (str), values are dictionaries mapping atom symbols (str, e.g., "H", "He") to the numerical property (float) for that atom. If provided, other property RACs (e.g., Z, S, T) will not be made. Returns ------- results_dictionary: dict Dictionary of all geo-based ligand product descriptors (both full and connecting atom scopes) - {'colnames': colnames, 'result_ax_full': result_ax_full, 'result_eq_full': result_eq_full, 'result_ax_con': result_ax_con, 'result_eq_con': result_eq_con}. """ if custom_ligand_dict: 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"] else: liglist, ligdents, ligcons = ligand_breakdown(mol, BondedOct=True) # Complex is assumed to be octahedral (ax_ligand_list, eq_ligand_list, _, _, ax_con_int_list, eq_con_int_list, _, _, _) = ligand_assign_consistent( mol, liglist, ligdents, ligcons, loud=loud) # Count ligands. n_ax = len(ax_ligand_list) n_eq = len(eq_ligand_list) # ############## replaced find_ligand_autocorrelations_oct function here # get full ligand AC result_ax_full, result_eq_full = [], [] for i in range(0, n_ax): if list(result_ax_full): result_ax_full += generate_full_complex_autocorrelations( ax_ligand_list[i].mol, depth=depth, custom_property_dict=custom_property_dict, NumB=NumB, Gval=Gval, use_dist=use_dist, size_normalize=size_normalize, )['results'] else: results_dict = generate_full_complex_autocorrelations( ax_ligand_list[i].mol, depth=depth, custom_property_dict=custom_property_dict, NumB=NumB, Gval=Gval, use_dist=use_dist, size_normalize=size_normalize, ) result_ax_full = results_dict['results'] result_ax_full = np.array(result_ax_full) colnames = results_dict['colnames'] # Average over the number of axial ligands. result_ax_full = np.divide(result_ax_full, n_ax) for i in range(0, n_eq): if list(result_eq_full): result_eq_full += generate_full_complex_autocorrelations( eq_ligand_list[i].mol, depth=depth, custom_property_dict=custom_property_dict, NumB=NumB, Gval=Gval, use_dist=use_dist, size_normalize=size_normalize, )['results'] else: results_dict = generate_full_complex_autocorrelations( eq_ligand_list[i].mol, depth=depth, custom_property_dict=custom_property_dict, NumB=NumB, Gval=Gval, use_dist=use_dist, size_normalize=size_normalize, ) result_eq_full = results_dict['results'] result_eq_full = np.array(result_eq_full) colnames = results_dict['colnames'] # Average over the number of equatorial ligands. result_eq_full = np.divide(result_eq_full, n_eq) result_ax_con, result_eq_con = [], [] for i in range(0, n_ax): if list(result_ax_con): result_ax_con += generate_atomonly_autocorrelations( ax_ligand_list[i].mol, ax_con_int_list[i], depth=depth, custom_property_dict=custom_property_dict, NumB=NumB, Gval=Gval, use_dist=use_dist, size_normalize=size_normalize, )['results'] else: result_ax_con = generate_atomonly_autocorrelations( ax_ligand_list[i].mol, ax_con_int_list[i], depth=depth, custom_property_dict=custom_property_dict, NumB=NumB, Gval=Gval, use_dist=use_dist, size_normalize=size_normalize, )['results'] result_ax_con = np.array(result_ax_con) # Average over the number of axial ligands. result_ax_con = np.divide(result_ax_con, n_ax) for i in range(0, n_eq): if list(result_eq_con): result_eq_con += generate_atomonly_autocorrelations( eq_ligand_list[i].mol, eq_con_int_list[i], depth=depth, custom_property_dict=custom_property_dict, NumB=NumB, Gval=Gval, use_dist=use_dist, size_normalize=size_normalize, )['results'] else: result_eq_con = generate_atomonly_autocorrelations( eq_ligand_list[i].mol, eq_con_int_list[i], depth=depth, custom_property_dict=custom_property_dict, NumB=NumB, Gval=Gval, use_dist=use_dist, size_normalize=size_normalize, )['results'] result_eq_con = np.array(result_eq_con) # Average over the number of equatorial ligands. result_eq_con = np.divide(result_eq_con, n_eq) result_ax_full = list(result_ax_full) result_eq_full = list(result_eq_full) result_ax_con = list(result_ax_con) result_eq_con = list(result_eq_con) if flag_name: results_dictionary = {'colnames': colnames, 'result_ax_full_ac': result_ax_full, 'result_eq_full_ac': result_eq_full, 'result_ax_con_ac': result_ax_con, 'result_eq_con_ac': result_eq_con} else: results_dictionary = {'colnames': colnames, 'result_ax_full': result_ax_full, 'result_eq_full': result_eq_full, 'result_ax_con': result_ax_con, 'result_eq_con': result_eq_con} return results_dictionary
[docs]def generate_all_ligand_autocorrelation_derivatives_lac(mol, loud=False, depth=4, flag_name=False, custom_ligand_dict=False, NumB=False, Gval=False): """ Utility for generating all ligand-based autocorrelation derivatives for a complex. Parameters ---------- mol : mol3D Molecule to get lc-RAC derivatives for. loud : bool, optional Print debugging information, by default False. depth : int, optional Depth of RACs to calculate, by default 4. flag_name : bool, optional Shift RAC names slightly, by default False. custom_ligand_dict : bool, optional Dict of ligands if passed - see generate_descriptor_vector, by default False. NumB : bool, optional Use number of bonds as descriptor property, by default False. Gval : bool, optional Use G value as descriptor property, by default False. Returns ------- results_dictionary: dict Dictionary of all geo-based ligand product descriptor derivatives (both full and connecting atom scopes) {'colnames': colnames, 'result_ax_full': result_ax_full, 'result_eq_full': result_eq_full, 'result_ax_con': result_ax_con, 'result_eq_con': result_eq_con}. """ result_ax_full = None result_eq_full = None result_ax_con = None result_eq_con = None colnames = [] allowed_strings = ['electronegativity', 'nuclear_charge', 'ident', 'topology', 'size'] labels_strings = ['chi', 'Z', 'I', 'T', 'S'] if Gval: allowed_strings += ['group_number'] labels_strings += ['Gval'] if NumB: allowed_strings += ["num_bonds"] labels_strings += ["NumB"] if custom_ligand_dict: 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"] else: liglist, ligdents, ligcons = ligand_breakdown(mol, BondedOct=True) # Complex is assumed to be octahedral ax_ligand_list, eq_ligand_list, _, _, ax_con_int_list, eq_con_int_list, \ _, _, _ = ligand_assign_consistent( mol, liglist, ligdents, ligcons, loud=loud) # count ligands n_ax = len(ax_ligand_list) n_eq = len(eq_ligand_list) for ii, properties in enumerate(allowed_strings): # allocate the full jacobian matrix ax_full_j = np.zeros([depth + 1, mol.natoms]) eq_full_j = np.zeros([depth + 1, mol.natoms]) ax_con_j = np.zeros([depth + 1, mol.natoms]) eq_con_j = np.zeros([depth + 1, mol.natoms]) ################# # full ligand ACs for i in range(0, n_ax): # for each ax ligand ax_ligand_ac_full_derivative = full_autocorrelation_derivative(ax_ligand_list[i].mol, properties, depth) # now we need to map back to full positions for jj, row in enumerate(ax_ligand_ac_full_derivative): for original_ids in list(ax_ligand_list[i].ext_int_dict.keys()): ax_full_j[jj, original_ids] += np.divide(row[ax_ligand_list[i].ext_int_dict[original_ids]], n_ax) for i in range(0, n_eq): # for each eq ligand # now we need to map back to full positions eq_ligand_eq_full_derivative = full_autocorrelation_derivative(eq_ligand_list[i].mol, properties, depth) for jj, row in enumerate(eq_ligand_eq_full_derivative): for original_ids in list(eq_ligand_list[i].ext_int_dict.keys()): eq_full_j[jj, original_ids] += np.divide(row[eq_ligand_list[i].ext_int_dict[original_ids]], n_eq) # ligand connection ACs for i in range(0, n_ax): ax_ligand_ac_con_derivative = atom_only_autocorrelation_derivative(ax_ligand_list[i].mol, properties, depth, ax_con_int_list[i]) # now we need to map back to full positions for jj, row in enumerate(ax_ligand_ac_con_derivative): for original_ids in list(ax_ligand_list[i].ext_int_dict.keys()): ax_con_j[jj, original_ids] += np.divide(row[ax_ligand_list[i].ext_int_dict[original_ids]], n_ax) for i in range(0, n_eq): eq_ligand_ac_con_derivative = atom_only_autocorrelation_derivative(eq_ligand_list[i].mol, properties, depth, eq_con_int_list[i]) # now we need to map back to full positions for jj, row in enumerate(eq_ligand_ac_con_derivative): for original_ids in list(eq_ligand_list[i].ext_int_dict.keys()): eq_con_j[jj, original_ids] += np.divide(row[eq_ligand_list[i].ext_int_dict[original_ids]], n_eq) ax_ligand_ac_full, eq_ligand_ac_full, ax_ligand_ac_con, eq_ligand_ac_con = ax_full_j, eq_full_j, ax_con_j, eq_con_j ################# for i in range(0, depth + 1): colnames.append(['d' + labels_strings[ii] + '-' + str(i) + '/d' + labels_strings[ii] + str(j) for j in range(0, mol.natoms)]) if result_ax_full is None: result_ax_full = ax_ligand_ac_full else: result_ax_full = np.row_stack([result_ax_full, ax_ligand_ac_full]) if result_eq_full is None: result_eq_full = eq_ligand_ac_full else: result_eq_full = np.row_stack([result_eq_full, eq_ligand_ac_full]) if result_ax_con is None: result_ax_con = ax_ligand_ac_con else: result_ax_con = np.row_stack([result_ax_con, ax_ligand_ac_con]) if result_eq_con is None: result_eq_con = eq_ligand_ac_con else: result_eq_con = np.row_stack([result_eq_con, eq_ligand_ac_con]) if flag_name: results_dictionary = {'colnames': colnames, 'result_ax_full_ac': result_ax_full, 'result_eq_full_ac': result_eq_full, 'result_ax_con_ac': result_ax_con, 'result_eq_con_ac': result_eq_con} else: results_dictionary = {'colnames': colnames, 'result_ax_full': result_ax_full, 'result_eq_full': result_eq_full, 'result_ax_con': result_ax_con, 'result_eq_con': result_eq_con} return results_dictionary
[docs]def generate_all_ligand_deltametrics_lac(mol, loud=False, depth=4, flag_name=False, custom_ligand_dict=False, NumB=False, Gval=False, use_dist=False, size_normalize=False, custom_property_dict={}, non_trivial=False): """ Utility for generating all ligand-based deltametric autocorrelations for a complex. Parameters ---------- mol : mol3D Molecule to get D_lc-RACs for. loud : bool, optional Print debugging information, by default False. depth : int, optional Depth of RACs to calculate, by default 4. flag_name : bool, optional Shift RAC names slightly, by default False. custom_ligand_dict : bool, optional Dict of ligands if passed - see generate_descriptor_vector, by default False. NumB : bool, optional Use number of bonds as descriptor property, by default False. Gval : bool, optional Use G value as descriptor property, by default False. use_dist : bool, optional Weigh autocorrelation by physical distance of atom from original, by default False. size_normalize : bool, optional Whether or not to normalize by the number of atoms. custom_property_dict : dict, optional Keys are custom property names (str), values are dictionaries mapping atom symbols (str, e.g., "H", "He") to the numerical property (float) for that atom. If provided, other property RACs (e.g., Z, S, T) will not be made. non_trivial : bool, optional Flag to exclude difference RACs of I, and depth zero difference RACs. These RACs are always zero. By default False. Returns ------- results_dictionary: dict Dictionary of all geo-based ligand deltametric descriptors (both full and connecting atom scopes) - {'colnames': colnames, 'result_ax_con': result_ax_con, 'result_eq_con': result_eq_con}. """ result_ax_con = list() result_eq_con = list() if custom_ligand_dict: 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"] else: liglist, ligdents, ligcons = ligand_breakdown(mol, BondedOct=True) # Complex is assumed to be octahedral (ax_ligand_list, eq_ligand_list, _, _, ax_con_int_list, eq_con_int_list, _, _, _) = ligand_assign_consistent(mol, liglist, ligdents, ligcons, loud=loud) # count ligands n_ax = len(ax_ligand_list) n_eq = len(eq_ligand_list) #################### # get partial ligand AC for i in range(0, n_ax): if list(result_ax_con): result_ax_con += generate_atomonly_deltametrics( ax_ligand_list[i].mol, ax_con_int_list[i], depth=depth, custom_property_dict=custom_property_dict, NumB=NumB, Gval=Gval, use_dist=use_dist, size_normalize=size_normalize, non_trivial=non_trivial, )['results'] else: results_dict = generate_atomonly_deltametrics( ax_ligand_list[i].mol, ax_con_int_list[i], depth=depth, custom_property_dict=custom_property_dict, NumB=NumB, Gval=Gval, use_dist=use_dist, size_normalize=size_normalize, non_trivial=non_trivial, ) result_ax_con = results_dict['results'] result_ax_con = np.array(result_ax_con) colnames = results_dict['colnames'] # Average over the number of axial ligands. result_ax_con = np.divide(result_ax_con, n_ax) for i in range(0, n_eq): if list(result_eq_con): result_eq_con += generate_atomonly_deltametrics( eq_ligand_list[i].mol, eq_con_int_list[i], depth=depth, custom_property_dict=custom_property_dict, NumB=NumB, Gval=Gval, use_dist=use_dist, size_normalize=size_normalize, non_trivial=non_trivial, )['results'] else: results_dict = generate_atomonly_deltametrics( eq_ligand_list[i].mol, eq_con_int_list[i], depth=depth, custom_property_dict=custom_property_dict, NumB=NumB, Gval=Gval, use_dist=use_dist, size_normalize=size_normalize, non_trivial=non_trivial, ) result_eq_con = results_dict['results'] result_eq_con = np.array(result_eq_con) colnames = results_dict['colnames'] # Average over the number of equatorial ligands. result_eq_con = np.divide(result_eq_con, n_eq) result_ax_con = list(result_ax_con) result_eq_con = list(result_eq_con) #################### if flag_name: results_dictionary = {'colnames': colnames, 'result_ax_con_del': result_ax_con, 'result_eq_con_del': result_eq_con} else: results_dictionary = {'colnames': colnames, 'result_ax_con': result_ax_con, 'result_eq_con': result_eq_con} return results_dictionary
[docs]def generate_all_ligand_deltametric_derivatives_lac(mol, loud=False, depth=4, flag_name=False, custom_ligand_dict=False, NumB=False, Gval=False): """ Utility for generating all ligand-based deltametric derivatives for a complex. Parameters ---------- mol : mol3D Molecule to get lc-RAC deltametric derivatives for. loud : bool, optional Print debugging information, by default False. depth : int, optional Depth of RACs to calculate, by default 4. flag_name : bool, optional Shift RAC names slightly, by default False. custom_ligand_dict : bool, optional Dict of ligands if passed - see generate_descriptor_vector, by default False. NumB : bool, optional Use number of bonds as descriptor property, by default False. Gval : bool, optional Use G value as descriptor property, by default False. Returns ------- results_dictionary: dict Dictionary of all geo-based ligand deltametric descriptor derivatives (both full and connecting atom scopes) - {'colnames': colnames, 'result_ax_con': result_ax_con, 'result_eq_con': result_eq_con}. """ result_ax_con = None result_eq_con = None colnames = [] allowed_strings = ['electronegativity', 'nuclear_charge', 'ident', 'topology', 'size'] labels_strings = ['chi', 'Z', 'I', 'T', 'S'] if Gval: allowed_strings += ['group_number'] labels_strings += ['Gval'] if NumB: allowed_strings += ["num_bonds"] labels_strings += ["NumB"] if custom_ligand_dict: 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"] else: liglist, ligdents, ligcons = ligand_breakdown(mol, BondedOct=True) # Complex is assumed to be octahedral ax_ligand_list, eq_ligand_list, _, _, ax_con_int_list, eq_con_int_list, \ _, _, _ = ligand_assign_consistent( mol, liglist, ligdents, ligcons, loud=loud) # count ligands n_ax = len(ax_ligand_list) n_eq = len(eq_ligand_list) for ii, properties in enumerate(allowed_strings): # allocate the full jacobian matrix ax_con_j = np.zeros([depth + 1, mol.natoms]) eq_con_j = np.zeros([depth + 1, mol.natoms]) ################# for i in range(0, n_ax): ax_ligand_ac_con_derivative = atom_only_deltametric_derivative(ax_ligand_list[i].mol, properties, depth, ax_con_int_list[i]) for jj, row in enumerate(ax_ligand_ac_con_derivative): for original_ids in list(ax_ligand_list[i].ext_int_dict.keys()): ax_con_j[jj, original_ids] += np.divide(row[ax_ligand_list[i].ext_int_dict[original_ids]], n_ax) for i in range(0, n_eq): eq_ligand_ac_con_derivative = atom_only_deltametric_derivative(eq_ligand_list[i].mol, properties, depth, eq_con_int_list[i]) for jj, row in enumerate(eq_ligand_ac_con_derivative): for original_ids in list(eq_ligand_list[i].ext_int_dict.keys()): eq_con_j[jj, original_ids] += np.divide(row[eq_ligand_list[i].ext_int_dict[original_ids]], n_eq) ################# ax_ligand_ac_con, eq_ligand_ac_con = ax_con_j, eq_con_j for i in range(0, depth + 1): colnames.append(['d' + labels_strings[ii] + '-' + str(i) + '/d' + labels_strings[ii] + str(j) for j in range(0, mol.natoms)]) if result_ax_con is None: result_ax_con = ax_ligand_ac_con else: result_ax_con = np.row_stack([result_ax_con, ax_ligand_ac_con]) if result_eq_con is None: result_eq_con = eq_ligand_ac_con else: result_eq_con = np.row_stack([result_eq_con, eq_ligand_ac_con]) if flag_name: results_dictionary = {'colnames': colnames, 'result_ax_con_del': result_ax_con, 'result_eq_con_del': result_eq_con} else: results_dictionary = {'colnames': colnames, 'result_ax_con': result_ax_con, 'result_eq_con': result_eq_con} return results_dictionary