class_docstr: This class creates a ``tf.data.Dataset`` instance from
  a sampler's layer_op function or generator.
  
  If ``from_generator``, ``Dataset.from_generator`` interface will be used,
  ``Dataset.map`` interface will be used otherwise::
  
      if the windows are from a image reader,
      the total number of windows produced
      will be: `epoch x n_subjects x windows_per_image`
  
      if the windows are from a generator,
      the total number of windows produced
      will be: "iterations from the generator" x num_threads
class_docstr_tok: ["This","class","creates","a","``","tf.data.Dataset","``","instance","from","a","sampler","'s","layer_op","function","or","generator",".","If","``","from_generator","``",",","``","Dataset.from_generator","``","interface","will","be","used",",","``","Dataset.map","``","interface","will","be","used","otherwise",":",":","if","the","windows","are","from","a","image","reader",",","the","total","number","of","windows","produced","will","be",":","`","epoch","x","n_subjects","x","windows_per_image","`","if","the","windows","are","from","a","generator",",","the","total","number","of","windows","produced","will","be",":","``","iterations","from","the","generator","''","x","num_threads"]
code: def __init__(
      self,
      reader=None,
      window_sizes=None,
      batch_size=1,
      windows_per_image=1,
      queue_length=10,
      shuffle=True,
      epoch=-1,
      smaller_final_batch_mode="pad",
      seed=None,
      name="image_dataset",
  ):
      Layer.__init__(self, name=name)
  
      self._num_threads = 1
      self._enqueuer = None
      self._seed = seed
  
      self.dataset = None
      self.iterator = None
      self.reader = reader
  
      self.batch_size = batch_size
      self.queue_length = int(
          max(queue_length, round(batch_size * 5.0))
      )
      if self.queue_length > queue_length:
          tf.logging.warning(
              "sampler queue_length should be larger than batch_size, "
              "defaulting to batch_size * 5.0 (%s).",
              self.queue_length,
          )
  
      self.from_generator = inspect.isgeneratorfunction(self.layer_op)
      self.shuffle = shuffle
      self.epoch = 1 if self.from_generator else epoch
      self.smaller_final_batch_mode = look_up_operations(
          smaller_final_batch_mode.lower(), SMALLER_FINAL_BATCH_MODE
      )
  
      self.n_subjects = 1
      self.window = None
      if reader is not None:
          self.window = ImageWindow.from_data_reader_properties(
              reader.input_sources,
              reader.shapes,
              reader.tf_dtypes,
              window_sizes or (-1, -1, -1),
          )
          self.n_subjects = reader.num_subjects
          self.window.n_samples = windows_per_image
  
imports: from __future__ import absolute_import, division, print_function
  import inspect
  import numpy
  import tensorflow
  from tensorflow.python.data.util import nest
  from tensorflow.python.keras.utils import GeneratorEnqueuer
  from niftynet.engine.image_window import ImageWindow, N_SPATIAL, LOCATION_FORMAT, BUFFER_POSITION_NP_TYPE
  from niftynet.io.misc_io import squeeze_spatial_temporal_dim
  from niftynet.layer.base_layer import Layer
  from niftynet.utilities.util_common import look_up_operations
label_desc: Use image node_id 1 to create a new ImageWindowDataset object from inherited base classes: Layer with example: obj = ImageWindowDataset(reader, window_sizes, batch_size, windows_per_image, queue_length, shuffle, epoch, smaller_final_batch_mode, seed, name)