示例#1
0
文件: PDA.py 项目: tzyii/fromage
def centre_of_mass(symbols, coordinates):
    """
    Calculates the centre of mass (COM) for a set of atomic positions, based on:

    COM_x = m1x1 + m2x2 + ... + mnxn / m1 + m2 + ... + mn
    COM_y = m1y1 + m2y2 + ... + mnyn / m1 + m2 + ... + mn
    COM_z = m1z1 + m2z2 + ... + mnzn / m1 + m2 + ... + mn

    Parameters
    ----------
    symbols: List of strings
        List of elemental symbols
    coordinates: Nx3 array of floats
        Array of x,y,z coordinates
    Returns
    ----------
    COM: np.array
        Array of x,y,z component of COM
    """
    if len(symbols) != len(coordinates):
        exit("Inputs not of the same dimension!")
    masses = np.array([elements.element(i).mass for i in symbols])
    mass_sum = np.sum(masses)

    x_coords = coordinates[:, 0]
    y_coords = coordinates[:, 1]
    z_coords = coordinates[:, 2]
    x_numerator = np.sum(np.dot(masses, x_coords))
    y_numerator = np.sum(np.dot(masses, y_coords))
    z_numerator = np.sum(np.dot(masses, z_coords))

    COM_x = x_numerator / mass_sum
    COM_y = y_numerator / mass_sum
    COM_z = z_numerator / mass_sum
    return np.array([COM_x, COM_y, COM_z])
示例#2
0
def read_xyz(g09_file):
    """
    Opens a g09 log file and returns the first geometry in Input orientation.

    Iterators are used so that the file is not all loaded into memory, which
    can be expensive.

    The function searches for the following text pattern in the log file:

>                            Input orientation:
>    ---------------------------------------------------------------------
>    Center     Atomic      Atomic             Coordinates (Angstroms)
>    Number     Number       Type             X           Y           Z
>    ---------------------------------------------------------------------

    And will save the coordinates and the atomic symbols succeeding it

    Parameters
    ----------
    g09_file: Path to g09 log file
        File path

    Returns
    -------
    coordinates: List of lists
        Outer list is whole xyz file, each inner list is a line of the file containing
        the symbol and x,y,z coordinates

    """
    with open(g09_file) as f:
        # Get the number of atoms so we can iterate without loading the file into memory
        for line in f:
            # Ensures line is not blank
            if line.strip():
                if line.split()[0] == "NAtoms=":
                    natoms = (int(line.split()[3]))
                    break
        # Will hold the coordinates and symbols
        coordinates = []
        # Reset the iterator to the top of the file
        f.seek(0)
        for line in f:
            if line.strip():
                if "Input orientation:" in line:
                    for i in range(5):
                        # Skip 5 lines to start of coordinates
                        line = next(f)
                    for i in range(natoms):
                        linesplit = line.split()

                        symb = str(elements.element(int(linesplit[1])).symbol)
                        x = float(linesplit[3])
                        y = float(linesplit[4])
                        z = float(linesplit[5])
                        coordinates.append([symb, x, y, z])
                        line = next(f)
                    break
        return coordinates
示例#3
0
def read_NTO(g09_file, natoms):
    """
    Reads a G09 logfile and returns the atomic centred Natural Transition Charges, obtained
    via the G09 input line:
    td=(nstates=1) nosymm Pop=NTO Density=(Transition=1)

    Parameters
    ----------
    g09_file: Path to g09 log file
        File path
    natoms: Integer
        Number of atoms
    Returns
    -------
    NTO: np.array
        N array of NTO charges in order of atomic positions

    """
    NTO = np.zeros(natoms)
    with open(g09_file) as f:
        # Get the number of atoms so we can iterate without loading the file into memory
        for line in f:
            # Ensures line is not blank
            if line.strip():
                if " Mulliken charges:" in line:
                    next(f)
                    line = next(f)
                    for i in range(natoms):
                        charge_line = line.split()
                        symbol = charge_line[1]
                        charge = float(charge_line[2])
                        # NTO charge is atomic number - charge
                        NTO[i] = elements.element(symbol).atomic - float(
                            charge)
                        line = next(f)

        f.close()
    return NTO