U
    vId                     @   s   d dl mZ d dlmZ d dlmZ d dlmZ d dlmZm	Z	m
Z
 d dlZd dlZddlmZ d	d
lmZmZ z$d dlZd dlmZmZmZmZ W n( ek
r   eeeef\ZZZZY nX G dd deZdd Zdd ZG dd deZdS )    )issparse)ceil)copy)partial)DictUnionSequenceN   )AnnData   )AnnCollection_ConcatViewMixin)SamplerBatchSamplerDataset
DataLoaderc                   @   s&   e Zd Zd	ddZdd Zdd ZdS )
BatchIndexSamplerFc                 C   s(   || _ ||k r|n|| _|| _|| _d S N)n_obs
batch_sizeshuffle	drop_last)selfr   r   r   r    r   `/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/anndata/experimental/pytorch/_annloader.py__init__   s    zBatchIndexSampler.__init__c                 c   sx   | j rtj| j }ntt| j}td| j| jD ]:}||t	|| j | j }t
|| jk rl| jrlq8|V  q8d S )Nr   )r   nprandomZpermutationr   tolistlistranger   minlenr   )r   indicesibatchr   r   r   __iter__   s    zBatchIndexSampler.__iter__c                 C   s(   | j r| j| j }nt| j| j }|S r   )r   r   r   r   )r   lengthr   r   r   __len__-   s    zBatchIndexSampler.__len__N)FF)__name__
__module____qualname__r   r&   r(   r   r   r   r   r      s   
r   c                 C   s   t | tjr(|r|  } q|r|  } nZ| jjdkrt| jtj	rt
| rT|  } |rhtj| dd} nt| } |r~|  n| } | S )Ncategorycuda)Zdevice)
isinstancetorchZTensorr-   
pin_memoryZdtypenamer   Z
issubdtypenumberr   ZtoarrayZtensor)arruse_cudar0   r   r   r   default_converter7   s    


r5   c                    sz    d kr}nht  r* fdd}|}nLi }|D ]B}| krH||< q2t|trXd }n|| }t | |||< q2|S )Nc                    s    | S r   r   )r3   converttop_convertr   r   compose_convertM   s    z(_convert_on_top.<locals>.compose_convert)callabler.   r   _convert_on_top)r7   r8   
attrs_keysZnew_convertr9   attrZas_ksr   r6   r   r;   H   s    

r;   c                       sD   e Zd ZdZdeee eeef f e	e
e
e
d fddZ  ZS )		AnnLoadera      PyTorch DataLoader for AnnData objects.

    Builds DataLoader from a sequence of AnnData objects, from an
    :class:`~anndata.experimental.AnnCollection` object or from an `AnnCollectionView` object.
    Takes care of the required conversions.

    Parameters
    ----------
    adatas
        `AnnData` objects or an `AnnCollection` object from which to load the data.
    batch_size
        How many samples per batch to load.
    shuffle
        Set to `True` to have the data reshuffled at every epoch.
    use_default_converter
        Use the default converter to convert arrays to pytorch tensors, transfer to
        the default cuda device (if `use_cuda=True`), do memory pinning (if `pin_memory=True`).
        If you pass an AnnCollection object with prespecified converters, the default converter
        won't overwrite these converters but will be applied on top of them.
    use_cuda
        Transfer pytorch tensors to the default cuda device after conversion.
        Only works if `use_default_converter=True`
    **kwargs
        Arguments for PyTorch DataLoader. If `adatas` is not an `AnnCollection` object, then also
        arguments for `AnnCollection` initialization.
       FT)adatasr   r   use_default_converterr4   c                    s  t |tr|g}t |ts.t |ts.t |tr|dd}|dd }|dd }	|dd }
|dd }|dd }|dd	}|d
d	}t||||	|
||||d	}nt |trt|}nt	d|r|dd}t
t||d}t|j|t|jg d|_d|k}d|k}d|ko"|d d k	}d|ko8|d dk}|pB|}|d k	r|dkr|s|s|dd}|r|d}t|||d}ntt||||}t j|fd |d| nt j|f||d| d S )Njoin_obsinner	join_obsmlabelkeysindex_uniquer7   harmonize_dtypesTindices_strict)rB   rD   rE   rF   rG   r7   rH   rI   z1adata should be of type AnnData or AnnCollection.r0   F)r4   r0   )XsamplerZbatch_samplerZworker_init_fnZnum_workersr   r?   r   )r   r   )r   rK   )r   r   )r.   r
   r   tupledictpopr   r   r   
ValueErrorr   r5   r;   r7   r<   r   r   r"   superr   )r   r@   r   r   rA   r4   kwargsrB   rD   rE   rF   rG   r7   rH   rI   Zdatasetr0   Z
_converterZhas_samplerZhas_batch_samplerZhas_worker_init_fnZhas_workersZuse_parallelr   rK   	__class__r   r   r   }   s    	


    

     zAnnLoader.__init__)r?   FTF)r)   r*   r+   __doc__r   r   r
   r   strintboolr   __classcell__r   r   rR   r   r>   `   s       r>   )Zscipy.sparser   mathr   r   	functoolsr   typingr   r   r   numpyr   warningsZ_core.anndatar
   Zmulti_files._anncollectionr   r   r/   Ztorch.utils.datar   r   r   r   ImportErrorobjectr   r5   r;   r>   r   r   r   r   <module>   s"    