48 ClassImp(RooNDKeysPdf);
71 RooNDKeysPdf::RooNDKeysPdf(
const char *name,
const char *title,
const RooArgList &varList,
const RooDataSet &data,
72 TString options, Double_t rho, Double_t nSigma, Bool_t rotate, Bool_t sortInput)
73 : RooAbsPdf(name, title), _varList(
"varList",
"List of variables", this),
74 _rhoList(
"rhoList",
"List of rho parameters", this), _data(&data), _options(options), _widthFactor(rho),
75 _nSigma(nSigma), _weights(&_weights0), _rotate(rotate), _sortInput(sortInput), _nAdpt(1), _tracker(0)
79 for (
const auto var : varList) {
80 if (!dynamic_cast<const RooAbsReal*>(var)) {
81 coutE(InputArguments) <<
"RooNDKeysPdf::ctor(" << GetName() <<
") ERROR: variable " << var->GetName()
82 <<
" is not of type RooAbsReal" << endl ;
86 _varName.push_back(var->GetName());
95 RooNDKeysPdf::RooNDKeysPdf(
const char *name,
const char *title,
const RooArgList &varList,
const TH1 &hist,
96 TString options, Double_t rho, Double_t nSigma, Bool_t rotate, Bool_t sortInput)
97 : RooAbsPdf(name, title), _varList(
"varList",
"List of variables", this),
98 _rhoList(
"rhoList",
"List of rho parameters", this), _ownedData(createDatasetFromHist(varList, hist)), _data(_ownedData.get()),
99 _options(options), _widthFactor(rho), _nSigma(nSigma), _weights(&_weights0), _rotate(rotate),
100 _sortInput(sortInput), _nAdpt(1), _tracker(0)
102 for (
const auto var : varList) {
103 if (!dynamic_cast<const RooAbsReal *>(var)) {
104 coutE(InputArguments) <<
"RooNDKeysPdf::ctor(" << GetName() <<
") ERROR: variable " << var->GetName()
105 <<
" is not of type RooAbsReal" << endl;
109 _varName.push_back(var->GetName());
118 RooNDKeysPdf::RooNDKeysPdf(
const char *name,
const char *title,
const RooArgList &varList,
const RooDataSet &data,
119 const TVectorD &rho, TString options, Double_t nSigma, Bool_t rotate, Bool_t sortInput)
120 : RooAbsPdf(name, title), _varList(
"varList",
"List of variables", this),
121 _rhoList(
"rhoList",
"List of rho parameters", this), _data(&data), _options(options), _widthFactor(-1.0),
122 _nSigma(nSigma), _weights(&_weights0), _rotate(rotate), _sortInput(sortInput), _nAdpt(1), _tracker(0)
124 for (
const auto var : varList) {
125 if (!dynamic_cast<const RooAbsReal*>(var)) {
126 coutE(InputArguments) <<
"RooNDKeysPdf::ctor(" << GetName() <<
") ERROR: variable " << var->GetName()
127 <<
" is not of type RooAbsReal" << endl;
131 _varName.push_back(var->GetName());
135 if( _varList.getSize() != rho.GetNrows() ) {
136 coutE(InputArguments)
137 <<
"ERROR: RooNDKeysPdf::RooNDKeysPdf() : The vector-size of rho is different from that of varList."
138 <<
"Unable to create the PDF." << endl;
139 R__ASSERT(_varList.getSize() == rho.GetNrows());
145 _rho.resize( rho.GetNrows() );
146 for (Int_t j = 0; j < rho.GetNrows(); j++) {
157 RooNDKeysPdf::RooNDKeysPdf(
const char *name,
const char *title,
const RooArgList &varList,
const RooDataSet &data,
158 const RooArgList &rhoList, TString options, Double_t nSigma, Bool_t rotate, Bool_t sortInput)
159 : RooAbsPdf(name, title), _varList(
"varList",
"List of variables", this),
160 _rhoList(
"rhoList",
"List of rho parameters", this), _data(&data), _options(options), _widthFactor(-1.0),
161 _nSigma(nSigma), _weights(&_weights0), _rotate(rotate), _sortInput(sortInput), _nAdpt(1)
163 for (
const auto var : varList) {
164 if (!dynamic_cast<RooAbsReal *>(var)) {
165 coutE(InputArguments) <<
"RooNDKeysPdf::ctor(" << GetName() <<
") ERROR: variable " << var->GetName()
166 <<
" is not of type RooAbsReal" << endl;
170 _varName.push_back(var->GetName());
173 _rho.resize(rhoList.getSize(), 1.0);
175 for (
unsigned int i=0; i < rhoList.size(); ++i) {
176 const auto rho = rhoList.at(i);
177 if (!dynamic_cast<const RooAbsReal *>(rho)) {
178 coutE(InputArguments) <<
"RooNDKeysPdf::ctor(" << GetName() <<
") ERROR: parameter " << rho->GetName()
179 <<
" is not of type RooRealVar" << endl;
183 _rho[i] = (
dynamic_cast<RooAbsReal *
>(rho))->getVal();
187 if ((_varList.getSize() != _rhoList.getSize())) {
188 coutE(InputArguments) <<
"ERROR: RooNDKeysPdf::RooNDKeysPdf() : The size of rhoList is different from varList."
189 <<
"Unable to create the PDF." << endl;
190 assert(_varList.getSize() == _rhoList.getSize());
194 _tracker =
new RooChangeTracker(
"tracker",
"track rho parameters", _rhoList,
true);
195 (void)_tracker->hasChanged(
true);
203 RooNDKeysPdf::RooNDKeysPdf(
const char *name,
const char *title,
const RooArgList &varList,
const TH1 &hist,
204 const RooArgList &rhoList, TString options, Double_t nSigma, Bool_t rotate, Bool_t sortInput)
205 : RooAbsPdf(name, title), _varList(
"varList",
"List of variables", this),
206 _rhoList(
"rhoList",
"List of rho parameters", this), _ownedData(createDatasetFromHist(varList, hist)), _data(_ownedData.get()),
207 _options(options), _widthFactor(-1), _nSigma(nSigma), _weights(&_weights0), _rotate(rotate), _sortInput(sortInput),
210 for (
const auto var : varList) {
211 if (!dynamic_cast<RooAbsReal *>(var)) {
212 coutE(InputArguments) <<
"RooNDKeysPdf::ctor(" << GetName() <<
") ERROR: variable " << var->GetName()
213 <<
" is not of type RooAbsReal" << endl;
217 _varName.push_back(var->GetName());
221 _rho.resize(rhoList.getSize(), 1.0);
223 for (
unsigned int i=0; i < rhoList.size(); ++i) {
224 const auto rho = rhoList.at(i);
225 if (!dynamic_cast<RooAbsReal *>(rho)) {
226 coutE(InputArguments) <<
"RooNDKeysPdf::ctor(" << GetName() <<
") ERROR: parameter " << rho->GetName()
227 <<
" is not of type RooRealVar" << endl;
231 _rho[i] = (
dynamic_cast<RooAbsReal *
>(rho))->getVal();
234 if ((_varList.getSize() != _rhoList.getSize())) {
235 coutE(InputArguments) <<
"ERROR: RooNDKeysPdf::RooNDKeysPdf() : The size of rhoList is different from varList."
236 <<
"Unable to create the PDF." << endl;
237 assert(_varList.getSize() == _rhoList.getSize());
241 _tracker =
new RooChangeTracker(
"tracker",
"track rho parameters", _rhoList,
true);
242 (void)_tracker->hasChanged(
true);
250 RooNDKeysPdf::RooNDKeysPdf(
const char *name,
const char *title, RooAbsReal &x,
const RooDataSet &data, Mirror mirror,
251 Double_t rho, Double_t nSigma, Bool_t rotate, Bool_t sortInput)
252 : RooAbsPdf(name, title), _varList(
"varList",
"List of variables", this),
253 _rhoList(
"rhoList",
"List of rho parameters", this), _data(&data), _options(
"a"), _widthFactor(rho),
254 _nSigma(nSigma), _weights(&_weights0), _rotate(rotate), _sortInput(sortInput), _nAdpt(1), _tracker(0)
257 _varName.push_back(x.GetName());
259 if (mirror != NoMirror) {
260 if (mirror != MirrorBoth)
261 coutW(InputArguments) <<
"RooNDKeysPdf::RooNDKeysPdf() : Warning : asymmetric mirror(s) no longer supported."
273 RooNDKeysPdf::RooNDKeysPdf(
const char *name,
const char *title, RooAbsReal &x, RooAbsReal &y,
const RooDataSet &data,
274 TString options, Double_t rho, Double_t nSigma, Bool_t rotate, Bool_t sortInput)
275 : RooAbsPdf(name, title), _varList(
"varList",
"List of variables", this),
276 _rhoList(
"rhoList",
"List of rho parameters", this), _data(&data), _options(options), _widthFactor(rho),
277 _nSigma(nSigma), _weights(&_weights0), _rotate(rotate), _sortInput(sortInput), _nAdpt(1), _tracker(0)
279 _varList.add(RooArgSet(x, y));
280 _varName.push_back(x.GetName());
281 _varName.push_back(y.GetName());
289 RooNDKeysPdf::RooNDKeysPdf(
const RooNDKeysPdf &other,
const char *name)
290 : RooAbsPdf(other, name), _varList(
"varList", this, other._varList), _rhoList(
"rhoList", this, other._rhoList),
291 _ownedData(other._ownedData ? new RooDataSet(*other._ownedData) : nullptr),
292 _data(_ownedData ? _ownedData.get() : other._data), _options(other._options), _widthFactor(other._widthFactor),
293 _nSigma(other._nSigma), _weights(&_weights0), _rotate(other._rotate), _sortInput(other._sortInput),
296 _tracker = (other._tracker != NULL ?
new RooChangeTracker(*other._tracker) : NULL);
299 _fixedShape = other._fixedShape;
300 _mirror = other._mirror;
301 _debug = other._debug;
302 _verbose = other._verbose;
304 _nEvents = other._nEvents;
305 _nEventsM = other._nEventsM;
306 _nEventsW = other._nEventsW;
309 _dataPts = other._dataPts;
310 _dataPtsR = other._dataPtsR;
311 _weights0 = other._weights0;
312 _weights1 = other._weights1;
313 if (_options.Contains(
"a")) {
314 _weights = &_weights1;
316 _sortTVIdcs = other._sortTVIdcs;
317 _varName = other._varName;
323 _xDatLo = other._xDatLo;
324 _xDatHi = other._xDatHi;
325 _xDatLo3s = other._xDatLo3s;
326 _xDatHi3s = other._xDatHi3s;
328 _sigma = other._sigma;
331 _netFluxZ = other._netFluxZ;
332 _nEventsBW = other._nEventsBW;
333 _nEventsBMSW = other._nEventsBMSW;
334 _xVarLo = other._xVarLo;
335 _xVarHi = other._xVarHi;
336 _xVarLoM3s = other._xVarLoM3s;
337 _xVarLoP3s = other._xVarLoP3s;
338 _xVarHiM3s = other._xVarHiM3s;
339 _xVarHiP3s = other._xVarHiP3s;
340 _bpsIdcs = other._bpsIdcs;
341 _ibNoSort = other._ibNoSort;
342 _sIdcs = other._sIdcs;
343 _bIdcs = other._bIdcs;
344 _bmsIdcs = other._bmsIdcs;
346 _rangeBoxInfo = other._rangeBoxInfo;
347 _fullBoxInfo = other._fullBoxInfo;
350 _minWeight = other._minWeight;
351 _maxWeight = other._maxWeight;
354 _covMat =
new TMatrixDSym(*other._covMat);
355 _corrMat =
new TMatrixDSym(*other._corrMat);
356 _rotMat =
new TMatrixD(*other._rotMat);
357 _sigmaR =
new TVectorD(*other._sigmaR);
358 _dx =
new TVectorD(*other._dx);
359 _sigmaAvgR = other._sigmaAvgR;
364 RooNDKeysPdf::~RooNDKeysPdf()
366 if (_covMat)
delete _covMat;
367 if (_corrMat)
delete _corrMat;
368 if (_rotMat)
delete _rotMat;
369 if (_sigmaR)
delete _sigmaR;
375 while ( !_rangeBoxInfo.empty() ) {
376 map<pair<string,int>,BoxInfo*>::iterator iter = _rangeBoxInfo.begin();
377 BoxInfo* box= (*iter).second;
378 _rangeBoxInfo.erase(iter);
386 void RooNDKeysPdf::createPdf(Bool_t firstCall)
397 loadDataSet(firstCall);
400 if (_mirror) mirrorDataSet();
411 const_cast<RooNDKeysPdf*
>(
this)->sortDataIndices();
414 calculateBandWidth();
420 void RooNDKeysPdf::setOptions()
424 if( _options.Contains(
"a") ) { _weights = &_weights1; }
425 else { _weights = &_weights0; }
426 if( _options.Contains(
"m") ) _mirror =
true;
427 else _mirror =
false;
428 if( _options.Contains(
"d") ) _debug =
true;
430 if( _options.Contains(
"v") ) { _debug =
true; _verbose =
true; }
431 else { _debug =
false; _verbose =
false; }
433 cxcoutD(InputArguments) <<
"RooNDKeysPdf::setOptions() options = " << _options
434 <<
"\n\tbandWidthType = " << _options.Contains(
"a")
435 <<
"\n\tmirror = " << _mirror
436 <<
"\n\tdebug = " << _debug
437 <<
"\n\tverbose = " << _verbose
441 coutW(InputArguments) <<
"RooNDKeysPdf::setOptions() : Warning : nSigma = " << _nSigma <<
" < 2.0. "
442 <<
"Calculated normalization could be too large."
447 if (_options.Contains(
"a")) {
448 if (!sscanf(_options.Data(),
"%d%*s", &_nAdpt)) {
457 void RooNDKeysPdf::initialize()
459 _nDim = _varList.getSize();
460 _nEvents = (Int_t)_data->numEntries();
461 _nEventsM = _nEvents;
469 coutE(InputArguments) <<
"ERROR: RooNDKeysPdf::initialize() : The observable list is empty. "
470 <<
"Unable to begin generating the PDF." << endl;
471 R__ASSERT (_nDim!=0);
475 coutE(InputArguments) <<
"ERROR: RooNDKeysPdf::initialize() : The input data set is empty. "
476 <<
"Unable to begin generating the PDF." << endl;
477 R__ASSERT (_nEvents!=0);
480 _d =
static_cast<Double_t
>(_nDim);
482 vector<Double_t> dummy(_nDim,0.);
483 _dataPts.resize(_nEvents,dummy);
484 _weights0.resize(_nEvents,dummy);
488 if (_widthFactor>0) { _rho.resize(_nDim,_widthFactor); }
492 _x0.resize(_nDim,0.);
493 _x1.resize(_nDim,0.);
494 _x2.resize(_nDim,0.);
496 _mean.resize(_nDim,0.);
497 _sigma.resize(_nDim,0.);
499 _xDatLo.resize(_nDim,0.);
500 _xDatHi.resize(_nDim,0.);
501 _xDatLo3s.resize(_nDim,0.);
502 _xDatHi3s.resize(_nDim,0.);
504 boxInfoInit(&_fullBoxInfo,0,0xFFFF);
514 _dx =
new TVectorD(_nDim); _dx->Zero();
515 _dataPtsR.resize(_nEvents,*_dx);
517 for(
unsigned int j=0; j < _varList.size(); ++j) {
518 auto& var =
static_cast<const RooRealVar&
>(_varList[j]);
519 _xDatLo[j] = var.getMin();
520 _xDatHi[j] = var.getMax();
527 void RooNDKeysPdf::loadDataSet(Bool_t firstCall)
const
532 TMatrixD mat(_nDim,_nDim);
533 if (!_covMat) _covMat =
new TMatrixDSym(_nDim);
534 if (!_corrMat) _corrMat=
new TMatrixDSym(_nDim);
535 if (!_rotMat) _rotMat =
new TMatrixD(_nDim,_nDim);
536 if (!_sigmaR) _sigmaR =
new TVectorD(_nDim);
544 const RooArgSet* values= _data->get();
545 vector<RooRealVar*> dVars(_nDim);
546 for (Int_t j=0; j<_nDim; j++) {
547 dVars[j] = (RooRealVar*)values->find(_varName[j].c_str());
548 _x0[j]=_x1[j]=_x2[j]=0.;
552 for (Int_t i=0; i<_nEvents; i++) {
556 vector<Double_t>& point = _dataPts[i];
557 TVectorD& pointV = _dataPtsR[i];
559 Double_t myweight = _data->weight();
560 if ( TMath::Abs(myweight)>_maxWeight ) { _maxWeight = TMath::Abs(myweight); }
561 _nEventsW += myweight;
563 for (Int_t j=0; j<_nDim; j++) {
564 for (Int_t k=0; k<_nDim; k++) {
565 mat(j,k) += dVars[j]->getVal() * dVars[k]->getVal() * myweight;
569 point[j] = pointV[j] = dVars[j]->getVal();
571 _x0[j] += 1. * myweight;
572 _x1[j] += point[j] * myweight ;
573 _x2[j] += point[j] * point[j] * myweight ;
574 if (_x2[j]!=_x2[j]) exit(3);
578 if (point[j]<_xDatLo[j]) { _xDatLo[j]=point[j]; }
579 if (point[j]>_xDatHi[j]) { _xDatHi[j]=point[j]; }
584 _n = TMath::Power(4./(_nEventsW*(_d+2.)), 1./(_d+4.)) ;
586 _minWeight = (0.5 - TMath::Erf(_nSigma/sqrt(2.))/2.) * _maxWeight;
588 for (Int_t j=0; j<_nDim; j++) {
589 _mean[j] = _x1[j]/_x0[j];
590 _sigma[j] = sqrt(_x2[j]/_x0[j]-_mean[j]*_mean[j]);
593 for (Int_t j=0; j<_nDim; j++) {
594 for (Int_t k=0; k<_nDim; k++) {
595 (*_covMat)(j,k) = mat(j,k)/_x0[j] - _mean[j]*_mean[k];
599 for (Int_t j=0; j<_nDim; j++) {
600 for (Int_t k=0; k<_nDim; k++)
601 (*_corrMat)(j,k) = (*_covMat)(j,k)/(_sigma[j]*_sigma[k]) ;
605 TMatrixDSymEigen evCalculator(*_covMat);
606 TVectorD sigmaRraw = evCalculator.GetEigenValues();
607 for (Int_t j=0; j<_nDim; j++) { sigmaRraw[j] = sqrt(sigmaRraw[j]); }
610 for (Int_t j=0; j<_nDim; j++) { _sigmaAvgR *= sigmaRraw[j]; }
611 _sigmaAvgR = TMath::Power(_sigmaAvgR, 1./_d) ;
614 if (_nDim > 1 && _rotate) {
616 *_rotMat = evCalculator.GetEigenVectors();
617 *_rotMat = _rotMat->T();
619 TMatrixD haar(_nDim, _nDim);
620 TMatrixD unit(TMatrixD::kUnit, haar);
638 if (_nDim > 1 && _rotate) {
640 for (Int_t i = 0; i < _nEvents; i++) {
641 TVectorD &pointR = _dataPtsR[i];
646 coutI(Contents) <<
"RooNDKeysPdf::loadDataSet(" <<
this <<
")"
647 <<
"\n Number of events in dataset: " << _nEvents
648 <<
"\n Weighted number of events in dataset: " << _nEventsW << endl;
658 void RooNDKeysPdf::mirrorDataSet()
const
660 for (Int_t j=0; j<_nDim; j++) {
661 _xDatLo3s[j] = _xDatLo[j] + _nSigma * (_n * _sigma[j]);
662 _xDatHi3s[j] = _xDatHi[j] - _nSigma * (_n * _sigma[j]);
668 vector<Double_t> dummy(_nDim,0.);
671 for (Int_t i=0; i<_nEvents; i++) {
672 vector<Double_t>& x = _dataPts[i];
675 vector<vector<Double_t> > mpoints(size,dummy);
676 vector<vector<Int_t> > mjdcs(size);
679 for (Int_t j=0; j<_nDim; j++) {
681 vector<Int_t>& mjdxK = mjdcs[0];
682 vector<Double_t>& mpointK = mpoints[0];
685 if ((x[j]>_xDatLo[j] && x[j]<_xDatLo3s[j]) && x[j]<(_xDatLo[j]+_xDatHi[j])/2.) {
686 mpointK[j] = 2.*_xDatLo[j]-x[j];
688 }
else if ((x[j]<_xDatHi[j] && x[j]>_xDatHi3s[j]) && x[j]>(_xDatLo[j]+_xDatHi[j])/2.) {
689 mpointK[j] = 2.*_xDatHi[j]-x[j];
694 vector<Int_t>& mjdx0 = mjdcs[0];
696 if (size==1 && mjdx0.size()==0)
continue;
700 vector<Int_t>& mjdx = mjdcs[0];
701 vector<Double_t>& mpoint = mpoints[0];
704 Int_t eMir = 1 << mjdx.size();
705 vector<vector<Double_t> > epoints(eMir,x);
707 for (Int_t m=0; m<Int_t(mjdx.size()); m++) {
708 Int_t size1 = 1 << m;
709 Int_t size2 = 1 << (m+1);
711 for (Int_t l=size1; l<size2; ++l) {
712 epoints[l] = epoints[l-size1];
714 vector<Double_t>& epoint = epoints[l];
715 epoint[mjdx[Int_t(mjdx.size()-1)-m]] = mpoint[mjdx[Int_t(mjdx.size()-1)-m]];
721 epoints.erase(epoints.begin());
724 TVectorD pointR(_nDim);
726 for (Int_t m=0; m<Int_t(epoints.size()); m++) {
728 _dataPts.push_back(epoints[m]);
730 for (Int_t j=0; j<_nDim; j++) { pointR[j] = (epoints[m])[j]; }
731 if (_nDim > 1 && _rotate) {
734 _dataPtsR.push_back(pointR);
742 _nEventsM = Int_t(_dataPts.size());
747 void RooNDKeysPdf::loadWeightSet()
const
751 for (Int_t i=0; i<_nEventsM; i++) {
753 Double_t myweight = _data->weight();
759 coutI(Contents) <<
"RooNDKeysPdf::loadWeightSet(" <<
this <<
") : Number of weighted events : " << _wMap.size() << endl;
767 void RooNDKeysPdf::calculateShell(BoxInfo* bi)
const
769 for (Int_t j=0; j<_nDim; j++) {
770 if (bi->xVarLo[j]==_xDatLo[j] && bi->xVarHi[j]==_xDatHi[j]) {
771 bi->netFluxZ = bi->netFluxZ && kTRUE;
772 }
else { bi->netFluxZ = kFALSE; }
774 bi->xVarLoM3s[j] = bi->xVarLo[j] - _nSigma * (_n * _sigma[j]);
775 bi->xVarLoP3s[j] = bi->xVarLo[j] + _nSigma * (_n * _sigma[j]);
776 bi->xVarHiM3s[j] = bi->xVarHi[j] - _nSigma * (_n * _sigma[j]);
777 bi->xVarHiP3s[j] = bi->xVarHi[j] + _nSigma * (_n * _sigma[j]);
785 map<Int_t,Double_t>::iterator wMapItr = _wMap.begin();
788 for (; wMapItr!=_wMap.end(); ++wMapItr) {
789 Int_t i = (*wMapItr).first;
791 const vector<Double_t>& x = _dataPts[i];
792 Bool_t inVarRange(kTRUE);
793 Bool_t inVarRangePlusShell(kTRUE);
795 for (Int_t j=0; j<_nDim; j++) {
797 if (x[j]>bi->xVarLo[j] && x[j]<bi->xVarHi[j]) {
798 inVarRange = inVarRange && kTRUE;
799 }
else { inVarRange = inVarRange && kFALSE; }
801 if (x[j]>bi->xVarLoM3s[j] && x[j]<bi->xVarHiP3s[j]) {
802 inVarRangePlusShell = inVarRangePlusShell && kTRUE;
803 }
else { inVarRangePlusShell = inVarRangePlusShell && kFALSE; }
808 bi->bIdcs.push_back(i);
812 if (inVarRangePlusShell) {
813 bi->bpsIdcs[i] = kTRUE;
814 Bool_t inShell(kFALSE);
815 for (Int_t j=0; j<_nDim; j++) {
816 if ((x[j]>bi->xVarLoM3s[j] && x[j]<bi->xVarLoP3s[j]) && x[j]<(bi->xVarLo[j]+bi->xVarHi[j])/2.) {
818 }
else if ((x[j]>bi->xVarHiM3s[j] && x[j]<bi->xVarHiP3s[j]) && x[j]>(bi->xVarLo[j]+bi->xVarHi[j])/2.) {
822 if (inShell) bi->sIdcs.push_back(i);
824 bi->bmsIdcs.push_back(i);
829 coutI(Contents) <<
"RooNDKeysPdf::calculateShell() : "
830 <<
"\n Events in shell " << bi->sIdcs.size()
831 <<
"\n Events in box " << bi->bIdcs.size()
832 <<
"\n Events in box and shell " << bi->bpsIdcs.size()
840 void RooNDKeysPdf::calculatePreNorm(BoxInfo* bi)
const
843 for (Int_t i=0; i<Int_t(bi->bmsIdcs.size()); i++)
844 bi->nEventsBMSW += _wMap[bi->bmsIdcs[i]];
847 for (Int_t i=0; i<Int_t(bi->bIdcs.size()); i++)
848 bi->nEventsBW += _wMap[bi->bIdcs[i]];
850 cxcoutD(Eval) <<
"RooNDKeysPdf::calculatePreNorm() : "
851 <<
"\n nEventsBMSW " << bi->nEventsBMSW
852 <<
"\n nEventsBW " << bi->nEventsBW
859 void RooNDKeysPdf::sortDataIndices(BoxInfo* bi)
864 for (
unsigned int i = 0; i < _dataPtsR.size(); ++i) {
865 _ibNoSort[i] = kTRUE;
871 vector<TVectorD>::iterator dpRItr = _dataPtsR.begin();
872 for (Int_t i = 0; dpRItr != _dataPtsR.end(); ++dpRItr, ++i) {
874 if (bi->bpsIdcs.find(i) != bi->bpsIdcs.end())
876 itrVecR.push_back(itPair(i, dpRItr));
878 itrVecR.push_back(itPair(i, dpRItr));
881 _sortTVIdcs.resize(_nDim);
882 for (Int_t j=0; j<_nDim; j++) {
883 _sortTVIdcs[j].clear();
884 sort(itrVecR.begin(), itrVecR.end(), [=](
const itPair& a,
const itPair& b) {
885 return (*a.second)[j] < (*b.second)[j];
887 _sortTVIdcs[j] = itrVecR;
890 for (Int_t j=0; j<_nDim; j++) {
891 cxcoutD(Eval) <<
"RooNDKeysPdf::sortDataIndices() : Number of sorted events : " << _sortTVIdcs[j].size() << endl;
897 void RooNDKeysPdf::calculateBandWidth()
const
899 cxcoutD(Eval) <<
"RooNDKeysPdf::calculateBandWidth()" << endl;
904 if(!_options.Contains(
"a")) {
905 cxcoutD(Eval) <<
"RooNDKeysPdf::calculateBandWidth() Using static bandwidth." << endl;
909 for (Int_t i=0; i<_nEvents; i++) {
910 vector<Double_t>& weight = _weights0[i];
911 for (Int_t j = 0; j < _nDim; j++) {
912 weight[j] = _n * (*_sigmaR)[j];
918 if (_options.Contains(
"a")) {
919 cxcoutD(Eval) <<
"RooNDKeysPdf::calculateBandWidth() Using adaptive bandwidth." << endl;
921 double sqrt12 = sqrt(12.);
922 double sqrtSigmaAvgR = sqrt(_sigmaAvgR);
924 vector<Double_t> dummy(_nDim, 0.);
925 _weights1.resize(_nEvents, dummy);
927 std::vector<std::vector<Double_t>> *weights_prev(0);
928 std::vector<std::vector<Double_t>> *weights_new(0);
932 for (Int_t k = 1; k <= _nAdpt; ++k) {
938 weights_prev = &_weights0;
939 weights_new = &_weights1;
941 weights_prev = &_weights1;
942 weights_new = &_weights0;
945 for (Int_t i = 0; i < _nEvents; ++i) {
946 vector<Double_t> &x = _dataPts[i];
947 Double_t f = TMath::Power(gauss(x, *weights_prev) / _nEventsW, -1. / (2. * _d));
949 vector<Double_t> &weight = (*weights_new)[i];
950 for (Int_t j = 0; j < _nDim; j++) {
951 Double_t norm = (_n * (*_sigmaR)[j]) / sqrtSigmaAvgR;
952 weight[j] = norm * f / sqrt12;
957 _weights = weights_new;
964 Double_t RooNDKeysPdf::gauss(vector<Double_t>& x, vector<vector<Double_t> >& weights)
const
966 if(_nEvents==0)
return 0.;
968 const double sqrt2pi = std::sqrt(TMath::TwoPi());
971 map<Int_t,Bool_t> ibMap;
975 if (_sortTVIdcs.empty())
976 const_cast<RooNDKeysPdf*>(
this)->sortDataIndices();
981 map<Int_t, Bool_t>::iterator ibMapItr, ibMapEnd;
982 ibMapItr = (_sortInput ? ibMap.begin() : _ibNoSort.begin());
983 ibMapEnd = (_sortInput ? ibMap.end() : _ibNoSort.end());
985 for (; ibMapItr != ibMapEnd; ++ibMapItr) {
986 Int_t i = (*ibMapItr).first;
990 if (i >= (Int_t)_idx.size()) {
994 const vector<Double_t> &point = _dataPts[i];
995 const vector<Double_t> &weight = weights[_idx[i]];
997 for (Int_t j = 0; j < _nDim; j++) {
998 (*_dx)[j] = x[j] - point[j];
1001 if (_nDim > 1 && _rotate) {
1005 for (Int_t j = 0; j < _nDim; j++) {
1006 Double_t r = (*_dx)[j];
1007 Double_t c = 1. / (2. * weight[j] * weight[j]);
1011 g *= exp(-c * r * r);
1012 g *= 1. / (sqrt2pi * weight[j]);
1014 z += (g * _wMap[_idx[i]]);
1022 void RooNDKeysPdf::loopRange(vector<Double_t>& x, map<Int_t,Bool_t>& ibMap)
const
1025 TVectorD xRm(_nDim);
1026 TVectorD xRp(_nDim);
1028 for (Int_t j = 0; j < _nDim; j++) {
1029 xRm[j] = xRp[j] = x[j];
1032 if (_nDim > 1 && _rotate) {
1036 for (Int_t j = 0; j < _nDim; j++) {
1037 xRm[j] -= _nSigma * (_n * (*_sigmaR)[j]);
1038 xRp[j] += _nSigma * (_n * (*_sigmaR)[j]);
1043 vector<TVectorD> xvecRm(1,xRm);
1044 vector<TVectorD> xvecRp(1,xRp);
1046 map<Int_t,Bool_t> ibMapRT;
1048 for (Int_t j=0; j<_nDim; j++) {
1050 auto comp = [=](
const itPair& a,
const itPair& b) {
1051 return (*a.second)[j] < (*b.second)[j];
1054 auto lo = lower_bound(_sortTVIdcs[j].begin(), _sortTVIdcs[j].end(), itPair(0, xvecRm.begin()), comp);
1055 auto hi = upper_bound(_sortTVIdcs[j].begin(), _sortTVIdcs[j].end(), itPair(0, xvecRp.begin()), comp);
1059 if (_nDim==1) {
for (it=lo; it!=hi; ++it) ibMap[(*it).first] = kTRUE; }
1060 else {
for (it=lo; it!=hi; ++it) ibMapRT[(*it).first] = kTRUE; }
1064 for (it=lo; it!=hi; ++it)
1065 if (ibMapRT.find((*it).first)!=ibMapRT.end()) { ibMap[(*it).first] = kTRUE; }
1068 if (j!=_nDim-1) { ibMapRT = ibMap; }
1074 void RooNDKeysPdf::boxInfoInit(BoxInfo* bi,
const char* rangeName, Int_t )
const
1076 vector<Bool_t> doInt(_nDim,kTRUE);
1078 bi->filled = kFALSE;
1080 bi->xVarLo.resize(_nDim,0.);
1081 bi->xVarHi.resize(_nDim,0.);
1082 bi->xVarLoM3s.resize(_nDim,0.);
1083 bi->xVarLoP3s.resize(_nDim,0.);
1084 bi->xVarHiM3s.resize(_nDim,0.);
1085 bi->xVarHiP3s.resize(_nDim,0.);
1087 bi->netFluxZ = kTRUE;
1088 bi->bpsIdcs.clear();
1091 bi->bmsIdcs.clear();
1096 for (
unsigned int j=0; j < _varList.size(); ++j) {
1097 auto var =
static_cast<const RooAbsRealLValue*
>(_varList.at(j));
1099 bi->xVarLo[j] = var->getMin(rangeName);
1100 bi->xVarHi[j] = var->getMax(rangeName);
1102 bi->xVarLo[j] = var->getVal() ;
1103 bi->xVarHi[j] = var->getVal() ;
1110 Double_t RooNDKeysPdf::evaluate()
const
1112 if (_tracker != NULL && _tracker->hasChanged(kTRUE)) {
1115 calculateBandWidth();
1118 const RooArgSet *nset = _varList.nset();
1119 for (
unsigned int j=0; j < _varList.size(); ++j) {
1120 auto var =
static_cast<const RooAbsReal*
>(_varList.at(j));
1121 _x[j] = var->getVal(nset);
1124 Double_t val = gauss(_x,*_weights);
1135 Int_t RooNDKeysPdf::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars,
const char* rangeName)
const
1137 if (rangeName)
return 0 ;
1140 if (matchArgs(allVars,analVars,RooArgSet(_varList))) { code=1; }
1148 Double_t RooNDKeysPdf::analyticalIntegral(Int_t code,
const char* rangeName)
const
1150 cxcoutD(Eval) <<
"Calling RooNDKeysPdf::analyticalIntegral(" << GetName() <<
") with code " << code
1151 <<
" and rangeName " << (rangeName?rangeName:
"<none>") << endl;
1154 Int_t nComb = 1 << (_nDim);
1155 R__ASSERT(code>=1 && code<nComb) ;
1157 vector<Bool_t> doInt(_nDim,kTRUE);
1163 string rangeNameStr(rangeName) ;
1164 bi = _rangeBoxInfo[make_pair(rangeNameStr,code)] ;
1167 _rangeBoxInfo[make_pair(rangeNameStr,code)] = bi ;
1168 boxInfoInit(bi,rangeName,code);
1170 }
else bi= &_fullBoxInfo ;
1173 Bool_t newBounds(kFALSE);
1174 for (
unsigned int j=0; j < _varList.size(); ++j) {
1175 auto var =
static_cast<const RooAbsRealLValue*
>(_varList.at(j));
1176 if ((var->getMin(rangeName)-bi->xVarLo[j]!=0) ||
1177 (var->getMax(rangeName)-bi->xVarHi[j]!=0)) {
1184 cxcoutD(Eval) <<
"RooNDKeysPdf::analyticalIntegral() : Found new boundaries ... " << (rangeName?rangeName:
"<none>") << endl;
1185 boxInfoInit(bi,rangeName,code);
1189 if (!bi->filled || newBounds) {
1192 calculatePreNorm(bi);
1194 const_cast<RooNDKeysPdf*
>(
this)->sortDataIndices(bi);
1198 Double_t norm=bi->nEventsBW;
1200 if (_mirror && bi->netFluxZ) {
1202 cxcoutD(Eval) <<
"RooNDKeysPdf::analyticalIntegral() : Using mirrored normalization : " << bi->nEventsBW << endl;
1203 return bi->nEventsBW;
1208 norm = bi->nEventsBMSW;
1209 if (norm<0.) norm=0.;
1211 for (Int_t i=0; i<Int_t(bi->sIdcs.size()); ++i) {
1213 const vector<Double_t>& x = _dataPts[bi->sIdcs[i]];
1214 const vector<Double_t>& weight = (*_weights)[_idx[bi->sIdcs[i]]];
1216 vector<Double_t> chi(_nDim,100.);
1218 for (Int_t j=0; j<_nDim; j++) {
1219 if(!doInt[j])
continue;
1221 if ((x[j]>bi->xVarLoM3s[j] && x[j]<bi->xVarLoP3s[j]) && x[j]<(bi->xVarLo[j]+bi->xVarHi[j])/2.)
1222 chi[j] = (x[j]-bi->xVarLo[j])/weight[j];
1223 else if ((x[j]>bi->xVarHiM3s[j] && x[j]<bi->xVarHiP3s[j]) && x[j]>(bi->xVarLo[j]+bi->xVarHi[j])/2.)
1224 chi[j] = (bi->xVarHi[j]-x[j])/weight[j];
1227 prob *= (0.5 + TMath::Erf(fabs(chi[j])/sqrt(2.))/2.);
1229 prob *= (0.5 - TMath::Erf(fabs(chi[j])/sqrt(2.))/2.);
1232 norm += prob * _wMap[_idx[bi->sIdcs[i]]];
1235 cxcoutD(Eval) <<
"RooNDKeysPdf::analyticalIntegral() : Final normalization : " << norm <<
" " << bi->nEventsBW << endl;
1243 RooDataSet* RooNDKeysPdf::createDatasetFromHist(
const RooArgList &varList,
const TH1 &hist)
const
1245 std::vector<RooRealVar *> varVec;
1246 RooArgSet varsAndWeightSet;
1248 for (
const auto var : varList) {
1249 if (!dynamic_cast<RooRealVar *>(var)) {
1250 coutE(InputArguments) <<
"RooNDKeysPdf::createDatasetFromHist(" << GetName() <<
") WARNING: variable "
1251 << var->GetName() <<
" is not of type RooRealVar. Skip." << endl;
1254 varsAndWeightSet.add(*var);
1255 varVec.push_back(static_cast<RooRealVar *>(var));
1259 RooRealVar weight(
"weight",
"event weight", 0);
1260 varsAndWeightSet.add(weight);
1263 unsigned int histndim(0);
1264 std::string classname = hist.ClassName();
1265 if (classname.find(
"TH1") == 0) {
1267 }
else if (classname.find(
"TH2") == 0) {
1269 }
else if (classname.find(
"TH3") == 0) {
1272 assert(histndim == varVec.size());
1274 if (histndim > 3 || histndim <= 0) {
1275 coutE(InputArguments) <<
"RooNDKeysPdf::createDatasetFromHist(" << GetName()
1276 <<
") ERROR: input histogram dimension not between [1-3]: " << histndim << endl;
1281 RooDataSet *dataFromHist =
new RooDataSet(
"datasetFromHist",
"datasetFromHist", varsAndWeightSet, weight.GetName());
1284 for (
int i = 1; i <= hist.GetXaxis()->GetNbins(); ++i) {
1287 Double_t xval = hist.GetXaxis()->GetBinCenter(i);
1288 varVec[0]->setVal(xval);
1290 if (varVec.size() == 1) {
1291 Double_t fval = hist.GetBinContent(i);
1292 weight.setVal(fval);
1293 dataFromHist->add(varsAndWeightSet, fval);
1296 for (
int j = 1; j <= hist.GetYaxis()->GetNbins(); ++j) {
1297 Double_t yval = hist.GetYaxis()->GetBinCenter(j);
1298 varVec[1]->setVal(yval);
1300 if (varVec.size() == 2) {
1301 Double_t fval = hist.GetBinContent(i, j);
1302 weight.setVal(fval);
1303 dataFromHist->add(varsAndWeightSet, fval);
1306 for (
int k = 1; k <= hist.GetZaxis()->GetNbins(); ++k) {
1307 Double_t zval = hist.GetZaxis()->GetBinCenter(k);
1308 varVec[2]->setVal(zval);
1310 Double_t fval = hist.GetBinContent(i, j, k);
1311 weight.setVal(fval);
1312 dataFromHist->add(varsAndWeightSet, fval);
1319 return dataFromHist;
1326 TMatrixD RooNDKeysPdf::getWeights(
const int &k)
const
1328 TMatrixD mref(_nEvents, _nDim + 1);
1330 cxcoutD(Eval) <<
"RooNDKeysPdf::getWeights() Return evaluated weights." << endl;
1332 for (Int_t i = 0; i < _nEvents; ++i) {
1333 vector<Double_t> &x = _dataPts[i];
1334 for (Int_t j = 0; j < _nDim; j++) {
1338 vector<Double_t> &weight = (*_weights)[i];
1339 mref(i, _nDim) = weight[k];
1346 void RooNDKeysPdf::updateRho()
const
1348 for (
unsigned int j = 0; j < _rhoList.size(); ++j) {
1349 auto rho =
static_cast<const RooAbsReal*
>(_rhoList.at(j));
1350 _rho[j] = rho->getVal();
1353 if (_nDim > 1 && _rotate) {
1354 TMatrixDSym covMatRho(_nDim);
1355 for (Int_t j = 0; j < _nDim; j++) {
1356 for (Int_t k = 0; k < _nDim; k++) {
1357 covMatRho(j, k) = (*_covMat)(j, k) * _rho[j] * _rho[k];
1361 TMatrixDSymEigen evCalculatorRho(covMatRho);
1362 *_sigmaR = evCalculatorRho.GetEigenValues();
1363 for (Int_t j = 0; j < _nDim; j++) {
1364 (*_sigmaR)[j] = sqrt((*_sigmaR)[j]);
1367 for (Int_t j = 0; j < _nDim; j++) {
1368 (*_sigmaR)[j] = (_sigma[j] * _rho[j]);