def analyse_bonds(model, A, B):
    '''
    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. "H"
        B: string, chemical symbol, e.g. "H"
    '''
    # Read file or Atoms object
    if isinstance(model, str) is True:
        model = read(model)

    analysis = Analysis(model)
    dash = "-" * 40
    print_AB = A + "-" + B
    # Retrieve bonds and values
    AB_Bonds = analysis.get_bonds(A, B)
    AB_BondsValues = analysis.get_values(AB_Bonds)
    # Table header
    print(dash)
    print(print_AB+"       Distance / Angstrom")
    print(dash)
    print('{:<6.5s}{:>4.10s}{:^13.10s}{:>4.10s}'.format(
        "count", "average", "minimum", "maximum"))
    # Table contents
    print('{:<6.0f}{:>4.6f}{:^12.6f}{:>4.6f}'.format(
        len(AB_BondsValues[0]), np.average(AB_BondsValues),
        np.amin(AB_BondsValues), np.amax(AB_BondsValues)))
def search_abnormal_bonds(model):
    '''
    Check all bond lengths in the model for abnormally
    short ones, ie. less than 0.74 Angstrom.
        model: Atoms object or string. If string it will read a file
        in the same folder, e.g. "name.traj"
    '''

    # Combination as AB = BA for bonds, avoiding redundancy
    from itertools import combinations_with_replacement
    # Read file or Atoms object
    if isinstance(model, str) is True:
        model = read(model)

    # Define lists of variables
    abnormal_bonds = []
    list_of_abnormal_bonds = []

    analysis = Analysis(model)
    # set() to ensure unique chemical symbols list
    list_of_symbols = list(set(model.get_chemical_symbols()))
    all_bonds = combinations_with_replacement(list_of_symbols, 2)

    # Iterate over all arrangements of chemical symbols
    for bonds in all_bonds:
        A = bonds[0]
        B = bonds[1]

        print_AB = A+'-'+B
        AB_Bonds = analysis.get_bonds(A, B)

        # Make sure bond exist before retrieving values
        if not AB_Bonds == [[]]:
            AB_BondsValues = analysis.get_values(AB_Bonds)

            for i in range(0, len(AB_BondsValues)):
                for values in AB_BondsValues[i]:
                    if values < 0.74:
                        abnormal_bonds += [1]
                        list_of_abnormal_bonds = list_of_abnormal_bonds + [print_AB]

    # Abnormality check
    if not len(abnormal_bonds) == 0:
        print("A total of", len(abnormal_bonds),
        "abnormal bond lengths observed (<0.74 A).")
        print("Identities:", list_of_abnormal_bonds)
    else:
        print("OK")
Exemple #3
0
def analyse_all_bonds(model):
    '''
    Returns a table of bond distance 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"
    '''
    # Combination as AB = BA for bonds, avoiding redundancy
    from itertools import combinations_with_replacement

    # 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_bonds = combinations_with_replacement(list_of_symbols, 2)

    # Table heading
    print(dash)
    print('{:<6.5s}{:<6.5s}{:>4.10s}{:^13.10s}{:>4.10s}'.format(
        "Bond", "Count", "Average", "Minimum", "Maximum"))
    print(dash)

    # Iterate over all arrangements of chemical symbols
    for bonds in all_bonds:
        A = bonds[0]
        B = bonds[1]

        print_AB = A + '-' + B
        AB_Bonds = analysis.get_bonds(A, B)

        # Make sure bond exist before retrieving values, then print contents
        if not AB_Bonds == [[]]:
            AB_BondsValues = analysis.get_values(AB_Bonds)
            print('{:<8.8s}{:<6.0f}{:>4.6f}{:^12.6f}{:>4.6f}'.format(
                print_AB, len(AB_BondsValues[0]), np.average(AB_BondsValues),
                np.amin(AB_BondsValues), np.amax(AB_BondsValues)))
Exemple #4
0
def analyse_bonds(model, A, B, verbose=True, multirow=False):
    '''
    Check A-B distances present in the model.

    Parameters:
    model: Atoms object
        XXX
    A: string, chemical symbol, e.g. "H"
    B: string, chemical symbol, e.g. "H"
    verbose: Boolean
        Whether to print information to screen
    multirow: Boolean
        Whether we are working with analyse_all_bonds, so the output is multirow,
        or just one specific analysis of a bond, in which case the table header is needed.
    '''

    from ase.geometry.analysis import Analysis
    analysis = Analysis(model)

    print_AB = A + "-" + B
    # Retrieve bonds and values
    AB_Bonds = analysis.get_bonds(A, B)
    if AB_Bonds == [[]]:
        AB_BondsValues = None
    else:
        AB_BondsValues = analysis.get_values(AB_Bonds)

    if verbose and AB_BondsValues is not None:
        if not multirow:
            print_bond_table_header()
        # Table contents
        import numpy as np
        print('{:<8.8s}{:<6.0f}{:>4.6f}{:^12.6f}{:>4.6f}'.format(
            print_AB, len(AB_BondsValues[0]), np.average(AB_BondsValues),
            np.amin(AB_BondsValues), np.amax(AB_BondsValues)))

    return print_AB, AB_Bonds, AB_BondsValues
AllSnIAngles = []
AllPbIPbAngles = []
AllSnISnAngles = []

for i in range(0, 16):

    # VASP POSCAR
    PEA2PbSnI4 = read('CONTCAR_PbSn' + str(i))

    #print(PEA2PbSnI4)

    ana = Analysis(PEA2PbSnI4)

    # Bonds

    PbIBonds = ana.get_bonds('Pb', 'I', unique=True)
    SnIBonds = ana.get_bonds('Sn', 'I', unique=True)

    #print("\nThere are {} Pb-I bonds in PEA2PbSnI4.".format(len(PbIBonds[0])))
    #print("There are {} Pb-I bonds in PEA2PbSnI4.".format(len(SnIBonds[0])))

    if len(PbIBonds[0]) > 0:
        PbIBondValues = ana.get_values(PbIBonds)

    if len(SnIBonds[0]) > 0:
        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:
Exemple #6
0
def search_abnormal_bonds(model, verbose=True):
    '''
    Check all bond lengths in the model for abnormally
    short ones, ie. less than 0.74 Angstrom.

    Parameters:
    model: Atoms object or string. If string it will read a file
        in the same folder, e.g. "name.traj"
    '''

    # Combination as AB = BA for bonds, avoiding redundancy
    from itertools import combinations_with_replacement
    # Imports necessary to work out accurate minimum bond distances
    from ase.data import chemical_symbols, covalent_radii

    # Read file or Atoms object
    if isinstance(model, str) is True:
        model = read(model)

    # Define lists of variables
    abnormal_bonds = []
    list_of_abnormal_bonds = []

    analysis = Analysis(model)
    # set() to ensure unique chemical symbols list
    list_of_symbols = list(set(model.get_chemical_symbols()))
    all_bonds = combinations_with_replacement(list_of_symbols, 2)

    # Iterate over all arrangements of chemical symbols

    for bonds in all_bonds:
        A = bonds[0]
        B = bonds[1]
        # For softcoded bond cutoff
        sum_of_covalent_radii = covalent_radii[chemical_symbols.index(
            A)] + covalent_radii[chemical_symbols.index(B)]

        print_AB = A + '-' + B
        AB_Bonds = analysis.get_bonds(A, B)

        # Make sure bond exist before retrieving values
        if not AB_Bonds == [[]]:
            AB_BondsValues = analysis.get_values(AB_Bonds)

            for i in range(0, len(AB_BondsValues)):
                for values in AB_BondsValues[i]:
                    # TODO: move the 75% of sum_of_covalent_radii before the loops
                    if values < max(0.4, sum_of_covalent_radii * 0.75):
                        abnormal_bonds += [1]
                        list_of_abnormal_bonds = list_of_abnormal_bonds + [
                            print_AB
                        ]

    # Abnormality check
    # is it possible to make a loop with different possible values instead of 0.75 and takes the average
    if len(abnormal_bonds) > 0:
        if verbose:
            print(
                "A total of", len(abnormal_bonds),
                "abnormal bond lengths observed (<" +
                str(max(0.4, sum_of_covalent_radii * 0.75)) + " A).")
            print("Identities:", list_of_abnormal_bonds)
        return False
    else:
        if verbose:
            print("OK")
        return True
Exemple #7
0
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))