152 _x(
"!x",
"Convolution Variable",this,convVar),
153 _xprime(
"!xprime",
"External Convolution Variable",this,false),
154 _pdf1(
"!pdf1",
"pdf1",this,pdf1,false),
155 _pdf2(
"!pdf2",
"pdf2",this,pdf2,false),
156 _params(
"!params",
"effective parameters",this),
161 _cacheObs(
"!cacheObs",
"Cached observables",this,false,false)
178 _x(
"!x",
"Convolution Variable",this,convVar,false,false),
179 _xprime(
"!xprime",
"External Convolution Variable",this,pdfConvVar),
180 _pdf1(
"!pdf1",
"pdf1",this,pdf1,false),
181 _pdf2(
"!pdf2",
"pdf2",this,pdf2,false),
182 _params(
"!params",
"effective parameters",this),
187 _cacheObs(
"!cacheObs",
"Cached observables",this,false,false)
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)
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;
245 coutE(Caching) <<
"The internal binning of variable " << convVar.
GetName()
246 <<
" is not uniform. The numerical FFT will likely yield wrong results." << std::endl;
260 name.Append(
"_CONV_") ;
294 string refName =
Form(
"refrange_fft_%s",self.
GetName()) ;
307 pdf1Clone->addOwnedComponents(*shiftObs1) ;
308 pdf1Clone->addOwnedComponents(*clonePdf1) ;
322 pdf1Clone->addOwnedComponents(*shiftObs2) ;
323 pdf1Clone->addOwnedComponents(*clonePdf2) ;
341 pdf1Clone->recursiveRedirectServers(fftParams) ;
342 pdf2Clone->recursiveRedirectServers(fftParams) ;
343 pdf1Clone->fixAddCoefRange(refName.c_str(),
true) ;
344 pdf2Clone->fixAddCoefRange(refName.c_str(),
true) ;
348 pdf1Clone->fixAddCoefNormalization(convSet,
true);
349 pdf2Clone->fixAddCoefNormalization(convSet,
true);
356 oocoutW(&self, Eval) <<
"The FFT convolution '" << self.
GetName() <<
"' will run with " <<
N
357 <<
" bins. A decent accuracy for difficult convolutions is typically only reached with n >= 1000. Suggest to increase the number"
358 " of bins of the observable '" << convObs->
GetName() <<
"'." << std::endl;
391 ret.
add(*pdf1Clone) ;
392 ret.
add(*pdf2Clone) ;
393 if (pdf1Clone->ownedComponents()) {
394 ret.
add(*pdf1Clone->ownedComponents()) ;
396 if (pdf2Clone->ownedComponents()) {
397 ret.
add(*pdf2Clone->ownedComponents()) ;
421 otherObs.
remove(*histArg,
true,
true) ;
427 if (otherObs.
empty()) {
437 std::vector<int> binCur(
n+1);
438 std::vector<int> binMax(
n+1);
441 std::vector<RooAbsLValue*> obsLV(
n);
443 for (
auto const& arg : otherObs) {
463 while(binCur[curObs]==binMax[curObs]) {
504 Int_t N,N2,binShift1,binShift2 ;
522 coutF(Eval) <<
"RooFFTConvPdf::fillCacheSlice(" <<
GetName() <<
"Cannot get a handle to fftw. Maybe ROOT was built without it?" << std::endl;
523 throw std::runtime_error(
"Cannot get a handle to fftw.");
528 aux.
fftr2c1->SetPoints(input1.data());
532 aux.
fftr2c2->SetPoints(input2.data());
537 for (
Int_t i=0 ; i<N2/2+1 ; i++) {
538 double re1,re2,im1,im2 ;
539 aux.
fftr2c1->GetPointComplex(i,re1,im1) ;
540 aux.
fftr2c2->GetPointComplex(i,re2,im2) ;
541 double re = re1*re2 - im1*im2 ;
542 double im = re1*im2 + re2*im1 ;
544 aux.
fftc2r->SetPointComplex(i,t) ;
550 Int_t totalShift = binShift1 + (N2-
N)/2 ;
554 std::unique_ptr<TIterator> iter{
const_cast<RooDataHist&
>(cacheHist).sliceIterator(
const_cast<RooAbsReal&
>(
_x.
arg()),slicePos)};
555 for (
Int_t i =0 ; i<
N ; i++) {
558 Int_t j = i + totalShift ;
560 while (j>=N2) j-= N2 ;
563 cacheHist.
set(aux.
fftc2r->GetPointReal(j)) ;
589 std::vector<double> array(N2);
598 }
else if (histX->
getMin()>0) {
608 zeroBin += binShift ;
609 while(zeroBin>=N2) zeroBin-= N2 ;
610 while(zeroBin<0) zeroBin+= N2 ;
613 std::vector<double> tmp(N2);
619 for (k=0 ; k<N2 ; k++) {
631 for (k=0 ; k<Nbuf ; k++) {
634 for (k=0 ; k<
N ; k++) {
640 for (k=0 ; k<Nbuf ; k++) {
641 tmp[
N+Nbuf+k] = val ;
649 for (k=0 ; k<
N ; k++) {
653 for (k=1 ; k<=Nbuf ; k++) {
663 for (
Int_t i=0 ; i<N2 ; i++) {
665 Int_t j = i - (zeroBin) ;
696 obs1->add(obs2,
true) ;
703 for(
auto const& arg : *obs1) {
708 obs1->remove(killList) ;
711 obs1->add(
_x.
arg(),
true) ;
720 for(
auto const& arg : *obs1) {
725 obs1->remove(killList) ;
730 obs1->add(
_x.
arg(),
true) ;
763 return histObservable ;
776 const RooArgSet* auxProto,
bool verbose)
const
790 <<
" has internal generator that is safe to use in current context" << endl ;
794 <<
" has internal generator that is safe to use in current context" << endl ;
797 cxcoutI(Generation) <<
"RooFFTConvPdf::genContext() generation requested for observables other than the convolution observable " <<
_x.
arg().
GetName() << endl ;
801 if (numAddDep>0 || !pdfCanDir || !resCanDir) {
804 cxcoutI(Generation) <<
"RooFFTConvPdf::genContext() selecting accept/reject generator context because one or both of the input "
805 <<
"p.d.f.s cannot use internal generator and/or "
806 <<
"observables other than the convolution variable are requested for generation" << endl ;
807 return new RooGenContext(*
this,vars,prototype,auxProto,verbose) ;
811 cxcoutI(Generation) <<
"RooFFTConvPdf::genContext() selecting specialized convolution generator context as both input "
812 <<
"p.d.fs are safe for internal generator and only "
813 <<
"the convolution observables is requested for generation" << endl ;
826 coutE(InputArguments) <<
"RooFFTConvPdf::setBufferFraction(" <<
GetName() <<
") fraction should be greater than or equal to zero" << endl ;
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
void setOperMode(OperMode mode, bool recurseADirty=true)
Set the operation mode of this node.
RooFit::OwningPtr< RooArgSet > getParameters(const RooAbsData *data, bool stripDisconnected=true) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don't match any of...
RooFit::OwningPtr< RooArgSet > getObservables(const RooArgSet &set, bool valueOnly=true) const
Given a set of possible observables, return the observables that this PDF depends on.
RooFit::OwningPtr< RooArgSet > getVariables(bool stripDisconnected=true) const
Return RooArgSet with all variables (tree leaf nodes of expresssion tree)
virtual RooAbsArg * cloneTree(const char *newname=nullptr) const
Clone tree expression of objects.
void attachDataSet(const RooAbsData &set)
Replace server nodes with names matching the dataset variable names with those data set variables,...
RooAbsBinning is the abstract base class for RooRealVar binning definitions.
int binNumber(double x) const
Returns the bin number corresponding to the value x.
Int_t numBins() const
Return number of bins.
virtual bool isUniform() const
virtual double highBound() const =0
virtual double lowBound() const =0
virtual RooAbsBinning * clone(const char *name=nullptr) const =0
RooAbsCachedPdf is the abstract base class for p.d.f.s that need or want to cache their evaluate() ou...
virtual const char * binningName() const
RooObjCacheManager _cacheMgr
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
bool contains(const RooAbsArg &var) const
Check if collection contains an argument with the same name as var.
Int_t getSize() const
Return the number of elements in the collection.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
RooAbsArg * find(const char *name) const
Find object with given name in list.
void setDirtyProp(bool flag)
Control propagation of dirty flags from observables in dataset.
RooAbsGenContext is the abstract base class for generator contexts of RooAbsPdf objects.
Abstract base class for objects that are lvalues, i.e.
virtual Int_t numBins(const char *rangeName=nullptr) const =0
virtual bool isDirectGenSafe(const RooAbsArg &arg) const
Check if given observable can be safely generated using the pdfs internal generator mechanism (if tha...
virtual Int_t getGenerator(const RooArgSet &directVars, RooArgSet &generateVars, bool staticInitOK=true) const
Load generatedVars with the subset of directVars that we can generate events for, and return a code t...
Int_t numBins(const char *rangeName=nullptr) const override
virtual double getMax(const char *name=nullptr) const
Get maximum of currently defined range.
void setBin(Int_t ibin, const char *rangeName=nullptr) override
Set value to center of bin 'ibin' of binning 'rangeName' (or of default binning if no range is specif...
virtual double getMin(const char *name=nullptr) const
Get minimum of currently defined range.
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
RooArgList is a container object that can hold multiple RooAbsArg objects.
RooAbsArg * absArg() const
Return pointer to contained argument.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
void removeAll() override
Remove all argument inset using remove(const RooAbsArg&).
bool add(const RooAbsArg &var, bool valueServer, bool shapeServer, bool silent)
Overloaded RooCollection_t::add() method insert object into set and registers object as server to own...
RooCustomizer is a factory class to produce clones of a prototype composite PDF object with the same ...
void replaceArg(const RooAbsArg &orig, const RooAbsArg &subst)
Replace any occurence of arg 'orig' with arg 'subst'.
RooAbsArg * build(const char *masterCatState, bool verbose=false)
Build a clone of the prototype executing all registered 'replace' rules and 'split' rules for the mas...
The RooDataHist is a container class to hold N-dimensional binned data.
void set(std::size_t binNumber, double weight, double wgtErr)
Set bin content of bin that was last loaded with get(std::size_t).
const RooArgSet * get() const override
Get bin centre of current bin.
RooDataSet is a container class to hold unbinned data.
std::unique_ptr< TVirtualFFT > fftr2c2
std::unique_ptr< TVirtualFFT > fftc2r
RooArgList containedArgs(Action) override
Returns all RooAbsArg objects contained in the cache element.
std::unique_ptr< RooAbsPdf > pdf2Clone
FFTCacheElem(const RooFFTConvPdf &self, const RooArgSet *nset)
Clone input pdf and attach to dataset.
std::unique_ptr< RooAbsBinning > histBinning
std::unique_ptr< RooAbsBinning > scanBinning
std::unique_ptr< RooAbsPdf > pdf1Clone
std::unique_ptr< TVirtualFFT > fftr2c1
PDF for the numerical (FFT) convolution of two PDFs.
friend class RooConvGenContext
RooSetProxy _params
Effective parameters of this p.d.f.
void calcParams()
(Re)calculate effective parameters of this p.d.f.
void setBufferFraction(double frac)
Change the size of the buffer on either side of the observable range to frac times the size of the ra...
double bufferFraction() const
Return value of buffer fraction applied in FFT calculation array beyond either end of the observable ...
TString histNameSuffix() const override
Suffix for cache histogram (added in addition to suffix for cache name)
void prepareFFTBinning(RooRealVar &convVar) const
Try to improve the binning and inform user if possible.
void fillCacheSlice(FFTCacheElem &cache, const RooArgSet &slicePosition) const
Fill a slice of cachePdf with the output of the FFT convolution calculation.
RooRealProxy _xprime
Input function representing value of convolution observable.
std::vector< double > scanPdf(RooRealVar &obs, RooAbsPdf &pdf, const RooDataHist &hist, const RooArgSet &slicePos, Int_t &N, Int_t &N2, Int_t &zeroBin, double shift) const
Scan the values of 'pdf' in observable 'obs' using the bin values stored in 'hist' at slice position ...
RooRealProxy _pdf1
First input p.d.f.
RooRealProxy _x
Convolution observable.
const char * inputBaseName() const override
Return base name component for cache components in this case 'PDF1_CONV_PDF2'.
RooAbsArg & pdfObservable(RooAbsArg &histObservable) const override
Return p.d.f.
~RooFFTConvPdf() override
Destructor.
RooFit::OwningPtr< RooArgSet > actualParameters(const RooArgSet &nset) const override
Return the parameters on which the cache depends given normalization set nset.
RooRealProxy _pdf2
Second input p.d.f.
void printMetaArgs(std::ostream &os) const override
Customized printing of arguments of a RooNumConvPdf to more intuitively reflect the contents of the p...
void setBufferStrategy(BufStrat bs)
Change strategy to fill the overflow buffer on either side of the convolution observable range.
PdfCacheElem * createCache(const RooArgSet *nset) const override
Return specialized cache subclass for FFT calculations.
RooAbsGenContext * genContext(const RooArgSet &vars, const RooDataSet *prototype=nullptr, const RooArgSet *auxProto=nullptr, bool verbose=false) const override
Create appropriate generator context for this convolution.
RooFit::OwningPtr< RooArgSet > actualObservables(const RooArgSet &nset) const override
Return the observables to be cached given the normalization set nset.
void fillCacheObject(PdfCacheElem &cache) const override
Fill the contents of the cache the FFT convolution output.
RooSetProxy _cacheObs
Non-convolution observables that are also cached.
Class RooGenContext implement a universal generator context for all RooAbsPdf classes that do not hav...
RooLinearVar is the most general form of a derived real-valued object that can be used by RooRealInte...
void sterilize() override
Clear the cache payload but retain slot mapping w.r.t to normalization and integration sets.
RooRealVar represents a variable that can be changed from the outside.
bool hasBinning(const char *name) const override
Returns true if variable has a binning named 'name'.
const RooAbsBinning & getBinning(const char *name=nullptr, bool verbose=true, bool createOnTheFly=false) const override
Return binning definition with name.
void setBinning(const RooAbsBinning &binning, const char *name=nullptr)
Add given binning under name 'name' with this variable.
void setRange(const char *name, double min, double max)
Set a fit or plotting range.
const T & arg() const
Return reference to object held in proxy.
const char * GetName() const override
Returns name of object.
static TVirtualFFT * FFT(Int_t ndim, Int_t *n, Option_t *option)
Returns a pointer to the FFT of requested size and type.
RooConstVar & RooConst(double val)
T * OwningPtr
An alias for raw pointers for indicating that the return type of a RooFit function is an owning point...