2 #ifndef RIVET_Correlators_HH 3 #define RIVET_Correlators_HH 21 #include "Rivet/Analysis.hh" 22 #include "Rivet/Projection.hh" 23 #include "Rivet/Projections/ParticleFinder.hh" 24 #include "YODA/Scatter2D.h" 55 int pMaxIn = 0, vector<double> pTbinEdgesIn = {});
59 int pMaxIn,
const YODA::Scatter2D hIn);
75 bool overflow =
false)
const;
86 vector<int> n1, vector<int> n2)
const;
99 const vector<pair<double,double>>
100 pTBinnedCorrelatorsGap(
const Correlators& other, vector<int> n1, vector<int> n2,
bool overflow=
false)
const;
106 static vector<int>
hVec(
int n,
int m) {
108 cout <<
"Harmonic Vector: Number of particles must be an even number." << endl;
111 vector<int> ret = {};
112 for (
int i = 0; i < m; ++i) {
113 if (i < m/2) ret.push_back(n);
114 else ret.push_back(-n);
122 int nMax = 0, pMax = 0;
123 for (vector<int> h : hList) {
124 int tmpN = 0, tmpP = 0;
125 for (
int i = 0; i < int(h.size()); ++i) {
129 if (tmpN > nMax) nMax = tmpN;
130 if (tmpP > pMax) pMax = tmpP;
132 return make_pair(nMax,pMax);
136 DEFAULT_RIVET_PROJ_CLONE(Correlators);
146 const Correlators* other =
dynamic_cast<const Correlators*
>(&p);
147 if (nMax != other->nMax)
return CmpState::NEQ;
148 if (pMax != other->pMax)
return CmpState::NEQ;
149 if (pTbinEdges != other->pTbinEdges)
return CmpState::NEQ;
154 void fillCorrelators(
const Particle& p,
const double& weight);
157 const complex<double> getQ(
int n,
int p)
const {
158 bool isNeg = (n < 0);
159 if (isNeg)
return conj( qVec[abs(n)][p] );
160 else return qVec[n][p];
164 const complex<double> getP(
int n,
int p,
double pT = 0.)
const {
165 bool isNeg = (n < 0);
166 map<double, Vec2D>::const_iterator pTitr = pVec.lower_bound(pT);
167 if (pTitr == pVec.end())
return DBL_NAN;
168 if (isNeg)
return conj( pTitr->second[abs(n)][p] );
169 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;
185 const complex<double> twoPartCorr(
int n1,
int n2,
int p1 = 1,
186 int p2 = 1,
double pT = 0.,
bool useP =
false)
const;
192 const complex<double> _ZERO = {0., 0.};
193 const double _TINY = 1e-10;
196 typedef vector< vector<complex<double>> > Vec2D;
200 map<double, Vec2D> pVec;
206 vector<double> pTbinEdges;
227 static const int BOOT_BINS = 9;
244 virtual ~CorBinBase() {};
246 virtual void fill(
const pair<double, double>& cor,
const double& weight = 1.0) = 0;
247 virtual const double mean()
const = 0;
256 class CorSingleBin :
public CorBinBase {
261 : _sumWX(0.), _sumW(0.), _sumW2(0.), _numEntries(0.)
270 void fill(
const pair<double, double>& cor,
const double& weight = 1.0) {
272 if (cor.second < 1e-10)
return;
275 _sumWX += cor.first * weight;
276 _sumW += weight * cor.second;
277 _sumW2 += weight * weight * cor.second * cor.second;
282 const double mean()
const {
283 if (_sumW < 1e-10)
return 0;
284 return _sumWX / _sumW;
288 const double sumW()
const {
293 const double sumW2()
const {
298 const double sumWX()
const {
303 const double numEntries()
const {
308 void addContent(
double ne,
double sw,
double sw2,
double swx) {
318 double _sumWX, _sumW, _sumW2, _numEntries;
327 class CorBin :
public CorBinBase {
335 CorBin() :
binIndex(0), nBins(BOOT_BINS) {
336 for(
size_t i = 0; i < nBins; ++i) bins.push_back(CorSingleBin());
343 void fill(
const pair<double, double>& cor,
const double& weight = 1.0) {
345 if (cor.second < 1e-10)
return;
353 const double mean()
const {
356 for (
auto b : bins) {
357 if (b.sumW() < 1e-10)
continue;
365 const vector<CorSingleBin> getBins()
const {
370 template<
class T=CorBinBase>
371 const vector<T*> getBinPtrs() {
372 vector<T*> ret(bins.size());
373 transform(bins.begin(), bins.end(), ret.begin(),
374 [](CorSingleBin& b) {
return &b;});
380 vector<CorSingleBin> bins;
411 : h1(h), h2({}), binX(binIn), binContent(binIn.size() - 1), reference()
418 ECorrelator(vector<int> h1In, vector<int> h2In, vector<double> binIn)
419 : h1(h1In), h2(h2In), binX(binIn), binContent(binIn.size() - 1), reference()
424 int index = getBinIndex(obs);
425 if (index < 0)
return;
434 cout <<
"Trying to fill gapped correlator, but harmonics behind the gap (h2) are not given!" << endl;
437 int index = getBinIndex(obs);
438 if (index < 0)
return;
449 if (diffCorr.size() != binX.size() - 1)
450 cout <<
"Tried to fill event with wrong binning (ungapped)" << endl;
451 for (
size_t i = 0; i < diffCorr.size(); ++i) {
452 int index = getBinIndex(binX[i]);
453 if (index < 0)
return;
454 binContent[index].fill(diffCorr[i], weight);
465 cout <<
"Trying to fill gapped correlator, but harmonics behind " 466 "the gap (h2) are not given!" << endl;
471 if (diffCorr.size() != binX.size() - 1)
472 cout <<
"Tried to fill event with wrong binning (gapped)" << endl;
473 for (
size_t i = 0; i < diffCorr.size(); ++i) {
474 int index = getBinIndex(binX[i]);
475 if (index < 0)
return;
476 binContent[index].fill(diffCorr[i], weight);
488 vector<CorBinBase*> ret(binContent.size());
489 transform(binContent.begin(), binContent.end(), ret.begin(), [](CorBin& b) {
return &b;});
515 if (reference.mean() < 1e-10)
516 cout <<
"Warning: ECorrelator, reference bin is zero." << endl;
528 auto refs = reference.getBinPtrs<CorSingleBin>();
529 for (
size_t i = 0; i < profs.size(); ++i) {
530 if (yao->path() ==
"/RAW/"+name+
"/TMP/"+profs[i]) {
531 YODA::Profile1DPtr pPtr = dynamic_pointer_cast<YODA::Profile1D>(yao);
532 for (
size_t j = 0; j < binX.size() - 1; ++j) {
533 const YODA::ProfileBin1D& pBin = pPtr->binAt(binX[j]);
534 auto tmp = binContent[j].getBinPtrs<CorSingleBin>();
535 tmp[i]->addContent(pBin.numEntries(), pBin.sumW(), pBin.sumW2(),
539 const YODA::Dbn2D& uBin = pPtr->underflow();
540 refs[i]->addContent(uBin.numEntries(), uBin.sumW(), uBin.sumW2(),
551 const int getBinIndex(
const double& obs)
const {
554 if (obs >= binX.back())
return -1;
556 if (obs < binX[0])
return -1;
558 for (
int i = 0, N = binX.size() - 1; i < N; ++i, ++index)
559 if (obs >= binX[i] && obs < binX[i + 1])
break;
569 vector<CorBin> binContent;
574 vector <string> profs;
581 vector< vector<int>> harmVecs;
582 for (
auto eItr = eCorrPtrs.begin(); eItr != eCorrPtrs.end(); ++eItr) {
583 vector<int> h1 = (*eItr)->getH1();
584 vector<int> h2 = (*eItr)->getH2();
585 if (h1.size() > 0) harmVecs.push_back(h1);
586 if (h2.size() > 0) harmVecs.push_back(h2);
588 if (harmVecs.size() == 0) {
589 cout <<
"Warning: You tried to extract max values from harmonic " 590 "vectors, but have not booked any." << endl;
591 return pair<int,int>();
602 vector<double> binIn;
603 for (
auto b : hIn.points()) binIn.push_back(b.xMin());
604 binIn.push_back(hIn.points().back().xMax());
605 return bookECorrelator(name, h, binIn);
611 ECorrPtr ecPtr = ECorrPtr(
new ECorrelator(h, binIn));
612 vector<string> eCorrProfs;
613 for (
int i = 0; i < BOOT_BINS; ++i) {
615 book(tmp,
"TMP/"+name+
"-"+to_string(i),binIn);
616 eCorrProfs.push_back(name+
"-"+to_string(i));
618 ecPtr->setProfs(eCorrProfs);
619 eCorrPtrs.push_back(ecPtr);
626 const vector<int>& h2, vector<double>& binIn) {
627 ECorrPtr ecPtr = ECorrPtr(
new ECorrelator(h1, h2, binIn));
628 vector<string> eCorrProfs;
629 for (
int i = 0; i < BOOT_BINS; ++i) {
631 book(tmp,
"TMP/"+name+
"-"+to_string(i),binIn);
632 eCorrProfs.push_back(name+
"-"+to_string(i));
634 ecPtr->setProfs(eCorrProfs);
635 eCorrPtrs.push_back(ecPtr);
642 const vector<int>& h2,
const YODA::Scatter2D& hIn ) {
643 vector<double> binIn;
644 for (
auto b : hIn.points()) binIn.push_back(b.xMin());
645 binIn.push_back(hIn.points().back().xMax());
646 return bookECorrelator(name, h1, h2, binIn);
654 const YODA::Scatter2D& hIn) {
655 const vector<int> h1(h.begin(), h.begin() + h.size() / 2);
656 const vector<int> h2(h.begin() + h.size() / 2, h.end());
657 return bookECorrelator(name, h1, h2, hIn);
664 template<
unsigned int N,
unsigned int M>
673 template<
unsigned int N,
unsigned int M>
682 template<
unsigned int N,
unsigned int M>
685 const vector<int> h1(h.begin(), h.begin() + h.size() / 2);
686 const vector<int> h2(h.begin() + h.size() / 2, h.end());
687 return bookECorrelator(name, h1, h2, hIn);
694 list<ECorrPtr> eCorrPtrs;
704 :
Analysis(n), errorMethod(VARIANCE)
715 static void fillScatter(Scatter2DPtr h, vector<double>& binx, T func) {
716 vector<YODA::Point2D> points;
718 bool hasBins = (h->points().size() > 0);
719 for (
int i = 0, N = binx.size() - 1; i < N; ++i) {
720 double xMid = (binx[i] + binx[i + 1]) / 2.0;
721 double xeMin = fabs(xMid - binx[i]);
722 double xeMax = fabs(xMid - binx[i + 1]);
724 xMid = h->points()[i].x();
725 xeMin = h->points()[i].xErrMinus();
726 xeMax = h->points()[i].xErrPlus();
728 double yVal = func(i);
729 if (std::isnan(yVal)) yVal = 0.;
731 points.push_back(YODA::Point2D(xMid, yVal, xeMin, xeMax, yErr, yErr));
735 for (
int i = 0, N = points.size(); i < N; ++i) h->addPoint(points[i]);
746 const void fillScatter(Scatter2DPtr h, vector<double>& binx, F func,
747 vector<pair<double, double> >& yErr)
const {
748 vector<YODA::Point2D> points;
750 bool hasBins = (h->points().size() > 0);
751 for (
int i = 0, N = binx.size() - 1; i < N; ++i) {
752 double xMid = (binx[i] + binx[i + 1]) / 2.0;
753 double xeMin = fabs(xMid - binx[i]);
754 double xeMax = fabs(xMid - binx[i + 1]);
756 xMid = h->points()[i].x();
757 xeMin = h->points()[i].xErrMinus();
758 xeMax = h->points()[i].xErrPlus();
760 double yVal = func(i);
761 if (std::isnan(yVal))
762 points.push_back(YODA::Point2D(xMid, 0., xeMin, xeMax,0., 0.));
764 points.push_back(YODA::Point2D(xMid, yVal, xeMin, xeMax,
765 yErr[i].first, yErr[i].second));
770 for (
int i = 0, N = points.size(); i < N; ++i)
771 h->addPoint(points[i]);
778 static void nthPow(Scatter2DPtr hOut,
const Scatter2DPtr hIn,
const double& n,
const double& k = 1.0) {
779 if (n == 0 || n == 1) {
780 cout <<
"Error: Do not take the 0th or 1st power of a Scatter2D," 781 " use scale instead." << endl;
784 if (hIn->points().size() != hOut->points().size()) {
785 cout <<
"nthRoot: Scatterplots: " << hIn->name() <<
" and " <<
786 hOut->name() <<
" not initialized with same length." << endl;
789 vector<YODA::Point2D> points;
791 double eFac = pow(k,1./n)/n;
792 for (
auto b : hIn->points()) {
793 double yVal = pow(k * b.y(),n);
794 if (std::isnan(yVal))
795 points.push_back(YODA::Point2D(b.x(), 0., b.xErrMinus(),
796 b.xErrPlus(), 0, 0 ));
798 double yemin = abs(eFac * pow(yVal,1./(n - 1.))) * b.yErrMinus();
799 if (std::isnan(yemin)) yemin = b.yErrMinus();
800 double yemax = abs(eFac * pow(yVal,1./(n - 1.))) * b.yErrPlus();
801 if (std::isnan(yemax)) yemax = b.yErrPlus();
802 points.push_back(YODA::Point2D(b.x(), yVal, b.xErrMinus(),
803 b.xErrPlus(), yemin, yemax ));
807 hOut->points().clear();
808 for (
int i = 0, N = points.size(); i < N; ++i)
809 hOut->addPoint(points[i]);
816 static void nthPow(Scatter2DPtr h,
const double& n,
const double& k = 1.0) {
817 if (n == 0 || n == 1) {
818 cout <<
"Error: Do not take the 0th or 1st power of a Scatter2D," 819 " use scale instead." << endl;
822 vector<YODA::Point2D> points;
823 vector<YODA::Point2D> pIn = h->points();
825 double eFac = pow(k,1./n)/n;
827 double yVal = pow(k * b.y(),n);
828 if (std::isnan(yVal))
829 points.push_back(YODA::Point2D(b.x(), 0., b.xErrMinus(),
830 b.xErrPlus(), 0, 0 ));
832 double yemin = abs(eFac * pow(yVal,1./(n - 1.))) * b.yErrMinus();
833 if (std::isnan(yemin)) yemin = b.yErrMinus();
834 double yemax = abs(eFac * pow(yVal,1./(n - 1.))) * b.yErrPlus();
835 if (std::isnan(yemax)) yemax = b.yErrPlus();
836 points.push_back(YODA::Point2D(b.x(), yVal, b.xErrMinus(),
837 b.xErrPlus(), yemin, yemax ));
842 for (
int i = 0, N = points.size(); i < N; ++i) h->addPoint(points[i]);
854 for (
int i = 0; i < BOOT_BINS; ++i) avg += func(i);
855 avg /= double(BOOT_BINS);
858 for (
int i = 0; i < BOOT_BINS; ++i) var += pow(func(i) - avg, 2.);
859 var /= (double(BOOT_BINS) - 1);
860 return pair<double, double>(var, var);
872 for (
int i = 0; i < BOOT_BINS; ++i) avg += func(i);
873 avg /= double(BOOT_BINS);
877 for (
int i = 0; i < BOOT_BINS; ++i) {
878 double yVal = func(i);
879 if (yMin > yVal) yMin = yVal;
880 else if (yMax < yVal) yMax = yVal;
882 return pair<double, double>(fabs(avg - yMin), fabs(yMax - avg));
889 if (errorMethod == VARIANCE)
return sampleVariance(func);
890 else if (errorMethod == ENVELOPE)
return sampleEnvelope(func);
892 cout <<
"Error: Error method not found!" << endl;
893 return pair<double, double>(0.,0.);
898 const void cnTwoInt(Scatter2DPtr h, ECorrPtr e2)
const {
899 vector<CorBin> bins = e2->getBins();
900 vector<double> binx = e2->getBinX();
902 if (binx.size() - 1 != bins.size()){
903 cout <<
"cnTwoInt: Bin size (x,y) differs!" << endl;
906 vector<CorBinBase*> binPtrs;
908 auto cn = [&] (
int i) {
return binPtrs[i]->mean(); };
910 vector<pair<double, double> > yErr;
911 for (
int j = 0, N = bins.size(); j < N; ++j) {
912 binPtrs = bins[j].getBinPtrs();
913 yErr.push_back(sampleError(cn));
915 binPtrs = e2->getBinPtrs();
916 fillScatter(h, binx, cn, yErr);
921 const void vnTwoInt(Scatter2DPtr h, ECorrPtr e2)
const {
930 const void corrPlot(Scatter2DPtr h, ECorrPtr e)
const {
938 void rawHookIn(YODA::AnalysisObjectPtr yao)
final {
940 for (
auto ec : eCorrPtrs)
if(ec->fillFromProfile(yao,
name()))
break;;
947 void rawHookOut(vector<MultiweightAOPtr> raos,
size_t iW)
final {
949 for (
auto ec : eCorrPtrs) {
950 vector<CorBin> corBins = ec->getBins();
951 vector<double> binx = ec->getBinX();
952 auto ref = ec->getReference();
953 auto refBins = ref.getBinPtrs<CorSingleBin>();
955 if (binx.size() - 1 != corBins.size()){
956 cout <<
"corrPlot: Bin size (x,y) differs!" << endl;
960 for (
int i = 0, N = ec->profs.size(); i < N; ++i) {
961 for (
auto rao : raos) {
962 if (rao->path() ==
"/"+
name()+
"/TMP/"+ec->profs[i]) {
964 rao.get()->setActiveWeightIdx(iW);
965 YODA::Profile1DPtr pPtr = dynamic_pointer_cast<YODA::Profile1D>(
966 rao.get()->activeYODAPtr());
968 vector<YODA::ProfileBin1D> profBins;
970 double ne = 0., sow = 0., sow2 = 0.;
971 for (
size_t j = 0, N = binx.size() - 1; j < N; ++j) {
972 vector<CorSingleBin*> binPtrs =
973 corBins[j].getBinPtrs<CorSingleBin>();
977 profBins.push_back( YODA::ProfileBin1D(pPtr->bin(j).xEdges(),
978 YODA::Dbn2D( binPtrs[i]->numEntries(), binPtrs[i]->sumW(),
979 binPtrs[i]->sumW2(), 0., 0., binPtrs[i]->sumWX(), 0, 0)));
980 ne += binPtrs[i]->numEntries();
981 sow += binPtrs[i]->sumW();
982 sow2 += binPtrs[i]->sumW2();
986 pPtr->bins().clear();
988 pPtr->addBins(profBins);
990 pPtr->setTotalDbn(YODA::Dbn2D(ne,sow,sow2,0.,0.,0.,0.,0.));
992 pPtr->setUnderflow(YODA::Dbn2D(refBins[i]->numEntries(),
993 refBins[i]->sumW(), refBins[i]->sumW2(), 0., 0.,
994 refBins[i]->sumWX(), 0., 0.));
1002 const void cnFourInt(Scatter2DPtr h, ECorrPtr e2, ECorrPtr e4)
const {
1003 auto e2bins = e2->getBins();
1004 auto e4bins = e4->getBins();
1005 auto binx = e2->getBinX();
1006 if (binx.size() - 1 != e2bins.size()){
1007 cout <<
"cnFourInt: Bin size (x,y) differs!" << endl;
1010 if (binx != e4->getBinX()) {
1011 cout <<
"Error in cnFourInt: Correlator x-binning differs!" << endl;
1014 vector<CorBinBase*> e2binPtrs;
1015 vector<CorBinBase*> e4binPtrs;
1016 auto cn = [&] (
int i) {
1017 double e22 = e2binPtrs[i]->mean() * e2binPtrs[i]->mean();
1018 return e4binPtrs[i]->mean() - 2. * e22;
1021 vector<pair<double, double> > yErr;
1022 for (
int j = 0, N = e2bins.size(); j < N; ++j) {
1023 e2binPtrs = e2bins[j].getBinPtrs();
1024 e4binPtrs = e4bins[j].getBinPtrs();
1025 yErr.push_back(sampleError(cn));
1028 e2binPtrs = e2->getBinPtrs();
1029 e4binPtrs = e4->getBinPtrs();
1030 fillScatter(h, binx, cn, yErr);
1035 const void vnFourInt(Scatter2DPtr h, ECorrPtr e2, ECorrPtr e4)
const {
1036 cnFourInt(h, e2, e4);
1037 nthPow(h, 0.25, -1.0);
1042 const void cnSixInt(Scatter2DPtr h, ECorrPtr e2, ECorrPtr e4,
1043 ECorrPtr e6)
const {
1044 auto e2bins = e2->getBins();
1045 auto e4bins = e4->getBins();
1046 auto e6bins = e6->getBins();
1047 auto binx = e2->getBinX();
1048 if (binx.size() - 1 != e2bins.size()){
1049 cout <<
"cnSixInt: Bin size (x,y) differs!" << endl;
1052 if (binx != e4->getBinX() || binx != e6->getBinX()) {
1053 cout <<
"Error in cnSixInt: Correlator x-binning differs!" << endl;
1056 vector<CorBinBase*> e2binPtrs;
1057 vector<CorBinBase*> e4binPtrs;
1058 vector<CorBinBase*> e6binPtrs;
1059 auto cn = [&] (
int i) {
1060 double e23 = pow(e2binPtrs[i]->
mean(), 3.0);
1061 return e6binPtrs[i]->mean() - 9.*e2binPtrs[i]->mean()*e4binPtrs[i]->mean() +
1065 vector<pair<double, double> > yErr;
1066 for (
int j = 0, N = e2bins.size(); j < N; ++j) {
1067 e2binPtrs = e2bins[j].getBinPtrs();
1068 e4binPtrs = e4bins[j].getBinPtrs();
1069 e6binPtrs = e6bins[j].getBinPtrs();
1070 yErr.push_back(sampleError(cn));
1073 e2binPtrs = e2->getBinPtrs();
1074 e4binPtrs = e4->getBinPtrs();
1075 e6binPtrs = e6->getBinPtrs();
1076 fillScatter(h, binx, cn, yErr);
1081 const void vnSixInt(Scatter2DPtr h, ECorrPtr e2, ECorrPtr e4,
1082 ECorrPtr e6)
const {
1083 cnSixInt(h, e2, e4, e6);
1084 nthPow(h, 1./6., 0.25);
1090 ECorrPtr e6, ECorrPtr e8)
const {
1091 auto e2bins = e2->getBins();
1092 auto e4bins = e4->getBins();
1093 auto e6bins = e6->getBins();
1094 auto e8bins = e8->getBins();
1095 auto binx = e2->getBinX();
1096 if (binx.size() - 1 != e2bins.size()){
1097 cout <<
"cnEightInt: Bin size (x,y) differs!" << endl;
1100 if (binx != e4->getBinX() || binx != e6->getBinX() ||
1101 binx != e8->getBinX()) {
1102 cout <<
"Error in cnEightInt: Correlator x-binning differs!" << endl;
1105 vector<CorBinBase*> e2binPtrs;
1106 vector<CorBinBase*> e4binPtrs;
1107 vector<CorBinBase*> e6binPtrs;
1108 vector<CorBinBase*> e8binPtrs;
1109 auto cn = [&] (
int i ) {
1110 double e22 = e2binPtrs[i]->mean() * e2binPtrs[i]->mean();
1111 double e24 = e22 * e22;
1112 double e42 = e4binPtrs[i]->mean() * e4binPtrs[i]->mean();
1113 return e8binPtrs[i]->mean() - 16. * e6binPtrs[i]->mean() *
1114 e2binPtrs[i]->mean() - 18. * e42 + 144. * e4binPtrs[i]->mean()*e22
1118 vector<pair<double, double> > yErr;
1119 for (
int j = 0, N = e2bins.size(); j < N; ++j) {
1120 e2binPtrs = e2bins[j].getBinPtrs();
1121 e4binPtrs = e4bins[j].getBinPtrs();
1122 e6binPtrs = e6bins[j].getBinPtrs();
1123 e8binPtrs = e8bins[j].getBinPtrs();
1124 yErr.push_back(sampleError(cn));
1127 e2binPtrs = e2->getBinPtrs();
1128 e4binPtrs = e4->getBinPtrs();
1129 e6binPtrs = e6->getBinPtrs();
1130 e8binPtrs = e8->getBinPtrs();
1131 fillScatter(h, binx, cn, yErr);
1136 const void vnEightInt(Scatter2DPtr h, ECorrPtr e2, ECorrPtr e4, ECorrPtr e6, ECorrPtr e8)
const {
1137 cnEightInt(h, e2, e4, e6, e8);
1138 nthPow(h, 1./8., -1./33.);
1143 const void vnTwoDiff(Scatter2DPtr h, ECorrPtr e2Dif)
const {
1144 auto e2bins = e2Dif->getBins();
1145 auto ref = e2Dif->getReference();
1146 auto binx = e2Dif->getBinX();
1147 if (binx.size() -1 != e2bins.size()) {
1148 cout <<
"vnTwoDif: Bin size (x,y) differs!" << endl;
1151 vector<CorBinBase*> e2binPtrs;
1152 vector<CorBinBase*> refPtrs;
1153 auto vn = [&] (
int i) {
1155 if (ref.mean() <= 0)
return 0.;
1156 return e2binPtrs[i]->mean() / sqrt(ref.mean());
1159 auto vnerr = [&] (
int i) {
1161 if (refPtrs[i]->
mean() <=0)
return 0.;
1162 return e2binPtrs[i]->mean() / sqrt(refPtrs[i]->
mean());
1165 vector<pair<double, double> > yErr;
1166 refPtrs = ref.getBinPtrs();
1167 for (
int j = 0, N = e2bins.size(); j < N; ++j) {
1168 e2binPtrs = e2bins[j].getBinPtrs();
1169 yErr.push_back(sampleError(vnerr));
1172 e2binPtrs = e2Dif->getBinPtrs();
1173 fillScatter(h, binx, vn);
1178 const void vnFourDiff(Scatter2DPtr h, ECorrPtr e2Dif, ECorrPtr e4Dif)
const {
1179 auto e2bins = e2Dif->getBins();
1180 auto e4bins = e4Dif->getBins();
1181 auto ref2 = e2Dif->getReference();
1182 auto ref4 = e4Dif->getReference();
1183 auto binx = e2Dif->getBinX();
1184 if (binx.size() - 1 != e2bins.size()){
1185 cout <<
"vnFourDif: Bin size (x,y) differs!" << endl;
1188 if (binx != e4Dif->getBinX()) {
1189 cout <<
"Error in vnFourDif: Correlator x-binning differs!" << endl;
1192 vector<CorBinBase*> e2binPtrs;
1193 vector<CorBinBase*> e4binPtrs;
1194 vector<CorBinBase*> ref2Ptrs;
1195 vector<CorBinBase*> ref4Ptrs;
1196 double denom = 2 * ref2.mean() * ref2.mean() - ref4.mean();
1197 auto vn = [&] (
int i) {
1199 if (denom <= 0 )
return 0.;
1200 return ((2 * ref2.mean() * e2bins[i].mean() - e4bins[i].mean()) / pow(denom, 0.75));
1203 auto vnerr = [&] (
int i) {
1204 double denom2 = 2 * ref2Ptrs[i]->mean() * ref2Ptrs[i]->mean() -
1205 ref4Ptrs[i]->mean();
1207 if (denom2 <= 0)
return 0.;
1208 return ((2 * ref2Ptrs[i]->
mean() * e2binPtrs[i]->
mean() - e4binPtrs[i]->
mean()) / pow(denom2, 0.75));
1211 vector<pair<double, double> > yErr;
1212 ref2Ptrs = ref2.getBinPtrs();
1213 ref4Ptrs = ref4.getBinPtrs();
1214 for (
int j = 0, N = e2bins.size(); j < N; ++j) {
1215 e2binPtrs = e2bins[j].getBinPtrs();
1216 e4binPtrs = e4bins[j].getBinPtrs();
1217 yErr.push_back(sampleError(vnerr));
1220 e2binPtrs = e2Dif->getBinPtrs();
1221 e4binPtrs = e4Dif->getBinPtrs();
1222 fillScatter(h, binx, vn, yErr);
ECorrPtr bookECorrelator(const string name, const YODA::Scatter2D &hIn)
Templated version of correlator booking which takes N desired harmonic and M number of particles...
Definition: Correlators.hh:674
Definition: MC_Cent_pPb.hh:10
static pair< double, double > sampleEnvelope(T func)
Calculate the bootstrapped sample envelope.
Definition: Correlators.hh:869
const vector< int > getH1() const
Get a copy of the h1 harmonic vector.
Definition: Correlators.hh:499
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:416
ECorrPtr bookECorrelator(const string name, const vector< int > &h, const YODA::Scatter2D &hIn)
Book an ECorrelator in the same way as a histogram.
Definition: Correlators.hh:601
const vector< double > getBinX() const
Get a copy of the bin x-values.
Definition: Correlators.hh:494
const void vnTwoInt(Scatter2DPtr h, ECorrPtr e2) const
Two particle integrated vn.
Definition: Correlators.hh:921
void rawHookOut(vector< MultiweightAOPtr > raos, size_t iW) final
Transform RAW ECorrelator Profiles to have content before writing them. Overloaded method from Analys...
Definition: Correlators.hh:947
const void cnSixInt(Scatter2DPtr h, ECorrPtr e2, ECorrPtr e4, ECorrPtr e6) const
Six particle integrated cn.
Definition: Correlators.hh:1042
CmpState compare(const Projection &p) const
Definition: Correlators.hh:145
ECorrPtr bookECorrelator(const string name, const vector< int > &h, vector< double > &binIn)
Book an ECorrelator in the same way as a histogram.
Definition: Correlators.hh:610
static vector< int > hVec(int n, int m)
Construct a harmonic vectors from n harmonics and m number of particles.
Definition: Correlators.hh:106
void fill(const Correlators &c1, const Correlators &c2, const double &weight=1.0)
Fill bins with the appropriate correlator, and a rapidity gap between two Correlators.
Definition: Correlators.hh:463
const vector< CorBinBase * > getBinPtrs()
Return the bins as pointers to the base class.
Definition: Correlators.hh:487
const vector< int > getH2() const
Get a copy of the h2 harmonic vector.
Definition: Correlators.hh:504
const void vnFourDiff(Scatter2DPtr h, ECorrPtr e2Dif, ECorrPtr e4Dif) const
Four particle differential vn.
Definition: Correlators.hh:1178
static pair< double, double > sampleVariance(T func)
Calculate the bootstrapped sample variance.
Definition: Correlators.hh:851
shared_ptr< ECorrelator > ECorrPtr
Typedef of shared pointer to ECorrelator.
Definition: Correlators.hh:597
ECorrPtr bookECorrelator(const string name, const vector< int > &h1, const vector< int > &h2, const YODA::Scatter2D &hIn)
Book a gapped ECorrelator with two harmonic vectors.
Definition: Correlators.hh:641
const void cnEightInt(Scatter2DPtr h, ECorrPtr e2, ECorrPtr e4, ECorrPtr e6, ECorrPtr e8) const
Eight particle integrated cn.
Definition: Correlators.hh:1089
ECorrelator(vector< int > h1In, vector< int > h2In, vector< double > binIn)
Constructor for gapped correlator.
Definition: Correlators.hh:418
Particle representation, either from a HepMC::GenEvent or reconstructed.
Definition: Particle.hh:18
A helper class to calculate all event averages of correlators.
Definition: Correlators.hh:393
void fill(const double &obs, const Correlators &c1, const Correlators &c2, double weight=1.0)
Fill the appropriate bin given an input (per event) observable, e.g. centrality, with a rapidity gap ...
Definition: Correlators.hh:432
static constexpr double DBL_NAN
Convenient const for getting the double NaN value.
Definition: Utils.hh:46
Base class for projections which return subsets of an event's particles.
Definition: ParticleFinder.hh:11
ECorrPtr bookECorrelator(const string name, vector< double > binIn)
Templated version of correlator booking which takes N desired harmonic and M number of particles...
Definition: Correlators.hh:665
Tools for flow analyses.
Definition: Correlators.hh:221
const vector< pair< double, double > > pTBinnedCorrelatorsGap(const Correlators &other, vector< int > n1, vector< int > n2, bool overflow=false) const
pT differential correlators of n1 harmonic, for number n1.size()
const void vnEightInt(Scatter2DPtr h, ECorrPtr e2, ECorrPtr e4, ECorrPtr e6, ECorrPtr e8) const
Eight particle integrated vn.
Definition: Correlators.hh:1136
ECorrPtr bookECorrelator(const string name, const vector< int > &h1, const vector< int > &h2, vector< double > &binIn)
Book a gapped ECorrelator with two harmonic vectors.
Definition: Correlators.hh:625
void fill(const Correlators &c, const double &weight=1.0)
Fill the bins with the appropriate correlator.
Definition: Correlators.hh:446
void fill(const double &obs, const Correlators &c, double weight=1.0)
Fill the appropriate bin given an input (per event) observable, e.g. centrality.
Definition: Correlators.hh:423
void setReference(CorBin refIn)
Replace reference flow bin with another, e.g. calculated in another phase space or with other pid...
Definition: Correlators.hh:509
void setProfs(vector< string > prIn)
Set the prIn list of profile histograms associated with the internal bins.
Definition: Correlators.hh:522
This is the base class of all analysis classes in Rivet.
Definition: Analysis.hh:64
Representation of a HepMC event, and enabler of Projection caching.
Definition: Event.hh:22
Cmp< Projection > mkPCmp(const Projection &otherparent, const std::string &pname) const
const void fillScatter(Scatter2DPtr h, vector< double > &binx, F func, vector< pair< double, double > > &yErr) const
Helper method for turning correlators into Scatter2Ds with error estimates.
Definition: Correlators.hh:746
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:121
bool fillFromProfile(YODA::AnalysisObjectPtr yao, string name)
Fill bins with content from preloaded 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.
Definition: Correlators.hh:816
static void fillScatter(Scatter2DPtr h, vector< double > &binx, T func)
Helper method for turning correlators into Scatter2Ds.
Definition: Correlators.hh:715
const pair< double, double > sampleError(T func) const
Selection method for which sample error to use, given in the constructor.
Definition: Correlators.hh:888
const vector< pair< double, double > > pTBinnedCorrelators(vector< int > n, bool overflow=false) const
pT differential correlator of n harmonic, for number of powers n.size()
const vector< CorBin > getBins() const
Get a copy of the bin contents.
Definition: Correlators.hh:482
virtual std::string name() const
Get the name of the projection.
Definition: Projection.hh:56
const pair< double, double > intCorrelatorGap(const Correlators &other, vector< int > n1, vector< int > n2) const
Integrated correlator of n1 harmonic, for number of powers n1.size()
Projection for calculating correlators for flow measurements.
Definition: Correlators.hh:38
const pair< int, int > getMaxValues() const
Get the correct max N and max P for the set of booked correlators.
Definition: Correlators.hh:580
CumulantAnalysis(const string &n)
Constructor.
Definition: Correlators.hh:703
void project(const Event &e)
const void vnSixInt(Scatter2DPtr h, ECorrPtr e2, ECorrPtr e4, ECorrPtr e6) const
Six particle integrated vn.
Definition: Correlators.hh:1081
const pair< double, double > intCorrelator(vector< int > n) const
Integrated correlator of n harmonic, with the number of powers being the size of n. E.G. n should be: <<2>>_2 => n = {2, -2} <<4>>_2 => n = {2, 2, -2, -2} <<2>>_4 => n = {4, -4} <<4>>_4 => n = {4, 4, -4, 4}, and so on.
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.
Definition: Correlators.hh:778
const void vnFourInt(Scatter2DPtr h, ECorrPtr e2, ECorrPtr e4) const
Four particle integrated vn.
Definition: Correlators.hh:1035
const void vnTwoDiff(Scatter2DPtr h, ECorrPtr e2Dif) const
Two particle differential vn.
Definition: Correlators.hh:1143
Correlators(const ParticleFinder &fsp, int nMaxIn=2, int pMaxIn=0, vector< double > pTbinEdgesIn={})
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:410
Base class for all Rivet projections.
Definition: Projection.hh:29
const void cnTwoInt(Scatter2DPtr h, ECorrPtr e2) const
Two-particle integrated cn.
Definition: Correlators.hh:898
std::enable_if< std::is_arithmetic< NUM >::value, double >::type mean(const vector< NUM > &sample)
Definition: MathUtils.hh:458
ECorrPtr bookECorrelatorGap(const string name, const YODA::Scatter2D &hIn)
Templated version of gapped correlator booking which takes N desired harmonic and M number of particl...
Definition: Correlators.hh:683
const CorBin getReference() const
Extract the reference flow from a differential event averaged correlator.
Definition: Correlators.hh:514
ECorrPtr bookECorrelatorGap(const string name, const vector< int > &h, const YODA::Scatter2D &hIn)
Definition: Correlators.hh:653
const void corrPlot(Scatter2DPtr h, ECorrPtr e) const
Put an event-averaged correlator into a Scatter2D.
Definition: Correlators.hh:930