o
    RŀgD                     @   s   d Z ddlZddlZddlmZ zddlmZ ddlmZ W n e	y0   ddl
mZ eddw zddlmZ W n e	yK   ddl
mZ ed	dw dd
lmZ ddlmZ dddZdd Zdd ZG dd dZdS )zClasses and functions to visualise a KGML Pathway Map.

The KGML definition is as of release KGML v0.7.1
(http://www.kegg.jp/kegg/xml/docs/)

Classes:
    N)BytesIO)colors)canvas)MissingPythonDependencyErrorz.Install reportlab if you want to use KGML_vis.)Imagez+Install pillow if you want to use KGML_vis.)urlopen)Pathwayffffff?c                 C   s,   t | }dD ]}t|||t||  q|S )zReturn darkened color as a ReportLab RGB color.

    Take a passed color and returns a Reportlab color that is darker by the
    factor indicated in the parameter.
    )redgreenblue)color_to_reportlabsetattrgetattr)colorfactornewcola r   I/var/www/html/myenv/lib/python3.10/site-packages/Bio/Graphics/KGML_vis.pydarken+   s   r   c                 C   s   t | tjr| S t | tr8| dr| dd t| dkr#t| S ztj| ddW S  ty7   t	ddw t | t
rBtj|  S | S )an  Return the passed color in Reportlab Color format.

    We allow colors to be specified as hex values, tuples, or Reportlab Color
    objects, and with or without an alpha channel. This function acts as a
    Rosetta stone for conversion of those formats to a Reportlab Color
    object, with alpha value.

    Any other color specification is returned directly
    0x#   T)hasAlphaz3Your reportlab seems to be too old, try 2.7 onwardsN)
isinstancer   Colorstr
startswithreplacelenHexColor	TypeErrorRuntimeErrortuple)r   r   r   r   r   7   s&   




r   c                 C   sF   t |  }tt|}tjddd}|j}|  |	|d |S )zReturn filename of temporary file containing downloaded image.

    Create a new temporary file to hold the image file at the passed URL
    and return the filename.
    Fz.png)deletesuffixPNG)
r   readr   openr   tempfileNamedTemporaryFilenameclosesave)urlimgimffnamer   r   r   get_temp_imagefilenameU   s   r4   c                   @   s   e Zd ZdZ														d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dS )
KGMLCanvasz<Reportlab Canvas-based representation of a KGML pathway map.FT	Helvetica   {Gz?r9   c                 C   sd   || _ || _|| _|| _|| _|| _|| _|| _|| _|| _	|| _
|	| _|
| _d| _|| _|| _dS )zInitialize the class.333333?N)pathway	show_mapsshow_orthologsshow_compounds
show_genesshow_reaction_entrieslabel_compoundslabel_orthologslabel_reaction_entries
label_mapsfontnamefontsizedraw_relationsnon_reactant_transparencyimport_imagemapmargins)selfr;   rI   rA   rB   rC   rD   r<   rE   rF   rG   r=   r>   r?   r@   rJ   r   r   r   __init__h   s    
zKGMLCanvas.__init__c              	   C   s  | j r!tj| jjr| jj}nt| jj}t|}|j	\}}n| jj
d d | jj
d d }}tj|d|dd| jd    |dd| jd    fd| _| j| j| j | j| jd | jj
d d  | jd | jj
d d   | j r| j  | jdd | jd|  | j|dd | j  | jr|   | jr|   | jr|   | jr|   | jr|    | j!  dS )z$Add the map elements to the drawing.   r      )bottomuppagesizeN)"rI   ospathisfiler;   imager4   r   r)   sizeboundsr   CanvasrJ   drawingsetFontrE   rF   	translate	saveStatescale	drawImagerestoreStater<   _KGMLCanvas__add_mapsr@   !_KGMLCanvas__add_reaction_entriesr=   _KGMLCanvas__add_orthologsr>   _KGMLCanvas__add_compoundsr?   _KGMLCanvas__add_genesr.   )rK   filename
imfilenamer1   cwidthcheightr   r   r   draw   sH   

"

zKGMLCanvas.drawc                 C   s\   | j jD ]'}|jD ]!}| jd | jd | | | jr*| jd | | q	qdS )a+  Add maps to the drawing of the map (PRIVATE).

        We do this first, as they're regional labels to be overlaid by
        information.  Also, we want to set the color to something subtle.

        We're using Hex colors because that's what KGML uses, and
        Reportlab doesn't mind.
        z#888888z#DDDDDDN)	r;   mapsgraphicsrY   setStrokeColorsetFillColor_KGMLCanvas__add_graphicsrD   _KGMLCanvas__add_labels)rK   mgr   r   r   
__add_maps   s   	


zKGMLCanvas.__add_mapsc              	   C   sN  |j dkrD| j }|jd \}}|jdur| j|j n| jd ||| |jD ]
\}}||| q-| j| | jd |j dkr[| jj	|j
|j|jd ddd dS |j dkr| jj|j
|jd  |j|jd  |j|jt|j|jd	 ddd dS |j d
kr| jj|j
|jd  |j|jd  |j|jddd dS dS )zAdd the passed graphics object to the map (PRIVATE).

        Add text, add after the graphics object, for sane Z-ordering.
        liner   NrM   circle      ?)strokefillroundrectangleg?	rectangle)typerY   	beginPathcoordswidthsetLineWidthmoveTolineTodrawPathrt   xy	roundRectheightminrect)rK   rk   pr   r   r   r   r   __add_graphics   sF   







	
zKGMLCanvas.__add_graphicsc                 C   s8  |j dkrGt|jd }t||kr t|d t|d }}nt|d t|}}|j| \}}|j| \}}d||  d||  }	}
n|j dkrT|j|j}	}
n|j dv r`|j|j}	}
|jj dkru|j}| j	| j
| jd  nt|jdk r|j}n	|jd	d
 d }| j|	|
| | j	| j
| j d	S )zAdd labels for the passed graphics objects to the map (PRIVATE).

        We don't check that the labels fit inside objects such as circles/
        rectangles/roundrectangles.
        rs   ru   rM   rt   )ry   rx   maprN      N   z...)rz   r    r|   intr   r   _parentr,   rY   rZ   rE   rF   drawCentredString)rK   rk   mid_idxidx1idx2x1y1x2y2r   r   textr   r   r   __add_labels  s(   


zKGMLCanvas.__add_labelsc                 C   n   | j jD ]0}|jD ]*}| jt|j | jt|j | 	| | j
r3| jt|j | | q	qdS )zAdd 'ortholog' Entry elements to the drawing of the map (PRIVATE).

        In KGML, these are typically line objects, so we render them
        before the compound circles to cover the unsightly ends/junctions.
        N)r;   	orthologsrk   rY   rl   r   fgcolorrm   bgcolorrn   rB   r   ro   )rK   orthologrq   r   r   r   __add_orthologs+     


zKGMLCanvas.__add_orthologsc                 C   r   )zAdd Entry elements for Reactions to the map drawing (PRIVATE).

        In KGML, these are typically line objects, so we render them
        before the compound circles to cover the unsightly ends/junctions
        N)r;   reaction_entriesrk   rY   rl   r   r   rm   r   rn   rC   r   ro   )rK   reactionrq   r   r   r   __add_reaction_entries<  r   z!KGMLCanvas.__add_reaction_entriesc              
   C   s   | j jD ]H}|jD ]B}t|j}|js| j| j9  _| j	t|j
 | j| | | | jrK|js8d}nd}| jtddd| | | q	qdS )z:Add compound elements to the drawing of the map (PRIVATE).r:   rM   g?N)r;   	compoundsrk   r   r   is_reactantalpharH   rY   rl   r   rm   rn   rA   r   r   ro   )rK   compoundrq   	fillcolortr   r   r   __add_compoundsM  s"   



zKGMLCanvas.__add_compoundsc                 C   r   )z6Add gene elements to the drawing of the map (PRIVATE).N)r;   genesrk   rY   rl   r   r   rm   r   rn   rA   r   ro   )rK   generq   r   r   r   __add_genesa  s   


zKGMLCanvas.__add_genesc                 C   sr   t | jjD ]0}|jdkr| jdd n| j  |jD ]}| jj|d  }| |j	| | ||j
 qqdS )a  Add relations to the map (PRIVATE).

        This is tricky. There is no defined graphic in KGML for a
        relation, and the corresponding entries are typically defined
        as objects 'to be connected somehow'.  KEGG uses KegSketch, which
        is not public, and most third-party software draws straight line
        arrows, with heads to indicate the appropriate direction
        (at both ends for reversible reactions), using solid lines for
        ECrel relation types, and dashed lines for maplink relation types.

        The relation has:
        - entry1: 'from' node
        - entry2: 'to' node
        - subtype: what the relation refers to

        Typically we have entry1 = map/ortholog; entry2 = map/ortholog,
        subtype = compound.
        maplinkr7      rM   N)listr;   	relationsrz   rY   setDashsubtypesentries_KGMLCanvas__draw_arrowentry1entry2)rK   relationssubtyper   r   r   __add_relationsl  s   


zKGMLCanvas.__add_relationsc                 C   s  |j |j }}d|d d |d d   d|d d |d d   f}d|d d |d d   d|d d |d d   f}| j }|d d |d   k rX|d d k rn n:|d |d kr{||d |d d  ||d |d d  nh||d |d d  ||d |d d  nO|d d |d   k r|d d k rn n9|d |d kr||d |d d  ||d |d d  n||d |d d  ||d |d d  | j| dS )zDraw an arrow between given Entry objects (PRIVATE).

        Draws an arrow from the g_from Entry object to the g_to
        Entry object; both must have Graphics objects.
        ru   r   rM   N)rW   rY   r{   r   r   r   )rK   g_fromg_tobounds_from	bounds_tocentre_from	centre_tor   r   r   r   __draw_arrow  s*   
,,zKGMLCanvas.__draw_arrowN)FTTTTFr6   r7   TTTTTr8   )__name__
__module____qualname____doc__rL   ri   r`   rn   ro   rb   ra   rc   rd   _KGMLCanvas__add_relationsr   r   r   r   r   r5   e   s6    
&:.#"r5   )r	   )r   rR   r*   ior   reportlab.libr   reportlab.pdfgenr   ImportErrorBior   PILr   urllib.requestr   Bio.KEGG.KGML.KGML_pathwayr   r   r   r4   r5   r   r   r   r   <module>   s>   
