def soft_cut(ref, u, selA, selB, radius=4.5, beta=5.0, lambda_constant=1.8): """ Reference implementation for testing """ # reference groups A and B from selection strings refA, refB = ref.select_atoms(selA), ref.select_atoms(selB) # 2D float array, reference distances (r0) dref = distance_array(refA.positions, refB.positions) # 2D bool array, select reference distances that are less than the cutoff # radius mask = dref < radius # group A and B in a trajectory grA, grB = u.select_atoms(selA), u.select_atoms(selB) results = [] for ts in u.trajectory: d = distance_array(grA.positions, grB.positions) r, r0 = d[mask], dref[mask] x = 1 / (1 + np.exp(beta * (r - lambda_constant * r0))) # average/normalize and append to results results.append((ts.time, x.sum() / mask.sum())) return np.asarray(results)
def __init__(self, u, selection, refgroup, method="hard_cut", radius=4.5, kwargs=None, **basekwargs): """ Parameters ---------- u : Universe trajectory selection : tuple(string, string) two contacting groups that change over time refgroup : tuple(AtomGroup, AtomGroup) two contacting atomgroups in their reference conformation. This can also be a list of tuples containing different atom groups radius : float, optional (4.5 Angstroms) radius within which contacts exist in refgroup method : string | callable (optional) Can either be one of ``['hard_cut' , 'soft_cut']`` or a callable with call signature ``func(r, r0, **kwargs)`` (the "Contacts API"). kwargs : dict, optional dictionary of additional kwargs passed to `method`. Check respective functions for reasonable values. verbose : bool (optional) Show detailed progress of the calculation if set to ``True``; the default is ``False``. """ self.u = u super(Contacts, self).__init__(self.u.trajectory, **basekwargs) if method == 'hard_cut': self.fraction_contacts = hard_cut_q elif method == 'soft_cut': self.fraction_contacts = soft_cut_q else: if not callable(method): raise ValueError("method has to be callable") self.fraction_contacts = method self.selection = selection self.grA = u.select_atoms(selection[0]) self.grB = u.select_atoms(selection[1]) # contacts formed in reference self.r0 = [] self.initial_contacts = [] if isinstance(refgroup[0], AtomGroup): refA, refB = refgroup self.r0.append(distance_array(refA.positions, refB.positions)) self.initial_contacts.append(contact_matrix(self.r0[-1], radius)) else: for refA, refB in refgroup: self.r0.append(distance_array(refA.positions, refB.positions)) self.initial_contacts.append(contact_matrix(self.r0[-1], radius)) self.fraction_kwargs = kwargs if kwargs is not None else {} self.timeseries = []
def time_distance_array(self, num_atoms): """Benchmark calculation of all distances between two numpy arrays of coordinates, using default arguments to distance_array. """ distances.distance_array(reference=self.coords_1, configuration=self.coords_2, box=None, result=None, backend='serial')
def time_distance_array_pre_allocated(self, num_atoms): """Benchmark calculation of all distances between two numpy arrays of coordinates, using distance_array with a preallocated result array. """ distances.distance_array(reference=self.coords_1, configuration=self.coords_2, box=None, result=self.allocated_array_2D, backend='serial')
def contacts_with (sim,polymer_text,tracers_text,bindingsites_text,teq,tsample,threshold) : """ Calculate the relative proportion of contacts of the tracers with binding sites compared with non-binding sites. As usual user should supply equilibration time, sampling time, and contact threshold value. """ # select polymer, tracers, and binding sites polymer = sim.u.select_atoms (polymer_text) tracers = sim.u.select_atoms (tracers_text) bss = sim.u.select_atoms (bindingsites_text) # select binding site indices bs_n = bss.n_atoms bs_idx = bss.indices # select non-binding site indices polymer_idx = polymer.indices nbs_idx = np.setdiff1d (polymer_idx,bs_idx) nbs_n = nbs_idx.size # evaluate contacts with binding sites and non-binding sites for each # independent simulation snapshot c = [] for i,ts in enumerate(sim.u.trajectory[teq::tsample]) : d = distance_array (polymer.positions,tracers.positions, box=ts.dimensions) contacts = d<threshold cB = np.sum (contacts[bs_idx]).astype('float') cA = np.sum (contacts[nbs_idx]).astype('float') if cA != 0 : c.append ((cB/cA) / (float(bs_n)/nbs_n)) return np.mean(np.array(c))
def potential_matrix(self): """Calculate molecular potential of nanodroplet. Returns ------- lj_mat : float[:,:], shape = (self._num_frame, num_mol), unit = (kJ/mol) coul_mat : float[:,:], shape = (self._num_frame, num_mol), unit = (kJ/mol) """ num_mol = int(self._num_atom / 4) lj_mat = np.zeros((self._num_frame, num_mol)) coul_mat = np.zeros_like(lj_mat) for i, ts in tqdm(enumerate(self._universe.trajectory), total=self._num_frame): dist_atom_vec = np.zeros((self._num_atom**2)) dist_atom_vec = mdanadist.distance_array( self._atom_vec.positions, self._atom_vec.positions, box=ts.dimensions).ravel() lj_mat[i] += np.sum(np.sum(self._lennard_jones(dist_atom_vec), axis=1).reshape((-1, 4)), axis=1) coul_mat[i] += np.sum(np.sum(self._coulomb(dist_atom_vec), axis=1).reshape((-1, 4)), axis=1) return (lj_mat, coul_mat)
def calculate_chipseq (self,polymer_text,tracer_text,teq,tsample, threshold=2.5,aggregate=True) : """ Calculates the 'ChIP-seq' profile of the tracers' contacts with the polymer. Users should provide the text to select the particles that belong to the polymer (polymer_text) and the one to select the tracers (tracer_text). User should provide the 'teq' and 'tsample' variables, which express, respectively, the number of frames to exclude at the start of the simulation, and the frequency at which the contact matrix should be calculated. Optional 'threshold' parameter for the thresholding of the contacts. """ u = self.u tracers = u.select_atoms (tracer_text) polymer = u.select_atoms (polymer_text) ntracers = tracers.n_atoms N = polymer.n_atoms chip_seq = np.zeros ((N,ntracers),dtype=int) for ts in u.trajectory[teq::tsample] : d = distance_array (polymer.positions,tracers.positions, box=ts.dimensions) chip_seq += d<threshold if aggregate : self.chip_seq = np.sum (chip_seq,axis=1) else : self.chip_seq = chip_seq
def contact_map(system, stride): '''The function creates contact map (0 and 1) for for every pair of aminoacids''' cutoff = 5.5 sel_heavy = 'not name H*' num_data_points = (len(system.trajectory) // stride) + (0 if (len(system.trajectory) % stride == 0) else 1) size = contact_size(system) contacts = np.empty((num_data_points, size), dtype=np.float) index = 0 for ts in system.trajectory[::stride]: if ts.frame % 100 == 0 : output = round(100 * ts.frame / len(system.trajectory), 1) print(output,"% complete",end='\r') sys.stdout.flush() contact_map = np.zeros(size, dtype=np.float) i = 0 for res1 in system.residues: for res2 in system.residues: if abs(res1.resid - res2.resid) > 1 and res1.resid < res2.resid: dist = distances.distance_array(res1.atoms.select_atoms(sel_heavy).positions, res2.atoms.select_atoms(sel_heavy).positions) if np.amin(dist) < cutoff: contact_map[i] = 1. i += 1 contacts[index,:] = contact_map index += 1 return contacts
def run2d_frame(self, g1_pos, g2_pos, dimensions): """ Run a RDF calculation for one frame. Great flexibility as it takes atomic positions Parameters ---------- g1_pos = g1.positions [A] g2_pos = g2.positions [A] dimensions = u.dimensions Outputs ------- RDF array [A] """ N = len(g1_pos) * len(g2_pos) if N == 0: return np.zeros(len(self.bins)) g1_pos[:, 2] = 0.0 g2_pos[:, 2] = 0.0 area = dimensions[0] * dimensions[1] density = N / area d = distance_array(g1_pos, g2_pos, box=dimensions) count = np.histogram(d[d != 0], **self.rdf_settings)[0] count = count.astype(np.float64) rdf = count / density / self.shell_area return rdf
def run(self, oto=False, tto=False, avc=False): print("Calculating order parameters ...") progress = {"ncols": 80} for ts in tqdm(self.u.trajectory, **progress): d = distance.distance_array(self.sel.positions, self.sel.positions, ts.dimensions) # distance array d_array = np.sort(d)[:, 1:5] # self and four nearest neighbors indexs neighbors = self.sel.positions[np.argsort(d)[:, 1:5]] # get neighbor vectors n_vectors = np.empty_like(neighbors) box = self.sel.dimensions[:3] for i in range(len(neighbors)): # periodic boundry conditions dr = neighbors[i] - self.sel.positions[i] n_vectors[i] = dr - box * np.round(dr / box) # oto self.Q += self.oto(n_vectors) # tto self.S += self.tto(d_array) self.output("oto") self.output("tto")
def calc_distance(): u = mda.Universe(STRUCTFNAME, TRAJFILE) head_atms = u.atoms.select_atoms("name {}".format(HEADATM)) tail_atms = u.atoms.select_atoms("name {}".format(' '.join(TAILATMS))) tail_atms = mda.AtomGroup(list(chunks(tail_atms, len(TAILATMS)))) LOGGER.debug("head_atms: %s tail atms %s", head_atms, tail_atms) if not isinstance(mda.AtomGroup, list): head_atms = mda.AtomGroup(head_atms) with open(OUTPUTFILENAME, "w") as outf: outf.write("{: <15}{: <10}{: <10}{: <20}\n".format( "time", "resid", "chain", "dist")) for ts in u.trajectory: LOGGER.info("at time %s", ts.time) outp_inf = [] #distances = distance_array(np.array([head.position for head in head_atms]), np.array([tail.position for tail in tail_atms])) for head, tail in zip(head_atms, tail_atms): #print("HEAD", head) distances = distance_array(head.position, tail.position)[0] #LOGGER.debug("distances:\n%s", distances) residue = head.residue #LOGGER.info("at residue %s", residue) for chainid, dist in enumerate(distances): outpline = "{: <15}{: <10}{: <10}{: <20}\n"\ .format(ts.time, residue.resid, chainid, dist ) outp_inf.append(outpline) for line in outp_inf: outf.write(line)
def contact_maps(coors): """ MDAnalysis takes all of the fun out of this one, but the mdad routines are all done within a KD Tree so it's faster than anything I would write. """ import MDAnalysis.analysis.distances as mdad return mdad.distance_array(coors, coors)
def get_neighborhood(leaflet, mdsys): """ Get neighborhood object for the give leaflet """ dist = distances.distance_array(leaflet.positions, leaflet.positions, mdsys.dimensions[:3]) nbrs = Neighborhood(leaflet.positions, dist, mdsys.dimensions[:3]) return nbrs
def ion_coord(u, n_species, func, block): '''Computes distribution and coordination numbers of water self-ions perpendicular to a surface. Args: u: MDAnalysis Universe object containing trajectory. n_species: Expected number of ions in the solution func: Function to sort for hydronium or hydroxide block: Range of frames composing block. Returns: Coordination numbers and heights of ions perpendicular to surface. ''' # Select oxygen and hydrogen atoms oxygen = u.select_atoms('name O') hydrogen = u.select_atoms('name H') # Initialize output, OH, OO distance arrays out = np.zeros((n_species * len(block), 2)) rOH = np.zeros((len(oxygen), len(hydrogen))) rOO = np.zeros((len(oxygen), len(oxygen))) for i, ts in enumerate(u.trajectory[block.start:block.stop]): print('Processing blocks %.1f%%' % (100 * i / len(block)), end='\r') # Compute OH and OO distance arrays distance_array(oxygen.positions, hydrogen.positions, box=u.dimensions, result=rOH) distance_array(oxygen.positions, oxygen.positions, box=u.dimensions, result=rOO) # Locate ions based on rOH variances ind = func(rOH, n_species) # Store ion positions and compute OO coordination numbers (rOO < 3.3) out[n_species * i:n_species * (i + 1), 0] = oxygen.positions[ind][:, 2] cns = [len(r[(r > 0) & (r < 3.3)]) for r in rOO[ind]] out[n_species * i:n_species * (i + 1), 1] = cns return out
def lsi(u, block): '''Computes local structure index (LSI). Args: u: MDAnalysis Universe object containing trajectory. block: Range of frames composing block. Returns: Local structure index and heights of each oxygen. ''' # Select oxygen atoms oxygen = u.select_atoms('name O') # Initialize OO distance array rOO = np.zeros((len(oxygen), len(oxygen))) lsindex = [] height = [] for i, ts in enumerate(u.trajectory[block.start:block.stop]): print('Processing blocks %.1f%%' % (100 * i / len(block)), end='\r') # Compute OO distance array distance_array(oxygen.positions, oxygen.positions, box=u.dimensions, result=rOO) # Loop over oxygen atoms for j, pos in enumerate(oxygen.positions): # Sort OO distance r = np.sort(rOO[j]) # Consider all OO distances less than 3.7 angstrom delta = r[np.roll((r > 0) * (r < 3.7), 1)] - r[(r > 0) * (r < 3.7)] # Get mean and evaluate LSI as mean of squared differences to mean ave = np.mean(delta) lsindex.append(np.sum((delta - ave)**2) / len(delta)) # Store height of oxygen height.append(pos[2]) return np.vstack((lsindex, height)).T
def nns(u, Prod): Phos = u.select_atoms("resid 12490 and name P8") Dist = distance_array(Phos.positions, Prod.positions, box=np.array( [130.2080, 130.2080, 82.9370, 90., 90., 90.], dtype=float32)) min_dis = np.amin(Dist) return min_dis
def calc_contact_map(trajectory_data, output_directory, distance_cutoff=9999.): """ """ # ---------------------------------------- # IO NAMING VARIABLES # ---------------------------------------- binary_contact_map_file_name = output_directory + 'binary_contact_map.dat' avg_node_node_distance_file_name = output_directory + 'avg_distance_contact_map.dat' # ---------------------------------------- # MEASURING THE AVERAGE DISTANCE BETWEEN NODES - add error analysis? # ---------------------------------------- nSteps = trajectory_data.shape[0] nSteps_range = range(nSteps) nNodes = trajectory_data.shape[1] nNodes_range = range(nNodes) avg_node_node_distance_array = np.zeros((nNodes, nNodes), dtype=np.float64) temp_avg_node_node_distance_array = np.zeros((nNodes, nNodes), dtype=np.float64) print 'Starting to calculate the average distance between nodes.' for ts in nSteps_range: avg_node_node_distance_array += distance_array( trajectory[ts, :, :], trajectory[ts, :, :], result=temp_avg_node_node_distance_array) #for i in nNodes_range[:-1]: # node1_pos = trajectory_data[ts,i] # for j in nNodes_range[i+1:]: # dist,dist2 = euclid_dist(node1_pos,trajectory_data[ts,j]) # avg_node_node_distance_array[i,j] += dist avg_node_node_distance_array /= nSteps # ---------------------------------------- # CREATING THE BINARY DISTANCE CONTACT MAP # ---------------------------------------- binary_node_node_distance_array = np.zeros((nNodes, nNodes), np.int) for i in nNodes_range[:-1]: for j in nNodes_range[i + 1:]: #avg_node_node_distance_array[j,i] = avg_node_node_distance_array[i,j] if avg_node_node_distance_array[i, j] < distance_cutoff: binary_node_node_distance_array[ i, j] = binary_node_node_distance_array[j, i] = 1 # ---------------------------------------- # SAVING THE AVERAGE AND BINARY CONTACT MAPS # ---------------------------------------- np.savetxt(binary_contact_map_file_name, binary_node_node_distance_array, fmt='%i') np.savetxt(avg_node_node_distance_file_name, avg_node_node_distance_array) # ---------------------------------------- # RETURNING BINARY AND AVERAGE DISTANCE CONTACT MAPS # ---------------------------------------- return binary_node_node_distance_array, avg_node_node_distance_array
def get_hopping_freq_dist( self, run_start: int, run_end: int, binding_site: str, binding_cutoff: float, hopping_cutoff: float, floating_atom: str = "cation", smooth: int = 51, mode: str = "full", ) -> Tuple[np.floating, np.floating]: """Calculates the cation hopping rate and hopping distance. Args: run_start: Start frame of analysis. run_end: End frame of analysis. binding_site: Floating ion binding site species. binding_cutoff: Binding cutoff distance. hopping_cutoff: Hopping out cutoff distance. floating_atom: Floating atom species. smooth: The length of the smooth filter window. Default to 51. mode: The mode of treating hopping event. Default to "full". Return: The floating_atom average hopping rate and average hopping distance. """ nvt_run = self.wrapped_run floating_atoms = nvt_run.select_atoms(self.select_dict.get(floating_atom)) freqs = [] hopping_distance = [] for ion in tqdm(floating_atoms[:]): neighbor_trj = neighbor_distance( nvt_run, ion, run_start, run_end, binding_site, self.select_dict, binding_cutoff ) if mode == "full": sites, freq, steps = find_nearest( neighbor_trj, self.time_step, binding_cutoff, hopping_cutoff, smooth=smooth ) elif mode == "free": sites, freq, steps = find_nearest_free_only( neighbor_trj, self.time_step, binding_cutoff, hopping_cutoff, smooth=smooth ) else: raise ValueError("invalid mode") coords = [] for step in steps: coord_ion = nvt_run.trajectory[step + run_start][ion.index] coords.append(coord_ion) if len(coords) > 1: dists = [] for i in range(len(coords) - 1): dist = distance_array(coords[i + 1], coords[i], box=self.get_nvt_dimension())[0][0] dists.append(dist) ion_mean_dists = np.mean(dists) hopping_distance.append(ion_mean_dists) freqs.append(freq) return np.mean(freqs), np.mean(hopping_distance)
def run(self, ag1, ag2, nn=6, mm=12, d0=0, r0=2.5, density=False, b=0, e=1e10, skip=1): """ Compute a coordination number s = [1 - ((r-d0)/r0)**n] / [1 - ((r-d0)/r0)**m] Parameter --------- ag1, ag2: atomic groups density: False [bool] nn = 6 [int] mm = 12 [int] d0 = 0 [A] r0 = 2.5 [A] b = 0 [ns] e = 1e10 [ns] skip = 1 [int] Output ------ [:,0] = time [ns] [:,1] = coordination number [unitless] """ assert isinstance(ag1, AtomGroup) assert isinstance(ag2, AtomGroup) u = ag1.universe bframe, eframe = Frame().frame(u, b, e) print("frame starts at %d" % bframe) print("frame ends at %d" % eframe) times = [] coords = [] for ts in u.trajectory[bframe:eframe + 1:skip]: times.append(ts.time / 1000) d = distance_array(ag1.positions, ag2.positions, box=u.dimensions) d[d < d0] = 1 D = (d - d0) / r0 sij = (1 - np.power(D, nn)) / (1 - np.power(D, mm)) coords.append(np.sum(sij)) if density: coords = np.array(coords) coords /= (ag1.n_atoms * ag2.n_atoms) return np.transpose([times, coords])
def perform_reach(covar, avgPos, selGroup): pairDist = distance_array(avgPos, avgPos) # compute hessian #hessian3D = hessian_from_covar(covar,303) hessian3D = kb * 303.0 * np.linalg.pinv(covar, rcond=1E-12) hessian = hessian_NxN_from_3Nx3N(hessian3D) # reachify hessian, fits = reachify_hessian(hessian, pairDist, selGroup) return hessian
def dist_restraints_filter_pearson_only(static_coord, mobile_coord, dist_mat_idx, dist_rest_data, cutoff=0.3): dist_mat = distances.distance_array(static_coord, mobile_coord) current_distances = dist_mat[tuple(dist_mat_idx)] pearson_correl = stats.pearsonr(dist_rest_data, current_distances)[0] pass_status = pearson_correl > cutoff return [current_distances, pearson_correl, pass_status]
def perform_reach_traj_com(coord, sel, nWindows=1, deltaFrame=1, thresh=1.0E-10): # setup some variables for windows and trajectory totalFrames = coord.trajectory.n_frames windowFrames = totalFrames // nWindows # declare arrays covar = np.zeros((3 * sel.n_residues, 3 * sel.n_residues), dtype=np.float64) hessian = np.zeros((sel.n_residues, sel.n_residues), dtype=np.float64) pairDist = np.zeros((sel.n_residues, sel.n_residues), dtype=np.float64) totalFrameCount = 0 # loop through trajectory in windows for window in range(nWindows): print("Window:", window) startFrame = window * windowFrames stopFrame = startFrame + windowFrames # start with total selection # perform iterative alignment to average and compute converged average structure avgPos, alignedPos = iterative_align_average_com(coord, sel, frameStart=startFrame, frameStop=stopFrame, deltaFrame=deltaFrame, thresh=thresh) # zero some loop variables frameCount = 0 covar = 0.0 print("Creating Covariance") # loop through trajectory and compute covariance for ts in coord.trajectory[startFrame:stopFrame:deltaFrame]: covar += np.dot( alignedPos[frameCount, :, :].reshape(3 * sel.n_residues, 1), alignedPos[frameCount, :, :].reshape(1, 3 * sel.n_residues)) pairDist += distance_array( np.float32(alignedPos[frameCount, :, :]), np.float32(alignedPos[frameCount, :, :]), box=ts.dimensions) frameCount += 1 totalFrameCount += 1 # finish covariance covar /= frameCount covar -= np.dot(avgPos.reshape(3 * sel.n_residues, 1), avgPos.reshape(1, 3 * sel.n_residues)) # compute hessian hessian3D = hessian_from_covar(covar, 303) hessian += hessian_NxN_from_3Nx3N(hessian3D) # finish pairwise distance average pairDist /= totalFrameCount hessian /= nWindows return pairDist, hessian, covar
def _single_frame(self): self.timeseries[self._frame_index][0] = self._ts.frame # compute distance array for a frame d = distance_array(self.grA.positions, self.grB.positions) for i, (initial_contacts, r0) in enumerate(zip(self.initial_contacts, self.r0), 1): # select only the contacts that were formed in the reference state r = d[initial_contacts] r0 = r0[initial_contacts] q = self.fraction_contacts(r, r0, **self.fraction_kwargs) self.timeseries[self._frame_index][i] = q
def make_gate_arr(md_uni, gate_EC, gate_IC): from MDAnalysis.analysis import distances import numpy as np gate_EC_dists = [] gate_IC_dists = [] for timestep in md_uni.trajectory: tm1 = md_uni.select_atoms( 'resid %i-%i' % (gate_EC[0][0], gate_EC[0][1])).center_of_mass() tm7 = md_uni.select_atoms( 'resid %i-%i' % (gate_EC[1][0], gate_EC[1][1])).center_of_mass() tm4 = md_uni.select_atoms( 'resid %i-%i' % (gate_IC[0][0], gate_IC[0][1])).center_of_mass() tm10 = md_uni.select_atoms( 'resid %i-%i' % (gate_IC[1][0], gate_IC[1][1])).center_of_mass() gate_EC_dists.append(float(distances.distance_array(tm1, tm7))) gate_IC_dists.append(float(distances.distance_array(tm4, tm10))) print("returning EC gate, IC gate dists") gate_EC_dists = np.array(gate_EC_dists) gate_IC_dists = np.array(gate_IC_dists) return gate_EC_dists, gate_IC_dists
def dist_restraints_filter(static_coord, mobile_coord, dist_mat_idx, dist_rest_data, cutoff=0.3): """Distance restraints (DR) filter. Pearson and Spearman correlations between the given distance restraints and the distances between C-alpha atoms of the corresponding residue pairs in docking poses. Poses passes the filter when both correlations are >0.3. Parameters ---------- static_ori_coord, mobile_ori_coord : np.array Nx3 coordinate array of the static and mobile monomers, respectively, from the docking pose. Where N is the number of atoms. dist_mat_idx : list Contains 2 lists. The lists represents the row (first list) and column (second) indices (0-indexed) of the distance matrix that corresponds to the residue pairs involved in the distance restraints. dist_rest_data : np.array Array containing the distance restraints. The length of the dist_rest_data should be the same as the 2 lists in dist_mat_idx. cutoff : float, optional If the docking pose's Spearman and Pearson correlation are >cutoff, the docking pose passes the filter. Returns ------- list Contains the distances between the C-alpha atoms (np.array), Spearman correlation (float), Pearson correlation (float) and pass status (bool). The pass status is True when the docking pose passes the filter and vice versa. """ dist_mat = distances.distance_array(static_coord, mobile_coord) current_distances = dist_mat[tuple(dist_mat_idx)] spearman_correl = stats.pearsonr(stats.rankdata(dist_rest_data), stats.rankdata(current_distances))[0] pearson_correl = stats.pearsonr(dist_rest_data, current_distances)[0] pass_status = (spearman_correl > cutoff) and (pearson_correl > cutoff) return [current_distances, spearman_correl, pearson_correl, pass_status]
def DKL_t (sim,polymer_text,tracer_text,teq,tsample,t_threshold,p_threshold) : # define DKL(t) vector nframes = traj_nslice(sim.u,teq,tsample) DKL_t = np.zeros(nframes) # define polymer and tracers polymer = sim.u.select_atoms(polymer_text) tracers = sim.u.select_atoms(tracer_text) N = polymer.n_atoms ntracers = tracers.n_atoms # init H and C vectors H = np.zeros((N,N)) C = np.zeros((N,ntracers)) # analyze all simulation frames as decided for i,ts in enumerate(sim.u.trajectory[teq::tsample]) : # calculate Hi-C at this time frame d = distance_array(polymer.positions,polymer.positions,box=ts.dimensions) H += (d<p_threshold) Rt = H.sum(axis=1) # calculate ChIP-seq at this time frame c = distance_array(polymer.positions,tracers.positions,box=ts.dimensions) C += (c<t_threshold) Ct = C.sum(axis=1) DKL_t[i] = mbt.KL_divergence(Ct,Rt) return DKL_t
def find_dist(lipid_resnames, lipids, sn_dic, distances): """ Finds the relative distance in X-Y space between the first and last atoms of both sn chains. """ for res in lipids.residues: sn1_atoms = res.atoms.select_atoms( f'name {sn_dic.get(res.resname)[0]}') sn2_atoms = res.atoms.select_atoms( f'name {sn_dic.get(res.resname)[1]}') sn1_len = [] sn2_len = [] for i in range(len(sn1_atoms.positions) - 1): dis = distance_array(sn1_atoms.positions[i], sn1_atoms.positions[i + 1]) sn1_len.append(dis) for i in range(len(sn2_atoms.positions) - 1): dis = distance_array(sn2_atoms.positions[i], sn2_atoms.positions[i + 1]) sn2_len.append(dis) sn1_dist = calc_dist(sn1_atoms[0].position, sn1_atoms[-1].position) / np.concatenate( sum(sn1_len))[0] sn2_dist = calc_dist(sn2_atoms[0].position, sn2_atoms[-1].position) / np.concatenate( sum(sn2_len))[0] # Need to decide whether to do average of both sn chains or save both distances[res.resid].append((sn1_dist + sn2_dist) / 2) #distances[res.resid].append((sn1_dist, sn2_dist)) return distances
def neighbor_distance( nvt_run: Universe, center_atom: Atom, run_start: int, run_end: int, species: str, select_dict: Dict[str, str], distance: float, ) -> Dict[str, np.ndarray]: """ Calculates a dictionary of distances between the ``center_atom`` and neighbor atoms. Args: nvt_run: An MDAnalysis ``Universe`` containing wrapped trajectory. center_atom: The center atom object. run_start: Start frame of analysis. run_end: End frame of analysis. species: The neighbor species in the select_dict. select_dict: A dictionary of atom species selection, where each atom species name is a key and the corresponding values are the selection language. distance: The neighbor cutoff distance. Returns: A dictionary of distance of neighbor atoms to the ``center_atom``. The keys are atom indexes in string type . """ dist_dict = {} time_count = 0 trj_analysis = nvt_run.trajectory[run_start:run_end:] species_selection = select_dict.get(species) if species_selection is None: raise ValueError("Invalid species selection") for ts in trj_analysis: selection = ("(" + species_selection + ") and (around " + str(distance) + " index " + str(center_atom.index) + ")") shell = nvt_run.select_atoms(selection, periodic=True) for atom in shell.atoms: if str(atom.index) not in dist_dict: dist_dict[str(atom.index)] = np.full(run_end - run_start, 100.0) time_count += 1 time_count = 0 for ts in trj_analysis: for atom_index, val in dist_dict.items(): dist = distance_array(ts[center_atom.index], ts[int(atom_index)], ts.dimensions) val[time_count] = dist time_count += 1 return dist_dict
def gas_count(gas_sel, aops, ts): oxy_sel = gas_sel.universe.select_atoms('type 3') # bounds as determined by AOP aop = aops[~np.isnan(aops).any(axis=1)] aop = aop[~(aop == 1).any(axis=1)] aop = aop[~(aop == 0.1).any(axis=1)] # wrap the atom positions so water box is centered as in AOP ts1 = center_in_box(oxy_sel, wrap=True)(ts) oxy_sel.universe.atoms.wrap() #left, right = np.min(aop[:, 0]), np.max(aop[:, 0]) left, right = np.min(oxy_sel.positions[:, 0]), np.max(oxy_sel.positions[:, 0]) # start by determining counts of gas in each of 8 bins gas_pos = gas_sel.positions[:, 0] # these are the indices of the gases within the bounds of the water box gas_in_box = np.where(np.logical_and(np.min(oxy_sel.positions[:, 0]) <= gas_pos, gas_pos <= np.max(oxy_sel.positions[:, 0])))[0] tot_counts = stats.binned_statistic(gas_pos[gas_in_box], gas_in_box, statistic='count', bins=8, range=(left, right)) tot_counts = tot_counts[0] # now we want to determine the number of these gases which are in # the hydrate # our criterion for "hydrate-like" is AOP < 0.05; criterion for gas # participating in the hydrate is >10 hydrate-like waters within 5.5A d = distance_array(gas_sel.positions, oxy_sel.positions, box=oxy_sel.universe.dimensions) gasind, oxind = np.where(d <= 5.5) ox_aops = aops[:, 1][oxind] # array to store 1 if given gas is participating in clathrate, # 0 otherwise box_gas_clath = np.zeros_like(gas_in_box) for i, g in enumerate(gas_in_box): g_aops = ox_aops[gasind == g] g_clath_h2os = len(g_aops[g_aops < 0.05]) if g_clath_h2os >= 10: box_gas_clath[i] = 1 clath_counts = stats.binned_statistic(gas_pos[gas_in_box], box_gas_clath, statistic='sum', bins=8, range=(left, right)) clath_counts = clath_counts[0] return np.stack((tot_counts, clath_counts))
def distance_matrix (sim,polymer_text,teq,tsample,threshold=2.5) : """ Calculate the matrix of average intra-polymer distances. User must supply the parameters teq, tsample and threshold. """ u = sim.u polymer = u.select_atoms (polymer_text) N = polymer.n_atoms nslice = mbt.traj_nslice (u,teq,tsample) d = np.zeros((N,N)) for i,ts in enumerate(u.trajectory[teq::tsample]) : this_d = distance_array(polymer.positions, polymer.positions, box=ts.dimensions) d = mbt.new_average(i,d,this_d) return d
def _single_frame(self): # compute distance array for a frame d = distance_array(self.grA.positions, self.grB.positions) y = np.empty(len(self.r0) + 1) y[0] = self._ts.frame for i, (initial_contacts, r0) in enumerate(zip(self.initial_contacts, self.r0)): # select only the contacts that were formed in the reference state r = d[initial_contacts] r0 = r0[initial_contacts] y[i + 1] = self.fraction_contacts(r, r0, **self.fraction_kwargs) if len(y) == 1: y = y[0] self.timeseries.append(y)
def _single_frame(self): # compute distance array for a frame d = distance_array(self.grA.positions, self.grB.positions) y = np.empty(len(self.r0) + 1) y[0] = self._ts.frame for i, (initial_contacts, r0) in enumerate(zip(self.initial_contacts, self.r0)): # select only the contacts that were formed in the reference state r = d[initial_contacts] r0 = r0[initial_contacts] y[i + 1] = self.fraction_contacts(r, r0, **self.fraction_kwargs) if len(y) == 1: y = y[0] self.timeseries.append(y)
def contact(self, ag1, ag2, rcut, density=False, b=0, e=1e10, skip=1): """ Compute the contact map s = 1 if d <= rcut s = 0 if d > rcut Parameter --------- ag1, ag2: atomic groups density: False [bool] rcut [A] b = 0 [ns] e = 1e10 [ns] skip = 1 [int] Output ------ [:,0] = time [ns] [:,1] = contact number [unitless] """ assert isinstance(ag1, AtomGroup) assert isinstance(ag2, AtomGroup) u = ag1.universe bframe, eframe = Frame().frame(u, b, e) print("frame starts at %d" % bframe) print("frame ends at %d" % eframe) times = [] coords = [] for ts in u.trajectory[bframe:eframe + 1:skip]: times.append(ts.time / 1000) d = distance_array(ag1.positions, ag2.positions, box=u.dimensions) d[d <= rcut] = 1 d[d > rcut] = 0 coords.append(np.sum(d)) if density: coords = np.array(coords) coords /= (ag1.n_atoms * ag2.n_atoms) return np.transpose([times, coords])
def contacts_t (sim,polymer_text,tracer_text,teq,tsample,threshold) : """ For the simulation 'sim', calculate the matrix of binding events of the polymer and the tracers. Returns a contacts matrix of the shape (ntracers,nslice,npolymer). """ u = sim.u polymer = u.select_atoms (polymer_text) tracers = u.select_atoms (tracer_text) ntracers = tracers.n_atoms npolymer = polymer.n_atoms nslice = mbt.traj_nslice(u,teq,tsample) C = np.zeros((ntracers,nslice,npolymer),dtype=bool) for i,ts in enumerate(u.trajectory [teq::tsample]) : d = distance_array (tracers.positions,polymer.positions, box=ts.dimensions) c = d<threshold C[:,i,:] = c return C
def distance_calculation_all(dists, **kwargs): """Calculates distances between pairs of atom groups (dist) for each set of selections "dists" using MDAnalysis D.distance_array method. Stores the distances in replicate as .npy. Returns the dataframe of distances or stores it as pickle.""" for k, v in kwargs.items(): exec(k + '=v') distances_df = pd.DataFrame( ) #Dataframe that stores all the distances for all cuttoffs distances = {} # This is the dictionary of d distances. for d, dist in enumerate( dists, 1 ): #iterate through the list of dists. For each dist, define atomgroup1 (sel1) and atomgroup2 (sel2) u = mda.Universe(replicate + TPR, replicate + XTC) sel1, sel2 = u.select_atoms(dist[0]), u.select_atoms(dist[1]) #print(sel1) #print(sel2) filename = 'distance{}-i{}-o{}-s{}-{}.npy'.format( d, start * ps, stop, dt, i) if not os.path.exists(replicate + 'results/' + filename): print("\tDistance{} file of replicate {} not found.".format(d, i)) distances[d] = np.around([ D.distance_array( sel1.positions, sel2.positions, box=u.dimensions) for ts in u.trajectory[start:stop:dt] ], decimals=3) np.save(replicate + 'results/' + filename, distances[d]) else: distances[d] = np.load(replicate + 'results/' + filename) print("\tDistance {} file of replicate {} found. Shape: {}".format( d, i, np.shape(distances[d])[0])) distances_df = pd.concat([ distances_df, pd.DataFrame(distances[d].ravel(), columns=[r'd{}@{}-{}'.format(d, c, i)]) ], axis=1) distances_df.index.name = 'frame' return distances_df '''
def _single_frame(self): grA, grB, r0, mask = self.grA, self.grB, self.r0, self.mask # compute distance array for a frame d = distance_array(grA.positions, grB.positions) # select only the contacts that were formed in the reference state # r, r0 are 1D array r, r0 = d[mask], r0[mask] if self._method == "cutoff": y = r <= r0 y = float(y.sum())/mask.sum() elif self._method == "best-hummer": y, _ = best_hummer_q(r, r0, self.beta, self.lambda_constant) else: raise ValueError("Unknown method type, has to be 'cutoff' or 'best-hummer'") cm = np.zeros((grA.positions.shape[0], grB.positions.shape[0])) cm[mask] = y self.contact_matrix.append(cm) self.timeseries.append((self._ts.frame , y, mask.sum()))
def GenerateContactMap(TimeStep,protocol): """Read a frame and compute the contactMap between two groups of atom given a ContactMapProtocol NOTE: if protocol.byres=True, then we report the number of atomic contacts for a given residue pair in contact Numbering of atoms and residues is the one given by the PSF file""" rowNS = AtomNeighborSearch(protocol.rowGroup) #KDE-tree object for rowGroup colNS = AtomNeighborSearch(protocol.colGroup) #KDE-tree object for colGroup rowClose = rowNS.search_list(protocol.colGroup,protocol.cutOff) #atoms of rowGroup in contact with colGroup if not rowClose: #no contacts shape=(TimeStep.numatoms,TimeStep.numatoms) #all atoms in the system if protocol.byres: shape=(protocol.numberOfResidues,protocol.numberOfResidues) csr=csr_matrix( ([],([],[])), shape, dtype='int32') #empty map cma=CMA.csr_ContactMap(csr) cma.setDistanceCutOff(protocol.cutOff) return cma colClose = colNS.search_list(rowClose,protocol.cutOff) #atoms of colGroup in contact with rowClose/rowGroup dd=distance_array(rowClose.coordinates(),colClose.coordinates(),TimeStep.dimensions[0:3]) (rowIndices,colIndices) = numpy.where(dd<protocol.cutOff) rowIndices=rowClose.indices()[rowIndices] colIndices=colClose.indices()[colIndices] if protocol.byres: #switch from atomic indices to residue numbers rowIndices=protocol.atom2res[rowIndices] colIndices=protocol.atom2res[colIndices] shape=(protocol.numberOfResidues,protocol.numberOfResidues) else: #Take into account if the first atomic index was zero rowIndices += protocol.shift colIndices += protocol.shift shape=(TimeStep.numatoms,TimeStep.numatoms) #all atoms in the system #create sparse matrix for the contact map. data=numpy.ones( len(rowIndices) ) #just signaling a contact map csr=csr_matrix( (data, (rowIndices,colIndices)), shape, dtype='int32') if protocol.byres: csr.data[:]=1 #overwrite number of atomic contacts per residue pair with 1 only #trace() if protocol.filter: csr=protocol.filter(csr) #Filtering cma=CMA.csr_ContactMap(csr) cma.setDistanceCutOff(protocol.cutOff) return cma
def make_bilayerGraph(self): adj = (distance_array(self.phosphates.coordinates(),self.phosphates.coordinates()) < self.bilayerDist[0]) self.graph = nx.connected_components(nx.Graph(adj))
def calc_mm_interaction_energy(u, ligand_spec, prm, solute_spec, vdw_shift=0.0, patches=None): """ Given an MDAnalysis universe, calculate the pairwise interaction energies between the specified ligand and the solute. :param u: MDAnalysis universe :param ligand_spec: Specification to find the ligand molecule, such as "resname APM" :param prm: Dict containing Lennard-Jones parameters by atom type, as read from ffparam_charges_vs_qm.load_prm :param solute_spec: Specification to find the solute, such as "protein or nucleic" :param vdw_shift: In L-J calculations only, increase interparticle distance by this many Angstroms for the sake of softcore FEP (see the documentation for alchVdwShiftCoeff in NAMD) :param patches: A dict containing modifications to the ligand to be applied, such as nudging charges. Should be like {SKE_N1_chargedelta: 0.1}, which increases the charge of the N1 atom of SKE by 0.1. :return: A tuple containing electrostatic and Lennard-Jones energies, as NxM arrays, with N ligand atoms and M frames """ ligand_atoms = u.select_atoms(ligand_spec) solute_atoms = u.select_atoms(solute_spec) if len(ligand_atoms) == 0: print >>sys.stderr, 'Cannot find any ligand atoms. Did you provide the correct residue name?' sys.exit(1) if len(solute_atoms) == 0: print >>sys.stderr, 'Cannot find any solute atoms. Did you provide the correct spec?' sys.exit(1) ligand_rmin2 = np.array([prm[a.type]['rmin2'] for a in ligand_atoms]) ligand_epsilon = np.array([prm[a.type]['epsilon'] for a in ligand_atoms]) solute_rmin2 = np.array([prm[a.type]['rmin2'] for a in solute_atoms]) solute_epsilon = np.array([prm[a.type]['epsilon'] for a in solute_atoms]) # We will be precomputing the pairwise charge products, which we will later scale by inverse distance, # as well as part of the Lennard-Jones calculation. # We can do this otherwise horrible O(n^2) calculation because we know we have a relatively # small number of ligand atoms, so the size of the resulting matrix is not cataclysmic. # There has got to be a Numpy-array-based way to do this, but since we only do it once # we can tolerate the slowness. charge_prod = np.zeros((len(ligand_atoms), len(solute_atoms))) lj6_partial, eps_partial = np.zeros_like(charge_prod), np.zeros_like(charge_prod) # Fill in default of no patches if patches is None: patches = {} # Modify solute atom parameters according to user-specified patches. # This mechanism is different from the ligand one because in the ligand case we want to # modify all ligand molecules in the same way. In this case, we really just want one # atom to change. Obviously this means there is no clear way to only modify one ligand # molecule, but I guess that can be added later if needed. for solute_i in range(len(solute_atoms)): solute_atom = solute_atoms[solute_i] # HSD_123_HB2_chargedelta: -0.5 chargedelta_key = '%s_%d_%s_chargedelta' % (solute_atom.resname, solute_atom.resid, solute_atom.name) if chargedelta_key in patches: solute_atom.charge += patches[chargedelta_key] # Modify ligand atom charges according to the patches specified by the user for ligand_i in range(len(ligand_atoms)): ligand_atom = ligand_atoms[ligand_i] # Modify charge of this ligand atom if user asked us to chargedelta_key = '%s_%s_chargedelta' % (ligand_atom.resname, ligand_atom.name) if chargedelta_key in patches: ligand_atom.charge += patches[chargedelta_key] ligand_charge = COULOMB * ligand_atom.charge l_rmin2, l_eps = ligand_rmin2[ligand_i], ligand_epsilon[ligand_i] for solute_i in range(len(solute_atoms)): charge_prod[ligand_i, solute_i] = ligand_charge * solute_atoms[solute_i].charge lj6_partial[ligand_i, solute_i] = (l_rmin2 + solute_rmin2[solute_i])**6 eps_partial[ligand_i, solute_i] = (l_eps * solute_epsilon[solute_i])**0.5 electro, lj = [], [] for ts in u.trajectory: # Tell the user every so often which frame we're on if (ts.frame > 0 and ts.frame % 50 == 49) or ts.frame+1 == len(u.trajectory): print >>sys.stderr, 'Processing frame %d of %d.' % (ts.frame+1, len(u.trajectory)) # Calculate pairwise distances, which thankfully we don't need to do manually, because # that would be incredibly slow in pure Python. dists = distance_array(ligand_atoms.positions, solute_atoms.positions) # ...and scale the precomputed charge products by those distances, summing over all solute # atoms to yield a per-ligand-atom electrostatic interaction energy. frame_electro = np.sum(charge_prod / dists, 1) # Then do the analogous thing for Lennard-Jones energies. # Lennard-Jones energy calculation was: # lj6 = ((a_rmin2 + prm[b.type]['rmin2']) / dist)**6 # ligand_lj[ligand_i] += (a_epsilon * prm[b.type]['epsilon'])**0.5 * (lj6**2 - 2*lj6) # For FEP softcore purposes, shift the interparticle distance if vdw_shift != 0.0: dists += vdw_shift lj6 = lj6_partial / (dists**6) frame_lj = np.sum(eps_partial * (lj6**2 - 2*lj6), 1) electro.append(frame_electro) lj.append(frame_lj) return np.array(electro), np.array(lj)
def loop_trajectory(sel1c, sel2c, indices1, indices2, config, suppl, selfInteraction): """Invoked to analyze trajectory chunk for contacts as a single thread.""" # print(len(sel1c) , len(sel2c)) # indices1 = suppl[0] # indices2 = suppl[1] cutoff, hbondcutoff, hbondcutangle = config # resname_array = comm.bcast(resname_array, root=0) # resid_array = comm.bcast(resid_array, root=0) # name_array = comm.bcast(name_array, root=0) bonds = suppl[0] # segids = comm.bcast(segids, root=0) # backbone = comm.bcast(backbone, root=0) name_array = suppl[1] resid_array = [] segids = [] if (selfInteraction): resid_array = suppl[2] segids = suppl[3] allRankContacts = [] # start = time.time() for s1, s2 in zip(sel1c, sel2c): frame = 0 currentFrameContacts = [] result = np.ndarray(shape=(len(s1), len(s2)), dtype=float) distarray = distances.distance_array(s1, s2, box=None, result=result) contacts = np.where(distarray <= cutoff) for idx1, idx2 in itertools.izip(contacts[0], contacts[1]): convindex1 = indices1[frame][idx1] # idx1 converted to global atom indexing convindex2 = indices2[frame][idx2] # idx2 converted to global atom indexing # jump out of loop if hydrogen contacts are found, only contacts between heavy atoms are considered, # hydrogen bonds can still be detected! if re.match("H(.*)", name_array[convindex1]) or re.match("H(.*)", name_array[convindex2]): continue if selfInteraction: if (resid_array[convindex1] - resid_array[convindex2]) < 5 and segids[convindex1] == segids[convindex2]: continue # distance between atom1 and atom2 distance = distarray[idx1, idx2] weight = weight_function(distance) hydrogenBonds = [] if (name_array[convindex1][0] in HydrogenBondAtoms.atoms and name_array[convindex2][0] in HydrogenBondAtoms.atoms): # print("hbond? %s - %s" % (type_array[convindex1], type_array[convindex2])) # search for hatom, check numbering in bond!!!!!!!!!! b1 = bonds[convindex1] b2 = bonds[convindex2] bondcount1 = 0 hydrogenAtomsBoundToAtom1 = [] # new code for b in b1.types: # b = bnd.type hydrogen = next((xx for xx in b if xx.startswith("H")), 0) # print(b) if hydrogen != 0: # print("h bond to atom1") bondindices1 = b1.to_indices()[bondcount1] # print bondindices1 # for j in bondindices1: # print(self.type_array[j+1]) hydrogenidx = next( (j for j in bondindices1 if name_array[j].startswith("H")), -1) if hydrogenidx != -1: # print(self.type_array[hydrogenidx]) hydrogenAtomsBoundToAtom1.append(hydrogenidx) bondcount1 += 1 # search for hydrogen atoms bound to atom 2 bondcount2 = 0 hydrogenAtomsBoundToAtom2 = [] for b in b2.types: # b = bnd2.type hydrogen = next((xx for xx in b if xx.startswith("H")), 0) # print(b) if hydrogen != 0: # print("h bond to atom2") bondindices2 = b2.to_indices()[bondcount2] hydrogenidx = next( (k for k in bondindices2 if name_array[k].startswith("H")), -1) if hydrogenidx != -1: # print(type_array[hydrogenidx]) hydrogenAtomsBoundToAtom2.append(hydrogenidx) bondcount2 += 1 for global_hatom in hydrogenAtomsBoundToAtom1: conv_hatom = np.where(indices1[frame] == global_hatom)[0][0] dist = distarray[conv_hatom, idx2] if dist <= hbondcutoff: donorPosition = s1[idx1] hydrogenPosition = s1[conv_hatom] acceptorPosition = s2[idx2] v1 = hydrogenPosition - acceptorPosition v2 = hydrogenPosition - donorPosition v1norm = np.linalg.norm(v1) v2norm = np.linalg.norm(v2) dot = np.dot(v1, v2) angle = np.degrees(np.arccos(dot / (v1norm * v2norm))) if angle >= hbondcutangle: new_hbond = HydrogenBond(convindex1, convindex2, global_hatom, dist, angle, hbondcutoff, hbondcutangle) hydrogenBonds.append(new_hbond) # print str(convindex1) + " " + str(convindex2) # print "hbond found: %d,%d,%d"%(convindex1,global_hatom,convindex2) # print angle for global_hatom in hydrogenAtomsBoundToAtom2: conv_hatom = np.where(indices2[frame] == global_hatom)[0][0] dist = distarray[idx1, conv_hatom] if dist <= hbondcutoff: donorPosition = s2[idx2] hydrogenPosition = s2[conv_hatom] acceptorPosition = s1[idx1] v1 = hydrogenPosition - acceptorPosition v2 = hydrogenPosition - donorPosition v1norm = np.linalg.norm(v1) v2norm = np.linalg.norm(v2) dot = np.dot(v1, v2) angle = np.degrees(np.arccos(dot / (v1norm * v2norm))) if angle >= hbondcutangle: new_hbond = HydrogenBond(convindex2, convindex1, global_hatom, dist, angle, hbondcutoff, hbondcutangle) hydrogenBonds.append(new_hbond) newAtomContact = AtomContact(int(frame), float(distance), float(weight), int(convindex1), int(convindex2), hydrogenBonds) currentFrameContacts.append(newAtomContact) allRankContacts.append(currentFrameContacts) frame += 1 return allRankContacts
gww.append(eachDis) distance=str(distance)+' '+str(eachDis)+'\n' print eachDis,'@@@@@@@@@@@@@@@@@@@@@@@' ,distance print gww ## output.write(distance) ## output.close() return gww for ts in water.trajectory: print ts oc1=o.coordinates() oc2=o.coordinates() d=distance_array(oc1,oc2,box) vwaterId=0 for i in d: vwaterId+=1 vresid='resid '+str(vwaterId) vH2O=water.selectAtoms(vresid) vCoord=vH2O.coordinates() cwaterId=0 for j in i: cwaterId+=1 ## print j no=int((j-2.0)/0.1) ## print no if 0<no<=39: ## vresid='resid '+str(vwaterId)
def __init__(self, u, selection, refgroup, method="hard_cut", radius=4.5, kwargs=None, start=None, stop=None, step=None,): """Initialization Parameters ---------- u : Universe trajectory selection : tuple(string, string) two contacting groups that change over time refgroup : tuple(AtomGroup, AtomGroup) two contacting atomgroups in their reference conformation. This can also be a list of tuples containing different atom groups radius : float, optional (4.5 Angstroms) radius within which contacts exist in refgroup method : string | callable (optional) Can either be one of ['hard_cut' , 'soft_cut'] or a callable that implements a API (r, r0, **kwargs). kwargs : dict, optional dictionary of additional kwargs passed to `method`. Check respective functions for reasonable values. start : int, optional First frame of trajectory to analyse, Default: 0 stop : int, optional Last frame of trajectory to analyse, Default: -1 step : int, optional Step between frames to analyse, Default: 1 """ if method == 'hard_cut': self.fraction_contacts = hard_cut_q elif method == 'soft_cut': self.fraction_contacts = soft_cut_q else: if not callable(method): raise ValueError("method has to be callable") self.fraction_contacts = method # setup boilerplate self.u = u self._setup_frames(self.u.trajectory, start, stop, step) self.selection = selection self.grA = u.select_atoms(selection[0]) self.grB = u.select_atoms(selection[1]) # contacts formed in reference self.r0 = [] self.initial_contacts = [] if isinstance(refgroup[0], AtomGroup): refA, refB = refgroup self.r0.append(distance_array(refA.positions, refB.positions)) self.initial_contacts.append(contact_matrix(self.r0[-1], radius)) else: for refA, refB in refgroup: self.r0.append(distance_array(refA.positions, refB.positions)) self.initial_contacts.append(contact_matrix(self.r0[-1], radius)) self.fraction_kwargs = kwargs if kwargs is not None else {} self.timeseries = []
def __init__(self, u, selection, refgroup, method="cutoff", radius=4.5, outfile=None, start=None, stop=None, step=None, **kwargs): """Calculate the persistence length for polymer chains Parameters ---------- u: Universe trajectory selection: tuple(string, string) two contacting groups that change over time refgroup: tuple(AtomGroup, AtomGroup) two contacting groups in their reference conformation radius: float, optional (4.5 Angstroms) radius within which contacts exist method: string either 'cutoff' or 'best-hummer' start : int, optional First frame of trajectory to analyse, Default: 0 stop : int, optional Last frame of trajectory to analyse, Default: -1 step : int, optional Step between frames to analyse, Default: 1 Parameters for 'best-hummer' method ----------------------------------- lambda_constant: float, optional (1.8 unitless) contact is considered formed between (lambda*r0,r0) beta: float, optional (5 Angstroms^-1) softness of the switching function, the lower the softer Attributes ---------- results: list Fraction of native contacts for each frame """ # check method if not method in ("cutoff", "best-hummer"): raise ValueError("method has to be 'cutoff' or 'best-hummer'") self._method = method # method-specific parameters if method == "best-hummer": self.beta = kwargs.get('beta', 5.0) self.lambda_constant = kwargs.get('lambda_constant', 1.8) # steup boilerplate self.u = u self._setup_frames(self.u.trajectory, start=start, stop=stop, step=step) self.selection = selection grA, grB = u.select_atoms(selection[0]), u.select_atoms(selection[1]) self.grA, self.grB = grA, grB refA, refB = refgroup # contacts formed in reference r0 = distance_array(refA.positions, refB.positions) self.r0 = r0 self.mask = r0 < radius self.contact_matrix = [] self.timeseries = [] self.outfile = outfile
##print list(w) box = rho.trajectory.ts.dimensions[:3] frameNo=1 for ts in rho.trajectory: distanceMat.write('frame'+' '+str(frameNo)+'\n') title='resname'+' '+'atomid'+' '+'resnumber'+' X Y Z '+' '+'segname'+'\n' distanceMat.write(title) wc=w.coordinates() ## print str(wc[0])[1:-1] ## print list(wc)[0] ## print pc d=distance_array(pc,wc,box) ## print len(d) ## print len(d[0]) print ts waterNP=[] for i in d: ## print len(i) waterid=0 for j in i: ## print j if j>6: waterid+=1 elif j<=6: water=str(waterResna[waterid])+' '+atomInf[waterid][0]+' '+str(waterResnu[waterid])+' '+str(wc[waterid])[1:-1]+' '+atomInf[waterid][1]+'\n' if water not in waterNP: