コード例 #1
0
def compute_files(cg_xyz, cg_top, t, molecule_name, element_names):
    # Create Trajectory object and save to .dcd file
    cg_traj = md.Trajectory(cg_xyz,
                            cg_top,
                            time=None,
                            unitcell_lengths=t.unitcell_lengths,
                            unitcell_angles=t.unitcell_angles)
    ## need better file naming convention and rule guideline
    cg_traj.save_dcd('cg_traj_{0:s}.dcd'.format(
        molecule_name))  ## need check statements to prevent file overwrite
    ## rename old/new files accordingly

    # Create rdfs file from pairs
    ## might need for loop if more elements (later implementation)
    ## need some way to recognize pairs of units - not just carbon elements if expanded
    pairs = cg_traj.top.select_pairs(
        selection1='name {0:s}'.format(element_names[0]),  ## Check element
        selection2='name {0:s}'.format(element_names[0]))  ## Check element
    r, g_r = md.compute_rdf(cg_traj,
                            pairs=pairs,
                            r_range=(0, 1.2),
                            bin_width=0.005)
    ## identify end of range with data pairs
    ## maybe something with read-file function - compare data values next to each other
    ## See where data drop-off occurs and plot respectively
    ## maybe use slope - negative less than some number, set as cutoff
    ## record cutoff point somewhere for debugging purposes
    np.savetxt('rdfs_aa.txt', np.transpose(
        [r, g_r]))  # need check statements to prevent file overwrite

    plot_output(r, g_r, molecule_name)
コード例 #2
0
def test_rdf_periodic():
    """ Test if the periodic argument gives the correct results"""
    test_file = TEST_FILE
    stack = load_structure(test_file)

    # calculate oxygen RDF for water
    oxygen = stack[:, stack.atom_name == 'OW']
    interval = np.array([0, 10])
    n_bins = 100
    bins, g_r = rdf(oxygen[:, 0].coord,
                    oxygen[:, 1:],
                    interval=interval,
                    bins=n_bins,
                    periodic=True)

    # Compare with MDTraj
    import mdtraj
    traj = mdtraj.load(TEST_FILE)
    ow = [a.index for a in traj.topology.atoms if a.name == 'O']
    pairs = itertools.product([ow[0]], ow[1:])
    mdt_bins, mdt_g_r = mdtraj.compute_rdf(traj,
                                           list(pairs),
                                           r_range=interval / 10,
                                           n_bins=n_bins,
                                           periodic=True)

    assert np.allclose(bins, mdt_bins * 10)
    assert np.allclose(g_r, mdt_g_r, rtol=0.0001)
コード例 #3
0
ファイル: pair.py プロジェクト: mattwthompson/msibi
    def compute_current_rdf(self, state, r_range, n_bins, smooth=True,
                            max_frames=1e3):
        """ """
        pairs = self.states[state]['pair_indices']
        # TODO: More elegant way to handle units.
        #       See https://github.com/ctk3b/msibi/issues/2
        g_r_all = None
        first_frame = 0
        max_frames = int(max_frames)
        for last_frame in range(max_frames,
                                state.traj.n_frames + max_frames,
                                max_frames):
            r, g_r = md.compute_rdf(state.traj[first_frame:last_frame],
                                    pairs, r_range= r_range, n_bins=n_bins)
            if g_r_all is None:
                g_r_all = np.zeros_like(g_r)
            g_r_all += g_r * len(state.traj[first_frame:last_frame]) / state.traj.n_frames
            first_frame = last_frame
        #r *= 10.0

        rdf = np.vstack((r, g_r)).T
        self.states[state]['current_rdf'] = rdf

        if smooth:
            current_rdf = self.states[state]['current_rdf']
            current_rdf[:, 1] = savitzky_golay(current_rdf[:, 1], 9, 2, deriv=0, rate=1)
            for row in current_rdf:
                row[1] = np.maximum(row[1], 0)

        # Compute fitness function comparing the two RDFs.
        f_fit = calc_similarity(rdf[:, 1], self.states[state]['target_rdf'][:, 1])
        self.states[state]['f_fit'].append(f_fit)
コード例 #4
0
def test_rdf():
    """ General test to reproduce oxygen RDF for a box of water"""
    test_file = TEST_FILE
    stack = load_structure(test_file)

    # calculate oxygen RDF for water
    oxygen = stack[:, stack.atom_name == 'OW']
    interval = np.array([0, 10])
    n_bins = 100
    bins, g_r = rdf(oxygen[:, 0].coord,
                    oxygen,
                    interval=interval,
                    bins=n_bins,
                    periodic=False)

    # Compare with MDTraj
    import mdtraj
    traj = mdtraj.load(TEST_FILE)
    ow = [a.index for a in traj.topology.atoms if a.name == 'O']
    pairs = itertools.product([ow[0]], ow)
    mdt_bins, mdt_g_r = mdtraj.compute_rdf(traj,
                                           list(pairs),
                                           r_range=interval / 10,
                                           n_bins=n_bins,
                                           periodic=False)

    assert np.allclose(bins, mdt_bins * 10)
    assert np.allclose(g_r, mdt_g_r, rtol=0.0001)
コード例 #5
0
def compute_rdf_from_partial(trj, r_range=None):
    compositions = dict()
    form_factors = dict()
    rdfs = dict()

    L = np.min(trj.unitcell_lengths)
    top = trj.topology
    elements = set([a.element for a in top.atoms])

    denom = 0
    for elem in elements:
        compositions[elem.symbol] = len(top.select('element {}'.format(elem.symbol)))/trj.n_atoms
        form_factors[elem.symbol] = elem.atomic_number
        denom += compositions[elem.symbol] * form_factors[elem.symbol]
    for i, (elem1, elem2) in enumerate(it.product(elements, repeat=2)):
        e1 = elem1.symbol
        e2 = elem2.symbol

        x_a = compositions[e1]
        x_b = compositions[e2]

        f_a = form_factors[e1]
        f_b = form_factors[e2]
        
        try:
            g_r = rdfs['{0}{1}'.format(e1, e2)]
        except KeyError:
            pairs = top.select_pairs(selection1='element {}'.format(e1),
                                     selection2='element {}'.format(e2))
            if r_range == None:
                r, g_r = md.compute_rdf(trj,
                                        pairs=pairs,
                                        r_range=(0, L / 2))
            else:
                r, g_r = md.compute_rdf(trj,
                                        pairs=pairs,
                                        r_range=r_range)
            rdfs['{0}{1}'.format(e1, e2)] = g_r
        if i == 0:
            total = g_r * (x_a*x_b*f_a*f_b) / denom**2
        else: 
            total += g_r * (x_a*x_b*f_a*f_b) / denom**2

    return r, total
コード例 #6
0
def compute_files(cg_xyz, cg_top, t, molecule_name, element_names):
    """Compute the trajectory and rdf files

    Parameters
    ----------
    cg_xyz : ?????
        Coarse-grained xyz coordinates of all the beads
    cg_top : mdTraj.Topology
        Coarse-grained topology object for all the beads
    t : mdTraj.Trajectory (???? unsure if needed)
        Initial trajectory object generated from structure and trajectory files
    molecule_name : str
        Name of the molecule(s) in the system
    element_names : (???)
        (???)

    """

    # Create Trajectory object and save to .dcd file
    cg_traj = md.Trajectory(cg_xyz,
                            cg_top,
                            time=None,
                            unitcell_lengths=t.unitcell_lengths,
                            unitcell_angles=t.unitcell_angles)
    ## need better file naming convention and rule guideline
    filepath = os.path.join(os.getcwd(),
                            'data/cg_traj_{0:s}.dcd'.format(molecule_name))
    cg_traj.save_dcd(
        filepath)  ## need check statements to prevent file overwrite
    ## rename old/new files accordingly

    # Create rdfs file from pairs
    ## might need for loop if more elements (later implementation)
    ## need some way to recognize pairs of units - not just carbon elements if expanded
    pairs = cg_traj.top.select_pairs(
        selection1='name {0:s}'.format(element_names[0]),  ## Check element
        selection2='name {0:s}'.format(element_names[0]))  ## Check element
    r, g_r = md.compute_rdf(cg_traj,
                            pairs=pairs,
                            r_range=(0, 1.2),
                            bin_width=0.005)
    ## identify end of range with data pairs
    ## maybe something with read-file function - compare data values next to each other
    ## See where data drop-off occurs and plot respectively
    ## maybe use slope - negative less than some number, set as cutoff
    ## record cutoff point somewhere for debugging purposes
    filepath = os.path.join(os.getcwd(), 'data/rdfs_aa.txt')
    np.savetxt(filepath, np.transpose(
        [r, g_r]))  # need check statements to prevent file overwrite
    print("Saved rdfs to file")
    plot_output(r, g_r, molecule_name)
コード例 #7
0
ファイル: pair.py プロジェクト: cmelab/msibi
    def compute_current_rdf(self,
                            state,
                            r_range,
                            n_bins,
                            smooth=True,
                            max_frames=50,
                            verbose=False):
        """ """
        pairs = self.states[state]["pair_indices"]
        # TODO: More elegant way to handle units.
        #       See https://github.com/ctk3b/msibi/issues/2
        g_r_all = None
        first_frame = 0
        max_frames = int(max_frames)
        for last_frame in range(max_frames, state.traj.n_frames + max_frames,
                                max_frames):
            r, g_r = md.compute_rdf(
                state.traj[first_frame:last_frame],
                pairs,
                r_range=r_range / 10,
                n_bins=n_bins,
            )
            if g_r_all is None:
                g_r_all = np.zeros_like(g_r)
            g_r_all += (g_r * len(state.traj[first_frame:last_frame]) /
                        state.traj.n_frames)
            first_frame = last_frame
        r *= 10
        rdf = np.vstack((r, g_r_all)).T
        self.states[state]["current_rdf"] = rdf

        if smooth:
            current_rdf = self.states[state]["current_rdf"]
            current_rdf[:, 1] = savitzky_golay(current_rdf[:, 1],
                                               9,
                                               2,
                                               deriv=0,
                                               rate=1)
            for row in current_rdf:
                row[1] = np.maximum(row[1], 0)
            if verbose:  # pragma: no cover
                plt.title(f"RDF smoothing for {state.name}")
                plt.plot(r, g_r, label="unsmoothed")
                plt.plot(r, current_rdf[:, 1], label="smoothed")
                plt.legend()
                plt.show()

        # Compute fitness function comparing the two RDFs.
        f_fit = calc_similarity(rdf[:, 1], self.states[state]["target_rdf"][:,
                                                                            1])
        self.states[state]["f_fit"].append(f_fit)
コード例 #8
0
ファイル: utils.py プロジェクト: mattwthompson/scattering
def rdf_by_frame(trj, **kwargs):
    """Helper function that computes rdf frame-wise and returns the average
    rdf over all frames. Can be useful for large systems in which a
    distance array of size n_frames * n_atoms (used internally in
    md.compute_rdf) takes requires too much memory.
    """
    g_r = None
    for frame in trj:
        r, g_r_frame = md.compute_rdf(frame, **kwargs) 
        if g_r is None:
            g_r = np.zeros_like(g_r_frame)
        g_r += g_r_frame
    g_r /= len(trj)
    return r, g_r
コード例 #9
0
ファイル: test_rdf.py プロジェクト: sroet/mdtraj
def test_compare_rdf_t_at_0(get_fn, periodic, opt):
    # Compute g(r, t) at t = 0 and compare to g(r)
    frames = 2
    traj = md.load(get_fn('tip3p_300K_1ATM.xtc'), top=get_fn('tip3p_300K_1ATM.pdb'))
    pairs = traj.top.select_pairs('name O', 'name O')
    times = list()
    for j in range(frames):
        times.append([j, j])

    r_t, g_r_t = md.compute_rdf_t(traj, pairs, times, self_correlation=False, periodic=periodic, opt=opt)
    mean_g_r_t = np.mean(g_r_t, axis=0)
    r, g_r = md.compute_rdf(traj[:frames], pairs, periodic=periodic, opt=periodic)

    assert eq(r_t, r)
    assert eq(mean_g_r_t, g_r, decimal=1)
コード例 #10
0
ファイル: pair.py プロジェクト: chloeoframe/msibi
    def compute_current_rdf(self,
                            state,
                            r_range,
                            n_bins,
                            smooth=True,
                            max_frames=1e3):
        """ """
        pairs = self.states[state]['pair_indices']
        # TODO: More elegant way to handle units.
        #       See https://github.com/ctk3b/msibi/issues/2
        g_r_all = None
        first_frame = 0
        max_frames = int(max_frames)
        for last_frame in range(max_frames, state.traj.n_frames + max_frames,
                                max_frames):
            r, g_r = md.compute_rdf(state.traj[first_frame:last_frame],
                                    pairs,
                                    r_range=r_range / 10,
                                    n_bins=n_bins)
            if g_r_all is None:
                g_r_all = np.zeros_like(g_r)
            g_r_all += g_r * len(
                state.traj[first_frame:last_frame]) / state.traj.n_frames
            first_frame = last_frame
        r *= 10
        rdf = np.vstack((r, g_r_all)).T
        self.states[state]['current_rdf'] = rdf

        if smooth:
            current_rdf = self.states[state]['current_rdf']
            current_rdf[:, 1] = savitzky_golay(current_rdf[:, 1],
                                               9,
                                               2,
                                               deriv=0,
                                               rate=1)
            for row in current_rdf:
                row[1] = np.maximum(row[1], 0)

        # Compute fitness function comparing the two RDFs.
        f_fit = calc_similarity(rdf[:, 1], self.states[state]['target_rdf'][:,
                                                                            1])
        self.states[state]['f_fit'].append(f_fit)
コード例 #11
0
def run_rdf(job):
    print('Loading trj {}'.format(job))
    if os.path.exists(os.path.join(job.workspace(), 'com.gro')):
        top_file = os.path.join(job.workspace(), 'com.gro')
        trj_file = os.path.join(job.workspace(), 'sample_com.xtc')
        trj = md.load(trj_file, top=top_file, stride=10)

        selections = dict()
        selections['cation'] = trj.topology.select('name li')
        selections['anion'] = trj.topology.select('resname {}'.format(job.statepoint()['anion']))
        selections['acn'] = trj.topology.select('resname ch3cn')
        selections['chlor'] = trj.topology.select('resname chlor')
        selections['all'] = trj.topology.select('all')

        combos = [('cation', 'anion'),
                  ('cation','cation'),
                  ('anion','anion'),
                  ('acn','anion'),
                  ('acn','cation'),
                  ('chlor','anion'),
                  ('chlor','cation'),
                  ('acn', 'chlor')]
        for combo in combos:
            fig, ax = plt.subplots()
            print('running rdf between {0} ({1}) and\t{2} ({3})\t...'.format(combo[0],
                                                                             len(selections[combo[0]]),
                                                                             combo[1],
                                                                             len(selections[combo[1]])))
            r, g_r = md.compute_rdf(trj, pairs=trj.topology.select_pairs(selections[combo[0]], selections[combo[1]]), r_range=((0.0, 2.0)))

            data = np.vstack([r, g_r])
            np.savetxt('txt_files/{}-{}-{}-rdf-{}-{}.txt'.format(job.sp.chlor_conc,
                    job.sp.acn_conc, job.sp.il_conc, combo[0], combo[1]),
                np.transpose(np.vstack([r, g_r])),
                header='# r (nm)\tg(r)')
            ax.plot(r, g_r)
            plt.xlabel('r (nm)')
            plt.ylabel('G(r)')
            plt.savefig(os.path.join(job.workspace(),
                   f'rdf-{combo[0]}-{combo[1]}.pdf'))
            print(' ... done\n')
コード例 #12
0
ファイル: cg_utils.py プロジェクト: ahy3nz/cg_mapping
    def compute_rdf(self, atomtype_i, atomtype_j, output, 
            bin_width=0.01, exclude_up_to=3, r_range=[0,2]):
        """
        Compute RDF between pair of atoms, save to text
    
        Parameters
        ---------
        atomtype_i : str
            First atomtype 
        atomtype_j : str
            Second atomtype
        output : str
            Filename
        exclude_up_to : int
            Exclude up to this many bonded terms for RDF calculation
            i.e., exclude_up_to=2 means 1-2 and 1-3 bonds are excluded from RDF

        Notes
        -----
        Be VERY aware of the exclusion terms for computing RDFs
    
            """
    
        """ Mine
        pairs = traj.topology.select_pairs(selection1='name {}'.format(atomtype_i),
                selection2='name {}'.format(atomtype_j))
        (first, second) = mdtraj.compute_rdf(traj, pairs, [0, 2], bin_width=0.01 )
        np.savetxt('{}.txt'.format(output), np.column_stack([first,second]))
        """


        pairs = self.traj.topology.select_pairs("name '{0}'".format(atomtype_i),
                                 "name '{0}'".format(atomtype_j))
        if exclude_up_to is not None:
            to_delete = find_1_n_exclusions(self.traj.topology, pairs, exclude_up_to)
            pairs = np.delete(pairs, to_delete, axis=0)
        (first, second) = mdtraj.compute_rdf(self.traj, pairs, r_range=r_range, bin_width=bin_width)
        np.savetxt('{}.txt'.format(output), np.column_stack([first,second]))
コード例 #13
0
ファイル: project.py プロジェクト: rmatsum836/signac-projects
def run_rdf(job):
    print('Loading trj {}'.format(job))
    if os.path.exists(os.path.join(job.workspace(), 'com.gro')):
        top_file = os.path.join(job.workspace(), 'com.gro')
        trj_file = os.path.join(job.workspace(), 'sample_com.xtc')
        trj = md.load(trj_file, top=top_file, stride=10)

        selections = dict()
        selections['cation'] = trj.topology.select('name {}'.format(job.statepoint()['cation']))
        selections['anion'] = trj.topology.select('name {}'.format(job.statepoint()['anion']))
        selections['ion'] = trj.topology.select('name {0} {1}'.format(job.statepoint()['cation'],
                                                                                job.statepoint()['anion']))
        selections['solvent'] = trj.topology.select('not name {0} {1}'.format(job.statepoint()['cation'],
                                                                              job.statepoint()['anion']))
        selections['all'] = trj.topology.select('all')

        combos = [('ion', 'ion'),
                  ('cation', 'anion'),
                  ('cation','cation'),
                  ('anion','anion'),
                  ('solvent','anion'),
                  ('solvent','cation'),
                  ('solvent', 'solvent')]
        for combo in combos:

            print('running rdf between {0} ({1}) and\t{2} ({3})\t...'.format(combo[0],
                                                                             len(selections[combo[0]]),
                                                                             combo[1],
                                                                             len(selections[combo[1]])))
            r, g_r = md.compute_rdf(trj, pairs=trj.topology.select_pairs(selections[combo[0]], selections[combo[1]]), r_range=((0.0, 2.0)))

            data = np.vstack([r, g_r])
            np.savetxt(os.path.join(job.workspace(),
                    'rdf-{}-{}.txt'.format(combo[0], combo[1])),
                np.transpose(np.vstack([r, g_r])),
                header='# r (nm)\tg(r)')
            print(' ... done\n')
コード例 #14
0
ファイル: rdf.py プロジェクト: mattwthompson/lammps-scripts
#uses mdtraj to calculate rdf
#only handles one frome, .pdb is a dummy file made with vmd from trj
import mdtraj as md
import numpy as np

traj = md.load('freeze.lammpstrj', top = 'freeze.pdb')
r, gofr = md.compute_rdf(traj)

np.savetxt('rdf-mdtraj.txt', np.hstack((r, gofr)))
コード例 #15
0
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Sun Feb 24 13:03:28 2019

@author: simon
"""

import matplotlib.pyplot as plt
import mdtraj as md

t = md.load_xyz('within.xyz', top='within.xyz')
md.compute_rdf("within.xyz")
コード例 #16
0
def structure_factor(
    trj,
    Q_range=(0.5, 50),
    n_points=1000,
    framewise_rdf=False,
    weighting_factor="fz",
    form="atomic",
):
    """Compute the structure factor through a fourier transform of
    the radial distribution function.

    The consdered trajectory must include valid elements.

    The computed structure factor is only valid for certain values of Q. The
    lowest value of Q that can sufficiently be described by a box of
    characteristic length `L` is `2 * pi / (L / 2)`.

    Parameters
    ----------
    trj : mdtraj.Trajectory
        A trajectory for which the structure factor is to be computed.
    Q_range : list or np.ndarray, default=(0.5, 50)
        Minimum and maximum Values of the scattering vector, in `1/nm`, to be
        consdered.
    n_points : int, default=1000
    framewise_rdf : boolean, default=False
        If True, computes the rdf frame-by-frame. This can be useful for
        managing memory in large systems.
    weighting_factor : string, optional, default='fz'
        Weighting factor for calculating the structure-factor, default is Faber-Ziman.
        See https://openscholarship.wustl.edu/etd/1358/ and http://isaacs.sourceforge.net/manual/page26_mn.html for details.
    form : string, optional, default='atomic'
        Method for determining form factors. If default, form factors are estimated from
        atomic numbers.  If 'cromer-mann', form factors are determined from Cromer-Mann
        tables.

    Returns
    -------
    Q : np.ndarray
        The values of the scattering vector, in `1/nm`, that was considered.
    S : np.ndarray
        The structure factor of the trajectory

    """
    if weighting_factor not in ["fz", "al"]:
        raise ValueError(
            "Invalid weighting_factor `{}` is given."
            "  The only weighting_factor currently supported is `fz`, and `al`."
            .format(weighting_factor))

    rho = np.mean(trj.n_atoms / trj.unitcell_volumes)
    L = np.min(trj.unitcell_lengths)

    top = trj.topology
    elements = set([a.element for a in top.atoms])

    compositions = dict()
    rdfs = dict()

    Q = np.logspace(np.log10(Q_range[0]), np.log10(Q_range[1]), num=n_points)
    S = np.zeros(shape=(len(Q)))

    for elem in elements:
        compositions[elem.symbol] = (
            len(top.select("element {}".format(elem.symbol))) / trj.n_atoms)

    for i, q in enumerate(Q):
        num = 0
        denom = 0

        for elem in elements:
            denom += _get_normalize(method=weighting_factor,
                                    c=compositions[elem.symbol],
                                    f=get_form_factor(elem.symbol,
                                                      q=q / 10,
                                                      method=form))

        for (elem1, elem2) in it.product(elements, repeat=2):
            e1 = elem1.symbol
            e2 = elem2.symbol

            f_a = get_form_factor(e1, q=q / 10, method=form)
            f_b = get_form_factor(e2, q=q / 10, method=form)

            x_a = compositions[e1]
            x_b = compositions[e2]

            try:
                g_r = rdfs["{0}{1}".format(e1, e2)]
            except KeyError:
                pairs = top.select_pairs(
                    selection1="element {}".format(e1),
                    selection2="element {}".format(e2),
                )
                if framewise_rdf:
                    r, g_r = rdf_by_frame(trj,
                                          pairs=pairs,
                                          r_range=(0, L / 2),
                                          bin_width=0.001)
                else:
                    r, g_r = md.compute_rdf(trj,
                                            pairs=pairs,
                                            r_range=(0, L / 2),
                                            bin_width=0.001)
                rdfs["{0}{1}".format(e1, e2)] = g_r
            integral = simps(r**2 * (g_r - 1) * np.sin(q * r) / (q * r), r)

            coefficient = x_a * x_b * f_a * f_b
            pre_factor = 4 * np.pi * rho

            partial_sq = (integral * pre_factor)
            num += coefficient * (partial_sq)

        if weighting_factor == "fz":
            denom = denom**2

        S[i] = num / denom
    return Q, S
コード例 #17
0
def structure_factor_pair_test(trj_full, trj_sep, pair, Q_range=(0.5, 50), n_points=1000, framewise_rdf=False, method='fz'):
"""
  trj_full is the trajectory with only IL, and trj_sep renamed the atoms in cation (using name of atom + 'ca') and renamed the
  atoms in anion (using name of atom + 'an').
  
"""     
    rho = np.mean(trj_full.n_atoms / trj_full.unitcell_volumes)
    L = np.min(trj_full.unitcell_lengths)

    top_full = trj_full.topology
    top_sep = trj_sep.topology
    
    elements_i = set()
    elements_j = set()
    
    for a in top_sep.atoms:
        string = a.element.symbol
        if string[-2:] == pair[0]:
            elements_i.add((a.element))
        if string[-2:] == pair[1]:  
            elements_j.add((a.element))

    Number_scale = dict()
    
    elements = set([a.element for a in top_full.atoms])

    compositions = dict()
    form_factors = dict()
    rdfs = dict()

    Q = np.logspace(np.log10(Q_range[0]),
                    np.log10(Q_range[1]),
                    num=n_points)
    S = np.zeros(shape=(len(Q)))

    for elem in elements:
        compositions[elem.symbol] = len(top_full.select('element {}'.format(elem.symbol)))/trj_full.n_atoms
        form_factors[elem.symbol] = elem.atomic_number
    

    for i, q in enumerate(Q):
        num = 0
        denom = 0

        for elem in elements:
            denom += compositions[elem.symbol] * form_factors[elem.symbol]

        for (elem1, elem2) in it.product(elements, repeat=2):
            e1 = elem1.symbol
            e2 = elem2.symbol
            
            atomtype1 = e1[0]
            atomtype2 = e2[0]

            f_a = form_factors[e1]
            f_b = form_factors[e2]

            x_a = compositions[e1]
            x_b = compositions[e2]
            
            length_1 = len(top_sep.select('element {}'.format(e1 + pair[0])))
            length_2 = len(top_sep.select('element {}'.format(e2 + pair[1])))

            
            if (length_1 == 0) or (length_2 == 0):
                integral = 0

            else:
                try:
                    g_r = rdfs['{0}{1}'.format(e1, e2)]
                    scale = Number_scale['{0}{1}'.format(e1, e2)]
                except KeyError:
                    pairs = top_sep.select_pairs(selection1='element {}'.format(e1 + pair[0]),
                                             selection2='element {}'.format(e2 + pair[1]))
                    if framewise_rdf:
                        r, g_r = rdf_by_frame(trj_sep,
                                             pairs=pairs,
                                             r_range=(0, L / 2),
                                             bin_width=0.001)
                    else:
                        r, g_r = md.compute_rdf(trj_sep,
                                                pairs=pairs,
                                                r_range=(0, L / 2),
                                                bin_width=0.001)
                    rdfs['{0}{1}'.format(e1, e2)] = g_r

                    N_i = len(top_full.select('element {}'.format(e1)))
                    N_j = len(top_full.select('element {}'.format(e2)))

                    N_i_1 = len(top_sep.select('element {}'.format(e1+ pair[0])))
                    N_i_2 = len(top_sep.select('element {}'.format(e2+ pair[1])))

                    scale = N_i_1 *  N_i_2 / (N_i * N_j)
                    Number_scale['{0}{1}'.format(e1, e2)] = scale

                integral = simps(r ** 2 * (g_r - g_r[-1]) * np.sin(q * r) / (q * r), r) * scale
#                 print(integral)

            if method == 'al':
                pre_factor = np.sqrt(x_a * x_b) * 4 * np.pi * rho
                partial_sq = (integral*pre_factor) 
                num += (f_a*f_b) * (partial_sq+1) * np.sqrt(x_a*x_b)
            elif method == 'fz':
                pre_factor = 4 * np.pi * rho
                partial_sq = (integral*pre_factor) 
                num += (x_a*f_a*x_b*f_b) * (partial_sq)
        S[i] = (num/(denom**2))
    return Q, S
コード例 #18
0
def structure_factor(trj, Q_range=(0.5, 50), n_points=1000, framewise_rdf=False, method='fz'):
    """Compute the structure factor.

    The consdered trajectory must include valid elements.

    The computed structure factor is only valid for certain values of Q. The
    lowest value of Q that can sufficiently be described by a box of
    characteristic length `L` is `2 * pi / (L / 2)`.

    Parameters
    ----------
    trj : mdtraj.Trajectory
        A trajectory for which the structure factor is to be computed.
    Q_range : list or np.ndarray, default=(0.5, 50)
        Minimum and maximum Values of the scattering vector, in `1/nm`, to be
        consdered.
    n_points : int, default=1000
    framewise_rdf : boolean, default=False
        If True, computes the rdf frame-by-frame. This can be useful for
        managing memory in large systems.
    method : string, optional, default='fz'
        Formalism for calculating the structure-factor, default is Faber-Ziman.
        Other option is the Faber-Ziman formalism.  See https://openscholarship.wustl.edu/etd/1358/ and http://isaacs.sourceforge.net/manual/page26_mn.html for details.

    Returns
    -------
    Q : np.ndarray
        The values of the scattering vector, in `1/nm`, that was considered.
    S : np.ndarray
        The structure factor of the trajectory

    """
    rho = np.mean(trj.n_atoms / trj.unitcell_volumes)
    L = np.min(trj.unitcell_lengths)

    top = trj.topology
    elements = set([a.element for a in top.atoms])

    compositions = dict()
    form_factors = dict()
    rdfs = dict()

    Q = np.logspace(np.log10(Q_range[0]),
                    np.log10(Q_range[1]),
                    num=n_points)
    S = np.zeros(shape=(len(Q)))

    for elem in elements:
        compositions[elem.symbol] = len(top.select('element {}'.format(elem.symbol)))/trj.n_atoms
        form_factors[elem.symbol] = elem.atomic_number

    for i, q in enumerate(Q):
        num = 0
        denom = 0

        for elem in elements:
            denom += compositions[elem.symbol] * form_factors[elem.symbol]

        for (elem1, elem2) in it.product(elements, repeat=2):
            e1 = elem1.symbol
            e2 = elem2.symbol

            f_a = form_factors[e1]
            f_b = form_factors[e2]

            x_a = compositions[e1]
            x_b = compositions[e2]
            
            try:
                g_r = rdfs['{0}{1}'.format(e1, e2)]
            except KeyError:
                pairs = top.select_pairs(selection1='element {}'.format(e1),
                                         selection2='element {}'.format(e2))
                if framewise_rdf:
                    r, g_r = rdf_by_frame(trj,
                                         pairs=pairs,
                                         r_range=(0, L / 2),
                                         bin_width=0.001)
                else:
                    r, g_r = md.compute_rdf(trj,
                                            pairs=pairs,
                                            r_range=(0, L / 2),
                                            bin_width=0.001)
                rdfs['{0}{1}'.format(e1, e2)] = g_r
            integral = simps(r ** 2 * (g_r - 1) * np.sin(q * r) / (q * r), r)

            if method == 'al':
                pre_factor = np.sqrt(x_a * x_b) * 4 * np.pi * rho
                partial_sq = (integral*pre_factor) + int(e1==e2)
                num += (f_a*f_b) * (partial_sq+1) * np.sqrt(x_a*x_b)
            elif method == 'fz':
                pre_factor = 4 * np.pi * rho
                partial_sq = (integral*pre_factor) + 1
                num += (x_a*f_a*x_b*f_b) * (partial_sq)
        S[i] = (num/(denom**2))
    return Q, S
コード例 #19
0
def structure_factor_pair(trj, pair, Q_range=(0.5, 50), n_points=1000, framewise_rdf=False, method='fz'):
    rho = np.mean(trj.n_atoms / trj.unitcell_volumes)
    L = np.min(trj.unitcell_lengths)

    top = trj.topology
    
    elements_i = set()
    elements_j = set()
    for a in top.atoms:
        string = a.element.symbol
        if string[-2:] == pair[0]:
            elements_i.add((a.element))
        if string[-2:] == pair[1]:  
            elements_j.add((a.element))

    compositions_i = dict()
    compositions_j = dict()
    form_factors_i = dict()
    form_factors_j = dict()
    rdfs = dict()


    Q = np.logspace(np.log10(Q_range[0]),
                    np.log10(Q_range[1]),
                    num=n_points)
    S = np.zeros(shape=(len(Q)))

    for elem in elements_i:
        compositions_i[elem.symbol] = len(top.select('element {}'.format(elem.symbol)))/trj.n_atoms
        form_factors_i[elem.symbol] = elem.atomic_number
    for elem in elements_j:
        compositions_j[elem.symbol] = len(top.select('element {}'.format(elem.symbol)))/trj.n_atoms
        form_factors_j[elem.symbol] = elem.atomic_number

    for i, q in enumerate(Q):
        num = 0
        denom = 0

        for elem in elements_i:
            denom += compositions_i[elem.symbol] * form_factors_i[elem.symbol]

        for (elem1, elem2) in it.product(elements_i,elements_j):
            e1 = elem1.symbol
            e2 = elem2.symbol

            f_i = form_factors_i[e1]
            f_j = form_factors_j[e2]

            x_i = compositions_i[e1]
            x_j = compositions_j[e2]



            try:
                g_r = rdfs['{0}{1}'.format(e1, e2)]
            except KeyError:
                pairs = top.select_pairs(selection1='element {}'.format(e1),
                                         selection2='element {}'.format(e2))
                if framewise_rdf:
                    r, g_r = rdf_by_frame(trj,
                                         pairs=pairs,
                                         r_range=(0, L / 2),
                                         bin_width=0.001)
                else:
                    r, g_r = md.compute_rdf(trj,
                                            pairs=pairs,
                                            r_range=(0, L / 2),
                                            bin_width=0.001)
                rdfs['{0}{1}'.format(e1, e2)] = g_r

            integral = simps(r ** 2 * (g_r - g_r[-1]) * np.sin(q * r) / (q * r), r)

            if method == 'al':
                pre_factor = np.sqrt(x_i * x_j) * 4 * np.pi * rho
                partial_sq = (integral*pre_factor) + int(e1==e2)
                num += (f_i*f_j) * (partial_sq + 1) * np.sqrt(x_i*x_j)
            elif method == 'fz':
                pre_factor = 4 * np.pi * rho
                partial_sq = (integral*pre_factor) + 1
                num += (x_i*f_i*x_j*f_j) * (partial_sq)
        S[i] = (num/(denom**2))
    return Q, S
コード例 #20
0
ファイル: scattering.py プロジェクト: colinebunner/scattering
def structure_factor(trj, Q_range=(0.5, 50), n_points=1000, framewise_rdf=False, weighting_factor='fz', isotopes={}, probe="neutron"):
    """Compute the structure factor through a fourier transform of
    the radial distribution function.

    The consdered trajectory must include valid elements.

    Atomic form factors are estimated by atomic number.

    The computed structure factor is only valid for certain values of Q. The
    lowest value of Q that can sufficiently be described by a box of
    characteristic length `L` is `2 * pi / (L / 2)`.

    Parameters
    ----------
    trj : mdtraj.Trajectory
        A trajectory for which the structure factor is to be computed.
    Q_range : list or np.ndarray, default=(0.5, 50)
        Minimum and maximum Values of the scattering vector, in `1/nm`, to be
        consdered.
    n_points : int, default=1000
    framewise_rdf : boolean, default=False
        If True, computes the rdf frame-by-frame. This can be useful for
        managing memory in large systems.
    weighting_factor : string, optional, default='fz'
         Weighting factor for calculating the structure-factor, default is Faber-Ziman.
        See https://openscholarship.wustl.edu/etd/1358/ and http://isaacs.sourceforge.net/manual/page26_mn.html for details.
    isotopes: dict, optional, default=None
        If the scattering experiment was run with specific isotopic compositions (i.e. an NDIS experiment), specify
        isotopic composition as follows:
            {
                element_1.symbol:
                    {
                        element_1.atomic_number_1: fraction,
                        element_1.atomic_number_2: fraction,
                        ...
                    },
                element_2.symbol:
                    {
                        ...
                    },
                ...
            }
        The sum over the fraction for each isotope for each element must be 1.0. An atomic number of -1 signifies
        no isotopic enrichment, at which point the average scattering length will be pulled.

    Returns
    -------
    Q : np.ndarray
        The values of the scattering vector, in `1/nm`, that was considered.
    S : np.ndarray
        The structure factor of the trajectory

    """
    if weighting_factor not in ['fz']:
        raise ValueError('Invalid weighting_factor `{}` is given.'
                         '  The only weighting_factor currently supported is `fz`.'.format(
                             weighting_factor))

    rho = np.mean(trj.n_atoms / trj.unitcell_volumes)
    L = np.min(trj.unitcell_lengths)

    top = trj.topology
    elements = set([a.element for a in top.atoms])

    compositions = dict()
    form_factors = dict()
    rdfs = dict()

    Q = np.logspace(np.log10(Q_range[0]),
                    np.log10(Q_range[1]),
                    num=n_points)
    S = np.zeros(shape=(len(Q)))

    for elem in elements:
        compositions[elem.symbol] = len(top.select('element {}'.format(elem.symbol)))/trj.n_atoms
        form_factors[elem.symbol] = get_form_factor(elem.atomic_number, isotopes.get(elem.atomic_number, {-1: 1.0}), probe=probe)

    for i, q in enumerate(Q):
        num = 0
        denom = 0

        for elem in elements:
            denom += compositions[elem.symbol] * form_factors[elem.symbol]

        for (elem1, elem2) in it.product(elements, repeat=2):
            e1 = elem1.symbol
            e2 = elem2.symbol

            f_a = form_factors[e1]
            f_b = form_factors[e2]

            x_a = compositions[e1]
            x_b = compositions[e2]
            
            try:
                g_r = rdfs['{0}{1}'.format(e1, e2)]
            except KeyError:
                pairs = top.select_pairs(selection1='element {}'.format(e1),
                                         selection2='element {}'.format(e2))
                if framewise_rdf:
                    r, g_r = rdf_by_frame(trj,
                                         pairs=pairs,
                                         r_range=(0, L / 2),
                                         bin_width=0.001)
                else:
                    r, g_r = md.compute_rdf(trj,
                                            pairs=pairs,
                                            r_range=(0, L / 2),
                                            bin_width=0.001)
                rdfs['{0}{1}'.format(e1, e2)] = g_r
            integral = simps(r ** 2 * (g_r - 1) * np.sin(q * r) / (q * r), r)

            if weighting_factor == 'fz':
                pre_factor = 4 * np.pi * rho
                # It's an unrestricted double sum, so non-identical pairs need to be counted twice
                if e1 != e2:
                    pre_factor *= 2.0
                partial_sq = (integral*pre_factor)
                num += (x_a*f_a*x_b*f_b) * (partial_sq)
        # Faber-Ziman comes out in units of barn/sr/atom. 100 is to convert between fm^2 and barn.
        if weighting_factor == 'fz':
            S[i] = num/100.0
        else:
            S[i] = (num/(denom**2))
    return Q, S
コード例 #21
0
bin_edges = np.linspace(0.0,1.0,n_bin)
for this_frame in water_dist:
    
    n_ideal = 4.* np.pi*rho_id/3.*(bin_edges[1:]**3.0-bin_edges[:-1]**3.0)
    
    n_hist, _ = np.histogram(this_frame, bins = bin_edges,density=True)
    this_g2 = n_hist/n_ideal
    g2s.append(this_g2)

g2s = np.array(g2s)
bin_edges = 0.5*(bin_edges[1:]+bin_edges[:-1])
ave_g2 = np.mean(g2s,axis=0)
g2_err = np.std(g2s,axis=0)/(ave_g2[-1])
ave_g2 = ave_g2/(ave_g2[-1])

r,grs = md.compute_rdf(traj, pairs = water_pairs,bin_width = 0.01)

fig4 = plt.figure()
plt.plot(r,grs,color='Green')
plt.errorbar(bin_edges,ave_g2,yerr=g2_err)
plt.xlabel('pairwise distances (nm)')
plt.ylabel('normalized g(r)')
plt.xlim(0,1.0)
plt.ylim(0,3.0)
plt.title('pair distribution function for simulated water')
#plt.axvline(x = 1.0,ymin= 0,ymax = 1000,linestyle='--')
fig4.savefig('/Users/shenglanqiao/Documents/GitHub/waterMD/output/norm_g_cubic_2nm.png')
plt.close(fig4)

# cut_off=np.where(mean_bin_edges >=1.0)[0][0]
# intensity = np.absolute(fft(ave_g2[:cut_off]))**2.0
コード例 #22
0
def structure_factor(trj, Q_range=(0.5, 50), n_points=1000, framewise_rdf=False):
    """Compute the structure factor.

    The consdered trajectory must include valid elements.

    The computed structure factor is only valid for certain values of Q. The
    lowest value of Q that can sufficiently be described by a box of
    characteristic length `L` is `2 * pi / (L / 2)`.

    Parameters
    ----------
    trj : mdtraj.Trajectory
        A trajectory for which the structure factor is to be computed.
    Q_range : list or np.ndarray, default=(0.5, 50)
        Minimum and maximum Values of the scattering vector, in `1/nm`, to be
        consdered.
    n_points : int, default=1000
    framewise_rdf : boolean, default=False
        If True, computes the rdf frame-by-frame. This can be useful for
        managing memory in large systems.

    Returns
    -------
    Q : np.ndarray
        The values of the scattering vector, in `1/nm`, that was considered.
    S : np.ndarray
        The structure factor of the trajectory

    """
    rho = np.mean(trj.n_atoms / trj.unitcell_volumes)
    L = np.min(trj.unitcell_lengths)

    top = trj.topology
    elements = set([a.element for a in top.atoms])

    compositions = dict()
    form_factors = dict()
    rdfs = dict()

    Q = np.logspace(np.log10(Q_range[0]),
                    np.log10(Q_range[1]),
                    num=n_points)
    S = np.zeros(shape=(len(Q)))

    for elem in elements:
        compositions[elem.symbol] = len(top.select('element {}'.format(elem.symbol)))/trj.n_atoms
        form_factors[elem.symbol] = elem.atomic_number

    for i, q in enumerate(Q):
        num = 0
        denom = 0
        for elem in elements:
            denom += (compositions[elem.symbol] * form_factors[elem.symbol]) ** 2

        for (elem1, elem2) in it.combinations_with_replacement(elements, 2):
            e1 = elem1.symbol
            e2 = elem2.symbol

            f_a = form_factors[e1]
            f_b = form_factors[e2]

            x_a = compositions[e1]
            x_b = compositions[e2]

            pre_factor = x_a * x_b * f_a * f_b * 4 * np.pi * rho
            try:
                g_r = rdfs['{0}{1}'.format(e1, e2)]
            except KeyError:
                pairs = top.select_pairs(selection1='element {}'.format(e1),
                                         selection2='element {}'.format(e2))
                if framewise_rdf:
                    r, g_r = rdf_by_frame(trj,
                                         pairs=pairs,
                                         r_range=(0, L / 2),
                                         bin_width=0.001)
                else:
                    r, g_r = md.compute_rdf(trj,
                                            pairs=pairs,
                                            r_range=(0, L / 2),
                                            bin_width=0.001)
                rdfs['{0}{1}'.format(e1, e2)] = g_r
            integral = simps(r ** 2 * (g_r - 1) * np.sin(q * r) / (q * r), r)
            num += pre_factor * integral + int(e1 == e2)
        S[i] = num/denom
    return Q, S
import os
import json
import pdb
import numpy as np

import mdtraj

curr_dir = os.getcwd()
index = json.load(open('index.txt', 'r'))

for comp in index.keys():
    print(comp)
    os.chdir(os.path.join(curr_dir, comp))

    all_rdfs = []
    for chunk in mdtraj.iterload('npt_80-100ns.xtc', top='npt.gro', chunk=100):
        pairs = chunk.topology.select_pairs(
            'resname DSPC and (name O22 or name O32)',
            'resname HOH and name O')
        bins, rdf = mdtraj.compute_rdf(chunk, pairs, r_range=[0, 2])
        all_rdfs.append(rdf)

    np.savetxt('ester-water_rdf.txt',
               np.column_stack(
                   [bins,
                    np.mean(all_rdfs, axis=0),
                    np.std(all_rdfs, axis=0)]),
               header='r, g(r), error')
コード例 #24
0
                        cg_top,
                        time=None,
                        unitcell_lengths=t.unitcell_lengths,
                        unitcell_angles=t.unitcell_angles)
cg_traj.save_dcd('cg_traj.dcd')

# print(cg_traj)
# print(cg_top)
# print(cg_xyz)

# ### Calculate RDF and save

# In[ ]:

pairs = cg_traj.top.select_pairs(selection1='name "carbon"',
                                 selection2='name "carbon"')

# mdtraj.compute_rdf(traj, pairs=None, r_range=None, bin_width=0.005, n_bins=None, periodic=True, opt=True)
r, g_r = md.compute_rdf(cg_traj,
                        pairs=pairs,
                        r_range=(0, 1.2),
                        bin_width=0.005)
np.savetxt('rdfs_aa.txt', np.transpose([r, g_r]))

# In[ ]:

fig, ax = plt.subplots()
ax.plot(r, g_r)
ax.set_xlabel("r")
ax.set_ylabel("g(r)")