class_docstr: Add SPM specific options to SpecifyModel
  
  Adds:
  
     - concatenate_runs
     - output_units
  
  Examples
  --------
  >>> from nipype.algorithms import modelgen
  >>> from nipype.interfaces.base import Bunch
  >>> s = modelgen.SpecifySPMModel()
  >>> s.inputs.input_units = 'secs'
  >>> s.inputs.output_units = 'scans'
  >>> s.inputs.high_pass_filter_cutoff = 128.
  >>> s.inputs.functional_runs = ['functional2.nii', 'functional3.nii']
  >>> s.inputs.time_repetition = 6
  >>> s.inputs.concatenate_runs = True
  >>> evs_run2 = Bunch(conditions=['cond1'], onsets=[[2, 50, 100, 180]], durations=[[1]])
  >>> evs_run3 = Bunch(conditions=['cond1'], onsets=[[30, 40, 100, 150]], durations=[[1]])
  >>> s.inputs.subject_info = [evs_run2, evs_run3]
class_docstr_tok: ["Add","SPM","specific","options","to","SpecifyModel","Adds",":","-","concatenate_runs","-","output_units","Examples","--","--","--","--",">",">",">","from","nipype.algorithms","import","modelgen",">",">",">","from","nipype.interfaces.base","import","Bunch",">",">",">","s","=","modelgen.SpecifySPMModel","(",")",">",">",">","s.inputs.input_units","=","'secs'",">",">",">","s.inputs.output_units","=","'scans'",">",">",">","s.inputs.high_pass_filter_cutoff","=","128",".",">",">",">","s.inputs.functional_runs","=","[","'functional2.nii","'",",","'functional3.nii","'","]",">",">",">","s.inputs.time_repetition","=","6",">",">",">","s.inputs.concatenate_runs","=","True",">",">",">","evs_run2","=","Bunch","(","conditions=","[","'cond1","'","]",",","onsets=","[","[","2",",","50",",","100",",","180","]","]",",","durations=","[","[","1","]","]",")",">",">",">","evs_run3","=","Bunch","(","conditions=","[","'cond1","'","]",",","onsets=","[","[","30",",","40",",","100",",","150","]","]",",","durations=","[","[","1","]","]",")",">",">",">","s.inputs.subject_info","=","[","evs_run2",",","evs_run3","]"]
code: def _generate_design(self, infolist=None):
      if (
          not isdefined(self.inputs.concatenate_runs)
          or not self.inputs.concatenate_runs
      ):
          super()._generate_design(infolist=infolist)
          return
  
      if isdefined(self.inputs.subject_info):
          infolist = self.inputs.subject_info
      else:
          infolist = gen_info(self.inputs.event_files)
      concatlist, nscans = self._concatenate_info(infolist)
      functional_runs = [ensure_list(self.inputs.functional_runs)]
      realignment_parameters = []
      if isdefined(self.inputs.realignment_parameters):
          realignment_parameters = []
          for parfile in self.inputs.realignment_parameters:
              mc = np.apply_along_axis(
                  func1d=normalize_mc_params,
                  axis=1,
                  arr=np.loadtxt(parfile),
                  source=self.inputs.parameter_source,
              )
              if not realignment_parameters:
                  realignment_parameters.insert(0, mc)
              else:
                  realignment_parameters[0] = np.concatenate(
                      (realignment_parameters[0], mc)
                  )
      outliers = []
      if isdefined(self.inputs.outlier_files):
          outliers = [[]]
          for i, filename in enumerate(self.inputs.outlier_files):
              try:
                  out = np.loadtxt(filename)
              except OSError:
                  iflogger.warning(
                      "Error reading outliers file %s", filename
                  )
                  out = np.array([])
  
              if out.size > 0:
                  iflogger.debug(
                      "fname=%s, out=%s, nscans=%d",
                      filename,
                      out,
                      sum(nscans[0:i]),
                  )
                  sumscans = out.astype(int) + sum(nscans[0:i])
  
                  if out.size == 1:
                      outliers[0] += [
                          np.array(sumscans, dtype=int).tolist()
                      ]
                  else:
                      outliers[0] += np.array(
                          sumscans, dtype=int
                      ).tolist()
  
      self._sessinfo = self._generate_standard_design(
          concatlist,
          functional_runs=functional_runs,
          realignment_parameters=realignment_parameters,
          outliers=outliers,
      )
  
imports: from copy import deepcopy
  import csv, math, os
  from nibabel import load
  import numpy
  from ..interfaces.base import BaseInterface, TraitedSpec, InputMultiPath, traits, File, Bunch, BaseInterfaceInputSpec, isdefined
  from ..utils.filemanip import ensure_list
  from ..utils.misc import normalize_mc_params
  from ..None import config, logging
label_desc: Use image node_id 2 for calling the SpecifySPMModel obj's underlying member method code with example usage: obj._generate_design(infolist) without return types