o
    RŀgkH                     @   s   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
 ddl	mZ d	d
 Zdd Ze
jddfddZde
jdfddZe
jddfddZe
jdddddfddZdd Zdd Zdd ZG dd  d ZdS )!aH  AbstractDrawer module (considered to be a private module, the API may change!).

Provides:
 - AbstractDrawer - Superclass for methods common to the Drawer objects
 - page_sizes - Method that returns a ReportLab pagesize when passed
   a valid ISO size
 - draw_box - Method that returns a closed path object when passed
   the proper coordinates.  For HORIZONTAL boxes only.
 - angle2trig - Method that returns a tuple of values that are the
   vector for rotating a point through a passed angle,
   about an origin
 - intermediate_points - Method that returns a list of values intermediate
   between the points in a passed dataset

For drawing capabilities, this module uses reportlab to draw and write
the diagram: http://www.reportlab.com

For dealing with biological information, the package expects Biopython objects
like SeqFeatures.
    )islice)cos)pi)sin)Polygon)colors)	pagesizesc                 C   s   i dt jdt jdt jdt jdt jdt jdt jdt jd	t j	d
t j
dt jdt jdt jdt jdt jdt jdt j}z||  W S  tyZ   t|  ddw )zConvert size string into a Reportlab pagesize.

    Arguments:
     - size - A string representing a standard page size, eg 'A4' or 'LETTER'

    A0A1A2A3A4A5A6B0B1B2B3B4B5B6ELEVENSEVENTEENLEGALLETTERz not in list of page sizesN)r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   KeyError
ValueError)sizesizes r   ^/var/www/html/myenv/lib/python3.10/site-packages/Bio/Graphics/GenomeDiagram/_AbstractDrawer.py
page_sizes2   sP   	

r    c                 C   s   t | tjstd| | tjkr|du rtj}|| fS |du r'| }|| fS |r<t |tjs6td||}|| fS d}|| fS )z,Deal with  border and fill colors (PRIVATE).zInvalid color NzInvalid border color )
isinstancer   Colorr   whiteblack)colorborderstrokecolorr   r   r   _stroke_and_fill_colorsR   s   	r(   Nc              	   K   s   | \}}|\}}	|dur|}~t ||\}
}t||t||	t||t||	f\}}}}	t||||||	||	gf|
|dd|S )a}  Draw a box.

    Arguments:
     - point1, point2 - coordinates for opposite corners of the box
       (x,y tuples)
     - color /colour - The color for the box (colour takes priority
       over color)
     - border - Border color for the box

    Returns a closed path object, beginning at (x1,y1) going round
    the four points in order, and filling with the passed color.
    Nr   strokeColor	fillColorstrokewidth)r(   minmaxr   )point1point2r%   r&   colourkwargsx1y1x2y2r'   r   r   r   draw_boxg   s    ,r7         ?c                 K   s   | \}}|\}}	|st | |||S |dk rtdt||\}
}|	| }|| }t|d | |d }t|d | |d }||| ||	| || |	|| |	||	| ||| || ||| |g}tt|f|
dd|d|S )z$Draw a box with the corners cut off.r   *Arrow head length ratio should be positiver8      r*   strokeWidthstrokeLineJoinr+   )r7   r   r(   r-   r   deduplicate)r/   r0   cornerr%   r&   r2   r3   r4   r5   r6   r'   	boxheightboxwidthx_cornery_cornerpointsr   r   r   draw_cut_corner_box   sL   rE   c           	      K   s^   |dur|}~t ||\}}g }| D ]\}}|| || qtt|f||dd|S )a  Draw polygon.

    Arguments:
     - list_of_point - list of (x,y) tuples for the corner coordinates
     - color / colour - The color for the box

    Returns a closed path object, beginning at (x1,y1) going round
    the four points in order, and filling with the passed colour.

    Nr   r)   )r(   appendr   r>   )	list_of_pointsr%   r&   r1   r2   r'   xy_listxyr   r   r   draw_polygon   s"   
rK   g?rightc                 K   s  | \}	}
|\}}|dk sd|k rt d|dk rt d|dur#|}~t||\}}t|	|t|
|}}t|	|t|
|}}|dkrO||||f\}	}}
}n|dkr^||||f\}	}}
}nt d|d	||
 }||	 }|| }tt|| t|}|dk r|d
9 }d||  }|| }|| }d| }|	|
| |	| |
| |	| |||
| |	| |
|	| |
| |	|
| g}tt|f|dd|d|S )a`  Draw an arrow.

    Returns a closed path object representing an arrow enclosed by the
    box with corners at {point1=(x1,y1), point2=(x2,y2)}, a shaft height
    given by shaft_height_ratio (relative to box height), a head length
    given by head_length_ratio (also relative to box height), and
    an orientation that may be 'left' or 'right'.
    r   r:   z2Arrow shaft height ratio should be in range 0 to 1r9   NrL   leftzInvalid orientation z, should be 'left' or 'right'r8   r;   )r   r(   r-   r.   absr   r>   )r/   r0   r%   r&   shaft_height_ratiohead_length_ratioorientationr1   r2   r3   r4   r5   r6   r'   xminyminxmaxymaxr@   rA   shaftheight
headlengthshafttop	shaftbaseheadbase	midheightrD   r   r   r   
draw_arrow   sl   
r]   c                 C   s   t | d dks
J t | dk r| S | dd }tt| dddt| dddD ]\}}||d ks7||d krA|| || q'|S )a   Remove adjacent duplicate points.

    This is important for use with the Polygon class since reportlab has a
    bug with duplicate points.

    Arguments:
     - points - list of points [x1, y1, x2, y2,...]

    Returns a list in the same format with consecutive duplicates removed
       r   N   rN   )lenzipr   rF   )rD   	newpointsrI   rJ   r   r   r   r>   7  s   &

r>   c                 C   s.   t | t d }t| t d }||| |fS )a&  Convert angle to a reportlab ready tuple.

    Arguments:
     - theta -  Angle in degrees, counter clockwise from horizontal

    Returns a representation of the passed angle in a format suitable
    for ReportLab rotations (i.e. cos(theta), sin(theta), -sin(theta),
    cos(theta) tuple)
       )r   r   r   )thetacsr   r   r   
angle2trigM  s   
rh   c                 C   s   g }| | |d d |d d |d d  d  |d d f tdt|d D ],}||d  \}}|| \}}||d  \}	}
| ||| d  ||	| d  |f q)| ||	| d  ||d d f |S )zGenerate intermediate points describing provided graph data..

    Returns a list of (start, end, value) tuples describing the passed
    graph data as 'bins' between position midpoints.
    r   r:          @rN   )rF   rangera   )startend
graph_datanewdataindexlastxvallastyvalxvalyvalnextxvalnextyvalr   r   r   intermediate_points\  s    &
 $rv   c                   @   sb   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S )AbstractDrawera  Abstract Drawer.

    Attributes:
     - tracklines    Boolean for whether to draw lines delineating tracks
     - pagesize      Tuple describing the size of the page in pixels
     - x0            Float X co-ord for leftmost point of drawable area
     - xlim          Float X co-ord for rightmost point of drawable area
     - y0            Float Y co-ord for lowest point of drawable area
     - ylim          Float Y co-ord for topmost point of drawable area
     - pagewidth     Float pixel width of drawable area
     - pageheight    Float pixel height of drawable area
     - xcenter       Float X co-ord of center of drawable area
     - ycenter       Float Y co-ord of center of drawable area
     - start         Int, base to start drawing from
     - end           Int, base to stop drawing at
     - length        Size of sequence to be drawn
     - cross_track_links List of tuples each with four entries (track A,
       feature A, track B, feature B) to be linked.

    r   	landscape皙?Nr   c                 C   sR   || _ | || | ||||||	 | |
| || _|du r$g }dS || _dS )a  Create the object.

        Arguments:
         - parent    Diagram object containing the data that the drawer draws
         - pagesize  String describing the ISO size of the image, or a tuple
           of pixels
         - orientation   String describing the required orientation of the
           final drawing ('landscape' or 'portrait')
         - x         Float (0->1) describing the relative size of the X
           margins to the page
         - y         Float (0->1) describing the relative size of the Y
           margins to the page
         - xl        Float (0->1) describing the relative size of the left X
           margin to the page (overrides x)
         - xr        Float (0->1) describing the relative size of the right X
           margin to the page (overrides x)
         - yt        Float (0->1) describing the relative size of the top Y
           margin to the page (overrides y)
         - yb        Float (0->1) describing the relative size of the lower Y
           margin to the page (overrides y)
         - start     Int, the position to begin drawing the diagram at
         - end       Int, the position to stop drawing the diagram at
         - tracklines    Boolean flag to show (or not) lines delineating tracks
           on the diagram
         - cross_track_links List of tuples each with four entries (track A,
           feature A, track B, feature B) to be linked.

        N)_parentset_page_sizeset_margins
set_bounds
tracklinescross_track_links)selfparentpagesizerR   rI   rJ   xlxrytybrk   rl   r~   r   r   r   r   __init__  s   ,
zAbstractDrawer.__init__c                 C   s   t |tr
t|}nt |trntd| dt|t|}}| }|dvr1td| d|dkr<||f| _dS ||f| _dS )a  Set page size of the drawing..

        Arguments:
         - pagesize      Size of the output image, a tuple of pixels (width,
           height, or a string in the reportlab.lib.pagesizes
           set of ISO sizes.
         - orientation   String: 'landscape' or 'portrait'

        z
Page size z not recognised)rx   portraitzOrientation rx   N)	r!   strr    tupler   r-   r.   lowerr   )r   r   rR   	shortsidelongsider   r   r   r{     s   



zAbstractDrawer.set_page_sizec                 C   s   |p|}|p|}|p|}	|p|}
| j d | | j d |
 | _| _| j d d|  | j d d|	  | _| _| j| j | _| j| j | _| j| jd  | j| jd  | _| _dS )at  Set page margins.

        Arguments:
         - x         Float(0->1), Absolute X margin as % of page
         - y         Float(0->1), Absolute Y margin as % of page
         - xl        Float(0->1), Left X margin as % of page
         - xr        Float(0->1), Right X margin as % of page
         - yt        Float(0->1), Top Y margin as % of page
         - yb        Float(0->1), Bottom Y margin as % of page

        Set the page margins as proportions of the page 0->1, and also
        set the page limits x0, y0 and xlim, ylim, and page center
        xorigin, yorigin, as well as overall page width and height
        r   r:   ri   N)	r   x0y0xlimylim	pagewidth
pageheightxcenterycenter)r   rI   rJ   r   r   r   r   	xmargin_l	xmargin_rymargin_topymargin_btmr   r   r   r|     s   "
zAbstractDrawer.set_marginsc                 C   s   | j  \}}|dur|dur||kr||}}|du s |dk r"d}|du s*|dk r.|d }t|t|| _| _| j| j d | _dS )zSet start and end points for the drawing as a whole.

        Arguments:
         - start - The first base (or feature mark) to draw from
         - end - The last base (or feature mark) to draw to

        Nr   r:   )rz   rj   intrk   rl   length)r   rk   rl   lowhighr   r   r   r}     s   
zAbstractDrawer.set_boundsc                 C   s   || j kr|| jkrdS dS )zCheck if given value is within the region selected for drawing.

        Arguments:
         - value - A base position

        r:   r   )rk   rl   )r   valuer   r   r   is_in_bounds  s   zAbstractDrawer.is_in_boundsc                 C   s   | j S )z,Return the length of the region to be drawn.)r   )r   r   r   r   __len__'  s   zAbstractDrawer.__len__c                 C   sZ   | j | j }|jd u r| j}nt| j|j}|jd u r"| j}||fS t| j|j}||fS )N)rz   current_track_levelrk   r.   rl   r-   )r   trackrk   rl   r   r   r   _current_track_start_end+  s   

z'AbstractDrawer._current_track_start_end)r   rx   ry   ry   NNNNNNr   N)__name__
__module____qualname____doc__r   r{   r|   r}   r   r   r   r   r   r   r   rw   }  s*    
8"rw   )r   	itertoolsr   mathr   r   r   reportlab.graphics.shapesr   reportlab.libr   r   r    r(   
lightgreenr7   rE   rK   r]   r>   rh   rv   rw   r   r   r   r   <module>   s6    
$
0
%
\!