o
     i                     @  s  d dl mZ d dlZd dlmZmZ d dlmZmZ d dl	m
Z
 d dlmZ d dlZd dlZd dlmZ d dlmZmZmZ d d	lmZmZmZmZmZmZ d d
lmZ d dlm Z  d dl!m"Z"m#Z# d dl$m%Z% d dl&m'Z'm(Z( d dl)m*Z* d dl+m,Z,m-Z-m.Z. d dl/m0Z0m1Z1 ee2dZ3g dZ4G dd de%eZ5G dd de5Z6G dd de5Z7G dd de5Z8G dd de5Z9G dd de5Z:G d d! d!e5Z;G d"d# d#e5Z<G d$d% d%e5Z=G d&d' d'e5Z>dS )(    )annotationsN)ABCabstractmethod)HashableMapping)deepcopy)Any)
get_logger)
OperationsSampleOperationsSummaryOperations)concat_multikeys_to_dictconcat_val_to_npget_foreground_imageget_foreground_labelget_label_ccpverify_report_format)ConfigParser)
ID_SEP_KEY)
MetaTensoraffine_to_spacing)MapTransform)sumunique)convert_to_numpy)DataStatsKeysImageStatsKeysLabelStatsKeys)ImageMetaKeylabel_union)module_name)
Analyzer
ImageStatsFgImageStats
LabelStatsImageStatsSummFgImageStatsSummLabelStatsSummFilenameStatsImageHistogramImageHistogramSummc                      sd   e Zd ZdZd fdd	ZdddZdddZd ddZedd Z	d!ddZ
ed"ddZ  ZS )#r!   a  
    The Analyzer component is a base class. Other classes inherit this class will provide a callable
    with the same class name and produces one pre-formatted dictionary for the input data. The format
    is pre-defined by the init function of the class that inherit this base class. Function operations
    can also be registered before the runtime of the callable.

    Args:
        report_format: a dictionary that outlines the key structures of the report format.

    
stats_namestrreport_formatdictreturnNonec                   s<   t  d  t|dd}|d| _|| _ti dd| _d S )NF)globals )super__init__r   getr-   r+   ops)selfr+   r-   parser	__class__ Z/home/dell461/cl/sdc2/last_ska_mid/HISourceFinder-master-l/src/monai/auto3dseg/analyzer.pyr4   F   s
   zAnalyzer.__init__keyopr
   c                 C  s<   || j |< t| j}||ddkr|||< |d| _dS )z
        Register a statistical operation to the Analyzer and update the report_format.

        Args:
            key: value key in the report.
            op: Operation sub-class object that represents statistical operations.

        r0   r2   N)r6   r   r-   r5   )r7   r=   r>   r8   r;   r;   r<   
update_opsM   s
   
	
zAnalyzer.update_ops
nested_keyc                 C  s   | t}t|dkrtd|\}}}|| jvri g| j|< | j| d |di || j|< t| j}||ddkrC|||< dS dS )a0  
        Update operations for nested label format. Operation value in report_format will be resolved
        to a dict with only keys.

        Args:
            nested_key: str that has format of 'key1#0#key2'.
            op: Operation sub-class object that represents statistical operations.
           zFNested_key input format is wrong. Please ensure it is like key1#0#key2r   NNA)	splitr   len
ValueErrorr6   updater   r-   r5   )r7   r@   r>   keysroot_Z	child_keyr8   r;   r;   r<   update_ops_nested_label^   s   
	



z Analyzer.update_ops_nested_labelc                 C  s   |  | j | jS )z
        Get the report format by resolving the registered operations recursively.

        Returns:
            a dictionary with {keys: None} pairs.

        )resolve_formatr-   r7   r;   r;   r<   get_report_formatw   s   zAnalyzer.get_report_formatc                 C  s8   t t| j}t| dr| jD ]	}||di q|S )a=  
        Unwrap a function value and generates the same set keys in a dict when the function is actually
        called in runtime

        Args:
            func: Operation sub-class object that represents statistical operations. The func object
                should have a `data` dictionary which stores the statistical operation information.
                For some operations (ImageStats for example), it may also contain the data_addon
                property, which is part of the update process.

        Returns:
            a dict with a set of keys.

        
data_addonN)r.   fromkeyslistdatahasattrrN   rF   )funcretr=   r;   r;   r<   
unwrap_ops   s
   

zAnalyzer.unwrap_opsreportc                 C  s^   |  D ](\}}t|tr| |||< qt|tr(t|dkr(| |d  q|||< qdS )z
        Resolve the format of the pre-defined report.

        Args:
            report: the dictionary to resolve. Values will be replaced in-place.

        r   N)items
isinstancer
   rU   rP   rD   rK   )r7   rV   kvr;   r;   r<   rK      s   

zAnalyzer.resolve_formatrQ   r   c                 C  s   t d| jj d)z:Analyze the dict format dataset, return the summary reportz	Subclass z must implement this method.)NotImplementedErrorr:   __name__)r7   rQ   r;   r;   r<   __call__   s   zAnalyzer.__call__)r+   r,   r-   r.   r/   r0   )r=   r,   r>   r
   r/   r0   )r@   r,   r>   r
   r/   r0   )r/   r.   )rV   r.   r/   r0   )rQ   r   r/   r.   )r\   
__module____qualname____doc__r4   r?   rJ   rM   staticmethodrU   rK   r   r]   __classcell__r;   r;   r9   r<   r!   :   s    




r!   c                      s0   e Zd ZdZejfd fddZd	d
 Z  ZS )r"   a  
    Analyzer to extract image stats properties for each case(image).

    Args:
        image_key: the key to find image data in the callable function input (data)

    Examples:

    .. code-block:: python

        import numpy as np
        from monai.auto3dseg import ImageStats
        from monai.data import MetaTensor

        input = {}
        input['image'] = np.random.rand(1,30,30,30)
        input['image'] = MetaTensor(np.random.rand(1,30,30,30))  # MetaTensor
        analyzer = ImageStats(image_key="image")
        print(analyzer(input)["image_stats"])

    Notes:
        if the image data is NumPy array, the spacing stats will be [1.0] * `ndims` of the array,
        where the `ndims` is the lesser value between the image dimension and 3.

    	image_keyr,   r+   r/   r0   c                   sb   t |ts	td|| _tjd tjd tjd tjd tj	d tj
d i}t || | tj
t  d S )Nzimage_key input must be str)rX   r,   rE   rc   r   SHAPECHANNELSCROPPED_SHAPESPACINGSIZEMM	INTENSITYr3   r4   r?   r   )r7   rc   r+   r-   r9   r;   r<   r4      s   
	zImageStats.__init__c                   s  t |tstdt|j dj|vrtdj d|j }t |tjt	j
tfs<tdj dt|j d|jdk rNtdj d	|j d	 t| t }t	 }t	d
  fddt j jd D }d vr}dd |D }t }dd |D |tj< t||tj< dd |D |tj< t |j trt|j j ndgtd|j j |tj< dd t|tj d |tj D |tj < fdd|D |tj!< t"| st#dj$ d| j%< t	| t&'dt |    S )Nz#Input data must be a dict, but got .zKey 'z' not found in input data.zValue for 'z>' must be a numpy array, torch.Tensor, or MetaTensor, but got rA   zImage data under 'z1' must have at least 3 dimensions, but got shape Fc                      g | ]	} j  | qS r;   rc   .0idr7   r;   r<   
<listcomp>      z'ImageStats.__call__.<locals>.<listcomp>r   nda_croppedsc                 S  s   g | ]}t |qS r;   )r   rn   ndar;   r;   r<   rr         c                 S     g | ]}t |jqS r;   rP   shaperu   r;   r;   r<   rr   	      c                 S  rx   r;   ry   rn   Znda_cr;   r;   r<   rr     r{   g      ?c                 S  s   g | ]\}}|| qS r;   r;   )rn   abr;   r;   r<   rr     s    c                      g | ]} j tj |qS r;   r6   r   ri   evaluater|   rL   r;   r<   rr         report generated by   differs from the report format.zGet image stats spent )(rX   r.   	TypeErrortyper\   rc   KeyErrornpndarraytorchTensorr   ndimrE   rz   timeis_grad_enabledset_grad_enabledranger   rM   r   rd   rD   re   rf   r   affinetolistminrg   ziprh   ri   r   RuntimeErrorr:   r+   loggerdebug)r7   rQ   imagestartrestore_grad_statendasrt   rV   r;   rp   r<   r]      sV   





$


zImageStats.__call__)rc   r,   r+   r,   r/   r0   	r\   r^   r_   r`   r   IMAGE_STATSr4   r]   rb   r;   r;   r9   r<   r"      s    r"   c                      s2   e Zd ZdZejfd fddZdddZ  ZS )r#   ay  
    Analyzer to extract foreground label properties for each case(image and label).

    Args:
        image_key: the key to find image data in the callable function input (data)
        label_key: the key to find label data in the callable function input (data)

    Examples:

    .. code-block:: python

        import numpy as np
        from monai.auto3dseg import FgImageStats

        input = {}
        input['image'] = np.random.rand(1,30,30,30)
        input['label'] = np.ones([30,30,30])
        analyzer = FgImageStats(image_key='image', label_key='label')
        print(analyzer(input)["image_foreground_stats"])

    rc   r,   	label_keyr+   c                   s8   || _ || _tjd i}t || | tjt  d S N)rc   r   r   ri   r3   r4   r?   r   )r7   rc   r   r+   r-   r9   r;   r<   r4   ;  s
   
zFgImageStats.__init__rQ   r   r/   r.   c                   s  t | t }t }td  fddt j jd D } j j|d jkr>t	dj d|d j fdd|D }dd |D }t
 }fd	d|D |tj< t| sptd
j d| j< t| tdt |    S )ak  
        Callable to execute the pre-defined functions

        Returns:
            A dictionary. The dict has the key in self.report_format and value
            in a list format. Each element of the value list has stats pre-defined
            by SampleOperations (max, min, ....).

        Raises:
            RuntimeError if the stats report generated is not consistent with the pre-
                defined report_format.

        Note:
            The stats operation uses numpy and torch to compute max, min, and other
            functions. If the input has nan/inf, the stats results will be nan/inf.
        Fc                   rk   r;   rl   rm   rp   r;   r<   rr   [  rs   z)FgImageStats.__call__.<locals>.<listcomp>r   Label shape  is different from image shape c                      g | ]}t | qS r;   r   ru   
ndas_labelr;   r<   rr   a  r{   c                 S  s&   g | ]}|  d kr|ntdgqS )r   g        )numelr   ru   r;   r;   r<   rr   b  s   & c                   r   r;   r   rn   Znda_frL   r;   r<   rr   g  r   r   r   z!Get foreground image stats spent )r.   r   r   r   r   r   rc   rz   r   rE   r   rM   r   ri   r   r   r:   r+   r   r   )r7   rQ   r   r   r   nda_foregroundsrV   r;   )rq   r   r7   r<   r]   D  s(   
$



zFgImageStats.__call__)rc   r,   r   r,   r+   r,   )rQ   r   r/   r.   	r\   r^   r_   r`   r   FG_IMAGE_STATSr4   r]   rb   r;   r;   r9   r<   r#   $  s    	r#   c                      s4   e Zd ZdZejdfd fd	d
ZdddZ  ZS )r$   a  
    Analyzer to extract label stats properties for each case(image and label).

    Args:
        image_key: the key to find image data in the callable function input (data)
        label_key: the key to find label data in the callable function input (data)
        do_ccp: performs connected component analysis. Default is True.

    Examples:

    .. code-block:: python

        import numpy as np
        from monai.auto3dseg import LabelStats

        input = {}
        input['image'] = np.random.rand(1,30,30,30)
        input['label'] = np.ones([30,30,30])
        analyzer = LabelStats(image_key='image', label_key='label')
        print(analyzer(input)["label_stats"])

    Trc   r,   r   r+   do_ccpbool | Nonec              	     s   || _ || _|| _tjd tjd tjtjd tjd igi}| jr.|tj d tj	d tj
d i t || | tjt  ttjdtjg}| |t  d S Nr   0)rc   r   r   r   	LABEL_UIDIMAGE_INTSTLABEL	PIXEL_PCTrF   LABEL_SHAPELABEL_NCOMPr3   r4   r?   r   r   joinrJ   )r7   rc   r   r+   r   r-   id_seqr9   r;   r<   r4     s   zLabelStats.__init__rQ   Mapping[Hashable, MetaTensor]r/   !dict[Hashable, MetaTensor | dict]c                   s  t | t }t j tjtfr j jjdkrd}nd}t	 }t
d  fddt j jd D } j tjj|d jkr[tdj d|d j fd	d|D }d
d |D }t}tttjfr~|j  }|tj }g }d}	g }
|D ]]}t }i }|kfdd|D }fdd|D |tj< t}|
| |	|7 }	jr|r~tj  t\}}||tj< ||tj < || t!"d| dt |   qt#|D ]\}}|| $tj%t&|
| |	 i qt'( }||tj)< fdd|D |tj< ||tj*< t+|( s2t,dj- d| j.< t
| t!"dt |    S )a  
        Callable to execute the pre-defined functions.

        Returns:
            A dictionary. The dict has the key in self.report_format and value
            in a list format. Each element of the value list has stats pre-defined
            by SampleOperations (max, min, ....).

        Examples:
            output dict contains {
                LabelStatsKeys.LABEL_UID:[0,1,3],
                LabelStatsKeys.IMAGE_INTST: {...},
                LabelStatsKeys.LABEL:[
                    {
                        LabelStatsKeys.PIXEL_PCT: 0.8,
                        LabelStatsKeys.IMAGE_INTST: {...},
                        LabelStatsKeys.LABEL_SHAPE: [...],
                        LabelStatsKeys.LABEL_NCOMP: 1
                    }
                    {
                        LabelStatsKeys.PIXEL_PCT: 0.1,
                        LabelStatsKeys.IMAGE_INTST: {...},
                        LabelStatsKeys.LABEL_SHAPE: [...],
                        LabelStatsKeys.LABEL_NCOMP: 1
                    }
                    {
                        LabelStatsKeys.PIXEL_PCT: 0.1,
                        LabelStatsKeys.IMAGE_INTST: {...},
                        LabelStatsKeys.LABEL_SHAPE: [...],
                        LabelStatsKeys.LABEL_NCOMP: 1
                    }
                ]
                }

        Raises:
            RuntimeError if the stats report generated is not consistent with the pre-
                defined report_format.

        Notes:
            The label class_ID of the dictionary in LabelStatsKeys.LABEL IS NOT the
            index. Instead, the class_ID is the LabelStatsKeys.LABEL_UID with the same
            index. For instance, the last dict in LabelStatsKeys.LABEL in the Examples
            is 3, which is the last element under LabelStatsKeys.LABEL_UID.

            The stats operation uses numpy and torch to compute max, min, and other
            functions. If the input has nan/inf, the stats results will be nan/inf.
        cudaTFc                   rk   r;   rl   rm   rp   r;   r<   rr     rs   z'LabelStats.__call__.<locals>.<listcomp>r   r   r   c                   r   r;   r   ru   r   r;   r<   rr     r{   c                 S  s(   g | ]}|  d kr|ntd gqS )r   )r   r   r   ru   r;   r;   r<   rr     s   ( c                   s   g | ]}|  qS r;   r;   ru   )
mask_indexr;   r<   rr     rw   c                   r   r;   r6   r   r   r   )rn   Znda_mrL   r;   r<   rr     r   z label z stats takes c                   r   r;   r   r   rL   r;   r<   rr     r   r   r   zGet label stats spent )/r.   r   rX   rc   r   r   r   devicer   r   r   r   rz   r   astypeint16rE   r   rQ   cpunumpyr   r   r   r   r   appendr   r   empty_cacher   r   r   r   r   	enumeraterF   r   floatr   rM   r   r   r   r   r:   r+   )r7   rQ   r   Z
using_cudar   r   r   unique_labelZlabel_substatsZ	pixel_sumZ	pixel_arrindexZstart_label
label_dictZ	nda_masksZpixel_count
shape_listncomponentsro   rI   rV   r;   )rq   r   r   r7   r<   r]     sl   0(
$





 "




zLabelStats.__call__)rc   r,   r   r,   r+   r,   r   r   )rQ   r   r/   r   	r\   r^   r_   r`   r   LABEL_STATSr4   r]   rb   r;   r;   r9   r<   r$   u  s
    r$   c                      4   e Zd ZdZejdfd fddZdddZ  ZS )r%   au  
    This summary analyzer processes the values of specific key `stats_name` in a list of dict.
    Typically, the list of dict is the output of case analyzer under the same prefix
    (ImageStats).

    Args:
        stats_name: the key of the to-process value in the dict.
        average: whether to average the statistical value across different image modalities.

    Tr+   r,   averager   c                   s   || _ tjd tjd tjd tjd tjd tjd i}t 	|| | 
tjt  | 
tjt  | 
tjt  | 
tjt  | 
tjt  | 
tjt  d S r   )summary_averager   rd   re   rf   rg   rh   ri   r3   r4   r?   r   r   r7   r+   r   r-   r9   r;   r<   r4   *  s   zImageStatsSumm.__init__rQ   
list[dict]r/   r.   c                 C  s(  t |tstd| j dt|dkrtd| j d| j|d vr,t| j dt|  }t	j
t	jt	jt	jt	jfD ] }t|| j|g}| j| j||jdkrX| jrXdndd||< q>t	j}||  }t|| j|g|}| j| j|| jr|d	ndd||< t||  std
| j d|S )  
        Callable to execute the pre-defined functions

        Returns:
            A dictionary. The dict has the key in self.report_format and value
            in a list format. Each element of the value list has stats pre-defined
            by SampleOperations (max, min, ....).

        Raises:
            RuntimeError if the stats report generated is not consistent with the pre-
                defined report_format.

        Examples:
            output dict contains a dictionary for all of the following keys{
                ImageStatsKeys.SHAPE:{...}
                ImageStatsKeys.CHANNELS: {...},
                ImageStatsKeys.CROPPED_SHAPE: {...},
                ImageStatsKeys.SPACING: {...},
                ImageStatsKeys.SIZEMM: {...},
                ImageStatsKeys.INTENSITY: {...},
                }

        Notes:
            The stats operation uses numpy and torch to compute max, min, and other
            functions. If the input has nan/inf, the stats results will be nan/inf.
        	Callable  requires list inputsr    input list is empty is not in input data   r      dimNr   r   )rX   rP   rE   r:   rD   r+   r   r   rM   r   rd   re   rf   rg   rh   r   r6   r   r   r   ri   rG   r   r   r   )r7   rQ   rV   rY   Zv_np	intst_strop_keys
intst_dictr;   r;   r<   r]   =  s,   
."zImageStatsSumm.__call__r+   r,   r   r   rQ   r   r/   r.   r   r;   r;   r9   r<   r%     s    r%   c                      r   )r&   ax  
    This summary analyzer processes the values of specific key `stats_name` in a list of
    dict. Typically, the list of dict is the output of case analyzer under the similar name
    (FgImageStats).

    Args:
        stats_name: the key of the to-process value in the dict.
        average: whether to average the statistical value across different image modalities.

    Tr+   r,   r   r   c                   2   || _ tjd i}t || | tjt  d S r   )r   r   ri   r3   r4   r?   r   r   r9   r;   r<   r4     s   
zFgImageStatsSumm.__init__rQ   r   r/   r.   c                 C  s   t |tstd| j dt|dkrtd| j d| j|d vr,t| j dt|  }t	j
}||  }t|| j|g|}| j| j|| jrOdndd||< t||  setd| j d	|S )
aY  
        Callable to execute the pre-defined functions.

        Returns:
            A dictionary. The dict has the key in self.report_format and value
            in a list format. Each element of the value list has stats pre-defined
            by SampleOperations (max, min, ....) and SummaryOperation (max of the
            max, mean of the mean, etc).

        Raises:
            RuntimeError if the stats report generated is not consistent with the pre-
                defined report_format.

        Examples:
            output dict contains a dictionary for all of the following keys{
                ImageStatsKeys.INTENSITY: {...},
                }

        Notes:
            The stats operation uses numpy and torch to compute max, min, and other
            functions. If the input has nan/inf, the stats results will be nan/inf.
        r   r   r   r   z is not in input data.Nr   r   r   )rX   rP   rE   r:   rD   r+   r   r   rM   r   ri   rG   r   r6   r   r   r   r   )r7   rQ   rV   r   r   r   r;   r;   r<   r]     s   
"zFgImageStatsSumm.__call__r   r   r   r;   r;   r9   r<   r&   x      r&   c                      s6   e Zd ZdZejddfd fdd	ZdddZ  ZS )r'   av  
    This summary analyzer processes the values of specific key `stats_name` in a list of
    dict. Typically, the list of dict is the output of case analyzer under the similar name
    (LabelStats).

    Args:
        stats_name: the key of the to-process value in the dict.
        average: whether to average the statistical value across different image modalities.

    Tr+   r,   r   r   r   c              	     s   || _ || _tjd tjd tjtjd tjd igi}| jr+|tj d tjd tj	d i t
 || | tjt  ttjdtjg}| |t  ttjdtjg}| |t  ttjdtjg}| |t  ttjdtj	g}| |t  d S r   )r   r   r   r   r   r   r   rF   r   r   r3   r4   r?   r   r   r   rJ   r   )r7   r+   r   r   r-   r   r9   r;   r<   r4     s(   zLabelStatsSumm.__init__rQ   r   r/   r.   c                 C  s  t |tstd| j dt|dkrtd| j d| j|d vr,t| j dt|  }t	|| jt
jgddd}t|}||t
j< t
j}||  }t|| j|g|}| j| j|| jrddndd	||< g }t
j}	|D ]}
i }t
j}| j|	|
|g}t	||dd
}| j|	 d | j||jdkr| jrdndd	||< | jrt
j}| jt
j|
|g}t	||dd
}| j|	 d | j||jdkr| jrdndd	||< t
j}| j|	|
t
jg}t	||ddd}| j|	 d | j||jdkr| jrdndd	||< t
j}| j|	|
|g}||	 d |  }t|||dd
}| j|	 d | j|| jr(dndd	||< || qq||t
j< t||  sJtd| j d|S )a  
        Callable to execute the pre-defined functions

        Returns:
            A dictionary. The dict has the key in self.report_format and value
            in a list format. Each element of the value list has stats pre-defined
            by SampleOperations (max, min, ....) and SummaryOperation (max of the
            max, mean of the mean, etc).

        Raises:
            RuntimeError if the stats report generated is not consistent with the pre-
                defined report_format.

        Notes:
            The stats operation uses numpy and torch to compute max, min, and other
            functions. If the input has nan/inf, the stats results will be nan/inf.
        r   r   r   r   r   NT)axisraggedr   )allow_missingr   r   )r   r   r   r   )rX   rP   rE   r:   rD   r+   r   r   rM   r   r   r   r   r   rG   r   r6   r   r   r   r   r   r   r   r   r   r   r   )r7   rQ   rV   Zuid_npr   r   r   r   Zdetailed_label_listZ	label_strZlabel_idstatsZpct_strZpct_fixed_keysZpct_npZ	ncomp_strZncomp_fixed_keysZncomp_npZ	shape_strZshape_fixed_keysshape_npZintst_fixed_keysr;   r;   r<   r]     sb   

"




zLabelStatsSumm.__call__)r+   r,   r   r   r   r   r   r   r;   r;   r9   r<   r'     s
     r'   c                      s*   e Zd ZdZd fdd	Zd
d Z  ZS )r(   a/  
    This class finds the file path for the loaded image/label and writes the info
    into the data pipeline as a monai transforms.

    Args:
        key: the key to fetch the filename (for example, "image", "label").
        stats_name: the key to store the filename in the output stats report.

    r=   
str | Noner+   r,   r/   r0   c                   s   || _ t |i  d S r   )r=   r3   r4   )r7   r=   r+   r9   r;   r<   r4   F  s   zFilenameStats.__init__c                 C  s   t |}| jrK| j|vrtd| j dt|| j ts&td| j dtj|| j jvr=ttj d|| j  d|| j jtj || j< |S d|| j< |S )NzData with key z is missing.zValue type of z is not MetaTensor.z not found in MetaTensor rj   r0   )	r.   r=   rE   rX   r   r   FILENAME_OR_OBJmetar+   )r7   rQ   rq   r;   r;   r<   r]   J  s   

zFilenameStats.__call__)r=   r   r+   r,   r/   r0   )r\   r^   r_   r`   r4   r]   rb   r;   r;   r9   r<   r(   ;  s    
r(   c                      s6   e Zd ZdZejddfd fd
dZdddZ  ZS )r)   a!  
    Analyzer to compute intensity histogram.

    Args:
        image_key: the key to find image data in the callable function input (data)
        hist_bins: list of positive integers (one for each channel) for setting the number of bins used to
            compute the histogram. Defaults to [100].
        hist_range: list of lists of two floats (one for each channel) setting the intensity range to
            compute the histogram. Defaults to [-500, 500].

    Examples:

    .. code-block:: python

        import numpy as np
        from monai.auto3dseg.analyzer import ImageHistogram

        input = {}
        input['image'] = np.random.rand(1,30,30,30)
        input['label'] = np.ones([30,30,30])
        analyzer = ImageHistogram(image_key='image')
        print(analyzer(input))

    Nrc   r,   r+   	hist_binslist[int] | int | None
hist_rangelist | Nonec           
        s<  || _ |d u r
dgn	t|tr|n|g| _|d u rddgn|| _d d d}t || | tj	t
  tdd | jD sC| jg| _t| jt| jkr^tdt| j dt| j d	tt| j| jD ]4\}}|\}}	t|trx|d
k rtd|d  d| t|	trt|	dkrtd|d  d|	 qgd S )Nd   ii  counts	bin_edgesc                 s  s    | ]}t |tV  qd S r   )rX   rP   )rn   hrr;   r;   r<   	<genexpr>  s    z*ImageHistogram.__init__.<locals>.<genexpr>zNumber of histogram bins () and histogram ranges (z) need to be the same!r   z	Expected r   z1. hist_bins value to be positive integer but got r   z8. hist_range values to be list of length 2 but received )rc   rX   rP   r   r   r3   r4   r?   r   	HISTOGRAMr   allrD   rE   r   r   int)
r7   rc   r+   r   r   r-   ro   Zhist_paramsZ
_hist_binsZ_hist_ranger9   r;   r<   r4   u  s.    

zImageHistogram.__init__rQ   r.   r/   c           
      C  sF  t |}t|| j dd}t|d }t| jdkr!|| j | _t| j|kr6td| dt| j dt| jdkrC|| j | _t| j|krXtd| dt| j dg }t	|D ]=}tj
||d	f | j| | j| d | j| d fd
\}}| | d}	t|	|  std| j d||	 q^||| j< |S )a  
        Callable to execute the pre-defined functions

        Returns:
            A dictionary. The dict has the key in self.report_format and value

        Raises:
            RuntimeError if the stats report generated is not consistent with the pre-
                defined report_format.

        Note:
            The stats operation uses numpy and torch to compute max, min, and other
            functions. If the input has nan/inf, the stats results will be nan/inf.
        T)wrap_sequencer   r   z4There is a mismatch between the number of channels (z) and number histogram bins (z).r   .)binsr   r   r   r   )r.   r   rc   r   rz   rD   r   rE   r   r   	histogramr   r   rM   r   r:   r   r+   )
r7   rQ   rq   r   Znr_channelsreportschannelr   r   _reportr;   r;   r<   r]     s@   


zImageHistogram.__call__)rc   r,   r+   r,   r   r   r   r   )rQ   r.   r/   r.   	r\   r^   r_   r`   r   IMAGE_HISTOGRAMr4   r]   rb   r;   r;   r9   r<   r)   [  s    #r)   c                      r   )r*   ay  
    This summary analyzer processes the values of specific key `stats_name` in a list of dict.
    Typically, the list of dict is the output of case analyzer under the same prefix
    (ImageHistogram).

    Args:
        stats_name: the key of the to-process value in the dict.
        average: whether to average the statistical value across different image modalities.

    Tr+   r,   r   r   c                   r   r   )r   r   r   r3   r4   r?   r   r   r9   r;   r<   r4     s   
zImageHistogramSumm.__init__rQ   r   r/   r.   c              	   C  s  t |tstd| j dt|dkrtd| j d| j|d vr,t| j di }|D ]d}|sP|tj }t	t|D ]}t
|| d || d< q?q0t	t|D ]=}|| d  t
|tj | d 7  < t
|| d |tj | d krtd|| d  d	|tj | d  qVq0t	t|D ]}|| d  || d< qtj|i}t||  std
| j d|S )r   r   r   r   r   r   r   r   zbin edges are not consistent! z vs. r   r   )rX   rP   rE   r:   rD   r+   r   r   r   r   r   arrayr   r   r   r   r   rM   r   )r7   rQ   Zsumm_histogramrq   rY   rV   r;   r;   r<   r]     s:   

($	
zImageHistogramSumm.__call__r   r   r   r;   r;   r9   r<   r*     r   r*   )?
__future__r   r   abcr   r   collections.abcr   r   copyr   typingr   r   r   r   monai.apps.utilsr	   Zmonai.auto3dseg.operationsr
   r   r   monai.auto3dseg.utilsr   r   r   r   r   r   monai.bundle.config_parserr   Zmonai.bundle.utilsr   
monai.datar   r   monai.transforms.transformr   0monai.transforms.utils_pytorch_numpy_unificationr   r   monai.utilsr   monai.utils.enumsr   r   r   monai.utils.miscr   r   r\   r   __all__r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r;   r;   r;   r<   <module>   sB    
tvQ *Z@  s