示例#1
0
    def init_histogram(self, **kwargs):
        # needs to be done separately because we might need additional information
        # after init (at least I cannot think of a better way...)
        smin = kwargs.pop("smin", self.min_coordinates(padding=self.padding))
        smax = kwargs.pop("smax", self.max_coordinates(padding=self.padding))

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

        # create empty grid with the right dimensions (and get the edges)
        grid, edges = numpy.histogramdd(numpy.zeros((1, 3)), bins=self.bins, range=self.arange, normed=False)
        grid *= 0.0
        h = grid.copy()

        self.grid = grid
        self.edges = edges
        self._h = h  # temporary for accumulation
示例#2
0
def density_from_Universe(
    universe,
    delta=1.0,
    atomselection="name OH2",
    metadata=None,
    padding=2.0,
    cutoff=0,
    soluteselection=None,
    verbosity=3,
    use_kdtree=True,
    **kwargs
):
    """Create a density grid from a MDAnalysis.Universe object.

      density_from_dcd(universe, delta=1.0, atomselection='name OH2', ...) --> density

    :Arguments:
      universe
            :class:`MDAnalysis.Universe` object with a trajectory

    :Keywords:
      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]
      parameters
            dict with some special parameters for :class:`~hop.sitemap.Density` (see doc)
      kwargs
            metadata, parameters are modified and passed on to :class:`~hop.sitemap.Density`

    :Returns: :class:`hop.sitemap.Density`

    """
    try:
        universe.selectAtoms("all")
        universe.trajectory.ts
    except AttributeError:
        errmsg = "density_from_Universe(): The universe must be a proper MDAnalysis.Universe instance."
        logger.fatal(errmsg)
        raise TypeError(errmsg)
    u = universe
    if cutoff > 0 and soluteselection is not None:
        # special fast selection for '<atomsel> not within <cutoff> of <solutesel>'
        notwithin_coordinates = notwithin_coordinates_factory(
            u, atomselection, soluteselection, cutoff, use_kdtree=use_kdtree
        )

        def current_coordinates():
            return notwithin_coordinates()

    else:
        group = u.selectAtoms(atomselection)

        def current_coordinates():
            return group.coordinates()

    coord = current_coordinates()
    logger.info(
        "Selected %d atoms out of %d atoms (%s) from %d total.",
        coord.shape[0],
        len(u.selectAtoms(atomselection)),
        atomselection,
        len(u.atoms),
    )

    # mild warning; typically this is run on RMS-fitted trajectories and
    # so the box information is rather meaningless
    box, angles = u.trajectory.ts.dimensions[:3], u.trajectory.ts.dimensions[3:]
    if tuple(angles) <> (90.0, 90.0, 90.0):
        logger.warn("Non-orthorhombic unit-cell --- make sure that it has been remapped properly!")

    # Make the box bigger to avoid as much as possible 'outlier'. This
    # is important if the sites are defined at a high density: in this
    # case the bulk regions don't have to be close to 1 * n0 but can
    # be less. It's much more difficult to deal with outliers.  The
    # ideal solution would use images: implement 'looking across the
    # periodic boundaries' but that gets complicate when the box
    # rotates due to RMS fitting.
    smin = numpy.min(coord, axis=0) - padding
    smax = numpy.max(coord, axis=0) + padding

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

    # create empty grid with the right dimensions (and get the edges)
    grid, edges = numpy.histogramdd(numpy.zeros((1, 3)), bins=bins, range=arange, normed=False)
    grid *= 0.0
    h = grid.copy()

    pm = CustomProgressMeter(
        u.trajectory.numframes,
        interval=10,
        format="Histograming %(other)d atoms in frame %(step)5d/%(numsteps)d  [%(percentage)5.1f%%]\r",
    )
    for ts in u.trajectory:
        coord = current_coordinates()
        if len(coord) == 0:
            continue
        h[:], edges[:] = numpy.histogramdd(coord, bins=bins, range=arange, normed=False)
        grid += h  # accumulate average histogram
        pm.echo(ts.frame, len(coord))
    numframes = u.trajectory.numframes / u.trajectory.skip
    grid /= float(numframes)

    # pick from kwargs
    metadata = kwargs.pop("metadata", {})
    metadata["psf"] = u.filename  # named psf for historical reasons
    metadata["dcd"] = u.trajectory.filename  # named dcd for historical reasons
    metadata["atomselection"] = atomselection
    metadata["numframes"] = numframes
    metadata["totaltime"] = round(
        u.trajectory.numframes
        * u.trajectory.delta
        * u.trajectory.skip_timestep
        * hop.constants.get_conversion_factor("time", "AKMA", "ps"),
        3,
    )
    metadata["dt"] = (
        u.trajectory.delta * u.trajectory.skip_timestep * hop.constants.get_conversion_factor("time", "AKMA", "ps")
    )
    metadata["time_unit"] = "ps"
    metadata["dcd_skip"] = u.trajectory.skip_timestep  # frames
    metadata["dcd_delta"] = u.trajectory.delta  # in AKMA
    if cutoff > 0 and soluteselection is not None:
        metadata["soluteselection"] = soluteselection
        metadata["cutoff"] = cutoff  # in Angstrom

    parameters = kwargs.pop("parameters", {})
    parameters["isDensity"] = False  # must override

    # all other kwargs are discarded

    # Density automatically converts histogram to density for isDensity=False
    g = Density(grid=grid, edges=edges, unit=dict(length="Angstrom"), parameters=parameters, metadata=metadata)
    logger.info("Histogram completed (initial density in Angstrom**-3)")

    return g
示例#3
0
    def __init__(
        self, psf, pdb, delta=1.0, atomselection="name OH2", metadata=None, padding=4.0, sigma=None, verbosity=3
    ):
        """Construct the density from psf and pdb and the atomselection.

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

        psf     Charmm psf topology file
        pdb     PDB file
        atomselection
                selection string (MDAnalysis syntax) for the species to be analyzed
        delta   approximate bin size for the density grid (same in x,y,z)
                (It is slightly adjusted when the box length is not an integer multiple
                of delta.)
        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
        verbosity=int  level of chattiness; 0 is silent, 3 is verbose

        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.

        """
        from MDAnalysis import Universe

        set_verbosity(verbosity)  # set to 0 for no messages
        u = Universe(psf, pdbfilename=pdb)
        group = u.selectAtoms(atomselection)
        coord = group.coordinates()
        logger.info(
            "BfactorDensityCreator: Selected %d atoms (%s) out of %d total.",
            coord.shape[0],
            atomselection,
            len(u.atoms),
        )
        smin = numpy.min(coord, axis=0) - padding
        smax = numpy.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 = numpy.histogramdd(numpy.zeros((1, 3)), bins=bins, range=arange, normed=False)
        self.delta = numpy.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)
        numframes = 1

        if sigma is None:
            # histogram individually, and smear out at the same time
            # with the appropriate B-factor
            if numpy.any(group.bfactors == 0.0):
                wmsg = "BfactorDensityCreator: Some B-factors are Zero."
                warnings.warn(wmsg, category=hop.MissingDataWarning)
                logger.warn(wmsg)
            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 = numpy.histogramdd(coord, bins=bins, range=arange, normed=False)
            logger.info("Histogrammed %6d atoms from pdb.", len(group.atoms))
            # just a convolution of the density with a Gaussian
            self.g = self._smear_sigma(grid, sigma)

        try:
            metadata["psf"] = psf
        except TypeError:
            metadata = dict(psf=psf)
        metadata["pdb"] = pdb
        metadata["atomselection"] = atomselection
        metadata["numframes"] = numframes
        metadata["sigma"] = sigma
        self.metadata = metadata

        # Density automatically converts histogram to density for isDensity=False
        logger.info("BfactorDensityCreator: Histogram completed (initial density in Angstrom**-3)\n")