docs: def get_design_matrix(self, names=None, format='long', mode='both',
                            force=False, sampling_rate='TR', **kwargs):
          ''' Get design matrix and associated information.
  
          Args:
              names (list): Optional list of names of variables to include in the
                  returned design matrix. If None, all variables are included.
              format (str): Whether to return the design matrix in 'long' or
                  'wide' format. Note that dense design matrices are always
                  returned in 'wide' format.
              mode (str): Specifies whether to return variables in a sparse
                  representation ('sparse'), dense representation ('dense'), or
                  both ('both').
              force (bool): Indicates how to handle columns not of the type
                  indicated by the mode argument. When False, variables of the
                  non-selected type will be silently ignored. When True,
                  variables will be forced to the desired representation. For
                  example, if mode='dense' and force=True, sparse variables will
                  be converted to dense variables and included in the returned
                  design matrix in the .dense attribute. The force argument is
                  ignored entirely if mode='both'.
              sampling_rate ('TR', 'highest' or float): Sampling rate at which to
                  generate the dense design matrix. When 'TR', the repetition
                  time is used, if available, to select the sampling rate (1/TR).
                  When 'highest', all variables are resampled to the highest
                  sampling rate of any variable. The sampling rate may also be
                  specified explicitly in Hz. Has no effect on sparse design
                  matrices.
              kwargs: Optional keyword arguments to pass onto each Variable's
                  to_df() call (e.g., sampling_rate, entities, timing, etc.).
  
          Returns:
              A DesignMatrixInfo namedtuple.
          '''
          sparse_df, dense_df = None, None
          coll = self.collection
  
          if self.level != 'run' and mode != 'sparse':
              mode = 'sparse'
  
          include_sparse = include_dense = (force and mode != 'both')
  
          if mode in ['sparse', 'both']:
              kwargs['sparse'] = True
              sparse_df = coll.to_df(names, format, include_dense=include_dense,
                                     **kwargs)
  
          if mode in ['dense', 'both']:
              # The current implementation of pivoting to wide in
              # BIDSVariableCollection.to_df() breaks if we don't have the
              # temporal columns to index on, so we force their inclusion first
              # and then drop them afterwards.
              kwargs['timing'] = True
              kwargs['sparse'] = False
  
              if sampling_rate == 'TR':
                  trs = {var.run_info[0].tr for var in self.collection.variables.values()}
                  if not trs:
                      raise ValueError("Repetition time unavailable; specify sampling_rate "
                                       "explicitly")
                  elif len(trs) > 1:
                      raise ValueError("Non-unique Repetition times found ({!r}); specify "
                                       "sampling_rate explicitly")
                  sampling_rate = 1. / trs.pop()
              elif sampling_rate == 'highest':
                  sampling_rate = None
              dense_df = coll.to_df(names, format='wide',
                                    include_sparse=include_sparse,
                                    sampling_rate=sampling_rate, **kwargs)
              if dense_df is not None:
                  dense_df = dense_df.drop(['onset', 'duration'], axis=1)
  
          return DesignMatrixInfo(sparse_df, dense_df, self.entities)