def create(self): """Loop through trajectory and build all densities. .. SeeAlso:: :class:`DensityCollector` """ u = self.universe pm = CustomProgressMeter( u.trajectory.numframes, interval=10, format="Histogramming %(other)s atoms in frame %(step)5d/%(numsteps)d [%(percentage)5.1f%%]\r", ) for ts in u.trajectory: status = "" for c in self.collectors: natoms = c.collect() status += "%s=%d " % (c.name, natoms) pm.echo(ts.frame, status) self.densities = {} for c in self.collectors: c.finish() self.densities[c.name] = c.Density() # should save precious files!!! return self.densities
def _smear_rmsf(self, coordinates, grid, edges, rmsf): # smear out each water with its individual Gaussian # (slower than smear_sigma) g = numpy.zeros(grid.shape) # holds the smeared out density N, D = coordinates.shape pm = CustomProgressMeter( N, interval=1, offset=1, format="Smearing out water position %(step)4d/%(numsteps)5d with RMSF %(other)4.2f A [%(percentage)5.2f%%\r", ) for iwat, coord in enumerate(coordinates): g += numpy.fromfunction(self._gaussian_cartesian, grid.shape, dtype=numpy.int, c=coord, sigma=rmsf[iwat]) pm.echo(iwat, rmsf[iwat]) return g
def _smear_sigma(self, grid, sigma): # smear out points # (not optimized -- just to test the principle; faster approach could use # convolution of the whole density with a single Gaussian via FFTs: # rho_smeared = F^-1[ F[g]*F[rho] ] g = numpy.zeros(grid.shape) # holds the smeared out density pos = numpy.where(grid <> 0) # position in histogram (as bin numbers) pm = CustomProgressMeter( len(pos[0]), interval=1, offset=1, format="Smearing out water position %(step)4d/%(numsteps)5d with RMSF %(other)4.2f A [%(percentage)5.2f%%\r", ) for iwat in xrange(len(pos[0])): # super-ugly loop p = tuple([wp[iwat] for wp in pos]) g += grid[p] * numpy.fromfunction(self._gaussian, grid.shape, dtype=numpy.int, p=p, sigma=sigma) pm.echo(iwat, sigma) return g
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