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.select_atoms` 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.as_Universe(universe)
        self.universe = universe
        self.selectionstring = selectionstring
        if type(self.selectionstring) == MDAnalysis.core.AtomGroup.AtomGroup:
            self.selection = self.selectionstring
        else:
            self.selection = universe.select_atoms(self.selectionstring)
        self.pbc = pbc
        self.sparse = sparse
        self._init_graph(cutoff)
Exemple #2
0
    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.select_atoms` 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.as_Universe(universe)
        self.universe = universe
        self.selectionstring = selectionstring
        if type(self.selectionstring) == MDAnalysis.core.AtomGroup.AtomGroup:
            self.selection = self.selectionstring
        else:
            self.selection = universe.select_atoms(self.selectionstring)
        self.pbc = pbc
        self.sparse = sparse
        self._init_graph(cutoff)
Exemple #3
0
    def __init__(self, pdb, delta=1.0, select='resname HOH and name O',
                 metadata=None, padding=1.0, sigma=None):
        """Construct the density from psf and pdb and the select.

        Parameters
        ----------
        pdb : str
            PDB file or :class:`MDAnalysis.Universe`;
        select : str
            selection string (MDAnalysis syntax) for the species to be analyzed
        delta : float
            bin size for the density grid in Angstrom (same in x,y,z) [1.0]
        metadata : dict
            dictionary of additional data to be saved with the object
        padding : float
            increase histogram dimensions by padding (on top of initial box size)
        sigma : float
            width (in Angstrom) of the gaussians that are used to build up the
            density; if ``None`` (the default) then uses B-factors from pdb


        Notes
        -----
        For assigning X-ray waters to MD densities one might have to use a sigma
        of about 0.5 A to obtain a well-defined and resolved x-ray water density
        that can be easily matched to a broader density distribution.

        .. versionchanged:: 1.0.0
           Changed `selection` keyword to `select`

        Examples
        --------
        The following creates the density with the B-factors from the pdb file::

          DC = BfactorDensityCreator(pdb, delta=1.0, select="name HOH",
                                     padding=2, sigma=None)
          density = DC.Density()

        See Also
        --------
        :func:`density_from_PDB` for a convenience function

        """
        u = MDAnalysis.as_Universe(pdb)
        group = u.select_atoms(select)
        coord = group.positions
        logger.info("Selected {0:d} atoms ({1!s}) out of {2:d} total.".format(coord.shape[0], select, len(u.atoms)))
        smin = np.min(coord, axis=0) - padding
        smax = np.max(coord, axis=0) + padding

        BINS = fixedwidth_bins(delta, smin, smax)
        arange = list(zip(BINS['min'], BINS['max']))
        bins = BINS['Nbins']

        # get edges by doing a fake run
        grid, self.edges = np.histogramdd(np.zeros((1, 3)),
                                             bins=bins, range=arange, normed=False)
        self.delta = np.diag([(e[-1] - e[0]) / (len(e) - 1) for e in self.edges])
        self.midpoints = [0.5 * (e[:-1] + e[1:]) for e in self.edges]
        self.origin = [m[0] for m in self.midpoints]
        n_frames = 1

        if sigma is None:
            # histogram individually, and smear out at the same time
            # with the appropriate B-factor
            if np.any(group.bfactors == 0.0):
                wmsg = "Some B-factors are Zero (will be skipped)."
                logger.warning(wmsg)
                warnings.warn(wmsg, category=MissingDataWarning)
            rmsf = Bfactor2RMSF(group.bfactors)
            grid *= 0.0  # reset grid
            self.g = self._smear_rmsf(coord, grid, self.edges, rmsf)
        else:
            # histogram 'delta functions'
            grid, self.edges = np.histogramdd(coord, bins=bins, range=arange, normed=False)
            logger.info("Histogrammed {0:6d} atoms from pdb.".format(len(group.atoms)))
            # just a convolution of the density with a Gaussian
            self.g = self._smear_sigma(grid, sigma)

        try:
            metadata['pdb'] = pdb
        except TypeError:
            metadata = {'pdb': pdb}
        metadata['select'] = select
        metadata['n_frames'] = n_frames
        metadata['sigma'] = sigma
        self.metadata = metadata

        logger.info("Histogram completed (initial density in Angstrom**-3)")
Exemple #4
0
    def __init__(self, pdb, delta=1.0, atomselection='resname HOH and name O',
                 metadata=None, padding=1.0, sigma=None):
        """Construct the density from psf and pdb and the atomselection.

        Parameters
        ----------
        pdb : str
            PDB file or :class:`MDAnalysis.Universe`;
        atomselection : str
            selection string (MDAnalysis syntax) for the species to be analyzed
        delta : float
            bin size for the density grid in Angstroem (same in x,y,z) [1.0]
        metadata : dict
            dictionary of additional data to be saved with the object
        padding : float
            increase histogram dimensions by padding (on top of initial box size)
        sigma : float
            width (in Angstrom) of the gaussians that are used to build up the
            density; if ``None`` (the default) then uses B-factors from pdb


        Notes
        -----
        For assigning X-ray waters to MD densities one might have to use a sigma
        of about 0.5 A to obtain a well-defined and resolved x-ray water density
        that can be easily matched to a broader density distribution.

        Examples
        --------
        The following creates the density with the B-factors from the pdb file::

          DC = BfactorDensityCreator(pdb, delta=1.0, atomselection="name HOH",
                                     padding=2, sigma=None)
          density = DC.Density()

        See Also
        --------
        :func:`density_from_PDB` for a convenience function

        """
        u = MDAnalysis.as_Universe(pdb)
        group = u.select_atoms(atomselection)
        coord = group.positions
        logger.info("Selected {0:d} atoms ({1!s}) out of {2:d} total.".format(coord.shape[0], atomselection, len(u.atoms)))
        smin = np.min(coord, axis=0) - padding
        smax = np.max(coord, axis=0) + padding

        BINS = fixedwidth_bins(delta, smin, smax)
        arange = list(zip(BINS['min'], BINS['max']))
        bins = BINS['Nbins']

        # get edges by doing a fake run
        grid, self.edges = np.histogramdd(np.zeros((1, 3)),
                                             bins=bins, range=arange, normed=False)
        self.delta = np.diag([(e[-1] - e[0]) / (len(e) - 1) for e in self.edges])
        self.midpoints = [0.5 * (e[:-1] + e[1:]) for e in self.edges]
        self.origin = [m[0] for m in self.midpoints]
        n_frames = 1

        if sigma is None:
            # histogram individually, and smear out at the same time
            # with the appropriate B-factor
            if np.any(group.bfactors == 0.0):
                wmsg = "Some B-factors are Zero (will be skipped)."
                logger.warning(wmsg)
                warnings.warn(wmsg, category=MissingDataWarning)
            rmsf = Bfactor2RMSF(group.bfactors)
            grid *= 0.0  # reset grid
            self.g = self._smear_rmsf(coord, grid, self.edges, rmsf)
        else:
            # histogram 'delta functions'
            grid, self.edges = np.histogramdd(coord, bins=bins, range=arange, normed=False)
            logger.info("Histogrammed {0:6d} atoms from pdb.".format(len(group.atoms)))
            # just a convolution of the density with a Gaussian
            self.g = self._smear_sigma(grid, sigma)

        try:
            metadata['pdb'] = pdb
        except TypeError:
            metadata = {'pdb': pdb}
        metadata['atomselection'] = atomselection
        metadata['n_frames'] = n_frames
        metadata['sigma'] = sigma
        self.metadata = metadata

        logger.info("Histogram completed (initial density in Angstrom**-3)")
Exemple #5
0
    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.as_Universe(*args, **universe_kwargs)
        self.mode = kwargs.pop("mode", "all")  # 'all' runs modes[1:]
        if not self.mode in self.modes:
            errmsg = "DensityCreator: mode must be one of %r, not %r" % (self.modes, self.mode)
            logger.fatal(errmsg)
            raise ValueError(errmsg)
        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
Exemple #6
0
    def __init__(self, pdb, delta=1.0, atomselection='resname HOH and name O',
                 metadata=None, padding=1.0, sigma=None):
        """Construct the density from psf and pdb and the atomselection.

          DC = BfactorDensityCreator(pdb, delta=<delta>, atomselection=<MDAnalysis selection>,
                                  metadata=<dict>, padding=2, sigma=None)

          density = DC.Density()

        :Arguments:

          pdb
            PDB file or :class:`MDAnalysis.Universe`; a PDB is read with the
            simpl PDB reader. If the Bio.PDB reader is required, either set
            the *permissive_pdb_reader* flag to ``False`` in
            :data:`MDAnalysis.core.flags` or supply a Universe
            that was created with the `permissive` = ``False`` keyword.
          atomselection
            selection string (MDAnalysis syntax) for the species to be analyzed
          delta
            bin size for the density grid in Angstroem (same in x,y,z) [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)
          sigma
            width (in Angstrom) of the gaussians that are used to build up the
            density; if None then uses B-factors from pdb

        For assigning X-ray waters to MD densities one might have to use a sigma
        of about 0.5 A to obtain a well-defined and resolved x-ray water density
        that can be easily matched to a broader density distribution.

        """
        u = MDAnalysis.as_Universe(pdb)
        group = u.select_atoms(atomselection)
        coord = group.coordinates()
        logger.info("Selected {0:d} atoms ({1!s}) out of {2:d} total.".format(coord.shape[0], atomselection, len(u.atoms)))
        smin = np.min(coord, axis=0) - padding
        smax = np.max(coord, axis=0) + padding

        BINS = fixedwidth_bins(delta, smin, smax)
        arange = zip(BINS['min'], BINS['max'])
        bins = BINS['Nbins']

        # get edges by doing a fake run
        grid, self.edges = np.histogramdd(np.zeros((1, 3)),
                                             bins=bins, range=arange, normed=False)
        self.delta = np.diag(map(lambda e: (e[-1] - e[0]) / (len(e) - 1), self.edges))
        self.midpoints = map(lambda e: 0.5 * (e[:-1] + e[1:]), self.edges)
        self.origin = map(lambda m: m[0], self.midpoints)
        n_frames = 1

        if sigma is None:
            # histogram individually, and smear out at the same time
            # with the appropriate B-factor
            if np.any(group.bfactors == 0.0):
                wmsg = "Some B-factors are Zero (will be skipped)."
                logger.warn(wmsg)
                warnings.warn(wmsg, category=MissingDataWarning)
            rmsf = Bfactor2RMSF(group.bfactors)
            grid *= 0.0  # reset grid
            self.g = self._smear_rmsf(coord, grid, self.edges, rmsf)
        else:
            # histogram 'delta functions'
            grid, self.edges = np.histogramdd(coord, bins=bins, range=arange, normed=False)
            logger.info("Histogrammed {0:6d} atoms from pdb.".format(len(group.atoms)))
            # just a convolution of the density with a Gaussian
            self.g = self._smear_sigma(grid, sigma)

        try:
            metadata['pdb'] = pdb
        except TypeError:
            metadata = {'pdb': pdb}
        metadata['atomselection'] = atomselection
        metadata['n_frames'] = n_frames
        metadata['sigma'] = sigma
        self.metadata = metadata

        logger.info("Histogram completed (initial density in Angstrom**-3)")
Exemple #7
0
    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:`np.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`.

        .. deprecated: 0.14.0

        """

        # 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

        warnings.warn(
            "ContactAnalysis1 is deprecated and will be removed "
            "in 1.0. Use Contacts instead.",
            category=DeprecationWarning)

        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.as_Universe(*args, **kwargs)

        self.selections = [
            self.universe.select_atoms(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 zip(self.references, self.selections,
                               self.selection_strings):
            if ref.atoms.n_atoms != sel.atoms.n_atoms:
                raise ValueError("selection=%r: Number of atoms differ "
                                 "between reference (%d) and trajectory (%d)" %
                                 (s, ref.atoms.n_atoms, sel.atoms.n_atoms))

        # compute reference contacts
        dref = MDAnalysis.lib.distances.distance_array(
            self.references[0].positions, self.references[1].positions)
        self.qref = self.qarray(dref)
        self.nref = self.qref.sum()

        # setup arrays for the trajectory
        self.d = np.zeros_like(dref)
        self.q = self.qarray(self.d)
        self._qtmp = np.zeros_like(self.q)  # pre-allocated array

        self.qavg = np.zeros(shape=self.q.shape, dtype=np.float64)
Exemple #8
0
    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:`np.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.as_Universe(*args, **kwargs)

        self.selections = [self.universe.select_atoms(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.n_atoms != sel.atoms.n_atoms:
                raise ValueError(
                    "selection=%r: Number of atoms differ between "
                    "reference (%d) and trajectory (%d)" % (s, ref.atoms.n_atoms, sel.atoms.n_atoms)
                )

        # compute reference contacts
        dref = MDAnalysis.lib.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 = np.zeros_like(dref)
        self.q = self.qarray(self.d)
        self._qtmp = np.zeros_like(self.q)  # pre-allocated array

        self.qavg = np.zeros(shape=self.q.shape, dtype=np.float64)
Exemple #9
0
    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.as_Universe(*args, **universe_kwargs)
        self.mode = kwargs.pop("mode", "all")  # 'all' runs modes[1:]
        if not self.mode in self.modes:
            errmsg = "DensityCreator: mode must be one of %r, not %r" % (
                self.modes, self.mode)
            logger.fatal(errmsg)
            raise ValueError(errmsg)
        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
Exemple #10
0
    def __init__(self,
                 pdb,
                 delta=1.0,
                 atomselection='resname HOH and name O',
                 metadata=None,
                 padding=1.0,
                 sigma=None):
        """Construct the density from psf and pdb and the atomselection.

          DC = BfactorDensityCreator(pdb, delta=<delta>, atomselection=<MDAnalysis selection>,
                                  metadata=<dict>, padding=2, sigma=None)

          density = DC.Density()

        :Arguments:

          pdb
            PDB file or :class:`MDAnalysis.Universe`; a PDB is read with the
            simpl PDB reader. If the Bio.PDB reader is required, either set
            the *permissive_pdb_reader* flag to ``False`` in
            :data:`MDAnalysis.core.flags` or supply a Universe
            that was created with the `permissive` = ``False`` keyword.
          atomselection
            selection string (MDAnalysis syntax) for the species to be analyzed
          delta
            bin size for the density grid in Angstroem (same in x,y,z) [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)
          sigma
            width (in Angstrom) of the gaussians that are used to build up the
            density; if None then uses B-factors from pdb

        For assigning X-ray waters to MD densities one might have to use a sigma
        of about 0.5 A to obtain a well-defined and resolved x-ray water density
        that can be easily matched to a broader density distribution.

        """
        u = MDAnalysis.as_Universe(pdb)
        group = u.select_atoms(atomselection)
        coord = group.coordinates()
        logger.info("Selected {0:d} atoms ({1!s}) out of {2:d} total.".format(
            coord.shape[0], atomselection, len(u.atoms)))
        smin = np.min(coord, axis=0) - padding
        smax = np.max(coord, axis=0) + padding

        BINS = fixedwidth_bins(delta, smin, smax)
        arange = zip(BINS['min'], BINS['max'])
        bins = BINS['Nbins']

        # get edges by doing a fake run
        grid, self.edges = np.histogramdd(np.zeros((1, 3)),
                                          bins=bins,
                                          range=arange,
                                          normed=False)
        self.delta = np.diag(
            map(lambda e: (e[-1] - e[0]) / (len(e) - 1), self.edges))
        self.midpoints = map(lambda e: 0.5 * (e[:-1] + e[1:]), self.edges)
        self.origin = map(lambda m: m[0], self.midpoints)
        n_frames = 1

        if sigma is None:
            # histogram individually, and smear out at the same time
            # with the appropriate B-factor
            if np.any(group.bfactors == 0.0):
                wmsg = "Some B-factors are Zero (will be skipped)."
                logger.warn(wmsg)
                warnings.warn(wmsg, category=MissingDataWarning)
            rmsf = Bfactor2RMSF(group.bfactors)
            grid *= 0.0  # reset grid
            self.g = self._smear_rmsf(coord, grid, self.edges, rmsf)
        else:
            # histogram 'delta functions'
            grid, self.edges = np.histogramdd(coord,
                                              bins=bins,
                                              range=arange,
                                              normed=False)
            logger.info("Histogrammed {0:6d} atoms from pdb.".format(
                len(group.atoms)))
            # just a convolution of the density with a Gaussian
            self.g = self._smear_sigma(grid, sigma)

        try:
            metadata['pdb'] = pdb
        except TypeError:
            metadata = {'pdb': pdb}
        metadata['atomselection'] = atomselection
        metadata['n_frames'] = n_frames
        metadata['sigma'] = sigma
        self.metadata = metadata

        logger.info("Histogram completed (initial density in Angstrom**-3)")