9 #include "Pythia8/Basics.h"
28 const int Rndm::DEFAULTSEED = 19780503;
34 bool Rndm::rndmEnginePtr( RndmEngine* rndmEngPtrIn) {
37 if (rndmEngPtrIn == 0)
return false;
38 rndmEngPtr = rndmEngPtrIn;
39 useExternalRndm =
true;
50 void Rndm::init(
int seedIn) {
54 if (seedIn < 0) seed = DEFAULTSEED;
55 else if (seedIn == 0) seed = int(time(0));
56 if (seed < 0) seed = -seed;
59 int ij = (seed/30082) % 31329;
60 int kl = seed % 30082;
61 int i = (ij/177) % 177 + 2;
63 int k = (kl/169) % 178 + 1;
67 for (
int ii = 0; ii < 97; ++ii) {
70 for (
int jj = 0; jj < 48; ++jj) {
71 int m = (( (i*j)%179 )*k) % 179;
76 if ( (l*m) % 64 >= 32) s += t;
84 for (
int i24 = 0; i24 < 24; ++i24) twom24 *= 0.5;
86 cd = 7654321. * twom24;
87 cm = 16777213. * twom24;
102 double Rndm::flat() {
105 if (useExternalRndm)
return rndmEngPtr->flat();
108 if (!initRndm) init(DEFAULTSEED);
114 uni = u[i97] - u[j97];
115 if (uni < 0.) uni += 1.;
117 if (--i97 < 0) i97 = 96;
118 if (--j97 < 0) j97 = 96;
122 if(uni < 0.) uni += 1.;
123 }
while (uni <= 0. || uni >= 1.);
132 int Rndm::pick(
const vector<double>& prob) {
135 for (
int i = 0; i < int(prob.size()); ++i) work += prob[i];
138 do work -= prob[++index];
139 while (work > 0. && index <
int(prob.size()));
148 bool Rndm::dumpState(
string fileName) {
151 const char* fn = fileName.c_str();
152 ofstream ofs(fn, ios::binary);
155 cout <<
" Rndm::dumpState: could not open output file" << endl;
160 ofs.write((
char *) &seedSave,
sizeof(
int));
161 ofs.write((
char *) &sequence,
sizeof(
long));
162 ofs.write((
char *) &i97,
sizeof(
int));
163 ofs.write((
char *) &j97,
sizeof(
int));
164 ofs.write((
char *) &c,
sizeof(
double));
165 ofs.write((
char *) &cd,
sizeof(
double));
166 ofs.write((
char *) &cm,
sizeof(
double));
167 ofs.write((
char *) &u,
sizeof(
double) * 97);
170 cout <<
" PYTHIA Rndm::dumpState: seed = " << seedSave
171 <<
", sequence no = " << sequence << endl;
180 bool Rndm::readState(
string fileName) {
183 const char* fn = fileName.c_str();
184 ifstream ifs(fn, ios::binary);
187 cout <<
" Rndm::readState: could not open input file" << endl;
192 ifs.read((
char *) &seedSave,
sizeof(
int));
193 ifs.read((
char *) &sequence,
sizeof(
long));
194 ifs.read((
char *) &i97,
sizeof(
int));
195 ifs.read((
char *) &j97,
sizeof(
int));
196 ifs.read((
char *) &c,
sizeof(
double));
197 ifs.read((
char *) &cd,
sizeof(
double));
198 ifs.read((
char *) &cm,
sizeof(
double));
199 ifs.read((
char *) &u,
sizeof(
double) *97);
202 cout <<
" PYTHIA Rndm::readState: seed " << seedSave
203 <<
", sequence no = " << sequence << endl;
220 const double Vec4::TINY = 1e-20;
226 void Vec4::rot(
double thetaIn,
double phiIn) {
228 double cthe = cos(thetaIn);
229 double sthe = sin(thetaIn);
230 double cphi = cos(phiIn);
231 double sphi = sin(phiIn);
232 double tmpx = cthe * cphi * xx - sphi * yy + sthe * cphi * zz;
233 double tmpy = cthe * sphi * xx + cphi * yy + sthe * sphi * zz;
234 double tmpz = -sthe * xx + cthe * zz;
245 void Vec4::rotaxis(
double phiIn,
double nx,
double ny,
double nz) {
247 double norm = 1./sqrt(nx*nx + ny*ny + nz*nz);
251 double cphi = cos(phiIn);
252 double sphi = sin(phiIn);
253 double comb = (nx * xx + ny * yy + nz * zz) * (1. - cphi);
254 double tmpx = cphi * xx + comb * nx + sphi * (ny * zz - nz * yy);
255 double tmpy = cphi * yy + comb * ny + sphi * (nz * xx - nx * zz);
256 double tmpz = cphi * zz + comb * nz + sphi * (nx * yy - ny * xx);
267 void Vec4::rotaxis(
double phiIn,
const Vec4& n) {
272 double norm = 1./sqrt(nx*nx + ny*ny + nz*nz);
276 double cphi = cos(phiIn);
277 double sphi = sin(phiIn);
278 double comb = (nx * xx + ny * yy + nz * zz) * (1. - cphi);
279 double tmpx = cphi * xx + comb * nx + sphi * (ny * zz - nz * yy);
280 double tmpy = cphi * yy + comb * ny + sphi * (nz * xx - nx * zz);
281 double tmpz = cphi * zz + comb * nz + sphi * (nx * yy - ny * xx);
292 void Vec4::bst(
double betaX,
double betaY,
double betaZ) {
294 double beta2 = betaX*betaX + betaY*betaY + betaZ*betaZ;
295 double gamma = 1. / sqrt(1. - beta2);
296 double prod1 = betaX * xx + betaY * yy + betaZ * zz;
297 double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
301 tt = gamma * (tt + prod1);
309 void Vec4::bst(
double betaX,
double betaY,
double betaZ,
double gamma) {
311 double prod1 = betaX * xx + betaY * yy + betaZ * zz;
312 double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
316 tt = gamma * (tt + prod1);
324 void Vec4::bst(
const Vec4& pIn) {
326 double betaX = pIn.xx / pIn.tt;
327 double betaY = pIn.yy / pIn.tt;
328 double betaZ = pIn.zz / pIn.tt;
329 double beta2 = betaX*betaX + betaY*betaY + betaZ*betaZ;
330 double gamma = 1. / sqrt(1. - beta2);
331 double prod1 = betaX * xx + betaY * yy + betaZ * zz;
332 double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
336 tt = gamma * (tt + prod1);
344 void Vec4::bst(
const Vec4& pIn,
double mIn) {
346 double betaX = pIn.xx / pIn.tt;
347 double betaY = pIn.yy / pIn.tt;
348 double betaZ = pIn.zz / pIn.tt;
349 double gamma = pIn.tt / mIn;
350 double prod1 = betaX * xx + betaY * yy + betaZ * zz;
351 double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
355 tt = gamma * (tt + prod1);
363 void Vec4::bstback(
const Vec4& pIn) {
365 double betaX = -pIn.xx / pIn.tt;
366 double betaY = -pIn.yy / pIn.tt;
367 double betaZ = -pIn.zz / pIn.tt;
368 double beta2 = betaX*betaX + betaY*betaY + betaZ*betaZ;
369 double gamma = 1. / sqrt(1. - beta2);
370 double prod1 = betaX * xx + betaY * yy + betaZ * zz;
371 double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
375 tt = gamma * (tt + prod1);
383 void Vec4::bstback(
const Vec4& pIn,
double mIn) {
385 double betaX = -pIn.xx / pIn.tt;
386 double betaY = -pIn.yy / pIn.tt;
387 double betaZ = -pIn.zz / pIn.tt;
388 double gamma = pIn.tt / mIn;
389 double prod1 = betaX * xx + betaY * yy + betaZ * zz;
390 double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
394 tt = gamma * (tt + prod1);
402 void Vec4::rotbst(
const RotBstMatrix& M) {
404 double x = xx;
double y = yy;
double z = zz;
double t = tt;
405 tt = M.M[0][0] * t + M.M[0][1] * x + M.M[0][2] * y + M.M[0][3] * z;
406 xx = M.M[1][0] * t + M.M[1][1] * x + M.M[1][2] * y + M.M[1][3] * z;
407 yy = M.M[2][0] * t + M.M[2][1] * x + M.M[2][2] * y + M.M[2][3] * z;
408 zz = M.M[3][0] * t + M.M[3][1] * x + M.M[3][2] * y + M.M[3][3] * z;
416 double m(
const Vec4& v1,
const Vec4& v2) {
417 double m2 = pow2(v1.tt + v2.tt) - pow2(v1.xx + v2.xx)
418 - pow2(v1.yy + v2.yy) - pow2(v1.zz + v2.zz);
419 return (m2 > 0.) ? sqrt(m2) : 0.;
426 double m2(
const Vec4& v1,
const Vec4& v2) {
427 double m2 = pow2(v1.tt + v2.tt) - pow2(v1.xx + v2.xx)
428 - pow2(v1.yy + v2.yy) - pow2(v1.zz + v2.zz);
436 double dot3(
const Vec4& v1,
const Vec4& v2) {
437 return v1.xx*v2.xx + v1.yy*v2.yy + v1.zz*v2.zz;
444 Vec4 cross3(
const Vec4& v1,
const Vec4& v2) {
446 v.xx = v1.yy * v2.zz - v1.zz * v2.yy;
447 v.yy = v1.zz * v2.xx - v1.xx * v2.zz;
448 v.zz = v1.xx * v2.yy - v1.yy * v2.xx;
return v;
455 double theta(
const Vec4& v1,
const Vec4& v2) {
456 double cthe = (v1.xx * v2.xx + v1.yy * v2.yy + v1.zz * v2.zz)
457 / sqrt( (v1.xx*v1.xx + v1.yy*v1.yy + v1.zz*v1.zz)
458 * (v2.xx*v2.xx + v2.yy*v2.yy + v2.zz*v2.zz) );
459 cthe = max(-1., min(1., cthe));
467 double costheta(
const Vec4& v1,
const Vec4& v2) {
468 double cthe = (v1.xx * v2.xx + v1.yy * v2.yy + v1.zz * v2.zz)
469 / sqrt( (v1.xx*v1.xx + v1.yy*v1.yy + v1.zz*v1.zz)
470 * (v2.xx*v2.xx + v2.yy*v2.yy + v2.zz*v2.zz) );
471 cthe = max(-1., min(1., cthe));
479 double phi(
const Vec4& v1,
const Vec4& v2) {
480 double cphi = (v1.xx * v2.xx + v1.yy * v2.yy) / sqrt( max( Vec4::TINY,
481 (v1.xx*v1.xx + v1.yy*v1.yy) * (v2.xx*v2.xx + v2.yy*v2.yy) ));
482 cphi = max(-1., min(1., cphi));
490 double cosphi(
const Vec4& v1,
const Vec4& v2) {
491 double cphi = (v1.xx * v2.xx + v1.yy * v2.yy) / sqrt( max( Vec4::TINY,
492 (v1.xx*v1.xx + v1.yy*v1.yy) * (v2.xx*v2.xx + v2.yy*v2.yy) ));
493 cphi = max(-1., min(1., cphi));
501 double phi(
const Vec4& v1,
const Vec4& v2,
const Vec4& n) {
502 double nx = n.xx;
double ny = n.yy;
double nz = n.zz;
503 double norm = 1. / sqrt(nx*nx + ny*ny + nz*nz);
504 nx *= norm; ny *=norm; nz *=norm;
505 double v1s = v1.xx * v1.xx + v1.yy * v1.yy + v1.zz * v1.zz;
506 double v2s = v2.xx * v2.xx + v2.yy * v2.yy + v2.zz * v2.zz;
507 double v1v2 = v1.xx * v2.xx + v1.yy * v2.yy + v1.zz * v2.zz;
508 double v1n = v1.xx * nx + v1.yy * ny + v1.zz * nz;
509 double v2n = v2.xx * nx + v2.yy * ny + v2.zz * nz;
510 double cphi = (v1v2 - v1n * v2n) / sqrt( max( Vec4::TINY,
511 (v1s - v1n*v1n) * (v2s - v2n*v2n) ));
512 cphi = max(-1., min(1., cphi));
520 double cosphi(
const Vec4& v1,
const Vec4& v2,
const Vec4& n) {
521 double nx = n.xx;
double ny = n.yy;
double nz = n.zz;
522 double norm = 1. / sqrt(nx*nx + ny*ny + nz*nz);
523 nx *= norm; ny *=norm; nz *=norm;
524 double v1s = v1.xx * v1.xx + v1.yy * v1.yy + v1.zz * v1.zz;
525 double v2s = v2.xx * v2.xx + v2.yy * v2.yy + v2.zz * v2.zz;
526 double v1v2 = v1.xx * v2.xx + v1.yy * v2.yy + v1.zz * v2.zz;
527 double v1n = v1.xx * nx + v1.yy * ny + v1.zz * nz;
528 double v2n = v2.xx * nx + v2.yy * ny + v2.zz * nz;
529 double cphi = (v1v2 - v1n * v2n) / sqrt( max( Vec4::TINY,
530 (v1s - v1n*v1n) * (v2s - v2n*v2n) ));
531 cphi = max(-1., min(1., cphi));
539 double RRapPhi(
const Vec4& v1,
const Vec4& v2) {
540 double dRap = abs(v1.rap() - v2.rap());
541 double dPhi = abs(v1.phi() - v2.phi());
542 if (dPhi > M_PI) dPhi = 2. * M_PI - dPhi;
543 return sqrt(dRap*dRap + dPhi*dPhi);
550 double REtaPhi(
const Vec4& v1,
const Vec4& v2) {
551 double dEta = abs(v1.eta() - v2.eta());
552 double dPhi = abs(v1.phi() - v2.phi());
553 if (dPhi > M_PI) dPhi = 2. * M_PI - dPhi;
554 return sqrt(dEta*dEta + dPhi*dPhi);
561 ostream& operator<<(ostream& os,
const Vec4& v) {
562 os << fixed << setprecision(3) <<
" " << setw(9) << v.xx <<
" "
563 << setw(9) << v.yy <<
" " << setw(9) << v.zz <<
" " << setw(9)
564 << v.tt <<
" (" << setw(9) << v.mCalc() <<
")\n";
580 const double RotBstMatrix::TINY = 1e-20;
586 void RotBstMatrix::rot(
double theta,
double phi) {
589 double cthe = cos(theta);
590 double sthe = sin(theta);
591 double cphi = cos(phi);
592 double sphi = sin(phi);
593 double Mrot[4][4] = {
595 {0., cthe * cphi, - sphi, sthe * cphi},
596 {0., cthe * sphi, cphi, sthe * sphi},
597 {0., -sthe, 0., cthe } };
601 for (
int i = 0; i < 4; ++i)
602 for (
int j = 0; j < 4; ++j)
603 Mtmp[i][j] = M[i][j];
604 for (
int i = 0; i < 4; ++i)
605 for (
int j = 0; j < 4; ++j)
606 M[i][j] = Mrot[i][0] * Mtmp[0][j] + Mrot[i][1] * Mtmp[1][j]
607 + Mrot[i][2] * Mtmp[2][j] + Mrot[i][3] * Mtmp[3][j];
615 void RotBstMatrix::rot(
const Vec4& p) {
617 double theta = p.theta();
618 double phi = p.phi();
628 void RotBstMatrix::bst(
double betaX,
double betaY,
double betaZ) {
631 double gm = 1. / sqrt( max( TINY, 1. - betaX*betaX - betaY*betaY
633 double gf = gm*gm / (1. + gm);
634 double Mbst[4][4] = {
635 { gm, gm*betaX, gm*betaY, gm*betaZ },
636 { gm*betaX, 1. + gf*betaX*betaX, gf*betaX*betaY, gf*betaX*betaZ },
637 { gm*betaY, gf*betaY*betaX, 1. + gf*betaY*betaY, gf*betaY*betaZ },
638 { gm*betaZ, gf*betaZ*betaX, gf*betaZ*betaY, 1. + gf*betaZ*betaZ } };
642 for (
int i = 0; i < 4; ++i)
643 for (
int j = 0; j < 4; ++j)
644 Mtmp[i][j] = M[i][j];
645 for (
int i = 0; i < 4; ++i)
646 for (
int j = 0; j < 4; ++j)
647 M[i][j] = Mbst[i][0] * Mtmp[0][j] + Mbst[i][1] * Mtmp[1][j]
648 + Mbst[i][2] * Mtmp[2][j] + Mbst[i][3] * Mtmp[3][j];
656 void RotBstMatrix::bst(
const Vec4& p) {
657 double betaX = p.px() / p.e();
658 double betaY = p.py() / p.e();
659 double betaZ = p.pz() / p.e();
660 bst(betaX, betaY, betaZ);
667 void RotBstMatrix::bstback(
const Vec4& p) {
668 double betaX = -p.px() / p.e();
669 double betaY = -p.py() / p.e();
670 double betaZ = -p.pz() / p.e();
671 bst(betaX, betaY, betaZ);
678 void RotBstMatrix::bst(
const Vec4& p1,
const Vec4& p2) {
679 double eSum = p1.e() + p2.e();
680 double betaX = (p2.px() - p1.px()) / eSum;
681 double betaY = (p2.py() - p1.py()) / eSum;
682 double betaZ = (p2.pz() - p1.pz()) / eSum;
683 double fac = 2. / (1. + betaX*betaX + betaY*betaY + betaZ*betaZ);
684 betaX *= fac; betaY *= fac; betaZ *= fac;
685 bst(betaX, betaY, betaZ);
693 void RotBstMatrix::toCMframe(
const Vec4& p1,
const Vec4& p2) {
697 double theta = dir.theta();
698 double phi = dir.phi();
709 void RotBstMatrix::fromCMframe(
const Vec4& p1,
const Vec4& p2) {
713 double theta = dir.theta();
714 double phi = dir.phi();
724 void RotBstMatrix::rotbst(
const RotBstMatrix& Mrb) {
726 for (
int i = 0; i < 4; ++i)
727 for (
int j = 0; j < 4; ++j)
728 Mtmp[i][j] = M[i][j];
729 for (
int i = 0; i < 4; ++i)
730 for (
int j = 0; j < 4; ++j)
731 M[i][j] = Mrb.M[i][0] * Mtmp[0][j] + Mrb.M[i][1] * Mtmp[1][j]
732 + Mrb.M[i][2] * Mtmp[2][j] + Mrb.M[i][3] * Mtmp[3][j];
739 void RotBstMatrix::invert() {
741 for (
int i = 0; i < 4; ++i)
742 for (
int j = 0; j < 4; ++j)
743 Mtmp[i][j] = M[i][j];
744 for (
int i = 0; i < 4; ++i)
745 for (
int j = 0; j < 4; ++j)
746 M[i][j] = ( (i == 0 && j > 0) || (i > 0 && j == 0) )
747 ? - Mtmp[j][i] : Mtmp[j][i];
754 void RotBstMatrix::reset() {
755 for (
int i = 0; i < 4; ++i)
756 for (
int j = 0; j < 4; ++j)
757 M[i][j] = (i==j) ? 1. : 0.;
764 double RotBstMatrix::deviation()
const {
766 for (
int i = 0; i < 4; ++i)
767 for (
int j = 0; j < 4; ++j)
768 devSum += (i==j) ? abs(M[i][j] - 1.) : abs(M[i][j]);
776 ostream& operator<<(ostream& os,
const RotBstMatrix& M) {
777 os << fixed << setprecision(5) <<
" Rotation/boost matrix: \n";
778 for (
int i = 0; i <4; ++i)
779 os << setw(10) << M.M[i][0] << setw(10) << M.M[i][1]
780 << setw(10) << M.M[i][2] << setw(10) << M.M[i][3] <<
"\n";
796 const int Hist::NBINMAX = 1000;
799 const int Hist::NCOLMAX = 100;
802 const int Hist::NLINES = 30;
805 const double Hist::TOLERANCE = 0.001;
808 const double Hist::TINY = 1e-20;
809 const double Hist::LARGE = 1e20;
812 const double Hist::SMALLFRAC = 0.1;
815 const double DYAC[] = {0.04, 0.05, 0.06, 0.08, 0.10,
816 0.12, 0.15, 0.20, 0.25, 0.30};
817 const char NUMBER[] = {
'0',
'1',
'2',
'3',
'4',
'5',
818 '6',
'7',
'8',
'9',
'X' };
824 void Hist::book(
string titleIn,
int nBinIn,
double xMinIn,
829 if (nBinIn < 1) nBin = 1;
830 if (nBinIn > NBINMAX) nBin = NBINMAX;
833 dx = (xMax - xMin)/nBin;
849 for (
int ix = 0; ix < nBin; ++ix) res[ix] = 0.;
857 void Hist::fill(
double x,
double w) {
860 int iBin = int(floor((x - xMin)/dx));
861 if (iBin < 0) under += w;
862 else if (iBin >= nBin) over += w;
863 else {inside += w; res[iBin] += w; }
871 ostream& operator<<(ostream& os,
const Hist& h) {
874 if (h.nFill <= 0)
return os;
879 strftime(date,18,
"%Y-%m-%d %H:%M",localtime(&t));
880 os <<
"\n\n " << date <<
" " << h.title <<
"\n\n";
884 int nGroup = 1 + (h.nBin - 1) / Hist::NCOLMAX;
885 int nCol = 1 + (h.nBin - 1) / nGroup;
886 vector<double> resCol(nCol);
887 for (
int iCol = 0; iCol < nCol; ++iCol) {
889 for (
int ix = nGroup * iCol; ix < min( h.nBin, nGroup * (iCol + 1)); ++ix)
890 resCol[iCol] += h.res[ix];
891 resCol[iCol] = max( -Hist::LARGE, min( Hist::LARGE, resCol[iCol] ) );
895 double yMin = resCol[0];
896 double yMax = resCol[0];
897 for (
int iCol = 1; iCol < nCol; ++iCol) {
898 if (resCol[iCol] < yMin) yMin = resCol[iCol];
899 if (resCol[iCol] > yMax) yMax = resCol[iCol];
903 if (yMax - yMin > Hist::NLINES * DYAC[0] * 1e-9) {
904 if (yMin > 0. && yMin < Hist::SMALLFRAC * yMax) yMin = 0.;
905 if (yMax < 0. && yMax > Hist::SMALLFRAC * yMin) yMax = 0.;
906 int iPowY = int(floor( log10(yMax - yMin) ));
907 if (yMax - yMin < Hist::NLINES * DYAC[0] * pow(10.,iPowY))
909 if (yMax - yMin > Hist::NLINES * DYAC[9] * pow(10.,iPowY))
911 double nLinePow = Hist::NLINES * pow(10.,iPowY);
912 double delY = DYAC[0];
913 for (
int idel = 0; idel < 9; ++idel)
914 if (yMax - yMin >= nLinePow * DYAC[idel]) delY = DYAC[idel+1];
915 double dy = delY * pow(10.,iPowY);
918 vector<int> row(nCol);
919 vector<int> frac(nCol);
920 for (
int iCol = 0; iCol < nCol ; ++iCol) {
921 double cta = abs(resCol[iCol]) / dy;
922 row[iCol] = int(cta + 0.95);
923 if(resCol[iCol] < 0.) row[iCol] = - row[iCol];
924 frac[iCol] = int(10. * (cta + 1.05 - floor(cta + 0.95)));
926 int rowMin = int(abs(yMin)/dy + 0.95);
927 if ( yMin < 0) rowMin = - rowMin;
928 int rowMax = int(abs(yMax)/dy + 0.95);
929 if ( yMax < 0) rowMax = - rowMax;
932 os << fixed << setprecision(2);
933 for (
int iRow = rowMax; iRow >= rowMin; iRow--)
if (iRow != 0) {
934 os <<
" " << setw(10) << iRow*delY <<
"*10^"
935 << setw(2) << iPowY <<
" ";
936 for (
int iCol = 0; iCol < nCol ; ++iCol) {
937 if (iRow == row[iCol]) os << NUMBER[frac[iCol]];
938 else if (iRow * (row[iCol] - iRow) > 0) os << NUMBER[10];
944 double maxim = log10(max(yMax, -yMin));
945 int iPowBin = int(floor(maxim + 0.0001));
947 for (
int iCol = 0; iCol < nCol ; ++iCol) {
948 if (resCol[iCol] < - pow(10., iPowBin - 4)) os <<
"-";
950 row[iCol] = int(abs(resCol[iCol]) * pow(10., 3 - iPowBin) + 0.5);
952 for (
int iRow = 3; iRow >= 0; iRow--) {
953 os <<
" *10^" << setw(2) << iPowBin + iRow - 3 <<
" ";
954 int mask = int( pow(10., iRow) + 0.5);
955 for (
int iCol = 0; iCol < nCol ; ++iCol) {
956 os << NUMBER[(row[iCol] / mask) % 10];
961 maxim = log10( max( -h.xMin, h.xMax - h.dx));
962 int iPowExp = int(floor(maxim + 0.0001));
964 for (
int iCol = 0; iCol < nCol ; ++iCol) {
965 if (h.xMin + iCol * nGroup * h.dx < - pow(10., iPowExp - 3)) os <<
"-";
967 row[iCol] = int(abs(h.xMin + iCol * nGroup * h.dx)
968 * pow(10., 2 - iPowExp) + 0.5);
970 for (
int iRow = 2; iRow >= 0; iRow--) {
971 os <<
" *10^" << setw(2) << iPowExp + iRow - 2 <<
" ";
972 int mask = int( pow(10., iRow) + 0.5);
973 for (
int iCol = 0; iCol < nCol ; ++iCol)
974 os << NUMBER[(row[iCol] / mask) % 10];
979 }
else os <<
" Histogram not shown since lowest value" << scientific
980 << setprecision(4) << setw(12) << yMin <<
" and highest value"
981 << setw(12) << yMax <<
" are too close \n \n";
987 for (
int ix = 0; ix < h.nBin ; ++ix) {
988 double cta = abs(h.res[ix]);
989 double x = h.xMin + (ix + 0.5) * h.dx;
991 cxSum = cxSum + cta * x;
992 cxxSum = cxxSum + cta * x * x;
994 double xmean = cxSum / max(cSum, Hist::TINY);
995 double rms = sqrtpos( cxxSum / max(cSum, Hist::TINY) - xmean*xmean );
996 os << scientific << setprecision(4)
997 <<
" Entries =" << setw(12) << h.nFill
998 <<
" Mean =" << setw(12) << xmean
999 <<
" Underflow =" << setw(12) << h.under
1000 <<
" Low edge =" << setw(12) << h.xMin <<
"\n"
1001 <<
" All chan =" << setw(12) << h.inside
1002 <<
" Rms =" << setw(12) << rms
1003 <<
" Overflow =" << setw(12) << h.over
1004 <<
" High edge =" << setw(12) << h.xMax << endl;
1012 void Hist::table(ostream& os,
bool printOverUnder,
bool xMidBin)
const {
1015 os << scientific << setprecision(4);
1016 double xBeg = (xMidBin) ? xMin + 0.5 * dx : xMin;
1018 os << setw(12) << xBeg - dx << setw(12) << under <<
"\n";
1019 for (
int ix = 0; ix < nBin; ++ix)
1020 os << setw(12) << xBeg + ix * dx << setw(12) << res[ix] <<
"\n";
1022 os << setw(12) << xBeg + nBin * dx << setw(12) << over <<
"\n";
1030 void table(
const Hist& h1,
const Hist& h2, ostream& os,
bool printOverUnder,
1034 if (h1.nBin != h2.nBin || abs(h1.xMin - h2.xMin) > Hist::TOLERANCE * h1.dx
1035 || abs(h1.xMax - h2.xMax) > Hist::TOLERANCE * h1.dx)
return;
1038 os << scientific << setprecision(4);
1039 double xBeg = (xMidBin) ? h1.xMin + 0.5 * h1.dx : h1.xMin;
1041 os << setw(12) << xBeg - h1.dx << setw(12) << h1.under
1042 << setw(12) << h2.under <<
"\n";
1043 for (
int ix = 0; ix < h1.nBin; ++ix)
1044 os << setw(12) << xBeg + ix * h1.dx << setw(12) << h1.res[ix]
1045 << setw(12) << h2.res[ix] <<
"\n";
1047 os << setw(12) << xBeg + h1.nBin * h1.dx << setw(12) << h1.over
1048 << setw(12) << h2.over <<
"\n";
1052 void table(
const Hist& h1,
const Hist& h2,
string fileName,
1053 bool printOverUnder,
bool xMidBin) {
1055 ofstream streamName(fileName.c_str());
1056 table( h1, h2, streamName, printOverUnder, xMidBin);
1066 double Hist::getBinContent(
int iBin)
const {
1068 if (iBin > 0 && iBin <= nBin)
return res[iBin - 1];
1069 else if (iBin == 0)
return under;
1070 else if (iBin == nBin + 1)
return over;
1079 bool Hist::sameSize(
const Hist& h)
const {
1081 if (nBin == h.nBin && abs(xMin - h.xMin) < TOLERANCE * dx &&
1082 abs(xMax - h.xMax) < TOLERANCE * dx)
return true;
1091 void Hist::takeLog(
bool tenLog) {
1094 double yMin = Hist::LARGE;
1095 for (
int ix = 0; ix < nBin; ++ix)
1096 if (res[ix] > Hist::TINY && res[ix] < yMin ) yMin = res[ix];
1101 for (
int ix = 0; ix < nBin; ++ix)
1102 res[ix] = log10( max( yMin, res[ix]) );
1103 under = log10( max( yMin, under) );
1104 inside = log10( max( yMin, inside) );
1105 over = log10( max( yMin, over) );
1109 for (
int ix = 0; ix < nBin; ++ix)
1110 res[ix] = log( max( yMin, res[ix]) );
1111 under = log( max( yMin, under) );
1112 inside = log( max( yMin, inside) );
1113 over = log( max( yMin, over) );
1122 void Hist::takeSqrt() {
1124 for (
int ix = 0; ix < nBin; ++ix) res[ix] = sqrtpos(res[ix]);
1125 under = sqrtpos(under);
1126 inside = sqrtpos(inside);
1127 over = sqrtpos(over);
1135 Hist& Hist::operator+=(
const Hist& h) {
1136 if (!sameSize(h))
return *
this;
1141 for (
int ix = 0; ix < nBin; ++ix) res[ix] += h.res[ix];
1149 Hist& Hist::operator-=(
const Hist& h) {
1150 if (!sameSize(h))
return *
this;
1155 for (
int ix = 0; ix < nBin; ++ix) res[ix] -= h.res[ix];
1163 Hist& Hist::operator*=(
const Hist& h) {
1164 if (!sameSize(h))
return *
this;
1169 for (
int ix = 0; ix < nBin; ++ix) res[ix] *= h.res[ix];
1177 Hist& Hist::operator/=(
const Hist& h) {
1178 if (!sameSize(h))
return *
this;
1180 under = (abs(h.under) < Hist::TINY) ? 0. : under/h.under;
1181 inside = (abs(h.inside) < Hist::TINY) ? 0. : inside/h.inside;
1182 over = (abs(h.over) < Hist::TINY) ? 0. : over/h.over;
1183 for (
int ix = 0; ix < nBin; ++ix)
1184 res[ix] = (abs(h.res[ix]) < Hist::TINY) ? 0. : res[ix]/h.res[ix];
1192 Hist& Hist::operator+=(
double f) {
1196 for (
int ix = 0; ix < nBin; ++ix) res[ix] += f;
1204 Hist& Hist::operator-=(
double f) {
1208 for (
int ix = 0; ix < nBin; ++ix) res[ix] -= f;
1216 Hist& Hist::operator*=(
double f) {
1220 for (
int ix = 0; ix < nBin; ++ix) res[ix] *= f;
1228 Hist& Hist::operator/=(
double f) {
1229 if (abs(f) > Hist::TINY) {
1233 for (
int ix = 0; ix < nBin; ++ix) res[ix] /= f;
1239 for (
int ix = 0; ix < nBin; ++ix) res[ix] = 0.;
1248 Hist operator+(
double f,
const Hist& h1) {
1249 Hist h = h1;
return h += f;}
1251 Hist operator+(
const Hist& h1,
double f) {
1252 Hist h = h1;
return h += f;}
1254 Hist operator+(
const Hist& h1,
const Hist& h2) {
1255 Hist h = h1;
return h += h2;}
1257 Hist operator-(
double f,
const Hist& h1) {
1259 h.under = f - h1.under;
1260 h.inside = h1.nBin * f - h1.inside;
1261 h.over = f - h1.over;
1262 for (
int ix = 0; ix < h1.nBin; ++ix) h.res[ix] = f - h1.res[ix];
1265 Hist operator-(
const Hist& h1,
double f) {
1266 Hist h = h1;
return h -= f;}
1268 Hist operator-(
const Hist& h1,
const Hist& h2) {
1269 Hist h = h1;
return h -= h2;}
1271 Hist operator*(
double f,
const Hist& h1) {
1272 Hist h = h1;
return h *= f;}
1274 Hist operator*(
const Hist& h1,
double f) {
1275 Hist h = h1;
return h *= f;}
1277 Hist operator*(
const Hist& h1,
const Hist& h2) {
1278 Hist h = h1;
return h *= h2;}
1280 Hist operator/(
double f,
const Hist& h1) {
1282 h.under = (abs(h1.under) < Hist::TINY) ? 0. : f/h1.under;
1283 h.inside = (abs(h1.inside) < Hist::TINY) ? 0. : f/h1.inside;
1284 h.over = (abs(h1.over) < Hist::TINY) ? 0. : f/h1.over;
1285 for (
int ix = 0; ix < h1.nBin; ++ix)
1286 h.res[ix] = (abs(h1.res[ix]) < Hist::TINY) ? 0. : f/h1.res[ix];
1290 Hist operator/(
const Hist& h1,
double f) {
1291 Hist h = h1;
return h /= f;}
1293 Hist operator/(
const Hist& h1,
const Hist& h2) {
1294 Hist h = h1;
return h /= h2;}