code: def _default_param_grid(estimator, X, y):
      """Generate sensible default for param_grid.
  
      Parameters
      ----------
      estimator: str
          The estimator to choose among:
          %(classifier_options)s
          %(regressor_options)s
  
      X: list of Niimg-like objects
          See :ref:`extracting_data`.
          Data on which model is to be fitted. If this is a list,
          the affine is considered the same for all.
  
      y: array or list of shape (n_samples)
          The dependent variable (age, sex, IQ, yes/no, etc.).
          Target variable to predict. Must have exactly as many elements as
          3D images in niimg.
  
      Returns
      -------
      param_grid: dict of str to sequence, or sequence of such. Sensible default
      dict has size 1 for linear models.
      """
      param_grid = {}
  
      # validate estimator
      if isinstance(estimator, (DummyClassifier, DummyRegressor)):
          if estimator.strategy in ["constant"]:
              message = (
                  "Dummy classification implemented only for strategies"
                  ' "most_frequent", "prior", "stratified"'
              )
              raise NotImplementedError(message)
      elif not isinstance(
          estimator,
          (
              LogisticRegressionCV,
              LinearSVC,
              RidgeCV,
              RidgeClassifierCV,
              SVR,
              LassoCV,
          ),
      ):
          raise ValueError(
              "Invalid estimator. The supported estimators are:"
              f" {list(SUPPORTED_ESTIMATORS.keys())}"
          )
  
      # use l1_min_c to get lower bound for estimators with L1 penalty
      if hasattr(estimator, "penalty") and (estimator.penalty == "l1"):
          # define loss function
          if isinstance(estimator, LogisticRegressionCV):
              loss = "log"
          elif isinstance(estimator, LinearSVC):
              loss = "squared_hinge"
  
          min_c = l1_min_c(X, y, loss=loss)
  
      # otherwise use 0.5 which will give param_grid["C"] = [1, 10, 100]
      else:
          min_c = 0.5
  
      # define sensible default for different types of estimators
      if isinstance(estimator, (RidgeCV, RidgeClassifierCV)):
          param_grid["alphas"] = [np.geomspace(1e-3, 1e4, 8)]
      elif isinstance(estimator, LogisticRegressionCV):
          # min_c value is set to 0.5 unless the estimator uses L1 penalty,
          # in which case min_c is computed with sklearn.svm.l1_min_c(),
          # so for L2 penalty, param_grid["Cs"] is either 1e-3, ..., 1e4, and
          # for L1 penalty the values are obtained in a more data-driven way
          param_grid["Cs"] = [np.geomspace(2e-3, 2e4, 8) * min_c]
      elif isinstance(estimator, LassoCV):
          # the default is to generate 30 alphas based on the data
          # (alpha values can also be set with the 'alphas' parameter, in which
          # case 'n_alphas' is ignored)
          param_grid["n_alphas"] = [30]
      elif isinstance(estimator, (LinearSVC, SVR)):
          # similar logic as above:
          # - for L2 penalty this is [1, 10, 100]
          # - for L1 penalty the values depend on the data
          param_grid["C"] = np.array([2, 20, 200]) * min_c
      else:
          param_grid = {}
  
      return param_grid
  
imports: import itertools
  import warnings
  from typing import Iterable
  import numpy
  from joblib import Parallel, delayed
  from sklearn import clone
  from sklearn.base import BaseEstimator, MultiOutputMixin
  from sklearn.dummy import DummyClassifier, DummyRegressor
  from sklearn.linear_model import LassoCV, LogisticRegressionCV, RidgeClassifierCV, RidgeCV
  from sklearn.metrics import check_scoring, get_scorer
  from sklearn.model_selection import LeaveOneGroupOut, ParameterGrid, ShuffleSplit, StratifiedShuffleSplit, check_cv
  from sklearn.preprocessing import LabelBinarizer
  from sklearn.svm import SVR, LinearSVC, l1_min_c
  from sklearn.utils.extmath import safe_sparse_dot
  from sklearn.utils.validation import check_is_fitted, check_X_y
  from nilearn._utils import CacheMixin, fill_doc
  from nilearn._utils.cache_mixin import _check_memory
  from nilearn._utils.masker_validation import check_embedded_masker
  from nilearn._utils.param_validation import check_feature_screening
  from nilearn.experimental.surface import SurfaceMasker
  from nilearn.regions.rena_clustering import ReNA
label_desc: Use image node_id 2 for calling a global function with example usage: _default_param_grid(estimator, X, y) and returns: param_grid