9 #include "Pythia8/VinciaCommon.h"
22 double Rambo::genPoint(
double eCM,
int nOut, vector<Vec4>& pOut) {
29 for (
int i = 0; i < nOut; ++i) {
31 double c = 2.0*rndmPtr->flat() - 1.0;
32 double s = sqrt(1.0-pow2(c));
33 double phi = 2.0*M_PI*rndmPtr->flat();
37 double r1 = rndmPtr->flat();
38 double r2 = rndmPtr->flat();
41 double En = -log(r12);
44 pOut[i].py(En*s*cos(phi));
45 pOut[i].px(En*s*sin(phi));
50 double Rmass = R.mCalc();
53 double a = 1.0/(1.0-R.e());
55 for (
int i = 0; i < nOut; ++i) {
56 double bq = dot3(R, pOut[i]);
57 pOut[i].px( x * (pOut[i].px()+R.px()*(pOut[i].e()+a*bq)) );
58 pOut[i].py( x * (pOut[i].py()+R.py()*(pOut[i].e()+a*bq)) );
59 pOut[i].pz( x * (pOut[i].pz()+R.pz()*(pOut[i].e()+a*bq)) );
60 pOut[i].e( x * (-R.e()*pOut[i].e()+bq) );
73 double Rambo::genPoint(
double eCM, vector<double> mIn, vector<Vec4>& pOut) {
76 int nOut = mIn.size();
77 if (nOut <= 1 || eCM <= 0.)
return 0.;
78 double weight = genPoint(eCM, nOut, pOut);
79 bool massesnonzero =
false;
82 vector<double> energies;
83 for (
int i = 0; i < nOut; i++) {
84 energies.push_back(pOut[i].e());
85 if (pow2(mIn[i]/eCM) > TINY) massesnonzero =
true;
89 if (!massesnonzero)
return weight;
92 TXiFunctor rhs = TXiFunctor(mIn, energies);
93 double xi = zbrent(rhs, eCM, 0., 1., 1e-10);
94 for (
int iMom = 0; iMom < nOut; iMom++) {
95 pOut[iMom].rescale3(xi);
96 pOut[iMom].e( sqrt(pow2(mIn[iMom]) + pow2(xi)*pow2(pOut[iMom].e())) );
100 double sumP(0.), prodPdivE(1.), sumP2divE(0.);
101 for (
int iMom = 0; iMom < nOut; iMom++) {
102 double pAbs2 = pOut[iMom].pAbs2();
103 double pAbs = sqrt(pAbs2);
105 prodPdivE *= pAbs/pOut[iMom].e();
106 sumP2divE += pAbs2/pOut[iMom].e();
111 weight *= pow(sumP/eCM,2*nOut-3)*prodPdivE*eCM/sumP2divE;
123 bool Colour::init() {
126 if (!isInitPtr)
return false;
129 verbose = settingsPtr->mode(
"Vincia:verbose");
132 inheritMode = settingsPtr->mode(
"Vincia:CRinheritMode");
154 bool Colour::colourise(
int iSys,
Event& event) {
158 printOut(
"Colour::colourise",
"ERROR! Colour not initialised");
161 else if (partonSystemsPtr->sizeAll(iSys) <= 1)
return false;
164 map<int, int> colourMap;
165 int startTag =
event.lastColTag();
171 int colRes(0), acolRes(0);
172 if (partonSystemsPtr->hasInRes(iSys)) {
173 int iRes = partonSystemsPtr->getInRes(iSys);
174 colRes =
event[iRes].col();
175 acolRes =
event[iRes].acol();
179 while (!accept && ++nTries < 10) {
183 int nextTagBase = 10*int((startTag/10)+1);
184 for (
int i=0; i<partonSystemsPtr->sizeAll(iSys); ++i) {
185 int i1 = partonSystemsPtr->getAll(iSys,i);
186 if (i1 <= 0)
continue;
187 Particle* partonPtr = &
event[i1];
188 if (partonPtr->colType() == 0)
continue;
192 if (i < partonSystemsPtr->sizeAll(iSys)
193 - partonSystemsPtr->sizeOut(iSys)) {
194 acol = partonPtr->col();
195 col = partonPtr->acol();
196 if (col == acolRes) col = 0;
197 if (acol == colRes) acol = 0;
200 col = partonPtr->col();
201 acol = partonPtr->acol();
202 if (col == colRes) col = 0;
203 if (acol == acolRes) acol = 0;
205 if (col == 0 && acol == 0)
continue;
206 int colIndx = colourMap[col];
207 int acolIndx = colourMap[acol];
213 while (colIndx == 0 || colIndx == acolIndx) {
214 colIndx = nextTagBase + int(rndmPtr->flat()*9) + 1;
216 colourMap[col] = -colIndx;
219 else colourMap[col] = abs(colourMap[col]);
226 while (acolIndx == 0 || colIndx == acolIndx) {
227 acolIndx = nextTagBase + int(rndmPtr->flat()*9) + 1;
229 colourMap[acol] = -acolIndx;
232 else colourMap[acol] = abs(colourMap[acol]);
240 for (
int i=0; i<partonSystemsPtr->sizeAll(iSys); ++i) {
241 int i1 = partonSystemsPtr->getAll(iSys,i);
242 Particle* partonPtr = &
event[i1];
243 if (partonPtr->colType() != 2)
continue;
244 int colIndexNew = colourMap[partonPtr->col()] % 10;
245 int acolIndexNew = colourMap[partonPtr->acol()] % 10;
246 if (colIndexNew == acolIndexNew) {
255 if (verbose >= 3)
event.list();
256 printOut(
"Colour::colourise",
"Warning! failed to avoid singlet gluon(s).");
260 for (
int i = 0; i < partonSystemsPtr->sizeAll(iSys); ++i) {
261 int ip = partonSystemsPtr->getAll(iSys,i);
262 Particle* partonPtr = &
event[ip];
263 if (partonPtr->colType() == 0)
continue;
264 if ( colourMap[partonPtr->col()] > 0 )
265 partonPtr->col(colourMap[partonPtr->col()]);
266 if ( colourMap[partonPtr->acol()] > 0 )
267 partonPtr->acol(colourMap[partonPtr->acol()]);
270 int lastTag =
event.lastColTag();
271 int colMax = max(abs(partonPtr->col()),abs(partonPtr->acol()));
272 while (colMax > lastTag) lastTag =
event.nextColTag();
283 vector<int> Colour::colourSort(vector<Particle*> partons) {
289 int nPartons=partons.size();
290 if (nPartons <= 1)
return iSorted;
293 vector<int> iTrip, iAnti, iOct, iOtherIn, iOtherOut;
311 map<int, int> iOfAcol;
312 for (
int i=partons.size()-1; i>=0; --i) {
313 int sign = (partons[i]->isFinal() ? 1 : -1);
314 int colType = particleDataPtr->colType(partons[i]->
id());
317 if (sign == 1 && ( colType == -1 || colType == 2))
318 iOfAcol[partons[i]->acol()] = i;
319 else if (sign == -1 && ( colType == 1 || colType == 2 ))
320 iOfAcol[partons[i]->col()] = i;
323 if (colType * sign == 1) iTrip.push_back(i);
326 else if (colType * sign == -1) iAnti.push_back(i);
328 else if (colType == 2) iOct.push_back(i);
331 else if (abs(colType) >= 3) {
332 cout <<
"colourSort(): ERROR! handling of coloured particles in "
333 <<
"representations higher than triplet or octet is not implemented"
338 else if (sign == -1) iOtherIn.push_back(i);
339 else iOtherOut.push_back(i);
344 bool beginNewChain =
true;
347 while (iSorted.size() < partons.size()) {
353 if (iOtherIn.size() > 0) {
354 iSorted.push_back(iOtherIn.back());
358 }
else if (iTrip.size() > 0) {
359 beginNewChain =
false;
360 iSorted.push_back(iTrip.back());
364 }
else if (iOct.size() > 0) {
365 beginNewChain =
false;
366 iSorted.push_back(iOct.back());
369 }
else if (iOtherOut.size() > 0) {
370 iSorted.push_back(iOtherOut.back());
371 iOtherOut.pop_back();
379 bool isFinal = partons[iSorted.back()]->isFinal();
380 int col = (isFinal) ? partons[iSorted.back()]->col()
381 : partons[iSorted.back()]->acol();
382 int iNext = iOfAcol[col];
386 cout <<
"colourSort(): ERROR! cannot step to < 0" << endl;
387 beginNewChain =
true;
390 }
else if (iNext == i1) {
391 beginNewChain =
true;
396 iSorted.push_back(iNext);
398 if (particleDataPtr->colType(partons[iNext]->id()) != 2)
399 beginNewChain =
true;
402 beginNewChain =
false;
404 for (
int i=0; i<(int)iOct.size(); ++i) {
405 if (iOct[i] == iNext) {
406 iOct.erase(iOct.begin()+i);
424 void Colour::makeColourMaps(
const int iSysIn,
const Event& event,
425 map<int,int>& indexOfAcol, map<int,int>& indexOfCol,
426 vector< pair<int,int> >& antLC,
const bool findFF,
const bool findIX) {
429 int iSysBeg = (iSysIn >= 0) ? iSysIn : 0;
430 int iSysEnd = (iSysIn >= 0) ? iSysIn + 1: partonSystemsPtr->sizeSys();
431 for (
int iSys = iSysBeg; iSys < iSysEnd; ++iSys) {
434 int sizeSystem = partonSystemsPtr->sizeAll(iSys);
435 for (
int i = 0; i < sizeSystem; ++i) {
436 int i1 = partonSystemsPtr->getAll( iSys, i);
437 if ( i1 <= 0 )
continue;
440 int col =
event[i1].col();
441 int acol =
event[i1].acol();
444 if (!event[i1].isFinal()) {
446 acol =
event[i1].col();
450 if (col > 0) indexOfCol[col] = i1;
451 else if (col < 0) indexOfAcol[-col] = i1;
452 if (acol > 0) indexOfAcol[acol] = i1;
453 else if (acol < 0) indexOfCol[-acol] = i1;
456 if (col > 0 && indexOfAcol.count(col) == 1) {
457 int i2 = indexOfAcol[col];
458 if ( event[i1].isFinal() &&
event[i2].isFinal() ) {
459 if (findFF) antLC.push_back( make_pair(i1,i2) );
460 }
else if (findIX) antLC.push_back( make_pair(i1,i2) );
464 if (acol > 0 && indexOfCol.count(acol) == 1) {
465 int i2 = indexOfCol[acol];
467 if (event[i1].isFinal() &&
event[i2].isFinal()) {
468 if (findFF) antLC.push_back( make_pair(i2, i1) );
469 }
else if (findIX) antLC.push_back( make_pair(i2,i1) );
473 if (acol < 0 && indexOfAcol.count(-acol) == 1) {
474 int i2 = indexOfAcol[-acol];
475 if (event[i1].isFinal() &&
event[i2].isFinal()) {
476 if (findFF) antLC.push_back( make_pair(i1,i2) );
477 }
else if (findIX) antLC.push_back( make_pair(i1,i2) );
479 if (col < 0 && indexOfCol.count(-col) == 1) {
480 int i2 = indexOfAcol[-acol];
481 if (event[i1].isFinal() &&
event[i2].isFinal()) {
482 if (findFF) antLC.push_back( make_pair(i1,i2) );
483 }
else if (findIX) antLC.push_back( make_pair(i1,i2) );
497 bool Colour::inherit01(
double s01,
double s12) {
500 printOut(
"VinciaColour::inherit01",
501 "ERROR! Colour not initialised");
502 if (isInitPtr && rndmPtr->flat() < 0.5)
return false;
507 if (inheritMode == 0) {
508 if (rndmPtr->flat() < 0.5)
return true;
513 double a12 = abs(s01);
514 double a23 = abs(s12);
518 if (inheritMode < 0) {
521 inheritMode = abs(inheritMode);
525 if (inheritMode == 2) {
526 if (a12 > a23)
return true;
530 if ( max(a12,a23) > TINY ) {
531 if ( a12 < TINY ) p12 = 0.;
532 else if ( a23 < TINY ) p12 = 1.;
535 if (r < TINY) p12 = 1. - r;
536 else if (r > 1./TINY) p12 = 1./r;
537 else p12 = 1./(1. + r);
540 if (rndmPtr->flat() < p12)
return true;
553 bool Resolution::init() {
557 printOut(
"Resolution::init",
"Cannot initialize, pointers not set.");
562 verbose = settingsPtr->mode(
"Vincia:verbose");
563 nFlavZeroMassSav = settingsPtr->mode(
"Vincia:nFlavZeroMass");
573 double Resolution::q2sector2to3(
const Particle* a,
const Particle* b,
574 const Particle* j,
bool) {
577 double saj = 2*a->p()*j->p();
578 double sjb = 2*b->p()*j->p();
579 double sab = 2*a->p()*b->p();
583 if (a->isFinal() && b->isFinal()) {
584 return saj * sjb / (saj + sjb + sab) ;
587 }
else if (b->isFinal()) {
588 return saj * sjb / (saj + sab) ;
591 }
else if (a->isFinal()) {
592 return saj * sjb / (sjb + sab) ;
596 return saj * sjb / sab;
600 }
else if (a->isFinal() && b->isFinal()) {
602 double m2j = pow2(j->m());
603 double m2qq = saj + 2*m2j;
606 if (j->col() != 0 && j->col() == b->acol())
612 double sAnt = saj + sjb + sab + 2 * m2j;
615 return m2qq * sqrt(sX/sAnt);
617 cout <<
"Sector criterion not implemented for II/IF splittings/conversions"
629 double Resolution::q2sector3to4(
const Particle*,
const Particle* ,
630 const Particle* j1,
const Particle* j2) {
631 Vec4 pqq = j1->p() + j2->p();
632 double m2qq = pqq.m2Calc();
641 double Resolution::q2sector2to4(
const Particle* a,
const Particle* b,
642 const Particle* j1,
const Particle* j2) {
643 return min(q2sector2to3(a,j2,j1),q2sector2to3(j1,b,j2));
651 double Resolution::q2sector3to5(Particle* a, Particle* b,
652 Particle* j1, Particle* j2, Particle* j3) {
658 if (j1->id() == 21) {
660 qPtr = (j2->id() > 0 ? j2 : j3);
661 qBarPtr = (j2->id() < 0 ? j2 : j3);
662 }
else if (j2->id() == 21) {
664 qPtr = (j1->id() > 0 ? j1 : j3);
665 qBarPtr = (j1->id() < 0 ? j1 : j3);
666 }
else if (j3->id() == 21) {
668 qPtr = (j2->id() > 0 ? j2 : j1);
669 qBarPtr = (j2->id() < 0 ? j2 : j1);
671 cout <<
" q2sector3to5: unable to identify branching type" << endl;
674 Vec4 pqq = qPtr->p() + qBarPtr->p();
675 double m2qq = pqq.m2Calc();
676 Particle* colPtr = a;
677 if (a->col() != gluPtr->acol()) colPtr = j1;
678 if (j1->col() != gluPtr->acol()) colPtr = j2;
679 if (j2->col() != gluPtr->acol()) colPtr = j3;
680 if (j3->col() != gluPtr->acol()) colPtr = b;
681 Particle* acolPtr = b;
682 if (b->acol() != gluPtr->col()) acolPtr = j3;
683 if (j3->acol() != gluPtr->col()) acolPtr = j2;
684 if (j2->acol() != gluPtr->col()) acolPtr = j1;
685 if (j1->acol() != gluPtr->col()) acolPtr = a;
686 double q2emit = q2sector2to3(colPtr,acolPtr,gluPtr);
687 return min(q2emit,m2qq);
698 double Resolution::findSector(vector<int>& iSec, vector<Particle> state,
701 map<int, int> colMap, acolMap;
702 map<int, vector<int> > flavMap;
704 int nFerm(0), nIn(0);
705 for (
int i=0; i<(int)state.size(); ++i) {
706 colMap[state[i].isFinal() ? state[i].col() : state[i].acol()] = i;
707 acolMap[state[i].isFinal() ? state[i].acol() : state[i].col()] = i;
708 flavMap[state[i].isFinal() ? state[i].id() :
709 -state[i].id()].push_back(i);
710 helX.push_back(state[i].isFinal() ? state[i].pol() : -state[i].pol());
711 if (state[i].isQuark() || state[i].isLepton()) ++nFerm;
712 if (!state[i].isFinal()) ++nIn;
722 for (
int ir = 0; ir < (int)state.size(); ++ir) {
724 if (!state[ir].isFinal())
continue;
726 if (state[ir].isGluon()) {
727 int ia = colMap[state[ir].acol()];
728 int ib = acolMap[state[ir].col()];
729 double q2this = q2sector2to3(&state[ia],&state[ib],&state[ir]);
730 if (q2this < q2min) {
740 if (state[ir].isQuark()) {
742 if (nFerm <= nFmin)
continue;
745 int ib = (state[ir].id() > 0) ? acolMap[state[ir].col()]
746 : colMap[state[ir].acol()];
751 aList = flavMap[-state[ir].id()];
752 for (
int ifa = 0; ifa < (int)aList.size(); ++ifa) {
754 if (helX[ir] != helX[ia] || helX[ia] == 9 || helX[ir] == 9) {
755 double q2this = q2sector2to3(&state[ia],&state[ib],&state[ir]);
756 if (q2this < q2min) {
782 bool VinciaCommon::init() {
787 printOut(
"VinciaCommon::init",
"Error! pointers not initialized");
792 verbose = settingsPtr->mode(
"Vincia:verbose");
793 epTolErr = settingsPtr->parm(
"Check:epTolErr");
794 epTolWarn = settingsPtr->parm(
"Check:epTolWarn");
795 mTolErr = settingsPtr->parm(
"Check:mTolErr");
796 mTolWarn = settingsPtr->parm(
"Check:mTolWarn");
805 nUnmatchedMass.resize(2);
807 for (
int i=0; i<2; i++) {
808 nUnmatchedMass[i] = 0;
813 mt = particleDataPtr->m0(6);
814 if (mt < TINY) mt = 171.0;
815 mb = min(mt,particleDataPtr->m0(5));
816 if (mb < TINY) mb = min(mt,4.8);
817 mc = min(mb,particleDataPtr->m0(4));
818 if (mc < TINY) mc = min(mb,1.5);
819 ms = min(mc,particleDataPtr->m0(3));
820 if (ms < TINY) ms = min(mc,0.1);
824 nFlavZeroMass = settingsPtr->mode(
"Vincia:nFlavZeroMass");
827 double alphaSvalue = settingsPtr->parmDefault(
"Vincia:alphaSvalue");
828 int alphaSorder = settingsPtr->modeDefault(
"Vincia:alphaSorder");
829 int alphaSnfmax = settingsPtr->modeDefault(
"Vincia:alphaSnfmax");
830 bool useCMW = settingsPtr->flagDefault(
"Vincia:useCMW");
831 alphaStrongDef.init( alphaSvalue, alphaSorder, alphaSnfmax,
false);
832 alphaStrongDefCMW.init( alphaSvalue, alphaSorder, alphaSnfmax,
true);
835 alphaSvalue = settingsPtr->parm(
"Vincia:alphaSvalue");
836 alphaSorder = settingsPtr->mode(
"Vincia:alphaSorder");
837 alphaSnfmax = settingsPtr->mode(
"Vincia:alphaSnfmax");
838 useCMW = settingsPtr->flag(
"Vincia:useCMW");
839 alphaS.init(alphaSvalue, alphaSorder, alphaSnfmax, useCMW);
842 alphaSvalue = settingsPtr->parm(
"Vincia:alphaSvalue");
843 alphaSorder = settingsPtr->mode(
"Vincia:alphaSorder");
844 alphaSnfmax = settingsPtr->mode(
"Vincia:alphaSnfmax");
845 useCMW = settingsPtr->flag(
"Vincia:useCMW");
846 alphaStrong.init( alphaSvalue, alphaSorder, alphaSnfmax,
false);
847 alphaStrongCMW.init( alphaSvalue, alphaSorder, alphaSnfmax,
true);
850 mu2freeze = pow2(settingsPtr->parm(
"Vincia:alphaSmuFreeze"));
851 alphaSmax = settingsPtr->parm(
"Vincia:alphaSmax");
855 double muMin = max(sqrt(mu2freeze),1.05*alphaS.Lambda3());
857 if (alphaStrong.alphaS(mu2min) < alphaSmax) {
859 }
else if (settingsPtr->mode(
"Vincia:alphaSorder") == 0) {
864 if (alphaS.alphaS(pow2(muMinASmax)) < alphaSmax)
break;
868 mu2min = pow2( max(muMinASmax, muMin) );
871 alphaEM.init(1, settingsPtr);
885 double VinciaCommon::mHadMin(
const int id1in,
const int id2in) {
886 int id1 = abs(id1in);
887 if (id1 == 21 || id1 <= 2) id1 = 1;
888 int id2 = abs(id2in);
889 if (id2 == 21 || id1 <= 2) id2 = 1;
890 int idMes = max(id1,id2)*100 + min(id1,id2)*10 + 1;
893 if (idMes == 331) idMes = 221;
894 return particleDataPtr->m0(idMes);
903 bool VinciaCommon::showerChecks(
Event& event,
bool ISR) {
906 if (verbose < 4)
return true;
910 double chargeSum = 0.0;
911 bool beamRemnantAdded =
false;
912 for (
int i = 0; i <
event.size(); ++i){
913 if(!beamRemnantAdded){
914 if (!event[i].isFinal()) {
915 if ( (event[i].mother1() == 1) || (
event[i].mother1() == 2) ) {
916 pSum -=
event[i].p();
917 chargeSum -=
event[i].charge();
920 if(abs(event[i].status())==63){
921 beamRemnantAdded=
true;
922 pSum = -(
event[1].p() +
event[2].p());
923 chargeSum = -(
event[1].charge()+
event[2].charge());
927 double eLab = abs(pSum.e());
930 for (
int i = 0; i <
event.size(); ++i) {
933 int id =
event[i].id();
934 if (
id == 0 || !particleDataPtr->isParticle(
id)) {
936 if (nUnkownPDG == 1){
937 cout <<
"ERROR in Vincia::ShowerChecks" << (ISR ?
"(ISR)" :
"(FSR)")
938 <<
": unknown particle code"
939 <<
", i = " << i <<
", id = " <<
id << endl;
946 int colType =
event[i].colType();
947 int col =
event[i].col();
948 int acol =
event[i].acol();
949 if ( (colType == 0 && (col > 0 || acol > 0))
950 || (colType == 1 && (col <= 0 || acol > 0))
951 || (colType == -1 && (col > 0 || acol <= 0))
952 || (colType == 2 && (col <= 0 || acol <= 0)) ) {
954 if (nIncorrectCol == 1){
955 cout <<
"ERROR in Vincia::ShowerChecks" << (ISR ?
"(ISR)" :
"(FSR)")
956 <<
": incorrect colours"
957 <<
", i = " << i <<
", id = " <<
id <<
" cols = " << col
958 <<
" " << acol << endl;
965 if (abs(event[i].px()) >= 0.0 && abs(event[i].py()) >= 0.0
966 && abs(event[i].pz()) >= 0.0 && abs(event[i].e()) >= 0.0
967 && abs(event[i].m()) >= 0.0 ) {
968 double errMass = abs(event[i].mCalc() - event[i].m()) /
969 max( 1.0, event[i].e());
971 if (errMass > mTolErr) {
973 if (nUnmatchedMass[0] == 1){
974 cout <<
"ERROR in Vincia::ShowerChecks" << (ISR ?
"(ISR)" :
"(FSR)")
975 <<
": unmatched particle energy/momentum/mass"
976 <<
", i = " << i <<
", id = " <<
id << endl;
979 }
else if (errMass > mTolWarn) {
981 if (nUnmatchedMass[1] == 1){
982 cout <<
"WARNING in Vincia::ShowerChecks"
983 << (ISR ?
"(ISR)" :
"(FSR)")
984 <<
": not quite matched particle energy/momentum/mass"
985 <<
", i = " << i <<
", id = " <<
id << endl;
991 cout <<
"ERROR in Vincia::ShowerChecks" << (ISR ?
"(ISR)" :
"(FSR)")
992 <<
": not-a-number energy/momentum/mass"
993 <<
", i = " << i <<
", id = " <<
id << endl;
999 if (abs(event[i].xProd()) >= 0.0 && abs(event[i].yProd()) >= 0.0
1000 && abs(event[i].zProd()) >= 0.0 && abs(event[i].tProd()) >= 0.0
1001 && abs(event[i].tau()) >= 0.0) {
1005 cout <<
"ERROR in Vincia::ShowerChecks" << (ISR ?
"(ISR)" :
"(FSR)")
1006 <<
": not-a-number vertex/lifetime"
1007 <<
", i = " << i <<
", id = " <<
id << endl;
1013 if (event[i].isFinal()) {
1014 pSum +=
event[i].p();
1015 chargeSum +=
event[i].charge();
1020 double epDev = abs( pSum.e()) + abs(pSum.px()) + abs(pSum.py())
1022 if (epDev > epTolErr * eLab) {
1024 if (nEPcons[0] == 1) {
1025 cout <<
"ERROR in Vincia::ShowerChecks" << (ISR ?
"(ISR)" :
"(FSR)")
1026 <<
": energy-momentum not conserved" << endl;
1027 cout <<
" epDev = " << epDev <<
" Ein = " << eLab
1028 <<
" pSum = " << pSum << endl;
1031 }
else if (epDev > epTolWarn * eLab) {
1033 if (nEPcons[1] == 1)
1034 cout <<
"WARNING in Vincia::ShowerChecks" << (ISR ?
"(ISR)" :
"(FSR)")
1035 <<
": energy-momentum not quite conserved" << endl;
1037 if (abs(chargeSum) > 0.1) {
1039 if (nChargeCons == 1){
1040 cout <<
"ERROR in Vincia::ShowerChecks" << (ISR ?
"(ISR)" :
"(FSR)")
1041 <<
": charge not conserved" << endl;
1047 vector<int> noMot, noDau;
1048 vector< pair<int,int> > noMotDau;
1051 bool hasBeams =
false;
1052 for (
int i = 0; i <
event.size(); ++i) {
1053 int status =
event[i].status();
1054 if (abs(status) == 12) hasBeams =
true;
1057 vector<int> mList =
event[i].motherList();
1058 vector<int> dList =
event[i].daughterList();
1059 if (mList.size() == 0 && abs(status) != 11 && abs(status) != 12)
1061 if (dList.size() == 0 && status < 0 && status != -11)
1065 for (
int j = 0; j < int(mList.size()); ++j) {
1066 if (event[mList[j]].daughter1() <= i
1067 &&
event[mList[j]].daughter2() >= i)
continue;
1068 vector<int> dmList =
event[mList[j]].daughterList();
1069 bool foundMatch =
false;
1070 for (
int k = 0; k < int(dmList.size()); ++k)
1071 if (dmList[k] == i) {
1075 if (!hasBeams && mList.size() == 1 && mList[0] == 0) foundMatch =
true;
1077 bool oldPair =
false;
1078 for (
int k = 0; k < int(noMotDau.size()); ++k)
1079 if (noMotDau[k].first == mList[j] && noMotDau[k].second == i) {
1083 if (!oldPair) noMotDau.push_back( make_pair( mList[j], i) );
1088 for (
int j = 0; j < int(dList.size()); ++j) {
1089 if (event[dList[j]].statusAbs() > 80
1090 &&
event[dList[j]].statusAbs() < 90
1091 &&
event[dList[j]].mother1() <= i
1092 &&
event[dList[j]].mother2() >= i )
continue;
1093 vector<int> mdList =
event[dList[j]].motherList();
1094 bool foundMatch =
false;
1095 for (
int k = 0; k < int(mdList.size()); ++k)
1096 if (mdList[k] == i) {
1101 bool oldPair =
false;
1102 for (
int k = 0; k < int(noMotDau.size()); ++k)
1103 if (noMotDau[k].first == i && noMotDau[k].second == dList[j]) {
1107 if (!oldPair) noMotDau.push_back( make_pair( i, dList[j]) );
1113 if (noMot.size() > 0 || noDau.size() > 0 || noMotDau.size() > 0) {
1116 cout <<
"ERROR in Vincia::ShowerChecks" << (ISR ?
"(ISR)" :
"(FSR)")
1117 <<
": mismatch in daughter and mother lists" << endl;
1119 if (noMot.size() > 0) {
1120 cout <<
" missing mothers for particles ";
1121 for (
int i = 0; i < int(noMot.size()); ++i) cout << noMot[i] <<
" ";
1124 if (noDau.size() > 0) {
1125 cout <<
" missing daughters for particles ";
1126 for (
int i = 0; i < int(noDau.size()); ++i) cout << noDau[i] <<
" ";
1129 if (noMotDau.size() > 0) {
1130 cout <<
" inconsistent history for (mother,daughter) pairs ";
1131 for (
int i = 0; i < int(noMotDau.size()); ++i)
1132 cout <<
"(" << noMotDau[i].first <<
","
1133 << noMotDau[i].second <<
") ";
1149 double VinciaCommon::getShowerStartingScale(
int iSys,
1150 PartonSystems* partonSystemsPtr,
const Event& event,
double sbbSav) {
1154 int qMaxMatch = settingsPtr->mode(
"Vincia:QmaxMatch");
1155 double q2maxFudge = pow2(settingsPtr->parm(
"Vincia:QmaxFudge"));
1156 bool hasFSpartons =
false;
1157 int nOut = partonSystemsPtr->sizeOut(iSys);
1159 for (
int iOut = 0; iOut < nOut; ++iOut) {
1160 int i = partonSystemsPtr->getOut(iSys,iOut);
1161 int idAbs =
event[i].idAbs();
1162 if ((idAbs >= 1 && idAbs <= 5) || idAbs == 21) hasFSpartons =
true;
1165 if (qMaxMatch == 1 || (qMaxMatch == 0 && hasFSpartons) ) {
1166 double Q2facSav = sbbSav;
1167 double Q2facFix = settingsPtr->parm(
"SigmaProcess:factorFixScale");
1168 double Q2facMult = settingsPtr->parm(
"SigmaProcess:factorMultFac");
1172 int factorScale1 = settingsPtr->mode(
"SigmaProcess:factorScale1");
1173 Q2facSav = ( factorScale1 == 1 ? Q2facMult*
event[iFS[0]].m2Calc() :
1177 }
else if (iFS.size() == 2) {
1178 int factorScale2 = settingsPtr->mode(
"SigmaProcess:factorScale2");
1179 double mT21 =
event[iFS[0]].mT2(), mT22 =
event[iFS[1]].mT2();
1180 double sHat = m2(event[iFS[0]],event[iFS[1]]);
1181 double tHat = m2(event[3],event[iFS[0]]);
1182 if (factorScale2 == 1) Q2facSav = min(mT21,mT22);
1183 else if (factorScale2 == 2) Q2facSav = sqrt(mT21*mT22);
1184 else if (factorScale2 == 3) Q2facSav = 0.5*(mT21+mT22);
1185 else if (factorScale2 == 4) Q2facSav = sHat;
1186 else if (factorScale2 == 5) Q2facSav = Q2facFix;
1187 else if (factorScale2 == 6) Q2facSav = abs(-tHat);
1188 if (factorScale2 != 5) Q2facSav *= Q2facMult;
1191 }
else if (iFS.size() == 3) {
1192 int factorScale3 = settingsPtr->mode(
"SigmaProcess:factorScale3");
1193 double mT21 =
event[iFS[0]].mT2(), mT22 =
event[iFS[1]].mT2(),
1194 mT23 =
event[iFS[2]].mT2();
1195 double mT2min1 = min(mT21,min(mT22,mT23));
1196 double mT2min2 = max(max(min(mT21,mT22),min(mT21,mT23)),min(mT22,mT23));
1197 double sHat = m2(event[iFS[0]],event[iFS[1]],event[iFS[2]]);
1198 if (factorScale3 == 1) Q2facSav = mT2min1;
1199 else if (factorScale3 == 2) Q2facSav = sqrt(mT2min1*mT2min2);
1200 else if (factorScale3 == 3) Q2facSav = pow(mT21*mT22*mT23,1.0/3.0);
1201 else if (factorScale3 == 4) Q2facSav = (mT21+mT22+mT23)/3.0;
1202 else if (factorScale3 == 5) Q2facSav = sHat;
1203 else if (factorScale3 == 6) Q2facSav = Q2facFix;
1204 if (factorScale3 != 6) Q2facSav *= Q2facMult;
1208 return q2maxFudge*Q2facSav;
1228 bool VinciaCommon::map3to2FFmassless(vector<Vec4>& pClu, vector<Vec4> pIn,
1229 int kMapType,
int a,
int r,
int b) {
1233 if (max(max(a,r),b) >
int(pIn.size()) || min(min(a,r),b) < 0) {
1235 printOut(
"VinciaCommon::map3to2FFmassless",
1236 "Error! Unable to cluster (a,r,b) = "+
1237 num2str(a)+num2str(r)+num2str(b)+
" p.size ="
1238 +num2str(
int(pIn.size())));
1243 if (verbose >= superdebug) {
1244 printOut(
"VinciaCommon:map3to2FFmassless",
"called with ");
1245 cout <<
"pi = " << pIn[a];
1246 cout <<
"pj = " << pIn[r];
1247 cout <<
"pk = " << pIn[b];
1251 Vec4 pSum = pIn[a] + pIn[r] + pIn[b];
1252 double m2Ant = pSum.m2Calc();
1253 if (m2Ant < 1e-20) {
1254 printOut(
"VinciaCommon::map3to2FFmassless",
1255 "Massless or spacelike system. Cannot find rest frame");
1261 if (kMapType == 1 || kMapType == 2 || kMapType == -1 || kMapType == -2) {
1264 Vec4 paDum = pIn[a];
1265 Vec4 pbDum = pIn[b];
1266 double eCM = sqrt(m2Ant);
1267 paDum.bstback(pSum);
1268 pbDum.bstback(pSum);
1271 double phiA = paDum.phi();
1272 paDum.rot(0.,-phiA);
1273 pbDum.rot(0.,-phiA);
1276 double theta = paDum.theta();
1277 pbDum.rot(-theta,0.);
1280 double phiB = pbDum.phi();
1283 double thetaAB = pbDum.theta();
1287 if (kMapType == 1) {
1288 psi = pbDum.e()*pbDum.e()/(paDum.e()*paDum.e() + pbDum.e()*pbDum.e())
1293 }
else if (kMapType == 2) {
1294 Vec4 pAR = pIn[a] + pIn[r];
1295 Vec4 pRB = pIn[r] + pIn[b];
1296 double sar = pAR.m2Calc();
1297 double srb = pRB.m2Calc();
1298 if (sar > srb) psi = 0.0;
1299 else psi = (M_PI - thetaAB);
1302 }
else if (kMapType == -1) {
1303 psi = M_PI - thetaAB;
1306 }
else if (kMapType == -2) {
1313 pClu[a] = Vec4(0.,0.,eCM/2.,eCM/2.);
1314 pClu[b] = Vec4(0.,0.,-eCM/2.,eCM/2.);
1317 pClu[a].rot(-psi,phiB);
1318 pClu[b].rot(-psi,phiB);
1321 pClu[a].rot(theta,phiA);
1322 pClu[b].rot(theta,phiA);
1333 double s01 = 2*pIn[a]*pIn[r];
1334 double s12 = 2*pIn[r]*pIn[b];
1335 double s02 = 2*pIn[a]*pIn[b];
1338 if (kMapType == 4 && ( ! (s01 < s12) ) ) {
1339 if (verbose >= superdebug) {
1340 printOut(
"VinciaCommon::map3to2FFmassless",
1341 "choose parton i as the recoiler");
1344 return map3to2FFmassless(pClu, pIn, kMapType, b, r, a);
1346 double sAnt = s01 + s12 + s02;
1351 double rMap = kMapType == 3 ? s12/(s01 + s12) : 1;
1352 double rho = sqrt(1.0+(4*rMap*(1.0-rMap)*s01*s12)/sAnt/s02);
1353 double x = 0.5/(s01+s02)*((1+rho)*(s01+s02)+(1+rho-2*rMap)*s12);
1354 double z = 0.5/(s12+s02)*((1-rho)*sAnt-2*rMap*s01);
1357 pClu[a] = x*pIn[a] + rMap*pIn[r] + z*pIn[b];
1358 pClu[b] = (1-x)*pIn[a] + (1-rMap)*pIn[r] + (1-z)*pIn[b];
1362 if (pClu[a].m2Calc()/m2Ant >= TINY || pClu[b].m2Calc()/m2Ant >= TINY) {
1364 printOut(
"VinciaCommon::map3to2FFmassless",
1365 "on-shell check failed. m2I/sIK ="
1366 + num2str(pClu[a].m2Calc()/m2Ant)+
" m2K/m2Ant ="
1367 + num2str(pClu[b].m2Calc()/m2Ant)+
" m2Ant = "+num2str(m2Ant));
1372 pClu.erase(pClu.begin()+r);
1384 bool VinciaCommon::map3to2FFmassive(vector<Vec4>& pClu, vector<Vec4> pIn,
1385 int kMapType,
int a,
int r,
int b,
double mI,
double mK) {
1391 double eAv = 1.0/3.0*( pIn[a].e() + pIn[r].e() + pIn[b].e() );
1392 if (mI/eAv < TINY && mK/eAv < TINY && pIn[a].mCalc()/eAv < TINY
1393 && pIn[r].mCalc()/eAv < TINY && pIn[b].mCalc()/eAv < TINY ) {
1394 return map3to2FFmassless(pClu, pIn, kMapType, a, r, b);
1399 if (max(max(a,r),b) >
int(pIn.size()) || min(min(a,r),b) < 0)
return false;
1402 if (verbose >= superdebug) {
1403 printOut(
"VinciaCommon:map3to2FFmassive",
"called with ");
1404 cout <<
"p0 = " << pIn[a];
1405 cout <<
"p1 = " << pIn[r];
1406 cout <<
"p2 = " << pIn[b];
1410 if (kMapType == 1) kMapType = 3;
1413 if (kMapType == 2) kMapType = 4;
1417 printOut(
"VinciaCommon::map3to2FFmassive",
"longitudinal clustering maps "
1418 "not yet implemented for massive partons.");
1423 double m0 = pIn[a].mCalc();
1424 double m1 = pIn[r].mCalc();
1425 double m2 = pIn[b].mCalc();
1426 double s01 = 2*pIn[a]*pIn[r];
1427 double s12 = 2*pIn[r]*pIn[b];
1428 double s02 = 2*pIn[a]*pIn[b];
1431 if (kMapType == 4 && (! (s01 < s12) ) ) {
1432 return map3to2FFmassive(pClu, pIn, kMapType, b, r, a, mK, mI);
1434 Vec4 pAnt = pIn[a] + pIn[r] + pIn[b];
1435 double m2Ant = pAnt.m2Calc();
1436 double mAnt = sqrt(m2Ant);
1440 double mu0 = m0/mAnt;
1441 double mu1 = m1/mAnt;
1442 double mu2 = m2/mAnt;
1443 double y01 = s01/m2Ant;
1444 double y12 = s12/m2Ant;
1445 double y02 = s02/m2Ant;
1446 double y01min = 2*mu0*mu1;
1447 double y12min = 2*mu1*mu2;
1448 double y02min = 2*mu0*mu2;
1449 double muI = mI/mAnt;
1450 double muK = mK/mAnt;
1451 double yIK = 1. - pow2(muI) - pow2(muK);
1452 double yIKmin = 2*muI*muK;
1453 double sig2 = 1 + pow2(muI) - pow2(muK);
1454 double gdetdimless = gramDet(y01,y12,y02,mu0,mu1,mu2);
1455 double gdetdimless01 = (y02*y12-2.*pow2(mu2)*y01)/4.;
1456 double gdetdimless12 = (y02*y01-2.*pow2(mu0)*y12)/4.;
1458 if ( kMapType == 3) {
1462 + sqrt( pow2(yIK) - pow2(yIKmin) )
1463 *( y12 - y12min - ( y01 - y01min ) )
1464 /( y12 - y12min + ( y01 - y01min ) )
1469 double mu01squa = pow2(mu0) + pow2(mu1) + y01;
1470 double lambda = 1 + pow2(mu01squa) + pow4(mu2) - 2*mu01squa - 2*pow2(mu2)
1471 - 2*mu01squa*pow2(mu2);
1472 rMap = (sig2 + sqrt(pow2(yIK) - pow2(yIKmin))
1473 *(1 - pow2(mu0) - pow2(mu1) + pow2(mu2) - y01)/sqrt(lambda))/2.;
1477 double bigsqr = sqrt(
1478 16.*( rMap*(1.-rMap) - (1.-rMap)*pow2(muI) - rMap*pow2(muK) )*gdetdimless
1479 + ( pow2(y02) - pow2(y02min) )*( pow2(yIK) - pow2(yIKmin) ));
1481 sig2*( pow2(y02) - pow2(y02min) + 4.*gdetdimless01)
1482 + 8.*rMap*( gdetdimless - gdetdimless01 )
1483 + bigsqr*( 1. - pow2(mu0) - pow2(mu1) + pow2(mu2) - y01)
1484 )/(2.*( 4.*gdetdimless + pow2(y02) - pow2(y02min) ));
1486 sig2*( pow2(y02) - pow2(y02min) + 4.*gdetdimless12)
1487 + 8.*rMap*( gdetdimless - gdetdimless12 )
1488 - bigsqr*( 1. + pow2(mu0) - pow2(mu1) - pow2(mu2) - y12)
1489 )/(2.*( 4.*gdetdimless + pow2(y02) - pow2(y02min)));
1490 pClu[a] = x*pIn[a] + rMap*pIn[r] + z*pIn[b];
1491 pClu[b] = (1-x)*pIn[a] + (1-rMap)*pIn[r] + (1-z)*pIn[b];
1494 double offshellnessI = abs(pClu[a].m2Calc() - pow2(mI))/m2Ant;
1495 double offshellnessK = abs(pClu[b].m2Calc() - pow2(mK))/m2Ant;
1496 if (offshellnessI > TINY || offshellnessK > TINY) {
1498 printOut(
"VinciaCommon::map3to2FFmassive",
"on-shell check failed");
1504 pClu.erase(pClu.begin()+r);
1513 bool VinciaCommon::map3to2IFmassive(vector<Vec4>& pClu, vector<Vec4>& pIn,
1514 double saj,
double sjk,
double sak) {
1515 double sAK = saj + sak - sjk;
1517 pA.rescale4(sAK/(sAK + sjk));
1518 Vec4 pK = pA - pIn[0] + pIn[1] + pIn[2];
1529 bool VinciaCommon::map3to2IImassive(vector<Vec4>& pClu, vector<Vec4>& pIn,
1530 vector<Vec4>& pRec,
double saj,
double sjb,
double sab,
bool doBoost) {
1533 double sAB = sab - saj - sjb;
1534 double rescaleFacA = 1./sqrt(sab/sAB * (sab - saj)/(sab - sjb));
1535 double rescaleFacB = 1./sqrt(sab/sAB * (sab - sjb)/(sab - saj));
1537 pA.rescale4(rescaleFacA);
1540 pB.rescale4(rescaleFacB);
1542 Vec4 pInSum = pIn[0] + pIn[2] - pIn[1];
1543 Vec4 pCluSum = pClu[0] + pClu[1];
1547 for (
int i=0; i<(int)pRec.size(); i++) {
1548 pRec[i].bstback(pInSum);
1549 pRec[i].bst(pCluSum);
1554 for (
int i=0; i<(int)pClu.size(); i++) {
1555 pClu[i].bstback(pCluSum);
1556 pClu[i].bst(pInSum);
1570 bool VinciaCommon::map2to3FFmassive(vector<Vec4>& pThree,
1571 const vector<Vec4>& pTwo,
int kMapType,
const vector<double>& invariants,
1572 double phi, vector<double> masses) {
1575 if (masses.size() < 3 ||
1576 (masses[0] <= TINY && masses[1] <= TINY && masses[2] <= TINY))
1577 return map2to3FFmassless(pThree,pTwo,kMapType,invariants,phi);
1580 double m2Ant = m2(pTwo[0],pTwo[1]);
1581 double mAnt = sqrt(m2Ant);
1582 double sAnt = invariants[0];
1583 if (sAnt <= 0.0)
return false;
1586 double mass0 = max(0.,masses[0]);
1587 double mass1 = max(0.,masses[1]);
1588 double mass2 = max(0.,masses[2]);
1592 if (mAnt < mass0 + mass1 + mass2) {
1593 cout <<
" (VinciaCommon::map2to3FFmassive:) "
1594 <<
"ERROR! unphysical phase space\n";
1597 double s01 = max(0.,invariants[1]);
1598 double s12 = max(0.,invariants[2]);
1599 double s02 = m2Ant - s01 - s12 - pow2(mass0) - pow2(mass1) - pow2(mass2);
1600 if (s02 <= 0.)
return false;
1603 double gDet = gramDet(s01, s12, s02, mass0, mass1, mass2);
1606 cout <<
" map2to3FFmassive: failed massive phase space check" << endl;
1612 cout <<
" (VinciaCommon::map2to3FFmassive:) m = " << num2str(mAnt)
1613 <<
" sqrtsIK = " << num2str(sqrt(sAnt)) <<
" sqrts(ij,jk,ik) ="
1614 << num2str(sqrt(s01)) <<
" " << num2str(sqrt(s12)) <<
" "
1615 << num2str(sqrt(s02)) <<
" m(i,j,k) =" << num2str(mass0) <<
" "
1616 << num2str(mass1) <<
" " << num2str(mass2) <<
" D = " << gDet << endl;
1618 Vec4 p1cm = pTwo[0];
1619 Vec4 p2cm = pTwo[1];
1620 M.toCMframe(p1cm,p2cm);
1623 Vec4 tot = p1cm+p2cm;
1624 cout <<
" (VinciaCommon::map2to3FFmassive:) starting dipole in CM\n"
1625 <<
" p1cm = " << p1cm <<
" p2cm = " << p2cm
1626 <<
" total = " << tot << endl;
1630 double E0 = (pow2(mass0) + s01/2 + s02/2)/mAnt;
1631 double E1 = (pow2(mass1) + s12/2 + s01/2)/mAnt;
1632 double E2 = (pow2(mass2) + s02/2 + s12/2)/mAnt;
1636 if (E0 < mass0 || E1 < mass1 || E2 < mass2) {
1637 cout <<
" (VinciaCommon::map2to3FFmassive:) ERROR! "
1638 <<
"Unphysical energy value(s)\n";
1641 double ap0 = sqrt( pow2(E0) - pow2(mass0) );
1642 double ap1 = sqrt( pow2(E1) - pow2(mass1) );
1643 double ap2 = sqrt( pow2(E2) - pow2(mass2) );
1644 double cos01 = (E0*E1 - s01/2)/(ap0*ap1);
1645 double cos02 = (E0*E2 - s02/2)/(ap0*ap2);
1648 if ( 1-abs(cos01) < 1e-15 ) cos01 = cos01 > 0 ? 1. : -1.;
1649 if ( 1-abs(cos02) < 1e-15 ) cos02 = cos02 > 0 ? 1. : -1.;
1652 double sin01 = (abs(cos01) < 1) ? sqrt(abs(1.0 - pow2(cos01))) : 0.0;
1653 double sin02 = (abs(cos02) < 1) ? sqrt(abs(1.0 - pow2(cos02))) : 0.0;
1657 Vec4 p1(0.0,0.0,ap0,E0);
1658 Vec4 p2(-ap1*sin01,0.0,ap1*cos01,E1);
1659 Vec4 p3(ap2*sin02,0.0,ap2*cos02,E2);
1662 if (verbose >= superdebug) {
1663 Vec4 tot = p1+p2+p3;
1664 cout <<
" (map2to3FFmassive:) configuration in CM* (def: 1 along z)\n";
1665 cout <<
" k1* = " << p1 <<
" k2* = " << p2 <<
" k3* = " << p3
1666 <<
" total = " << tot << endl;
1673 if (kMapType == -2) psi = 0.0;
1674 else if (kMapType == -1) psi = M_PI - acos(cos02);
1677 double m2I = max(0.0,m2(pTwo[0]));
1678 double m2K = max(0.0,m2(pTwo[1]));
1679 double sig2 = m2Ant + m2I - m2K;
1680 double sAntMin = 2*sqrt(m2I*m2K);
1681 double s01min = max(0.0,2*mass0*mass1);
1682 double s12min = max(0.0,2*mass1*mass2);
1683 double s02min = max(0.0,2*mass0*mass2);
1686 double rAntMap = ( sig2 + sqrt( pow2(sAnt) - pow2(sAntMin) )
1687 * ( s12-s12min - (s01-s01min) )
1688 / ( s01-s01min + s12-s12min ) ) / (2*m2Ant);
1689 double bigRantMap2 = 16*gDet * ( m2Ant*rAntMap * (1.-rAntMap)
1690 - (1.-rAntMap)*m2I - rAntMap*m2K )
1691 + ( pow2(s02) - pow2(s02min) )
1692 * ( pow2(sAnt) - pow2(sAntMin) );
1693 if(bigRantMap2 < 0.){
1695 ss<<
"On line "<<__LINE__;
1696 infoPtr->errorMsg(
"Warning in "+__METHOD_NAME__
1697 +
": kinematics map is broken.",ss.str());
1700 double bigRantMap = sqrt( bigRantMap2 );
1701 double p1dotpI = (sig2*(pow2(s02) - pow2(s02min))*
1702 (m2Ant + pow2(mass0) - pow2(mass1) - pow2(mass2) - s12)
1703 +8*rAntMap*(m2Ant + pow2(mass0) - pow2(mass1) - pow2(mass2) - s12)*gDet
1704 -bigRantMap*(pow2(s02) - pow2(s02min) + s01*s02-2*s12*pow2(mass0)))
1705 /(4*(4*gDet + m2Ant*(pow2(s02) - pow2(s02min))));
1710 double apInum2 = pow2(m2Ant) + pow2(m2I) + pow2(m2K) - 2*m2Ant*m2I
1711 - 2*m2Ant*m2K - 2*m2I*m2K;
1714 ss<<
"On line "<<__LINE__;
1715 infoPtr->errorMsg(
"Warning in "+__METHOD_NAME__
1716 +
": kinematics map is broken.",ss.str());
1719 double apI = sqrt(apInum2)/(2*mAnt);
1720 double EI = sqrt( pow2(apI) + m2I );
1723 double cospsi = ((E0*EI) - p1dotpI)/(ap0*apI);
1724 if (cospsi >= 1.0) {
1726 }
else if (cospsi <= -1.0) {
1728 }
else if(isnan(cospsi)){
1731 ss <<
"ap0 = " << ap0;
1732 ss <<
" apI = " << apI;
1733 ss <<
" E0 = " << E0;
1734 ss <<
" mass0 = " << mass0;
1735 ss <<
" mAnt = " << mAnt;
1736 ss <<
" sum1 = " << pow2(sAnt) + pow2(m2I) + pow2(m2K);
1737 ss <<
" sum2 = " << 2*sAnt*m2I + 2*sAnt*m2K + 2*m2I*m2K;
1738 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__
1739 +
": cos(psi) = nan.",ss.str());
1743 psi = acos( cospsi );
1754 Vec4 tot = p1+p2+p3;
1755 printOut(
"VinciaCommon::map2to3FFmassive:",
"phi = " + num2str(phi,6)
1756 +
" cospsi = " + num2str(cos(psi),6) +
" psi = " + num2str(psi,6));
1757 printOut(
"VinciaCommon::map2to3FFmassive:",
1758 "mapType = " + num2str(kMapType));
1759 printOut(
"VinciaCommon::map2to3FFmassive:",
"final momenta in CM");
1760 cout <<
" k1cm = " << p1 <<
" k2cm = " << p2 <<
" k3cm = " << p3
1761 <<
" total = " << tot << endl;
1766 M.fromCMframe(pTwo[0],pTwo[1]);
1767 if (verbose >= superdebug) {
1768 Vec4 tot = pTwo[0]+pTwo[1];
1769 cout <<
" (VinciaCommon::map2to3FFmassive) boosting to LAB frame "
1771 cout <<
" p1 = " << pTwo[0] <<
" p2 = " << pTwo[1]
1772 <<
" total = " << tot << endl;
1778 Vec4 tot = p1+p2+p3;
1779 cout <<
" (VinciaCommon::map2to3FFmassive:) final momenta in LAB\n";
1780 cout <<
" k1 = " << p1 <<
" k2 = " << p2 <<
" k3 = " << p3
1781 <<
" total = " << tot << endl;
1786 pThree.push_back(p1);
1787 pThree.push_back(p2);
1788 pThree.push_back(p3);
1790 Vec4 total = pTwo[0] + pTwo[1];
1791 total -= (p1+p2+p3);
1792 if (abs(total.e()) > SMALL || abs(total.px()) > SMALL
1793 || abs(total.py()) > SMALL || abs(total.pz()) > SMALL ){
1794 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__+
1795 ": Failed momentum conservation test. Aborting.");
1796 infoPtr->setAbortPartonLevel(
true);
1800 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__+
": (E,p) = nan.");
1815 bool VinciaCommon::map2to3FFmassless(vector<Vec4>& pThree,
1816 const vector<Vec4>& pTwo,
int kMapType,
const vector<double>& invariants,
1819 if (verbose >= superdebug) printOut(__METHOD_NAME__,
"begin --------------");
1822 double m2Ant = m2(pTwo[0],pTwo[1]);
1823 double mAnt = sqrt(m2Ant);
1826 double s01 = invariants[1];
1827 double s12 = invariants[2];
1828 double s02 = m2Ant - s01 - s12;
1832 cout <<
" (VinciaCommon::map2to3FFmassless:) m = " << num2str(mAnt)
1833 <<
" m12 =" << num2str(sqrt(s01))
1834 <<
" m23 =" << num2str(sqrt(s12))
1835 <<
" m13 =" << num2str(sqrt(s02)) << endl;
1837 Vec4 p1cm = pTwo[0];
1838 Vec4 p2cm = pTwo[1];
1839 M.toCMframe(p1cm,p2cm);
1842 Vec4 tot = p1cm+p2cm;
1843 cout <<
" (VinciaCommon::map2to3FFmassless:) starting dipole in CM\n"
1844 <<
" p1cm = " << p1cm <<
" p2cm = " << p2cm
1845 <<
" total = " << tot<<endl;
1849 double E0 = 1/mAnt*(s01/2 + s02/2);
1850 double E1 = 1/mAnt*(s01/2 + s12/2);
1851 double E2 = 1/mAnt*(s02/2 + s12/2);
1855 double cos01 = (E0*E1 - s01/2)/(ap0*ap1);
1856 double cos02 = (E0*E2 - s02/2)/(ap0*ap2);
1859 if ( 1-abs(cos01) < 1e-15 ) cos01 = cos01 > 0 ? 1. : -1.;
1860 if ( 1-abs(cos02) < 1e-15 ) cos02 = cos02 > 0 ? 1. : -1.;
1861 double sin01 = (abs(cos01) < 1) ? sqrt(abs(1.0 - pow2(cos01))) : 0.0;
1862 double sin02 = (abs(cos02) < 1) ? sqrt(abs(1.0 - pow2(cos02))) : 0.0;
1866 Vec4 p1(0.0,0.0,ap0,E0);
1867 Vec4 p2(-ap1*sin01,0.0,ap1*cos01,E1);
1868 Vec4 p3(ap2*sin02,0.0,ap2*cos02,E2);
1871 if (verbose >= superdebug) {
1872 Vec4 tot = p1+p2+p3;
1873 cout <<
" (map2to3FFmassless:) configuration in CM* (def: 1 along z)\n"
1874 <<
" k1* = " << p1 <<
" k2* = " << p2 <<
" k3* = " << p3
1875 <<
" total = " << tot << endl;
1882 if (kMapType == -2) {
1886 }
else if (kMapType == -1) {
1887 psi = M_PI - acos(max(-1.,min(1.,cos02)));
1890 }
else if (kMapType == 1) {
1891 psi = E2*E2/(E0*E0+E2*E2)*(M_PI-acos(cos02));
1894 }
else if (kMapType == 2) {
1896 if (s01 < s12 || (s01 == s12 && rndmPtr->flat() > 0.5) )
1897 psi = M_PI-acos(cos02);
1902 if (kMapType == 3) rMap = s12/(s01+s12);
1903 double rho=sqrt(1.0+4.0*rMap*(1.0-rMap)*s01*s12/s02/m2Ant);
1904 double s00=-( (1.0-rho)*m2Ant*s02 + 2.0*rMap*s01*s12 ) / 2.0 /
1906 psi=acos(1.0+2.0*s00/(m2Ant-s12));
1916 Vec4 tot = p1+p2+p3;
1917 printOut(__METHOD_NAME__,
"phi = " + num2str(phi,6) +
"psi = " +
1919 printOut(__METHOD_NAME__,
"final momenta in CM");
1920 cout <<
" k1cm = " << p1 <<
" k2cm = " << p2 <<
" k3cm = " << p3
1921 <<
" total = " << tot << endl;
1926 M.fromCMframe(pTwo[0],pTwo[1]);
1927 Vec4 total = pTwo[0] + pTwo[1];
1928 if (verbose >= superdebug) {
1929 cout <<
" (VinciaCommon::map2to3FFmassless:) boosting to LAB frame "
1930 <<
"defined by\n" <<
" p1 = " << pTwo[0] <<
" p2 = " << pTwo[1]
1931 <<
" total = " << total << endl;
1937 Vec4 tot = p1 + p2 + p3 ;
1938 printOut(__METHOD_NAME__,
"final momenta in LAB");
1939 cout <<
" k1 = "<<p1<<
" k2 = "<<p2<<
" k3 = "<<p3
1940 <<
" total = "<<tot<<endl;
1945 pThree.push_back(p1);
1946 pThree.push_back(p2);
1947 pThree.push_back(p3);
1950 Vec4 diff = total - (p1+p2+p3);
1951 if(abs(diff.e()) / abs(total.e()) > SMALL ||
1952 abs(diff.px()) / abs(total.e()) > SMALL ||
1953 abs(diff.py()) / abs(total.e()) > SMALL ||
1954 abs(diff.pz()) / abs(total.e()) > SMALL) {
1955 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__
1956 +
": (E,p) not conserved.",
"Aborting.");
1957 cout << setprecision(10) <<
" difference = " << total.px() <<
" "
1958 << total.py() <<
" " << total.pz() <<
" " << total.e() << endl;
1959 infoPtr->setAbortPartonLevel(
true);
1972 bool VinciaCommon::map2to3RFmassive(vector<Vec4>& pThree, vector<Vec4> pTwo,
1973 vector<double> invariants,
double phi,
1974 vector<double> masses) {
1976 if (verbose >= superdebug) printOut(__METHOD_NAME__,
"begin --------------");
1979 if(pTwo.size() != 2){
1980 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__
1981 +
": Wrong number of momenta provided.");
1986 Vec4 pAKBefore = pTwo.at(0);
1987 Vec4 pKBefore = pTwo.at(1);
1988 Vec4 pABefore = pKBefore + pAKBefore;
1989 Vec4 pACoM = pABefore;
1992 pKBefore.bstback(pABefore);
1993 pAKBefore.bstback(pABefore);
1994 pACoM.bstback(pABefore);
1997 double thetaK = pKBefore.theta();
1998 double phiK = pKBefore.phi();
2003 double saj = invariants[1];
2004 double sjk = invariants[2];
2005 double sak = invariants[3];
2006 double mA = masses[0];
2007 double mj = masses[1];
2008 double mk = masses[2];
2009 double mAK = masses[3];
2010 double invDiff = mA*mA + mj*mj + mk*mk -saj-sak+sjk;
2014 double EjAfter = saj/(2.0*mA);
2015 double EkAfter = sak/(2.0*mA);
2016 if (EkAfter < mk)
return false;
2017 else if (EjAfter < mj)
return false;
2018 else if (invDiff > SMALL)
return false;
2021 double cosTheta = getCosTheta(EjAfter,EkAfter, mj,mk, sjk);
2022 if (abs(cosTheta) > 1.0)
return false;
2023 double sinTheta = sqrt(1.0 - cosTheta*cosTheta);
2024 double pk = sqrt(EkAfter*EkAfter-mk*mk);
2025 double pj = sqrt(EjAfter*EjAfter-mj*mj);
2028 Vec4 pkAfter(0.,0.,pk, EkAfter);
2029 Vec4 pjAfter(pj*sinTheta,0.,pj*cosTheta, EjAfter);
2030 Vec4 pajkAfter = pACoM - pkAfter - pjAfter;
2033 double thetaEff = -(M_PI-pajkAfter.theta());
2034 pkAfter.rot(thetaEff,0.);
2035 pjAfter.rot(thetaEff,0.);
2036 pajkAfter.rot(thetaEff,0.);
2039 pkAfter.rot(0.,phi);
2040 pjAfter.rot(0.,phi);
2041 pajkAfter.rot(0.,phi);
2044 pkAfter.rot(thetaK,phiK);
2045 pjAfter.rot(thetaK,phiK);
2046 pajkAfter.rot(thetaK,phiK);
2049 pkAfter.bst(pABefore);
2050 pjAfter.bst(pABefore);
2051 pajkAfter.bst(pABefore);
2053 pThree.push_back(pajkAfter);
2054 pThree.push_back(pjAfter);
2055 pThree.push_back(pkAfter);
2081 bool VinciaCommon::map2toNRFmassive(vector<Vec4>& pAfter, vector<Vec4> pBefore,
2082 unsigned int posR,
unsigned int posF, vector<double> invariants,
double phi,
2083 vector<double> masses) {
2085 if (verbose >= superdebug) printOut(__METHOD_NAME__,
"begin --------------");
2089 Vec4 pR = pBefore.at(posR);
2090 Vec4 pF = pBefore.at(posF);
2091 Vec4 pSum(0.,0.,0.,0.);
2093 for(
unsigned int imom = 0; imom < pBefore.size(); imom++){
2094 if (imom==posF || imom==posR) {
2097 pSum+= pBefore.at(imom);
2098 pRec.push_back(pBefore.at(imom));
2102 vector<Vec4> pThree;
2103 pTwo.push_back(pSum);
2107 if (!map2to3RFmassive(pThree,pTwo,invariants,phi,masses)) {
2109 }
else if (pThree.size() != 3) {
2114 pAfter.push_back(pR);
2115 pAfter.push_back(pThree.at(1));
2116 pAfter.push_back(pThree.at(2));
2117 Vec4 pSumAfter = pThree.at(0);
2118 if (abs(pSumAfter.mCalc() - pSum.mCalc()) > SMALL) {
2119 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__
2120 +
": Failed to conserve mass of system.");
2125 if (pRec.size() == 1) {
2126 pAfter.push_back(pSumAfter);
2130 for(
unsigned int imom = 0; imom < pRec.size(); imom++) {
2131 double mRecBef = pRec.at(imom).mCalc();
2132 pRec.at(imom).bstback(pSum,pSum.mCalc());
2133 pRec.at(imom).bst(pSumAfter,pSum.mCalc());
2134 double mRecAfter = pRec.at(imom).mCalc();
2137 if (abs(mRecAfter- mRecBef) > SMALL) {
2138 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__
2139 +
": Failed to conserve mass of recoilers.");
2142 pAfter.push_back(pRec.at(imom));
2154 bool VinciaCommon::map2to3II(vector<Vec4>& pNew, vector<Vec4>& pRec,
2155 vector<Vec4>& pOld,
double sAB,
double saj,
double sjb,
double sab,
2156 double phi,
double mj2) {
2158 if (verbose >= superdebug) printOut(__METHOD_NAME__,
"begin --------------");
2162 return map2to3IImassless(pNew, pRec, pOld, sAB, saj, sjb, sab, phi);
2173 double sCM = m2(pOld[0] + pOld[1]);
2174 double fac = sqrt(sAB/sCM);
2175 double e0 = pOld[0].e();
2176 double e1 = pOld[1].e();
2177 if (abs(1. - fac) > TINY) {
2178 if (verbose >= 3 && abs(1.-fac) > 1.01)
2179 printOut(
"VinClu::map2to3II",
"Warning: scaling AB so m2(AB) = sAB");
2183 int sign = pOld[0].pz() > 0 ? 1 : -1;
2185 pOld[0].pz(sign * e0);
2187 pOld[1].pz(-sign * e1);
2194 double G = saj*sjb*sab - mj2*sab*sab;
2195 if (G < 0. || sab < 0.)
return false;
2196 if ((sab <= sjb) || (sab <= saj)) {
2197 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__
2198 +
": Incompatible invariants.");
2203 double rescaleFacA = sqrt(sab/sAB * (sab - saj)/(sab - sjb));
2204 double rescaleFacB = sqrt(sab/sAB * (sab - sjb)/(sab - saj));
2205 pNew[0].rescale4(rescaleFacA);
2206 pNew[2].rescale4(rescaleFacB);
2209 double preFacA = sjb*sqrt((sab - saj)/(sab - sjb)/sab/sAB);
2210 double preFacB = saj*sqrt((sab - sjb)/(sab - saj)/sab/sAB);
2211 double preFacT = sqrt(saj*sjb/sab - mj2);
2212 Vec4 pTrans(cos(phi), sin(phi), 0.0, 0.0);
2213 pNew[1] = preFacA*pOld[0] + preFacB*pOld[1] + preFacT*pTrans;
2215 if (verbose >= superdebug) {
2216 printOut(
"VinClu::map2to3II",
"Invariants are");
2217 cout << scientific <<
" sAB = " << sAB <<
" saj = " << saj
2218 <<
" sjb = " << sjb <<
" sab = " << sab << endl
2219 <<
" Given momenta are" << endl;
2220 for (
int i = 0; i < 2; i++) cout <<
" " << pOld[i];
2221 cout <<
" New momenta are" << endl;
2222 for (
int i = 0; i < 3; i++) cout <<
" " << pNew[i];
2226 double check = 1e-6;
2227 double sajNew = 2*pNew[0]*pNew[1];
2228 double sjbNew = 2*pNew[1]*pNew[2];
2229 double sabNew = 2*pNew[0]*pNew[2];
2230 if (abs(sabNew - sab)/sab > check) {
2232 printOut(
"VinClu::map2to3II",
"ERROR! Invariants differ!");
2233 cout << scientific <<
" sab (" << sab <<
") fracdiff = ydiff = "
2234 << abs(sabNew-sab)/sab << endl <<
" Old momenta are" << endl;
2235 for (
int i=0; i<2; i++) cout <<
" " << pOld[i];
2236 cout <<
" New momenta are" << endl;
2237 for (
int i=0; i<3; i++) cout <<
" " << pNew[i];
2240 }
else if (abs(sajNew - saj)/sab > check) {
2242 printOut(
"VinClu::map2to3II",
"ERROR! Invariants differ!");
2243 cout << scientific <<
" saj (" << saj <<
") fracdiff = "
2244 << abs(sajNew-saj)/saj <<
" ydiff = "
2245 << abs(sajNew-saj)/sab << endl <<
" Old momenta are" << endl;
2246 for (
int i=0; i<2; i++) cout <<
" " << pOld[i];
2247 cout <<
" New momenta are" << endl;
2248 for (
int i=0; i<3; i++) cout <<
" " << pNew[i];
2251 }
else if (abs(sjbNew - sjb)/sab > check) {
2253 printOut(
"VinClu::map2to3II",
"ERROR! Invariants differ!");
2254 cout << scientific <<
" sjb (" << sjb <<
") fracdiff = "
2255 << abs(sjbNew-sjb)/sjb <<
" ydiff = " << abs(sjbNew-sjb)/sab
2256 << endl <<
" Old momenta are" << endl;
2257 for (
int i=0; i<2; i++) cout <<
" " << pOld[i];
2258 cout <<
" New momenta are" << endl;
2259 for (
int i=0; i<3; i++) cout <<
" " << pNew[i];
2267 Vec4 pSum = pOld[0] + pOld[1];
2268 Vec4 pRecSumBefore(0.,0.,0.,0.);
2269 Vec4 pRecSumAfter(0.,0.,0.,0.);
2270 for (
int i=0; i<(int)pRec.size(); i++){
2271 pRecSumBefore+=pRec[i];
2272 pRec[i].bstback(pSum);
2276 Vec4 pPrime = pNew[0] + pNew[2] - pNew[1];
2277 for (
int i=0; i<(int)pRec.size(); i++) {
2278 pRec[i].bst(pPrime, pPrime.mCalc());
2279 pRecSumAfter+=pRec[i];
2281 if(verbose >= superdebug) {
2282 Vec4 total= pOld[0]+pOld[1];
2283 cout <<
" Total In before" << total << endl
2284 <<
" Total Out before" << pRecSumBefore << endl;
2285 total = pNew[0] + pNew[2] - pNew[1];
2286 cout <<
" Total In After" << total << endl
2287 <<
" Total Out After" << pRecSumAfter << endl
2288 <<
" Total diff After" << total-pRecSumAfter << endl;
2298 bool VinciaCommon::map2to3IImassless(vector<Vec4>& pNew, vector<Vec4>& pRec,
2299 vector<Vec4>& pOld,
double sAB,
double saj,
double sjb,
double sab,
2302 if (verbose >= superdebug) printOut(__METHOD_NAME__,
"begin --------------");
2311 double sCM = m2(pOld[0] + pOld[1]);
2312 double fac = sqrt(sAB/sCM);
2313 double e0 = pOld[0].e();
2314 double e1 = pOld[1].e();
2315 if (abs(1. - fac) > TINY) {
2316 if (verbose >= 3 && abs(1. - fac) > 1.01)
2317 printOut(
"VinciaCommon::map2to3IImassless",
2318 "Warning: scaling AB so m2(AB) = sAB");
2322 int sign = pOld[0].pz() > 0 ? 1 : -1;
2324 pOld[0].pz(sign * e0);
2326 pOld[1].pz(-sign * e1);
2333 double rescaleFacA = sqrt(sab/(sAB+saj) * (1. + sjb/sAB));
2334 double rescaleFacB = sqrt(sab/(sAB+sjb) * (1. + saj/sAB));
2335 pNew[0].rescale4(rescaleFacA);
2336 pNew[2].rescale4(rescaleFacB);
2339 double preFacA = sjb*sqrt((sAB+sjb)/(sAB+saj)/sab/sAB);
2340 double preFacB = saj*sqrt((sAB+saj)/(sAB+sjb)/sab/sAB);
2341 double preFacT = sqrt(saj*sjb/sab);
2342 Vec4 pTrans(cos(phi), sin(phi), 0.0, 0.0);
2343 pNew[1] = preFacA*pOld[0] + preFacB*pOld[1] + preFacT*pTrans;
2346 if (verbose >= superdebug) {
2348 ss <<
"Invariants are: "
2349 << scientific <<
" sAB = " << sAB <<
" saj = " << saj
2350 <<
" sjb = " << sjb <<
" sab = " << sab;
2351 printOut(__METHOD_NAME__, ss.str());
2352 printOut(__METHOD_NAME__,
"Given momenta are");
2353 for (
int i = 0; i < 2; i++) cout <<
" " << pOld[i];
2354 printOut(__METHOD_NAME__,
"New momenta are");
2355 for (
int i = 0; i < 3; i++) cout <<
" " << pNew[i];
2359 double check = 1e-6;
2360 double sajNew = 2*pNew[0]*pNew[1];
2361 double sjbNew = 2*pNew[1]*pNew[2];
2362 double sabNew = 2*pNew[0]*pNew[2];
2363 if (abs(sabNew - sab)/sab > check) {
2365 printOut(
"VinciaCommon::map2to3IImassless",
"ERROR! Invariants differ!");
2366 cout << scientific <<
" sab (" << sab <<
") fracdiff = ydiff = "
2367 << abs(sabNew - sab)/sab << endl
2368 <<
" Old momenta are" << endl;
2369 for (
int i=0; i<2; i++) cout <<
" " << pOld[i];
2370 cout <<
" New momenta are" << endl;
2371 for (
int i=0; i<3; i++) cout <<
" " << pNew[i];
2374 }
else if (abs(sajNew - saj)/sab > check) {
2376 printOut(
"VinciaCommon::map2to3IImassless",
"ERROR! Invariants differ!");
2377 cout << scientific <<
" saj (" << saj <<
") fracdiff = "
2378 << abs(sajNew-saj)/saj <<
" ydiff = "<< abs(sajNew - saj)/sab
2379 << endl <<
" Old momenta are" << endl;
2380 for (
int i=0; i<2; i++) cout <<
" " << pOld[i];
2381 cout <<
" New momenta are" << endl;
2382 for (
int i=0; i<3; i++) cout <<
" " << pNew[i];
2385 }
else if ( abs(sjbNew-sjb)/sab > check ) {
2387 printOut(
"VinciaCommon::map2to3IImassless",
"ERROR! Invariants differ!");
2388 cout << scientific <<
" sjb (" << sjb <<
") fracdiff = "
2389 << abs(sjbNew-sjb)/sjb <<
" ydiff = "<< abs(sjbNew - sjb)/sab
2390 << endl <<
" Old momenta are" << endl;
2391 for (
int i=0; i<2; i++) cout <<
" " << pOld[i];
2392 cout <<
" New momenta are" << endl;
2393 for (
int i=0; i<3; i++) cout <<
" " << pNew[i];
2401 Vec4 pSum = pOld[0] + pOld[1];
2402 for (
int i=0; i<(int)pRec.size(); i++) pRec[i].bstback(pSum);
2405 Vec4 pPrime = pNew[0] + pNew[2] - pNew[1];
2406 for (
int i=0; i<(int)pRec.size(); i++) pRec[i].bst(pPrime);
2416 bool VinciaCommon::map2to3IFlocal(vector<Vec4>& pNew, vector<Vec4>& pOld,
2417 double sAK,
double saj,
double sjk,
double sak,
double phi,
2418 double mK2,
double mj2,
double mk2) {
2420 if (verbose >= superdebug) printOut(__METHOD_NAME__,
"begin --------------");
2423 if (verbose >= superdebug) {
2424 printOut(
"VinClu::map2to3IFlocal",
"Invariants are");
2425 cout <<
" sAK = " << sAK <<
" saj = " << saj
2426 <<
" sjk = " << sjk <<
" sak = " << sak << endl
2427 <<
" mK = " << sqrt(mK2) <<
" mj = " << sqrt(mj2)
2428 <<
" mk = " << sqrt(mk2) << endl
2429 <<
" Given momenta are" << endl;
2430 for (
int i=0; i<2; i++) cout <<
" " << pOld[i];
2434 double check = 1.e-3;
2435 double inv1Norm = (saj + sak)/(sAK + sjk);
2436 double inv2Norm = 1.0 + (mj2 + mk2 - mK2)/(sAK + sjk);
2437 double diff = abs(inv1Norm-inv2Norm);
2440 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__
2441 +
": Inconsistent invariants.",
"Aborting.");
2442 cout <<
" yaj + yak = " << inv1Norm
2443 <<
" 1 + muj2 + muk2 - muK2 = "<< inv2Norm
2444 <<
" Diff = " << diff << endl;
2446 infoPtr->setAbortPartonLevel(
true);
2451 double G = saj*sjk*sak - mj2*sak*sak - mk2*saj*saj;
2452 if (G < 0. || sak < 0.)
return false;
2455 Vec4 pSum = pOld[0] + pOld[1];
2456 Vec4 pOldBst = pOld[0];
2457 pOldBst.bstback(pSum);
2458 double thetaRot = pOldBst.theta();
2459 double phiRot = pOldBst.phi();
2460 Vec4 pTrans(cos(phi), sin(phi), 0.0, 0.0);
2463 pTrans.rot(thetaRot, phiRot);
2467 if (pTrans*pOld[0] > pOld[0][0]*1e-3 || pTrans*pOld[1] > pOld[1][0]*1e-3) {
2468 if (verbose >= normal) {
2469 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__
2470 +
": The transverse momentum is not transverse after boosting");
2474 double sig = sak + saj;
2475 double cj = (sig*(sak + mj2 - mk2) + mK2*(sak - saj) - sAK*sak)/(sAK*sig);
2476 double ck = (sig*(saj - mj2 + mk2) + mK2*(saj - sak) - sAK*saj)/(sAK*sig);
2477 double dj = saj/sig;
2478 double dk = sak/sig;
2482 pNew[0].rescale4(sig/sAK);
2483 pNew[1] = cj*pOld[0] + dj*pOld[1] + (sqrt(G)/sig)*pTrans;
2484 pNew[2] = ck*pOld[0] + dk*pOld[1] - (sqrt(G)/sig)*pTrans;
2487 double sakNew = pNew[0]*pNew[2]*2;
2488 double sajNew = pNew[0]*pNew[1]*2;
2489 double sjkNew = pNew[1]*pNew[2]*2;
2490 if (abs(sakNew - sak)/sak > check) {
2492 printOut(
"VinClu::map2to3IFlocal",
"ERROR! sak is inconsistent!");
2493 cout << scientific <<
" sak (" << sak <<
") diff = "
2494 << abs(sakNew-sak)/sak << endl
2495 <<
" Old momenta are" << endl;
2496 for (
int i=0; i<2; i++) cout <<
" " << pOld[i];
2497 cout <<
" New momenta are" << endl;
2498 for (
int i=0; i<3; i++) cout <<
" " << pNew[i];
2499 cout <<
"Masses: mK2 = " << mK2 <<
" mj2 = " << mj2
2500 <<
" mk2 = " << mk2 << endl;
2503 }
else if (abs(sajNew - saj)/saj > check) {
2504 if (verbose >= 2 ) {
2505 printOut(
"VinClu::map2to3IFlocal",
"ERROR! saj is inconsistent!");
2506 cout << scientific <<
" saj (" << saj <<
") diff = ";
2507 cout << abs(sajNew-saj)/saj << endl;
2508 cout <<
" Old momenta are" << endl;
2509 for (
int i=0; i<2; i++) cout <<
" " << pOld[i];
2510 cout <<
" New momenta are" << endl;
2511 for (
int i=0; i<3; i++) cout <<
" " << pNew[i];
2512 cout <<
"Masses: mK2 = " << mK2 <<
" mj2 = " << mj2
2513 <<
" mk2 = " << mk2 << endl;
2516 }
else if ( abs(sjkNew-sjk)/sjk > check ) {
2518 printOut(
"VinClu::map2to3IFlocal",
"ERROR! sjk is inconsistent!");
2519 cout << scientific <<
" sjk (" << sjk <<
") diff = ";
2520 cout << abs(sjkNew-sjk)/sjk << endl;
2521 cout <<
" Old momenta are" << endl;
2522 for (
int i=0; i<2; i++) cout <<
" " << pOld[i];
2523 cout <<
" New momenta are" << endl;
2524 for (
int i=0; i<3; i++) cout <<
" " << pNew[i];
2525 cout <<
"Masses: mK2 = " << mK2 <<
" mj2 = " << mj2
2526 <<
" mk2 = " << mk2 << endl;
2528 infoPtr->setAbortPartonLevel(
true);
2539 bool VinciaCommon::map2to3IFglobal(vector<Vec4>& pNew,
2540 vector<Vec4>& pRec, vector<Vec4>& pOld, Vec4 &pB,
2541 double sAK,
double saj,
double sjk,
double sak,
double phi,
2542 double mK2,
double mj2,
double mk2) {
2544 if (verbose >= superdebug) printOut(__METHOD_NAME__,
"begin --------------");
2549 Vec4 pSum = pOld[0] + pOld[1];
2550 Vec4 pAcm = pOld[0];
2552 double thetaRot = pAcm.theta();
2553 double phiRot = pAcm.phi();
2554 Vec4 pTrans(cos(phi), sin(phi), 0.0, 0.0);
2557 pTrans.rot(thetaRot, phiRot);
2561 if (pTrans*pOld[0] > pOld[0].e()*1e-3 || pTrans*pOld[1] > pOld[1].e()*1e-3) {
2562 if (verbose >= superdebug) {
2563 printOut(
"VinciaCommon:map2to3IFglobal",
2564 "The transverse momentum is not transverse after boosting");
2570 vector<double> v; v.resize(5);
2571 double sig = sAK - saj;
2573 v[1] = (saj*sjk)/(sAK*sig);
2575 v[3] = (saj*sak)/(sAK*sig);
2576 v[4] = sjk*saj*sak/pow2(sig);
2584 vector<double> f(5, 0);
2585 f[0] = v[0]*v[1]*sAK + pow2(v[1])*mK2 - v[4];
2586 f[1] = v[2]*v[3]*sAK + pow2(v[3])*mK2 - v[4] - mj2;
2587 f[2] = (v[0] - v[2] - 1)*(v[1] - v[3] + 1)*sAK
2588 + pow2(v[1] - v[3] + 1)*mK2 - mk2;
2589 f[3] = (v[0]*v[3] + v[1]*v[2])*sAK + 2*v[1]*v[3]*mK2 - 2*v[4] - saj;
2590 f[4] = (v[2]*(v[1] - v[3] + 1) + v[3]*(v[0] - v[2] - 1))*sAK
2591 + 2*v[3]*(v[1] - v[3] + 1)*mK2 - sjk;
2594 vector<vector<double> > A(5, vector<double>(5, 0));
2596 A[0][1] = v[0]*sAK + 2*v[1]*mK2;
2603 A[1][3] = v[2]*sAK + 2*v[3]*mK2;
2605 A[2][0] = (v[1] - v[3] + 1)*sAK;
2606 A[2][1] = (v[0] - v[2] - 1)*sAK + 2*(v[1] - v[3] + 1)*mK2;
2607 A[2][2] = -(v[1] - v[3] + 1)*sAK;
2608 A[2][3] = -( (v[0] - v[2] - 1)*sAK + 2*(v[1] - v[3] + 1)*mK2 );
2611 A[3][1] = v[2]*sAK + 2*v[3]*mK2;
2613 A[3][3] = v[0]*sAK + 2*v[1]*mK2;
2616 A[4][1] = v[2]*sAK + 2*v[3]*mK2;
2617 A[4][2] = (v[1] - 2*v[3] + 1)*sAK;
2618 A[4][3] = (v[0] - 2*v[2] - 1)*sAK + 2*(v[1] - 2*v[3] + 1)*mK2;
2623 for (
int i = 0; i < n; i++) {
2628 for (
int i = 0; i < n; i++) {
2630 double eleMax = abs(A[i][i]);
2632 for (
int k=i+1; k<n; k++) {
2633 if (abs(A[k][i]) > eleMax) {
2640 A[rowMax].swap(A[i]);
2643 for (
int k = i+1; k < n; k++) {
2644 double c = -A[k][i]/A[i][i];
2645 for (
int j = i; j < 2*n; j++) {
2649 A[k][j] += c * A[i][j];
2656 for (
int i = n-1; i >= 0; i--) {
2657 for (
int k = n; k < 2*n; k++) {
2660 for (
int j = i-1; j >= 0; j--) {
2661 for (
int k = n; k < 2*n; k++) {
2662 A[j][k] -= A[i][k] * A[j][i];
2668 for (
int i = 0; i < n; i++) {
2669 A[i].erase(A[i].begin(), A[i].begin()+n);
2673 vector<double> vNew(5, 0);
2674 for (
int i = 0; i < n; i++) {
2676 for (
int j=0; j<n; j++) {
2677 vNew[i] -= A[i][j]*f[j];
2683 for (
int i=0; i<n; i++) {
2684 if (abs(vNew[i] - v[i])/abs(v[i]) > eps) {
2685 eps = abs(vNew[i] - v[i])/abs(v[i]);
2691 if (nCount == 1000) {
return false;}
2692 if ((nCount%100) == 0) {
2693 for (
int i=0; i<n; i++) {
2694 v[i] *= (2*rndmPtr->flat() - 1);
2697 if (eps < 1E-6) {
break;}
2701 pNew[0] = v[0]*pOld[0] + v[1]*pOld[1] - sqrt(v[4])*pTrans;
2702 pNew[1] = v[2]*pOld[0] + v[3]*pOld[1] - sqrt(v[4])*pTrans;
2703 pNew[2] = (v[0] - v[2] - 1)*pOld[0] + (v[1] - v[3] + 1)*pOld[1];
2713 for (
int i=0; i<3; i++) {
2715 pNew[i] += pB*((pa*p)/qaB) - pa*((pB*p)/qaB) + pA*((pB*p)/qAB)
2716 - pB*((pA*p)/qAB) + pB*(qAa*(pB*p)/(qAB*qaB));
2720 double ea = pNew[i].e();
2721 double sign = (pNew[0].pz() > 0) ? 1 : -1;
2722 pNew[0] = Vec4(0, 0, sign*ea, ea);
2727 for (
int i=0; i<(int)pRec.size(); i++) {
2729 pRec[i] += pB*((pa*p)/qaB) - pa*((pB*p)/qaB) + pA*((pB*p)/qAB)
2730 - pB*((pA*p)/qAB) + pB*(qAa*(pB*p)/(qAB*qaB));
2732 double sajNew = 2*pNew[0]*pNew[1];
2733 double sjkNew = 2*pNew[1]*pNew[2];
2734 double sakNew = 2*pNew[0]*pNew[2];
2736 if (abs(sajNew - saj)/saj > 1E-3)
2737 printOut(
"VinciaCommon:map2to3IFglobal",
"saj not quite correct");
2738 if (abs(sjkNew - sjk)/sjk > 1E-3)
2739 printOut(
"VinciaCommon:map2to3IFglobal",
"sjk not quite correct");
2740 if (abs(sakNew - sak)/sak > 1E-3)
2741 printOut(
"VinciaCommon:map2to3IFglobal",
"sak not quite correct");
2750 bool VinciaCommon::map2to3RFmassive(vector<Vec4>& pNew, vector<Vec4>& pRec,
2751 vector<Vec4> pOld,
double saj,
double sjk,
double phi,
2752 double mA2 = 0.0,
double mj2 = 0.0,
double mK2 = 0.0) {
2755 if (pOld.size() != 2) {
return false;}
2756 Vec4 pABefore = pOld[0];
2757 Vec4 pKBefore = pOld[1];
2758 Vec4 pAKBefore = pABefore - pKBefore;
2759 Vec4 pACoM = pABefore;
2760 double sAK = 2.0*pABefore*pKBefore;
2761 double sak = sAK - saj + sjk;
2764 if (sak < 0) {
return false;}
2765 if (saj*sjk*sak - mA2*sjk*sjk - mj2*sak*sak - mK2*saj*saj < 0)
return false;
2768 pKBefore.bstback(pABefore);
2769 pAKBefore.bstback(pABefore);
2770 pACoM.bstback(pABefore);
2773 double EjAfter = saj/(2.0*sqrt(mA2));
2774 double pVecjAfter = sqrt(pow2(EjAfter) - mj2);
2775 double EkAfter = sak/(2.0*sqrt(mA2));
2776 double pVeckAfter = sqrt(pow2(EkAfter) - mK2);
2777 double cosTheta = (2.*EjAfter*EkAfter - sjk)/2./pVecjAfter/pVeckAfter;
2778 if (abs(cosTheta) > 1) {
return false;}
2779 double sinTheta = sqrt(1.0 - cosTheta*cosTheta);
2782 Vec4 pkAfter(0., 0., pVeckAfter, EkAfter);
2783 Vec4 pjAfter(pVecjAfter*sinTheta*cos(phi), pVecjAfter*sinTheta*sin(phi),
2784 pVecjAfter*cosTheta, EjAfter);
2785 Vec4 pajkAfter = pACoM - pkAfter - pjAfter;
2788 pkAfter.bst(pABefore);
2789 pjAfter.bst(pABefore);
2790 pajkAfter.bst(pABefore, sqrt(mA2));
2792 pNew.push_back(pABefore);
2793 pNew.push_back(pjAfter);
2794 pNew.push_back(pkAfter);
2797 if (pRec.size() == 1) {
2798 pRec[0] = pajkAfter;
2803 for(
int i=0; i<(int)pRec.size(); i++) {
2804 pRec[i].bstback(pAKBefore);
2805 pRec[i].bst(pajkAfter);
2816 bool VinciaCommon::onShellCM(Vec4& p1, Vec4& p2,
double m1,
double m2,
2819 double s1 = pow2(m1);
2820 double s2 = pow2(m2);
2821 double s01 = Vec4(p1+p2).m2Calc();
2822 double s1Calc = p1.m2Calc();
2823 double s2Calc = p2.m2Calc();
2824 if (abs(s1Calc-s1)/s01 > tol || abs(s2Calc-s2)/s01 > tol) {
2826 printOut(
"VinClu::onShellCM",
"forcing particles on mass shell");
2828 M.fromCMframe(p1,p2);
2831 double E0 = (s01 + s1 - s2)/(2*sqrt(s01));
2832 double E1 = (s01 - s1 + s2)/(2*sqrt(s01));
2833 double pz = pow2(E0)-s1;
2834 Vec4 p1new = Vec4(0.0,0.0,-pz,E0);
2835 Vec4 p2new = Vec4(0.0,0.0,pz,E1);
2838 double s1Test = p1new.m2Calc();
2839 double s2Test = p2new.m2Calc();
2841 cout <<
" p1 : " << p1 <<
" p1new: " << p1new
2842 <<
" p2 : " << p1 <<
" p2new: " << p1new;
2846 if (abs(s1Test-s1)/s01 <= abs(s1Calc-s1)/s01
2847 && abs(s2Test-s2)/s01 <= abs(s2Calc-s2)/s01) {
2864 bool VinciaCommon::mapToMassless(
int iSys,
Event& event,
2865 PartonSystems* partonSystemsPtr,
bool makeNewCopies) {
2868 if (makeNewCopies) {
2874 if (partonSystemsPtr->hasInAB(iSys)) {
2875 iOld = partonSystemsPtr->getInA(iSys);
2876 iNew =
event.copy(iOld,-42);
2877 partonSystemsPtr->replace(iSys, iOld, iNew);
2878 iOld = partonSystemsPtr->getInB(iSys);
2879 iNew =
event.copy(iOld,-42);
2880 partonSystemsPtr->replace(iSys, iOld, iNew);
2885 for (
int i=0; i<partonSystemsPtr->sizeOut(iSys); ++i) {
2886 iOld = partonSystemsPtr->getOut(iSys,i);
2887 iNew =
event.copy(iOld, 52);
2892 if (partonSystemsPtr->hasInAB(iSys) ) {
2893 int iA = partonSystemsPtr->getInA(iSys);
2894 int iB = partonSystemsPtr->getInB(iSys);
2895 if (event[iA].mCalc() != 0.0 || event[iB].mCalc() != 0.0) {
2898 if (event[iA].pz() < 0 || event[iB].pz() > 0) {
2899 iA = partonSystemsPtr->getInB(iSys);
2900 iB = partonSystemsPtr->getInA(iSys);
2904 if (event[iA].pT() > 1.e-6 || event[iB].pT() > 1.e-6) {
2905 cout<<
"Vincia::VinciaCommon::mapToMassless) Error: incoming partons "
2906 "have nonvanishing transverse momenta for system iSys = "
2907 <<iSys<<
"; giving up"<<endl;
2912 if (verbose > superdebug) {
2914 ss<<
"Warning: forcing initial"
2915 "-state partons to be massless for system "<<iSys;
2916 printOut(__METHOD_NAME__,ss.str());
2920 double pPos =
event[iA].pPos() +
event[iB].pPos();
2921 double pNeg =
event[iA].pNeg() +
event[iB].pNeg();
2922 event[iA].pz( 0.5 * pPos);
2923 event[iA].e ( 0.5 * pPos);
2925 event[iB].pz(-0.5 * pNeg);
2926 event[iB].e ( 0.5 * pNeg);
2932 if (partonSystemsPtr->sizeOut(iSys) >= 2) {
2933 vector<Vec4> momenta;
2934 vector<double> massOrg;
2935 bool makeMassless =
false;
2937 for (
int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
2938 momenta.push_back(event[partonSystemsPtr->getOut(iSys,i)].p());
2939 massOrg.push_back(event[partonSystemsPtr->getOut(iSys,i)].m());
2940 if (massOrg[i] > 0. && event[partonSystemsPtr->getOut(iSys,i)].idAbs()
2941 <= nFlavZeroMass) makeMassless =
true;
2942 pSysOrg += momenta[i];
2945 if (!makeMassless)
return true;
2948 vector<Vec4> momentaOrg = momenta;
2951 double sCM = m2(pSysOrg);
2952 bool isInCM = ( pow2(pSysOrg.pAbs())/sCM < 1e-10 );
2954 for (
int i=0; i<(int)momenta.size(); ++i) momenta[i].bstback(pSysOrg);
2961 for (
int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
2962 int ip = partonSystemsPtr->getOut(iSys,i);
2963 if (event[ip].idAbs() <= nFlavZeroMass && event[ip].m() != 0.) {
2964 double facInv = momenta[i].pAbs()/momenta[i].e();
2968 printOut(
"VinciaCommon:mapToMassless",
2969 "Remap failed. Particle is spacelike or at rest.");
2971 for (
int j=0; j < partonSystemsPtr->sizeOut(iSys); ++j)
2972 event[partonSystemsPtr->getOut(iSys,j)].m(massOrg[j]);
2976 momenta[i].rescale3(1./facInv);
2979 double mNew = momenta[i].mCalc();
2980 if (pow2(mNew/momenta[i].e()) > TINY) {
2981 printOut(
"VinciaCommon:mapToMassless",
"Warning: rounding problem.");
2983 cout<<scientific <<
"(p,e) = "<<momenta[i].pAbs() <<
" "
2984 << momenta[i].e() <<
" facInv = " << facInv
2985 <<
" 1/facInv = " << 1./facInv <<
" mNew = " << mNew << endl;
2991 pSysNew += momenta[i];
2996 Vec4 delta = pSysOrg - pSysNew;
2997 if (delta.e()/sqrt(sCM) < TINY && delta.pAbs()/sqrt(sCM) < TINY) {
2999 for (
int i = 0; i < (int)momenta.size(); ++i)
3000 event[partonSystemsPtr->getOut(iSys,i)].p(momenta[i]);
3001 if (verbose >= superdebug)
3002 printOut(
"VinciaCommon:mapToMassless",
"No further rescalings needed.");
3005 if (!checkCoM(iSys,event,partonSystemsPtr)) {
3006 infoPtr->setAbortPartonLevel(
true);
3007 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__+
3008 ": Failed (E,p) conservation check.",
"Aborting.");
3016 double sCMnew = m2(pSysNew);
3017 double scaleFac = sqrt(sCM/sCMnew);
3018 if (verbose >= 7 && pow2(scaleFac-1.0) > TINY)
3019 printOut(
"VinciaCommon:mapToMassless",
3020 "Rescaling 4-vectors to restore eCM");
3022 for (
int i = 0; i < (int)momenta.size(); ++i) {
3023 momenta[i].rescale4(scaleFac);
3024 pSysNewB += momenta[i];
3026 double sCMnewB = m2(pSysNewB);
3027 if (verbose >= superdebug)
3028 cout <<
"old CM energy = " << sqrt(sCM) <<
" intermediate CM energy = "
3029 << sqrt(sCMnew) <<
" new CM energy = " << sqrt(sCMnewB) << endl;
3032 printOut(
"VinciaCommon:mapToMassless",
"Boosting back to CM frame");
3033 for (
int i=0; i<(int)momenta.size(); ++i) {
3035 momenta[i].bstback(pSysNewB);
3037 if (!isInCM) momenta[i].bst(pSysOrg);
3040 event[partonSystemsPtr->getOut(iSys,i)].p(momenta[i]);
3046 cout <<
"Final configuration:" << endl;
3047 for (
int i = 0; i < (int)momenta.size(); ++i)
3048 cout <<
" " << i <<
" " << momenta[i];
3054 if(!checkCoM(iSys, event,partonSystemsPtr)){
3055 infoPtr->setAbortPartonLevel(
true);
3056 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__
3057 +
": Failed (E,p) conservation check.",
"Aborting.");
3070 bool VinciaCommon::checkCoM(
int iSys,
Event& event,
3071 PartonSystems* partonSystemsPtr){
3072 Vec4 total(0.,0.,0.,0.);
3073 if (!partonSystemsPtr->hasInRes(iSys)){
3074 if (partonSystemsPtr->getInA(iSys) > 0)
3075 total+= event[partonSystemsPtr->getInA(iSys)].p();
3076 if (partonSystemsPtr->getInB(iSys) > 0)
3077 total+= event[partonSystemsPtr->getInB(iSys)].p();
3078 }
else total+=
event[partonSystemsPtr->getInRes(iSys)].p();
3079 double sysMass = total.mCalc();
3082 for(
int iPart=0; iPart<partonSystemsPtr->sizeOut(iSys); iPart++){
3083 int iOut = partonSystemsPtr->getOut(iSys,iPart);
3086 if (event[iOut].isFinal()) total -=
event[iOut].p();
3089 ss <<
"iSys = " << iSys <<
" iOut = " << iOut;
3090 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__
3091 +
": isFinal()=false for outgoing parton.",ss.str());
3092 partonSystemsPtr->list();
3098 if(abs(total.e()) > SMALL || abs(total.px()) > SMALL
3099 || abs(total.py()) > SMALL || abs(total.pz()) > SMALL) {
3101 cout <<
"total = " << setprecision(10) << total.e() <<
" " << total.px()
3102 <<
" " << total.py() <<
" " << total.pz() << endl;
3103 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__
3104 +
" Failed (E,p) conservation check.");
3106 }
else if(isnan(total)){
3108 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__
3109 +
" Failed (E,p) isnan check.");
3123 TXiFunctor::TXiFunctor(vector<double> mIn, vector<double> energiesIn) {
3124 if (mIn.size() != energiesIn.size()) {
3125 m = vector<double>(0); energies = vector<double>(0);
3126 }
else {m = mIn; energies = energiesIn;}
3129 double TXiFunctor::operator() (
double xi) {
3131 for (vector<double>::size_type i = 0; i < m.size(); i++)
3132 retval += sqrt( pow2(m[i]) + pow2(xi)*pow2(energies[i]));
3144 double m(
const Vec4& v) {
3145 double s = m2(v);
return (s >= 0) ? sqrt(s) : -sqrt(-s);}
3147 double m2(
const Vec4& v) {
3148 return pow2(v.e()) - pow2(v.px()) - pow2(v.py()) - pow2(v.pz());}
3150 double m2(
const Vec4& v1,
const Vec4& v2,
const Vec4& v3) {
3151 return pow2(v1.e() + v2.e() + v3.e())
3152 - pow2(v1.px() + v2.px() + v3.px())
3153 - pow2(v1.py() + v2.py() + v3.py())
3154 - pow2(v1.pz() + v2.pz() + v3.pz());}
3156 double m2(
const Vec4& v1,
const Vec4& v2,
const Vec4& v3,
const Vec4& v4) {
3157 return pow2(v1.e() + v2.e() + v3.e() + v4.e())
3158 - pow2(v1.px() + v2.px() + v3.px() + v4.px())
3159 - pow2(v1.py() + v2.py() + v3.py() + v4.py())
3160 - pow2(v1.pz() + v2.pz() + v3.pz() + v4.pz());}
3162 double m2(
const Particle& p1,
const Particle& p2,
const Particle& p3) {
3163 return m2(p1.p(), p2.p(), p3.p());}
3165 double dot4(
const Particle& p1,
const Particle& p2) {
return p1.p()*p2.p();}
3167 double getCosTheta(
double E1,
double E2,
double m1,
double m2,
double s12){
3168 return (2.0*E1*E2 - s12)/(2.0*sqrt(E1*E1 - m1*m1)*sqrt(E2*E2 - m2*m2));}
3174 string num2str(
int i,
int width) {
3176 if (width <= 1) tmp << i;
3177 else if (abs(i) < pow(10.0, width - 1) || ( i > 0 && i < pow(10.0, width)))
3178 tmp << fixed << setw(width) << i;
3182 if (abs(i) < 1e5) {r/=1e3;}
3183 else if (abs(i) < 1e8) {r/=1e6; ab =
"M";}
3184 else if (abs(i) < 1e11) {r/=1e9; ab =
"G";}
3185 else if (abs(i) < 1e14) {r/=1e12; ab =
"T";}
3186 tmp << fixed << setw(width - 1)
3187 << (r > 10 ? setprecision(width-4) : setprecision(width-3)) << r << ab;
3192 string num2str(
double r,
int width) {
3194 if (width <= 0) tmp << r;
3195 else if (r == 0.0 || (abs(r) > 0.1 && abs(r) < pow(10., max(width-3,1)))
3196 || width <= 8) tmp << fixed << setw(max(width,3))
3197 << setprecision(min(3, max(1, width - 2))) << r;
3198 else tmp << scientific << setprecision(max(2, width - 7))
3199 << setw(max(9, width)) << r;
3203 string bool2str(
bool b,
int width) {
3204 string tmp = b ?
"on" :
"off";
3205 int nPad = width - tmp.length();
3206 for (
int i = 1; i <= nPad; ++i) tmp =
" " + tmp;
3210 void printOut(
string place,
string message) {
3211 cout.setf(ios::internal);
3212 cout <<
" (" << (place +
") ") << message <<
"\n";
3219 double gramDet(
double s01tilde,
double s12tilde,
double s02tilde,
3220 double m0,
double m1,
double m2) {
3221 return ((s01tilde*s12tilde*s02tilde - pow2(s01tilde)*pow2(m2)
3222 - pow2(s02tilde)*pow2(m1) - pow2(s12tilde)*pow2(m0))/4
3223 + pow2(m0)*pow2(m1)*pow2(m2));
3226 double gramDet(Vec4 p0, Vec4 p1, Vec4 p2) {
3227 return gramDet(2*p0*p1, 2*p1*p2, 2*p0*p2, p0.mCalc(), p1.mCalc(),
3236 double Li2(
const double x,
const double kmax,
const double xerr) {
3237 if (x < 0.0)
return 0.5*Li2(x*x) - Li2(-x);
3239 double sum(x), term(x);
3240 for (
int k = 2; k < kmax; k++) {
3241 double rk = (k-1.0)/k;
3244 if (abs(term/sum) < xerr)
return sum;
3246 cout <<
"Maximum number of iterations exceeded in Li2" << endl;
3249 if (x < 1.0)
return M_PI*M_PI/6.0 - Li2(1.0 - x) - log(x)*log(1.0 - x);
3250 if (x == 1.0)
return M_PI*M_PI/6.0;
3252 const double eps(x - 1.0), lne(log(eps)),
3253 c0(M_PI*M_PI/6.0), c1( 1.0 - lne),
3254 c2(-(1.0 - 2.0*lne)/4.0), c3( (1.0 - 3.0*lne)/9.0),
3255 c4(-(1.0 - 4.0*lne)/16.0), c5( (1.0 - 5.0*lne)/25.0),
3256 c6(-(1.0 - 6.0*lne)/36.0), c7( (1.0 - 7.0*lne)/49.0),
3257 c8(-(1.0 - 8.0*lne)/64.0);
3258 return c0 + eps*(c1 + eps*(c2 + eps*(c3 + eps*(c4 + eps*(c5 + eps*(
3259 c6 + eps*(c7 + eps*c8)))))));
3261 double logx = log(x);
3262 if (x<=2.0)
return M_PI*M_PI/6.0 + Li2(1.0 - 1.0/x) -
3263 logx*(log(1.0 - 1.0/x) + 0.5*logx);
3264 return M_PI*M_PI/3.0 - Li2(1.0/x) - 0.5*logx*logx;
3269 double factorial(
const int n) {
3271 for (
int i = 2; i <= n; i++) fac *= i;
3275 int binomial(
const int n,
const int m) {
3276 if (m < 0 || m > n)
return 0;
3277 else if (m == n || m == 0)
return 1;
3278 else if (m == 1 || m == n - 1)
return n;
3279 else return factorial(n)/factorial(m)/factorial(n - m) + 0.01;
3291 double LambertW(
const double x) {
3292 if (x == 0.)
return 0.;
3294 cout <<
"Warning in "<<__METHOD_NAME__
3295 <<
": Accuracy less than three decimal places for x < -0.2";
3296 }
else if (x > 10.) {
3297 cout <<
"Warning in "<<__METHOD_NAME__
3298 <<
": Accuracy less than three decimal places for x > 10.";
3300 return x*(1. + x*(2.445053 + x*(1.343664 + x*(0.14844 + 0.000804*x))))
3301 /(1. + x*(3.444708 + x*(3.292489 + x*(0.916460 + x*(0.053068)))));
3305 double zbrent(TFunctor& fun,
double r,
double x1,
double x2,
double tol) {
3307 double a(x1), b(x2), c(x2), d(x2-x1), e(x2-x1), min1, min2;
3308 double fa(fun(a) - r), fb(fun(b) - r), fc, p, q, r1, s, tol1, xm;
3309 double REALTINY = min(TINY, 1e-12);
3310 tol = max(tol, REALTINY);
3313 if (fa*fb > 0)
return 0.0;
3317 for (iter = 1; iter < max(1000,
int(1.0/sqrt(tol))); iter++) {
3318 if ((fb > 0.0 && fc > 0.0) || (fb < 0.0 && fc < 0.0)) {
3319 c = a; fc = fa; e = d = b-a;
3321 if (abs(fc) < abs(fb)) {
3322 a = b; b = c; c= a; fa = fb; fb = fc; fc = fa;
3324 tol1 = 2.0*REALTINY*abs(b) + 0.5*tol;
3326 if (abs(xm) <= tol1 || fb == 0.0)
return b;
3327 if (abs(e) >= tol1 && abs(fa) > abs(fb)) {
3329 if (a == c) {p = 2.0*xm*s; q = 1.0-s;}
3331 q = fa/fc; r1 = fb/fc;
3332 p = s*(2.0*xm*q*(q - r1) - (b - a)*(r1 - 1.0));
3333 q = (q - 1.0)*(r1 - 1.0)*(s - 1.0);
3335 if (p > 0.0) q = -q;
3337 min1 = 3.0*xm*q - abs(tol1*q);
3339 if (2.0*p < (min1 < min2 ? min1 : min2)) {e = d; d= p/q;}
3340 else {d = xm; e = d;}
3341 }
else {d = xm; e = d;}
3344 b += abs(d) > tol1 ? d : (xm > 1) ? tol1 : - tol1;
3347 cerr <<
"(brent:) -> Maximum number of iterations exceeded" << endl;