Esempio n. 1
0
def rdf(u, thresholds, n_bins, pair, block):
    '''Computes water radial distribution functions (RDF).

    Args:
        u: MDAnalysis Universe object containing trajectory.
        t: Thresholds specifying layer boundaries.
        n_bins: Number of bins for RDF.
        pair: Pair of elements to consider.
        block: Range of frames composing block.

    Returns:
        Radial distribution function.
    '''

    atoms = list(pair)

    # Select appropriate atom groups within specified layers
    down = 'prop z > %s and prop z < %s' % (*thresholds[:2], )
    up = 'prop z > %s and prop z < %s' % (*thresholds[2:], )
    ag1 = u.select_atoms('name %s and ((%s) or (%s))' % (atoms[0], down, up),
                         updating=True)
    ag2 = u.select_atoms('name %s' % atoms[1])

    # Compute the RDF between ag1 and ag2
    rdf = InterRDF(ag1, ag2, nbins=n_bins, range=(0, 6), verbose=True)
    rdf.run(start=block.start, stop=block.stop)

    return (rdf.results.bins, rdf.results.rdf)
Esempio n. 2
0
 def test_double_run(self):
     # running rdf twice should give the same result
     self._linear_water()
     s1, s2 = self._get_sels()
     rdf = InterRDF(s1, s2).run()
     rdf.run()
     assert_(len(rdf.count[rdf.count == 4]) == 2)
Esempio n. 3
0
class SimpleRdfBench(object):
    """Benchmarks for MDAnalysis.analysis.rdf
    """

    params = ([20, 75, 200], [[0, 5], [0, 15], [0, 20]])

    param_names = ['nbins', 'range_val']

    def setup(self, nbins, range_val):

        self.sel_str = 'name OW'

        self.u = MDAnalysis.Universe(TPR, XTC)

        try:
            self.sel = self.u.select_atoms(self.sel_str)[:200]
        except AttributeError:
            self.sel = self.u.selectAtoms(self.sel_str)[:200]

        # do not include initialization of the
        # InterRDF object in the benchmark itself

        self.rdf = InterRDF(g1=self.sel,
                            g2=self.sel,
                            nbins=nbins,
                            range=range_val)

    def time_interrdf(self, nbins, range_val):
        """Benchmark a full trajectory parse
        by MDAnalysis.analysis.rdf.InterRDF
        """
        self.rdf.run()
Esempio n. 4
0
    def test_exclusion(self):
        # should see two distances with 4 counts each
        self._linear_water()

        s1, s2 = self._get_sels()

        rdf = InterRDF(s1, s2, exclusion_block=(1, 2))
        rdf.run()

        assert_(rdf.count.sum() == 4)
Esempio n. 5
0
    def test_count(self):
        # should see two distances with 4 counts each
        self._linear_water()

        s1, s2 = self._get_sels()

        rdf = InterRDF(s1, s2)
        rdf.run()

        assert_(len(rdf.count[rdf.count == 4]) == 2)
Esempio n. 6
0
    def test_count_sum(self):
        # OW vs HW
        # should see 8 comparisons in count
        self._linear_water()

        s1, s2 = self._get_sels()

        rdf = InterRDF(s1, s2)
        rdf.run()

        assert_(rdf.count.sum() == 8)
Esempio n. 7
0
class SimpleRdfBench(object):
    """Benchmarks for MDAnalysis.analysis.rdf
    """

    params = ([20,75,200],
              [[0,5], [0,15], [0,20]],
              [1, 100, 1000, 10000])

    param_names = ['nbins',
                   'range_val',
                   'natoms']

    def setup(self, nbins, range_val, natoms):
        
        self.sel_str = 'name OW'

        self.u = MDAnalysis.Universe(TPR, XTC)

        try:
            self.sel = self.u.select_atoms(self.sel_str)[:natoms]
        except AttributeError:
            self.sel = self.u.selectAtoms(self.sel_str)[:natoms]

        # do not include initialization of the
        # InterRDF object in the benchmark itself

        self.rdf = InterRDF(g1=self.sel,
                            g2=self.sel,
                            nbins=nbins,
                            range=range_val)

    def time_interrdf(self, nbins, range_val):
        """Benchmark a full trajectory parse
        by MDAnalysis.analysis.rdf.InterRDF
        """
        self.rdf.run()
Esempio n. 8
0
u.atoms.write("system.pdb")
print("===> The initial configuration has been written to system.pdb ")

#
# ========================================================="
# Example #3: Calculate a radial distribution function     "
# ========================================================="
#
from MDAnalysis.analysis.rdf import InterRDF

charged = u.select_atoms("prop charge  > 0")
rdf = InterRDF(charged, charged, nbins=7, range=(0, 10))

# This runs so far only over the single frame we have loaded.
# Multiframe averaging must be done by hand
rdf.run()

#
# ========================================================="
# Example #4: Saving frames to a GROMACS's TRR trajectory
# ========================================================="
#

from MDAnalysis.coordinates.TRR import TRRWriter

W = TRRWriter("traj.trr", n_atoms=len(system.part))

for i in range(100):
    # integrate
    system.integrator.run(1)
    # replace last frame
Esempio n. 9
0
def test_double_run(sels):
    # running rdf twice should give the same result
    s1, s2 = sels
    rdf = InterRDF(s1, s2).run()
    rdf.run()
    assert len(rdf.count[rdf.count == 4]) == 2
Esempio n. 10
0
def test_double_run(sels):
    # running rdf twice should give the same result
    s1, s2 = sels
    rdf = InterRDF(s1, s2).run()
    rdf.run()
    assert len(rdf.count[rdf.count == 4]) == 2
def compute_microstructure(molten_salt_system, ensemble, start, stop, step, nbins=500, rdf_flag=True, cn_flag=True, adf_flag=True):
	"""
		Description:
			compute microstructure info including radial distribution fuction(rdf), coordination number(cn) and angle distribution function(adf) using MDAnalysis module. adf is not completed

		Args:
			molten_salt_system: 
			ensemble: 
			start: 
			stop: 
			step: 
			rdf_flag: 
			cn_flag: 
			adf_flag: 

		Returns:
			return dicts according to setting
	"""

	global dir_molten_salt_system
	global dir_list

	# analysis elements and get cations and inions according cif file
	os.chdir(dir_molten_salt_system)
	cations_list, anions_list = [], []
	with open(molten_salt_system+'.cif', 'r') as f_cif:
		flag = False
		atoms_list = []
		for line in f_cif:
			if line.startswith(' _atom_type_oxidation_number'):
				flag = True
				continue
			if line.startswith('loop_'):
				flag = False
				continue
			if flag:
				tmp_tuple = tuple(list(filter(None, line.strip().split(' '))))
				atoms_list.append(tmp_tuple)
	for i in range(len(atoms_list)):
		if float(atoms_list[i][1]) > 0:
			cations_list.append((re.findall(r"[A-Za-z]+", atoms_list[i][0])[0]).upper()) # transfered to uppercase because MDAnalysis can just identify capitalization
		elif float(atoms_list[i][1]) < 0:
			anions_list.append((re.findall(r"[A-Za-z]+", atoms_list[i][0])[0]).upper())
	elements_list = cations_list+anions_list
	elements_count = len(elements_list)

	# determine # of pairs(used in rdf and cn)
	pairs_count = 0
	for i in range(elements_count):
		for j in range(i, elements_count):
			pairs_count += 1

	# radial_distribution_function_dense_dict, coordination_number_dense_dict= [{} for i in range(pairs_count)], [{} for i in range(pairs_count)] # 加密的
	radial_distribution_function_dict, coordination_number_dict= [{} for i in range(pairs_count)], [{} for i in range(pairs_count)]	# 原始的
	for dirname in dir_list:
		os.chdir(os.path.join(dir_molten_salt_system, dirname))
		deal_with_PDB(dirname, ensemble) # write MODEL and ENDMDL into xxx.pdb file and stored as traj.pdb
		universe = MDA.Universe('traj.pdb')
		# determine cutoff of rdf
		tmp_list = list(filter(None, os.popen('grep CRY '+dirname+'-'+ensemble+'.pdb').readlines()[-1].strip().split(' ')))
		equilibrium_lattice_constant_a = float(tmp_list[1])
		equilibrium_lattice_constant_b = float(tmp_list[2])
		equilibrium_lattice_constant_c = float(tmp_list[3])
		equilibrium_lattice_constant_min = min(equilibrium_lattice_constant_a, equilibrium_lattice_constant_b, equilibrium_lattice_constant_c)
		cutoff = equilibrium_lattice_constant_min//2

		# begin compute rdf and cn
		columns_count = -1
		for i in range(elements_count):
			for j in range(i, elements_count):
				columns_count += 1
				atomgroup1 = universe.select_atoms('name '+elements_list[i])
				atomgroup2 = universe.select_atoms('name '+elements_list[j])
				rdf = InterRDF(atomgroup1, atomgroup2, nbins=nbins, range=(0.0, cutoff))
				rdf.run(start=start, stop=stop, step=step) # after run, rdf and count have been generated
				rdf.rdf[0] = 0 # 第一个数莫名奇妙的超级大,本该为0
				
				# This part is discarded because of the limitation of 16MB for single file in mongodb
				'''
				# 加密10倍的
				# store rdf results into a dict
				# make curve smoother
				rdf_new = np.linspace(rdf.bins.min(), rdf.bins.max(), nbins*10) # 加密十倍, 画出来的图更光滑
				rdf_smooth = spline(rdf.bins, rdf.rdf, rdf_new)
				# get rdf_rmax(first peak) and rdf_rmin(first peak valley) of rdf
				rdf_rmax_index = np.argmax(rdf_smooth)
				rdf_rmax = rdf_new[rdf_rmax_index]
				rdf_rmin_index = np.argmin(rdf_smooth[rdf_rmax_index:])
				rdf_rmin = rdf_new[rdf_rmax_index:][rdf_rmin_index]
				radial_distribution_function_dense_dict[columns_count]['pair'] = elements_list[i]+'-'+elements_list[j]
				radial_distribution_function_dense_dict[columns_count][dirname] = {'rdf_rmax': rdf_rmax, 'rdf_rmin': rdf_rmin, 'rdf_value': Binary(pickle.dumps(np.vstack((rdf_new, rdf_smooth)), protocol=2))} # numpy必须转换成二进制才能存进pymongo
				# store cn results into a dict
				rdf_count = rdf.count.copy()
				rdf_count = rdf_count/(len(atomgroup1)*rdf.__dict__['n_frames']) # average
				cn = rdf_count.cumsum() # integrate
				# make curve smoother
				cn_smooth = spline(rdf.bins, cn, rdf_new)
				# get cn_rmin according to first peak valley in rdf
				cn_rmin = cn_smooth[rdf_rmax_index:][rdf_rmin_index]
				coordination_number_dense_dict[columns_count]['pair'] = elements_list[i]+'-'+elements_list[j]
				coordination_number_dense_dict[columns_count][dirname] = {'cn_rmin': cn_rmin, 'cn_value': Binary(pickle.dumps(np.vstack((rdf_new, cn_smooth)), protocol=2))}
				'''

				# 原始的
				# rdf
				radial_distribution_function_dict[columns_count]['pair'] = elements_list[i]+'-'+elements_list[j]
				radial_distribution_function_dict[columns_count][dirname] = Binary(pickle.dumps(np.vstack((rdf.bins, rdf.rdf)), protocol=2))
				# cn
				rdf_count = rdf.count.copy()
				rdf_count = rdf_count/(len(atomgroup1)*rdf.__dict__['n_frames']) # average
				cn = rdf_count.cumsum() # integrate
				coordination_number_dict[columns_count]['pair'] = elements_list[i]+'-'+elements_list[j]
				coordination_number_dict[columns_count][dirname] = Binary(pickle.dumps(np.vstack((rdf.bins, cn)), protocol=2))
		os.system('rm traj.pdb')
		os.chdir(dir_molten_salt_system)

	return radial_distribution_function_dict, coordination_number_dict
end = u.trajectory.n_frames

# RDF analysis

print("#------------------------------------------------------#")
print("Start RDF analysis")
os.system("mkdir RDF")
os.system("cd RDF")

ow = u.select_atoms("name OW")
hw = u.select_atoms("name HW1 or name HW2")
selcation = u.select_atoms("name %s" % (cation[0]))
selanion = u.select_atoms("name %s" % (anion[0]))

ow_ow = IRDF(ow, ow, nbins=100, exclusion_block=(1, 1))
rdf_ow_ow = ow_ow.run()
print("ow ow rdf analysis done")
ow_hw = IRDF(ow, hw, nbins=100)
rdf_ow_hw = ow_hw.run()
print("ow hw rdf analysis done")
cation_ow = IRDF(selcation, ow, nbins=100)
rdf_cation_ow = cation_ow.run()
print("cation ow rdf analysis done")
anion_ow = IRDF(selanion, ow, nbins=100)
rdf_anion_ow = anion_ow.run()
print("anion ow rdf analysis done")

with open("rdf.txt", "w") as f:
    f.write("# RDF result for ow-ow,ow-hw,cation-ow,anion-ow\n")
    for i in range(len(ow_ow.bins)):
        f.write("%.3f %.3f %.3f %.3f %.3f \n"%(rdf_ow_ow.bins[i],\