§
    È ´i¬  ã                   ó2   — d Z ddlmZ  G d„ de¦  «        ZdS )z°Transformations Base Class --- :mod:`MDAnalysis.transformations.base`
=====================================================================

.. autoclass:: TransformationBase

é    )Úthreadpool_limitsc                   ó$   — e Zd ZdZd„ Zd„ Zd„ ZdS )ÚTransformationBasea.
  Base class for defining on-the-fly transformations

    The class is designed as a template for creating on-the-fly
    Transformation classes. This class will

    1) set up a context manager framework on limiting the threads
    per call, which may be the multi-thread OpenBlas backend of NumPy.
    This backend may kill the performance when subscribing hyperthread
    or oversubscribing the threads when used together with other parallel
    engines e.g. Dask.
    (PR `#2950 <https://github.com/MDAnalysis/mdanalysis/pull/2950>`_)

    Define ``max_threads=1`` when that is the case.

    2) set up a boolean attribute `parallelizable` for checking if the
    transformation can be applied in a **split-apply-combine** parallelism.
    For example, the :class:`~MDAnalysis.transformations.positionaveraging.PositionAverager`
    is history-dependent and can not be used in parallel analysis natively.
    (Issue `#2996 <https://github.com/MDAnalysis/mdanalysis/issues/2996>`_)

    To define a new Transformation, :class:`TransformationBase`
    has to be subclassed.
    ``max_threads`` will be set to ``None`` by default,
    i.e. does not do anything and any settings in the environment such as
    the environment variable :envvar:`OMP_NUM_THREADS`
    (see the `OpenMP specification for OMP_NUM_THREADS <https://www.openmp.org/spec-html/5.0/openmpse50.html>`_)
    are used.
    ``parallelizable`` will be set to ``True`` by default.
    You may need to double check if it can be used in parallel analysis;
    if not, override the value to ``False``.
    Note this attribute is not checked anywhere in MDAnalysis yet.
    Developers of the parallel analysis have to check it in their own code.

    .. code-block:: python

       class NewTransformation(TransformationBase):
           def __init__(self, ag, parameter,
                        max_threads=1, parallelizable=True):
               super().__init__(max_threads=max_threads,
                                 parallelizable=parallelizable)
               self.ag = ag
               self._param = parameter

           def _transform(self, ts):
               #  REQUIRED
               ts.positions = some_function(ts, self.ag, self._param)
               return ts

    Afterwards the new transformation can be run like this.

    .. code-block:: python

       new_transformation = NewTransformation(ag, param)
       u.trajectory.add_transformations(new_transformation)


    .. versionadded:: 2.0.0
       Add the base class for all transformations to limit threads and
       check if it can be used in parallel analysis.
    c                 ór   — |                      dd¦  «        | _        |                      dd¦  «        | _        dS )a…  
        Parameters
        ----------
        max_threads: int, optional
           The maximum thread number can be used.
           Default is ``None``, which means the default or the external setting.
        parallelizable: bool, optional
           A check for if this can be used in split-apply-combine parallel
           analysis approach.
           Default is ``True``.
        Úmax_threadsNÚparallelizableT)Úpopr   r   )ÚselfÚkwargss     úi/srv/www/vhosts/g4struct/public_html/venv/lib/python3.11/site-packages/MDAnalysis/transformations/base.pyÚ__init__zTransformationBase.__init___   s7   € ð "Ÿ:š: m°TÑ:Ô:ˆÔØ$ŸjšjÐ)9¸4Ñ@Ô@ˆÔÐÐó    c                 óˆ   — t          | j        ¦  «        5  |                      |¦  «        cddd¦  «         S # 1 swxY w Y   dS )zÏThe function that makes transformation can be called as a function

        The thread limit works as a context manager with given `max_threads`
        wrapping the real :func:`_transform` function
        N)r   r   Ú
_transform©r
   Útss     r   Ú__call__zTransformationBase.__call__n   sˆ   € õ ˜tÔ/Ñ0Ô0ð 	'ð 	'Ø—?’? 2Ñ&Ô&ð	'ð 	'ð 	'ð 	'ñ 	'ô 	'ð 	'ð 	'ð 	'ð 	'ð 	'ð 	'øøøð 	'ð 	'ð 	'ð 	'ð 	'ð 	's   •7·;¾;c                 ó    — t          d¦  «        ‚)ziTransform the given `Timestep`

        It deals with the transformation of a single `Timestep`.
        z!Only implemented in child classes)ÚNotImplementedErrorr   s     r   r   zTransformationBase._transformw   s   € õ
 "Ð"EÑFÔFÐFr   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   © r   r   r   r   !   sT   € € € € € ð;ð ;ðzAð Að Að'ð 'ð 'ðGð Gð Gð Gð Gr   r   N)r   Úthreadpoolctlr   Úobjectr   r   r   r   ú<module>r      sk   ðð.ð ð ,Ð +Ð +Ð +Ð +Ð +ð[Gð [Gð [Gð [Gð [G˜ñ [Gô [Gð [Gð [Gð [Gr   