4 // See the class description in the header file.
6 #include "TG4PhysicsManager.h"
7 #include "TG4PhysicsList.h"
8 #include "TG4CutVector.h"
9 #include "TG4FlagVector.h"
10 #include "TG4G3Defaults.h"
12 #include <G4ParticleDefinition.hh>
14 #include <TDatabasePDG.h>
16 TG4PhysicsManager* TG4PhysicsManager::fgInstance = 0;
18 TG4PhysicsManager::TG4PhysicsManager()
26 TG4Globals::Exception(
27 "TG4PhysicsManager: attempt to create two instances of singleton.");
32 // initialize fIsCutVector
33 fIsCutVector = new TG4boolVector;
35 //for (i=0; i<kNofParticlesWSP; i++) fIsCutVector->insert(false);
36 for (i=0; i<kNofParticlesWSP; i++) fIsCutVector->push_back(false);
38 // initialize fIsFlagVector
39 fIsFlagVector = new TG4boolVector;
40 //for (i=0; i<kNofParticlesWSP; i++) fIsFlagVector->insert(false);
41 for (i=0; i<kNofParticlesWSP; i++) fIsFlagVector->push_back(false);
43 // define fCutNameVector
44 fG3CutNameVector.insert("CUTGAM");
45 fG3CutNameVector.insert("CUTELE");
46 fG3CutNameVector.insert("CUTNEU");
47 fG3CutNameVector.insert("CUTHAD");
48 fG3CutNameVector.insert("CUTMUO");
49 fG3CutNameVector.insert("BCUTE");
50 fG3CutNameVector.insert("BCUTM");
51 fG3CutNameVector.insert("DCUTE");
52 fG3CutNameVector.insert("DCUTM");
53 fG3CutNameVector.insert("PPCUTM");
55 // define fFlagNameVector
56 fG3FlagNameVector.insert("PAIR");
57 fG3FlagNameVector.insert("COMP");
58 fG3FlagNameVector.insert("PHOT");
59 fG3FlagNameVector.insert("PFIS");
60 fG3FlagNameVector.insert("DRAY");
61 fG3FlagNameVector.insert("ANNI");
62 fG3FlagNameVector.insert("BREM");
63 fG3FlagNameVector.insert("HADR");
64 fG3FlagNameVector.insert("MUNU");
65 fG3FlagNameVector.insert("DCAY");
66 fG3FlagNameVector.insert("LOSS");
67 fG3FlagNameVector.insert("MULS");
70 TG4PhysicsManager::TG4PhysicsManager(const TG4PhysicsManager& right) {
72 TG4Globals::Exception(
73 "Attempt to copy TG4PhysicsManager singleton.");
76 TG4PhysicsManager::~TG4PhysicsManager() {
85 TG4PhysicsManager::operator=(const TG4PhysicsManager& right)
87 // check assignement to self
88 if (this == &right) return *this;
90 TG4Globals::Exception(
91 "Attempt to assign TG4PhysicsManager singleton.");
98 void TG4PhysicsManager::LockException() const
100 // Gives exception in case of attempt to modified physics
101 // setup after physics manager was locked.
104 G4String text = "TG4PhysicsManager: \n";
105 text = text + " It is too late to change physics setup. \n";
106 text = text + " PhysicsManager has been already locked.";
107 TG4Globals::Exception(text);
110 G4int TG4PhysicsManager::GetPDGEncoding(G4ParticleDefinition* particle)
112 // Returns the PDG code of particle;
113 // if standard PDG code is not defined the TDatabasePDG
117 // get PDG encoding from G4 particle definition
118 G4int pdgEncoding = particle->GetPDGEncoding();
120 if (pdgEncoding == 0) {
121 // get PDG encoding from TDatabasePDG
123 // get particle name from the name map
124 G4String g4name = particle->GetParticleName();
125 G4String tname = fParticleNameMap.GetSecond(g4name);
126 if (tname == "Undefined") {
127 G4String text = "TG4PhysicsManager::GetPDGEncoding: \n";
128 text = text + " Particle " + g4name;
129 text = text + " was not found in the name map.";
130 TG4Globals::Exception(text);
133 // get particle from TDatabasePDG
134 TDatabasePDG* pdgDB = TDatabasePDG::Instance();
135 TParticlePDG* particle = pdgDB->GetParticle(tname);
137 G4String text = "TG4PhysicsManager::GetPDGEncoding: \n";
138 text = text + " Particle " + tname;
139 text = text + " was not found in TDatabasePDG.";
140 TG4Globals::Exception(text);
144 pdgEncoding = particle->PdgCode();
150 G4int TG4PhysicsManager::GetPDGEncoding(G4String particleName)
152 // Returns the PDG code of particle sepcified by name.
155 G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
157 G4ParticleDefinition* particle = 0;
158 particle = particleTable->FindParticle(particleName);
160 G4String text = "TG4PhysicsManager::GetPDGEncoding:\n";
161 text = text + " G4ParticleTable::FindParticle() " + particleName;
162 text = text + " failed.";
163 TG4Globals::Exception(text);
166 return GetPDGEncoding(particle);
169 void TG4PhysicsManager::SetCut(TG3Cut cut, G4double cutValue)
171 // Sets kinetic energy cut (in a G3-like way).
175 // create vector of kinetic energy cut values
176 fCutVector = new TG4CutVector();
178 fCutVector->SetG3Cut(cut, cutValue);
179 SwitchIsCutVector(cut);
182 void TG4PhysicsManager::SetProcess(TG3Flag flag, G4int flagValue)
184 // Sets control process flag (in a G3-like way).
188 // create vector of control process flag values
189 fFlagVector = new TG4FlagVector;
191 fFlagVector->SetG3Flag(flag, flagValue);
195 Float_t TG4PhysicsManager::Xsec(char* ch, Float_t p1, Int_t i1, Int_t i2)
197 // Not yet implemented -> gives exception.
200 TG4Globals::Exception(
201 "TG4PhysicsManager::Xsec: not yet implemented.");
206 Int_t TG4PhysicsManager::IdFromPDG(Int_t pdgID) const
208 // G4 does not use the integer particle identifiers
209 // Id <-> PDG is identity.
215 Int_t TG4PhysicsManager::PDGFromId(Int_t mcID) const
217 // G4 does not use integer particle identifiers
218 // Id <-> PDG is identity.
224 void TG4PhysicsManager::DefineParticles()
227 // Taken from TGeant3
229 // Use ENDF-6 mapping for ions = 10000*z+10*a+iso
231 // and numbers above 5 000 000 for special applications
234 const Int_t kion=10000000;
235 const Int_t kspe=50000000;
237 const Double_t kGeV=0.9314943228;
238 const Double_t kHslash = 1.0545726663e-27;
239 const Double_t kErgGeV = 1/1.6021773349e-3;
240 const Double_t kHshGeV = kHslash*kErgGeV;
241 const Double_t kYearsToSec = 3600*24*365.25;
243 TDatabasePDG *pdgDB = TDatabasePDG::Instance();
245 pdgDB->AddParticle("Deuteron","Deuteron",2*kGeV+8.071e-3,kTRUE,
246 0,1,"Ion",kion+10020);
248 pdgDB->AddParticle("Triton","Triton",3*kGeV+14.931e-3,kFALSE,
249 kHshGeV/(12.33*kYearsToSec),1,"Ion",kion+10030);
251 pdgDB->AddParticle("Alpha","Alpha",4*kGeV+2.424e-3,kTRUE,
252 kHshGeV/(12.33*kYearsToSec),2,"Ion",kion+20040);
254 pdgDB->AddParticle("HE3","HE3",3*kGeV+14.931e-3,kFALSE,
255 0,2,"Ion",kion+20030);
257 pdgDB->AddParticle("Cherenkov","Cherenkov",0,kFALSE,
258 0,0,"Special",kspe+50);
260 pdgDB->AddParticle("FeedbackPhoton","FeedbackPhoton",0,kFALSE,
261 0,0,"Special",kspe+51);
264 // To do: define the PDG database extension
267 // AliMC::ExtendPDGDatabase();
269 // end of "common" implementation
272 // map G4 particle names to TDatabasePDG names
273 // (the map is built only for particles that have not
274 // defined standard PDG encoding)
276 fParticleNameMap.Add("deuteron","Deuteron");
277 fParticleNameMap.Add("triton", "Triton");
278 fParticleNameMap.Add("alpha", "Alpha");
279 fParticleNameMap.Add("He3", "HE3");
280 fParticleNameMap.Add("opticalphoton","Cherenkov");
281 // fParticleNameMap.Add("???","FeedbackPhoton");
282 fParticleNameMap.Add("geantino", "Rootino");
284 // map G4 particle names to TDatabasePDG encodings
285 fParticlePDGMap.Add("deuteron", GetPDGEncoding("deuteron"));
286 fParticlePDGMap.Add("triton", GetPDGEncoding("triton"));
287 fParticlePDGMap.Add("alpha", GetPDGEncoding("alpha"));
288 fParticlePDGMap.Add("He3", GetPDGEncoding("He3") );
289 fParticlePDGMap.Add("opticalphoton", GetPDGEncoding("opticalphoton"));
290 // fParticlePDGMap.Add("???","FeedbackPhoton");
291 fParticleNameMap.Add("geantino", GetPDGEncoding("geantino"));
294 G4cout << "Particle maps have been filled." << G4endl;
295 //fParticleNameMap.PrintAll();
296 //fParticlePDGMap.PrintAll();
299 void TG4PhysicsManager::SwitchIsCutVector(TG3Cut cut)
301 // Updates the vector of booleans (fIsCutVector) for the specified cut.
306 (*fIsCutVector)[kGamma] = true;
309 (*fIsCutVector)[kGamma] = true;
312 (*fIsCutVector)[kGamma] = true;
315 (*fIsCutVector)[kElectron] = true;
318 (*fIsCutVector)[kElectron] = true;
321 (*fIsCutVector)[kElectron] = true;
324 (*fIsCutVector)[kNeutralHadron] = true;
327 (*fIsCutVector)[kChargedHadron] = true;
330 (*fIsCutVector)[kMuon] = true;
337 void TG4PhysicsManager::SwitchIsFlagVector(TG3Flag flag)
339 // Updates the vector of booleans (fIsFlagVector) for the specified flag.
345 (*fIsFlagVector)[kGamma] = true;
349 (*fIsFlagVector)[kGamma] = true;
353 (*fIsFlagVector)[kGamma] = true;
357 (*fIsFlagVector)[kGamma] = true;
360 // all charged particles
361 (*fIsFlagVector)[kElectron] = true;
362 (*fIsFlagVector)[kEplus] = true;
363 (*fIsFlagVector)[kChargedHadron] = true;
364 (*fIsFlagVector)[kMuon] = true;
368 (*fIsFlagVector)[kEplus] = true;
372 (*fIsFlagVector)[kElectron] = true;
373 (*fIsFlagVector)[kEplus] = true;
374 (*fIsFlagVector)[kMuon] = true;
378 (*fIsFlagVector)[kNeutralHadron] = true;
379 (*fIsFlagVector)[kChargedHadron] = true;
383 (*fIsFlagVector)[kMuon] = true;
387 (*fIsFlagVector)[kAny] = true;
390 // all charged particles
391 (*fIsFlagVector)[kElectron] = true;
392 (*fIsFlagVector)[kEplus] = true;
393 (*fIsFlagVector)[kChargedHadron] = true;
394 (*fIsFlagVector)[kMuon] = true;
397 // all charged particles
398 (*fIsFlagVector)[kElectron] = true;
399 (*fIsFlagVector)[kEplus] = true;
400 (*fIsFlagVector)[kChargedHadron] = true;
401 (*fIsFlagVector)[kMuon] = true;
408 TG3Cut TG4PhysicsManager::GetG3Cut(G4String cutName)
410 // Retrieves corresponding TG3Cut constant from the cutName.
413 if (cutName == fG3CutNameVector[kCUTGAM]) return kCUTGAM;
414 else if (cutName == fG3CutNameVector[kBCUTE]) return kBCUTE;
415 else if (cutName == fG3CutNameVector[kBCUTM]) return kBCUTM;
416 else if (cutName == fG3CutNameVector[kCUTELE]) return kCUTELE;
417 else if (cutName == fG3CutNameVector[kDCUTE]) return kDCUTE;
418 else if (cutName == fG3CutNameVector[kDCUTM]) return kDCUTM;
419 else if (cutName == fG3CutNameVector[kCUTNEU]) return kCUTNEU;
420 else if (cutName == fG3CutNameVector[kCUTHAD]) return kCUTHAD;
421 else if (cutName == fG3CutNameVector[kCUTMUO]) return kCUTMUO;
422 else return kNoG3Cuts;
425 TG3Flag TG4PhysicsManager::GetG3Flag(G4String flagName)
427 // Retrieves corresponding TG3Flag constant from the flagName.
430 if (flagName == fG3FlagNameVector[kPAIR]) return kPAIR;
431 else if (flagName == fG3FlagNameVector[kCOMP]) return kCOMP;
432 else if (flagName == fG3FlagNameVector[kPHOT]) return kPHOT;
433 else if (flagName == fG3FlagNameVector[kPFIS]) return kPFIS;
434 else if (flagName == fG3FlagNameVector[kDRAY]) return kDRAY;
435 else if (flagName == fG3FlagNameVector[kANNI]) return kANNI;
436 else if (flagName == fG3FlagNameVector[kBREM]) return kBREM;
437 else if (flagName == fG3FlagNameVector[kHADR]) return kHADR;
438 else if (flagName == fG3FlagNameVector[kMUNU]) return kMUNU;
439 else if (flagName == fG3FlagNameVector[kDCAY]) return kDCAY;
440 else if (flagName == fG3FlagNameVector[kLOSS]) return kLOSS;
441 else if (flagName == fG3FlagNameVector[kMULS]) return kMULS;
442 else return kNoG3Flags;
447 void TG4PhysicsManager::BuildPhysics()
449 // Empty function - not needed in G4.
450 // (Physics is built within /run/initialize.)
453 "TG4PhysicsManager::BuildPhysics: is empty function in G4 MC.");
456 void TG4PhysicsManager::SetCut(const char* cutName, Float_t cutValue)
458 // Sets the specified cut.
461 if (fLock) LockException();
462 TG3Cut g3Cut = GetG3Cut(cutName);
463 if (g3Cut != kNoG3Cuts)
464 SetCut(g3Cut, cutValue);
466 G4String text = "TG4PhysicsManager::SetCut:\n";
467 text = text + " Parameter " + cutName;
468 text = text + " is not implemented.";
469 TG4Globals::Warning(text);
473 void TG4PhysicsManager::SetProcess(const char* flagName, Int_t flagValue)
475 // Sets the specified process control.
478 if (fLock) LockException();
479 TG3Flag g3Flag = GetG3Flag(flagName);
480 if (g3Flag != kNoG3Flags)
481 SetProcess(g3Flag, flagValue);
483 G4String text = "TG4PhysicsManager::SetProcess:\n";
484 text = text + " Parameter " + flagName;
485 text = text + " is not implemented.";
486 TG4Globals::Warning(text);
490 void TG4PhysicsManager::SetProcessActivation()
492 // (In)Activates built processes according
493 // to the setup in fFlagVector.
497 // temporarily excluded
498 // fPhysicsList->SetProcessActivation();
501 G4String text = "TG4PhysicsManager::SetProcessActivation:\n";
502 text = text + " There is no physics list set.";
503 TG4Globals::Exception(text);
507 G4int TG4PhysicsManager::GetPDGEncodingFast(G4ParticleDefinition* particle)
509 // Returns the PDG code of particle;
510 // if standard PDG code is not defined the preregistred
511 // fParticlePDGMap is used.
514 // get PDG encoding from G4 particle definition
515 G4int pdgEncoding = particle->GetPDGEncoding();
517 if (pdgEncoding == 0) {
518 // use FParticlePDGMap if standard PDG code is not defined
519 G4String name = particle->GetParticleName();
520 pdgEncoding = fParticlePDGMap.GetSecond(name);
526 G4bool TG4PhysicsManager::CheckCutWithCutVector(G4String name,
527 G4double value, TG3Cut& cut)
529 // Retrieves corresponding TG3Cut from the name and
530 // in case the value is different from the value in cutVector
531 // sets true the value of the fIsCutVector element
532 // corresponding to this cut and returns true;
533 // returns false otherwise.
536 // convert cut name -> TG3Cut
537 cut = GetG3Cut(name);
539 // set switch vector element only if the value
540 // is different from the value in cutVector
541 if (cut !=kNoG3Cuts) {
542 // get tolerance from TG4G3Defaults in GeV
543 G4double tolerance = TG4G3Defaults::CutTolerance()/GeV;
544 if (!(fCutVector) || (abs(value - (*fCutVector)[cut]) > tolerance)) {
545 SwitchIsCutVector(cut);
553 G4bool TG4PhysicsManager::CheckFlagWithFlagVector(G4String name,
554 G4double value, TG3Flag& flag)
556 // Retrieves corresponding TG3Flag from the name and
557 // in case the value is different from the value in flagVector
558 // sets true the value of the fIsFlagVector element
559 // corresponding to this flag and returns true;
560 // returns false otherwise.
563 // convert flag name -> TG3Flag
564 flag = GetG3Flag(name);
566 // set switch vector element only if the value
567 // is different from the value in flagVector
568 if (flag !=kNoG3Flags) {
569 if (!(fFlagVector) || (abs(value - (*fFlagVector)[flag]) > 0.01)) {
570 SwitchIsFlagVector(flag);
578 G4bool TG4PhysicsManager::CheckCutWithG3Defaults(G4String name,
579 G4double value, TG3Cut& cut)
581 // Retrieves corresponding TG3Cut from the name and
582 // in case the value is different from the G3 default value
583 // sets true the value of the SwitchCutVector element
584 // corresponding to this cut and returns true;
585 // returns false otherwise.
588 // convert cut name -> TG3Cut
589 cut = GetG3Cut(name);
591 // set switch vector element only if the value
592 // is different from G3 default
593 if (cut !=kNoG3Cuts) {
594 if (!TG4G3Defaults::IsDefaultCut(cut, value)) {
595 SwitchIsCutVector(cut);
603 G4bool TG4PhysicsManager::CheckFlagWithG3Defaults(G4String name,
604 G4double value, TG3Flag& flag)
606 // Retrieves corresponding TG3Flag from the name and
607 // in case the value is different from the G3 default value
608 // sets true the value of the SwitchFlagVector element
609 // corresponding to this flag and returns true;
610 // returns false otherwise.
613 // convert flag name -> TG3Flag
614 flag = GetG3Flag(name);
616 // set switch vector element only if the value
617 // is different from G3 default
618 if (flag !=kNoG3Flags) {
619 if (!TG4G3Defaults::IsDefaultFlag(flag, value)) {
620 SwitchIsFlagVector(flag);
628 void TG4PhysicsManager::SetG3DefaultCuts()
630 // Sets G3 default values of kinetic energy cuts.
633 if (fLock) LockException();
635 // create vector of kinetic energy cut values
636 fCutVector = new TG4CutVector();
638 fCutVector->SetG3Defaults();
641 void TG4PhysicsManager::SetG3DefaultProcesses()
643 // Sets G3 default values of control process flags.
646 if (fLock) LockException();
648 // create vector of control process flag values
649 fFlagVector = new TG4FlagVector;
651 fFlagVector->SetG3Defaults();
654 G4bool TG4PhysicsManager::IsSpecialCuts() const
656 // Returns true if any special cut value is set.
659 for (G4int i=0; i<kNofParticlesWSP; i++)
660 { if ((*fIsCutVector)[i]) return true; }
665 G4bool TG4PhysicsManager::IsSpecialFlags() const
667 // Returns true if any special flag value is set.
670 for (G4int i=0; i<kNofParticlesWSP; i++)
671 { if ((*fIsFlagVector)[i]) return true; }
676 TG3ParticleWSP TG4PhysicsManager::GetG3ParticleWSP(
677 G4ParticleDefinition* particle) const
679 // Returns TG3ParticleWSP constant for the specified particle.
680 // (See TG3ParticleWSP.h, too.)
683 G4String name = particle->GetParticleName();
684 G4String pType = particle->GetParticleType();
686 if (name == "gamma") {
689 else if (name == "e-") {
692 else if (name == "e+") {
695 else if (( pType == "baryon" || pType == "meson" || pType == "nucleus" )) {
696 if (particle->GetPDGCharge() == 0) {
697 return kNeutralHadron;
700 return kChargedHadron;
702 else if ( name == "mu-" || name == "mu+" ) {
706 return kNofParticlesWSP;
710 void TG4PhysicsManager::GetG3ParticleWSPName(G4int particleWSP,
711 G4String& name) const
713 // Fills the passed name with the name/type of particle specified
714 // by TG3ParticleWSP constant.
715 // (See TG3ParticleWSP.h, too.)
718 switch (particleWSP) {
729 name = "NeutralHadron";
732 name = "ChargedHadron";
740 case kNofParticlesWSP:
744 G4String text = "TG4PhysicsList::GetG3ParticleWSPName:\n";
745 text = text + " Wrong particleWSP.";
746 TG4Globals::Exception(text);