예제 #1
0
def test_correlation_acf_1():
    N = 100
    size = (N, 4)
    data = np.random.random(size=size)
    acf = tidynamics.acf(data)
    comparison = tidynamics.correlation(data, data)
    assert np.allclose(acf, comparison[-N:])
예제 #2
0
def test_cst_acf_1d():
    N = 0
    data = np.ones(N)
    reference_acf = np.ones_like(data)
    print(reference_acf)
    computed_acf = tidynamics.acf(data)
    assert np.allclose(reference_acf, computed_acf)
예제 #3
0
def test_cst_acf_nd():
    N = 0
    ND = 3
    data = np.ones((N, ND))
    reference_acf = ND*np.ones(N)
    computed_acf = tidynamics.acf(data)
    assert np.allclose(reference_acf, computed_acf)
예제 #4
0
def VACF(df, conversion="x"):
    """
    Computes the Velocity Autocorrelation Fuction (VACF)
    which is the correlation  between the velocities of the fronts


    Parameters:
    --------------------------
    df : pandas dataframe with the coordinates
    conversion : string variable to convert pixels in micrometers, because the conversion is different for
    the x and y axes

    Returns a numpy array with the VACF

    References:
    -----------------
    [1] http://lab.pdebuyl.be/tidynamics/
    """
    #conversion from pixels to micrometers
    if conversion == "y":
        df = df / 1200 * 633
    else:
        df = df / 1600 * 844
    #computes the velocity in one direction between the frames
    dif = pd.DataFrame()

    for i in range(1, len(df.T)):
        dif[i - 1] = velocity(df[i - 1], df[i])
    vel = []
    for i in range(len(dif)):
        vel.append(tidynamics.acf(dif.T[i]))

        #return the velocities in array
    return np.array(vel)
예제 #5
0
def acf(data, n_use=50):
    """Computes the normalized auto correlation function (ACF) of a time dependent quantity or vector

    Parameters
    ----------
        data : ndarray
            An (N,M) numpy array of dimension 2. The first column should
            represent time, while the remaining ones are quantity or
            vector components values.
        n_use : int
            Only the first n_use elements of the ACF are returned. Default is 50.

    Returns
    -------
        tuple
            An tuple with time and ACF, where ACF is
            normalized, each of length n_use.

    Raises
    ------
        ValueError
            If the value of n_use is larger than the length of ACF.
    """
    time = data[:, 0]  # Each row, first column.
    if time.size < n_use:
        msg = 'Cannot select first ' + str(
            n_use) + ' elements from ACF of length ' + str(time.size) + '.'
        raise ValueError(msg)
    time0 = time[0]
    time -= time0
    v = data[:, 1:]  # Each row, columns 1 and up.
    acf = td.acf(v)
    acf0 = acf[0]
    nacf = acf / acf0
    pacf = nacf[0:n_use]
    ptime = time[0:n_use]
    return ptime, pacf
예제 #6
0
    def acf(self, A: np.ndarray, frame_spacing: float):
        """
        Computes the autocorrelation of data which is provided as a 2D numpy array. Since the 
        components are all independent, this is flatted into a sequence of 1D arrays, and the 
        correlation function is computed for each component of each atom and averaged.
        The correlation function is computed by taking the FFT and inverse FFT fo the data.

        Takes the spacing in time between frames in femtoseconds.
        """
        self.frame_spacing = frame_spacing
        data = np.asarray([a.ravel() for a in A])
        data = np.vstack(data.T)
        self.signal = np.zeros(data.shape[1] // 2)
        N = data.shape[1]
        M = len(self.signal)
        for i in tqdm(range(N - M)):
            for iAtom in range(data.shape[0]):
                self.signal += acf(data[iAtom, i:M + i].T)
        self.signal /= (data.shape[0])
        self.signal /= (self.signal[0])
        self.frequencies = np.fft.fftfreq(
            self.signal.size, self.frame_spacing)[0:int(self.signal.size / 2)]
        self.frequencies *= 10**(15) / (2.9979 * (10**10))
        return self.frequencies, self.signal
예제 #7
0
def vacf(u, u_vel, t, species, block):
    '''Computes velocity-velocity autocorrelation function for given species.

    Args:
        u: MDAnalysis Universe object containing trajectory (positions).
        u_vel: MDAnalysis Universe object containing trajectory (velocities).
        t: Thresholds specifying layer boundaries.
        species: For which species (elements) to compute autocorrelation.
        block: Range of frames composing block.

    Returns:
        Velocity-velocity autocorrelation function.
    '''

    # Which species to include in velocity autocorrelation
    if species == 'HH':
        selection = 'name H'
    elif species == 'OO':
        selection = 'name O'
    elif species == 'OH':
        selection = 'name O or name H'

    # Get position and velocity trajectories of selection
    ag_trj = u.select_atoms(selection)
    ag_vel = u_vel.select_atoms(selection)
    n_atoms = ag_vel.n_atoms

    # Initialize arrays for velocities and atom heights
    velocity_array = np.zeros((len(block), n_atoms, 3))
    height_array = np.zeros((len(block), n_atoms))
    corr = []

    for i, ts in enumerate(u_vel.trajectory[block.start:block.stop]):
        print('Processing velocities %.1f%%' % (100 * i / len(block)),
              end='\r')

        # Update positions
        u.trajectory[ts.frame]

        # Loop over atoms
        for j, vel in enumerate(ag_vel):

            # Store heights and velocities of atom
            height_array[i, j] = ag_trj.positions[j, 2]
            velocity_array[i, j, :] = vel.position

    # Loop over atoms
    for k in range(n_atoms):

        # Get frames where atoms in specified region
        z = height_array[:, k]
        z_bool = (z > t[0]) * (z < t[1]) + (z > t[2]) * (z < t[3])

        # Select intervals where remain remains continuously in region
        contiguous_region = find_objects(label(z_bool)[0])

        # Compute dipole autocorrelation for all intervals and starting times
        for reg in contiguous_region:
            corr.append(
                tidynamics.acf(velocity_array[reg[0].start:reg[0].stop, k, :]))

    return tolerant.mean(corr)
예제 #8
0
    all_N.append(N + int(2 * N / 3))
    N = 2 * N
all_N = np.array(all_N)

max_direct_N = 32768
all_time = []
direct_time = []
n_runs = 5

for N in all_N:
    t = 0
    direct_t = 0
    for i in range(n_runs):
        data = np.random.random(size=N)
        t0 = time.time()
        acf = tidynamics.acf(data)
        t += time.time() - t0
        if N <= max_direct_N:
            t0 = time.time()
            acf = np.correlate(data, data, mode='full')
            direct_t += time.time() - t0

    all_time.append(t / n_runs)
    if N <= max_direct_N:
        direct_time.append(direct_t / n_runs)

plt.plot(all_N, all_time, label='actual compute time')
plt.plot(all_N,
         all_time[-1] * all_N * np.log(all_N) /
         (all_N[-1] * np.log(all_N[-1])),
         label=r'$N\log N$ scaling')
예제 #9
0
def rotation(u, a, t, block):
    '''Computes water orientational (dipole) relaxation.

    Args:
        u: MDAnalysis Universe object containing trajectory.
        a: Lateral lattice vector assuming equal lateral dimensions
        t: Thresholds specifying layer boundaries.
        block: Range of frames composing block.

    Returns:
        Water orientational (dipole) autocorrelation function.
    '''

    size = len(block)
    wor = []

    # Select oxygen and hydrogen atoms
    oxygen = u.select_atoms('name O')
    hydrogen = u.select_atoms('name H')

    # Initialize OH distance array, dipole array and height array
    rOH = np.zeros((oxygen.n_atoms, hydrogen.n_atoms))
    dipole_array = np.zeros((len(block), oxygen.n_atoms, 3))
    height_array = np.zeros((len(block), oxygen.n_atoms))

    for i, ts in enumerate(u.trajectory[block.start:block.stop]):
        print('Processing blocks %.1f%%' % (100 * i / size), end='\r')

        # Wrap atoms to box
        oxygen.wrap(box=u.dimensions)
        hydrogen.wrap(box=u.dimensions)

        # Compute OH distance array
        distance_array(oxygen.positions,
                       hydrogen.positions,
                       box=u.dimensions,
                       result=rOH)

        # Store heights of all oxygens
        height_array[i, :] = oxygen.positions[:, 2]

        # Loop over all oxygen positions
        for j, pos in enumerate(oxygen.positions):

            # Get bound hydrogens and combine molecules broken over PBCs
            hbound = hydrogen.positions[(rOH < 1.2)[j]]
            hbound[hbound - pos < -1.2] += a
            hbound[hbound - pos > 1.2] -= a

            # Compute dipole vectors
            dip = np.mean(hbound, axis=0) - pos
            dipole_array[i, j, :] = dip / np.linalg.norm(dip)

    # Loop over all oxygens
    for k in range(oxygen.n_atoms):

        # Get frames where oxygen in specified region
        z = height_array[:, k]
        z_bool = (z > t[0]) * (z < t[1]) + (z > t[2]) * (z < t[3])

        # Select intervals where oxygen remains continuously in region
        contiguous_region = find_objects(label(z_bool)[0])

        # Compute dipole autocorrelation for all intervals and starting times
        for reg in contiguous_region:
            corr = tidynamics.acf(dipole_array[reg[0].start:reg[0].stop, k, :])
            wor.append(lg2(corr))

    # Average autocorrelation functions of (possibly) different length
    return tolerant.mean(wor)
예제 #10
0
    v = v - gamma * v * dt + noise_force

v_data = []
noise_data = []

for i in range(N):
    noise_force = v_factor * np.random.normal()
    v = v - gamma * v * dt + noise_force
    v_data.append(v)
    noise_data.append(noise_force)
v_data = np.array(v_data)
noise_data = np.array(noise_data) / np.sqrt(dt)

# Compute the autocorrelation function and plot the result

acf = tidynamics.acf(v_data)[:N // 64]

time = np.arange(N // 64) * dt

plt.plot(time, acf, label='VACF (num.)')

plt.plot(time, T * np.exp(-gamma * time), label='VACF (theo.)')

plt.legend()
plt.title('Velocity autocorrelation')
plt.xlabel(r'$\tau$')
plt.ylabel(r'$\langle v(t) v(t+\tau) \rangle$')

# Compute the force velocity correlation and plot the result

plt.figure()
예제 #11
0
np.savetxt from NumPy.

For more information, consult the documentation of tidynamics at
http://lab.pdebuyl.be/tidynamics/

"""
from __future__ import print_function, division

import argparse
import numpy as np
import tidynamics

parser = argparse.ArgumentParser(
    description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('action',
                    help='Choice of computation to perform on input file',
                    choices=['acf', 'msd'])
parser.add_argument('input_file', help='Filename for input data')
parser.add_argument('output_file',
                    help='Filename for the result of the computation')
args = parser.parse_args()

input_data = np.loadtxt(args.input_file)

if args.action == 'acf':
    result = tidynamics.acf(input_data)
elif args.action == 'msd':
    result = tidynamics.msd(input_data)

np.savetxt(args.output_file, result)