
:>"^Y`                 @   s  d  Z  d d l m Z d d l m Z d d l m Z m Z d d l m	 Z	 m
 Z
 d d l m Z Gd d   d e  Z d	 d
   Z d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z Gd d    d  e	  Z d! S)"a  Implementations of Biopython-like Seq objects on top of BioSQL.

This allows retrival of items stored in a BioSQL database using
a biopython-like SeqRecord and Seq interface.

Note: Currently we do not support recording per-letter-annotations
(like quality scores) in BioSQL.
    )unicode)Alphabet)Seq
UnknownSeq)	SeqRecord_RestrictedDict)
SeqFeaturec               @   s   e  Z d  Z d Z d d   Z d d   Z d d   Z d d	   Z d
 d   Z e	 e d d Z
 d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z d S)DBSeqz.BioSQL equivalent of the Biopython Seq object.c             C   s1   | |  _  | |  _ | |  _ | |  _ | |  _ d S)zCreate a new DBSeq object referring to a BioSQL entry.

        You wouldn't normally create a DBSeq object yourself, this is done
        for you when retreiving a DBSeqRecord object from the database.
        N)
primary_idadaptoralphabet_lengthstart)selfr
   r   r   r   length r   2/tmp/pip-build-ww9dw3qa/biopython/BioSQL/BioSeq.py__init__    s
    				zDBSeq.__init__c             C   s   |  j  S)z"Return the length of the sequence.)r   )r   r   r   r   __len__,   s    zDBSeq.__len__c             C   sG  t  | t  r | } | d k  rM | |  j k r= t |   | |  j } n | |  j k rh t |   |  j j |  j |  j | |  j | d  St  | t  s t	 d   | j d k r d } n	 | j } | d k  r| |  j k r t |   | |  j } n | |  j k r|  j } | j
 d k r:|  j } n	 | j
 } | d k  r{| |  j k rkt |   | |  j } n | |  j k r|  j } | | k rt d |  j  S| j d k s| j d k r|  j |  j |  j |  j |  j | | |  S|  j j |  j |  j | |  j |  } t | d d | j  |  j  Sd S)z&Return a subsequence or single letter.r      zUnexpected index typeN )
isinstanceintr   
IndexErrorr   get_subseq_as_stringr
   r   slice	TypeErrorstopr   r   step	__class__)r   indexijfullr   r   r   __getitem__0   sL    	"					'	 zDBSeq.__getitem__c             C   sB   d d l  } | j d t  |  j j |  j |  j |  j |  j  S)zReturn the full sequence as a python string (DEPRECATED).

        You are now encouraged to use str(my_seq) instead of
        my_seq.tostring().
        r   NzMThis method is obsolete; please use str(my_seq) instead of my_seq.tostring().)warningswarnPendingDeprecationWarningr   r   r
   r   r   )r   r%   r   r   r   tostringn   s    	zDBSeq.tostringc             C   s&   |  j  j |  j |  j |  j |  j  S)z,Return the full sequence as a python string.)r   r   r
   r   r   )r   r   r   r   __str__   s    	zDBSeq.__str__doczSequence as string (DEPRECATED)c             C   s   t  t |   |  j  S)z)Return the full sequence as a Seq object.)r   strr   )r   r   r   r   toseq   s    zDBSeq.toseqc             C   s   |  j    | S)zAdd another sequence or string to this sequence.

        The sequence is first converted to a Seq object before the addition.
        The returned object is a Seq object, not a DBSeq object.
        )r,   )r   otherr   r   r   __add__   s    zDBSeq.__add__c             C   s   | |  j    S)zAdd another sequence or string to the left.

        The sequence is first converted to a Seq object before the addition.
        The returned object is a Seq object, not a DBSeq object.
        )r,   )r   r-   r   r   r   __radd__   s    zDBSeq.__radd__c             C   s   |  j    | S)zMultiply sequence by an integer.

        The sequence is first converted to a Seq object before multiplication.
        The returned object is a Seq object, not a DBSeq object.
        )r,   )r   r-   r   r   r   __mul__   s    zDBSeq.__mul__c             C   s   | |  j    S)zMultiply integer by a sequence.

        The sequence is first converted to a Seq object before multiplication.
        The returned object is a Seq object, not a DBSeq object.
        )r,   )r   r-   r   r   r   __rmul__   s    zDBSeq.__rmul__c             C   s   |  j    | S)zMultiply sequence by integer in-place.

        The sequence is first converted to a Seq object before multiplication.
        The returned object is a Seq object, not a DBSeq object.
        )r,   )r   r-   r   r   r   __imul__   s    zDBSeq.__imul__N)__name__
__module____qualname____doc__r   r   r$   r(   r)   propertydatar,   r.   r/   r0   r1   r2   r   r   r   r   r	      s   >				r	   c             C   sN   |  j  d | f  } | s d  St |  d k s7 t  | d \ } t |  S)Nz5SELECT length FROM biosequence WHERE bioentry_id = %sr   r   )execute_and_fetchalllenAssertionErrorr   )r   r
   seqsgiven_lengthr   r   r   _retrieve_seq_len   s    r>   c       	      C   s  |  j  d | f  } | s d  St |  d k s7 t  | d \ } } } y4 t |  } t |  } | | k sw t  d } Wn t k
 r| d  k s t  |  j  d | f  } t |  d k s t  | d \ } } } | d  k s | d k s t  t |  } d } ~ Yn X~ | j   } | d k r?t j } nX | d	 k rWt j } n@ | d
 k rot j	 } n( | d k rt j
 } n t d |   | rt | |  | d t |   St | |  Sd  S)NzLSELECT alphabet, length, length(seq) FROM biosequence WHERE bioentry_id = %sr   r   TzDSELECT alphabet, length, seq FROM biosequence WHERE bioentry_id = %sr   FZdnaZrnaZproteinunknownzUnknown moltype: %s)r9   r:   r;   r   r   lowerr   Zgeneric_dnaZgeneric_rnaZgeneric_proteinZsingle_letter_alphabetr	   r   )	r   r
   r<   Zmoltyper=   r   Zhave_seqseqr   r   r   r   _retrieve_seq   sJ    
rB   c             C   s{   g  } |  j  d | f  } xY | D]Q \ } } } | rV | d k rV d | | f } n | } | j d | | f  q" W| S)zBRetrieve the database cross references for the sequence (PRIVATE).z{SELECT dbname, accession, version FROM bioentry_dbxref join dbxref using (dbxref_id) WHERE bioentry_id = %s ORDER BY "rank"0z%s.%sz%s:%s)r9   append)r   r
   _dbxrefsdbxrefsdbname	accessionversionvr   r   r   _retrieve_dbxrefs   s    rK   c             C   s  d } |  j  | | f  } g  } x| D]\ } } } |  j  d | f  } i  }	 x- | D]% \ }
 } |	 j |
 g   j |  qY W|  j  d | f  } x= | D]5 \ }
 } d |
 | f } |	 j d g   j |  q W|  j  d | f  } g  } x| D] \ } } } } | r| d 8} | d k r-d  } | d k rOt d	 | | f   | d  k	 r| d  k	 r| | k  rd d  l } d d
 l m } | j d | | | f |  | d  k rt j	   } | d  k rt j	   } | j | | | | f  q W|  j  d | f  } i  } xg | D]_ \ } } } } | rR| d k rRd | | f } n | } | d k rjd  } | | f | | <qWt j d |  } | | _
 |	 | _ t |  d k rnJt |  d k r<| d \ } } } } t |  |  | _ | j | d  \ } } t j | |  | _ | | _ | | _ | | _ n g  } xc | D][ } | \ } } } } | j | d  \ } } | j t j | | d | d | d |  qIWd d   | D } t |  d k rd | k r| d  d  d  } t j | d  | _ | j |  q( W| S)NzSELECT seqfeature_id, type.name, "rank" FROM seqfeature join term type on (type_term_id = type.term_id) WHERE bioentry_id = %s ORDER BY "rank"zvSELECT name, value FROM seqfeature_qualifier_value  join term using (term_id) WHERE seqfeature_id = %s ORDER BY "rank"zSELECT dbxref.dbname, dbxref.accession FROM dbxref join seqfeature_dbxref using (dbxref_id) WHERE seqfeature_dbxref.seqfeature_id = %s ORDER BY "rank"z%s:%sZdb_xrefzeSELECT location_id, start_pos, end_pos, strand FROM location WHERE seqfeature_id = %s ORDER BY "rank"r   r   z8Invalid strand %s found in database for seqfeature_id %s)BiopythonWarningz<Inverted location start/end (%i and %i) for seqfeature_id %szsSELECT location_id, dbname, accession, version FROM location join dbxref using (dbxref_id) WHERE seqfeature_id = %srC   z%s.%sr   typestrandrefref_dbc             S   s   h  |  ] } | j   q Sr   )rN   ).0lr   r   r   	<setcomp>  s   	 z%_retrieve_features.<locals>.<setcomp>joinr   )r   rU   N)NN)NNrU   rU   )r9   
setdefaultrD   
ValueErrorr%   BiorL   r&   r   ZUnknownPositionZ_seqfeature_id
qualifiersr:   "_retrieve_location_qualifier_valueZlocation_operatorgetFeatureLocationlocationrN   rP   rO   ZCompoundLocation)r   r
   ZsqlresultsZseq_feature_listZseqfeature_idZseqfeature_typeZseqfeature_rankqvsrY   Zqv_nameZqv_valuevalue	locationslocation_idr   endrN   r%   rL   Zremote_resultslookuprG   rH   rI   rJ   featureZlocsr]   Zstrandsr   r   r   _retrieve_features  s    
$				#rf   c             C   s>   |  j  d | f  } y | d SWn t k
 r9 d SYn Xd  S)NzASELECT value FROM location_qualifier_value WHERE location_id = %sr   r   )execute_and_fetch_col0r   )r   rb   r`   r   r   r   rZ     s    rZ   c             C   s   i  } | j  t |  |   | j  t |  |   | j  t |  | |   | j  t |  |   i  } xd | j   D]V \ } } t | t  r d d   | D } n t | t  r t	 |  } | | | <qt W| S)Nc             S   s   g  |  ] } t  |   q Sr   )_make_unicode_into_string)rQ   xr   r   r   
<listcomp>  s   	 z)_retrieve_annotations.<locals>.<listcomp>)
update_retrieve_qualifier_value_retrieve_reference_retrieve_taxon_retrieve_commentitemsr   listr   r+   )r   r
   taxon_idannotationsZstr_annskeyvalr   r   r   _retrieve_annotations  s    rv   c             C   s!   t  |  t  r t |   S|  Sd  S)N)r   r   r+   )textr   r   r   rh     s    
rh   c             C   s   |  j  d | f  } i  } xi | D]a \ } } | d k rC d } n' | d k rX d } n | d k rj d } | j | g   j |  q" W| S)NzqSELECT name, value FROM bioentry_qualifier_value JOIN term USING (term_id) WHERE bioentry_id = %s ORDER BY "rank"keywordkeywordsZdate_changeddateZsecondary_accessionZ
accessions)r9   rV   rD   )r   r
   r_   rY   namer`   r   r   r   rl     s    		rl   c             C   s  |  j  d | f  } g  } x | D] \ } } } } } }	 }
 t j   } | d  k	 sa | d  k	 r | d  k	 rw | d 8} t j | |  g | _ | r | | _ | r | | _ | | _ |	 d k r |
 | _ n |	 d k r |
 | _	 | j
 |  q" W| rd | i Si  Sd  S)NzSELECT start_pos, end_pos,  location, title, authors, dbname, accession FROM bioentry_reference JOIN reference USING (reference_id) LEFT JOIN dbxref USING (dbxref_id) WHERE bioentry_id = %s ORDER BY "rank"r   ZPUBMEDZMEDLINE
references)r9   r   Z	Referencer\   r]   authorstitleZjournalZ	pubmed_idZ
medline_idrD   )r   r
   refsr|   r   rc   r]   r~   r}   rG   rH   	referencer   r   r   rm     s.    "
				
rm   c             C   s  i  } |  j  d | f  } | r/ | d | d <|  j  d | f  } | rX | d | d <|  j  d | f  } | r | d r | d d k r | d | d <g  } xK | r |  j d	 | f  \ } }	 }
 | |
 k r P| j d |  |
 } q W| r | | d
 <| S)NzVSELECT name FROM taxon_name WHERE taxon_id = %s AND name_class = 'genbank common name'r   sourcezRSELECT name FROM taxon_name WHERE taxon_id = %s AND name_class = 'scientific name'Zorganismz3SELECT ncbi_taxon_id FROM taxon WHERE taxon_id = %srC   Z
ncbi_taxidzSELECT taxon_name.name, taxon.node_rank, taxon.parent_taxon_id FROM taxon, taxon_name WHERE taxon.taxon_id=taxon_name.taxon_id AND taxon_name.name_class='scientific name' AND taxon.taxon_id = %staxonomy)rg   execute_oneinsert)r   r
   rr   aZcommon_namesZscientific_namesZncbi_taxidsr   r{   ZrankZparent_taxon_idr   r   r   rn     s6     	

rn   c             C   s@   |  j  d | f  } d d   | D } | r8 d | i Si  Sd  S)NzESELECT comment_text FROM comment WHERE bioentry_id=%s ORDER BY "rank"c             S   s   g  |  ] } | d   q S)r   r   )rQ   Zcommr   r   r   rj   8  s   	 z%_retrieve_comment.<locals>.<listcomp>comment)r9   )r   r
   r_   commentsr   r   r   ro   3  s    
ro   c               @   s  e  Z d  Z d Z d d   Z d d   Z d d   Z d d	   Z e e e e d
  Z	 d d   Z
 d d   Z d d   Z e e
 e e d  Z d d   Z d d   Z d d   Z e e e e d  Z d d   Z d d   Z d d   Z e e e e d  Z d  S)!DBSeqRecordz4BioSQL equivalent of the Biopython SeqRecord object.c          	   C   s   | |  _  | |  _ |  j  j d |  j f  \ |  _ |  _ |  _ } } |  _ |  _ |  _ | r | d k r d | | f |  _	 n	 | |  _	 t
 | |  } t d |  |  _ d S)a8  Create a DBSeqRecord object.

        Arguments:
         - adaptor - A BioSQL.BioSeqDatabase.Adaptor object
         - primary_id - An internal integer ID used by BioSQL

        You wouldn't normally create a DBSeqRecord object yourself,
        this is done for you when using a BioSeqDatabase object
        zSELECT biodatabase_id, taxon_id, name, accession, version, identifier, division, description FROM bioentry WHERE bioentry_id = %srC   z%s.%sr   N)_adaptor_primary_idr   Z_biodatabase_id	_taxon_idr{   _identifier	_divisiondescriptionidr>   r   Z_per_letter_annotations)r   r   r
   rH   rI   r   r   r   r   r   C  s    
			9	zDBSeqRecord.__init__c             C   s.   t  |  d  s' t |  j |  j  |  _ |  j S)N_seq)hasattrrB   r   r   r   )r   r   r   r   Z	__get_seqk  s    zDBSeqRecord.__get_seqc             C   s   | |  _  d  S)N)r   )r   rA   r   r   r   Z	__set_seqp  s    zDBSeqRecord.__set_seqc             C   s
   |  `  d  S)N)r   )r   r   r   r   Z	__del_seqt  s    zDBSeqRecord.__del_seqz
Seq objectc             C   s.   t  |  d  s' t |  j |  j  |  _ |  j S)NrE   )r   rK   r   r   rE   )r   r   r   r   Z__get_dbxrefsy  s    zDBSeqRecord.__get_dbxrefsc             C   s   | |  _  d  S)N)rE   )r   rF   r   r   r   Z__set_dbxrefs~  s    zDBSeqRecord.__set_dbxrefsc             C   s
   |  `  d  S)N)rE   )r   r   r   r   Z__del_dbxrefs  s    zDBSeqRecord.__del_dbxrefszDatabase cross referencesc             C   s.   t  |  d  s' t |  j |  j  |  _ |  j S)N	_features)r   rf   r   r   r   )r   r   r   r   Z__get_features  s    zDBSeqRecord.__get_featuresc             C   s   | |  _  d  S)N)r   )r   featuresr   r   r   Z__set_features  s    zDBSeqRecord.__set_featuresc             C   s
   |  `  d  S)N)r   )r   r   r   r   Z__del_features  s    zDBSeqRecord.__del_featuresZFeaturesc             C   sf   t  |  d  s_ t |  j |  j |  j  |  _ |  j rF |  j |  j d <|  j r_ |  j |  j d <|  j S)N_annotationsZgiZdata_file_division)r   rv   r   r   r   r   r   r   )r   r   r   r   Z__get_annotations  s    		zDBSeqRecord.__get_annotationsc             C   s   | |  _  d  S)N)r   )r   rs   r   r   r   Z__set_annotations  s    zDBSeqRecord.__set_annotationsc             C   s
   |  `  d  S)N)r   )r   r   r   r   Z__del_annotations  s    zDBSeqRecord.__del_annotationsZAnnotationsN)r3   r4   r5   r6   r   Z_DBSeqRecord__get_seqZ_DBSeqRecord__set_seqZ_DBSeqRecord__del_seqr7   rA   Z_DBSeqRecord__get_dbxrefsZ_DBSeqRecord__set_dbxrefsZ_DBSeqRecord__del_dbxrefsrF   Z_DBSeqRecord__get_featuresZ_DBSeqRecord__set_featuresZ_DBSeqRecord__del_featuresr   Z_DBSeqRecord__get_annotationsZ_DBSeqRecord__set_annotationsZ_DBSeqRecord__del_annotationsrs   r   r   r   r   r   @  s(   (r   N)r6   Z	Bio._py3kr   rX   r   ZBio.Seqr   r   ZBio.SeqRecordr   r   r   r	   r>   rB   rK   rf   rZ   rv   rh   rl   rm   rn   ro   r   r   r   r   r   <module>   s$   9'7