Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 58 additions & 85 deletions roofit/roofitcore/src/RooAbsData.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1942,6 +1942,44 @@ RooPlot *RooAbsData::plotOn(RooPlot *frame, PlotOpt o) const
return frame;
}

namespace {

RooHist *createAndFillRooHist(RooAbsData const &absData, RooPlot const &frame, RooAbsRealLValue const &var,
std::string cuts1, std::string cuts2, RooAbsData::PlotOpt opt, bool efficiency,
double scaleFactor)
{
// create and fill temporary histograms of this variable for each state
std::string hist1Name = std::string{absData.GetName()} + "_plot_1";
std::string hist2Name = std::string{absData.GetName()} + "_plot_2";
std::unique_ptr<TH1> hist1;
std::unique_ptr<TH1> hist2;

if (opt.bins) {
hist1.reset(var.createHistogram(hist1Name.c_str(), "Events", *opt.bins));
hist2.reset(var.createHistogram(hist2Name.c_str(), "Events", *opt.bins));
} else {
auto &axis = *frame.GetXaxis();
hist1.reset(var.createHistogram(hist1Name.c_str(), "Events", axis.GetXmin(), axis.GetXmax(), frame.GetNbinsX()));
hist2.reset(var.createHistogram(hist2Name.c_str(), "Events", axis.GetXmin(), axis.GetXmax(), frame.GetNbinsX()));
}

if (opt.cuts && strlen(opt.cuts)) {
std::string cuts = opt.cuts;
cuts1 += "&&(" + cuts + ")";
cuts2 += "&&(" + cuts + ")";
}

if (!absData.fillHistogram(hist1.get(), RooArgList(var), cuts1.c_str(), opt.cutRange) ||
!absData.fillHistogram(hist2.get(), RooArgList(var), cuts2.c_str(), opt.cutRange)) {
return nullptr;
}

// convert this histogram to a RooHist object on the heap
return new RooHist(*hist1, *hist2, 0, 1, opt.etype, opt.xErrorSize, efficiency, scaleFactor);
}

} // namespace

////////////////////////////////////////////////////////////////////////////////
/// Create and fill a histogram with the asymmetry N[+] - N[-] / ( N[+] + N[-] ),
/// where N(+/-) is the number of data points with asymCat=+1 and asymCat=-1
Expand Down Expand Up @@ -1969,47 +2007,13 @@ RooPlot* RooAbsData::plotAsymOn(RooPlot* frame, const RooAbsCategoryLValue& asym
return nullptr;
}

// create and fill temporary histograms of this variable for each state
std::string hist1Name(GetName());
std::string hist2Name(GetName());
hist1Name += "_plot1";
std::unique_ptr<TH1> hist1;
std::unique_ptr<TH1> hist2;
hist2Name += "_plot2";

if (o.bins) {
hist1.reset( var->createHistogram(hist1Name.c_str(), "Events", *o.bins) );
hist2.reset( var->createHistogram(hist2Name.c_str(), "Events", *o.bins) );
} else {
hist1.reset( var->createHistogram(hist1Name.c_str(), "Events",
frame->GetXaxis()->GetXmin(), frame->GetXaxis()->GetXmax(),
frame->GetNbinsX()) );
hist2.reset( var->createHistogram(hist2Name.c_str(), "Events",
frame->GetXaxis()->GetXmin(), frame->GetXaxis()->GetXmax(),
frame->GetNbinsX()) );
}

assert(hist1 && hist2);

std::string cuts1;
std::string cuts2;
if (o.cuts && strlen(o.cuts)) {
cuts1 = Form("(%s)&&(%s>0)",o.cuts,asymCat.GetName());
cuts2 = Form("(%s)&&(%s<0)",o.cuts,asymCat.GetName());
} else {
cuts1 = Form("(%s>0)",asymCat.GetName());
cuts2 = Form("(%s<0)",asymCat.GetName());
}

if(! fillHistogram(hist1.get(), RooArgList(*var),cuts1.c_str(),o.cutRange) ||
! fillHistogram(hist2.get(), RooArgList(*var),cuts2.c_str(),o.cutRange)) {
coutE(Plotting) << ClassName() << "::" << GetName()
<< ":plotAsymOn: createHistogram() failed" << std::endl;
return nullptr;
std::string catName = asymCat.GetName();
RooHist *graph =
createAndFillRooHist(*this, *frame, *var, "(" + catName + ">0)", "(" + catName + "<0)", o, false, o.scaleFactor);
if (graph == nullptr) {
coutE(Plotting) << ClassName() << "::" << GetName() << ":plotAsymOn: createHistogram() failed" << std::endl;
return nullptr;
}

// convert this histogram to a RooHist object on the heap
RooHist *graph= new RooHist(*hist1,*hist2,0,1,o.etype,o.xErrorSize,false,o.scaleFactor);
graph->setYAxisLabel((std::string{"Asymmetry in "} + asymCat.GetName()).c_str());

// initialize the frame's normalization setup, if necessary
Expand Down Expand Up @@ -2063,48 +2067,16 @@ RooPlot* RooAbsData::plotEffOn(RooPlot* frame, const RooAbsCategoryLValue& effCa
return nullptr;
}

// create and fill temporary histograms of this variable for each state
std::string hist1Name(GetName());
std::string hist2Name(GetName());
hist1Name += "_plot1";
std::unique_ptr<TH1> hist1;
std::unique_ptr<TH1> hist2;
hist2Name += "_plot2";
std::string catName = effCat.GetName();
RooHist *graph =
createAndFillRooHist(*this, *frame, *var, "(" + catName + "==1)", "(" + catName + "==0)", o, true, 1.0);

if (o.bins) {
hist1.reset( var->createHistogram(hist1Name.c_str(), "Events", *o.bins) );
hist2.reset( var->createHistogram(hist2Name.c_str(), "Events", *o.bins) );
} else {
hist1.reset( var->createHistogram(hist1Name.c_str(), "Events",
frame->GetXaxis()->GetXmin(), frame->GetXaxis()->GetXmax(),
frame->GetNbinsX()) );
hist2.reset( var->createHistogram(hist2Name.c_str(), "Events",
frame->GetXaxis()->GetXmin(), frame->GetXaxis()->GetXmax(),
frame->GetNbinsX()) );
if (graph == nullptr) {
coutE(Plotting) << ClassName() << "::" << GetName() << ":plotEffOn: createHistogram() failed" << std::endl;
return nullptr;
}

assert(hist1 && hist2);

std::string cuts1;
std::string cuts2;
if (o.cuts && strlen(o.cuts)) {
cuts1 = Form("(%s)&&(%s==1)",o.cuts,effCat.GetName());
cuts2 = Form("(%s)&&(%s==0)",o.cuts,effCat.GetName());
} else {
cuts1 = Form("(%s==1)",effCat.GetName());
cuts2 = Form("(%s==0)",effCat.GetName());
}

if(! fillHistogram(hist1.get(), RooArgList(*var),cuts1.c_str(),o.cutRange) ||
! fillHistogram(hist2.get(), RooArgList(*var),cuts2.c_str(),o.cutRange)) {
coutE(Plotting) << ClassName() << "::" << GetName()
<< ":plotEffOn: createHistogram() failed" << std::endl;
return nullptr;
}

// convert this histogram to a RooHist object on the heap
RooHist *graph= new RooHist(*hist1,*hist2,0,1,o.etype,o.xErrorSize,true);
graph->setYAxisLabel(Form("Efficiency of %s=%s", effCat.GetName(), effCat.lookupName(1).c_str()));
graph->setYAxisLabel(("Efficiency of " + catName + "=" + effCat.lookupName(1)).c_str());

// initialize the frame's normalization setup, if necessary
frame->updateNormVars(_vars);
Expand All @@ -2113,12 +2085,12 @@ RooPlot* RooAbsData::plotEffOn(RooPlot* frame, const RooAbsCategoryLValue& effCa
if (o.histName) {
graph->SetName(o.histName) ;
} else {
std::string hname(Form("h_%s_Eff[%s]",GetName(),effCat.GetName())) ;
if (o.cutRange && strlen(o.cutRange)>0) {
hname += Form("_CutRange[%s]",o.cutRange);
std::string hname = "h_" + std::string{GetName()} + "_Eff[" + catName + "]";
if (o.cutRange && strlen(o.cutRange) > 0) {
hname += "_CutRange[" + std::string{o.cutRange} + " ]";
}
if (o.cuts && strlen(o.cuts)>0) {
hname += Form("_Cut[%s]",o.cuts);
hname += "_Cut[" + std::string{o.cuts} + " ]";
}
graph->SetName(hname.c_str()) ;
}
Expand Down Expand Up @@ -2614,11 +2586,12 @@ TH2F *RooAbsData::createHistogram(const RooAbsRealLValue &var1, const RooAbsReal
}
}

const std::string histName = std::string{GetName()} + "_" + name + "_" + Form("%08x", counter++);
std::stringstream histName;
histName << GetName() << "_" << name << "_" << std::setw(8) << std::setfill('0') << std::hex << counter++;

// create the histogram
auto *histogram =
new TH2F(histName.c_str(), "Events", nx, var1.getMin(), var1.getMax(), ny, var2.getMin(), var2.getMax());
new TH2F(histName.str().c_str(), "Events", nx, var1.getMin(), var1.getMax(), ny, var2.getMin(), var2.getMax());
if (!histogram) {
coutE(DataHandling) << GetName() << "::createHistogram: unable to create a new histogram" << std::endl;
return nullptr;
Expand Down
17 changes: 9 additions & 8 deletions roofit/roofitcore/src/RooAbsReal.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ RooFit::OwningPtr<RooAbsReal> RooAbsReal::createIntObj(const RooArgSet& iset2, c
if (!cacheParams.empty()) {
cxcoutD(Caching) << "RooAbsReal::createIntObj(" << GetName() << ") INFO: constructing " << cacheParams.size()
<< "-dim value cache for integral over " << iset2 << " as a function of " << cacheParams << " in range " << (rangeName?rangeName:"<none>") << std::endl ;
std::string name = Form("%s_CACHE_[%s]",integral->GetName(),cacheParams.contentsString().c_str()) ;
std::string name = std::string{integral->GetName()} + "_CACHE_[" + cacheParams.contentsString() + "]";
auto cachedIntegral = std::make_unique<RooCachedReal>(name.c_str(),name.c_str(),*integral,cacheParams);
cachedIntegral->setInterpolationOrder(2) ;
cachedIntegral->addOwnedComponents(std::move(integral));
Expand Down Expand Up @@ -1943,9 +1943,9 @@ RooPlot* RooAbsReal::plotOn(RooPlot *frame, PlotOpt o) const

// Inform user about projections
if (!projectedVars.empty()) {
coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") plot on " << plotVar->GetName()
<< " integrates over variables " << projectedVars
<< (o.projectionRangeName?Form(" in range %s",o.projectionRangeName):"") << std::endl;
coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") plot on " << plotVar->GetName()
<< " integrates over variables " << projectedVars
<< (o.projectionRangeName ? (" in range " + std::string{o.projectionRangeName}) : "") << std::endl;
}
if (projDataNeededVars && !projDataNeededVars->empty()) {
coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") plot on " << plotVar->GetName()
Expand Down Expand Up @@ -2387,15 +2387,16 @@ RooPlot* RooAbsReal::plotAsymOn(RooPlot *frame, const RooAbsCategoryLValue& asym


// Set default name of curve
TString curveName(funcAsym.GetName()) ;
std::stringstream curveName;
curveName << funcAsym.GetName();
if (!sliceSet.empty()) {
curveName.Append(Form("_Slice[%s]",sliceSet.contentsString().c_str())) ;
curveName << "_Slice[" << sliceSet.contentsString() << "]";
}
if (o.curveNameSuffix) {
// Append any suffixes imported from RooAbsPdf::plotOn
curveName.Append(o.curveNameSuffix) ;
curveName << o.curveNameSuffix;
}
curve->SetName(curveName.Data()) ;
curve->SetName(curveName.str().c_str());

// add this new curve to the specified plot frame
frame->addPlotable(curve, o.drawOptions);
Expand Down
54 changes: 33 additions & 21 deletions roofit/roofitcore/src/RooMinimizer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,6 @@ void RooMinimizer::determineStatus(bool fitterReturnValue)
/// \param[in] alg Fit algorithm to use. (Optional)
int RooMinimizer::minimize(const char *type, const char *alg)
{
FreezeDisconnectedParametersRAII freeze(this, *_fcn);

if (_cfg.timingAnalysis) {
#ifdef ROOFIT_MULTIPROCESS
Expand Down Expand Up @@ -778,6 +777,7 @@ void RooMinimizer::profileStop()

ROOT::Math::IMultiGenFunction *RooMinimizer::getMultiGenFcn() const
{

return _fcn->getMultiGenFcn();
}

Expand Down Expand Up @@ -908,19 +908,19 @@ bool RooMinimizer::fitFCN(const ROOT::Math::IMultiGenFunction &fcn)
{
// fit a user provided FCN function
// create fit parameter settings

// Check number of parameters
unsigned int npar = fcn.NDim();
if (npar == 0) {
coutE(Minimization) << "RooMinimizer::fitFCN(): FCN function has zero parameters" << std::endl;
return false;
}

// initiate the minimizer
// initiate the minimizer
initMinimizer();

// Identify floating RooCategory parameters
RooArgSet floatingCats;

for (auto arg : _fcn->allParams()) {
if (arg->isCategory() && !arg->isConstant())
floatingCats.add(*arg);
Expand All @@ -942,7 +942,8 @@ bool RooMinimizer::fitFCN(const ROOT::Math::IMultiGenFunction &fcn)
}

if (nPdfs == 0) {

coutI(Minimization) << "[fitFCN] No discrete parameters, performing continuous minimization only" << std::endl;
FreezeDisconnectedParametersRAII freeze(this, *_fcn);
bool isValid = _minimizer->Minimize();
if (!_result)
_result = std::make_unique<FitResult>();
Expand All @@ -953,8 +954,7 @@ bool RooMinimizer::fitFCN(const ROOT::Math::IMultiGenFunction &fcn)
}

// set also new parameter values and errors in FitConfig

// Prepare discrete indices
// Prepare discrete indices
std::vector<int> maxIndices;
for (auto *cat : pdfIndices)
maxIndices.push_back(cat->size());
Expand All @@ -963,11 +963,10 @@ bool RooMinimizer::fitFCN(const ROOT::Math::IMultiGenFunction &fcn)
std::map<std::vector<int>, double> nllMap;
std::vector<int> bestIndices(nPdfs, 0);
double bestNLL = 1e30;
bool improved = true;

bool improved = true;
while (improved) {
improved = false;

auto combos = generateOrthogonalCombinations(maxIndices);
reorderCombinations(combos, maxIndices, bestIndices);

Expand All @@ -984,7 +983,7 @@ bool RooMinimizer::fitFCN(const ROOT::Math::IMultiGenFunction &fcn)
wasConst[i] = pdfIndices[i]->isConstant();
pdfIndices[i]->setConstant(true);
}

FreezeDisconnectedParametersRAII freeze(this, *_fcn);
_minimizer->Minimize();

for (size_t i = 0; i < nPdfs; ++i)
Expand All @@ -1002,36 +1001,49 @@ bool RooMinimizer::fitFCN(const ROOT::Math::IMultiGenFunction &fcn)
}
}

for (size_t i = 0; i < nPdfs; ++i)
for (size_t i = 0; i < nPdfs; ++i) {
pdfIndices[i]->setIndex(bestIndices[i]);
pdfIndices[i]->setConstant(true);
}

FreezeDisconnectedParametersRAII freeze(this, *_fcn);
_minimizer->Minimize();

coutI(Minimization) << "All NLL Values per Combination:\n" << std::endl;
coutI(Minimization) << "All NLL Values per Combination:" << std::endl;
for (const auto &entry : nllMap) {
const auto &combo = entry.first;
double val = entry.second;
coutI(Minimization) << "Combo: [" << std::endl;
for (size_t i = 0; i < combo.size(); ++i)
std::cout << combo[i] << (i + 1 < combo.size() ? ", " : "");
coutI(Minimization) << "], NLL: " << val << "\n" << std::endl;

std::stringstream ss;
ss << "Combo: [";
for (size_t i = 0; i < combo.size(); ++i) {
ss << combo[i];
if (i + 1 < combo.size())
ss << ", ";
}
ss << "], NLL: " << val;

coutI(Minimization) << ss.str() << std::endl;
}

coutI(Minimization) << "DP Best Indices: [" << std::endl;
std::stringstream ssBest;
ssBest << "DP Best Indices: [";
for (size_t i = 0; i < bestIndices.size(); ++i) {
coutI(Minimization) << bestIndices[i] << std::endl;
ssBest << bestIndices[i];
if (i + 1 < bestIndices.size())
coutI(Minimization) << ", " << std::endl;
ssBest << ", ";
}
coutI(Minimization) << "], NLL = " << bestNLL << "\n" << std::endl;
ssBest << "], NLL = " << bestNLL;

coutI(Minimization) << ssBest.str() << std::endl;

// Fill FitResult and update FitConfig
if (!_result)
_result = std::make_unique<FitResult>();
fillResult(true);
updateFitConfig();

return true;
}

bool RooMinimizer::calculateHessErrors()
{
// compute the Hesse errors according to configuration
Expand Down
10 changes: 5 additions & 5 deletions roofit/roofitcore/src/RooProdPdf.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1059,14 +1059,14 @@ void RooProdPdf::rearrangeProduct(RooProdPdf::CacheElem& cache) const

RooAddition* tmpadd = static_cast<RooAddition*>(parg) ;

RooCustomizer cust(*tmpadd->list1().first(),Form("blah_%s",iter->c_str())) ;
RooCustomizer cust(*tmpadd->list1().first(), ("blah_" + *iter).c_str());
cust.replaceArg(*ratio,*specializedRatio) ;
partCust = cust.build() ;

} else {
RooCustomizer cust(*parg,Form("blah_%s",iter->c_str())) ;
cust.replaceArg(*ratio,*specializedRatio) ;
partCust = cust.build() ;
RooCustomizer cust(*parg, ("blah_" + *iter).c_str());
cust.replaceArg(*ratio, *specializedRatio);
partCust = cust.build();
}

// Print customized denominator
Expand Down Expand Up @@ -1139,7 +1139,7 @@ void RooProdPdf::rearrangeProduct(RooProdPdf::CacheElem& cache) const
return ;
}

string name = Form("%s_numerator",GetName()) ;
string name = std::string{GetName()} + "_numerator";
// WVE FIX THIS (2)

std::unique_ptr<RooAbsReal> numerator = std::make_unique<RooProduct>(name.c_str(),name.c_str(),nomList) ;
Expand Down
Loading
Loading