2 #ifndef RIVET_Correlators_HH 3 #define RIVET_Correlators_HH 5 #include "Rivet/Projection.hh" 6 #include "Rivet/Projections/ParticleFinder.hh" 8 #include "YODA/Scatter2D.h" 9 #include "Rivet/Analysis.hh" 54 int pMaxIn = 0, vector<double> pTbinEdgesIn = {});
58 int pMaxIn,
const Scatter2DPtr hIn);
75 bool overflow =
false)
const;
86 vector<int> n1, vector<int> n2)
const;
102 const Correlators& other, vector<int> n1, vector<int> n2,
103 bool oveflow =
false)
const;
108 static vector<int>
hVec(
int n,
int m) {
110 cout <<
"Harmonic Vector: Number of particles " 111 "must be an even number." << endl;
114 vector<int> ret = {};
115 for (
int i = 0; i < m; ++i) {
116 if (i < m/2) ret.push_back(n);
117 else ret.push_back(-n);
125 int nMax = 0, pMax = 0;
126 for (vector<int> h : hList) {
127 int tmpN = 0, tmpP = 0;
128 for (
int i = 0; i < int(h.size()); ++i) {
132 if (tmpN > nMax) nMax = tmpN;
133 if (tmpP > pMax) pMax = tmpP;
135 return make_pair(nMax,pMax);
138 DEFAULT_RIVET_PROJ_CLONE(Correlators);
149 const Correlators* other =
dynamic_cast<const Correlators*
>(&p);
150 if (nMax != other->nMax)
return UNDEFINED;
151 if (pMax != other->pMax)
return UNDEFINED;
152 if (pTbinEdges != other->pTbinEdges)
return UNDEFINED;
157 void fillCorrelators(
const Particle& p,
const double& weight);
160 const complex<double> getQ(
int n,
int p)
const {
161 bool isNeg = (n < 0);
162 if (isNeg)
return conj( qVec[abs(n)][p] );
163 else return qVec[n][p];
167 const complex<double> getP(
int n,
int p,
double pT = 0.)
const {
168 bool isNeg = (n < 0);
169 map<double, Vec2D>::const_iterator pTitr = pVec.lower_bound(pT);
170 if (pTitr == pVec.end())
return DBL_NAN;
171 if (isNeg)
return conj( pTitr->second[abs(n)][p] );
172 else return pTitr->second[n][p];
178 const complex<double> recCorr(
int order, vector<int> n,
179 vector<int> p,
bool useP,
double pT = 0.)
const;
184 const complex<double> twoPartCorr(
int n1,
int n2,
int p1 = 1,
185 int p2 = 1,
double pT = 0.,
bool useP =
false)
const;
191 const complex<double> _ZERO = {0., 0.};
192 const double _TINY = 1e-10;
195 typedef vector< vector<complex<double>> > Vec2D;
199 map<double, Vec2D> pVec;
204 vector<double> pTbinEdges;
224 static const int BOOT_BINS = 9;
240 virtual ~CorBinBase() {};
242 virtual void fill(
const pair<double, double>& cor,
const double& weight) = 0;
243 virtual const double mean()
const = 0;
250 class CorSingleBin :
public CorBinBase {
254 CorSingleBin() : _sumWX(0.), _sumW(0.), _sumW2(0.), _numEntries(0.) {}
259 void fill(
const pair<double, double>& cor,
const double& weight) {
261 if (cor.second < 1e-10)
return;
264 _sumWX += cor.first * weight;
265 _sumW += weight * cor.second;
266 _sumW2 += weight * weight * cor.second * cor.second;
270 const double mean()
const {
271 if (_sumW < 1e-10)
return 0;
272 return _sumWX / _sumW;
276 const double sumW()
const {
280 const double sumW2()
const {
285 const double sumWX()
const {
290 const double numEntries()
const {
294 void addContent(
double ne,
double sw,
double sw2,
double swx) {
302 double _sumWX, _sumW, _sumW2, _numEntries;
309 class CorBin :
public CorBinBase {
314 CorBin() :
binIndex(0), nBins(BOOT_BINS) {
315 for(
size_t i = 0; i < nBins; ++i) bins.push_back(CorSingleBin());
321 void fill(
const pair<double, double>& cor,
const double& weight) {
323 if (cor.second < 1e-10)
return;
332 const double mean()
const {
336 if (b.sumW() < 1e-10)
continue;
344 const vector<CorSingleBin> getBins()
const {
349 template<
class T=CorBinBase>
350 const vector<T*> getBinPtrs() {
351 vector<T*> ret(bins.size());
352 transform(bins.begin(), bins.end(), ret.begin(),
353 [](CorSingleBin& b) {
return &b;});
358 vector<CorSingleBin> bins;
383 binX(binIn), binContent(binIn.size() - 1), reference() {};
387 ECorrelator(vector<int> h1In, vector<int> h2In, vector<double> binIn) :
388 h1(h1In), h2(h2In), binX(binIn), binContent(binIn.size() - 1),
394 const double weight = 1.0) {
395 int index = getBinIndex(obs);
396 if (index < 0)
return;
404 const Correlators& c2,
const double weight = 1.0) {
406 cout <<
"Trying to fill gapped correlator, but harmonics behind " 407 "the gap (h2) are not given!" << endl;
410 int index = getBinIndex(obs);
411 if (index < 0)
return;
421 if (diffCorr.size() != binX.size() - 1)
422 cout <<
"Tried to fill event with wrong binning (ungapped)" << endl;
423 for (
size_t i = 0; i < diffCorr.size(); ++i) {
424 int index = getBinIndex(binX[i]);
425 if (index < 0)
return;
426 binContent[index].fill(diffCorr[i], weight);
435 const double& weight = 1.0) {
437 cout <<
"Trying to fill gapped correlator, but harmonics behind " 438 "the gap (h2) are not given!" << endl;
443 if (diffCorr.size() != binX.size() - 1)
444 cout <<
"Tried to fill event with wrong binning (gapped)" << endl;
445 for (
size_t i = 0; i < diffCorr.size(); ++i) {
446 int index = getBinIndex(binX[i]);
447 if (index < 0)
return;
448 binContent[index].fill(diffCorr[i], weight);
459 const vector<CorBinBase*> getBinPtrs() {
460 vector<CorBinBase*> ret(binContent.size());
461 transform(binContent.begin(), binContent.end(), ret.begin(),
462 [](CorBin& b) {
return &b;});
491 if (reference.mean() < 1e-10)
492 cout <<
"Warning: ECorrelator, reference bin is zero." << endl;
504 list<Profile1DPtr>::iterator hItr = profs.begin();
505 auto refs = reference.getBinPtrs<CorSingleBin>();
506 for (
size_t i = 0; i < profs.size(); ++i, ++hItr) {
507 for (
size_t j = 0; j < binX.size() - 1; ++j) {
508 const YODA::ProfileBin1D& pBin = (*hItr)->binAt(binX[j]);
509 auto tmp = binContent[j].getBinPtrs<CorSingleBin>();
510 tmp[i]->addContent(pBin.numEntries(), pBin.sumW(), pBin.sumW2(),
514 const YODA::Dbn2D& uBin = (*hItr)->underflow();
515 refs[i]->addContent(uBin.numEntries(), uBin.sumW(), uBin.sumW2(),
523 return profs.begin();
533 const int getBinIndex(
const double& obs)
const {
536 if (obs >= binX.back())
return -1;
538 if (obs < binX[0])
return -1;
540 for (
int i = 0, N = binX.size() - 1; i < N; ++i, ++index)
541 if (obs >= binX[i] && obs < binX[i + 1])
break;
550 vector<CorBin> binContent;
554 list<Profile1DPtr> profs;
561 vector< vector<int>> harmVecs;
562 for (
auto eItr = eCorrPtrs.begin(); eItr != eCorrPtrs.end(); ++eItr) {
563 vector<int> h1 = (*eItr)->getH1();
564 vector<int> h2 = (*eItr)->getH2();
565 if (h1.size() > 0) harmVecs.push_back(h1);
566 if (h2.size() > 0) harmVecs.push_back(h2);
568 if (harmVecs.size() == 0) {
569 cout <<
"Warning: You tried to extract max values from harmonic " 570 "vectors, but have not booked any." << endl;
571 return pair<int,int>();
577 typedef shared_ptr<ECorrelator> ECorrPtr;
580 ECorrPtr bookECorrelator(
const string name,
const vector<int>& h,
const Scatter2DPtr hIn) {
581 vector<double> binIn;
582 for (
auto b : hIn->points()) binIn.push_back(b.xMin());
583 binIn.push_back(hIn->points().back().xMax());
584 ECorrPtr ecPtr = ECorrPtr(
new ECorrelator(h, binIn));
585 list<Profile1DPtr> eCorrProfs;
586 for (
int i = 0; i < BOOT_BINS; ++i) {
587 Profile1DPtr tmp = bookProfile1D(name+
"-"+to_string(i),*hIn);
588 tmp->setPath(this->
name()+
"/FINAL/" + name+
"-"+to_string(i));
590 eCorrProfs.push_back(tmp);
592 ecPtr->setProfs(eCorrProfs);
593 eCorrPtrs.push_back(ecPtr);
598 ECorrPtr bookECorrelator(
const string name,
const vector<int>& h1,
599 const vector<int>& h2,
const Scatter2DPtr hIn ) {
600 vector<double> binIn;
601 for (
auto b : hIn->points()) binIn.push_back(b.xMin());
602 binIn.push_back(hIn->points().back().xMax());
603 ECorrPtr ecPtr = ECorrPtr(
new ECorrelator(h1, h2, binIn));
604 list<Profile1DPtr> eCorrProfs;
605 for (
int i = 0; i < BOOT_BINS; ++i) {
606 Profile1DPtr tmp = bookProfile1D(name+
"-"+to_string(i),*hIn);
607 tmp->setPath(this->
name()+
"/FINAL/" + name+
"-"+to_string(i));
609 eCorrProfs.push_back(tmp);
611 ecPtr->setProfs(eCorrProfs);
612 eCorrPtrs.push_back(ecPtr);
618 ECorrPtr bookECorrelatorGap (
const string name,
const vector<int>& h,
619 const Scatter2DPtr hIn) {
620 const vector<int> h1(h.begin(), h.begin() + h.size() / 2);
621 const vector<int> h2(h.begin() + h.size() / 2, h.end());
622 return bookECorrelator(name, h1, h2, hIn);
628 template<
unsigned int N,
unsigned int M>
629 ECorrPtr bookECorrelator(
const string name,
const Scatter2DPtr hIn) {
635 template<
unsigned int N,
unsigned int M>
636 ECorrPtr bookECorrelatorGap(
const string name,
const Scatter2DPtr hIn) {
644 for (
auto ecItr = eCorrPtrs.begin(); ecItr != eCorrPtrs.end(); ++ecItr){
645 (*ecItr)->fillFromProfs();
646 corrPlot(list<Profile1DPtr>((*ecItr)->profBegin(),
647 (*ecItr)->profEnd()), *ecItr);
653 list<ECorrPtr> eCorrPtrs;
669 static void fillScatter(Scatter2DPtr h, vector<double>& binx, T func) {
670 vector<YODA::Point2D> points;
671 for (
int i = 0, N = binx.size() - 1; i < N; ++i) {
672 double xMid = (binx[i] + binx[i + 1]) / 2.0;
673 double xeMin = fabs(xMid - binx[i]);
674 double xeMax = fabs(xMid - binx[i + 1]);
675 double yVal = func(i);
676 if (std::isnan(yVal)) yVal = 0.;
678 points.push_back(YODA::Point2D(xMid, yVal, xeMin, xeMax, yErr, yErr));
682 for (
int i = 0, N = points.size(); i < N; ++i) h->addPoint(points[i]);
695 const void fillScatter(Scatter2DPtr h, vector<double>& binx, F func,
696 vector<pair<double, double> >& yErr)
const {
697 vector<YODA::Point2D> points;
698 for (
int i = 0, N = binx.size() - 1; i < N; ++i) {
699 double xMid = (binx[i] + binx[i + 1]) / 2.0;
700 double xeMin = fabs(xMid - binx[i]);
701 double xeMax = fabs(xMid - binx[i + 1]);
702 double yVal = func(i);
703 if (std::isnan(yVal))
704 points.push_back(YODA::Point2D(xMid, 0., xeMin, xeMax,0., 0.));
706 points.push_back(YODA::Point2D(xMid, yVal, xeMin, xeMax,
707 yErr[i].first, yErr[i].second));
711 for (
int i = 0, N = points.size(); i < N; ++i)
712 h->addPoint(points[i]);
719 static void nthPow(Scatter2DPtr hOut,
const Scatter2DPtr hIn,
720 const double& n,
const double& k = 1.0) {
721 if (n == 0 || n == 1) {
722 cout <<
"Error: Do not take the 0th or 1st power of a Scatter2D," 723 " use scale instead." << endl;
726 if (hIn->points().size() != hOut->points().size()) {
727 cout <<
"nthRoot: Scatterplots: " << hIn->name() <<
" and " <<
728 hOut->name() <<
" not initialized with same length." << endl;
731 vector<YODA::Point2D> points;
733 double eFac = pow(k,1./n)/n;
734 for (
auto b : hIn->points()) {
735 double yVal = pow(k * b.y(),n);
736 if (std::isnan(yVal))
737 points.push_back(YODA::Point2D(b.x(), 0., b.xErrMinus(),
738 b.xErrPlus(), 0, 0 ));
740 double yemin = abs(eFac * pow(yVal,1./(n - 1.))) * b.yErrMinus();
741 if (std::isnan(yemin)) yemin = b.yErrMinus();
742 double yemax = abs(eFac * pow(yVal,1./(n - 1.))) * b.yErrPlus();
743 if (std::isnan(yemax)) yemax = b.yErrPlus();
744 points.push_back(YODA::Point2D(b.x(), yVal, b.xErrMinus(),
745 b.xErrPlus(), yemin, yemax ));
749 hOut->points().clear();
750 for (
int i = 0, N = points.size(); i < N; ++i)
751 hOut->addPoint(points[i]);
757 static void nthPow(Scatter2DPtr h,
const double& n,
758 const double& k = 1.0) {
759 if (n == 0 || n == 1) {
760 cout <<
"Error: Do not take the 0th or 1st power of a Scatter2D," 761 " use scale instead." << endl;
764 vector<YODA::Point2D> points;
765 vector<YODA::Point2D> pIn = h->points();
767 double eFac = pow(k,1./n)/n;
769 double yVal = pow(k * b.y(),n);
770 if (std::isnan(yVal))
771 points.push_back(YODA::Point2D(b.x(), 0., b.xErrMinus(),
772 b.xErrPlus(), 0, 0 ));
774 double yemin = abs(eFac * pow(yVal,1./(n - 1.))) * b.yErrMinus();
775 if (std::isnan(yemin)) yemin = b.yErrMinus();
776 double yemax = abs(eFac * pow(yVal,1./(n - 1.))) * b.yErrPlus();
777 if (std::isnan(yemax)) yemax = b.yErrPlus();
778 points.push_back(YODA::Point2D(b.x(), yVal, b.xErrMinus(),
779 b.xErrPlus(), yemin, yemax ));
784 for (
int i = 0, N = points.size(); i < N; ++i) h->addPoint(points[i]);
790 static pair<double, double> sampleVariance(T func) {
793 for (
int i = 0; i < BOOT_BINS; ++i) avg += func(i);
794 avg /= double(BOOT_BINS);
797 for (
int i = 0; i < BOOT_BINS; ++i) var += pow(func(i) - avg, 2.);
798 var /= (double(BOOT_BINS) - 1);
799 return pair<double, double>(var, var);
805 static pair<double, double> sampleEnvelope(T func) {
808 for (
int i = 0; i < BOOT_BINS; ++i) avg += func(i);
809 avg /= double(BOOT_BINS);
813 for (
int i = 0; i < BOOT_BINS; ++i) {
814 double yVal = func(i);
815 if (yMin > yVal) yMin = yVal;
816 else if (yMax < yVal) yMax = yVal;
818 return pair<double, double>(fabs(avg - yMin), fabs(yMax - avg));
824 const pair<double, double> sampleError(T func)
const {
825 if (errorMethod == VARIANCE)
return sampleVariance(func);
826 else if (errorMethod == ENVELOPE)
return sampleEnvelope(func);
828 cout <<
"Error: Error method not found!" << endl;
829 return pair<double, double>(0.,0.);
833 const void cnTwoInt(Scatter2DPtr h, ECorrPtr e2)
const {
834 vector<CorBin> bins = e2->getBins();
835 vector<double> binx = e2->getBinX();
837 if (binx.size() - 1 != bins.size()){
838 cout <<
"cnTwoInt: Bin size (x,y) differs!" << endl;
841 vector<CorBinBase*> binPtrs;
843 auto cn = [&] (
int i) {
return binPtrs[i]->mean(); };
845 vector<pair<double, double> > yErr;
846 for (
int j = 0, N = bins.size(); j < N; ++j) {
847 binPtrs = bins[j].getBinPtrs();
848 yErr.push_back(sampleError(cn));
850 binPtrs = e2->getBinPtrs();
851 fillScatter(h, binx, cn, yErr);
855 const void vnTwoInt(Scatter2DPtr h, ECorrPtr e2)
const {
862 const void corrPlot(Scatter2DPtr h, ECorrPtr e)
const {
868 const void corrPlot(list<Profile1DPtr> profs, ECorrPtr e)
const {
869 vector<CorBin> corBins = e->getBins();
870 vector<double> binx = e->getBinX();
871 auto ref = e->getReference();
872 auto refBins = ref.getBinPtrs<CorSingleBin>();
874 if (binx.size() - 1 != corBins.size()){
875 cout <<
"corrPlot: Bin size (x,y) differs!" << endl;
878 list<Profile1DPtr>::iterator hItr = profs.begin();
880 for (
size_t i = 0; i < profs.size(); ++i, ++hItr) {
881 vector<YODA::ProfileBin1D> profBins;
883 double ne = 0., sow = 0., sow2 = 0.;
884 for (
size_t j = 0, N = binx.size() - 1; j < N; ++j) {
885 vector<CorSingleBin*> binPtrs =
886 corBins[j].getBinPtrs<CorSingleBin>();
890 profBins.push_back( YODA::ProfileBin1D((*hItr)->bin(j).xEdges(),
891 YODA::Dbn2D( binPtrs[i]->numEntries(), binPtrs[i]->sumW(),
892 binPtrs[i]->sumW2(), 0., 0., binPtrs[i]->sumWX(), 0, 0)));
893 ne += binPtrs[i]->numEntries();
894 sow += binPtrs[i]->sumW();
895 sow2 += binPtrs[i]->sumW2();
899 (*hItr)->bins().clear();
902 (*hItr)->setTotalDbn(YODA::Dbn2D(ne,sow,sow2,0.,0.,0.,0.,0.));
904 for (
int j = 0, N = profBins.size(); j < N; ++j)
905 (*hItr)->addBin(profBins[j]);
907 (*hItr)->setUnderflow(YODA::Dbn2D(refBins[i]->numEntries(),
908 refBins[i]->sumW(), refBins[i]->sumW2(), 0., 0.,
909 refBins[i]->sumWX(), 0., 0.));
913 const void cnFourInt(Scatter2DPtr h, ECorrPtr e2, ECorrPtr e4)
const {
914 auto e2bins = e2->getBins();
915 auto e4bins = e4->getBins();
916 auto binx = e2->getBinX();
917 if (binx.size() - 1 != e2bins.size()){
918 cout <<
"cnFourInt: Bin size (x,y) differs!" << endl;
921 if (binx != e4->getBinX()) {
922 cout <<
"Error in cnFourInt: Correlator x-binning differs!" << endl;
925 vector<CorBinBase*> e2binPtrs;
926 vector<CorBinBase*> e4binPtrs;
927 auto cn = [&] (
int i) {
928 double e22 = e2binPtrs[i]->mean() * e2binPtrs[i]->mean();
929 return e4binPtrs[i]->mean() - 2. * e22;
932 vector<pair<double, double> > yErr;
933 for (
int j = 0, N = e2bins.size(); j < N; ++j) {
934 e2binPtrs = e2bins[j].getBinPtrs();
935 e4binPtrs = e4bins[j].getBinPtrs();
936 yErr.push_back(sampleError(cn));
939 e2binPtrs = e2->getBinPtrs();
940 e4binPtrs = e4->getBinPtrs();
941 fillScatter(h, binx, cn, yErr);
945 const void vnFourInt(Scatter2DPtr h, ECorrPtr e2, ECorrPtr e4)
const {
946 cnFourInt(h, e2, e4);
947 nthPow(h, 0.25, -1.0);
951 const void cnSixInt(Scatter2DPtr h, ECorrPtr e2, ECorrPtr e4,
953 auto e2bins = e2->getBins();
954 auto e4bins = e4->getBins();
955 auto e6bins = e6->getBins();
956 auto binx = e2->getBinX();
957 if (binx.size() - 1 != e2bins.size()){
958 cout <<
"cnSixInt: Bin size (x,y) differs!" << endl;
961 if (binx != e4->getBinX() || binx != e6->getBinX()) {
962 cout <<
"Error in cnSixInt: Correlator x-binning differs!" << endl;
965 vector<CorBinBase*> e2binPtrs;
966 vector<CorBinBase*> e4binPtrs;
967 vector<CorBinBase*> e6binPtrs;
968 auto cn = [&] (
int i) {
969 double e23 = pow(e2binPtrs[i]->
mean(), 3.0);
970 return e6binPtrs[i]->mean() - 9.*e2binPtrs[i]->mean()*e4binPtrs[i]->mean() +
974 vector<pair<double, double> > yErr;
975 for (
int j = 0, N = e2bins.size(); j < N; ++j) {
976 e2binPtrs = e2bins[j].getBinPtrs();
977 e4binPtrs = e4bins[j].getBinPtrs();
978 e6binPtrs = e6bins[j].getBinPtrs();
979 yErr.push_back(sampleError(cn));
982 e2binPtrs = e2->getBinPtrs();
983 e4binPtrs = e4->getBinPtrs();
984 e6binPtrs = e6->getBinPtrs();
985 fillScatter(h, binx, cn, yErr);
989 const void vnSixInt(Scatter2DPtr h, ECorrPtr e2, ECorrPtr e4,
991 cnSixInt(h, e2, e4, e6);
992 nthPow(h, 1./6., 0.25);
996 const void cnEightInt(Scatter2DPtr h, ECorrPtr e2, ECorrPtr e4,
997 ECorrPtr e6, ECorrPtr e8)
const {
998 auto e2bins = e2->getBins();
999 auto e4bins = e4->getBins();
1000 auto e6bins = e6->getBins();
1001 auto e8bins = e8->getBins();
1002 auto binx = e2->getBinX();
1003 if (binx.size() - 1 != e2bins.size()){
1004 cout <<
"cnEightInt: Bin size (x,y) differs!" << endl;
1007 if (binx != e4->getBinX() || binx != e6->getBinX() ||
1008 binx != e8->getBinX()) {
1009 cout <<
"Error in cnEightInt: Correlator x-binning differs!" << endl;
1012 vector<CorBinBase*> e2binPtrs;
1013 vector<CorBinBase*> e4binPtrs;
1014 vector<CorBinBase*> e6binPtrs;
1015 vector<CorBinBase*> e8binPtrs;
1016 auto cn = [&] (
int i ) {
1017 double e22 = e2binPtrs[i]->mean() * e2binPtrs[i]->mean();
1018 double e24 = e22 * e22;
1019 double e42 = e4binPtrs[i]->mean() * e4binPtrs[i]->mean();
1020 return e8binPtrs[i]->mean() - 16. * e6binPtrs[i]->mean() *
1021 e2binPtrs[i]->mean() - 18. * e42 + 144. * e4binPtrs[i]->mean()*e22
1025 vector<pair<double, double> > yErr;
1026 for (
int j = 0, N = e2bins.size(); j < N; ++j) {
1027 e2binPtrs = e2bins[j].getBinPtrs();
1028 e4binPtrs = e4bins[j].getBinPtrs();
1029 e6binPtrs = e6bins[j].getBinPtrs();
1030 e8binPtrs = e8bins[j].getBinPtrs();
1031 yErr.push_back(sampleError(cn));
1034 e2binPtrs = e2->getBinPtrs();
1035 e4binPtrs = e4->getBinPtrs();
1036 e6binPtrs = e6->getBinPtrs();
1037 e8binPtrs = e8->getBinPtrs();
1038 fillScatter(h, binx, cn, yErr);
1042 const void vnEightInt(Scatter2DPtr h, ECorrPtr e2, ECorrPtr e4,
1043 ECorrPtr e6, ECorrPtr e8)
const {
1044 cnEightInt(h, e2, e4, e6, e8);
1045 nthPow(h, 1./8., -1./33.);
1049 const void vnTwoDiff(Scatter2DPtr h, ECorrPtr e2Dif)
const {
1050 auto e2bins = e2Dif->getBins();
1051 auto ref = e2Dif->getReference();
1052 auto binx = e2Dif->getBinX();
1053 if (binx.size() -1 != e2bins.size()) {
1054 cout <<
"vnTwoDif: Bin size (x,y) differs!" << endl;
1057 vector<CorBinBase*> e2binPtrs;
1058 vector<CorBinBase*> refPtrs;
1059 auto vn = [&] (
int i) {
1061 if (ref.mean() <= 0)
return 0.;
1062 return e2binPtrs[i]->mean() / sqrt(ref.mean());
1066 auto vnerr = [&] (
int i) {
1068 if (refPtrs[i]->
mean() <=0)
return 0.;
1069 return e2binPtrs[i]->mean() / sqrt(refPtrs[i]->
mean());
1072 vector<pair<double, double> > yErr;
1073 refPtrs = ref.getBinPtrs();
1074 for (
int j = 0, N = e2bins.size(); j < N; ++j) {
1075 e2binPtrs = e2bins[j].getBinPtrs();
1076 yErr.push_back(sampleError(vnerr));
1079 e2binPtrs = e2Dif->getBinPtrs();
1080 fillScatter(h, binx, vn);
1084 const void vnFourDiff(Scatter2DPtr h, ECorrPtr e2Dif,
1085 ECorrPtr e4Dif)
const {
1086 auto e2bins = e2Dif->getBins();
1087 auto e4bins = e4Dif->getBins();
1088 auto ref2 = e2Dif->getReference();
1089 auto ref4 = e4Dif->getReference();
1090 auto binx = e2Dif->getBinX();
1091 if (binx.size() - 1 != e2bins.size()){
1092 cout <<
"vnFourDif: Bin size (x,y) differs!" << endl;
1095 if (binx != e4Dif->getBinX()) {
1096 cout <<
"Error in vnFourDif: Correlator x-binning differs!" << endl;
1099 vector<CorBinBase*> e2binPtrs;
1100 vector<CorBinBase*> e4binPtrs;
1101 vector<CorBinBase*> ref2Ptrs;
1102 vector<CorBinBase*> ref4Ptrs;
1103 double denom = 2 * ref2.mean() * ref2.mean() - ref4.mean();
1104 auto vn = [&] (
int i) {
1106 if (denom <= 0 )
return 0.;
1107 return ((2 * ref2.mean() * e2bins[i].mean() - e4bins[i].mean()) /
1112 auto vnerr = [&] (
int i) {
1113 double denom2 = 2 * ref2Ptrs[i]->mean() * ref2Ptrs[i]->mean() -
1114 ref4Ptrs[i]->mean();
1116 if (denom2 <= 0)
return 0.;
1117 return ((2 * ref2Ptrs[i]->
mean() * e2binPtrs[i]->
mean() -
1118 e4binPtrs[i]->
mean()) / pow(denom2, 0.75));
1121 vector<pair<double, double> > yErr;
1122 ref2Ptrs = ref2.getBinPtrs();
1123 ref4Ptrs = ref4.getBinPtrs();
1124 for (
int j = 0, N = e2bins.size(); j < N; ++j) {
1125 e2binPtrs = e2bins[j].getBinPtrs();
1126 e4binPtrs = e4bins[j].getBinPtrs();
1127 yErr.push_back(sampleError(vnerr));
1130 e2binPtrs = e2Dif->getBinPtrs();
1131 e4binPtrs = e4Dif->getBinPtrs();
1132 fillScatter(h, binx, vn, yErr);
Definition: ALICE_2010_I880049.cc:13
const vector< int > getH1() const
Get a copy of the h1 harmonic vector.
Definition: Correlators.hh:472
std::enable_if< std::is_arithmetic< NUM1 >::value &&std::is_arithmetic< NUM2 >::value, int >::type binIndex(NUM1 val, std::initializer_list< NUM2 > binedges, bool allow_overflow=false)
Return the bin index of the given value, val, given a vector of bin edges.
Definition: MathUtils.hh:356
void fillFromProfs()
Fill bins with content from preloaded histograms.
Definition: Correlators.hh:503
const vector< double > getBinX() const
Get a copy of the bin x-values.
Definition: Correlators.hh:467
const vector< pair< double, double > > pTBinnedCorrelators(vector< int > n, bool overflow=false) const
pT differential correlator of n harmonic, with the number of powers being the size of n...
Definition: Correlators.cc:63
static vector< int > hVec(int n, int m)
Construct a harmonic vectors from n harmonics and m number of particles. TODO: In C++14 this can be...
Definition: Correlators.hh:108
void fill(const Correlators &c1, const Correlators &c2, const double &weight=1.0)
Fill bins with the appropriate correlator, taking the binning directly from the Correlators object...
Definition: Correlators.hh:434
const vector< int > getH2() const
Get a copy of the h2 harmonic vector.
Definition: Correlators.hh:477
ECorrelator(vector< int > h1In, vector< int > h2In, vector< double > binIn)
Constructor for gapped correlator. Takes as argument the desired harmonics for the two final states...
Definition: Correlators.hh:387
Particle representation, either from a HepMC::GenEvent or reconstructed.
Definition: Particle.hh:18
The ECorrelator is a helper class to calculate all event averages of correlators, in order to constru...
Definition: Correlators.hh:368
const pair< double, double > intCorrelatorGap(const Correlators &other, vector< int > n1, vector< int > n2) const
Integrated correlator of n1 harmonic, with the number of powers being the size of n1...
Definition: Correlators.cc:88
static constexpr double DBL_NAN
Convenient const for getting the double NaN value.
Definition: Utils.hh:54
Base class for projections which return subsets of an event's particles.
Definition: ParticleFinder.hh:11
Tools for flow analyses. The following are helper classes to construct event averaged correlators as ...
Definition: Correlators.hh:218
void fill(const Correlators &c, const double &weight=1.0)
Fill the bins with the appropriate correlator, taking the binning directly from the Correlators objec...
Definition: Correlators.hh:418
void setReference(CorBin refIn)
Replace reference flow bin with another reference flow bin, eg. calculated in another phase space or ...
Definition: Correlators.hh:484
const vector< pair< double, double > > pTBinnedCorrelatorsGap(const Correlators &other, vector< int > n1, vector< int > n2, bool oveflow=false) const
pT differential correlators of n1 harmonic, with the number of powers being the size of n1...
Definition: Correlators.cc:113
This is the base class of all analysis classes in Rivet.
Definition: Analysis.hh:52
void fill(const double &obs, const Correlators &c1, const Correlators &c2, const double weight=1.0)
Fill the appropriate bin given an input (per event) observable, eg. centrality. Using a rapidity gap ...
Definition: Correlators.hh:403
Cmp< Projection > mkPCmp(const Projection &otherparent, const std::string &pname) const
Definition: Projection.cc:55
static pair< int, int > getMaxValues(vector< vector< int > > &hList)
Return the maximal values for n, p to be used in the constructor of Correlators(xxx, nMax, pMax, xxxx)
Definition: Correlators.hh:124
list< Profile1DPtr >::iterator profEnd()
end() iterator for the list of associated profile histograms.
Definition: Correlators.hh:527
static void nthPow(Scatter2DPtr h, const double &n, const double &k=1.0)
Take the n th power of all points in h, and put the result back in the same Scatter2D. Optionally put a k constant below the root.
Definition: Correlators.hh:757
int compare(const Projection &p) const
Definition: Correlators.hh:148
const vector< CorBin > getBins() const
Get a copy of the bin contents.
Definition: Correlators.hh:454
virtual std::string name() const
Get the name of the projection.
Definition: Projection.hh:56
Definition: Correlators.hh:39
void project(const Event &e)
Definition: Correlators.cc:149
list< Profile1DPtr >::iterator profBegin()
begin() iterator for the list of associated profile histograms.
Definition: Correlators.hh:522
const pair< double, double > intCorrelator(vector< int > n) const
Integrated correlator of n harmonic, with the number of powers being the size of n...
Definition: Correlators.cc:49
static void nthPow(Scatter2DPtr hOut, const Scatter2DPtr hIn, const double &n, const double &k=1.0)
Take the n th power of all points in hIn, and put the result in hOut. Optionally put a k constant...
Definition: Correlators.hh:719
void setProfs(list< Profile1DPtr > prIn)
set the prIn list of profile histograms associated with the internal bins. Is called automatically w...
Definition: Correlators.hh:498
ECorrelator(vector< int > h, vector< double > binIn)
Constructor. Takes as argument the desired harmonic and number of correlated particles as a generic f...
Definition: Correlators.hh:382
Base class for all Rivet projections.
Definition: Projection.hh:29
std::enable_if< std::is_arithmetic< NUM >::value, double >::type mean(const vector< NUM > &sample)
Definition: MathUtils.hh:398
void fill(const double &obs, const Correlators &c, const double weight=1.0)
Fill the appropriate bin given an input (per event) observable, eg. centrality.
Definition: Correlators.hh:393
const CorBin getReference() const
Extract the reference flow from a differential event averaged correlator.
Definition: Correlators.hh:490