[docs]classAnalysisBase(object):"""Base class for defining multi frame analysis The class it is designed as a template for creating multiframe analyses. This class will automatically take care of setting up the trajectory reader for iterating, and it offers to show a progress meter. To define a new Analysis, `AnalysisBase` needs to be subclassed `_single_frame` must be defined. It is also possible to define `_prepare` and `_conclude` for pre and post processing. See the example below. .. code-block:: python class NewAnalysis(AnalysisBase): def __init__(self, atomgroup, parameter, **kwargs): super(NewAnalysis, self).__init__(atomgroup.universe.trajectory, **kwargs) self._parameter = parameter self._ag = atomgroup def _prepare(self): # OPTIONAL # Called before iteration on the trajectory has begun. # Data structures can be set up at this time self.result = [] def _single_frame(self): # REQUIRED # Called after the trajectory is moved onto each new frame. # store result of `some_function` for a single frame self.result.append(some_function(self._ag, self._parameter)) def _conclude(self): # OPTIONAL # Called once iteration on the trajectory is finished. # Apply normalisation and averaging to results here. self.result = np.asarray(self.result) / np.sum(self.result) Afterwards the new analysis can be run like this. .. code-block:: python na = NewAnalysis(u.select_atoms('name CA'), 35).run(start=10, stop=20) print(na.result) """def__init__(self,trajectory,verbose=False,**kwargs):""" Parameters ---------- trajectory : mda.Reader A trajectory Reader verbose : bool, optional Turn on more logging and debugging, default ``False`` """self._trajectory=trajectoryself._verbose=verbose# do deprecated kwargs# remove in 1.0deps=[]forargin['start','stop','step']:ifarginkwargsandnotkwargs[arg]isNone:deps.append(arg)setattr(self,arg,kwargs[arg])ifdeps:warnings.warn('Setting the following kwargs should be ''done in the run() method: {}'.format(', '.join(deps)),DeprecationWarning)def_setup_frames(self,trajectory,start=None,stop=None,step=None):""" Pass a Reader object and define the desired iteration pattern through the trajectory Parameters ---------- trajectory : mda.Reader A trajectory Reader start : int, optional start frame of analysis stop : int, optional stop frame of analysis step : int, optional number of frames to skip between each analysed frame """self._trajectory=trajectory# TODO: Remove once start/stop/step are deprecated from init# See if these have been set as class attributes, and use thatstart=getattr(self,'start',start)stop=getattr(self,'stop',stop)step=getattr(self,'step',step)start,stop,step=trajectory.check_slice_indices(start,stop,step)self.start=startself.stop=stopself.step=stepself.n_frames=len(range(start,stop,step))interval=int(self.n_frames//100)ifinterval==0:interval=1verbose=getattr(self,'_verbose',False)self._pm=ProgressMeter(self.n_framesifself.n_frameselse1,interval=interval,verbose=verbose)def_single_frame(self):"""Calculate data from a single frame of trajectory Don't worry about normalising, just deal with a single frame. """raiseNotImplementedError("Only implemented in child classes")def_prepare(self):"""Set things up before the analysis loop begins"""pass# pylint: disable=unnecessary-passdef_conclude(self):"""Finalise the results you've gathered. Called at the end of the run() method to finish everything up. """pass# pylint: disable=unnecessary-pass