class_docstr: Performs utility analysis for DP aggregations.
  
  This class reuses the computation graph from the DP computation code by
  subclassing from pipeline_dp.DPEngine and by replacing some nodes of the
  computational graph from DP computation to analysis.
class_docstr_tok: ["Performs","utility","analysis","for","DP","aggregations",".","This","class","reuses","the","computation","graph","from","the","DP","computation","code","by","subclassing","from","pipeline_dp.DPEngine","and","by","replacing","some","nodes","of","the","computational","graph","from","DP","computation","to","analysis","."]
code: def _create_compound_combiner(
      self, aggregate_params: pipeline_dp.AggregateParams
  ) -> combiners.CompoundCombiner:
      # Create Utility analysis combiners.
      internal_combiners = [
          per_partition_combiners.RawStatisticsCombiner()
      ]
      for params in data_structures.get_aggregate_params(self._options):
          # Each parameter configuration has own BudgetAccountant which allows
          # different mechanisms to be used in different configurations.
          budget_accountant = copy.deepcopy(self._budget_accountant)
  
          mechanism_type = None
          if params.noise_kind is None:
              # This is select partition case.
              assert not aggregate_params.metrics, (
                  f"Noise kind should be given when "
                  f"{aggregate_params.metrics[0]} is analyzed"
              )
          else:
              mechanism_type = (
                  params.noise_kind.convert_to_mechanism_type()
              )
          # WARNING: Do not change the order here,
          # _create_aggregate_error_compound_combiner() in utility_analysis.py
          # depends on it.
          if not self._is_public_partitions:
              internal_combiners.append(
                  per_partition_combiners.PartitionSelectionCombiner(
                      budget_accountant.request_budget(
                          pipeline_dp.MechanismType.GENERIC
                      ),
                      params,
                  )
              )
          if pipeline_dp.Metrics.SUM in aggregate_params.metrics:
              internal_combiners.append(
                  per_partition_combiners.SumCombiner(
                      budget_accountant.request_budget(mechanism_type),
                      params,
                  )
              )
          if pipeline_dp.Metrics.COUNT in aggregate_params.metrics:
              internal_combiners.append(
                  per_partition_combiners.CountCombiner(
                      budget_accountant.request_budget(mechanism_type),
                      params,
                  )
              )
          if (
              pipeline_dp.Metrics.PRIVACY_ID_COUNT
              in aggregate_params.metrics
          ):
              internal_combiners.append(
                  per_partition_combiners.PrivacyIdCountCombiner(
                      budget_accountant.request_budget(mechanism_type),
                      params,
                  )
              )
          budget_accountant.compute_budgets()
  
      return per_partition_combiners.CompoundCombiner(
          internal_combiners, return_named_tuple=False
      )
  
imports: import copy
  from typing import Optional, Union
  import pipeline_dp
  from pipeline_dp import budget_accounting
  from pipeline_dp import combiners
  from pipeline_dp import contribution_bounders
  from pipeline_dp import pipeline_backend
  import analysis
  import analysis.contribution_bounders
  from analysis import per_partition_combiners
  from analysis import data_structures
label_desc: Use image node_id 5 for calling the UtilityAnalysisEngine obj's underlying member method code with example usage: obj._create_compound_combiner(aggregate_params) and returns: per_partition_combiners