-
Notifications
You must be signed in to change notification settings - Fork 393
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
These are the remaining developments from the RooFit ICHEP 2024 AD branch.
- Loading branch information
1 parent
6980f6f
commit 58b6ea4
Showing
9 changed files
with
310 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#ifndef HiggsAnalysis_CombinedLimit_CombineCodegenImpl_h | ||
#define HiggsAnalysis_CombinedLimit_CombineCodegenImpl_h | ||
|
||
#include <ROOT/RConfig.hxx> // for ROOT_VERSION | ||
|
||
#if ROOT_VERSION_CODE >= ROOT_VERSION(6,35,0) | ||
# define COMBINE_DECLARE_CODEGEN_IMPL(CLASS_NAME) \ | ||
namespace RooFit { namespace Experimental { void codegenImpl(CLASS_NAME &arg, CodegenContext &ctx); }} | ||
# define COMBINE_DECLARE_TRANSLATE | ||
#elif ROOT_VERSION_CODE >= ROOT_VERSION(6,32,0) | ||
# define COMBINE_DECLARE_CODEGEN_IMPL(CLASS_NAME) | ||
# define COMBINE_DECLARE_TRANSLATE void translate(RooFit::Detail::CodeSquashContext &ctx) const override; | ||
#else | ||
# define COMBINE_DECLARE_CODEGEN_IMPL | ||
# define COMBINE_DECLARE_TRANSLATE | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import numpy as np | ||
import ROOT | ||
import argparse | ||
|
||
parser = argparse.ArgumentParser() | ||
parser.add_argument("--input", "-i", help="input ws file") | ||
parser.add_argument("--backend", help='set evaluation backend, default is "combine"') | ||
|
||
args = parser.parse_args() | ||
|
||
with ROOT.TFile.Open(args.input) as f: | ||
ws = f.Get("w") | ||
|
||
global_observables = ws.set("globalObservables") | ||
constrain = ws.set("nuisances") | ||
|
||
pdf = ws["model_s"] | ||
data = ws["data_obs"] | ||
|
||
# To use the evaluation backends of RooFit | ||
ROOT.gInterpreter.Declare("#include <HiggsAnalysis/CombinedLimit/interface/Combine.h>") | ||
|
||
ROOT.Combine.nllBackend_ = args.backend | ||
|
||
# Change verbosity | ||
ROOT.RooMsgService.instance().getStream(1).removeTopic(ROOT.RooFit.Minimization) | ||
ROOT.RooMsgService.instance().getStream(1).removeTopic(ROOT.RooFit.Fitting) | ||
|
||
ROOT.gInterpreter.Declare("#include <HiggsAnalysis/CombinedLimit/interface/CombineMathFuncs.h>") | ||
|
||
nll = pdf.createNLL(data, Constrain=constrain, GlobalObservables=global_observables, Offset="initial") | ||
|
||
cfg = ROOT.RooMinimizer.Config() | ||
minim = ROOT.RooMinimizer(nll, cfg) | ||
minim.setEps(1.0) | ||
minim.setStrategy(0) | ||
minim.minimize("Minuit2", "") | ||
minim.save().Print() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
#include "../interface/CombineCodegenImpl.h" | ||
|
||
#if ROOT_VERSION_CODE >= ROOT_VERSION(6,32,0) | ||
|
||
#include "../interface/AsymPow.h" | ||
#include "../interface/ProcessNormalization.h" | ||
#include "../interface/VerticalInterpHistPdf.h" | ||
|
||
#include <RooUniformBinning.h> | ||
|
||
#if ROOT_VERSION_CODE >= ROOT_VERSION(6,35,0) | ||
namespace RooFit { | ||
namespace Experimental { | ||
# define CODEGEN_IMPL(CLASS_NAME) void codegenImpl(CLASS_NAME &arg0, CodegenContext &ctx) | ||
# define ARG_VAR auto &arg = arg0; | ||
#else | ||
# define CODEGEN_IMPL(CLASS_NAME) void CLASS_NAME::translate(RooFit::Detail::CodeSquashContext &ctx) const | ||
# define ARG_VAR auto &arg = *this; | ||
#endif | ||
|
||
|
||
CODEGEN_IMPL(AsymPow) { | ||
ARG_VAR; | ||
ctx.addResult(&arg, | ||
ctx.buildCall("RooFit::Detail::MathFuncs::asymPow", arg.theta(), arg.kappaLow(), arg.kappaHigh())); | ||
} | ||
|
||
CODEGEN_IMPL(ProcessNormalization) { | ||
ARG_VAR; | ||
|
||
std::vector<double> logAsymmKappaLow; | ||
std::vector<double> logAsymmKappaHigh; | ||
logAsymmKappaLow.reserve(arg.logAsymmKappa().size()); | ||
logAsymmKappaHigh.reserve(arg.logAsymmKappa().size()); | ||
for (auto [lo, hi] : arg.logAsymmKappa()) { | ||
logAsymmKappaLow.push_back(lo); | ||
logAsymmKappaHigh.push_back(hi); | ||
} | ||
|
||
ctx.addResult(&arg, | ||
ctx.buildCall("RooFit::Detail::MathFuncs::processNormalization", | ||
arg.nominalValue(), | ||
arg.thetaList().size(), | ||
arg.asymmThetaList().size(), | ||
arg.otherFactorList().size(), | ||
arg.thetaList(), | ||
arg.logKappa(), | ||
arg.asymmThetaList(), | ||
logAsymmKappaLow, | ||
logAsymmKappaHigh, | ||
arg.otherFactorList())); | ||
} | ||
|
||
CODEGEN_IMPL(FastVerticalInterpHistPdf2) { | ||
ARG_VAR; | ||
|
||
if (arg.smoothAlgo() < 0) { | ||
throw std::runtime_error("We only support smoothAlgo >= 0"); | ||
} | ||
|
||
RooRealVar const &xVar = arg.x(); | ||
|
||
int numBins = xVar.numBins(); | ||
|
||
std::vector<double> nominalVec(numBins); | ||
std::vector<double> widthVec(numBins); | ||
std::vector<double> morphsVecSum; | ||
std::vector<double> morphsVecDiff; | ||
|
||
auto const &cacheNominal = arg.cacheNominal(); | ||
|
||
for (int i = 0; i < numBins; ++i) { | ||
nominalVec[i] = cacheNominal.GetBinContent(i); | ||
widthVec[i] = cacheNominal.GetWidth(i); | ||
} | ||
|
||
std::size_t nCoefs = arg.coefList().size(); | ||
|
||
morphsVecSum.reserve(numBins * nCoefs); | ||
morphsVecDiff.reserve(numBins * nCoefs); | ||
auto const &morphs = arg.morphs(); | ||
for (unsigned int j = 0; j < nCoefs; ++j) { | ||
for (int i = 0; i < numBins; ++i) { | ||
morphsVecSum.push_back(morphs[j].sum[i]); | ||
morphsVecDiff.push_back(morphs[j].diff[i]); | ||
} | ||
} | ||
|
||
for (int i = 0; i < numBins; ++i) { | ||
nominalVec[i] = cacheNominal.GetBinContent(i); | ||
} | ||
|
||
// The bin index part | ||
// We also have to assert that x is uniformely binned! | ||
if (!dynamic_cast<RooUniformBinning const *>(&xVar.getBinning())) { | ||
throw std::runtime_error("We only support uniform binning!"); | ||
} | ||
double xLow = xVar.getMin(); | ||
double xHigh = xVar.getMax(); | ||
std::string binIdx = ctx.buildCall("RooFit::Detail::MathFuncs::getUniformBinning", xLow, xHigh, xVar, numBins); | ||
|
||
std::string arrName = ctx.getTmpVarName(); | ||
|
||
std::stringstream code; | ||
code << "double " << arrName << "[" << numBins << "];\n"; | ||
code << ctx.buildCall("RooFit::Detail::MathFuncs::fastVerticalInterpHistPdf2", | ||
numBins, | ||
nCoefs, | ||
arg.coefList(), | ||
nominalVec, | ||
widthVec, | ||
morphsVecSum, | ||
morphsVecDiff, | ||
arg.smoothRegion(), | ||
arrName) + | ||
";\n"; | ||
|
||
ctx.addToCodeBody(code.str(), true); | ||
ctx.addResult(&arg, arrName + "[" + binIdx + "]"); | ||
} | ||
|
||
CODEGEN_IMPL(FastVerticalInterpHistPdf2D2) { | ||
ARG_VAR; | ||
|
||
if (arg.smoothAlgo() < 0) { | ||
throw std::runtime_error("We only support smoothAlgo >= 0"); | ||
} | ||
|
||
if (!arg.conditional()) { | ||
throw std::runtime_error("We only support conditional == true"); | ||
} | ||
|
||
RooRealVar const &xVar = arg.x(); | ||
RooRealVar const &yVar = arg.y(); | ||
|
||
// We also have to assert that x and y are uniformely binned! | ||
if (!dynamic_cast<RooUniformBinning const *>(&xVar.getBinning())) { | ||
throw std::runtime_error("We only support uniform binning!"); | ||
} | ||
if (!dynamic_cast<RooUniformBinning const *>(&yVar.getBinning())) { | ||
throw std::runtime_error("We only support uniform binning!"); | ||
} | ||
|
||
auto const &cacheNominal = arg.cacheNominal(); | ||
|
||
int numBinsX = cacheNominal.binX(); | ||
int numBinsY = cacheNominal.binY(); | ||
int numBins = numBinsY * numBinsY; | ||
|
||
std::vector<double> nominalVec(numBins); | ||
std::vector<double> widthVec(numBins); | ||
std::vector<double> morphsVecSum; | ||
std::vector<double> morphsVecDiff; | ||
|
||
for (int i = 0; i < numBins; ++i) { | ||
nominalVec[i] = cacheNominal.GetBinContent(i); | ||
widthVec[i] = cacheNominal.GetWidth(i); | ||
} | ||
|
||
std::size_t nCoefs = arg.coefList().size(); | ||
|
||
morphsVecSum.reserve(numBins * nCoefs); | ||
morphsVecDiff.reserve(numBins * nCoefs); | ||
auto const &morphs = arg.morphs(); | ||
for (unsigned int j = 0; j < nCoefs; ++j) { | ||
for (int i = 0; i < numBins; ++i) { | ||
morphsVecSum.push_back(morphs[j].sum[i]); | ||
morphsVecDiff.push_back(morphs[j].diff[i]); | ||
} | ||
} | ||
|
||
for (int i = 0; i < numBins; ++i) { | ||
nominalVec[i] = cacheNominal.GetBinContent(i); | ||
} | ||
|
||
// The bin index part | ||
double xLow = xVar.getMin(); | ||
double xHigh = xVar.getMax(); | ||
std::string binIdxX = ctx.buildCall("RooFit::Detail::MathFuncs::getUniformBinning", xLow, xHigh, arg.x(), numBinsX); | ||
double yLow = yVar.getMin(); | ||
double yHigh = yVar.getMax(); | ||
std::string binIdxY = ctx.buildCall("RooFit::Detail::MathFuncs::getUniformBinning", yLow, yHigh, arg.y(), numBinsY); | ||
|
||
std::stringstream binIdx; | ||
binIdx << "(" << binIdxY << " + " << yVar.numBins() << " * " << binIdxX << ")"; | ||
|
||
std::string arrName = ctx.getTmpVarName(); | ||
|
||
std::stringstream code; | ||
code << "double " << arrName << "[" << (numBinsX * numBinsY) << "];\n"; | ||
code << ctx.buildCall("RooFit::Detail::MathFuncs::fastVerticalInterpHistPdf2D2", | ||
numBinsX, | ||
numBinsY, | ||
nCoefs, | ||
arg.coefList(), | ||
nominalVec, | ||
widthVec, | ||
morphsVecSum, | ||
morphsVecDiff, | ||
arg.smoothRegion(), | ||
arrName) + | ||
";\n"; | ||
|
||
ctx.addToCodeBody(code.str(), true); | ||
ctx.addResult(&arg, arrName + "[" + binIdx.str() + "]"); | ||
} | ||
|
||
#if ROOT_VERSION_CODE >= ROOT_VERSION(6,35,0) | ||
} // namespace RooFit | ||
} // namespace Experimental | ||
#endif | ||
|
||
#endif // ROOT_VERSION_CODE >= ROOT_VERSION(6,32,0) |
Oops, something went wrong.