code: def compute_hist(
      self,
      ctx: Context,
      nodes: List[Node],
      bin_train_data: DataFrame,
      gh: DataFrame,
      sample_pos: DataFrame = None,
      node_map={},
      pk=None,
      evaluator=None,
      gh_pack=False,
  ):
      node_num = len(nodes)
      is_first_layer = self._is_first_layer(nodes)
      need_hist_sub_process = (not is_first_layer) and self._hist_sub
  
      weak_nodes, new_node_map, mapping = None, None, None
      if need_hist_sub_process:
          weak_nodes, new_node_map, mapping = self._prepare_hist_sub(
              nodes, node_map, self._last_layer_node_map
          )
          node_num = len(weak_nodes)
          logger.debug(
              "weak nodes {}, new_node_map {}, mapping {}".format(
                  weak_nodes, new_node_map, mapping
              )
          )
  
      if ctx.is_on_guest:
          schema = self._get_plain_text_schema(gh.dtypes)
      elif ctx.is_on_host:
          if pk is None or evaluator is None:
              schema = self._get_plain_text_schema(gh.dtypes)
          else:
              if gh_pack:
                  schema = self._get_pack_en_hist_schema(
                      pk, evaluator, gh.dtypes
                  )
              else:
                  schema = self._get_enc_hist_schema(
                      pk, evaluator, gh.dtypes
                  )
      else:
          raise ValueError(
              "not support called on role: {}".format(ctx.local)
          )
  
      if need_hist_sub_process:
          node_mapping = {
              node_map[k]: v for k, v in new_node_map.items()
          }
      else:
          node_mapping = None
  
      hist = HistogramBuilder(
          num_node=node_num,
          feature_bin_sizes=self.feat_bin_num,
          value_schemas=schema,
          global_seed=self.global_random_seed,
          seed=self.random_seed,
          node_mapping=node_mapping,
      )
  
      # if goss is enabled
      if len(sample_pos) > len(gh):
          sample_pos = sample_pos.loc(
              gh.get_indexer(target="sample_id"), preserve_order=True
          )
          map_sample_pos = sample_pos.apply_row(
              lambda x: node_map[x["node_idx"]]
          )
          bin_train_data = bin_train_data.loc(
              gh.get_indexer(target="sample_id"), preserve_order=True
          )
      else:
          map_sample_pos = sample_pos.apply_row(
              lambda x: node_map[x["node_idx"]]
          )
  
      stat_obj = bin_train_data.distributed_hist_stat(
          hist, map_sample_pos, gh
      )
  
      if need_hist_sub_process:
          stat_obj = self._cache_parent_hist.compute_child(
              stat_obj, mapping
          )
  
      if self._hist_sub:
          self._cache_parent_hist = stat_obj
          self._last_layer_node_map = node_map
  
      stat_obj = stat_obj.shuffle_splits()
  
      return hist, stat_obj
  
imports: import typing
  import torch
  from typing import Dict
  from fate.arch.histogram import HistogramBuilder, DistributedHistogram
  from fate.ml.ensemble.learner.decision_tree.tree_core.decision_tree import Node
  from typing import List
  import numpy
  from fate.arch.dataframe import DataFrame
  from fate.arch import Context
  import logging
label_desc: Use image node_id 8 for calling the SBTHistogramBuilder obj's underlying member method code with example usage: obj.compute_hist(ctx, nodes, bin_train_data, gh, sample_pos, node_map, pk, evaluator, gh_pack) and returns: hist,  stat_obj