Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
39
40#include "Riostream.h"
41#include "TClass.h"
42#include <cstring>
43
44#include "RooAbsData.h"
45#include "RooAbsDataStore.h"
46#include "RooAbsPdf.h"
47#include "RooAddPdf.h"
48#include "RooArgSet.h"
49#include "RooBinSamplingPdf.h"
50#include "RooBinning.h"
51#include "RooCategory.h"
52#include "RooDataHist.h"
53#include "RooDataSet.h"
54#include "RooErrorHandler.h"
55#include "RooFitImplHelpers.h"
56#include "RooGlobalFunc.h"
57#include "RooMsgService.h"
58#include "RooProdPdf.h"
59#include "RooProduct.h"
60#include "RooRealSumPdf.h"
61#include "RooRealVar.h"
62#include "RooTrace.h"
63#include "RooVectorDataStore.h"
64
65#include "ROOT/StringUtils.hxx"
66
67using namespace std;
68
70
71
72////////////////////////////////////////////////////////////////////////////////
73/// Create a test statistic, and optimise its calculation.
74/// \param[in] name Name of the instance.
75/// \param[in] title Title (for e.g. plotting).
76/// \param[in] real Function to evaluate.
77/// \param[in] indata Dataset for which to compute test statistic.
78/// \param[in] projDeps A set of projected observables.
79/// \param[in] cfg the statistic configuration
80///
81/// cfg contains:
82/// - rangeName If not null, only events in the dataset inside the range will be used in the test
83/// statistic calculation.
84/// - addCoefRangeName If not null, all RooAddPdf components of `real` will be
85/// instructed to fix their fraction definitions to the given named range.
86/// - nCPU If > 1, the test statistic calculation will be parallelised over multiple processes. By default, the data
87/// is split with 'bulk' partitioning (each process calculates a contiguous block of fraction 1/nCPU
88/// of the data). For binned data, this approach may be suboptimal as the number of bins with >0 entries
89/// in each processing block may vary greatly; thereby distributing the workload rather unevenly.
90/// - interleave Strategy how to distribute events among workers. If an interleave partitioning strategy is used where each partition
91/// i takes all bins for which (ibin % ncpu == i), an even distribution of work is more likely.
92/// - splitCutRange If true, a different rangeName constructed as `rangeName_{catName}` will be used
93/// as range definition for each index state of a RooSimultaneous.
94/// - cloneInputData Not used. Data is always cloned.
95/// - integrateOverBinsPrecision If > 0, PDF in binned fits are integrated over the bins. This sets the precision. If = 0,
96/// only unbinned PDFs fit to RooDataHist are integrated. If < 0, PDFs are never integrated.
98 RooAbsData &indata, const RooArgSet &projDeps,
100 : RooAbsTestStatistic(name, title, real, indata, projDeps, cfg),
101 _integrateBinsPrecision(cfg.integrateOverBinsPrecision)
102{
103 // Don't do a thing in master mode
104 if (operMode() != Slave) {
105 return;
106 }
107
108 initSlave(real, indata, projDeps, _rangeName.c_str(), _addCoefRangeName.c_str());
109}
110
111////////////////////////////////////////////////////////////////////////////////
112/// Copy constructor
113
115 : RooAbsTestStatistic(other, name),
116 _sealed(other._sealed),
117 _sealNotice(other._sealNotice),
118 _skipZeroWeights(other._skipZeroWeights),
119 _integrateBinsPrecision(other._integrateBinsPrecision)
120{
121 // Don't do a thing in master mode
122 if (operMode() != Slave) {
123
124 if (other._normSet) {
125 _normSet = new RooArgSet;
126 other._normSet->snapshot(*_normSet);
127 }
128 return;
129 }
130
131 initSlave(*other._funcClone, *other._dataClone, other._projDeps ? *other._projDeps : RooArgSet(),
132 other._rangeName.c_str(), other._addCoefRangeName.c_str());
133}
134
135
136
137////////////////////////////////////////////////////////////////////////////////
138
139void RooAbsOptTestStatistic::initSlave(RooAbsReal& real, RooAbsData& indata, const RooArgSet& projDeps, const char* rangeName,
140 const char* addCoefRangeName) {
141 // ******************************************************************
142 // *** PART 1 *** Clone incoming pdf, attach to each other *
143 // ******************************************************************
144
145 // Clone FUNC
146 _funcClone = RooHelpers::cloneTreeWithSameParameters(real, indata.get()).release();
147 _funcCloneSet = nullptr ;
148
149 // Attach FUNC to data set
150 _funcObsSet = std::unique_ptr<RooArgSet>{_funcClone->getObservables(indata)}.release();
151
152 if (_funcClone->getAttribute("BinnedLikelihood")) {
153 _funcClone->setAttribute("BinnedLikelihoodActive") ;
154 }
155
156 // Mark all projected dependents as such
157 if (!projDeps.empty()) {
158 std::unique_ptr<RooArgSet> projDataDeps{static_cast<RooArgSet*>(_funcObsSet->selectCommon(projDeps))};
159 projDataDeps->setAttribAll("projectedDependent") ;
160 }
161
162 // If PDF is a RooProdPdf (with possible constraint terms)
163 // analyze pdf for actual parameters (i.e those in unconnected constraint terms should be
164 // ignored as here so that the test statistic will not be recalculated if those
165 // are changed
166 RooProdPdf* pdfWithCons = dynamic_cast<RooProdPdf*>(_funcClone) ;
167 if (pdfWithCons) {
168
169 std::unique_ptr<RooArgSet> connPars{pdfWithCons->getConnectedParameters(*indata.get())};
170 // Add connected parameters as servers
171 _paramSet.add(*connPars) ;
172
173 } else {
174 // Add parameters as servers
176 }
177
178 // Store normalization set
179 _normSet = new RooArgSet;
180 indata.get()->snapshot(*_normSet, false);
181
182 // Expand list of observables with any observables used in parameterized ranges.
183 // This NEEDS to be a counting loop since we are inserting during the loop.
184 for (std::size_t i = 0; i < _funcObsSet->size(); ++i) {
185 auto realDepRLV = dynamic_cast<const RooAbsRealLValue*>((*_funcObsSet)[i]);
186 if (realDepRLV && realDepRLV->isDerived()) {
187 RooArgSet tmp2;
188 realDepRLV->leafNodeServerList(&tmp2, nullptr, true);
189 _funcObsSet->add(tmp2,true);
190 }
191 }
192
193
194
195 // ******************************************************************
196 // *** PART 2 *** Clone and adjust incoming data, attach to PDF *
197 // ******************************************************************
198
199 // Check if the fit ranges of the dependents in the data and in the FUNC are consistent
200 const RooArgSet* dataDepSet = indata.get() ;
201 for (const auto arg : *_funcObsSet) {
202
203 // Check that both dataset and function argument are of type RooRealVar
204 RooRealVar* realReal = dynamic_cast<RooRealVar*>(arg) ;
205 if (!realReal) continue ;
206 RooRealVar* datReal = dynamic_cast<RooRealVar*>(dataDepSet->find(realReal->GetName())) ;
207 if (!datReal) continue ;
208
209 // Check that range of observables in pdf is equal or contained in range of observables in data
210
211 if (!realReal->getBinning().lowBoundFunc() && realReal->getMin()<(datReal->getMin()-1e-6)) {
212 coutE(InputArguments) << "RooAbsOptTestStatistic: ERROR minimum of FUNC observable " << arg->GetName()
213 << "(" << realReal->getMin() << ") is smaller than that of "
214 << arg->GetName() << " in the dataset (" << datReal->getMin() << ")" << endl ;
216 return ;
217 }
218
219 if (!realReal->getBinning().highBoundFunc() && realReal->getMax()>(datReal->getMax()+1e-6)) {
220 coutE(InputArguments) << "RooAbsOptTestStatistic: ERROR maximum of FUNC observable " << arg->GetName()
221 << " is larger than that of " << arg->GetName() << " in the dataset" << endl ;
223 return ;
224 }
225 }
226
227 // Copy data and strip entries lost by adjusted fit range, _dataClone ranges will be copied from realDepSet ranges
228 if (rangeName && strlen(rangeName)) {
229 _dataClone = std::unique_ptr<RooAbsData>{indata.reduce(RooFit::SelectVars(*_funcObsSet),RooFit::CutRange(rangeName))}.release();
230 // cout << "RooAbsOptTestStatistic: reducing dataset to fit in range named " << rangeName << " resulting dataset has " << _dataClone->sumEntries() << " events" << endl ;
231 } else {
232 _dataClone = (RooAbsData*) indata.Clone() ;
233 }
234 _ownData = true ;
235
236
237 // ******************************************************************
238 // *** PART 3 *** Make adjustments for fit ranges, if specified *
239 // ******************************************************************
240
241 std::unique_ptr<RooArgSet> origObsSet( real.getObservables(indata) );
242 if (rangeName && strlen(rangeName)) {
243 cxcoutI(Fitting) << "RooAbsOptTestStatistic::ctor(" << GetName() << ") constructing test statistic for sub-range named " << rangeName << endl ;
244
245 if(auto pdfClone = dynamic_cast<RooAbsPdf*>(_funcClone)) {
246 pdfClone->setNormRange(rangeName);
247 }
248
249 // Print warnings if the requested ranges are not available for the observable
250 for (const auto arg : *_funcObsSet) {
251
252 if (auto realObs = dynamic_cast<RooRealVar*>(arg)) {
253
254 auto tokens = ROOT::Split(rangeName, ",");
255 for(std::string const& token : tokens) {
256 if(!realObs->hasRange(token.c_str())) {
257 std::stringstream errMsg;
258 errMsg << "The observable \"" << realObs->GetName() << "\" doesn't define the requested range \""
259 << token << "\". Replacing it with the default range." << std::endl;
260 coutI(Fitting) << errMsg.str() << std::endl;
261 }
262 }
263 }
264 }
265 }
266
267
268 // ******************************************************************
269 // *** PART 3.2 *** Binned fits *
270 // ******************************************************************
271
273
274
275 // Fix RooAddPdf coefficients to original normalization range
276 if (rangeName && strlen(rangeName)) {
277
278 // WVE Remove projected dependents from normalization
280
281 if (addCoefRangeName && strlen(addCoefRangeName)) {
282 cxcoutI(Fitting) << "RooAbsOptTestStatistic::ctor(" << GetName()
283 << ") fixing interpretation of coefficients of any RooAddPdf component to range " << addCoefRangeName << endl ;
284 _funcClone->fixAddCoefRange(addCoefRangeName,false) ;
285 }
286 }
287
288
289 // This is deferred from part 2 - but must happen after part 3 - otherwise invalid bins cannot be properly marked in cacheValidEntries
292
293
294
295
296 // *********************************************************************
297 // *** PART 4 *** Adjust normalization range for projected observables *
298 // *********************************************************************
299
300 // Remove projected dependents from normalization set
301 if (projDeps.getSize()>0) {
302
303 _projDeps = new RooArgSet;
304 projDeps.snapshot(*_projDeps, false) ;
305
306 //RooArgSet* tobedel = (RooArgSet*) _normSet->selectCommon(*_projDeps) ;
307 _normSet->remove(*_projDeps,true,true) ;
308
309 // Mark all projected dependents as such
310 RooArgSet projDataDeps;
311 _funcObsSet->selectCommon(*_projDeps, projDataDeps);
312 projDataDeps.setAttribAll("projectedDependent") ;
313 }
314
315
316 coutI(Optimization) << "RooAbsOptTestStatistic::ctor(" << GetName() << ") optimizing internal clone of p.d.f for likelihood evaluation."
317 << "Lazy evaluation and associated change tracking will disabled for all nodes that depend on observables" << endl ;
318
319
320 // *********************************************************************
321 // *** PART 4 *** Finalization and activation of optimization *
322 // *********************************************************************
323
324 // Redirect pointers of base class to clone
325 _func = _funcClone ;
326 _data = _dataClone ;
327
329
331
332 // It would be unusual if the global observables are used in the likelihood
333 // outside of the constraint terms, but if they are we have to be consistent
334 // and also redirect them to the snapshots in the dataset if appropriate.
337 }
338
339}
340
341
342////////////////////////////////////////////////////////////////////////////////
343/// Destructor
344
346{
347 if (operMode()==Slave) {
348 delete _funcClone ;
349 delete _funcObsSet ;
350 if (_projDeps) {
351 delete _projDeps ;
352 }
353 if (_ownData) {
354 delete _dataClone ;
355 }
356 }
357 delete _normSet ;
358}
359
360
361
362////////////////////////////////////////////////////////////////////////////////
363/// Method to combined test statistic results calculated into partitions into
364/// the global result. This default implementation adds the partition return
365/// values
366
368{
369 // Default implementation returns sum of components
370 double sum(0), carry(0);
371 for (Int_t i = 0; i < n; ++i) {
372 double y = array[i]->getValV();
373 carry += reinterpret_cast<RooAbsOptTestStatistic*>(array[i])->getCarry();
374 y -= carry;
375 const double t = sum + y;
376 carry = (t - sum) - y;
377 sum = t;
378 }
379 _evalCarry = carry;
380 return sum ;
381}
382
383
384
385////////////////////////////////////////////////////////////////////////////////
386/// Catch server redirect calls and forward to internal clone of function
387
388bool RooAbsOptTestStatistic::redirectServersHook(const RooAbsCollection& newServerList, bool mustReplaceAll, bool nameChange, bool isRecursive)
389{
390 RooAbsTestStatistic::redirectServersHook(newServerList,mustReplaceAll,nameChange,isRecursive) ;
391 if (operMode()!=Slave) return false ;
392 bool ret = _funcClone->recursiveRedirectServers(newServerList,false,nameChange) ;
393 return ret || RooAbsReal::redirectServersHook(newServerList, mustReplaceAll, nameChange, isRecursive);
394}
395
396
397
398////////////////////////////////////////////////////////////////////////////////
399/// Catch print hook function and forward to function clone
400
402{
404 if (operMode()!=Slave) return ;
405 TString indent2(indent) ;
406 indent2 += "opt >>" ;
407 _funcClone->printCompactTree(os,indent2.Data()) ;
408 os << indent2 << " dataset clone = " << _dataClone << " first obs = " << _dataClone->get()->first() << endl ;
409}
410
411
412
413////////////////////////////////////////////////////////////////////////////////
414/// Driver function to propagate constant term optimizations in test statistic.
415/// If code Activate is sent, constant term optimization will be executed.
416/// If code Deactivate is sent, any existing constant term optimizations will
417/// be abandoned. If codes ConfigChange or ValueChange are sent, any existing
418/// constant term optimizations will be redone.
419
421{
422 // cout << "ROATS::constOpt(" << GetName() << ") funcClone structure dump BEFORE const-opt" << endl ;
423 // _funcClone->Print("t") ;
424
425 RooAbsTestStatistic::constOptimizeTestStatistic(opcode,doAlsoTrackingOpt);
426 if (operMode()!=Slave) return ;
427
428 if (_dataClone->hasFilledCache() && _dataClone->store()->cacheOwner()!=this) {
429 if (opcode==Activate) {
430 cxcoutW(Optimization) << "RooAbsOptTestStatistic::constOptimize(" << GetName()
431 << ") dataset cache is owned by another object, no constant term optimization can be applied" << endl ;
432 }
433 return ;
434 }
435
436 if (!allowFunctionCache()) {
437 if (opcode==Activate) {
438 cxcoutI(Optimization) << "RooAbsOptTestStatistic::constOptimize(" << GetName()
439 << ") function caching prohibited by test statistic, no constant term optimization is applied" << endl ;
440 }
441 return ;
442 }
443
444 if (_dataClone->hasFilledCache() && opcode==Activate) {
445 opcode=ValueChange ;
446 }
447
448 switch(opcode) {
449 case Activate:
450 cxcoutI(Optimization) << "RooAbsOptTestStatistic::constOptimize(" << GetName()
451 << ") optimizing evaluation of test statistic by finding all nodes in p.d.f that depend exclusively"
452 << " on observables and constant parameters and precalculating their values" << endl ;
453 optimizeConstantTerms(true,doAlsoTrackingOpt) ;
454 break ;
455
456 case DeActivate:
457 cxcoutI(Optimization) << "RooAbsOptTestStatistic::constOptimize(" << GetName()
458 << ") deactivating optimization of constant terms in test statistic" << endl ;
459 optimizeConstantTerms(false) ;
460 break ;
461
462 case ConfigChange:
463 cxcoutI(Optimization) << "RooAbsOptTestStatistic::constOptimize(" << GetName()
464 << ") one ore more parameter were changed from constant to floating or vice versa, "
465 << "re-evaluating constant term optimization" << endl ;
466 optimizeConstantTerms(false) ;
467 optimizeConstantTerms(true,doAlsoTrackingOpt) ;
468 break ;
469
470 case ValueChange:
471 cxcoutI(Optimization) << "RooAbsOptTestStatistic::constOptimize(" << GetName()
472 << ") the value of one ore more constant parameter were changed re-evaluating constant term optimization" << endl ;
473 // Request a forcible cache update of all cached nodes
475
476 break ;
477 }
478
479// cout << "ROATS::constOpt(" << GetName() << ") funcClone structure dump AFTER const-opt" << endl ;
480// _funcClone->Print("t") ;
481}
482
483
484
485////////////////////////////////////////////////////////////////////////////////
486/// This method changes the value caching logic for all nodes that depends on any of the observables
487/// as defined by the given dataset. When evaluating a test statistic constructed from the RooAbsReal
488/// with a dataset the observables are guaranteed to change with every call, thus there is no point
489/// in tracking these changes which result in a net overhead. Thus for observable-dependent nodes,
490/// the evaluation mechanism is changed from being dependent on a 'valueDirty' flag to guaranteed evaluation.
491/// On the dataset side, the observables objects are modified to no longer send valueDirty messages
492/// to their client
493
495{
496// cout << "RooAbsOptTestStatistic::optimizeCaching(" << GetName() << "," << this << ")" << endl ;
497
498 // Trigger create of all object caches now in nodes that have deferred object creation
499 // so that cache contents can be processed immediately
501
502 // Set value caching mode for all nodes that depend on any of the observables to ADirty
504
505 // Disable propagation of dirty state flags for observables
506 _dataClone->setDirtyProp(false) ;
507
508 // Disable reading of observables that are not used
510}
511
512
513
514////////////////////////////////////////////////////////////////////////////////
515/// Driver function to activate global constant term optimization.
516/// If activated, constant terms are found and cached with the dataset.
517/// The operation mode of cached nodes is set to AClean meaning that
518/// their getVal() call will never result in an evaluate call.
519/// Finally the branches in the dataset that correspond to observables
520/// that are exclusively used in constant terms are disabled as
521/// they serve no more purpose
522
523void RooAbsOptTestStatistic::optimizeConstantTerms(bool activate, bool applyTrackingOpt)
524{
525 if(activate) {
526
527 if (_optimized) {
528 return ;
529 }
530
531 // Trigger create of all object caches now in nodes that have deferred object creation
532 // so that cache contents can be processed immediately
534
535
536 // WVE - Patch to allow customization of optimization level per component pdf
537 if (_funcClone->getAttribute("NoOptimizeLevel1")) {
538 coutI(Minimization) << " Optimization customization: Level-1 constant-term optimization prohibited by attribute NoOptimizeLevel1 set on top-level pdf "
539 << _funcClone->ClassName() << "::" << _funcClone->GetName() << endl ;
540 return ;
541 }
542 if (_funcClone->getAttribute("NoOptimizeLevel2")) {
543 coutI(Minimization) << " Optimization customization: Level-2 constant-term optimization prohibited by attribute NoOptimizeLevel2 set on top-level pdf "
544 << _funcClone->ClassName() << "::" << _funcClone->GetName() << endl ;
545 applyTrackingOpt=false ;
546 }
547
548 // Apply tracking optimization here. Default strategy is to track components
549 // of RooAddPdfs and RooRealSumPdfs. If these components are a RooProdPdf
550 // or a RooProduct respectively, track the components of these products instead
551 // of the product term
552 RooArgSet trackNodes ;
553
554
555 // Add safety check here - applyTrackingOpt will only be applied if present
556 // dataset is constructed in terms of a RooVectorDataStore
557 if (applyTrackingOpt) {
558 if (!dynamic_cast<RooVectorDataStore*>(_dataClone->store())) {
559 coutW(Optimization) << "RooAbsOptTestStatistic::optimizeConstantTerms(" << GetName()
560 << ") WARNING Cache-and-track optimization (Optimize level 2) is only available for datasets"
561 << " implement in terms of RooVectorDataStore - ignoring this option for current dataset" << endl ;
562 applyTrackingOpt = false ;
563 }
564 }
565
566 if (applyTrackingOpt) {
567 RooArgSet branches ;
568 _funcClone->branchNodeServerList(&branches) ;
569 for (auto arg : branches) {
570 arg->setCacheAndTrackHints(trackNodes);
571 }
572 // Do not set CacheAndTrack on constant expressions
573 RooArgSet* constNodes = (RooArgSet*) trackNodes.selectByAttrib("Constant",true) ;
574 trackNodes.remove(*constNodes) ;
575 delete constNodes ;
576
577 // Set CacheAndTrack flag on all remaining nodes
578 trackNodes.setAttribAll("CacheAndTrack",true) ;
579 }
580
581 // Find all nodes that depend exclusively on constant parameters
583
585
586 // Cache constant nodes with dataset - also cache entries corresponding to zero-weights in data when using BinnedLikelihood
588
589 // Put all cached nodes in AClean value caching mode so that their evaluate() is never called
590 for (auto cacheArg : _cachedNodes) {
591 cacheArg->setOperMode(RooAbsArg::AClean) ;
592 }
593
594 RooArgSet* constNodes = (RooArgSet*) _cachedNodes.selectByAttrib("ConstantExpressionCached",true) ;
595 RooArgSet actualTrackNodes(_cachedNodes) ;
596 actualTrackNodes.remove(*constNodes) ;
597 if (constNodes->getSize()>0) {
598 if (constNodes->getSize()<20) {
599 coutI(Minimization) << " The following expressions have been identified as constant and will be precalculated and cached: " << *constNodes << endl ;
600 } else {
601 coutI(Minimization) << " A total of " << constNodes->getSize() << " expressions have been identified as constant and will be precalculated and cached." << endl ;
602 }
603 }
604 if (actualTrackNodes.getSize()>0) {
605 if (actualTrackNodes.getSize()<20) {
606 coutI(Minimization) << " The following expressions will be evaluated in cache-and-track mode: " << actualTrackNodes << endl ;
607 } else {
608 coutI(Minimization) << " A total of " << constNodes->getSize() << " expressions will be evaluated in cache-and-track-mode." << endl ;
609 }
610 }
611 delete constNodes ;
612
613 // Disable reading of observables that are no longer used
615
616 _optimized = true ;
617
618 } else {
619
620 // Delete the cache
622
623 // Reactivate all tree branches
625
626 // Reset all nodes to ADirty
628
629 // Disable propagation of dirty state flags for observables
630 _dataClone->setDirtyProp(false) ;
631
633
634
635 _optimized = false ;
636 }
637}
638
639
640
641////////////////////////////////////////////////////////////////////////////////
642/// Change dataset that is used to given one. If cloneData is true, a clone of
643/// in the input dataset is made. If the test statistic was constructed with
644/// a range specification on the data, the cloneData argument is ignored and
645/// the data is always cloned.
646bool RooAbsOptTestStatistic::setDataSlave(RooAbsData& indata, bool cloneData, bool ownNewData)
647{
648
649 if (operMode()==SimMaster) {
650 //cout << "ROATS::setDataSlave() ERROR this is SimMaster _funcClone = " << _funcClone << endl ;
651 return false ;
652 }
653
654 //cout << "ROATS::setDataSlave() new dataset size = " << indata.numEntries() << endl ;
655 //indata.Print("v") ;
656
657
658 // If the current dataset is owned, transfer the ownership to unique pointer
659 // that will get out of scope at the end of this function. We can't delete it
660 // right now, because there might be global observables in the model that
661 // first need to be redirected to the new dataset with a later call to
662 // RooAbsArg::recursiveRedirectServers.
663 std::unique_ptr<RooAbsData> oldOwnedData;
664 if (_ownData) {
665 oldOwnedData.reset(_dataClone);
666 _dataClone = nullptr ;
667 }
668
669 if (!cloneData && !_rangeName.empty()) {
670 coutW(InputArguments) << "RooAbsOptTestStatistic::setData(" << GetName() << ") WARNING: test statistic was constructed with range selection on data, "
671 << "ignoring request to _not_ clone the input dataset" << endl ;
672 cloneData = true ;
673 }
674
675 if (cloneData) {
676 // Cloning input dataset
677 if (_rangeName.empty()) {
678 _dataClone = std::unique_ptr<RooAbsData>{indata.reduce(*indata.get())}.release();
679 } else {
680 _dataClone = std::unique_ptr<RooAbsData>{indata.reduce(RooFit::SelectVars(*indata.get()),RooFit::CutRange(_rangeName.c_str()))}.release();
681 }
682 _ownData = true ;
683
684 } else {
685
686 // Taking input dataset
687 _dataClone = &indata ;
688 _ownData = ownNewData ;
689
690 }
691
692 // Attach function clone to dataset
694 _dataClone->setDirtyProp(false) ;
695 _data = _dataClone ;
696
697 // ReCache constant nodes with dataset
698 if (!_cachedNodes.empty()) {
700 }
701
702 // Adjust internal event count
703 setEventCount(indata.numEntries()) ;
704
705 setValueDirty() ;
706
707 // It would be unusual if the global observables are used in the likelihood
708 // outside of the constraint terms, but if they are we have to be consistent
709 // and also redirect them to the snapshots in the dataset if appropriate.
712 }
713
714 return true ;
715}
716
717
718
719
720////////////////////////////////////////////////////////////////////////////////
721
723{
724 if (_sealed) {
725 bool notice = (sealNotice() && strlen(sealNotice())) ;
726 coutW(ObjectHandling) << "RooAbsOptTestStatistic::data(" << GetName()
727 << ") WARNING: object sealed by creator - access to data is not permitted: "
728 << (notice?sealNotice():"<no user notice>") << endl ;
729 static RooDataSet dummy ("dummy","dummy",RooArgSet()) ;
730 return dummy ;
731 }
732 return *_dataClone ;
733}
734
735
736////////////////////////////////////////////////////////////////////////////////
737
739{
740 if (_sealed) {
741 bool notice = (sealNotice() && strlen(sealNotice())) ;
742 coutW(ObjectHandling) << "RooAbsOptTestStatistic::data(" << GetName()
743 << ") WARNING: object sealed by creator - access to data is not permitted: "
744 << (notice?sealNotice():"<no user notice>") << endl ;
745 static RooDataSet dummy ("dummy","dummy",RooArgSet()) ;
746 return dummy ;
747 }
748 return *_dataClone ;
749}
750
751
752////////////////////////////////////////////////////////////////////////////////
753/// Inspect PDF to find out if we are doing a binned fit to a 1-dimensional unbinned PDF.
754/// If this is the case, enable finer sampling of bins by wrapping PDF into a RooBinSamplingPdf.
755/// The member _integrateBinsPrecision decides how we act:
756/// - < 0: Don't do anything.
757/// - = 0: Only enable feature if fitting unbinned PDF to RooDataHist.
758/// - > 0: Enable as requested.
760
761 auto& pdf = static_cast<RooAbsPdf&>(*_funcClone);
764 _funcClone = newPdf.release();
765 }
766
767}
768
769
770/// Returns a suffix string that is unique for RooAbsOptTestStatistic
771/// instances that don't share the same cloned input data object.
773 return Form("_%lx", _dataClone->uniqueId().value()) ;
774}
775
776
777void RooAbsOptTestStatistic::runRecalculateCache(std::size_t firstEvent, std::size_t lastEvent, std::size_t stepSize) const
778{
779 _dataClone->store()->recalculateCache(_projDeps, firstEvent, lastEvent, stepSize, _skipZeroWeights);
780}
#define e(i)
Definition RSha256.hxx:103
#define coutI(a)
#define cxcoutI(a)
#define coutW(a)
#define cxcoutW(a)
#define coutE(a)
#define ClassImp(name)
Definition Rtypes.h:377
static void indent(ostringstream &buf, int indent_level)
char name[80]
Definition TGX11.cxx:110
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2467
bool recursiveRedirectServers(const RooAbsCollection &newServerList, bool mustReplaceAll=false, bool nameChange=false, bool recurseInNewSet=true)
Recursively replace all servers with the new servers in newSet.
RooFit::OwningPtr< RooArgSet > getParameters(const RooAbsData *data, bool stripDisconnected=true) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don't match any of...
RooFit::OwningPtr< RooArgSet > getObservables(const RooArgSet &set, bool valueOnly=true) const
Given a set of possible observables, return the observables that this PDF depends on.
bool addOwnedComponents(const RooAbsCollection &comps)
Take ownership of the contents of 'comps'.
bool 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 ...
void printCompactTree(const char *indent="", const char *fileName=nullptr, const char *namePat=nullptr, RooAbsArg *client=nullptr)
Print tree structure of expression tree on stdout, or to file if filename is specified.
void setValueDirty()
Mark the element dirty. This forces a re-evaluation when a value is requested.
Definition RooAbsArg.h:490
bool getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
virtual void optimizeCacheMode(const RooArgSet &observables)
Activate cache mode optimization with given definition of observables.
void setAttribute(const Text_t *name, bool value=true)
Set (default) or clear a named boolean attribute of this object.
void branchNodeServerList(RooAbsCollection *list, const RooAbsArg *arg=nullptr, bool recurseNonDerived=false) const
Fill supplied list with all branch nodes of the arg tree starting with ourself as top node.
virtual RooAbsReal * highBoundFunc() const
Return pointer to RooAbsReal parameterized upper bound, if any.
virtual RooAbsReal * lowBoundFunc() const
Return pointer to RooAbsReal parameterized lower bound, if any.
Abstract container object that can hold multiple RooAbsArg objects.
RooAbsCollection * selectByAttrib(const char *name, bool value) const
Create a subset of the current collection, consisting only of those elements with the specified attri...
virtual void removeAll()
Remove all arguments from our set, deleting them if we own them.
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
Int_t getSize() const
Return the number of elements in the collection.
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
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...
RooAbsArg * find(const char *name) const
Find object with given name in list.
virtual const RooAbsArg * cacheOwner()=0
virtual void forceCacheUpdate()
virtual void recalculateCache(const RooArgSet *, Int_t, Int_t, Int_t, bool)
Abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:57
virtual const RooArgSet * get() const
Definition RooAbsData.h:101
RooAbsDataStore * store()
Definition RooAbsData.h:77
RooFit::UniqueId< RooAbsData > const & uniqueId() const
Returns a unique ID that is different for every instantiated RooAbsData object.
Definition RooAbsData.h:308
void setDirtyProp(bool flag)
Control propagation of dirty flags from observables in dataset.
RooFit::OwningPtr< RooAbsData > reduce(const RooCmdArg &arg1, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={})
Create a reduced copy of this dataset.
virtual void setArgStatus(const RooArgSet &set, bool active)
virtual void cacheArgs(const RooAbsArg *owner, RooArgSet &varSet, const RooArgSet *nset=nullptr, bool skipZeroWeights=false)
Internal method – Cache given set of functions with data.
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'.
bool hasFilledCache() const
virtual Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
RooArgSet const * getGlobalObservables() const
Returns snapshot of global observables stored in this data.
Definition RooAbsData.h:288
virtual void resetCache()
Internal method – Remove cached function values.
void attachBuffers(const RooArgSet &extObs)
RooAbsOptTestStatistic is the abstract base class for test statistics objects that evaluate a functio...
bool setDataSlave(RooAbsData &data, bool cloneData=true, bool ownNewDataAnyway=false) override
Change dataset that is used to given one.
~RooAbsOptTestStatistic() override
Destructor.
RooAbsReal * _funcClone
Pointer to internal clone of input function.
bool _sealed
Is test statistic sealed – i.e. no access to data.
void optimizeConstantTerms(bool, bool=true)
Driver function to activate global constant term optimization.
double combinedValue(RooAbsReal **gofArray, Int_t nVal) const override
Method to combined test statistic results calculated into partitions into the global result.
void runRecalculateCache(std::size_t firstEvent, std::size_t lastEvent, std::size_t stepSize) const override
bool _ownData
Do we own the dataset.
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
bool _skipZeroWeights
! Whether to skip entries with weight zero in the evaluation
RooArgSet * _funcObsSet
List of observables in the pdf expression.
RooAbsOptTestStatistic(const char *name, const char *title, RooAbsReal &real, RooAbsData &data, const RooArgSet &projDeps, RooAbsTestStatistic::Configuration const &cfg)
Create a test statistic, and optimise its calculation.
void constOptimizeTestStatistic(ConstOpCode opcode, bool doAlsoTrackingOpt=true) override
Driver function to propagate constant term optimizations in test statistic.
void setUpBinSampling()
Inspect PDF to find out if we are doing a binned fit to a 1-dimensional unbinned PDF.
bool redirectServersHook(const RooAbsCollection &newServerList, bool mustReplaceAll, bool nameChange, bool isRecursive) override
Catch server redirect calls and forward to internal clone of function.
RooArgSet _cachedNodes
! List of nodes that are cached as constant expressions
void initSlave(RooAbsReal &real, RooAbsData &indata, const RooArgSet &projDeps, const char *rangeName, const char *addCoefRangeName)
void printCompactTreeHook(std::ostream &os, const char *indent="") override
Catch print hook function and forward to function clone.
RooArgSet * _normSet
Pointer to set with observables used for normalization.
const char * cacheUniqueSuffix() const override
Returns a suffix string that is unique for RooAbsOptTestStatistic instances that don't share the same...
RooArgSet * _funcCloneSet
Set owning all components of internal clone of input function.
RooAbsData * _dataClone
Pointer to internal clone if input data.
virtual RooArgSet requiredExtraObservables() const
RooArgSet * _projDeps
Set of projected observable.
Abstract interface for all probability density functions.
Definition RooAbsPdf.h:40
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
virtual double getMax(const char *name=nullptr) const
Get maximum of currently defined range.
virtual double getMin(const char *name=nullptr) const
Get minimum of currently defined range.
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:59
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:103
virtual double getValV(const RooArgSet *normalisationSet=nullptr) const
Return value of object.
virtual void fixAddCoefNormalization(const RooArgSet &addNormSet=RooArgSet(), bool force=true)
Fix the interpretation of the coefficient of any RooAddPdf component in the expression tree headed by...
bool redirectServersHook(const RooAbsCollection &newServerList, bool mustReplaceAll, bool nameChange, bool isRecursiveStep) override
Function that is called at the end of redirectServers().
virtual void fixAddCoefRange(const char *rangeName=nullptr, bool force=true)
Fix the interpretation of the coefficient of any RooAddPdf component in the expression tree headed by...
Abstract base class for all test statistics.
double _evalCarry
! carry of Kahan sum in evaluatePartition
std::string _addCoefRangeName
Name of reference to be used for RooAddPdf components.
GOFOpMode operMode() const
RooSetProxy _paramSet
Parameters of the test statistic (=parameters of the input function)
RooAbsReal * _func
Pointer to original input function.
void printCompactTreeHook(std::ostream &os, const char *indent="") override
Add extra information on component test statistics when printing itself as part of a tree structure.
std::string _rangeName
Name of range in which to calculate test statistic.
void constOptimizeTestStatistic(ConstOpCode opcode, bool doAlsoTrackingOpt=true) override
Forward constant term optimization management calls to component test statistics.
void setEventCount(Int_t nEvents)
virtual double getCarry() const
RooAbsData * _data
Pointer to original input dataset.
const bool _takeGlobalObservablesFromData
If the global observable values are taken from data.
bool redirectServersHook(const RooAbsCollection &newServerList, bool mustReplaceAll, bool nameChange, bool isRecursive) override
Forward server redirect calls to component test statistics.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition RooArgSet.h:178
static std::unique_ptr< RooAbsPdf > create(RooAbsPdf &pdf, RooAbsData const &data, double precision)
Creates a wrapping RooBinSamplingPdf if appropriate.
bool add(const RooAbsArg &var, bool valueServer, bool shapeServer, bool silent)
Overloaded RooCollection_t::add() method insert object into set and registers object as server to own...
RooDataSet is a container class to hold unbinned data.
Definition RooDataSet.h:57
static void softAbort()
Soft abort function that interrupts macro execution but doesn't kill ROOT.
Efficient implementation of a product of PDFs of the form.
Definition RooProdPdf.h:33
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:37
const RooAbsBinning & getBinning(const char *name=nullptr, bool verbose=true, bool createOnTheFly=false) const override
Return binning definition with name.
RooVectorDataStore uses std::vectors to store data columns.
TObject * Clone(const char *newname="") const override
Make a clone of an object using the Streamer facility.
Definition TNamed.cxx:74
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:207
Basic string class.
Definition TString.h:139
const char * Data() const
Definition TString.h:380
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
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
std::unique_ptr< T > cloneTreeWithSameParameters(T const &arg, RooArgSet const *observables=nullptr)
Clone RooAbsArg object and reattach to original parameters.
constexpr Value_t value() const
Return numerical value of ID.
Definition UniqueId.h:59
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2345