def test_director(): directors = order._compute_director(TRAJ2_LINE1) assert eq(directors, np.array([[1, 0, 0], # Frame 0 [0, 1, 0], # Frame 1 [0, 0, 1], # Frame 2 [1, 0, 0], # Frame 3 [1, 0, 0], # Frame 4 ])) directors = order._compute_director(TRAJ2_LINE2) assert eq(directors, np.array([[1, 0, 0], # Frame 0 [0, 1, 0], # Frame 1 [0, 0, 1], # Frame 2 [0, 1, 0], # Frame 3 [0, 0, 1], # Frame 4 ]))
def calc_avg_tilt_angle(traj_filename, top_filename, output_filename, ndx_filename, n_chains): """Calculate the avg. tilt angle of both monolayers in a two monolayer system Returns the average tilt angle of each monolayer at each frame of a trajectory in a dual monolayer system. Parameters ---------- traj_filename : str Name of trajectory file top_filename : str Name of topology file output_filename : str Name of output file ndx_filename : str Name of Gromacs .ndx file which specifies atom groups n_chains : int Number of chains per monolayer """ groups = read_ndx(ndx_filename) bottom_chains = [id - 1 for id in groups['bottom_chains']] bottom_chains = [ chain.tolist() for chain in np.array_split(bottom_chains, n_chains) ] top_chains = [id - 1 for id in groups['top_chains']] top_chains = [ chain.tolist() for chain in np.array_split(top_chains, n_chains) ] traj = md.load(traj_filename, top=top_filename) tilts = [] tilts_err = [] for monolayer in [bottom_chains, top_chains]: monolayer_tilt = [] for i, chain in enumerate(monolayer): chain_slice = traj.atom_slice(chain) directors = _compute_director(chain_slice) monolayer_tilt.append([ _tilt_angle(director, [0.0, 0.0, 1.0]) for director in directors ]) monolayer_tilt = np.asarray(monolayer_tilt) monolayer_tilt = np.transpose(monolayer_tilt) tilts_by_frame = np.mean(monolayer_tilt, axis=1) tilts_err_by_frame = np.std(monolayer_tilt, axis=1) tilts.append(tilts_by_frame) tilts_err.append(tilts_err_by_frame) tilts = np.asarray(tilts) tilts = np.transpose(tilts) np.savetxt(output_filename, np.column_stack((traj.time, tilts)), header='Time\tBottom\tTop')
def test_director(traj2): traj2_line1 = traj2.atom_slice((0, 1)) traj2_line2 = traj2.atom_slice((2, 3)) directors = order._compute_director(traj2_line1) assert eq( directors, np.array([ [1, 0, 0], # Frame 0 [0, 1, 0], # Frame 1 [0, 0, 1], # Frame 2 [1, 0, 0], # Frame 3 [1, 0, 0], # Frame 4 ])) directors = order._compute_director(traj2_line2) assert eq( directors, np.array([ [1, 0, 0], # Frame 0 [0, 1, 0], # Frame 1 [0, 0, 1], # Frame 2 [0, 1, 0], # Frame 3 [0, 0, 1], # Frame 4 ]))
def calc_avg_tilt_angle(traj_filename, top_filename, ndx_filename, output_filename, n_chains, C_only=False): """Calculate the average tilt angle of a monolayer Outputs the average tilt angle at each frame of a trajectory, averaged between the top and bottom monolayers in a dual monolayer system. Output is directed to a file with the filename specified by the user. Parameters ---------- traj_filename : str Name of trajectory file (typically XTC format) top_filename : str Name of topology file (typically GRO format) ndx_filename : str Name of the GROMACS index file to read group information from output_filename : str Name of file to output results to n_chains : int Number of monolayer chains per surface C_only : bool, optional, default=False Only include carbon atoms in the calculation Notes ----- Only valid for single-component monolayers (assumes that all chains in a monolayer contain the same number of atoms). Only valid for systems featuring the same number of chains in each monolayer. To-do ----- Support for multi-component monolayers Support for systems where each monolayer features an arbitrary number of chains """ bottom_chains, top_chains = _gather_chains(top_filename, ndx_filename, n_chains, C_only=C_only) traj = md.load(traj_filename, top=top_filename) tilt_means = [] tilt_errs = [] for monolayer, normal in zip([bottom_chains, top_chains], [[0.0, 0.0, 1.0], [0.0, 0.0, -1.0]]): monolayer_tilt = [] for i, chain in enumerate(monolayer): chain_slice = traj.atom_slice(chain) directors = _compute_director(chain_slice) monolayer_tilt.append( [_tilt_angle(director, normal) for director in directors]) monolayer_tilt = np.transpose(monolayer_tilt) tilt_means.append(np.mean(monolayer_tilt, axis=1)) tilt_errs.append(np.std(monolayer_tilt, axis=1)) tilt_means = np.transpose(tilt_means) tilt_errs = np.transpose(tilt_errs) np.savetxt(output_filename, np.column_stack((traj.time, tilt_means, tilt_errs)), header='Time\tBottom\tTop\tBottom_std\tTop_std')
def calc_OCF(traj_filename, top_filename, output_filetag, ndx_filename, chainlength): """Calculate the orientational correlation function of monolayer chains Parameters ---------- traj_filename : str Name of (unwrapped) trajectory file top_filename : str Name of topology file output_filename : str Name of output file """ topology = md.load(top_filename).topology atoms = np.array(list(topology.atoms)) atom_names = [atom.name for atom in atoms] groups = read_ndx(ndx_filename) bottom_chains = [ id - 1 for id in groups['bottom_chains'] if atom_names[id - 1] == 'C' ] n_chains = int(len(bottom_chains) / chainlength) bottom_chains = [ chain.tolist() for chain in np.array_split(bottom_chains, n_chains) ] top_chains = [ id - 1 for id in groups['top_chains'] if atom_names[id - 1] == 'C' ] top_chains = [ chain.tolist() for chain in np.array_split(top_chains, n_chains) ] traj = md.load(traj_filename, top=top_filename) directors = [] locations = [] for i, chain in enumerate(bottom_chains): chain_slice = traj.atom_slice(chain) chain_director = _compute_director(chain_slice) for director in chain_director: if director[-1] < 0: director *= -1. directors.append(chain_director) com = md.compute_center_of_mass(chain_slice) for com_frame in com: for j in range(2): if com_frame[j] < 0: com_frame[j] += traj.unitcell_lengths[0, j] elif com_frame[j] > traj.unitcell_lengths[0, j]: com_frame[j] -= traj.unitcell_lengths[0, j] locations.append(com) directors = np.array(directors).transpose(1, 0, 2) film_directors = np.mean(directors, axis=1) film_directors /= np.linalg.norm(film_directors, axis=1).reshape(len(film_directors), 1) locations = np.array(locations).transpose(1, 0, 2) com_traj = _create_com_traj(locations, traj.time, traj.unitcell_lengths, traj.unitcell_angles) pairs = com_traj.top.select_pairs('all', 'all') distances = md.compute_distances(com_traj, pairs, periodic=True) cof = [] cof_6 = [] for i, frame in enumerate(directors): frame_angles = np.array( [_angle(film_directors[i], director) for director in frame]) dist_hist = np.histogram(distances[i], bins=np.arange(0.25, 2.5, 0.1)) correlations = np.cos( np.array([ 2. * (frame_angles[pairs[j, 0]] - frame_angles[pairs[j, 1]]) for j, dist in enumerate(distances[i]) ])) correlation_hist = np.histogram(distances[i], bins=np.arange(0.25, 2.5, 0.1), weights=correlations) correlations_6 = np.cos( np.array([ 6. * (frame_angles[pairs[j, 0]] - frame_angles[pairs[j, 1]]) for j, dist in enumerate(distances[i]) ])) correlation_hist_6 = np.histogram(distances[i], bins=np.arange(0.25, 2.5, 0.1), weights=correlations_6) cof.append(correlation_hist[0] / dist_hist[0]) cof_6.append(correlation_hist_6[0] / dist_hist[0]) cof = np.array(cof) cof = np.mean(cof, axis=0) cof_6 = np.array(cof_6) cof_6 = np.mean(cof_6, axis=0) r_vals = np.arange(0.25, 2.5, 0.1) r_vals = np.array([(val + r_vals[i + 1]) / 2 for i, val in enumerate(r_vals[:-1])]) np.savetxt(output_filetag + '2.txt', np.vstack((r_vals, cof))) np.savetxt(output_filetag + '6.txt', np.vstack((r_vals, cof_6)))
def calc_avg_tilt_angle(traj_filename, top_filename, output_filename, ndx_filename, chainlength): """Calculate the average tilt angle of a monolayer Returns the average tilt angle at each frame of a trajectory, averaged between the top and bottom monolayers in a dual monolayer system. Parameters ---------- traj_filename : str Name of trajectory file top_filename : str Name of topology file output_filename : str Name of output file ndx_filename : str Name of Gromacs .ndx file which specifies atom groups chainlength : int Number of carbons per chain """ topology = md.load(top_filename).topology atoms = np.array(list(topology.atoms)) atom_names = [atom.name for atom in atoms] groups = read_ndx(ndx_filename) bottom_chains = [ id - 1 for id in groups['bottom_chains'] if atom_names[id - 1] == 'C' ] n_chains = int(len(bottom_chains) / chainlength) bottom_chains = [ chain.tolist() for chain in np.array_split(bottom_chains, n_chains) ] top_chains = [ id - 1 for id in groups['top_chains'] if atom_names[id - 1] == 'C' ] top_chains = [ chain.tolist() for chain in np.array_split(top_chains, n_chains) ] bottom_chemisorbed = [ id - 1 for id in groups['bottom_chemisorbed'] if atom_names[id - 1] == 'C' ] n_chemisorbed = int(len(bottom_chemisorbed) / chainlength) bottom_chemisorbed = [ chain.tolist() for chain in np.array_split(bottom_chemisorbed, n_chemisorbed) ] top_chemisorbed = [ id - 1 for id in groups['top_chemisorbed'] if atom_names[id - 1] == 'C' ] top_chemisorbed = [ chain.tolist() for chain in np.array_split(top_chemisorbed, n_chemisorbed) ] n_crosslinked = n_chains - n_chemisorbed if n_crosslinked > 0: bottom_crosslinked = [ id - 1 for id in groups['bottom_crosslinked'] if atom_names[id - 1] == 'C' ] bottom_crosslinked = [ chain.tolist() for chain in np.array_split(bottom_crosslinked, n_crosslinked) ] top_crosslinked = [ id - 1 for id in groups['top_crosslinked'] if atom_names[id - 1] == 'C' ] top_crosslinked = [ chain.tolist() for chain in np.array_split(top_crosslinked, n_crosslinked) ] traj = md.load(traj_filename, top=top_filename) if n_crosslinked > 0: tilt_groups = [ bottom_chains, top_chains, bottom_chemisorbed, top_chemisorbed, bottom_crosslinked, top_crosslinked ] else: tilt_groups = [ bottom_chains, top_chains, bottom_chemisorbed, top_chemisorbed ] tilts = [] tilts_err = [] for group in tilt_groups: group_tilt_angles = [] for i, chain in enumerate(group): chain_slice = traj.atom_slice(chain) directors = _compute_director(chain_slice) group_tilt_angles.append([ _tilt_angle(director, [0.0, 0.0, 1.0]) for director in directors ]) group_tilt_angles = np.asarray(group_tilt_angles) group_tilt_angles = np.transpose(group_tilt_angles) tilts_by_frame = np.mean(group_tilt_angles, axis=1) tilts_err_by_frame = np.std(group_tilt_angles, axis=1) tilts.append(tilts_by_frame) tilts_err.append(tilts_err_by_frame) tilts_mean_chains = np.mean([tilts[0], tilts[1]], axis=0) tilts_mean_chemisorbed = np.mean([tilts[2], tilts[3]], axis=0) tilts.insert(2, tilts_mean_chains) tilts.insert(5, tilts_mean_chemisorbed) if n_crosslinked > 0: tilts_mean_crosslinked = np.mean([tilts[6], tilts[7]], axis=0) tilts.append(tilts_mean_crosslinked) tilts = np.asarray(tilts) tilts = np.transpose(tilts) if n_crosslinked > 0: np.savetxt(output_filename, np.column_stack((traj.time, tilts)), header='Time\tBottom\tTop\tAll-mean\tBottom-chemisorbed\t' + 'Top-chemisorbed\tChemisorbed-mean\tBottom-crosslinked\t' + 'Top-crosslinked\tCrosslinked-mean') else: np.savetxt(output_filename, np.column_stack((traj.time, tilts)), header='Time\tBottom\tTop\tAll-mean\tBottom-chemisorbed\t' + 'Top-chemisorbed\tChemisorbed-mean')