B
    ž3RcÉ@  ã               @   s$  d dl mZmZm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 d6d
d„Zd7dd„Zd8dd„Zdd„ Zdd„ Zdd„ Zeddddddddd d!d"d#gƒZd$d%„ Zd9d'd(„Zd)d*„ Zd+d,„ Zd:d-d.„Zd;d/d0„Zd<d1d2„Zd3d4„ Zed5kr d dl Z eƒ \Z!Z"e  #e!¡ dS )=é    )ÚdefaultdictÚCounterÚ
namedtupleN)Úlinalg)ÚChem)ÚAllChem)ÚrdMolDraw2Dé   ©éú   é–   é   c          	   C   s(  t  dt j¡}d}d}d}t| ƒ| }	t| ƒ| r:|	d7 }	dg|	|  }
|d }||d |d d   |	|d |  f}d}x0t| |ƒD ] \}}| |¡ ¡ \}}}|dkrð| d |d ¡d |d ¡¡}| d	 |d ¡d	 |d ¡¡}|dkrü|}d
}| 	d¡}g }| 
d |¡¡ | 
| |d d |d |d  |d ¡¡ t|ƒdkr„| 
| |d d |d |d  |d ¡¡ | 
d¡ d |¡}|| |
|< |d7 }qŠW x`t|
ƒD ]T\}}|| }|| }|| }d||d |d d   ||d |  |f |
|< qºW |d |
¡ | }|S )Nz&^(<.*>\n)(<rect .*</rect>\n)(.*)</svg>Ú z</svg>é   é   r   g      $@zwidth='{}px'zheight='{}px'z"<tspan x="{0}" y="{1}">{2}</tspan>ú|zR<text font-family="sans-serif" font-size="{}px" text-anchor="middle" fill="black">g       @é   g      @z</text>Ú
z'<g transform="translate(%d,%d)" >%s</g>)ÚreÚcompileÚDOTALLÚlenÚzipÚmatchÚgroupsÚreplaceÚformatÚsplitÚappendÚjoinÚ	enumerate)ÚsvgsÚlabelsÚ
svgsPerRowÚmolSizeÚfontSizeZmatcherZhdrZftrZrectZnRowsZblocksZlabelSizeDistZfullSizeÚcountÚsvgÚnameÚhÚrÚbZtspanFmtÚnamesZlegendÚiÚelemÚrowÚcolZres© r1   ú4share/RDKit/Contrib/ChiralPairs/ChiralDescriptors.pyÚ_svgsToGrid.   sH     (  
,,

8r3   Fc          	      s~  ||  }dd„ t |ƒD ƒ}ttƒ}ttƒ}ttƒ}x2|D ]*}	||	  |	¡ ||	  d7  < d||	< q8W d}
tt |¡ƒ}xät|
|d ƒD ]Ò‰ |rštdˆ ƒ ‡ fdd„t |ƒD ƒ}x¨|D ] }|rÌtd|d	ˆ ƒ | 	|¡}x~| 
¡ D ]r}	|	 ¡ }xd| ¡ D ]X\}}||krö||krö||krö||  |¡ ||  d7  < ˆ ||< |rötd|d
|ƒ qöW qàW q¶W qˆW |rtt|ƒ t|ƒ |||fS )Nc             S   s   g | ]\}}|d kr|‘qS )r   r1   )Ú.0Únr-   r1   r1   r2   ú
<listcomp>\   s    z-determineAtomSubstituents.<locals>.<listcomp>r   r   r   zShell: c                s   g | ]\}}|ˆ kr|‘qS r1   r1   )r4   r5   r-   )Údr1   r2   r6   n   s    zAtom z
 in shell z assigned to )r    r   ÚlistÚintr   ÚnpÚmaxÚrangeÚprintÚGetAtomWithIdxZGetNeighborsÚGetIdxÚitems)ZatomIDÚmolZdistanceMatrixÚverboseZ	atomPathsZ	neighborsÚsubsÚsharedNeighborsÚmaxShellr5   ZmindistZmaxdistZnewShellZaidxÚatomZnidxÚkÚvr1   )r7   r2   ÚdetermineAtomSubstituentsY   s@    



rI   Tc                s&   |rt ‡ fdd„| D ƒƒS t| ƒS d S )Nc             3   s   | ]}d ˆ |  V  qdS )g      ð?Nr1   )r4   Úa)rD   r1   r2   ú	<genexpr>‡   s    z)_getSizeOfSubstituents.<locals>.<genexpr>)Úsumr   )ÚsubrD   ZweighdownSharedr1   )rD   r2   Ú_getSizeOfSubstituents…   s    rN   c             C   sH   g }x>|   ¡ D ]2}| ¡ }| ¡ }||kr||kr| | ¡ ¡ qW |S )N)ZGetBondsZGetBeginAtomIdxZGetEndAtomIdxr   r?   )rA   ZatomsÚbondsr+   Úa1Úa2r1   r1   r2   ÚgetBondsSubstituent‹   s    rR   c                s   t ‡ fdd„tˆ |ƒD ƒƒS )Nc             3   s    | ]}ˆ   |¡ ¡ rd V  qdS )r   N)ZGetBondWithIdxÚGetIsAromatic)r4   r+   )rA   r1   r2   rK   •   s    z1getNumAromaticBondsSubstituent.<locals>.<genexpr>)rL   rR   )rA   ÚsubAtomsr1   )rA   r2   ÚgetNumAromaticBondsSubstituent”   s    rU   c             C   sF   t  d¡}|  |¡}d}x(|D ] \}}||kr||kr|d7 }qW |S )Nz[!$(*#*)&!D1]-&!@[!$(*#*)&!D1]r   r   )r   ZMolFromSmartsZGetSubstructMatches)rA   rT   ZrotatableBondZmatchesÚnumRotBondsrP   rQ   r1   r1   r2   ÚgetNumRotatableBondsSubstituent˜   s    

rW   ÚsubstituentDescriptorÚsizeÚrelSizeÚnumNOÚrelNumNOÚ
relNumNO_2Ú
pathLengthÚrelPathLengthÚrelPathLength_2rD   rV   ÚnumAroBondsc             C   s<  t ƒ }|  ¡ }xÔt| ¡ dd„ dD ]¼\}}t||ƒ}d}	d}
xB|D ]:}|  |¡ ¡ dkrj|	d||  7 }	|| dkrD|
d7 }
qDW t| t|ƒƒ}t	| t|ƒƒ}t
||| |	|	| |	| || || | || | |
||d||< q$W t|ƒd	k r8xDtd	t|ƒ ƒD ]0}t
dddddddddddd|d
t|ƒ < qW |S )Nc             S   s   t | d ƒS )Nr   )r   )Úxr1   r1   r2   Ú<lambda>©   ó    z&calcSizeSubstituents.<locals>.<lambda>)Úkeyr   )é   é   g      ð?r   )rY   rZ   r[   r\   r]   r^   r_   r`   rD   rV   ra   r	   ÚH)r   ÚGetNumAtomsÚsortedr@   rN   r>   ÚGetAtomicNumrW   ÚsetrU   rX   r   r<   Ústr)rA   rC   rD   rE   ZsizeDictÚnumAtomsZsidxrM   rY   ZnumNOsZ	numSharedr-   ZnumRotBsZaroBondsr1   r1   r2   ÚcalcSizeSubstituents¦   s.    


ro   ©i,  r   c                s`  t  | ¡}t  | ¡d d }t|| |dƒ\}‰}tjt|ƒdd}tj| |d}	d}
g }g }xìt	| 
¡ ‡fdd„dD ]Ð}t||
 ƒ‰ |
d	7 }
‡ fd
d„|D ƒ}t| t|ƒƒ}‡ fdd„|D ƒ}t |d |d	 ¡}|j|	| ¡ |||d | ¡  | ¡ }| | dd¡¡ | dt|
ƒ d tt|ƒƒ d tt|ˆƒƒ d ¡ qvW t||t|ƒ|ddS )Nr   Fg333333ã?)Ús)Úkekulizec                s
   t | ˆ ƒS )N)rN   )rb   )rD   r1   r2   rc   Î   rd   z+visualizeSubstituentsGrid.<locals>.<lambda>)re   r   c                s   i | ]
}ˆ |“qS r1   r1   )r4   rF   )Úcolorr1   r2   ú
<dictcomp>Ñ   s    z-visualizeSubstituentsGrid.<locals>.<dictcomp>c                s   i | ]
}ˆ |“qS r1   r1   )r4   Zbond)rs   r1   r2   rt   Ô   s    )ZhighlightAtomsZhighlightAtomColorsZhighlightBondsZhighlightBondColorszsvg:r   zSubstituent z
 (#atoms: z, size normed: ú)r   )r#   r$   r%   )r   ÚGetDistanceMatrixÚFindMolChiralCentersrI   ÚsnsZhusl_paletter   r   ZPrepareMolForDrawingrj   ÚvaluesÚtuplerR   rl   ZMolDraw2DSVGZDrawMoleculeÚkeysZFinishDrawingZGetDrawingTextr   r   rm   rN   r3   )rA   ZaIdxr$   rr   ÚdistsÚ	idxChiralrC   rE   ZcolorsZmcr&   r!   r"   rM   ZatColorsrO   ZbnColorsZdrawerr'   r1   )rs   rD   r2   ÚvisualizeSubstituentsGridÄ   s.    
8r~   c             C   s   t  | ¡d d }t| |ƒS )Nr   )r   rw   r~   )rA   r}   r1   r1   r2   ÚvisualizeChiralSubstituentsGridà   s    r   c             C   sŽ   t | ƒdkrtdƒ‚t dddg¡}t dddg¡}t dddg¡}t dddg¡}t | d | | d |  | d |  | d |  ¡}|S )Nr	   zQFunction "calcSP3CarbonSubstituentMoment" expects an array of size 4 as parameterr   éÿÿÿÿr   r   é   )r   Ú
ValueErrorr:   Zarrayr   Znorm)ZsubSizesZx1Zx2Zx3Zx4ZsubstituentMomentr1   r1   r2   ÚcalcSP3CarbonSubstituentMomentå   s    6rƒ   c                sè  i }t |ˆ||ƒ\}}}tˆ|||ƒ}|| }	ˆ ¡ |d< ˆ ¡ |d< t ˆ¡|d< tˆ |¡ ¡ ƒ|d< t	 
|¡|d d |d   |d< tt	 |¡ƒ|d< t	 
|	¡|d d  |d< tt	 |	¡ƒ|d	< t|	 t¡ƒ}
x&tdd
ƒD ]‰ |
ˆ  |dtˆ ƒ < qäW x<tddƒD ].‰ t‡ ‡fdd„t|	ƒD ƒƒ|dtˆ ƒ < qW x<tddƒD ].‰ t‡ ‡fdd„t|	ƒD ƒƒ|dtˆ ƒ < qJW xÎtt| ¡ dd„ ddƒD ]°\}}dt|ƒ }|j||d < |j||d < |j||d < |j||d < |j||d < |j||d < |j||d < |j||d < |j||d < |j||d < |j||d  < q˜W |d! |d"  |d#< |d$ |d%  |d&< |d' |d(  |d)< |d* |d+  |d,< t|d- |d. |d! |d" gƒ|d/< t|d0 |d1 |d$ |d% gƒ|d2< |S )3Nrn   ZnumBondsrV   ZringChiralCenterr   ZmeanDistZmaxDistZmeanDistFromCCZmaxDistfromCCé   ZnLevelr	   c                s.   g | ]&\}}|ˆ krˆ  |¡ ¡ d kr|‘qS ))rf   rg   )r>   rk   )r4   r5   Új)r-   rA   r1   r2   r6     s    z.calculateChiralDescriptors.<locals>.<listcomp>ZphLevelc                s*   g | ]"\}}|ˆ krˆ  |¡ ¡ r|‘qS r1   )r>   rS   )r4   r5   r…   )r-   rA   r1   r2   r6     s    ZarLevelc             S   s   | j S )N)rY   )rb   r1   r1   r2   rc     rd   z,calculateChiralDescriptors.<locals>.<lambda>)re   rq   Z_sizeZ_relSizeZ_phSizeZ
_phRelSizeZ_phRelSize_2Z_pathLengthZ_relPathLengthZ_relPathLength_2Z_numSharedNeighborsZ_numRotBondsZ_numAroBondsZs3_sizeZs4_sizeZs34_sizeZ	s3_phSizeZ	s4_phSizeZ
s34_phSizeZ
s3_relSizeZ
s4_relSizeZs34_relSizeZs3_phRelSizeZs4_phRelSizeZs34_phRelSizeZs1_sizeZs2_sizeZchiralMomentZ	s1_phSizeZ	s2_phSizeZchiralPhMoment) rI   ro   ri   ZGetNumBondsr   ZCalcNumRotatableBondsr9   r>   ZIsInRingr:   rL   r;   r   Zastyper<   rm   r   r    rj   ry   rY   rZ   r[   r\   r]   r^   r_   r`   rD   rV   ra   rƒ   )rA   r}   r|   rB   ÚdescrC   rD   rE   ZsizesÚpathsZnlevelsr5   rH   Zsnr1   )r-   rA   r2   ÚcalculateChiralDescriptorsó   sP    "..$$rˆ   c             C   s>   i }t  | ¡}x*t  | ¡D ]\}}t| ||dd||< qW |S )a  
    Generates descriptors for all chiral centers in the molecule.
    Details of these descriptors are described in: 
    Schneider et al., Chiral Cliffs: Investigating the Influence of Chirality on Binding Affinity
    https://doi.org/10.1002/cmdc.201700798. 
    >>> # test molecules are taken from the publication above (see Figure 3 and Figure 8)
    >>> testmols = {
    ...   "CHEMBL319180" : 'CCCN1C(=O)[C@@H](NC(=O)Nc2cccc(C)c2)N=C(N3CCN(C)CC3)c4ccccc14',
    ...   }
    >>> mol = Chem.MolFromSmiles(testmols['CHEMBL319180'])
    >>> desc = generateChiralDescriptorsForAllCenters(mol)
    >>> desc.keys()
    dict_keys([6])
    >>> desc[6]['arLevel2']
    0
    >>> desc[6]['s4_pathLength']
    7
    >>> desc[6]['maxDist']
    14
    >>> desc[6]['maxDistfromCC']
    7
    F)rB   )r   rv   rw   rˆ   )rA   rB   r†   r|   r}   Ú_r1   r1   r2   Ú&generateChiralDescriptorsForAllCenters)  s
    
rŠ   c             C   s,   t  | ¡}t  | ¡d d }t| ||ddS )a˜  
    Generates descriptors for the 'first' chiral centers in the molecule.
    Details of these descriptors are described in: 
    Schneider et al., Chiral Cliffs: Investigating the Influence of Chirality on Binding Affinity
    https://doi.org/10.1002/cmdc.201700798. 
    >>> # test molecules are taken from the publication above (see Figure 3 and Figure 8)
    >>> testmols = {
    ...   "CHEMBL319180" : 'CCCN1C(=O)[C@@H](NC(=O)Nc2cccc(C)c2)N=C(N3CCN(C)CC3)c4ccccc14',
    ...   "CHEMBL3350250" : 'CC(C)[C@@]1(CCc2ccc(O)cc2)CC(=O)C(=C(O)O1)Sc3cc(C)c(NS(=O)(=O)c4ccc(cn4)C(F)(F)F)cc3C(C)(C)C',
    ...   "CHEMBL3698720" : 'N[C@@H]1CCN(C1)c2cnc(Nc3ncc4c5ccncc5n(C6CCCC6)c4n3)cn2'
    ...   }
    >>> mol = Chem.MolFromSmiles(testmols['CHEMBL319180'])
    >>> desc = generateChiralDescriptors(mol)
    >>> desc['arLevel2']
    0
    >>> desc['s4_pathLength']
    7
    >>> desc['maxDist']
    14
    >>> desc['maxDistfromCC']
    7
    >>> mol = Chem.MolFromSmiles(testmols['CHEMBL3350250'])
    >>> desc = generateChiralDescriptors(mol)
    >>> desc['nLevel8']
    5
    >>> desc['s1_pathLength']
    2
    >>> desc['s2_size']
    9.0
    >>> desc['numRotBonds']
    9
    >>> mol = Chem.MolFromSmiles(testmols['CHEMBL3698720'])
    >>> desc = generateChiralDescriptors(mol)
    >>> desc['s3_numRotBonds']
    0
    >>> desc['s34_size']
    29.0
    >>> desc['phLevel2']
    1
    >>> desc['s2_numSharedNeighbors']
    0
    
    r   F)rB   )r   rv   rw   rˆ   )rA   rB   r|   r}   r1   r1   r2   ÚgenerateChiralDescriptorsG  s    -
r‹   c              C   s    dd l } dd l}|  |jd ¡S )Nr   Ú__main__)ÚdoctestÚsysZtestmodÚmodules)r   rŽ   r1   r1   r2   Ú_test}  s    r   rŒ   )r	   r
   r   )F)T)rp   T)F)F)F)$Úcollectionsr   r   r   Zseabornrx   Znumpyr:   r   r   Zrdkitr   Z
rdkit.Chemr   Zrdkit.Chem.Drawr   r3   rI   rN   rR   rU   rW   rX   ro   r~   r   rƒ   rˆ   rŠ   r‹   r   Ú__name__rŽ   ZfailedZtriedÚexitr1   r1   r1   r2   Ú<module>"   s8   
+
,
	


6

6

