code: def _unpack_frame(fit, columns, valid_cols, save_warmup, dtypes):
      """Transform fit to dictionary containing ndarrays.
  
      Called when fit object created by cmdstanpy version < 0.9.68
  
      Parameters
      ----------
      data: cmdstanpy.CmdStanMCMC
      columns: list
      valid_cols: list
      save_warmup: bool
      dtypes: dict
  
      Returns
      -------
      dict
          key, values pairs. Values are formatted to shape = (chains, draws, *shape)
      """
      if (
          save_warmup and not fit._save_warmup
      ):  # pylint: disable=protected-access
          save_warmup = False
      if hasattr(fit, "draws"):
          data = fit.draws(inc_warmup=save_warmup)
          if save_warmup:
              num_warmup = (
                  fit._draws_warmup
              )  # pylint: disable=protected-access
              data_warmup = data[:num_warmup]
              data = data[num_warmup:]
      else:
          data = fit.sample
          if save_warmup:
              data_warmup = fit.warmup[: data.shape[0]]
  
      draws, chains, *_ = data.shape
      if save_warmup:
          draws_warmup, *_ = data_warmup.shape
  
      column_groups = defaultdict(list)
      column_locs = defaultdict(list)
      # iterate flat column names
      for i, col in enumerate(columns):
          if "." in col:
              # parse parameter names e.g. X.1.2 --> X, (1,2)
              col_base, *col_tail = col.split(".")
          else:
              # parse parameter names e.g. X[1,2] --> X, (1,2)
              col_base, *col_tail = (
                  col.replace("]", "").replace("[", ",").split(",")
              )
          if len(col_tail):
              # gather nD array locations
              column_groups[col_base].append(tuple(map(int, col_tail)))
          # gather raw data locations for each parameter
          column_locs[col_base].append(i)
      # gather parameter dimensions (assumes dense arrays)
      dims = {
          colname: tuple(np.array(col_dims).max(0))
          for colname, col_dims in column_groups.items()
      }
      sample = {}
      sample_warmup = {}
      valid_base_cols = []
      # get list of parameters for extraction (basename) X.1.2 --> X
      for col in valid_cols:
          base_col = col.split("[")[0].split(".")[0]
          if base_col not in valid_base_cols:
              valid_base_cols.append(base_col)
  
      # extract each wanted parameter to ndarray with correct shape
      for key in valid_base_cols:
          ndim = dims.get(key, None)
          shape_location = column_groups.get(key, None)
          if ndim is not None:
              sample[key] = np.full((chains, draws, *ndim), np.nan)
              if save_warmup:
                  sample_warmup[key] = np.full(
                      (chains, draws_warmup, *ndim), np.nan
                  )
          if shape_location is None:
              # reorder draw, chain -> chain, draw
              (i,) = column_locs[key]
              sample[key] = np.swapaxes(data[..., i], 0, 1)
              if save_warmup:
                  sample_warmup[key] = np.swapaxes(
                      data_warmup[..., i], 0, 1
                  )
          else:
              for i, shape_loc in zip(column_locs[key], shape_location):
                  # location to insert extracted array
                  shape_loc = tuple(
                      [Ellipsis] + [j - 1 for j in shape_loc]
                  )
                  # reorder draw, chain -> chain, draw and insert to ndarray
                  sample[key][shape_loc] = np.swapaxes(
                      data[..., i], 0, 1
                  )
                  if save_warmup:
                      sample_warmup[key][shape_loc] = np.swapaxes(
                          data_warmup[..., i], 0, 1
                      )
  
      for key, dtype in dtypes.items():
          if key in sample:
              sample[key] = sample[key].astype(dtype)
              if save_warmup and key in sample_warmup:
                  sample_warmup[key] = sample_warmup[key].astype(dtype)
      return sample, sample_warmup
  
imports: import logging
  import re
  from collections import defaultdict
  from copy import deepcopy
  from pathlib import Path
  import numpy
  from ..rcparams import rcParams
  from .base import dict_to_dataset, infer_stan_dtypes, make_attrs, requires
  from .inference_data import InferenceData
label_desc: Use image node_id 7 for calling a global function with example usage: _unpack_frame(fit, columns, valid_cols, save_warmup, dtypes) and returns: sample,  sample_warmup