9 #include "Pythia8/HeavyIons.h"
10 #include "Pythia8/Pythia.h"
33 map<string,Flag> flags = settings.getFlagMap(match);
34 for ( map<string,Flag>::iterator it = flags.begin();
35 it != flags.end(); ++it )
36 settings.addFlag(
"HI" + it->second.name, it->second.valDefault);
37 map<string,Mode> modes = settings.getModeMap(match);
38 for ( map<string,Mode>::iterator it = modes.begin();
39 it != modes.end(); ++it )
40 settings.addMode(
"HI" + it->second.name, it->second.valDefault,
41 it->second.hasMin, it->second.hasMax,
42 it->second.valMin, it->second.valMax, it->second.optOnly);
43 map<string,Parm> parms = settings.getParmMap(match);
44 for ( map<string,Parm>::iterator it = parms.begin();
45 it != parms.end(); ++it )
46 settings.addParm(
"HI" + it->second.name, it->second.valDefault,
47 it->second.hasMin, it->second.hasMax,
48 it->second.valMin, it->second.valMax);
49 map<string,Word> words = settings.getWordMap(match);
50 for ( map<string,Word>::iterator it = words.begin();
51 it != words.end(); ++it )
52 settings.addWord(
"HI" + it->second.name, it->second.valDefault);
53 map<string,FVec> fvecs = settings.getFVecMap(match);
54 for ( map<string, FVec>::iterator it = fvecs.begin();
55 it != fvecs.end(); ++it )
56 settings.addFVec(
"HI" + it->second.name, it->second.valDefault);
57 map<string,MVec> mvecs = settings.getMVecMap(match);
58 for ( map<string,MVec>::iterator it = mvecs.begin();
59 it != mvecs.end(); ++it )
60 settings.addMVec(
"HI" + it->second.name, it->second.valDefault,
61 it->second.hasMin, it->second.hasMax,
62 it->second.valMin, it->second.valMax);
63 map<string,PVec> pvecs = settings.getPVecMap(match);
64 for ( map<string,PVec>::iterator it = pvecs.begin();
65 it != pvecs.end(); ++it )
66 settings.addPVec(
"HI" + it->second.name, it->second.valDefault,
67 it->second.hasMin, it->second.hasMax,
68 it->second.valMin, it->second.valMax);
69 map<string,WVec> wvecs = settings.getWVecMap(match);
70 for ( map<string,WVec>::iterator it = wvecs.begin();
71 it != wvecs.end(); ++it )
72 settings.addWVec(
"HI" + it->second.name, it->second.valDefault);
77 map<string, Flag> flags = opts.getFlagMap(match);
78 for ( map<string, Flag>::iterator it = flags.begin();
79 it != flags.end(); ++it )
80 opts.flag(it->second.name.substr(2), it->second.valNow,
true);
81 map<string, Mode> modes = opts.getModeMap(match);
82 for ( map<string, Mode>::iterator it = modes.begin();
83 it != modes.end(); ++it )
84 opts.mode(it->second.name.substr(2), it->second.valNow,
true);
85 map<string, Parm> parms = opts.getParmMap(match);
86 for ( map<string, Parm>::iterator it = parms.begin();
87 it != parms.end(); ++it )
88 opts.parm(it->second.name.substr(2), it->second.valNow,
true);
89 map<string, Word> words = opts.getWordMap(match);
90 for ( map<string, Word>::iterator it = words.begin();
91 it != words.end(); ++it )
92 opts.word(it->second.name.substr(2), it->second.valNow,
true);
93 map<string, FVec> fvecs = opts.getFVecMap(match);
94 for ( map<string, FVec>::iterator it = fvecs.begin();
95 it != fvecs.end(); ++it )
96 opts.fvec(it->second.name.substr(2), it->second.valNow,
true);
97 map<string, MVec> mvecs = opts.getMVecMap(match);
98 for ( map<string, MVec>::iterator it = mvecs.begin();
99 it != mvecs.end(); ++it )
100 opts.mvec(it->second.name.substr(2), it->second.valNow,
true);
101 map<string, PVec> pvecs = opts.getPVecMap(match);
102 for ( map<string, PVec>::iterator it = pvecs.begin();
103 it != pvecs.end(); ++it )
104 opts.pvec(it->second.name.substr(2), it->second.valNow,
true);
105 map<string, WVec> wvecs = opts.getWVecMap(match);
106 for ( map<string, WVec>::iterator it = wvecs.begin();
107 it != wvecs.end(); ++it )
108 opts.wvec(it->second.name.substr(2), it->second.valNow,
true);
116 for ( map<string,int>::const_iterator it = other.messages.begin();
117 it != other.messages.end(); ++it )
118 in.messages[tag + it->first] += it->second;
127 string path = pyt.settings.word(
"xmlPath");
128 pyt.settings.init(path +
"QCDProcesses.xml",
true);
129 pyt.settings.init(path +
"ElectroweakProcesses.xml",
true);
130 pyt.settings.init(path +
"OniaProcesses.xml",
true);
131 pyt.settings.init(path +
"TopProcesses.xml",
true);
132 pyt.settings.init(path +
"FourthGenerationProcesses.xml",
true);
133 pyt.settings.init(path +
"HiggsProcesses.xml",
true);
134 pyt.settings.init(path +
"SUSYProcesses.xml",
true);
135 pyt.settings.init(path +
"NewGaugeBosonProcesses.xml",
true);
136 pyt.settings.init(path +
"LeftRightSymmetryProcesses.xml",
true);
137 pyt.settings.init(path +
"LeptoquarkProcesses.xml",
true);
138 pyt.settings.init(path +
"CompositenessProcesses.xml",
true);
139 pyt.settings.init(path +
"HiddenValleyProcesses.xml",
true);
140 pyt.settings.init(path +
"ExtraDimensionalProcesses.xml",
true);
141 pyt.settings.init(path +
"DarkMatterProcesses.xml",
true);
142 pyt.settings.init(path +
"ASecondHardProcess.xml",
true);
143 pyt.settings.init(path +
"PhaseSpaceCuts.xml",
true);
159 double norm = 1.0/double(
hiinfo.NSave);
163 for ( map<int,int>::iterator ip =
hiinfo.NPrim.begin();
164 ip !=
hiinfo.NPrim.end(); ++ip ) {
168 double w =
hiinfo.sumPrimW[pc]/millibarn;
169 double w2 =
hiinfo.sumPrimW2[pc]/pow2(millibarn);
171 w*norm, sqrt(w2*norm)/N, w);
177 wall*norm, sqrt(w2all*norm)/Nall, wall);
184 void HeavyIons::stat() {
192 cout <<
"\n *----- HeavyIon Event and Cross Section Statistics ------"
193 <<
"-------------------------------------------------------*\n"
196 <<
" | Subprocess Code | "
197 <<
" Number of events | sigma +- delta |\n"
199 <<
"Tried Selected Accepted | (estimated) (mb) |\n"
202 <<
" |------------------------------------------------------------"
203 <<
"-----------------------------------------------------|\n"
207 vector<int> pc = in.codesHard();
208 for (
int i = 0, N = pc.size(); i < N; ++i ) {
209 cout <<
" | " << left << setw(45) << in.nameProc(pc[i])
210 << right << setw(5) << pc[i] <<
" | "
211 << setw(11) << in.nTried(pc[i]) <<
" "
212 << setw(10) << in.nSelected(pc[i]) <<
" "
213 << setw(10) << in.nAccepted(pc[i]) <<
" | "
214 << scientific << setprecision(3)
215 << setw(11) << in.sigmaGen(pc[i])
216 << setw(11) << in.sigmaErr(pc[i]) <<
" |\n";
218 if ( pc.empty() ) in.setSigma(0,
"sum",
hiinfo.NSave, 0, 0, 0.0, 0.0, 0.0);
222 <<
" | " << left << setw(50) <<
"sum" << right <<
" | " << setw(11)
223 << in.nTried(0) <<
" " << setw(10) << in.nSelected(0) <<
" "
224 << setw(10) << in.nAccepted(0) <<
" | " << scientific
225 << setprecision(3) << setw(11)
226 << in.sigmaGen(0) << setw(11) << in.sigmaErr(0) <<
" |\n";
227 cout <<
" | " << left << setw(50) <<
"(Estimated total cross section)"
228 << right <<
" | " << setw(11)
230 << 0 <<
" | " << scientific << setprecision(3) << setw(11)
232 cout <<
" | " << left << setw(50)
233 <<
"(Estimated non-diffractive cross section)"
234 << right <<
" | " << setw(11)
236 << 0 <<
" | " << scientific << setprecision(3) << setw(11)
241 <<
" *----- End HeavyIon Event and Cross Section Statistics -----"
242 <<
"-----------------------------------------------------*" << endl;
244 if ( reset )
hiinfo = HIInfo();
246 for (
int i = 1, np =
pythia.size(); i < np; ++i )
248 in.errorStatistics();
250 if ( reset ) in.errorReset();
259 int idProj = settings.mode(
"Beams:idA");
260 int idTarg = settings.mode(
"Beams:idB");
261 return ( abs(idProj/100000000) == 10 ||abs(idTarg/100000000) == 10 );
273 :
HeavyIons(mainPythiaIn), hasSignal(true),
274 bGenPtr(0), projPtr(0), targPtr(0), collPtr(0), recoilerMode(1), bMode(0) {
291 Angantyr::~Angantyr() {
322 ei.
event = pyt.event;
328 ei.
projs[coll->proj] = make_pair(1, ei.
event.size());
329 ei.targs[coll->
targ] = make_pair(2, ei.
event.size());
344 bool print = settings.flag(
"HeavyIon:showInit");
346 int idProj = settings.mode(
"Beams:idA");
347 int idTarg = settings.mode(
"Beams:idB");
348 int idProjP = idProj;
350 int idTargP = idTarg;
352 bool isHIProj = ( abs(idProj/100000000) == 10 );
353 bool isHITarg = ( abs(idTarg/100000000) == 10 );
354 bool isHI = isHIProj || isHITarg || settings.mode(
"HeavyIon:mode") > 1;
356 idProjP = idProj > 0? 2212: -2212;
357 idProjN = idProj > 0? 2112: -2112;
359 if ( abs(idTarg/100000000) == 10 ) {
360 idTargP = idTarg > 0? 2212: -2212;
361 idTargN = idTarg > 0? 2112: -2112;
363 if ( settings.mode(
"HeavyIon:mode") == 1 && !isHI ) {
364 info.errorMsg(
"Angantyr Info: No heavy ions requested"
365 " - reverting to normal Pythia behavior.");
366 settings.mode(
"HeavyIon:mode", 0);
370 recoilerMode = settings.mode(
"Angantyr:SDRecoil");
371 bMode = settings.mode(
"Angantyr:impactMode");
373 int frame = settings.mode(
"Beams:frameType");
374 bool dohad = settings.flag(
"HadronLevel:all");
376 info.errorMsg(
"Angantyr warning: Currently only Beams:frameType = 1 or 2 "
377 "is supported. Assuming 2.");
378 double eAbm = settings.parm(
"Beams:eA");
379 double eBbm = settings.parm(
"Beams:eB");
380 if ( frame == 1 ) eAbm = eBbm = settings.parm(
"Beams:eCM")/2.0;
381 settings.parm(
"Beams:eA", eAbm);
382 settings.parm(
"Beams:eB", eBbm);
383 settings.mode(
"Beams:frameType", 2);
385 settings.mode(
"Next:numberCount", 0);
386 settings.mode(
"Next:numberShowLHA", 0);
387 settings.mode(
"Next:numberShowInfo", 0);
388 settings.mode(
"Next:numberShowProcess", 0);
389 settings.mode(
"Next:numberShowEvent", 0);
390 settings.flag(
"HadronLevel:all",
false);
391 settings.flag(
"SoftQCD:all",
false);
392 settings.flag(
"SoftQCD:elastic",
false);
393 settings.flag(
"SoftQCD:nonDiffractive",
false);
394 settings.flag(
"SoftQCD:singleDiffractive",
false);
395 settings.flag(
"SoftQCD:doubleDiffractive",
false);
396 settings.flag(
"SoftQCD:centralDiffractive",
false);
398 for (
int i =
MBIAS; i <
ALL; ++i ) {
400 pythia[i]->settings.mode(
"HeavyIon:mode", 1);
407 sigtot.calc(2212, 2212, sqrt(4.0*eAbm*eBbm));
411 pythia[
MBIAS]->settings.mode(
"Beams:idA", idProjP);
412 pythia[
MBIAS]->settings.mode(
"Beams:idB", idTargP);
416 sdabsopts.flag(
"SoftQCD:singleDiffractive",
true);
423 if ( sdabsopts.mode(
"Angantyr:SASDmode") > 0 ) {
424 double pT0Ref = sdabsopts.parm(
"MultipartonInteractions:pT0Ref");
425 double ecmRef = sdabsopts.parm(
"MultipartonInteractions:ecmRef");
426 double ecmPow = sdabsopts.parm(
"MultipartonInteractions:ecmPow");
427 double ecm = sqrt(4.0*eBbm*eAbm);
428 sdabsopts.parm(
"Beams:eCM", ecm);
429 double pT0 = pT0Ref * pow(ecm / ecmRef, ecmPow);
430 sdabsopts.parm(
"MultipartonInteractions:pT0Ref", pT0);
431 sdabsopts.parm(
"MultipartonInteractions:ecmRef", ecm);
432 sdabsopts.parm(
"MultipartonInteractions:ecmPow", 0.0);
433 sdabsopts.word(
"PDF:PomSet",
"11");
434 if ( sdabsopts.mode(
"Angantyr:SASDmode") == 2 ) {
435 sdabsopts.parm(
"Diffraction:mRefPomP", ecm);
436 double sigND =
sigtot.sigmaND();
437 double mmin = sdabsopts.parm(
"Diffraction:mMinPert");
438 double powp = sdabsopts.parm(
"HIDiffraction:mPowPomP");
439 sdabsopts.parm(
"Diffraction:mPowPomP", powp,
true);
440 if ( powp > 0.0 ) sigND /= ((1.0 - pow(mmin/ecm, powp))/powp);
441 else sigND /= log(ecm/mmin);
442 sdabsopts.parm(
"Diffraction:sigmaRefPomP", sigND,
true);
444 if ( sdabsopts.mode(
"Angantyr:SASDmode") >= 3 ) {
445 sdabsopts.parm(
"Diffraction:mRefPomP", ecm);
446 double sigND =
sigtot.sigmaND();
447 sdabsopts.parm(
"Diffraction:sigmaRefPomP", sigND,
true);
448 sdabsopts.parm(
"Diffraction:mPowPomP", 0.0);
451 sdabsopts.mode(
"Beams:idA", idProjP);
452 sdabsopts.mode(
"Beams:idB", idTargP);
455 pythia[
HADRON]->settings.flag(
"ProcessLevel:all",
false);
456 pythia[
HADRON]->settings.flag(
"PartonLevel:all",
false);
457 pythia[
HADRON]->settings.flag(
"HadronLevel:all", dohad);
461 pythia[
SIGPP]->settings.mode(
"Beams:idA", idProjP);
462 pythia[
SIGPP]->settings.mode(
"Beams:idB", idTargP);
464 pythia[
SIGPN]->settings.mode(
"Beams:idA", idProjP);
465 pythia[
SIGPN]->settings.mode(
"Beams:idB", idTargN);
468 pythia[
SIGNP]->settings.mode(
"Beams:idA", idProjN);
469 pythia[
SIGNP]->settings.mode(
"Beams:idB", idTargP);
471 if ( idProjN && idTargN ) {
472 pythia[
SIGNN]->settings.mode(
"Beams:idA", idProjN);
473 pythia[
SIGNN]->settings.mode(
"Beams:idB", idTargN);
494 else if ( settings.mode(
"Angantyr:CollisionModel") == 1 )
496 else if ( settings.mode(
"Angantyr:CollisionModel") == 2 )
501 collPtr->initPtr(*projPtr, *targPtr,
sigtot, settings,
503 if ( !collPtr->
init() )
return false;
506 bGenPtr =
HIHooksPtr->impactParameterGenerator();
509 bGenPtr->initPtr(*collPtr, *projPtr, *targPtr,
512 if ( !projPtr->init() )
return false;
513 if ( !targPtr->init() )
return false;
514 if ( !bGenPtr->
init() )
return false;
524 if ( print ) cout <<
" Angantyr Info: No signal process specified. "
525 <<
"Assuming minimum bias." << endl;
528 cout <<
" Angantyr Info: Initializing signal process (pp)." << endl
530 <<
"Generating a few signal events (pp) to build up statistics"
537 cout <<
" Angantyr Info: Initializing signal process (pn)." << endl;
540 cout <<
"Generating a few signal events (pn) to build up statistics"
547 cout <<
" Angantyr Info: Initializing signal process (np)." << endl;
550 cout <<
"Generating a few signal events (np) to build up statistics"
555 if ( idProjN && idTargN ) {
557 cout <<
" Angantyr Info: Initializing signal process (nn)." << endl;
560 cout <<
"Generating a few signal events (nn) to build up statistics"
569 cout <<
" Angantyr Info: Initializing minimum bias processes." << endl;
574 cout <<
" Angantyr Info: Initializing secondary absorptive processes as"
575 <<
" single diffraction." << endl;
579 if (
pythia[HADRON]->flag(
"HadronLevel:all") ) {
581 cout <<
" Angantyr Info: Initializing hadronisation processes." << endl;
583 settings.flag(
"ProcessLevel:all",
false);
596 int pytsel =
SIGPP + coll.nucleons();
603 "Could not setup signal sub collision.");
610 if ( bMode > 0 && procid == 101 ) bp = coll->
bp;
611 HoldProcess hold(selectMB, procid, bp);
620 EventInfo Angantyr::getSASD(
const SubCollision * coll,
int procid) {
623 if ( bMode > 1 ) bp = coll->bp;
624 HoldProcess hold(selectSASD, procid, bp);
638 bool Angantyr::genAbs(
const multiset<SubCollision> & coll,
639 list<EventInfo> & subevents) {
641 vector<multiset<SubCollision>::const_iterator> abscoll;
643 vector<multiset<SubCollision>::const_iterator> abspart;
645 multiset<EventInfo> ndeve, sigeve;
648 for ( multiset<SubCollision>::iterator cit = coll.begin();
649 cit != coll.end(); ++cit ) {
651 if (!cit->proj->done() && !cit->targ->done() ) {
652 abscoll.push_back(cit);
655 assert( ie.info.code() == 101 );
661 abspart.push_back(cit);
664 if ( abscoll.empty() )
return true;
666 int Nabs = abscoll.size();
667 int Nadd = abspart.size();
670 for (
int i = 0; i < Nabs + Nadd; ++i ) {
672 assert( ie.info.code() == 101 );
676 vector<int> Nii(4, 0);
677 vector<double> w(4, 0.0);
684 for (
int i = 0, N = abscoll.size(); i < N; ++i )
685 ++Nii[abscoll[i]->nucleons()];
686 for (
int i = 0, N = abspart.size(); i < N; ++i )
687 ++Nii[abspart[i]->nucleons()];
698 wsum = Nii[0]*w[0] + Nii[1]*w[1] + Nii[2]*w[2] + Nii[3]*w[3];
699 P1 = 1.0 - pow(1.0 - w[0], Nii[0])*pow(1.0 - w[1], Nii[1])*
700 pow(1.0 - w[2], Nii[2])*pow(1.0 - w[3], Nii[3]);
704 bool noSignal = hasSignal;
709 multiset<EventInfo>::iterator it = ndeve.begin();
711 for (
int i = 0, N = abscoll.size(); i < N; ++i ) {
712 int b = abscoll[i]->nucleons();
714 && ( noSignal || w[b]*(wsum/P1 - 1.0)/(wsum - w[b]) >
721 subevents.push_back(ei);
722 if ( !setupFullCollision(subevents.back(), *abscoll[i],
727 if ( noSignal )
return false;
739 void Angantyr::addSASD(
const multiset<SubCollision> & coll) {
745 for ( multiset<SubCollision>::iterator cit = coll.begin();
746 cit != coll.end(); ++cit )
748 if ( cit->targ->done() && !cit->proj->done() ) {
750 for (
int itry = 0; itry < ntry; ++itry ) {
758 }
else if ( cit->proj->done() && !cit->targ->done() ) {
760 for (
int itry = 0; itry < ntry; ++itry ) {
776 bool Angantyr::addDD(
const multiset<SubCollision> & coll,
777 list<EventInfo> & subevents) {
779 for ( multiset<SubCollision>::iterator cit = coll.begin();
780 cit != coll.end(); ++cit )
782 !cit->proj->done() && !cit->targ->done() ) {
783 subevents.push_back(getDD(*cit));
784 if ( !setupFullCollision(subevents.back(), *cit,
795 bool Angantyr::addSD(
const multiset<SubCollision> & coll,
796 list<EventInfo> & subevents) {
798 for ( multiset<SubCollision>::iterator cit = coll.begin();
799 cit != coll.end(); ++cit )
800 if ( !cit->proj->done() && !cit->targ->done() ) {
802 subevents.push_back(getSDP(*cit));
803 if ( !setupFullCollision(subevents.back(), *cit,
808 subevents.push_back(getSDT(*cit));
809 if ( !setupFullCollision(subevents.back(), *cit,
822 void Angantyr::addSDsecond(
const multiset<SubCollision> & coll) {
827 for ( multiset<SubCollision>::iterator cit = coll.begin();
828 cit != coll.end(); ++cit ) {
829 if ( !cit->proj->done() &&
833 for (
int itry = 0; itry < ntry; ++itry ) {
842 if ( !cit->targ->done() &&
846 for (
int itry = 0; itry < ntry; ++itry ) {
862 bool Angantyr::addCD(
const multiset<SubCollision> & coll,
863 list<EventInfo> & subevents) {
865 for ( multiset<SubCollision>::iterator cit = coll.begin();
866 cit != coll.end(); ++cit )
868 !cit->proj->done() && !cit->targ->done() ) {
869 subevents.push_back(getCD(*cit));
870 if ( !setupFullCollision(subevents.back(), *cit,
882 void Angantyr::addCDsecond(
const multiset<SubCollision> & coll) {
884 for ( multiset<SubCollision>::iterator cit = coll.begin();
885 cit != coll.end(); ++cit ) {
907 bool Angantyr::addEL(
const multiset<SubCollision> & coll,
908 list<EventInfo> & subevents) {
910 for ( multiset<SubCollision>::iterator cit = coll.begin();
911 cit != coll.end(); ++cit )
913 !cit->proj->done() && !cit->targ->done() ) {
914 subevents.push_back(getEl(*cit));
915 if ( !setupFullCollision(subevents.back(), *cit,
926 void Angantyr::addELsecond(
const multiset<SubCollision> & coll) {
928 for ( multiset<SubCollision>::iterator cit = coll.begin();
929 cit != coll.end(); ++cit ) {
957 double ymax = ei.event[1].y();
958 Vec4 bmax = ei.coll->proj->bPos();
959 double ymin = ei.event[2].y();
960 Vec4 bmin = ei.coll->targ->bPos();
961 for (
int i = 0, N = ei.event.size(); i < N; ++i ) {
962 Vec4 shift = bmin + (bmax - bmin)*(ei.event[i].y() - ymin)/(ymax - ymin);
963 ei.event[i].xProd(ei.event[i].xProd() + shift.px());
964 ei.event[i].yProd(ei.event[i].yProd() + shift.py());
974 setupFullCollision(
EventInfo & ei,
const SubCollision & coll,
976 if ( !ei.ok )
return false;
977 coll.proj->select(ei, ptype);
978 coll.targ->select(ei, ttype);
981 ei.projs[coll.proj] = make_pair(1, ei.event.size());
983 ei.targs[coll.targ] = make_pair(2, ei.event.size());
985 ei.event[1].status(-203);
986 ei.event[1].mother1(1);
987 ei.event[1].mother2(0);
988 ei.event[2].status(-203);
989 ei.event[2].mother1(2);
990 ei.event[2].mother2(0);
991 return fixIsoSpin(ei);
998 int Angantyr::getBeam(
Event & ev,
int i) {
999 if (
int mom = ev[i].mother1() ) {
1000 if ( ev[mom].status() != -203 && ev[mom].mother1() < mom )
1001 return getBeam(ev, mom);
1016 bool Angantyr::fixIsoSpin(
EventInfo & ei) {
1021 int pshift = 0, tshift = 0;
1022 if ( ei.event[1].id() == 2212 && ei.coll->proj->id() == 2112 )
1024 if ( ei.event[1].id() == -2212 && ei.coll->proj->id() == -2112 )
1027 ei.event[1].id(pshift*2112);
1028 if ( ei.event[2].id() == 2212 && ei.coll->targ->id() == 2112 )
1030 if ( ei.event[2].id() == -2212 && ei.coll->targ->id() == -2112 )
1033 ei.event[2].id(tshift*2112);
1035 if ( !pshift && !tshift )
return true;
1038 for (
int i = ei.event.size() - 1; i > 2 && ( pshift || tshift ); --i ) {
1039 if ( pshift && ( ei.event[i].status() == 63 || ei.event[i].status() == 14 )
1040 && getBeam(ei.event, i) == 1 ) {
1042 if ( ei.event[i].id() == 2*pshift ) newid = 1*pshift;
1043 if ( ei.event[i].id() == 2101*pshift ) newid = 1103*pshift;
1044 if ( ei.event[i].id() == 2103*pshift ) newid = 1103*pshift;
1045 if ( ei.event[i].id() == 2203*pshift ) newid = 2103*pshift;
1046 if ( ei.event[i].id() == 2212*pshift ) newid = 2112*pshift;
1048 ei.event[i].id(newid);
1053 if ( tshift && ( ei.event[i].status() == 63 || ei.event[i].status() == 14 )
1054 && getBeam(ei.event, i) == 2 ) {
1056 if ( ei.event[i].id() == 2*tshift ) newid = 1*tshift;
1057 if ( ei.event[i].id() == 2101*tshift ) newid = 1103*tshift;
1058 if ( ei.event[i].id() == 2103*tshift ) newid = 1103*tshift;
1059 if ( ei.event[i].id() == 2203*tshift ) newid = 2103*tshift;
1060 if ( ei.event[i].id() == 2212*tshift ) newid = 2112*tshift;
1062 ei.event[i].id(newid);
1069 if ( !pshift && !tshift )
return true;
1077 for (
int i = ei.event.size() - 1; i > 2 && ( pshift || tshift ); --i ) {
1078 if ( pshift && ei.event[i].isFinal() && ei.event[i].id() == 2*pshift) {
1079 if ( ei.event[i].y() > yselp ) {
1081 yselp = ei.event[i].y();
1084 if ( tshift && ei.event[i].isFinal() && ei.event[i].id() == 2*tshift) {
1085 if ( ei.event[i].y() < yselt ) {
1087 yselt = ei.event[i].y();
1092 ei.event[qselp].id(1*pshift);
1096 ei.event[qselt].id(1*tshift);
1100 return !pshift && !tshift;
1109 vector<int> Angantyr::
1110 findRecoilers(
const Event & e,
bool tside,
int beam,
int end,
1111 const Vec4 & pdiff,
const Vec4 & pbeam) {
1113 multimap<double,int> ordered;
1114 double mtd2 = pdiff.m2Calc() + pdiff.pT2();
1115 int dir = tside? -1: 1;
1116 double ymax = -log(pdiff.pNeg());
1117 if ( tside ) ymax = -log(pdiff.pPos());
1118 for (
int i = beam, N = end; i < N; ++i )
1119 if ( e[i].status() > 0 )
1120 ordered.insert(make_pair(e[i].y()*dir, i));
1122 double pzfree2 = 0.0;
1123 multimap<double,int>::iterator it = ordered.begin();
1129 while ( it != ordered.end() ) {
1130 if ( it->first > ymax )
break;
1131 int i = (*it++).second;
1132 Vec4 test = prec + e[i].p();
1133 double mtr2 = test.m2Calc() + test.pT2();
1134 double S = (pbeam + test).m2Calc();
1135 double pz2 = 0.25*(pow2(S - mtr2 - mtd2) - 4.0*mtr2*mtd2)/S;
1136 if ( pz2 < pzfree2 ) {
1162 return HIHooksPtr->addNucleonExcitation(ei, sub, colConnect);
1164 typedef map<Nucleon *, pair<int, int> >::iterator NucPos;
1166 NucPos recnuc = ei.
projs.find(sub.
coll->proj);
1167 if ( recnuc != ei.
projs.end() ) tside =
true;
1168 NucPos rectarg = ei.targs.find(sub.
coll->
targ);
1169 if ( rectarg != ei.targs.end() ) {
1171 info.errorMsg(
"Warning from Angantyr::addNucleonExcitation:"
1172 " Nucleon already added.");
1178 int olddiff = tside? 4: 3;
1179 int beam = tside? 2: 1;
1180 int recbeam = recnuc->second.first;
1181 int recend = recnuc->second.second;
1184 if ( sub.info.code() == 106 ) pdiff += sub.
event[5].p();
1190 else if ( recoilerMode == 2 )
1191 rec = findRecoilers(ei.
event, tside, recbeam, recend, pdiff, pbeam);
1193 if ( tside && ei.info.code() == 104 && ei.
event[4].status() > 0 )
1195 else if ( !tside && ei.info.code() == 103 && ei.
event[3].status() > 0 )
1197 else if ( tside && ei.
event[3].status() > 0 &&
1198 ( ei.info.code() == 102 || ei.info.code() == 106 ) )
1200 else if ( !tside && ei.
event[4].status() > 0 &&
1201 ( ei.info.code() == 102 || ei.info.code() == 106 ) )
1204 for (
int i = recbeam, N = recend; i < N; ++i )
1205 if ( ei.
event[i].status() == 63 && getBeam(ei.
event, i) == recbeam )
1208 if ( rec.empty() )
return false;
1209 for (
int i = 0, N = rec.size(); i < N; ++i ) prec += ei.
event[rec[i]].p();
1212 pair<RotBstMatrix,RotBstMatrix> R12;
1214 ei.info.code(), sub.info.code()) )
1218 for (
int i = 0, N = rec.size(); i < N; ++i )
1219 ei.
event[rec[i]].rotbst(R12.first);
1223 int newbeam = ei.
event.size();
1225 ei.
event.back().status(-203);
1226 ei.
event.back().mother1(beam);
1227 ei.
event.back().mother2(0);
1229 int newdiff = ei.
event.size();
1232 ei.
event.back().rotbst(R12.second);
1233 ei.
event.back().mother1(newbeam);
1234 ei.
event.back().mother2(0);
1235 if ( sub.info.code() == 102 ) {
1237 ei.targs[sub.
coll->
targ] = make_pair(newbeam, ei.
event.size());
1243 int idoff = tside? newdiff - olddiff: newdiff - olddiff - 1;
1244 if ( sub.info.code() == 106 ) {
1248 idoff = newdiff - 5;
1250 ei.
event.back().rotbst(R12.second);
1251 ei.
event.back().mother1(newbeam);
1252 ei.
event.back().mother2(0);
1254 ei.
event.back().daughter1(sub.
event[olddiff].daughter1() + idoff);
1255 ei.
event.back().daughter2(sub.
event[olddiff].daughter2() + idoff);
1256 int coloff = ei.
event.lastColTag();
1260 for (
int i = nextpos; i < sub.
event.size(); ++i) {
1264 if ( temp.mother1() == olddiff ) temp.mother1(newdiff);
1265 else if ( temp.mother1() > 0 ) temp.mother1(temp.mother1() + idoff );
1266 if ( temp.mother2() == olddiff ) temp.mother2(newdiff);
1267 else if ( temp.mother2() > 0 ) temp.mother2(temp.mother2() + idoff );
1268 if ( temp.daughter1() > 0 ) temp.daughter1( temp.daughter1() + idoff );
1269 if ( temp.daughter2() > 0 ) temp.daughter2( temp.daughter2() + idoff );
1270 if ( temp.col() > 0 ) temp.col( temp.col() + coloff );
1271 if ( temp.acol() > 0 ) temp.acol( temp.acol() + coloff );
1272 temp.rotbst(R12.second);
1274 ei.
event.append( temp );
1280 ei.targs[sub.
coll->
targ] = make_pair(newbeam, ei.
event.size());
1294 pair<RotBstMatrix,RotBstMatrix> & R12,
1295 int code1,
int code2) {
1301 Ri.toCMframe(pbeam, prec);
1310 if ( pd1.pT() >= abs(pr2.pz()) ) {
1314 double the = asin(pd1.pT()/abs(pr2.pz()));
1316 R1.rot(the, pd1.phi());
1320 double S = (prec + pbeam).m2Calc();
1321 double mtr2 = pr2.pT2() + pr2.m2Calc();
1322 double mtd2 = pd1.pT2() + pd1.m2Calc();
1323 if ( sqrt(S) <= sqrt(mtr2) + sqrt(mtd2) ) {
1327 double z2 = 0.25*(mtr2*mtr2 + (mtd2 - S)*(mtd2 - S) - 2.0*mtr2*(mtd2 + S))/S;
1332 double z = sqrt(z2);
1333 double ppo2 = pow2(pr2.pNeg());
1334 double ppn2 = pow2(z + sqrt(z2 + mtr2));
1335 R1.bst(0.0, 0.0, -(ppn2 - ppo2)/(ppn2 + ppo2));
1337 ppo2 = pow2(pd1.pPos());
1338 ppn2 = pow2(z + sqrt(z2 + mtd2));
1340 R2.bst(0.0, 0.0, (ppn2 - ppo2)/(ppn2 + ppo2));
1354 R12.first = R12.second = Ri;
1355 R12.first.rotbst(R1);
1356 R12.second.rotbst(R2);
1357 R12.first.rotbst(Rf);
1358 R12.second.rotbst(Rf);
1359 prec.rotbst(R12.first);
1360 pdiff.rotbst(R12.second);
1374 int idoff = evnt.size() - 1;
1375 int coloff = evnt.lastColTag();
1377 for (
int i = 1; i < sub.size(); ++i) {
1381 if ( temp.status() == -203 )
1384 if ( temp.mother1() > 0 ) temp.mother1(temp.mother1() + idoff );
1385 if ( temp.mother2() > 0 ) temp.mother2( temp.mother2() + idoff );
1387 if ( temp.daughter1() > 0 ) temp.daughter1( temp.daughter1() + idoff );
1388 if ( temp.daughter2() > 0 ) temp.daughter2( temp.daughter2() + idoff );
1389 if ( temp.col() > 0 ) temp.col( temp.col() + coloff );
1390 if ( temp.acol() > 0 ) temp.acol( temp.acol() + coloff );
1392 evnt.append( temp );
1395 addJunctions(evnt, sub, coloff);
1399 void Angantyr::addJunctions(
Event & ev,
Event & addev,
int coloff) {
1404 for (
int i = 0; i < addev.sizeJunction(); ++i) {
1405 tempJ = addev.getJunction(i);
1408 for (
int j = 0; j < 3; ++j) {
1409 begCol = tempJ.col(j);
1410 endCol = tempJ.endCol(j);
1411 if (begCol > 0) begCol += coloff;
1412 if (endCol > 0) endCol += coloff;
1413 tempJ.cols( j, begCol, endCol);
1416 ev.appendJunction( tempJ );
1428 double bp =
pythia[
SASD]->parm(
"Angantyr:SDTestB");
1431 if ( !ei.ok )
return false;
1438 if ( !
pythia[
HADRON]->forceHadronLevel(
false) )
return false;
1448 bool Angantyr::buildEvent(list<EventInfo> & subevents,
1449 const vector<Nucleon> & proj,
1450 const vector<Nucleon> & targ) {
1453 etmp.append(projPtr->produceIon(
false));
1454 etmp.append(targPtr->produceIon(
true));
1455 etmp[0].p(etmp[1].p() + etmp[2].p());
1456 etmp[0].m(etmp[0].mCalc());
1461 for ( list<EventInfo>::iterator sit = subevents.begin();
1462 sit != subevents.end(); ++sit ) {
1463 if ( sit->info.code() >= 101 && sit->info.code() <= 106 )
continue;
1465 if ( !found )
hiinfo.select(sit->info);
1466 hiinfo.addSubCollision(*sit->coll);
1467 subevents.erase(sit);
1473 " Failed to generate signal event.");
1477 hiinfo.select(subevents.begin()->info);
1480 for ( list<EventInfo>::iterator sit = subevents.begin();
1481 sit != subevents.end(); ++sit ) {
1483 hiinfo.addSubCollision(*sit->coll);
1498 const vector<Nucleon> & targ) {
1503 for (
int i = 0, N = proj.size(); i< N; ++i ) {
1504 if ( proj[i].event() )
hiinfo.addProjectileNucleon(proj[i]);
1507 double m =
pythia[
HADRON]->particleData.m0(proj[i].
id());
1508 double pz = sqrt(max(e*e - m*m, 0.0));
1509 if ( proj[i].
id() == 2212 ) {
1511 ppsum +=
Vec4(0.0, 0.0, pz, e);
1512 }
else if ( proj[i].
id() == 2112 ) {
1514 ppsum +=
Vec4(0.0, 0.0, pz, e);
1516 etmp.append(proj[i].
id(), 14, 1, 0, 0, 0, 0, 0, 0.0, 0.0, pz, e, m);
1522 for (
int i = 0, N = targ.size(); i< N; ++i ) {
1523 if ( targ[i].event() )
hiinfo.addTargetNucleon(targ[i]);
1526 double m =
pythia[
HADRON]->particleData.m0(targ[i].
id());
1527 double pz = -sqrt(max(e*e - m*m, 0.0));
1528 if ( targ[i].
id() == 2212 ) {
1530 tpsum +=
Vec4(0.0, 0.0, pz, e);
1531 }
else if ( targ[i].
id() == 2112 ) {
1533 tpsum +=
Vec4(0.0, 0.0, pz, e);
1535 etmp.append(targ[i].
id(), 14, 2, 0, 0, 0, 0, 0, 0.0, 0.0, pz, e, m);
1539 Vec4 ptot = etmp[0].p();
1540 for (
int i = 0, N = etmp.size(); i < N; ++i )
1541 if ( etmp[i].status() > 0 ) ptot -= etmp[i].p();
1543 if ( npp + nnp +npt + nnt == 0 )
return true;
1546 if ( npp + nnp > 1 ) {
1547 idp = 1000000009 + 10000*npp + 10*(nnp + npp);
1548 pdt.addParticle(idp,
"NucRem", 0, 3*npp, 0, ppsum.mCalc());
1549 pdt.particleDataEntryPtr(idp)->setHasChanged(
false);
1551 else if ( npp == 1 ) idp = 2212;
1552 else if ( nnp == 1 ) idp = 2112;
1554 if ( npt + nnt > 1 ) {
1555 idt = 1000000009 + 10000*npt + 10*(nnt + npt);
1556 pdt.addParticle(idt,
"NucRem", 0, 3*npt, 0, tpsum.mCalc());
1557 pdt.particleDataEntryPtr(idt)->setHasChanged(
false);
1559 else if ( npt == 1 ) idt = 2212;
1560 else if ( nnt == 1 ) idt = 2112;
1562 if ( npp + nnp > npt + nnt ) {
1563 if ( npt + nnt > 0 ) {
1564 etmp.append(idt, 14, 2, 0, 0, 0, 0, 0, tpsum, tpsum.mCalc());
1567 etmp.append(idp, 14, 1, 0, 0, 0, 0, 0, ptot, ptot.mCalc());
1569 if ( npp + nnp > 0 ) {
1570 etmp.append(idp, 14, 1, 0, 0, 0, 0, 0, ppsum, ppsum.mCalc());
1573 etmp.append(idt, 14, 2, 0, 0, 0, 0, 0, ptot, ptot.mCalc());
1595 double bweight = 0.0;
1598 subColls = collPtr->
getCollisions(projectile, target, bvec, T);
1599 hiinfo.addAttempt(T, bvec.pT(), bweight);
1600 hiinfo.subCollisionsPtr(&subColls);
1604 if ( subColls.empty() )
continue;
1607 list<EventInfo> subevents;
1609 if ( !genAbs(subColls, subevents) ) {
1611 "Could not setup signal or ND collisions.");
1614 if ( hasSignal && subevents.empty() )
continue;
1621 if ( !addDD(subColls, subevents) ) {
1623 " Could not setup DD sub collision.");
1628 if ( !addSD(subColls, subevents) ) {
1630 " Could not setup SD sub collision.");
1635 addSDsecond(subColls);
1638 if ( !addSD(subColls, subevents) ) {
1640 " Could not setup CD sub collisions.");
1645 addCDsecond(subColls);
1648 if ( !addEL(subColls, subevents) ) {
1650 " Could not setup elastic sub collisions.");
1655 addELsecond(subColls);
1658 if ( subevents.empty() )
continue;
1660 if ( !buildEvent(subevents, projectile, target) )
continue;
1667 if ( !
pythia[
HADRON]->forceHadronLevel(
false) )
continue;
1680 mainPythiaPtr->info.errorMsg(
"Abort from Angantyr::next: Too many attempts "
1681 "to generate a working impact parameter point. "
1682 "Consider reducing HeavyIon:bWidth.");
static bool getTransforms(Vec4 p1, Vec4 p2, const Vec4 &p1p, pair< RotBstMatrix, RotBstMatrix > &R12, int, int)
The nucleon is absorptively wounded.
This is an absorptive (non-diffractive) collision.
Both excited but with central diffraction.
virtual bool init()
Virtual init method.
Both projectile and target are diffractively excited.
Optional object for signal processes (nn).
virtual bool next()
Produce a collision involving heavy ions.
virtual bool hasProjectileModel() const
A suser-supplied NucleusModel for the projectile and target.
bool addNucleonExcitation(EventInfo &orig, EventInfo &add, bool colConnect=false)
void initPtr(int idIn, Settings &settingsIn, ParticleData &particleDataIn, Rndm &rndIn)
Init method.
double avNDB() const
Return the average non-diffractive impact parameter.
double sigmaNDErr() const
The estimated statistical error on sigmaND().
static void addSpecialSettings(Settings &settings)
EventInfo getSignal(const SubCollision &coll)
Generate events from the internal Pythia oblects;.
double ordering
The ordering variable of this event.
virtual bool canFixIsoSpin() const
bool nextSASD(int proc)
Generate a single diffractive.
Optional object for signal processes (pp).
map< Nucleon *, pair< int, int > > projs
PythiaObject
Enumerate the different internal Pythia objects.
virtual bool canFindRecoilers() const
virtual bool hasImpactParameterGenerator() const
A user-supplied impact parameter generator.
bool canAddNucleonExcitation() const
Event event
The Event and info objects.
EventInfo mkEventInfo(Pythia &pyt, const SubCollision *coll=0)
Setup an EventInfo object from a Pythia instance.
double sigND() const
The non-diffractive (absorptive) cross section.
void failedExcitation()
Register a failed nucleon excitation.
virtual bool canShiftEvent() const
A user-supplied method for shifting the event in impact parameter space.
virtual multiset< SubCollision > getCollisions(vector< Nucleon > &proj, vector< Nucleon > &targ, const Vec4 &bvec, double &T)=0
Nucleon * targ
The target nucleon.
vector< Pythia * > pythia
void clearProcessLevel(Pythia &pyt)
This is an elastic scattering.
The projectile is diffractively excited.
virtual vector< Nucleon > generate() const =0
The nucleon is elastically scattered.
Single diffractive as one side of non-diffractive.
void sumUpMessages(Info &in, string tag, const Info &other)
virtual bool hasEventOrdering() const
A user-supplied ordering of events in (inverse) hardness.
virtual bool hasSubCollisionModel()
static void setupSpecials(Settings &settings, string match)
Duplicate setting on the form match: to settings on the form HImatch:
Optional object for signal processes (pn).
virtual bool init()
Initialize Angantyr.
virtual void init(int idProjIn, int idTargIn)
Initialize this user hook.
bool ok
Is the event properly generated?
Optional object for signal processes (np).
The target is diffractively excited.
const SubCollision * coll
The associated SubCollision object.
double sigmaTot() const
The Monte Carlo integrated total cross section in the current run.
Angantyr(Pythia &mainPythiaIn)
The nucleon is diffractively wounded.
long nAttempts() const
The number of attempted impact parameter points.
bool setUserHooksPtr(PythiaObject sel, UserHooks *userHooksPtrIn)
Set UserHooks for specific (or ALL) internal Pythia objects.
bool addNucleusRemnants(const vector< Nucleon > &proj, const vector< Nucleon > &targ)
virtual Vec4 generate(double &weight) const
double sigmaTotErr() const
The estimated statistical error on sigmaTot().
Status
Enum for specifying the status of a nucleon.
vector< string > pythiaNames
The names associated with the secondary pythia objects.
void addSubEvent(Event &evnt, Event &sub)
Add a sub-event to the final event record.
internal class to redirect stdout
virtual bool canForceHadronLevel() const
A user supplied wrapper around the Pythia::forceHadronLevel()
double weight() const
The weight for this collision.
static bool isHeavyIon(Settings &settings)
virtual bool init()
Virtual init method.