3 #include "TVirtualMCDecayer.h"
5 #include "TClonesArray.h"
6 #include "StarDecayManager.h"
7 #include "St_geant_Maker/St_geant_Maker.h"
8 #include "StarGenerator/UTIL/StarParticleData.h"
13 #define geant3 St_geant_Maker::instance()->Geant3()
20 struct StopOnParticle :
public std::runtime_error {
StopOnParticle ( std::string
const& message ) : std::runtime_error( message ) { LOG_ERROR << message << endm; } };
21 struct MissingPdgEntry :
public std::runtime_error {
MissingPdgEntry ( std::string
const& message ) : std::runtime_error( message ) { LOG_ERROR << message << endm; } };
32 {
static AgUDecay &decay = AgUDecay::instance();
39 void gsking_(
int &igk);
43 void gsking(
int igk ){ gsking_(igk); }
48 std::map<int,int> AgUDecay::mParticleStop;
50 Int_t AgUDecay::operator()()
53 Gctrak_t& gctrak = *(geant3->Gctrak());
54 Gcking_t& gcking = *(geant3->Gcking());
55 Gckin3_t& gckin3 = *(geant3->Gckin3());
57 float x = gctrak.vect[0];
58 float y = gctrak.vect[1];
59 float z = gctrak.vect[2];
62 if (0==mDecayer)
return 0;
65 mDecayer -> ForceDecay();
67 int idGeant3 = geant3->Gckine()->ipart;
69 double pmom = double( gctrak.vect[6] );
70 double px = double( gctrak.vect[3] ) * pmom;
71 double py = double( gctrak.vect[4] ) * pmom;
72 double pz = double( gctrak.vect[5] ) * pmom;
73 double E = double( gctrak.getot );
75 mP[0] = px; mP[1] = py; mP[2] = pz; mP[3] = E;
84 AGAIN:
while (
true ) {
86 LOG_WARN <<
"Decay chain rejected (all or in part) due to unknown PDG" << endm;
88 TString msg = Form(
"No path to decay after 1k attempts: idpdg=%i idg3=%i",idPdg,idGeant3);
89 if ( nretry > 1000 )
throw
95 mDecayer -> Decay( idPdg, &mP );
98 np = mDecayer -> ImportParticles( mArray );
if ( np<1 )
return np;
104 for (
int ip = 0; ip<np; ip++ ) {
106 TParticle* part = (TParticle *)mArray->At(ip);
109 int thispdgid = part->GetPdgCode();
110 if ( thispdgid == idPdg ) go =
true;
113 if ( 0 == part->GetPDG() && ++nretry ) {
114 if ( nretry==1000 ) {
115 LOG_INFO <<
"1k failures... this particle may be a culprit" << endm;
132 TParticle* mother = (TParticle*)mArray->At(0);
133 if ( mParticleStop[idPdg] || mParticleStop[-idPdg] ) {
134 LOG_INFO <<
"User stop on pdgid = " << idPdg << endm;
135 LOG_INFO <<
"==================================================" << endm;
137 LOG_INFO <<
"==================================================" << endm;
139 LOG_INFO <<
"==================================================" << endm;
144 for (
int i=0;i<np;i++ ) {
145 mother = (TParticle*)mArray->At(i);
if ( mother->GetPdgCode() == idPdg )
break;
147 int first = mother->GetFirstDaughter();
148 int last = mother->GetLastDaughter();
149 double EnergySum = 0;
150 for (
int i=first ; i <= last; i++ )
153 TParticle *particle = (TParticle *)mArray->At(i);
155 LOG_WARN <<
"Daughter " << i <<
" not valid for particle " << Form(
"%s [@0x%p]",mother->GetName(),mother) << endm;
160 EnergySum += StackParticleForTransport( particle );
165 if ( (violation = TMath::Abs(E - EnergySum)/E > 0.1E-5) ) {
167 TParticle *particle = (TParticle *)mArray->At(0);
168 LOG_INFO <<
"Stop due to energy nonconservation on pdgid = " << idPdg << endm;
169 LOG_INFO <<
"==================================================" << endm;
171 LOG_INFO <<
"==================================================" << endm;
173 LOG_INFO <<
"==================================================" << endm;
174 throw EnergyNotConserved( Form(
"%s decay violates E conservation", particle->GetName() ) );
182 bool AgUDecay::MayTransport(
const TParticle* particle )
185 int first = particle->GetFirstDaughter();
186 int last = particle->GetLastDaughter();
187 int pdgid = particle->GetPdgCode();
188 int status = particle->GetStatusCode();
189 TParticlePDG *particlePDG = pdb.
GetParticle(pdgid);
190 int g3id = particlePDG->TrackingCode();
194 int apdgid = TMath::Abs(pdgid);
195 if ( apdgid == 12 || apdgid == 14 || apdgid == 16 ) {
201 switch( mDiscovery ) {
206 assert(mNextG3id < 60000);
219 double AgUDecay::StackParticleForTransport(
const TParticle* particle )
222 Gctrak_t& gctrak = *(geant3->Gctrak());
223 Gcking_t& gcking = *(geant3->Gcking());
224 Gckin3_t& gckin3 = *(geant3->Gckin3());
226 double EnergySum = 0.0;
228 int first = particle->GetFirstDaughter();
229 int last = particle->GetLastDaughter();
230 int pdgid = particle->GetPdgCode();
231 int status = particle->GetStatusCode();
232 TParticlePDG *particlePDG = pdb.
GetParticle(pdgid);
233 int g3id = particlePDG->TrackingCode();
237 if ( 0 == MayTransport(particle) )
239 LOG_INFO << Form(
"%s [@0x%p] decayed in place", particle->GetName(),particle) << endm;
240 for (
int kid=first; kid<=last; kid++ )
242 TParticle* daughter = (TParticle*)mArray->At( kid );
243 LOG_INFO << Form(
" %s [@x%p] visit kid: %s [@0x%p]", particle->GetName(),particle,daughter->GetName(),daughter) << endm;
244 EnergySum += StackParticleForTransport( daughter );
249 if ( g3id == 4 || g3id == 0 ) {
250 LOG_INFO << Form(
"%s [@0x%p] ... ignore neutrinos for transport ...", particle->GetName(),particle) << endm;
251 EnergySum += particle->Energy();
257 LOG_INFO << Form(
"%s [@0x%p] stacked for transport", particle->GetName(),particle) << endm;
259 int &index = gcking.ngkine;
262 (gcking.gkin[index][0]) = particle->Px();
263 (gcking.gkin[index][1]) = particle->Py();
264 (gcking.gkin[index][2]) = particle->Pz();
265 (gcking.gkin[index][3]) = particle->Energy(); EnergySum += particle->Energy();
267 (gcking.gkin[index][4]) =
float(g3id);
271 (gckin3.gpos[index][0]) = gctrak.vect[0];
272 (gckin3.gpos[index][1]) = gctrak.vect[1];
273 (gckin3.gpos[index][2]) = gctrak.vect[2];
276 (gcking.tofd[index]) = 0.;
285 (gcking.iflgk[index]) = 0;
294 AgUDecay::AgUDecay() : mDecayer( 0 ),
295 mArray( new TClonesArray(
"TParticle",1000) ),
297 mDiscovery( kDecay ),
304 AgUDecay::~AgUDecay() {
TParticlePDG * GetParticleG3(const Int_t id)
Get a particle by G3 ID.
Interface between starsim and virtual decayer (VMC implementation)
static StarParticleData & instance()
Returns a reference to the single instance of this class.
TParticlePDG * GetParticle(const Char_t *name)
Get a particle by name.
Interface to PDG information.
TParticlePDG * AddParticleToG3(const char *name, const double mass, const double lifetime, const double charge, const int tracktype, const int pdgcode, const int g3code, const double *bratio=0, const int *mode=0)