26 void Clustering::list()
const {
27 cout <<
" emt " << emitted
29 <<
" rec " << recoiler
30 <<
" partner " << partner
31 <<
" pTscale " << pTscale << endl;
64 History::History(
int depth,
68 MergingHooks* mergingHooksPtrIn,
71 ParticleData* particleDataPtrIn,
73 bool isOrdered =
true,
74 bool isStronglyOrdered =
true,
80 foundOrderedPath(false),
81 foundStronglyOrderedPath(false),
82 foundCompletePath(false),
86 mergingHooksPtr(mergingHooksPtrIn),
89 particleDataPtr(particleDataPtrIn),
96 if(mother && mergingHooksPtr->includeRedundant()) prob *= pdfForSudakov();
101 double acoll = (mother->state[clusterIn.emittor].isFinal())
102 ? mergingHooksPtr->herwigAcollFSR()
103 : mergingHooksPtr->herwigAcollISR();
104 sumScalarPT = mother->sumScalarPT + acoll*scale;
110 vector<Clustering> clusterings;
111 if ( depth > 0 ) clusterings = getAllClusterings();
115 if ( clusterings.empty() ) {
116 registerPath(*
this, isOrdered, isStronglyOrdered, depth == 0);
122 multimap<double, Clustering *> sorted;
123 for (
int i = 0, N = clusterings.size(); i < N; ++i ) {
124 sorted.insert(make_pair(clusterings[i].pT(), &clusterings[i]));
127 for ( multimap<double, Clustering *>::iterator it = sorted.begin();
128 it != sorted.end(); ++it ) {
132 bool stronglyOrdered = isStronglyOrdered;
133 if ( mergingHooksPtr->enforceStrongOrdering() &&
136 &&(it->first < mergingHooksPtr->scaleSeparationFactor()*scale )))){
137 if ( onlyStronglyOrderedPaths() )
continue;
138 stronglyOrdered =
false;
141 bool ordered = isOrdered;
142 if(mergingHooksPtr->orderInRapidity()){
144 double z = getCurrentZ((*it->second).emittor,
145 (*it->second).recoiler,(*it->second).emitted);
147 double zOld = (!mother) ? 0. : mother->getCurrentZ(clusterIn.emittor,
148 clusterIn.recoiler,clusterIn.emitted);
151 if ( !ordered || ( mother && (it->first < scale
152 || it->first < pow(1. - z,2) / (z * (1. - zOld ))*scale ))) {
153 if ( onlyOrderedPaths() )
continue;
160 if ( !ordered || ( mother && (it->first < scale) ) ) {
161 if ( onlyOrderedPaths() )
continue;
167 if( mergingHooksPtr->canCutOnRecState()
168 && mergingHooksPtr->doCutOnRecState(cluster(*it->second)) ){
174 children.push_back(
new History(depth - 1,it->first,cluster(*it->second),
175 *it->second, mergingHooksPtr, beamA, beamB, particleDataPtr,
176 infoPtr, ordered, stronglyOrdered, prob*getProb(*it->second),
193 double History::weightTREE(PartonLevel* trial, AlphaStrong * asFSR,
194 AlphaStrong * asISR,
double RN){
197 double asME = infoPtr->alphaS();
198 double maxScale = (foundCompletePath) ? infoPtr->eCM() : infoPtr->QFac();
201 History * selected = select(RN);
203 selected->setScalesInHistory();
213 double asWeight = 1.;
214 double pdfWeight = 1.;
217 double wt = selected->weightTree(trial,asME,maxScale, asFSR,
218 asISR, asWeight, pdfWeight);
220 return (wt*asWeight*pdfWeight);
227 void History::getStartingConditions(
const double RN,
Event& outState ) {
230 History * selected = select(RN);
236 if(!selected->mother){
238 for(
int i=0; i < int(outState.size()); ++i)
239 if(outState[i].isFinal()) nFinal++;
241 outState.scale(infoPtr->QFac());
258 if(mergingHooksPtr->getNumberOfClusteringSteps(state) == 0) {
259 infoPtr->zNowISR(0.5);
260 infoPtr->pT2NowISR(pow(state[0].e(),2));
261 infoPtr->hasHistory(
true);
264 infoPtr->zNowISR(selected->zISR());
265 infoPtr->pT2NowISR(pow(selected->pTISR(),2));
266 infoPtr->hasHistory(
true);
274 infoPtr->zNowISR(selected->zISR());
275 infoPtr->pT2NowISR(pow(selected->pTISR(),2));
276 infoPtr->hasHistory(
true);
285 double History::getPDFratio(
int side,
bool forSudakov,
286 int flavNum,
double xNum,
double muNum,
287 int flavDen,
double xDen,
double muDen) {
290 if( abs(flavNum) > 10 && flavNum != 21 )
return 1.0;
291 if( abs(flavDen) > 10 && flavDen != 21 )
return 1.0;
294 double pdfRatio = 1.0;
303 pdfNum = mother->beamA.xfISR(0, flavNum, xNum, muNum*muNum);
305 pdfNum = beamA.xfISR(0, flavNum, xNum, muNum*muNum);
307 pdfDen = max(1e-10, beamA.xfISR(0, flavDen, xDen, muDen*muDen));
309 pdfDen = max(1e-10, beamA.xfISR(0, flavDen, xDen, muDen*muDen));
313 pdfNum = mother->beamB.xfISR(0, flavNum, xNum, muNum*muNum);
315 pdfNum = beamB.xfISR(0, flavNum, xNum, muNum*muNum);
318 pdfDen = max(1e-10,beamB.xfISR(0, flavDen, xDen, muDen*muDen));
320 pdfDen = max(1e-10,beamB.xfISR(0, flavDen, xDen, muDen*muDen));
324 if( pdfNum > 1e-15 && pdfDen > 1e-10 )
325 pdfRatio *= pdfNum / pdfDen;
327 infoPtr->errorMsg(
"Warning in History:getPDFratio: Found tiny PDF in",
328 "calculation of PDF ratio, put PDF ratio to 1.");
343 void History::setScalesInHistory() {
350 setScales(ident,
true);
365 void History::findPath(vector<int>& out) {
368 if(!mother &&
int(children.size()) < 1)
return;
373 int size = int(mother->children.size());
375 for (
int i=0; i < size; ++i){
376 if( mother->children[i]->scale == scale
377 && mother->children[i]->prob == prob
378 && equalClustering(mother->children[i]->clusterIn,clusterIn)) {
385 out.push_back(iChild);
386 mother->findPath(out);
411 void History::setScales( vector<int> index,
bool forward) {
415 if( children.empty() && forward ){
418 double scaleNew = 1.;
420 if(mergingHooksPtr->incompleteScalePrescip()==0){
421 scaleNew = infoPtr->QFac();
422 }
else if(mergingHooksPtr->incompleteScalePrescip()==1){
425 for(
int i=0; i<int(state.size()); ++i)
426 if(state[i].isFinal())
427 pOut += state[i].p();
428 scaleNew = pOut.mCalc();
429 }
else if (mergingHooksPtr->incompleteScalePrescip()==2){
430 scaleNew = state[0].e();
433 scaleNew = max( mergingHooksPtr->pTcut(), scaleNew);
435 state.scale(scaleNew);
436 for(
int i=3; i < int(state.size());++i)
437 if(state[i].colType() != 0)
438 state[i].scale(scaleNew);
442 state.scale( state[0].e() );
444 bool isLEP = ( state[3].isLepton() && state[4].isLepton() );
446 vector<int> finalPartons;
447 for(
int i=0; i < int(state.size());++i) {
448 if(state[i].isFinal() && state[i].colType() != 0){
449 finalPartons.push_back(i);
451 if(state[i].isFinal() && state[i].colType() == 0){
457 if(!isLEP && isQCD &&
int(finalPartons.size()) == 2)
458 state.scale(state[finalPartons[0]].pT());
464 if(mother && forward) {
466 double scaleNew = 1.;
467 if(mergingHooksPtr->unorderedScalePrescip() == 0){
469 scaleNew = max( mergingHooksPtr->pTcut(), max(scale,mother->scale));
470 }
else if (mergingHooksPtr->unorderedScalePrescip() == 1){
472 if(scale < mother->scale)
473 scaleNew *= max( mergingHooksPtr->pTcut(), min(scale,mother->scale));
475 scaleNew *= max( mergingHooksPtr->pTcut(), max(scale,mother->scale));
480 mother->state[clusterIn.emitted].scale(scaleNew);
481 mother->state[clusterIn.emittor].scale(scaleNew);
482 mother->state[clusterIn.recoiler].scale(scaleNew);
486 mother->scaleCopies(clusterIn.emitted, mother->state, scaleNew);
487 mother->scaleCopies(clusterIn.emittor, mother->state, scaleNew);
488 mother->scaleCopies(clusterIn.recoiler, mother->state, scaleNew);
491 mother->setScales(index,
true);
496 if(!mother || !forward) {
499 if(
int(index.size()) > 0 ) {
500 iChild = index.back();
506 scale = max(mergingHooksPtr->pTcut(), scale);
509 if(iChild != -1 && !children.empty()) {
511 if(scale > children[iChild]->scale ) {
512 if(mergingHooksPtr->unorderedScalePrescip() == 0){
514 double scaleNew = max( mergingHooksPtr->pTcut(),
515 max(scale,children[iChild]->scale));
517 for(
int i = 0; i < int(children[iChild]->state.size()); ++i)
518 if(children[iChild]->state[i].scale() == children[iChild]->scale)
519 children[iChild]->state[i].scale(scaleNew);
521 children[iChild]->scale = scaleNew;
523 }
else if( mergingHooksPtr->unorderedScalePrescip() == 1){
525 double scaleNew = max(mergingHooksPtr->pTcut(),
526 min(scale,children[iChild]->scale));
528 for(
int i = 0; i < int(state.size()); ++i)
529 if(state[i].scale() == scale)
530 state[i].scale(scaleNew);
536 double scalemin = state[0].e();
537 for(
int i = 0; i < int(state.size()); ++i)
538 if(state[i].colType() != 0)
539 scalemin = max(mergingHooksPtr->pTcut(),
540 min(scalemin,state[i].scale()));
541 state.scale(scalemin);
542 scale = max(mergingHooksPtr->pTcut(), scale);
545 children[iChild]->setScales(index,
false);
561 void History::scaleCopies(
int iPart,
const Event& refEvent,
double rho) {
566 for(
int i=0; i < mother->state.size(); ++i) {
567 if( ( mother->state[i].id() == refEvent[iPart].id()
568 && mother->state[i].colType() == refEvent[iPart].colType()
569 && mother->state[i].chargeType() == refEvent[iPart].chargeType()
570 && mother->state[i].col() == refEvent[iPart].col()
571 && mother->state[i].acol() == refEvent[iPart].acol() )
574 mother->state[i].scale(rho);
577 mother->scaleCopies( iPart, refEvent, rho );
590 void History::setEventScales() {
594 mother->state.scale(scale);
596 mother->setEventScales();
606 double History::zISR() {
609 if (!mother)
return 0.0;
611 if (mother->state[clusterIn.emittor].isFinal())
return mother->zISR();
613 int rad = clusterIn.emittor;
614 int rec = clusterIn.recoiler;
615 int emt = clusterIn.emitted;
616 double z = (mother->state[rad].p() + mother->state[rec].p()
617 - mother->state[emt].p()).m2Calc()
618 / (mother->state[rad].p() + mother->state[rec].p()).m2Calc();
620 double znew = mother->zISR();
622 if(znew > 0.) z = znew;
633 double History::zFSR() {
636 if (!mother)
return 0.0;
638 if (!mother->state[clusterIn.emittor].isFinal())
return mother->zFSR();
640 int rad = clusterIn.emittor;
641 int rec = clusterIn.recoiler;
642 int emt = clusterIn.emitted;
644 Vec4 sum = mother->state[rad].p() + mother->state[rec].p()
645 + mother->state[emt].p();
646 double m2Dip = sum.m2Calc();
647 double x1 = 2. * (sum * mother->state[rad].p()) / m2Dip;
648 double x3 = 2. * (sum * mother->state[emt].p()) / m2Dip;
650 double z = x1/(x1+x3);
652 double znew = mother->zFSR();
654 if(znew > 0.) z = znew;
665 double History::pTISR() {
667 if (!mother)
return 0.0;
669 if(mother->state[clusterIn.emittor].isFinal())
return mother->pTISR();
670 double pT = mother->state.scale();
672 double pTnew = mother->pTISR();
674 if(pTnew > 0.) pT = pTnew;
685 double History::pTFSR() {
687 if (!mother)
return 0.0;
689 if (!mother->state[clusterIn.emittor].isFinal())
return mother->pTFSR();
690 double pT = mother->state.scale();
692 double pTnew = mother->pTFSR();
694 if(pTnew > 0.) pT = pTnew;
705 History * History::select(
double rnd) {
706 if ( paths.empty() )
return 0;
708 if(mergingHooksPtr->pickBySumPT()){
711 for (
int i=0; i < state.size(); ++i)
712 if(state[i].isFinal())
715 double sumMin = (nFinal-2)*state[0].e();
716 for ( map<double, History*>::iterator it = paths.begin();
717 it != paths.end(); ++it ){
719 if(it->second->sumScalarPT < sumMin){
720 sumMin = it->second->sumScalarPT;
725 return paths.lower_bound(iMin)->second;
728 return paths.upper_bound(sumpath*rnd)->second;
746 double History::weightTree(PartonLevel* trial,
double as0,
double maxscale,
747 AlphaStrong * asFSR, AlphaStrong * asISR,
748 double& asWeight,
double& pdfWeight) {
751 double newScale = scale;
756 int sideRad = (state[3].pz() > 0) ? 1 :-1;
757 int sideRec = (state[4].pz() > 0) ? 1 :-1;
759 if (state[3].colType() != 0) {
761 double x = 2.*state[3].e() / state[0].e();
762 int flav = state[3].id();
765 double scaleNum = (children.empty()) ? infoPtr->QFac() : maxscale;
766 double scaleDen = infoPtr->QFac();
768 double ratio = getPDFratio(sideRad,
false, flav, x, scaleNum,
774 if (state[4].colType() != 0) {
776 double x = 2.*state[4].e() / state[0].e();
777 int flav = state[4].id();
780 double scaleNum = (children.empty()) ? infoPtr->QFac() : maxscale;
781 double scaleDen = infoPtr->QFac();
783 double ratio = getPDFratio(sideRec,
false, flav, x, scaleNum,
792 double w = mother->weightTree(trial, as0, newScale, asFSR, asISR,
793 asWeight, pdfWeight);
796 if(state.size() < 3)
return 1.0;
798 if ( w < 1e-12 )
return 0.0;
800 w *= doTrialShower(trial, maxscale);
801 if ( w < 1e-12 )
return 0.0;
804 if ( asFSR && asISR ) {
805 double asScale = newScale;
806 if(mergingHooksPtr->unorderedASscalePrescip() == 1)
807 asScale = clusterIn.pT();
808 bool FSR = mother->state[clusterIn.emittor].isFinal();
809 double alphaSinPS = (FSR) ? (*asFSR).alphaS(asScale*asScale)
810 : (*asISR).alphaS(asScale*asScale
811 + pow(mergingHooksPtr->pT0ISR(),2));
812 asWeight *= alphaSinPS / as0;
818 int sideP = (mother->state[inP].pz() > 0) ? 1 :-1;
819 int sideM = (mother->state[inM].pz() > 0) ? 1 :-1;
821 if ( mother->state[inP].colType() != 0 ) {
823 double x = getCurrentX(sideP);
824 int flav = getCurrentFlav(sideP);
827 double scaleNum = (children.empty()) ? infoPtr->QFac() : maxscale;
829 double ratio = getPDFratio(sideP,
false, flav, x, scaleNum,
834 if ( mother->state[inM].colType() != 0 ) {
836 double x = getCurrentX(sideM);
837 int flav = getCurrentFlav(sideM);
840 double scaleNum = (children.empty()) ? infoPtr->QFac() : maxscale;
842 double ratio = getPDFratio(sideM,
false, flav, x, scaleNum,
862 double History::doTrialShower(PartonLevel* trial,
double maxscale) {
866 Event process = state;
870 double pTreclus = scale;
872 double pTtrial = 0.0;
875 event.init(
"(hard process-modified)", particleDataPtr);
880 if(pTreclus >= maxscale)
return 1.0;
885 double z = ( mergingHooksPtr->getNumberOfClusteringSteps(state) == 0)
887 : mother->getCurrentZ(clusterIn.emittor,clusterIn.recoiler,
891 infoPtr->pT2NowISR(pow(maxscale,2));
892 infoPtr->hasHistory(
true);
895 trial->next(process,event);
898 pTtrial = trial->pTLastInShower();
900 if(pTtrial > pTreclus)
return 0.0;
904 int typeTrial = trial->typeLastInShower();
908 vector<int> finalPartons;
909 for(
int i=0; i < state.size(); ++i){
910 if(state[i].isFinal()) {
912 if( state[i].colType() != 0)
913 finalPartons.push_back(i);
917 if( nFinal == 2 &&
int(finalPartons.size()) == 2
918 && pTtrial > event[finalPartons[0]].pT() ) {
925 if( pTtrial < pTreclus )
return 1.0;
939 bool History::onlyOrderedPaths() {
940 if ( !mother || foundOrderedPath )
return foundOrderedPath;
941 return foundOrderedPath = mother->onlyOrderedPaths();
950 bool History::onlyStronglyOrderedPaths() {
951 if ( !mother || foundStronglyOrderedPath )
return foundStronglyOrderedPath;
952 return foundStronglyOrderedPath = mother->onlyStronglyOrderedPaths();
964 bool History::registerPath(History & l,
bool isOrdered,
965 bool isStronglyOrdered,
bool isComplete) {
968 if ( l.prob <= 0.0)
return false;
970 if ( mother )
return mother->registerPath(l, isOrdered,
971 isStronglyOrdered, isComplete);
973 if ( sumpath == sumpath + l.prob )
return false;
974 if ( mergingHooksPtr->enforceStrongOrdering()
975 && foundStronglyOrderedPath && !isStronglyOrdered )
return false;
976 if ( foundOrderedPath && !isOrdered )
return false;
977 if ( foundCompletePath && !isComplete )
return false;
979 if ( mergingHooksPtr->enforceStrongOrdering() && isStronglyOrdered
981 if ( !foundStronglyOrderedPath || !foundCompletePath ) {
988 foundStronglyOrderedPath =
true;
989 foundCompletePath =
true;
992 if ( isOrdered && isComplete ) {
993 if ( !foundOrderedPath || !foundCompletePath ) {
999 foundOrderedPath =
true;
1000 foundCompletePath =
true;
1003 if ( !foundCompletePath ) {
1009 foundCompletePath =
true;
1014 paths[sumpath] = &l;
1026 vector<Clustering> History::getAllClusterings() {
1027 vector<Clustering> ret;
1030 vector <int> PosFinalPartn;
1031 vector <int> PosInitPartn;
1032 vector <int> PosFinalGluon;
1033 vector <int> PosFinalQuark;
1034 vector <int> PosFinalAntiq;
1035 vector <int> PosInitGluon;
1036 vector <int> PosInitQuark;
1037 vector <int> PosInitAntiq;
1041 for (
int i=0; i < state.size(); ++i)
1042 if( state[i].isFinal() && state[i].colType() !=0 ) {
1044 if(state[i].
id() == 21) PosFinalGluon.push_back(i);
1045 else if ( abs(state[i].
id()) < 10 && state[i].
id() > 0)
1046 PosFinalQuark.push_back(i);
1047 else if ( abs(state[i].
id()) < 10 && state[i].
id() < 0)
1048 PosFinalAntiq.push_back(i);
1049 }
else if (state[i].status() == -21 && state[i].colType() != 0 ) {
1051 if(state[i].
id() == 21) PosInitGluon.push_back(i);
1052 else if ( abs(state[i].
id()) < 10 && state[i].
id() > 0)
1053 PosInitQuark.push_back(i);
1054 else if ( abs(state[i].
id()) < 10 && state[i].
id() < 0)
1055 PosInitAntiq.push_back(i);
1059 vector<Clustering> systems;
1060 systems = getClusterings(state);
1061 ret.insert(ret.end(), systems.begin(), systems.end());
1065 if( !ret.empty() )
return ret;
1070 else if( ret.empty()
1071 && mergingHooksPtr->allowColourShuffling() ) {
1074 for(
int i = 0; i < int(PosFinalQuark.size()); ++i){
1076 if( mergingHooksPtr->hardProcess.matchesAnyOutgoing(PosFinalQuark[i],
1079 int col = NewState[PosFinalQuark[i]].col();
1080 for(
int j = 0; j < int(PosInitAntiq.size()); ++j){
1082 int acl = NewState[PosInitAntiq[j]].acol();
1083 if( col == acl )
continue;
1084 NewState[PosFinalQuark[i]].col(acl);
1085 NewState[PosInitAntiq[j]].acol(col);
1086 systems = getClusterings(NewState);
1087 if(!systems.empty()) {
1090 ret.insert(ret.end(), systems.begin(), systems.end());
1097 for(
int i = 0; i < int(PosFinalAntiq.size()); ++i){
1099 if( mergingHooksPtr->hardProcess.matchesAnyOutgoing(PosFinalAntiq[i],
1102 int acl = NewState[PosFinalAntiq[i]].acol();
1103 for(
int j = 0; j < int(PosInitQuark.size()); ++j){
1105 int col = NewState[PosInitQuark[j]].col();
1106 if( col == acl )
continue;
1107 NewState[PosFinalAntiq[i]].acol(col);
1108 NewState[PosInitQuark[j]].col(acl);
1109 systems = getClusterings(NewState);
1110 if(!systems.empty()) {
1113 ret.insert(ret.end(), systems.begin(), systems.end());
1121 infoPtr->errorMsg(
"Warning in History::getAllClusterings: Changed",
1122 "colour structure to allow at least one clustering");
1124 infoPtr->errorMsg(
"Warning in History::getAllClusterings: No clusterings",
1125 "found. History incomplete");
1129 infoPtr->errorMsg(
"Warning in History::getAllClusterings: No clusterings",
1130 "found. History incomplete");
1142 vector<Clustering> History::getClusterings(
const Event& event) {
1143 vector<Clustering> ret;
1147 vector <int> PosFinalPartn;
1148 vector <int> PosInitPartn;
1150 vector <int> PosFinalGluon;
1151 vector <int> PosFinalQuark;
1152 vector <int> PosFinalAntiq;
1154 vector <int> PosInitGluon;
1155 vector <int> PosInitQuark;
1156 vector <int> PosInitAntiq;
1160 for (
int i=0; i <
event.size(); ++i)
1161 if( event[i].isFinal() &&
event[i].colType() !=0 ) {
1163 PosFinalPartn.push_back(i);
1164 if(event[i].
id() == 21) PosFinalGluon.push_back(i);
1165 else if ( abs(event[i].
id()) < 10 && event[i].
id() > 0)
1166 PosFinalQuark.push_back(i);
1167 else if ( abs(event[i].
id()) < 10 && event[i].
id() < 0)
1168 PosFinalAntiq.push_back(i);
1169 }
else if (event[i].status() == -21 && event[i].colType() != 0 ) {
1171 PosInitPartn.push_back(i);
1172 if(event[i].
id() == 21) PosInitGluon.push_back(i);
1173 else if ( abs(event[i].
id()) < 10 && event[i].
id() > 0)
1174 PosInitQuark.push_back(i);
1175 else if ( abs(event[i].
id()) < 10 && event[i].
id() < 0)
1176 PosInitAntiq.push_back(i);
1179 int nFiGluon = int(PosFinalGluon.size());
1180 int nFiQuark = int(PosFinalQuark.size());
1181 int nFiAntiq = int(PosFinalAntiq.size());
1182 int nInGluon = int(PosInitGluon.size());
1183 int nInQuark = int(PosInitQuark.size());
1184 int nInAntiq = int(PosInitAntiq.size());
1186 vector<Clustering> systems;
1190 for (
int i = 0; i < nFiGluon; ++i) {
1191 int EmtGluon = PosFinalGluon[i];
1192 systems = findTriple( EmtGluon, 2, event, PosFinalPartn, PosInitPartn);
1193 ret.insert(ret.end(), systems.begin(), systems.end());
1199 bool check_g2qq =
true;
1200 if( ( ( nInQuark + nInAntiq == 0 )
1202 && (nFiQuark == 1) && (nFiAntiq == 1) )
1203 || ( ( nFiQuark + nFiAntiq == 0)
1204 && (nInQuark == 1) && (nInAntiq == 1) ) )
1211 for(
int i=0; i < nFiQuark; ++i) {
1212 int EmtQuark = PosFinalQuark[i];
1213 systems = findTriple( EmtQuark, 1, event, PosFinalPartn, PosInitPartn);
1214 ret.insert(ret.end(), systems.begin(), systems.end());
1220 for(
int i=0; i < nFiAntiq; ++i) {
1221 int EmtAntiq = PosFinalAntiq[i];
1222 systems = findTriple( EmtAntiq, 1, event, PosFinalPartn, PosInitPartn);
1223 ret.insert(ret.end(), systems.begin(), systems.end());
1243 vector<Clustering> History::findTriple (
int EmtTagIn,
int colTopIn,
1245 vector<int> PosFinalPartn,
1246 vector <int> PosInitPartn ) {
1249 int EmtTag = EmtTagIn;
1252 int colTop = colTopIn;
1255 int FinalSize = int(PosFinalPartn.size());
1256 int InitSize = int(PosInitPartn.size());
1257 int Size = InitSize + FinalSize;
1259 vector<Clustering> clus;
1263 for (
int a = 0; a < Size; ++a ) {
1264 int i = (a < FinalSize)? a : (a - FinalSize) ;
1265 int iRad = (a < FinalSize)? PosFinalPartn[i] : PosInitPartn[i];
1267 if( event[iRad].col() ==
event[EmtTag].col()
1268 &&
event[iRad].acol() ==
event[EmtTag].acol() )
1271 if (iRad != EmtTag ) {
1272 int pTdef =
event[iRad].isFinal() ? 1 : -1;
1273 int sign = (a < FinalSize)? 1 : -1 ;
1279 if ( event[iRad].
id() == -sign*
event[EmtTag].id() ) {
1282 if(event[iRad].
id() < 0) {
1283 col =
event[EmtTag].acol();
1284 acl =
event[iRad].acol();
1286 col =
event[EmtTag].col();
1287 acl =
event[iRad].col();
1296 iRec = FindCol(col,iRad,EmtTag,event,1,
true);
1299 if( (sign < 0) && (event[iRec].isFinal()) ){
1303 for(
int l = 0; l < int(PosInitPartn.size()); ++l)
1304 if(PosInitPartn[l] != iRad) iRec = PosInitPartn[l];
1310 if( iRec != 0 && iPartner != 0
1311 && allowedClustering( iRad, EmtTag, iRec, iPartner, event) ){
1312 clus.push_back( Clustering(EmtTag, iRad, iRec, iPartner,
1313 pTLund(event[iRad], event[EmtTag], event[iRec], pTdef) ));
1320 iRec = FindCol(col,iRad,EmtTag,event,2,
true);
1323 if( (sign < 0) && (event[iRec].isFinal()) ){
1327 for(
int l = 0; l < int(PosInitPartn.size()); ++l)
1328 if(PosInitPartn[l] != iRad) iRec = PosInitPartn[l];
1334 if( iRec != 0 && iPartner != 0
1335 && allowedClustering( iRad, EmtTag, iRec, iPartner, event) ){
1336 clus.push_back( Clustering(EmtTag, iRad, iRec, iPartner,
1337 pTLund(event[iRad], event[EmtTag], event[iRec], pTdef) ));
1347 iRec = FindCol(acl,iRad,EmtTag,event,1,
true);
1350 if( (sign < 0) && (event[iRec].isFinal()) ){
1354 for(
int l = 0; l < int(PosInitPartn.size()); ++l)
1355 if(PosInitPartn[l] != iRad) iRec = PosInitPartn[l];
1361 if( iRec != 0 && iPartner != 0
1362 && allowedClustering( iRad, EmtTag, iRec, iPartner, event) ){
1363 clus.push_back( Clustering(EmtTag, iRad, iRec, iPartner,
1364 pTLund(event[iRad], event[EmtTag], event[iRec], pTdef) ));
1371 iRec = FindCol(acl,iRad,EmtTag,event,2,
true);
1374 if( (sign < 0) && (event[iRec].isFinal()) ){
1378 for(
int l = 0; l < int(PosInitPartn.size()); ++l)
1379 if(PosInitPartn[l] != iRad) iRec = PosInitPartn[l];
1385 if( iRec != 0 && iPartner != 0
1386 && allowedClustering( iRad, EmtTag, iRec, iPartner, event) ){
1387 clus.push_back( Clustering(EmtTag, iRad, iRec, iPartner,
1388 pTLund(event[iRad], event[EmtTag], event[iRec], pTdef) ));
1393 }
else if( event[iRad].
id() == 21
1394 &&( event[iRad].col() == event[EmtTag].col()
1395 || event[iRad].acol() == event[EmtTag].acol() )) {
1401 for(
int l = 0; l < int(PosInitPartn.size()); ++l)
1402 if(PosInitPartn[l] != iRad) RecInit = PosInitPartn[l];
1406 int col = getRadBeforeCol(iRad, EmtTag, event);
1407 int acl = getRadBeforeAcol(iRad, EmtTag, event);
1417 int colRemove = (
event[iRad].col() ==
event[EmtTag].col())
1418 ? event[iRad].col() : 0;
1421 if(colRemove > 0 && col > 0)
1422 iPartner = FindCol(col,iRad,EmtTag,event,1,
true)
1423 + FindCol(col,iRad,EmtTag,event,2,
true);
1424 else if(colRemove > 0 && acl > 0)
1425 iPartner = FindCol(acl,iRad,EmtTag,event,1,
true)
1426 + FindCol(acl,iRad,EmtTag,event,2,
true);
1428 if( allowedClustering( iRad, EmtTag, RecInit, iPartner, event ) ) {
1429 clus.push_back( Clustering(EmtTag, iRad, RecInit, iPartner,
1430 pTLund(event[iRad],event[EmtTag],event[RecInit], pTdef) ));
1438 if ( (event[iRad].col() == event[EmtTag].acol())
1439 || (event[iRad].acol() == event[EmtTag].col())
1440 || (event[iRad].col() == event[EmtTag].col())
1441 || (event[iRad].acol() == event[EmtTag].acol()) ) {
1448 if(event[iRad].isFinal() ) {
1449 if ( event[iRad].
id() < 0) {
1450 acl =
event[EmtTag].acol();
1451 col =
event[iRad].col();
1452 }
else if( event[iRad].
id() > 0 && event[iRad].
id() < 10) {
1453 col =
event[EmtTag].col();
1454 acl =
event[iRad].acol();
1456 col =
event[iRad].col();
1457 acl =
event[iRad].acol();
1462 iRec = FindCol(col,iRad,EmtTag,event,1,
true);
1463 if( (sign < 0) && (event[iRec].isFinal()) ) iRec = 0;
1465 && allowedClustering( iRad, EmtTag, iRec, iRec, event) ){
1466 clus.push_back( Clustering(EmtTag, iRad, iRec, iRec,
1467 pTLund(event[iRad],event[EmtTag],event[iRec], pTdef) ));
1471 iRec = FindCol(col,iRad,EmtTag,event,2,
true);
1472 if( (sign < 0) && (event[iRec].isFinal()) ) iRec = 0;
1474 && allowedClustering( iRad, EmtTag, iRec, iRec, event) ){
1475 clus.push_back( Clustering(EmtTag, iRad, iRec, iRec,
1476 pTLund(event[iRad],event[EmtTag],event[iRec], pTdef) ));
1482 iRec = FindCol(acl,iRad,EmtTag,event,1,
true);
1483 if( (sign < 0) && (event[iRec].isFinal()) ) iRec = 0;
1485 && allowedClustering( iRad, EmtTag, iRec, iRec, event) ){
1486 clus.push_back( Clustering(EmtTag, iRad, iRec, iRec,
1487 pTLund(event[iRad],event[EmtTag],event[iRec], pTdef) ));
1491 iRec = FindCol(acl,iRad,EmtTag,event,2,
true);
1492 if( (sign < 0) && (event[iRec].isFinal()) ) iRec = 0;
1494 && allowedClustering( iRad, EmtTag, iRec, iRec, event) ){
1495 clus.push_back( Clustering(EmtTag, iRad, iRec, iRec,
1496 pTLund(event[iRad],event[EmtTag],event[iRec], pTdef) ));
1509 for(
int l = 0; l < int(PosInitPartn.size()); ++l)
1510 if(PosInitPartn[l] != iRad) RecInit = PosInitPartn[l];
1514 col = getRadBeforeCol(iRad, EmtTag, event);
1515 acl = getRadBeforeAcol(iRad, EmtTag, event);
1525 int colRemove = (
event[iRad].col() ==
event[EmtTag].col())
1526 ? event[iRad].col() : 0;
1527 iPartner = (colRemove > 0)
1528 ? FindCol(col,iRad,EmtTag,event,1,
true)
1529 + FindCol(col,iRad,EmtTag,event,2,
true)
1530 : FindCol(acl,iRad,EmtTag,event,1,true)
1531 + FindCol(acl,iRad,EmtTag,event,2,true);
1533 if( allowedClustering( iRad, EmtTag, RecInit, iPartner, event) ){
1534 clus.push_back( Clustering(EmtTag, iRad, RecInit, iPartner,
1535 pTLund(event[iRad],event[EmtTag],event[RecInit], pTdef)));
1556 double History::getProb(
const Clustering & SystemIn) {
1559 int Rad = SystemIn.emittor;
1560 int Rec = SystemIn.recoiler;
1561 int Emt = SystemIn.emitted;
1564 double showerProb = 0.0;
1568 if(SystemIn.pT() <= 0.){
1569 infoPtr->errorMsg(
"Warning in History::getProb: Reconstructed evolution",
1570 "variable has negative value, set splitting probability to 0.");
1578 double TR = NF / 2.;
1581 bool isFSR = (state[Rad].isFinal() && state[Rec].isFinal());
1582 bool isFSRinREC = (state[Rad].isFinal() && !state[Rec].isFinal());
1583 bool isISR = !state[Rad].isFinal();
1588 for(
int i=0; i < state.size(); ++i)
1589 if(state[i].isFinal()) nFinal++;
1590 bool isLast = (nFinal == (mergingHooksPtr->hardProcess.nQuarksOut()
1591 +mergingHooksPtr->hardProcess.nLeptonOut()+1));
1598 for(
int i=0;i< int(state.size()); ++i){
1599 if(state[i].mother1() == 1) inP = i;
1600 if(state[i].mother1() == 2) inM = i;
1603 Vec4 sum = state[Rad].p() + state[Rec].p() - state[Emt].p();
1604 double m2Dip = sum.m2Calc();
1605 double sHat = (state[inM].p() + state[inP].p()).m2Calc();
1607 double z1 = m2Dip / sHat;
1609 Vec4 Q1( state[Rad].p() - state[Emt].p() );
1610 Vec4 Q2( state[Rec].p() - state[Emt].p() );
1612 double Q1sq = -Q1.m2Calc();
1614 double pT1sq = pow(SystemIn.pT(),2);
1617 bool g2QQmassive = mergingHooksPtr->includeMassive()
1618 && state[Rad].id() == 21
1619 && ( abs(state[Emt].
id()) >= 4 && abs(state[Emt].
id()) < 7);
1620 bool Q2Qgmassive = mergingHooksPtr->includeMassive()
1621 && state[Emt].id() == 21
1622 && ( abs(state[Rad].
id()) >= 4 && abs(state[Rad].
id()) < 7);
1623 bool isMassive = mergingHooksPtr->includeMassive()
1624 && (g2QQmassive || Q2Qgmassive);
1625 double m2Emt0 = pow(particleDataPtr->m0(state[Emt].id()),2);
1626 double m2Rad0 = pow(particleDataPtr->m0(state[Rad].id()),2);
1629 if( g2QQmassive) Q1sq += m2Emt0;
1630 else if(Q2Qgmassive) Q1sq += m2Rad0;
1633 double pT0sq = pow(mergingHooksPtr->pT0ISR(),2);
1634 double Q2sq = -Q2.m2Calc();
1637 bool g2QQmassiveRec = mergingHooksPtr->includeMassive()
1638 && state[Rec].id() == 21
1639 && ( abs(state[Emt].
id()) >= 4 && abs(state[Emt].
id()) < 7);
1640 bool Q2QgmassiveRec = mergingHooksPtr->includeMassive()
1641 && state[Emt].id() == 21
1642 && ( abs(state[Rec].
id()) >= 4 && abs(state[Rec].
id()) < 7);
1643 double m2Rec0 = pow(particleDataPtr->m0(state[Rad].id()),2);
1644 if( g2QQmassiveRec) Q2sq += m2Emt0;
1645 else if(Q2QgmassiveRec) Q2sq += m2Rec0;
1647 bool hasJoinedEvol = (state[Emt].id() == 21
1648 || state[Rad].id() == state[Rec].id());
1653 if( mergingHooksPtr->pickByFull() || mergingHooksPtr->pickBySumPT()){
1654 double facJoined = ( Q2sq + pT0sq/(1.-z1) )
1655 * 1./(Q1sq*Q2sq + pT0sq*sHat + pow(pT0sq/(1.-z1),2));
1656 double facSingle = mergingHooksPtr->nonJoinedNorm()*1./( pT1sq + pT0sq);
1658 fac = (hasJoinedEvol && isLast) ? facJoined : facSingle;
1660 }
else if(mergingHooksPtr->pickByPoPT2()) {
1661 fac = 1./(pT1sq + pT0sq);
1663 infoPtr->errorMsg(
"Error in History::getProb: Scheme for calculating",
1664 "shower splitting probability is undefined.");
1671 if ( state[Emt].
id() == 21 && state[Rad].
id() != 21) {
1673 double num = CF*(1. + pow(z1,2)) / (1.-z1);
1674 if(isMassive) num -= CF * z1 * (1.-z1) * (m2Rad0/pT1sq);
1677 double meReweighting = 1.;
1681 for(
int i=0; i < state.size(); ++i)
1682 if(state[i].isFinal() && state[i].colType() != 0
1683 && !mergingHooksPtr->hardProcess.matchesAnyOutgoing(i,state))
1688 &&
int(mergingHooksPtr->hardProcess.hardIntermediate.size()) == 1){
1689 double sH = m2Dip / z1;
1691 double uH = Q1sq - m2Dip * (1. - z1) / z1;
1692 double misMatch = (uH*tH - (uH + tH)*pT0sq/(1.-z1)
1693 + pow(pT0sq/(1.-z1),2) ) / (uH*tH);
1694 meReweighting *= (tH*tH + uH*uH + 2. * m2Dip * sH)
1695 / (sH*sH + m2Dip*m2Dip);
1696 meReweighting *= misMatch;
1699 showerProb = num*fac*meReweighting;
1702 }
else if ( state[Emt].
id() == 21 && state[Rad].id() == 21) {
1704 double num = 2.*NC*pow2(1. - z1*(1.-z1)) / (z1*(1.-z1));
1706 showerProb = num*fac;
1709 }
else if ( state[Emt].
id() != 21 && state[Rad].id() != 21) {
1711 double num = CF*(1. + pow2(1.-z1)) / z1;
1713 showerProb = num*fac;
1716 }
else if ( state[Emt].
id() != 21 && state[Rad].id() == 21) {
1718 double num = TR * ( pow(z1,2) + pow(1.-z1,2) );
1719 if(isMassive) num += TR * 2.*z1*(1.-z1)*(m2Emt0/pT1sq);
1721 double meReweighting = 1.;
1725 for(
int i=0; i < state.size(); ++i)
1726 if(state[i].isFinal() && state[i].colType() != 0
1727 && !mergingHooksPtr->hardProcess.matchesAnyOutgoing(i,state))
1732 &&
int(mergingHooksPtr->hardProcess.hardIntermediate.size()) == 1){
1733 double sH = m2Dip / z1;
1735 double uH = Q1sq - m2Dip * (1. - z1) / z1;
1737 double misMatch = ( uH - pT0sq/(1.-z1) ) / uH;
1738 double me = (sH*sH + uH*uH + 2. * m2Dip * tH)
1739 / (pow2(sH - m2Dip) + m2Dip*m2Dip);
1741 meReweighting *= me;
1742 meReweighting *= misMatch;
1745 showerProb = num*fac*meReweighting;
1749 infoPtr->errorMsg(
"Error in History::getProb: Splitting kernel undefined",
1750 "in ISR clustering.");
1754 double m2Sister0 = pow(state[Emt].m0(),2);
1755 double pT2corr = (Q1sq - z1*(m2Dip + Q1sq)*(Q1sq + m2Sister0)/m2Dip);
1756 if(pT2corr < 0.) showerProb *= 1e-9;
1760 if ( state[Emt].
id() == state[Rad].id()
1761 && ( abs(state[Rad].
id()) == 4 || abs(state[Rad].
id()) == 5 )) {
1762 double m2QQsister = 2.*4.*m2Sister0;
1763 double pT2QQcorr = Q1sq - z1*(m2Dip + Q1sq)*(Q1sq + m2QQsister)
1765 if(pT2QQcorr < 0.0) showerProb *= 1e-9;
1768 if(mergingHooksPtr->includeRedundant()){
1770 AlphaStrong* asISR = mergingHooksPtr->AlphaS_ISR();
1771 double as = (*asISR).alphaS(pT1sq + pT0sq) / (2.*M_PI);
1778 }
else if (isFSR || isFSRinREC){
1781 Vec4 sum = state[Rad].p() + state[Rec].p() + state[Emt].p();
1782 double m2Dip = sum.m2Calc();
1784 double x1 = 2. * (sum * state[Rad].p()) / m2Dip;
1785 double x2 = 2. * (sum * state[Rec].p()) / m2Dip;
1786 double prop1 = max(1e-12, 1. - x1);
1787 double prop2 = max(1e-12, 1. - x2);
1788 double x3 = max(1e-12, 2. - x1 - x2);
1790 double z1 = x1/(x1 + x3);
1793 Vec4 Q1( state[Rad].p() + state[Emt].p() );
1794 Vec4 Q2( state[Rec].p() + state[Emt].p() );
1796 double Q1sq = Q1.m2Calc();
1798 double pT1sq = pow(SystemIn.pT(),2);
1800 double Q2sq = Q2.m2Calc();
1803 double m2Rad0 = pow(particleDataPtr->m0(state[Rad].id()),2);
1804 double m2Rec0 = pow(particleDataPtr->m0(state[Rad].id()),2);
1805 if( abs(state[Rad].
id()) >= 4 && abs(state[Rad].
id()) < 7)
1807 if( abs(state[Rec].
id()) >= 4 && abs(state[Rec].
id()) < 7)
1813 if( mergingHooksPtr->pickByFull() || mergingHooksPtr->pickBySumPT()){
1814 double facJoined = (1.-z1)/Q1sq * m2Dip/( Q1sq + Q2sq );
1815 double facSingle = mergingHooksPtr->fsrInRecNorm() * 1./ pT1sq;
1816 fac = (!isFSRinREC && isLast) ? facJoined : facSingle;
1817 }
else if(mergingHooksPtr->pickByPoPT2()) {
1820 infoPtr->errorMsg(
"Error in History::getProb: Scheme for calculating",
1821 "shower splitting probability is undefined.");
1827 if ( state[Emt].
id() == 21 && state[Rad].
id() == 21) {
1829 double num = 0.5* NC * (1. + pow3(z1)) / (1.-z1);
1831 showerProb = num*fac;
1834 }
else if ( state[Emt].
id() == 21 && state[Rad].
id() != 21
1835 && state[Rec].
id() != 21) {
1838 double num = CF * 2./(1.-z1);
1842 for(
int i=0; i < state.size(); ++i)
1843 if(state[i].isFinal() && state[i].colType() != 0
1844 && !mergingHooksPtr->hardProcess.matchesAnyOutgoing(i,state))
1848 ||
int(mergingHooksPtr->hardProcess.hardIntermediate.size()) > 1)
1849 num = CF * (1. + pow2(z1)) /(1.-z1);
1851 double meReweighting = 1.;
1855 &&
int(mergingHooksPtr->hardProcess.hardIntermediate.size()) == 1){
1857 double ShowerRate1 = 2./( x3 * prop2 );
1858 double meDividingFactor1 = prop1 / x3;
1859 double me = (pow(x1,2) + pow(x2,2))/(prop1*prop2);
1860 meReweighting = meDividingFactor1 * me / ShowerRate1;
1863 showerProb = num*fac*meReweighting;
1866 }
else if ( state[Emt].
id() == 21 && state[Rad].id() != 21
1867 && state[Rec].id() == 21) {
1871 double num = CF * (1. + pow2(z1)) / (1.-z1);
1872 showerProb = num*fac;
1875 }
else if ( state[Emt].
id() != 21) {
1877 int flavour = state[Emt].id();
1880 double mFlavour = particleDataPtr->m0(flavour);
1882 double mDipole = m(state[Rad].p(), state[Emt].p());
1884 double beta = sqrtpos( 1. - 4.*pow2(mFlavour)/pow2(mDipole) );
1886 double num = 0.5*TR * ( z1*z1 + (1.-z1)*(1.-z1) );
1888 infoPtr->errorMsg(
"Warning in History::getProb: g->qqbar",
1889 "kinematically not allowed.");
1892 showerProb = num*fac*beta;
1896 infoPtr->errorMsg(
"Error in History::getProb: Splitting kernel undefined",
1897 "in FSR clustering.");
1900 if(mergingHooksPtr->includeRedundant()){
1902 AlphaStrong* asFSR = mergingHooksPtr->AlphaS_FSR();
1903 double as = (*asFSR).alphaS(pT1sq) / (2.*M_PI);
1910 infoPtr->errorMsg(
"Error in History::getProb: Radiation could not be",
1911 "interpreted as FSR or ISR.");
1914 if(showerProb <= 0.){
1915 infoPtr->errorMsg(
"Warning in History::getProb: Splitting probability",
1916 "negative, raised to 0.");
1937 void History::setupBeams(){
1942 if(state.size() < 4)
return;
1944 if( state[3].colType() == 0 )
return;
1945 if( state[4].colType() == 0 )
return;
1951 for(
int i=0;i< int(state.size()); ++i){
1952 if(state[i].mother1() == 1) inP = i;
1953 if(state[i].mother1() == 2) inM = i;
1958 int motherPcompRes = -1;
1959 int motherMcompRes = -1;
1961 bool sameFlavP =
false;
1962 bool sameFlavM =
false;
1967 for(
int i=0;i< int(mother->state.size()); ++i){
1968 if(mother->state[i].mother1() == 1) inMotherP = i;
1969 if(mother->state[i].mother1() == 2) inMotherM = i;
1971 sameFlavP = (state[inP].id() == mother->state[inMotherP].id());
1972 sameFlavM = (state[inM].id() == mother->state[inMotherM].id());
1974 motherPcompRes = (sameFlavP) ? beamA[0].companion() : -2;
1975 motherMcompRes = (sameFlavM) ? beamB[0].companion() : -2;
1983 double Ep = 2. * state[inP].e();
1984 double Em = 2. * state[inM].e();
1987 if (state[inP].m() != 0. || state[inM].m() != 0.) {
1988 Ep = state[inP].pPos() + state[inM].pPos();
1989 Em = state[inP].pNeg() + state[inM].pNeg();
1993 double x1 = Ep / state[inS].m();
1994 beamA.append( inP, state[inP].
id(), x1);
1995 double x2 = Em / state[inS].m();
1996 beamB.append( inM, state[inM].
id(), x2);
2000 double scalePDF = (mother) ? scale : infoPtr->QFac();
2004 beamA.xfISR( 0, state[inP].
id(), x1, scalePDF*scalePDF);
2006 beamA.pickValSeaComp();
2008 beamA[0].companion(motherPcompRes);
2010 beamB.xfISR( 0, state[inM].
id(), x2, scalePDF*scalePDF);
2012 beamB.pickValSeaComp();
2014 beamB[0].companion(motherMcompRes);
2024 double History::pdfForSudakov() {
2027 if( state[3].colType() == 0 )
return 1.0;
2028 if( state[4].colType() == 0 )
return 1.0;
2031 bool FSR = ( mother->state[clusterIn.emittor].isFinal()
2032 && mother->state[clusterIn.recoiler].isFinal());
2033 bool FSRinRec = ( mother->state[clusterIn.emittor].isFinal()
2034 && !mother->state[clusterIn.recoiler].isFinal());
2039 int iInMother = (FSRinRec)? clusterIn.recoiler : clusterIn.emittor;
2041 int side = ( mother->state[iInMother].pz() > 0 ) ? 1 : -1;
2045 for(
int i=0;i< int(state.size()); ++i){
2046 if(state[i].mother1() == 1) inP = i;
2047 if(state[i].mother1() == 2) inM = i;
2051 int idMother = mother->state[iInMother].id();
2053 int iDau = (side == 1) ? inP : inM;
2054 int idDaughter = state[iDau].id();
2056 double xMother = 2. * mother->state[iInMother].e() / mother->state[0].e();
2058 double xDaughter = 2.*state[iDau].e() / state[0].e();
2061 double ratio = getPDFratio(side,
true, idMother, xMother, scale,
2062 idDaughter, xDaughter, scale);
2067 return ( (FSRinRec)? min(1.,ratio) : ratio);
2077 Event History::cluster(
const Clustering & inSystem) {
2080 int Rad = inSystem.emittor;
2081 int Rec = inSystem.recoiler;
2082 int Emt = inSystem.emitted;
2084 double eCM = state[0].e();
2086 int radType = state[Rad].isFinal() ? 1 : -1;
2087 int recType = state[Rec].isFinal() ? 1 : -1;
2091 NewEvent.init(
"(hard process-modified)", particleDataPtr);
2094 for (
int i = 0; i < state.size(); ++i)
2095 if( i != Rad && i != Rec && i != Emt )
2096 NewEvent.append( state[i] );
2099 for (
int i = 0; i < state.sizeJunction(); ++i)
2100 NewEvent.appendJunction( state.getJunction(i) );
2102 NewEvent.setPDTPtr();
2104 double mu = choseHardScale(state);
2106 NewEvent.saveSize();
2107 NewEvent.saveJunctionSize();
2109 NewEvent.scaleSecond(mu);
2113 Particle RecBefore = Particle( state[Rec] );
2114 RecBefore.daughters(0,0);
2116 int radID = getRadBeforeFlav(Rad, Emt, state);
2117 Particle RadBefore = Particle( state[Rad] );
2118 RadBefore.id(radID);
2119 RadBefore.daughters(0,0);
2121 RadBefore.cols(RecBefore.acol(),RecBefore.col());
2123 RecBefore.m(particleDataPtr->m0(state[Rec].id()));
2124 RadBefore.m(particleDataPtr->m0(radID));
2128 if(radType + recType == 2){
2131 Vec4 sum = state[Rad].p() + state[Rec].p() + state[Emt].p();
2132 double eCMME = sum.mCalc();
2138 Rad4mom.p( 0., 0., 0.5*eCMME, 0.5*eCMME);
2139 Rec4mom.p( 0., 0.,-0.5*eCMME, 0.5*eCMME);
2142 Vec4 old1 = Vec4(state[Rad].p() + state[Emt].p());
2143 Vec4 old2 = Vec4(state[Rec].p());
2144 RotBstMatrix fromCM;
2145 fromCM.fromCMframe(old1, old2);
2147 Rad4mom.rotbst(fromCM);
2148 Rec4mom.rotbst(fromCM);
2150 RadBefore.p(Rad4mom);
2151 RecBefore.p(Rec4mom);
2153 }
else if(radType + recType == 0) {
2156 Vec4 sum = state[Rad].p() + state[Rec].p() + state[Emt].p();
2157 double eCMME = sum.mCalc();
2162 Rad4mom.p( 0., 0., 0.5*eCMME, 0.5*eCMME);
2163 Rec4mom.p( 0., 0.,-0.5*eCMME, 0.5*eCMME);
2166 Vec4 old1 = Vec4(state[Rad].p() + state[Emt].p());
2167 Vec4 old2 = Vec4(state[Rec].p());
2168 RotBstMatrix fromCM;
2169 fromCM.fromCMframe(old1, old2);
2171 Rad4mom.rotbst(fromCM);
2172 Rec4mom.rotbst(fromCM);
2175 Rec4mom = 2.*state[Rec].p() - Rec4mom;
2177 RadBefore.p(Rad4mom);
2178 RecBefore.p(Rec4mom);
2190 Vec4 pMother( state[Rad].p() );
2191 Vec4 pSister( state[Emt].p() );
2192 Vec4 pPartner( state[Rec].p() );
2193 Vec4 pDaughter( 0.,0.,0.,0. );
2194 Vec4 pRecoiler( 0.,0.,0.,0. );
2198 int sign = state[Rad].pz() > 0 ? 1 : -1;
2202 double phi = pSister.phi();
2204 RotBstMatrix rot_by_mphi;
2205 rot_by_mphi.rot(0.,-phi);
2207 RotBstMatrix rot_by_pphi;
2208 rot_by_pphi.rot(0.,phi);
2211 pMother.rotbst( rot_by_mphi );
2212 pSister.rotbst( rot_by_mphi );
2213 pPartner.rotbst( rot_by_mphi );
2214 for(
int i=3; i< NewEvent.size(); ++i)
2215 NewEvent[i].rotbst( rot_by_mphi );
2219 double x1 = 2. * pMother.e() / eCM;
2221 double x2 = 2. * pPartner.e() / eCM;
2223 pDaughter.p( pMother - pSister);
2224 pRecoiler.p( pPartner );
2228 RotBstMatrix from_CM_to_DR;
2230 from_CM_to_DR.toCMframe(pDaughter, pRecoiler);
2232 from_CM_to_DR.toCMframe(pRecoiler, pDaughter);
2235 pMother.rotbst( from_CM_to_DR );
2236 pPartner.rotbst( from_CM_to_DR );
2237 pSister.rotbst( from_CM_to_DR );
2238 for(
int i=3; i< NewEvent.size(); ++i)
2239 NewEvent[i].rotbst( from_CM_to_DR );
2243 double theta = pMother.theta();
2244 if( pMother.px() < 0. ) theta *= -1.;
2245 if(sign == -1) theta += M_PI;
2247 RotBstMatrix rot_by_ptheta;
2248 rot_by_ptheta.rot(theta, 0.);
2251 pMother.rotbst( rot_by_ptheta );
2252 pPartner.rotbst( rot_by_ptheta );
2253 pSister.rotbst( rot_by_ptheta );
2254 for(
int i=3; i< NewEvent.size(); ++i)
2255 NewEvent[i].rotbst( rot_by_ptheta );
2258 Vec4 qDip( pMother - pSister);
2259 Vec4 qAfter(pMother + pPartner);
2260 Vec4 qBefore(qDip + pPartner);
2261 double z = qBefore.m2Calc() / qAfter.m2Calc();
2264 double x1New = z*x1;
2266 double sHat = x1New*x2New*eCM*eCM;
2269 pDaughter.p( 0., 0., sign*0.5*sqrt(sHat), 0.5*sqrt(sHat));
2270 pRecoiler.p( 0., 0., -sign*0.5*sqrt(sHat), 0.5*sqrt(sHat));
2275 RotBstMatrix from_DR_to_CM;
2276 from_DR_to_CM.bst( 0., 0., sign*( x1New - x2New ) / ( x1New + x2New ) );
2279 pMother.rotbst( from_DR_to_CM );
2280 pPartner.rotbst( from_DR_to_CM );
2281 pSister.rotbst( from_DR_to_CM );
2282 pDaughter.rotbst( from_DR_to_CM );
2283 pRecoiler.rotbst( from_DR_to_CM );
2284 for(
int i=3; i< NewEvent.size(); ++i)
2285 NewEvent[i].rotbst( from_DR_to_CM );
2288 pMother.rotbst( rot_by_pphi );
2289 pPartner.rotbst( rot_by_pphi );
2290 pSister.rotbst( rot_by_pphi );
2291 pDaughter.rotbst( rot_by_pphi );
2292 pRecoiler.rotbst( rot_by_pphi );
2293 for(
int i=3; i< NewEvent.size(); ++i)
2294 NewEvent[i].rotbst( rot_by_pphi );
2297 RecBefore.p( pRecoiler );
2298 RadBefore.p( pDaughter );
2303 RecBefore.scale(mu);
2304 RadBefore.scale(mu);
2305 RecBefore.setPDTPtr(particleDataPtr);
2306 RadBefore.setPDTPtr(particleDataPtr);
2309 NewEvent.append(RecBefore);
2311 if( !connectRadiator( RadBefore, radType, RecBefore, recType, NewEvent) ){
2320 outState.init(
"(hard process-modified)", particleDataPtr);
2324 for (
int i = 0; i < 3; ++i)
2325 outState.append( NewEvent[i] );
2327 for (
int i = 0; i < state.sizeJunction(); ++i)
2328 outState.appendJunction( state.getJunction(i) );
2330 outState.setPDTPtr();
2332 outState.saveSize();
2333 outState.saveJunctionSize();
2335 outState.scaleSecond(mu);
2336 bool radAppended =
false;
2337 bool recAppended =
false;
2338 int size = int(outState.size());
2342 if( RecBefore.mother1() == 1){
2343 outState.append( RecBefore );
2345 }
else if( RadBefore.mother1() == 1 ){
2346 radPos = outState.append( RadBefore );
2351 for(
int i=0; i < int(state.size()); ++i)
2352 if(state[i].mother1() == 1) in1 =i;
2353 outState.append( state[in1] );
2357 if( RecBefore.mother1() == 2){
2358 outState.append( RecBefore );
2360 }
else if( RadBefore.mother1() == 2 ){
2361 radPos = outState.append( RadBefore );
2366 for(
int i=0; i < int(state.size()); ++i)
2367 if(state[i].mother1() == 2) in2 =i;
2369 outState.append( state[in2] );
2374 if(!recAppended && !RecBefore.isFinal()){
2376 outState.append( RecBefore);
2379 if(!radAppended && !RadBefore.isFinal()){
2381 radPos = outState.append( RadBefore);
2386 for (
int i = 0; i < int(NewEvent.size()-1); ++i)
2387 if(NewEvent[i].status() == -22) outState.append( NewEvent[i] );
2389 if(!recAppended) outState.append(RecBefore);
2390 if(!radAppended) radPos = outState.append(RadBefore);
2393 for(
int i = 0; i < int(NewEvent.size()-1); ++i)
2394 if(NewEvent[i].colType() != 0 && NewEvent[i].isFinal())
2395 outState.append( NewEvent[i] );
2397 for(
int i = 0; i < int(NewEvent.size()-1); ++i)
2398 if(NewEvent[i].colType() == 0 && NewEvent[i].isFinal())
2399 outState.append( NewEvent[i]);
2402 vector<int> PosIntermediate;
2403 vector<int> PosDaughter1;
2404 vector<int> PosDaughter2;
2405 for(
int i=0; i < int(outState.size()); ++i)
2406 if(outState[i].status() == -22) {
2407 PosIntermediate.push_back(i);
2408 int d1 = outState[i].daughter1();
2409 int d2 = outState[i].daughter2();
2411 int daughter1 = FindParticle( state[d1], outState);
2412 int daughter2 = FindParticle( state[d2], outState);
2417 PosDaughter1.push_back( daughter1);
2420 while(!outState[daughter1].isFinal() ) daughter1++;
2421 PosDaughter1.push_back( daughter1);
2424 PosDaughter2.push_back( daughter2);
2426 daughter2 = outState.size()-1;
2427 while(!outState[daughter2].isFinal() ) daughter2--;
2428 PosDaughter2.push_back( daughter2);
2433 for(
int i=0; i < int(PosIntermediate.size()); ++i){
2434 outState[PosIntermediate[i]].daughters(PosDaughter1[i],PosDaughter2[i]);
2435 outState[PosDaughter1[i]].mother1(PosIntermediate[i]);
2436 outState[PosDaughter2[i]].mother1(PosIntermediate[i]);
2440 int minParFinal = int(outState.size());
2441 int maxParFinal = 0;
2442 for(
int i=0; i < int(outState.size()); ++i)
2443 if(outState[i].mother1() == 3 && outState[i].mother2() == 4){
2444 minParFinal = min(i,minParFinal);
2445 maxParFinal = max(i,maxParFinal);
2448 if(minParFinal == maxParFinal) maxParFinal = 0;
2449 outState[3].daughters(minParFinal,maxParFinal);
2450 outState[4].daughters(minParFinal,maxParFinal);
2453 outState.saveSize();
2454 outState.saveJunctionSize();
2468 if( radType == -1 && state[Rad].colType() == 1){
2470 for(
int i=0; i < int(state.size()); ++i)
2471 if( i != Rad && i != Emt && i != Rec
2472 && state[i].status() == -22
2473 && state[i].col() == state[Rad].col() )
2475 }
else if( radType == -1 && state[Rad].colType() == -1){
2477 for(
int i=0; i < int(state.size()); ++i)
2478 if( i != Rad && i != Emt && i != Rec
2479 && state[i].status() == -22
2480 && state[i].acol() == state[Rad].acol() )
2482 }
else if( radType == 1 && state[Rad].colType() == 1){
2484 for(
int i=0; i < int(state.size()); ++i)
2485 if( i != Rad && i != Emt && i != Rec
2486 && state[i].status() == -22
2487 && state[i].acol() == state[Rad].col() )
2489 }
else if( radType == 1 && state[Rad].colType() == -1){
2491 for(
int i=0; i < int(state.size()); ++i)
2492 if( i != Rad && i != Emt && i != Rec
2493 && state[i].status() == -22
2494 && state[i].col() == state[Rad].acol() )
2500 int iColResNow = FindParticle( state[iColRes], outState);
2502 int radCol = outState[radPos].col();
2503 int radAcl = outState[radPos].acol();
2505 int resCol = outState[iColResNow].col();
2506 int resAcl = outState[iColResNow].acol();
2508 bool matchesRes = (radCol > 0
2509 && ( radCol == resCol || radCol == resAcl))
2511 && ( radAcl == resCol || radAcl == resAcl));
2515 if(!matchesRes && iColResNow > 0) {
2516 if( radType == -1 && outState[radPos].colType() == 1)
2517 outState[iColResNow].col(radCol);
2518 else if( radType ==-1 && outState[radPos].colType() ==-1)
2519 outState[iColResNow].acol(radAcl);
2520 else if( radType == 1 && outState[radPos].colType() == 1)
2521 outState[iColResNow].acol(radCol);
2522 else if( radType == 1 && outState[radPos].colType() ==-1)
2523 outState[iColResNow].col(radAcl);
2528 if ( !validEvent(outState) ){
2545 int History::getRadBeforeFlav(
const int RadAfter,
const int EmtAfter,
2546 const Event& event){
2548 int type =
event[RadAfter].isFinal() ? 1 :-1;
2549 int emtID =
event[EmtAfter].id();
2550 int radID =
event[RadAfter].id();
2551 int emtCOL =
event[EmtAfter].col();
2552 int radCOL =
event[RadAfter].col();
2553 int emtACL =
event[EmtAfter].acol();
2554 int radACL =
event[RadAfter].acol();
2556 bool colConnected = ((type == 1) && ( (emtCOL !=0 && (emtCOL ==radACL))
2557 || (emtACL !=0 && (emtACL ==radCOL)) ))
2558 ||((type ==-1) && ( (emtCOL !=0 && (emtCOL ==radCOL))
2559 || (emtACL !=0 && (emtACL ==radACL)) ));
2565 if( type == 1 && emtID == -radID && !colConnected)
2568 if( type ==-1 && radID == 21)
2571 if( type ==-1 && emtID != 21 && radID != 21 && !colConnected)
2576 double m2final = (
event[RadAfter].p()+
event[EmtAfter].p()).m2Calc();
2578 if( emtID == 22 || emtID == 23)
return radID;
2580 if( type == 1 && emtID == -radID && colConnected && sqrt(m2final) <= 10. )
2583 if( type == 1 && emtID == -radID && colConnected && sqrt(m2final) > 10. )
2586 if( type ==-1 && (radID == 22 || radID == 23))
2589 if( type ==-1 && abs(emtID) < 10 && abs(radID) < 10 && colConnected)
2611 bool History::connectRadiator( Particle& Radiator,
const int RadType,
2612 const Particle& Recoiler,
const int RecType,
2613 const Event& event ){
2616 Radiator.cols( -1, -1 );
2620 if( Radiator.colType() == -1 ) {
2623 if( RadType + RecType == 2 )
2624 Radiator.cols( 0, Recoiler.col());
2625 else if( RadType + RecType == 0 )
2626 Radiator.cols( 0, Recoiler.acol());
2634 for (
int i = 0; i <
event.size(); ++i) {
2635 int col =
event[i].col();
2636 int acl =
event[i].acol();
2638 if( event[i].isFinal()) {
2640 if( acl > 0 && FindCol(acl,i,0,event,1,
true) == 0
2641 && FindCol(acl,i,0,event,2,
true) == 0 )
2642 Radiator.acol(event[i].acol());
2645 if( col > 0 && FindCol(col,i,0,event,1,
true) == 0
2646 && FindCol(col,i,0,event,2,
true) == 0 )
2647 Radiator.acol(event[i].col());
2652 }
else if ( Radiator.colType() == 1 ) {
2655 if( RadType + RecType == 2 )
2656 Radiator.cols( Recoiler.acol(), 0);
2657 else if( RadType + RecType == 0 )
2658 Radiator.cols( Recoiler.col(), 0);
2667 for (
int i = 0; i <
event.size(); ++i) {
2668 int col =
event[i].col();
2669 int acl =
event[i].acol();
2671 if( event[i].isFinal()) {
2673 if( col > 0 && FindCol(col,i,0,event,1,
true) == 0
2674 && FindCol(col,i,0,event,2,
true) == 0)
2675 Radiator.col(event[i].col());
2678 if( acl > 0 && FindCol(acl,i,0,event,1,
true) == 0
2679 && FindCol(acl,i,0,event,2,
true) == 0)
2680 Radiator.col(event[i].acol());
2686 }
else if ( Radiator.colType() == 2 ) {
2692 for (
int i = 0; i <
event.size(); ++i) {
2693 int col =
event[i].col();
2694 int acl =
event[i].acol();
2697 if( event[i].isFinal()) {
2698 if( col > 0 && FindCol(col,iEx,0,event,1,
true) == 0
2699 && FindCol(col,iEx,0,event,2,
true) == 0){
2700 if(Radiator.status() < 0 ) Radiator.col(event[i].col());
2701 else Radiator.acol(event[i].col());
2703 if( acl > 0 && FindCol(acl,iEx,0,event,2,
true) == 0
2704 && FindCol(acl,iEx,0,event,1,
true) == 0 ){
2705 if(Radiator.status() < 0 ) Radiator.acol(event[i].acol());
2706 else Radiator.col(event[i].acol());
2709 if( col > 0 && FindCol(col,iEx,0,event,1,
true) == 0
2710 && FindCol(col,iEx,0,event,2,
true) == 0){
2711 if(Radiator.status() < 0 ) Radiator.acol(event[i].col());
2712 else Radiator.col(event[i].col());
2714 if( acl > 0 && (FindCol(acl,iEx,0,event,2,
true) == 0
2715 && FindCol(acl,iEx,0,event,1,
true) == 0)){
2716 if(Radiator.status() < 0 ) Radiator.col(event[i].acol());
2717 else Radiator.acol(event[i].acol());
2724 if (Radiator.col() < 0 || Radiator.acol() < 0)
return false;
2746 int History::FindCol(
int col,
int iExclude1,
int iExclude2,
2747 const Event& event,
int type,
bool isHardIn){
2749 bool isHard = isHardIn;
2754 for(
int n = 0; n <
event.size(); ++n) {
2755 if( n != iExclude1 && n != iExclude2
2756 && event[n].colType() != 0
2757 &&(
event[n].status() > 0
2758 ||
event[n].status() == -21) ) {
2759 if ( event[n].acol() == col ) {
2763 if ( event[n].col() == col ){
2772 for(
int n = 0; n <
event.size(); ++n) {
2773 if( n != iExclude1 && n != iExclude2
2774 && event[n].colType() != 0
2775 &&(
event[n].status() == 43
2776 ||
event[n].status() == 51
2777 ||
event[n].status() == -41
2778 ||
event[n].status() == -42) ) {
2779 if ( event[n].acol() == col ) {
2783 if ( event[n].col() == col ){
2791 if( type == 1 && index < 0)
return abs(index);
2792 if( type == 2 && index > 0)
return abs(index);
2806 int History::FindParticle(
const Particle& particle,
const Event& event){
2810 for(
int i=0; i < int(event.size()); ++i)
2811 if( event[i].status() == particle.status()
2812 &&
event[i].id() == particle.id()
2813 &&
event[i].colType() == particle.colType()
2814 &&
event[i].chargeType() == particle.chargeType()
2815 &&
event[i].col() == particle.col()
2816 &&
event[i].acol() == particle.acol()
2817 &&
event[i].charge() == particle.charge()){
2834 int History::getRadBeforeCol(
const int rad,
const int emt,
2835 const Event& event){
2838 int type = (
event[rad].isFinal()) ? 1 :-1;
2840 int radBeforeFlav = getRadBeforeFlav(rad,emt,event);
2842 int radBeforeCol = -1;
2844 if(radBeforeFlav == 21) {
2847 if (type == 1 && event[emt].
id() != 21) {
2848 radBeforeCol = (
event[rad].col() > 0)
2849 ? event[rad].col() :
event[emt].col();
2851 }
else if (type == -1 && event[emt].
id() != 21) {
2852 radBeforeCol = (
event[rad].col() > 0)
2853 ? event[rad].col() :
event[emt].acol();
2855 }
else if (type == 1 && event[emt].
id() == 21) {
2858 int colRemove = (
event[rad].col() ==
event[emt].acol())
2859 ? event[rad].acol() :
event[rad].col();
2860 radBeforeCol = (
event[rad].col() == colRemove)
2861 ? event[emt].col() :
event[rad].col();
2863 }
else if (type == -1 && event[emt].
id() == 21) {
2866 int colRemove = (
event[rad].col() ==
event[emt].col())
2867 ? event[rad].col() :
event[rad].acol();
2868 radBeforeCol = (
event[rad].col() == colRemove)
2869 ? event[emt].acol() :
event[rad].col();
2873 }
else if ( radBeforeFlav != 21 && radBeforeFlav > 0){
2876 if (type == 1 && event[emt].
id() != 21) {
2879 int colRemove = (
event[rad].col() ==
event[emt].acol())
2880 ? event[rad].acol() : 0;
2881 radBeforeCol = (
event[rad].col() == colRemove)
2882 ? event[emt].col() :
event[rad].col();
2884 }
else if (type == 1 && event[emt].
id() == 21) {
2887 int colRemove = (
event[rad].col() ==
event[emt].acol())
2888 ? event[rad].col() : 0;
2889 radBeforeCol = (
event[rad].col() == colRemove)
2890 ? event[emt].col() :
event[rad].col();
2892 }
else if (type == -1 && event[emt].
id() != 21) {
2895 int colRemove = (
event[rad].col() ==
event[emt].col())
2896 ? event[rad].col() : 0;
2897 radBeforeCol = (
event[rad].col() == colRemove)
2898 ? event[emt].acol() :
event[rad].col();
2900 }
else if (type == -1 && event[emt].
id() == 21) {
2903 int colRemove = (
event[rad].col() ==
event[emt].col())
2904 ? event[rad].col() : 0;
2905 radBeforeCol = (
event[rad].col() == colRemove)
2906 ? event[emt].acol() :
event[rad].col();
2913 return radBeforeCol;
2926 int History::getRadBeforeAcol(
const int rad,
const int emt,
2927 const Event& event){
2930 int type = (
event[rad].isFinal()) ? 1 :-1;
2932 int radBeforeFlav = getRadBeforeFlav(rad,emt,event);
2934 int radBeforeAcl = -1;
2936 if(radBeforeFlav == 21) {
2939 if (type == 1 && event[emt].
id() != 21) {
2940 radBeforeAcl = (
event[rad].acol() > 0)
2941 ? event[rad].acol() :
event[emt].acol();
2943 }
else if (type == -1 && event[emt].
id() != 21) {
2944 radBeforeAcl = (
event[rad].acol() > 0)
2945 ? event[rad].acol() :
event[emt].col();
2947 }
else if (type == 1 && event[emt].
id() == 21) {
2950 int colRemove = (
event[rad].col() ==
event[emt].acol())
2951 ? event[rad].acol() :
event[rad].col();
2952 radBeforeAcl = (
event[rad].acol() == colRemove)
2953 ? event[emt].acol() :
event[rad].acol();
2955 }
else if (type == -1 && event[emt].
id() == 21) {
2958 int colRemove = (
event[rad].col() ==
event[emt].col())
2959 ? event[rad].col() :
event[rad].acol();
2960 radBeforeAcl = (
event[rad].acol() == colRemove)
2961 ? event[emt].col() :
event[rad].acol();
2965 }
else if ( radBeforeFlav != 21 && radBeforeFlav < 0){
2968 if (type == 1 && event[emt].
id() != 21) {
2971 int colRemove = (
event[rad].col() ==
event[emt].acol())
2972 ? event[rad].acol() : 0;
2973 radBeforeAcl = (
event[rad].acol() == colRemove)
2974 ? event[emt].acol() :
event[rad].acol();
2976 }
else if (type == 1 && event[emt].
id() == 21) {
2979 int colRemove = (
event[rad].acol() ==
event[emt].col())
2980 ? event[rad].acol() : 0;
2981 radBeforeAcl = (
event[rad].acol() == colRemove)
2982 ? event[emt].acol() :
event[rad].acol();
2984 }
else if (type == -1 && event[emt].
id() != 21) {
2987 int colRemove = (
event[rad].acol() ==
event[emt].acol())
2988 ? event[rad].acol() : 0;
2989 radBeforeAcl = (
event[rad].acol() == colRemove)
2990 ? event[emt].col() :
event[rad].acol();
2992 }
else if (type == -1 && event[emt].
id() == 21) {
2995 int colRemove = (
event[rad].acol() ==
event[emt].acol())
2996 ? event[rad].acol() : 0;
2997 radBeforeAcl = (
event[rad].acol() == colRemove)
2998 ? event[emt].col() :
event[rad].acol();
3005 return radBeforeAcl;
3017 int History::getColPartner(
const int in,
const Event& event){
3019 if(event[in].col() == 0)
return 0;
3023 partner = FindCol(event[in].col(),in,0,event,1,
true);
3026 partner = FindCol(event[in].col(),in,0,event,2,
true);
3040 int History::getAcolPartner(
const int in,
const Event& event){
3042 if(event[in].acol() == 0)
return 0;
3046 partner = FindCol(event[in].acol(),in,0,event,2,
true);
3049 partner = FindCol(event[in].acol(),in,0,event,1,
true);
3066 vector<int> History::getReclusteredPartners(
const int rad,
const int emt,
3067 const Event& event){
3070 int type =
event[rad].isFinal() ? 1 : -1;
3072 int radBeforeCol = getRadBeforeCol(rad, emt, event);
3073 int radBeforeAcl = getRadBeforeAcol(rad, emt, event);
3075 vector<int> partners;
3080 for(
int i=0; i < int(event.size()); ++i){
3082 if( i != emt && i != rad
3083 && event[i].status() == -21
3084 &&
event[i].col() > 0
3085 &&
event[i].col() == radBeforeCol)
3086 partners.push_back(i);
3088 if( i != emt && i != rad
3089 && event[i].isFinal()
3090 && event[i].acol() > 0
3091 && event[i].acol() == radBeforeCol)
3092 partners.push_back(i);
3094 if( i != emt && i != rad
3095 && event[i].status() == -21
3096 && event[i].acol() > 0
3097 && event[i].acol() == radBeforeAcl)
3098 partners.push_back(i);
3100 if( i != emt && i != rad
3101 && event[i].isFinal()
3102 && event[i].col() > 0
3103 && event[i].col() == radBeforeAcl)
3104 partners.push_back(i);
3109 for(
int i=0; i < int(event.size()); ++i){
3111 if( i != emt && i != rad
3112 && event[i].status() == -21
3113 &&
event[i].acol() > 0
3114 &&
event[i].acol() == radBeforeCol)
3115 partners.push_back(i);
3117 if( i != emt && i != rad
3118 && event[i].isFinal()
3119 && event[i].col() > 0
3120 && event[i].col() == radBeforeCol)
3121 partners.push_back(i);
3123 if( i != emt && i != rad
3124 && event[i].status() == -21
3125 && event[i].col() > 0
3126 && event[i].col() == radBeforeAcl)
3127 partners.push_back(i);
3129 if( i != emt && i != rad
3130 && event[i].isFinal()
3131 && event[i].acol() > 0
3132 && event[i].acol() == radBeforeAcl)
3133 partners.push_back(i);
3160 bool History::getColSinglet(
const int flavType,
const int iParton,
3161 const Event& event, vector<int>& exclude, vector<int>& colSinglet){
3164 if(iParton < 0)
return false;
3172 for(
int i=0; i < int(event.size()); ++i)
3173 if( event[i].isFinal() &&
event[i].colType() != 0)
3178 int nExclude = int(exclude.size());
3179 int nInitExclude = 0;
3180 if(!event[exclude[2]].isFinal())
3182 if(!event[exclude[3]].isFinal())
3186 if(nFinal == nExclude - nInitExclude)
3196 colSinglet.push_back(iParton);
3198 exclude.push_back(iParton);
3201 colP = getColPartner(iParton,event);
3204 colP = getAcolPartner(iParton,event);
3207 for(
int i = 0; i < int(exclude.size()); ++i)
3208 if(colP == exclude[i])
3212 return getColSinglet(flavType,colP,event,exclude,colSinglet);
3223 bool History::isColSinglet(
const Event& event,
3224 vector<int> system ){
3227 for(
int i=0; i < int(system.size()); ++i ){
3230 && (event[system[i]].colType() == 1
3231 ||
event[system[i]].colType() == 2) ) {
3232 for(
int j=0; j < int(system.size()); ++j)
3236 && event[system[i]].col() ==
event[system[j]].acol()){
3245 && (event[system[i]].colType() == -1
3246 || event[system[i]].colType() == 2) ) {
3247 for(
int j=0; j < int(system.size()); ++j)
3251 && event[system[i]].acol() ==
event[system[j]].col()){
3263 bool isColSing =
true;
3264 for(
int i=0; i < int(system.size()); ++i)
3265 if( system[i] != 0 )
3282 bool History::isFlavSinglet(
const Event& event,
3283 vector<int> system,
int flav){
3288 for(
int i=0; i < int(system.size()); ++i)
3289 if( system[i] > 0 ) {
3290 for(
int j=0; j < int(system.size()); ++j){
3294 if( event[i].idAbs() != 21
3295 &&
event[i].idAbs() != 22
3296 &&
event[i].idAbs() != 23
3297 &&
event[i].idAbs() != 24
3300 &&
event[system[i]].isFinal()
3301 &&
event[system[j]].isFinal()
3302 &&
event[system[i]].id() == -1*
event[system[j]].id()) {
3305 if(abs(flav) > 0 &&
event[system[i]].idAbs() != flav)
3315 if( event[i].idAbs() != 21
3316 &&
event[i].idAbs() != 22
3317 &&
event[i].idAbs() != 23
3318 &&
event[i].idAbs() != 24
3321 && ( ( !
event[system[i]].isFinal() &&
event[system[j]].isFinal())
3322 ||( !event[system[j]].isFinal() &&
event[system[i]].isFinal()) )
3323 &&
event[system[i]].id() ==
event[system[j]].id()) {
3326 if(abs(flav) > 0 &&
event[system[i]].idAbs() != flav)
3339 bool isFlavSing =
true;
3340 for(
int i=0; i < int(system.size()); ++i)
3341 if( system[i] != 0 )
3356 bool History::allowedClustering(
int rad,
int emt,
int rec,
int partner,
3357 const Event& event ){
3360 bool allowed =
true;
3365 bool isSing = isSinglett(rad,emt,partner,event);
3366 int type = (
event[rad].isFinal()) ? 1 :-1;
3368 int radBeforeFlav = getRadBeforeFlav(rad,emt,event);
3370 int radBeforeCol = getRadBeforeCol(rad,emt,event);
3371 int radBeforeAcl = getRadBeforeAcol(rad,emt,event);
3373 vector<int> radBeforeColP = getReclusteredPartners(rad, emt, event);
3376 int nPartonInHard = 0;
3377 for(
int i=0; i < int(event.size()); ++i)
3379 if( event[i].isFinal()
3380 &&
event[i].colType() != 0
3381 && mergingHooksPtr->hardProcess.matchesAnyOutgoing(i, event))
3387 for(
int i=0; i < int(event.size()); ++i)
3389 if( i!=emt && i!=rad && i!=rec
3390 && event[i].isFinal()
3391 &&
event[i].colType() != 0
3392 && !mergingHooksPtr->hardProcess.matchesAnyOutgoing(i, event))
3396 int nInitialPartons = 0;
3397 for(
int i=0; i < int(event.size()); ++i)
3398 if( event[i].status() == -21
3399 &&
event[i].colType() != 0 )
3404 for(
int i=0; i < int(event.size()); ++i)
3405 if( event[i].isFinal()
3406 &&(
event[i].id() == 22
3407 ||
event[i].id() == 23
3408 ||
event[i].id() == 24
3409 ||
event[i].id() == 25
3410 ||(
event[i].idAbs() > 10 &&
event[i].idAbs() < 20)))
3417 int nFinalQuark = 0;
3419 int nFinalQuarkExc = 0;
3420 for(
int i=0; i < int(event.size()); ++i) {
3421 if(i !=rad && i != emt && i != rec) {
3422 if(event[i].isFinal() &&
event[i].isQuark() ){
3423 if ( !mergingHooksPtr->hardProcess.matchesAnyOutgoing(i,event) )
3432 if(event[rec].isFinal() &&
event[rec].isQuark()) nFinalQuark++;
3434 if(event[rad].isFinal() && abs(radBeforeFlav) < 10) nFinalQuark++;
3437 int nInitialQuark = 0;
3439 if(event[rec].isFinal()){
3440 if(event[3].isQuark()) nInitialQuark++;
3441 if(event[4].isQuark()) nInitialQuark++;
3443 int iOtherIn = (rec == 3) ? 4 : 3;
3444 if(event[rec].isQuark()) nInitialQuark++;
3445 if(event[iOtherIn].isQuark()) nInitialQuark++;
3449 if(event[rec].isQuark()) nInitialQuark++;
3451 if(abs(radBeforeFlav) < 10) nInitialQuark++;
3460 for(
int i=0; i < int(event.size()); ++i)
3461 if(event[i].idAbs() == 6)
3467 vector<int> unmatchedCol;
3468 vector<int> unmatchedAcl;
3470 for (
int i = 0; i <
event.size(); ++i)
3471 if( i != emt && i != rad
3472 && (event[i].isFinal() || event[i].status() == -21)
3473 &&
event[i].colType() != 0 ) {
3475 int colP = getColPartner(i,event);
3476 int aclP = getAcolPartner(i,event);
3478 if(event[i].col() > 0
3479 && (colP == emt || colP == rad || colP == 0) )
3480 unmatchedCol.push_back(i);
3481 if(event[i].acol() > 0
3482 && (aclP == emt || aclP == rad || aclP == 0) )
3483 unmatchedAcl.push_back(i);
3489 if(
int(unmatchedCol.size()) +
int(unmatchedAcl.size()) > 2)
3496 if(isSing && (abs(radBeforeFlav)<10 &&
event[rec].isQuark()) )
3500 if( mergingHooksPtr->hardProcess.matchesAnyOutgoing(emt,event)
3501 || mergingHooksPtr->hardProcess.matchesAnyOutgoing(rad,event) )
3506 if(nFinalEW != 0 && nInitialQuark == 0
3507 && nFinalQuark == 0 && nFinalQuarkExc == 0)
3510 if( nTop == 0 && (nInitialQuark + nFinalQuark)%2 != 0 )
3512 if( nTop > 0 && (nInitialQuark + nFinalQuark + nFinalQuarkExc)%2 != 0 )
3521 if(event[3].col() ==
event[4].acol()
3522 &&
event[3].acol() ==
event[4].col()
3523 && nFinalQuark == 0)
3527 if(event[emt].
id() == 21)
3534 vector<int> iInQuarkFlav;
3535 for(
int i=0; i < int(event.size()); ++i)
3537 if( i != emt && i != rad
3538 && event[i].status() == -21
3539 &&
event[i].idAbs() ==
event[emt].idAbs() )
3540 iInQuarkFlav.push_back(i);
3543 vector<int> iOutQuarkFlav;
3544 for(
int i=0; i < int(event.size()); ++i)
3546 if( i != emt && i != rad
3547 && event[i].isFinal()
3548 &&
event[i].idAbs() ==
event[emt].idAbs()
3549 && !mergingHooksPtr->hardProcess.matchesAnyOutgoing(i, event))
3550 iOutQuarkFlav.push_back(i);
3553 int nInQuarkFlav = int(iInQuarkFlav.size());
3554 int nOutQuarkFlav = int(iOutQuarkFlav.size());
3559 if( event[partner].isFinal()
3560 &&
event[partner].id() == 21
3561 && radBeforeFlav == 21
3562 &&
event[partner].col() == radBeforeCol
3563 &&
event[partner].acol() == radBeforeAcl)
3567 if(nInQuarkFlav + nOutQuarkFlav == 0)
3574 vector<int> partons;
3575 for(
int i=0; i < int(event.size()); ++i)
3577 if( i!=emt && i!=rad
3578 && event[i].colType() != 0
3579 && (
event[i].isFinal() ||
event[i].status() == -21) ){
3581 partons.push_back(i);
3583 if(event[i].colType() == 2)
3585 else if (event[i].colType() == 1)
3587 else if (event[i].colType() == -1)
3593 bool isFSRg2qq = ((type == 1) && (event[rad].
id() == -1*
event[emt].id()) );
3594 bool isISRg2qq = ((type ==-1) && (event[rad].
id() ==
event[emt].id()) );
3599 if( (isFSRg2qq || isISRg2qq)
3600 && int(quark.size()) +
int(antiq.size())
3601 +
int(gluon.size()) > nPartonInHard ) {
3603 vector<int> colours;
3604 vector<int> anticolours;
3609 colours.push_back(radBeforeCol);
3610 anticolours.push_back(radBeforeAcl);
3612 colours.push_back(radBeforeAcl);
3613 anticolours.push_back(radBeforeCol);
3616 for(
int i=0; i < int(gluon.size()); ++i)
3617 if(event[gluon[i]].isFinal()){
3618 colours.push_back(event[gluon[i]].col());
3619 anticolours.push_back(event[gluon[i]].acol());
3621 colours.push_back(event[gluon[i]].acol());
3622 anticolours.push_back(event[gluon[i]].col());
3627 for(
int i=0; i < int(colours.size()); ++i)
3628 for(
int j=0; j < int(anticolours.size()); ++j)
3629 if(colours[i] > 0 && anticolours[j] > 0
3630 && colours[i] == anticolours[j]){
3637 bool allMatched =
true;
3638 for(
int i=0; i < int(colours.size()); ++i)
3641 for(
int i=0; i < int(anticolours.size()); ++i)
3642 if(anticolours[i] != 0)
3650 for(
int i=0; i < int(quark.size()); ++i)
3651 if( event[quark[i]].isFinal()
3652 && mergingHooksPtr->hardProcess.matchesAnyOutgoing(quark[i], event))
3653 colours.push_back(event[quark[i]].col());
3655 for(
int i=0; i < int(antiq.size()); ++i)
3656 if( event[antiq[i]].isFinal()
3657 && mergingHooksPtr->hardProcess.matchesAnyOutgoing(antiq[i], event))
3658 anticolours.push_back(event[antiq[i]].acol());
3662 for(
int i=0; i < int(colours.size()); ++i)
3663 for(
int j=0; j < int(anticolours.size()); ++j)
3664 if(colours[i] > 0 && anticolours[j] > 0
3665 && colours[i] == anticolours[j]){
3673 for(
int i=0; i < int(colours.size()); ++i)
3676 for(
int i=0; i < int(anticolours.size()); ++i)
3677 if(anticolours[i] != 0)
3687 if(isFSRg2qq && nInQuarkFlav + nOutQuarkFlav > 0){
3691 for(
int i=0; i < int(gluon.size()); ++i){
3692 if(!event[gluon[i]].isFinal()
3693 &&
event[gluon[i]].col() == radBeforeCol
3694 &&
event[gluon[i]].acol() == radBeforeAcl)
3700 for(
int i=0; i < int(gluon.size()); ++i){
3701 if(event[gluon[i]].isFinal()
3702 &&
event[gluon[i]].col() == radBeforeAcl
3703 &&
event[gluon[i]].acol() == radBeforeCol)
3709 if(
int(radBeforeColP.size()) == 2
3710 && event[radBeforeColP[0]].isFinal()
3711 &&
event[radBeforeColP[1]].isFinal()
3712 &&
event[radBeforeColP[0]].id() == -1*
event[radBeforeColP[1]].id() ){
3716 if(nInitialPartons > 0)
3723 if(
int(radBeforeColP.size()) == 2
3724 && (( event[radBeforeColP[0]].status() == -21
3725 && event[radBeforeColP[1]].isFinal())
3726 ||(
event[radBeforeColP[0]].isFinal()
3727 &&
event[radBeforeColP[1]].status() == -21))
3728 &&
event[radBeforeColP[0]].id() ==
event[radBeforeColP[1]].id() ){
3735 int incoming = (
event[radBeforeColP[0]].isFinal())
3736 ? radBeforeColP[1] : radBeforeColP[0];
3737 int outgoing = (
event[radBeforeColP[0]].isFinal())
3738 ? radBeforeColP[0] : radBeforeColP[1];
3741 bool clusPossible =
false;
3742 for(
int i=0; i < int(event.size()); ++i)
3743 if( i != emt && i != rad
3744 && i != incoming && i != outgoing
3745 && !mergingHooksPtr->hardProcess.matchesAnyOutgoing(i,event) ){
3747 if( event[i].status() == -21
3748 && (
event[i].id() ==
event[outgoing].id()
3749 ||
event[i].id() == -1*
event[incoming].id()) )
3750 clusPossible =
true;
3752 if( event[i].isFinal()
3753 && (
event[i].id() == -1*
event[outgoing].id()
3754 ||
event[i].id() ==
event[incoming].id()) )
3755 clusPossible =
true;
3766 vector<int> excludeIn1;
3767 for(
int i=0; i < 4; ++i)
3768 excludeIn1.push_back(0);
3769 vector<int> colSingletIn1;
3770 int flavIn1Type = (
event[incoming].id() > 0) ? 1 : -1;
3772 bool isColSingIn1 = getColSinglet(flavIn1Type,incoming,event,
3773 excludeIn1,colSingletIn1);
3775 bool isFlavSingIn1 = isFlavSinglet(event,colSingletIn1);
3780 int incoming2 = (incoming == 3) ? 4 : 3;
3781 vector<int> excludeIn2;
3782 for(
int i=0; i < 4; ++i)
3783 excludeIn2.push_back(0);
3784 vector<int> colSingletIn2;
3785 int flavIn2Type = (
event[incoming2].id() > 0) ? 1 : -1;
3787 bool isColSingIn2 = getColSinglet(flavIn2Type,incoming2,event,
3788 excludeIn2,colSingletIn2);
3790 bool isFlavSingIn2 = isFlavSinglet(event,colSingletIn2);
3794 && (!isColSingIn1 || !isFlavSingIn1
3795 || !isColSingIn2 || !isFlavSingIn2))
3807 int flav =
event[emt].id();
3808 vector<int> exclude;
3809 exclude.push_back(emt);
3810 exclude.push_back(rad);
3811 exclude.push_back(radBeforeColP[0]);
3812 exclude.push_back(radBeforeColP[1]);
3813 vector<int> colSinglet;
3817 for(
int i=0; i < int(event.size()); ++i)
3822 && i != radBeforeColP[0]
3823 && i != radBeforeColP[1]
3824 && event[i].isFinal() ) {
3826 if(event[i].
id() == flav){
3832 int flavType = (
event[iOther].id() > 0) ? 1 : -1;
3834 bool isColSing = getColSinglet(flavType,iOther,event,exclude,colSinglet);
3836 bool isFlavSing = isFlavSinglet(event,colSinglet);
3839 if(isColSing && isFlavSing){
3845 vector<int> allFinal;
3846 for(
int i=0; i < int(event.size()); ++i)
3847 if( event[i].isFinal() )
3848 allFinal.push_back(i);
3851 bool isFullColSing = isColSinglet(event,allFinal);
3853 bool isFullFlavSing = isFlavSinglet(event,allFinal,flav);
3858 if(!isFullColSing || !isFullFlavSing)
3865 if(isISRg2qq && nInQuarkFlav + nOutQuarkFlav > 0){
3869 for(
int i=0; i < int(gluon.size()); ++i){
3870 if(event[gluon[i]].isFinal()
3871 &&
event[gluon[i]].col() == radBeforeCol
3872 &&
event[gluon[i]].acol() == radBeforeAcl)
3878 for(
int i=0; i < int(gluon.size()); ++i){
3879 if(event[gluon[i]].status() == -21
3880 &&
event[gluon[i]].acol() == radBeforeCol
3881 &&
event[gluon[i]].col() == radBeforeAcl)
3887 if(
int(radBeforeColP.size()) == 2
3888 && event[radBeforeColP[0]].isFinal()
3889 &&
event[radBeforeColP[1]].isFinal()
3890 &&
event[radBeforeColP[0]].id() == -1*
event[radBeforeColP[1]].id() ) {
3897 bool clusPossible =
false;
3898 for(
int i=0; i < int(event.size()); ++i)
3899 if( i != emt && i != rad
3900 && i != radBeforeColP[0]
3901 && i != radBeforeColP[1]
3902 && !mergingHooksPtr->hardProcess.matchesAnyOutgoing(i,event) ){
3903 if(event[i].status() == -21
3904 && (
event[radBeforeColP[0]].id() ==
event[i].id()
3905 ||
event[radBeforeColP[1]].id() ==
event[i].id() ))
3906 clusPossible =
true;
3907 if(event[i].isFinal()
3908 && (
event[radBeforeColP[0]].id() == -1*
event[i].id()
3909 ||
event[radBeforeColP[1]].id() == -1*
event[i].id() ))
3910 clusPossible =
true;
3922 vector<int> excludeIn1;
3923 for(
int i=0; i < 4; ++i)
3924 excludeIn1.push_back(0);
3925 vector<int> colSingletIn1;
3926 int flavIn1Type = (
event[incoming1].id() > 0) ? 1 : -1;
3928 bool isColSingIn1 = getColSinglet(flavIn1Type,incoming1,event,
3929 excludeIn1,colSingletIn1);
3931 bool isFlavSingIn1 = isFlavSinglet(event,colSingletIn1);
3937 vector<int> excludeIn2;
3938 for(
int i=0; i < 4; ++i)
3939 excludeIn2.push_back(0);
3940 vector<int> colSingletIn2;
3941 int flavIn2Type = (
event[incoming2].id() > 0) ? 1 : -1;
3943 bool isColSingIn2 = getColSinglet(flavIn2Type,incoming2,event,
3944 excludeIn2,colSingletIn2);
3946 bool isFlavSingIn2 = isFlavSinglet(event,colSingletIn2);
3950 && (!isColSingIn1 || !isFlavSingIn1
3951 || !isColSingIn2 || !isFlavSingIn2))
3970 bool History::isSinglett(
int rad,
int emt,
int rec,
const Event& event ){
3972 int radCol =
event[rad].col();
3973 int emtCol =
event[emt].col();
3974 int recCol =
event[rec].col();
3975 int radAcl =
event[rad].acol();
3976 int emtAcl =
event[emt].acol();
3977 int recAcl =
event[rec].acol();
3978 int recType =
event[rec].isFinal() ? 1 : -1;
3980 bool isSing =
false;
3983 && radCol + emtCol == recCol && radAcl + emtAcl == recAcl)
3985 && radCol + emtCol == recAcl && radAcl + emtAcl == recCol) )
4001 bool History::validEvent(
const Event& event ){
4004 bool validColour =
true;
4005 for (
int i = 0; i <
event.size(); ++i)
4007 if( event[i].isFinal() &&
event[i].colType() == 1
4009 && ( FindCol(event[i].col(),i,0,event,1,
true) == 0
4011 && FindCol(event[i].col(),i,0,event,2,
true) == 0 )) {
4012 validColour =
false;
4015 }
else if ( event[i].isFinal() &&
event[i].colType() == -1
4017 && ( FindCol(event[i].acol(),i,0,event,2,
true) == 0
4019 && FindCol(event[i].acol(),i,0,event,1,
true) == 0 )) {
4020 validColour =
false;
4023 }
else if ( event[i].isFinal() &&
event[i].colType() == 2
4025 && ( FindCol(event[i].col(),i,0,event,1,
true) == 0
4027 && FindCol(event[i].col(),i,0,event,2,
true) == 0 )
4029 && ( FindCol(event[i].acol(),i,0,event,2,
true) == 0
4031 && FindCol(event[i].acol(),i,0,event,1,
true) == 0 )) {
4032 validColour =
false;
4037 bool validCharge =
true;
4038 double initCharge =
event[3].charge() +
event[4].charge();
4039 double finalCharge = 0.0;
4040 for(
int i = 0; i <
event.size(); ++i)
4041 if(event[i].isFinal()) finalCharge += event[i].charge();
4042 if(abs(initCharge-finalCharge) > 1e-12) validCharge =
false;
4044 return (validColour && validCharge);
4053 bool History::equalClustering( Clustering clus1 , Clustering clus2 ) {
4054 return ( (clus1.emittor == clus2.emittor)
4055 && (clus1.emitted == clus2.emitted)
4056 && (clus1.recoiler == clus2.recoiler)
4057 && (clus1.partner == clus2.partner)
4058 && (clus1.pT() == clus2.pT()) );
4067 double History::choseHardScale(
const Event& event )
const {
4070 double mHat = (
event[3].p() +
event[4].p()).mCalc();
4077 for(
int i = 0; i <
event.size(); ++i)
4078 if( event[i].isFinal() ) {
4081 if( abs(event[i].
id()) == 23
4082 || abs(event[i].
id()) == 24 ){
4085 mBos +=
event[i].m();
4087 }
else if( abs(event[i].status()) == 22
4088 && ( abs(event[i].
id()) == 23
4089 || abs(event[i].
id()) == 24 )) {
4091 mBos +=
event[i].m();
4095 if( nBosons > 0 && (nFinal + nFinBos*2) <= 3)
4096 return (mBos /
double(nBosons));
4106 int History::getCurrentFlav(
const int side)
const {
4107 int in = (side == 1) ? 3 : 4;
4108 return state[in].id();
4113 double History::getCurrentX(
const int side)
const {
4114 int in = (side == 1) ? 3 : 4;
4115 return ( 2.*state[in].e()/state[0].e() );
4120 double History::getCurrentZ(
const int rad,
4121 const int rec,
const int emt)
const {
4123 int type = state[rad].isFinal() ? 1 : -1;
4128 Vec4 sum = state[rad].p() + state[rec].p()
4130 double m2Dip = sum.m2Calc();
4131 double x1 = 2. * (sum * state[rad].p()) / m2Dip;
4132 double x3 = 2. * (sum * state[emt].p()) / m2Dip;
4137 Vec4 qBR(state[rad].p() - state[emt].p() + state[rec].p());
4138 Vec4 qAR(state[rad].p() + state[rec].p());
4140 z = (qBR.m2Calc())/( qAR.m2Calc());
4151 double History::pTLund(
const Particle& RadAfterBranch,
4152 const Particle& EmtAfterBranch,
4153 const Particle& RecAfterBranch,
int ShowerType){
4156 int Type = ShowerType;
4158 int sign = (Type==1) ? 1 : -1;
4159 Vec4 Q(RadAfterBranch.p() + sign*EmtAfterBranch.p());
4160 double Qsq = sign * Q.m2Calc();
4162 double m2Rad = (mergingHooksPtr->includeMassive()
4163 && abs(RadAfterBranch.id()) >= 4
4164 && abs(RadAfterBranch.id()) < 7)
4165 ? pow(particleDataPtr->m0(RadAfterBranch.id()), 2)
4168 Vec4 sum = RadAfterBranch.p() + RecAfterBranch.p()
4169 + EmtAfterBranch.p();
4170 double m2Dip = sum.m2Calc();
4171 double x1 = 2. * (sum * RadAfterBranch.p()) / m2Dip;
4172 double x3 = 2. * (sum * EmtAfterBranch.p()) / m2Dip;
4174 Vec4 qBR(RadAfterBranch.p() - EmtAfterBranch.p() + RecAfterBranch.p());
4175 Vec4 qAR(RadAfterBranch.p() + RecAfterBranch.p());
4177 double z = (Type==1) ? x1/(x1+x3)
4178 : (qBR.m2Calc())/( qAR.m2Calc());
4180 double pTpyth = (Type==1) ? z*(1.-z) : (1.-z);
4182 pTpyth *= (Qsq - sign*m2Rad);
4184 infoPtr->errorMsg(
"Warning in History::pTLund: Reconstructed evolution",
4185 "variable for massive splitting negative, raised to 0.");
4189 return sqrt(pTpyth);