1 #include"G4ParticleTable.hh"
2 #include "Randomize.hh"
12 #include"SimG4Core/CustomPhysics/interface/G4ProcessHelper.hh"
16 using namespace CLHEP;
20 particleTable = G4ParticleTable::GetParticleTable();
22 theProton = particleTable->FindParticle(
"proton");
23 theNeutron = particleTable->FindParticle(
"neutron");
29 std::ifstream process_stream (processDefFilePath.c_str());
34 amplitude = p.
getParameter<
double>(
"amplitude")*millibarn;
35 suppressionfactor = p.
getParameter<
double>(
"reggeSuppression");
36 hadronlifetime = p.
getParameter<
double>(
"hadronLifeTime");
40 edm::LogInfo(
"CustomPhysics")<<
"Read in physics parameters:"<<G4endl;
41 edm::LogInfo(
"CustomPhysics")<<
"Resonant = "<< resonant <<G4endl;
42 edm::LogInfo(
"CustomPhysics")<<
"ResonanceEnergy = "<<ek_0/GeV<<
" GeV"<<G4endl;
43 edm::LogInfo(
"CustomPhysics")<<
"Gamma = "<<gamma/GeV<<
" GeV"<<G4endl;
44 edm::LogInfo(
"CustomPhysics")<<
"Amplitude = "<<amplitude/millibarn<<
" millibarn"<<G4endl;
45 edm::LogInfo(
"CustomPhysics")<<
"ReggeSuppression = "<<100*suppressionfactor<<
" %"<<G4endl;
46 edm::LogInfo(
"CustomPhysics")<<
"HadronLifeTime = "<<hadronlifetime<<
" s"<<G4endl;
47 edm::LogInfo(
"CustomPhysics")<<
"ReggeModel = "<< reggemodel <<G4endl;
48 edm::LogInfo(
"CustomPhysics")<<
"Mixing = "<< mixing*100 <<
" %"<<G4endl;
57 while(getline(process_stream,line)){
58 std::vector<G4String> tokens;
60 ReadAndParse(line,tokens,
"#");
62 G4String incident = tokens[0];
64 G4ParticleDefinition* incidentDef = particleTable->FindParticle(incident);
66 G4int incidentPDG = incidentDef->GetPDGEncoding();
67 known_particles[incidentDef]=
true;
69 G4String
target = tokens[1];
71 <<
" Target: "<<target<<G4endl;
75 for (
size_t i = 2;
i != tokens.size();
i++){
76 G4String
part = tokens[
i];
77 if (particleTable->contains(part))
79 prod.push_back(particleTable->FindParticle(part)->GetPDGEncoding());
81 edm::LogInfo(
"CustomPhysics")<<
"Particle: "<<part<<
" is unknown."<<G4endl;
82 G4Exception(
"G4ProcessHelper",
"UnkownParticle", FatalException,
83 "Initialization: The reaction product list contained an unknown particle");
86 if (target ==
"proton")
88 pReactionMap[incidentPDG].push_back(prod);
89 }
else if (target ==
"neutron") {
90 nReactionMap[incidentPDG].push_back(prod);
92 G4Exception(
"G4ProcessHelper",
"IllegalTarget", FatalException,
93 "Initialization: The reaction product list contained an illegal target particle");
97 process_stream.close();
99 G4ParticleTable::G4PTblDicIterator* theParticleIterator;
100 theParticleIterator = particleTable->GetIterator();
102 theParticleIterator->reset();
103 while( (*theParticleIterator)() ){
106 G4DecayTable*
table = theParticleIterator->value()->GetDecayTable();
107 if(particle!=0&&table!=0&&name.find(
"cloud")>name.size()&&hadronlifetime > 0)
109 particle->SetPDGLifeTime(hadronlifetime*
s);
110 particle->SetPDGStable(
false);
111 edm::LogInfo(
"CustomPhysics")<<
"Lifetime of: "<<name<<
" set to: "<<particle->GetPDGLifeTime()/s<<
" s."<<G4endl;
112 edm::LogInfo(
"CustomPhysics")<<
"Stable: "<<particle->GetPDGStable()<<G4endl;
115 theParticleIterator->reset();
120 G4bool G4ProcessHelper::ApplicabilityTester(
const G4ParticleDefinition& aPart){
121 const G4ParticleDefinition* aP = &aPart;
122 if (known_particles[aP])
return true;
126 G4double G4ProcessHelper::GetInclusiveCrossSection(
const G4DynamicParticle *aParticle,
127 const G4Element *anElement){
134 G4int thePDGCode = aParticle->GetDefinition()->GetPDGEncoding();
135 double boost = (aParticle->GetKineticEnergy()+aParticle->GetMass())/aParticle->GetMass();
137 G4double theXsec = 0;
138 G4String name = aParticle->GetDefinition()->GetParticleName();
143 theXsec = 24 * millibarn;
147 for (std::vector<G4int>::iterator it = nq.begin();
152 if (*it == 1 || *it == 2) theXsec += 12 * millibarn;
153 if (*it == 3) theXsec += 6 * millibarn;
159 double R = Regge(boost);
160 double P = Pom(boost);
183 double e_0 = ek_0 + aParticle->GetDefinition()->GetPDGMass();
185 e_0 =
sqrt(aParticle->GetDefinition()->GetPDGMass()*aParticle->GetDefinition()->GetPDGMass()
186 + theProton->GetPDGMass()*theProton->GetPDGMass()
187 + 2.*e_0*theProton->GetPDGMass());
190 double sqrts=
sqrt(aParticle->GetDefinition()->GetPDGMass()*aParticle->GetDefinition()->GetPDGMass()
191 + theProton->GetPDGMass()*theProton->GetPDGMass() + 2*aParticle->GetTotalEnergy()*theProton->GetPDGMass());
193 double res_result = amplitude*(gamma*gamma/4.)/((sqrts-e_0)*(sqrts-e_0)+(gamma*gamma/4.));
195 theXsec += res_result;
202 return theXsec *
pow(anElement->GetN(),0.7)*1.25;
206 ReactionProduct G4ProcessHelper::GetFinalState(
const G4Track& aTrack, G4ParticleDefinition*& aTarget){
208 const G4DynamicParticle* aDynamicParticle = aTrack.GetDynamicParticle();
215 G4Material* aMaterial = aTrack.GetMaterial();
216 const G4ElementVector* theElementVector = aMaterial->GetElementVector() ;
217 const G4double* NbOfAtomsPerVolume = aMaterial->GetVecNbOfAtomsPerVolume();
219 G4double NumberOfProtons=0;
220 G4double NumberOfNucleons=0;
222 for (
size_t elm=0 ; elm < aMaterial->GetNumberOfElements() ; elm++ )
225 NumberOfProtons += NbOfAtomsPerVolume[elm]*(*theElementVector)[elm]->GetZ();
227 NumberOfNucleons += NbOfAtomsPerVolume[elm]*(*theElementVector)[elm]->GetN();
230 if(G4UniformRand()<NumberOfProtons/NumberOfNucleons)
232 theReactionMap = &pReactionMap;
233 theTarget = theProton;
235 theReactionMap = &nReactionMap;
236 theTarget = theNeutron;
240 G4int theIncidentPDG = aDynamicParticle->GetDefinition()->GetPDGEncoding();
244 && G4UniformRand()*mixing>0.5
245 &&aDynamicParticle->GetDefinition()->GetPDGCharge()==0.
249 theIncidentPDG *= -1;
253 bool baryonise=
false;
256 && G4UniformRand()>0.9
266 ReactionProductList* aReactionProductList = &((*theReactionMap)[theIncidentPDG]);
278 ReactionProductList theReactionProductList;
279 std::vector<bool> theChargeChangeList;
281 for (ReactionProductList::iterator prod_it = aReactionProductList->begin();
282 prod_it != aReactionProductList->end();
284 G4int secondaries = prod_it->size();
287 if(ReactionIsPossible(*prod_it,aDynamicParticle)
289 (baryonise&&ReactionGivesBaryon(*prod_it))
291 (!baryonise&&!ReactionGivesBaryon(*prod_it))
300 theReactionProductList.push_back(*prod_it);
301 if (secondaries == 2){
303 }
else if (secondaries ==3) {
306 G4cerr <<
"ReactionProduct has unsupported number of secondaries: "<<secondaries<<G4endl;
314 if (theReactionProductList.size()==0) G4Exception(
"G4ProcessHelper",
"NoProcessPossible", FatalException,
315 "GetFinalState: No process could be selected from the given list.");
320 int n_rps = theReactionProductList.size();
321 int select = (int)( G4UniformRand()*n_rps);
323 return theReactionProductList[
select];
329 G4double p23 = 1-p22;
331 std::vector<G4double> Probabilities;
332 std::vector<G4bool> TwotoThreeFlag;
334 G4double CumulatedProbability = 0;
338 for (
unsigned int i = 0;
i != theReactionProductList.size();
i++){
339 if (theReactionProductList[
i].
size() == 2) {
340 CumulatedProbability += p22/N22;
341 TwotoThreeFlag.push_back(
false);
343 CumulatedProbability += p23/N23;
344 TwotoThreeFlag.push_back(
true);
346 Probabilities.push_back(CumulatedProbability);
352 for (std::vector<G4double>::iterator it = Probabilities.begin();
353 it != Probabilities.end();
356 *it /= CumulatedProbability;
363 G4bool selected =
false;
369 while(!selected && tries < 100){
371 G4double dice = G4UniformRand();
373 while(dice>Probabilities[i] && i<theReactionProductList.size()){
380 if(!TwotoThreeFlag[i]) {
385 if (PhaseSpace(theReactionProductList[i],aDynamicParticle)>G4UniformRand()) selected =
true;
389 if(selected&&particleTable->FindParticle(theReactionProductList[i][0])->GetPDGCharge()!=aDynamicParticle->GetDefinition()->GetPDGCharge())
397 if(G4UniformRand()<suppressionfactor) selected =
false;
402 if(tries>=100) G4cerr<<
"Could not select process!!!!"<<G4endl;
408 if (theReactionProductList[i].
size()==2) {
414 checkfraction = (1.0*n_22)/(n_22+n_23);
418 return theReactionProductList[
i];
421 G4double G4ProcessHelper::ReactionProductMass(
const ReactionProduct& aReaction,
const G4DynamicParticle* aDynamicParticle){
423 G4double E_incident = aDynamicParticle->GetTotalEnergy();
426 G4double m_1 = aDynamicParticle->GetDefinition()->GetPDGMass();
427 G4double m_2 = theTarget->GetPDGMass();
429 G4double sqrts =
sqrt(m_1*m_1 + m_2*(m_2 + 2 * E_incident));
432 G4double M_after = 0;
433 for (ReactionProduct::const_iterator r_it = aReaction.begin(); r_it !=aReaction.end(); r_it++){
435 M_after += particleTable->FindParticle(*r_it)->GetPDGMass();
438 return sqrts - M_after;
441 G4bool G4ProcessHelper::ReactionIsPossible(
const ReactionProduct& aReaction,
const G4DynamicParticle* aDynamicParticle){
442 if (ReactionProductMass(aReaction,aDynamicParticle)>0)
return true;
446 G4bool G4ProcessHelper::ReactionGivesBaryon(
const ReactionProduct& aReaction){
447 for (ReactionProduct::const_iterator it = aReaction.begin();it!=aReaction.end();it++)
452 G4double G4ProcessHelper::PhaseSpace(
const ReactionProduct& aReaction,
const G4DynamicParticle* aDynamicParticle){
453 G4double qValue = ReactionProductMass(aReaction,aDynamicParticle);
454 G4double
phi =
sqrt(1+qValue/(2*0.139*GeV))*
pow(qValue/(1.1*GeV),3./2.);
455 return (phi/(1+phi));
458 void G4ProcessHelper::ReadAndParse(
const G4String& str,
459 std::vector<G4String>& tokens,
460 const G4String& delimiters)
467 while (G4String::npos != pos || G4String::npos != lastPos)
470 G4String
temp = str.substr(lastPos, pos - lastPos);
471 while(temp.c_str()[0] ==
' ') temp.erase(0,1);
472 while(temp[temp.size()-1] ==
' ') temp.erase(temp.size()-1,1);
474 tokens.push_back(temp);
476 lastPos = str.find_first_not_of(delimiters, pos);
478 pos = str.find_first_of(delimiters, lastPos);
482 double G4ProcessHelper::Regge(
const double boost)
484 double a=2.165635078566177;
485 double b=0.1467453738547229;
486 double c=-0.9607903711871166;
487 return 1.5*
exp(a+b/boost+c*
log(boost));
491 double G4ProcessHelper::Pom(
const double boost)
493 double a=4.138224000651535;
494 double b=1.50377557581421;
495 double c=-0.05449742257808247;
496 double d=0.0008221235048211401;
497 return a + b*
sqrt(boost) + c*boost + d*
pow(boost,1.5);
T getParameter(std::string const &) const
static bool s_isRGlueball(int pdg)
static bool s_isSbaryon(int pdg)
static bool s_isRMeson(int pdg)
static bool s_isMesonino(int pdg)
static bool s_isRBaryon(int pdg)
static std::vector< int > s_containedQuarks(int pdg)
std::string fullPath() const
tuple size
Write out results.
Power< A, B >::type pow(const A &a, const B &b)