Ejemplo n.º 1
0
def calc_nematic_order(traj_filename, top_filename, output_filename,
                       ndx_filename, n_chains):
    """Calculate the nematic order of both monolayers in a two monolayer system
    Returns the nematic order 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)
    S2_bottom = md.compute_nematic_order(traj, indices=bottom_chains)
    S2_top = md.compute_nematic_order(traj, indices=top_chains)
    np.savetxt(output_filename,
               np.column_stack((traj.time, S2_bottom, S2_top)),
               header='Time\tBottom\tTop')
Ejemplo n.º 2
0
def calc_nematic_order(traj_filename,
                       top_filename,
                       ndx_filename,
                       output_filename,
                       n_chains,
                       C_only=False):
    """Calculate the nematic order of a monolayer

    Outputs the average nematic order at each frame of a trajectory
    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)
    S2_bottom = md.compute_nematic_order(traj, indices=bottom_chains)
    S2_top = md.compute_nematic_order(traj, indices=top_chains)

    np.savetxt(output_filename,
               np.column_stack((traj.time, S2_bottom, S2_top)),
               header='Time\tBottom\tTop')
Ejemplo n.º 3
0
def test_order_from_traj():
    """Made a perfectly aligned monolayer, should have S2 = 1
    """
    traj = md.load(get_fn('alkane-monolayer.pdb'))
    indices = [list(range(1900+x, 1900+x+36)) for x in range(0, 64*36, 36)]
    s2 = md.compute_nematic_order(traj, indices=indices)
    assert_allclose(1.0, s2)
Ejemplo n.º 4
0
def test_order_from_traj(get_fn):
    """Made a perfectly aligned monolayer, should have S2 = 1
    """
    traj = md.load(get_fn('alkane-monolayer.pdb'))
    indices = [
        list(range(1900 + x, 1900 + x + 36)) for x in range(0, 64 * 36, 36)
    ]
    s2 = md.compute_nematic_order(traj, indices=indices)
    np.testing.assert_allclose(1.0, s2)
Ejemplo n.º 5
0
def calc_nematic_order(traj, lipid_dict):
    """Compute nematic order parameter
    
    Parameters
    ----------
    traj : mdTraj traj()
    
    lipid_dict : dict()
        dictionary apping residue indices to associated atom indices

    Returns
    -------
    s2_ave : float
        Average S2 over all frames
    s2_std : 
        S2 standard dviation
    s2_list :
        Frame by frame list of S2 values

    Notes
    -----
    Assumes 64 residues per leaflet
        """
    top_chains = []
    bot_chains = []
    for i, key in enumerate(lipid_dict.keys()):
        indices = [int(item) for item in lipid_dict[key]]
        if i <= 63:
            top_chains.append(indices)
        else:
            bot_chains.append(indices)
    s2_top = mdtraj.compute_nematic_order(traj, indices=top_chains)
    s2_bot = mdtraj.compute_nematic_order(traj, indices=bot_chains)
    s2_list = (s2_top + s2_bot) / 2
    #s2_blocks = s2_list[:-1].reshape(int((traj.n_frames-1)/250),250)
    #s2_block_avgs = np.mean(s2_blocks, axis = 1)
    s2_block_avgs = np.mean(s2_list)
    s2_ave = np.mean(s2_block_avgs)
    #s2_std = np.std(s2_block_avgs)
    s2_std = np.std(s2_list)
    return s2_ave, s2_std, s2_list
Ejemplo n.º 6
0
def calc_moving_s2(traj, tail_groups, selected_keys, window_size=3):
    """ Compute S2 over a moving window so you can look at different segments

    Parameters
    ----------
    traj : MDTraj trajectory
    tail_groups : dict
        Keys: residue IDs
        Values: atom indices 
    selected_keys: list
        residue IDs so we can pick out specific residue chains
    window_size: int, default 3
        number of consecutive carbons to look at for S2

    Returns
    -------
    all_s2: array, traj.n_frames x n_carbons - window_size
        Each row is the nematic order for a frame
        Each column is the nematic order for that selection of chains.
            i.e. column 0 looks at the S2 for carbon[0,window_size)
    """
    n_carbons = len([
        a for a in tail_groups[selected_keys[0]]
        if 'H' != traj.topology.atom(a).name[0]
    ])
    all_s2 = np.zeros((traj.n_frames, n_carbons - 3))
    for i, carbon_start in enumerate(range(n_carbons - 3)):
        tail_no_h = {
            key: [
                int(a) for a in tail_groups[key]
                if 'H' != traj.topology.atom(a).name[0]
            ]
            for key in tail_groups.keys()
        }
        sub_tails = [
            tail_no_h[key][carbon_start:carbon_start + 3]
            for key in selected_keys
        ]
        all_s2[:, i] = mdtraj.compute_nematic_order(traj, indices=sub_tails)
    return all_s2
Ejemplo n.º 7
0
def calc_nematic_order(traj_filename, top_filename, output_filename,
                       ndx_filename, chainlength):
    """Calculate the nematic order of a monolayer

    Returns the average nematic order at each frame of a trajectory
    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)
    S2_bottom = md.compute_nematic_order(traj, indices=bottom_chains)
    S2_top = md.compute_nematic_order(traj, indices=top_chains)
    S2_bottom_chemisorbed = md.compute_nematic_order(
        traj, indices=bottom_chemisorbed)
    S2_top_chemisorbed = md.compute_nematic_order(traj,
                                                  indices=top_chemisorbed)
    if n_crosslinked > 0:
        S2_bottom_crosslinked = md.compute_nematic_order(
            traj, indices=bottom_crosslinked)
        S2_top_crosslinked = md.compute_nematic_order(traj,
                                                      indices=top_crosslinked)
        S2_mean_crosslinked = np.mean(
            [S2_bottom_crosslinked, S2_top_crosslinked], axis=0)

    S2_mean_chains = np.mean([S2_bottom, S2_top], axis=0)
    S2_mean_chemisorbed = np.mean([S2_bottom_chemisorbed, S2_top_chemisorbed],
                                  axis=0)

    if n_crosslinked > 0:
        np.savetxt(output_filename,
                   np.column_stack(
                       (traj.time, S2_bottom, S2_top, S2_mean_chains,
                        S2_bottom_chemisorbed, S2_top_chemisorbed,
                        S2_mean_chemisorbed, S2_bottom_crosslinked,
                        S2_top_crosslinked, S2_mean_crosslinked)),
                   header='Time\tBottom\tTop\tAll-mean\t' +
                   'Bottom-chemisorbed\tTop-chemisorbed\tChemisorbed-mean\t' +
                   'Bottom-crosslinked\tTop-crosslinked\tCrosslinked-mean')
    else:
        np.savetxt(output_filename,
                   np.column_stack((traj.time, S2_bottom, S2_top,
                                    S2_mean_chains, S2_bottom_chemisorbed,
                                    S2_top_chemisorbed, S2_mean_chemisorbed)),
                   header='Time\tBottom\tTop\tAll-mean\t' +
                   'Bottom-chemisorbed\tTop-chemisorbed\tChemisorbed-mean')
Ejemplo n.º 8
0
    toss = 1000 / dt  # 1 ns
    traj = traj[toss:]

    # Nematic order parameter
    atoms_per_chain = (traj.n_atoms // 2 - 1800 -
                       hydrogens_per_surface) // n_chains_per_surface
    bot_chain_indices = [[
        n + x for x in range(atoms_per_chain)
    ] for n in range(1800, traj.n_atoms // 2 -
                     hydrogens_per_surface, atoms_per_chain)]
    top_chain_indices = [[
        n + x for x in range(atoms_per_chain)
    ] for n in range(traj.n_atoms // 2 + 1800, traj.n_atoms -
                     hydrogens_per_surface, atoms_per_chain)]

    bot_s2 = md.compute_nematic_order(traj, indices=bot_chain_indices)
    top_s2 = md.compute_nematic_order(traj, indices=top_chain_indices)

    plt.plot(traj.time / 1000, bot_s2, alpha=0.5, lw=0.5, label='bot')
    plt.plot(traj.time / 1000, top_s2, alpha=0.5, lw=0.5, label='top')
    plt.ylim(0, 1)
    plt.xlabel('time (ns)')
    plt.ylabel('S2')
    plt.legend()

    plt.savefig('{}.png'.format(name), bbox_inches='tight')
    plt.clf()

    S2[name]['top'] = np.mean(top_s2)
    S2[name]['top_std'] = np.std(top_s2)
    S2[name]['bot'] = np.mean(bot_s2)