code: def apply_signal(
      signal_function,
      volume_signal,
  ):
      """Combine the signal volume with its timecourse
  
      Apply the convolution of the HRF and stimulus time course to the
      volume.
  
      Parameters
      ----------
  
      signal_function : timepoint by timecourse array, float
          The timecourse of the signal over time. If there is only one column
          then the same timecourse is applied to all non-zero voxels in
          volume_signal. If there is more than one column then each column is
          paired with a non-zero voxel in the volume_signal (a 3d numpy array
          generated in generate_signal).
  
      volume_signal : multi dimensional array, float
          The volume containing the signal to be convolved with the same
          dimensions as the output volume. The elements in volume_signal
          indicate how strong each signal in signal_function are modulated by
          in the output volume
  
  
      Returns
      ----------
      signal : multidimensional array, float
          The convolved signal volume with the same 3d as volume signal and
          the same 4th dimension as signal_function
  
      """
  
      # How many timecourses are there within the signal_function
      timepoints = signal_function.shape[0]
      timecourses = signal_function.shape[1]
  
      # Preset volume
      signal = np.zeros(
          [
              volume_signal.shape[0],
              volume_signal.shape[1],
              volume_signal.shape[2],
              timepoints,
          ]
      )
  
      # Find all the non-zero voxels in the brain
      idxs = np.where(volume_signal != 0)
      if timecourses == 1:
          # If there is only one time course supplied then duplicate it for
          # every voxel
          signal_function = np.tile(signal_function, (1, len(idxs[0])))
  
      elif len(idxs[0]) != timecourses:
          raise IndexError(
              "The number of non-zero voxels in the volume and "
              "the number of timecourses does not match. Aborting"
          )
  
      # For each coordinate with a non zero voxel, fill in the timecourse for
      # that voxel
      for idx_counter in range(len(idxs[0])):
          x = idxs[0][idx_counter]
          y = idxs[1][idx_counter]
          z = idxs[2][idx_counter]
  
          # Pull out the function for this voxel
          signal_function_temp = signal_function[:, idx_counter]
  
          # Multiply the voxel value by the function timecourse
          signal[x, y, z, :] = (
              volume_signal[x, y, z] * signal_function_temp
          )
  
      return signal
  
imports: import logging
  from itertools import product
  from statsmodels.tsa.arima.model import ARIMA
  import math
  import numpy
  from numpy.linalg import LinAlgError
  from pkg_resources import resource_stream
  from scipy import stats
  from scipy import signal
  import scipy.ndimage
  import copy
  from scipy import optimize
label_desc: Use image node_id 9 for calling a global function with example usage: apply_signal(signal_function, volume_signal) and returns: signal