def extract_params_onetep(self): """ TODO Move this to file_handling.py From ONETEP output files, extract the necessary parameters for calculation of L-J. Insert data into ddec_data in standard format This will exclusively be used by this class. It will also give less information, hence why it is here, not in the helpers file. """ # Just fill in None values until they are known ddec_data = { i: CustomNamespace(atomic_symbol=atom.atomic_symbol, charge=None, volume=None, r_aim=None, b_i=None, a_i=None) for i, atom in enumerate(self.molecule.atoms) } # Second file contains the rest (charges, dipoles and volumes): ddec_output_file = 'ddec.onetep' if os.path.exists( 'ddec.onetep') else 'iter_1/ddec.onetep' with open(ddec_output_file, 'r') as file: lines = file.readlines() charge_pos, vol_pos = None, None for pos, line in enumerate(lines): # Charges marker in file: if 'DDEC density' in line: charge_pos = pos + 7 # Volumes marker in file: if 'DDEC Radial' in line: vol_pos = pos + 4 if any(position is None for position in [charge_pos, vol_pos]): raise EOFError( 'Cannot locate charges and / or volumes in ddec.onetep file.') charges = [ float(line.split()[-1]) for line in lines[charge_pos:charge_pos + len(self.molecule.atoms)] ] # Add the AIM-Valence and the AIM-Core to get V^AIM volumes = [ float(line.split()[2]) + float(line.split()[3]) for line in lines[vol_pos:vol_pos + len(self.molecule.atoms)] ] for atom_index in ddec_data: ddec_data[atom_index].charge = charges[atom_index] ddec_data[atom_index].volume = volumes[atom_index] return ddec_data
def _extract_charge_data_onetep(self): """ From ONETEP output files, extract the necessary parameters for calculation of L-J. Insert data into ddec_data in standard format. Used exclusively by LennardJones class. """ # Just fill in None values until they are known ddec_data = { i: CustomNamespace( atomic_symbol=atom.atomic_symbol, charge=None, volume=None, r_aim=None, b_i=None, a_i=None, ) for i, atom in enumerate(self.molecule.atoms) } # Second file contains the rest (charges, dipoles and volumes): ddec_output_file = ("ddec.onetep" if os.path.exists("ddec.onetep") else "iter_1/ddec.onetep") with open(ddec_output_file, "r") as file: lines = file.readlines() charge_pos, vol_pos = None, None for pos, line in enumerate(lines): # Charges marker in file: if "DDEC density" in line: charge_pos = pos + 7 # Volumes marker in file: if "DDEC Radial" in line: vol_pos = pos + 4 if any(position is None for position in [charge_pos, vol_pos]): raise EOFError( "Cannot locate charges and / or volumes in ddec.onetep file.") charges = [ float(line.split()[-1]) for line in lines[charge_pos:charge_pos + len(self.molecule.atoms)] ] # Add the AIM-Valence and the AIM-Core to get V^AIM volumes = [ float(line.split()[2]) + float(line.split()[3]) for line in lines[vol_pos:vol_pos + len(self.molecule.atoms)] ] for atom_index in ddec_data: ddec_data[atom_index].charge = charges[atom_index] ddec_data[atom_index].volume = volumes[atom_index] self.molecule.ddec_data = ddec_data
def _extract_charge_data_chargemol(self): """ From Chargemol output files, extract the necessary parameters for calculation of L-J. :returns: 3 CustomNamespaces, ddec_data; dipole_moment_data; and quadrupole_moment_data ddec_data used for calculating monopole esp and L-J values (used by both LennardJones and Charges classes) dipole_moment_data used for calculating dipole esp quadrupole_moment_data used for calculating quadrupole esp """ if self.molecule.ddec_version == 6: net_charge_file_name = "DDEC6_even_tempered_net_atomic_charges.xyz" elif self.molecule.ddec_version == 3: net_charge_file_name = "DDEC3_net_atomic_charges.xyz" else: raise ValueError( "Unsupported DDEC version; please use version 3 or 6.") if not os.path.exists(net_charge_file_name): raise FileNotFoundError( "Cannot find the DDEC output file.\nThis could be indicative of several issues.\n" "Please check Chargemol is installed in the correct location and that the configs" " point to that location.") with open(net_charge_file_name, "r+") as charge_file: lines = charge_file.readlines() # Find number of atoms atom_total = int(lines[0]) # Find data markers: ddec_start_pos, cloud_pen_pos = 0, 0 for pos, row in enumerate(lines): if "The following XYZ" in row: ddec_start_pos = pos + 2 # [sic] elif "The sperically averaged" in row: cloud_pen_pos = pos + 2 if ddec_start_pos and cloud_pen_pos: break else: raise EOFError( f"Cannot find charge or cloud penetration data in {net_charge_file_name}." ) ddec_data = {} dipole_moment_data = {} quadrupole_moment_data = {} cloud_pen_data = {} for line in lines[ddec_start_pos:ddec_start_pos + atom_total]: # _'s are the xyz coords, then the quadrupole moment tensor eigenvalues. ( atom_count, atomic_symbol, _, _, _, charge, x_dipole, y_dipole, z_dipole, _, q_xy, q_xz, q_yz, q_x2_y2, q_3z2_r2, *_, ) = line.split() # File counts from 1 not 0; thereby requiring -1 to get the index. atom_index = int(atom_count) - 1 ddec_data[atom_index] = CustomNamespace( atomic_symbol=atomic_symbol, charge=float(charge), volume=None, r_aim=None, b_i=None, a_i=None, ) dipole_moment_data[atom_index] = CustomNamespace( x_dipole=float(x_dipole), y_dipole=float(y_dipole), z_dipole=float(z_dipole), ) quadrupole_moment_data[atom_index] = CustomNamespace( q_xy=float(q_xy), q_xz=float(q_xz), q_yz=float(q_yz), q_x2_y2=float(q_x2_y2), q_3z2_r2=float(q_3z2_r2), ) for line in lines[cloud_pen_pos:cloud_pen_pos + atom_total]: # _'s are the xyz coords and the r_squared. atom_count, atomic_symbol, _, _, _, a, b, _ = line.split() atom_index = int(atom_count) - 1 cloud_pen_data[atom_index] = CustomNamespace( atomic_symbol=atomic_symbol, a=float(a), b=float(b)) r_cubed_file_name = "DDEC_atomic_Rcubed_moments.xyz" with open(r_cubed_file_name, "r+") as vol_file: lines = vol_file.readlines() vols = [float(line.split()[-1]) for line in lines[2:atom_total + 2]] for atom_index in ddec_data: ddec_data[atom_index].volume = vols[atom_index] self.molecule.ddec_data = ddec_data self.molecule.dipole_moment_data = dipole_moment_data self.molecule.quadrupole_moment_data = quadrupole_moment_data self.molecule.cloud_pen_data = cloud_pen_data
def mol(): """ Initialise the Ligand molecule object with data for Chloromethane """ molecule = Ligand.from_file(file_name=get_data("chloromethane.pdb")) molecule.ddec_data = { 0: CustomNamespace( a_i=72461.2438863321, atomic_symbol="C", b_i=36.09781017184126, charge=-0.220088, r_aim=1.9933297947778903, volume=30.276517, ), 1: CustomNamespace( a_i=153692.84134145387, atomic_symbol="Cl", b_i=101.44341268889193, charge=1.815899, r_aim=1.9020122149415648, volume=67.413573, ), 2: CustomNamespace( a_i=149.1117208173859, atomic_symbol="H", b_i=1.247688109065071, charge=0.13473, r_aim=1.2455924332095252, volume=3.329737, ), 3: CustomNamespace( a_i=149.1117208173859, atomic_symbol="H", b_i=1.247688109065071, charge=0.13473, r_aim=1.2455924332095252, volume=3.329737, ), 4: CustomNamespace( a_i=149.1117208173859, atomic_symbol="H", b_i=1.247688109065071, charge=0.134729, r_aim=1.2455924332095252, volume=3.329737, ), } molecule.dipole_moment_data = { 0: CustomNamespace(x_dipole=0.109154, y_dipole=0.006347, z_dipole=-0.000885), 1: CustomNamespace(x_dipole=-0.139599, y_dipole=-0.006372, z_dipole=0.000994), 2: CustomNamespace(x_dipole=-0.005778, y_dipole=-0.018142, z_dipole=-0.029462), 3: CustomNamespace(x_dipole=-0.00516, y_dipole=-0.016898, z_dipole=0.030335), 4: CustomNamespace(x_dipole=-0.00839, y_dipole=0.035106, z_dipole=-0.000628), } molecule.quadrupole_moment_data = { 0: CustomNamespace( q_3z2_r2=-0.150042, q_x2_y2=0.148149, q_xy=0.007494, q_xz=-0.001301, q_yz=-0.000128, ), 1: CustomNamespace( q_3z2_r2=-1.074695, q_x2_y2=1.070914, q_xy=0.052325, q_xz=-0.006765, q_yz=-0.000286, ), 2: CustomNamespace( q_3z2_r2=0.013971, q_x2_y2=0.011282, q_xy=0.001128, q_xz=0.000274, q_yz=0.011593, ), 3: CustomNamespace( q_3z2_r2=0.01544, q_x2_y2=0.011683, q_xy=0.001125, q_xz=-0.000412, q_yz=-0.01131, ), 4: CustomNamespace( q_3z2_r2=-0.043386, q_x2_y2=-0.007519, q_xy=-0.001058, q_xz=-5.4e-05, q_yz=-0.000249, ), } molecule.cloud_pen_data = { 0: CustomNamespace(a=2.102843, atomic_symbol="C", b=2.40575), 1: CustomNamespace(a=7.939831, atomic_symbol="Cl", b=3.395079), 2: CustomNamespace(a=0.1242, atomic_symbol="H", b=2.533532), 3: CustomNamespace(a=0.123448, atomic_symbol="H", b=2.533309), 4: CustomNamespace(a=0.120282, atomic_symbol="H", b=2.533191), } print(f"mol coords: {molecule.coordinates}") return molecule
def extract_charge_data(ddec_version=6): """ From Chargemol output files, extract the necessary parameters for calculation of L-J. :returns: 3 CustomNamespaces, ddec_data; dipole_moment_data; and quadrupole_moment_data ddec_data used for calculating monopole esp and L-J values (used by both LennardJones and Charges classes) dipole_moment_data used for calculating dipole esp quadrupole_moment_data used for calculating quadrupole esp """ if ddec_version == 6: net_charge_file_name = 'DDEC6_even_tempered_net_atomic_charges.xyz' elif ddec_version == 3: net_charge_file_name = 'DDEC3_net_atomic_charges.xyz' else: raise ValueError( 'Unsupported DDEC version; please use version 3 or 6.') if not os.path.exists(net_charge_file_name): raise FileNotFoundError( 'Cannot find the DDEC output file.\nThis could be indicative of several issues.\n' 'Please check Chargemol is installed in the correct location and that the configs' ' point to that location.') with open(net_charge_file_name, 'r+') as charge_file: lines = charge_file.readlines() # Find number of atoms atom_total = int(lines[0]) for pos, row in enumerate(lines): # Data marker: if 'The following XYZ' in row: start_pos = pos + 2 break else: raise EOFError(f'Cannot find charge data in {net_charge_file_name}.') ddec_data = {} dipole_moment_data = {} quadrupole_moment_data = {} for line in lines[start_pos:start_pos + atom_total]: # _s are the xyz coords, then the quadrupole moment tensor eigenvalues atom_count, atomic_symbol, _, _, _, charge, x_dipole, y_dipole, z_dipole, _, q_xy, q_xz, q_yz, q_x2_y2, q_3z2_r2, *_ = line.split( ) # File counts from 1 not 0; thereby requiring -1 to get the index atom_index = int(atom_count) - 1 ddec_data[atom_index] = CustomNamespace(atomic_symbol=atomic_symbol, charge=float(charge), volume=None, r_aim=None, b_i=None, a_i=None) dipole_moment_data[atom_index] = CustomNamespace( x_dipole=float(x_dipole), y_dipole=float(y_dipole), z_dipole=float(z_dipole)) quadrupole_moment_data[atom_index] = CustomNamespace( q_xy=float(q_xy), q_xz=float(q_xz), q_yz=float(q_yz), q_x2_y2=float(q_x2_y2), q_3z2_r2=float(q_3z2_r2)) r_cubed_file_name = 'DDEC_atomic_Rcubed_moments.xyz' with open(r_cubed_file_name, 'r+') as vol_file: lines = vol_file.readlines() vols = [float(line.split()[-1]) for line in lines[2:atom_total + 2]] for atom_index in ddec_data: ddec_data[atom_index].volume = vols[atom_index] return ddec_data, dipole_moment_data, quadrupole_moment_data
def __init__(self): self.name = "water" self.atoms = [ Atom(8, "O", 0, -0.827099, [1, 2]), Atom(1, "H", 1, 0.41355, [0]), Atom(1, "H", 1, 0.41355, [0]), ] self.coords = { "qm": np.array([ [-0.00191868, 0.38989824, 0.0], [-0.7626204, -0.19870548, 0.0], [0.76453909, -0.19119276, 0.0], ]) } self.topology = nx.Graph() self.topology.add_node(0) self.topology.add_node(1) self.topology.add_node(2) self.topology.add_edge(0, 1) self.topology.add_edge(0, 2) self.ddec_data = { 0: CustomNamespace( a_i=44312.906375462444, atomic_symbol="O", b_i=47.04465571009466, charge=-0.827099, r_aim=1.7571614241044191, volume=29.273005, ), 1: CustomNamespace( a_i=0.0, atomic_symbol="H", b_i=0, charge=0.41355, r_aim=0.6833737065249833, volume=2.425428, ), 2: CustomNamespace( a_i=0.0, atomic_symbol="H", b_i=0, charge=0.413549, r_aim=0.6833737065249833, volume=2.425428, ), } self.dipole_moment_data = { 0: CustomNamespace(x_dipole=-0.000457, y_dipole=0.021382, z_dipole=0.0), 1: CustomNamespace(x_dipole=-0.034451, y_dipole=-0.010667, z_dipole=0.0), 2: CustomNamespace(x_dipole=0.03439, y_dipole=-0.010372, z_dipole=-0.0), } self.quadrupole_moment_data = { 0: CustomNamespace(q_3z2_r2=-0.786822, q_x2_y2=0.307273, q_xy=0.001842, q_xz=-0.0, q_yz=0.0), 1: CustomNamespace(q_3z2_r2=-0.097215, q_x2_y2=0.018178, q_xy=0.001573, q_xz=0.0, q_yz=0.0), 2: CustomNamespace( q_3z2_r2=-0.097264, q_x2_y2=0.018224, q_xy=-0.001287, q_xz=-0.0, q_yz=-0.0, ), } self.cloud_pen_data = { 0: CustomNamespace(a=-0.126185, atomic_symbol="O", b=2.066872), 1: CustomNamespace(a=-2.638211, atomic_symbol="H", b=1.917509), 2: CustomNamespace(a=-2.627835, atomic_symbol="H", b=1.920499), } self.enable_symmetry = True self.v_site_error_factor = 1.005