docs: def split_norm_shape(histosys, nominal_hist):
      """
      Split a HistoSys into normalization (OverallSys) and shape (HistoSys)
      components.
  
      It is recommended to use OverallSys as much as possible, which tries to
      enforce continuity up to the second derivative during
      interpolation/extrapolation. So, if there is indeed a shape variation, then
      factorize it into shape and normalization components.
      """
      up = histosys.GetHistoHigh()
      dn = histosys.GetHistoLow()
      up = up.Clone(name=up.name + '_shape')
      dn = dn.Clone(name=dn.name + '_shape')
      n_nominal = nominal_hist.integral(overflow=True)
      n_up = up.integral(overflow=True)
      n_dn = dn.integral(overflow=True)
      if n_up != 0:
          up.Scale(n_nominal / n_up)
      if n_dn != 0:
          dn.Scale(n_nominal / n_dn)
      shape = HistoSys(histosys.GetName(), low=dn, high=up)
      norm = OverallSys(histosys.GetName(),
                        low=n_dn / n_nominal if n_nominal != 0 else 1.,
                        high=n_up / n_nominal if n_nominal != 0 else 1.)
      return norm, shape