
     i                     B    d Z ddlZddlZddlmZ  G d de          ZdS )av  Trajectory Coordinate Averaging --- :mod:`MDAnalysis.transformations.positionaveraging` 
=======================================================================================

Averages the coordinates of a given trajectory with the N previous frames.
For frames < N, the average of the frames iterated up to that point will be
returned. 

.. autoclass:: PositionAverager

    N   )TransformationBasec                   B     e Zd ZdZ	 	 	 d
 fd	Zd Zd Zd Zd	 Z xZ	S )PositionAveragera  
    Averages the coordinates of a given timestep so that the coordinates
    of the AtomGroup correspond to the average positions of the N previous
    frames.
    For frames < N, the average of the frames iterated up to that point will
    be returned.

    Example
    -------

    Average the coordinates of a given AtomGroup over the course of
    the previous N frames. For ``N=3``, the output will correspond to the
    average of the coordinates over the last 3 frames.
    When ``check_reset=True``, the averager will be reset once the iteration is
    complete, or if the frames iterated are not sequential.

    .. code-block:: python

        N=3
        transformation = PositionAverager(N, check_reset=True)
        u.trajectory.add_transformations(transformation)
        for ts in u.trajectory:
            print(ts.positions)

    In this case, ``ts.positions`` will return the average coordinates of the
    last N iterated frames.


    When ``check_reset=False``, the average of coordinates from non
    sequential timesteps can also be computed. However, the averager must be
    manually reset before restarting an iteration. In this case,
    ``ts.positions`` will return the average coordinates of the last N
    iterated frames, despite them not being sequential
    (``frames = [0, 7, 1, 6]``).

    .. code-block:: python

        N=3
        transformation = PositionAverager(N, check_reset=False)
        u.trajectory.add_transformations(transformation)
        frames = [0, 7, 1, 6]
        transformation.resetarrays()
        for ts in u.trajectory[frames]:
            print(ts.positions)

    If ``check_reset=True``, the ``PositionAverager`` would have automatically
    reset after detecting a non sequential iteration (i.e. when iterating from
    frame 7 to frame 1 or when resetting the iterator from frame 6 back to
    frame 0).


    For frames < N, the average is calculated with the frames iterated up
    to that point and thus will not follow the same behaviour as for
    frames > N. This can be followed by comparing the number of frames being
    used to compute the current averaged frame (``current_avg``) to the one
    requested when calling ``PositionAverager`` (``avg_frames``) which in
    these examples corresponds to ``N=3``.

    .. code-block:: python

        N=3
        transformation = PositionAverager(N, check_reset=True)
        u.trajectory.add_transformations(transformation)
        for ts in u.trajectory:
            if transformation.current_avg == transformation.avg_frames:
                print(ts.positions)

    In the case of ``N=3``, as the average is calculated with the frames
    iterated up to the current iteration, the first frame returned will
    not be averaged. During the first iteration no other frames are stored in
    memory thus far and, consequently, ``transformation.current_avg = 1``.
    The second frame iterated will return the average of frame 1 and frame 2,
    with ``transformation.current_avg = 2``. Only during the third and
    following iterations will ``ts.positions`` start returning the average of
    the last 3 frames and thus ``transformation.current_avg = 3``
    These initial frames are typically not desired during analysis, but one can
    easily avoid them, as seen in the previous example with
    ``if transformation.current_avg == transformation.avg_frames:`` or by
    simply removing the first ``avg_frames-1`` frames from the analysis.



    Parameters
    ----------
    avg_frames: int
        Determines the number of frames to be used for the position averaging.
    check_reset: bool, optional
        If ``True``, position averaging will be reset and a warning raised
        when the trajectory iteration direction changes. If ``False``, position
        averaging will not reset, regardless of the iteration.


    Returns
    -------
    MDAnalysis.coordinates.timestep.Timestep


    .. versionchanged:: 2.0.0
       The transformation was changed to inherit from the base class for
       limiting threads and checking if it can be used in parallel analysis.
    TNFc                     t                                          ||           || _        || _        d| _        |                                  d| _        d S )N)max_threadsparallelizabler   )super__init__
avg_framescheck_resetcurrent_avgresetarrayscurrent_frame)selfr   r   r   r	   	__class__s        v/srv/www/vhosts/g4struct/public_html/venv/lib/python3.11/site-packages/MDAnalysis/transformations/positionaveraging.pyr   zPositionAverager.__init__   sd     	#N 	 	
 	
 	
 %&    c                 n    t          j        | j                  | _        t           j        | j        d d <   d S )N)npemptyr   	idx_arraynan)r   s    r   r   zPositionAverager.resetarrays   s-    $/22Fqqqr   c                 b    t          j        | j        d          | _        |j        | j        d<   d S )Nr   r   )r   rollr   frame)r   tss     r   rollidxzPositionAverager.rollidx   s+    33Hqr   c                 L   	 | j         j         nS# t          $ rF |j        j        d         |j        j        d         | j        f}t          j        |          | _         Y nw xY wt          j        | j         dd          | _         |j        	                                | j         d<   d S )Nr   r      axis).r   )
coord_arraysizeAttributeError	positionsshaper   r   r   r   copy)r   r   r$   s      r   rollposxzPositionAverager.rollposx   s    	.!!! 	. 	. 	."1%"1%D
  "x~~D	. 74#3QQ???#%<#4#4#6#6   s    AAAc                 ~   |j         | j        k    rt          | d          rot          j        | j                                                  sDt          j        | j                   }t          j        | j        d|f         d          |_	        |S |j         | _        | 
                    |           t          j        | j                   }t          |          | _        | j        rt          j        t          j        | j        |                             }t          j        |dk              sQt          j        |dk              s9t!          j        dt$                     |                                   | |          S |                     |           t          j        | j        d|f         d          |_	        |S )Nr#   .r    r!   r   zMCannot average position for non sequentialiterations. Averager will be reset.)r   r   hasattrr   isnanr   allmeanr#   r&   r   sumr   r   signdiffwarningswarnWarningr   r)   )r   r   testr1   s       r   
_transformzPositionAverager._transform   s   
 H***m,, +HT^,,0022 + HT^,,,D74#3CI#>QGGGBLI!#DR(((t99 		 7274>$#78899DF419%%  
););  :  
   """tBxxbwt/T	:CCC	r   )TNF)
__name__
__module____qualname____doc__r   r   r   r)   r7   __classcell__)r   s   @r   r   r   )   s        d dR       # # #% % %7 7 7             r   r   )r;   numpyr   r3   baser   r    r   r   <module>r@      sw   0
 
      $ $ $ $ $ $m m m m m) m m m m mr   