code: def series_from_mask(
      filenames,
      mask,
      dtype=np.float32,
      smooth=False,
      ensure_finite=True,
  ):
      """Read the time series from the given sessions filenames, using the mask.
  
      Parameters
      -----------
      filenames: list of 3D nifti file names, or 4D nifti filename.
                 Files are grouped by session.
      mask: 3d ndarray
            3D mask array: true where a voxel should be used.
      smooth: False or float, optional
              If smooth is not False, it gives the size, in voxel of the
              spatial smoothing to apply to the signal.
      ensure_finite: boolean, optional
              If ensure_finite is True, the non-finite values (NaNs and infs)
              found in the images will be replaced by zeros
  
      Returns
      --------
      session_series: ndarray
              3D array of time course: (session, voxel, time)
      header: header object
              The header of the first file.
  
      Notes
      -----
      When using smoothing, ensure_finite should be True: as elsewhere non
      finite values will spread across the image.
      """
      assert len(filenames) != 0, (
          "filenames should be a file name or a list of file names, "
          f"{filenames} (type {type(filenames)}) was passed"
      )
      mask = mask.astype(np.bool_)
      if smooth:
          # Convert from a sigma to a FWHM:
          smooth /= np.sqrt(8 * np.log(2))
      if isinstance(filenames, str):
          # We have a 4D nifti file
          data_file = load(filenames)
          header = get_header(data_file)
          series = data_file.get_fdata()
          if ensure_finite:
              # SPM tends to put NaNs in the data outside the brain
              series[np.logical_not(np.isfinite(series))] = 0
          series = series.astype(dtype)
          affine = get_affine(data_file)[:3, :3]
          del data_file
          if isinstance(series, np.memmap):
              series = np.asarray(series).copy()
          if smooth:
              vox_size = np.sqrt(np.sum(affine**2, axis=0))
              smooth_sigma = smooth / vox_size
              for this_volume in np.rollaxis(series, -1):
                  this_volume[...] = ndimage.gaussian_filter(
                      this_volume, smooth_sigma
                  )
          series = series[mask]
      else:
          nb_time_points = len(list(filenames))
          series = np.zeros((mask.sum(), nb_time_points), dtype=dtype)
          for index, filename in enumerate(filenames):
              data_file = load(filename)
              data = data_file.get_fdata()
              if ensure_finite:
                  # SPM tends to put NaNs in the data outside the brain
                  data[np.logical_not(np.isfinite(data))] = 0
              data = data.astype(dtype)
              if smooth is not False:
                  affine = get_affine(data_file)[:3, :3]
                  vox_size = np.sqrt(np.sum(affine**2, axis=0))
                  smooth_sigma = smooth / vox_size
                  data = ndimage.gaussian_filter(data, smooth_sigma)
  
              series[:, index] = data[mask]
              # Free memory early
              del data
              if index == 0:
                  header = get_header(data_file)
  
      return series, header
  
file_path: nipy/nipy/labs/mask.py
imports: import math
  import numpy
  from nibabel import load, nifti1, save
  from scipy import ndimage
  from ..io.nibcompat import get_affine, get_header, get_unscaled_data
label_desc: Use image node_id 7 for calling a global function with example usage: series_from_mask(filenames, mask, dtype, smooth, ensure_finite) and returns: series,  header