def __init__(self, solute, gro, traj, build_monomer, spline=False, npores=4): self.npores = npores print('Loading trajectory...', end='', flush=True) self.t = md.load(traj, top=gro) print('Done!') self.solute = topology.Solute(solute) self.monomer = topology.LC(build_monomer) # monomer head group only for testing purposes # ref = ['C', 'C1', 'C2', 'C3', 'C4', 'C5'] # solutes_indices = [a.index for a in self.t.topology.atoms if a.residue.name == solute and a.name in ref] # self.nsolute = 400 # self.solute_vectors = self.direction_vectors() # self.com = physical.center_of_mass(self.t.xyz[:, solutes_indices, :], [v for v in self.solute.mass.values()][:6]) solutes_indices = [a.index for a in self.t.topology.atoms if a.residue.name == solute] self.nsolute = len(solutes_indices) // self.solute.natoms self.solute_vectors = self.direction_vectors() self.com = physical.center_of_mass(self.t.xyz[:, solutes_indices, :], [v for v in self.solute.mass.values()]) reference_atoms = [a.index for a in self.t.topology.atoms if a.name in self.monomer.pore_defining_atoms and a.residue.name in self.monomer.residues] self.pore_centers = physical.avg_pore_loc(4, self.t.xyz[:, reference_atoms, :], self.t.unitcell_vectors) self.pore_vectors = self.pore_center_vectors() self.costheta = self.angles() self.nematic_order_parameter = self.nematic()
def placement(placement_region): if placement_region == 'pores': # find the pore centers pore_atom_indices = [ a.index for a in t.topology.atoms if a.name in args.pore_atoms ] pore_centers = physical.avg_pore_loc(4, t.xyz[0, pore_atom_indices, :]) # randomly choose a pore from a uniform distribution pore = np.random.choice([0, 1, 2, 3]) random_cylinder_point = random_pt_cylinder( args.radius_pore, t.unitcell_vectors[0, 2, 2]) # height is z-box vector water_placement_point = random_cylinder_point + [ pore_centers[0, pore], pore_centers[1, pore], 0 ] # shift so cylinder is centered at chosen pore center else: tail_atom_indices = [ a.index for a in t.topology.atoms if a.name in args.tail_atoms ] # indices of oxygens in tails placement_atom = np.random.choice( tail_atom_indices ) # randomly choose which atom to place water molecule near # place point within spherical shell centered at placement_atom with inner radius=rmin and outside radius=rmax water_placement_point = solvate_tails.random_pt_spherical_shell( t.xyz[0, placement_atom, :], args.rmin, args.rmax) return water_placement_point
def locate_pore_centers(self, spline=False): # find pore centers # can use physical.avg_pore_loc with spline argument instead of if/else below pore_atoms = [ a.index for a in self.t.topology.atoms if a.name in self.pore_atoms ] if spline: print('Creating pore splines') self.pore_centers = physical.trace_pores( self.pos[:, pore_atoms, :], self.t.unitcell_vectors, 20) else: self.pore_centers = physical.avg_pore_loc( self.npores, self.pos[:, pore_atoms, :], self.t.unitcell_vectors)
def radial_distribution_function(self, bins=50, cut=1.5, spline=False, progress=True, npts_spline=10): """ Calculate the radial distribution function based on xy distance of solute center of mass from pore center :param bins: number of bins in histogram of radial distances :param cut: largest distance to include in radial distance histogram :param spline: locate pore centers as a function of z. Recommended. Slower, but more accurate :param progress: Show progress bar while generating spline :param npts_spline: Number of points making up spline tr each pore :return: """ self.r = np.zeros([bins]) self.density = np.zeros([self.t.n_frames, bins]) pore_defining_atoms = [ a.index for a in self.t.topology.atoms if a.name in self.monomer.pore_defining_atoms and a.residue.name == self.monomer.name ] if spline: print('Generating spline through each pore...') pore_centers = physical.avg_pore_loc( 4, self.t.xyz[:, pore_defining_atoms, :], self.box, spline=spline, progress=progress, npts=npts_spline) if spline: self.build_spline( pore_centers ) # to check that the spline was constructed properly print('Calculating component density') self.r, self.density = physical.compdensity(self.com, pore_centers, self.t.unitcell_vectors, nbins=bins, spline=spline, cut=cut)
def restrict_to_pore(self, r, dwell_fraction=0.95, tails=False, build_monomer='NAcarb11V.gro', spline=False, buffer=0, npores=4): """ Restrict calculations to center of masses (COMs) that primarily stay in the pore OR tail region :param r: radius of pore. Anything greater than r from the pore center is considered the tail region :param dwell_fraction: Fraction of time spent in region of interest required in order to keep trajectory :param tails: if True, then restrict calculations to COMs primarily in the tail region :param build_monomer: monomer coordinate file of which liquid crystal membrane is mode :param spline: track pore centers with a 3D spline :param buffer: Do not count molecules below _buffer_ or above z-box-vector - _buffer_ :type r: float :type tails: bool :type build_monomer: str :type spline: bool :type buffer: float """ # find pore centers pore_defining_atoms = topology.LC(build_monomer).pore_defining_atoms pore_atoms = [a.index for a in self.t.topology.atoms if a.name in pore_defining_atoms] if spline: print('Creating pore splines') pore_centers = physical.trace_pores(self.t.xyz[:, pore_atoms, :], self.t.unitcell_vectors, 20) else: pore_centers = physical.avg_pore_loc(npores, self.t.xyz[:, pore_atoms, :], self.t.unitcell_vectors) results = 0 if tails: results = 1 inregion = physical.partition(self.com, pore_centers, r, buffer=buffer, unitcell=self.t.unitcell_vectors, npores=npores)[results] dwell = np.full((self.t.n_frames, self.com.shape[1]), False, dtype=bool) for t in range(self.t.n_frames): dwell[t, inregion[t]] = True fraction_dwelled = np.sum(dwell, axis=0) / self.t.n_frames # fraction of total time spend in region of interest keep = np.where(fraction_dwelled >= dwell_fraction)[0] self.com = self.com[:, keep, :]
box = t.unitcell_vectors nT = t.n_frames npores = 4 r_max = 0 if args.solvate: results = np.zeros([len(regions) + 1, args.bins]) else: results = np.zeros([len(regions), args.bins]) #keep = [a.index for a in t.topology.atoms if a.residue.name != 'HOH'] # everything kept if system not solvated components = ['C', 'C1', 'C2', 'C3', 'C4', 'C5'] comp = [a.index for a in t.topology.atoms if a.name in components] p_centers = physical.avg_pore_loc(npores, t.xyz[:, comp, :]) for i, reg in enumerate(regions): print('Calculating number density of %s region' % reg) pos = p2p.restrict_atoms(t, reg) # restrict trajectory to region p = duplicate(pos, t.unitcell_vectors) # duplicate things periodically equil = 0 density, r, bin_width = compdensity(pos, p_centers, equil, box,
xbounds = np.array([-3, max(times)]) return xbounds, ybounds if __name__ == "__main__": args = initialize() t = md.load(args.traj, top=args.gro) # load gromacs trajectory keep = [a.index for a in t.topology.atoms if a.name in args.components ] # get the index of all atoms in components # pore_components = t.atom_slice(keep) # create a new trajectory object only describing those atoms pos = t.xyz[:, keep, :] pcenters = physical.avg_pore_loc(4, pos) # find the pore centers radii = physical.limits( pos, pcenters) # find the average radius of each pore in each frame r = np.zeros(radii.shape[0]) # find average pore radius at each frame r_std = np.zeros(radii.shape[0]) # standard deviation at each frame for i in range(radii.shape[0]): r[i] = np.mean(radii[i, :]) r_std[i] = np.std(radii[i, :]) poresize_equil = timeseries.detectEquilibration(r)[0] order_equil = timeseries.detectEquilibration(old_div(r, r_std))[0] # Calculate standard deviation in poresize after equilibration based on standard deviation at each frame # Ref: https://stats.stackexchange.com/questions/25848/how-to-sum-a-standard-deviation # std_poresize_equil = 0