예제 #1
0
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
                        ]))
예제 #2
0
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')
예제 #3
0
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
        ]))
예제 #4
0
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')
예제 #5
0
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)))
예제 #6
0
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')