U
    Phk                  
   @  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Z3ddddddddddg
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                      s   e Zd ZdZdddd fddZdddd	d
dZddddddZddddZedd Z	dddddZ
edd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.

    strdictNone)
stats_namereport_formatreturnc                   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__ M/home/dell461/cl/sdc2/HISourceFinder-master-l/src/monai/auto3dseg/analyzer.pyr4   F   s
    zAnalyzer.__init__r
   )keyopr0   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.

        r-   r2   N)r6   r   r/   r5   )r7   r=   r>   r8   r;   r;   r<   
update_opsM   s
    	

zAnalyzer.update_ops)
nested_keyr>   r0   c                 C  s   | t}t|dkrtd|\}}}|| jkr>i g| j|< | j| d |di || j|< t| j}||ddkr|||< 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_label)r0   c                 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r4| 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)reportr0   c                 C  s^   |  D ]P\}}t|tr*| |||< qt|trPt|dkrP| |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_formatr   rQ   r0   c                 C  s   t d| jj ddS )z:Analyze the dict format dataset, return the summary reportz	Subclass z must implement this method.N)NotImplementedErrorr:   __name__)r7   rQ   r;   r;   r<   __call__   s    zAnalyzer.__call__)r]   
__module____qualname____doc__r4   r?   rJ   rM   staticmethodrU   rK   r   r^   __classcell__r;   r;   r9   r<   r!   :   s   
c                      s8   e Zd ZdZejfddd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.

    r+   r-   )	image_keyr.   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   rd   r   SHAPECHANNELSCROPPED_SHAPESPACINGSIZEMM	INTENSITYr3   r4   r?   r   )r7   rd   r.   r/   r9   r;   r<   r4      s$    
      	zImageStats.__init__c                   st  t | t }t }td  fddt j jd D }d k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|	 sDt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. The value of
            ImageStatsKeys.INTENSITY is 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                   s   g | ]} j  | qS r;   rd   .0idr7   r;   r<   
<listcomp>   s     z'ImageStats.__call__.<locals>.<listcomp>r   nda_croppedsc                 S  s   g | ]}t |qS r;   )r   rm   ndar;   r;   r<   rq      s     c                 S  s   g | ]}t |jqS r;   rP   shapers   r;   r;   r<   rq      s     c                 S  s   g | ]}t |jqS r;   ru   rm   Znda_cr;   r;   r<   rq      s     g      ?rA   c                 S  s   g | ]\}}|| qS r;   r;   )rm   abr;   r;   r<   rq     s    c                   s   g | ]} j tj |qS r;   r6   r   rj   evaluaterw   rL   r;   r<   rq     s    report generated by   differs from the report format.zGet image stats spent ) r,   timetorchis_grad_enabledset_grad_enabledrangerd   rv   r   rM   r   re   rD   rf   rg   rX   r   r   affinetolistminndimrh   zipri   rj   r   RuntimeErrorr:   r.   loggerdebug)r7   rQ   startrestore_grad_statendasrr   rV   r;   ro   r<   r^      s6    
$


zImageStats.__call__	r]   r_   r`   ra   r   IMAGE_STATSr4   r^   rc   r;   r;   r9   r<   r"      s   c                      s@   e Zd ZdZejfdddd fddZdd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"])

    r+   )rd   	label_keyr.   c                   s8   || _ || _tjd i}t || | tjt  d S N)rd   r   r   rj   r3   r4   r?   r   )r7   rd   r   r.   r/   r9   r;   r<   r4   +  s
    
zFgImageStats.__init__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| st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                   s   g | ]} j  | qS r;   rk   rl   ro   r;   r<   rq   K  s     z)FgImageStats.__call__.<locals>.<listcomp>r   Label shape  is different from image shape c                   s   g | ]}t | qS r;   r   rs   
ndas_labelr;   r<   rq   Q  s     c                 S  s&   g | ]}|  d kr|ntdgqS )r   g        )numelr   rs   r;   r;   r<   rq   R  s     c                   s   g | ]} j tj |qS r;   rz   rm   Znda_frL   r;   r<   rq   W  s    r|   r}   z!Get foreground image stats spent )r,   r~   r   r   r   r   rd   rv   r   rE   r   rM   r   rj   r   r   r:   r.   r   r   )r7   rQ   r   r   r   nda_foregroundsrV   r;   )rp   r   r7   r<   r^   4  s(    
$



zFgImageStats.__call__	r]   r_   r`   ra   r   FG_IMAGE_STATSr4   r^   rc   r;   r;   r9   r<   r#     s   	c                      sD   e Zd ZdZejdfddddd fddZdd	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"])

    Tr+   bool | None)rd   r   r.   do_ccpc              	     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)rd   r   r   r   	LABEL_UIDIMAGE_INTSTLABEL	PIXEL_PCTrF   LABEL_SHAPELABEL_NCOMPr3   r4   r?   r   r   joinrJ   )r7   rd   r   r.   r   r/   id_seqr9   r;   r<   r4   }  s$       zLabelStats.__init__zMapping[Hashable, MetaTensor]z!dict[Hashable, MetaTensor | dict]r[   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rt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 |   qt#|D ]*\}}|| $tj%t&|
| |	 i qt'( }||tj)< fdd|D |tj< ||tj*< t+|( slt,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                   s   g | ]} j  | qS r;   rk   rl   ro   r;   r<   rq     s     z'LabelStats.__call__.<locals>.<listcomp>r   r   r   c                   s   g | ]}t | qS r;   r   rs   r   r;   r<   rq     s     c                 S  s(   g | ] }|  d kr|n
td gqS )r   )r   r   Tensorrs   r;   r;   r<   rq     s     c                   s   g | ]}|  qS r;   r;   rs   )
mask_indexr;   r<   rq     s     c                   s   g | ]} j tj |qS r;   r6   r   r   r{   )rm   Znda_mrL   r;   r<   rq     s    z label z stats takes c                   s   g | ]} j tj |qS r;   r   r   rL   r;   r<   rq     s    r|   r}   zGet label stats spent )/r,   r~   rX   rd   r   r   r   devicetyper   r   r   rv   r   astypeint16rE   r   rQ   cpunumpynpr   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ncomponentsrn   rI   rV   r;   )rp   r   r   r7   r<   r^     sl    0(
$





"$




zLabelStats.__call__	r]   r_   r`   ra   r   LABEL_STATSr4   r^   rc   r;   r;   r9   r<   r$   e  s
    c                      s@   e Zd ZdZejdfddd fddZdd	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   r.   averagec                   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   re   rf   rg   rh   ri   rj   r3   r4   r?   r   r   r7   r.   r   r/   r9   r;   r<   r4     s*          zImageStatsSumm.__init__
list[dict]r,   r[   c                 C  s*  t |tstd| j dt|dkr:td| j d| j|d krXt| j dt|  }t	j
t	jt	jt	jt	jfD ]@}t|| j|g}| j| j||jdkr| jrdndd||< q|t	j}||  }t|| j|g|}| j| j|| jrd	ndd||< t||  s&t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.   KeyErrorr   rM   r   re   rf   rg   rh   ri   r   r6   r{   r   r   rj   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;   r9   r<   r%     s   c                      s@   e Zd ZdZejdfddd fddZdd	d
ddZ  ZS )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   c                   s2   || _ tjd i}t || | tjt  d S r   )r   r   rj   r3   r4   r?   r   r   r9   r;   r<   r4   t  s    
zFgImageStatsSumm.__init__r   r,   r[   c                 C  s   t |tstd| j dt|dkr:td| j d| j|d krXt| j dt|  }t	j
}||  }t|| j|g|}| j| j|| jrdndd||< t||  st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   rj   rG   r   r6   r{   r   r   r   )r7   rQ   rV   r   r   r   r;   r;   r<   r^   {  s    
"zFgImageStatsSumm.__call__r   r;   r;   r9   r<   r&   h  s   c                      sD   e Zd ZdZejddfdddd fddZdd	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rV|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__r   r,   r[   c                 C  s  t |tstd| j dt|dkr:td| j d| j|d krXt| j dt|  }t	|| jt
jgddd}t|}||t
j< t
j}||  }t|| j|g|}| j| j|| jrdndd	||< g }t
j}	|D ]}
i }t
j}| j|	|
|g}t	||dd
}| j|	 d | j||jdkr:| jr:dndd	||< | jrt
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	||< || q||t
j< t||  st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^     sj    

"
 
 
 
 

zLabelStatsSumm.__call__r   r;   r;   r9   r<   r'     s      c                      s2   e Zd ZdZddd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.

    z
str | Noner+   r-   )r=   r.   r0   c                   s   || _ t |i  d S r   )r=   r3   r4   )r7   r=   r.   r9   r;   r<   r4   6  s    zFilenameStats.__init__c                 C  s   t |}| jr| j|kr*td| j dt|| j tsLtd| j dtj|| j jkrzttj d|| j  d|| j jtj || j< n
d|| j< |S )NzData with key z is missing.zValue type of z is not MetaTensor.z not found in MetaTensor .r-   )	r,   r=   rE   rX   r   r   FILENAME_OR_OBJmetar.   )r7   rQ   rp   r;   r;   r<   r^   :  s    

zFilenameStats.__call__)r]   r_   r`   ra   r4   r^   rc   r;   r;   r9   r<   r(   +  s   
c                      sF   e Zd ZdZejddfddddd fddZd	d	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))

    Nr+   zlist[int] | int | Nonezlist | None)rd   r.   	hist_bins
hist_rangec           
        s@  || _ |d krdgnt|tr"|n|g| _|d kr:ddgn|| _d d d}t || | tj	t
  tdd | jD s| jg| _t| jt| jkrtdt| j dt| j d	tt| j| jD ]l\}}|\}}	t|tr|d
k r
td|d  d| t|	tr"t|	dkrtd|d  d|	 qd S )Nd   ii  counts	bin_edgesc                 s  s   | ]}t |tV  qd S r   )rX   rP   )rm   hrr;   r;   r<   	<genexpr>z  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 )rd   rX   rP   r   r   r3   r4   r?   r   	HISTOGRAMr   allrD   rE   r   r   int)
r7   rd   r.   r   r   r/   rn   Zhist_paramsZ
_hist_binsZ_hist_ranger9   r;   r<   r4   e  s&     

zImageHistogram.__init__r,   r[   c           
      C  sH  t |}t|| j dd}t|d }t| jdkrB|| j | _t| j|krltd| dt| j dt| jdkr|| j | _t| j|krtd| dt| j dg }t	|D ]|}tj
||d	f | j| | j| d | j| d fd
\}}| | d}	t|	|  s.t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   rd   r   rv   rD   r   rE   r   r   	histogramr   r   rM   r   r:   r   r.   )
r7   rQ   rp   r   Znr_channelsreportschannelr   r   _reportr;   r;   r<   r^     s8    


zImageHistogram.__call__	r]   r_   r`   ra   r   IMAGE_HISTOGRAMr4   r^   rc   r;   r;   r9   r<   r)   K  s   #c                      s@   e Zd ZdZejdfddd fddZdd	d
ddZ  ZS )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   c                   s2   || _ tjd i}t || | tjt  d S r   )r   r   r   r3   r4   r?   r   r   r9   r;   r<   r4     s    
zImageHistogramSumm.__init__r   r,   r[   c              	   C  s  t |tstd| j dt|dkr:td| j d| j|d krXt| j di }|D ]}|s|tj }t	t|D ]}t
|| d || d< q~q`t	t|D ]z}|| d  t
|tj | d 7  < t
|| d |tj | d krtd|| d  d	|tj | d  qq`t	t|D ]}|| d  || d< q6t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_histogramrp   rY   rV   r;   r;   r<   r^     s0    

($$
zImageHistogramSumm.__call__r   r;   r;   r9   r<   r*     s   )?
__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>   sT    
tfQ *Z@  s