docstr: This function concatenate image and label volumes at the last dim
  and randomly cropping the volumes (also the cropping margins)
docstr_tok: ["This","function","concatenate","image","and","label","volumes","at","the","last","dim","and","randomly","cropping","the","volumes","(","also","the","cropping","margins",")"]
code: def layer_op(self):
      """
      This function concatenate image and label volumes at the last dim
      and randomly cropping the volumes (also the cropping margins)
      """
      (
          image_id,
          fixed_inputs,
          moving_inputs,
          fixed_shape,
          moving_shape,
      ) = self.iterator.get_next()
      # TODO preprocessing layer modifying
      #      image shapes will not be supported
      # assuming the same shape across modalities, using the first
      image_id.set_shape((self.batch_size,))
      image_id = tf.to_float(image_id)
  
      fixed_inputs.set_shape(
          (self.batch_size,) + (None,) * self.spatial_rank + (2,)
      )
      # last dim is 1 image + 1 label
      moving_inputs.set_shape(
          (self.batch_size,) + self.moving_image_shape + (2,)
      )
      fixed_shape.set_shape((self.batch_size, self.spatial_rank + 1))
      moving_shape.set_shape((self.batch_size, self.spatial_rank + 1))
  
      # resizing the moving_inputs to match the target
      # assumes the same shape across the batch
      target_spatial_shape = tf.unstack(fixed_shape[0], axis=0)[
          : self.spatial_rank
      ]
      moving_inputs = Resize(new_size=target_spatial_shape)(
          moving_inputs
      )
      combined_volume = tf.concat(
          [fixed_inputs, moving_inputs], axis=-1
      )
  
      # smoothing_layer = Smoothing(
      #     sigma=1, truncate=3.0, type_str='gaussian')
      # combined_volume = tf.unstack(combined_volume, axis=-1)
      # combined_volume[0] = tf.expand_dims(combined_volume[0], axis=-1)
      # combined_volume[1] = smoothing_layer(
      #     tf.expand_dims(combined_volume[1]), axis=-1)
      # combined_volume[2] = tf.expand_dims(combined_volume[2], axis=-1)
      # combined_volume[3] = smoothing_layer(
      #     tf.expand_dims(combined_volume[3]), axis=-1)
      # combined_volume = tf.stack(combined_volume, axis=-1)
  
      # TODO affine data augmentation here
      if self.spatial_rank == 3:
          window_channels = (
              np.prod(self.window_size[self.spatial_rank :]) * 4
          )
          # TODO if no affine augmentation:
          img_spatial_shape = target_spatial_shape
          win_spatial_shape = [
              tf.constant(dim)
              for dim in self.window_size[: self.spatial_rank]
          ]
          # when img==win make sure shift => 0.0
          # otherwise interpolation is out of bound
          batch_shift = [
              tf.random_uniform(
                  shape=(self.batch_size, 1),
                  minval=0,
                  maxval=tf.maximum(tf.to_float(img - win - 1), 0.01),
              )
              for (win, img) in zip(
                  win_spatial_shape, img_spatial_shape
              )
          ]
          batch_shift = tf.concat(batch_shift, axis=1)
          affine_constraints = (
              (1.0, 0.0, 0.0, None),
              (0.0, 1.0, 0.0, None),
              (0.0, 0.0, 1.0, None),
          )
          computed_grid = AffineGridWarperLayer(
              source_shape=(None, None, None),
              output_shape=self.window_size[: self.spatial_rank],
              constraints=affine_constraints,
          )(batch_shift)
          computed_grid.set_shape(
              (self.batch_size,)
              + self.window_size[: self.spatial_rank]
              + (self.spatial_rank,)
          )
          resampler = ResamplerLayer(
              interpolation="linear", boundary="replicate"
          )
          windows = resampler(combined_volume, computed_grid)
          out_shape = (
              [self.batch_size]
              + list(self.window_size[: self.spatial_rank])
              + [window_channels]
          )
          windows.set_shape(out_shape)
  
          image_id = tf.reshape(image_id, (self.batch_size, 1))
          start_location = tf.zeros(
              (self.batch_size, self.spatial_rank)
          )
          locations = tf.concat(
              [image_id, start_location, batch_shift], axis=1
          )
      return windows, locations
  
file_path: NiftyNet/niftynet/contrib/sampler_pairwise/sampler_pairwise_uniform_csv.py
imports: from __future__ import absolute_import, division, print_function
  import numpy
  import tensorflow
  from niftynet.engine.image_window import ImageWindow
  from niftynet.layer.base_layer import Layer
  from niftynet.layer.grid_warper import AffineGridWarperLayer
  from niftynet.layer.resampler import ResamplerLayer
  from niftynet.layer.linear_resize import LinearResizeLayer
label_desc: Use image node_id 4 for calling the PairwiseUniformSampler obj's underlying member method code with example usage: obj.layer_op() and returns: windows,  locations