Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
xRooNLLVar.cxx
Go to the documentation of this file.
1/*
2 * Project: xRooFit
3 * Author:
4 * Will Buttinger, RAL 2022
5 *
6 * Copyright (c) 2022, CERN
7 *
8 * Redistribution and use in source and binary forms,
9 * with or without modification, are permitted according to the terms
10 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)
11 */
12
13#include "RVersion.h"
14
15#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
16#define protected public
17#endif
18#include "RooFitResult.h"
19#include "RooNLLVar.h"
20#ifdef protected
21#undef protected
22#endif
23
24#include "xRooFit/xRooFit.h"
25
26#include "RooCmdArg.h"
27#include "RooAbsPdf.h"
28#include "RooAbsData.h"
29
30#include "RooConstraintSum.h"
31#include "RooSimultaneous.h"
33#include "TPRegexp.h"
34#include "TEfficiency.h"
35
36#include "RooRealVar.h"
37#include "Math/ProbFunc.h"
38#include "RooRandom.h"
39
40#include "TPad.h"
41#include "TSystem.h"
42
43#include "coutCapture.h"
44
45#include <chrono>
46
47#include "Math/GenAlgoOptions.h"
48
49#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
50#define private public
51#define GETWS(a) a->_myws
52#define GETWSSETS(w) w->_namedSets
53#else
54#define GETWS(a) a->workspace()
55#define GETWSSETS(w) w->sets()
56#endif
57#include "RooWorkspace.h"
58#ifdef private
59#undef private
60#endif
61
62#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
63#define protected public
64#endif
66#ifdef protected
67#undef protected
68#endif
69
70#include "TMultiGraph.h"
71#include "TCanvas.h"
72#include "TArrow.h"
73#include "RooStringVar.h"
74#include "TDirectory.h"
75#include "TStyle.h"
76#include "TH1D.h"
77#include "TLegend.h"
78
79
81
82std::set<int> xRooNLLVar::xRooHypoPoint::allowedStatusCodes = {0};
83
84xRooNLLVar::~xRooNLLVar() {}
85
86xRooNLLVar::xRooNLLVar(RooAbsPdf &pdf, const std::pair<RooAbsData *, const RooAbsCollection *> &data,
87 const RooLinkedList &nllOpts)
88 : xRooNLLVar(std::shared_ptr<RooAbsPdf>(&pdf, [](RooAbsPdf *) {}),
89 std::make_pair(std::shared_ptr<RooAbsData>(data.first, [](RooAbsData *) {}),
90 std::shared_ptr<const RooAbsCollection>(data.second, [](const RooAbsCollection *) {})),
91 nllOpts)
92{
93}
94
95xRooNLLVar::xRooNLLVar(const std::shared_ptr<RooAbsPdf> &pdf,
96 const std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>> &data,
97 const RooLinkedList &opts)
98 : fPdf(pdf), fData(data.first), fGlobs(data.second)
99{
100
102
103 fOpts = std::shared_ptr<RooLinkedList>(new RooLinkedList, [](RooLinkedList *l) {
104 if (l)
105 l->Delete();
106 delete l;
107 });
108 fOpts->SetName("");
109
110 for (int i = 0; i < opts.GetSize(); i++) {
111 if (strlen(opts.At(i)->GetName()) == 0)
112 continue; // skipping "none" cmds
113 if (strcmp(opts.At(i)->GetName(), "GlobalObservables") == 0) {
114 // will skip here to add with the obs from the function below
115 // must match global observables
116 auto gl = dynamic_cast<RooCmdArg *>(opts.At(i))->getSet(0);
117 if (!fGlobs || !fGlobs->equals(*gl)) {
118 throw std::runtime_error("GlobalObservables mismatch");
119 }
120 } else {
121 if (strcmp(opts.At(i)->GetName(), "Optimize") == 0) {
122 // this flag will trigger constOptimizeTestStatistic to be called on the nll in createNLL method
123 // we should ensure that the fitconfig setting is consistent with it ...
124 fitConfigOptions()->SetValue("OptimizeConst", dynamic_cast<RooCmdArg *>(opts.At(i))->getInt(0));
125 }
126 fOpts->Add(opts.At(i)->Clone(nullptr)); // nullptr needed because accessing Clone via TObject base class puts
127 // "" instead, so doesnt copy names
128 }
129 }
130 if (fGlobs) {
131 // add global observables opt with function obs
132 auto _vars = std::unique_ptr<RooArgSet>(fPdf->getVariables());
133 auto _funcGlobs = std::unique_ptr<RooArgSet>(dynamic_cast<RooArgSet *>(_vars->selectCommon(*fGlobs)));
134 fOpts->Add(RooFit::GlobalObservables(*_funcGlobs).Clone());
135 }
136
137 if (auto flag = dynamic_cast<RooCmdArg *>(fOpts->find("ReuseNLL"))) {
138 kReuseNLL = flag->getInt(0);
139 }
140
141 // if fit range specified, and pdf is a RooSimultaneous, may need to 'reduce' the model if some of the pdfs are in
142 // range and others are not
143 if (auto range = dynamic_cast<RooCmdArg *>(fOpts->find("RangeWithName"))) {
144 TString rangeName = range->getString(0);
145
146 // reduce the data here for convenience, not really necessary because will happen inside RooNLLVar but still
147 // fData.reset( fData->reduce(RooFit::SelectVars(*fData->get()),RooFit::CutRange(rangeName)) );
148
149 if (auto s = dynamic_cast<RooSimultaneous *>(fPdf.get()); s) {
150 auto &_cat = const_cast<RooAbsCategoryLValue &>(s->indexCat());
151 std::vector<TString> chanPatterns;
152 TStringToken pattern(rangeName, ",");
153 bool hasRange(false);
154 std::string noneCatRanges;
155 while (pattern.NextToken()) {
156 chanPatterns.emplace_back(pattern);
157 if (_cat.hasRange(chanPatterns.back()))
158 hasRange = true;
159 else {
160 if (!noneCatRanges.empty())
161 noneCatRanges += ",";
162 noneCatRanges += chanPatterns.back();
163 }
164 }
165 if (hasRange) {
166 // must remove the ranges that referred to selections on channel category
167 // otherwise RooFit will incorrectly evaluate the NLL (it creates a partition for each range given in the
168 // list, which all end up being equal) the NLL would become scaled by the number of ranges given
169 if (noneCatRanges.empty()) {
170 fOpts->Remove(range);
171 SafeDelete(range);
172 } else {
173 range->setString(0, noneCatRanges.c_str());
174 }
175 // must reduce because category var has one of the ranges
176 auto newPdf =
177 std::make_shared<RooSimultaneous>(TString::Format("%s_reduced", s->GetName()), "Reduced model", _cat);
178 for (auto &c : _cat) {
179 auto _pdf = s->getPdf(c.first.c_str());
180 if (!_pdf)
181 continue;
182 _cat.setIndex(c.second);
183 bool matchAny = false;
184 for (auto &p : chanPatterns) {
185 if (_cat.hasRange(p) && _cat.inRange(p)) {
186 matchAny = true;
187 break;
188 }
189 }
190 if (matchAny) {
191 newPdf->addPdf(*_pdf, c.first.c_str());
192 }
193 }
194 fPdf = newPdf;
195 }
196 }
197 }
198
199 // if (fGlobs) {
200 // // must check GlobalObservables is in the list
201 // }
202 //
203 // if (auto globs = dynamic_cast<RooCmdArg*>(fOpts->find("GlobalObservables"))) {
204 // // first remove any obs the pdf doesnt depend on
205 // auto _vars = std::unique_ptr<RooAbsCollection>( fPdf->getVariables() );
206 // auto _funcGlobs = std::unique_ptr<RooAbsCollection>(_vars->selectCommon(*globs->getSet(0)));
207 // fGlobs.reset( std::unique_ptr<RooAbsCollection>(globs->getSet(0)->selectCommon(*_funcGlobs))->snapshot() );
208 // globs->setSet(0,dynamic_cast<const RooArgSet&>(*_funcGlobs)); // globs in linked list has its own argset
209 // but args need to live as long as the func
210 // /*RooArgSet toRemove;
211 // for(auto a : *globs->getSet(0)) {
212 // if (!_vars->find(*a)) toRemove.add(*a);
213 // }
214 // const_cast<RooArgSet*>(globs->getSet(0))->remove(toRemove);
215 // fGlobs.reset( globs->getSet(0)->snapshot() );
216 // fGlobs->setAttribAll("Constant",true);
217 // const_cast<RooArgSet*>(globs->getSet(0))->replace(*fGlobs);*/
218 // }
219};
220
221xRooNLLVar::xRooNLLVar(const std::shared_ptr<RooAbsPdf> &pdf, const std::shared_ptr<RooAbsData> &data,
222 const RooLinkedList &opts)
223 : xRooNLLVar(
224 pdf,
225 std::make_pair(data, std::shared_ptr<const RooAbsCollection>(
226 (opts.find("GlobalObservables"))
227 ? dynamic_cast<RooCmdArg *>(opts.find("GlobalObservables"))->getSet(0)->snapshot()
228 : nullptr)),
229 opts)
230{
231}
232
234{
235 std::cout << "PDF: ";
236 if (fPdf)
237 fPdf->Print();
238 else
239 std::cout << "<null>" << std::endl;
240 std::cout << "Data: ";
241 if (fData)
242 fData->Print();
243 else
244 std::cout << "<null>" << std::endl;
245 std::cout << "NLL Options: " << std::endl;
246 for (int i = 0; i < fOpts->GetSize(); i++) {
247 auto c = dynamic_cast<RooCmdArg *>(fOpts->At(i));
248 if (!c)
249 continue;
250 std::cout << " " << c->GetName() << " : ";
251 if (c->getString(0))
252 std::cout << c->getString(0);
253 else if (c->getSet(0) && !c->getSet(0)->empty())
254 std::cout << (c->getSet(0)->contentsString());
255 else
256 std::cout << c->getInt(0);
257 std::cout << std::endl;
258 }
259 if (fFitConfig) {
260 std::cout << "Fit Config: " << std::endl;
261 std::cout << " UseParabErrors: " << (fFitConfig->ParabErrors() ? "True" : "False")
262 << " [toggles HESSE algorithm]" << std::endl;
263 std::cout << " MinimizerOptions: " << std::endl;
264 fFitConfig->MinimizerOptions().Print();
265 }
266 std::cout << "Last Rebuild Log Output: " << fFuncCreationLog << std::endl;
267}
268
270{
271 TString oldName = "";
272 if (std::shared_ptr<RooAbsReal>::get())
273 oldName = std::shared_ptr<RooAbsReal>::get()->GetName();
274 if (fPdf) {
276 // need to find all RooRealSumPdf nodes and mark them binned or unbinned as required
277 RooArgSet s;
278 fPdf->treeNodeServerList(&s, nullptr, true, false);
279 bool isBinned = false;
280 bool hasBinned = false; // if no binned option then 'auto bin' ...
281 if (auto a = dynamic_cast<RooCmdArg *>(fOpts->find("Binned")); a) {
282 hasBinned = true;
283 isBinned = a->getInt(0);
284 }
285 std::map<RooAbsArg *, bool> origValues;
286 if (hasBinned) {
287 for (auto a : s) {
288 if (a->InheritsFrom("RooRealSumPdf")) {
289 // since RooNLLVar will assume binBoundaries available (not null), we should check bin boundaries
290 // available
291 bool setBinned = false;
292 if (isBinned) {
293 std::unique_ptr<RooArgSet> obs(a->getObservables(fData->get()));
294 if (obs->size() == 1) { // RooNLLVar requires exactly 1 obs
295 auto *var = static_cast<RooRealVar *>(obs->first());
296 std::unique_ptr<std::list<Double_t>> boundaries{dynamic_cast<RooAbsReal *>(a)->binBoundaries(
297 *var, -std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity())};
298 if (boundaries) {
299 if (!std::shared_ptr<RooAbsReal>::get())
300 Info("xRooNLLVar", "%s will be evaluated as a Binned PDF (%d bins)", a->GetName(),
301 int(boundaries->size() - 1));
302 setBinned = true;
303 }
304 }
305 }
306 origValues[a] = a->getAttribute("BinnedLikelihood");
307 a->setAttribute("BinnedLikelihood", setBinned);
308 }
309 }
310 }
311 // before creating, clear away caches if any if pdf is in ws
312 if (GETWS(fPdf)) {
313 std::set<std::string> setNames;
314 for (auto &a : GETWSSETS(GETWS(fPdf))) {
315 if (TString(a.first.c_str()).BeginsWith("CACHE_")) {
316 setNames.insert(a.first);
317 }
318 }
319 for (auto &a : setNames) {
320 GETWS(fPdf)->removeSet(a.c_str());
321 }
322 }
323 std::set<std::string> attribs;
324 if (std::shared_ptr<RooAbsReal>::get())
325 attribs = std::shared_ptr<RooAbsReal>::get()->attributes();
326 this->reset(std::unique_ptr<RooAbsReal>{fPdf->createNLL(*fData, *fOpts)}.release());
327 // RooFit only swaps in what it calls parameters, this misses out the RooConstVars which we treat as pars as well
328 // so swap those in ... question: is recursiveRedirectServers usage in RooAbsOptTestStatic (and here) a memory
329 // leak?? where do the replaced servers get deleted??
330
331 for (auto &a : attribs)
332 std::shared_ptr<RooAbsReal>::get()->setAttribute(a.c_str());
333 // create parent on next line to avoid triggering workspace initialization code in constructor of xRooNode
334 if (GETWS(fPdf)) {
335 xRooNode(*GETWS(fPdf), std::make_shared<xRooNode>()).sterilize();
336 } // there seems to be a nasty bug somewhere that can make the cache become invalid, so clear it here
337 if (oldName != "")
338 std::shared_ptr<RooAbsReal>::get()->SetName(oldName);
339 if (!origValues.empty()) {
340 // need to evaluate NOW so that slaves are created while the BinnedLikelihood settings are in place
341 std::shared_ptr<RooAbsReal>::get()->getVal();
342 for (auto &[o, v] : origValues)
343 o->setAttribute("BinnedLikelihood", v);
344 }
345 }
346
347 fFuncVars = std::unique_ptr<RooArgSet>{std::shared_ptr<RooAbsReal>::get()->getVariables()};
348 if (fGlobs) {
349 fFuncGlobs.reset(fFuncVars->selectCommon(*fGlobs));
350 fFuncGlobs->setAttribAll("Constant", true);
351 }
352 fConstVars.reset(fFuncVars->selectByAttrib("Constant", true)); // will check if any of these have floated
353}
354
355std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>>
356xRooNLLVar::generate(bool expected, int seed)
357{
358 if (!fPdf)
359 return std::pair(nullptr, nullptr);
360 auto fr = std::make_shared<RooFitResult>(TUUID().AsString());
361 fr->setFinalParList(RooArgList());
363 l.add((fFuncVars) ? *fFuncVars : *std::unique_ptr<RooAbsCollection>(fPdf->getParameters(*fData)));
364 fr->setConstParList(l);
365 const_cast<RooArgList&>(fr->constPars()).setAttribAll("global", false);
366 if (fGlobs)
367 std::unique_ptr<RooAbsCollection>(fr->constPars().selectCommon(*fGlobs))->setAttribAll("global", true);
368 return xRooFit::generateFrom(*fPdf, fr, expected, seed);
369}
370
371xRooNLLVar::xRooFitResult::xRooFitResult(const std::shared_ptr<xRooNode> &in)
372 : std::shared_ptr<const RooFitResult>(std::dynamic_pointer_cast<const RooFitResult>(in->fComp)), fNode(in)
373{
374}
376{
377 return fNode->get<RooFitResult>();
378}
379// xRooNLLVar::xRooFitResult::operator std::shared_ptr<const RooFitResult>() const { return
380// std::dynamic_pointer_cast<const RooFitResult>(fNode->fComp); }
381xRooNLLVar::xRooFitResult::operator const RooFitResult *() const
382{
383 return fNode->get<const RooFitResult>();
384}
386{
387 fNode->Draw(opt);
388}
389
390xRooNLLVar::xRooFitResult xRooNLLVar::minimize(const std::shared_ptr<ROOT::Fit::FitConfig> &_config)
391{
392 auto &nll = *get();
393 auto out = xRooFit::minimize(nll, (_config) ? _config : fitConfig());
394 // add any pars that are const here that aren't in constPars list because they may have been
395 // const-optimized and their values cached with the dataset, so if subsequently floated the
396 // nll wont evaluate correctly
397 // fConstVars.reset( fFuncVars->selectByAttrib("Constant",true) );
398
399 // if saving fits, check the nllOpts have been saved as well ...
400
401 if (out && !nll.getAttribute("readOnly")) {
402 if (strlen(fOpts->GetName()) == 0)
403 fOpts->SetName(TUUID().AsString());
404 auto cacheDir = gDirectory;
405 if (cacheDir && cacheDir->IsWritable()) {
406 // save a copy of fit result to relevant dir
407 if (!cacheDir->GetDirectory(nll.GetName()))
408 cacheDir->mkdir(nll.GetName());
409 if (auto dir = cacheDir->GetDirectory(nll.GetName()); dir) {
410 if (!dir->FindKey(fOpts->GetName())) {
411 dir->WriteObject(fOpts.get(), fOpts->GetName());
412 }
413 }
414 }
415 }
416
417 // before returning, flag which of the constPars were actually global observables
418 if (out) {
419 const_cast<RooArgList&>(out->constPars()).setAttribAll("global", false);
420 if (fGlobs)
421 std::unique_ptr<RooAbsCollection>(out->constPars().selectCommon(*fGlobs))->setAttribAll("global", true);
422 }
423 return xRooFitResult(std::make_shared<xRooNode>(out, fPdf));
424}
425
427public:
428 AutoRestorer(const RooAbsCollection &s, xRooNLLVar *nll = nullptr) : fSnap(s.snapshot()), fNll(nll)
429 {
430 fPars.add(s);
431 if (fNll) {
432 // if (!fNll->kReuseNLL) fOldNll = *fNll;
433 fOldData = fNll->getData();
434 fOldName = fNll->get()->GetName();
435 fOldTitle = fNll->get()->getStringAttribute("fitresultTitle");
436 }
437 }
439 {
440 ((RooAbsCollection &)fPars) = *fSnap;
441 if (fNll) {
442 // commented out code was attempt to speed up things avoid unnecessarily reinitializing things over and over
443 // if (!fNll->kReuseNLL) {
444 // // can be faster just by putting back in old nll
445 // fNll->std::shared_ptr<RooAbsReal>::operator=(fOldNll);
446 // fNll->fData = fOldData.first;
447 // fNll->fGlobs = fOldData.second;
448 // } else {
449 // fNll->setData(fOldData);
450 // fNll->get()->SetName(fOldName);
451 // fNll->get()->setStringAttribute("fitresultTitle", (fOldTitle == "") ? nullptr : fOldTitle);
452 // }
453 fNll->setData(fOldData);
454 fNll->get()->SetName(fOldName);
455 fNll->get()->setStringAttribute("fitresultTitle", (fOldTitle == "") ? nullptr : fOldTitle);
456 }
457 }
459 std::unique_ptr<RooAbsCollection> fSnap;
460 xRooNLLVar *fNll = nullptr;
461 // std::shared_ptr<RooAbsReal> fOldNll;
462 std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>> fOldData;
463 TString fOldName, fOldTitle;
464};
465
466std::shared_ptr<ROOT::Fit::FitConfig> xRooNLLVar::fitConfig()
467{
468 if (!fFitConfig)
470 return fFitConfig;
471}
472
474{
475 if (auto conf = fitConfig(); conf)
476 return const_cast<ROOT::Math::IOptions *>(conf->MinimizerOptions().ExtraOptions());
477 return nullptr;
478}
479
480double xRooNLLVar::getEntryVal(size_t entry)
481{
482 auto _data = data();
483 if (!_data)
484 return 0;
485 if (size_t(_data->numEntries()) <= entry)
486 return 0;
487 auto _pdf = pdf();
488 *std::unique_ptr<RooAbsCollection>(_pdf->getObservables(_data)) = *_data->get(entry);
489 // if (auto s = dynamic_cast<RooSimultaneous*>(_pdf.get());s) return
490 // -_data->weight()*s->getPdf(s->indexCat().getLabel())->getLogVal(_data->get());
491 return -_data->weight() * _pdf->getLogVal(_data->get());
492}
493
494std::shared_ptr<RooArgSet> xRooNLLVar::pars(bool stripGlobalObs)
495{
496 auto out = std::shared_ptr<RooArgSet>(get()->getVariables());
497 if (stripGlobalObs && fGlobs) {
498 out->remove(*fGlobs, true, true);
499 }
500 return out;
501}
502
504{
505 TString sOpt(opt);
506
507 auto _pars = pars();
508
509 if (sOpt == "sensitivity") {
510
511 // will make a plot of DeltaNLL
512 }
513
514 if (sOpt == "floating") {
515 // start scanning floating pars
516 auto floats = std::unique_ptr<RooAbsCollection>(_pars->selectByAttrib("Constant", false));
517 TVirtualPad *pad = gPad;
518 if (!pad) {
520 pad = gPad;
521 }
523 gr->SetName("multigraph");
524 gr->SetTitle(TString::Format("%s;Normalized Parameter Value;#Delta NLL", get()->GetTitle()));
525 /*((TPad*)pad)->DivideSquare(floats->size());
526 int i=0;
527 for(auto a : *floats) {
528 i++;
529 pad->cd(i);
530 Draw(a->GetName());
531 }*/
532 return;
533 }
534
535 RooArgList vars;
536 TStringToken pattern(sOpt, ":");
537 while (pattern.NextToken()) {
538 TString s(pattern);
539 if (auto a = _pars->find(s); a)
540 vars.add(*a);
541 }
542
543 if (vars.size() == 1) {
544 TGraph *out = new TGraph;
545 out->SetBit(kCanDelete);
546 TGraph *bad = new TGraph;
547 bad->SetBit(kCanDelete);
548 bad->SetMarkerColor(kRed);
549 bad->SetMarkerStyle(5);
550 TMultiGraph *gr = (gPad) ? dynamic_cast<TMultiGraph *>(gPad->GetPrimitive("multigraph")) : nullptr;
551 bool normRange = false;
552 if (!gr) {
553 gr = new TMultiGraph;
554 gr->Add(out, "LP");
556 } else {
557 normRange = true;
558 }
559 out->SetName(get()->GetName());
560 gr->SetTitle(TString::Format("%s;%s;#Delta NLL", get()->GetTitle(), vars.at(0)->GetTitle()));
561 // scan outwards from current value towards limits
562 auto v = dynamic_cast<RooRealVar *>(vars.at(0));
563 double low = v->getVal();
564 double high = low;
565 double step = (v->getMax() - v->getMin()) / 100;
566 double init = v->getVal();
567 double initVal = func()->getVal();
568 // double xscale = (normRange) ? (2.*(v->getMax() - v->getMin())) : 1.;
569 auto currTime = std::chrono::steady_clock::now();
570 while (out->GetN() < 100 && (low > v->getMin() || high < v->getMax())) {
571 if (out->GetN() == 0) {
572 out->SetPoint(out->GetN(), low, 0);
573 low -= step;
574 high += step;
575 if (!normRange) {
576 gr->Draw("A");
577 gPad->SetGrid();
578 }
579 continue;
580 }
581 if (low > v->getMin()) {
582 v->setVal(low);
583 auto _v = func()->getVal();
584 if (std::isnan(_v) || std::isinf(_v)) {
585 if (bad->GetN() == 0)
586 gr->Add(bad, "P");
587 bad->SetPoint(bad->GetN(), low, out->GetPointY(0));
588 } else {
589 out->SetPoint(out->GetN(), low, _v - initVal);
590 }
591 low -= step;
592 }
593 if (high < v->getMax()) {
594 v->setVal(high);
595 auto _v = func()->getVal();
596 if (std::isnan(_v) || std::isinf(_v)) {
597 if (bad->GetN() == 0)
598 gr->Add(bad, "P");
599 bad->SetPoint(bad->GetN(), high, out->GetPointY(0));
600 } else {
601 out->SetPoint(out->GetN(), high, _v - initVal);
602 }
603 high += step;
604 }
605 out->Sort();
606 // should only do processEvents once every second in case using x11 (which is slow)
607 gPad->Modified();
608 if (std::chrono::steady_clock::now() - currTime > std::chrono::seconds(1)) {
609 currTime = std::chrono::steady_clock::now();
610 gPad->Update();
612 }
613 }
614 // add arrow to show current par value
615 TArrow a;
616 a.DrawArrow(init, 0, init, -0.1);
617 gPad->Update();
619 v->setVal(init);
620 } else {
621 Error("Draw", "Name a parameter to scan over: Draw(<name>) , choose from: %s",
622 _pars->empty() ? "" : _pars->contentsString().c_str());
623 }
624}
625
626std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>> xRooNLLVar::getData() const
627{
628 return std::make_pair(fData, fGlobs);
629}
630
632{
633 if (data.fComp && !data.get<RooAbsData>()) {
634 return false;
635 }
636 return setData(std::dynamic_pointer_cast<RooAbsData>(data.fComp),
637 std::shared_ptr<const RooAbsCollection>(data.globs().argList().snapshot()));
638}
639
640Bool_t xRooNLLVar::setData(const std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>> &_data)
641{
642
643 if (fData == _data.first && fGlobs == _data.second)
644 return true;
645
646 auto _globs = fGlobs; // done to keep globs alive while NLL might still be alive.
647
648 if (fGlobs && !(fGlobs->empty() && !_data.second) &&
649 _data.first) { // second condition allows for no globs being a nullptr, third allow globs to remain if nullifying
650 // data
651 if (!_data.second)
652 throw std::runtime_error("Missing globs");
653 // ignore 'extra' globs
654 RooArgSet s;
655 s.add(*fGlobs);
656 std::unique_ptr<RooAbsCollection> _actualGlobs(fPdf->getObservables(s));
657 RooArgSet s2;
658 s2.add(*_data.second);
659 std::unique_ptr<RooAbsCollection> _actualGlobs2(fPdf->getObservables(s2));
660 if (!_actualGlobs->equals(*_actualGlobs2)) {
661 RooArgSet rC;
662 rC.add(*_actualGlobs2);
663 rC.remove(*std::unique_ptr<RooAbsCollection>(rC.selectCommon(*_actualGlobs)));
664 TString r = (!rC.empty()) ? rC.contentsString() : "";
665 RooArgSet lC;
666 lC.add(*_actualGlobs);
667 lC.remove(*std::unique_ptr<RooAbsCollection>(lC.selectCommon(*_actualGlobs2)));
668 TString l = (!lC.empty()) ? lC.contentsString() : "";
669 throw std::runtime_error(TString::Format("globs mismatch: adding %s removing %s", r.Data(), l.Data()));
670 }
671 fGlobs = _data.second;
672 }
673
674 if (!std::shared_ptr<RooAbsReal>::get()) {
675 fData = _data.first;
676 return true; // not loaded yet so nothing to do
677 }
678
679 try {
680 if (!kReuseNLL || nllTerm()->operMode() == RooAbsTestStatistic::MPMaster) {
681 throw std::runtime_error("not supported");
682 }
683 bool out = false;
684 if (_data.first)
685 out = nllTerm()->setData(*_data.first, false /* clone data? */);
686 else
687 reset();
688 fData = _data.first;
689 return out;
690 } catch (std::runtime_error &) {
691 // happens when using MP need to rebuild the nll instead
692 AutoRestorer snap(*fFuncVars);
693 // ensure the const state is back where it was at nll construction time;
694 fFuncVars->setAttribAll("Constant", false);
695 fConstVars->setAttribAll("Constant", true);
696 std::shared_ptr<RooAbsData> __data = fData; // do this just to keep fData alive while killing previous NLLVar
697 // (can't kill data while NLL constructed with it)
698 fData = _data.first;
699 reinitialize();
700 return true;
701 }
702 throw std::runtime_error("Unable to setData");
703}
704
705std::shared_ptr<RooAbsReal> xRooNLLVar::func() const
706{
707 if (!(*this)) {
708 const_cast<xRooNLLVar *>(this)->reinitialize();
709 } else if (auto f = std::unique_ptr<RooAbsCollection>(fConstVars->selectByAttrib("Constant", false)); !f->empty()) {
710 // have to reinitialize if const par values have changed - const optimization forces this
711 // TODO: currently changes to globs also triggers this since the vars includes globs (vars are the non-obs pars)
712 // std::cout << "Reinitializing because of change of const parameters:" << f->contentsString() << std::endl;
713 const_cast<xRooNLLVar *>(this)->reinitialize();
714
715 // note ... it may be sufficient here to do:
716 // nll.constOptimizeTestStatistic(RooAbsArg::ConfigChange, constOptimize>1 /* do tracking too if >1 */); //
717 // trigger a re-evaluate of which nodes to cache-and-track nll.constOptimizeTestStatistic(RooAbsArg::ValueChange,
718 // constOptimize>1); // update the cache values -- is this needed??
719 // this forces the optimization to be redone
720 // for now leave as a reinitialize though, until had a chance to test this properly
721 }
722 if (fGlobs && fFuncGlobs) {
723 *fFuncGlobs = *fGlobs;
724 fFuncGlobs->setAttribAll("Constant", true);
725 }
726 return *this;
727}
728
730{
731 fOpts->Add(opt.Clone(nullptr));
732 if (std::shared_ptr<RooAbsReal>::get())
733 reinitialize(); // do this way to keep name of nll if user set
734 else
735 reset(); // will trigger reinitialize
736}
737
739{
740 auto _nll = nllTerm();
741 if (!_nll)
742 return fData.get();
743 RooAbsData *out = &_nll->data();
744 if (!out)
745 return fData.get();
746 return out;
747}
748
750{
751 auto _func = func();
752 if (auto a = dynamic_cast<RooNLLVar *>(_func.get()); a)
753 return a;
754 for (auto s : _func->servers()) {
755 if (auto a = dynamic_cast<RooNLLVar *>(s); a)
756 return a;
757 }
758 return nullptr;
759}
760
762{
763 // returns Nexp - Nobs*log(Nexp)
764 return fPdf->extendedTerm(fData->sumEntries(), fData->get());
765}
766
768{
769 if (auto s = dynamic_cast<RooSimultaneous *>(fPdf.get()); s) {
770 return fData->sumEntries() * log(1.0 * (s->servers().size() - 1)); // one of the servers is the cat
771 }
772 return 0;
773}
774
776{
777 // this is only relevant if BinnedLikelihood active
778 double out = 0;
779 for (int i = 0; i < fData->numEntries(); i++) {
780 fData->get(i);
781 out += TMath::LnGamma(fData->weight() + 1);
782 }
783 return out;
784}
785
787{
788 auto _func = func();
789 if (auto a = dynamic_cast<RooConstraintSum *>(_func.get()); a)
790 return a;
791 for (auto s : _func->servers()) {
792 if (auto a = dynamic_cast<RooConstraintSum *>(s); a)
793 return a;
794 }
795 return nullptr;
796}
797
798/*xRooNLLVar::operator RooAbsReal &() const {
799 // this works in c++ but not in python
800 std::cout << "implicit conversion" << std::endl;
801 return *fFunc;
802}*/
803
804std::pair<double, double> xRooNLLVar::xRooHypoPoint::getVal(const char *what)
805{
806 TString sWhat(what);
807 sWhat.ToLower();
808 bool doTS = sWhat.Contains("ts");
809 bool doCLs = sWhat.Contains("cls");
810 bool doNull = sWhat.Contains("null");
811 bool doAlt = sWhat.Contains("alt");
812 double nSigma = (sWhat.Contains("exp"))
813 ? (TString(sWhat(sWhat.Index("exp") + 3, sWhat.Index(" ", sWhat.Index("exp")) == -1
814 ? sWhat.Length()
815 : sWhat.Index(" ", sWhat.Index("exp"))))
816 .Atof())
817 : std::numeric_limits<double>::quiet_NaN();
818
819 bool toys = sWhat.Contains("toys");
820 // bool asymp = sWhat.Contains("asymp");
821
822 bool readOnly = sWhat.Contains("readonly");
823
824 struct RestoreNll {
825 RestoreNll(std::shared_ptr<xRooNLLVar> &v, bool r) : rr(r), var(v)
826 {
827 if (rr && var && var->get()) {
828 _readOnly = var->get()->getAttribute("readOnly");
829 var->get()->setAttribute("readOnly", rr);
830 } else {
831 rr = false;
832 }
833 };
834 ~RestoreNll()
835 {
836 if (rr)
837 var->get()->setAttribute("readOnly", _readOnly);
838 };
839
840 bool rr = false;
841 bool _readOnly = false;
842
843 std::shared_ptr<xRooNLLVar> &var;
844 };
845
846 RestoreNll rest(nllVar, readOnly);
847
848 if (doTS)
849 return (toys) ? ts_toys(nSigma) : ts_asymp(nSigma);
850 if (doNull)
851 return (toys) ? pNull_toys(nSigma) : pNull_asymp(nSigma);
852 if (doAlt)
853 return (toys) ? pAlt_toys(nSigma) : pAlt_asymp(nSigma);
854 if (doCLs)
855 return (toys) ? pCLs_toys(nSigma) : pCLs_asymp(nSigma);
856
857 throw std::runtime_error(std::string("Unknown: ") + what);
858}
859
861{
862 RooArgList out;
863 out.setName("poi");
864 out.add(*std::unique_ptr<RooAbsCollection>(coords->selectByAttrib("poi", true)));
865 return out;
866}
867
869{
870 RooArgList out;
871 out.setName("alt_poi");
872 out.addClone(*std::unique_ptr<RooAbsCollection>(coords->selectByAttrib("poi", true)));
873 for (auto a : out) {
874 auto v = dynamic_cast<RooAbsRealLValue *>(a);
875 if (!v)
876 continue;
877 if (auto s = a->getStringAttribute("altVal"); s && strlen(s)) {
878 v->setVal(TString(s).Atof());
879 } else {
880 v->setVal(std::numeric_limits<double>::quiet_NaN());
881 }
882 }
883 return out;
884}
885
887{
888 auto &me = const_cast<xRooHypoPoint &>(*this);
889 int out = 0;
890 if (me.ufit(true) && !allowedStatusCodes.count(me.ufit(true)->status()))
891 out += 1;
892 if (me.cfit_null(true) && !allowedStatusCodes.count(me.cfit_null(true)->status()))
893 out += 1 << 1;
894 if (me.cfit_alt(true) && !allowedStatusCodes.count(me.cfit_alt(true)->status()))
895 out += 1 << 2;
896 if (me.asimov(true))
897 out += me.asimov(true)->status() << 3;
898 return out;
899}
900
902{
903 std::cout << "POI: " << poi().contentsString() << " , null: " << dynamic_cast<RooAbsReal *>(poi().first())->getVal()
904 << " , alt: " << dynamic_cast<RooAbsReal *>(alt_poi().first())->getVal();
905 std::cout << " , pllType: " << fPllType << std::endl;
906
907 std::cout << " - ufit: ";
908 if (fUfit) {
909 std::cout << fUfit->minNll() << " (status=" << fUfit->status() << ") (" << mu_hat().GetName()
910 << "_hat: " << mu_hat().getVal() << " +/- " << mu_hat().getError() << ")" << std::endl;
911 } else {
912 std::cout << "Not calculated" << std::endl;
913 }
914 std::cout << " - null cfit: ";
915 if (fNull_cfit) {
916 std::cout << fNull_cfit->GetName() << " " << fNull_cfit->minNll() << " (status=" << fNull_cfit->status() << ")";
917 } else {
918 std::cout << "Not calculated";
919 }
920 if (!std::isnan(dynamic_cast<RooAbsReal *>(alt_poi().first())->getVal())) {
921 std::cout << std::endl << " - alt cfit: ";
922 if (fAlt_cfit) {
923 std::cout << fAlt_cfit->GetName() << " " << fAlt_cfit->minNll() << " (status=" << fAlt_cfit->status() << ")"
924 << std::endl;
925 } else {
926 std::cout << "Not calculated" << std::endl;
927 }
928 std::cout << " sigma_mu: ";
929 if (!fAsimov || !fAsimov->fUfit || !fAsimov->fNull_cfit) {
930 std::cout << "Not calculated";
931 } else {
932 std::cout << sigma_mu().first << " +/- " << sigma_mu().second;
933 }
934 if (fAsimov) {
935 std::cout << std::endl;
936 std::cout << " - asimov ufit: ";
937 if (fAsimov->fUfit)
938 std::cout << fAsimov->fUfit->GetName() << " " << fAsimov->fUfit->minNll()
939 << " (status=" << fAsimov->fUfit->status() << ")";
940 else
941 std::cout << "Not calculated";
942 std::cout << std::endl << " - asimov null cfit: ";
943 if (fAsimov->fNull_cfit)
944 std::cout << fAsimov->fNull_cfit->GetName() << " " << fAsimov->fNull_cfit->minNll()
945 << " (status=" << fAsimov->fNull_cfit->status() << ")";
946 else
947 std::cout << "Not calculated";
948 }
949 std::cout << std::endl;
950 } else {
951 std::cout << std::endl;
952 }
953 if (fGenFit)
954 std::cout << " - genFit: " << fGenFit->GetName() << std::endl;
955 if (!nullToys.empty() || !altToys.empty()) {
956 std::cout << " * null toys: " << nullToys.size();
957 size_t firstToy = 0;
958 while (firstToy < nullToys.size() && std::isnan(std::get<1>(nullToys[firstToy])))
959 firstToy++;
960 if (firstToy > 0)
961 std::cout << " [ of which " << firstToy << " are bad]";
962 std::cout << " , alt toys: " << altToys.size();
963 firstToy = 0;
964 while (firstToy < altToys.size() && std::isnan(std::get<1>(altToys[firstToy])))
965 firstToy++;
966 if (firstToy > 0)
967 std::cout << " [ of which " << firstToy << " are bad]";
968 std::cout << std::endl;
969 }
970 // std::cout << " nllVar: " << nllVar << std::endl;
971}
972
974{
975 if (ufit()) {
976 auto var = dynamic_cast<RooRealVar *>(ufit()->floatParsFinal().find(fPOIName()));
977 if (var)
978 return *var;
979 else
980 throw std::runtime_error("Cannot find POI");
981 }
982 throw std::runtime_error("Unconditional fit unavailable");
983}
984
985std::shared_ptr<xRooNLLVar::xRooHypoPoint> xRooNLLVar::xRooHypoPoint::asimov(bool readOnly)
986{
987
988 if (!fAsimov && nllVar) {
989 if (!nllVar->fFuncVars)
990 nllVar->reinitialize();
991 AutoRestorer snap(*nllVar->fFuncVars);
992 auto theFit = (!data.first && fGenFit) ? fGenFit : cfit_alt(readOnly);
993 if (!theFit || allowedStatusCodes.find(theFit->status()) == allowedStatusCodes.end())
994 return fAsimov;
995 *nllVar->fFuncVars = theFit->floatParsFinal();
996 *nllVar->fFuncVars = theFit->constPars();
997 auto asimov = nllVar->generate(true);
998 fAsimov = std::make_shared<xRooHypoPoint>(*this);
999 fAsimov->fPllType = xRooFit::Asymptotics::TwoSided;
1000 fAsimov->fUfit.reset();
1001 fAsimov->fNull_cfit.reset();
1002 fAsimov->fAlt_cfit.reset();
1003 fAsimov->data = asimov;
1004 fAsimov->fGenFit = theFit;
1005 fAsimov->isExpected = true;
1006 }
1007
1008 return fAsimov;
1009}
1010
1011std::pair<double, double> xRooNLLVar::xRooHypoPoint::pNull_asymp(double nSigma)
1012{
1013 if (fPllType != xRooFit::Asymptotics::Uncapped && ts_asymp(nSigma).first == 0)
1014 return std::pair(1, 0);
1015 auto first_poi = dynamic_cast<RooRealVar *>(poi().first());
1016 if (!first_poi)
1017 return std::pair(std::numeric_limits<double>::quiet_NaN(), 0);
1018 double nom = xRooFit::Asymptotics::PValue(fPllType, ts_asymp(nSigma).first, fNullVal(), fNullVal(), sigma_mu().first,
1019 first_poi->getMin("physical"), first_poi->getMax("physical"));
1020 double up =
1021 xRooFit::Asymptotics::PValue(fPllType, ts_asymp(nSigma).first + ts_asymp(nSigma).second, fNullVal(), fNullVal(),
1022 sigma_mu().first, first_poi->getMin("physical"), first_poi->getMax("physical"));
1023 double down =
1024 xRooFit::Asymptotics::PValue(fPllType, ts_asymp(nSigma).first - ts_asymp(nSigma).second, fNullVal(), fNullVal(),
1025 sigma_mu().first, first_poi->getMin("physical"), first_poi->getMax("physical"));
1026 return std::pair(nom, std::max(std::abs(up - nom), std::abs(down - nom)));
1027}
1028
1029std::pair<double, double> xRooNLLVar::xRooHypoPoint::pAlt_asymp(double nSigma)
1030{
1031 if (fPllType != xRooFit::Asymptotics::Uncapped && ts_asymp(nSigma).first == 0)
1032 return std::pair(1, 0);
1033 auto first_poi = dynamic_cast<RooRealVar *>(poi().first());
1034 if (!first_poi)
1035 return std::pair(std::numeric_limits<double>::quiet_NaN(), 0);
1036
1037 double nom = xRooFit::Asymptotics::PValue(fPllType, ts_asymp(nSigma).first, fNullVal(), fAltVal(), sigma_mu().first,
1038 first_poi->getMin("physical"), first_poi->getMax("physical"));
1039 double up =
1040 xRooFit::Asymptotics::PValue(fPllType, ts_asymp(nSigma).first + ts_asymp(nSigma).second, fNullVal(), fAltVal(),
1041 sigma_mu().first, first_poi->getMin("physical"), first_poi->getMax("physical"));
1042 double down =
1043 xRooFit::Asymptotics::PValue(fPllType, ts_asymp(nSigma).first - ts_asymp(nSigma).second, fNullVal(), fAltVal(),
1044 sigma_mu().first, first_poi->getMin("physical"), first_poi->getMax("physical"));
1045
1046 return std::pair(nom, std::max(std::abs(up - nom), std::abs(down - nom)));
1047}
1048
1049std::pair<double, double> xRooNLLVar::xRooHypoPoint::pCLs_asymp(double nSigma)
1050{
1051 if (fNullVal() == fAltVal())
1052 return std::pair(1, 0); // by construction
1053 if (fPllType != xRooFit::Asymptotics::Uncapped && ts_asymp(nSigma).first == 0)
1054 return std::pair(1, 0);
1055 auto first_poi = dynamic_cast<RooRealVar *>(poi().first());
1056 if (!first_poi)
1057 return std::pair(std::numeric_limits<double>::quiet_NaN(), 0);
1058
1059 double nom1 =
1060 xRooFit::Asymptotics::PValue(fPllType, ts_asymp(nSigma).first, fNullVal(), fNullVal(), sigma_mu().first,
1061 first_poi->getMin("physical"), first_poi->getMax("physical"));
1062 double up1 =
1063 xRooFit::Asymptotics::PValue(fPllType, ts_asymp(nSigma).first + ts_asymp(nSigma).second, fNullVal(), fNullVal(),
1064 sigma_mu().first, first_poi->getMin("physical"), first_poi->getMax("physical"));
1065 double down1 =
1066 xRooFit::Asymptotics::PValue(fPllType, ts_asymp(nSigma).first - ts_asymp(nSigma).second, fNullVal(), fNullVal(),
1067 sigma_mu().first, first_poi->getMin("physical"), first_poi->getMax("physical"));
1068 double nom2 = xRooFit::Asymptotics::PValue(fPllType, ts_asymp(nSigma).first, fNullVal(), fAltVal(), sigma_mu().first,
1069 first_poi->getMin("physical"), first_poi->getMax("physical"));
1070 double up2 =
1071 xRooFit::Asymptotics::PValue(fPllType, ts_asymp(nSigma).first + ts_asymp(nSigma).second, fNullVal(), fAltVal(),
1072 sigma_mu().first, first_poi->getMin("physical"), first_poi->getMax("physical"));
1073 double down2 =
1074 xRooFit::Asymptotics::PValue(fPllType, ts_asymp(nSigma).first - ts_asymp(nSigma).second, fNullVal(), fAltVal(),
1075 sigma_mu().first, first_poi->getMin("physical"), first_poi->getMax("physical"));
1076
1077 auto nom = (nom1 == 0) ? 0 : nom1 / nom2;
1078 auto up = (up1 == 0) ? 0 : up1 / up2;
1079 auto down = (down1 == 0) ? 0 : down1 / down2;
1080
1081 return std::make_pair(nom, std::max(std::abs(up - nom), std::abs(down - nom)));
1082}
1083
1084std::pair<double, double> xRooNLLVar::xRooHypoPoint::ts_asymp(double nSigma)
1085{
1086 auto first_poi = dynamic_cast<RooRealVar *>(poi().first());
1087 if (!first_poi || (!std::isnan(nSigma) && std::isnan(sigma_mu().first)))
1088 return std::pair(std::numeric_limits<double>::quiet_NaN(), 0);
1089 if (std::isnan(nSigma))
1090 return pll();
1091 double nom = xRooFit::Asymptotics::k(fPllType, ROOT::Math::gaussian_cdf(nSigma), fNullVal(), fAltVal(),
1092 sigma_mu().first, first_poi->getMin("physical"), first_poi->getMax("physical"));
1093 double up = xRooFit::Asymptotics::k(fPllType, ROOT::Math::gaussian_cdf(nSigma), fNullVal(), fAltVal(),
1094 sigma_mu().first + sigma_mu().second, first_poi->getMin("physical"),
1095 first_poi->getMax("physical"));
1096 double down = xRooFit::Asymptotics::k(fPllType, ROOT::Math::gaussian_cdf(nSigma), fNullVal(), fAltVal(),
1097 sigma_mu().first - sigma_mu().second, first_poi->getMin("physical"),
1098 first_poi->getMax("physical"));
1099 return std::pair<double, double>(nom, std::max(std::abs(nom - up), std::abs(nom - down)));
1100}
1101
1102std::pair<double, double> xRooNLLVar::xRooHypoPoint::ts_toys(double nSigma)
1103{
1104 if (std::isnan(nSigma))
1105 return pll();
1106 // nans should appear in the alt toys first ... so loop until past nans
1107 size_t firstToy = 0;
1108 while (firstToy < altToys.size() && std::isnan(std::get<1>(altToys[firstToy])))
1109 firstToy++;
1110 if (firstToy >= altToys.size())
1111 return std::make_pair(std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN());
1112 int targetIdx =
1113 (altToys.size() - firstToy) * ROOT::Math::gaussian_cdf(nSigma) + firstToy; // TODO: Account for weights
1114 return std::make_pair(
1115 std::get<1>(altToys[targetIdx]),
1116 (std::get<1>(altToys[std::min(int(altToys.size()), targetIdx)]) - std::get<1>(altToys[std::max(0, targetIdx)])) /
1117 2.);
1118}
1119
1120std::pair<double, double> xRooNLLVar::xRooHypoPoint::pll(bool readOnly)
1121{
1122 if (!ufit(readOnly) || allowedStatusCodes.find(ufit(readOnly)->status()) == allowedStatusCodes.end())
1123 return std::make_pair(std::numeric_limits<double>::quiet_NaN(), 0);
1124 auto cFactor = xRooFit::Asymptotics::CompatFactor(fPllType, fNullVal(), mu_hat().getVal());
1125 if (cFactor == 0)
1126 return std::make_pair(0, 0);
1127 if (!cfit_null(readOnly) || allowedStatusCodes.find(cfit_null(readOnly)->status()) == allowedStatusCodes.end())
1128 return std::make_pair(std::numeric_limits<double>::quiet_NaN(), 0);
1129 // std::cout << cfit->minNll() << ":" << cfit->edm() << " " << ufit->minNll() << ":" << ufit->edm() << std::endl;
1130 return std::make_pair(2. * cFactor * (cfit_null(readOnly)->minNll() - ufit(readOnly)->minNll()),
1131 2. * cFactor * sqrt(pow(cfit_null(readOnly)->edm(), 2) + pow(ufit(readOnly)->edm(), 2)));
1132 // return 2.*cFactor*(cfit->minNll()+cfit->edm() - ufit->minNll()+ufit->edm());
1133}
1134
1135std::shared_ptr<const RooFitResult> xRooNLLVar::xRooHypoPoint::ufit(bool readOnly)
1136{
1137 if (fUfit)
1138 return fUfit;
1139 if (!nllVar || (readOnly && nllVar->get() && !nllVar->get()->getAttribute("readOnly")))
1140 return nullptr;
1141 if (!nllVar->fFuncVars)
1142 nllVar->reinitialize();
1143 AutoRestorer snap(*nllVar->fFuncVars, nllVar.get());
1144 nllVar->setData(data);
1145 nllVar->fFuncVars->setAttribAll("Constant", false);
1146 *nllVar->fFuncVars = *coords; // will reconst the coords
1147 if (nllVar->fFuncGlobs)
1148 nllVar->fFuncGlobs->setAttribAll("Constant", true);
1149 std::unique_ptr<RooAbsCollection>(nllVar->fFuncVars->selectCommon(poi()))
1150 ->setAttribAll("Constant", false); // float the poi
1151 if (fGenFit) {
1152 // make initial guess same as pars we generated with
1153 nllVar->fFuncVars->assignValueOnly(fGenFit->constPars());
1154 nllVar->fFuncVars->assignValueOnly(fGenFit->floatParsFinal());
1155 // rename nll so if caching fit results will cache into subdir
1156 nllVar->get()->SetName(
1157 TString::Format("%s/%s_%s", nllVar->get()->GetName(), fGenFit->GetName(), (isExpected) ? "asimov" : "toys"));
1158 } else if (!std::isnan(fAltVal())) {
1159 // guess data given is expected to align with alt value
1160 nllVar->fFuncVars->setRealValue(fPOIName(), fAltVal());
1161 }
1162 return (fUfit = nllVar->minimize());
1163}
1164
1165std::string collectionContents(const RooAbsCollection &coll)
1166{
1167 std::string out;
1168 for (auto &c : coll) {
1169 if (!out.empty())
1170 out += ",";
1171 out += c->GetName();
1172 if (auto v = dynamic_cast<RooAbsReal *>(c); v)
1173 out += TString::Format("=%g", v->getVal());
1174 else if (auto cc = dynamic_cast<RooAbsCategory *>(c); cc)
1175 out += TString::Format("=%s", cc->getLabel());
1176 else if (auto s = dynamic_cast<RooStringVar *>(c); v)
1177 out += TString::Format("=%s", s->getVal());
1178 }
1179 return out;
1180}
1181
1182std::shared_ptr<const RooFitResult> xRooNLLVar::xRooHypoPoint::cfit_null(bool readOnly)
1183{
1184 if (fNull_cfit)
1185 return fNull_cfit;
1186 if (!nllVar || (readOnly && nllVar->get() && !nllVar->get()->getAttribute("readOnly")))
1187 return nullptr;
1188 if (!nllVar->fFuncVars)
1189 nllVar->reinitialize();
1190 AutoRestorer snap(*nllVar->fFuncVars, nllVar.get());
1191 nllVar->setData(data);
1192 if (fUfit) {
1193 // move to ufit coords before evaluating
1194 *nllVar->fFuncVars = fUfit->floatParsFinal();
1195 }
1196 nllVar->fFuncVars->setAttribAll("Constant", false);
1197 *nllVar->fFuncVars = *coords; // will reconst the coords
1198 if (nllVar->fFuncGlobs)
1199 nllVar->fFuncGlobs->setAttribAll("Constant", true);
1200 nllVar->fFuncVars->find(fPOIName())
1201 ->setStringAttribute("altVal", (!std::isnan(fAltVal())) ? TString::Format("%g", fAltVal()) : nullptr);
1202 if (fGenFit)
1203 nllVar->get()->SetName(
1204 TString::Format("%s/%s_%s", nllVar->get()->GetName(), fGenFit->GetName(), (isExpected) ? "asimov" : "toys"));
1205 nllVar->get()->setStringAttribute("fitresultTitle", collectionContents(poi()).c_str());
1206 return (fNull_cfit = nllVar->minimize());
1207}
1208
1209std::shared_ptr<const RooFitResult> xRooNLLVar::xRooHypoPoint::cfit_alt(bool readOnly)
1210{
1211 if (std::isnan(fAltVal()))
1212 return nullptr;
1213 if (fAlt_cfit)
1214 return fAlt_cfit;
1215 if (!nllVar || (readOnly && nllVar->get() && !nllVar->get()->getAttribute("readOnly")))
1216 return nullptr;
1217 if (!nllVar->fFuncVars)
1218 nllVar->reinitialize();
1219 AutoRestorer snap(*nllVar->fFuncVars, nllVar.get());
1220 nllVar->setData(data);
1221 if (fUfit) {
1222 // move to ufit coords before evaluating
1223 *nllVar->fFuncVars = fUfit->floatParsFinal();
1224 }
1225 nllVar->fFuncVars->setAttribAll("Constant", false);
1226 *nllVar->fFuncVars = *coords; // will reconst the coords
1227 if (nllVar->fFuncGlobs)
1228 nllVar->fFuncGlobs->setAttribAll("Constant", true);
1229 *nllVar->fFuncVars = alt_poi();
1230 if (fGenFit)
1231 nllVar->get()->SetName(
1232 TString::Format("%s/%s_%s", nllVar->get()->GetName(), fGenFit->GetName(), (isExpected) ? "asimov" : "toys"));
1233 nllVar->get()->setStringAttribute("fitresultTitle", collectionContents(alt_poi()).c_str());
1234 return (fAlt_cfit = nllVar->minimize());
1235}
1236
1237std::pair<double, double> xRooNLLVar::xRooHypoPoint::sigma_mu(bool readOnly)
1238{
1239
1240 if (!asimov(readOnly)) {
1241 return std::make_pair(std::numeric_limits<double>::quiet_NaN(), 0);
1242 }
1243
1244 auto out = asimov(readOnly)->pll(readOnly);
1245 return std::make_pair(std::abs(fNullVal() - fAltVal()) / sqrt(out.first),
1246 out.second * 0.5 * std::abs(fNullVal() - fAltVal()) / (out.first * sqrt(out.first)));
1247}
1248
1249std::pair<double, double> xRooNLLVar::xRooHypoPoint::pX_toys(bool alt, double nSigma)
1250{
1251 auto _ts = ts_toys(nSigma);
1252 if (std::isnan(_ts.first))
1253 return _ts;
1254
1255 TEfficiency eff("", "", 1, 0, 1);
1256
1257 auto &_theToys = (alt) ? altToys : nullToys;
1258
1259 // loop over toys, count how many are > ts value
1260 // nans (mean bad ts evaluations) will count towards uncertainty
1261 int nans = 0;
1262 double result = 0;
1263 double result_err_up = 0;
1264 double result_err_down = 0;
1265 for (auto &toy : _theToys) {
1266 if (std::isnan(std::get<1>(toy)))
1267 nans++;
1268 else {
1269 bool res = std::get<1>(toy) >= _ts.first;
1270 if (std::get<2>(toy) != 1)
1271 eff.FillWeighted(res, 0.5, std::get<2>(toy));
1272 else
1273 eff.Fill(res, 0.5);
1274 if (res)
1275 result += std::get<2>(toy);
1276 if (std::get<1>(toy) >= _ts.first - _ts.second)
1277 result_err_up += std::get<2>(toy);
1278 if (std::get<1>(toy) >= _ts.first - _ts.second)
1279 result_err_down += std::get<2>(toy);
1280 }
1281 }
1282 // symmetrize the error
1283 result_err_up -= result;
1284 result_err_down -= result;
1285 double result_err = std::max(std::abs(result_err_up), std::abs(result_err_down));
1286 // assume the nans would "add" to the p-value, conservative scenario
1287 result_err += nans;
1288 result_err /= _theToys.size();
1289
1290 // don't include the nans for the central value though
1291 result /= (_theToys.size() - nans);
1292
1293 // add to the result_err (in quadrature) the uncert due to limited stats
1294 result_err = sqrt(result_err * result_err + eff.GetEfficiencyErrorUp(1) * eff.GetEfficiencyErrorUp(1));
1295 return std::make_pair(result, result_err);
1296}
1297
1298std::pair<double, double> xRooNLLVar::xRooHypoPoint::pNull_toys(double nSigma)
1299{
1300 return pX_toys(false, nSigma);
1301}
1302
1303std::pair<double, double> xRooNLLVar::xRooHypoPoint::pAlt_toys(double nSigma)
1304{
1305 return pX_toys(true, nSigma);
1306}
1307
1309{
1310 xRooHypoPoint out;
1311 out.coords = coords;
1312 out.fPllType = fPllType; // out.fPOIName = fPOIName; out.fNullVal=fNullVal; out.fAltVal = fAltVal;
1313 out.nllVar = nllVar;
1314 if (!nllVar)
1315 return out;
1316 if (!cfit_null())
1317 return out;
1318 if (!nllVar->fFuncVars)
1319 nllVar->reinitialize();
1320 //*nllVar->fFuncVars = cfit_null()->floatParsFinal();
1321 //*nllVar->fFuncVars = cfit_null()->constPars();
1322 out.data = xRooFit::generateFrom(*nllVar->fPdf, cfit_null(), false, seed); // nllVar->generate(false,seed);
1323 out.fGenFit = cfit_null();
1324 return out;
1325}
1326
1328{
1329 xRooHypoPoint out;
1330 out.coords = coords;
1331 out.fPllType = fPllType; // out.fPOIName = fPOIName; out.fNullVal=fNullVal; out.fAltVal = fAltVal;
1332 out.nllVar = nllVar;
1333 if (!nllVar)
1334 return out;
1335 if (!cfit_alt())
1336 return out;
1337 if (!nllVar->fFuncVars)
1338 nllVar->reinitialize();
1339 //*nllVar->fFuncVars = cfit_alt()->floatParsFinal();
1340 //*nllVar->fFuncVars = cfit_alt()->constPars();
1341 out.data = xRooFit::generateFrom(*nllVar->fPdf, cfit_alt(), false, seed); // out.data = nllVar->generate(false,seed);
1342 out.fGenFit = cfit_alt();
1343 return out;
1344}
1345
1346void xRooNLLVar::xRooHypoPoint::addToys(bool alt, int nToys, int initialSeed)
1347{
1348 if ((alt && !cfit_alt()) || (!alt && !cfit_null())) {
1349 throw std::runtime_error("Cannot add toys, invalid conditional fit");
1350 }
1351 auto &toys = (alt) ? altToys : nullToys;
1352 int nans = 0;
1353 std::vector<float> times(nToys);
1354 float lastTime = 0;
1355 int lasti = -1;
1356 TStopwatch s2;
1357 s2.Start();
1358 TStopwatch s;
1359 s.Start();
1360 for (auto i = 0; i < nToys; i++) {
1361 if (i == 0 && initialSeed != 0)
1362 RooRandom::randomGenerator()->SetSeed(initialSeed);
1363 int seed = RooRandom::randomGenerator()->Integer(std::numeric_limits<uint32_t>::max());
1364 toys.push_back(std::make_tuple(seed, ((alt) ? generateAlt(seed) : generateNull(seed)).pll().first, 1.));
1365 if (std::isnan(std::get<1>(toys.back())))
1366 nans++;
1367 times[i] = s.RealTime() - lastTime; // stops the clock
1368 lastTime = s.RealTime();
1369 if (s.RealTime() > 10) {
1370 std::cout << "\r"
1371 << TString::Format("Generated %d/%d %s hypothesis toys [%.2f toys/s]...", i + 1, nToys,
1372 alt ? "alt" : "null", double(i - lasti) / s.RealTime())
1373 << std::flush;
1374 lasti = i;
1375 s.Reset();
1376 s.Start();
1377 // std::cout << "Generated " << i << "/" << nToys << (alt ? " alt " : " null ") << " hypothesis toys " ..." <<
1378 // std::endl;
1379 }
1380 s.Continue();
1381 }
1382 if (lasti)
1383 std::cout << "\r"
1384 << TString::Format("Generated %d/%d %s hypothesis toys [%.2f toys/s overall]...Done!", nToys, nToys,
1385 alt ? "alt" : "null", double(nToys) / s2.RealTime())
1386 << std::endl;
1387 auto g = gDirectory->Get<TGraph>("toyTime");
1388 if (!g) {
1389 g = new TGraph;
1390 g->SetNameTitle("toyTime", "Time per toy;Toy;time [s]");
1391 gDirectory->Add(g);
1392 }
1393 g->Set(times.size());
1394 for (size_t i = 0; i < times.size(); i++)
1395 g->SetPoint(i, i, times[i]);
1396 // sort the toys ... put nans first - do by setting all as negative inf
1397 for (auto &t : toys) {
1398 if (std::isnan(std::get<1>(t)))
1399 std::get<1>(t) = -std::numeric_limits<double>::infinity();
1400 }
1401 std::sort(toys.begin(), toys.end(),
1402 [](const decltype(nullToys)::value_type &a, const decltype(nullToys)::value_type &b) -> bool {
1403 if (std::isnan(std::get<1>(a)))
1404 return true;
1405 if (std::isnan(std::get<1>(b)))
1406 return false;
1407 return std::get<1>(a) < std::get<1>(b);
1408 });
1409 for (auto &t : toys) {
1410 if (std::isinf(std::get<1>(t)))
1411 std::get<1>(t) = std::numeric_limits<double>::quiet_NaN();
1412 }
1413 if (nans > 0)
1414 std::cout << "Warning: " << nans << " toys were bad" << std::endl;
1415}
1416
1418{
1419 addToys(false, nToys, seed);
1420}
1422{
1423 addToys(true, nToys, seed);
1424}
1425
1427xRooNLLVar::hypoPoint(const char *parName, double value, double alt_value, const xRooFit::Asymptotics::PLLType &pllType)
1428{
1429 xRooHypoPoint out;
1430 // out.fPOIName = parName; out.fNullVal = value; out.fAltVal = alt_value;
1431
1432 if (!fFuncVars) {
1433 reinitialize();
1434 }
1435
1436 out.nllVar = std::make_shared<xRooNLLVar>(*this);
1437 out.data = getData();
1438
1439 auto poi = dynamic_cast<RooRealVar *>(fFuncVars->find(parName));
1440 if (!poi)
1441 return out;
1442 AutoRestorer snap((RooArgSet(*poi)));
1443 poi->setVal(value);
1444 poi->setConstant();
1445 auto _snap = std::unique_ptr<RooAbsCollection>(fFuncVars->selectByAttrib("Constant", true))->snapshot();
1446 _snap->find(poi->GetName())->setAttribute("poi", true);
1447 if (std::isnan(alt_value))
1448 _snap->find(poi->GetName())->setStringAttribute("altVal", nullptr);
1449 else
1450 _snap->find(poi->GetName())->setStringAttribute("altVal", TString::Format("%g", alt_value));
1451 if (fGlobs)
1452 _snap->remove(*fGlobs, true, true);
1453 out.coords.reset(_snap);
1454
1455 auto _type = pllType;
1456 if (_type == xRooFit::Asymptotics::Unknown) {
1457 // decide based on values
1458 if (std::isnan(alt_value))
1460 else if (value >= alt_value)
1462 else
1464 }
1465
1466 out.fPllType = _type;
1467
1468 return out;
1469}
1470
1472xRooNLLVar::hypoPoint(double value, double alt_value, const xRooFit::Asymptotics::PLLType &pllType)
1473{
1474 if (!fFuncVars) {
1475 reinitialize();
1476 }
1477 std::unique_ptr<RooAbsCollection> _poi(fFuncVars->selectByAttrib("poi", true));
1478 if (_poi->empty()) {
1479 throw std::runtime_error("No POI specified in model");
1480 } else if (_poi->size() != 1) {
1481 throw std::runtime_error("Multiple POI specified in model");
1482 }
1483 return hypoPoint(_poi->first()->GetName(), value, alt_value, pllType);
1484}
1485
1487{
1488
1489 if (!nllVar)
1490 return;
1491
1492 TString sOpt(opt);
1493 sOpt.ToLower();
1494 bool hasSame = sOpt.Contains("same");
1495 sOpt.ReplaceAll("same", "");
1496
1497 TVirtualPad *pad = gPad;
1498
1499 TH1 *hAxis = nullptr;
1500
1501 auto clearPad = []() {
1502 gPad->Clear();
1503 if (gPad->GetNumber() == 0) {
1504 gPad->SetBottomMargin(gStyle->GetPadBottomMargin());
1505 gPad->SetTopMargin(gStyle->GetPadTopMargin());
1506 gPad->SetLeftMargin(gStyle->GetPadLeftMargin());
1507 gPad->SetRightMargin(gStyle->GetPadRightMargin());
1508 }
1509 };
1510
1511 if (!hasSame || !pad) {
1512 if (!pad) {
1514 pad = gPad;
1515 }
1516 clearPad();
1517 } else {
1518 // get the histogram representing the axes
1519 hAxis = dynamic_cast<TH1 *>(pad->GetPrimitive("axis"));
1520 if (!hAxis) {
1521 for (auto o : *pad->GetListOfPrimitives()) {
1522 if (hAxis = dynamic_cast<TH1 *>(o); hAxis)
1523 break;
1524 }
1525 }
1526 }
1527
1528 // get min and max values
1529 double _min = std::numeric_limits<double>::quiet_NaN();
1530 double _max = -std::numeric_limits<double>::quiet_NaN();
1531
1532 for (auto &p : nullToys) {
1533 if (std::get<2>(p) == 0)
1534 continue;
1535 if (std::isnan(std::get<1>(p)))
1536 continue;
1537 _min = std::min(std::get<1>(p), _min);
1538 _max = std::max(std::get<1>(p), _max);
1539 }
1540 for (auto &p : altToys) {
1541 if (std::get<2>(p) == 0)
1542 continue;
1543 if (std::isnan(std::get<1>(p)))
1544 continue;
1545 _min = std::min(std::get<1>(p), _min);
1546 _max = std::max(std::get<1>(p), _max);
1547 }
1548
1549 auto obs = pll();
1550 if (!std::isnan(obs.first)) {
1551 _min = std::min(obs.first - std::abs(obs.first) * 0.1, _min);
1552 _max = std::max(obs.first + std::abs(obs.first) * 0.1, _max);
1553 }
1554
1555 auto asi = (fAsimov && fAsimov->fUfit && fAsimov->fNull_cfit) ? fAsimov->pll().first
1556 : std::numeric_limits<double>::quiet_NaN();
1557 if (!std::isnan(asi) && asi > 0 && fPllType != xRooFit::Asymptotics::Unknown) {
1558 // can calculate asymptotic distributions,
1559 _min = std::min(asi - std::abs(asi), _min);
1560 _max = std::max(asi + std::abs(asi), _max);
1561 }
1562 if (_min > 0)
1563 _min = 0;
1564
1565 auto _poi = dynamic_cast<RooRealVar *>(poi().first());
1566
1567 auto makeHist = [&](bool isAlt) {
1568 TString title;
1569 auto h = new TH1D((isAlt) ? "alt_toys" : "null_toys", "", 100, _min, _max + (_max - _min) * 0.01);
1570 h->SetDirectory(0);
1571 size_t nBadOrZero = 0;
1572 for (auto &p : (isAlt) ? altToys : nullToys) {
1573 double w = std::isnan(std::get<1>(p)) ? 0 : std::get<2>(p);
1574 if (w == 0)
1575 nBadOrZero++;
1576 if (!std::isnan(std::get<1>(p)))
1577 h->Fill(std::get<1>(p), w);
1578 }
1579 if (h->GetEntries() > 0)
1580 h->Scale(1. / h->Integral(0, h->GetNbinsX() + 1));
1581
1582 // add POI values to identify hypos
1583 // for(auto p : *fPOI) {
1584 // if (auto v = dynamic_cast<RooRealVar*>(p)) {
1585 // if (auto v2 = dynamic_cast<RooRealVar*>(fAltPoint->fCoords->find(*v)); v2 &&
1586 // v2->getVal()!=v->getVal()) {
1587 // // found point that differs in poi and altpoint value, so print my coords value for this
1588 // title += TString::Format("%s' = %g,
1589 // ",v->GetTitle(),dynamic_cast<RooRealVar*>(fCoords->find(*v))->getVal());
1590 // }
1591 // }
1592 // }
1593 title += TString::Format("%s' = %g", fPOIName(), (isAlt) ? fAltVal() : fNullVal());
1594 title += (std::string(" , N_{toys}=") + ((isAlt) ? altToys.size() : nullToys.size()));
1595 if (nBadOrZero > 0)
1596 title += (std::string(" (N_{bad/0}=") + nBadOrZero + ')');
1597 title += ";";
1598 title += tsTitle();
1599 title += TString::Format(";Probability Mass");
1600 h->SetTitle(title);
1601 h->SetLineColor(isAlt ? kRed : kBlue);
1602 h->SetLineWidth(2);
1603 h->SetMarkerSize(0);
1604 h->SetBit(kCanDelete);
1605 return h;
1606 };
1607
1608 auto nullHist = makeHist(false);
1609 auto altHist = makeHist(true);
1610
1611 TLegend *l = nullptr;
1612 auto h = nullHist;
1613 if (!hasSame) {
1614 gPad->SetLogy();
1615 auto axis = (TH1 *)h->Clone(".axis");
1616 axis->Reset("ICES");
1617 axis->SetMinimum(1e-7);
1618 axis->SetMaximum(h->GetMaximum());
1619 axis->SetTitle(TString::Format("HypoPoint"));
1620 axis->SetLineWidth(0);
1621 axis->Draw(""); // h->Draw("axis"); cant use axis option if want title drawn
1622 hAxis = axis;
1623 l = new TLegend(0.4, 0.7, 1. - gPad->GetRightMargin(), 1. - gPad->GetTopMargin());
1624 l->SetName("legend");
1625 l->SetFillStyle(0);
1626 l->SetBorderSize(0);
1628 l->Draw();
1629 } else {
1630 for (auto o : *gPad->GetListOfPrimitives()) {
1631 l = dynamic_cast<TLegend *>(o);
1632 if (l)
1633 break;
1634 }
1635 }
1636
1637 if (h->GetEntries() > 0)
1638 h->Draw("histesame");
1639 else
1640 h->Draw("axissame"); // for unknown reason if second histogram empty it still draws with two weird bars???
1641 h = altHist;
1642 if (h->GetEntries() > 0)
1643 h->Draw("histesame");
1644 else
1645 h->Draw("axissame"); // for unknown reason if second histogram empty it still draws with two weird bars???
1646
1647 if (l) {
1648 l->AddEntry(nullHist);
1649 l->AddEntry(altHist);
1650 }
1651
1652 if (fAsimov && fAsimov->fUfit && fAsimov->fNull_cfit && !std::isnan(sigma_mu().first) && !std::isnan(fAltVal())) {
1653 auto hh = (TH1 *)nullHist->Clone("null_asymp");
1654 hh->SetLineStyle(2);
1655 hh->Reset();
1656 for (int i = 1; i <= hh->GetNbinsX(); i++) {
1657 hh->SetBinContent(
1658 i, xRooFit::Asymptotics::PValue(fPllType, hh->GetBinLowEdge(i), fNullVal(), fNullVal(), sigma_mu().first,
1659 _poi->getMin("physical"), _poi->getMax("physical")) -
1660 xRooFit::Asymptotics::PValue(fPllType, hh->GetBinLowEdge(i + 1), fNullVal(), fNullVal(),
1661 sigma_mu().first, _poi->getMin("physical"), _poi->getMax("physical")));
1662 }
1663 hh->Draw("lsame");
1664 hh = (TH1 *)altHist->Clone("alt_asymp");
1665 hh->SetLineStyle(2);
1666 hh->Reset();
1667 for (int i = 1; i <= hh->GetNbinsX(); i++) {
1668 hh->SetBinContent(
1669 i, xRooFit::Asymptotics::PValue(fPllType, hh->GetBinLowEdge(i), fNullVal(), fAltVal(), sigma_mu().first,
1670 _poi->getMin("physical"), _poi->getMax("physical")) -
1671 xRooFit::Asymptotics::PValue(fPllType, hh->GetBinLowEdge(i + 1), fNullVal(), fAltVal(),
1672 sigma_mu().first, _poi->getMin("physical"), _poi->getMax("physical")));
1673 }
1674 hh->Draw("lsame");
1675 }
1676
1677 // draw observed points
1678 TLine ll;
1679 ll.SetLineStyle(2);
1680 // for(auto p : fObs) {
1681 auto tl = ll.DrawLine(pll().first, hAxis->GetMinimum(), pll().first, 0.1);
1682 auto label = TString::Format("obs ts = %.4f", pll().first);
1683 if (pll().second)
1684 label += TString::Format(" #pm %.4f", pll().second);
1685 auto pNull = pNull_toys();
1686 auto pAlt = pAlt_toys();
1687
1688 auto pNullA = pNull_asymp();
1689 auto pAltA = pAlt_asymp();
1690
1691 l->AddEntry(tl, label, "l");
1692 label = "";
1693 if (!std::isnan(pNull.first) || !std::isnan(pAlt.first)) {
1694 auto pCLs = pCLs_toys();
1695 label += " p_{toy}=(";
1696 label += (std::isnan(pNull.first)) ? "-" : TString::Format("%.4f #pm %.4f", pNull.first, pNull.second);
1697 label += (std::isnan(pAlt.first)) ? ",-" : TString::Format(",%.4f #pm %.4f", pAlt.first, pAlt.second);
1698 label += (std::isnan(pCLs.first)) ? ",-)" : TString::Format(",%.4f #pm %.4f", pCLs.first, pCLs.second);
1699 }
1700 if (label.Length() > 0)
1701 l->AddEntry("", label, "");
1702 label = "";
1703 if (!std::isnan(pNullA.first) || !std::isnan(pAltA.first)) {
1704 auto pCLs = pCLs_asymp();
1705 label += " p_{asymp}=(";
1706 label += (std::isnan(pNullA.first)) ? "-" : TString::Format("%.4f #pm %.4f", pNullA.first, pNullA.second);
1707 label += (std::isnan(pAltA.first)) ? ",-" : TString::Format(",%.4f #pm %.4f", pAltA.first, pAltA.second);
1708 label += (std::isnan(pCLs.first)) ? ",-)" : TString::Format(",%.4f #pm %.4f", pCLs.first, pCLs.second);
1709 }
1710 if (label.Length() > 0)
1711 l->AddEntry("", label, "");
1712
1713 //}
1714}
1715
1717{
1718 auto v = dynamic_cast<RooRealVar *>(poi().empty() ? nullptr : poi().first());
1720 if (v && v->hasRange("physical") && v->getMin("physical") != -std::numeric_limits<double>::infinity())
1721 return TString::Format("#tilde{q}_{%s=%g}", v->GetTitle(), v->getVal());
1722 else if (v)
1723 return TString::Format("q_{%s=%g}", v->GetTitle(), v->getVal());
1724 else
1725 return "q";
1726 } else if (fPllType == xRooFit::Asymptotics::TwoSided) {
1727 if (v && v->hasRange("physical") && v->getMin("physical") != -std::numeric_limits<double>::infinity())
1728 return TString::Format("#tilde{t}_{%s=%g}", v->GetTitle(), v->getVal());
1729 else if (v)
1730 return TString::Format("t_{%s=%g}", v->GetTitle(), v->getVal());
1731 else
1732 return "t";
1733 } else if (fPllType == xRooFit::Asymptotics::OneSidedNegative) {
1734 if (v && v->hasRange("physical") && v->getMin("physical") != -std::numeric_limits<double>::infinity())
1735 return TString::Format("#tilde{r}_{%s=%g}", v->GetTitle(), v->getVal());
1736 else if (v)
1737 return TString::Format("r_{%s=%g}", v->GetTitle(), v->getVal());
1738 else
1739 return "r";
1740 } else if (fPllType == xRooFit::Asymptotics::Uncapped) {
1741 if (v && v->hasRange("physical") && v->getMin("physical") != -std::numeric_limits<double>::infinity())
1742 return TString::Format("#tilde{s}_{%s=%g}", v->GetTitle(), v->getVal());
1743 else if (v)
1744 return TString::Format("s_{%s=%g}", v->GetTitle(), v->getVal());
1745 else
1746 return "s";
1747 } else {
1748 return "Test Statistic";
1749 }
1750}
1751
1753{
1754 return (poi().first())->GetName();
1755}
1757{
1758 return dynamic_cast<RooAbsReal *>(poi().first())->getVal();
1759}
1761{
1762 return dynamic_cast<RooAbsReal *>(alt_poi().first())->getVal();
1763}
1764
1765xRooNLLVar::xRooHypoSpace xRooNLLVar::hypoSpace(const char *parName, int nPoints, double low, double high,
1766 double alt_value, const xRooFit::Asymptotics::PLLType &pllType)
1767{
1768 xRooNLLVar::xRooHypoSpace hs = hypoSpace(parName, pllType);
1769 hs.poi().first()->setStringAttribute("altVal", std::isnan(alt_value) ? nullptr : TString::Format("%f", alt_value));
1770 if (nPoints > 0)
1771 hs.AddPoints(parName, nPoints, low, high);
1772 return hs;
1773}
1774
1775xRooNLLVar::xRooHypoSpace xRooNLLVar::hypoSpace(int nPoints, double low, double high, double alt_value,
1776 const xRooFit::Asymptotics::PLLType &pllType)
1777{
1778 auto _poi = std::unique_ptr<RooAbsCollection>(
1779 std::unique_ptr<RooAbsCollection>(pdf()->getVariables())->selectByAttrib("poi", true));
1780 if (_poi->empty())
1781 throw std::runtime_error("You must specify a POI for the hypoSpace");
1782 return hypoSpace(_poi->first()->GetName(), nPoints, low, high, alt_value, pllType);
1783}
1784
1786{
1787 xRooNLLVar::xRooHypoSpace s(parName, parName);
1788
1789 s.AddModel(pdf());
1790 if (strlen(parName)) {
1791 auto poi = s.pars()->find(parName);
1792 if (!poi)
1793 throw std::runtime_error("parameter not found");
1794 s.pars()->setAttribAll("poi", false);
1795 poi->setAttribute("poi", true);
1796 } else if (std::unique_ptr<RooAbsCollection>(s.pars()->selectByAttrib("poi", true))->empty()) {
1797 throw std::runtime_error("You must specify a POI for the hypoSpace");
1798 }
1799 s.fNlls[s.fPdfs.begin()->second] = std::make_shared<xRooNLLVar>(*this);
1800 s.fTestStatType = pllType;
1801 return s;
1802}
1803
1805{
1807 out.SetBackgroundAsAlt(true);
1808
1809 bool setReadonly = false;
1810 if (nllVar && !nllVar->get()->getAttribute("readOnly")) {
1811 setReadonly = true;
1812 nllVar->get()->setAttribute("readOnly");
1813 }
1814
1815 auto ts_obs = ts_asymp();
1816
1817 out.SetTestStatisticData(ts_obs.first);
1818 RooArgList nullDetails;
1819 if (!nullToys.empty()) {
1820
1821 std::vector<double> values;
1822 std::vector<double> weights;
1823 values.reserve(nullToys.size());
1824 weights.reserve(nullToys.size());
1825 size_t badToys = 0;
1826 for (auto &t : nullToys) {
1827 if (std::isnan(std::get<1>(t))) {
1828 badToys++;
1829 } else {
1830 values.push_back(std::get<1>(t));
1831 weights.push_back(std::get<2>(t));
1832 }
1833 }
1834 nullDetails.addClone(RooRealVar("badToys", "Number of bad Toys", badToys));
1835
1836 out.SetNullDistribution(new RooStats::SamplingDistribution("null", "Null dist", values, weights, tsTitle()));
1837 out.SetNullDetailedOutput(new RooDataSet("nullDetails", "nullDetails", nullDetails));
1838 out.GetNullDetailedOutput()->add(nullDetails);
1839 } else {
1840#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
1841 out.fNullPValue = pNull_asymp().first;
1842 out.fNullPValueError = pNull_asymp().second;
1843#else
1844 out.SetNullPValue(pNull_asymp().first);
1845 out.SetNullPValueError(pNull_asymp().second);
1846#endif
1847 }
1848
1849 RooArgList altDetails;
1850 if (!altToys.empty()) {
1851 std::vector<double> values;
1852 std::vector<double> weights;
1853 values.reserve(nullToys.size());
1854 weights.reserve(nullToys.size());
1855 size_t badToys = 0;
1856 for (auto &t : nullToys) {
1857 if (std::isnan(std::get<1>(t))) {
1858 badToys++;
1859 } else {
1860 values.push_back(std::get<1>(t));
1861 weights.push_back(std::get<2>(t));
1862 }
1863 }
1864 nullDetails.addClone(RooRealVar("badToys", "Number of bad Toys", badToys));
1865
1866 out.SetAltDistribution(new RooStats::SamplingDistribution("alt", "Alt dist", values, weights, tsTitle()));
1867 out.SetAltDetailedOutput(new RooDataSet("altDetails", "altDetails", altDetails));
1868 out.GetAltDetailedOutput()->add(altDetails);
1869 } else {
1870#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
1871 out.fAlternatePValue = pAlt_asymp().first;
1872 out.fAlternatePValueError = pAlt_asymp().second;
1873#else
1874 out.SetAltPValue(pAlt_asymp().first);
1875 out.SetAltPValueError(pAlt_asymp().second);
1876#endif
1877 }
1878
1879 if (setReadonly) {
1880 nllVar->get()->setAttribute("readOnly", false);
1881 }
1882
1883 return out;
1884}
1885
#define SafeDelete(p)
Definition RConfig.hxx:540
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define g(i)
Definition RSha256.hxx:105
#define a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
RooAbsReal * _func
Definition RooMinuit.h:90
const char Option_t
Definition RtypesCore.h:66
@ kRed
Definition Rtypes.h:66
@ kBlue
Definition Rtypes.h:66
#define gDirectory
Definition TDirectory.h:386
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:230
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:197
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
@ kCanDelete
Definition TObject.h:369
R__EXTERN TStyle * gStyle
Definition TStyle.h:414
R__EXTERN TSystem * gSystem
Definition TSystem.h:560
#define gPad
AutoRestorer(const RooAbsCollection &s, xRooNLLVar *nll=nullptr)
RooArgSet fPars
TString fOldName
std::pair< std::shared_ptr< RooAbsData >, std::shared_ptr< const RooAbsCollection > > fOldData
std::unique_ptr< RooAbsCollection > fSnap
Generic interface for defining configuration options of a numerical algorithm.
Definition IOptions.h:31
void SetValue(const char *name, double val)
generic methods for retrieving options
Definition IOptions.h:45
void Print(Option_t *options=nullptr) const override
Print the object to the defaultPrintStream().
Definition RooAbsArg.h:318
void setStringAttribute(const Text_t *key, const Text_t *value)
Associate string 'value' to this object under key 'key'.
const RefCountList_t & servers() const
List of all servers of this object.
Definition RooAbsArg.h:204
RooAbsCategoryLValue is the common abstract base class for objects that represent a discrete value th...
A space to attach TBranches.
RooAbsCollection is an abstract container object that can hold multiple RooAbsArg objects.
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
void setAttribAll(const Text_t *name, bool value=true)
Set given attribute in each element of the collection by calling each elements setAttribute() functio...
Storage_t::size_type size() const
RooAbsArg * first() const
void reserve(Storage_t::size_type count)
virtual RooAbsArg * addClone(const RooAbsArg &var, bool silent=false)
Add a clone of the specified argument to list.
bool selectCommon(const RooAbsCollection &refColl, RooAbsCollection &outColl) const
Create a subset of the current collection, consisting only of those elements that are contained as we...
std::string contentsString() const
Return comma separated list of contained object names as STL string.
void setName(const char *name)
RooAbsData is the common abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:59
virtual const RooArgSet * get() const
Definition RooAbsData.h:103
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
virtual void setVal(double value)=0
Set the current value of the object. Needs to be overridden by implementations.
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition RooAbsReal.h:62
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:91
bool setData(RooAbsData &data, bool cloneData=true) override
Change dataset that is used to given one.
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition RooArgList.h:22
RooAbsArg * at(Int_t idx) const
Return object at given index, or nullptr if index is out of range.
Definition RooArgList.h:110
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
RooCmdArg is a named container for two doubles, two integers two object points and three string point...
Definition RooCmdArg.h:26
Int_t getInt(Int_t idx) const
Definition RooCmdArg.h:86
TObject * Clone(const char *newName=nullptr) const override
Make a clone of an object using the Streamer facility.
Definition RooCmdArg.h:57
RooConstraintSum calculates the sum of the -(log) likelihoods of a set of RooAbsPfs that represent co...
RooDataSet is a container class to hold unbinned data.
Definition RooDataSet.h:57
void add(const RooArgSet &row, double weight=1.0, double weightError=0.0) override
Add one ore more rows of data.
RooFitResult is a container class to hold the input and output of a PDF fit to a dataset.
static Double_t k(const IncompatFunc &compatRegions, double pValue, double poiVal, double poiPrimeVal, double sigma_mu=0, double mu_low=-std::numeric_limits< double >::infinity(), double mu_high=std::numeric_limits< double >::infinity())
static Double_t PValue(const IncompatFunc &compatRegions, double k, double mu, double mu_prime, double sigma_mu=0, double mu_low=-std::numeric_limits< double >::infinity(), double mu_high=std::numeric_limits< double >::infinity())
static int CompatFactor(const IncompatFunc &func, double mu_hat)
static std::shared_ptr< const RooFitResult > minimize(RooAbsReal &nll, const std::shared_ptr< ROOT::Fit::FitConfig > &fitConfig=nullptr)
Definition xRooFit.cxx:503
static std::shared_ptr< ROOT::Fit::FitConfig > createFitConfig()
Definition xRooFit.cxx:401
static std::pair< std::shared_ptr< RooAbsData >, std::shared_ptr< const RooAbsCollection > > generateFrom(RooAbsPdf &pdf, const std::shared_ptr< const RooFitResult > &fr, bool expected=false, int seed=0)
Definition xRooFit.cxx:115
xRooFitResult(const std::shared_ptr< xRooNode > &in)
void addToys(bool alt, int nToys, int initialSeed=0)
std::pair< double, double > getVal(const char *what)
std::pair< double, double > pNull_toys(double nSigma=std::numeric_limits< double >::quiet_NaN())
std::pair< double, double > pAlt_toys(double nSigma=std::numeric_limits< double >::quiet_NaN())
std::pair< double, double > ts_asymp(double nSigma=std::numeric_limits< double >::quiet_NaN())
std::shared_ptr< const RooAbsCollection > coords
Definition xRooNLLVar.h:169
std::shared_ptr< xRooHypoPoint > asimov(bool readOnly=false)
std::pair< std::shared_ptr< RooAbsData >, std::shared_ptr< const RooAbsCollection > > data
Definition xRooNLLVar.h:119
std::pair< double, double > pll(bool readOnly=false)
std::shared_ptr< const RooFitResult > ufit(bool readOnly=false)
std::shared_ptr< const RooFitResult > cfit_null(bool readOnly=false)
std::pair< double, double > sigma_mu(bool readOnly=false)
std::shared_ptr< const RooFitResult > cfit_alt(bool readOnly=false)
std::pair< double, double > pX_toys(bool alt, double nSigma=std::numeric_limits< double >::quiet_NaN())
std::shared_ptr< const RooFitResult > fGenFit
Definition xRooNLLVar.h:172
std::pair< double, double > pAlt_asymp(double nSigma=std::numeric_limits< double >::quiet_NaN())
std::pair< double, double > ts_toys(double nSigma=std::numeric_limits< double >::quiet_NaN())
std::pair< double, double > pNull_asymp(double nSigma=std::numeric_limits< double >::quiet_NaN())
std::pair< double, double > pCLs_asymp(double nSigma=std::numeric_limits< double >::quiet_NaN())
xRooFit::Asymptotics::PLLType fTestStatType
Definition xRooNLLVar.h:259
bool AddModel(const xRooNode &pdf, const char *validity="")
std::shared_ptr< RooArgSet > pars() const
Definition xRooNLLVar.h:223
std::set< std::pair< std::shared_ptr< RooArgList >, std::shared_ptr< xRooNode > > > fPdfs
Definition xRooNLLVar.h:266
int AddPoints(const char *parName, size_t nPoints, double low, double high)
std::map< std::shared_ptr< xRooNode >, std::shared_ptr< xRooNLLVar > > fNlls
Definition xRooNLLVar.h:262
void AddOption(const RooCmdArg &opt)
std::shared_ptr< RooAbsReal > func() const
ROOT::Math::IOptions * fitConfigOptions()
std::shared_ptr< RooAbsCollection > fFuncGlobs
Definition xRooNLLVar.h:319
std::shared_ptr< RooAbsCollection > fFuncVars
Definition xRooNLLVar.h:317
Bool_t setData(const std::pair< std::shared_ptr< RooAbsData >, std::shared_ptr< const RooAbsCollection > > &_data)
std::shared_ptr< RooAbsPdf > fPdf
Definition xRooNLLVar.h:310
RooConstraintSum * constraintTerm() const
std::shared_ptr< RooAbsCollection > fConstVars
Definition xRooNLLVar.h:318
std::shared_ptr< const RooAbsCollection > fGlobs
Definition xRooNLLVar.h:312
std::shared_ptr< RooAbsData > fData
Definition xRooNLLVar.h:311
xRooHypoSpace hypoSpace(const char *parName, int nPoints, double low, double high, double alt_value=std::numeric_limits< double >::quiet_NaN(), const xRooFit::Asymptotics::PLLType &pllType=xRooFit::Asymptotics::Unknown)
std::shared_ptr< RooAbsPdf > pdf() const
Definition xRooNLLVar.h:283
xRooNLLVar(RooAbsPdf &pdf, const std::pair< RooAbsData *, const RooAbsCollection * > &data, const RooLinkedList &nllOpts=RooLinkedList())
std::shared_ptr< RooLinkedList > fOpts
Definition xRooNLLVar.h:314
std::pair< std::shared_ptr< RooAbsData >, std::shared_ptr< const RooAbsCollection > > generate(bool expected=false, int seed=0)
std::pair< std::shared_ptr< RooAbsData >, std::shared_ptr< const RooAbsCollection > > getData() const
std::shared_ptr< ROOT::Fit::FitConfig > fitConfig()
std::shared_ptr< ROOT::Fit::FitConfig > fFitConfig
Definition xRooNLLVar.h:315
std::shared_ptr< RooArgSet > pars(bool stripGlobalObs=true)
xRooHypoPoint hypoPoint(const char *parName, double value, double alt_value=std::numeric_limits< double >::quiet_NaN(), const xRooFit::Asymptotics::PLLType &pllType=xRooFit::Asymptotics::Unknown)
xRooFitResult minimize(const std::shared_ptr< ROOT::Fit::FitConfig > &=nullptr)
RooLinkedList is an collection class for internal use, storing a collection of RooAbsArg pointers in ...
Int_t GetSize() const
TObject * At(int index) const
Return object stored in sequential position given by index.
static RooMsgService & instance()
Return reference to singleton instance.
StreamConfig & getStream(Int_t id)
Class RooNLLVar implements a -log(likelihood) calculation from a dataset and a PDF.
Definition RooNLLVar.h:30
static TRandom * randomGenerator()
Return a pointer to a singleton random-number generator implementation.
Definition RooRandom.cxx:51
RooRealVar represents a variable that can be changed from the outside.
Definition RooRealVar.h:40
RooSimultaneous facilitates simultaneous fitting of multiple PDFs to subsets of a given dataset.
HypoTestResult is a base class for results from hypothesis tests.
void SetAltDetailedOutput(RooDataSet *d)
double fNullPValue
p-value for the null hypothesis (small number means disfavoured)
double fAlternatePValueError
error of p-value for the alternate hypothesis (small number means disfavoured)
void SetNullDetailedOutput(RooDataSet *d)
RooDataSet * GetNullDetailedOutput(void) const
void SetBackgroundAsAlt(bool l=true)
void SetAltPValue(double pvalue)
void SetNullDistribution(SamplingDistribution *null)
void SetTestStatisticData(const double tsd)
void SetAltPValueError(double err)
double fNullPValueError
error of p-value for the null hypothesis (small number means disfavoured)
void SetAltDistribution(SamplingDistribution *alt)
RooDataSet * GetAltDetailedOutput(void) const
double fAlternatePValue
p-value for the alternate hypothesis (small number means disfavoured)
void SetNullPValue(double pvalue)
void SetNullPValueError(double err)
This class simply holds a sampling distribution of some test statistic.
RooStringVar is a RooAbsArg implementing string values.
Draw all kinds of Arrows.
Definition TArrow.h:29
virtual TArrow * DrawArrow(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Float_t arrowsize=0, Option_t *option="")
Draw this arrow with new coordinates.
Definition TArrow.cxx:135
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition TAttLine.h:42
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition TAttMarker.h:38
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition TAttMarker.h:40
static TCanvas * MakeDefCanvas()
Static function to build a default canvas.
Definition TCanvas.cxx:1504
Class to handle efficiency histograms.
Definition TEfficiency.h:28
void FillWeighted(Bool_t bPassed, Double_t weight, Double_t x, Double_t y=0, Double_t z=0)
This function is used for filling the two histograms with a weight.
Double_t GetEfficiencyErrorUp(Int_t bin) const
Returns the upper error on the efficiency in the given global bin.
void Fill(Bool_t bPassed, Double_t x, Double_t y=0, Double_t z=0)
This function is used for filling the two histograms.
A TGraph is an object made of two arrays X and Y with npoints each.
Definition TGraph.h:41
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
Definition TGraph.cxx:2325
Int_t GetN() const
Definition TGraph.h:129
virtual void Sort(Bool_t(*greater)(const TGraph *, Int_t, Int_t)=&TGraph::CompareX, Bool_t ascending=kTRUE, Int_t low=0, Int_t high=-1111)
Sorts the points of this TGraph using in-place quicksort (see e.g.
Definition TGraph.cxx:2469
void SetName(const char *name="") override
Set graph name.
Definition TGraph.cxx:2364
void Draw(Option_t *chopt="") override
Draw this graph with its current attributes.
Definition TGraph.cxx:808
virtual Double_t GetPointY(Int_t i) const
Get y value for point i.
Definition TGraph.cxx:1539
void SetTitle(const char *title="") override
Change (i.e.
Definition TGraph.cxx:2380
void SetNameTitle(const char *name="", const char *title="") override
Set graph name and title.
Definition TGraph.cxx:2400
1-D histogram with a double per channel (see TH1 documentation)}
Definition TH1.h:620
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:58
virtual Double_t GetMinimum(Double_t minval=-FLT_MAX) const
Return minimum value larger than minval of bins in the range, unless the value has been overridden by...
Definition TH1.cxx:8501
This class displays a legend box (TPaveText) containing several legend entries.
Definition TLegend.h:23
void Draw(Option_t *option="") override
Draw this legend with its current attributes.
Definition TLegend.cxx:422
Use the TLine constructor to create a simple line.
Definition TLine.h:22
virtual TLine * DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Draw this line with new coordinates.
Definition TLine.cxx:102
A TMultiGraph is a collection of TGraph (or derived) objects.
Definition TMultiGraph.h:34
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
void Clear(Option_t *option="") override
Set name and title to empty strings ("").
Definition TNamed.cxx:64
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:439
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition TObject.cxx:223
virtual void Delete(Option_t *option="")
Delete this object.
Definition TObject.cxx:248
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:774
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition TObject.cxx:274
virtual void SetSeed(ULong_t seed=0)
Set the random generator seed.
Definition TRandom.cxx:608
virtual UInt_t Integer(UInt_t imax)
Returns a random integer uniformly distributed on the interval [ 0, imax-1 ].
Definition TRandom.cxx:360
Stopwatch class.
Definition TStopwatch.h:28
Double_t RealTime()
Stop the stopwatch (if it is running) and return the realtime (in seconds) passed between the start a...
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
void Continue()
Resume a stopped stopwatch.
void Reset()
Definition TStopwatch.h:52
Provides iteration through tokens of a given string.
Definition TPRegexp.h:143
Bool_t NextToken()
Get the next token, it is stored in this TString.
Definition TPRegexp.cxx:975
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:421
void ToLower()
Change string to lower-case.
Definition TString.cxx:1170
Double_t Atof() const
Return floating-point value contained in string.
Definition TString.cxx:2032
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:627
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2356
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:636
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:651
Float_t GetPadRightMargin() const
Definition TStyle.h:206
Float_t GetPadLeftMargin() const
Definition TStyle.h:205
Float_t GetPadBottomMargin() const
Definition TStyle.h:203
Float_t GetPadTopMargin() const
Definition TStyle.h:204
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
Definition TSystem.cxx:419
This class defines a UUID (Universally Unique IDentifier), also known as GUIDs (Globally Unique IDent...
Definition TUUID.h:42
const char * AsString() const
Return UUID as string. Copy string immediately since it will be reused.
Definition TUUID.cxx:571
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
virtual TList * GetListOfPrimitives() const =0
virtual TObject * GetPrimitive(const char *name) const =0
RooCmdArg GlobalObservables(Args_t &&... argsOrArgSet)
TGraphErrors * gr
Definition legend1.C:25
double gaussian_cdf(double x, double sigma=1, double x0=0)
Alternative name for same function.
@ NumIntegration
Double_t LnGamma(Double_t z)
Computation of ln[gamma(z)] for all z.
Definition TMath.cxx:509
Definition first.py:1
#define BEGIN_XROOFIT_NAMESPACE
Definition Config.h:24
#define END_XROOFIT_NAMESPACE
Definition Config.h:25
static const char * what
Definition stlLoader.cc:6
void removeTopic(RooFit::MsgTopic oldTopic)
TLine l
Definition textangle.C:4
std::string collectionContents(const RooAbsCollection &coll)
#define GETWS(a)
#define GETWSSETS(w)