#include <FastSimulation/MaterialEffects/interface/NuclearInteractionSimulator.h>
Public Member Functions | |
NuclearInteractionSimulator (std::vector< double > &pionEnergies, std::vector< int > &pionTypes, std::vector< std::string > &pionNames, std::vector< double > &pionMasses, std::vector< double > &pionPMin, double pionEnergy, std::vector< double > &lengthRatio, std::vector< std::vector< double > > &ratios, std::map< int, int > &idMap, std::string inputFile, unsigned int distAlgo, double distCut, const RandomEngine *engine) | |
Constructor. | |
bool | read (std::string inputFile) |
Read former nuclear interaction (from previous run). | |
void | save () |
Save current nuclear interaction (for later use). | |
~NuclearInteractionSimulator () | |
Default Destructor. | |
Private Member Functions | |
void | compute (ParticlePropagator &Particle) |
Generate a nuclear interaction according to the probability that it happens. | |
double | distanceToPrimary (const RawParticle &Particle, const RawParticle &aDaughter) const |
Compute distance between secondary and primary. | |
unsigned | index (int thePid) |
Return a hashed index for a given pid. | |
Private Attributes | |
unsigned | ien4 |
unsigned | myOutputBuffer |
std::ofstream | myOutputFile |
std::vector< std::vector < TBranch * > > | theBranches |
std::vector< std::vector < unsigned > > | theCurrentEntry |
std::vector< std::vector < unsigned > > | theCurrentInteraction |
unsigned | theDistAlgo |
double | theDistCut |
std::vector< std::vector < std::string > > | theFileNames |
std::vector< std::vector < TFile * > > | theFiles |
std::map< int, int > | theIDMap |
std::vector< double > | theLengthRatio |
std::vector< std::vector < NUEvent * > > | theNUEvents |
std::vector< std::vector < unsigned > > | theNumberOfEntries |
std::vector< std::vector < unsigned > > | theNumberOfInteractions |
std::vector< std::vector < double > > | thePionCM |
std::vector< double > | thePionEN |
double | thePionEnergy |
std::vector< int > | thePionID |
std::vector< double > | thePionMA |
std::vector< std::string > | thePionNA |
std::vector< double > | thePionPMin |
std::vector< std::vector < double > > | theRatios |
std::vector< std::vector < TTree * > > | theTrees |
Definition at line 33 of file NuclearInteractionSimulator.h.
NuclearInteractionSimulator::NuclearInteractionSimulator | ( | std::vector< double > & | pionEnergies, | |
std::vector< int > & | pionTypes, | |||
std::vector< std::string > & | pionNames, | |||
std::vector< double > & | pionMasses, | |||
std::vector< double > & | pionPMin, | |||
double | pionEnergy, | |||
std::vector< double > & | lengthRatio, | |||
std::vector< std::vector< double > > & | ratios, | |||
std::map< int, int > & | idMap, | |||
std::string | inputFile, | |||
unsigned int | distAlgo, | |||
double | distCut, | |||
const RandomEngine * | engine | |||
) |
Constructor.
Definition at line 20 of file NuclearInteractionSimulator.cc.
References GenMuonPlsPt100GeV_cfg::cout, lat::endl(), Exception, EgammaValidation_cff::filename, RandomEngine::flatShoot(), edm::FileInPath::fullPath(), ien4, iggi_31X_cfg::input, myOutputBuffer, myOutputFile, MaterialEffectsSimulator::random, read(), funct::sqrt(), theBranches, theCurrentEntry, theCurrentInteraction, theFileNames, theFiles, theNUEvents, theNumberOfEntries, theNumberOfInteractions, thePionCM, thePionEN, thePionMA, thePionNA, and theTrees.
00034 : 00035 MaterialEffectsSimulator(engine), 00036 thePionEN(pionEnergies), 00037 thePionID(pionTypes), 00038 thePionNA(pionNames), 00039 thePionMA(pionMasses), 00040 thePionPMin(pionPMin), 00041 thePionEnergy(pionEnergy), 00042 theLengthRatio(lengthRatio), 00043 theRatios(ratios), 00044 theIDMap(idMap), 00045 theDistAlgo(distAlgo), 00046 theDistCut(distCut) 00047 00048 { 00049 00050 gROOT->cd(); 00051 00052 std::string fullPath; 00053 00054 // Prepare the map of files 00055 // Loop over the particle names 00056 std::vector<TFile*> aVFile(thePionEN.size(),static_cast<TFile*>(0)); 00057 std::vector<TTree*> aVTree(thePionEN.size(),static_cast<TTree*>(0)); 00058 std::vector<TBranch*> aVBranch(thePionEN.size(),static_cast<TBranch*>(0)); 00059 std::vector<NUEvent*> aVNUEvents(thePionEN.size(),static_cast<NUEvent*>(0)); 00060 std::vector<unsigned> aVCurrentEntry(thePionEN.size(),static_cast<unsigned>(0)); 00061 std::vector<unsigned> aVCurrentInteraction(thePionEN.size(),static_cast<unsigned>(0)); 00062 std::vector<unsigned> aVNumberOfEntries(thePionEN.size(),static_cast<unsigned>(0)); 00063 std::vector<unsigned> aVNumberOfInteractions(thePionEN.size(),static_cast<unsigned>(0)); 00064 std::vector<std::string> aVFileName(thePionEN.size(),static_cast<std::string>("")); 00065 std::vector<double> aVPionCM(thePionEN.size(),static_cast<double>(0)); 00066 theFiles.resize(thePionNA.size()); 00067 theTrees.resize(thePionNA.size()); 00068 theBranches.resize(thePionNA.size()); 00069 theNUEvents.resize(thePionNA.size()); 00070 theCurrentEntry.resize(thePionNA.size()); 00071 theCurrentInteraction.resize(thePionNA.size()); 00072 theNumberOfEntries.resize(thePionNA.size()); 00073 theNumberOfInteractions.resize(thePionNA.size()); 00074 theFileNames.resize(thePionNA.size()); 00075 thePionCM.resize(thePionNA.size()); 00076 for ( unsigned iname=0; iname<thePionNA.size(); ++iname ) { 00077 theFiles[iname] = aVFile; 00078 theTrees[iname] = aVTree; 00079 theBranches[iname] = aVBranch; 00080 theNUEvents[iname] = aVNUEvents; 00081 theCurrentEntry[iname] = aVCurrentEntry; 00082 theCurrentInteraction[iname] = aVCurrentInteraction; 00083 theNumberOfEntries[iname] = aVNumberOfEntries; 00084 theNumberOfInteractions[iname] = aVNumberOfInteractions; 00085 theFileNames[iname] = aVFileName; 00086 thePionCM[iname] = aVPionCM; 00087 } 00088 00089 // Read the information from a previous run (to keep reproducibility) 00090 bool input = this->read(inputFile); 00091 if ( input ) 00092 std::cout << "***WARNING*** You are reading nuclear-interaction information from the file " 00093 << inputFile << " created in an earlier run." 00094 << std::endl; 00095 00096 // Open the file for saving the information of the current run 00097 myOutputFile.open ("NuclearInteractionOutputFile.txt"); 00098 myOutputBuffer = 0; 00099 00100 00101 // Open the root files 00102 // for ( unsigned file=0; file<theFileNames.size(); ++file ) { 00103 unsigned fileNb = 0; 00104 for ( unsigned iname=0; iname<thePionNA.size(); ++iname ) { 00105 for ( unsigned iene=0; iene<thePionEN.size(); ++iene ) { 00106 //std::cout << "iname/iene " << iname << " " << iene << std::endl; 00107 std::ostringstream filename; 00108 double theEne = thePionEN[iene]; 00109 filename << "NuclearInteractionsVal_" << thePionNA[iname] << "_E"<< theEne << ".root"; 00110 theFileNames[iname][iene] = filename.str(); 00111 //std::cout << "thePid/theEne " << thePionID[iname] << " " << theEne << std::endl; 00112 00113 edm::FileInPath myDataFile("FastSimulation/MaterialEffects/data/"+theFileNames[iname][iene]); 00114 fullPath = myDataFile.fullPath(); 00115 // theFiles[file] = TFile::Open(theFileNames[file].c_str()); 00116 theFiles[iname][iene] = TFile::Open(fullPath.c_str()); 00117 if ( !theFiles[iname][iene] ) throw cms::Exception("FastSimulation/MaterialEffects") 00118 << "File " << theFileNames[iname][iene] << " " << fullPath << " not found "; 00119 ++fileNb; 00120 // 00121 theTrees[iname][iene] = (TTree*) theFiles[iname][iene]->Get("NuclearInteractions"); 00122 if ( !theTrees[iname][iene] ) throw cms::Exception("FastSimulation/MaterialEffects") 00123 << "Tree with name NuclearInteractions not found in " << theFileNames[iname][iene]; 00124 // 00125 theBranches[iname][iene] = theTrees[iname][iene]->GetBranch("nuEvent"); 00126 //std::cout << "The branch = " << theBranches[iname][iene] << std::endl; 00127 if ( !theBranches[iname][iene] ) throw cms::Exception("FastSimulation/MaterialEffects") 00128 << "Branch with name nuEvent not found in " << theFileNames[iname][iene]; 00129 // 00130 theNUEvents[iname][iene] = new NUEvent(); 00131 //std::cout << "The branch = " << theBranches[iname][iene] << std::endl; 00132 theBranches[iname][iene]->SetAddress(&theNUEvents[iname][iene]); 00133 // 00134 theNumberOfEntries[iname][iene] = theTrees[iname][iene]->GetEntries(); 00135 00136 // Add some randomness (if there was no input file) 00137 if ( !input ) 00138 theCurrentEntry[iname][iene] = (unsigned) (theNumberOfEntries[iname][iene] * random->flatShoot()); 00139 00140 theTrees[iname][iene]->GetEntry(theCurrentEntry[iname][iene]); 00141 unsigned NInteractions = theNUEvents[iname][iene]->nInteractions(); 00142 theNumberOfInteractions[iname][iene] = NInteractions; 00143 // Add some randomness (if there was no input file) 00144 if ( !input ) 00145 theCurrentInteraction[iname][iene] = (unsigned) (theNumberOfInteractions[iname][iene] * random->flatShoot()); 00146 00147 /* 00148 std::cout << "File " << theFileNames[iname][iene] 00149 << " is opened with " << theNumberOfEntries[iname][iene] 00150 << " entries and will be read from Entry/Interaction " 00151 << theCurrentEntry[iname][iene] << "/" << theCurrentInteraction[iname][iene] 00152 << std::endl; 00153 */ 00154 00155 // 00156 // Compute the corresponding cm energies of the nuclear interactions 00157 XYZTLorentzVector Proton(0.,0.,0.,0.986); 00158 XYZTLorentzVector 00159 Reference(0., 00160 0., 00161 std::sqrt(thePionEN[iene]*thePionEN[iene] 00162 -thePionMA[iname]*thePionMA[iname]), 00163 thePionEN[iene]); 00164 thePionCM[iname][iene] = (Reference+Proton).M(); 00165 00166 } 00167 00168 } 00169 00170 // Find the index for which EN = 4. (or thereabout) 00171 ien4 = 0; 00172 while ( thePionEN[ien4] < 4.0 ) ++ien4; 00173 00174 // Return Loot in the same state as it was when entering. 00175 gROOT->cd(); 00176 00177 // Information (Should be on LogInfo) 00178 // std::cout << " ---> A total of " << fileNb 00179 // << " nuclear-interaction files was sucessfully open" << std::endl; 00180 00181 // dbe = edm::Service<DaqMonitorBEInterface>().operator->(); 00182 // htot = dbe->book1D("Total", "All particles",150,0.,150.); 00183 // helas = dbe->book1D("Elastic", "Elastic interactions",150,0.,150.); 00184 // hinel = dbe->book1D("Inelastic", "Inelastic interactions",150,0.,150.); 00185 // hscatter = dbe->book1D("Scattering","Elastic Scattering angle",200,0.,2.); 00186 // hscatter2 = dbe->book2D("Scattering2","Elastic Scattering angle vs p",100,0.,10.,200,0.,2.); 00187 // hAfter = dbe->book1D("eAfter","Energy after collision",200,0.,4.); 00188 // hAfter2 = dbe->book2D("eAfter2","Energy after collision",100,-2.5,2.5,100,0.,4); 00189 // hAfter3 = dbe->book2D("eAfter3","Energy after collision",100,0.,1000.,100,0.,4); 00190 00191 }
NuclearInteractionSimulator::~NuclearInteractionSimulator | ( | ) |
Default Destructor.
Definition at line 193 of file NuclearInteractionSimulator.cc.
References indexGen::ifile, myOutputFile, and theFiles.
00193 { 00194 00195 // Close all local files 00196 // Among other things, this allows the TROOT destructor to end up 00197 // without crashing, while trying to close these files from outside 00198 for ( unsigned ifile=0; ifile<theFiles.size(); ++ifile ) { 00199 for ( unsigned iene=0; iene<theFiles[ifile].size(); ++iene ) { 00200 // std::cout << "Closing file " << iene << " with name " << theFileNames[ifile][iene] << std::endl; 00201 theFiles[ifile][iene]->Close(); 00202 } 00203 } 00204 00205 // Close the output file 00206 myOutputFile.close(); 00207 00208 // And return Loot in the same state as it was when entering. 00209 gROOT->cd(); 00210 00211 // dbe->save("test.root"); 00212 00213 }
void NuclearInteractionSimulator::compute | ( | ParticlePropagator & | Particle | ) | [private, virtual] |
Generate a nuclear interaction according to the probability that it happens.
Implements MaterialEffectsSimulator.
Definition at line 215 of file NuclearInteractionSimulator.cc.
References MaterialEffectsSimulator::_theUpdatedState, funct::abs(), RawParticle::boost(), distanceToPrimary(), relval_parameters_module::energy, funct::exp(), NUEvent::NUInteraction::first, RandomEngine::flatShoot(), NUEvent::NUParticle::id, ien4, index(), NUEvent::NUInteraction::last, lastTrack, funct::log(), NUEvent::NUParticle::mass, RawParticle::mass(), MaterialEffectsSimulator::orthogonal(), phi, RawParticle::pid(), funct::pow(), NUEvent::NUParticle::px, NUEvent::NUParticle::py, NUEvent::NUParticle::pz, MaterialEffectsSimulator::radLengths, MaterialEffectsSimulator::random, RawParticle::rotate(), RawParticle::setID(), funct::sin(), slope, funct::sqrt(), MaterialEffectsSimulator::theA(), MaterialEffectsSimulator::theClosestChargedDaughterId, theCurrentEntry, theCurrentInteraction, theDistCut, theIDMap, theLengthRatio, theNUEvents, theNumberOfEntries, theNumberOfInteractions, thePionCM, thePionEnergy, thePionPMin, theRatios, theta, and theTrees.
00216 { 00217 00218 // Read a Nuclear Interaction in a random manner 00219 00220 double pHadron = std::sqrt(Particle.Vect().Mag2()); 00221 // htot->Fill(pHadron); 00222 00223 // The hadron has enough momentum to create some relevant final state 00224 if ( pHadron > thePionEnergy ) { 00225 00226 // The particle type 00227 std::map<int,int>::const_iterator thePit = theIDMap.find(Particle.pid()); 00228 00229 int thePid = thePit != theIDMap.end() ? thePit->second : Particle.pid(); 00230 00231 // Is this particle type foreseen? 00232 unsigned fPid = abs(thePid); 00233 if ( fPid != 211 && fPid != 130 && fPid != 321 && fPid != 2112 && fPid != 2212 ) { 00234 return; 00235 //std::cout << "Unknown particle type = " << thePid << std::endl; 00236 //thePid = 211; 00237 } 00238 00239 // The inelastic interaction length at p(pion) = 5 GeV/c 00240 unsigned thePidIndex = index(thePid); 00241 double theInelasticLength = radLengths * theLengthRatio[thePidIndex]; 00242 00243 // The elastic interaction length 00244 // The baroque parameterization is a fit to Fig. 40.13 of the PDG 00245 double ee = pHadron > 0.6 ? 00246 exp(-std::sqrt((pHadron-0.6)/1.122)) : exp(std::sqrt((0.6-pHadron)/1.122)); 00247 double theElasticLength = ( 0.8753 * ee + 0.15 ) 00248 // double theElasticLength = ( 0.15 + 0.195 / log(pHadron/0.4) ) 00249 // double theElasticLength = ( 0.15 + 0.305 / log(pHadron/0.35) ) 00250 * theInelasticLength; 00251 00252 // The total interaction length 00253 double theTotalInteractionLength = theInelasticLength + theElasticLength; 00254 00255 // Probability to interact is dl/L0 (maximum for 4 GeV pion) 00256 double aNuclInteraction = -std::log(random->flatShoot()); 00257 if ( aNuclInteraction < theTotalInteractionLength ) { 00258 00259 // The elastic part 00260 double elastic = random->flatShoot(); 00261 if ( elastic < theElasticLength/theTotalInteractionLength ) { 00262 00263 // helas->Fill(pHadron); 00264 00265 // Characteristic scattering angle for the elastic part 00266 double theta0 = std::sqrt(3.)/ std::pow(theA(),1./3.) * Particle.mass()/pHadron; 00267 00268 // Draw an angle with theta/theta0*exp[(-theta/2theta0)**2] shape 00269 double theta = theta0 * std::sqrt(-2.*std::log(random->flatShoot())); 00270 double phi = 2. * 3.14159265358979323 * random->flatShoot(); 00271 00272 // Rotate the particle accordingly 00273 RawParticle::Rotation rotation1(orthogonal(Particle.Vect()),theta); 00274 RawParticle::Rotation rotation2(Particle.Vect(),phi); 00275 Particle.rotate(rotation1); 00276 Particle.rotate(rotation2); 00277 00278 // Distance 00279 double distance = std::sin(theta); 00280 00281 // Create a daughter if the kink is large engough 00282 if ( distance > theDistCut ) { 00283 _theUpdatedState.resize(1); 00284 _theUpdatedState[0].SetXYZT(Particle.Px(), Particle.Py(), 00285 Particle.Pz(), Particle.E()); 00286 _theUpdatedState[0].setID(Particle.pid()); 00287 } 00288 00289 // hscatter->Fill(myTheta); 00290 // hscatter2->Fill(pHadron,myTheta); 00291 00292 } 00293 00294 // The inelastic part 00295 else { 00296 00297 // Avoid multiple map access 00298 const std::vector<double>& aPionCM = thePionCM[thePidIndex]; 00299 const std::vector<double>& aRatios = theRatios[thePidIndex]; 00300 // Find the file with the closest c.m energy 00301 // The target nucleon 00302 XYZTLorentzVector Proton(0.,0.,0.,0.939); 00303 // The current particle 00304 const XYZTLorentzVector& Hadron = (const XYZTLorentzVector&)Particle; 00305 // The smallest momentum for inelastic interactions 00306 double pMin = thePionPMin[thePidIndex]; 00307 // The correspong smallest four vector 00308 XYZTLorentzVector Hadron0(0.,0.,pMin,std::sqrt(pMin*pMin+Particle.M2())); 00309 00310 // The current centre-of-mass energy 00311 double ecm = (Proton+Hadron).M(); 00312 //std::cout << "Proton = " << Proton << std::endl; 00313 //std::cout << "Hadron = " << Hadron << std::endl; 00314 //std::cout << "ecm = " << ecm << std::endl; 00315 // Get the files of interest (closest c.m. energies) 00316 unsigned ene1=0; 00317 unsigned ene2=0; 00318 // The smallest centre-of-mass energy 00319 // double ecm1=1.63; 00320 double ecm1= (Proton+Hadron0).M(); 00321 //std::cout << "ecm1 = " << ecm1 << std::endl; 00322 //std::cout << "ecm[0] = " << aPionCM[0] << std::endl; 00323 //std::cout << "ecm[11] = " << aPionCM [ aPionCM.size()-1 ] << std::endl; 00324 double ecm2=aPionCM[0]; 00325 double ratio1=0.; 00326 double ratio2=aRatios[0]; 00327 if ( ecm > aPionCM[0] && ecm < aPionCM [ aPionCM.size()-1 ] ) { 00328 for ( unsigned ene=1; 00329 ene < aPionCM.size() && ecm > aPionCM[ene-1]; 00330 ++ene ) { 00331 if ( ecm<aPionCM[ene] ) { 00332 ene2 = ene; 00333 ene1 = ene2-1; 00334 ecm1 = aPionCM[ene1]; 00335 ecm2 = aPionCM[ene2]; 00336 ratio1 = aRatios[ene1]; 00337 ratio2 = aRatios[ene2]; 00338 } 00339 } 00340 } else if ( ecm > aPionCM[ aPionCM.size()-1 ] ) { 00341 ene1 = aPionCM.size()-1; 00342 ene2 = aPionCM.size()-2; 00343 ecm1 = aPionCM[ene1]; 00344 ecm2 = aPionCM[ene2]; 00345 ratio1 = aRatios[ene2]; 00346 ratio2 = aRatios[ene2]; 00347 } 00348 00349 00350 // The inelastic part of the cross section depends cm energy 00351 double slope = (std::log10(ecm )-std::log10(ecm1)) 00352 / (std::log10(ecm2)-std::log10(ecm1)); 00353 double inelastic = ratio1 + (ratio2-ratio1) * slope; 00354 double inelastic4 = pHadron < 4. ? aRatios[ien4] : 1.; 00355 00356 //std::cout << "Inelastic = " << ratio1 << " " << ratio2 << " " << inelastic << std::endl; 00357 // std::cout << "Energy/Inelastic : " 00358 // << Hadron.e() << " " << inelastic << std::endl; 00359 00360 // Simulate an inelastic interaction 00361 if ( elastic > 1.- (inelastic*theInelasticLength) 00362 /theTotalInteractionLength ) { 00363 00364 // Avoid mutliple map access 00365 std::vector<unsigned>& aCurrentInteraction = theCurrentInteraction[thePidIndex]; 00366 std::vector<unsigned>& aNumberOfInteractions = theNumberOfInteractions[thePidIndex]; 00367 std::vector<NUEvent*>& aNUEvents = theNUEvents[thePidIndex]; 00368 // hinel->Fill(pHadron); 00369 // std::cout << "INELASTIC INTERACTION ! " 00370 // << pHadron << " " << theInelasticLength << " " 00371 // << inelastic * theInelasticLength << std::endl; 00372 // Choice of the file to read according the the log10(ecm) distance 00373 // and protection against low momentum proton and neutron that never interacts 00374 // (i.e., empty files) 00375 unsigned ene; 00376 if ( random->flatShoot() < slope || aNumberOfInteractions[ene1] == 0 ) 00377 ene = ene2; 00378 else 00379 ene = ene1; 00380 00381 //std::cout << "Ecm1/2 = " << ecm1 << " " << ecm2 << std::endl; 00382 //std::cout << "Ratio1/2 = " << ratio1 << " " << ratio2 << std::endl; 00383 //std::cout << "Ene = " << ene << " slope = " << slope << std::endl; 00384 00385 //std::cout << "Pion energy = " << Hadron.E() 00386 // << "File chosen " << theFileNames[thePidIndex][ene] 00387 // << std::endl; 00388 00389 // The boost characteristics 00390 XYZTLorentzVector theBoost = Proton + Hadron; 00391 theBoost /= theBoost.e(); 00392 00393 // std::cout << "File chosen : " << thePid << "/" << ene 00394 // << " Current interaction = " << aCurrentInteraction[ene] 00395 // << " Total interactions = " << aNumberOfInteractions[ene] 00396 // << std::endl; 00397 // theFiles[thePidIndex][ene]->cd(); 00398 // gDirectory->ls(); 00399 00400 // Check we are not either at the end of an interaction bunch 00401 // or at the end of a file 00402 if ( aCurrentInteraction[ene] == aNumberOfInteractions[ene] ) { 00403 // std::cout << "End of interaction bunch ! "; 00404 std::vector<unsigned>& aCurrentEntry = theCurrentEntry[thePidIndex]; 00405 std::vector<unsigned>& aNumberOfEntries = theNumberOfEntries[thePidIndex]; 00406 std::vector<TTree*>& aTrees = theTrees[thePidIndex]; 00407 ++aCurrentEntry[ene]; 00408 // std::cerr << "Read the next entry " 00409 // << aCurrentEntry[ene] << std::endl; 00410 aCurrentInteraction[ene] = 0; 00411 if ( aCurrentEntry[ene] == aNumberOfEntries[ene] ) { 00412 aCurrentEntry[ene] = 0; 00413 // std::cout << "End of file - Rewind! " << std::endl; 00414 } 00415 unsigned myEntry = aCurrentEntry[ene]; 00416 // std::cout << "The new entry " << myEntry 00417 // << " is read ... in TTree " << aTrees[ene] << " "; 00418 aTrees[ene]->GetEntry(myEntry); 00419 // std::cout << "The number of interactions in the new entry is ... "; 00420 aNumberOfInteractions[ene] = aNUEvents[ene]->nInteractions(); 00421 // std::cout << aNumberOfInteractions[ene] << std::endl; 00422 } 00423 00424 // Read the interaction 00425 NUEvent::NUInteraction anInteraction 00426 = aNUEvents[ene]->theNUInteractions()[aCurrentInteraction[ene]]; 00427 00428 unsigned firstTrack = anInteraction.first; 00429 unsigned lastTrack = anInteraction.last; 00430 // std::cout << "First and last tracks are " << firstTrack << " " << lastTrack << std::endl; 00431 00432 _theUpdatedState.resize(lastTrack-firstTrack+1); 00433 00434 double distMin = 1E99; 00435 00436 // Some rotation around the boost axis, for more randomness 00437 XYZVector theAxis = theBoost.Vect().Unit(); 00438 double theAngle = random->flatShoot() * 2. * 3.14159265358979323; 00439 RawParticle::Rotation axisRotation(theAxis,theAngle); 00440 RawParticle::Boost axisBoost(theBoost.x(),theBoost.y(),theBoost.z()); 00441 00442 // A rotation to bring the particles back to the pion direction 00443 XYZVector zAxis(0.,0.,1.); 00444 XYZVector orthAxis = (zAxis.Cross(theBoost.Vect())).Unit(); 00445 double orthAngle = acos(theBoost.Vect().Unit().Z()); 00446 RawParticle::Rotation orthRotation(orthAxis,orthAngle); 00447 00448 // A few checks 00449 // double eAfter = 0.; 00450 00451 // Loop on the nuclear interaction products 00452 for ( unsigned iTrack=firstTrack; iTrack<=lastTrack; ++iTrack ) { 00453 00454 unsigned idaugh = iTrack - firstTrack; 00455 NUEvent::NUParticle aParticle = aNUEvents[ene]->theNUParticles()[iTrack]; 00456 // std::cout << "Track " << iTrack 00457 // << " id/px/py/pz/mass " 00458 // << aParticle.id << " " 00459 // << aParticle.px << " " 00460 // << aParticle.py << " " 00461 // << aParticle.pz << " " 00462 // << aParticle.mass << " " << endl; 00463 00464 // Add a RawParticle with the proper energy in the c.m frame of 00465 // the nuclear interaction 00466 double energy = std::sqrt( aParticle.px*aParticle.px 00467 + aParticle.py*aParticle.py 00468 + aParticle.pz*aParticle.pz 00469 + aParticle.mass*aParticle.mass/(ecm*ecm) ); 00470 00471 RawParticle& aDaughter = _theUpdatedState[idaugh]; 00472 aDaughter.SetXYZT(aParticle.px*ecm,aParticle.py*ecm, 00473 aParticle.pz*ecm,energy*ecm); 00474 aDaughter.setID(aParticle.id); 00475 00476 // Rotate to the collision axis 00477 aDaughter.rotate(orthRotation); 00478 00479 // Rotate around the boost axis for more randomness 00480 aDaughter.rotate(axisRotation); 00481 00482 // Boost it in the lab frame 00483 aDaughter.boost(axisBoost); 00484 00485 // Store the closest daughter index (for later tracking purposes, so charged particles only) 00486 double distance = distanceToPrimary(Particle,aDaughter); 00487 // Find the closest daughter, if closer than a given upper limit. 00488 if ( distance < distMin && distance < theDistCut ) { 00489 distMin = distance; 00490 theClosestChargedDaughterId = idaugh; 00491 } 00492 00493 // eAfter += aDaughter.E(); 00494 00495 } 00496 00497 /* 00498 double eBefore = Particle.E(); 00499 double rapid = Particle.momentum().Eta(); 00500 if ( eBefore > 0. ) { 00501 hAfter->Fill(eAfter/eBefore); 00502 hAfter2->Fill(rapid,eAfter/eBefore); 00503 hAfter3->Fill(eBefore,eAfter/eBefore); 00504 } 00505 */ 00506 00507 // Increment for next time 00508 ++aCurrentInteraction[ene]; 00509 00510 // Simulate a stopping hadron (low momentum) 00511 } else if ( pHadron < 4. && 00512 elastic > 1.- (inelastic4*theInelasticLength) 00513 /theTotalInteractionLength ) { 00514 // A fake particle with 0 momentum as a daughter! 00515 _theUpdatedState.resize(1); 00516 _theUpdatedState[0].SetXYZT(0.,0.,0.,0.); 00517 _theUpdatedState[0].setID(22); 00518 } 00519 00520 } 00521 00522 } 00523 00524 } 00525 00526 }
double NuclearInteractionSimulator::distanceToPrimary | ( | const RawParticle & | Particle, | |
const RawParticle & | aDaughter | |||
) | const [private] |
Compute distance between secondary and primary.
Definition at line 529 of file NuclearInteractionSimulator.cc.
References RawParticle::charge(), and theDistAlgo.
Referenced by compute().
00530 { 00531 00532 double distance = 2E99; 00533 00534 // Compute the distance only for charged primaries 00535 if ( fabs(Particle.charge()) > 1E-12 ) { 00536 00537 // The secondary must have the same charge 00538 double chargeDiff = fabs(aDaughter.charge()-Particle.charge()); 00539 if ( fabs(chargeDiff) < 1E-12 ) { 00540 00541 // Here are two distance definitions * to be tuned * 00542 switch ( theDistAlgo ) { 00543 00544 case 1: 00545 // sin(theta12) 00546 distance = (aDaughter.Vect().Unit().Cross(Particle.Vect().Unit())).R(); 00547 break; 00548 00549 case 2: 00550 // sin(theta12) * p1/p2 00551 distance = (aDaughter.Vect().Cross(Particle.Vect())).R() 00552 /aDaughter.Vect().Mag2(); 00553 break; 00554 00555 default: 00556 // Should not happen 00557 distance = 2E99; 00558 break; 00559 00560 } 00561 00562 } 00563 00564 } 00565 00566 return distance; 00567 00568 }
unsigned NuclearInteractionSimulator::index | ( | int | thePid | ) | [private] |
Return a hashed index for a given pid.
Definition at line 688 of file NuclearInteractionSimulator.cc.
References thePionID.
Referenced by compute().
00688 { 00689 00690 unsigned myIndex=0; 00691 while ( thePid != thePionID[myIndex] ) ++myIndex; 00692 // std::cout << "pid/index = " << thePid << " " << myIndex << std::endl; 00693 return myIndex; 00694 00695 }
bool NuclearInteractionSimulator::read | ( | std::string | inputFile | ) |
Read former nuclear interaction (from previous run).
Definition at line 624 of file NuclearInteractionSimulator.cc.
References size, theCurrentEntry, and theCurrentInteraction.
Referenced by NuclearInteractionSimulator().
00624 { 00625 00626 ifstream myInputFile; 00627 struct stat results; 00628 // 00629 unsigned size1 = 00630 theCurrentEntry.size()* 00631 theCurrentEntry.begin()->size(); 00632 std::vector<unsigned> theCurrentEntries; 00633 theCurrentEntries.resize(size1); 00634 size1*=sizeof(unsigned); 00635 // 00636 unsigned size2 = 00637 theCurrentInteraction.size()* 00638 theCurrentInteraction.begin()->size(); 00639 std::vector<unsigned> theCurrentInteractions; 00640 theCurrentInteractions.resize(size2); 00641 size2 *= sizeof(unsigned); 00642 // 00643 unsigned size = 0; 00644 00645 00646 // Open the file (if any) 00647 myInputFile.open (inputFile.c_str()); 00648 if ( myInputFile.is_open() ) { 00649 00650 // Get the size of the file 00651 if ( stat(inputFile.c_str(), &results) == 0 ) size = results.st_size; 00652 else return false; // Something is wrong with that file ! 00653 00654 // Position the pointer just before the last record 00655 myInputFile.seekg(size-size1-size2); 00656 myInputFile.read((char*)(&theCurrentEntries.front()),size1); 00657 myInputFile.read((char*)(&theCurrentInteractions.front()),size2); 00658 myInputFile.close(); 00659 00660 // Read the current entries 00661 std::vector< std::vector<unsigned> >::iterator aCurrentEntry = theCurrentEntry.begin(); 00662 std::vector< std::vector<unsigned> >::iterator lastCurrentEntry = theCurrentEntry.end(); 00663 unsigned allEntries=0; 00664 for ( ; aCurrentEntry!=lastCurrentEntry; ++aCurrentEntry ) { 00665 unsigned size = aCurrentEntry->size(); 00666 for ( unsigned iene=0; iene<size; ++iene ) 00667 (*aCurrentEntry)[iene] = theCurrentEntries[allEntries++]; 00668 } 00669 00670 // Read the current interactions 00671 std::vector< std::vector<unsigned> >::iterator aCurrentInteraction = theCurrentInteraction.begin(); 00672 std::vector< std::vector<unsigned> >::iterator lastCurrentInteraction = theCurrentInteraction.end(); 00673 unsigned allInteractions=0; 00674 for ( ; aCurrentInteraction!=lastCurrentInteraction; ++aCurrentInteraction ) { 00675 unsigned size = aCurrentInteraction->size(); 00676 for ( unsigned iene=0; iene<size; ++iene ) 00677 (*aCurrentInteraction)[iene] = theCurrentInteractions[allInteractions++]; 00678 } 00679 00680 return true; 00681 } 00682 00683 return false; 00684 00685 }
void NuclearInteractionSimulator::save | ( | ) |
Save current nuclear interaction (for later use).
Definition at line 571 of file NuclearInteractionSimulator.cc.
References myOutputBuffer, myOutputFile, size, theCurrentEntry, and theCurrentInteraction.
Referenced by MaterialEffects::save().
00571 { 00572 00573 // Size of buffer 00574 ++myOutputBuffer; 00575 00576 // Periodically close the current file and open a new one 00577 if ( myOutputBuffer/1000*1000 == myOutputBuffer ) { 00578 myOutputFile.close(); 00579 myOutputFile.open ("NuclearInteractionOutputFile.txt"); 00580 // myOutputFile.seekp(0); // No need to rewind in that case 00581 } 00582 // 00583 unsigned size1 = 00584 theCurrentEntry.size()* 00585 theCurrentEntry.begin()->size(); 00586 std::vector<unsigned> theCurrentEntries; 00587 theCurrentEntries.resize(size1); 00588 size1*=sizeof(unsigned); 00589 // 00590 unsigned size2 = 00591 theCurrentInteraction.size()* 00592 theCurrentInteraction.begin()->size(); 00593 std::vector<unsigned> theCurrentInteractions; 00594 theCurrentInteractions.resize(size2); 00595 size2 *= sizeof(unsigned); 00596 00597 // Save the current entries 00598 std::vector< std::vector<unsigned> >::const_iterator aCurrentEntry = theCurrentEntry.begin(); 00599 std::vector< std::vector<unsigned> >::const_iterator lastCurrentEntry = theCurrentEntry.end(); 00600 unsigned allEntries=0; 00601 for ( ; aCurrentEntry!=lastCurrentEntry; ++aCurrentEntry ) { 00602 unsigned size = aCurrentEntry->size(); 00603 for ( unsigned iene=0; iene<size; ++iene ) 00604 theCurrentEntries[allEntries++] = (*aCurrentEntry)[iene]; 00605 } 00606 00607 // Save the current interactions 00608 std::vector< std::vector<unsigned> >::const_iterator aCurrentInteraction = theCurrentInteraction.begin(); 00609 std::vector< std::vector<unsigned> >::const_iterator lastCurrentInteraction = theCurrentInteraction.end(); 00610 unsigned allInteractions=0; 00611 for ( ; aCurrentInteraction!=lastCurrentInteraction; ++aCurrentInteraction ) { 00612 unsigned size = aCurrentInteraction->size(); 00613 for ( unsigned iene=0; iene<size; ++iene ) 00614 theCurrentInteractions[allInteractions++] = (*aCurrentInteraction)[iene]; 00615 } 00616 // 00617 myOutputFile.write((const char*)(&theCurrentEntries.front()), size1); 00618 myOutputFile.write((const char*)(&theCurrentInteractions.front()), size2); 00619 myOutputFile.flush(); 00620 00621 }
unsigned NuclearInteractionSimulator::ien4 [private] |
Definition at line 94 of file NuclearInteractionSimulator.h.
Referenced by compute(), and NuclearInteractionSimulator().
unsigned NuclearInteractionSimulator::myOutputBuffer [private] |
Definition at line 99 of file NuclearInteractionSimulator.h.
Referenced by NuclearInteractionSimulator(), and save().
std::ofstream NuclearInteractionSimulator::myOutputFile [private] |
Definition at line 98 of file NuclearInteractionSimulator.h.
Referenced by NuclearInteractionSimulator(), save(), and ~NuclearInteractionSimulator().
std::vector< std::vector<TBranch*> > NuclearInteractionSimulator::theBranches [private] |
Definition at line 84 of file NuclearInteractionSimulator.h.
Referenced by NuclearInteractionSimulator().
std::vector< std::vector<unsigned> > NuclearInteractionSimulator::theCurrentEntry [private] |
Definition at line 86 of file NuclearInteractionSimulator.h.
Referenced by compute(), NuclearInteractionSimulator(), read(), and save().
std::vector< std::vector<unsigned> > NuclearInteractionSimulator::theCurrentInteraction [private] |
Definition at line 87 of file NuclearInteractionSimulator.h.
Referenced by compute(), NuclearInteractionSimulator(), read(), and save().
unsigned NuclearInteractionSimulator::theDistAlgo [private] |
double NuclearInteractionSimulator::theDistCut [private] |
std::vector< std::vector<std::string> > NuclearInteractionSimulator::theFileNames [private] |
Definition at line 90 of file NuclearInteractionSimulator.h.
Referenced by NuclearInteractionSimulator().
std::vector< std::vector<TFile*> > NuclearInteractionSimulator::theFiles [private] |
Definition at line 82 of file NuclearInteractionSimulator.h.
Referenced by NuclearInteractionSimulator(), and ~NuclearInteractionSimulator().
std::map< int, int > NuclearInteractionSimulator::theIDMap [private] |
std::vector<double> NuclearInteractionSimulator::theLengthRatio [private] |
std::vector< std::vector<NUEvent*> > NuclearInteractionSimulator::theNUEvents [private] |
Definition at line 85 of file NuclearInteractionSimulator.h.
Referenced by compute(), and NuclearInteractionSimulator().
std::vector< std::vector<unsigned> > NuclearInteractionSimulator::theNumberOfEntries [private] |
Definition at line 88 of file NuclearInteractionSimulator.h.
Referenced by compute(), and NuclearInteractionSimulator().
std::vector< std::vector<unsigned> > NuclearInteractionSimulator::theNumberOfInteractions [private] |
Definition at line 89 of file NuclearInteractionSimulator.h.
Referenced by compute(), and NuclearInteractionSimulator().
std::vector< std::vector<double> > NuclearInteractionSimulator::thePionCM [private] |
Definition at line 91 of file NuclearInteractionSimulator.h.
Referenced by compute(), and NuclearInteractionSimulator().
std::vector<double> NuclearInteractionSimulator::thePionEN [private] |
Definition at line 73 of file NuclearInteractionSimulator.h.
Referenced by NuclearInteractionSimulator().
double NuclearInteractionSimulator::thePionEnergy [private] |
std::vector<int> NuclearInteractionSimulator::thePionID [private] |
std::vector<double> NuclearInteractionSimulator::thePionMA [private] |
Definition at line 76 of file NuclearInteractionSimulator.h.
Referenced by NuclearInteractionSimulator().
std::vector<std::string> NuclearInteractionSimulator::thePionNA [private] |
Definition at line 75 of file NuclearInteractionSimulator.h.
Referenced by NuclearInteractionSimulator().
std::vector<double> NuclearInteractionSimulator::thePionPMin [private] |
std::vector< std::vector<double> > NuclearInteractionSimulator::theRatios [private] |
std::vector< std::vector<TTree*> > NuclearInteractionSimulator::theTrees [private] |
Definition at line 83 of file NuclearInteractionSimulator.h.
Referenced by compute(), and NuclearInteractionSimulator().