Logo ROOT  
Reference Guide
RooFFTConvPdf.cxx
Go to the documentation of this file.
1 
2  /*****************************************************************************
3  * Project: RooFit *
4  * *
5  * Copyright (c) 2000-2005, Regents of the University of California *
6  * and Stanford University. All rights reserved. *
7  * *
8  * Redistribution and use in source and binary forms, *
9  * with or without modification, are permitted according to the terms *
10  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
11  *****************************************************************************/
12 
13 //////////////////////////////////////////////////////////////////////////////
14 /// \class RooFFTConvPdf
15 /// \ingroup Roofitcore
16 ///
17 /// This class implements a generic one-dimensional numeric convolution of two PDFs,
18 /// and can convolve any two RooAbsPdfs. The class exploits the convolution theorem
19 /// \f[
20 /// f(x) * g(x) \rightarrow F(k_i) \cdot G(k_i)
21 /// \f]
22 /// to calculate the convolution by calculating a Real->Complex FFT of both input PDFs,
23 /// multiplying the complex coefficients and performing the reverse Complex->Real FFT
24 /// to get the result in the input space. This class uses the ROOT FFT interface to
25 /// the (free) FFTW3 package (www.fftw.org), and requires that your ROOT installation is
26 /// compiled with the `fftw3=ON` (default). Instructions for manually installing fftw below.
27 ///
28 /// Note that the performance in terms of speed and stability of RooFFTConvPdf is
29 /// vastly superior to that of RooNumConvPdf.
30 ///
31 /// An important feature of FFT convolutions is that the observable is assumed to be
32 /// cyclical. This is correct for cyclical observables such as angles,
33 /// but does not hold in general. For non-cyclical variables, wrap-around artifacts may be
34 /// encountered, *e.g.* if the PDF is zero at xMin and non-zero at xMax. A rising tail may appear at xMin.
35 /// This is inevitable when using FFTs. A distribution with 3 bins therefore looks like:
36 /// ```
37 /// ... 0 1 2 0 1 2 0 1 2 ...
38 /// ```
39 ///
40 /// Therefore, if bins 0 and 2 are not equal, the FFT sees a cyclical function with a step at the 2|0 boundary, which causes
41 /// artifacts in Fourier space.
42 ///
43 /// The spillover or discontinuity can be reduced or eliminated by
44 /// introducing a buffer zone in the FFT calculation. If this feature is activated (on by default),
45 /// the sampling array for the FFT calculation is extended in both directions,
46 /// and padded with the lowest/highest bin.
47 /// Example:
48 /// ```
49 /// original: -5 -4 -3 -2 -1 0 +1 +2 +3 +4 +5
50 /// add buffer zones: U U -5 -4 -3 -2 -1 0 +1 +2 +3 +4 +5 O O
51 /// rotate: 0 +1 +2 +3 +4 +5 O O U U -5 -4 -3 -2 -1
52 /// ```
53 /// The buffer bins are stripped away when the FFT output values
54 /// are transferred back to the p.d.f cache. The default buffer size is 10% of the
55 /// observable domain size, and can be changed with the `setBufferFraction()` member function.
56 ///
57 /// The RooFFTConvPdf uses caching inherited from a RooAbsCachedPdf. If it is
58 /// evaluated for a particular value of x, the FFT and convolution is calculated
59 /// for all bins in the observable space for the given choice of parameters,
60 /// which are also stored in the cache. Subsequent evaluations for different values of the convolution observable and
61 /// identical parameters will be retrieved from the cache. If one or more
62 /// of the parameters change, the cache will be updated, *i.e.*, a new FFT runs.
63 ///
64 /// The sampling density of the FFT is controlled by the binning of the
65 /// the convolution observable, which can be changed using RooRealVar::setBins(N).
66 /// For good results, N should be large (>=1000). Additional interpolation
67 /// between the bins may improve the result if coarse binnings are chosen. These can be
68 /// activated in the constructor or by calling `setInterpolationOrder()`.
69 /// For N >> 1000, interpolation will not substantially improve the accuracy.
70 ///
71 /// Additionial information on caching can be displayed by monitoring
72 /// the message stream with topic "Caching" at the INFO level, *i.e.*
73 /// by calling `RooMsgService::instance().addStream(RooMsgService::INFO,Topic("Caching"))`
74 /// to see these message on stdout.
75 ///
76 /// Multi-dimensional convolutions are not supported at the moment.
77 ///
78 /// ---
79 ///
80 /// Installing an external version of FFTW on Linux and compiling ROOT to use it
81 /// -------
82 ///
83 /// You have two options:
84 /// * **Recommended**: ROOT can automatically install FFTW for itself, see `builtin_fftw3` at https://root.cern.ch/building-root
85 /// * Install FFTW and let ROOT discover it. `fftw3` is on by default (see https://root.cern.ch/building-root)
86 ///
87 /// 1) Go to www.fftw.org and download the latest stable version (a .tar.gz file)
88 ///
89 /// If you have root access to your machine and want to make a system installation of FFTW
90 ///
91 /// 2) Untar fftw-XXX.tar.gz in /tmp, cd into the untarred directory
92 /// and type './configure' followed by 'make install'.
93 /// This will install fftw in /usr/local/bin,lib etc...
94 ///
95 /// 3) Start from a source installation of ROOT. ROOT should discover it. See https://root.cern.ch/building-root
96 ///
97 ///
98 /// If you do not have root access and want to make a private installation of FFTW
99 ///
100 /// 2) Make a private install area for FFTW, e.g. /home/myself/fftw
101 ///
102 /// 3) Untar fftw-XXX.tar.gz in /tmp, cd into the untarred directory
103 /// and type './configure --prefix=/home/myself/fftw' followed by 'make install'.
104 /// Substitute /home/myself/fftw with a directory of your choice. This
105 /// procedure will install FFTW in the location designated by you
106 ///
107 /// 4) Start from a source installation of ROOT.
108 /// Look up and set the proper paths for ROOT to discover FFTW. See https://root.cern.ch/building-root
109 ///
110 
111 #include "RooFFTConvPdf.h"
112 
113 #include "RooAbsReal.h"
114 #include "RooMsgService.h"
115 #include "RooDataHist.h"
116 #include "RooHistPdf.h"
117 #include "RooRealVar.h"
118 #include "RooGenContext.h"
119 #include "RooConvGenContext.h"
120 #include "RooBinning.h"
121 #include "RooLinearVar.h"
122 #include "RooCustomizer.h"
123 #include "RooGlobalFunc.h"
124 #include "RooConstVar.h"
125 #include "RooUniformBinning.h"
126 
127 #include "TClass.h"
128 #include "TComplex.h"
129 #include "TVirtualFFT.h"
130 
131 #include <iostream>
132 #include <stdexcept>
133 
134 using namespace std;
135 
137 
138 
139 ////////////////////////////////////////////////////////////////////////////////
140 /// Constructor for numerical (FFT) convolution of PDFs.
141 /// \param[in] name Name of this PDF
142 /// \param[in] title Title for plotting this PDF
143 /// \param[in] convVar Observable to convolve the PDFs in \attention Use a high number of bins (>= 1000) for good accuracy.
144 /// \param[in] pdf1 First PDF to be convolved
145 /// \param[in] pdf2 Second PDF to be convolved
146 /// \param[in] ipOrder Order for interpolation between bins (since FFT is discrete)
147 /// The binning used for the FFT sampling is controlled by the binning named "cache" in the convolution observable `convVar`.
148 /// If such a binning is not set, the same number of bins as for `convVar` will be used.
149 
150 RooFFTConvPdf::RooFFTConvPdf(const char *name, const char *title, RooRealVar& convVar, RooAbsPdf& pdf1, RooAbsPdf& pdf2, Int_t ipOrder) :
151  RooAbsCachedPdf(name,title,ipOrder),
152  _x("!x","Convolution Variable",this,convVar),
153  _xprime("!xprime","External Convolution Variable",this,0),
154  _pdf1("!pdf1","pdf1",this,pdf1,kFALSE),
155  _pdf2("!pdf2","pdf2",this,pdf2,kFALSE),
156  _params("!params","effective parameters",this),
157  _bufFrac(0.1),
158  _bufStrat(Extend),
159  _shift1(0),
160  _shift2(0),
161  _cacheObs("!cacheObs","Cached observables",this,kFALSE,kFALSE)
162 {
163  prepareFFTBinning(convVar);
164 
165  _shift2 = (convVar.getMax("cache")+convVar.getMin("cache"))/2 ;
166 
167  calcParams() ;
168 
169 }
170 
171 ////////////////////////////////////////////////////////////////////////////////
172 /// \copydoc RooFFTConvPdf(const char*, const char*, RooRealVar&, RooAbsPdf&, RooAbsPdf&, Int_t)
173 /// \param[in] pdfConvVar If the variable used for convolution is a PDF, itself, pass the PDF here, and pass the convolution variable to
174 /// `convVar`. See also rf210_angularconv.C in the <a href="https://root.cern.ch/root/html/tutorials/roofit/index.html.">roofit tutorials</a>
175 
176 RooFFTConvPdf::RooFFTConvPdf(const char *name, const char *title, RooAbsReal& pdfConvVar, RooRealVar& convVar, RooAbsPdf& pdf1, RooAbsPdf& pdf2, Int_t ipOrder) :
177  RooAbsCachedPdf(name,title,ipOrder),
178  _x("!x","Convolution Variable",this,convVar,kFALSE,kFALSE),
179  _xprime("!xprime","External Convolution Variable",this,pdfConvVar),
180  _pdf1("!pdf1","pdf1",this,pdf1,kFALSE),
181  _pdf2("!pdf2","pdf2",this,pdf2,kFALSE),
182  _params("!params","effective parameters",this),
183  _bufFrac(0.1),
184  _bufStrat(Extend),
185  _shift1(0),
186  _shift2(0),
187  _cacheObs("!cacheObs","Cached observables",this,kFALSE,kFALSE)
188 {
189  prepareFFTBinning(convVar);
190 
191  _shift2 = (convVar.getMax("cache")+convVar.getMin("cache"))/2 ;
192 
193  calcParams() ;
194 }
195 
196 
197 
198 ////////////////////////////////////////////////////////////////////////////////
199 /// Copy constructor
200 
201 RooFFTConvPdf::RooFFTConvPdf(const RooFFTConvPdf& other, const char* name) :
202  RooAbsCachedPdf(other,name),
203  _x("!x",this,other._x),
204  _xprime("!xprime",this,other._xprime),
205  _pdf1("!pdf1",this,other._pdf1),
206  _pdf2("!pdf2",this,other._pdf2),
207  _params("!params",this,other._params),
208  _bufFrac(other._bufFrac),
209  _bufStrat(other._bufStrat),
210  _shift1(other._shift1),
211  _shift2(other._shift2),
212  _cacheObs("!cacheObs",this,other._cacheObs)
213  {
214  }
215 
216 
217 
218 ////////////////////////////////////////////////////////////////////////////////
219 /// Destructor
220 
222 {
223 }
224 
225 
226 ////////////////////////////////////////////////////////////////////////////////
227 /// Try to improve the binning and inform user if possible.
228 /// With a 10% buffer fraction, 930 raw bins yield 1024 FFT bins,
229 /// a sweet spot for the speed of FFTW.
230 
232  if (!convVar.hasBinning("cache")) {
233  const RooAbsBinning& varBinning = convVar.getBinning();
234  const int optimal = static_cast<Int_t>(1024/(1.+_bufFrac));
235 
236  //Can improve precision if binning is uniform
237  if (varBinning.numBins() < optimal && varBinning.isUniform()) {
238  coutI(Caching) << "Changing internal binning of variable '" << convVar.GetName()
239  << "' in FFT '" << fName << "'"
240  << " from " << varBinning.numBins()
241  << " to " << optimal << " to improve the precision of the numerical FFT."
242  << " This can be done manually by setting an additional binning named 'cache'." << std::endl;
243  convVar.setBinning(RooUniformBinning(varBinning.lowBound(), varBinning.highBound(), optimal, "cache"), "cache");
244  } else {
245  coutE(Caching) << "The internal binning of variable " << convVar.GetName()
246  << " is not uniform. The numerical FFT will likely yield wrong results." << std::endl;
247  convVar.setBinning(varBinning, "cache");
248  }
249  }
250 }
251 
252 
253 ////////////////////////////////////////////////////////////////////////////////
254 /// Return base name component for cache components in this case 'PDF1_CONV_PDF2'
255 
256 const char* RooFFTConvPdf::inputBaseName() const
257 {
258  static TString name ;
259  name = _pdf1.arg().GetName() ;
260  name.Append("_CONV_") ;
261  name.Append(_pdf2.arg().GetName()) ;
262  return name.Data() ;
263 }
264 
265 
266 
267 
268 ////////////////////////////////////////////////////////////////////////////////
269 /// Return specialized cache subclass for FFT calculations
270 
272 {
273  return new FFTCacheElem(*this,nset) ;
274 }
275 
276 
277 
278 
279 ////////////////////////////////////////////////////////////////////////////////
280 /// Clone input pdf and attach to dataset
281 
283  PdfCacheElem(self,nsetIn),
284  fftr2c1(0),fftr2c2(0),fftc2r(0)
285 {
286  RooAbsPdf* clonePdf1 = (RooAbsPdf*) self._pdf1.arg().cloneTree() ;
287  RooAbsPdf* clonePdf2 = (RooAbsPdf*) self._pdf2.arg().cloneTree() ;
288  clonePdf1->attachDataSet(*hist()) ;
289  clonePdf2->attachDataSet(*hist()) ;
290 
291  // Shift observable
292  RooRealVar* convObs = (RooRealVar*) hist()->get()->find(self._x.arg().GetName()) ;
293 
294  // Install FFT reference range
295  string refName = Form("refrange_fft_%s",self.GetName()) ;
296  convObs->setRange(refName.c_str(),convObs->getMin(),convObs->getMax()) ;
297 
298  if (self._shift1!=0) {
299  RooLinearVar* shiftObs1 = new RooLinearVar(Form("%s_shifted_FFTBuffer1",convObs->GetName()),"shiftObs1",
300  *convObs,RooFit::RooConst(1),RooFit::RooConst(-1*self._shift1)) ;
301 
302  RooArgSet clonedBranches1 ;
303  RooCustomizer cust(*clonePdf1,"fft") ;
304  cust.replaceArg(*convObs,*shiftObs1) ;
305 
306  pdf1Clone = (RooAbsPdf*) cust.build() ;
307 
308  pdf1Clone->addOwnedComponents(*shiftObs1) ;
309  pdf1Clone->addOwnedComponents(*clonePdf1) ;
310 
311  } else {
312  pdf1Clone = clonePdf1 ;
313  }
314 
315  if (self._shift2!=0) {
316  RooLinearVar* shiftObs2 = new RooLinearVar(Form("%s_shifted_FFTBuffer2",convObs->GetName()),"shiftObs2",
317  *convObs,RooFit::RooConst(1),RooFit::RooConst(-1*self._shift2)) ;
318 
319  RooArgSet clonedBranches2 ;
320  RooCustomizer cust(*clonePdf2,"fft") ;
321  cust.replaceArg(*convObs,*shiftObs2) ;
322 
323  pdf1Clone->addOwnedComponents(*shiftObs2) ;
324  pdf1Clone->addOwnedComponents(*clonePdf2) ;
325 
326  pdf2Clone = (RooAbsPdf*) cust.build() ;
327 
328  } else {
329  pdf2Clone = clonePdf2 ;
330  }
331 
332 
333  // Attach cloned pdf to all original parameters of self
334  RooArgSet* fftParams = self.getParameters(*convObs) ;
335 
336  // Remove all cache histogram from fftParams as these
337  // observable need to remain attached to the histogram
338  fftParams->remove(*hist()->get(),kTRUE,kTRUE) ;
339 
340  pdf1Clone->recursiveRedirectServers(*fftParams) ;
341  pdf2Clone->recursiveRedirectServers(*fftParams) ;
342  pdf1Clone->fixAddCoefRange(refName.c_str(), true) ;
343  pdf2Clone->fixAddCoefRange(refName.c_str(), true) ;
344 
345  // Ensure that coefficients for Add PDFs are only interpreted with respect to the convolution observable
346  RooArgSet convSet(self._x.arg());
347  pdf1Clone->fixAddCoefNormalization(convSet, true);
348  pdf2Clone->fixAddCoefNormalization(convSet, true);
349 
350  delete fftParams ;
351 
352  // Save copy of original histX binning and make alternate binning
353  // for extended range scanning
354 
355  const Int_t N = convObs->numBins();
356  if (N < 900) {
357  oocoutW(&self, Eval) << "The FFT convolution '" << self.GetName() << "' will run with " << N
358  << " bins. A decent accuracy for difficult convolutions is typically only reached with n >= 1000. Suggest to increase the number"
359  " of bins of the observable '" << convObs->GetName() << "'." << std::endl;
360  }
361  Int_t Nbuf = static_cast<Int_t>((N*self.bufferFraction())/2 + 0.5) ;
362  Double_t obw = (convObs->getMax() - convObs->getMin())/N ;
363  Int_t N2 = N+2*Nbuf ;
364 
365  scanBinning = new RooUniformBinning (convObs->getMin()-Nbuf*obw,convObs->getMax()+Nbuf*obw,N2) ;
366  histBinning = convObs->getBinning().clone() ;
367 
368  // Deactivate dirty state propagation on datahist observables
369  // and set all nodes on both pdfs to operMode AlwaysDirty
370  hist()->setDirtyProp(kFALSE) ;
371  convObs->setOperMode(ADirty,kTRUE) ;
372 }
373 
374 
375 ////////////////////////////////////////////////////////////////////////////////
376 /// Suffix for cache histogram (added in addition to suffix for cache name)
377 
379 {
380  return TString(Form("_BufFrac%3.1f_BufStrat%d",_bufFrac,_bufStrat)) ;
381 }
382 
383 
384 
385 ////////////////////////////////////////////////////////////////////////////////
386 /// Returns all RooAbsArg objects contained in the cache element
387 
389 {
391 
392  ret.add(*pdf1Clone) ;
393  ret.add(*pdf2Clone) ;
394  if (pdf1Clone->ownedComponents()) {
395  ret.add(*pdf1Clone->ownedComponents()) ;
396  }
397  if (pdf2Clone->ownedComponents()) {
398  ret.add(*pdf2Clone->ownedComponents()) ;
399  }
400 
401  return ret ;
402 }
403 
404 
405 ////////////////////////////////////////////////////////////////////////////////
406 
408 {
409  delete fftr2c1 ;
410  delete fftr2c2 ;
411  delete fftc2r ;
412 
413  delete pdf1Clone ;
414  delete pdf2Clone ;
415 
416  delete histBinning ;
417  delete scanBinning ;
418 
419 }
420 
421 
422 
423 
424 ////////////////////////////////////////////////////////////////////////////////
425 /// Fill the contents of the cache the FFT convolution output
426 
428 {
429  RooDataHist& cacheHist = *cache.hist() ;
430 
431  ((FFTCacheElem&)cache).pdf1Clone->setOperMode(ADirty,kTRUE) ;
432  ((FFTCacheElem&)cache).pdf2Clone->setOperMode(ADirty,kTRUE) ;
433 
434  // Determine if there other observables than the convolution observable in the cache
435  RooArgSet otherObs ;
436  RooArgSet(*cacheHist.get()).snapshot(otherObs) ;
437 
438  RooAbsArg* histArg = otherObs.find(_x.arg().GetName()) ;
439  if (histArg) {
440  otherObs.remove(*histArg,kTRUE,kTRUE) ;
441  }
442 
443  //cout << "RooFFTConvPdf::fillCacheObject() otherObs = " << otherObs << endl ;
444 
445  // Handle trivial scenario -- no other observables
446  if (otherObs.getSize()==0) {
448  return ;
449  }
450 
451  // Handle cases where there are other cache slices
452  // Iterator over available slice positions and fill each
453 
454  // Determine number of bins for each slice position observable
455  Int_t n = otherObs.getSize() ;
456  Int_t* binCur = new Int_t[n+1] ;
457  Int_t* binMax = new Int_t[n+1] ;
458  Int_t curObs = 0 ;
459 
460  RooAbsLValue** obsLV = new RooAbsLValue*[n] ;
461  TIterator* iter = otherObs.createIterator() ;
462  RooAbsArg* arg ;
463  Int_t i(0) ;
464  while((arg=(RooAbsArg*)iter->Next())) {
465  RooAbsLValue* lvarg = dynamic_cast<RooAbsLValue*>(arg) ;
466  obsLV[i] = lvarg ;
467  binCur[i] = 0 ;
468  // coverity[FORWARD_NULL]
469  binMax[i] = lvarg->numBins(binningName())-1 ;
470  i++ ;
471  }
472  delete iter ;
473 
474  Bool_t loop(kTRUE) ;
475  while(loop) {
476  // Set current slice position
477  for (Int_t j=0 ; j<n ; j++) { obsLV[j]->setBin(binCur[j],binningName()) ; }
478 
479 // cout << "filling slice: bin of obsLV[0] = " << obsLV[0]->getBin() << endl ;
480 
481  // Fill current slice
482  fillCacheSlice((FFTCacheElem&)cache,otherObs) ;
483 
484  // Determine which iterator to increment
485  while(binCur[curObs]==binMax[curObs]) {
486 
487  // Reset current iterator and consider next iterator ;
488  binCur[curObs]=0 ;
489  curObs++ ;
490 
491  // master termination condition
492  if (curObs==n) {
493  loop=kFALSE ;
494  break ;
495  }
496  }
497 
498  // Increment current iterator
499  binCur[curObs]++ ;
500  curObs=0 ;
501 
502  }
503 
504  delete[] obsLV ;
505  delete[] binMax ;
506  delete[] binCur ;
507 
508 }
509 
510 
511 ////////////////////////////////////////////////////////////////////////////////
512 /// Fill a slice of cachePdf with the output of the FFT convolution calculation
513 
514 void RooFFTConvPdf::fillCacheSlice(FFTCacheElem& aux, const RooArgSet& slicePos) const
515 {
516  // Extract histogram that is the basis of the RooHistPdf
517  RooDataHist& cacheHist = *aux.hist() ;
518 
519  // Sample array of input points from both pdfs
520  // Note that returned arrays have optional buffers zones below and above range ends
521  // to reduce cyclical effects and have been cyclically rotated so that bin containing
522  // zero value is at position zero. Example:
523  //
524  // original: -5 -4 -3 -2 -1 0 +1 +2 +3 +4 +5
525  // add buffer zones: U U -5 -4 -3 -2 -1 0 +1 +2 +3 +4 +5 O O
526  // rotate: 0 +1 +2 +3 +4 +5 O O U U -5 -4 -3 -2 -1
527  //
528  //
529 
530  Int_t N,N2,binShift1,binShift2 ;
531 
532  RooRealVar* histX = (RooRealVar*) cacheHist.get()->find(_x.arg().GetName()) ;
533  if (_bufStrat==Extend) histX->setBinning(*aux.scanBinning) ;
534  Double_t* input1 = scanPdf((RooRealVar&)_x.arg(),*aux.pdf1Clone,cacheHist,slicePos,N,N2,binShift1,_shift1) ;
535  Double_t* input2 = scanPdf((RooRealVar&)_x.arg(),*aux.pdf2Clone,cacheHist,slicePos,N,N2,binShift2,_shift2) ;
536  if (_bufStrat==Extend) histX->setBinning(*aux.histBinning) ;
537 
538 
539 
540 
541  // Retrieve previously defined FFT transformation plans
542  if (!aux.fftr2c1) {
543  aux.fftr2c1 = TVirtualFFT::FFT(1, &N2, "R2CK");
544  aux.fftr2c2 = TVirtualFFT::FFT(1, &N2, "R2CK");
545  aux.fftc2r = TVirtualFFT::FFT(1, &N2, "C2RK");
546 
547  if (aux.fftr2c1 == nullptr || aux.fftr2c2 == nullptr || aux.fftc2r == nullptr) {
548  coutF(Eval) << "RooFFTConvPdf::fillCacheSlice(" << GetName() << "Cannot get a handle to fftw. Maybe ROOT was built without it?" << std::endl;
549  throw std::runtime_error("Cannot get a handle to fftw.");
550  }
551  }
552 
553  // Real->Complex FFT Transform on p.d.f. 1 sampling
554  aux.fftr2c1->SetPoints(input1);
555  aux.fftr2c1->Transform();
556 
557  // Real->Complex FFT Transform on p.d.f 2 sampling
558  aux.fftr2c2->SetPoints(input2);
559  aux.fftr2c2->Transform();
560 
561  // Loop over first half +1 of complex output results, multiply
562  // and set as input of reverse transform
563  for (Int_t i=0 ; i<N2/2+1 ; i++) {
564  Double_t re1,re2,im1,im2 ;
565  aux.fftr2c1->GetPointComplex(i,re1,im1) ;
566  aux.fftr2c2->GetPointComplex(i,re2,im2) ;
567  Double_t re = re1*re2 - im1*im2 ;
568  Double_t im = re1*im2 + re2*im1 ;
569  TComplex t(re,im) ;
570  aux.fftc2r->SetPointComplex(i,t) ;
571  }
572 
573  // Reverse Complex->Real FFT transform product
574  aux.fftc2r->Transform() ;
575 
576  Int_t totalShift = binShift1 + (N2-N)/2 ;
577 
578  // Store FFT result in cache
579 
580  TIterator* iter = const_cast<RooDataHist&>(cacheHist).sliceIterator(const_cast<RooAbsReal&>(_x.arg()),slicePos) ;
581  for (Int_t i =0 ; i<N ; i++) {
582 
583  // Cyclically shift array back so that bin containing zero is back in zeroBin
584  Int_t j = i + totalShift ;
585  while (j<0) j+= N2 ;
586  while (j>=N2) j-= N2 ;
587 
588  iter->Next() ;
589  cacheHist.set(aux.fftc2r->GetPointReal(j)) ;
590  }
591  delete iter ;
592 
593  // cacheHist.dump2() ;
594 
595  // Delete input arrays
596  delete[] input1 ;
597  delete[] input2 ;
598 
599 }
600 
601 
602 ////////////////////////////////////////////////////////////////////////////////
603 /// Scan the values of 'pdf' in observable 'obs' using the bin values stored in 'hist' at slice position 'slicePos'
604 /// N is filled with the number of bins defined in hist, N2 is filled with N plus the number of buffer bins
605 /// The return value is an array of doubles of length N2 with the sampled values. The caller takes ownership
606 /// of the array
607 
608 Double_t* RooFFTConvPdf::scanPdf(RooRealVar& obs, RooAbsPdf& pdf, const RooDataHist& hist, const RooArgSet& slicePos,
609  Int_t& N, Int_t& N2, Int_t& zeroBin, Double_t shift) const
610 {
611 
612  RooRealVar* histX = (RooRealVar*) hist.get()->find(obs.GetName()) ;
613 
614  // Calculate number of buffer bins on each size to avoid cyclical flow
615  N = histX->numBins(binningName()) ;
616  Int_t Nbuf = static_cast<Int_t>((N*bufferFraction())/2 + 0.5) ;
617  N2 = N+2*Nbuf ;
618 
619 
620  // Allocate array of sampling size plus optional buffer zones
621  Double_t* array = new Double_t[N2] ;
622 
623  // Set position of non-convolution observable to that of the cache slice that were are processing now
624  hist.get(slicePos) ;
625 
626  // Find bin ID that contains zero value
627  zeroBin = 0 ;
628  if (histX->getMax()>=0 && histX->getMin()<=0) {
629  zeroBin = histX->getBinning().binNumber(0) ;
630  } else if (histX->getMin()>0) {
631  Double_t bw = (histX->getMax() - histX->getMin())/N2 ;
632  zeroBin = Int_t(-histX->getMin()/bw) ;
633  } else {
634  Double_t bw = (histX->getMax() - histX->getMin())/N2 ;
635  zeroBin = Int_t(-1*histX->getMax()/bw) ;
636  }
637 
638  Int_t binShift = Int_t((N2* shift) / (histX->getMax()-histX->getMin())) ;
639 
640  zeroBin += binShift ;
641  while(zeroBin>=N2) zeroBin-= N2 ;
642  while(zeroBin<0) zeroBin+= N2 ;
643 
644  // First scan hist into temp array
645  Double_t *tmp = new Double_t[N2] ;
646  Int_t k(0) ;
647  switch(_bufStrat) {
648 
649  case Extend:
650  // Sample entire extended range (N2 samples)
651  for (k=0 ; k<N2 ; k++) {
652  histX->setBin(k) ;
653  tmp[k] = pdf.getVal(hist.get()) ;
654  }
655  break ;
656 
657  case Flat:
658  // Sample original range (N samples) and fill lower and upper buffer
659  // bins with p.d.f. value at respective boundary
660  {
661  histX->setBin(0) ;
662  Double_t val = pdf.getVal(hist.get()) ;
663  for (k=0 ; k<Nbuf ; k++) {
664  tmp[k] = val ;
665  }
666  for (k=0 ; k<N ; k++) {
667  histX->setBin(k) ;
668  tmp[k+Nbuf] = pdf.getVal(hist.get()) ;
669  }
670  histX->setBin(N-1) ;
671  val = pdf.getVal(hist.get()) ;
672  for (k=0 ; k<Nbuf ; k++) {
673  tmp[N+Nbuf+k] = val ;
674  }
675  }
676  break ;
677 
678  case Mirror:
679  // Sample original range (N samples) and fill lower and upper buffer
680  // bins with mirror image of sampled range
681  for (k=0 ; k<N ; k++) {
682  histX->setBin(k) ;
683  tmp[k+Nbuf] = pdf.getVal(hist.get()) ;
684  }
685  for (k=1 ; k<=Nbuf ; k++) {
686  histX->setBin(k) ;
687  tmp[Nbuf-k] = pdf.getVal(hist.get()) ;
688  histX->setBin(N-k) ;
689  tmp[Nbuf+N+k-1] = pdf.getVal(hist.get()) ;
690  }
691  break ;
692  }
693 
694  // Scan function and store values in array
695  for (Int_t i=0 ; i<N2 ; i++) {
696  // Cyclically shift writing location by zero bin position
697  Int_t j = i - (zeroBin) ;
698  if (j<0) j+= N2 ;
699  if (j>=N2) j-= N2 ;
700  array[i] = tmp[j] ;
701  }
702 
703  // Cleanup
704  delete[] tmp ;
705  return array ;
706 }
707 
708 
709 
710 ////////////////////////////////////////////////////////////////////////////////
711 /// Return the observables to be cached given the normalization set nset.
712 ///
713 /// If the cache observable is in nset then this is
714 /// - the convolution observable plus
715 /// - any member of nset that is either a RooCategory,
716 /// - or was previously specified through setCacheObservables().
717 ///
718 /// In case the cache observable is *not* in nset, then it is
719 /// - the convolution observable plus
720 /// - all member of nset that are observables of this p.d.f.
721 ///
722 
724 {
725  // Get complete list of observables
726  RooArgSet* obs1 = _pdf1.arg().getObservables(nset) ;
727  RooArgSet* obs2 = _pdf2.arg().getObservables(nset) ;
728  obs1->add(*obs2,kTRUE) ;
729 
730  // Check if convolution observable is in nset
731  if (nset.contains(_x.arg())) {
732 
733  // Now strip out all non-category observables
734  TIterator* iter = obs1->createIterator() ;
735  RooAbsArg* arg ;
736  RooArgSet killList ;
737  while((arg=(RooAbsArg*)iter->Next())) {
738  if (arg->IsA()->InheritsFrom(RooAbsReal::Class()) && !_cacheObs.find(arg->GetName())) {
739  killList.add(*arg) ;
740  }
741  }
742  delete iter ;
743  obs1->remove(killList) ;
744 
745  // And add back the convolution observables
746  obs1->add(_x.arg(),kTRUE) ;
747 
748  obs1->add(_cacheObs) ;
749 
750  delete obs2 ;
751 
752  } else {
753 
754  // If cacheObs was filled, cache only observables in there
755  if (_cacheObs.getSize()>0) {
756  TIterator* iter = obs1->createIterator() ;
757  RooAbsArg* arg ;
758  RooArgSet killList ;
759  while((arg=(RooAbsArg*)iter->Next())) {
760  if (arg->IsA()->InheritsFrom(RooAbsReal::Class()) && !_cacheObs.find(arg->GetName())) {
761  killList.add(*arg) ;
762  }
763  }
764  delete iter ;
765  obs1->remove(killList) ;
766  }
767 
768 
769  // Make sure convolution observable is always in there
770  obs1->add(_x.arg(),kTRUE) ;
771  delete obs2 ;
772 
773  }
774 
775  return obs1 ;
776 }
777 
778 
779 
780 ////////////////////////////////////////////////////////////////////////////////
781 /// Return the parameters on which the cache depends given normalization
782 /// set nset. For this p.d.f these are the parameters of the input p.d.f.
783 /// but never the convolution variable, in case it is not part of nset.
784 
786 {
787  RooArgSet* vars = getVariables() ;
788  RooArgSet* obs = actualObservables(nset) ;
789  vars->remove(*obs) ;
790  delete obs ;
791 
792  return vars ;
793 }
794 
795 
796 
797 ////////////////////////////////////////////////////////////////////////////////
798 /// Return p.d.f. observable (which can be a function) to substitute given
799 /// p.d.f. observable. Substitutes x by xprime if xprime is set.
800 
802 {
803  if (_xprime.absArg() && string(histObservable.GetName())==_x.absArg()->GetName()) {
804  return (*_xprime.absArg()) ;
805  }
806  return histObservable ;
807 }
808 
809 
810 
811 ////////////////////////////////////////////////////////////////////////////////
812 /// Create appropriate generator context for this convolution. If both input p.d.f.s support
813 /// internal generation, if it is safe to use them and if no observables other than the convolution
814 /// observable are requested for generation, use the specialized convolution generator context
815 /// which implements a smearing strategy in the convolution observable. If not return the
816 /// regular accept/reject generator context
817 
819  const RooArgSet* auxProto, Bool_t verbose) const
820 {
821  RooArgSet vars2(vars) ;
822  vars2.remove(_x.arg(),kTRUE,kTRUE) ;
823  Int_t numAddDep = vars2.getSize() ;
824 
825  RooArgSet dummy ;
826  Bool_t pdfCanDir = (((RooAbsPdf&)_pdf1.arg()).getGenerator(_x.arg(),dummy) != 0 && \
828  Bool_t resCanDir = (((RooAbsPdf&)_pdf2.arg()).getGenerator(_x.arg(),dummy) !=0 &&
830 
831  if (pdfCanDir) {
832  cxcoutI(Generation) << "RooFFTConvPdf::genContext() input p.d.f " << _pdf1.arg().GetName()
833  << " has internal generator that is safe to use in current context" << endl ;
834  }
835  if (resCanDir) {
836  cxcoutI(Generation) << "RooFFTConvPdf::genContext() input p.d.f. " << _pdf2.arg().GetName()
837  << " has internal generator that is safe to use in current context" << endl ;
838  }
839  if (numAddDep>0) {
840  cxcoutI(Generation) << "RooFFTConvPdf::genContext() generation requested for observables other than the convolution observable " << _x.arg().GetName() << endl ;
841  }
842 
843 
844  if (numAddDep>0 || !pdfCanDir || !resCanDir) {
845  // Any resolution model with more dependents than the convolution variable
846  // or pdf or resmodel do not support direct generation
847  cxcoutI(Generation) << "RooFFTConvPdf::genContext() selecting accept/reject generator context because one or both of the input "
848  << "p.d.f.s cannot use internal generator and/or "
849  << "observables other than the convolution variable are requested for generation" << endl ;
850  return new RooGenContext(*this,vars,prototype,auxProto,verbose) ;
851  }
852 
853  // Any other resolution model: use specialized generator context
854  cxcoutI(Generation) << "RooFFTConvPdf::genContext() selecting specialized convolution generator context as both input "
855  << "p.d.fs are safe for internal generator and only "
856  << "the convolution observables is requested for generation" << endl ;
857  return new RooConvGenContext(*this,vars,prototype,auxProto,verbose) ;
858 }
859 
860 
861 
862 ////////////////////////////////////////////////////////////////////////////////
863 /// Change the size of the buffer on either side of the observable range to `frac` times the
864 /// size of the range of the convolution observable.
865 
867 {
868  if (frac<0) {
869  coutE(InputArguments) << "RooFFTConvPdf::setBufferFraction(" << GetName() << ") fraction should be greater than or equal to zero" << endl ;
870  return ;
871  }
872  _bufFrac = frac ;
873 
874  // Sterilize the cache as certain partial results depend on buffer fraction
875  _cacheMgr.sterilize() ;
876 }
877 
878 
879 ////////////////////////////////////////////////////////////////////////////////
880 /// Change strategy to fill the overflow buffer on either side of the convolution observable range.
881 ///
882 /// - `Extend` means is that the input p.d.f convolution observable range is widened to include the buffer range
883 /// - `Flat` means that the buffer is filled with the p.d.f. value at the boundary of the observable range
884 /// - `Mirror` means that the buffer is filled with a mirror image of the p.d.f. around the convolution observable boundary
885 ///
886 /// The default strategy is extend. If one of the input p.d.f.s is a RooAddPdf, it is configured so that the interpretation
887 /// range of the fraction coefficients is kept at the nominal convolutions observable range (instead of interpreting coefficients
888 /// in the widened range including the buffer).
889 
891 {
892  _bufStrat = bs ;
893 }
894 
895 
896 
897 ////////////////////////////////////////////////////////////////////////////////
898 /// Customized printing of arguments of a RooNumConvPdf to more intuitively reflect the contents of the
899 /// product operator construction
900 
901 void RooFFTConvPdf::printMetaArgs(ostream& os) const
902 {
903  os << _pdf1.arg().GetName() << "(" << _x.arg().GetName() << ") (*) " << _pdf2.arg().GetName() << "(" << _x.arg().GetName() << ") " ;
904 }
905 
906 
907 
908 ////////////////////////////////////////////////////////////////////////////////
909 /// (Re)calculate effective parameters of this p.d.f.
910 
912 {
913  RooArgSet* params1 = _pdf1.arg().getParameters(_x.arg()) ;
914  RooArgSet* params2 = _pdf2.arg().getParameters(_x.arg()) ;
915  _params.removeAll() ;
916  _params.add(*params1) ;
917  _params.add(*params2,kTRUE) ;
918  delete params1 ;
919  delete params2 ;
920 }
921 
922 
923 
924 ////////////////////////////////////////////////////////////////////////////////
925 ///calcParams() ;
926 
927 Bool_t RooFFTConvPdf::redirectServersHook(const RooAbsCollection& /*newServerList*/, Bool_t /*mustReplaceAll*/, Bool_t /*nameChange*/, Bool_t /*isRecursive*/)
928 {
929  return kFALSE ;
930 }
RooFFTConvPdf::scanPdf
Double_t * scanPdf(RooRealVar &obs, RooAbsPdf &pdf, const RooDataHist &hist, const RooArgSet &slicePos, Int_t &N, Int_t &N2, Int_t &zeroBin, Double_t shift) const
Scan the values of 'pdf' in observable 'obs' using the bin values stored in 'hist' at slice position ...
Definition: RooFFTConvPdf.cxx:608
RooFFTConvPdf::FFTCacheElem::fftr2c2
TVirtualFFT * fftr2c2
Definition: RooFFTConvPdf.h:86
RooFFTConvPdf::fillCacheSlice
void fillCacheSlice(FFTCacheElem &cache, const RooArgSet &slicePosition) const
Fill a slice of cachePdf with the output of the FFT convolution calculation.
Definition: RooFFTConvPdf.cxx:514
n
const Int_t n
Definition: legend1.C:16
RooAbsArg::ADirty
@ ADirty
Definition: RooAbsArg.h:390
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:100
RooAbsReal.h
RooAbsBinning::numBins
Int_t numBins() const
Return number of bins.
Definition: RooAbsBinning.h:38
RooFFTConvPdf::histNameSuffix
virtual TString histNameSuffix() const
Suffix for cache histogram (added in addition to suffix for cache name)
Definition: RooFFTConvPdf.cxx:378
RooMsgService.h
TComplex
Definition: TComplex.h:27
RooUniformBinning.h
RooAbsRealLValue::getMax
virtual Double_t getMax(const char *name=0) const
Get maximum of currently defined range.
Definition: RooAbsRealLValue.h:89
RooTemplateProxy::arg
const T & arg() const
Return reference to object held in proxy.
Definition: RooTemplateProxy.h:290
RooFit::InputArguments
@ InputArguments
Definition: RooGlobalFunc.h:61
RooAbsArg::getParameters
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...
Definition: RooAbsArg.cxx:578
RooFFTConvPdf::setBufferFraction
void setBufferFraction(Double_t frac)
Change the size of the buffer on either side of the observable range to frac times the size of the ra...
Definition: RooFFTConvPdf.cxx:866
RooAbsBinning::highBound
virtual Double_t highBound() const =0
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
Form
char * Form(const char *fmt,...)
RooAbsBinning::binNumber
virtual Int_t binNumber(Double_t x) const =0
RooCustomizer
RooCustomizer is a factory class to produce clones of a prototype composite PDF object with the same ...
Definition: RooCustomizer.h:35
RooFFTConvPdf::FFTCacheElem::FFTCacheElem
FFTCacheElem(const RooFFTConvPdf &self, const RooArgSet *nset)
Clone input pdf and attach to dataset.
Definition: RooFFTConvPdf.cxx:282
RooFFTConvPdf::RooFFTConvPdf
RooFFTConvPdf()
Definition: RooFFTConvPdf.h:28
RooAbsLValue::numBins
virtual Int_t numBins(const char *rangeName=0) const =0
coutE
#define coutE(a)
Definition: RooMsgService.h:33
RooArgList
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgList.h:21
RooGenContext
Class RooGenContext implement a universal generator context for all RooAbsPdf classes that do not hav...
Definition: RooGenContext.h:30
RooAbsCachedPdf::_cacheMgr
RooObjCacheManager _cacheMgr
Definition: RooAbsCachedPdf.h:109
RooAbsReal::getVal
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:91
Int_t
int Int_t
Definition: RtypesCore.h:45
RooFFTConvPdf::actualParameters
virtual RooArgSet * actualParameters(const RooArgSet &nset) const
Return the parameters on which the cache depends given normalization set nset.
Definition: RooFFTConvPdf.cxx:785
N
#define N
RooAbsCollection::remove
virtual Bool_t remove(const RooAbsArg &var, Bool_t silent=kFALSE, Bool_t matchByNameOnly=kFALSE)
Remove the specified argument from our list.
Definition: RooAbsCollection.cxx:585
TNamed::fName
TString fName
Definition: TNamed.h:32
RooAbsCollection::find
RooAbsArg * find(const char *name) const
Find object with given name in list.
Definition: RooAbsCollection.cxx:810
RooFFTConvPdf::Extend
@ Extend
Definition: RooFFTConvPdf.h:47
RooFFTConvPdf::FFTCacheElem::pdf2Clone
RooAbsPdf * pdf2Clone
Definition: RooFFTConvPdf.h:90
RooAbsArg::setOperMode
void setOperMode(OperMode mode, Bool_t recurseADirty=kTRUE)
Set the operation mode of this node.
Definition: RooAbsArg.cxx:1817
RooFFTConvPdf::_pdf2
RooRealProxy _pdf2
Definition: RooFFTConvPdf.h:70
RooAbsPdf::getGenerator
virtual Int_t getGenerator(const RooArgSet &directVars, RooArgSet &generateVars, Bool_t staticInitOK=kTRUE) const
Load generatedVars with the subset of directVars that we can generate events for, and return a code t...
Definition: RooAbsPdf.cxx:2474
coutI
#define coutI(a)
Definition: RooMsgService.h:30
TClass.h
RooObjCacheManager::sterilize
void sterilize()
Clear the cache payload but retain slot mapping w.r.t to normalization and integration sets.
Definition: RooObjCacheManager.cxx:159
RooAbsReal
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:61
RooFFTConvPdf::RooConvGenContext
friend class RooConvGenContext
Definition: RooFFTConvPdf.h:120
RooFFTConvPdf::FFTCacheElem::~FFTCacheElem
~FFTCacheElem()
Definition: RooFFTConvPdf.cxx:407
RooAbsArg::recursiveRedirectServers
Bool_t recursiveRedirectServers(const RooAbsCollection &newServerList, Bool_t mustReplaceAll=kFALSE, Bool_t nameChange=kFALSE, Bool_t recurseInNewSet=kTRUE)
Recursively replace all servers with the new servers in newSet.
Definition: RooAbsArg.cxx:1159
RooFFTConvPdf::genContext
virtual RooAbsGenContext * genContext(const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t verbose=kFALSE) const
Create appropriate generator context for this convolution.
Definition: RooFFTConvPdf.cxx:818
TVirtualFFT.h
RooFFTConvPdf::pdfObservable
virtual RooAbsArg & pdfObservable(RooAbsArg &histObservable) const
Return p.d.f.
Definition: RooFFTConvPdf.cxx:801
TString
Basic string class.
Definition: TString.h:136
RooRealVar::setRange
void setRange(const char *name, Double_t min, Double_t max)
Set a fit or plotting range.
Definition: RooRealVar.cxx:526
RooCustomizer::build
RooAbsArg * build(const char *masterCatState, Bool_t verbose=kFALSE)
Build a clone of the prototype executing all registered 'replace' rules and 'split' rules for the mas...
Definition: RooCustomizer.cxx:397
RooFFTConvPdf::FFTCacheElem::pdf1Clone
RooAbsPdf * pdf1Clone
Definition: RooFFTConvPdf.h:89
TObject::InheritsFrom
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:445
RooAbsReal::fixAddCoefNormalization
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...
Definition: RooAbsReal.cxx:3903
RooAbsPdf::isDirectGenSafe
virtual Bool_t isDirectGenSafe(const RooAbsArg &arg) const
Check if given observable can be safely generated using the pdfs internal generator mechanism (if tha...
Definition: RooAbsPdf.cxx:2509
RooFFTConvPdf::inputBaseName
virtual const char * inputBaseName() const
Return base name component for cache components in this case 'PDF1_CONV_PDF2'.
Definition: RooFFTConvPdf.cxx:256
RooFFTConvPdf::actualObservables
virtual RooArgSet * actualObservables(const RooArgSet &nset) const
Return the observables to be cached given the normalization set nset.
Definition: RooFFTConvPdf.cxx:723
bool
TIterator
Iterator abstract base class.
Definition: TIterator.h:30
RooAbsRealLValue::getMin
virtual Double_t getMin(const char *name=0) const
Get miniminum of currently defined range.
Definition: RooAbsRealLValue.h:86
RooCustomizer::replaceArg
void replaceArg(const RooAbsArg &orig, const RooAbsArg &subst)
Replace any occurence of arg 'orig' with arg 'subst'.
Definition: RooCustomizer.cxx:341
RooFFTConvPdf::_bufStrat
BufStrat _bufStrat
Definition: RooFFTConvPdf.h:112
RooLinearVar
RooLinearVar is the most general form of a derived real-valued object that can be used by RooRealInte...
Definition: RooLinearVar.h:30
TVirtualFFT::SetPointComplex
virtual void SetPointComplex(Int_t ipoint, TComplex &c)=0
RooFFTConvPdf::redirectServersHook
Bool_t redirectServersHook(const RooAbsCollection &newServerList, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t isRecursive)
calcParams() ;
Definition: RooFFTConvPdf.cxx:927
RooFFTConvPdf::FFTCacheElem::fftr2c1
TVirtualFFT * fftr2c1
Definition: RooFFTConvPdf.h:85
TVirtualFFT::Transform
virtual void Transform()=0
RooAbsCollection::contains
Bool_t contains(const RooAbsArg &var) const
Check if collection contains an argument with the same name as var.
Definition: RooAbsCollection.h:143
RooDataHist
The RooDataHist is a container class to hold N-dimensional binned data.
Definition: RooDataHist.h:37
RooLinearVar.h
RooFFTConvPdf::_params
RooSetProxy _params
Definition: RooFFTConvPdf.h:71
RooDataHist::get
const RooArgSet * get() const override
Get bin centre of current bin.
Definition: RooDataHist.h:74
RooAbsRealLValue::numBins
virtual Int_t numBins(const char *rangeName=0) const
Definition: RooAbsRealLValue.h:54
RooCustomizer.h
TVirtualFFT::GetPointReal
virtual Double_t GetPointReal(Int_t ipoint, Bool_t fromInput=kFALSE) const =0
RooAbsBinning::isUniform
virtual Bool_t isUniform() const
Definition: RooAbsBinning.h:48
RooFFTConvPdf::printMetaArgs
void printMetaArgs(std::ostream &os) const
Customized printing of arguments of a RooNumConvPdf to more intuitively reflect the contents of the p...
Definition: RooFFTConvPdf.cxx:901
TVirtualFFT::SetPoints
virtual void SetPoints(const Double_t *data)=0
Double_t
a
auto * a
Definition: textangle.C:12
RooFit::Generation
@ Generation
Definition: RooGlobalFunc.h:60
RooFFTConvPdf::_shift2
Double_t _shift2
Definition: RooFFTConvPdf.h:115
RooAbsData::setDirtyProp
void setDirtyProp(Bool_t flag)
Control propagation of dirty flags from observables in dataset.
Definition: RooAbsData.cxx:359
RooArgProxy::absArg
RooAbsArg * absArg() const
Definition: RooArgProxy.h:37
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:101
RooFFTConvPdf::prepareFFTBinning
void prepareFFTBinning(RooRealVar &convVar) const
Try to improve the binning and inform user if possible.
Definition: RooFFTConvPdf.cxx:231
RooDataHist.h
RooAbsCachedPdf::PdfCacheElem::hist
RooDataHist * hist()
Definition: RooAbsCachedPdf.h:73
RooAbsCollection::createIterator
TIterator * createIterator(Bool_t dir=kIterForward) const
TIterator-style iteration over contained elements.
Definition: RooAbsCollection.h:178
RooRealVar::hasBinning
Bool_t hasBinning(const char *name) const
Returns true if variable has a binning named 'name'.
Definition: RooRealVar.cxx:305
RooFFTConvPdf::~RooFFTConvPdf
virtual ~RooFFTConvPdf()
Destructor.
Definition: RooFFTConvPdf.cxx:221
RooAbsBinning
RooAbsBinning is the abstract base class for RooRealVar binning definitions.
Definition: RooAbsBinning.h:26
RooUniformBinning
RooUniformBinning is an implementation of RooAbsBinning that provides a uniform binning in 'n' bins b...
Definition: RooUniformBinning.h:23
RooFFTConvPdf::FFTCacheElem::containedArgs
virtual RooArgList containedArgs(Action)
Returns all RooAbsArg objects contained in the cache element.
Definition: RooFFTConvPdf.cxx:388
RooAbsCollection
RooAbsCollection is an abstract container object that can hold multiple RooAbsArg objects.
Definition: RooAbsCollection.h:33
RooAbsArg::RooArgSet
friend class RooArgSet
Definition: RooAbsArg.h:599
RooAbsGenContext
RooAbsGenContext is the abstract base class for generator contexts of RooAbsPdf objects.
Definition: RooAbsGenContext.h:26
RooAbsCollection::add
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
Definition: RooAbsCollection.cxx:455
RooGenContext.h
RooAbsCachedPdf::binningName
virtual const char * binningName() const
Definition: RooAbsCachedPdf.h:95
RooFFTConvPdf::_bufFrac
Double_t _bufFrac
Definition: RooFFTConvPdf.h:111
oocoutW
#define oocoutW(o, a)
Definition: RooMsgService.h:47
RooAbsArg::attachDataSet
void attachDataSet(const RooAbsData &set)
Replace server nodes with names matching the dataset variable names with those data set variables,...
Definition: RooAbsArg.cxx:1553
RooFFTConvPdf::_xprime
RooRealProxy _xprime
Definition: RooFFTConvPdf.h:68
RooRealVar.h
RooFFTConvPdf::FFTCacheElem
Definition: RooFFTConvPdf.h:78
TVirtualFFT::GetPointComplex
virtual void GetPointComplex(Int_t ipoint, Double_t &re, Double_t &im, Bool_t fromInput=kFALSE) const =0
RooAbsCachedPdf
RooAbsCachedPdf is the abstract base class for p.d.f.s that need or want to cache their evaluate() ou...
Definition: RooAbsCachedPdf.h:25
RooFFTConvPdf::FFTCacheElem::histBinning
RooAbsBinning * histBinning
Definition: RooFFTConvPdf.h:92
TIterator::Next
virtual TObject * Next()=0
RooConstVar.h
RooAbsCachedPdf::PdfCacheElem
Definition: RooAbsCachedPdf.h:63
RooGlobalFunc.h
RooSetProxy::removeAll
virtual void removeAll() override
Remove all argument inset using remove(const RooAbsArg&).
Definition: RooSetProxy.cxx:229
RooAbsLValue::setBin
virtual void setBin(Int_t ibin, const char *rangeName=0)=0
RooRealVar::getBinning
const RooAbsBinning & getBinning(const char *name=0, Bool_t verbose=kTRUE, Bool_t createOnTheFly=kFALSE) const
Return binning definition with name.
Definition: RooRealVar.cxx:318
RooHistPdf.h
RooFFTConvPdf::calcParams
void calcParams()
(Re)calculate effective parameters of this p.d.f.
Definition: RooFFTConvPdf.cxx:911
RooFFTConvPdf::_pdf1
RooRealProxy _pdf1
Definition: RooFFTConvPdf.h:69
RooFFTConvPdf::fillCacheObject
virtual void fillCacheObject(PdfCacheElem &cache) const
Fill the contents of the cache the FFT convolution output.
Definition: RooFFTConvPdf.cxx:427
RooFFTConvPdf::createCache
virtual PdfCacheElem * createCache(const RooArgSet *nset) const
Return specialized cache subclass for FFT calculations.
Definition: RooFFTConvPdf.cxx:271
TVirtualFFT::FFT
static TVirtualFFT * FFT(Int_t ndim, Int_t *n, Option_t *option)
Returns a pointer to the FFT of requested size and type.
Definition: TVirtualFFT.cxx:131
RooFFTConvPdf::Mirror
@ Mirror
Definition: RooFFTConvPdf.h:47
RooFFTConvPdf
PDF for the numerical (FFT) convolution of two PDFs.
Definition: RooFFTConvPdf.h:25
RooAbsArg::getObservables
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Given a set of possible observables, return the observables that this PDF depends on.
Definition: RooAbsArg.h:295
RooAbsArg::addOwnedComponents
Bool_t addOwnedComponents(const RooArgSet &comps)
Take ownership of the contents of 'comps'.
Definition: RooAbsArg.cxx:2216
RooFFTConvPdf::FFTCacheElem
friend class FFTCacheElem
Definition: RooFFTConvPdf.h:97
RooRealVar::setBinning
void setBinning(const RooAbsBinning &binning, const char *name=0)
Add given binning under name 'name' with this variable.
Definition: RooRealVar.cxx:415
RooAbsBinning::clone
virtual RooAbsBinning * clone(const char *name=0) const =0
RooAbsCacheElement::Action
Action
Definition: RooAbsCacheElement.h:39
coutF
#define coutF(a)
Definition: RooMsgService.h:34
RooAbsArg::cloneTree
virtual RooAbsArg * cloneTree(const char *newname=0) const
Clone tree expression of objects.
Definition: RooAbsArg.cxx:2230
name
char name[80]
Definition: TGX11.cxx:110
TComplex.h
RooFFTConvPdf.h
genreflex::verbose
bool verbose
Definition: rootcling_impl.cxx:133
RooBinning.h
RooFit::Caching
@ Caching
Definition: RooGlobalFunc.h:61
RooDataSet
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:33
RooAbsArg
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition: RooAbsArg.h:72
RooAbsPdf
Definition: RooAbsPdf.h:41
RooAbsLValue
Abstract base class for objects that are lvalues, i.e.
Definition: RooAbsLValue.h:26
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
RooAbsReal::fixAddCoefRange
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...
Definition: RooAbsReal.cxx:3933
RooFFTConvPdf::_shift1
Double_t _shift1
Definition: RooFFTConvPdf.h:114
RooAbsArg::getVariables
RooArgSet * getVariables(Bool_t stripDisconnected=kTRUE) const
Return RooArgSet with all variables (tree leaf nodes of expresssion tree)
Definition: RooAbsArg.cxx:2008
RooFFTConvPdf::_cacheObs
RooSetProxy _cacheObs
Definition: RooFFTConvPdf.h:121
RooFFTConvPdf::setBufferStrategy
void setBufferStrategy(BufStrat bs)
Change strategy to fill the overflow buffer on either side of the convolution observable range.
Definition: RooFFTConvPdf.cxx:890
Class
void Class()
Definition: Class.C:29
RooRealVar
RooRealVar represents a variable that can be changed from the outside.
Definition: RooRealVar.h:39
RooFit::Eval
@ Eval
Definition: RooGlobalFunc.h:61
RooFFTConvPdf::BufStrat
BufStrat
Definition: RooFFTConvPdf.h:47
RooAbsBinning::lowBound
virtual Double_t lowBound() const =0
RooFFTConvPdf::Flat
@ Flat
Definition: RooFFTConvPdf.h:47
cxcoutI
#define cxcoutI(a)
Definition: RooMsgService.h:85
RooConvGenContext.h
RooDataHist::set
void set(std::size_t binNumber, double weight, double wgtErr)
Set bin content of bin that was last loaded with get(std::size_t).
Definition: RooDataHist.cxx:1433
RooAbsCollection::getSize
Int_t getSize() const
Definition: RooAbsCollection.h:231
RooFFTConvPdf::FFTCacheElem::scanBinning
RooAbsBinning * scanBinning
Definition: RooFFTConvPdf.h:93
RooFFTConvPdf::FFTCacheElem::fftc2r
TVirtualFFT * fftc2r
Definition: RooFFTConvPdf.h:87
RooSetProxy::add
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE) override
Overloaded RooArgSet::add() method inserts 'var' into set and registers 'var' as server to owner with...
Definition: RooSetProxy.cxx:165
RooArgSet
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:33
RooFFTConvPdf::bufferFraction
Double_t bufferFraction() const
Definition: RooFFTConvPdf.h:41
RooFFTConvPdf::_x
RooRealProxy _x
Definition: RooFFTConvPdf.h:67
int
RooAbsCachedPdf::PdfCacheElem::containedArgs
virtual RooArgList containedArgs(Action)
Returns all RooAbsArg objects contained in the cache element.
Definition: RooAbsCachedPdf.cxx:350
RooAbsRealLValue::setBin
virtual void setBin(Int_t ibin, const char *rangeName=0)
Set value to center of bin 'ibin' of binning 'rangeName' (or of default binning if no range is specif...
Definition: RooAbsRealLValue.cxx:433
RooFit::RooConst
RooConstVar & RooConst(Double_t val)
Definition: RooGlobalFunc.cxx:383