How to modify RooHistFunc to perform interpolation

Let’s say I have a HistFactory-based signal model (let’s say the one produced via prepareHistFactory), and I’d like to edit the produced workspace to replace my signal histogram with an interpolation of N different histograms. This interpolation would depend on the parameter of interest (signal strength), i.e. from a parameter on which no constraints are applied.

Do you have any suggestions on how to do that?
Naively I would use combined->factory("EDIT::simPdf(simPdf, signal_channel1_Hist_alphanominal=mynewclassinstance)"), where mynewclassinstance would be an instance of a new class I have to write, inheriting from RooHistFunc, which implements this interpolation/extrapolation. Is this a good idea? Or there are other elements which may be re-used for the purpose?

(I think they are not, as PiecewiseInterpolation works with the assumption that the “pivots” of the interpolation consists of the up and down 1sigma histograms, and that the parameter is 0 when the histogram is identical to the nominal one.)

Hi @rene!

signal histogram with an interpolation of N different histograms

What kind of interpolation do you you mean? Can you explain mathematically what you want to achieve? Right now I can only guess. Do you mean some kind of horizontal morphing, i.e. you add your histograms with some coefficients in front where the coefficients add up to one?

In that case, you can create one RooHistFunc for each histogram, and then add them with the RooRealSumPdf.

Sorry in advance if I guessed wrong, feel free to clarify what you mean by the interpolation and then I can follow up!

Cheers,
Jonas

Hi @jonas,

what I mean is that the content of each bin i should be expressed as something like

y(i) = ( f(x(i, 1), x(i, 2), x(i, 3)) ... x(i, N) ; mu)

where x(i, j) is the content of the i-th bin of the j-th histogram of the set of N histograms we want to interpolate from, and f performs piecewise interpolation or some other interpolation strategy, governed by parameter mu. Note that by construction y(i) represents a bin content (as the original RooHistFunc used by HistFactory).

The logic behind the interpolation is that we want mu (signal cross-section modifier) to act as (pseudo-code)

def f(i, mu, x):
  ''' example of a linear interpolation
      in this pseudo-code, x[i, j].content is the content of
      the i-jth bin of the j-th histogram, and x[i, j].mu is
      the value of mu this j-th histogram corresponds to
  '''
  if mu < x[i, 0].mu:
    x0, y0, x1, y1 = 0, 0, x[i, 0].mu, x[i, 0].content
  elif mu > x[-2].mu:
    x0, y0, x1, y1 = x[i, -2].mu, x[i, -2].content, x[i, -1].mu, x[i, -1].content
  elif mu > x[-3].mu:
    x0, y0, x1, y1 = x[i, -3].mu, x[i, -3].content, x[i, -2].mu, x[i, -2].content
  elif # etc...

  return (y1 - y0) / (x1 - x0) * (x - x0) + y0

In other words, both the shape and normalization of the histogram (and not only the latter) should change as a function of mu, in a way which depends on some interpolation of N>2 input hitsograms.