00001 #include "Randomize.hh"
00002 #include "G4ParticleTable.hh"
00003
00004 #include <iostream>
00005 #include <fstream>
00006 #include <string>
00007
00008 #include "SimG4Core/CustomPhysics/interface/CustomPDGParser.h"
00009 #include "SimG4Core/CustomPhysics/interface/HadronicProcessHelper.hh"
00010
00011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00012 #include "FWCore/ParameterSet/interface/FileInPath.h"
00013
00014 HadronicProcessHelper::HadronicProcessHelper(const std::string & fileName){
00015
00016 m_particleTable = G4ParticleTable::GetParticleTable();
00017 m_proton = m_particleTable->FindParticle("proton");
00018 m_neutron = m_particleTable->FindParticle("neutron");
00019
00020 G4String line;
00021
00022 std::ifstream processListStream (fileName.c_str());
00023
00024 while(getline(processListStream,line)){
00025 std::vector<G4String> tokens;
00026
00027
00028 m_readAndParse(line,tokens,"#");
00029
00030
00031 G4String incident = tokens[0];
00032 G4ParticleDefinition* incidentDef = m_particleTable->FindParticle(incident);
00033 G4int incidentPDG = incidentDef->GetPDGEncoding();
00034 m_knownParticles[incidentDef]=true;
00035
00036 G4String target = tokens[1];
00037
00038
00039
00040 ReactionProduct prod;
00041 for (size_t i = 2; i != tokens.size();i++){
00042 G4String part = tokens[i];
00043 if (m_particleTable->contains(part))
00044 {
00045 prod.push_back(m_particleTable->FindParticle(part)->GetPDGEncoding());
00046 } else {
00047 G4cout<<"Particle: "<<part<<" is unknown."<<G4endl;
00048 G4Exception("HadronicProcessHelper", "UnkownParticle", FatalException,
00049 "Initialization: The reaction product list contained an unknown particle");
00050 }
00051 }
00052 if (target == "proton")
00053 {
00054 m_protonReactionMap[incidentPDG].push_back(prod);
00055 } else if (target == "neutron") {
00056 m_neutronReactionMap[incidentPDG].push_back(prod);
00057 } else {
00058 G4Exception("HadronicProcessHelper", "IllegalTarget", FatalException,
00059 "Initialization: The reaction product list contained an illegal target particle");
00060 }
00061 }
00062
00063 processListStream.close();
00064
00065
00066 m_checkFraction = 0;
00067 m_n22 = 0;
00068 m_n23 = 0;
00069
00070
00071 }
00072
00073
00074 G4bool HadronicProcessHelper::applicabilityTester(const G4ParticleDefinition& aPart){
00075 const G4ParticleDefinition* aP = &aPart;
00076 if (m_knownParticles[aP]) return true;
00077 return false;
00078 }
00079
00080 G4double HadronicProcessHelper::inclusiveCrossSection(const G4DynamicParticle *particle,
00081 const G4Element *element){
00082
00083
00084
00085 G4int pdgCode = particle->GetDefinition()->GetPDGEncoding();
00086
00087
00088 if(CustomPDGParser::s_isRGlueball(pdgCode)) return 24 * millibarn * element->GetN();
00089
00090
00091 std::vector<G4int> quarks=CustomPDGParser::s_containedQuarks(pdgCode);
00092
00093 G4double totalNucleonCrossSection = 0;
00094
00095 for (std::vector<G4int>::iterator it = quarks.begin();
00096 it != quarks.end();
00097 it++)
00098 {
00099
00100 if (*it == 1 || *it == 2) totalNucleonCrossSection += 12 * millibarn;
00101
00102 if (*it == 3) totalNucleonCrossSection += 6 * millibarn;
00103 }
00104
00105
00106
00107 return totalNucleonCrossSection * pow(element->GetN(),0.7)*1.25;
00108 }
00109
00110 HadronicProcessHelper::ReactionProduct HadronicProcessHelper::finalState(const G4DynamicParticle* incidentDynamicParticle,
00111 const G4Material *material, G4ParticleDefinition*& target){
00112
00113
00114
00115
00116
00117
00118
00119 ReactionMap* m_reactionMap;
00120
00121 const G4ElementVector* elementVector = material->GetElementVector() ;
00122 const G4double* numberOfAtomsPerVolume = material->GetVecNbOfAtomsPerVolume();
00123
00124 G4double numberOfProtons=0;
00125 G4double numberOfNucleons=0;
00126
00127
00128 for ( size_t elm=0 ; elm < material->GetNumberOfElements() ; elm++ )
00129 {
00130
00131 numberOfProtons += numberOfAtomsPerVolume[elm]*(*elementVector)[elm]->GetZ();
00132
00133 numberOfNucleons += numberOfAtomsPerVolume[elm]*(*elementVector)[elm]->GetN();
00134 }
00135
00136
00137 if(G4UniformRand()<numberOfProtons/numberOfNucleons)
00138 {
00139 m_reactionMap = &m_protonReactionMap;
00140 target = m_proton;
00141 } else {
00142 m_reactionMap = &m_neutronReactionMap;
00143 target = m_neutron;
00144 }
00145
00146 const G4int incidentPDG = incidentDynamicParticle->GetDefinition()->GetPDGEncoding();
00147
00148
00149 ReactionProductList* reactionProductList = &((*m_reactionMap)[incidentPDG]);
00150
00151
00152
00153
00154
00155
00156
00157 G4int good22 = 0;
00158 G4int good23 = 0;
00159
00160
00161 ReactionProductList goodReactionProductList;
00162
00163 for (ReactionProductList::iterator prod_it = reactionProductList->begin();
00164 prod_it != reactionProductList->end();
00165 prod_it++){
00166 G4int secondaries = prod_it->size();
00167
00168 if(m_reactionIsPossible(*prod_it,incidentDynamicParticle,target)){
00169
00170 goodReactionProductList.push_back(*prod_it);
00171 if (secondaries == 2){
00172 good22++;
00173 } else if (secondaries ==3) {
00174 good23++;
00175 } else {
00176 G4cerr << "ReactionProduct has unsupported number of secondaries: "<<secondaries<<G4endl;
00177 }
00178 }
00179
00180
00181 }
00182
00183
00184 if (goodReactionProductList.size()==0) G4Exception("HadronicProcessHelper", "NoProcessPossible", FatalException,
00185 "GetFinalState: No process could be selected from the given list.");
00186
00187
00188 G4double prob22 = 0.15;
00189 G4double prob23 = 1-prob22;
00190
00191 std::vector<G4double> probabilities;
00192 std::vector<G4bool> twoToThreeFlag;
00193
00194 G4double cumulatedProbability = 0;
00195
00196
00197
00198 size_t numberOfReactions = goodReactionProductList.size();
00199 for (size_t i = 0; i != numberOfReactions; i++){
00200 if (goodReactionProductList[i].size() == 2) {
00201 cumulatedProbability += prob22/good22;
00202 twoToThreeFlag.push_back(false);
00203 } else {
00204 cumulatedProbability += prob23/good23;
00205 twoToThreeFlag.push_back(true);
00206 }
00207 probabilities.push_back(cumulatedProbability);
00208 }
00209
00210
00211 for (std::vector<G4double>::iterator it = probabilities.begin();
00212 it != probabilities.end();
00213 it++)
00214 {
00215 *it /= cumulatedProbability;
00216 }
00217
00218
00219 G4bool selected = false;
00220 G4int tries = 0;
00221
00222
00223
00224 size_t i;
00225 while(!selected && tries < 100){
00226 i=0;
00227 G4double dice = G4UniformRand();
00228
00229 while(dice>probabilities[i] && i<numberOfReactions) i++;
00230
00231 if(twoToThreeFlag[i]) {
00232
00233 if (m_phaseSpace(goodReactionProductList[i],incidentDynamicParticle,target)>G4UniformRand()) selected = true;
00234 } else {
00235
00236 selected = true;
00237 }
00238 tries++;
00239 }
00240 if(tries>=100) G4cerr<<"Could not select process!!!!"<<G4endl;
00241
00242
00243
00244
00245 if (goodReactionProductList[i].size()==2) {
00246 m_n22++;
00247 } else {
00248 m_n23++;
00249 }
00250 m_checkFraction = (1.0*m_n22)/(m_n22+m_n23);
00251
00252
00253 return goodReactionProductList[i];
00254 }
00255
00256 G4double HadronicProcessHelper::m_reactionProductMass(const ReactionProduct& reactionProd,
00257 const G4DynamicParticle* incidentDynamicParticle,G4ParticleDefinition* target){
00258
00259 G4double incidentEnergy = incidentDynamicParticle->GetTotalEnergy();
00260 G4double m_1 = incidentDynamicParticle->GetDefinition()->GetPDGMass();
00261 G4double m_2 = target->GetPDGMass();
00262
00263 G4double sqrtS = sqrt(m_1*m_1 + m_2*(m_2 + 2 * incidentEnergy));
00264
00265 G4double productsMass = 0;
00266
00267 for (ReactionProduct::const_iterator r_it = reactionProd.begin(); r_it !=reactionProd.end(); r_it++){
00268
00269 productsMass += m_particleTable->FindParticle(*r_it)->GetPDGMass();
00270 }
00271
00272 return sqrtS - productsMass;
00273 }
00274
00275 G4bool HadronicProcessHelper::m_reactionIsPossible(const ReactionProduct& aReaction,
00276 const G4DynamicParticle* aDynamicParticle,G4ParticleDefinition* target){
00277 if (m_reactionProductMass(aReaction,aDynamicParticle,target)>0) return true;
00278 return false;
00279 }
00280
00281 G4double HadronicProcessHelper::m_phaseSpace(const ReactionProduct& aReaction,
00282 const G4DynamicParticle* aDynamicParticle,G4ParticleDefinition* target){
00283 G4double qValue = m_reactionProductMass(aReaction,aDynamicParticle,target);
00284 G4double phi = sqrt(1+qValue/(2*0.139*GeV))*pow(qValue/(1.1*GeV),3./2.);
00285 return (phi/(1+phi));
00286 }
00287
00288 void HadronicProcessHelper::m_readAndParse(const G4String& str,
00289 std::vector<G4String>& tokens,
00290 const G4String& delimiters)
00291 {
00292
00293 G4String::size_type lastPos = str.find_first_not_of(delimiters, 0);
00294
00295 G4String::size_type pos = str.find_first_of(delimiters, lastPos);
00296
00297 while (G4String::npos != pos || G4String::npos != lastPos)
00298 {
00299
00300 G4String temp = str.substr(lastPos, pos - lastPos);
00301 while(temp.c_str()[0] == ' ') temp.erase(0,1);
00302 while(temp[temp.size()-1] == ' ') temp.erase(temp.size()-1,1);
00303
00304 tokens.push_back(temp);
00305
00306 lastPos = str.find_first_not_of(delimiters, pos);
00307
00308 pos = str.find_first_of(delimiters, lastPos);
00309 }
00310 }