code: def preprocess(self, data_group):
      input_data = data_group.preprocessed_case
  
      if self.mask is not None:
          mask_numpy = read_image_files(self.mask)[..., 0]
      elif self.mask_preprocessor is not None:
          mask_numpy = read_image_files(
              self.mask_preprocessor.mask_numpy
          )[..., 0]
      else:
          mask_numpy = None
  
      if self.channels is not None:
          return_data = np.copy(input_data).astype(float)
          input_data = np.take(
              input_data, indices=self.channels, axis=-1
          )
  
      if self.normalize_by_channel:
          # Make this an optional parameter.
          data_group.preprocessed_case = (
              data_group.preprocessed_case.astype(float)
          )
          for channel in range(data_group.preprocessed_case.shape[-1]):
              data_group.preprocessed_case[
                  ..., channel
              ] = self.normalize(input_data[..., channel], mask_numpy)
      else:
          data_group.preprocessed_case = self.normalize(
              input_data, mask_numpy
          )
  
      if self.channels is not None:
          for channel_idx, channel in enumerate(self.channels):
              return_data[..., channel] = data_group.preprocessed_case[
                  ..., channel_idx
              ]
          data_group.preprocessed_case = return_data
  
      # TODO: Reduce redundancy in naming
      self.output_data = data_group.preprocessed_case
  
imports: import subprocess
  import os
  import numpy
  from deepneuro.preprocessing.preprocessor import Preprocessor
  from deepneuro.utilities.conversion import read_image_files
  from deepneuro.utilities.util import add_parameter, quotes
label_desc: Use image node_id 2 for calling the Normalization obj's underlying member method code with example usage: obj.preprocess(data_group) without return types