class_docstr: This class generators ND image samples with a sliding window.
code: def layer_op(self, idx=None):
      while True:
          image_id, data, _ = self.reader(idx=None, shuffle=False)
          if not data:
              break
          image_shapes = {
              name: data[name].shape for name in self.window.names
          }
          static_window_shapes = self.window.match_image_shapes(
              image_shapes
          )
          coordinates = grid_spatial_coordinates(
              image_id,
              image_shapes,
              static_window_shapes,
              self.border_size,
          )
  
          # extend the number of sampling locations to be divisible
          # by batch size
          n_locations = list(coordinates.values())[0].shape[0]
          extra_locations = 0
          if (n_locations % self.batch_size) > 0:
              extra_locations = (
                  self.batch_size - n_locations % self.batch_size
              )
          total_locations = n_locations + extra_locations
  
          tf.logging.info("grid sampling image sizes: %s", image_shapes)
          tf.logging.info(
              "grid sampling window sizes: %s", static_window_shapes
          )
          if extra_locations > 0:
              tf.logging.info(
                  "yielding %s locations from image, "
                  "extended to %s to be divisible by batch size %s",
                  n_locations,
                  total_locations,
                  self.batch_size,
              )
          else:
              tf.logging.info(
                  "yielding %s locations from image", n_locations
              )
          for i in range(total_locations):
              idx = i % n_locations
              #  initialise output dict
              output_dict = {}
              for name in list(data):
                  assert coordinates[name].shape[0] == n_locations, (
                      "different number of grid samples from the input"
                      "images, don't know how to combine them in the queue"
                  )
                  (
                      x_start,
                      y_start,
                      z_start,
                      x_end,
                      y_end,
                      z_end,
                  ) = coordinates[name][idx, 1:]
                  try:
                      image_window = data[name][
                          x_start:x_end,
                          y_start:y_end,
                          z_start:z_end,
                          ...,
                      ]
                  except ValueError:
                      tf.logging.fatal(
                          "dimensionality miss match in input volumes, "
                          "please specify spatial_window_size with a "
                          "3D tuple and make sure each element is "
                          "smaller than the image length in each dim."
                      )
                      raise
                  # fill output dict with data
                  coord_key = LOCATION_FORMAT.format(name)
                  image_key = name
                  output_dict[coord_key] = coordinates[name][
                      idx : idx + 1, ...
                  ]
                  output_dict[image_key] = image_window[np.newaxis, ...]
                  if self.csv_reader is not None:
                      _, label_dict, _ = self.csv_reader(idx=image_id)
                      output_dict.update(label_dict)
                      for name in self.csv_reader.names:
                          output_dict[name + "_location"] = output_dict[
                              "image_location"
                          ]
              yield output_dict
  
      # this is needed because otherwise reading beyond the last element
      # raises an out-of-range error, and the last grid sample
      # will not be processed properly.
      try:
          for name in list(output_dict):
              output_dict[name] = np.ones_like(output_dict[name]) * -1
          if self.csv_reader is not None:
              _, label_dict, _ = self.csv_reader(idx=image_id)
              output_dict.update(label_dict)
              for name in self.csv_reader.task_param.keys():
                  output_dict[name + "_location"] = output_dict[
                      "image_location"
                  ]
          yield output_dict
      except (NameError, KeyError):
          tf.logging.fatal("No feasible samples from %s", self)
          raise
  
file_path: NiftyNet/niftynet/contrib/csv_reader/sampler_grid_v2_csv.py
imports: from __future__ import absolute_import, division, print_function
  import numpy
  import tensorflow
  from niftynet.engine.image_window_dataset import ImageWindowDataset
  from niftynet.contrib.csv_reader.sampler_csv_rows import ImageWindowDatasetCSV
  from niftynet.engine.image_window import N_SPATIAL, LOCATION_FORMAT
label_desc: Use image node_id 2 for calling the GridSamplerCSV obj's underlying member method code with example usage: obj.layer_op(idx) without return types