def analyse_angles(model, A, B, C): ''' Check A-B distances present in the model. model: Atoms object or string. If string it will read a file in the same folder, e.g. "name.traj" A: string, chemical symbol, e.g. "O" B: string, chemical symbol, e.g. "C" C: string, chemical symbol, e.g. "O" ''' # Read file or Atoms object if isinstance(model, str) is True: model = read(model) analysis = Analysis(model) dash = "-"*40 print_ABC = A + "-" + B + "-" + C # Retrieve bonds and values ABC_Angle = analysis.get_angles(A, B, C) ABC_AngleValues = analysis.get_values(ABC_Angle) # Table header print(dash) print(print_ABC+" Angle / Degrees") print(dash) print('{:<6.5s}{:>4.10s}{:^13.10s}{:>4.10s}'.format( "count", "average", "minimum", "maximum")) # Table contents print('{:<6.0f}{:>4.4f}{:^12.4f}{:>4.4f}'.format( len(ABC_Angle[0]), np.average(ABC_AngleValues), np.amin(ABC_AngleValues), np.amax(ABC_AngleValues)))
def test_analysis(): #test the geometry.analysis module mol = molecule('CH3CH2OH') ana = Analysis(mol) assert np.shape(ana.adjacency_matrix[0].todense()) == (9, 9) for imI in range(len(ana.all_bonds)): l1 = sum([len(x) for x in ana.all_bonds[imI]]) l2 = sum([len(x) for x in ana.unique_bonds[imI]]) assert l1 == l2 * 2 for imi in range(len(ana.all_angles)): l1 = sum([len(x) for x in ana.all_angles[imi]]) l2 = sum([len(x) for x in ana.unique_angles[imi]]) assert l1 == l2 * 2 for imi in range(len(ana.all_dihedrals)): l1 = sum([len(x) for x in ana.all_dihedrals[imi]]) l2 = sum([len(x) for x in ana.unique_dihedrals[imi]]) assert l1 == l2 * 2 assert len(ana.get_angles('C', 'C', 'H', unique=False)[0]) == len( ana.get_angles('C', 'C', 'H', unique=True)[0]) * 2 csixty = molecule('C60') mol = molecule('C7NH5') ana = Analysis(csixty) ana2 = Analysis(mol) for imI in range(len(ana.all_bonds)): l1 = sum([len(x) for x in ana.all_bonds[imI]]) l2 = sum([len(x) for x in ana.unique_bonds[imI]]) assert l1 == l2 * 2 for imI in range(len(ana.all_angles)): l1 = sum([len(x) for x in ana.all_angles[imI]]) l2 = sum([len(x) for x in ana.unique_angles[imI]]) assert l1 == l2 * 2 for imI in range(len(ana.all_dihedrals)): l1 = sum([len(x) for x in ana.all_dihedrals[imI]]) l2 = sum([len(x) for x in ana.unique_dihedrals[imI]]) assert l1 == l2 * 2 assert len(ana2.get_angles('C', 'C', 'H', unique=False)[0]) == len( ana2.get_angles('C', 'C', 'H', unique=True)[0]) * 2 assert len(ana2.get_dihedrals('H', 'C', 'C', 'H', unique=False)[0]) == len( ana2.get_dihedrals('H', 'C', 'C', 'H', unique=True)[0]) * 2
def analyse_all_angles(model): ''' Returns a table of bond angle analysis for the supplied model. Parameters: model: Atoms object or string. If string it will read a file in the same folder, e.g. "name.traj" ''' # Product to get all possible arrangements from itertools import product # Read file or Atoms object if isinstance(model, str) is True: model = read(model) analysis = Analysis(model) dash = "-" * 40 # set() to ensure unique chemical symbols list list_of_symbols = list(set(model.get_chemical_symbols())) all_angles = product(list_of_symbols, repeat=3) # Table heading print(dash) print('{:<9.8s}{:<6.5s}{:>4.10s}{:^13.10s}{:>4.10s}'.format( "Angle", "Count", "Average", "Minimum", "Maximum")) print(dash) # Iterate over all arrangements of chemical symbols for angles in all_angles: A = angles[0] B = angles[1] C = angles[2] print_ABC = A + '-' + B + '-' + C ABC_Angle = analysis.get_angles(A, B, C) # Make sure angles exist before retrieving values, print table contents if not ABC_Angle == [[]]: ABC_AngleValues = analysis.get_values(ABC_Angle) print('{:<9.8s}{:<6.0f}{:>4.4f}{:^12.4f}{:>4.4f}'.format( print_ABC, len(ABC_Angle[0]), np.average(ABC_AngleValues), np.amin(ABC_AngleValues), np.amax(ABC_AngleValues)))
def analyse_angles(model, A, B, C, verbose=True, multirow=False): ''' Check A-B-C angles present in the model. Parameters: model: Atoms object XXX A: string, chemical symbol, e.g. "O" B: string, chemical symbol, e.g. "C" C: string, chemical symbol, e.g. "O" verbose: Boolean Whether to print information to screen multirow: Boolean Whether we are returning multiple sets of results in a Table ''' from ase.geometry.analysis import Analysis analysis = Analysis(model) print_ABC = A + "-" + B + "-" + C # Retrieve bonds and values ABC_indices = analysis.get_angles(A, B, C) if len(ABC_indices[0]) == 0: ABC_values = None else: ABC_values = analysis.get_values(ABC_indices) if verbose and ABC_values is not None: # Table header if not multirow: print_angles_table_header() # Table contents import numpy as np print('{:<9.8s}{:<6.0f}{:>4.4f}{:^12.4f}{:>4.4f}'.format( print_ABC, len(ABC_indices[0]), np.average(ABC_values), np.amin(ABC_values), np.amax(ABC_values))) return ABC_indices, ABC_values
SnIBondValues = ana.get_values(SnIBonds) #print("The average Pb-I bond length is {}.".format(np.average(PbIBondValues))) #print("The average Sn-I bond length is {}.".format(np.average(SnIBondValues))) if len(PbIBonds[0]) > 0: AllPbIBonds.append(np.average(PbIBondValues)) if len(SnIBonds[0]) > 0: AllSnIBonds.append(np.average(SnIBondValues)) # # Angles IPbIAngles = ana.get_angles('I', 'Pb', 'I', unique=True) ISnIAngles = ana.get_angles('I', 'Sn', 'I', unique=True) PbIPbAngles = ana.get_angles('Pb', 'I', 'Pb', unique=True) SnISnAngles = ana.get_angles('Sn', 'I', 'Sn', unique=True) #print("\nThere are {} I-Pb-I angles in PEA2PbSnI4.".format(len(IPbIAngles[0]))) #print("There are {} I-Sn-I angles in PEA2PbSnI4.".format(len(ISnIAngles[0]))) if len(IPbIAngles[0]) > 0: IPbIAngleValues = ana.get_values(IPbIAngles) IPbIAngleValuesOver120 = np.array(IPbIAngleValues)[( np.array(IPbIAngleValues) >= 120)] AllPbIAngles.append(np.average(IPbIAngleValuesOver120)) if len(PbIPbAngles[0]) > 0: PbIPbAngleValues = ana.get_values(PbIPbAngles)
for imI in range(len(ana.all_bonds)): l1 = sum([len(x) for x in ana.all_bonds[imI]]) l2 = sum([len(x) for x in ana.unique_bonds[imI]]) assert l1 == l2 * 2 for imi in range(len(ana.all_angles)): l1 = sum([len(x) for x in ana.all_angles[imi]]) l2 = sum([len(x) for x in ana.unique_angles[imi]]) assert l1 == l2 * 2 for imi in range(len(ana.all_dihedrals)): l1 = sum([len(x) for x in ana.all_dihedrals[imi]]) l2 = sum([len(x) for x in ana.unique_dihedrals[imi]]) assert l1 == l2 * 2 assert len(ana.get_angles('C','C','H', unique=False)[0]) == len(ana.get_angles('C','C','H', unique=True)[0])*2 csixty = molecule('C60') mol = molecule('C7NH5') ana = Analysis(csixty) ana2 = Analysis(mol) for imI in range(len(ana.all_bonds)): l1 = sum([len(x) for x in ana.all_bonds[imI]]) l2 = sum([len(x) for x in ana.unique_bonds[imI]]) assert l1 == l2 * 2 for imI in range(len(ana.all_angles)): l1 = sum([len(x) for x in ana.all_angles[imI]]) l2 = sum([len(x) for x in ana.unique_angles[imI]]) assert l1 == l2 * 2
from ase.io.trajectory import Trajectory import numpy as np from ase.io import read from ase.geometry.analysis import Analysis #old file see bonds.py for better version file = read('tin_acetate.xyz') traj = Trajectory('tin_acetate.traj', 'w') traj.write(file) file = read('tin_acetate.traj') ana = Analysis(file) SiOBonds = ana.get_bonds('Sn', 'O') SiOSiAngles = ana.get_angles('O', 'Sn', 'O') print("there are {} Si-O bonds in BETA".format(len(SiOBonds[0]))) print("there are {} Si-O-Si angles in BETA".format(len(SiOSiAngles[0]))) SiOBondsValues = ana.get_values(SiOBonds) SiOSiAngleValues = ana.get_values(SiOSiAngles) print("bond length data:") print("the average Si-O bond length is {}.".format(np.average(SiOBondsValues))) print("the minimum Si-O Distance is:", np.amin(SiOBondsValues)) print("the maximum Si-O Distance is:", np.amax(SiOBondsValues)) print("bond angle data:") print("the average Si-O-Si angle is {}.".format(np.average(SiOSiAngleValues))) print("the maximum Si-O-Si angle is:", np.amax(SiOSiAngleValues)) print("the minimum Si-O-Si angle is:", np.amin(SiOSiAngleValues))
from ase.io.trajectory import Trajectory import numpy as np from ase.io import read from ase.geometry.analysis import Analysis BEA = read('BEA.cif') traj = Trajectory('BEA.traj', 'w') traj.write(BEA) BEA = read('BEA.traj') ana = Analysis(BEA) SiOBonds = ana.get_bonds('Si', 'O') SiOSiAngles = ana.get_angles('Si', 'O', 'Si') print("there are {} Si-O bonds in BETA".format(len(SiOBonds[0]))) print("there are {} Si-O-Si angles in BETA".format(len(SiOSiAngles[0]))) SiOBondsValues = ana.get_values(SiOBonds) SiOSiAngleValues = ana.get_values(SiOSiAngles) print("bond length data:") print("the average Si-O bond length is {}.".format(np.average(SiOBondsValues))) print("the minimum Si-O Distance is:", np.amin(SiOBondsValues)) print("the maximum Si-O Distance is:", np.amax(SiOBondsValues)) print("bond angle data:") print("the average Si-O-Si angle is {}.".format(np.average(SiOSiAngleValues))) print("the maximum Si-O-Si angle is:", np.amax(SiOSiAngleValues)) print("the minimum Si-O-Si angle is:", np.amin(SiOSiAngleValues))