[docs]defget_ddec6_index_map(dir_name:str|Path)->list[int]:"""Return a list of integers mapping DDEC6 indices to ASE indices. The ASE index of the atom at index i in the DDEC6 structure can be found as follows: index_map = get_ddec6_index_map(dir_name) index = index_map[i] Args: dir_name: The directory containing a calculation. """with(Path(dir_name).joinpath("run.py").open(mode="r",encoding="utf-8")aspython_script):input_traj=extract_structure_name(python_script).removeprefix("./")ase_atoms=ase.io.read(Path(dir_name).joinpath(input_traj))ase_atoms.center()xyz_file=Path(dir_name).joinpath(DDEC_NET_ATOMIC_CHARGE_FILE)ddec_atoms=ase.io.read(xyz_file)ddec_atoms.cell=ase_atoms.cellddec_atoms.center()ddec6_index_map=[]foratominddec_atoms:closest_ase_atom=ase_atoms[0]_,min_distance=geometry.get_distances([atom.position],[ase_atoms[0].position],cell=ddec_atoms.cell,pbc=True,)forase_atominase_atoms:_,distance=geometry.get_distances([atom.position],[ase_atom.position],cell=ddec_atoms.cell,pbc=True,)ifdistance<=min_distance:closest_ase_atom=ase_atommin_distance=distanceddec6_index_map.append(closest_ase_atom.index)iflen(ddec6_index_map)!=len(set(ddec6_index_map)):msg=(f"DDEC6 map is incomplete for calculation in directory: {dir_name}")raiseRuntimeError(msg)returnddec6_index_map
[docs]defload_ddec6_data(dir_name:str|Path)->DDEC6Analysis:"""Extract the DDEC6 data from the job directory. Args: dir_name: The directory of the completed calculation. Returns: The DDEC6 data. If no data is found, every value will be None. """logger.info(f"Loading DDEC6 data for {dir_name!s}")rsquared_moments=rcubed_moments=rfourth_moments=Nonedipoles=charges=spin_densities=bond_orders=Nonetry:analysis=ChargemolAnalysis(path=dir_name,run_chargemol=False)ddec6_index_map=get_ddec6_index_map(dir_name)charges=[0.0]*len(ddec6_index_map)spin_densities=[0.0]*len(ddec6_index_map)bond_orders:BondOrderDict={}dipoles=[0.0]*len(ddec6_index_map)fori_ddec,i_aseinenumerate(ddec6_index_map):charges[i_ase]=analysis.ddec_charges[i_ddec]spin_densities[i_ase]=analysis.ddec_spin_moments[i_ddec]bond_orders[i_ase]=analysis.bond_order_dict[i_ddec]dipoles[i_ase]=analysis.dipoles[i_ddec]rsquared_moments[i_ase]=analysis.ddec_rsquared_moments[i_ddec]rcubed_moments[i_ase]=analysis.ddec_rcubed_moments[i_ddec]rfourth_moments[i_ase]=analysis.ddec_rfourth_moments[i_ddec]forbond_orderinbond_orders.values():forbonded_toinbond_order["bonded_to"]:bonded_to["index"]=ddec6_index_map[bonded_to["index"]]logger.info(f"Successfully loaded DDEC6 data for {dir_name!s}")exceptFileNotFoundError:logger.warning(f"Unable to load DDEC6 data for {dir_name!s}")returnDDEC6Analysis(partial_charges=charges,spin_moments=spin_densities,dipoles=dipoles,rsquared_moments=rsquared_moments,rcubed_moments=rcubed_moments,rfourth_moments=rfourth_moments,bond_order_dict=bond_orders,)