code: def check_pdmultiindex_panel(
      obj, return_metadata=False, var_name="obj", panel=True
  ):
      if not isinstance(obj, pd.DataFrame):
          msg = f"{var_name} must be a pd.DataFrame, found {type(obj)}"
          return _ret(False, msg, None, return_metadata)
  
      if not isinstance(obj.index, pd.MultiIndex):
          msg = f"{var_name} must have a MultiIndex, found {type(obj.index)}"
          return _ret(False, msg, None, return_metadata)
  
      index = obj.index
  
      # check that columns are unique
      col_names = obj.columns
      if not col_names.is_unique:
          msg = f"{var_name} must have unique column indices, but found {col_names}"
          return _ret(False, msg, None, return_metadata)
  
      # check that no dtype is object
      if "object" in obj.dtypes.values:
          msg = f"{var_name} should not have column of 'object' dtype"
          return _ret(False, msg, None, return_metadata)
  
      # check that there are precisely two index levels
      nlevels = index.nlevels
      if panel is True and not nlevels == 2:
          msg = f"{var_name} must have a MultiIndex with 2 levels, found {nlevels}"
          return _ret(False, msg, None, return_metadata)
      elif panel is False and not nlevels > 2:
          msg = f"{var_name} must have a MultiIndex with 3 or more levels, found {nlevels}"
          return _ret(False, msg, None, return_metadata)
  
      # check whether the time index is of valid type
      if not is_in_valid_index_types(index.levels[-1]):
          msg = (
              f"{type(index)} is not supported for {var_name}, use "
              f"one of {VALID_INDEX_TYPES} or integer index instead."
          )
          return _ret(False, msg, None, return_metadata)
  
      # check instance index being integer or range index
      inst_inds = index.levels[0]
      if not is_in_valid_multiindex_types(inst_inds):
          msg = (
              f"instance index (first/highest index) must be {VALID_MULTIINDEX_TYPES}, "
              f"integer index, but found {type(inst_inds)}"
          )
          return _ret(False, msg, None, return_metadata)
  
      # check if time index is monotonic increasing for each group
      if not index.is_monotonic_increasing:
          index_frame = index.to_frame()
          if (
              not index_frame.groupby(
                  level=list(range(index.nlevels - 1)), sort=False
              )[index_frame.columns[-1]]
              .is_monotonic_increasing.astype(bool)
              .all()
          ):
              msg = (
                  f"The (time) index of {var_name} must be sorted monotonically "
                  f"increasing. Use {var_name}.sort_index() to sort the index, or "
                  f"{var_name}.duplicated() to find duplicates."
              )
              return _ret(False, msg, None, return_metadata)
  
      metadata = dict()
  
      if _req("is_univariate", return_metadata):
          metadata["is_univariate"] = len(obj.columns) < 2
      if _req("is_empty", return_metadata):
          metadata["is_empty"] = len(index) < 1 or len(obj.columns) < 1
      if _req("has_nans", return_metadata):
          metadata["has_nans"] = obj.isna().values.any()
      if _req("n_features", return_metadata):
          metadata["n_features"] = len(obj.columns)
      if _req("feature_names", return_metadata):
          metadata["feature_names"] = obj.columns.to_list()
  
      # check whether index is equally spaced or if there are any nans
      #   compute only if needed
      requires_series_grps = [
          "n_instances",
          "is_one_series",
          "is_equal_length",
          "is_equally_spaced",
      ]
      if _req(requires_series_grps, return_metadata):
          series_groups = obj.groupby(
              level=list(range(index.nlevels - 1)), sort=False
          )
          n_series = series_groups.ngroups
  
          if _req("n_instances", return_metadata):
              metadata["n_instances"] = n_series
          if _req("is_one_series", return_metadata):
              metadata["is_one_series"] = n_series == 1
          if _req("is_equal_length", return_metadata):
              metadata["is_equal_length"] = _list_all_equal(
                  series_groups.size().to_numpy()
              )
          if _req("is_equally_spaced", return_metadata):
              metadata["is_equally_spaced"] = all(
                  _index_equally_spaced(
                      group.index.get_level_values(-1)
                  )
                  for _, group in series_groups
              )
  
      requires_panel_grps = ["n_panels", "is_one_panel"]
      if _req(requires_panel_grps, return_metadata):
          if panel:
              n_panels = 1
          else:
              panel_groups = obj.groupby(
                  level=list(range(index.nlevels - 2)), sort=False
              )
              n_panels = panel_groups.ngroups
  
          if _req("n_panels", return_metadata):
              metadata["n_panels"] = n_panels
          if _req("is_one_panel", return_metadata):
              metadata["is_one_panel"] = n_panels == 1
  
      return _ret(True, None, metadata, return_metadata)
  
file_path: sktime/sktime/datatypes/_panel/_check.py
imports: import numpy
  import pandas
  from pandas.core.dtypes.cast import is_nested_object
  from sktime.datatypes._common import _req, _ret
  from sktime.datatypes._series._check import _index_equally_spaced, check_pddataframe_series
  from sktime.utils.validation._dependencies import _check_soft_dependencies
  from sktime.utils.validation.series import is_in_valid_index_types, is_integer_index
label_desc: Use image node_id 5 for calling a global function with example usage: check_pdmultiindex_panel(obj, return_metadata, var_name, panel) and returns: _ret, _ret, _ret, _ret, _ret, _ret, _ret, _ret, _ret, _ret