
:>"^Ù;  ã               @   sÆ   d  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	 m
 Z
 d d d	 d
 d d d d d d d d d d d d d d d d d d g i Z e	 ƒ  Z Gd d „  d e
 ƒ Z d S)zcWrite an mmCIF file.

See https://www.iucr.org/resources/cif/spec/version1.1/cifsyntax for syntax.
é    N)Údefaultdict)Ú
basestring)ÚStructureBuilder)ÚSelectÚStructureIOZ
_atom_siteZ	group_PDBÚidZtype_symbolZlabel_atom_idZlabel_alt_idZlabel_comp_idÚlabel_asym_idZlabel_entity_idÚlabel_seq_idZpdbx_PDB_ins_codeZCartn_xZCartn_yZCartn_zZ	occupancyZB_iso_or_equivZpdbx_formal_chargeZauth_seq_idZauth_comp_idZauth_asym_idZauth_atom_idZpdbx_PDB_model_numc               @   sˆ   e  Z d  Z d Z d d „  Z d d „  Z e d d d „ Z d	 d
 „  Z d d „  Z	 d d „  Z
 d d „  Z d d „  Z d d „  Z d S)ÚMMCIFIOaç  Write a Structure object or a mmCIF dictionary as a mmCIF file.

    Examples
    --------
        >>> from Bio.PDB import MMCIFParser
        >>> from Bio.PDB.mmcifio import MMCIFIO
        >>> parser = MMCIFParser()
        >>> structure = parser.get_structure("1a8o", "PDB/1A8O.cif")
        >>> io=MMCIFIO()
        >>> io.set_structure(structure)
        >>> io.save("bio-pdb-mmcifio-out.cif")
        >>> import os
        >>> os.remove("bio-pdb-mmcifio-out.cif")  # tidy up


    c             C   s   d S)zInitialise.N© )Úselfr   r   ú4/tmp/pip-build-ww9dw3qa/biopython/Bio/PDB/mmcifio.pyÚ__init__E   s    zMMCIFIO.__init__c             C   s   | |  _  d S)z+Set the mmCIF dictionary to be written out.N)Údic)r   r   r   r   r   Úset_dictI   s    zMMCIFIO.set_dictFc             C   s—   t  | t ƒ r' t | d ƒ } d } n | } d } t |  d ƒ rX |  j | | | ƒ n+ t |  d ƒ rw |  j | ƒ n t d ƒ ‚ | r“ | j ƒ  d S)a  Save the structure to a file.

        :param filepath: output file
        :type filepath: string or filehandle

        :param select: selects which entities will be written.
        :type select: object

        Typically select is a subclass of L{Select}, it should
        have the following methods:

         - accept_model(model)
         - accept_chain(chain)
         - accept_residue(residue)
         - accept_atom(atom)

        These methods should return 1 if the entity is to be
        written out, 0 otherwise.
        ÚwTFÚ	structurer   zKUse set_structure or set_dict to set a structure or dictionary to write outN)Ú
isinstancer   ÚopenÚhasattrÚ_save_structureÚ
_save_dictÚ
ValueErrorÚclose)r   ÚfilepathÚselectÚpreserve_atom_numberingÚfpZ
close_filer   r   r   ÚsaveM   s    		zMMCIFIO.savec             C   s­  i  } x¥ |  j  D]š } | d k r2 |  j  | } q t j d | ƒ } t | ƒ d k rš | d | k r‚ | | d j | d ƒ qª | d g | | d <q t d | ƒ ‚ q Wx­ | j ƒ  D]Ÿ \ } } | t k r» g  } xX | D]P } y | j t | j | ƒ ƒ Wqà t k
 r/| j t t | ƒ ƒ Yqà Xqà Wd d „  t	 t
 | | ƒ ƒ Dƒ | | <q» W| ry| j d | d	 ƒ x-| j ƒ  D]\ } } |  j  | d
 | d }	 t |	 ƒ }
 x‰ | D] } |  j  | d
 | } t |	 t ƒ r	t | t ƒ s't | ƒ |
 k s't |	 t ƒ r¾t | t ƒ r¾t d | d
 | ƒ ‚ q¾Wt |	 t ƒ sst |	 t ƒ rKt |	 ƒ d k rKd } x, | D]$ } t | ƒ | k r€t | ƒ } q€Wxí| D]• } t |	 t ƒ rÜ|  j  | d
 | } n |  j  | d
 | d } | j d j d | d
 | d t | ƒ | d ƒ |  j | t | ƒ ƒ d ƒ q¯WnMt |	 t ƒ r|| j d ƒ i  } x  | D]˜ } | j | d
 | d ƒ d | | <xl |  j  | d
 | D]U } t | ƒ } |  j | ƒ rî|  j | ƒ rî| d 7} | | | k r³| | | <q³WqtWx… t |
 ƒ D]X } xB | D]: } | j |  j |  j  | d
 | | | | d ƒ ƒ q*W| j d ƒ qWn t d t t |	 ƒ ƒ ƒ ‚ | j d ƒ q†Wd  S)NÚdata_z\.é   r   é   z!Invalid key in mmCIF dictionary: c             S   s   g  |  ] \ } } | ‘ q Sr   r   )Ú.0Ú_Úkr   r   r   ú
<listcomp>‘   s   	 z&MMCIFIO._save_dict.<locals>.<listcomp>z
#
Ú.z-Inconsistent list sizes in mmCIF dictionary: z{k: <{width}}r$   Úwidthé   Ú
zloop_
z"Invalid type in mmCIF dictionary: z#
)r   ÚreÚsplitÚlenÚappendr   ÚitemsÚmmcif_orderÚindexÚsortedÚzipÚwriter   ÚlistÚstrÚformatÚ_format_mmcif_colÚ_requires_quoteÚ_requires_newlineÚrangeÚtype)r   Úout_fileZ	key_listsÚkeyZdata_valÚsZkey_listZindsÚiZ
sample_valZn_valsÚvalÚmZvalue_no_listZ
col_widthsZlen_valÚcolr   r   r   r   u   s‚     *!!P


,zMMCIFIO._save_dictc             C   s   |  j  | ƒ r d | d S|  j | ƒ ru d | k rT d j d d | d d | ƒ Sd j d d | d d | ƒ Sn d j d | d | ƒ Sd  S)	Nz
;z
;
z' z{v: <{width}}Úvú"r'   ú')r9   r8   r6   )r   r@   Z	col_widthr   r   r   r7   Û   s    !zMMCIFIO._format_mmcif_colc             C   s0   d | k s$ d | k r( d | k r( d Sd Sd  S)Nr)   z' z" TFr   )r   r@   r   r   r   r9   ð   s    $zMMCIFIO._requires_newlinec             C   sj   d | k s^ d | k s^ d | k s^ | d d k s^ | j  d ƒ s^ | j  d ƒ s^ | d k rb d Sd Sd  S)Nú rE   rD   r   r#   ú#ú$ú[ú]ú;r   Zsave_Úloop_Ústop_Úglobal_TF)r#   rG   rH   rI   rJ   rK   )rL   rM   rN   )Ú
startswith)r   r@   r   r   r   r8   ÷   s    zMMCIFIO._requires_quotec             C   sY   | } d } xF | d k rT | d d } | t  d | ƒ 7} t | | d ƒ } q W| S)NÚ r   r!   é   éA   )ÚchrÚint)r   Ú	entity_idÚdivÚoutÚmodr   r   r   Ú_get_label_asym_id  s    zMMCIFIO._get_label_asym_idc          	   C   s-  t  t ƒ } x°|  j j ƒ  D]Ÿ} | j | ƒ s4 q | j d k rL d } n t | j ƒ } d } | sm d } xK| j ƒ  D]=}	 | j |	 ƒ s’ qz |	 j ƒ  }
 |
 d k r° d }
 d } d } d } xò|	 j	 ƒ  D]ä} | j
 | ƒ sç qÏ | j ƒ  \ } } } | d k r'd } t | ƒ } | d 7} n d } d } t | ƒ } | d k rQd	 } | j ƒ  } | | k s| d k r‹| | k r‹| d 7} | } | } |  j | ƒ } x
| j	 ƒ  D]ü} | j | ƒ r³| d
 j | ƒ | rë| j ƒ  } | d j t | ƒ ƒ | s| d 7} | j j ƒ  } | d k r3d	 } | d j | ƒ | d j | j ƒ  j ƒ  ƒ | j ƒ  } | d k rd } | d j | ƒ | d j | j ƒ  ƒ | d j | ƒ | d j d	 ƒ | d j | ƒ | d j | ƒ | j ƒ  } | d j d | d ƒ | d j d | d ƒ | d j d | d ƒ | d j t | j ƒ  ƒ ƒ | d j t | j ƒ  ƒ ƒ | d j | ƒ | d j |
 ƒ | d j | ƒ q³WqÏ Wqz Wq W|  j j } x; d d d  d! d" d# d d$ d% g	 D] } | j | d ƒ } qíW| | d& <| |  _ |  j | ƒ d  S)'Nr   Ú1r!   rF   r&   rP   ZATOMZHETATMú?z_atom_site.group_PDBz_atom_site.idz_atom_site.type_symbolz_atom_site.label_atom_idz_atom_site.label_alt_idz_atom_site.label_comp_idz_atom_site.label_asym_idz_atom_site.label_entity_idz_atom_site.label_seq_idz_atom_site.pdbx_PDB_ins_codez_atom_site.Cartn_xz%.3fz_atom_site.Cartn_yz_atom_site.Cartn_zr    z_atom_site.occupancyz_atom_site.B_iso_or_equivz_atom_site.auth_seq_idz_atom_site.auth_asym_idz_atom_site.pdbx_PDB_model_numrG   rH   rE   rD   rI   rJ   ú	r)   r   )r   r4   r   Zget_listZaccept_modelZ
serial_numr5   Zaccept_chainZget_idZget_unpacked_listZaccept_residueZget_resnamerY   Zaccept_atomr-   Zget_serial_numberÚelementÚstripÚget_nameZ
get_altlocZ	get_coordZget_occupancyZget_bfactorr   Úreplacer   r   )r   r<   r   r   Z	atom_dictÚmodelZmodel_nrU   Zatom_numberÚchainZchain_idZresidue_numberZprev_residue_typeZprev_resnameZresidueZhetfieldZresseqZicodeZresidue_typer	   Úresnamer   Zatomr]   ZaltlocZcoordZstructure_idÚcr   r   r   r     s     	





!(
	zMMCIFIO._save_structureN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   Ú_selectr   r   r7   r9   r8   rY   r   r   r   r   r   r
   3   s   (fr
   )rh   r*   Úcollectionsr   Z	Bio._py3kr   ZBio.PDB.StructureBuilderr   ZBio.PDB.PDBIOr   r   r/   ri   r
   r   r   r   r   Ú<module>   s:   	