code: def computePerfOnCombinedForecasts(self, iForecast_DF):
      logger = tsutil.get_pyaf_logger()
  
      self.mEstimPerfs = {}
      self.mValidPerfs = {}
      lCombinationMethods = self.mOptions.mHierarchicalCombinationMethod
      if type(lCombinationMethods) is not list:
          lCombinationMethods = [lCombinationMethods]
      lPrefixes = [
          lPrefix
          for lPrefix in lCombinationMethods
          if (lPrefix != "TD")
      ]
      if "TD" in lCombinationMethods:
          lPrefixes = lPrefixes + ["AHP_TD", "PHA_TD"]
      lPerfs = {}
      lFrameFit = self.getEstimPart(iForecast_DF)
      lFrameValid = self.getValidPart(iForecast_DF)
      logger.info(
          "STRUCTURE " + str(sorted(list(self.mStructure.keys())))
      )
      logger.info("DATASET_COLUMNS " + str(iForecast_DF.columns))
      for level in sorted(self.mStructure.keys()):
          logger.info(
              "STRUCTURE_LEVEL "
              + str(
                  (level, sorted(list(self.mStructure[level].keys())))
              )
          )
          logger.info(
              "MODEL_LEVEL "
              + str((level, sorted(list(self.mModels[level].keys()))))
          )
          for signal in sorted(self.mStructure[level].keys()):
              lEngine = self.mModels[level][signal]
              lPerfFit = lEngine.computePerf(
                  lFrameFit[signal],
                  lFrameFit[str(signal) + "_Forecast"],
                  signal,
              )
              lPerfValid = lEngine.computePerf(
                  lFrameValid[signal],
                  lFrameValid[str(signal) + "_Forecast"],
                  signal,
              )
              self.mEstimPerfs[str(signal) + "_Forecast"] = lPerfFit
              self.mValidPerfs[str(signal) + "_Forecast"] = lPerfValid
              for iPrefix in lPrefixes:
                  lPerfFit_Combined = lEngine.computePerf(
                      lFrameFit[signal],
                      lFrameFit[
                          str(signal) + "_" + iPrefix + "_Forecast"
                      ],
                      signal,
                  )
                  lPerfValid_Combined = lEngine.computePerf(
                      lFrameValid[signal],
                      lFrameValid[
                          str(signal) + "_" + iPrefix + "_Forecast"
                      ],
                      signal,
                  )
                  lPerfs[str(signal) + "_" + iPrefix] = (
                      lPerfFit,
                      lPerfValid,
                      lPerfFit_Combined,
                      lPerfValid_Combined,
                  )
                  self.mEstimPerfs[
                      str(signal) + "_" + iPrefix + "_Forecast"
                  ] = lPerfFit_Combined
                  self.mValidPerfs[
                      str(signal) + "_" + iPrefix + "_Forecast"
                  ] = lPerfValid_Combined
  
      for sig, perf in sorted(lPerfs.items()):
          logger.info(
              "REPORT_COMBINED_FORECASTS_FIT_PERF "
              + str(
                  (
                      sig,
                      perf[0].mL2,
                      perf[0].mMAPE,
                      perf[2].mL2,
                      perf[2].mMAPE,
                  )
              )
          )
          logger.info(
              "REPORT_COMBINED_FORECASTS_VALID_PERF "
              + str(
                  (
                      sig,
                      perf[1].mL2,
                      perf[1].mMAPE,
                      perf[3].mL2,
                      perf[3].mMAPE,
                  )
              )
          )
      return lPerfs
  
imports: import pandas
  import numpy
  from ..None import ForecastEngine
  from .None import Options
  from .None import Perf
  from .None import Utils
  from .None import Plots
  import time
label_desc: Use image node_id 22 for calling the cSignalHierarchy obj's underlying member method code with example usage: obj.computePerfOnCombinedForecasts(iForecast_DF) and returns: lPerfs