code: def permutohedral_compute(
      data_vectors,
      barycentric,
      blur_neighbours1,
      blur_neighbours2,
      indices,
      name,
      reverse,
  ):
      """
      Splat, Gaussian blur, and slice
  
      :param data_vectors: value map to be filtered
      :param barycentric: embedding coordinates
      :param blur_neighbours1: first neighbours' coordinates relative to indices
      :param blur_neighbours2: second neighbours' coordinates relative to indices
      :param indices: corresponding locations of data_vectors
      :param name: layer name
      :param reverse: transpose the Gaussian kernel if True
      :return: filtered data_vectors (sliced to the original space)
      """
  
      num_simplex_corners = barycentric.shape.as_list()[-1]
      n_ch = num_simplex_corners - 1
      batch_size, n_voxels, n_ch_data = data_vectors.shape.as_list()
      data_vectors = tf.reshape(data_vectors, [-1, n_ch_data])
  
      # Splatting
      with tf.variable_scope(name):
          splat = tf.contrib.framework.local_variable(
              tf.constant(0.0), validate_shape=False, name="splatbuffer"
          )
  
      # with tf.control_dependencies([splat.initialized_value()]):
      initial_splat = tf.zeros(
          [tf.shape(blur_neighbours1[0])[0] + 1, batch_size, n_ch_data]
      )
      reset_splat = tf.assign(
          splat, initial_splat, validate_shape=False
      )
      with tf.control_dependencies([reset_splat]):
          for scit in range(num_simplex_corners):
              data = data_vectors * barycentric[:, scit : scit + 1]
              splat = tf.scatter_nd_add(splat, indices[scit], data)
  
      # Blur with 1D kernels
      for dit in range(n_ch, -1, -1) if reverse else range(n_ch + 1):
          b1 = tf.gather(splat, blur_neighbours1[dit])
          b3 = tf.gather(splat, blur_neighbours2[dit])
          splat = tf.concat(
              [splat[:1, ...], splat[1:, ...] + 0.5 * (b1 + b3)], 0
          )
  
      # Slice
      sliced = 0.0
      # Alpha is a magic scaling constant from CRFAsRNN code
      alpha = 1.0 / (1.0 + np.power(2.0, -n_ch))
      for scit in range(0, num_simplex_corners):
          sliced += (
              tf.gather_nd(splat, indices[scit])
              * barycentric[:, scit : scit + 1]
              * alpha
          )
      sliced = tf.reshape(sliced, [batch_size, n_voxels, n_ch_data])
      return sliced
  
file_path: NiftyNet/niftynet/layer/crf.py
imports: from __future__ import absolute_import, print_function
  import numpy
  import tensorflow
  from niftynet.layer.base_layer import TrainableLayer
  from niftynet.layer.layer_util import infer_spatial_rank, expand_spatial_params
label_desc: Use image node_id 3 for calling a global function with example usage: permutohedral_compute(data_vectors, barycentric, blur_neighbours1, blur_neighbours2, indices, name, reverse) and returns: sliced