def test_trj_len(sels, step): # should see same results from analysis.rdf and pmda.rdf s1, s2 = sels nrdf = rdf.InterRDF(s1, s2).run(step=step) prdf = InterRDF(s1, s2).run(step=step) assert_almost_equal(nrdf.n_frames, prdf.n_frames) assert_almost_equal(nrdf.rdf, prdf.rdf)
def test_same_result(sels, n_blocks): # should see same results from analysis.rdf and pmda.rdf s1, s2 = sels nrdf = rdf.InterRDF(s1, s2).run() prdf = InterRDF(s1, s2).run(n_blocks=n_blocks) assert_almost_equal(nrdf.count, prdf.count) assert_almost_equal(nrdf.rdf, prdf.rdf)
def _anal_rdf(u, sel1, sel2, exl, filename): g1 = u.select_atoms(sel1) g2 = u.select_atoms(sel2) rdfo = rdf.InterRDF(g1, g2, exclusion_block=exl, step=50) rdfo.run() with open(filename, "w") as f: for b, r in zip(rdfo.bins, rdfo.rdf): f.write("%.3f %.3f\n" % (b, r))
def rdf_calculation(system_specs, specs): """ Parameters ---------- system_specs : TYPE DESCRIPTION. specs : TYPE DESCRIPTION. Returns ------- TYPE DESCRIPTION. """ import MDAnalysis.analysis.rdf as RDF (trajectory, topology, results_folder, name) = system_specs (selection, start, stop, timestep, stride, units_x, units_y) = specs names, indexes, column_index = Featurize.df_template(system_specs, unit=[units_y]) task = 'MDAnalysis' traj = Trajectory.Trajectory.loadTrajectory(topology, trajectory, task) if traj != None: ref, sel = traj.select_atoms(selection[0]), traj.select_atoms( selection[1]) rdf_ = RDF.InterRDF(ref, sel) rdf_.run(start, stop, stride) rows = pd.Index(rdf_.bins, name=units_x) df_system = pd.DataFrame(rdf_.rdf, columns=column_index, index=rows) #df_system=df_system.mask(df_system > 90) #print(df_system) return df_system else: return pd.DataFrame()
def getSimpleEleEleRdf(traj, eleA, eleB, distRange, nBins=None): """ Gets radial distribution function between two elements Args: traj: (TrajectoryInMemory object) Contains all information on the trajectory eleA: (str) Str representation for the first element eleB: (str) Str representation for the second element distRange: (len-2 iter) [minDist, maxDist] Defines the range of distances to calculate over nBins: (int) The number of bins to use. Default is distRange/10 Returns rdfResults: (RdfBinnedResultsSimple) Contains the radial distribution function between two elements Raises: ValueError: if distRange[-1]>L/2 where L is the shortest lattice parameter. Note: You can go to longer range by creating supercells for each trajectory step, but its unlikely to be a good idea generally """ nBins = int((distRange[1] - distRange[0]) * 10) if nBins is None else nBins _checkRdfRangeWithinLOver2(traj, distRange) #Use MDAnalysis to do the hard work universeObj = mdAnalysisInter.getSimpleAtomicUniverseObjFromTrajObj(traj) groupA = universeObj.select_atoms("name {}".format(eleA)) groupB = universeObj.select_atoms("name {}".format(eleB)) exclusionBlock = ( 1, 1 ) if eleA == eleB else None #Stops (for example) atom0-atom0 being counted rdfObj = rdfHelp.InterRDF(groupA, groupB, nbins=nBins, range=distRange, exclusion_block=exclusionBlock) output = rdfObj.run() #Get the results in the format we use outObj = _getRdfBinnedResultsFromUniverseOutput(output) return outObj
def getStaticGroupToGroupRdf(traj, indicesA, indicesB, distRange, nBins=None): """ Gets radial distribution function between two groups of atoms; groups are defined by atomic indices and hence cant change over the timescale of the simulation. FOR NOW: the groups of indices cant overlap (i may change this later with a keyword) Args: traj: (TrajectoryInMemory object) Contains all information on the trajectory indicesA: [iter of ints] Indices for the first group of elements indicesB: [iter of ints] Indices for the second group of elements distRange: (len-2 iter) [minDist, maxDist] Defines the range of distances to calculate over nBins: (int) The number of bins to use. Default is distRange/10 Returns rdfResults: (RdfBinnedResultsSimple) Contains the radial distribution function Raises: ValueError: if distRange[-1]>L/2 where L is the shortest lattice parameter. Note: You can go to longer range by creating supercells for each trajectory step, but its unlikely to be a good idea generally """ nBins = int((distRange[1] - distRange[0]) * 10) if nBins is None else nBins _checkRdfRangeWithinLOver2(traj, distRange) anySharedIndices = set(indicesA) & set(indicesB) if anySharedIndices: raise ValueError( "indicesA and indicesB must not contain overlapping values") #Convert to MDAnalysis format(TODO: Probably want an option to skip this step and just pass a Universe Trajectory in) universeObj = mdAnalysisInter.getSimpleAtomicUniverseObjFromTrajObj(traj) groupA = mdAnalysisInter.getSelectAtomsObjFromIndices( universeObj, indicesA) groupB = mdAnalysisInter.getSelectAtomsObjFromIndices( universeObj, indicesB) #Calculate the rdf rdfObj = rdfHelp.InterRDF(groupA, groupB, nbins=nBins, range=distRange) output = rdfObj.run() outObj = _getRdfBinnedResultsFromUniverseOutput(output) return outObj
def atom_atom_rdf(gro, trr, out, atom_name_a='AU', atom_name_b='S', interval=(0.0, 50.0), **kwargs): """Computes time resolved rdf between atom groups identified by atom name. https://www.mdanalysis.org/docs/documentation_pages/analysis/rdf.html Units in output textfile are default MDAnalysis units. https://www.mdanalysis.org/mdanalysis/documentation_pages/units.html Parameters ---------- gro: str GROMACS gro coordinates file trr: str GROMACS trr trajectory file with N frames out: str output text file atom_name_a, atom_name_b: str, optional defaults: 'AU' and 'S' interval: tuple or list, optional inner and outer cutoff for rdf. default (0.0,80.0) **kwargs: keyword arguments forwarded to MDAnalysis.analysis.rdf.InterRDF Output ------ out text file contains bins (1st data line), rdf (following data lines) bins: (M,) np.ndarray, centers of M bins rdf: (M,N) np.ndarray, rdf on M bins for N frames """ comm = MPI.COMM_WORLD size = comm.Get_size() rank = comm.Get_rank() logger = logging.getLogger("%s:rank[%i/%i]" % (__name__, rank, size)) mda_trr = mda.Universe(gro, trr) atom_group_a = mda_trr.atoms[mda_trr.atoms.names == atom_name_a] atom_group_b = mda_trr.atoms[mda_trr.atoms.names == atom_name_b] # in the standard case #ranks > #frames, N = len(mda_trr.trajectory) span = N // size # special treatment for more ranks than frames if span < 1: # less frames than ranks span = 1 n1 = rank * span n2 = (rank + 1) * span if rank >= N: # treatment for rank > N n1 = 0 n2 = 0 # in this case, just return empty time_resolved_rdf elif rank == size - 1: # treatment for last rank if N >= size n2 = N logger.info("RDF for frame %i to %i." % (n1, n2)) time_resolved_rdf = [] for i in range(n1, n2): rdf = mda_rdf.InterRDF(atom_group_a, atom_group_b, range=interval, **kwargs) rdf.run(start=i, stop=i + 1) time_resolved_rdf.append(rdf.rdf.copy()) # bins is the center of a bin, see # https://www.mdanalysis.org/docs/_modules/MDAnalysis/analysis/rdf.html # self.bins = 0.5 * (edges[:-1] + edges[1:]) time_resolved_rdf = np.array(time_resolved_rdf) # gathers list of arrays at rank 0 time_resolved_rdf_list = comm.gather(time_resolved_rdf, root=0) if rank == 0: # sort out empty frames filtered_time_resolved_rdf_list = [ l for l in time_resolved_rdf_list if len(l) > 0 ] time_resolved_rdf = np.vstack(filtered_time_resolved_rdf_list) # write file # 1st dim is time (frame), 2nd dim is bin bins = rdf.bins.copy() data = np.vstack((bins, time_resolved_rdf)) np.savetxt( out, data, fmt='%.8e', header='\n'.join(( '{modulename:s}, {username:s}@{hostname:s}, {timestamp:s}'. format( modulename=__name__, username=getpass.getuser(), hostname=socket.gethostname(), timestamp=str(datetime.datetime.now()), ), 'https://www.mdanalysis.org/docs/documentation_pages/analysis/rdf.html', 'g_ab(r)=(N_a N_b)^-1 sum_i=1^N_a sum_j=1^N_b <delta(|r_i-r_j|-r)>', 'normalized to g_ab(r) -> 1 for r -> infty', 'first line: bin centers [Ang], following lines: per-frame rdf' )))
#!/usr/bin/env python2 # -*- coding: utf-8 -*- """ Created on Sun Feb 24 16:33:02 2019 @author: simon """ import MDAnalysis as mda import MDAnalysis.analysis.rdf as rdf import matplotlib.pyplot as plt u = mda.Universe("1.cxyz", format='xyz') monomers = u.select_atoms("type 3") solutes = u.select_atoms("type 2") g_r = rdf.InterRDF(monomers, solutes) g_r.run() plt.plot(g_r.bins, g_r.rdf) plt.show()
def cal_rdf(u, ele1, ele2, cutoff=None, nbins=75, plot=True): """ calculate RDF Parameters ---------- u : MDAnalysis universe ele1 : str, element 1 ele2 : str, element 2 cutoff : float, cutoff for RDF, default, half of the box size Return ---------- bins : array rdf : array Examples ---------- from vatic.interpy.write_pdb import write_pdb import MDAnalysis as mda from vatic.interpy.rdf_cnp import cal_cn, cal_rdf file = '/Users/jiedeng/GD/Computation/VESTA/VData/Bridgmanite/Pv+H/Pv_H_1to4_3k/homogeneous_run/XDATCAR' write_pdb(8000,9900,file=file) u = mda.Universe('XDATCAR_8000_9900.pdb') ele1 = 'H' ele2 = 'H' bins,rdf = cal_rdf(u,ele1,ele2) cn,cnp,bins = cal_cn(u,ele1,ele2,1.2) Notes ---------- tested against StrucAna for the example run For coding details, refer to 1) /Users/jiedeng/Google Drive/Learn/MDanalysis_learn/learn_rdf.py 2) /Users/jiedeng/Google Drive/Learn/MDanalysis_learn/ckDTree_learn.py 3) https://arxiv.org/pdf/1808.01826.pdf 4) https://www.mdanalysis.org/docs/documentation_pages/analysis/rdf.html 5) https://github.com/patvarilly/periodic_kdtree 6) https://stackoverflow.com/questions/42397870/calculation-of-contact-coordination-number-with-periodic-boundary-conditions 7) /Users/jiedeng/Google Drive/Computation/VESTA/VData/Bridgmanite/Pv+H/Pv_H_1to4_3k/homogeneous_run/rdf_cnp.py """ e1 = u.select_atoms('type ' + ele1) e2 = u.select_atoms('type ' + ele2) if cutoff is None: cutoff = min(u.dimensions[:1]) / 2 rdf_mda = RDF.InterRDF(e1, e2, nbins=75, range=(0.0, cutoff)) rdf_mda.run() bins = rdf_mda.bins rdf = rdf_mda.rdf if ele1 is ele2: bins[0] = bins[1] - (bins[2] - bins[1] ) ## why the first element blocked? rdf[0] = rdf[1] else: bins = rdf_mda.bins rdf = rdf_mda.rdf if plot: fig = plt.figure(figsize=(5, 4)) ax = fig.add_subplot(111) ax.plot(bins, rdf, 'k-', label=ele1 + '-' + ele2) ax.legend(loc="best") ax.set_xlabel(r"Distance ($\AA$)") ax.set_ylabel(r"RDF") return bins, rdf
def rdf(topology, trajectory, output_log, ion_atomselection, solvent_atomselection, rdf_shell=20, integration_shell=6, bulk=False, print_rdf=None, no_smooth=False, resid="1", nframes=6000): u = Universe(topology, trajectory) framestart = u.trajectory.n_frames - nframes # for the newer simulations, the resid is no longer always 1 # so we can check for the resid in those new sims' logs # if the regex matches something, it's a new sim: record the resid # otherwise, keep using 1 as the resid with open(output_log) as log: i = 0 for line in log.readlines(): if i > 200: break # there probably is no match for the regex m = residRegex.match(line) if m is not None: resid = m.group(1) break i += 1 ion_group = u.select_atoms(ion_atomselection + " and resid " + resid) solvent_group = u.select_atoms(solvent_atomselection) # print(ion_group) # print(solvent_group) if bulk: ion_group += u.select_atoms(ion_atomselection) rdfs = [] window_frames = nframes // 60 for i in range(0, nframes, window_frames): frame = i + framestart rdf = mdaRDF.InterRDF(ion_group, solvent_group, nbins=100, range=(0.0, rdf_shell), start=frame, stop=frame + window_frames) rdf.run() rdfs.append(rdf) end = int(len(rdfs[0].bins) * (integration_shell / rdf_shell)) dims = u.trajectory.dimensions boxVolume = box_volume(dims) density = solvent_group.n_residues / boxVolume # print(boxVolume, density) return_strings = [] if print_rdf is not None: for i in range(len(rdfs[print_rdf].bins)): return_strings.append( "%f %f" % (rdfs[print_rdf].bins[i], rdfs[print_rdf].rdf[i])) else: for rdf in rdfs: data = [g * rdf.bins[i]**2 for i, g in enumerate(rdf.rdf[:end])] coordinationNum = (4 * 3.14159 * density) * sp.integrate.trapz( data, rdf.bins[:len(data)]) return_strings.append(coordinationNum) if no_smooth or (print_rdf is not None): return return_strings return smooth([float(x) for x in return_strings])
topology_format='LAMMPSDUMP') ag = u.atoms pos_hold = np.copy(u.atoms.positions) rem_z = np.ones(pos_hold.shape) rem_y = np.ones(pos_hold.shape) rem_x = np.ones(pos_hold.shape) print(rem_z.shape) rem_z[:, 2] = 0 rem_y[:, 1] = 0 rem_x[:, 0] = 0 ag.positions = pos_hold * rem_z # Calculate 3D rdf Ta_3D_rdf = RDF.InterRDF(ag, ag, range=[0.0, 20.0], verbose=True) Ta_3D_rdf.run() print('3D rdf calculated.') #Calculate 2D rdfs # print(ag.positions[0]) # # Ta_2D_z_rdf = RDF.InterRDF(ag,ag,range=[0.0,20.0],verbose=True) # # Ta_2D_z_rdf.run() # # print('2D rdf in Z calculated.') # ag.positions = pos_hold*rem_y # print(ag.positions[0]) # # Ta_2D_y_rdf = RDF.InterRDF(ag,ag,range=[0.0,20.0],verbose=True) # # Ta_2D_y_rdf.run() # # print('2D rdf in Y calculated.')