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mZ d dlmZ d d	lmZ d d
lmZmZmZmZmZmZmZm Z m!Z! e!ddd\Z"Z#e!ddd\ZZ#e!ddd\Z$Z#g dZ%d_ddZ&ej'fd`ddZ(edd d!d"d#	$	%		&dadbd0d1Z)	2	dcddd6d7Z*	2		&	&	8dedfd=d>Z+dgdBdCZ,dhdidFdGZ-djdLdMZ.dNdOgdPd$ggdQdRgdSdTggdNdOgdPd$gggdUZ/eddVdkdWdXZ0dkdYdZZ1dkd[d\Z2dkd]d^Z3dS )l    )annotationsN)IterableSequence)	lru_cachepartial)
ModuleType)Any)NdarrayOrTensorNdarrayTensor)CropForegroundD)distance_transform_edt)	MetricReductionconvert_to_cupyconvert_to_dst_typeconvert_to_numpyconvert_to_tensordeprecated_argensure_tuple_replook_up_optionoptional_importzscipy.ndimagebinary_erosionnamer   distance_transform_cdt)ignore_backgrounddo_metric_reductionget_mask_edgesget_surface_distanceis_binary_tensorremap_instance_idprepare_spacingget_code_to_measure_tabley_predr
   yreturn#tuple[NdarrayTensor, NdarrayTensor]c                 C  sT   |j d dkr|ddddf n|}| j d dkr$| ddddf n| } | |fS )al  
    This function is used to remove background (the first channel) for `y_pred` and `y`.

    Args:
        y_pred: predictions. As for classification tasks,
            `y_pred` should has the shape [BN] where N is larger than 1. As for segmentation tasks,
            the shape should be [BNHW] or [BNHWD].
        y: ground truth, the first dim is batch.

       N)shape)r"   r#    r(   U/home/dell461/cl/sdc2/last_ska_mid/HISourceFinder-master-l/src/monai/metrics/utils.pyr   6   s   &&r   ftorch.Tensor	reductionMetricReduction | str'tuple[torch.Tensor | Any, torch.Tensor]c                 C  s  t | }| }t jd| jt jd}t|t}|tjkr"| | fS d| |< |tjkrc|j	dd }t 
|dk| j	dd | |} |dkj	dd }t 
|dk| j	dd | |} | |fS |tjkr|j	ddgd }t j	| ddgd} | |fS |tjkr|j	dd }t 
|dk| j	dd | |} | |fS |tjkr|j	dd }| j	dd } | |fS |tjkr|j	dd }t 
|dk| j	dd | |} | |fS |tjkr|j	dd }| j	dd } | |fS |tjkrtd| d| |fS )ak  
    This function is to do the metric reduction for calculated `not-nan` metrics of each sample's each class.
    The function also returns `not_nans`, which counts the number of not nans for the metric.

    Args:
        f: a tensor that contains the calculated metric scores per batch and
            per class. The first two dims should be batch and class.
        reduction: define the mode to reduce metrics, will only apply reduction on `not-nan` values,
            available reduction modes: {``"none"``, ``"mean"``, ``"sum"``, ``"mean_batch"``, ``"sum_batch"``,
            ``"mean_channel"``, ``"sum_channel"``}, default to ``"mean"``.
            if "none", return the input f tensor and not_nans.

    Raises:
        ValueError: When ``reduction`` is not one of
            ["mean", "sum", "mean_batch", "sum_batch", "mean_channel", "sum_channel" "none"].
    r&   devicedtyper   dimzUnsupported reduction: zi, available options are ["mean", "sum", "mean_batch", "sum_batch", "mean_channel", "sum_channel" "none"].)torchisnanzerosr0   floatr   r   NONEMEANsumwhereSUM
MEAN_BATCH	SUM_BATCHMEAN_CHANNELSUM_CHANNEL
ValueError)r*   r,   nansnot_nansZt_zeror(   r(   r)   r   G   sL   



""

"

"	

r   always_return_as_numpyz1.5.0z1.7.0zQThe option is removed and the return type will always be equal to the input type.)r   sinceremoved
msg_suffixr&   TFseg_predr	   seg_gt	label_idxintcropboolspacingSequence | Nonec                 C  s  t ddd\}}| j|jkrtd| j d|j dt| tjr-|s-tt| jd}t}	nt	}t
}	|du oB|oBt| tjoB| jjd	k}
| jttjfvrO| |k} |jttjfvr[||k}|r| |B }| s|	j| jtd
|	j|jtd
}}|du r~||fS ||||fS | d |d |d g}|du r|
st|dtd\} }}n
t|tjd
\} }}tddgdddddd}|| ||d}|d d |d d } }|du r|
st	| |gtd
\} }t| | A }t||A }nt| |gtd
\} }|| | A }|||A }|||ftd
S t|| jd\}}t|}|dkrtjjjntjjj}tj| d |d gdd }||||\}}t|d }|dk||k@ }|dk||k@ }t|d|d  |j}t|d|d  |j}|d |d |d |d f}||ddS )a  
    Compute edges from binary segmentation masks. This
    function is helpful to further calculate metrics such as Average Surface
    Distance and Hausdorff Distance.
    The input images can be binary or labelfield images. If labelfield images
    are supplied, they are converted to binary images using `label_idx`.

    In order to improve the computing efficiency, before getting the edges,
    the images can be cropped and only keep the foreground if not specifies
    ``crop = False``.

    We require that images are the same size, and assume that they occupy the
    same space (spacing, orientation, etc.).

    Args:
        seg_pred: the predicted binary or labelfield image.
        seg_gt: the actual binary or labelfield image.
        label_idx: for labelfield images, convert to binary with
            `seg_pred = seg_pred == label_idx`.
        crop: crop input images and only keep the foregrounds. In order to
            maintain two inputs' shapes, here the bounding box is achieved
            by ``(seg_pred | seg_gt)`` which represents the union set of two
            images. Defaults to ``True``.
        spacing: the input spacing. If not None, the subvoxel edges and areas will be computed.
            otherwise `scipy`'s binary erosion is used to calculate the edges.
        always_return_as_numpy: whether to a numpy array regardless of the input type.
            If False, return the same type as inputs.
            The default value is changed from `True` to `False` in v1.5.0.
    zcucim.skimage.morphologyr   r   z1seg_pred and seg_gt should have same shapes, got z and .r0   Ncudar1   cpur/   predgtsrcr&   F)
source_keymarginallow_smallerstart_coord_keyend_coord_key)rU   rV   rW   r      r2   )wrap_sequence)!r   r'   rA   
isinstancer4   Tensorr   r   r0   r   nptyper1   rM   anyr6   float16r   r   r   r!   lennn
functionalconv3dconv2dstackr7   toindex_selectviewrK   reshape)rH   rI   rJ   rL   rN   rD   Zcucim_binary_erosionZhas_cucim_binary_erosion	converterlibZ	use_cucimZor_volrU   rV   channel_firstcroppercropped
edges_prededges_gtZcode_to_area_tablekspatial_dimsconvvolZ	code_predZcode_gtall_onesZ
areas_predZareas_gtretr(   r(   r)   r      sl   ,

"
  r   	euclideandistance_metricstr7int | float | np.ndarray | Sequence[int | float] | Nonec                 C  s   t | tjrtnt}| stj|j||jd }nD|| s8tj|j||jd }|| }t|| |j	dd S |dkrHt
| d |dd }n|dv rVtt| |d}ntd| d	t|| |jdd }||  S )
ae  
    This function is used to compute the surface distances from `seg_pred` to `seg_gt`.

    Args:
        seg_pred: the edge of the predictions.
        seg_gt: the edge of the ground truth.
        distance_metric: : [``"euclidean"``, ``"chessboard"``, ``"taxicab"``]
            the metric used to compute surface distance. Defaults to ``"euclidean"``.

            - ``"euclidean"``, uses Exact Euclidean distance transform.
            - ``"chessboard"``, uses `chessboard` metric in chamfer type of transform.
            - ``"taxicab"``, uses `taxicab` metric in chamfer type of transform.
        spacing: spacing of pixel (or voxel). This parameter is relevant only if ``distance_metric`` is set to ``"euclidean"``.
            Several input options are allowed:
            (1) If a single number, isotropic spacing with that value is used.
            (2) If a sequence of numbers, the length of the sequence must be equal to the image dimensions.
            (3) If ``None``, spacing of unity is used. Defaults to ``None``.

    Note:
        If seg_pred or seg_gt is all 0, may result in nan/inf distance.

    rS   r   r}   )N.)sampling>   
chessboardtaxicab)metriczdistance_metric z is not implemented.)r`   r4   ra   rb   rd   inf	ones_likefloat32r   r1   monai_distance_transform_edtr   r   rA   )rH   rI   r~   rN   rq   disr(   r(   r)   r      s   
r   r^   use_subvoxels	symmetricclass_indextuple[tuple[torch.Tensor, torch.Tensor], tuple[torch.Tensor, torch.Tensor] | tuple[torch.Tensor], tuple[torch.Tensor, torch.Tensor] | tuple[()]]c                 C  s   d}|r|dur
|ndgt | j }t| |d|dd^}}	}
|	 s1td|dkr+|nd d	 | sDtd
|dkr>|nd d	 |rUt||	||t|	|||f}nt||	||f}t||	f|t|
f| j	dS )af  
    This function is used to compute the surface distance from `y_pred` to `y` using the edges of the masks.

    Args:
        y_pred: the predicted binary or labelfield image. Expected to be in format (H, W[, D]).
        y: the actual binary or labelfield image. Expected to be in format (H, W[, D]).
        distance_metric: : [``"euclidean"``, ``"chessboard"``, ``"taxicab"``]
            See :py:func:`monai.metrics.utils.get_surface_distance`.
        spacing: spacing of pixel (or voxel). This parameter is relevant only if ``distance_metric`` is set to ``"euclidean"``.
            See :py:func:`monai.metrics.utils.get_surface_distance`.
        use_subvoxels: whether to use subvoxel resolution (using the spacing).
            This will return the areas of the edges.
        symmetric: whether to compute the surface distance from `y_pred` to `y` and from `y` to `y_pred`.
        class_index: The class-index used for context when warning about empty ground truth or prediction.

    Returns:
        (edges_pred, edges_gt), (distances_pred_to_gt, [distances_gt_to_pred]), (areas_pred, areas_gt) | tuple()

    Nr&   TF)rL   rN   rD   zthe ground truth of class r^   Unknownz/ is all 0, this may result in nan/inf distance.zthe prediction of class rQ   )
rf   r'   r   rd   warningswarnr   r   tupler0   )r"   r#   r~   rN   r   r   r   Zedges_spacingru   rv   areas	distancesr(   r(   r)   get_edge_surface_distance   s(    
r   inputr   Nonec                 C  s\   t | tjst| dt|  | kr"|  dks"|  dk r,t	| d dS dS )aM  Determines whether the input tensor is torch binary tensor or not.

    Args:
        input (torch.Tensor): tensor to validate.
        name (str): name of the tensor being checked.

    Raises:
        ValueError: if `input` is not a PyTorch Tensor.

    Note:
        A warning message is printed, if the tensor is not binary.
    z  must be of type PyTorch Tensor.r&   r   z should be a binarized tensor.N)
r`   r4   ra   rA   allbytemaxminr   r   )r   r   r(   r(   r)   r   [  s
   *r   rU   by_sizec           
        s   t   }dd |D }|s S |r0 fdd|D }t||}t|dd dd}t| \}}tj tjd}t|D ]\}}	|d	 | |	k< q<|S )
ae  
    This function is used to rename all instance id of `pred`, so that the id is
    contiguous.
    For example: all ids of the input can be [0, 1, 2] rather than [0, 2, 5].
    This function is helpful for calculating metrics like Panoptic Quality (PQ).
    The implementation refers to:

    https://github.com/vqdang/hover_net

    Args:
        pred: segmentation predictions in the form of torch tensor. Each
            value of the tensor should be an integer, and represents the prediction of its corresponding instance id.
        by_size: if True, largest instance will be assigned a smaller id.

    c                 S  s   g | ]}|d kr|qS )r   r(   ).0ir(   r(   r)   
<listcomp>      z%remap_instance_id.<locals>.<listcomp>c                   s   g | ]} |k  qS r(   )r:   )r   instance_idrU   r(   r)   r     r   c                 S  s   | d S )Nr&   r(   )xr(   r(   r)   <lambda>  s    z#remap_instance_id.<locals>.<lambda>T)keyreverserS   r&   )listuniquezipsortedr4   
zeros_likerK   	enumerate)
rU   r   Zpred_idZinstance_sizeZ	pair_dataZ	pair_list_Znew_predidxr   r(   r   r)   r   n  s   
r   \int | float | np.ndarray | Sequence[int | float | np.ndarray | Sequence[int | float]] | None
batch_sizeimg_dimASequence[None | int | float | np.ndarray | Sequence[int | float]]c                   sb  du st ttfrtg| S t ttjfrtfddtD r/td dt d ttjfryt	|krJtd| d dt fd	dtD rbtd
  d dt
dd tD sutd dtS t d ttfrt	 krtd  d dfddt|D S tdtd  td d)a  
    This function is used to prepare the `spacing` parameter to include batch dimension for the computation of
    surface distance, hausdorff distance or surface dice.

    An example with batch_size = 4 and img_dim = 3:
    input spacing = None -> output spacing = [None, None, None, None]
    input spacing = 0.8 -> output spacing = [0.8, 0.8, 0.8, 0.8]
    input spacing = [0.8, 0.5, 0.9] -> output spacing = [[0.8, 0.5, 0.9], [0.8, 0.5, 0.9], [0.8, 0.5, 0.9], [0.8, 0.5, 0.9]]
    input spacing = [0.8, 0.7, 1.2, 0.8] -> output spacing = [0.8, 0.7, 1.2, 0.8] (same as input)

    An example with batch_size = 3 and img_dim = 3:
    input spacing = [0.8, 0.5, 0.9] ->
    output spacing = [[0.8, 0.5, 0.9], [0.8, 0.5, 0.9], [0.8, 0.5, 0.9], [0.8, 0.5, 0.9]]

    Args:
        spacing: can be a float, a sequence of length `img_dim`, or a sequence with length `batch_size`
        that includes floats or sequences of length `img_dim`.

    Raises:
        ValueError: when `spacing` is a sequence of sequence, where the outer sequence length does not
        equal `batch_size` or inner sequence length does not equal `img_dim`.

    Returns:
        spacing: a sequence with length `batch_size` that includes integers, floats or sequences of length `img_dim`.
    Nc                 3  s$    | ]}t |t d   V  qdS )r   N)r`   rc   r   srN   r(   r)   	<genexpr>  s   " z"prepare_spacing.<locals>.<genexpr>zEif `spacing` is a sequence, its elements should be of same type, got rP   r   zcif `spacing` is a sequence of sequences, the outer sequence should have same length as batch size (z), got c                 3  s    | ]	}t | kV  qd S N)rf   r   )r   r(   r)   r     s    zKeach element of `spacing` list should either have same length asimage dim (c                 s  s,    | ]}t |D ]
}t|ttfV  qqd S r   )r   r`   rK   r7   )r   r   r   r(   r(   r)   r     s   * ziif `spacing` is a sequence of sequences or 2D np.ndarray, the elements should be integers or floats, got zPif `spacing` is a sequence of numbers, it should have same length as image dim (c                   s   g | ]} qS r(   r(   )r   r   r   r(   r)   r     s    z#prepare_spacing.<locals>.<listcomp>z;`spacing` is a sequence of elements with unsupported type: z[`spacing` should either be a number, a sequence of numbers or a sequence of sequences, got )r`   rK   r7   r   r   rb   ndarrayrd   rA   rf   r   rangerc   )rN   r   r   r(   )r   rN   r)   r      sV   
r                @          r   r]   )maxsizec                 C  s  g d}g ||||gg d|||gg d|||gg dg d||gg d|||gg dg d||gg dg d||gg d	g d
g d|gg d|||gg dg d||gg dg d||gg dg dg d|gg dg d||gg dg dg d|gg dg dg d|gg dg d||gg d|||gg dg d||gg dg d||gg dg d
g d|gg dg d||gg dg d
g d|gg dg dg d|gg dg dg d
g dgg dg d||gg dg dg d|gg dg dg d|gg dg dg dg dgg dg dg d|gg dg dg dg dgg dg dg dg dgg dg dg d|gg d|||gg dg d||gg dg d||gg dg dg d |gg dg d||gg dg dg d|gg dg dg d|gg d!g d"g dg dgg dg d||gg dg dg d|gg d#g dg d|gg d g d g dg dgg dg dg d|gg dg dg dg dgg dg d$g dg d%gg dg dg d|gg dg d||gg d&g dg d|gg d&g dg d'|gg d&g d||gg dg dg d|gg d(g dg dg dgg dg dg dg dgg dg dg d|gg dg dg d|gg d&g d g dg dgg d)g dg dg dgg d&g d g d|gg dg dg dg dgg dg dg d|gg dg dg d|gg dg d||gg d|||gg dg d||gg dg d||gg dg dg d|gg dg d||gg d*g dg d|gg dg dg d|gg d+g dg dg d%gg dg d||gg dg dg d|gg dg dg d|gg dg dg dg dgg d,g d'g d|gg d'g d'g dg dgg d-g d$g dg dgg dg d'g d|gg dg d.||gg d#g dg d|gg dg dg d.|gg dg d/g dg dgg dg d g d|gg d#g d*||gg dg dg d
g d*gg dg d
g d*|gg dg d.g d|gg d#g dg dg dgg dg dg dg d.gg dg dg d|gg dg d!g dg dgg d#g dg d|gg dg dg d|gg dg d||gg dg d||gg dg dg d|gg dg dg d|gg dg dg d g dgg dg dg d|gg d*g dg dg dgg dg dg dg dgg dg dg d|gg dg dg d|gg dg dg dg dgg d#g dg dg dgg dg dg d|gg d,g d'g dg dgg dg dg d|gg dg dg d|gg dg d||gg d	g d0g d|gg dg dg dg dgg d+g dg dg dgg dg dg d|gg d!g dg dg dgg dg dg d*|gg dg dg d|gg dg d||gg d	g d
g dg dgg dg dg d|gg dg dg d|gg dg d||gg dg dg d|gg dg d||gg dg d||gg d|||gg d|||gg dg d||gg dg d||gg dg dg d|gg dg d||gg dg dg d|gg dg dg d|gg d	g d
g dg dgg dg d||gg dg dg d|gg dg dg d*|gg d!g dg dg dgg dg dg d|gg d+g dg dg dgg dg dg dg dgg d	g d0g d|gg dg d||gg dg dg d|gg dg dg d|gg d,g d'g dg dgg dg dg d|gg d#g dg dg dgg dg dg dg dgg dg dg d|gg dg dg d|gg dg dg dg dgg d*g dg dg dgg dg dg d|gg dg dg d g dgg dg dg d|gg dg dg d|gg dg d||gg dg d||gg dg dg d|gg d#g dg d|gg dg d!g dg dgg dg dg d|gg dg dg dg dgg d#g dg dg dgg dg d.g d|gg dg d
g d*|gg dg dg d
g d*gg d#g d*||gg dg d g d|gg dg d/g dg dgg dg dg d.|gg d#g dg d|gg dg d.||gg dg d'g d|gg d-g d$g dg dgg d'g d'g dg dgg d,g d'g d|gg dg dg dg dgg dg dg d|gg dg dg d|gg dg d||gg d+g dg dg d%gg dg dg d|gg d*g dg d|gg dg d||gg dg dg d|gg dg d||gg dg d||gg d|||gg dg d||gg dg dg d|gg dg dg d|gg dg dg dg dgg d&g d g d|gg d)g dg dg dgg d&g d g dg dgg dg dg d|gg dg dg d|gg dg dg dg dgg d(g dg dg dgg dg dg d|gg d&g d||gg d&g dg d'|gg d&g dg d|gg dg d||gg dg dg d|gg dg d$g dg d%gg dg dg dg dgg dg dg d|gg d g d g dg dgg d#g dg d|gg dg dg d|gg dg d||gg d!g d"g dg dgg dg dg d|gg dg dg d|gg dg d||gg dg dg d |gg dg d||gg dg d||gg d|||gg dg dg d|gg dg dg dg dgg dg dg dg dgg dg dg d|gg dg dg dg dgg dg dg d|gg dg dg d|gg dg d||gg dg dg d
g dgg dg dg d|gg dg d
g d|gg dg d||gg dg d
g d|gg dg d||gg dg d||gg d|||gg dg d||gg dg dg d|gg dg dg d|gg dg d||gg dg dg d|gg dg d||gg dg d||gg d|||gg d	g d
g d|gg dg d||gg dg d||gg d|||gg dg d||gg d|||gg d|||g||||g}t j|| d1S )2a  
    returns a lookup table. For every binary neighbour code (2x2x2 neighbourhood = 8 neighbours = 8 bits = 256 codes)
    it contains the surface normals of the triangles. The length of the normal vector encodes the surfel area.
    Adapted from https://github.com/deepmind/surface-distance

    created using the marching_cube algorithm see e.g. https://en.wikipedia.org/wiki/Marching_cubes

    Args:
        device: torch device to use for the table.
    )        r   r   )      ?r   r   )      r   r   )      пr   r   )      ?r          )r   r   r   )r   r   r   )r   r   r   )      ?r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )      r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )      ?r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )      ؿr   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   rQ   )r4   	as_tensor)r0   r6   r|   r(   r(   r)   $_get_neighbour_code_to_normals_table  s  
	
 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                 	  
                                               !  "  #  $  %  &  '  (  )  *  +  ,  -  .  /  0  1  2  3  4  5  6  7  8  9  :  ;  <  =  >  ?  @  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  [  \  ]  ^  _  `  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  {  |  }  ~         
    r   c                 C  s   t | d} t|}tj| d | d  | d | d  | d | d  ggg||jd}tjj|| dd}|d}|tjtd gg|dfS )	a\  
    Returns an array mapping neighbourhood code to the surface elements area.
    Adapted from https://github.com/deepmind/surface-distance

    Note that the normals encode the initial surface area. This function computes
    the area corresponding to the given `spacing`.

    Args:
        spacing_mm: a sequence of 3 numbers. Voxel spacing along the first 3 spatial axes.
        device: device to put the table on.

    Returns:
        An array of size 256, mapping neighbourhood code to the surface area.
        ENCODING_KERNEL[3] which is the kernel used to compute the neighbourhood code.
    r]   r&   r   r   r/   r^   r2   rQ   )	r   r   r4   r   r1   linalgnormr:   ENCODING_KERNEL)
spacing_mmr0   cr   r   Zneighbour_code_to_surface_arear(   r(   r)   +create_table_neighbour_code_to_surface_area  s   
0
r   c                 C  s&  t | d} | \}}dtj|  }tjdg|jd}||tdd< ||tdd< ||tdd< ||tdd< ||td	d< d| |td
d< ||tdd< ||tdd< d| |tdd< ||tdd< ||tdd< ||tdd< ||tdd< ||tdd< t||d}|tj	t
d gg|dfS )aU  
    Returns an array mapping neighbourhood code to the contour length.
    Adapted from https://github.com/deepmind/surface-distance

    In 2D, each point has 4 neighbors. Thus, are 16 configurations. A
    configuration is encoded with '1' meaning "inside the object" and '0' "outside
    the object". For example,
    "0101" and "1010" both encode an edge along the first spatial axis with length spacing[0] mm;
    "0011" and "1100" both encode an edge along the second spatial axis with length spacing[1] mm.

    Args:
        spacing_mm: 2-element list-like structure. Pixel spacing along the 1st and 2nd spatial axes.
        device: device to put the table on.

    Returns:
        A 16-element array mapping neighbourhood code to the contour length.
        ENCODING_KERNEL[2] which is the kernel used to compute the neighbourhood code.
    r   r   r   rS   Z0001Z0010Z0011Z0100Z0101Z0110Z01111000Z1001Z1010Z1011Z1100Z1101Z1110rQ   )r   rb   r   r   r6   r1   rK   r   r4   r   r   )r   r0   firstseconddiagZ neighbour_code_to_contour_lengthr(   r(   r)   -create_table_neighbour_code_to_contour_length  s(   
r   c                 C  s4   t | }t| t|d} |dkrt| |S t| |S )z
    returns a table mapping neighbourhood code to the surface area or contour length.

    Args:
        spacing: a sequence of 2 or 3 numbers, indicating the spacing in the spatial dimensions.
        device: device to put the table on.
    r   r   )rf   r   r   r   r   )rN   r0   rx   r(   r(   r)   r!   -  s
   

r!   )r"   r
   r#   r
   r$   r%   )r*   r+   r,   r-   r$   r.   )r&   TNF)rH   r	   rI   r	   rJ   rK   rL   rM   rN   rO   rD   rM   r$   r%   )r}   N)
rH   r	   rI   r	   r~   r   rN   r   r$   r	   )r}   NFFr^   )r"   r+   r#   r+   r~   r   rN   r   r   rM   r   rM   r   rK   r$   r   )r   r+   r   r   r$   r   )F)rU   r+   r   rM   r$   r+   )rN   r   r   rK   r   rK   r$   r   r   )4
__future__r   r   collections.abcr   r   	functoolsr   r   typesr   typingr   numpyrb   r4   monai.configr	   r
   Z#monai.transforms.croppad.dictionaryr   monai.transforms.utilsr   r   monai.utilsr   r   r   r   r   r   r   r   r   r   r   r   __all__r   r9   r   r   r   r   r   r   r    r   r   r   r   r!   r(   r(   r(   r)   <module>   sd   ,
>	j1
;
"2A  

*