o
    Rŀg^<                     @   sb   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 dg d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)Select)StructureIO)StructureBuilder
_atom_site)	group_PDBidtype_symbollabel_atom_idlabel_alt_idlabel_comp_idlabel_asym_idlabel_entity_idlabel_seq_idpdbx_PDB_ins_codeCartn_xCartn_yCartn_z	occupancyB_iso_or_equivpdbx_formal_chargeauth_seq_idauth_comp_idauth_asym_idauth_atom_id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   C/var/www/html/myenv/lib/python3.10/site-packages/Bio/PDB/mmcifio.py__init__E   s    zMMCIFIO.__init__c                 C   s"   || _ t| drt| d dS 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   sn   t |trt|d}d}n|}d}t| dr| ||| nt| dr)| | ntd|r5|  dS 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fp
close_filer   r   r   saveO   s   



zMMCIFIO.savec              
   C   s  i }| j D ]9}|dkr| j | }qtd|}t|dkr9|d |v r/||d  |d  q|d g||d < qtd| | D ];\}}|tv r~g }|D ] }z|t| | W qO tyo   |tt|  Y qOw dd t	t
||D ||< qC|r|d| d	  n|d
 | D ].\}}| j |d |d   }	t|	}
|D ]/}| j |d |  }t|	trt|tst||
kst|	trt|trtd| d | qt|	tst|	tr<t|	dkr<d}|D ]}t||krt|}q|D ];}t|	tr| j |d |  }n| j |d |  d }|dj|d | t|| d d| |t| d  qnt|	tr|d i }|D ]>}||d | d  d||< | j |d |  D ]"}t|}| |r{| |s{|d7 }||| kr|||< qeqKt|
D ]$}|D ]}|| | j |d |  | || d  q|d qn
tdtt|	 |d qd 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data_
#
.z-Inconsistent list sizes in mmCIF dictionary: z{k: <{width}}   )r9   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_file	key_listskeydata_valskey_listindsi
sample_valn_valsvalmvalue_no_list
col_widthslen_valcolr   r   r   r+   w   s   


 
	zMMCIFIO._save_dictc                 C   sb   |  |rd| d S | |r*d|v rdjd| d |dS djd| d |dS dj||dS )Nz
;z
;
' z{v: <{width}}")vr=   ')rM   rL   rJ   )r   rZ   	col_widthr   r   r   rK      s   

zMMCIFIO._format_mmcif_colc                 C   s    d|v sd|v rd|v rdS dS )Nr>   r`   z" TFr   r   rZ   r   r   r   rM      s   zMMCIFIO._requires_newlinec                 C   s>   d|v sd|v sd|v s|d dv s| ds|dv rdS d	S )
N rc   ra   r   )r8   #$[];)r4   save_)loop_stop_global_TF)
startswithre   r   r   r   rL      s   zMMCIFIO._requires_quotec                 C   sH   |}d}|dkr"|d d }|t d| 7 }t|| d }|dks|S )N r   r6      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}| j D ]T}||sq	|jdkrd}nt|j}d}|s%d}| D ]3}	||	s2q)|	 }
|
dkr<d}
d}d}d}|		 D ]}|
|sOqF| \}}}|dkred}t|}|d7 }nd}d}t|}|dkrsd	}| }||ks|dkr||kr|d7 }|}|}| |}|	 D ]}||r[|d
 | |r| }|d t| |s|d7 }|j }|dkrd	}|d | |d |   | }|dkrd}|d | |d |  |d | |d d	 |d | |d | | }|d |d d |d |d d |d |d d |d t|  |d t|  |d | |d |
 |d | qqFq)q	| jj}dD ]	}||d}qe||d< || _| | d S ) Nr   1r6   rf   r;   rq   ATOM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_zr5   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   rc   ra   ri   rj   rf   	r>   r4   )r   rI   r!   get_listaccept_model
serial_numr(   accept_chainget_idget_unpacked_listaccept_residueget_resnamerz   accept_atomrB   get_serial_numberelementstripget_name
get_altloc	get_coordget_occupancyget_bfactorr   replacer"   r+   )r   rP   r/   r0   	atom_dictmodelmodel_nrv   atom_numberchainchain_idresidue_numberprev_residue_typeprev_resnameresiduehetfieldresseqicoderesidue_typer   resnamer   atomr   altloccoordstructure_idcr   r   r   r*     s   










OzMMCIFIO._save_structureN)__name__
__module____qualname____doc__r    r%   _selectr3   r+   rK   rM   rL   rz   r*   r   r   r   r   r   3   s    (hr   )r   r?   collectionsr   Bio.PDB.PDBIOr   r   Bio.PDB.StructureBuilderr   rD   r   r   r   r   r   r   <module>   s   