
     is                         d Z ddlZddlZddlZddlZddlmZmZmZ ddl	m
Z
 ddlZddlZddlmZmZ ddlmZ dd	lmZ dd
lmZ  G d de          Z G d de          Z G d de          Z G d de          ZdS )aS  
Auxiliary Readers --- :mod:`MDAnalysis.auxiliary.base`
======================================================

Base classes for deriving all auxiliary data readers. See the API in :mod:`MDAnalysis.auxiliary.__init__`.

.. autoclass:: AuxStep
   :members:

.. autoclass:: AuxReader
   :members:

.. autoclass:: AuxFileReader
   :members:

    N)UnionOptionalDict)defaultdict   )
asiterableanyopen)units   )_AUXREADERS)	auxreaderc                       e Zd Zd ZdS )_AuxReaderMetac                     t                               t           |||           	 t          |d                   }|D ]}| t          |<   d S # t          $ r Y d S w xY w)Nformat)type__init__r   r   KeyError)clsnamebases	classdictfmtfs         c/srv/www/vhosts/g4struct/public_html/venv/lib/python3.11/site-packages/MDAnalysis/auxiliary/base.pyr   z_AuxReaderMeta.__init__=   s{    dD%333	%Yx011C  % %!$A% %  	 	 	DD	s   A
 

AAN)__name__
__module____qualname__r        r   r   r   ;   s#        % % % % %r    r   c                       e Zd ZdZ	 	 	 	 	 	 ddZed             Zed             Zed	             Zej	        d
             Zed             Z
e
j	        d             Z
d ZdS )AuxStepa  Base class for auxiliary timesteps.

    Stores the auxiliary data for the current auxiliary step. On creation,
    ``step`` is set to -1.

    .. versionchanged:: 2.4.0
        Added memory_limit parameter to control raising memory usage warnings.

    Parameters
    ----------
    dt : float, optional
        Change in time between auxiliary steps (in ps). If not specified, will
        attempt to determine from auxiliary data; otherwise defaults to 1 ps.
        Ignored if ``constant_dt`` is False.
    initial_time : float, optional
        Time of first auxiliary step (in ps). If not specified, will attempt to
        determine from auxiliary data; otherwise defaults to 0 ps. Ignored if
        ``constant_dt`` is False.
    time_selector: optional
        Key to select 'time' value from the full set of data read for each
        step, if time selection is enabled; type will vary depending on the
        auxiliary data format (see individual AuxReader documentation). If
        ``None`` (default value), time is instead calculated as: ``time = step
        * dt + initial_time``
    data_selector: optional
        Key(s) to select auxiliary data values of interest from the full set of
        data read for each step, if data selection is enabled by the reader;
        type will vary depending on the auxiliary data format (see individual
        AuxReader documentation).
        If ``None`` (default value), the full set of data is returned.
    constant_dt : bool, optional
        (Default: True) Set to False if ``dt`` is not constant
        throughout the auxiliary data set, in which case a valid
        ``time_selector`` must be provided.
    memory_limit : float, optional
        Sets the threshold of memory usage by auxiliary data  (in GB) at which
        to issue a warning. Default: 1 GB.

    Attributes
    ----------
    step : int
        Number of the current auxiliary step (0-based).
    r   r   NTc                 Z    d| _         || _        || _        || _        || _        || _        d S )N)step_initial_time_dt_constant_dt_time_selector__data_selector_)selfdtinitial_timetime_selectordata_selectorconstant_dtmemory_limits          r   r   zAuxStep.__init__u   s:     	)'  -,r    c                     | j         |                     | j                   S | j        r| j        | j        z  | j        z   S t          d          )a  Time in ps of current auxiliary step (as float).

        Read from the set of auxiliary data read each step if time selection
        is enabled and a valid ``time_selector`` is specified; otherwise
        calculated as ``step * dt + initial_time``.
        Nz6If dt is not constant, must have a valid time selector)_time_selector_select_timer(   r%   r'   r&   
ValueErrorr+   s    r   timezAuxStep.time   s[     *$$T%8999 	9tx'$*<<<K  r    c                 R    | j         |                     | j                   S | j        S )a  Auxiliary values of interest for the current step (as ndarray).

        Read from the full set of data read for each step if data selection is
        enabled and a valid ``data_selector`` is specified; otherwise
        defaults to the full set of data.
        )_data_selector_select_data_datar6   s    r   datazAuxStep.data   s,     *$$T%8999zr    c                     	 | j          nB# t          $ r5 t          j        d                    | j        j                             Y dS w xY w| j        S )a  'Key' to select time from the full set of data read in each step.

        Will be passed to ``_select_time()``, defined separately for each
        auxiliary format, when returning the time of the current step.
        Format will depend on the auxiliary format. e.g. for the XVGReader,
        this is an index and ``_select_time()`` returns the value in that column
        of the current step data.

        Defaults to 'None' if time selection is not enabled.
        z8{} does not support time selection. Reverting to defaultN)r4   AttributeErrorwarningswarnr   	__class__r   r)   r6   s    r   r3   zAuxStep._time_selector   sm    	 	 	 	M &!899   44	 ##   
 ;A	A	c                     	 | j         } ||           || _        d S # t          $ r5 t          j        d                    | j        j                             Y d S w xY w)Nz"{} does not support time selection)r4   r)   r>   r?   r@   r   rA   r   r+   newselects      r   r3   zAuxStep._time_selector       	'&F F3KKK#&D     	 	 	M4;;N+      	    ;AAc                     	 | j          nB# t          $ r5 t          j        d                    | j        j                             Y dS w xY w| j        S )al  'Key' to select values of interest from full set of auxiliary data.
        These are the values that will be stored in ``data`` (and
        ``frame_data`` and ``frame_rep``).

        Will be passed to ``_select_data()``, defined separately for each
        auxiliary format, when returning the data of interest for the current
        step (``data``). Format will depend on the auxiliary format; e.g.
        for the XVGReader, this is a list of indices and `_select_data()` returns
        the value(s) in those columns of the current step data.

        Defaults to 'None' if data selection is not enabled.
        z8{} does not support data selection. Reverting to defaultN)r:   r>   r?   r@   r   rA   r   r*   r6   s    r   r9   zAuxStep._data_selector   sm    	 	 	 	M &!899   44	 ##rB   c                     	 | j         } ||           || _        d S # t          $ r5 t          j        d                    | j        j                             Y d S w xY w)Nz"{} does not support data selection)r:   r*   r>   r?   r@   r   rA   r   rD   s      r   r9   zAuxStep._data_selector   rG   rH   c                 b    t          j        | j        t           j        t           j                  S )a  Create an 'empty' ``data``-like placeholder.

        Returns an ndarray in the format of ``data`` with all values set to
        np.nan; to use at the 'representative value' when no auxiliary steps
        are assigned to a trajectory timestep/within the cutoff.

        Default behaviour here works when ``data`` is a ndarray of floats. May
        need to overwrite in individual format's AuxSteps.

        .. versionchanged:: 2.4.0
            dtype changed to np.float64 from np.float_
        )dtype)np	full_liker<   nanfloat64r6   s    r   _empty_datazAuxStep._empty_data   s!     |DIrvRZ@@@@r    )r   r   NNTN)r   r   r   __doc__r   propertyr7   r<   r3   setterr9   rQ   r   r    r   r"   r"   H   s       * *\ - - - -&   X" 
 
 X
 $ $ X$* ' ' '  $ $ X$. ' ' ' A A A A Ar    r"   c                   x   e Zd ZdZeZddgZg dZ	 d6dZd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Z	 	 d7deeeeeef         f                  dee         ddfdZd Zd8dZd Zd Zd Zd Zd Zd Zd Z d Z!d  Z"d! Z#d" Z$d# Z%d$ Z&e'd%             Z(d& Z)e'd'             Z*e*j+        d(             Z*d) Z,d* Z-d+ Z.e'd,             Z/e'd-             Z0e'd.             Z1e'd/             Z2e'd0             Z3e3j+        d1             Z3e'd2             Z4e4j+        d3             Z4e'd4             Z5e5j+        d5             Z5dS )9	AuxReadera  Base class for auxiliary readers.

    Allows iteration over a set of data from a trajectory, additional
    ('auxiliary') to the regular positions/velocities/etc. This auxiliary
    data may be stored in e.g. an array or a separate file.

    See the :ref:`Auxiliary API` for more on use.

    .. versionchanged:: 2.4.0
        Behaviour of ``cutoff`` changed, default parameter which specifies
        not cutoff is set is now None, not -1.

    .. versionchanged:: 2.4.0
        :class:`AuxReader` instances now have a :meth:`copy` method which
        creates a deep copy of the instance.

    Parameters
    ----------
    auxname : str, optional
        Name for auxiliary data. When added to a trajectory, the representative
        auxiliary value(s) for the timestep may be accessed as ``ts.aux.auxname``
        or ``ts.aux['auxname']``.
    represent_ts_as : str
        Method to use to calculate representative value of auxiliary data for a
        trajectory timestep. See :func:`calc_representative` for valid options.
    cutoff : float, optional
        Auxiliary steps further from the trajectory timestep than *cutoff*
        (in ps) will be ignored when calculating representative values. If None
        (default), all auxiliary steps assigned to that timestep will be used.
    **kwargs
        Options to be passed to :class:`~AuxStep`


    Attributes
    ----------
    auxstep :
       :class:`~AuxStep` object containing data for current step.
    frame_data : dict
        Dictionary containing ``data`` from each auxiliary step assigned to the
        current trajectory timestep, indexed by the difference in time between
        the step and trajectory timestep (i.e. ``auxstep.time - ts.time``; in ps)
    frame_rep : ndarray
        Representative value(s) of auxiliary data for current trajectory timestep.


    Note
    ----
    Auxiliary data are assumed to be time ordered and contain no duplicates.
    closestaverage)
represent_ts_ascutoffr,   r-   r.   r/   r0   auxnamer   _auxdataNc                 t   || _         || _        ||dk    r|nd | _        d | _        d | _         | j        di || _        |                                  | j        [| j	        rV| j
        | j        _        |                                  | j
        | j        z
  | j        _        |                                  d S d S d S )Nr   r   )r[   rY   rZ   
frame_data	frame_rep_Auxstepauxstep_read_next_stepr.   r0   r7   r&   r-   r'   rewind)r+   rY   r[   rZ   kwargss        r   r   zAuxReader.__init__L  s    
 . !' 2v{{ff$t}..v.. )d.>))-DL&  """#y4+<<DLKKMMMMM	 *)))r    c                 V    t          j        |           }t          j        |          }|S )z$Returns a deep copy of the AuxReader)pickledumpsloads)r+   	orig_dict
new_readers      r   copyzAuxReader.copyd  s&    L&&	\),,
r    c                     | j         S )z"Number of steps in auxiliary data.)n_stepsr6   s    r   __len__zAuxReader.__len__j  s
    |r    c                 *    |                                  S z$Move to next step of auxiliary data.)rb   r6   s    r   nextzAuxReader.nextn  s    ##%%%r    c                 *    |                                  S rp   )rq   r6   s    r   __next__zAuxReader.__next__r  s    yy{{r    c                 .    |                                   | S )z!Iterate over all auxiliary steps.)_restartr6   s    r   __iter__zAuxReader.__iter__v  s    r    c                     d| j         _        dS )z;Reset back to start; calling next() should read first step.r$   Nra   r%   r6   s    r   ru   zAuxReader._restart{  s     r    c                 R    |                                   |                                 S )zReturn to and read first step.)ru   rb   r6   s    r   rc   zAuxReader.rewind  s#     	##%%%r    c                      t          d          )zzMove to next step and update auxstep.

        Should return the AuxStep instance corresponding to the next step.
        z4BUG: Override _read_next_step() in auxiliary reader!NotImplementedErrorr6   s    r   rb   zAuxReader._read_next_step  s     "B
 
 	
r    c                     | j         st          d          |                     |           t          |j        | j         | j                   |S )az  Read auxiliary steps corresponding to and update the trajectory
        timestep *ts*.

        Calls :meth:`read_ts`, then updates *ts* with the representative value.
        ``auxname`` must be set; the representative value will be accessible in
        *ts* as ``ts.aux.auxname`` or ``ts.aux['auxname']``.

        Parameters
        ----------
        ts : :class:`~MDAnalysis.coordinates.timestep.Timestep` object
            The trajectory timestep for which corresponding auxiliary data is
            to be read and updated.

        Returns
        -------
        :class:`~MDAnalysis.coordinates.timestep.Timestep`
            *ts* with the representative auxiliary
            value in ``ts.aux`` be updated appropriately.

        Raises
        ------
        ValueError
            If ``auxname`` is not set.

        See Also
        --------
        :meth:`read_ts`
        zjAuxiliary name not set, cannot set representative value in timestep. Name auxiliary or use read_ts instead)r[   r5   read_tssetattrauxr_   )r+   tss     r   	update_tszAuxReader.update_ts  sV    : | 	  
 	Rdn555	r    c                 f   |                      | j        |          }|                      | j        dz   |          }|L|!||j        k    r|                     |           n)||j        cxk     r|k    sn |                     |           |                                  |                      | j        dz   |          |j        k    rU|                                  |                     |j                   |                      | j        dz   |          |j        k    U|                                 | _	        dS )a   Read auxiliary steps corresponding to the trajectory timestep *ts*.

        Read the auxiliary steps 'assigned' to *ts* (the steps that are within
        ``ts.dt/2`` of of the trajectory timestep/frame - ie. closer to *ts*
        than either the preceding or following frame). Then calculate a
        'representative value' for the timestep from the data in each of these
        auxiliary steps.

        To update *ts* with the representative value, use ``update_ts`` instead.

        Parameters
        ----------
        ts : :class:`~MDAnalysis.coordinates.timestep.Timestep` object
            The trajectory timestep for which corresponding auxiliary data is
            to be read.

        See Also
        --------
        :meth:`update_ts`

        Note
        ----
        The auxiliary reader will end up positioned at the last step assigned
        to the trajectory frame or, if the frame includes no auxiliary steps,
        (as when auxiliary data are less frequent), the most recent auxiliary
        step before the frame.
        r   N)
step_to_framer%   frame
move_to_ts_reset_frame_datarb   _add_step_to_frame_datar7   calc_representativer_   )r+   r   frame_for_stepframe_for_next_steps       r   r~   zAuxReader.read_ts  s3   @ ++DIr::"00QCC%"*!RX--OOB'''$rxFFFF3FFFFF###     Q33rx??  """((111   Q33rx?? 1133r    aux_specr   returnc                    d|v r|d         di}n-|d | j         D             }nt          |t                    r|di}|D ]}||j        v rt	          d| d          d|v rt          j        d| d| d	           |                                 }i ||}t          di |}||_	        |j
        ||         |_
        ||j        |<   |                    |j                  |_        d
}	|                    dd          }
|j                                        D ]}|	|                                z  }	|	|
k    r%d}t          j        d|	|z   d|
|z   d           dS dS )a  Attaches the data specified in `aux_spec` to the `coord_parent`

        This method is called from within
        :meth:`MDAnalysis.coordinates.base.ReaderBase.add_auxiliary()`.
        `add_auxiliary` should be agnostic to the type of AuxReader, so the
        method call leads here instead. First, some checks are done on
        the arguments to make sure the input is treated properly. Then,
        the AuxReader(s) with appropriate :attr:`data_selector` are
        associated with the `coord_parent` from which `add_auxiliary` was
        called.

        Parameters
        ----------
        coord_parent : MDAnalysis.coordinates.base.ReaderBase
            Reader object to which to attach the auxiliary data.

        aux_spec : str, Dict[str, str], None
            Specifies which data to add to `coord_parent`. String types are
            for :class:`MDAnalysis.auxiliary.XVG.XVGReader` only. Dictionaries
            are the standard way of providing `aux_spec` information (see also:
            :mod:`MDAnalysis.auxiliary.EDR`).
            Passing `None` causes all data to be added.

        Returns
        -------
        None

        Raises
        ------
        ValueError
            If trying to add data under an `aux_spec` key that is already
            assigned.

        r[   Nc                     i | ]}||S r   r   ).0terms     r   
<dictcomp>z.AuxReader.attach_auxiliary.<locals>.<dictcomp>  s    :::td:::r    zAuxiliary data with name z already exists zAuxiliary name 'zW' contains a space. Only dictionary style accession, not attribute style accession of 'z' will work.r   r1   g    eAz9AuxReader: memory usage warning! Auxiliary data takes up z GB of memory (Warning limit: z GB).r   )terms
isinstancestraux_listr5   r?   r@   get_descriptionr   r[   r/   _auxsr   r   getvalues_memory_usage)r+   coord_parentr   r   rd   r[   descriptiondescription_kwargsr   aux_memory_usager1   readerconvs                r   attach_auxiliaryzAuxReader.attach_auxiliary  s   R 
 y)40HH::tz:::HH#&& 	(
 !$'H 	= 	=G,/// KKKK   g~~Aw A A+2A A A  
 ..00K!:K!:6!: 11011C!CK ( %-W$5!*-Lw'!mmLO<<LOOzz.$77"(//11 	7 	7F 4 4 6 66l**DM+;D+@ 0<T0A       +*r    c                      t          d          )Nz2BUG: Override _memory_usage() in auxiliary reader!r{   r6   s    r   r   zAuxReader._memory_usageK  s    !C
 
 	
r    Fc                 <   || j         k    s|dk     rdS |j        |j        |j        z  z
  }|                     |          }t          t          j        ||z
  |j        dz  z   |j        z                      }|s|S |||j        z  z   }t          ||z
            }||fS )a  Calculate closest trajectory frame for auxiliary step *step*.

        Calculated given dt, time and frame from *ts*::

            time_frame_0 = ts.time - ts.frame*ts.dt   # time at frame 0

            frame = floor((step_to_time(step) - time_frame_0 + ts.dt/2)/ts.dt))

        The difference in time between the step and the calculated frame can
        also optionally be returned with *return_time_diff*.

        Parameters
        ----------
        step : int
            Number of the auxiliary step to calculate closest trajectory frame
            for.
        ts : :class:`~MDAnalysis.coordinates.timestep.Timestep` object
            (Any) timestep from the trajectory the calculated frame number is to
            correspond to.
        return_time_diff : bool, optional
            (Default: False) Additionally return the time difference between
            *step* and returned frame.

        Returns
        -------
        frame_index : int or None
            Number of the trajectory frame closest (in time) to the given
            auxiliary step. If the step index is out of range for the auxiliary
            data, ``None`` is returned instead.
        time_diff : float (optional)
            Difference in time between *step* and *frame_index*.

        Note
        ----
        Assumes trajectory dt is consant.
        The returned frame number may be out of range for the trajectory.
        r   Ng       @)	rm   r7   r   r,   step_to_timeintmathfloorabs)	r+   r%   r   return_time_difftime_frame_0	time_stepframe_index
time_frame	time_diffs	            r   r   zAuxReader.step_to_frameP  s    L 4<4!884wBE!11%%d++	J	L0253;>"%GHH
 
   	*%be(;;JJ233I	))r    c                    | j         rht          t          j        |j        |j        dz  z
  | j        z
  | j        z                      }t          t          || j	        dz
            d          }n?t          | j	        dz             D ]"}|                     |          |j        k    r n#|dz
  }|dk    r|                                  dS |                     |           dS )a0  Position auxiliary reader just before trajectory timestep *ts*.

        Calling ``next()`` should read the first auxiliary step 'assigned' to
        the trajectory timestep *ts* or, if no auxiliary steps are
        assigned to that timestep (as in the case of less frequent auxiliary
        data), the first auxiliary step after *ts*.

        Parameters
        ----------
        ts : :class:`~MDAnalysis.coordinates.timestep.Timestep` object
            The trajectory timestep before which the auxiliary reader is to
            be positioned.
        r   r   r$   N)r0   r   r   r   r7   r,   r-   maxminrm   ranger   r   ru   _go_to_step)r+   r   r%   is       r   r   zAuxReader.move_to_ts  s      	
BGbeai/$2CCtwNOO D s4!122B77DD 4<!+,,  %%a((BH44E 5 q5D2::MMOOOOOT"""""r    c                     | j         }|| j        dz
  k     rK|                     | j         dz   |d          \  }}| j        || j        k    r|dz   }n|S || j        dz
  k     KdS )a@  Find the next trajectory frame for which a representative auxiliary
        value can be calculated.

        That is, the next trajectory frame to which one or more auxiliary steps
        are assigned and fall within the cutoff.

        Starts looking from the current step time. If the end of the auxiliary
        data is reached before a trajectory frame is found, None is returned.

        Parameters
        ----------
        ts : :class:`~MDAnalysis.coordinates.timestep.Timestep` object
            Any timestep from the trajectory for which the next 'non-empty'
            frame is to be found.

        Returns
        -------
        int
            Index of the next auxiliary-containing frame in the trajectory.

        Note
        ----
        The returned index may be out of range for the trajectory.
        r   T)r   N)r%   rm   r   rZ   )r+   r   r%   
next_framer   s        r   next_nonempty_framezAuxReader.next_nonempty_frame  s    2 yT\A%%%$($6$6	ArD %7 % %!J	 {&9t{+B+Bax!! T\A%%% tr    c                     t          |t          j                  r*                     |          }                     |          S t          |t
          t          j        f          r!                      fd|D                       S t          |t                    r|j
                             |j
                  nd}|j         j        k    r|j        n'|j                             |j                  n j        }|j        pd}t          |t          j                  r|dk     rt          d          ||k    rt          d                               t          |||                    S t#          d          )a  Return the AuxStep corresponding to the *i*-th auxiliary step(s)
        (0-based). Negative numbers are counted from the end.

        *i* may be an integer (in which case the corresponding AuxStep is
        returned) or a list of integers or slice (in which case an iterator is
        returned)::

             step_10 = aux_reader[10]

        will move to step 10 of the auxiliary and return the :class:`AuxStep`.
        By using a slice/list, we can iterated over specified steps in the
        auxiliary, e.g. when performing analysis ::

             for auxstep in aux_reader[100:200]:   # analyse only steps 100 to 200
                 run_analysis(auxstep)

             for auxstep in aux_reader[::10]       # analyse every 10th step
                 run_analysis(auxstep)
        c                 :    g | ]}                     |          S r   )_check_index)r   xr+   s     r   
<listcomp>z)AuxReader.__getitem__.<locals>.<listcomp>  s'    #D#D#DQD$5$5a$8$8#D#D#Dr    Nr   r   zStep must be positive integerz$Stop frame is lower than start framez0Index must be integer, list of integers or slice)r   numbersIntegralr   r   listrM   ndarray
_list_iterslicestartstoprm   r%   r5   
IndexError_slice_iter	TypeError)r+   r   r   r   r%   s   `    r   __getitem__zAuxReader.__getitem__  s~   ( a)** 	P!!!$$A##A&&&D"*-.. 	P??#D#D#D#D!#D#D#DEEE5!! 	P23'2ED%%ag...1E 6T\))  v) %%af---  6;QDdG$455 B !@AAAt|| !GHHH##E%t$<$<===NOOOr    c                     t          |t          j                  st          d          |dk     r
|| j        z   }|dk     s|| j        k    r(t          d                    || j                            |S )NzStep indices must be integersr   z/{} is out of range of auxiliary (num. steps {}))r   r   r   r   rm   r   r   r+   r   s     r   r   zAuxReader._check_index  s    !W-.. 	=;<<<q55DL Aq55A%%fQ--   r    c              #   B   K   |D ]}|                      |          V  d S N)r   r+   r   js      r   r   zAuxReader._list_iter  s<       	& 	&A""1%%%%%%	& 	&r    c              #   ~   K   t          |j        |j        |j                  D ]}|                     |          V  d S r   )r   r   r   r%   r   r   s      r   r   zAuxReader._slice_iter  sN      qw// 	& 	&A""1%%%%%%	& 	&r    c                      t          d          )z%Move to and read i-th auxiliary step.z0BUG: Override _go_to_step() in auxiliary reader!r{   r   s     r   r   zAuxReader._go_to_step  s     ">
 
 	
r    c                     i | _         d S r   )r^   r6   s    r   r   zAuxReader._reset_frame_data  s    r    c                 B    | j         |z
  }| j        j        | j        |<   dS )a  Update ``frame_data`` with values for the current step.

        Parameters
        ----------
        ts_time : float
            the time of the timestep the current step is being 'added to'. Used
            to calculate difference in time between current step and timestep.
        N)r7   ra   r<   r^   )r+   ts_timer   s      r   r   z!AuxReader._add_step_to_frame_data  s'     I'	%)\%6	"""r    c                      j          j        }n% fd j                                        D             }t          |          dk    r j                                        }n j        dk    r<t          d |D                       }	 ||          }n# t          $ r ||         }Y nw xY w j        dk    r	 t          j
        t          j        d |                                D                       d          }no# t          $ rb t          t                    }|D ](} j        D ]}||xx         ||         |         z  cc<   )|D ]}||         t          |          z  ||<   Y nw xY w|S )	aK  Calculate representative auxiliary value(s) from the data in
        *frame_data*.

        Currently implemented options for calculating representative value are:

          * `closest`: default; the value(s) from the step closest to in time
            to the trajectory timestep

          * `average`: average of the value(s) from steps 'assigned' to the
            trajectory timestep.

        Additionally, if ``cutoff`` is specified, only steps within this time
        of the trajectory timestep are considered in calculating the
        representative.

        If no auxiliary steps were assigned to the timestep, or none fall
        within the cutoff, representative values are set to ``np.nan``.

        Returns
        -------
        ndarray
            Array of auxiliary value(s) 'representative' for the timestep.
        Nc                 L    i | ] \  }}t          |          j        k    ||!S r   )r   rZ   )r   keyvalr+   s      r   r   z1AuxReader.calc_representative.<locals>.<dictcomp>D  s<       Cs88t{** S***r    r   rW   c                 ,    g | ]}t          |          S r   )r   )r   r   s     r   r   z1AuxReader.calc_representative.<locals>.<listcomp>O  s    888qCFF888r    rX   c                     g | ]}|S r   r   )r   r   s     r   r   z1AuxReader.calc_representative.<locals>.<listcomp>Y  s    BBBccBBBr    )axis)rZ   r^   itemslenra   rQ   rY   r   r   rM   meanarrayr   r   r   floatr   )r+   cutoff_datavaluemin_diffdatasetr   s   `     r   r   zAuxReader.calc_representative)  s   0 ;/KK    $ 5 5 7 7  K {q   L,,..EE!Y..88K88899H.#XI. . . .#H-.!Y..AHBB[-?-?-A-ABBBCC!    	A 	A 	A $E*** B BG $
 B Bd{7';D'AAB! A AD"'+K0@0@"@E$KKA A	A s&   		B B('B(7AC< <A)E('E(c                     | S r   r   r6   s    r   	__enter__zAuxReader.__enter__g  s    r    c                 .    |                                   dS )NFclose)r+   exc_typeexc_valexc_tbs       r   __exit__zAuxReader.__exit__j  s    

ur    c                     d S r   r   r6   s    r   r   zAuxReader.closen  s    r    c                 r    	 | j         S # t          $ r# |                                 | _         | j         cY S w xY w)z,Total number of steps in the auxiliary data.)_n_stepsr>   _count_n_stepsr6   s    r   rm   zAuxReader.n_stepsr  sK    	!=  	! 	! 	! //11DM=   	!s   	 *66c                 "   || j         k    r(t          d                    || j                             | j        r|| j        z  | j        z   S 	 | j        |         S # t          $ r) |                                 | _        | j        |         cY S w xY w)a   Return time of auxiliary step *i*.

        Calculated using ``dt`` and ``initial_time`` if ``constant_dt`` is True;
        otherwise from the list of times as read from the auxiliary data for
        each step.

        Parameters
        ----------
        i : int
            Index (0-based) of step to return time for

        Returns
        -------
        time : float
            Time (in ps) of step *i*

        Raises
        ------
        ValueError
            When *i* not in valid range
        z<{0} is not a valid step index (total number of steps is {1}))	rm   r5   r   r0   r,   r-   _timesr>   read_all_timesr   s     r   r   zAuxReader.step_to_time{  s    ,   &q$, 7 7    	&tw;!222&{1~%! & & &"1133{1~%%%&s   A 0BBc                     | j         S )zgMethod by which 'representative' timestep values of auxiliary data
        will be calculated.
        )_represent_ts_asr6   s    r   rY   zAuxReader.represent_ts_as  s    
 $$r    c                 v    || j         vr(t          d                    || j                             || _        d S )Nz[{0} is not a valid option for calculating representative value(s). Enabled options are: {1})represent_optionsr5   r   r   r+   rE   s     r   rY   zAuxReader.represent_ts_as  sI    d,,,fS$"899  
 !$r    c                 .    |                                   d S r   r   r6   s    r   __del__zAuxReader.__del__  s    

r    c                 .      fd j         D             }|S )a  Get the values of the parameters necessary for replicating the
        AuxReader.

        An AuxReader can be duplicated using
        :func:`~MDAnalysis.auxiliary.core.auxreader`::

            description = original_aux.get_description()
            new_aux = MDAnalysis.auxiliary.auxreader(**description)

        The resulting dictionary may also be passed directly to
        :meth:`~MDAnalysis.coordinates.base.ProtoReader.add_auxiliary` to
        reload an auxiliary into a trajectory::

             trajectory.add_auxiliary(**description)

        Returns
        -------
        dict
            Key-word arguments and values that can be used to replicate the
            AuxReader.
        c                 X    i | ]&}|                     d           t          |          'S )_)stripgetattr)r   attrr+   s     r   r   z-AuxReader.get_description.<locals>.<dictcomp>  s?     
 
 
 JJsOOWT400
 
 
r    )required_attrs)r+   r   s   ` r   r   zAuxReader.get_description  s6    ,
 
 
 
+
 
 
 r    c                 d    | j         D ]'}t          | |          t          ||          k    r dS (dS )NFT)r  r  )r+   otherr  s      r   __eq__zAuxReader.__eq__  sD    ' 	 	DtT""geT&:&:::uu ;tr    c                     | j         j        S )zQNumber of the current auxiliary step (as stored in ``auxstep``;
        0-based).rx   r6   s    r   r%   zAuxReader.step  s     |  r    c                     | j         j        S )z@Time of current auxiliary step (as stored in ``auxstep``; in ps))ra   r7   r6   s    r   r7   zAuxReader.time  s     |  r    c                     | j         j        S )zPChange in time between auxiliary steps (as stored in ``auxstep``;
        in ps))ra   r'   r6   s    r   r,   zAuxReader.dt  s     |r    c                     | j         j        S )z>Time of first auxiliary step (as stored in ``auxstep``; in ps))ra   r&   r6   s    r   r-   zAuxReader.initial_time  s     |))r    c                     | j         j        S )a  Key to select 'time' value from the full set of data read for each step.
        As stored in ``austep``.

        Type differs between auxiliary formats, depending how the data for each
        step is read in and stored; e.g. data from .xvg files is read in as a
        list and `time_selector` must be a valid index. If time selection is not
        enabled by the reader, ``time_selector`` will default to ``None``.

        See each individual auxiliary reader.
        )ra   r3   r6   s    r   r.   zAuxReader.time_selector  s     |**r    c                 n    | j         j        }|| j         _        ||k    r	 | `d S # t          $ r Y d S w xY wd S r   )ra   r3   r   r>   )r+   rE   olds      r   r.   zAuxReader.time_selector  sV    l)&)##::KKK!    :s   $ 
22c                     | j         j        S )a
  Key(s) to select auxiliary data values of interest from the full set
        of data read for each step (as stored in ``auxstep``).

        Type differs between auxiliary formats, depending how the data for each
        step is read in and stored - e.g. data from .xvg files is read in as
        a list and `data_selector` must be a list of valid indicies. If data
        selection is not enabled by the reader, ``data_selector`` will default
        to ``None``.

        See each individual auxiliary reader.
        ra   r9   r6   s    r   r/   zAuxReader.data_selector  s     |**r    c                     || j         _        d S r   r  r   s     r   r/   zAuxReader.data_selector  s    &)###r    c                     | j         j        S )zVTrue if ``dt`` is constant throughout the auxiliary (as stored in
        ``auxstep``)ra   r(   r6   s    r   r0   zAuxReader.constant_dt  s     |((r    c                     || j         _        d S r   r  r   s     r   r0   zAuxReader.constant_dt  s    $'!!!r    )rW   NN)NN)F)6r   r   r   rR   r"   r`   r   r  r   rk   rn   rq   rs   rv   ru   rc   rb   r   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rS   rm   r   rY   rT   r   r   r  r%   r7   r,   r-   r.   r/   r0   r   r    r   rV   rV     s       0 0d H"I.  N ?C   0    & & &    
  
& & &
 
 
% % %N/4 /4 /4h :> $	` ` 5d38n!456` 	` 
` ` ` `D
 
 

2* 2* 2* 2*h #  #  #D$ $ $L1P 1P 1Pf
 
 
& & && & &
 
 
  
7 
7 
7< < <|       ! ! X!"& "& "&H % % X% $ $ $    8   ! ! X!
 ! ! X!     X 
 * * X* + + X+ 	 	 	 + + X+ * * * ) ) X)
 ( ( ( ( (r    rV   )	metaclassc                   :     e Zd ZdZ fdZd Zd Zd Zd Z xZ	S )AuxFileReadera  Base class for auxiliary readers that read from file.

    Extends AuxReader with attributes and methods particular to reading
    auxiliary data from an open file, for use when auxiliary files may be too
    large to read in at once.

    Parameters
    ----------
    filename : str
       Location of the file containing the auxiliary data.
    **kwargs
       Other AuxReader options.

    See also
    --------
    :class:`AuxReader`

    Attributes
    ----------
    auxfile
       File object for the auxiliary file.

    c                     t          |          | _        t          j                            |          | _         t          t          |           j        di | d S )Nr   )	r	   auxfileospathabspathr\   superr  r   )r+   filenamerd   rA   s      r   r   zAuxFileReader.__init__<  sP    x((11+mT""+55f55555r    c                 X    | j         dS | j                                          d| _         dS )zClose *auxfile*.N)r  r   r6   s    r   r   zAuxFileReader.closeA  s.    <Fr    c                 R    | j                             d           d| j        _        dS )z%Reposition to just before first step.r   r$   N)r  seekra   r%   r6   s    r   ru   zAuxFileReader._restartH  s(    !r    c                     | j         | j                                          t          | j                  | _         d| j        _        dS )z Close and then reopen *auxfile*.Nr$   )r  r   openr\   ra   r%   r6   s    r   _reopenzAuxFileReader._reopenM  s?    <#L   DM**r    c                     || j         k    r(t          d                    || j                             |                                 }| j        |k    r|                                 }| j        |k    |S )a  Move to and read i-th auxiliary step.

        Parameters
        ----------
        i : int
            Step number (0-indexed) to move to

        Raises
        ------
        ValueError
            If step index not in valid range.

        Note
        ----
        Works by reading through all steps consecutively until correct step
        is reached. Overwrite if this can be done more efficiently.
        z:Step index {0} is not valid for auxiliary (num. steps {1}!)rm   r5   r   rc   r%   rq   )r+   r   r   s      r   r   zAuxFileReader._go_to_stepT  sr    & ##)6!T\#:#:   i1nnIIKKE i1nnr    )
r   r   r   rR   r   r   ru   r#  r   __classcell__)rA   s   @r   r  r  #  s~         06 6 6 6 6
    
        r    r  )rR   r  r   r   r?   typingr   r   r   collectionsr   rf   numpyrM   lib.utilr   r	    r
   r   corer   r   r   objectr"   rV   r  r   r    r   <module>r-     s  2 " 
			    ( ( ( ( ( ( ( ( ( ( # # # # # #      * * * * * * * *                  
% 
% 
% 
% 
%T 
% 
% 
%|A |A |A |A |Af |A |A |A~Y( Y( Y( Y( Y(. Y( Y( Y( Y(xL L L L LI L L L L Lr    