code: def non_parametric_inference(
      second_level_input,
      confounds=None,
      design_matrix=None,
      second_level_contrast=None,
      first_level_contrast=None,
      mask=None,
      smoothing_fwhm=None,
      model_intercept=True,
      n_perm=10000,
      two_sided_test=False,
      random_state=None,
      n_jobs=1,
      verbose=0,
      threshold=None,
      tfce=False,
  ):
      """Generate p-values corresponding to the contrasts provided \
      based on permutation testing.
  
      This function is a light wrapper around
      :func:`~nilearn.mass_univariate.permuted_ols`, with additional steps to
      ensure compatibility with the :mod:`~nilearn.glm.second_level` module.
  
      Parameters
      ----------
      %(second_level_input)s
  
      confounds : :obj:`pandas.DataFrame` or None, optional
          Must contain a subject_label column. All other columns are
          considered as confounds and included in the model. If
          ``design_matrix`` is provided then this argument is ignored.
          The resulting second level design matrix uses the same column
          names as in the given :obj:`~pandas.DataFrame` for confounds.
          At least two columns are expected, ``subject_label`` and at
          least one confound.
  
      design_matrix : :obj:`pandas.DataFrame` or None, optional
          Design matrix to fit the :term:`GLM`. The number of rows
          in the design matrix must agree with the number of maps derived
          from ``second_level_input``.
          Ensure that the order of maps given by a ``second_level_input``
          list of Niimgs matches the order of the rows in the design matrix.
  
      %(second_level_contrast)s
  
      first_level_contrast : :obj:`str`, optional
          In case a pandas DataFrame was provided as second_level_input this
          is the map name to extract from the pandas dataframe map_name column.
          It has to be a 't' contrast.
  
          .. versionadded:: 0.9.0
  
      mask : Niimg-like, :obj:`~nilearn.maskers.NiftiMasker` or \
              :obj:`~nilearn.maskers.MultiNiftiMasker` object, optional
          Mask to be used on data. If an instance of masker is passed,
          then its mask will be used. If no mask is given, it will be computed
          automatically by a :class:`~nilearn.maskers.MultiNiftiMasker` with
          default parameters. Automatic mask computation assumes first level
          imgs have already been masked.
  
      %(smoothing_fwhm)s
  
      model_intercept : :obj:`bool`, default=True
          If ``True``, a constant column is added to the confounding variates
          unless the tested variate is already the intercept.
  
      n_perm : :obj:`int`, default=10000
          Number of permutations to perform.
          Permutations are costly but the more are performed, the more precision
          one gets in the p-values estimation.
  
      two_sided_test : :obj:`bool`, default=False
  
          - If ``True``, performs an unsigned t-test.
            Both positive and negative effects are considered; the null
            hypothesis is that the effect is zero.
          - If ``False``, only positive effects are considered as relevant.
            The null hypothesis is that the effect is zero or negative.
  
  
      %(random_state)s
          Use this parameter to have the same permutations in each
          computing units.
  
      %(n_jobs)s
  
      %(verbose0)s
  
      threshold : None or :obj:`float`, default=None
          Cluster-forming threshold in p-scale.
          This is only used for cluster-level inference.
          If None, no cluster-level inference will be performed.
  
          .. warning::
  
              Performing cluster-level inference will increase the computation
              time of the permutation procedure.
  
          .. versionadded:: 0.9.2
  
      tfce : :obj:`bool`, default=False
          Whether to calculate :term:`TFCE` as part of the permutation procedure
          or not.
          The TFCE calculation is implemented as described in
          :footcite:t:`Smith2009a`.
  
          .. warning::
  
              Performing TFCE-based inference will increase the computation
              time of the permutation procedure considerably.
              The permutations may take multiple hours, depending on how many
              permutations are requested and how many jobs are performed in
              parallel.
  
          .. versionadded:: 0.9.2
  
      Returns
      -------
      neg_log10_vfwe_pvals_img : :class:`~nibabel.nifti1.Nifti1Image`
          The image which contains negative logarithm of the
          voxel-level FWER-corrected p-values.
  
          .. note::
              This is returned if ``threshold`` is None (the default).
  
      outputs : :obj:`dict`
          Output images, organized in a dictionary.
          Each image is 3D/4D, with the potential fourth dimension corresponding
          to the regressors.
  
          .. note::
              This is returned if ``tfce`` is False or ``threshold`` is not None.
  
          .. versionadded:: 0.9.2
  
          Here are the keys:
  
          =============== =======================================================
          key             description
          =============== =======================================================
          t               T-statistics associated with the significance test of
                          the n_regressors explanatory variates against the
                          n_descriptors target variates.
          logp_max_t      Negative log10 family-wise error rate-corrected
                          p-values corrected based on the distribution of maximum
                          t-statistics from permutations.
          size            Cluster size values associated with the significance
                          test of the n_regressors explanatory variates against
                          the n_descriptors target variates.
  
                          Returned only if ``threshold`` is not ``None``.
          logp_max_size   Negative log10 family-wise error rate-corrected
                          p-values corrected based on the distribution of maximum
                          cluster sizes from permutations.
                          This map is generated through cluster-level methods, so
                          the values in the map describe the significance of
                          clusters, rather than individual voxels.
  
                          Returned only if ``threshold`` is not ``None``.
          mass            Cluster mass values associated with the significance
                          test of the n_regressors explanatory variates against
                          the n_descriptors target variates.
  
                          Returned only if ``threshold`` is not ``None``.
          logp_max_mass   Negative log10 family-wise error rate-corrected
                          p-values corrected based on the distribution of maximum
                          cluster masses from permutations.
                          This map is generated through cluster-level methods, so
                          the values in the map describe the significance of
                          clusters, rather than individual voxels.
  
                          Returned only if ``threshold`` is not ``None``.
          tfce            :term:`TFCE` values associated
                          with the significance test of
                          the n_regressors explanatory variates against the
                          n_descriptors target variates.
  
                          Returned only if ``tfce`` is ``True``.
          logp_max_tfce   Negative log10 family-wise error rate-corrected
                          p-values corrected based on the distribution of maximum
                          TFCE values from permutations.
  
                          Returned only if ``tfce`` is ``True``.
          =============== =======================================================
  
      See Also
      --------
      :func:`~nilearn.mass_univariate.permuted_ols` : For more information on \
          the permutation procedure.
  
      References
      ----------
      .. footbibliography::
      """
      _check_second_level_input(second_level_input, design_matrix)
      _check_confounds(confounds)
      _check_design_matrix(design_matrix)
  
      if isinstance(second_level_input, pd.DataFrame):
          second_level_input = _sort_input_dataframe(second_level_input)
      sample_map, _ = _process_second_level_input(second_level_input)
  
      # Report progress
      t0 = time.time()
      if verbose > 0:
          sys.stderr.write("Fitting second level model...")
  
      # Learn the mask. Assume the first level imgs have been masked.
      if not isinstance(mask, NiftiMasker):
          masker = NiftiMasker(
              mask_img=mask,
              smoothing_fwhm=smoothing_fwhm,
              memory=Memory(None),
              verbose=max(0, verbose - 1),
              memory_level=1,
          )
  
      else:
          masker = clone(mask)
          if (
              smoothing_fwhm is not None
              and getattr(masker, "smoothing_fwhm") is not None
          ):
              warn("Parameter smoothing_fwhm of the masker overridden")
              setattr(masker, "smoothing_fwhm", smoothing_fwhm)
  
      masker.fit(sample_map)
  
      # Report progress
      if verbose > 0:
          sys.stderr.write(
              "\nComputation of second level model done in "
              f"{time.time() - t0} seconds\n"
          )
  
      # Check and obtain the contrast
      contrast = _get_con_val(second_level_contrast, design_matrix)
      # Get first-level effect_maps
      effect_maps = _infer_effect_maps(
          second_level_input, first_level_contrast
      )
  
      # Check design matrix and effect maps agree on number of rows
      _check_effect_maps(effect_maps, design_matrix)
  
      # Obtain design matrix vars
      var_names = design_matrix.columns.tolist()
  
      # Obtain tested_var
      column_mask = [bool(val) for val in contrast]
      tested_var = np.dot(design_matrix, contrast)
  
      # Remove tested var from remaining var names
      var_names = [
          var for var, mask in zip(var_names, column_mask) if not mask
      ]
  
      # Obtain confounding vars
      if len(var_names) == 0:
          # No other vars in design matrix
          confounding_vars = None
      else:
          # Use remaining vars as confounding vars
          confounding_vars = np.asarray(design_matrix[var_names])
  
      # Mask data
      target_vars = masker.transform(effect_maps)
  
      # Perform massively univariate analysis with permuted OLS
      outputs = permuted_ols(
          tested_var,
          target_vars,
          confounding_vars=confounding_vars,
          model_intercept=model_intercept,
          n_perm=n_perm,
          two_sided_test=two_sided_test,
          random_state=random_state,
          n_jobs=n_jobs,
          verbose=max(0, verbose - 1),
          masker=masker,
          threshold=threshold,
          tfce=tfce,
          output_type="dict",
      )
      neg_log10_vfwe_pvals_img = masker.inverse_transform(
          np.ravel(outputs["logp_max_t"])
      )
  
      if (not tfce) and (threshold is None):
          return neg_log10_vfwe_pvals_img
  
      t_img = masker.inverse_transform(np.ravel(outputs["t"]))
  
      out = {
          "t": t_img,
          "logp_max_t": neg_log10_vfwe_pvals_img,
      }
  
      if tfce:
          neg_log10_tfce_pvals_img = masker.inverse_transform(
              np.ravel(outputs["logp_max_tfce"]),
          )
          out["tfce"] = masker.inverse_transform(
              np.ravel(outputs["tfce"])
          )
          out["logp_max_tfce"] = neg_log10_tfce_pvals_img
  
      if threshold is not None:
          # Cluster size-based p-values
          neg_log10_csfwe_pvals_img = masker.inverse_transform(
              np.ravel(outputs["logp_max_size"]),
          )
  
          # Cluster mass-based p-values
          neg_log10_cmfwe_pvals_img = masker.inverse_transform(
              np.ravel(outputs["logp_max_mass"]),
          )
  
          out["size"] = masker.inverse_transform(
              np.ravel(outputs["size"])
          )
          out["logp_max_size"] = neg_log10_csfwe_pvals_img
          out["mass"] = masker.inverse_transform(
              np.ravel(outputs["mass"])
          )
          out["logp_max_mass"] = neg_log10_cmfwe_pvals_img
  
      return out
  
imports: import sys
  import time
  from warnings import warn
  import numpy
  import pandas
  from joblib import Memory
  from nibabel import Nifti1Image
  from sklearn.base import clone
  from nilearn._utils import fill_doc, stringify_path
  from nilearn._utils.niimg_conversions import check_niimg
  from nilearn.glm._base import BaseGLM
  from nilearn.glm.contrasts import compute_contrast, expression_to_contrast_vector
  from nilearn.glm.first_level import FirstLevelModel, run_glm
  from nilearn.glm.first_level.design_matrix import make_second_level_design_matrix
  from nilearn.glm.regression import RegressionResults, SimpleRegressionResults
  from nilearn.image import mean_img
  from nilearn.maskers import NiftiMasker
  from nilearn.mass_univariate import permuted_ols
label_desc: Use image node_id 21 for calling a global function with example usage: non_parametric_inference(second_level_input, confounds, design_matrix, second_level_contrast, first_level_contrast, mask, smoothing_fwhm, model_intercept, n_perm, two_sided_test, random_state, n_jobs, verbose, threshold, tfce) and returns: out, neg_log10_vfwe_pvals_img