code: def register_image_loader(
      name, requires, min_version=None, auto_discover=True
  ):
      """
      Function decorator to register an image loader.
  
      SUPPORTED_LOADERS:
          Ordered dictionary were each entry is a function decorated with
          `@register_image_loader`. This is, every loader that NiftyNet supports.
          This dictionary will be dynamically filled and will be identical for
          every NiftyNet installation.
  
          Used only for information or error messages and logging purposes.
  
      AVAILABLE_LOADERS:
          A subset of the `SUPPORTED_LOADERS` that contain only the loaders that
          have the required library/module installed on the system. Dynamically
          filled from every function decorated with `@register_image_loader` that
          passes the import check. This list will be different for every
          installation, as it is platform dependant.
  
          Inspedted and used to load images in runtime.
  
      Adding a new loader only requires to decorate a function with
      `@register_image_loader` and it will populate SUPPORTED_LOADERS and
      AVAILABLE_LOADERS accordingly in runtime. The function will receive
      a filename as its only parameter, and will return an image and its
      `4x4` affinity matrix. Dummy example:
  
          @register_image_loader('fake', requires='numpy', min_version='1.13.3',
                                 auto_discover=False)
          def imread_numpy(filename):
              np = require_module('numpy')
              return image2nibabel(np.random.rand(100, 100, 3), np.eye(4))
  
      It registers a loader named 'fake' that requires `numpy` version >= '1.13.3'
      to be installed. It will first dynamically load numpy library and then
      return a `(100, 100, 3)` fake color image and an identity `(4, 4)`
      affinity matrix. `loader = fake` in the data section of a config file will
      select this loader and generate fake data.
  
      When `auto_discover=True` (default) the method will be available to be
      automatically discovered and used if `loader` is not provided in the
      config file. This is, if no loader is specified, all the loaders
      registered with `auto_discover=True` will be looped in priority order.
      """
  
      def _wrapper(func):
          """Wrapper that registers a function if it satisfies requirements."""
          try:
              auto_d = auto_discover
              require_module(
                  requires, min_version=min_version, mandatory=True
              )
              AVAILABLE_LOADERS[name] = dict(
                  func=func, auto_discover=auto_d
              )
          except (ImportError, AssertionError):
              pass
          SUPPORTED_LOADERS[name] = (requires, min_version)
          return func
  
      return _wrapper
  
file_path: NiftyNet/niftynet/io/image_loader.py
imports: from collections import OrderedDict
  import nibabel
  import numpy
  import tensorflow
  from niftynet.utilities.util_import import require_module
label_desc: Use image node_id 1 for calling a global function with example usage: register_image_loader(name, requires, min_version, auto_discover) and returns: _wrapper, func