o
    Rŀg&                     @   s2   d Z ddlmZ dd Zdd ZG dd dZd	S )
aF  Code to work with GenePop.

See http://wbiomed.curtin.edu.au/genepop/ , the format is documented
here: http://wbiomed.curtin.edu.au/genepop/help_input.html .

Classes:
Record           Holds GenePop data.

Functions:
read             Parses a GenePop record (file) into a Record object.


Partially inspired by MedLine Code.

    )deepcopyc                    s   dd  |  d\}}|dd d}dd |D }t|d d	v r&d
ndz fdd|D }W n tyG    fdd|D }Y nw ||fS )z>Extract the details of the individual information on the line.c                 S   s   t | }|dkr
dS |S )z*Return integer of val, or None if is zero.r   N)int)valv r   O/var/www/html/myenv/lib/python3.10/site-packages/Bio/PopGen/GenePop/__init__.pyint_no_zero   s   zget_indiv.<locals>.int_no_zero,	 c                 S   s   g | ]}|d kr|qS ) r   .0markerr   r   r   
<listcomp>&   s    zget_indiv.<locals>.<listcomp>r   )      r      c                    s,   g | ]} |d   |d fqS )r   Nr   r   r   
marker_lenr   r   r   ,   s    c                    s   g | ]} |d  fqS )r   r   r   r   r   r   r   1   s    )splitreplacelen
ValueError)line
indiv_namemarker_linemarkersallele_listr   r   r   	get_indiv   s   

r   c                 C   s^  t  }t|  |_t|  dd}|d}|j| | D ]}| }| dkr/ n|j	| q!t
d|j	g  | D ]%}| }| dkrU|j	g  qBt|\}}|_|jd 	||f qB|j}|jD ]>}|j	|d d  |D ]/}	tt|D ]&}
|	d |
 }g }|D ]}|dkr|	d	 q|	| qt||	d |
< qq|qn|S )
zpParse a handle containing a GenePop file.

    handle is a file-like object that contains a GenePop record.
    r	   r   r   POPz;No population data found, file probably not GenePop relatedr      N)Recordnextrstripcomment_liner   r   	loci_listextendupperappendr   populationsr   r   pop_listranger   tuple)handlerecordsample_loci_lineall_locir   r   r   locipopindivmk_imk_origmk_realalr   r   r   read5   sB   


r:   c                   @   sH   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )r#   a  Hold information from a GenePop record.

    Members:

        - marker_len         The marker length (2 or 3 digit code per allele).

        - comment_line       Comment line.

        - loci_list          List of loci names.

        - pop_list           List of population names.

        - populations        List of population data.

    In most genepop files, the population name is not trustable.
    It is strongly recommended that populations are referred by index.

    populations has one element per population. Each element is itself
    a list of individuals, each individual is a pair composed by individual
    name and a list of alleles (2 per marker or 1 for haploids):
    Example::

        [
            [
                ('Ind1', [(1,2),    (3,3), (200,201)],
                ('Ind2', [(2,None), (3,3), (None,None)],
            ],
            [
                ('Other1', [(1,1),  (4,3), (200,200)],
            ]
        ]

    c                 C   s"   d| _ d| _g | _g | _g | _dS )zInitialize the class.r   r   N)r   r&   r'   r,   r+   )selfr   r   r   __init__   s
   
zRecord.__init__c           	      C   s   | j d g}|d| jd  | jD ]R}|d |D ]H}|\}}|| |d |D ]0}|d |D ]&}|du r@d}t|}t|| jk rYdd|g}t|| jk sK|| q8q/|d qqd|S )z6Return (reconstruct) a GenePop textual representation.
zPop
r	   r   N0r   )r&   r*   joinr'   r+   strr   r   )	r;   repr4   r5   namer   r   r9   aStrr   r   r   __str__   s,   





zRecord.__str__c                 C   sV   i }t | jD ]!\}}t }| j|_| j|_t| j|_t|g|_|||| < q|S )a$  Split a GP record in a dictionary with 1 pop per entry.

        Given a record with n pops and m loci returns a dictionary
        of records (key pop_name) where each item is a record
        with a single pop and m loci.

        Arguments:
        - pop_names - Population names

        )	enumerater+   r#   r   r&   r   r'   )r;   	pop_namesgp_popsi
populationgp_popr   r   r   split_in_pops   s   zRecord.split_in_popsc           	      C   s   i }t | jD ]>\}}t }| j|_| j|_|g|_g |_| jD ]}g }|D ]}||d |d | gf q&|j| q |||jd < q|S )zSplit a GP record in a dictionary with 1 locus per entry.

        Given a record with n pops and m loci returns a dictionary
        of records (key locus name) where each item is a record
        with a single locus and n pops.
        r   r"   )rE   r'   r#   r   r&   r+   r*   )	r;   gpgp_locirH   locusrJ   r4   my_popr5   r   r   r   split_in_loci   s   
zRecord.split_in_locic                 C   s   | j |= dS )z"Remove a population (by position).N)r+   )r;   posr   r   r   remove_population   s   zRecord.remove_populationc                 C   s0   | j |= | jD ]}|D ]	}|\}}||= qqdS )zRemove a locus by position.N)r'   r+   )r;   rQ   r4   r5   rB   r3   r   r   r   remove_locus_by_position   s   
zRecord.remove_locus_by_positionc                 C   s0   t | jD ]\}}||kr| |  dS qdS )zRemove a locus by name.N)rE   r'   rS   )r;   rB   rH   rN   r   r   r   remove_locus_by_name   s   
zRecord.remove_locus_by_nameN)__name__
__module____qualname____doc__r<   rD   rK   rP   rR   rS   rT   r   r   r   r   r#   a   s    "r#   N)rX   copyr   r   r:   r#   r   r   r   r   <module>   s
   ,