
    {TiC                         d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
  G d	 d
e      Zedk(  rddlmZ  e        yy)z3Bio.SearchIO object to model a single database hit.    )chain)allitems)getattr_str)optionalcascade   )_BaseSearchObject)HSPc                      e Zd ZdZdZd&dZd Zd Zd Zd Z	d	 Z
d
 Zd Zd Zd Zd Z eddd      Z eddd      Z eddd      Z eddd      Z ed      Zed        Zed        Zed        Zd  Zd'd!Zd" Zd'd#Zd(d$Zd)d%Z y)*Hita  Class representing a single database hit of a search result.

    Hit objects are the second-level container in the SearchIO module. They
    are the objects contained within a QueryResult (see QueryResult). They
    themselves are container for HSP objects and will contain at least one
    HSP.

    To have a quick look at a Hit and its contents, invoke ``print`` on it::

        >>> from Bio import SearchIO
        >>> qresult = next(SearchIO.parse('Blast/mirna.xml', 'blast-xml'))
        >>> hit = qresult[3]
        >>> print(hit)
        Query: 33211
               mir_1
          Hit: gi|301171322|ref|NR_035857.1| (86)
               Pan troglodytes microRNA mir-520c (MIR520C), microRNA
         HSPs: ----  --------  ---------  ------  ---------------  ---------------------
                  #   E-value  Bit score    Span      Query range              Hit range
               ----  --------  ---------  ------  ---------------  ---------------------
                  0   8.9e-20     100.47      60           [1:61]                [13:73]
                  1   3.3e-06      55.39      60           [0:60]                [13:73]

    You can invoke ``len`` on a Hit object to see how many HSP objects it contains::

        >>> len(hit)
        2

    Hit objects behave very similar to Python lists. You can retrieve the HSP
    object inside a Hit using the HSP's integer index. Hit objects can also be
    sliced, which will return a new Hit objects containing only the sliced HSPs::

        # HSP items inside the Hit can be retrieved using its integer index
        >>> hit[0]
        HSP(hit_id='gi|301171322|ref|NR_035857.1|', query_id='33211', 1 fragments)

        # slicing returns a new Hit
        >>> hit
        Hit(id='gi|301171322|ref|NR_035857.1|', query_id='33211', 2 hsps)
        >>> hit[:1]
        Hit(id='gi|301171322|ref|NR_035857.1|', query_id='33211', 1 hsps)
        >>> print(hit[1:])
        Query: 33211
               mir_1
          Hit: gi|301171322|ref|NR_035857.1| (86)
               Pan troglodytes microRNA mir-520c (MIR520C), microRNA
         HSPs: ----  --------  ---------  ------  ---------------  ---------------------
                  #   E-value  Bit score    Span      Query range              Hit range
               ----  --------  ---------  ------  ---------------  ---------------------
                  0   3.3e-06      55.39      60           [0:60]                [13:73]

    Hit objects provide ``filter`` and ``map`` methods, which are analogous to
    Python's built-in ``filter`` and ``map`` except that they return a new Hit
    object instead of a list.

    Here is an example of using ``filter`` to select for HSPs whose e-value is
    less than 1e-10::

        >>> evalue_filter = lambda hsp: hsp.evalue < 1e-10
        >>> filtered_hit = hit.filter(evalue_filter)
        >>> len(hit)
        2
        >>> len(filtered_hit)
        1
        >>> print(filtered_hit)
        Query: 33211
               mir_1
          Hit: gi|301171322|ref|NR_035857.1| (86)
               Pan troglodytes microRNA mir-520c (MIR520C), microRNA
         HSPs: ----  --------  ---------  ------  ---------------  ---------------------
                  #   E-value  Bit score    Span      Query range              Hit range
               ----  --------  ---------  ------  ---------------  ---------------------
                  0   8.9e-20     100.47      60           [1:61]                [13:73]

    There are also other methods which are counterparts of Python lists' methods
    with the same names: ``append``, ``index``, ``pop``, and ``sort``. Consult their
    respective documentations for more details and examples of their usage.

    _itemsNc           
      T   || _         g | _        || _        d| _        g | _        d| _        i | _        g | _        dD ]6  }t        |D ch c]  }t        ||       c}      dkD  s*t        d|z         g | _        |D ]$  }| j                  |       | j                  |       & yc c}w )a  Initialize a Hit object.

        :param hsps: HSP objects contained in the Hit object
        :type hsps: iterable yielding HSP
        :param id: hit ID
        :type id: string
        :param query_id: query ID
        :type query_id: string

        If multiple HSP objects are used for initialization, they must all
        have the same ``query_id``, ``query_description``, ``hit_id``, and
        ``hit_description`` properties.
        N)query_idquery_descriptionhit_idhit_descriptionr   z6Hit object can not contain HSPs with more than one %s.)_id_id_alt	_query_id_description_description_alt_query_description
attributesdbxrefslengetattr
ValueErrorr   _validate_hspappend)selfhspsidr   attrhsps         J/home/agent/.local/lib/python3.12/site-packages/Bio/SearchIO/_model/hit.py__init__zHit.__init__g   s     !  ""& S 	D
 $73GC&781< LtS 	  	Cs#KK		 8s   B%
c                 T    d| j                   d| j                  dt        |       dS )z+Return string representation of Hit object.zHit(id=z, query_id=, z hsps))r"   r   r   r    s    r%   __repr__zHit.__repr__   s*    ;t}}.?r#d)fUU    c                 ,    t        | j                        S )zIterate over hsps.)iterr!   r)   s    r%   __iter__zHit.__iter__       DIIr+   c                 ,    t        | j                        S )zReturn number of hsps.)r   r!   r)   s    r%   __len__zHit.__len__   s    499~r+   c                 ,    t        | j                        S )zReturn True if there are hsps.)boolr!   r)   s    r%   __bool__zHit.__bool__   r/   r+   c                     || j                   v S )zReturn True if hsp in items.r   r    r$   s     r%   __contains__zHit.__contains__   s    dkk!!r+   c           
      T   g }d| j                   z  }|j                  |       | j                  r8d| j                  z  }t        |      dkD  r|dd dz   n|}|j                  |       d| j                  z  }	 | j
                  }|d|z  z  }|j                  |       | j                  r8d| j                  z  }t        |      dkD  r|dd dz   n|}|j                  |       t        | j                  j                               D ]  \  }}|j                  d	| d
|         | j                  r-|j                  ddj                  | j                        z          | j                  s|j                  d       n|j                  ddz         d}|j                  |dz         |j                  |dz         t        | j                        D ]  \  }	}
t        |
dd      }t        |
dd      }t        |
d      }t        |
d      }t        |
d      }d| d| d}t        |      dkD  r|dd dz   n|}t        |
d       }t        |
d!      }d| d| d}t        |      d"kD  r|dd# dz   n|}|j                  ||	|||||fz          d$j                  |      S # t        $ r Y w xY w)%z2Return a human readable summary of the Hit object.z	Query: %sz	       %sP   NM   z...z	  Hit: %sz (%i) z: zDatabase cross-references: r(   z HSPs: ?z HSPs: %s  %s  %s  %s  %s  %s)z----z--------z	---------z------z---------------z---------------------z%11s  %8s  %9s  %6s  %15s  %21s)#zE-valuez	Bit scoreSpanzQuery rangez	Hit rangeevaluez%.2g)fmtbitscorez%.2faln_spanquery_start	query_end[:]      z~]	hit_starthit_end      
)r   r   r   r   r"   seq_lenAttributeErrordescriptionsortedr   itemsr   joinr!   	enumerater   )r    linesqid_linelinehid_linerN   keyvaluepatternidxr$   r>   r@   rA   rB   rC   query_rangerI   rJ   	hit_ranges                       r%   __str__zHit.__str__   s    .X!!!7!77D(+D	B49u$DDLL (	*llG '))HX!1!11D(+D	B49u$DDLL !!6!6!89 	-JCLL1SEE7+,	- <<LL64<<9PPQ yyLL$LL/JK 8GLLST LLRR &dii0 S$S(?&sJFC&sJ7)#}='[9	 !+a	{!< 03;/?"/DK$t++  ([9	%c95	{!G9A6	58^b5HIcrNT1i	sFHhYWW+2 yyw  		s   7J 	J'&J'c                     t        |t              r1| j                  | j                  |         }| j	                  |       |S | j
                  |   S )z)Return the HSP object at the given index.)
isinstanceslice	__class__r!   _transfer_attrsr   )r    r\   objs      r%   __getitem__zHit.__getitem__   sF     c5!..30C  %J{{3r+   c                     t        |t        t        f      r|D ]  }| j                  |        n| j                  |       || j                  |<   y)zAssign hsps to index idx.N)ra   listtupler   r   )r    r\   r!   r$   s       r%   __setitem__zHit.__setitem__   sM     dT5M* (""3'( t$Cr+   c                     | j                   |= y)zDelete item of index idx.Nr   )r    r\   s     r%   __delitem__zHit.__delitem__  s    KKr+   c                 8   t        |t              st        d      | j                  rr| j                  ?|j
                  | j                  k7  r7t        d| j                  d|j
                  d      |j
                  | _        | j                  ?|j                  | j                  k7  r7t        d| j                  d|j                  d      |j                  | _        | j                  ?|j                  | j                  k7  r7t        d| j                  d|j                  d      |j                  | _	        | j                  @|j                  | j                  k7  r&t        d| j                  d|j                  d      y|j                  | _
        yy)	zValidate an HSP object (PRIVATE).

        Valid HSP objects have the same hit_id as the Hit object ID and the
        same query_id as the Hit object's query_id.

        z)Hit objects can only contain HSP objects.NzExpected HSP with hit ID z, found z	 instead.z"Expected HSP with hit description zExpected HSP with query ID z$Expected HSP with query description )ra   r	   	TypeErrorr   r"   r   r   rP   r   r   r   r6   s     r%   r   zHit._validate_hsp  sa    #s#GHH;;ww"::($77CJJ0 
 **+&&$*:*::$++S-@-@B 
 $'#6#6 }}(<<4==0$==#,,8 
 !$%%1((D,B,BB$1133H3HJ  C *-)>)>&G r+   r   r   zHit descriptionr   r   z.Description of the query that produced the hitr   r   zHit ID string.r   r   z,ID string of the query that produced the hitz HSP objects contained in the Hit)docc                 6    | j                   g| j                  z   S )zAlternative ID(s) of the Hit.)r"   r   r)   s    r%   id_allz
Hit.id_allK  s     y4<<''r+   c                 6    | j                   g| j                  z   S )z$Alternative descriptions of the Hit.)rP   r   r)   s    r%   description_allzHit.description_allP  s       !D$9$999r+   c                 8    t        t        | j                         S )z4Access the HSPFragment objects contained in the Hit.)rh   r   r   r)   s    r%   	fragmentszHit.fragmentsU  s     E4;;'((r+   c                 \    | j                  |       | j                  j                  |       y)a0  Add a HSP object to the end of Hit.

        Parameters
        hsp -- HSP object to append.

        Any HSP object appended must have the same ``hit_id`` property as the
        Hit object's ``id`` property and the same ``query_id`` property as the
        Hit object's ``query_id`` property.

        N)r   r   r   r6   s     r%   r   z
Hit.append[  s$     	33r+   c                     t        t        || j                              }|r$| j                  |      }| j	                  |       |S y)ae  Create new Hit object whose HSP objects pass the filter function.

        :param func: function for filtering
        :type func: callable, accepts HSP, returns bool

        ``filter`` is analogous to Python's built-in ``filter`` function, except
        that instead of returning a list it returns a ``Hit`` object. Here is an
        example of using ``filter`` to select for HSPs having bitscores bigger
        than 60::

            >>> from Bio import SearchIO
            >>> qresult = next(SearchIO.parse('Blast/mirna.xml', 'blast-xml'))
            >>> hit = qresult[3]
            >>> evalue_filter = lambda hsp: hsp.bitscore > 60
            >>> filtered_hit = hit.filter(evalue_filter)
            >>> len(hit)
            2
            >>> len(filtered_hit)
            1
            >>> print(filtered_hit)
            Query: 33211
                   mir_1
              Hit: gi|301171322|ref|NR_035857.1| (86)
                   Pan troglodytes microRNA mir-520c (MIR520C), microRNA
             HSPs: ----  --------  ---------  ------  ---------------  ---------------------
                      #   E-value  Bit score    Span      Query range              Hit range
                   ----  --------  ---------  ------  ---------------  ---------------------
                      0   8.9e-20     100.47      60           [1:61]                [13:73]

        N)rh   filterr!   rc   rd   )r    funcr!   re   s       r%   rx   z
Hit.filteri  sB    > F4+,..&C  %J r+   c                 8    | j                   j                  |      S )z{Return the index of a given HSP object, zero-based.

        :param hsp: object to look up
        :type hsp: HSP

        )r   indexr6   s     r%   r{   z	Hit.index  s     {{  %%r+   c                     |#| j                   dd D cg c]
  } ||       }}n| j                   dd }|r$| j                  |      }| j                  |       |S yc c}w )aK  Create new Hit object, mapping the given function to its HSPs.

        :param func: function for mapping
        :type func: callable, accepts HSP, returns HSP

        ``map`` is analogous to Python's built-in ``map`` function. It is applied to
        all HSPs contained in the Hit object and returns a new Hit object.

        N)r!   rc   rd   )r    ry   xr!   re   s        r%   mapzHit.map  sd     %)YYq\2DG2D299Q<D..&C  %J  3s   Ac                 8    | j                   j                  |      S )zRemove and returns the HSP object at the specified index.

        :param index: index of HSP object to pop
        :type index: int

        )r   pop)r    r{   s     r%   r   zHit.pop  s     {{u%%r+   c                     |r| j                   j                  ||       y| j                  dd }|j                  ||       | j                  |      }| j	                  |       |S )a&  Sort the HSP objects.

        :param key: sorting function
        :type key: callable, accepts HSP, returns key for sorting
        :param reverse: whether to reverse sorting results or no
        :type reverse: bool
        :param in_place: whether to do in-place sorting or no
        :type in_place: bool

        ``sort`` defaults to sorting in-place, to mimic Python's ``list.sort``
        method. If you set the ``in_place`` argument to False, it will treat
        return a new, sorted Hit object and keep the initial one unsorted

        )rY   reverseN)r   sortr!   rc   rd   )r    rY   r   in_placer!   re   s         r%   r   zHit.sort  s\     KKg699Q<DII#wI/..&C  %Jr+   ) NN)N))NFT)!__name__
__module____qualname____doc___NON_STICKY_ATTRSr&   r*   r.   r1   r4   r7   r_   rf   rj   rl   r   r   rP   r   r"   r   r   r!   propertyrq   rs   ru   r   rx   r{   r~   r   r   r   r+   r%   r   r      s   Nd $)VV"K Z 	 
-?` ")+@K (<
 
*>	?BZ!SH >?D( ( : : ) )
 #J&&&r+   r   __main__)run_doctestN)r   	itertoolsr   Bio.SearchIO._utilsr   r   r   _baser   r$   r	   r   r   
Bio._utilsr   r   r+   r%   <module>r      sC    :  ( + / $ w
 wv z&M r+   