
     i5                     z   d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	 ddlm
Z
 ej         G d d	e                      Z G d
 de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          ZdddddddZ G d de          ZdS )z
Core Topology Objects --- :mod:`MDAnalysis.core.topologyobjects`
================================================================

The building blocks for MDAnalysis' description of topology

    N   )mdamath)cached)util)	distancesc                       e Zd ZdZdZddZed             Zed             Zed             Z	ed	             Z
ed
             Zd Zd Zd Zd Zd Zd Zd Zd Zd ZdS )TopologyObjecta  Base class for all Topology items.

    Defines the behaviour by which Bonds/Angles/etc in MDAnalysis should
    behave.

    .. versionadded:: 0.9.0
    .. versionchanged:: 0.10.0
       All TopologyObject now keep track of if they were guessed or not
       via the ``is_guessed`` managed property.
    .. versionadded:: 0.11.0
       Added the `value` method to return the size of the object
    .. versionchanged:: 2.6.0
       Updated Atom ID representation order to match that of AtomGroup indices
    )_ix_ubtype	_bondtype_guessedorderNFc                 L    || _         || _        || _        || _        || _        dS )a  Create a topology object

        Parameters
        ----------
        ix : numpy array
          indices of the Atoms
        universe : MDAnalysis.Universe
        type : optional
          Type of the bond
        guessed : optional
          If the Bond is guessed
        N)r
   r   r   r   r   )selfixuniversetypeguessedr   s         i/srv/www/vhosts/g4struct/public_html/venv/lib/python3.11/site-packages/MDAnalysis/core/topologyobjects.py__init__zTopologyObject.__init__<   s+     


    c                 0    | j         j        | j                 S )zAtoms within this Bond)r   atomsr
   r   s    r   r   zTopologyObject.atomsO   s     w}TX&&r   c                     | j         S )zRTuple of indices describing this object

        .. versionadded:: 0.10.0
        )r
   r   s    r   indiceszTopologyObject.indicesT   s     xr   c                     | j         S Nr   r   s    r   r   zTopologyObject.universe\   	    wr   c                 P    | j         | j         S t          | j        j                  S )zType of the bond as a tuple

        Note
        ----
        When comparing types, it is important to consider the reverse
        of the type too, i.e.::

            a.type == b.type or a.type == b.type[::-1]

        )r   tupler   typesr   s    r   r   zTopologyObject.type`   s'     >%>!)***r   c                 *    t          | j                  S r   )boolr   r   s    r   
is_guessedzTopologyObject.is_guessedq   s    DM"""r   c                 R    t          | j        t          | j                  f          S r   )hashr   r#   r   r   s    r   __hash__zTopologyObject.__hash__u   s!    TWeDL112333r   c                     d                     | j        j        d                    d | j        D                                 S )z8Return representation in same order of AtomGroup indicesz<{cname} between: {conts}>, c                 8    g | ]}d                      |          S )zAtom {0})format).0is     r   
<listcomp>z+TopologyObject.__repr__.<locals>.<listcomp>|   s&    HHHaZ..q11HHHr   )cnameconts)r.   	__class____name__joinr   r   s    r   __repr__zTopologyObject.__repr__x   sG    +22.)))HH4<HHHII 3 
 
 	
r   c                     || j         v S )z8Check whether an atom is in this :class:`TopologyObject`r   r   others     r   __contains__zTopologyObject.__contains__   s    
""r   c                     | j         |j         k    sdS t          j        | j        |j                  p't          j        | j        ddd         |j                  S )z/Check whether two bonds have identical contentsFN)r   nparray_equalr   r:   s     r   __eq__zTopologyObject.__eq__   sU    }..5~dlEM:: 
bnL2?
 ?
 	
r   c                     | |k     S r    r:   s     r   __ne__zTopologyObject.__ne__       5=  r   c                 V    t          | j                  t          |j                  k     S r   )r#   r   r:   s     r   __lt__zTopologyObject.__lt__   s!    T\""U5=%9%999r   c                     | j         |         S )z%Can retrieve a given Atom from withinr9   r   items     r   __getitem__zTopologyObject.__getitem__   s    z$r   c                 *    t          | j                  S r   )iterr   r   s    r   __iter__zTopologyObject.__iter__   s    DJr   c                 *    t          | j                  S r   )lenr
   r   s    r   __len__zTopologyObject.__len__   s    48}}r   )NFN)r5   
__module____qualname____doc__	__slots__r   propertyr   r   r   r   r'   r*   r7   r<   rA   rD   rG   rK   rN   rQ   rC   r   r   r	   r	   )   sH         II   & ' ' X'   X   X + + X+  # # X#4 4 4
 
 
# # #
 
 
! ! !: : :              r   r	   c                   (    e Zd ZdZdZd ZddZeZdS )Bonda  A bond between two :class:`~MDAnalysis.core.groups.Atom` instances.

    Two :class:`Bond` instances can be compared with the ``==`` and
    ``!=`` operators. A bond is equal to another if the same atom
    numbers are connected and they have the same bond order. The
    ordering of the two atom numbers is ignored as is the fact that a
    bond was guessed.

    The presence of a particular atom can also be queried::

      >>> Atom in Bond

    will return either ``True`` or ``False``.

    .. versionchanged:: 0.9.0
       Now a subclass of :class:`TopologyObject`. Changed class to use
       :attr:`__slots__` and stores atoms in :attr:`atoms` attribute.
    bondc                     || j         d         k    r| j         d         S || j         d         k    r| j         d         S t          d          )zBond.partner(Atom)

        Returns
        -------
        the other :class:`~MDAnalysis.core.groups.Atom` in this
        bond
        r      Unrecognised Atomr   
ValueErrorr   atoms     r   partnerzBond.partner   sM     4:a=  :a= TZ]"":a= 0111r   Tc                 z    |r| j         j        nd}t          j        | d         j        | d         j        |          S )zLength of the bond.

        .. versionchanged:: 0.11.0
           Added pbc keyword
        .. versionchanged:: 0.19.0
           Changed default of pbc to True
        Nr   r[   r   
dimensionsr   
calc_bondspositionr   pbcboxs      r   lengthzBond.length   s;     +.7dm&&4#DG$4d1g6FLLLr   NT)r5   rR   rS   rT   r   ra   rj   valuerC   r   r   rX   rX      sM         & E2 2 2
M 
M 
M 
M EEEr   rX   c                   "    e Zd ZdZdZddZeZdS )Anglea)  An angle between three :class:`~MDAnalysis.core.groups.Atom` instances.
    Atom 2 is the apex of the angle

    .. versionadded:: 0.8
    .. versionchanged:: 0.9.0
       Now a subclass of :class:`TopologyObject`; now uses
       :attr:`__slots__` and stores atoms in :attr:`atoms` attribute
    angleTc                     |r| j         j        nd}t          j        t	          j        | d         j        | d         j        | d         j        |                    S )a  Returns the angle in degrees of this Angle.

        Angle between atoms 0 and 2 with apex at 1::

              2
             /
            /
           1------0

        Note
        ----
        The numerical precision is typically not better than
        4 decimals (and is only tested to 3 decimals).

        .. versionadded:: 0.9.0
        .. versionchanged:: 0.17.0
           Fixed angles close to 180 giving NaN
        .. versionchanged:: 0.19.0
           Added pbc keyword, default True
        Nr   r[   r   )r   rd   r?   rad2degr   calc_anglesrf   rg   s      r   ro   zAngle.angle   sZ    * +.7dm&&4z!Q $q'"2DG4Dc 
 
 	
r   Nrk   )r5   rR   rS   rT   r   ro   rl   rC   r   r   rn   rn      s:          E
 
 
 
: EEEr   rn   c                   "    e Zd ZdZdZddZeZdS )Dihedrala  Dihedral (dihedral angle) between four
    :class:`~MDAnalysis.core.groups.Atom` instances.

    The dihedral is defined as the angle between the planes formed by
    Atoms (1, 2, 3) and (2, 3, 4).

    .. versionadded:: 0.8
    .. versionchanged:: 0.9.0
       Now a subclass of :class:`TopologyObject`; now uses :attr:`__slots__`
       and stores atoms in :attr:`atoms` attribute.
    .. versionchanged:: 0.11.0
       Renamed to Dihedral (was Torsion)

    dihedralTc           	          |r| j         j        nd}| j        \  }}}}t          j        t          j        |j        |j        |j        |j        |                    S )a  Calculate the dihedral angle in degrees.

        Dihedral angle around axis connecting atoms 1 and 2 (i.e. the angle
        between the planes spanned by atoms (0,1,2) and (1,2,3))::

                  3
                  |
            1-----2
           /
          0


        Note
        ----
        The numerical precision is typically not better than
        4 decimals (and is only tested to 3 decimals).

        .. versionadded:: 0.9.0
        .. versionchanged:: 0.19.0
           Added pbc keyword, default True
        N)r   rd   r   r?   rq   r   calc_dihedralsrf   )r   rh   ri   ABCDs          r   ru   zDihedral.dihedral  s^    , +.7dm&&4Z
1az$
AJ
AJ 
 
 	
r   Nrk   )r5   rR   rS   rT   r   ru   rl   rC   r   r   rt   rt      s:           E
 
 
 
> EEEr   rt   c                       e Zd ZdZdZd ZdS )ImproperDihedrala  
    Improper Dihedral (improper dihedral angle) between four
    :class:`~MDAnalysis.core.groups.Atom` instances.

    MDAnalysis treats the improper dihedral angle as the angle between
    the planes formed by Atoms (1, 2, 3) and (2, 3, 4).

    .. warning:: Definitions of Atom ordering in improper dihedrals
                 can change. Check the definitions here against
                 your software.

    .. versionadded:: 0.9.0
    .. versionchanged:: 0.11.0
       Renamed to ImproperDihedral (was Improper_Torsion)
    improperc                 *    |                                  S )zImproper dihedral angle in degrees.

        Note
        ----
        The numerical precision is typically not better than
        4 decimals (and is only tested to 3 decimals).
        )ru   r   s    r   r~   zImproperDihedral.improperF  s     }}r   N)r5   rR   rS   rT   r   r~   rC   r   r   r}   r}   2  s4         " E    r   r}   c                   (    e Zd ZdZdZd ZddZeZdS )UreyBradleya'  A Urey-Bradley angle between two :class:`~MDAnalysis.core.groups.Atom` instances.
    Two :class:`UreyBradley` instances can be compared with the ``==`` and
    ``!=`` operators. A UreyBradley angle is equal to another if the same atom
    numbers are involved.

    .. versionadded:: 1.0.0
    ureybradleyc                     || j         d         k    r| j         d         S || j         d         k    r| j         d         S t          d          )zUreyBradley.partner(Atom)
        Returns
        -------
        the other :class:`~MDAnalysis.core.groups.Atom` in this
        interaction
        r   r[   r\   r]   r_   s     r   ra   zUreyBradley.partner\  sM     4:a=  :a= TZ]"":a= 0111r   Tc                 z    |r| j         j        nd}t          j        | d         j        | d         j        |          S )zDistance between the atoms.Nr   r[   rc   rg   s      r   distancezUreyBradley.distancej  s9    *-7dm&&4#DG$4d1g6FLLLr   Nrk   )r5   rR   rS   rT   r   ra   r   rl   rC   r   r   r   r   Q  sM          E2 2 2M M M M
 EEEr   r   c                       e Zd ZdZdZdS )CMapz
    Coupled-torsion correction map term between five
    :class:`~MDAnalysis.core.groups.Atom` instances.

    .. versionadded:: 1.0.0
    cmapN)r5   rR   rS   rT   r   rC   r   r   r   r   r  s          EEEr   r   c                   X    e Zd ZdZd Zd Zed             Zd Zd Z	d Z
d Zd	 Zd
 ZdS )TopologyDicta  A customised dictionary designed for sorting the bonds, angles and
    dihedrals present in a group of atoms.

    Usage::

      topologydict = TopologyDict(members)


    TopologyDicts are also built lazily from a :class:`TopologyGroup.topDict`
    attribute.

    The :class:`TopologyDict` collects all the selected topology type from the
    atoms and categorises them according to the types of the atoms within. A
    :class:`TopologyGroup` containing all of a given bond type can be made by
    querying with the appropriate key. The keys to the :class:`TopologyDict`
    are a tuple of the atom types that the bond represents and can be viewed
    using the :meth:`keys` method.

    For example, from a system containing pure ethanol ::

      >>> td = u.bonds.topDict
      >>> td.keys()
      [('C', 'C'),
       ('C', 'H'),
       ('O', 'H'),
       ('C', 'O')]
      >>> td['C', 'O']
      < TopologyGroup containing 912 bonds >

    .. Note::

       The key for a bond is taken from the type attribute of the atoms.

       Getting and setting types of bonds is done smartly, so a C-C-H
       angle is considered identical to a H-C-C angle.

    Duplicate entries are automatically removed upon creation and
    combination of different Dicts.  This means a bond between atoms
    1 and 2 will only ever appear once in a dict despite both atoms 1
    and 2 having the bond in their :attr:`bond` attribute.

    Two :class:`TopologyDict` instances can be combined using
    addition and it will not create any duplicate bonds in the process.

    Arguments
    ---------
    members :
      A list of :class:`TopologyObject` instances


    .. versionadded:: 0.8
    .. versionchanged:: 0.9.0
       Changed initialisation to use a list of :class:`TopologyObject`
       instances instead of list of atoms; now used from within
       :class:`TopologyGroup` instead of accessed from :class:`AtomGroup`.

    c                    t          |t                    st          d          t                      | _        |j        | _        |j        | _        |D ];}|j        }	 | j        |xx         |gz  cc<   !# t          $ r |g| j        |<   Y 8w xY w| j        rUt          t          | j                                                  d         t                    r|                                  d S d S d S )Nz%Can only construct from TopologyGroupr   )
isinstanceTopologyGroup	TypeErrordictr   r   r   toptyper   KeyErrorlistkeysr#   _removeDupes)r   topologygroupbr   s       r   r   zTopologyDict.__init__  s   -77 	ECDDDFF	($* 	' 	'AFE'	%   QC'     ' ' '$%3	%   ' 9 	 D)9)9$:$:1$=uEE 	 	  	  	  	 s   A33B
Bc                     t                      }| j         D ]D}|ddd         |vr| j         |         ||<    ||ddd         xx         | j         |         z  cc<   E|| _         dS )zoSorts through contents and makes sure that there are
        no duplicate keys (through type reversal)
        Nr>   r   )r   newdictks      r   r   zTopologyDict._removeDupes  s     &&  	1 	1ATTrT7g%%!Yq\

$$B$   DIaL0    			r   c                     | j         S r   r    r   s    r   r   zTopologyDict.universe  r!   r   c                 N    t          | j                                                  S )z>Returns the number of types of bond in the topology dictionary)rP   r   r   r   s    r   rQ   zTopologyDict.__len__  s    49>>##$$$r   c                 4    | j                                         S )z8Returns a list of the different types of available bonds)r   r   r   s    r   r   zTopologyDict.keys  s    y~~r   c                 *    t          | j                  S )z%Iterator over keys in this dictionary)rM   r   r   s    r   rN   zTopologyDict.__iter__  s    DIr   c                 T    d                     t          |           | j                  S )Nz(<TopologyDict with {num} unique {type}s>numr   )r.   rP   r   r   s    r   r7   zTopologyDict.__repr__  s-    9@@D		 A 
 
 	
r   c                     || v rg|| j         v r| j         |         }n| j         |ddd                  }t          j        d |D                       }t          || j        | j                  S t          |          )zfReturns a TopologyGroup matching the criteria if possible,
        otherwise returns ``None``
        Nr>   c                     g | ]	}|j         
S rC   r   )r/   ss     r   r1   z,TopologyDict.__getitem__.<locals>.<listcomp>   s    :::1QY:::r   r   )r   r?   vstackr   r   r   r   )r   key	selectionbixs       r   rK   zTopologyDict.__getitem__  s     $;;di IcN		 Ic$$B$i0	)::	:::;;C dgT\BBBB3--r   c                 8    || j         v p|ddd         | j         v S )z
        Returns boolean on whether a given type exists within this dictionary

        For topology groups the key (1,2,3) is considered the same as (3,2,1)
        Nr>   r   r:   s     r   r<   zTopologyDict.__contains__  s'     	!=U44R4[DI%==r   N)r5   rR   rS   rT   r   r   rV   r   rQ   r   rN   r7   rK   r<   rC   r   r   r   r   }  s        8 8t     2      X% % %       
 
 

      > > > > >r   r            )rY   r   ro   ru   r~   r   c                   Z   e Zd ZdZ	 	 	 	 ddZed             Zd ZeZd Z	e e
d          d                         Zd	 Zed
             Zd ZeZd Zd Zd Zd Zd Zd Zd Zd Zed             Zed             Zed             Zed             Zd ZddddZd dZd!dZd!dZ dS )"r   a  A container for a groups of bonds.

    All bonds of a certain types can be retrieved from within the
    :class:`TopologyGroup` by querying with a tuple of types::

      tg2 = tg.select_bonds([key])

    Where *key* describes the desired bond as a tuple of the involved
    :class:`~MDAnalysis.core.groups.Atom` types, as defined by the .type Atom
    attribute). A list of available keys can be displayed using the
    :meth:`types` method.

    Alternatively, all the bonds which are in a given
    :class:`~MDAnalysis.core.groups.AtomGroup` can be extracted using
    :meth:`atomgroup_intersection`::

      tg2 = tg.atomgroup_intersection(ag)

    This allows the keyword *strict* to be given, which forces all members of
    all bonds to be inside the AtomGroup passed to it.

    Finally, a TopologyGroup can be sliced similarly to AtomGroups::

      tg2 = tg[5:10]

    The :meth:`bonds`, :meth:`angles` and :meth:`dihedrals` methods offer
    a "shortcut" to the Cython distance calculation functions in
    :class:`MDAnalysis.lib.distances`.

    TopologyGroups can be combined with TopologyGroups of the same bond
    type (ie can combine two angle containing TopologyGroups).

    .. versionadded:: 0.8
    .. versionchanged:: 0.9.0
       Overhauled completely: (1) Added internal :class:`TopologyDict`
       accessible by the :attr:`topDict` attribute. (2)
       :meth:`selectBonds` allows the :attr:`topDict` to be queried
       with tuple of types. (3) Added :meth:`atomgroup_intersection`
       to allow bonds which are in a given :class:`AtomGroup` to be retrieved.
    .. versionchanged:: 0.10.0
       Added :func:`from_indices` constructor, allowing class to be created
       from indices.
       Can now create empty Group.
       Renamed :meth:`dump_contents` to :meth:`to_indices`
    .. versionchanged:: 0.11.0
       Added `values` method to return the size of each object in this group
       Deprecated selectBonds method in favour of select_bonds
    .. versionchanged:: 0.19.0
       Empty TopologyGroup now returns correctly shaped empty array via
       indices property and to_indices()
    .. versionchanged::1.0.0
       ``type``, ``guessed``, and ``order`` are no longer reshaped to arrays
       with an extra dimension
    Nc                 :    |%ddddt          |d                             _        nK|t          v r| _        n:t          d                    d                    t                                        t          j        |          }t          |          }|t          j        d |          }|t          j        d|          }n9|du s|d	u rt          j        ||          }nt          j        |t          
          }|t          j        d |          }|dk    ryt          j        |d          \  }}	| _        ||	          _        ||	          _        ||	          _         fdt!           j        j        d                   D              _        nkt          j        g            _        t          j        g            _        t          j        g            _        t          j        g            _        g  _         _        t+                       _        d S )NrY   ro   ru   )r   r   r   r   z"Unsupported btype, use one of '{}'r,   TFdtype)return_indexc                 H    g | ]}j         j        d d |f                  S r   )r   _bix)r/   r0   r   r   s     r   r1   z*TopologyGroup.__init__.<locals>.<listcomp>  s>        tyA/  r   r[   )rP   r   _BTYPE_TO_SHAPEr^   r.   r6   r?   asarrayrepeatr&   r   unique_rowsr   
_bondtypesr   _orderrangeshape_agsarrayr   r   _cache)
r   bondidxr   r   r   r   r   nbondsuniquniq_idxs
   ` `       r   r   zTopologyGroup.__init__Q  s    = $J??GAJDJJ o%%DJJ6$))O4455  
 *W%%W<9T6**D?if--GG__5 0 0i00GGj555G=IdF++EA::!-gDIIIND(DI"8nDO#H-DM/DK    tyq122  DII DI hrllDOHRLLDM(2,,DKDIffr   c                     | j         S )zThe Universe that we belong tor    r   s    r   r   zTopologyGroup.universe  s     wr   c                     | j         |         S )zRetrieves a selection from this topology group based on types.

        .. seeAlso :meth:`types`

        .. versionadded 0.9.0
        )topDict)r   r   s     r   select_bondszTopologyGroup.select_bonds  s     |I&&r   c                 N    t          | j                                                  S )z]Return a list of the bond types in this TopologyGroup

        .. versionadded 0.9.0
        )r   r   r   r   s    r   r$   zTopologyGroup.types  s     
 DL%%''(((r   r   c                      t          |           S )a!  
        Returns the TopologyDict for this topology group.

        This is used for the select_bonds method when fetching a certain type
        of bond.

        This is a cached property so will be generated the first time it is
        accessed.

        .. versionadded 0.9.0
        )r   r   s    r   r   zTopologyGroup.topDict  s     D!!!r   c                     | s| S |                     dd          rt          j        nt          j        }|j        fd| j        j        D             } ||d          }| |         S )a  Retrieve all bonds from within this TopologyGroup that are within
        the AtomGroup which is passed.

        Parameters
        ----------
        ag : AtomGroup
            The `:class:~MDAnalysis.core.groups.AtomGroup` to intersect
            with.
        strict : bool
            Only retrieve bonds which are completely contained within the
            AtomGroup. [``False``]


        .. versionadded:: 0.9.0
        strictFc                 :    g | ]}t          j        |          S rC   )r?   isin)r/   colatom_idxs     r   r1   z8TopologyGroup.atomgroup_intersection.<locals>.<listcomp>  s%    >>>3X&&>>>r   r   )axis)getr?   allanyr   r   T)r   agkwargsfuncseenmaskr   s         @r   atomgroup_intersectionz$TopologyGroup.atomgroup_intersection  sz    "  	K  He44@rvv"&: ?>>>$)+>>> tDq!!!Dzr   c                 |    | s4t           | j                 }t          j        d|ft          j                  S | j        S )zvall bond indices

        See Also
        --------
        to_indices : function that just returns `indices`
        r   r   )r   r   r?   zerosint32r   )r   r   s     r   r   zTopologyGroup.indices  s;      	#DJ/E8QJbh77779r   c                     | j         S )a  Return a data structure with atom indices describing the bonds.

        This format should be identical to the original contents of the
        entries in universe._topology.
        Note that because bonds are sorted as they are initialised, the order
        that atoms are defined in each entry might be reversed.

        Returns
        -------
        indices : tuple
            A tuple of tuples which define the contents of this
            TopologyGroup in terms of the atom numbers.  (0 based
            index within u.atoms)

        .. versionadded:: 0.9.0
        .. versionchanged:: 0.10.0
           Renamed from "dump_contents" to "to_indices"

        r   r   s    r   
to_indiceszTopologyGroup.to_indices  s    ( |r   c                 &    | j         j        d         S )z%Number of bonds in the topology groupr   )r   r   r   s    r   rQ   zTopologyGroup.__len__  s    yq!!r   c                 j   t          |t          t          f          s/t          d                    t          |                              |s| S | st          |t                    rvt          |j        dddf         |j        |j        t          j
        |j        g          t          j
        |j        g          t          j
        |j        g                    S t          |j        |j        |j        |j        |j        |j                  S |j        | j        k    st          d          t          |t                    rt          t          j        | j        |j        dddf         g          | j        | j        t          j        | j        t          j
        |j        g          g          t          j        | j        t          j
        |j        g          g          t          j        | j        t          j
        |j        g          g                    S t          t          j        | j        |j        g          | j        | j        t          j        | j        |j        g          t          j        | j        |j        g          t          j        | j        |j        g                    S )zCombine two TopologyGroups together.

        Can combined two TopologyGroup of the same type, or add a single
        TopologyObject to a TopologyGroup.
        zJCan only combine TopologyObject or TopologyGroup to TopologyGroup, not {0}Nr   r   r   r   z6Cannot add different types of TopologyObjects together)r   r	   r   r   r.   r   r   r   r   r?   r   r   r'   r   r   r   r   concatenater:   s     r   __add__zTopologyGroup.__add__  s    %.-!@AA 	6$u++&&    	K 2	%00 $M$'*N+5?"344He&6%788(EK=11    %MN+)!N,    ;$*,,O   %00 $NDL%-aaa2H#IJJM*"(EO3D*E*EF  N%2B1C(D(DE  .bh}&=&=>      %NDL%-#@AAM*%:J(KLLNDM5>+JKK.$+u|)DEE   r   c           	         t          |t          j                  rst          t          t
          t          t          t          d| j	                 } || j
        |         | j        | j        |         | j        |         | j        |                   S |                     | j
        |         | j        | j	        | j        |         | j        |         | j        |                   S )zReturns a particular bond as single object or a subset of
        this TopologyGroup as another TopologyGroup

        .. versionchanged:: 0.10.0
           Allows indexing via boolean numpy array
        )rY   ro   ru   r~   r   r   )r   r   r   r   )r   numbersIntegralrX   rn   rt   r}   r   r   r   r   r   r   r   r   r4   )r   rJ   outclasss      r   rK   zTopologyGroup.__getitem__H  s     dG,-- 	$,*  jH 8	$_T*d+k$'    >>	$j_T*d+k$' "   r   c                     |j         | j        v S )z+Tests if this TopologyGroup contains a bond)r   r   rI   s     r   r<   zTopologyGroup.__contains__k  s    |ty((r   c                 T    d                     t          |           | j                  S )Nz(<TopologyGroup containing {num} {type}s>r   )r.   rP   r   r   s    r   r7   zTopologyGroup.__repr__o  s-    9@@D		
 A 
 
 	
r   c                 @    t          j        | j        |j                  S )z,Test if contents of TopologyGroups are equal)r?   r@   r   r:   s     r   rA   zTopologyGroup.__eq__t  s    ~dlEM:::r   c                     | |k     S r   rC   r:   s     r   rD   zTopologyGroup.__ne__x  rE   r   c                 *    t          |           dk     S )Nr   )rP   r   s    r   __nonzero__zTopologyGroup.__nonzero__{  s    t99>!!r   c                     | j         d         S )z3The first atom in each TopologyObject in this Groupr   r   r   s    r   atom1zTopologyGroup.atom1~       y|r   c                     | j         d         S )z4The second atom in each TopologyObject in this Groupr[   r   r   s    r   atom2zTopologyGroup.atom2  r   r   c                     	 | j         d         S # t          $ r1 t          | j                 }d| j         d| d}t          |          dw xY w)z3The third atom in each TopologyObject in this Groupr   TopologyGroup of s only has  vertical AtomGroupsNr   
IndexErrorr   r   r   nverterrmsgs      r   atom3zTopologyGroup.atom3  u    	/9Q< 	/ 	/ 	/#DJ/E'DJ ' '5 ' ' '  V$$$.	/	    ;A
c                     	 | j         d         S # t          $ r1 t          | j                 }d| j         d| d}t          |          dw xY w)z4The fourth atom in each TopologyObject in this Groupr   r   r   r   Nr   r   s      r   atom4zTopologyGroup.atom4  r   r  c                     | j         dk    r | j        di |S | j         dk    r | j        di |S | j         dk    r | j        di |S | j         dk    r | j        di |S dS )ab  Return the size of each object in this Group

        :Keywords:
           *pbc*
              apply periodic boundary conditions when calculating distance
              [``False``]
           *result*
              allows a predefined results array to be used,
              note that this will be overwritten

        .. versionadded:: 0.11.0
        rY   ro   ru   r~   NrC   )r   bondsangles	dihedrals)r   r   s     r   valueszTopologyGroup.values  s     :4:'''''Z7""4;(((((Z:%%!4>++F+++Z:%%!4>++F+++ &%r   F)resultrh   c                F    t           fd|D                       s(d                    |          }t          d| d          |s,t          j        t                     t          j                  }|sd n j        d         j        }d  j        D             } ||||dS )Nc              3   .   K   | ]}j         |k    V  d S r   r   )r/   r   r   s     r   	<genexpr>z8TopologyGroup._calc_connection_values.<locals>.<genexpr>  s*      ;;54:&;;;;;;r   z' or 'zTopologyGroup is not of type ''r   c                     g | ]	}|j         
S rC   )	positions)r/   r   s     r   r1   z9TopologyGroup._calc_connection_values.<locals>.<listcomp>  s    666bR\666r   )ri   r	  )	r   r6   r   r?   r   rP   float64r   rd   )r   r   r	  rh   btypesstrbtyperi   r  s   `       r   _calc_connection_valuesz%TopologyGroup._calc_connection_values  s    ;;;;F;;;;; 	J}}V,,HHXHHHIII 	5Xc$ii44F:dd49Q<#:66DI666	tYC7777r   c                 H    |                      t          j        d||          S )as  Calculates the distance between all bonds in this TopologyGroup

        :Keywords:
           *pbc*
              apply periodic boundary conditions when calculating distance
              [False]
           *result*
              allows a predefined results array to be used,
              note that this will be overwritten

        Uses cython implementation
        rY   rh   r	  )r  r   re   )r   rh   r	  s      r   r  zTopologyGroup.bonds  s-     ++ &c& , 
 
 	
r   c                 H    |                      t          j        d||          S )a  Calculates the angle in radians formed between a bond
        between atoms 1 and 2 and a bond between atoms 2 & 3

        Parameters
        ----------
        result : array_like
            allows a predefined results array to be used, note that this
            will be overwritten
        pbc : bool
            apply periodic boundary conditions when calculating angles
            [``False``] this is important when connecting vectors between
            atoms might require minimum image convention

        Returns
        -------
        angles : ndarray

        .. versionchanged :: 0.9.0
           Added *pbc* option (default ``False``)

        ro   r  )r  r   rr   r   r	  rh   s      r   r  zTopologyGroup.angles  s-    , ++!7F , 
 
 	
r   c                 J    |                      t          j        dd||          S )a  Calculate the dihedral angle in radians for this topology
        group.

        Defined as the angle between a plane formed by atoms 1, 2 and
        3 and a plane formed by atoms 2, 3 and 4.

        Parameters
        ----------
        result : array_like
            allows a predefined results array to be used, note that this
            will be overwritten
        pbc : bool
            apply periodic boundary conditions when calculating angles
            [``False``] this is important when connecting vectors between
            atoms might require minimum image convention

        Returns
        -------
        angles : ndarray

        .. versionchanged:: 0.9.0
           Added *pbc* option (default ``False``)
        ru   r~   r  )r  r   rw   r  s      r   r  zTopologyGroup.dihedrals  s3    0 ++$ , 
 
 	
r   )NNNN)FN)NF)!r5   rR   rS   rT   r   rV   r   r   selectBondsr$   r   r   r   r   r   dump_contentsrQ   r   rK   r<   r7   rA   rD   r   r   r   r   r  r  r  r  r  r  rC   r   r   r   r     sE       5 5v < < < <|   X' ' ' K) ) ) VF^^" " ^ X"     D   X  , M" " "C C CJ! ! !F) ) )
 
 

; ; ;! ! !" " "   X   X 
/ 
/ X
/ 
/ 
/ X
/, , ,, =Ae 8 8 8 8 8
 
 
 
"
 
 
 
4
 
 
 
 
 
r   r   )rT   r   numpyr?   	functoolslibr   lib.utilr   r   r   total_orderingobjectr	   rX   rn   rt   r}   r   r   r   r   r   rC   r   r   <module>r!     sN  0                                   o o o o oV o o od1 1 1 1 1> 1 1 1h) ) ) ) )N ) ) )X2 2 2 2 2~ 2 2 2l    x   >    .   B    >   O> O> O> O> O>6 O> O> O>f  t
 t
 t
 t
 t
F t
 t
 t
 t
 t
r   