def __init__(self, universe, selectionstring, cutoff=15.0, pbc=False, sparse=None): """Initialize from a *universe* or pdb file. :Arguments: *universe* :class:`MDAnalysis.Universe` or a PDB file name. *selection* :class:`MDAnalysis.core.AtomGroup.AtomGroup` or a :meth:`MDAnalysis.Universe.selectAtoms` selection string for atoms that define the lipid head groups, e.g. universe.atoms.PO4 or "name PO4" or "name P*" :Keywords: *cutoff* head group-defining atoms within a distance of *cutoff* Angstroms are deemed to be in the same leaflet [15.0] *pbc* take periodic boundary conditions into account (only works for orthorhombic boxes) [``False``] *sparse* ``None``: use fastest possible routine; ``True``: use slow sparse matrix implementation (for large systems); ``False``: use fast :func:`~MDAnalysis.analysis.distances.distance_array` implementation [``None``]. """ universe = MDAnalysis.asUniverse(universe) self.universe = universe self.selectionstring = selectionstring if type(self.selectionstring) == MDAnalysis.core.AtomGroup.AtomGroup: self.selection = self.selectionstring else: self.selection = universe.selectAtoms(self.selectionstring) self.pbc = pbc self.sparse = sparse self._init_graph(cutoff)
def __init__(self, *args, **kwargs): """Create a density grid from a trajectory. density_from_trajectory(PSF, DCD, delta=1.0, atomselection='name OH2', ...) --> density or density_from_trajectory(PDB, XTC, delta=1.0, atomselection='name OH2', ...) --> density :Arguments: psf/pdb/gro topology file dcd/xtc/trr/pdb trajectory; if reading a single PDB file it is sufficient to just provide it once as a single argument :Keywords: mode 'solvent', 'bulk' or 'all' ('all' does both 'solvent' and \bulk' at the same time and thus :meth:`DensityCreator.Density`` returns a list of densities; this saves time!) ['all'] atomselection selection string (MDAnalysis syntax) for the species to be analyzed ["name OH2"] delta approximate bin size for the density grid in Angstroem (same in x,y,z) (It is slightly adjusted when the box length is not an integer multiple of delta.) [1.0] metadata dictionary of additional data to be saved with the object padding increase histogram dimensions by padding (on top of initial box size) in Angstroem [2.0] soluteselection MDAnalysis selection for the solute, e.g. "protein" [``None``] cutoff With *cutoff*, select '<atomsel> NOT WITHIN <cutoff> OF <soluteselection>' (Special routines that are faster than the standard AROUND selection) [0] verbosity: int level of chattiness; 0 is silent, 3 is verbose [3] :Returns: :class:`hop.sitemap.Density` :TODO: * Should be able to also set skip and start/stop for data collection. .. Note:: * In order to calculate the bulk density, use atomselection='name OH2',soluteselection='protein and not name H*',cutoff=3.5 This will select water oxygens not within 3.5 A of the protein heavy atoms. Alternatively, use the VMD-based :func:`density_from_volmap` function. * The histogramming grid is determined by the initial frames min and max. * metadata will be populated with psf, dcd, and a few other items. This allows more compact downstream processing. """ _kwargs = self.defaults.copy() _kwargs.update(kwargs) kwargs = _kwargs # workaround for python 2.5 *args,**kwargs only allowed: universe_kwargs = {'permissive': kwargs.pop('permissive', False)} self.universe = MDAnalysis.asUniverse(*args, **universe_kwargs) self.mode = kwargs.pop("mode", "all") # 'all' runs modes[1:] if not self.mode in self.modes: raise ValueError("mode must be one of %r, not %r" % (self.modes, self.mode)) if self.mode == "all": modes = self.modes[1:] else: modes = [self.mode] self.collectors = [] min_coords = [] max_coords = [] for mode in modes: modeargs = kwargs.copy() if mode == "solvent": modeargs['soluteselection'] = None modeargs['cutoff'] = 0 c = DensityCollector(mode, self.universe, **modeargs) self.collectors.append(c) min_coords.append( c.min_coordinates()) # with default padding from modeargs max_coords.append(c.max_coordinates()) # determine maximum bounding box from initial positions of solvent # (add generous padding... probably more than my default 2 A) smin = numpy.sort(min_coords, axis=0)[0] # the three smallest values smax = numpy.sort(max_coords, axis=0)[-1] # the three largest values for c in self.collectors: c.init_histogram(smin=smin, smax=smax) # also guarantees compatible grid self.densities = {} # densities will be stored with mode as key
def __init__(self, *args, **kwargs): """Calculate native contacts within a group or between two groups. :Arguments: *topology* psf or pdb file *trajectory* dcd or xtc/trr file *universe* instead of a topology/trajectory combination, one can also supply a :class:`MDAnalysis.Universe` :Keywords: *selection* selection string that determines which distances are calculated; if this is a tuple or list with two entries then distances are calculated between these two different groups ["name CA or name B*"] *refgroup* reference group, either a single :class:`~MDAnalysis.core.AtomGroup.AtomGroup` (if there is only a single *selection*) or a list of two such groups. The reference contacts are directly computed from *refgroup* and hence the atoms in the reference group(s) must be equivalent to the ones produced by the *selection* on the input trajectory. *radius* contacts are deemed any atoms within radius [8.0 A] *outfile* name of the output file; with the gz or bz2 suffix, a compressed file is written. The average <q> is written to a second, gzipped file that has the same name with 'array' included. E.g. for the default name "q1.dat.gz" the <q> file will be "q1.array.gz". The format is the matrix in column-row format, i.e. selection 1 residues are the columns and selection 2 residues are rows. The file can be read with :func:`numpy.loadtxt`. ["q1.dat.gz"] The function calculates the percentage of native contacts q1 along a trajectory. "Contacts" are defined as the number of atoms within *radius* of a given other atom. *q1* is the fraction of contacts relative to the reference state 1 (typically the starting conformation of the trajectory). The timeseries is written to a file *outfile* and is also accessible as the attribute :attr:`ContactAnalysis1.timeseries`. """ # XX or should I use as input # sel = (group1, group2), ref = (refgroup1, refgroup2) # and get the universe from sel? # Currently it's a odd hybrid. # # Enhancements: # - select contact pairs to write out as a timecourse # - make this selection based on qavg from os.path import splitext self.selection_strings = self._return_tuple2( kwargs.pop('selection', "name CA or name B*"), "selection") self.references = self._return_tuple2(kwargs.pop('refgroup', None), "refgroup") self.radius = kwargs.pop('radius', 8.0) self.targetdir = kwargs.pop('targetdir', os.path.curdir) self.output = kwargs.pop('outfile', "q1.dat.gz") self.outarray = splitext(splitext(self.output)[0])[0] + ".array.gz" self.force = kwargs.pop('force', False) self.timeseries = None # final result self.filenames = args self.universe = MDAnalysis.asUniverse(*args, **kwargs) self.selections = [ self.universe.selectAtoms(s) for s in self.selection_strings ] # sanity checkes for x in self.references: if x is None: raise ValueError("a reference AtomGroup must be supplied") for ref, sel, s in izip(self.references, self.selections, self.selection_strings): if ref.atoms.numberOfAtoms() != sel.atoms.numberOfAtoms(): raise ValueError( "selection=%r: Number of atoms differ between " "reference (%d) and trajectory (%d)" % (s, ref.atoms.numberOfAtoms(), sel.atoms.numberOfAtoms())) # compute reference contacts dref = MDAnalysis.core.distances.distance_array( self.references[0].coordinates(), self.references[1].coordinates()) self.qref = self.qarray(dref) self.nref = self.qref.sum() # setup arrays for the trajectory self.d = numpy.zeros_like(dref) self.q = self.qarray(self.d) self._qtmp = numpy.zeros_like(self.q) # pre-allocated array self.qavg = numpy.zeros(shape=self.q.shape, dtype=numpy.float64)
def __init__(self, *args, **kwargs): """Create a density grid from a trajectory. density_from_trajectory(PSF, DCD, delta=1.0, atomselection='name OH2', ...) --> density or density_from_trajectory(PDB, XTC, delta=1.0, atomselection='name OH2', ...) --> density :Arguments: psf/pdb/gro topology file dcd/xtc/trr/pdb trajectory; if reading a single PDB file it is sufficient to just provide it once as a single argument :Keywords: mode 'solvent', 'bulk' or 'all' ('all' does both 'solvent' and \bulk' at the same time and thus :meth:`DensityCreator.Density`` returns a list of densities; this saves time!) ['all'] atomselection selection string (MDAnalysis syntax) for the species to be analyzed ["name OH2"] delta approximate bin size for the density grid in Angstroem (same in x,y,z) (It is slightly adjusted when the box length is not an integer multiple of delta.) [1.0] metadata dictionary of additional data to be saved with the object padding increase histogram dimensions by padding (on top of initial box size) in Angstroem [2.0] soluteselection MDAnalysis selection for the solute, e.g. "protein" [``None``] cutoff With *cutoff*, select '<atomsel> NOT WITHIN <cutoff> OF <soluteselection>' (Special routines that are faster than the standard AROUND selection) [0] verbosity: int level of chattiness; 0 is silent, 3 is verbose [3] :Returns: :class:`hop.sitemap.Density` :TODO: * Should be able to also set skip and start/stop for data collection. .. Note:: * In order to calculate the bulk density, use atomselection='name OH2',soluteselection='protein and not name H*',cutoff=3.5 This will select water oxygens not within 3.5 A of the protein heavy atoms. Alternatively, use the VMD-based :func:`density_from_volmap` function. * The histogramming grid is determined by the initial frames min and max. * metadata will be populated with psf, dcd, and a few other items. This allows more compact downstream processing. """ _kwargs = self.defaults.copy() _kwargs.update(kwargs) kwargs = _kwargs # workaround for python 2.5 *args,**kwargs only allowed: universe_kwargs = {'permissive':kwargs.pop('permissive',False)} self.universe = MDAnalysis.asUniverse(*args, **universe_kwargs) self.mode = kwargs.pop("mode", "all") # 'all' runs modes[1:] if not self.mode in self.modes: raise ValueError("mode must be one of %r, not %r" % (self.modes, self.mode)) if self.mode == "all": modes = self.modes[1:] else: modes = [self.mode] self.collectors = [] min_coords = [] max_coords = [] for mode in modes: modeargs = kwargs.copy() if mode == "solvent": modeargs['soluteselection'] = None modeargs['cutoff'] = 0 c = DensityCollector(mode, self.universe, **modeargs) self.collectors.append(c) min_coords.append(c.min_coordinates()) # with default padding from modeargs max_coords.append(c.max_coordinates()) # determine maximum bounding box from initial positions of solvent # (add generous padding... probably more than my default 2 A) smin = numpy.sort(min_coords, axis=0)[0] # the three smallest values smax = numpy.sort(max_coords, axis=0)[-1] # the three largest values for c in self.collectors: c.init_histogram(smin=smin, smax=smax) # also guarantees compatible grid self.densities = {} # densities will be stored with mode as key
def __init__(self, *args, **kwargs): """Calculate native contacts within a group or between two groups. :Arguments: *topology* psf or pdb file *trajectory* dcd or xtc/trr file *universe* instead of a topology/trajectory combination, one can also supply a :class:`MDAnalysis.Universe` :Keywords: *selection* selection string that determines which distances are calculated; if this is a tuple or list with two entries then distances are calculated between these two different groups ["name CA or name B*"] *refgroup* reference group, either a single :class:`~MDAnalysis.core.AtomGroup.AtomGroup` (if there is only a single *selection*) or a list of two such groups. The reference contacts are directly computed from *refgroup* and hence the atoms in the reference group(s) must be equivalent to the ones produced by the *selection* on the input trajectory. *radius* contacts are deemed any atoms within radius [8.0 A] *outfile* name of the output file; with the gz or bz2 suffix, a compressed file is written. The average <q> is written to a second, gzipped file that has the same name with 'array' included. E.g. for the default name "q1.dat.gz" the <q> file will be "q1.array.gz". The format is the matrix in column-row format, i.e. selection 1 residues are the columns and selection 2 residues are rows. The file can be read with :func:`numpy.loadtxt`. ["q1.dat.gz"] The function calculates the percentage of native contacts q1 along a trajectory. "Contacts" are defined as the number of atoms within *radius* of a given other atom. *q1* is the fraction of contacts relative to the reference state 1 (typically the starting conformation of the trajectory). The timeseries is written to a file *outfile* and is also accessible as the attribute :attr:`ContactAnalysis1.timeseries`. """ # XX or should I use as input # sel = (group1, group2), ref = (refgroup1, refgroup2) # and get the universe from sel? # Currently it's a odd hybrid. # # Enhancements: # - select contact pairs to write out as a timecourse # - make this selection based on qavg from os.path import splitext self.selection_strings = self._return_tuple2(kwargs.pop('selection', "name CA or name B*"), "selection") self.references = self._return_tuple2(kwargs.pop('refgroup', None), "refgroup") self.radius = kwargs.pop('radius', 8.0) self.targetdir = kwargs.pop('targetdir', os.path.curdir) self.output = kwargs.pop('outfile', "q1.dat.gz") self.outarray = splitext(splitext(self.output)[0])[0] + ".array.gz" self.force = kwargs.pop('force', False) self.timeseries = None # final result self.filenames = args self.universe = MDAnalysis.asUniverse(*args, **kwargs) self.selections = [self.universe.selectAtoms(s) for s in self.selection_strings] # sanity checkes for x in self.references: if x is None: raise ValueError("a reference AtomGroup must be supplied") for ref, sel, s in izip(self.references, self.selections, self.selection_strings): if ref.atoms.numberOfAtoms() != sel.atoms.numberOfAtoms(): raise ValueError("selection=%r: Number of atoms differ between " "reference (%d) and trajectory (%d)" % (s, ref.atoms.numberOfAtoms(), sel.atoms.numberOfAtoms())) # compute reference contacts dref = MDAnalysis.core.distances.distance_array( self.references[0].coordinates(), self.references[1].coordinates()) self.qref = self.qarray(dref) self.nref = self.qref.sum() # setup arrays for the trajectory self.d = numpy.zeros_like(dref) self.q = self.qarray(self.d) self._qtmp = numpy.zeros_like(self.q) # pre-allocated array self.qavg = numpy.zeros(shape=self.q.shape, dtype=numpy.float64)