"""Extract charge and spin data for a given subset of atoms for graphing."""
import glob
[docs]def get_files(file_pattern):
"""
Find all examples of a file type in the current directory.
Parameters
----------
file_pattern : str
The type of file the for which the user would like to search the current directory.
Returns
-------
xyz_filename_list : list
A list of files found matching the user's pattern.
"""
file_list = glob.glob(file_pattern)
file_list = sorted(file_list)
print(f" > We found {file_list} using the pattern {file_pattern}")
return file_list
[docs]def get_selection(file):
"""
Get the user's atom set.
Returns
-------
atoms : selection
The index of the atom for which the user would like the spin and charge.
"""
# For which frames would the user like
selection = input(f"What frames would you like for {file}: ")
# Convert user input to a list even if it is hyphenated
temp = [
(lambda sub: range(sub[0], sub[-1] + 1))(list(map(int, ele.split("-"))))
for ele in selection.split(",")
]
selection = [int(b) for a in temp for b in a]
return selection
[docs]def get_atoms():
# For which atoms would the user like to sum the spin and charge
my_atoms = input(" > What atom indexes would you like to sum (e.g., 58-76): ")
# Convert user input to a list even if it is hyphenated
temp = [
(lambda sub: range(sub[0], sub[-1] + 1))(list(map(int, ele.split("-"))))
for ele in my_atoms.split(",")
]
atoms = [str(b) for a in temp for b in a]
return atoms
[docs]def get_spins(atoms, file, selection):
"""
Gets the charges for the atoms specified by the user and sums them.
Parameters
----------
atoms : list
List of atoms indices.
file : str
The name of the file that you would like to analyze.
selection : list
The indices of the atoms for which the user would like the charge and spin.
Returns
-------
net_spins : list
List fo spins corresponding to each image in the scan.
"""
# Sum the spins for the user selected atoms
net_spins = []
net_spin = 0
step_count = 0
with open(file, "r") as scan_spin_file:
for line in scan_spin_file:
line_list = line.split()
if line_list[0] in atoms:
net_spin += float(line_list[9])
if line_list[0] == "End":
step_count += 1
net_spins.append(f"{step_count},{net_spin}\n")
net_spin = 0
net_spins_reference = net_spins.copy()
for index, spin in enumerate(net_spins_reference):
if index + 1 not in selection:
net_spins.remove(net_spins_reference[index])
reverse = input(f" > Press any key to reverse data for {file}: ")
if reverse:
net_spins.reverse()
return net_spins
[docs]def get_charges(atoms, file, selection):
"""
Gets the charge for the atoms specified by the user and sums them.
Parameters
----------
atoms : list
List of atoms indices.
file : str
The name of the file that you would like to analyze.
selection : list
The atom indices for which the user would like the charge and spin.
Returns
-------
net_spins : list
List fo spins corresponding to each image in the scan.
"""
# Sum the charges for the user selected atoms
net_charges = []
net_charge = 0
step_count = 0
with open(file, "r") as scan_charge_file:
for line in scan_charge_file:
line_list = line.split()
if line_list[0] in atoms:
net_charge += float(line_list[2])
if line_list[0] == "End":
step_count += 1
net_charges.append(f"{step_count},{net_charge}\n")
net_charge = 0
net_charges_reference = net_charges.copy()
for index, charge in enumerate(net_charges_reference):
if index + 1 not in selection:
net_charges.remove(net_charges_reference[index])
reverse = input(f" > Press any key to reverse data for {file}: ")
if reverse:
net_charges.reverse()
return net_charges
[docs]def write_data(file, net_data):
"""
Writes out the data for either the charge or spin.
Parameters
----------
file : str
The name of the file where we are going to write out the data.
net_data : list
List of data extracted from either the spin or charge files.
"""
with open(file, "w") as select_file:
for pair in net_data:
select_file.write(pair)
if __name__ == "__main__":
charge_spin_extractor()