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:])
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)
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)
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)
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
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
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)
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')
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)
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()
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)