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