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)
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)")
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)")
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
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)")
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)
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)
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
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)")