def __init__(self,hopgraph,dir=".",verbosity=3): """Analyse hopgraph. a = HopgraphAnalysis(hopgraph) The show() method prints statistics on the HoppingGraph and histograms() produces a number of plots as pdf files in the current directory. :Arguments: hopgraph can be the name of a pickled file or a HoppingGraph instance dir save figures in this directory verbosity=3 chattiness :Attributes: S statistics dictionary (see keys for explanation) D raw data dictionary :Methods: all() show() and histograms() show() print stats histograms() produce histograms """ set_verbosity(verbosity) h = hop.utilities.easy_load(hopgraph,hop.graph.HoppingGraph,'stats') self.pdf = {'degree':'degree.pdf', 'occupancy':'occupancy.pdf', 'lifetime':'lifetime.pdf', } self.D = {} self.S = h.stats(data=self.D) # pulls out all the statistics from graph for k,v in self.pdf.items(): self.pdf[k] = os.path.join(dir,v)
def run(self,Ntotal=500000,Nskip=1000,verbosity=None): """MCMC run multiple cycles of lebgth <Nskip> scans for a total of <Ntotal>. run(Ntotal=500000,Nskip=1000) Starts from the current configuration in state. Creates the collection of configurations states: one state every Nskip steps """ set_verbosity(verbosity) Ntotal = int(Ntotal) Nskip = int(Nskip) Ncycle = int(Ntotal/Nskip) self.runparameters = {'Ntotal':Ntotal,'Nskip':Nskip,'Ncycle':Ncycle} state_list = [] msg(1,"Running MCMC:\n\tNtotal = %(Ntotal)d\n\tSaving state every cycle of Nskip steps = %(Nskip)d\n\t" "Hence in total Ncycle cycles = %(Ncycle)d\n" % locals()) for i in xrange(1,Ncycle+1): msg(3,"cycle %(i)4d/%(Ncycle)4d\r" % locals()) self.sample(Nskip) state_list.append(self.statevector) msg(3,"\n") if len(self.states) == 0: self.states = numpy.array(state_list) else: msg(2,"Extending states from %d configurations by %d new ones." \ % (len(self.states), len(state_list))) self.states = numpy.concatenate((self.states, numpy.array(state_list)))
def write(self,filename,start=None,step=None,delta=None,load=True): """Write hopping trajectory as standard dcd file. write('TAP') :Arguments: load = True Immediately loads the trajectory so that further calls to next() will use the computed trajectory and don't use expensive mapping. Ignore the other options and leave them at the defaults. Currently, only the whole trajectory is written. All atoms in the original trajectory are written to the output so you should be able to use your original psf file. NOTE: Fixed atoms are possibly not accounted for properly. Note that it is your responsibility to load the TAP trajectory and the appropriate psf together as there is very limited information stored in the dcd itself. """ set_verbosity(self.verbosity) # this is stupid psfname = self.filename(filename,'psf') dcdname = self.filename(filename,'dcd') # see MDAnalysis/src/dcd/dcd.c for explanations if start is None: start = self.traj.start_timestep # starting time step for DCD file if step is None: step = self.traj.skip_timestep # NSAVC (# ts between written DCD frames) if delta is None: delta = self.traj.delta # length of ts (AKMA units) dcdwriter = MDAnalysis.DCD.DCDWriter(dcdname,self.ts.numatoms, start,step,delta, remarks='TAP trajectory') pm = ProgressMeter(self.numframes, interval=10, format="Mapping TAP frame %(step)5d/%(numsteps)6d [%(percentage)5.1f%%]\r") for ts in self.map_dcd(): dcdwriter.write_next_timestep(ts) pm.echo(ts.frame) dcdwriter.close() logger.info("TAPTrajectory.write(): wrote TAP traj %r.", dcdname) if load is True: self.TAPtraj = MDAnalysis.DCD.DCDReader(dcdname) self.trajectory = self.TAPtraj
def run(self, Ntotal=500000, Nskip=1000, verbosity=None): """MCMC run multiple cycles of lebgth <Nskip> scans for a total of <Ntotal>. run(Ntotal=500000,Nskip=1000) Starts from the current configuration in state. Creates the collection of configurations states: one state every Nskip steps """ set_verbosity(verbosity) Ntotal = int(Ntotal) Nskip = int(Nskip) Ncycle = int(Ntotal / Nskip) self.runparameters = { 'Ntotal': Ntotal, 'Nskip': Nskip, 'Ncycle': Ncycle } state_list = [] msg( 1, "Running MCMC:\n\tNtotal = %(Ntotal)d\n\tSaving state every cycle of Nskip steps = %(Nskip)d\n\t" "Hence in total Ncycle cycles = %(Ncycle)d\n" % locals()) for i in xrange(1, Ncycle + 1): msg(3, "cycle %(i)4d/%(Ncycle)4d\r" % locals()) self.sample(Nskip) state_list.append(self.statevector) msg(3, "\n") if len(self.states) == 0: self.states = numpy.array(state_list) else: msg(2,"Extending states from %d configurations by %d new ones." \ % (len(self.states), len(state_list))) self.states = numpy.concatenate( (self.states, numpy.array(state_list)))
def density_from_volmap(psf, dcd, dx=None, delta=1.0, atomselection="name OH2", metadata=None, verbosity=3, **kwargs): """Create the density using VMD's VolMap plugin and an intermediate dx file. density_from_volmap(psf,dcd,dx,delta=1.0,atomselection='name OH2', metadata=dict(psf=psf,dcd=dcd,system='I-FABP apo') psf Charmm psf topology file dcd Charmm trajectory dx dx file that holds the density generated by VolMap; if not provided a temporary file is created (and deleted) 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.) verbosity=int level of chattiness; 0 is silent, 3 is verbose **kwargs metadata and parameters are passed to Density(), everything else to VolMap Density args: metadata dictionary of additional data to be saved with the object parameters dict of special Density parameters (see Density() doc) VolMap args: load_new True: load psf and dcd into VMD. False: use psf and dcd already loaded into VMD (default is True) Returns a Density object. """ import hop.external import tempfile set_verbosity(verbosity) # set to 0 for no messages # pick Density parameters from kwargs parameters = kwargs.pop("parameters", {}) metadata = kwargs.pop("metadata", {}) # ... everything else is VolMap args remove_dx = False if not dx: remove_dx = True dxhandle, dx = tempfile.mkstemp(".dx") logger.debug("Using tempororary dx file %r.", dx) logger.info("Connecting to VMD (ignore 'error: uncaptured python exception')") vmd = hop.external.VMD() logger.info("VolMap calculates the density. This takes a while...") vmd.volmap(psf, dcd, dx, delta=delta, atomselection=atomselection, **kwargs) metadata["psf"] = psf metadata["dcd"] = dcd metadata["vmd_dx"] = dx metadata["atomselection"] = atomselection parameters["isDensity"] = True # must override logger.info("Building density object from dx file '%(dx)s'...\n", vars()) g = Density(dxfile=dx, unit=dict(length="Angstrom", density="Angstrom"), parameters=parameters, metadata=metadata) if remove_dx: os.remove(dx) return g
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")
def __init__(self,trajectory=None,group=None,TAPradius=2.8,TAPsteps=3, filename=None,dcd=None,psf=None,fixtrajectory=None,verbosity=3): """A TAP trajectory object converts a trajectory into a TAP trajectory. Create from a coordinate trajectory of a group of water residues: u = MDAnalysis.Universe(psf,dcd) water = u.selectAtoms('resname TIP*') # see NOTE below!! water = u.selectAtoms('name OH2') # better, see NOTE below!! h = TAPtrajectory(trajectory=u.trajectory,group=water) Load from a saved hopping trajectory (in dcd format with dummy psf) h = TAPtrajectory(dcd='TAP.trajectory',psf='TAP.psf') The given atom group is filtered according to the Time-Averaged Positon algorithm (Henchman and McCammon, J Comp Chem 23 (2002), 861). Original positions are replaced by their TAPs: A particles last position (TAP) is retained unless it has moved farther than TAPradius from its TAP measured by its root mean square distance over the last TAPsteps frames. One can use a TAP filtered trajectory 'on-the-fly' to build the density: u = Universe(psf,dcd) oxy = u.selectAtoms('name OH2') TAP = TAPtrajectory(u.trajectory,oxy) u.trajectory = TAP.trajectory # <--- replace orig dcd with TAP !! dens = hop.sitemap.density_from_Universe(u,atomselection='name OH2') NOTE: In the current implementation residues are often ripped apart because all coordinates are processed independently. It is recommended to only do TAP on the water oxygens (for speed). This will create a trajectory in which hydrogens are always ripped from the oxygen but this trajectory is ONLY being used for creating a density from those oxygen using hop.sitemap.build_density(). (This could be fixed at the cost of speed; in this case TAP would be done on the centre of mass and the whole residue would be translated.) :Arguments: trajectory MDAnalysis.trajectory trajectory instance group MDAnalysis.group instance (from the same Universe as trajectory) TAPradius particles are considered to be on the TAP as long as they haven't moved farther than TAPradius over the last TAPsteps frames TAPsteps RMS distance of particle from TAP over TAPsteps is compared to TAPradius dcd dcd written by write() psf psf written by write() (or write_psf()) filename or simply provide one filename prefix for psf and dcd fixtrajectory dictionary with attributes of a dcd object and new values; used to provide correct values after using a catdcd-generated trajectory (hack!), e.g. fixtrajectory = {'delta':10.22741474887299} verbosity show status messages for >= 3 """ self.verbosity = verbosity set_verbosity(self.verbosity) if not (trajectory is None or group is None): self.traj = trajectory # MDAnalysis.Universe.trajectory self.tgroup = group # atom selection for trajectory self.tgroup_indices = self.tgroup.indices() # cache indices if not isinstance(self.tgroup,MDAnalysis.core.AtomGroup.AtomGroup): raise TypeError('group must be a <AtomGroup>, eg MDAnalyis.Universe.selectAtoms().') self.universe = self.tgroup.atoms[0].universe # Universe of dcd and group (hackish..) if isinstance(fixtrajectory,dict): for attr,val in fixtrajectory.items(): if not hasattr(trajectory,attr): raise AttributeError('fixtrajectory: dcd object does not have attribute "'\ +str(attr)+'"') trajectory.__dict__[attr] = val self.totaltime = totaltime(trajectory) self.traj.rewind() # make sure to start from frame 0 self.ts = self.traj.ts # output will look like input (no copy, see _coord2TAP!) self.TAPtraj = None # no TAP trajectory available self.TAPradius = TAPradius self.TAPsteps = TAPsteps # store last TAPsteps in __lastframes self.__lastframes = hop.utilities.Ringbuffer(self.TAPsteps) # store the last TAP coordinates: initialized here self.__currentTAP = self.tgroup.coordinates().copy() # fake DCD object that can be slotted into another universe self.dcd_attributes = {} for k in ['dcdfilename','delta','filename','fixed','numframes', 'numatoms','periodic','remarks', 'skip','skip_timestep','start_timestep']: self.dcd_attributes[k] = self.traj.__dict__[k] self.trajectory = ThinDCDReader(self) self.numframes = self.dcd_attributes['numframes'] elif not (dcd is None or psf is None) or filename is not None: # read from dcd try: self.traj,self.tgroup except AttributeError: self.traj,self.tgroup = [None] * 2 if filename is not None: psf = self.filename(filename,'psf') dcd = self.filename(filename,'dcd') u = MDAnalysis.Universe(psf,dcd) group = u.selectAtoms('type *') # TODO: why do I need this? self.group = group # group that refers to hopping trajectory self.TAPtraj = u.trajectory # DCD trajectory object self.ts = self.TAPtraj.ts self.numframes = self.TAPtraj.numframes self.totaltime = totaltime(self.TAPtraj) # DCD object that can be slotted into another universe self.trajectory = u.trajectory else: raise ValueError('Not sufficient data to create a TAP trajectory.')
def write(self,filename,start=None,step=None,delta=None,load=True): """Write hopping trajectory as standard dcd file, together with a minimal psf. write('hop') Arguments: load = True Immediately loads the trajectory so that further calls to next() will use the computed trajectory and don't use expensive mapping. Ignore the other options and leave them at the defaults. Currently, only the whole trajectory is written. For visualization one also needs the dummy psf of the group. Results: filename.trajectory and filename.psf Note that it is your responsibility to load the hopping trajectory and the appropriate psf together as there is very limited information stored in the dcd itself. """ set_verbosity(self.verbosity) # this is stupid psfname = self.filename(filename,'psf') dcdname = self.filename(filename,'dcd') # see MDAnalysis/src/dcd/dcd.c for explanations; # other trajectories do not have certain values so we just fake them... if start is None: try: start = self.traj.start_timestep # starting time step for DCD file except AttributeError: start = 1 if step is None: try: step = self.traj.skip_timestep # NSAVC (# ts between written DCD frames) except AttributeError: step = 1 if delta is None: from MDAnalysis.core.units import get_conversion_factor delta_ps = self.traj.convert_time_from_native(self.traj.delta) # length of ts in ps delta = get_conversion_factor('time', 'ps', 'AKMA') * delta_ps dcdwriter = MDAnalysis.coordinates.DCD.DCDWriter(dcdname,self.ts.numatoms, start,step,delta, remarks='Hopping trajectory: x=site y=orbit_site z=0') pm = ProgressMeter(self.numframes, interval=10, format="Mapping frame %(step)5d/%(numsteps)6d [%(percentage)5.1f%%]\r") for ts in self.map_dcd(): dcdwriter.write_next_timestep(ts) pm.echo(ts.frame) dcdwriter.close() logger.info("HoppingTrajectory.write(): wrote hoptraj %r.", dcdname) self.write_psf(psfname) logger.info("HoppingTrajectory.write(): wrote hoppsf %r.", psfname) if load is True: self.__init__(filename=filename,verbosity=self.verbosity)
def __init__(self,trajectory=None,group=None,density=None, filename=None,hopdcd=None,hoppsf=None,fixtrajectory=None,verbosity=3): """Converts a trajectory into a hopping trajectory, using a sitemap as an index for sites. >>> h = HoppingTrajectory(trajectory=DCDReader,group=AtomGroup,density=Density, fixtrajectory=<dict>,verbosity=3) >>> h = HoppingTrajectory(filename=<name>) Create from a coordinate trajectory of a group of atoms and a site map: u = MDAnalysis.Universe(psf,dcd) water = u.selectAtoms('name OH2') h = HoppingTrajectory(trajectory=u.trajectory,group=water,density=water_density) Load from a saved hopping trajectory (in dcd format with dummy psf) h = HoppingTrajectory(hopdcd='hops.trajectory',hoppsf='hops.psf') :Arguments: trajectory MDAnalysis.trajectory trajectory instance group MDAnalysis.group instance density grid3Dc.Grid instance with sitemap set hopdcd dcd written by write() hoppsf psf written by write() (or write_psf()) filename or simply provide one filename prefix for psf and dcd fixtrajectory dictionary with attributes of a dcd object and new values; used to provide correct values after using a catdcd-generated trajectory (hack!), e.g. fixtrajectory = {'delta':10.22741474887299} verbosity show status messages for >= 3 """ self.verbosity = verbosity set_verbosity(self.verbosity) if not (trajectory is None or group is None or density is None): self.traj = trajectory # MDAnalysis.Universe.trajectory self.tgroup = group # atom selection for trajectory if not isinstance(self.tgroup, MDAnalysis.core.AtomGroup.AtomGroup): raise TypeError('group must be a <AtomGroup>, eg MDAnalyis.Universe.selectAtoms().') if isinstance(fixtrajectory,dict): for attr,val in fixtrajectory.items(): if not hasattr(trajectory,attr): raise AttributeError('fixtrajectory: dcd object does not have attribute "'\ +str(attr)+'"') trajectory.__dict__[attr] = val self.totaltime = totaltime(trajectory) self.traj.rewind() # make sure to start from frame 0 self._GD = density # sitemap.Density object self.map = self._GD.map # map of sites self.edges = self._GD.edges # N+1 edges of bins self.dedges = map(numpy.diff,self.edges) # N bin widths try: if not self._GD.grid.shape == self.map.shape: raise ValueError except (AttributeError,ValueError): raise ValueError("The density object must have its site map computed.") Dmap = numpy.rank(self.map) coord = numpy.asarray(self.tgroup.coordinates()) Natoms,D = coord.shape if not D == Dmap: raise ValueError("Coordinates and map have different dimensions.") # NOTE: # Any count outside the histogram becomes 'outlier' so # one should take care to choose a large enough map for the region # of interest. See _coord2hop(). self.buffered_map = SITELABEL['outlier'] * \ numpy.ones(tuple(numpy.asarray(self.map.shape) + 2)) # Here we commit to writing a DCD hopping trajectory: self.ts = MDAnalysis.coordinates.DCD.Timestep(Natoms) # empty time step for N atoms self.ts.frame = self.traj.ts.frame # current frame numlabels = float(self.map.max() - self.map.min() + 2) # naive... but not crucial # fake unit cell for visualization # Layout of DCD unitcell is [A, alpha, B, beta, gamma, C] (sic!) self.ts._unitcell = numpy.array((numlabels,90, numlabels,90, 90,1),dtype=numpy.float32) # current hopping trajectory frame is in ts._pos[] # _pos = numpy.empty(coord.shape) # x=site label y=s(t)==0?s(t-1):s(t) z=0 self.numframes = self.traj.numframes # total numer of frames self._init_coord2hop() # init for _map_next_timestep() self._map_next_timestep() # initialize with first timestep self.hoptraj = None # no hopping trajectory available elif not (hopdcd is None or hoppsf is None) or filename is not None: # read from dcd try: self.traj,self.tgroup,self.map,self.edges,self.dedges except AttributeError: self.traj,self.tgroup,self.map,self.edges,self.dedges = [None] * 5 if filename is not None: hoppsf = self.filename(filename,'psf') hopdcd = self.filename(filename,'dcd') u = MDAnalysis.Universe(hoppsf,hopdcd) group = u.selectAtoms('type *') self.group = group # group that refers to hopping trajectory self.hoptraj = u.trajectory # DCD(!) trajectory object self.ts = self.hoptraj.ts self.numframes = self.hoptraj.numframes self.totaltime = totaltime(self.hoptraj) else: raise ValueError('Not sufficient data to create a hopping trajectory.')
def __init__(self,hoppinggraphs,normalization="maxabs",verbosity=1,prune='default'): """Create a 'heatmap' for the Hopgraph statistics from a dictionary of CombinedGraphs. >>> hm = HeatmapAnalysis(hg,normalize="maxabs") :Arguments: HoppingGraphs Dictionary of HoppingGraph instances. The key is used to label the simulation in the heat map and thus should be expressive. normalization Method to normalize the data across observables. Can be None (not recommended), 'maxabs', or 'zscore'. See the normalize() method for documentation. NOTE that the normalization strongly influences the clustering in the heat map. verbosity Chattiness; use at least 1 in order to be notified if you should install additional packages. Otherwise a less powerful alternative is chosen silently, prune dict with keys that are removed from the heat map; see prune_default class attribute. :Methods: plot plot the heat map normalize normalize using the 'normalize' method labels dictionary of row, column names (and the normalization constants as strings) annotation 'enumerate' dictionaries of labels but not stringified """ # TODO: input a dict of HopGraph or CombinedGraph instances # and a dict with metadata # Currently assumes CombinedGraph as input set_verbosity(verbosity) hg = hoppinggraphs self._filename = None # holds default filename if prune is 'default': prune = self.prune_default elif prune is None: prune = [] else: try: 'foo' in prune except: raise TypeError("prune must support 'in' lookup") self.columns = hg.keys() # labels for sim: 'R13_1_plm', 'R13_1_apo', ... self.names = [] self.heatmap = None self.normalization_method = normalization # boring data reorganization table = {} for sim,hopgraph in hg.items(): for k,v in hopgraph.stats().items(): try: table[k].append(v) except: table[k] = [v] self.names = [k for k in sorted(table.keys()) if k not in prune] self.data = numpy.array([table[k] for k in self.names]) # reference values, tagged with row name # colum offsets are the indices in self.columns self.taggeddata = numpy.rec.fromarrays(self.data,names=self.names) self.heatmap = self.data.copy() self.normalizations = numpy.zeros(len(self.heatmap)) self.normalize(method=normalization) # modifies heatmap and normalizations # set up annotation self.annotation()
def __init__(self,densities,reference,dir="./figs", bulkdensities=None,refbulkdensity=None, bulkname='bulk',verbosity=3): """Analyze densities. :Arguments: densities list of densities (instances or filenames) reference reference density (instance or filename) bulkdensities needed to rebuild densities with scan; same sequence as densities refbulkdensity ... bulkname eg 'bulk': searches for '<bulkname>.pickle' in the same directory as the density dir basedir for graphs verbosity=3 chattiness :Methods: show() basic stats scan() scan statistics for a range of rho_cut save() pickle scan results load() load scan results """ set_verbosity(verbosity) self.densities = hop.utilities.easy_load(densities,hop.sitemap.Density,'stats') self.reference = hop.utilities.easy_load(reference,hop.sitemap.Density,'stats') try: self.n = len(self.densities) # densities are numbered 0 .. n-1 except TypeError: self.densities = [self.densities] self.n = 1 if bulkdensities and refbulkdensity: self.bulkdensities = hop.utilities.easy_load(bulkdensities,hop.sitemap.Density,'stats') self.refbulkdensity = hop.utilities.easy_load(refbulkdensity,hop.sitemap.Density,'stats') elif bulkname: self.refbulkdensity = hop.utilities.easy_load( os.path.join(os.path.dirname(self.reference.filename()),bulkname), hop.sitemap.Density,'stats') self.bulkdensities = [ hop.utilities.easy_load( os.path.join(os.path.dirname(d.filename()),bulkname), hop.sitemap.Density,'stats') for d in self.densities ] else: self.bulkdensities = None self.refbulkdensity = None if self.bulkdensities and type(self.bulkdensities) is not list: self.bulkdensities = [self.bulkdensities] # D contains raw data, indexed by density or 'reference' self.D = dict( [(k,{}) for k in xrange(self.n)] ) self.D['reference'] = {} # S contains all the statistics self.S = dict( [(k,x.stats(data=self.D[k])) for k,x in enumerate(self.densities)] ) self.S['reference'] = self.reference.stats(data=self.D['reference']) # scanner is used for scan() self.scanner = DensityScanner(self) # default pdf file names self.pdf = {'scan':'scan.pdf', } for k,v in self.pdf.items(): self.pdf[k] = os.path.join(dir,v)