code: def candidate_indices(win_sizes, data, constraint):
      """
      This functions creates a binary map of potential candidate indices given
      the specified constraints and the recalculated probability to select each of
       these candidates so as to uniformise the sampling according to the size of
       connected elements
      :param win_sizes:
      :param data: segmentation
      :param constraint: sampling constraint
      :return: candidates: binary map of potential indices, proba_fin:
      corresponding maps of associated sampling probability
      """
      unique = np.unique(np.round(data))
      list_labels = []
      data = np.round(data)
      if constraint.list_labels:
          list_labels = constraint.list_labels
  
          print("list labels is ", list_labels)
          for label in list_labels:
              if label not in unique:
                  print("Label %d is not there" % label)
                  return np.zeros_like(data), None
      num_labels_add = (
          max(constraint.num_labels - len(list_labels), 0)
          if constraint.num_labels > 0
          else 0
      )
      if len(unique) < constraint.num_labels:
          print("Missing labels")
          return np.zeros_like(data), None
      if constraint.min_ratio > 0:
          num_min = constraint.min_number_from_ratio(win_sizes)
          spatial_win_sizes = np.asarray(
              win_sizes[:N_SPATIAL], dtype=np.int32
          )
          max_spatial_win = spatial_win_sizes[0]
          # Create segmentation for this label
          list_counts = []
          shape_ones = np.asarray(data.shape)
          # print(shape_ones, max_spatial_win)
          half_max_size = np.floor(max_spatial_win / 2)
          padding = []
          for i in range(0, len(win_sizes)):
              if i < N_SPATIAL:
                  shape_ones[i] -= 2 * half_max_size
                  padding = padding + [
                      [half_max_size, half_max_size],
                  ]
              else:
                  padding = padding + [
                      [0, 0],
                  ]
  
          final = np.pad(
              np.ones(shape_ones),
              np.asarray(padding, dtype=np.int32),
              "constant",
          )
          # print(shape_ones, padding, data.shape, np.sum(np.ones(data.shape)),
          #       np.sum(final))
          window_ones = np.ones(win_sizes, dtype=np.int32)
          mean_counts_size = []
          # print(unique)
          for value in unique:
              # print(np.sum(data), 'sum in data', np.prod(data.shape),
              #       ' elements in data')
              seg_label = (data == value).astype(data.dtype)
              # print(np.sum(seg_label), " num values in seg_label ", value)
              label_size = create_label_size_map(seg_label)
              # print(value, np.sum(seg_label), seg_label.shape,
              #       window_ones.shape, num_min)
              # print('Begin fft convolve')
              counts_window = fftconvolve(
                  seg_label, window_ones, "same"
              )
              # print('finished fft convolve')
              valid_places = (
                  counts_window > np.max([num_min, 1])
              ).astype(data.dtype)
              counts_size = fftconvolve(
                  label_size * valid_places, window_ones, "same"
              )
              mean_counts_size_temp = np.nan_to_num(
                  counts_size * 1.0 / counts_window
              )
              mean_counts_size_temp[counts_window == 0] = 0
              # print(np.max(counts_size), " max size")
              # print(np.sum(valid_places), value)
              if value in list_labels:
                  # print(value, 'in list_labels')
                  mean_counts_size.append(mean_counts_size_temp)
                  # print(np.sum(valid_places))
                  valid_places = np.where(
                      final == 0, np.zeros_like(final), valid_places
                  )
                  final = np.copy(valid_places)
                  # print(np.sum(valid_places))
                  print("final calculated for value in list_labels")
              else:
                  list_counts.append(valid_places)
          list_counts.append(final)
          # print(len(list_counts))
          print("final characterisation")
          # for i in range(0, len(list_counts)):
          #     # print(final.shape, list_counts[i].shape, np.max(final), np.max(
          #     #     list_counts[i]))
          #     final += list_counts[i]
          final = np.sum(np.asarray(list_counts), axis=0)
          # print(final.shape, 'shape of final', len(list_counts))
          print("initialising candidates", num_labels_add)
          candidates = np.where(
              final >= num_labels_add + 1,
              np.ones_like(final),
              np.zeros_like(final),
          )
          # candidates[final >= num_labels_add + 1] = 1
          print(np.sum(candidates), "number of candidates")
          proba_fin = None
          if constraint.proba_connected:
              proba_fin = create_probability_weights(
                  candidates, mean_counts_size
              )
          return candidates, proba_fin
  
file_path: NiftyNet/niftynet/contrib/segmentation_selective_sampler/sampler_selective.py
imports: from __future__ import absolute_import, print_function, division
  import numpy
  import tensorflow
  from scipy import ndimage
  from scipy.signal import fftconvolve
  from niftynet.engine.image_window import N_SPATIAL
  from niftynet.engine.sampler_uniform_v2 import UniformSampler
label_desc: Use image node_id 2 for calling a global function with example usage: candidate_indices(win_sizes, data, constraint) and returns: np,  None, candidates,  proba_fin, np,  None