9 #include "Pythia8/Basics.h"
29 const int Rndm::DEFAULTSEED = 19780503;
35 bool Rndm::rndmEnginePtr( RndmEngine* rndmEngPtrIn) {
38 if (rndmEngPtrIn == 0)
return false;
39 rndmEngPtr = rndmEngPtrIn;
40 useExternalRndm =
true;
51 void Rndm::init(
int seedIn) {
55 if (seedIn < 0) seed = DEFAULTSEED;
56 else if (seedIn == 0) seed = int(time(0));
57 if (seed < 0) seed = -seed;
60 int ij = (seed/30082) % 31329;
61 int kl = seed % 30082;
62 int i = (ij/177) % 177 + 2;
64 int k = (kl/169) % 178 + 1;
68 for (
int ii = 0; ii < 97; ++ii) {
71 for (
int jj = 0; jj < 48; ++jj) {
72 int m = (( (i*j)%179 )*k) % 179;
77 if ( (l*m) % 64 >= 32) s += t;
85 for (
int i24 = 0; i24 < 24; ++i24) twom24 *= 0.5;
87 cd = 7654321. * twom24;
88 cm = 16777213. * twom24;
103 double Rndm::flat() {
106 if (useExternalRndm)
return rndmEngPtr->flat();
109 if (!initRndm) init(DEFAULTSEED);
115 uni = u[i97] - u[j97];
116 if (uni < 0.) uni += 1.;
118 if (--i97 < 0) i97 = 96;
119 if (--j97 < 0) j97 = 96;
123 if(uni < 0.) uni += 1.;
124 }
while (uni <= 0. || uni >= 1.);
133 int Rndm::pick(
const vector<double>& prob) {
136 for (
int i = 0; i < int(prob.size()); ++i) work += prob[i];
139 do work -= prob[++index];
140 while (work > 0. && index <
int(prob.size()));
149 bool Rndm::dumpState(
string fileName) {
152 const char* fn = fileName.c_str();
153 ofstream ofs(fn, ios::binary);
156 cout <<
" Rndm::dumpState: could not open output file" << endl;
161 ofs.write((
char *) &seedSave,
sizeof(
int));
162 ofs.write((
char *) &sequence,
sizeof(
long));
163 ofs.write((
char *) &i97,
sizeof(
int));
164 ofs.write((
char *) &j97,
sizeof(
int));
165 ofs.write((
char *) &c,
sizeof(
double));
166 ofs.write((
char *) &cd,
sizeof(
double));
167 ofs.write((
char *) &cm,
sizeof(
double));
168 ofs.write((
char *) &u,
sizeof(
double) * 97);
171 cout <<
" PYTHIA Rndm::dumpState: seed = " << seedSave
172 <<
", sequence no = " << sequence << endl;
181 bool Rndm::readState(
string fileName) {
184 const char* fn = fileName.c_str();
185 ifstream ifs(fn, ios::binary);
188 cout <<
" Rndm::readState: could not open input file" << endl;
193 ifs.read((
char *) &seedSave,
sizeof(
int));
194 ifs.read((
char *) &sequence,
sizeof(
long));
195 ifs.read((
char *) &i97,
sizeof(
int));
196 ifs.read((
char *) &j97,
sizeof(
int));
197 ifs.read((
char *) &c,
sizeof(
double));
198 ifs.read((
char *) &cd,
sizeof(
double));
199 ifs.read((
char *) &cm,
sizeof(
double));
200 ifs.read((
char *) &u,
sizeof(
double) *97);
203 cout <<
" PYTHIA Rndm::readState: seed " << seedSave
204 <<
", sequence no = " << sequence << endl;
221 const double Vec4::TINY = 1e-20;
227 void Vec4::rot(
double thetaIn,
double phiIn) {
229 double cthe = cos(thetaIn);
230 double sthe = sin(thetaIn);
231 double cphi = cos(phiIn);
232 double sphi = sin(phiIn);
233 double tmpx = cthe * cphi * xx - sphi * yy + sthe * cphi * zz;
234 double tmpy = cthe * sphi * xx + cphi * yy + sthe * sphi * zz;
235 double tmpz = -sthe * xx + cthe * zz;
246 void Vec4::rotaxis(
double phiIn,
double nx,
double ny,
double nz) {
248 double norm = 1./sqrt(nx*nx + ny*ny + nz*nz);
252 double cphi = cos(phiIn);
253 double sphi = sin(phiIn);
254 double comb = (nx * xx + ny * yy + nz * zz) * (1. - cphi);
255 double tmpx = cphi * xx + comb * nx + sphi * (ny * zz - nz * yy);
256 double tmpy = cphi * yy + comb * ny + sphi * (nz * xx - nx * zz);
257 double tmpz = cphi * zz + comb * nz + sphi * (nx * yy - ny * xx);
268 void Vec4::rotaxis(
double phiIn,
const Vec4& n) {
273 double norm = 1./sqrt(nx*nx + ny*ny + nz*nz);
277 double cphi = cos(phiIn);
278 double sphi = sin(phiIn);
279 double comb = (nx * xx + ny * yy + nz * zz) * (1. - cphi);
280 double tmpx = cphi * xx + comb * nx + sphi * (ny * zz - nz * yy);
281 double tmpy = cphi * yy + comb * ny + sphi * (nz * xx - nx * zz);
282 double tmpz = cphi * zz + comb * nz + sphi * (nx * yy - ny * xx);
293 void Vec4::bst(
double betaX,
double betaY,
double betaZ) {
295 double beta2 = betaX*betaX + betaY*betaY + betaZ*betaZ;
296 if (beta2 >= 1.)
return;
297 double gamma = 1. / sqrt(1. - beta2);
298 double prod1 = betaX * xx + betaY * yy + betaZ * zz;
299 double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
303 tt = gamma * (tt + prod1);
311 void Vec4::bst(
double betaX,
double betaY,
double betaZ,
double gamma) {
313 double prod1 = betaX * xx + betaY * yy + betaZ * zz;
314 double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
318 tt = gamma * (tt + prod1);
326 void Vec4::bst(
const Vec4& pIn) {
328 if (abs(pIn.tt) < Vec4::TINY)
return;
329 double betaX = pIn.xx / pIn.tt;
330 double betaY = pIn.yy / pIn.tt;
331 double betaZ = pIn.zz / pIn.tt;
332 double beta2 = betaX*betaX + betaY*betaY + betaZ*betaZ;
333 if (beta2 >= 1.)
return;
334 double gamma = 1. / sqrt(1. - beta2);
335 double prod1 = betaX * xx + betaY * yy + betaZ * zz;
336 double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
340 tt = gamma * (tt + prod1);
348 void Vec4::bst(
const Vec4& pIn,
double mIn) {
350 if (abs(pIn.tt) < Vec4::TINY)
return;
351 double betaX = pIn.xx / pIn.tt;
352 double betaY = pIn.yy / pIn.tt;
353 double betaZ = pIn.zz / pIn.tt;
354 double gamma = pIn.tt / mIn;
355 double prod1 = betaX * xx + betaY * yy + betaZ * zz;
356 double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
360 tt = gamma * (tt + prod1);
368 void Vec4::bstback(
const Vec4& pIn) {
370 if (abs(pIn.tt) < Vec4::TINY)
return;
371 double betaX = -pIn.xx / pIn.tt;
372 double betaY = -pIn.yy / pIn.tt;
373 double betaZ = -pIn.zz / pIn.tt;
374 double beta2 = betaX*betaX + betaY*betaY + betaZ*betaZ;
375 if (beta2 >= 1.)
return;
376 double gamma = 1. / sqrt(1. - beta2);
377 double prod1 = betaX * xx + betaY * yy + betaZ * zz;
378 double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
382 tt = gamma * (tt + prod1);
390 void Vec4::bstback(
const Vec4& pIn,
double mIn) {
392 if (abs(pIn.tt) < Vec4::TINY)
return;
393 double betaX = -pIn.xx / pIn.tt;
394 double betaY = -pIn.yy / pIn.tt;
395 double betaZ = -pIn.zz / pIn.tt;
396 double gamma = pIn.tt / mIn;
397 double prod1 = betaX * xx + betaY * yy + betaZ * zz;
398 double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
402 tt = gamma * (tt + prod1);
410 void Vec4::rotbst(
const RotBstMatrix& M) {
412 double x = xx;
double y = yy;
double z = zz;
double t = tt;
413 tt = M.M[0][0] * t + M.M[0][1] * x + M.M[0][2] * y + M.M[0][3] * z;
414 xx = M.M[1][0] * t + M.M[1][1] * x + M.M[1][2] * y + M.M[1][3] * z;
415 yy = M.M[2][0] * t + M.M[2][1] * x + M.M[2][2] * y + M.M[2][3] * z;
416 zz = M.M[3][0] * t + M.M[3][1] * x + M.M[3][2] * y + M.M[3][3] * z;
424 ostream& operator<<(ostream& os,
const Vec4& v) {
425 os << fixed << setprecision(3) <<
" " << setw(9) << v.xx <<
" "
426 << setw(9) << v.yy <<
" " << setw(9) << v.zz <<
" " << setw(9)
427 << v.tt <<
" (" << setw(9) << v.mCalc() <<
")\n";
435 double m(
const Vec4& v1,
const Vec4& v2) {
436 double m2 = pow2(v1.tt + v2.tt) - pow2(v1.xx + v2.xx)
437 - pow2(v1.yy + v2.yy) - pow2(v1.zz + v2.zz);
438 return (m2 > 0.) ? sqrt(m2) : 0.;
445 double m2(
const Vec4& v1,
const Vec4& v2) {
446 double m2 = pow2(v1.tt + v2.tt) - pow2(v1.xx + v2.xx)
447 - pow2(v1.yy + v2.yy) - pow2(v1.zz + v2.zz);
455 double dot3(
const Vec4& v1,
const Vec4& v2) {
456 return v1.xx*v2.xx + v1.yy*v2.yy + v1.zz*v2.zz;
463 Vec4 cross3(
const Vec4& v1,
const Vec4& v2) {
465 v.xx = v1.yy * v2.zz - v1.zz * v2.yy;
466 v.yy = v1.zz * v2.xx - v1.xx * v2.zz;
467 v.zz = v1.xx * v2.yy - v1.yy * v2.xx;
return v;
475 Vec4 cross4(
const Vec4& a,
const Vec4& b,
const Vec4& c) {
477 v.tt = a.xx*b.yy*c.zz + a.yy*b.zz*c.xx + a.zz*b.xx*c.yy
478 - a.xx*b.zz*c.yy - a.zz*b.yy*c.xx - a.yy*b.xx*c.zz;
479 v.xx = -(- a.tt*b.yy*c.zz - a.yy*b.zz*c.tt - a.zz*b.tt*c.yy
480 + a.tt*b.zz*c.yy + a.zz*b.yy*c.tt + a.yy*b.tt*c.zz);
481 v.yy = -(- a.xx*b.tt*c.zz - a.tt*b.zz*c.xx - a.zz*b.xx*c.tt
482 + a.xx*b.zz*c.tt + a.zz*b.tt*c.xx + a.tt*b.xx*c.zz);
483 v.zz = -(- a.xx*b.yy*c.tt - a.yy*b.tt*c.xx - a.tt*b.xx*c.yy
484 + a.xx*b.tt*c.yy + a.tt*b.yy*c.xx + a.yy*b.xx*c.tt);
492 double theta(
const Vec4& v1,
const Vec4& v2) {
493 double cthe = (v1.xx * v2.xx + v1.yy * v2.yy + v1.zz * v2.zz)
494 / sqrt( (v1.xx*v1.xx + v1.yy*v1.yy + v1.zz*v1.zz)
495 * (v2.xx*v2.xx + v2.yy*v2.yy + v2.zz*v2.zz) );
496 cthe = max(-1., min(1., cthe));
504 double costheta(
const Vec4& v1,
const Vec4& v2) {
505 double cthe = (v1.xx * v2.xx + v1.yy * v2.yy + v1.zz * v2.zz)
506 / sqrt( (v1.xx*v1.xx + v1.yy*v1.yy + v1.zz*v1.zz)
507 * (v2.xx*v2.xx + v2.yy*v2.yy + v2.zz*v2.zz) );
508 cthe = max(-1., min(1., cthe));
516 double phi(
const Vec4& v1,
const Vec4& v2) {
517 double cphi = (v1.xx * v2.xx + v1.yy * v2.yy) / sqrt( max( Vec4::TINY,
518 (v1.xx*v1.xx + v1.yy*v1.yy) * (v2.xx*v2.xx + v2.yy*v2.yy) ));
519 cphi = max(-1., min(1., cphi));
527 double cosphi(
const Vec4& v1,
const Vec4& v2) {
528 double cphi = (v1.xx * v2.xx + v1.yy * v2.yy) / sqrt( max( Vec4::TINY,
529 (v1.xx*v1.xx + v1.yy*v1.yy) * (v2.xx*v2.xx + v2.yy*v2.yy) ));
530 cphi = max(-1., min(1., cphi));
538 double phi(
const Vec4& v1,
const Vec4& v2,
const Vec4& n) {
539 double nx = n.xx;
double ny = n.yy;
double nz = n.zz;
540 double norm = 1. / sqrt(nx*nx + ny*ny + nz*nz);
541 nx *= norm; ny *=norm; nz *=norm;
542 double v1s = v1.xx * v1.xx + v1.yy * v1.yy + v1.zz * v1.zz;
543 double v2s = v2.xx * v2.xx + v2.yy * v2.yy + v2.zz * v2.zz;
544 double v1v2 = v1.xx * v2.xx + v1.yy * v2.yy + v1.zz * v2.zz;
545 double v1n = v1.xx * nx + v1.yy * ny + v1.zz * nz;
546 double v2n = v2.xx * nx + v2.yy * ny + v2.zz * nz;
547 double cphi = (v1v2 - v1n * v2n) / sqrt( max( Vec4::TINY,
548 (v1s - v1n*v1n) * (v2s - v2n*v2n) ));
549 cphi = max(-1., min(1., cphi));
557 double cosphi(
const Vec4& v1,
const Vec4& v2,
const Vec4& n) {
558 double nx = n.xx;
double ny = n.yy;
double nz = n.zz;
559 double norm = 1. / sqrt(nx*nx + ny*ny + nz*nz);
560 nx *= norm; ny *=norm; nz *=norm;
561 double v1s = v1.xx * v1.xx + v1.yy * v1.yy + v1.zz * v1.zz;
562 double v2s = v2.xx * v2.xx + v2.yy * v2.yy + v2.zz * v2.zz;
563 double v1v2 = v1.xx * v2.xx + v1.yy * v2.yy + v1.zz * v2.zz;
564 double v1n = v1.xx * nx + v1.yy * ny + v1.zz * nz;
565 double v2n = v2.xx * nx + v2.yy * ny + v2.zz * nz;
566 double cphi = (v1v2 - v1n * v2n) / sqrt( max( Vec4::TINY,
567 (v1s - v1n*v1n) * (v2s - v2n*v2n) ));
568 cphi = max(-1., min(1., cphi));
576 double RRapPhi(
const Vec4& v1,
const Vec4& v2) {
577 double dRap = abs(v1.rap() - v2.rap());
578 double dPhi = abs(v1.phi() - v2.phi());
579 if (dPhi > M_PI) dPhi = 2. * M_PI - dPhi;
580 return sqrt(dRap*dRap + dPhi*dPhi);
587 double REtaPhi(
const Vec4& v1,
const Vec4& v2) {
588 double dEta = abs(v1.eta() - v2.eta());
589 double dPhi = abs(v1.phi() - v2.phi());
590 if (dPhi > M_PI) dPhi = 2. * M_PI - dPhi;
591 return sqrt(dEta*dEta + dPhi*dPhi);
599 bool pShift( Vec4& p1Move, Vec4& p2Move,
double m1New,
double m2New) {
602 double sH = (p1Move + p2Move).m2Calc();
603 double r1 = p1Move.m2Calc() / sH;
604 double r2 = p2Move.m2Calc() / sH;
605 double r3 = m1New * m1New / sH;
606 double r4 = m2New * m2New / sH;
607 double l12 = sqrtpos(pow2(1. - r1 - r2) - 4. * r1 * r2);
608 double l34 = sqrtpos(pow2(1. - r3 - r4) - 4. * r3 * r4);
611 if (sH <= pow2(m1New + m2New) || l12 < Vec4::TINY || l34 < Vec4::TINY)
615 double c1 = 0.5 * ( (1. - r1 + r2) * l34 / l12 - (1. - r3 + r4) );
616 double c2 = 0.5 * ( (1. + r1 - r2) * l34 / l12 - (1. + r3 - r4) );
617 Vec4 pSh = c1 * p1Move - c2 * p2Move;
627 pair<Vec4,Vec4> getTwoPerpendicular(
const Vec4& v1,
const Vec4& v2) {
630 Vec4 nPerp( cross3(v1,v2) );
631 double TINY = std::numeric_limits<double>::epsilon();
632 if ( abs(nPerp.pAbs()) < TINY) {
634 if (v1.px() != 0.) aux.p(v1.yy,v1.px(),v1.pz(),v1.e());
635 else if (v1.py() != 0.) aux.p(v1.px(),v1.pz(),v1.py(),v1.e());
636 else if (v1.pz() != 0.) aux.p(v1.pz(),v1.py(),v1.px(),v1.e());
637 nPerp.p( cross3(v1,aux) );
639 nPerp /= abs(nPerp.pAbs());
642 Vec4 lPerp( cross4(v1,v2,nPerp) );
643 lPerp /= sqrt(abs(lPerp.m2Calc()));
644 return make_pair(nPerp,lPerp);
659 const double RotBstMatrix::TINY = 1e-20;
665 void RotBstMatrix::rot(
double theta,
double phi) {
668 double cthe = cos(theta);
669 double sthe = sin(theta);
670 double cphi = cos(phi);
671 double sphi = sin(phi);
672 double Mrot[4][4] = {
674 {0., cthe * cphi, - sphi, sthe * cphi},
675 {0., cthe * sphi, cphi, sthe * sphi},
676 {0., -sthe, 0., cthe } };
680 for (
int i = 0; i < 4; ++i)
681 for (
int j = 0; j < 4; ++j)
682 Mtmp[i][j] = M[i][j];
683 for (
int i = 0; i < 4; ++i)
684 for (
int j = 0; j < 4; ++j)
685 M[i][j] = Mrot[i][0] * Mtmp[0][j] + Mrot[i][1] * Mtmp[1][j]
686 + Mrot[i][2] * Mtmp[2][j] + Mrot[i][3] * Mtmp[3][j];
694 void RotBstMatrix::rot(
const Vec4& p) {
696 double theta = p.theta();
697 double phi = p.phi();
707 void RotBstMatrix::bst(
double betaX,
double betaY,
double betaZ) {
710 double gm = 1. / sqrt( max( TINY, 1. - betaX*betaX - betaY*betaY
712 double gf = gm*gm / (1. + gm);
713 double Mbst[4][4] = {
714 { gm, gm*betaX, gm*betaY, gm*betaZ },
715 { gm*betaX, 1. + gf*betaX*betaX, gf*betaX*betaY, gf*betaX*betaZ },
716 { gm*betaY, gf*betaY*betaX, 1. + gf*betaY*betaY, gf*betaY*betaZ },
717 { gm*betaZ, gf*betaZ*betaX, gf*betaZ*betaY, 1. + gf*betaZ*betaZ } };
721 for (
int i = 0; i < 4; ++i)
722 for (
int j = 0; j < 4; ++j)
723 Mtmp[i][j] = M[i][j];
724 for (
int i = 0; i < 4; ++i)
725 for (
int j = 0; j < 4; ++j)
726 M[i][j] = Mbst[i][0] * Mtmp[0][j] + Mbst[i][1] * Mtmp[1][j]
727 + Mbst[i][2] * Mtmp[2][j] + Mbst[i][3] * Mtmp[3][j];
735 void RotBstMatrix::bst(
const Vec4& p) {
736 double betaX = p.px() / p.e();
737 double betaY = p.py() / p.e();
738 double betaZ = p.pz() / p.e();
739 bst(betaX, betaY, betaZ);
746 void RotBstMatrix::bstback(
const Vec4& p) {
747 double betaX = -p.px() / p.e();
748 double betaY = -p.py() / p.e();
749 double betaZ = -p.pz() / p.e();
750 bst(betaX, betaY, betaZ);
757 void RotBstMatrix::bst(
const Vec4& p1,
const Vec4& p2) {
758 double eSum = p1.e() + p2.e();
759 double betaX = (p2.px() - p1.px()) / eSum;
760 double betaY = (p2.py() - p1.py()) / eSum;
761 double betaZ = (p2.pz() - p1.pz()) / eSum;
762 double fac = 2. / (1. + betaX*betaX + betaY*betaY + betaZ*betaZ);
763 betaX *= fac; betaY *= fac; betaZ *= fac;
764 bst(betaX, betaY, betaZ);
772 void RotBstMatrix::toCMframe(
const Vec4& p1,
const Vec4& p2) {
776 double theta = dir.theta();
777 double phi = dir.phi();
788 void RotBstMatrix::fromCMframe(
const Vec4& p1,
const Vec4& p2) {
792 double theta = dir.theta();
793 double phi = dir.phi();
803 void RotBstMatrix::rotbst(
const RotBstMatrix& Mrb) {
805 for (
int i = 0; i < 4; ++i)
806 for (
int j = 0; j < 4; ++j)
807 Mtmp[i][j] = M[i][j];
808 for (
int i = 0; i < 4; ++i)
809 for (
int j = 0; j < 4; ++j)
810 M[i][j] = Mrb.M[i][0] * Mtmp[0][j] + Mrb.M[i][1] * Mtmp[1][j]
811 + Mrb.M[i][2] * Mtmp[2][j] + Mrb.M[i][3] * Mtmp[3][j];
818 void RotBstMatrix::invert() {
820 for (
int i = 0; i < 4; ++i)
821 for (
int j = 0; j < 4; ++j)
822 Mtmp[i][j] = M[i][j];
823 for (
int i = 0; i < 4; ++i)
824 for (
int j = 0; j < 4; ++j)
825 M[i][j] = ( (i == 0 && j > 0) || (i > 0 && j == 0) )
826 ? - Mtmp[j][i] : Mtmp[j][i];
833 void RotBstMatrix::reset() {
834 for (
int i = 0; i < 4; ++i)
835 for (
int j = 0; j < 4; ++j)
836 M[i][j] = (i==j) ? 1. : 0.;
843 double RotBstMatrix::deviation()
const {
845 for (
int i = 0; i < 4; ++i)
846 for (
int j = 0; j < 4; ++j)
847 devSum += (i==j) ? abs(M[i][j] - 1.) : abs(M[i][j]);
855 ostream& operator<<(ostream& os,
const RotBstMatrix& M) {
856 os << fixed << setprecision(5) <<
" Rotation/boost matrix: \n";
857 for (
int i = 0; i <4; ++i)
858 os << setw(10) << M.M[i][0] << setw(10) << M.M[i][1]
859 << setw(10) << M.M[i][2] << setw(10) << M.M[i][3] <<
"\n";
875 const int Hist::NBINMAX = 10000;
878 const int Hist::NCOLMAX = 100;
881 const int Hist::NLINES = 30;
884 const double Hist::TOLERANCE = 0.001;
887 const double Hist::TINY = 1e-20;
888 const double Hist::LARGE = 1e20;
891 const double Hist::SMALLFRAC = 0.1;
894 const double DYAC[] = {0.04, 0.05, 0.06, 0.08, 0.10,
895 0.12, 0.15, 0.20, 0.25, 0.30};
896 const char NUMBER[] = {
'0',
'1',
'2',
'3',
'4',
'5',
897 '6',
'7',
'8',
'9',
'X' };
903 void Hist::book(
string titleIn,
int nBinIn,
double xMinIn,
904 double xMaxIn,
bool logXIn) {
908 if (nBinIn < 1) nBin = 1;
909 if (nBinIn > NBINMAX) {
911 cout <<
" Warning: number of bins for histogram " << titleIn
912 <<
" reduced to " << nBin << endl;
917 if (!linX && xMin < TINY) {
919 cout <<
" Warning: lower x border of histogram " << titleIn
920 <<
" increased to " << xMin << endl;
922 if (xMax < xMin + TINY) {
924 cout <<
" Warning: upper x border of histogram " << titleIn
925 <<
" increased to " << xMax << endl;
927 dx = (linX) ? (xMax - xMin) / nBin : log10(xMax / xMin) / nBin;
943 for (
int ix = 0; ix < nBin; ++ix) res[ix] = 0.;
951 void Hist::fill(
double x,
double w) {
954 if (x < xMin) {under += w;
return;}
955 if (x > xMax) {over += w;
return;}
956 int iBin = (linX) ?
int( floor( (x - xMin) / dx) )
957 :
int( floor( log10(x / xMin) / dx) );
958 if (iBin < 0) under += w;
959 else if (iBin >= nBin) over += w;
960 else {inside += w; res[iBin] += w; }
968 ostream& operator<<(ostream& os,
const Hist& h) {
971 if (h.nFill <= 0)
return os;
976 strftime(date,18,
"%Y-%m-%d %H:%M",localtime(&t));
977 os <<
"\n\n " << date <<
" " << h.titleSave <<
"\n\n";
981 int nGroup = 1 + (h.nBin - 1) / Hist::NCOLMAX;
982 int nCol = 1 + (h.nBin - 1) / nGroup;
983 vector<double> resCol(nCol);
984 for (
int iCol = 0; iCol < nCol; ++iCol) {
986 for (
int ix = nGroup * iCol; ix < min( h.nBin, nGroup * (iCol + 1)); ++ix)
987 resCol[iCol] += h.res[ix];
988 resCol[iCol] = max( -Hist::LARGE, min( Hist::LARGE, resCol[iCol] ) );
992 double yMin = resCol[0];
993 double yMax = resCol[0];
994 for (
int iCol = 1; iCol < nCol; ++iCol) {
995 if (resCol[iCol] < yMin) yMin = resCol[iCol];
996 if (resCol[iCol] > yMax) yMax = resCol[iCol];
1000 if (yMax - yMin > Hist::NLINES * DYAC[0] * 1e-9) {
1001 if (yMin > 0. && yMin < Hist::SMALLFRAC * yMax) yMin = 0.;
1002 if (yMax < 0. && yMax > Hist::SMALLFRAC * yMin) yMax = 0.;
1003 int iPowY = int(floor( log10(yMax - yMin) ));
1004 if (yMax - yMin < Hist::NLINES * DYAC[0] * pow(10.,iPowY))
1006 if (yMax - yMin > Hist::NLINES * DYAC[9] * pow(10.,iPowY))
1008 double nLinePow = Hist::NLINES * pow(10.,iPowY);
1009 double delY = DYAC[0];
1010 for (
int idel = 0; idel < 9; ++idel)
1011 if (yMax - yMin >= nLinePow * DYAC[idel]) delY = DYAC[idel+1];
1012 double dy = delY * pow(10.,iPowY);
1015 vector<int> row(nCol);
1016 vector<int> frac(nCol);
1017 for (
int iCol = 0; iCol < nCol ; ++iCol) {
1018 double cta = abs(resCol[iCol]) / dy;
1019 row[iCol] = int(cta + 0.95);
1020 if(resCol[iCol] < 0.) row[iCol] = - row[iCol];
1021 frac[iCol] = int(10. * (cta + 1.05 - floor(cta + 0.95)));
1023 int rowMin = int(abs(yMin)/dy + 0.95);
1024 if ( yMin < 0) rowMin = - rowMin;
1025 int rowMax = int(abs(yMax)/dy + 0.95);
1026 if ( yMax < 0) rowMax = - rowMax;
1029 os << fixed << setprecision(2);
1030 for (
int iRow = rowMax; iRow >= rowMin; iRow--)
if (iRow != 0) {
1031 os <<
" " << setw(10) << iRow*delY <<
"*10^"
1032 << setw(2) << iPowY <<
" ";
1033 for (
int iCol = 0; iCol < nCol ; ++iCol) {
1034 if (iRow == row[iCol]) os << NUMBER[frac[iCol]];
1035 else if (iRow * (row[iCol] - iRow) > 0) os << NUMBER[10];
1041 double maxim = log10(max(yMax, -yMin));
1042 int iPowBin = int(floor(maxim + 0.0001));
1044 for (
int iCol = 0; iCol < nCol ; ++iCol) {
1045 if (resCol[iCol] < - pow(10., iPowBin - 4)) os <<
"-";
1047 row[iCol] = int(abs(resCol[iCol]) * pow(10., 3 - iPowBin) + 0.5);
1049 for (
int iRow = 3; iRow >= 0; iRow--) {
1050 os <<
" *10^" << setw(2) << iPowBin + iRow - 3 <<
" ";
1051 int mask = int( pow(10., iRow) + 0.5);
1052 for (
int iCol = 0; iCol < nCol ; ++iCol) {
1053 os << NUMBER[(row[iCol] / mask) % 10];
1058 maxim = (h.linX) ? log10( max( -h.xMin, h.xMax - h.dx))
1059 : log10( max( -log10(h.xMin), log10(h.xMax) - h.dx ) );
1060 int iPowExp = int(floor(maxim + 0.0001));
1062 for (
int iCol = 0; iCol < nCol ; ++iCol) {
1063 double edgeNow = (h.linX) ? h.xMin + iCol * nGroup * h.dx
1064 : log10(h.xMin) + iCol * nGroup * h.dx;
1065 os << ( ( edgeNow < - pow(10., iPowExp - 3) ) ?
"-" :
" " );
1066 row[iCol] = int( abs(edgeNow) * pow(10., 2 - iPowExp) + 0.5 );
1068 for (
int iRow = 2; iRow >= 0; iRow--) {
1069 os <<
" *10^" << setw(2) << iPowExp + iRow - 2 <<
" ";
1070 int mask = int( pow(10., iRow) + 0.5);
1071 for (
int iCol = 0; iCol < nCol ; ++iCol)
1072 os << NUMBER[(row[iCol] / mask) % 10];
1077 }
else os <<
" Histogram not shown since lowest value" << scientific
1078 << setprecision(4) << setw(12) << yMin <<
" and highest value"
1079 << setw(12) << yMax <<
" are too close \n \n";
1085 for (
int ix = 0; ix < h.nBin ; ++ix) {
1086 double cta = abs(h.res[ix]);
1087 double x = (h.linX) ? h.xMin + (ix + 0.5) * h.dx
1088 : h.xMin * pow( 10., (ix + 0.5) * h.dx);
1090 cxSum = cxSum + cta * x;
1091 cxxSum = cxxSum + cta * x * x;
1093 double xmean = cxSum / max(cSum, Hist::TINY);
1094 double rms = sqrtpos( cxxSum / max(cSum, Hist::TINY) - xmean*xmean );
1095 os << scientific << setprecision(4)
1096 <<
" Entries =" << setw(12) << h.nFill
1097 <<
" Mean =" << setw(12) << xmean
1098 <<
" Underflow =" << setw(12) << h.under
1099 <<
" Low edge =" << setw(12) << h.xMin <<
"\n"
1100 <<
" All chan =" << setw(12) << h.inside
1101 <<
" Rms =" << setw(12) << rms
1102 <<
" Overflow =" << setw(12) << h.over
1103 <<
" High edge =" << setw(12) << h.xMax << endl;
1111 void Hist::table(ostream& os,
bool printOverUnder,
bool xMidBin)
const {
1114 os << scientific << setprecision(4);
1115 double xBeg = (xMidBin) ? xMin + 0.5 * dx : xMin;
1116 if (!linX && xMidBin) xBeg = xMin * pow( 10., 0.5 * dx);
1118 os << setw(12) << (linX ? xBeg - dx : xBeg * pow(10., -dx))
1119 << setw(12) << under <<
"\n";
1120 for (
int ix = 0; ix < nBin; ++ix)
1121 os << setw(12) << (linX ? xBeg + ix * dx : xBeg * pow(10., ix * dx))
1122 << setw(12) << res[ix] <<
"\n";
1124 os << setw(12) << (linX ? xBeg + nBin * dx : xBeg * pow(10., nBin * dx))
1125 << setw(12) << over <<
"\n";
1133 void Hist::rivetTable(ostream& os,
bool printError)
const {
1137 os << scientific << setprecision(4);
1139 double xEnd = (linX) ? xMin + dx : xMin * pow(10., dx);
1140 for (
int ix = 0; ix < nBin; ++ix) {
1141 double err = (printError) ? sqrtpos(res[ix]) : 0.0;
1142 os << setw(12) << (linX ? xBeg + ix * dx : xBeg * pow(10., ix * dx))
1143 << setw(12) << (linX ? xEnd + ix * dx : xEnd * pow(10., ix * dx))
1144 << setw(12) << res[ix] << setw(12) << err << setw(12) << err <<
"\n";
1153 void Hist::pyplotTable(ostream& os,
bool isHist)
const {
1156 os << scientific << setprecision(4);
1159 double xBeg = (linX) ? xMin + 0.5 * dx : xMin * pow( 10., 0.5 * dx);
1161 for (
int ix = 0; ix < nBin; ++ix) {
1162 xNow = (linX) ? xBeg + ix * dx : xBeg * pow(10., ix * dx);
1163 xEdge = (linX) ? xMin + ix * dx : xMin * pow(10., ix * dx);
1164 os << setw(12) << xNow << setw(12) << res[ix];
1165 if (isHist) os << setw(12) << xEdge <<
"\n";
1171 double xEnd = (linX) ? xMax - 0.5 * dx : xMax * pow( 10., -0.5 * dx);
1172 os << setw(12) << xEnd << setw(12) << 0. << setw(12) << xMax <<
"\n";
1181 void table(
const Hist& h1,
const Hist& h2, ostream& os,
bool printOverUnder,
1187 if (nBin != h2.nBin || abs(h1.xMin - h2.xMin) > Hist::TOLERANCE * dx
1188 || abs(h1.xMax - h2.xMax) > Hist::TOLERANCE * dx || h1.linX != h2.linX)
1192 os << scientific << setprecision(4);
1193 double xBeg = (xMidBin) ? h1.xMin + 0.5 * dx : h1.xMin;
1194 if (!h1.linX && xMidBin) xBeg = h1.xMin * pow(10., 0.5 * dx);
1196 os << setw(12) << (h1.linX ? xBeg - dx : xBeg * pow(10., -dx))
1197 << setw(12) << h1.under << setw(12) << h2.under <<
"\n";
1198 for (
int ix = 0; ix < nBin; ++ix)
1199 os << setw(12) << (h1.linX ? xBeg + ix * dx : xBeg * pow(10., ix * dx))
1200 << setw(12) << h1.res[ix] << setw(12) << h2.res[ix] <<
"\n";
1202 os << setw(12) << (h1.linX ? xBeg + nBin * dx : xBeg * pow(10., nBin * dx))
1203 << setw(12) << h1.over << setw(12) << h2.over <<
"\n";
1207 void table(
const Hist& h1,
const Hist& h2,
string fileName,
1208 bool printOverUnder,
bool xMidBin) {
1210 ofstream streamName(fileName.c_str());
1211 table( h1, h2, streamName, printOverUnder, xMidBin);
1221 double Hist::getBinContent(
int iBin)
const {
1223 if (iBin > 0 && iBin <= nBin)
return res[iBin - 1];
1224 else if (iBin == 0)
return under;
1225 else if (iBin == nBin + 1)
return over;
1234 bool Hist::sameSize(
const Hist& h)
const {
1236 if (nBin == h.nBin && abs(xMin - h.xMin) < TOLERANCE * dx &&
1237 abs(xMax - h.xMax) < TOLERANCE * dx)
return true;
1246 void Hist::takeLog(
bool tenLog) {
1249 double yMin = Hist::LARGE;
1250 for (
int ix = 0; ix < nBin; ++ix)
1251 if (res[ix] > Hist::TINY && res[ix] < yMin ) yMin = res[ix];
1256 for (
int ix = 0; ix < nBin; ++ix)
1257 res[ix] = log10( max( yMin, res[ix]) );
1258 under = log10( max( yMin, under) );
1259 inside = log10( max( yMin, inside) );
1260 over = log10( max( yMin, over) );
1264 for (
int ix = 0; ix < nBin; ++ix)
1265 res[ix] = log( max( yMin, res[ix]) );
1266 under = log( max( yMin, under) );
1267 inside = log( max( yMin, inside) );
1268 over = log( max( yMin, over) );
1277 void Hist::takeSqrt() {
1279 for (
int ix = 0; ix < nBin; ++ix) res[ix] = sqrtpos(res[ix]);
1280 under = sqrtpos(under);
1281 inside = sqrtpos(inside);
1282 over = sqrtpos(over);
1290 double Hist::smallestAbsValue()
const {
1292 double smallest = 1e20;
double yAbs;
1293 for (
int ix = 0; ix < nBin; ++ix) { yAbs = abs(res[ix]);
1294 if (yAbs > 1e-20 && yAbs < smallest) smallest = yAbs; }
1303 Hist& Hist::operator+=(
const Hist& h) {
1304 if (!sameSize(h))
return *
this;
1309 for (
int ix = 0; ix < nBin; ++ix) res[ix] += h.res[ix];
1317 Hist& Hist::operator-=(
const Hist& h) {
1318 if (!sameSize(h))
return *
this;
1323 for (
int ix = 0; ix < nBin; ++ix) res[ix] -= h.res[ix];
1331 Hist& Hist::operator*=(
const Hist& h) {
1332 if (!sameSize(h))
return *
this;
1337 for (
int ix = 0; ix < nBin; ++ix) res[ix] *= h.res[ix];
1345 Hist& Hist::operator/=(
const Hist& h) {
1346 if (!sameSize(h))
return *
this;
1348 under = (abs(h.under) < Hist::TINY) ? 0. : under/h.under;
1349 inside = (abs(h.inside) < Hist::TINY) ? 0. : inside/h.inside;
1350 over = (abs(h.over) < Hist::TINY) ? 0. : over/h.over;
1351 for (
int ix = 0; ix < nBin; ++ix)
1352 res[ix] = (abs(h.res[ix]) < Hist::TINY) ? 0. : res[ix]/h.res[ix];
1360 Hist& Hist::operator+=(
double f) {
1364 for (
int ix = 0; ix < nBin; ++ix) res[ix] += f;
1372 Hist& Hist::operator-=(
double f) {
1376 for (
int ix = 0; ix < nBin; ++ix) res[ix] -= f;
1384 Hist& Hist::operator*=(
double f) {
1388 for (
int ix = 0; ix < nBin; ++ix) res[ix] *= f;
1396 Hist& Hist::operator/=(
double f) {
1397 if (abs(f) > Hist::TINY) {
1401 for (
int ix = 0; ix < nBin; ++ix) res[ix] /= f;
1407 for (
int ix = 0; ix < nBin; ++ix) res[ix] = 0.;
1412 Hist Hist::operator+(
double f)
const {
1413 Hist h = *
this;
return h += f;}
1415 Hist Hist::operator+(
const Hist& h2)
const {
1416 Hist h = *
this;
return h += h2;}
1418 Hist Hist::operator-(
double f)
const {
1419 Hist h = *
this;
return h -= f;}
1421 Hist Hist::operator-(
const Hist& h2)
const {
1422 Hist h = *
this;
return h -= h2;}
1424 Hist Hist::operator*(
double f)
const {
1425 Hist h = *
this;
return h *= f;}
1427 Hist Hist::operator*(
const Hist& h2)
const {
1428 Hist h = *
this;
return h *= h2;}
1430 Hist Hist::operator/(
double f)
const {
1431 Hist h = *
this;
return h /= f;}
1433 Hist Hist::operator/(
const Hist& h2)
const {
1434 Hist h = *
this;
return h /= h2;}
1440 Hist operator+(
double f,
const Hist& h1) {
1441 Hist h = h1;
return h += f;}
1443 Hist operator-(
double f,
const Hist& h1) {
1445 h.under = f - h1.under;
1446 h.inside = h1.nBin * f - h1.inside;
1447 h.over = f - h1.over;
1448 for (
int ix = 0; ix < h1.nBin; ++ix) h.res[ix] = f - h1.res[ix];
1451 Hist operator*(
double f,
const Hist& h1) {
1452 Hist h = h1;
return h *= f;}
1454 Hist operator/(
double f,
const Hist& h1) {
1456 h.under = (abs(h1.under) < Hist::TINY) ? 0. : f/h1.under;
1457 h.inside = (abs(h1.inside) < Hist::TINY) ? 0. : f/h1.inside;
1458 h.over = (abs(h1.over) < Hist::TINY) ? 0. : f/h1.over;
1459 for (
int ix = 0; ix < h1.nBin; ++ix)
1460 h.res[ix] = (abs(h1.res[ix]) < Hist::TINY) ? 0. : f/h1.res[ix];
1473 void HistPlot::plot(
bool logY) {
1476 if (frameName !=
"") {
1477 if (nPDF > 0) toPython <<
"pp.close()" << endl;
1479 fileName = frameName;
1480 toPython <<
"pp = PdfPages('" << fileName <<
".pdf')" << endl;
1486 toPython <<
"tmp" << nFrame <<
" = plt.figure(" << nFrame <<
")" << endl;
1489 double yAbsMin = 1e20;
1490 for (
int iHist = 0; iHist < int(histos.size()); ++iHist) {
1493 string legendNow = (legends[iHist] !=
"void") ? legends[iHist]
1494 : histos[iHist]->getTitle();
1496 nBin << histos[iHist]->getBinNumber();
1497 double yAbsNow = histos[iHist]->smallestAbsValue();
1498 if (yAbsNow < yAbsMin) yAbsMin = yAbsNow;
1501 string styleNow = (styles[iHist] ==
"") ?
"h" : styles[iHist];
1502 string style1 = styleNow;
1504 if (styleNow.find(
",") != string::npos) {
1505 int iComma = styleNow.find(
",");
1506 style1 = (iComma > 0) ? styleNow.substr( 0, iComma) :
"h";
1507 if (iComma + 1 <
int(styleNow.length()))
1508 style2 = styleNow.substr( iComma + 1);
1512 stringstream encode;
1513 encode << fileName <<
"-" << nTable + iHist <<
".dat";
1514 histos[iHist]->pyplotTable( encode.str(), (style1 ==
"h") );
1517 toPython <<
"plot = open('" << encode.str() <<
"')" << endl
1518 <<
"plot = [line.split() for line in plot]" << endl
1519 <<
"valx = [float(x[0]) for x in plot]" << endl
1520 <<
"valy = [float(x[1]) for x in plot]" << endl;
1521 if (style1 ==
"h") toPython <<
"vale = [float(x[2]) for x in plot]"
1522 << endl <<
"plt.hist( valx, vale, weights = valy,"
1523 <<
" histtype='step',";
1524 else toPython <<
"plt.plot( valx, valy, '" << style1 <<
"',";
1525 if (style2 !=
"") toPython <<
" color='" << style2 <<
"',";
1526 toPython <<
" label=r'" << legendNow <<
"')" << endl;
1530 if (!histos[0]->getLinX()) toPython <<
"plt.xscale('log')" << endl;
1531 if (logY) toPython <<
"plt.yscale('symlog', linthreshy=" << scientific
1532 << setprecision(2) << yAbsMin <<
")" << endl;
1533 else toPython <<
"plt.ticklabel_format(axis='y', style='sci', "
1534 <<
"scilimits=(-2,3))" << endl;
1535 toPython <<
"plt.legend(frameon=False,loc='best')" << endl
1536 <<
"plt.title(r'" << title <<
"')" << endl
1537 <<
"plt.xlabel(r'" << xLabel <<
"')" << endl
1538 <<
"plt.ylabel(r\'" << yLabel <<
"')" << endl
1539 <<
"pp.savefig(tmp" << nFrame <<
",bbox_inches='tight')"
1540 << endl <<
"plt.clf()" << endl;
1543 nTable += histos.size();