Logo ROOT  
Reference Guide
RooAbsOptTestStatistic.cxx
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: RooFit *
3 * Package: RooFitCore *
4 * @(#)root/roofitcore:$Id$
5 * Authors: *
6 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8 * *
9 * Copyright (c) 2000-2005, Regents of the University of California *
10 * and Stanford University. All rights reserved. *
11 * *
12 * Redistribution and use in source and binary forms, *
13 * with or without modification, are permitted according to the terms *
14 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15 *****************************************************************************/
16
17/**
18\file RooAbsOptTestStatistic.cxx
19\class RooAbsOptTestStatistic
20\ingroup Roofitcore
21
22RooAbsOptTestStatistic is the abstract base class for test
23statistics objects that evaluate a function or PDF at each point of a given
24dataset. This class provides generic optimizations, such as
25caching and precalculation of constant terms that can be made for
26all such quantities.
27
28Implementations should define evaluatePartition(), which calculates the
29value of a (sub)range of the dataset and optionally combinedValue(),
30which combines the values calculated for each partition. If combinedValue()
31is not overloaded, the default implementation will add the partition results
32to obtain the combined result.
33
34Support for calculation in partitions is needed to allow multi-core
35parallelized calculation of test statistics.
36**/
37
38#include "RooFit.h"
39
40#include "Riostream.h"
41#include <string.h>
42
43
45#include "RooMsgService.h"
46#include "RooAbsPdf.h"
47#include "RooAbsData.h"
48#include "RooDataHist.h"
49#include "RooArgSet.h"
50#include "RooRealVar.h"
51#include "RooErrorHandler.h"
52#include "RooGlobalFunc.h"
53#include "RooBinning.h"
54#include "RooAbsDataStore.h"
55#include "RooCategory.h"
56#include "RooDataSet.h"
57#include "RooProdPdf.h"
58#include "RooAddPdf.h"
59#include "RooProduct.h"
60#include "RooRealSumPdf.h"
61#include "RooTrace.h"
62#include "RooVectorDataStore.h"
63
64using namespace std;
65
67;
68
69
70////////////////////////////////////////////////////////////////////////////////
71/// Default Constructor
72
74{
75 // Initialize all non-persisted data members
76
77 _funcObsSet = 0 ;
78 _funcCloneSet = 0 ;
79 _funcClone = 0 ;
80
81 _normSet = 0 ;
82 _projDeps = 0 ;
83
84 _origFunc = 0 ;
85 _origData = 0 ;
86
87 _ownData = kTRUE ;
88 _sealed = kFALSE ;
90}
91
92
93
94////////////////////////////////////////////////////////////////////////////////
95/// Constructor taking function (real), a dataset (data), a set of projected observables (projSet). If
96/// rangeName is not null, only events in the dataset inside the range will be used in the test
97/// statistic calculation. If addCoefRangeName is not null, all RooAddPdf component of 'real' will be
98/// instructed to fix their fraction definitions to the given named range. If nCPU is greater than
99/// 1 the test statistic calculation will be paralellized over multiple processes. By default the data
100/// is split with 'bulk' partitioning (each process calculates a contigious block of fraction 1/nCPU
101/// of the data). For binned data this approach may be suboptimal as the number of bins with >0 entries
102/// in each processing block many vary greatly thereby distributing the workload rather unevenly.
103/// If interleave is set to true, the interleave partitioning strategy is used where each partition
104/// i takes all bins for which (ibin % ncpu == i) which is more likely to result in an even workload.
105/// If splitCutRange is true, a different rangeName constructed as rangeName_{catName} will be used
106/// as range definition for each index state of a RooSimultaneous
107
108RooAbsOptTestStatistic::RooAbsOptTestStatistic(const char *name, const char *title, RooAbsReal& real, RooAbsData& indata,
109 const RooArgSet& projDeps, const char* rangeName, const char* addCoefRangeName,
110 Int_t nCPU, RooFit::MPSplit interleave, Bool_t verbose, Bool_t splitCutRange, Bool_t /*cloneInputData*/) :
111 RooAbsTestStatistic(name,title,real,indata,projDeps,rangeName, addCoefRangeName, nCPU, interleave, verbose, splitCutRange),
112 _projDeps(0),
113 _sealed(kFALSE),
114 _optimized(kFALSE)
115{
116 // Don't do a thing in master mode
117
118 if (operMode()!=Slave) {
119 _funcObsSet = 0 ;
120 _funcCloneSet = 0 ;
121 _funcClone = 0 ;
122 _normSet = 0 ;
123 _projDeps = 0 ;
124 _origFunc = 0 ;
125 _origData = 0 ;
126 _ownData = kFALSE ;
127 _sealed = kFALSE ;
128 return ;
129 }
130
131 _origFunc = 0 ; //other._origFunc ;
132 _origData = 0 ; // other._origData ;
133
134 initSlave(real,indata,projDeps,rangeName,addCoefRangeName) ;
135}
136
137////////////////////////////////////////////////////////////////////////////////
138/// Copy constructor
139
141 RooAbsTestStatistic(other,name), _sealed(other._sealed), _sealNotice(other._sealNotice), _optimized(kFALSE)
142{
143 // Don't do a thing in master mode
144 if (operMode()!=Slave) {
145
146 _funcObsSet = 0 ;
147 _funcCloneSet = 0 ;
148 _funcClone = 0 ;
149 _normSet = other._normSet ? ((RooArgSet*) other._normSet->snapshot()) : 0 ;
150 _projDeps = 0 ;
151 _origFunc = 0 ;
152 _origData = 0 ;
153 _ownData = kFALSE ;
154 return ;
155 }
156
157 _origFunc = 0 ; //other._origFunc ;
158 _origData = 0 ; // other._origData ;
159 _projDeps = 0 ;
160
161 initSlave(*other._funcClone,*other._dataClone,other._projDeps?*other._projDeps:RooArgSet(),other._rangeName.c_str(),other._addCoefRangeName.c_str()) ;
162}
163
164
165
166////////////////////////////////////////////////////////////////////////////////
167
168void RooAbsOptTestStatistic::initSlave(RooAbsReal& real, RooAbsData& indata, const RooArgSet& projDeps, const char* rangeName,
169 const char* addCoefRangeName)
170{
171 RooArgSet obs(*indata.get()) ;
172 obs.remove(projDeps,kTRUE,kTRUE) ;
173
174
175 // ******************************************************************
176 // *** PART 1 *** Clone incoming pdf, attach to each other *
177 // ******************************************************************
178
179 // Clone FUNC
180 _funcClone = (RooAbsReal*) real.cloneTree() ;
181 _funcCloneSet = 0 ;
182
183 // Attach FUNC to data set
185
186 if (_funcClone->getAttribute("BinnedLikelihood")) {
187 _funcClone->setAttribute("BinnedLikelihoodActive") ;
188 }
189
190 // Reattach FUNC to original parameters
191 RooArgSet* origParams = (RooArgSet*) real.getParameters(indata) ;
193
194 // Mark all projected dependents as such
195 if (projDeps.getSize()>0) {
196 RooArgSet *projDataDeps = (RooArgSet*) _funcObsSet->selectCommon(projDeps) ;
197 projDataDeps->setAttribAll("projectedDependent") ;
198 delete projDataDeps ;
199 }
200
201 // If PDF is a RooProdPdf (with possible constraint terms)
202 // analyze pdf for actual parameters (i.e those in unconnected constraint terms should be
203 // ignored as here so that the test statistic will not be recalculated if those
204 // are changed
205 RooProdPdf* pdfWithCons = dynamic_cast<RooProdPdf*>(_funcClone) ;
206 if (pdfWithCons) {
207
208 RooArgSet* connPars = pdfWithCons->getConnectedParameters(*indata.get()) ;
209 // Add connected parameters as servers
211 _paramSet.add(*connPars) ;
212 delete connPars ;
213
214 } else {
215 // Add parameters as servers
216 _paramSet.add(*origParams) ;
217 }
218
219
220 delete origParams ;
221
222 // Store normalization set
223 _normSet = (RooArgSet*) indata.get()->snapshot(kFALSE) ;
224
225 // Expand list of observables with any observables used in parameterized ranges.
226 // This NEEDS to be a counting loop since we are inserting during the loop.
227 for (std::size_t i = 0; i < _funcObsSet->size(); ++i) {
228 auto realDepRLV = dynamic_cast<const RooAbsRealLValue*>((*_funcObsSet)[i]);
229 if (realDepRLV && realDepRLV->isDerived()) {
230 RooArgSet tmp2;
231 realDepRLV->leafNodeServerList(&tmp2, 0, kTRUE);
232 _funcObsSet->add(tmp2,kTRUE);
233 }
234 }
235
236
237
238 // ******************************************************************
239 // *** PART 2 *** Clone and adjust incoming data, attach to PDF *
240 // ******************************************************************
241
242 // Check if the fit ranges of the dependents in the data and in the FUNC are consistent
243 const RooArgSet* dataDepSet = indata.get() ;
244 for (const auto arg : *_funcObsSet) {
245
246 // Check that both dataset and function argument are of type RooRealVar
247 RooRealVar* realReal = dynamic_cast<RooRealVar*>(arg) ;
248 if (!realReal) continue ;
249 RooRealVar* datReal = dynamic_cast<RooRealVar*>(dataDepSet->find(realReal->GetName())) ;
250 if (!datReal) continue ;
251
252 // Check that range of observables in pdf is equal or contained in range of observables in data
253
254 if (!realReal->getBinning().lowBoundFunc() && realReal->getMin()<(datReal->getMin()-1e-6)) {
255 coutE(InputArguments) << "RooAbsOptTestStatistic: ERROR minimum of FUNC observable " << arg->GetName()
256 << "(" << realReal->getMin() << ") is smaller than that of "
257 << arg->GetName() << " in the dataset (" << datReal->getMin() << ")" << endl ;
259 return ;
260 }
261
262 if (!realReal->getBinning().highBoundFunc() && realReal->getMax()>(datReal->getMax()+1e-6)) {
263 coutE(InputArguments) << "RooAbsOptTestStatistic: ERROR maximum of FUNC observable " << arg->GetName()
264 << " is larger than that of " << arg->GetName() << " in the dataset" << endl ;
266 return ;
267 }
268
269 }
270
271 // Copy data and strip entries lost by adjusted fit range, _dataClone ranges will be copied from realDepSet ranges
272 if (rangeName && strlen(rangeName)) {
274// cout << "RooAbsOptTestStatistic: reducing dataset to fit in range named " << rangeName << " resulting dataset has " << _dataClone->sumEntries() << " events" << endl ;
275 } else {
276 _dataClone = (RooAbsData*) indata.Clone() ;
277 }
278 _ownData = kTRUE ;
279
280
281 // ******************************************************************
282 // *** PART 3 *** Make adjustments for fit ranges, if specified *
283 // ******************************************************************
284
285 RooArgSet* origObsSet = real.getObservables(indata) ;
286 RooArgSet* dataObsSet = (RooArgSet*) _dataClone->get() ;
287 if (rangeName && strlen(rangeName)) {
288 cxcoutI(Fitting) << "RooAbsOptTestStatistic::ctor(" << GetName() << ") constructing test statistic for sub-range named " << rangeName << endl ;
289
290 bool observablesKnowRange = false;
291 // Adjust FUNC normalization ranges to requested fitRange, store original ranges for RooAddPdf coefficient interpretation
292 for (const auto arg : *_funcObsSet) {
293
294 RooRealVar* realObs = dynamic_cast<RooRealVar*>(arg) ;
295 if (realObs) {
296
297 observablesKnowRange |= realObs->hasRange(rangeName);
298
299 // If no explicit range is given for RooAddPdf coefficients, create explicit named range equivalent to original observables range
300 if (!(addCoefRangeName && strlen(addCoefRangeName))) {
301 realObs->setRange(Form("NormalizationRangeFor%s",rangeName),realObs->getMin(),realObs->getMax()) ;
302 }
303
304 // Adjust range of function observable to those of given named range
305 realObs->setRange(realObs->getMin(rangeName),realObs->getMax(rangeName)) ;
306
307 // Adjust range of data observable to those of given named range
308 RooRealVar* dataObs = (RooRealVar*) dataObsSet->find(realObs->GetName()) ;
309 dataObs->setRange(realObs->getMin(rangeName),realObs->getMax(rangeName)) ;
310
311 // Keep track of list of fit ranges in string attribute fit range of original p.d.f.
312 if (!_splitRange) {
313 const std::string fitRangeName = std::string("fit_") + GetName();
314 const char* origAttrib = real.getStringAttribute("fitrange") ;
315 std::string newAttr = origAttrib ? origAttrib : "";
316
317 if (newAttr.find(fitRangeName) == std::string::npos) {
318 newAttr += (newAttr.empty() ? "" : ",") + fitRangeName;
319 }
320 real.setStringAttribute("fitrange", newAttr.c_str());
321 RooRealVar* origObs = (RooRealVar*) origObsSet->find(arg->GetName()) ;
322 if (origObs) {
323 origObs->setRange(fitRangeName.c_str(), realObs->getMin(rangeName), realObs->getMax(rangeName));
324 }
325 }
326 }
327 }
328
329 if (!observablesKnowRange)
330 coutW(Fitting) << "None of the fit observables seem to know the range '" << rangeName << "'. This means that the full range will be used." << std::endl;
331 }
332 delete origObsSet ;
333
334 // If dataset is binned, activate caching of bins that are invalid because the're outside the
335 // updated range definition (WVE need to add virtual interface here)
336 RooDataHist* tmph = dynamic_cast<RooDataHist*>(_dataClone) ;
337 if (tmph) {
338 tmph->cacheValidEntries() ;
339 }
340
341 // Fix RooAddPdf coefficients to original normalization range
342 if (rangeName && strlen(rangeName)) {
343
344 // WVE Remove projected dependents from normalization
346
347 if (addCoefRangeName && strlen(addCoefRangeName)) {
348 cxcoutI(Fitting) << "RooAbsOptTestStatistic::ctor(" << GetName()
349 << ") fixing interpretation of coefficients of any RooAddPdf component to range " << addCoefRangeName << endl ;
350 _funcClone->fixAddCoefRange(addCoefRangeName,kFALSE) ;
351 } else {
352 cxcoutI(Fitting) << "RooAbsOptTestStatistic::ctor(" << GetName()
353 << ") fixing interpretation of coefficients of any RooAddPdf to full domain of observables " << endl ;
354 _funcClone->fixAddCoefRange(Form("NormalizationRangeFor%s",rangeName),kFALSE) ;
355 }
356 }
357
358
359 // This is deferred from part 2 - but must happen after part 3 - otherwise invalid bins cannot be properly marked in cacheValidEntries
362
363
364
365
366 // *********************************************************************
367 // *** PART 4 *** Adjust normalization range for projected observables *
368 // *********************************************************************
369
370 // Remove projected dependents from normalization set
371 if (projDeps.getSize()>0) {
372
373 _projDeps = (RooArgSet*) projDeps.snapshot(kFALSE) ;
374
375 //RooArgSet* tobedel = (RooArgSet*) _normSet->selectCommon(*_projDeps) ;
377
378 // Mark all projected dependents as such
380 projDataDeps->setAttribAll("projectedDependent") ;
381 delete projDataDeps ;
382 }
383
384
385 coutI(Optimization) << "RooAbsOptTestStatistic::ctor(" << GetName() << ") optimizing internal clone of p.d.f for likelihood evaluation."
386 << "Lazy evaluation and associated change tracking will disabled for all nodes that depend on observables" << endl ;
387
388
389 // *********************************************************************
390 // *** PART 4 *** Finalization and activation of optimization *
391 // *********************************************************************
392
393 //_origFunc = _func ;
394 //_origData = _data ;
395
396 // Redirect pointers of base class to clone
397 _func = _funcClone ;
398 _data = _dataClone ;
399
401
402// cout << "ROATS::ctor(" << GetName() << ") funcClone structure dump BEFORE opt" << endl ;
403// _funcClone->Print("t") ;
404
406
407
408// cout << "ROATS::ctor(" << GetName() << ") funcClone structure dump AFTER opt" << endl ;
409// _funcClone->Print("t") ;
410
411}
412
413
414////////////////////////////////////////////////////////////////////////////////
415/// Destructor
416
418{
419 if (operMode()==Slave) {
420 delete _funcClone ;
421 delete _funcObsSet ;
422 if (_projDeps) {
423 delete _projDeps ;
424 }
425 if (_ownData) {
426 delete _dataClone ;
427 }
428 }
429 delete _normSet ;
430}
431
432
433
434////////////////////////////////////////////////////////////////////////////////
435/// Method to combined test statistic results calculated into partitions into
436/// the global result. This default implementation adds the partition return
437/// values
438
440{
441 // Default implementation returns sum of components
442 Double_t sum(0), carry(0);
443 for (Int_t i = 0; i < n; ++i) {
444 Double_t y = array[i]->getValV();
445 carry += reinterpret_cast<RooAbsOptTestStatistic*>(array[i])->getCarry();
446 y -= carry;
447 const Double_t t = sum + y;
448 carry = (t - sum) - y;
449 sum = t;
450 }
451 _evalCarry = carry;
452 return sum ;
453}
454
455
456
457////////////////////////////////////////////////////////////////////////////////
458/// Catch server redirect calls and forward to internal clone of function
459
460Bool_t RooAbsOptTestStatistic::redirectServersHook(const RooAbsCollection& newServerList, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t isRecursive)
461{
462 RooAbsTestStatistic::redirectServersHook(newServerList,mustReplaceAll,nameChange,isRecursive) ;
463 if (operMode()!=Slave) return kFALSE ;
464 Bool_t ret = _funcClone->recursiveRedirectServers(newServerList,kFALSE,nameChange) ;
465 return ret ;
466}
467
468
469
470////////////////////////////////////////////////////////////////////////////////
471/// Catch print hook function and forward to function clone
472
474{
476 if (operMode()!=Slave) return ;
477 TString indent2(indent) ;
478 indent2 += "opt >>" ;
479 _funcClone->printCompactTree(os,indent2.Data()) ;
480 os << indent2 << " dataset clone = " << _dataClone << " first obs = " << _dataClone->get()->first() << endl ;
481}
482
483
484
485////////////////////////////////////////////////////////////////////////////////
486/// Driver function to propagate constant term optimizations in test statistic.
487/// If code Activate is sent, constant term optimization will be executed.
488/// If code Deactivate is sent, any existing constant term optimizations will
489/// be abandoned. If codes ConfigChange or ValueChange are sent, any existing
490/// constant term optimizations will be redone.
491
493{
494 // cout << "ROATS::constOpt(" << GetName() << ") funcClone structure dump BEFORE const-opt" << endl ;
495 // _funcClone->Print("t") ;
496
497 RooAbsTestStatistic::constOptimizeTestStatistic(opcode,doAlsoTrackingOpt);
498 if (operMode()!=Slave) return ;
499
500 if (_dataClone->hasFilledCache() && _dataClone->store()->cacheOwner()!=this) {
501 if (opcode==Activate) {
502 cxcoutW(Optimization) << "RooAbsOptTestStatistic::constOptimize(" << GetName()
503 << ") dataset cache is owned by another object, no constant term optimization can be applied" << endl ;
504 }
505 return ;
506 }
507
508 if (!allowFunctionCache()) {
509 if (opcode==Activate) {
510 cxcoutI(Optimization) << "RooAbsOptTestStatistic::constOptimize(" << GetName()
511 << ") function caching prohibited by test statistic, no constant term optimization is applied" << endl ;
512 }
513 return ;
514 }
515
516 if (_dataClone->hasFilledCache() && opcode==Activate) {
517 opcode=ValueChange ;
518 }
519
520 switch(opcode) {
521 case Activate:
522 cxcoutI(Optimization) << "RooAbsOptTestStatistic::constOptimize(" << GetName()
523 << ") optimizing evaluation of test statistic by finding all nodes in p.d.f that depend exclusively"
524 << " on observables and constant parameters and precalculating their values" << endl ;
525 optimizeConstantTerms(kTRUE,doAlsoTrackingOpt) ;
526 break ;
527
528 case DeActivate:
529 cxcoutI(Optimization) << "RooAbsOptTestStatistic::constOptimize(" << GetName()
530 << ") deactivating optimization of constant terms in test statistic" << endl ;
532 break ;
533
534 case ConfigChange:
535 cxcoutI(Optimization) << "RooAbsOptTestStatistic::constOptimize(" << GetName()
536 << ") one ore more parameter were changed from constant to floating or vice versa, "
537 << "re-evaluating constant term optimization" << endl ;
539 optimizeConstantTerms(kTRUE,doAlsoTrackingOpt) ;
540 break ;
541
542 case ValueChange:
543 cxcoutI(Optimization) << "RooAbsOptTestStatistic::constOptimize(" << GetName()
544 << ") the value of one ore more constant parameter were changed re-evaluating constant term optimization" << endl ;
545 // Request a forcible cache update of all cached nodes
547
548 break ;
549 }
550
551// cout << "ROATS::constOpt(" << GetName() << ") funcClone structure dump AFTER const-opt" << endl ;
552// _funcClone->Print("t") ;
553}
554
555
556
557////////////////////////////////////////////////////////////////////////////////
558/// This method changes the value caching logic for all nodes that depends on any of the observables
559/// as defined by the given dataset. When evaluating a test statistic constructed from the RooAbsReal
560/// with a dataset the observables are guaranteed to change with every call, thus there is no point
561/// in tracking these changes which result in a net overhead. Thus for observable-dependent nodes,
562/// the evaluation mechanism is changed from being dependent on a 'valueDirty' flag to guaranteed evaluation.
563/// On the dataset side, the observables objects are modified to no longer send valueDirty messages
564/// to their client
565
567{
568// cout << "RooAbsOptTestStatistic::optimizeCaching(" << GetName() << "," << this << ")" << endl ;
569
570 // Trigger create of all object caches now in nodes that have deferred object creation
571 // so that cache contents can be processed immediately
573
574 // Set value caching mode for all nodes that depend on any of the observables to ADirty
576
577 // Disable propagation of dirty state flags for observables
579
580 // Disable reading of observables that are not used
582}
583
584
585
586////////////////////////////////////////////////////////////////////////////////
587/// Driver function to activate global constant term optimization.
588/// If activated, constant terms are found and cached with the dataset.
589/// The operation mode of cached nodes is set to AClean meaning that
590/// their getVal() call will never result in an evaluate call.
591/// Finally the branches in the dataset that correspond to observables
592/// that are exclusively used in constant terms are disabled as
593/// they serve no more purpose
594
596{
597 if(activate) {
598
599 if (_optimized) {
600 return ;
601 }
602
603 // Trigger create of all object caches now in nodes that have deferred object creation
604 // so that cache contents can be processed immediately
606
607 // Apply tracking optimization here. Default strategy is to track components
608 // of RooAddPdfs and RooRealSumPdfs. If these components are a RooProdPdf
609 // or a RooProduct respectively, track the components of these products instead
610 // of the product term
611 RooArgSet trackNodes ;
612
613
614 // Add safety check here - applyTrackingOpt will only be applied if present
615 // dataset is constructed in terms of a RooVectorDataStore
616 if (applyTrackingOpt) {
617 if (!dynamic_cast<RooVectorDataStore*>(_dataClone->store())) {
618 coutW(Optimization) << "RooAbsOptTestStatistic::optimizeConstantTerms(" << GetName()
619 << ") WARNING Cache-and-track optimization (Optimize level 2) is only available for datasets"
620 << " implement in terms of RooVectorDataStore - ignoring this option for current dataset" << endl ;
621 applyTrackingOpt = kFALSE ;
622 }
623 }
624
625 if (applyTrackingOpt) {
626 RooArgSet branches ;
627 _funcClone->branchNodeServerList(&branches) ;
628 for (auto arg : branches) {
629 arg->setCacheAndTrackHints(trackNodes);
630 }
631 // Do not set CacheAndTrack on constant expressions
632 RooArgSet* constNodes = (RooArgSet*) trackNodes.selectByAttrib("Constant",kTRUE) ;
633 trackNodes.remove(*constNodes) ;
634 delete constNodes ;
635
636 // Set CacheAndTrack flag on all remaining nodes
637 trackNodes.setAttribAll("CacheAndTrack",kTRUE) ;
638 }
639
640 // Find all nodes that depend exclusively on constant parameters
642
644
645// cout << "ROATS::oCT(" << GetName() << ") funcClone structure dump BEFORE cacheArgs" << endl ;
646// _funcClone->Print("t") ;
647
648
649 // Cache constant nodes with dataset - also cache entries corresponding to zero-weights in data when using BinnedLikelihood
650 _dataClone->cacheArgs(this,_cachedNodes,_normSet,!_funcClone->getAttribute("BinnedLikelihood")) ;
651
652// cout << "ROATS::oCT(" << GetName() << ") funcClone structure dump AFTER cacheArgs" << endl ;
653// _funcClone->Print("t") ;
654
655
656 // Put all cached nodes in AClean value caching mode so that their evaluate() is never called
657 for (auto cacheArg : _cachedNodes) {
658 cacheArg->setOperMode(RooAbsArg::AClean) ;
659 }
660
661
662// cout << "_cachedNodes = " << endl ;
663// RooFIter i = _cachedNodes.fwdIterator() ;
664// RooAbsArg* aa ;
665// while ((aa=i.next())) {
666// cout << aa->IsA()->GetName() << "::" << aa->GetName() << (aa->getAttribute("ConstantExpressionCached")?" CEC":" ") << (aa->getAttribute("CacheAndTrack")?" CAT":" ") << endl ;
667// }
668
669 RooArgSet* constNodes = (RooArgSet*) _cachedNodes.selectByAttrib("ConstantExpressionCached",kTRUE) ;
670 RooArgSet actualTrackNodes(_cachedNodes) ;
671 actualTrackNodes.remove(*constNodes) ;
672 if (constNodes->getSize()>0) {
673 if (constNodes->getSize()<20) {
674 coutI(Minimization) << " The following expressions have been identified as constant and will be precalculated and cached: " << *constNodes << endl ;
675 } else {
676 coutI(Minimization) << " A total of " << constNodes->getSize() << " expressions have been identified as constant and will be precalculated and cached." << endl ;
677 }
678// RooFIter i = constNodes->fwdIterator() ;
679// RooAbsArg* cnode ;
680// while((cnode=i.next())) {
681// cout << cnode->IsA()->GetName() << "::" << cnode->GetName() << endl ;
682// }
683 }
684 if (actualTrackNodes.getSize()>0) {
685 if (actualTrackNodes.getSize()<20) {
686 coutI(Minimization) << " The following expressions will be evaluated in cache-and-track mode: " << actualTrackNodes << endl ;
687 } else {
688 coutI(Minimization) << " A total of " << constNodes->getSize() << " expressions will be evaluated in cache-and-track-mode." << endl ;
689 }
690 }
691 delete constNodes ;
692
693 // Disable reading of observables that are no longer used
695
696 _optimized = kTRUE ;
697
698 } else {
699
700 // Delete the cache
702
703 // Reactivate all tree branches
705
706 // Reset all nodes to ADirty
708
709 // Disable propagation of dirty state flags for observables
711
713
714
716 }
717}
718
719
720
721////////////////////////////////////////////////////////////////////////////////
722/// Change dataset that is used to given one. If cloneData is kTRUE, a clone of
723/// in the input dataset is made. If the test statistic was constructed with
724/// a range specification on the data, the cloneData argument is ignored and
725/// the data is always cloned.
727{
728
729 if (operMode()==SimMaster) {
730 //cout << "ROATS::setDataSlave() ERROR this is SimMaster _funcClone = " << _funcClone << endl ;
731 return kFALSE ;
732 }
733
734 //cout << "ROATS::setDataSlave() new dataset size = " << indata.numEntries() << endl ;
735 //indata.Print("v") ;
736
737
738 // Delete previous dataset now, if it was owned
739 if (_ownData) {
740 delete _dataClone ;
741 _dataClone = 0 ;
742 }
743
744 if (!cloneData && _rangeName.size()>0) {
745 coutW(InputArguments) << "RooAbsOptTestStatistic::setData(" << GetName() << ") WARNING: test statistic was constructed with range selection on data, "
746 << "ignoring request to _not_ clone the input dataset" << endl ;
747 cloneData = kTRUE ;
748 }
749
750 if (cloneData) {
751 // Cloning input dataset
752 if (_rangeName.size()==0) {
753 _dataClone = (RooAbsData*) indata.reduce(*indata.get()) ;
754 } else {
756 }
757 _ownData = kTRUE ;
758
759 } else {
760
761 // Taking input dataset
762 _dataClone = &indata ;
763 _ownData = ownNewData ;
764
765 }
766
767 // Attach function clone to dataset
770 _data = _dataClone ;
771
772 // ReCache constant nodes with dataset
773 if (_cachedNodes.getSize()>0) {
775 }
776
777 // Adjust internal event count
778 setEventCount(indata.numEntries()) ;
779
780 setValueDirty() ;
781
782// cout << "RAOTS::setDataSlave(" << this << ") END" << endl ;
783
784 return kTRUE ;
785}
786
787
788
789
790////////////////////////////////////////////////////////////////////////////////
791
793{
794 if (_sealed) {
795 Bool_t notice = (sealNotice() && strlen(sealNotice())) ;
796 coutW(ObjectHandling) << "RooAbsOptTestStatistic::data(" << GetName()
797 << ") WARNING: object sealed by creator - access to data is not permitted: "
798 << (notice?sealNotice():"<no user notice>") << endl ;
799 static RooDataSet dummy ("dummy","dummy",RooArgSet()) ;
800 return dummy ;
801 }
802 return *_dataClone ;
803}
804
805
806////////////////////////////////////////////////////////////////////////////////
807
809{
810 if (_sealed) {
811 Bool_t notice = (sealNotice() && strlen(sealNotice())) ;
812 coutW(ObjectHandling) << "RooAbsOptTestStatistic::data(" << GetName()
813 << ") WARNING: object sealed by creator - access to data is not permitted: "
814 << (notice?sealNotice():"<no user notice>") << endl ;
815 static RooDataSet dummy ("dummy","dummy",RooArgSet()) ;
816 return dummy ;
817 }
818 return *_dataClone ;
819}
820
821
#define e(i)
Definition: RSha256.hxx:103
static RooMathCoreReg dummy
#define coutI(a)
Definition: RooMsgService.h:30
#define cxcoutI(a)
Definition: RooMsgService.h:85
#define coutW(a)
Definition: RooMsgService.h:32
#define cxcoutW(a)
Definition: RooMsgService.h:93
#define coutE(a)
Definition: RooMsgService.h:33
int Int_t
Definition: RtypesCore.h:43
const Bool_t kFALSE
Definition: RtypesCore.h:90
bool Bool_t
Definition: RtypesCore.h:61
double Double_t
Definition: RtypesCore.h:57
const Bool_t kTRUE
Definition: RtypesCore.h:89
#define ClassImp(name)
Definition: Rtypes.h:361
static void indent(ostringstream &buf, int indent_level)
char name[80]
Definition: TGX11.cxx:109
char * Form(const char *fmt,...)
virtual RooAbsArg * cloneTree(const char *newname=0) const
Clone tree expression of objects.
Definition: RooAbsArg.cxx:2121
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Return the observables of this pdf given a set of observables.
Definition: RooAbsArg.h:276
void printCompactTree(const char *indent="", const char *fileName=0, const char *namePat=0, RooAbsArg *client=0)
Print tree structure of expression tree on stdout, or to file if filename is specified.
Definition: RooAbsArg.cxx:1745
void setStringAttribute(const Text_t *key, const Text_t *value)
Associate string 'value' to this object under key 'key'.
Definition: RooAbsArg.cxx:289
Bool_t findConstantNodes(const RooArgSet &observables, RooArgSet &cacheList)
Find branch nodes with all-constant parameters, and add them to the list of nodes that can be cached ...
Definition: RooAbsArg.cxx:1612
friend class RooArgSet
Definition: RooAbsArg.h:572
const Text_t * getStringAttribute(const Text_t *key) const
Get string attribute mapped under key 'key'.
Definition: RooAbsArg.cxx:302
RooArgSet * getParameters(const RooAbsData *data, Bool_t stripDisconnected=kTRUE) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don't match any of...
Definition: RooAbsArg.cxx:544
void setAttribute(const Text_t *name, Bool_t value=kTRUE)
Set (default) or clear a named boolean attribute of this object.
Definition: RooAbsArg.cxx:257
void setValueDirty()
Mark the element dirty. This forces a re-evaluation when a value is requested.
Definition: RooAbsArg.h:487
virtual void optimizeCacheMode(const RooArgSet &observables)
Activate cache mode optimization with given definition of observables.
Definition: RooAbsArg.cxx:1549
@ DeActivate
Definition: RooAbsArg.h:374
@ ValueChange
Definition: RooAbsArg.h:374
@ ConfigChange
Definition: RooAbsArg.h:374
Bool_t getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
Definition: RooAbsArg.cxx:280
void branchNodeServerList(RooAbsCollection *list, const RooAbsArg *arg=0, Bool_t recurseNonDerived=kFALSE) const
Fill supplied list with all branch nodes of the arg tree starting with ourself as top node.
Definition: RooAbsArg.cxx:486
Bool_t recursiveRedirectServers(const RooAbsCollection &newServerList, Bool_t mustReplaceAll=kFALSE, Bool_t nameChange=kFALSE, Bool_t recurseInNewSet=kTRUE)
Definition: RooAbsArg.cxx:1064
virtual RooAbsReal * highBoundFunc() const
Definition: RooAbsBinning.h:87
virtual RooAbsReal * lowBoundFunc() const
Definition: RooAbsBinning.h:83
RooAbsCollection is an abstract container object that can hold multiple RooAbsArg objects.
virtual void removeAll()
Remove all arguments from our set, deleting them if we own them.
RooAbsCollection * selectCommon(const RooAbsCollection &refColl) const
Create a subset of the current collection, consisting only of those elements that are contained as we...
Int_t getSize() const
Storage_t::size_type size() const
RooAbsArg * first() const
void setAttribAll(const Text_t *name, Bool_t value=kTRUE)
Set given attribute in each element of the collection by calling each elements setAttribute() functio...
RooAbsCollection * selectByAttrib(const char *name, Bool_t value) const
Create a subset of the current collection, consisting only of those elements with the specified attri...
virtual Bool_t remove(const RooAbsArg &var, Bool_t silent=kFALSE, Bool_t matchByNameOnly=kFALSE)
Remove the specified argument from our list.
RooAbsArg * find(const char *name) const
Find object with given name in list.
virtual const RooAbsArg * cacheOwner()=0
virtual void forceCacheUpdate()
RooAbsData is the common abstract base class for binned and unbinned datasets.
Definition: RooAbsData.h:44
virtual const RooArgSet * get() const
Definition: RooAbsData.h:87
RooAbsDataStore * store()
Definition: RooAbsData.h:63
virtual void optimizeReadingWithCaching(RooAbsArg &arg, const RooArgSet &cacheList, const RooArgSet &keepObsList)
Prepare dataset for use with cached constant terms listed in 'cacheList' of expression 'arg'.
RooAbsData * reduce(const RooCmdArg &arg1, const RooCmdArg &arg2=RooCmdArg(), const RooCmdArg &arg3=RooCmdArg(), const RooCmdArg &arg4=RooCmdArg(), const RooCmdArg &arg5=RooCmdArg(), const RooCmdArg &arg6=RooCmdArg(), const RooCmdArg &arg7=RooCmdArg(), const RooCmdArg &arg8=RooCmdArg())
Create a reduced copy of this dataset.
Definition: RooAbsData.cxx:381
virtual Int_t numEntries() const
Definition: RooAbsData.cxx:306
virtual void resetCache()
Internal method – Remove cached function values.
Definition: RooAbsData.cxx:337
Bool_t hasFilledCache() const
virtual void cacheArgs(const RooAbsArg *owner, RooArgSet &varSet, const RooArgSet *nset=0, Bool_t skipZeroWeights=kFALSE)
Internal method – Cache given set of functions with data.
Definition: RooAbsData.cxx:329
void attachBuffers(const RooArgSet &extObs)
virtual void setArgStatus(const RooArgSet &set, Bool_t active)
Definition: RooAbsData.cxx:353
void setDirtyProp(Bool_t flag)
Control propagation of dirty flags from observables in dataset.
Definition: RooAbsData.cxx:361
RooAbsOptTestStatistic is the abstract base class for test statistics objects that evaluate a functio...
virtual ~RooAbsOptTestStatistic()
Destructor.
RooAbsReal * _origFunc
List of nodes that are cached as constant expressions.
void optimizeCaching()
This method changes the value caching logic for all nodes that depends on any of the observables as d...
const char * sealNotice() const
void optimizeConstantTerms(Bool_t, Bool_t=kTRUE)
Driver function to activate global constant term optimization.
virtual Bool_t allowFunctionCache()
virtual Bool_t redirectServersHook(const RooAbsCollection &newServerList, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t isRecursive)
Catch server redirect calls and forward to internal clone of function.
virtual void printCompactTreeHook(std::ostream &os, const char *indent="")
Catch print hook function and forward to function clone.
void initSlave(RooAbsReal &real, RooAbsData &indata, const RooArgSet &projDeps, const char *rangeName, const char *addCoefRangeName)
virtual Double_t combinedValue(RooAbsReal **gofArray, Int_t nVal) const
Method to combined test statistic results calculated into partitions into the global result.
virtual RooArgSet requiredExtraObservables() const
RooAbsOptTestStatistic()
Default Constructor.
Bool_t setDataSlave(RooAbsData &data, Bool_t cloneData=kTRUE, Bool_t ownNewDataAnyway=kFALSE)
Change dataset that is used to given one.
void constOptimizeTestStatistic(ConstOpCode opcode, Bool_t doAlsoTrackingOpt=kTRUE)
Driver function to propagate constant term optimizations in test statistic.
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
virtual Double_t getMax(const char *name=0) const
Get maximum of currently defined range.
virtual Bool_t hasRange(const char *name) const
Check if variable has a binning with given name.
virtual Double_t getMin(const char *name=0) const
Get miniminum of currently defined range.
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:60
virtual void fixAddCoefRange(const char *rangeName=0, Bool_t force=kTRUE)
Fix the interpretation of the coefficient of any RooAddPdf component in the expression tree headed by...
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:90
virtual Double_t getValV(const RooArgSet *normalisationSet=nullptr) const
Return value of object.
Definition: RooAbsReal.cxx:270
virtual void fixAddCoefNormalization(const RooArgSet &addNormSet=RooArgSet(), Bool_t force=kTRUE)
Fix the interpretation of the coefficient of any RooAddPdf component in the expression tree headed by...
RooAbsTestStatistic is the abstract base class for all test statistics.
GOFOpMode operMode() const
virtual void constOptimizeTestStatistic(ConstOpCode opcode, Bool_t doAlsoTrackingOpt=kTRUE)
Forward constant term optimization management calls to component test statistics.
virtual Bool_t redirectServersHook(const RooAbsCollection &newServerList, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t isRecursive)
Forward server redirect calls to component test statistics.
void setEventCount(Int_t nEvents)
virtual Double_t getCarry() const
Double_t _evalCarry
avoids loss of precision
virtual void printCompactTreeHook(std::ostream &os, const char *indent="")
Add extra information on component test statistics when printing itself as part of a tree structure.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:28
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition: RooArgSet.h:126
virtual Bool_t add(const RooAbsCollection &col, Bool_t silent=kFALSE)
Add a collection of arguments to this collection by calling add() for each element in the source coll...
Definition: RooArgSet.h:88
The RooDataHist is a container class to hold N-dimensional binned data.
Definition: RooDataHist.h:40
void cacheValidEntries()
Cache the datahist entries with bin centers that are inside/outside the current observable definitio.
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:33
static void softAbort()
RooProdPdf is an efficient implementation of a product of PDFs of the form.
Definition: RooProdPdf.h:31
RooArgSet * getConnectedParameters(const RooArgSet &observables) const
Return all parameter constraint p.d.f.s on parameters listed in constrainedParams.
RooRealVar represents a variable that can be changed from the outside.
Definition: RooRealVar.h:35
void setRange(const char *name, Double_t min, Double_t max)
Set a fit or plotting range.
Definition: RooRealVar.cxx:495
const RooAbsBinning & getBinning(const char *name=0, Bool_t verbose=kTRUE, Bool_t createOnTheFly=kFALSE) const
Return binning definition with name.
Definition: RooRealVar.cxx:287
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Overloaded RooArgSet::add() method inserts 'var' into set and registers 'var' as server to owner with...
virtual void removeAll()
Remove all argument inset using remove(const RooAbsArg&).
RooVectorDataStore is the abstract base class for data collection that use a TTree as internal storag...
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:74
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Basic string class.
Definition: TString.h:131
const char * Data() const
Definition: TString.h:364
RooCmdArg SelectVars(const RooArgSet &vars)
RooCmdArg CutRange(const char *rangeName)
Double_t y[n]
Definition: legend1.C:17
const Int_t n
Definition: legend1.C:16
@ Minimization
Definition: RooGlobalFunc.h:67
@ Optimization
Definition: RooGlobalFunc.h:68
@ InputArguments
Definition: RooGlobalFunc.h:68
@ ObjectHandling
Definition: RooGlobalFunc.h:68
static long int sum(long int i)
Definition: Factory.cxx:2275