docstr: Take an array of workflow objects and use introspection to extract
  the parameters, types and docstrings of their run method. Only the
  optional input parameters are extracted for these as they are treated
  as sub workflows.
  
  Parameters
  ----------
  sub_flows : array of dipy.workflows.workflow.Workflow
      Workflows to inspect.
  
  Returns
  -------
  sub_flow_optionals : dictionary of all sub workflow optional parameters
docstr_tok: ["Take","an","array","of","workflow","objects","and","use","introspection","to","extract","the","parameters",",","types","and","docstrings","of","their","run","method",".","Only","the","optional","input","parameters","are","extracted","for","these","as","they","are","treated","as","sub","workflows",".","Parameters","--","--","--","--","--","sub_flows",":","array","of","dipy.workflows.workflow.Workflow","Workflows","to","inspect",".","Returns","--","--","--","-","sub_flow_optionals",":","dictionary","of","all","sub","workflow","optional","parameters"]
code: def add_sub_flow_args(self, sub_flows):
      """Take an array of workflow objects and use introspection to extract
      the parameters, types and docstrings of their run method. Only the
      optional input parameters are extracted for these as they are treated
      as sub workflows.
  
      Parameters
      ----------
      sub_flows : array of dipy.workflows.workflow.Workflow
          Workflows to inspect.
  
      Returns
      -------
      sub_flow_optionals : dictionary of all sub workflow optional parameters
      """
  
      sub_flow_optionals = dict()
      for name, flow, short_name in sub_flows:
          sub_flow_optionals[name] = {}
          doc = inspect.getdoc(flow)
          npds = NumpyDocString(doc)
          _doc = npds["Parameters"]
  
          args, defaults = get_args_default(flow)
  
          len_args = len(args)
          len_defaults = len(defaults)
  
          flow_args = self.add_argument_group(
              "{0} arguments(optional)".format(name)
          )
  
          for i, arg_name in enumerate(args):
              is_not_optionnal = i < len_args - len_defaults
              if "out_" in arg_name or is_not_optionnal:
                  continue
  
              arg_name = "{0}.{1}".format(short_name, arg_name)
              sub_flow_optionals[name][arg_name] = None
              prefix = "--"
              typestr = _doc[i][1]
              dtype, isnarg = self._select_dtype(typestr)
              help_msg = "".join(_doc[i][2])
  
              _args = ["{0}{1}".format(prefix, arg_name)]
              _kwargs = {
                  "help": help_msg,
                  "type": dtype,
                  "action": "store",
                  "metavar": dtype.__name__,
              }
  
              if dtype is bool:
                  _kwargs["action"] = "store_true"
                  default_ = dict()
                  default_[arg_name] = False
                  self.set_defaults(**default_)
                  del _kwargs["type"]
                  del _kwargs["metavar"]
              elif dtype is bool:
                  _kwargs["type"] = int
                  _kwargs["choices"] = [0, 1]
  
              if dtype is tuple:
                  _kwargs["type"] = str
  
              if isnarg:
                  _kwargs["nargs"] = "*"
  
              if _kwargs["action"] != "store_true":
                  _kwargs["type"] = none_or_dtype(_kwargs["type"])
              flow_args.add_argument(*_args, **_kwargs)
  
      return sub_flow_optionals
  
file_path: dipy/dipy/workflows/base.py
imports: import argparse
  import inspect
  from dipy.workflows.docstring_parser import NumpyDocString
label_desc: Use image node_id 3 for calling the IntrospectiveArgumentParser obj's underlying member method code with example usage: obj.add_sub_flow_args(sub_flows) and returns: sub_flow_optionals