code: def realign4d(
      runs,
      affine_class=Rigid,
      time_interp=True,
      align_runs=True,
      loops=5,
      between_loops=5,
      speedup=5,
      refscan=0,
      borders=(1, 1, 1),
      optimizer="ncg",
      xtol=XTOL,
      ftol=FTOL,
      gtol=GTOL,
      stepsize=STEPSIZE,
      maxiter=MAXITER,
      maxfun=MAXFUN,
  ):
      """
      Parameters
      ----------
      runs : list of Image4d objects
  
      Returns
      -------
      transforms : list
                   nested list of rigid transformations
  
  
      transforms map an 'ideal' 4d grid (conventionally aligned with the
      first scan of the first run) to the 'acquisition' 4d grid for each
      run
      """
  
      # Single-session case
      if type(runs) not in (list, tuple, np.array):
          runs = [runs]
      nruns = len(runs)
      if nruns == 1:
          align_runs = False
  
      # Correct motion and slice timing in each sequence separately
      transforms = [
          single_run_realign4d(
              run,
              affine_class=affine_class,
              time_interp=time_interp,
              loops=loops,
              speedup=speedup,
              refscan=refscan,
              borders=borders,
              optimizer=optimizer,
              xtol=xtol,
              ftol=ftol,
              gtol=gtol,
              stepsize=stepsize,
              maxiter=maxiter,
              maxfun=maxfun,
          )
          for run in runs
      ]
  
      if not align_runs:
          return transforms, transforms, None
  
      # Correct between-session motion using the mean image of each
      # corrected run, and creating a fake time series with no temporal
      # smoothness. If the runs have different affines, a correction is
      # applied to the transforms associated with each run (except for
      # the first run) so that all images included in the fake series
      # have the same affine, namely that of the first run.
      is_same_affine = lambda a1, a2: np.max(np.abs(a1 - a2)) < 1e-5
      mean_img_shape = list(runs[0].get_shape()[0:3]) + [nruns]
      mean_img_data = np.zeros(mean_img_shape)
      for i in range(nruns):
          if is_same_affine(runs[0].affine, runs[i].affine):
              transforms_i = transforms[i]
          else:
              runs[i].affine = runs[0].affine
              aff_corr = Affine(
                  np.dot(runs[0].affine, np.linalg.inv(runs[i].affine))
              )
              transforms_i = [
                  aff_corr.compose(Affine(t.as_affine()))
                  for t in transforms[i]
              ]
          corr_run = resample4d(
              runs[i], transforms=transforms_i, time_interp=time_interp
          )
          mean_img_data[..., i] = corr_run.mean(3)
      del corr_run
  
      mean_img = Image4d(
          mean_img_data, affine=runs[0].affine, tr=1.0, slice_times=0
      )
      transfo_mean = single_run_realign4d(
          mean_img,
          affine_class=affine_class,
          time_interp=False,
          loops=between_loops,
          speedup=speedup,
          borders=borders,
          optimizer=optimizer,
          xtol=xtol,
          ftol=ftol,
          gtol=gtol,
          stepsize=stepsize,
          maxiter=maxiter,
          maxfun=maxfun,
      )
  
      # Compose transformations for each run
      ctransforms = [None for i in range(nruns)]
      for i in range(nruns):
          ctransforms[i] = [
              t.compose(transfo_mean[i]) for t in transforms[i]
          ]
      return ctransforms, transforms, transfo_mean
  
imports: import os
  import warnings
  import numpy
  from nibabel import io_orientation
  from nibabel.affines import apply_affine
  from ...core.image.image_spaces import as_xyz_image, make_xyz_image, xyz_affine
  from ...io.nibcompat import get_header
  from ..slicetiming import timefuncs
  from ._registration import _cspline_sample3d, _cspline_sample4d, _cspline_transform
  from .affine import Affine, Rigid
  from .optimizer import configure_optimizer, use_derivatives
  from .type_check import check_type, check_type_and_shape
label_desc: Use image node_id 9 for calling a global function with example usage: realign4d(runs, affine_class, time_interp, align_runs, loops, between_loops, speedup, refscan, borders, optimizer, xtol, ftol, gtol, stepsize, maxiter, maxfun) and returns: ctransforms,  transforms,  transfo_mean, transforms,  transforms,  None