B
    ‰°b2<  ã               @   s€   d Z ddl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
G d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)Ú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f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
   ú.lib/python3.7/site-packages/Bio/PDB/mmcifio.pyÚ__init__D   s    zMMCIFIO.__init__c             C   s   || _ t| dƒrt| dƒ dS )z+Set the mmCIF dictionary to be written out.Ú	structureN)ÚdicÚhasattrÚdelattr)r   r   r
   r
   r   Úset_dictH   s    
zMMCIFIO.set_dictFc             C   sj   t |tƒrt|dƒ}d}n|}d}t| dƒr<|  |||¡ nt| dƒrR|  |¡ ntdƒ‚|rf| ¡  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.
        ÚwTFr   r   zKUse set_structure or set_dict to set a structure or dictionary to write outN)Ú
isinstanceÚstrÚopenr   Ú_save_structureÚ
_save_dictÚ
ValueErrorÚclose)r   ÚfilepathÚselectÚpreserve_atom_numberingÚfpZ
close_filer
   r
   r   ÚsaveO   s    



zMMCIFIO.savec          
   C   sÎ  i }x~| j D ]t}|dkr$| j | }qt d|¡}t|ƒdkrt|d |kr`||d   |d ¡ q€|d g||d < qtd| ƒ‚qW xŠ| ¡ D ]~\}}|tkrŽg }xL|D ]D}y| t|  |¡¡ W q¨ tk
rê   | tt| ƒ¡ Y q¨X q¨W dd„ t	t
||ƒƒD ƒ||< qŽW |r(| d| d	 ¡ xž| ¡ D ]\}}| j |d
 |d   }	t|	ƒ}
xr|D ]j}| j |d
 |  }t|	tƒržt|tƒs¶t|ƒ|
ks¶t|	tƒrbt|tƒrbtd| d
 | ƒ‚qbW t|	tƒsöt|	tƒr¦t|	ƒdkr¦d}x$|D ]}t|ƒ|kr t|ƒ}q W x€|D ]x}t|	tƒrJ| j |d
 |  }n| j |d
 |  d }| dj|d
 | t|ƒ| d d|  |t|ƒ¡ d ¡ q&W nt|	tƒr¦| d¡ i }xˆ|D ]€}| |d
 | d ¡ d||< xZ| j |d
 |  D ]D}t|ƒ}|  |¡r(|  |¡s(|d7 }||| krü|||< qüW qÆW xnt|
ƒD ]L}x:|D ]2}| |  | j |d
 |  | || d ¡¡ q^W | d¡ qTW ntdtt|	ƒƒ ƒ‚| d¡ q4W d S )NÚdata_z\.é   r   é   z!Invalid key in mmCIF dictionary: c             S   s   g | ]\}}|‘qS r
   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   Úlistr   Ú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   w   s‚    
 


B


*zMMCIFIO._save_dictc             C   sh   |   |¡rd| d S |  |¡rVd|kr>djd| d |dS djd| d |dS ndj||dS d S )Nz
;z
;
z' z{v: <{width}}ú")Úvr)   ú')r9   r8   r6   )r   r@   Z	col_widthr
   r
   r   r7   Ý   s    

zMMCIFIO._format_mmcif_colc             C   s$   d|ksd|krd|krdS dS d S )Nr*   z' z" TFr
   )r   r@   r
   r
   r   r9   ò   s    zMMCIFIO._requires_newlinec             C   sL   d|ks@d|ks@d|ks@|d dks@|  d¡s@|  d¡s@|dkrDd	S d
S d S )Nú rE   rC   r   )r$   ú#ú$ú[ú]ú;r    Zsave_)Zloop_Zstop_Zglobal_TF)Ú
startswith)r   r@   r
   r
   r   r8   ù   s    

zMMCIFIO._requires_quotec             C   sF   |}d}x8|dkr@|d d }|t d| ƒ7 }t|| d ƒ}q
W |S )NÚ r   r"   é   éA   )ÚchrÚint)r   Ú	entity_idZdivÚoutÚmodr
   r
   r   Ú_get_label_asym_id  s    
zMMCIFIO._get_label_asym_idc          	   C   s(  t tƒ}xÜ| j ¡ D ]Ì}| |¡s(q|jdkr8d}n
t|jƒ}d}|sNd}x’| ¡ D ]„}	| |	¡slqZ|	 ¡ }
|
dkr€d}
d}d}d}xP|	 	¡ D ]B}| 
|¡sªq˜| ¡ \}}}|dkrÖd}t|ƒ}|d7 }nd}d}t|ƒ}|dkròd	}| ¡ }||ks|dkr ||kr |d7 }|}|}|  |¡}x¦| 	¡ D ]˜}| |¡r>|d
  |¡ |rl| ¡ }|d  t|ƒ¡ |sŒ|d7 }|j ¡ }|dkr¤d	}|d  |¡ |d  | ¡  ¡ ¡ | ¡ }|dkrÞd}|d  |¡ |d  | ¡ ¡ |d  |¡ |d  d	¡ |d  |¡ |d  |¡ | ¡ }|d  d|d  ¡ |d  d|d  ¡ |d  d|d  ¡ |d  t| ¡ ƒ¡ |d  t| ¡ ƒ¡ |d  |¡ |d  |
¡ |d  |¡ q>W q˜W qZW qW | jj}xdD ]}| |d¡}qöW ||d< || _|  |¡ d S ) Nr   Ú1r"   rF   r'   rM   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_num)	rG   rH   rE   rC   rI   rJ   rF   ú	r*   r    )r   r5   r   Zget_listZaccept_modelZ
serial_numr   Zaccept_chainZget_idZget_unpacked_listZaccept_residueZget_resnamerU   Zaccept_atomr.   Zget_serial_numberÚelementÚstripZget_nameZ
get_altlocZ	get_coordZget_occupancyZget_bfactorr   Úreplacer   r   )r   r<   r   r   Z	atom_dictZmodelZmodel_nrR   Zatom_numberÚchainZchain_idZresidue_numberZprev_residue_typeZprev_resnameZresidueZhetfieldZresseqZicodeZresidue_typer   Zresnamer   ZatomrY   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   rU   r   r
   r
   r
   r   r	   2   s   (fr	   )ra   r+   Úcollectionsr   ZBio.PDB.StructureBuilderr   ZBio.PDB.PDBIOr   r   r0   rb   r	   r
   r
   r
   r   Ú<module>   s8   