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
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
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. """ from MDAnalysis import asUniverse u = asUniverse(pdb) group = u.selectAtoms(atomselection) coord = group.coordinates() logger.info("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 = "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 = 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['pdb'] = pdb except TypeError: metadata = {'pdb': pdb} metadata['atomselection'] = atomselection metadata['numframes'] = numframes metadata['sigma'] = sigma self.metadata = metadata logger.info("Histogram completed (initial density in Angstrom**-3)")
def density_from_Universe(universe, delta=1.0, atomselection='name OH2', metadata=None, padding=2.0, cutoff=0, soluteselection=None, use_kdtree=True, **kwargs): """Create a density grid from a MDAnalysis.Universe object. density_from_Universe(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 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) 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] parameters dict with some special parameters for :class:`Density` (see doc) kwargs metadata, parameters are modified and passed on to :class:`Density` :Returns: :class:`Density` """ try: universe.selectAtoms('all') universe.trajectory.ts except AttributeError: raise TypeError("The universe must be a proper MDAnalysis.Universe instance.") 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., 90., 90.): msg = "Non-orthorhombic unit-cell --- make sure that it has been remapped properly!" warnings.warn(msg) logger.warn(msg) # 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() for ts in u.trajectory: print "Histograming %6d atoms in frame %5d/%d [%5.1f%%]\r" % \ (len(coord), ts.frame, u.trajectory.numframes, 100.0 * ts.frame / u.trajectory.numframes), coord = current_coordinates() if len(coord) == 0: continue h[:], edges[:] = numpy.histogramdd(coord, bins=bins, range=arange, normed=False) grid += h # accumulate average histogram print numframes = u.trajectory.numframes / u.trajectory.skip grid /= float(numframes) # pick from kwargs metadata = kwargs.pop('metadata', {}) metadata['psf'] = u.filename metadata['dcd'] = u.trajectory.filename metadata['atomselection'] = atomselection metadata['numframes'] = numframes metadata['totaltime'] = round(u.trajectory.numframes * u.trajectory.dt, 3) metadata['dt'] = u.trajectory.dt metadata['time_unit'] = MDAnalysis.core.flags['time_unit'] metadata['trajectory_skip'] = u.trajectory.skip_timestep # frames metadata['trajectory_delta'] = u.trajectory.delta # in native units 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 g = Density(grid=grid, edges=edges, units={'length': MDAnalysis.core.flags['length_unit']}, parameters=parameters, metadata=metadata) g.make_density() logger.info("Density completed (initial density in Angstrom**-3)") return g