ATLAS Offline Software
Loading...
Searching...
No Matches
Pythia8ForDecays Class Reference

#include <Pythia8ForDecays.h>

Collaboration diagram for Pythia8ForDecays:

Public Member Functions

 Pythia8ForDecays ()
virtual ~Pythia8ForDecays ()=default
void Py1ent (const G4Track &, std::vector< G4DynamicParticle * > &)
 Function that decays the RHadron; returns products in G4 format.

Private Member Functions

G4ParticleDefinition * GetParticleDefinition (const int) const
 Helper for getting G4ParticleDefinition from PDG ID.
void fillParticle (const G4Track &, Pythia8::Event &event) const
 Fill a Pythia8 event with the information from a G4Track.
std::pair< int, int > fromIdWithGluino (int idRHad, Pythia8::Rndm *rndmPtr) const
 Get the quarks from a gluino R-hadron. From Pythia8 code.
std::pair< int, int > fromIdWithSquark (int idRHad) const
bool isGluinoRHadron (int pdgId) const

Private Attributes

std::unique_ptr< Pythia8::Pythia > m_pythia
 The instance of Pythia8 that will do the work.

Detailed Description

Definition at line 25 of file Pythia8ForDecays.h.

Constructor & Destructor Documentation

◆ Pythia8ForDecays()

Pythia8ForDecays::Pythia8ForDecays ( )

Definition at line 35 of file Pythia8ForDecays.cxx.

36 {
37 // Pythia instance where RHadrons can decay
38 std::string docstring = Pythia8_i::xmlpath();
39 m_pythia = std::make_unique<Pythia8::Pythia>(docstring);
40 m_pythia->readString("SLHA:file = SLHA_INPUT.DAT");
41 m_pythia->readString("ProcessLevel:all = off");
42 m_pythia->readString("Init:showChangedSettings = off");
43 m_pythia->readString("RHadrons:allow = on");
44 m_pythia->readString("RHadrons:allowDecay = on");
45 m_pythia->readString("RHadrons:probGluinoball = 0.1");
46 m_pythia->readString("PartonLevel:FSR = off");
47 m_pythia->readString("Init:showAllParticleData = on");
48
49 // Process the file of commands left for us by the python layer
50 std::string line;
51 std::ifstream command_stream ("PYTHIA8_COMMANDS.TXT");
52 while(getline(command_stream,line)){
53 // Leaving it to the top-level to get this file right
54 m_pythia->readString(line);
55 }
56 command_stream.close();
57
58 m_pythia->init();
59
60}
std::unique_ptr< Pythia8::Pythia > m_pythia
The instance of Pythia8 that will do the work.
static std::string xmlpath()

◆ ~Pythia8ForDecays()

virtual Pythia8ForDecays::~Pythia8ForDecays ( )
virtualdefault

Member Function Documentation

◆ fillParticle()

void Pythia8ForDecays::fillParticle ( const G4Track & aTrack,
Pythia8::Event & event ) const
private

Fill a Pythia8 event with the information from a G4Track.

Add a G4Track to a Pythia8 event to make it a single-particle gun.

The particle must be a colour singlet. Input: particle, Pythia8 event

Definition at line 152 of file Pythia8ForDecays.cxx.

153{
154 // Reset event record to allow for new event.
155 event.reset();
156
157 // Select particle mass; where relevant according to Breit-Wigner.
158 double mm = aTrack.GetDynamicParticle()->GetMass();
159
160 // Store the particle in the event record.
161 event.append( aTrack.GetDefinition()->GetPDGEncoding(), 1, 0, 0, aTrack.GetMomentum().x()/CLHEP::GeV, aTrack.GetMomentum().y()/CLHEP::GeV,
162 aTrack.GetMomentum().z()/CLHEP::GeV, aTrack.GetDynamicParticle()->GetTotalEnergy()/CLHEP::GeV, mm/CLHEP::GeV);
163 // Note: this function returns an int, but we don't need or use its output
164}

◆ fromIdWithGluino()

std::pair< int, int > Pythia8ForDecays::fromIdWithGluino ( int idRHad,
Pythia8::Rndm * rndmPtr ) const
private

Get the quarks from a gluino R-hadron. From Pythia8 code.

Definition at line 93 of file Pythia8ForDecays.cxx.

94{
95 // Find light flavour content of R-hadron.
96 int idLight = (abs(idRHad) - 1000000) / 10;
97 int id1, id2, idTmp, idA, idB, idC;
98 double diquarkSpin1RH = 0.5;
99
100 // Gluinoballs: split g into d dbar or u ubar.
101 if (idLight < 100) {
102 id1 = (rndmPtr->flat() < 0.5) ? 1 : 2;
103 id2 = -id1;
104
105 // Gluino-meson: split into q + qbar.
106 } else if (idLight < 1000) {
107 id1 = (idLight / 10) % 10;
108 id2 = -(idLight % 10);
109 // Flip signs when first quark of down-type.
110 if (id1%2 == 1) {
111 idTmp = id1;
112 id1 = -id2;
113 id2 = -idTmp;
114 }
115
116 // Gluino-baryon: split to q + qq (diquark).
117 // Pick diquark at random, except if c or b involved.
118 } else {
119 idA = (idLight / 100) % 10;
120 idB = (idLight / 10) % 10;
121 idC = idLight % 10;
122 double rndmQ = 3. * rndmPtr->flat();
123 if (idA > 3) rndmQ = 0.5;
124 if (rndmQ < 1.) {
125 id1 = idA;
126 id2 = 1000 * idB + 100 * idC + 3;
127 if (idB != idC && rndmPtr->flat() > diquarkSpin1RH) id2 -= 2;
128 } else if (rndmQ < 2.) {
129 id1 = idB;
130 id2 = 1000 * idA + 100 * idC + 3;
131 if (idA != idC && rndmPtr->flat() > diquarkSpin1RH) id2 -= 2;
132 } else {
133 id1 = idC;
134 id2 = 1000 * idA + 100 * idB +3;
135 if (idA != idB && rndmPtr->flat() > diquarkSpin1RH) id2 -= 2;
136 }
137 }
138 // Flip signs for anti-R-hadron.
139 if (idRHad < 0) {
140 idTmp = id1;
141 id1 = -id2;
142 id2 = -idTmp;
143 }
144
145 // Done.
146 return std::make_pair( id1, id2);
147
148}
HWIdentifier id2

◆ fromIdWithSquark()

std::pair< int, int > Pythia8ForDecays::fromIdWithSquark ( int idRHad) const
private

Definition at line 71 of file Pythia8ForDecays.cxx.

72{
73
74 // Find squark flavour content.
75 int idRSb = m_pythia->settings.mode("RHadrons:idSbottom");
76 int idRSt = m_pythia->settings.mode("RHadrons:idStop");
77 int idLight = (abs(idRHad) - 1000000) / 10;
78 int idSq = (idLight < 100) ? idLight/10 : idLight/100;
79 int id1 = (idSq == 6) ? idRSt : idRSb;
80 if (idRHad < 0) id1 = -id1;
81
82 // Find light (di)quark flavour content.
83 int id2 = (idLight < 100) ? idLight%10 : idLight%100;
84 if (id2 > 10) id2 = 100 * id2 + abs(idRHad)%10;
85 if ((id2 < 10 && idRHad > 0) || (id2 > 10 && idRHad < 0)) id2 = -id2;
86
87 // Done.
88 return std::make_pair( id1, id2);
89
90}

◆ GetParticleDefinition()

G4ParticleDefinition * Pythia8ForDecays::GetParticleDefinition ( const int pdgEncoding) const
private

Helper for getting G4ParticleDefinition from PDG ID.

Definition at line 62 of file Pythia8ForDecays.cxx.

63{
64 G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
65 G4ParticleDefinition* particleDefinition(nullptr);
66 if (pdgEncoding != 0) particleDefinition = particleTable->FindParticle(pdgEncoding);
67 return particleDefinition;
68}

◆ isGluinoRHadron()

bool Pythia8ForDecays::isGluinoRHadron ( int pdgId) const
private

Definition at line 166 of file Pythia8ForDecays.cxx.

166 {
167 // Checking what kind of RHadron this is based on the digits in its PDGID
168 const unsigned short digitValue_q1 = nth_digit(pdgId,4);
169 const unsigned short digitValue_l = nth_digit(pdgId,5);
170
171 // Gluino R-Hadrons have the form 109xxxx or 1009xxx
172 if (digitValue_l == 9 || (digitValue_l==0 && digitValue_q1 == 9) ){
173 // This is a gluino R-Hadron
174 return true;
175 }
176
177 // Special case : R-gluinoball
178 if (pdgId==1000993) return true;
179
180 // This is not a gluino R-Hadron (probably a squark R-Hadron)
181 return false;
182
183}
static unsigned short int nth_digit(const int &val, const unsigned short &n)

◆ Py1ent()

void Pythia8ForDecays::Py1ent ( const G4Track & aTrack,
std::vector< G4DynamicParticle * > & particles )

Function that decays the RHadron; returns products in G4 format.

Definition at line 185 of file Pythia8ForDecays.cxx.

186{
187
188 // Get members from Pythia8 instance where RHadrons can decay
189 Pythia8::Event& event = m_pythia->event;
190 Pythia8::ParticleData& pdt = m_pythia->particleData;
191
192 // Use pythiaDecay information to fill event with the input particle
193 fillParticle(aTrack, event);
194
195 // Copy and paste of RHadron decay code
196 int iRNow = 1;
197 int idRHad = event[iRNow].id();
198 double mRHad = event[iRNow].m();
199 int iR0 = 0;
200 int iR2 = 0;
201
202 bool isTriplet = !isGluinoRHadron(idRHad);
203
204 // Find flavour content of squark or gluino R-hadron.
205 std::pair<int,int> idPair = (isTriplet) ? fromIdWithSquark( idRHad) : fromIdWithGluino( idRHad, &(m_pythia->rndm));
206 int id1 = idPair.first;
207 int id2 = idPair.second;
208
209 // Sharing of momentum: the squark/gluino should be restored
210 // to original mass, but error if negative-mass spectators.
211 int idRSb = m_pythia->settings.mode("RHadrons:idSbottom");
212 int idRSt = m_pythia->settings.mode("RHadrons:idStop");
213 int idRGo = m_pythia->settings.mode("RHadrons:idGluino");
214 int idLight = (abs(idRHad) - 1000000) / 10;
215 int idSq = (idLight < 100) ? idLight/10 : idLight/100;
216 int idRSq = (idSq == 6) ? idRSt : idRSb;
217
218 // Handling R-Hadrons with anti-squarks
219 idRSq = idRSq * std::copysign(1, idRHad);
220
221 int idRBef = isTriplet ? idRSq : idRGo;
222
223 // Mass of the underlying sparticle
224 double mRBef = pdt.mSel(idRBef);
225
226 // Fraction of the RHadron mass given by the sparticle
227 double fracR = mRBef / mRHad;
228 int counter=0;
229 while (fracR>=1.){
230 if (counter==10){
231 G4cout << "Needed more than 10 attempts with constituent " << idRBef << " mass (" << mRBef << " above R-Hadron " << idRHad << " mass " << mRHad << G4endl;
232 } else if (counter>100){
233 G4cout << "Pythia8ForDecays::Py1ent ERROR Failed >100 times. Constituent " << idRBef << " mass (" << mRBef << " above R-Hadron " << idRHad << " mass " << mRHad << G4endl;
234 return;
235 }
236 mRBef = pdt.mSel(idRBef);
237 fracR = mRBef / mRHad;
238 counter++;
239 }
240
241 // Squark case
242 if(isTriplet){
243 const int col = (pdt.colType(idRBef) != 0) ? event.nextColTag() : 0; // NB There should be no way that this can be zero (see discussion on ATLASSIM-6687), but leaving check in there just in case something changes in the future.
244 int tmpSparticleColor = id1>0 ? col : 0;
245 int tmpSparticleAnticolor = id1>0 ? 0 : col;
246
247 // Store the constituents of a squark R-hadron.
248
249 // Sparticle
250 // (id, status, mother1, mother2, daughter1, daughter2, col, acol, px, py, pz, e, m=0., scaleIn=0., polIn=9.)
251 iR0 = event.append( id1, 106, iRNow, 0, 0, 0, tmpSparticleColor, tmpSparticleAnticolor, fracR * event[iRNow].p(), fracR * mRHad, 0.);
252 // Spectator quark
253 iR2 = event.append( id2, 106, iRNow, 0, 0, 0, tmpSparticleAnticolor, tmpSparticleColor, (1. - fracR) * event[iRNow].p(), (1. - fracR) * mRHad, 0.);
254 }
255 // Gluino case
256 else{
257 double mOffsetCloudRH = 0.2; // could be read from internal data?
258 double m1Eff = pdt.constituentMass(id1) + mOffsetCloudRH;
259 double m2Eff = pdt.constituentMass(id2) + mOffsetCloudRH;
260 double frac1 = (1. - fracR) * m1Eff / ( m1Eff + m2Eff);
261 double frac2 = (1. - fracR) * m2Eff / ( m1Eff + m2Eff);
262
263 // Two new colours needed in the breakups.
264 int col1 = event.nextColTag();
265 int col2 = event.nextColTag();
266
267 // Store the constituents of a gluino R-hadron.
268 iR0 = event.append( idRBef, 106, iRNow, 0, 0, 0, col2, col1, fracR * event[iRNow].p(), fracR * mRHad, 0.);
269 event.append( id1, 106, iRNow, 0, 0, 0, col1, 0, frac1 * event[iRNow].p(), frac1 * mRHad, 0.);
270 iR2 = event.append( id2, 106, iRNow, 0, 0, 0, 0, col2, frac2 * event[iRNow].p(), frac2 * mRHad, 0.);
271 }
272
273 // Mark R-hadron as decayed and update history.
274 event[iRNow].statusNeg();
275 event[iRNow].daughters( iR0, iR2);
276
277 // Generate events. Quit if failure.
278 if (!m_pythia->next()) {
279 m_pythia->forceRHadronDecays();
280 }
281
283 // Add the particles from the Pythia event into the GEANT particle vector
285 particles.clear();
286
287 for(int i=0; i<m_pythia->event.size(); i++){
288 if ( m_pythia->event[i].status()<0 ) continue; // stable only
289 G4ThreeVector momentum( m_pythia->event[i].px() , m_pythia->event[i].py() , m_pythia->event[i].pz() );
290 momentum*=1000.0;//GeV to MeV
291 const G4ParticleDefinition * particleDefinition = GetParticleDefinition( m_pythia->event[i].id() );
292
293 if (!particleDefinition){
294 G4cout << "I don't know a definition for pdgid "<<m_pythia->event[i].id()<<"! Skipping it..." << G4endl;
295 continue;
296 }
297
298 G4DynamicParticle* dynamicParticle = new G4DynamicParticle(particleDefinition, momentum);
299 particles.push_back( dynamicParticle );
300 }
301
302}
void fillParticle(const G4Track &, Pythia8::Event &event) const
Fill a Pythia8 event with the information from a G4Track.
G4ParticleDefinition * GetParticleDefinition(const int) const
Helper for getting G4ParticleDefinition from PDG ID.
bool isGluinoRHadron(int pdgId) const
std::pair< int, int > fromIdWithSquark(int idRHad) const
std::pair< int, int > fromIdWithGluino(int idRHad, Pythia8::Rndm *rndmPtr) const
Get the quarks from a gluino R-hadron. From Pythia8 code.

Member Data Documentation

◆ m_pythia

std::unique_ptr<Pythia8::Pythia> Pythia8ForDecays::m_pythia
private

The instance of Pythia8 that will do the work.

Definition at line 47 of file Pythia8ForDecays.h.


The documentation for this class was generated from the following files: