CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
List of all members | Public Member Functions | Private Member Functions | Private Attributes
NuclearInteractionSimulator Class Reference

#include <NuclearInteractionSimulator.h>

Inheritance diagram for NuclearInteractionSimulator:
MaterialEffectsSimulator

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)
 Constructor. More...
 
bool read (std::string inputFile)
 Read former nuclear interaction (from previous run) More...
 
void save ()
 Save current nuclear interaction (for later use) More...
 
 ~NuclearInteractionSimulator ()
 Default Destructor. More...
 
- Public Member Functions inherited from MaterialEffectsSimulator
RHEP_const_iter beginDaughters () const
 Returns const iterator to the beginning of the daughters list. More...
 
int closestDaughterId ()
 The id of the closest charged daughter (filled for nuclear interactions only) More...
 
double eMass () const
 Electron mass in GeV/c2. More...
 
RHEP_const_iter endDaughters () const
 Returns const iterator to the end of the daughters list. More...
 
double excitE () const
 Mean excitation energy (in GeV) More...
 
 MaterialEffectsSimulator (double A=28.0855, double Z=14.0000, double density=2.329, double radLen=9.360)
 
unsigned nDaughters () const
 Returns the number of daughters. More...
 
XYZVector orthogonal (const XYZVector &) const
 A vector orthogonal to another one (because it's not in XYZTLorentzVector) More...
 
double radLenIncm () const
 One radiation length in cm. More...
 
double rho () const
 Density in g/cm3. More...
 
void setNormalVector (const GlobalVector &normal)
 Sets the vector normal to the surface traversed. More...
 
double theA () const
 A. More...
 
double theZ () const
 Z. More...
 
void updateState (ParticlePropagator &myTrack, double radlen, RandomEngineAndDistribution const *)
 Compute the material effect (calls the sub class) More...
 
virtual ~MaterialEffectsSimulator ()
 

Private Member Functions

void compute (ParticlePropagator &Particle, RandomEngineAndDistribution const *)
 Generate a nuclear interaction according to the probability that it happens. More...
 
double distanceToPrimary (const RawParticle &Particle, const RawParticle &aDaughter) const
 Compute distance between secondary and primary. More...
 
unsigned index (int thePid)
 Return a hashed index for a given pid. More...
 

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
 

Additional Inherited Members

- Public Types inherited from MaterialEffectsSimulator
typedef std::vector
< RawParticle >
::const_iterator 
RHEP_const_iter
 
- Protected Attributes inherited from MaterialEffectsSimulator
std::vector< RawParticle_theUpdatedState
 
double A
 
double density
 
double radLen
 
double radLengths
 
int theClosestChargedDaughterId
 
GlobalVector theNormalVector
 
double Z
 

Detailed Description

Definition at line 33 of file NuclearInteractionSimulator.h.

Constructor & Destructor Documentation

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 
)

Constructor.

Definition at line 20 of file NuclearInteractionSimulator.cc.

References gather_cfg::cout, edm::hlt::Exception, lut2db_cfg::filename, RandomEngineAndDistribution::flatShoot(), edm::FileInPath::fullPath(), ien4, input, myOutputBuffer, myOutputFile, random, read(), mathSSE::sqrt(), AlCaHLTBitMon_QueryRunRegistry::string, theBranches, theCurrentEntry, theCurrentInteraction, theFileNames, theFiles, theNUEvents, theNumberOfEntries, theNumberOfInteractions, thePionCM, thePionEN, thePionMA, thePionNA, and theTrees.

33  :
35  thePionEN(pionEnergies),
36  thePionID(pionTypes),
37  thePionNA(pionNames),
38  thePionMA(pionMasses),
39  thePionPMin(pionPMin),
40  thePionEnergy(pionEnergy),
41  theLengthRatio(lengthRatio),
43  theIDMap(idMap),
44  theDistAlgo(distAlgo),
45  theDistCut(distCut)
46 
47 {
48 
49  gROOT->cd();
50 
51  std::string fullPath;
52 
53  // Prepare the map of files
54  // Loop over the particle names
55  std::vector<TFile*> aVFile(thePionEN.size(),static_cast<TFile*>(0));
56  std::vector<TTree*> aVTree(thePionEN.size(),static_cast<TTree*>(0));
57  std::vector<TBranch*> aVBranch(thePionEN.size(),static_cast<TBranch*>(0));
58  std::vector<NUEvent*> aVNUEvents(thePionEN.size(),static_cast<NUEvent*>(0));
59  std::vector<unsigned> aVCurrentEntry(thePionEN.size(),static_cast<unsigned>(0));
60  std::vector<unsigned> aVCurrentInteraction(thePionEN.size(),static_cast<unsigned>(0));
61  std::vector<unsigned> aVNumberOfEntries(thePionEN.size(),static_cast<unsigned>(0));
62  std::vector<unsigned> aVNumberOfInteractions(thePionEN.size(),static_cast<unsigned>(0));
63  std::vector<std::string> aVFileName(thePionEN.size(),static_cast<std::string>(""));
64  std::vector<double> aVPionCM(thePionEN.size(),static_cast<double>(0));
65  theFiles.resize(thePionNA.size());
66  theTrees.resize(thePionNA.size());
67  theBranches.resize(thePionNA.size());
68  theNUEvents.resize(thePionNA.size());
69  theCurrentEntry.resize(thePionNA.size());
70  theCurrentInteraction.resize(thePionNA.size());
71  theNumberOfEntries.resize(thePionNA.size());
72  theNumberOfInteractions.resize(thePionNA.size());
73  theFileNames.resize(thePionNA.size());
74  thePionCM.resize(thePionNA.size());
75  for ( unsigned iname=0; iname<thePionNA.size(); ++iname ) {
76  theFiles[iname] = aVFile;
77  theTrees[iname] = aVTree;
78  theBranches[iname] = aVBranch;
79  theNUEvents[iname] = aVNUEvents;
80  theCurrentEntry[iname] = aVCurrentEntry;
81  theCurrentInteraction[iname] = aVCurrentInteraction;
82  theNumberOfEntries[iname] = aVNumberOfEntries;
83  theNumberOfInteractions[iname] = aVNumberOfInteractions;
84  theFileNames[iname] = aVFileName;
85  thePionCM[iname] = aVPionCM;
86  }
87 
88  // Read the information from a previous run (to keep reproducibility)
89  bool input = this->read(inputFile);
90  if ( input )
91  std::cout << "***WARNING*** You are reading nuclear-interaction information from the file "
92  << inputFile << " created in an earlier run."
93  << std::endl;
94 
95  // Open the file for saving the information of the current run
96  myOutputFile.open ("NuclearInteractionOutputFile.txt");
97  myOutputBuffer = 0;
98 
99 
100  // Open the root files
101  // for ( unsigned file=0; file<theFileNames.size(); ++file ) {
102  unsigned fileNb = 0;
103  for ( unsigned iname=0; iname<thePionNA.size(); ++iname ) {
104  for ( unsigned iene=0; iene<thePionEN.size(); ++iene ) {
105  //std::cout << "iname/iene " << iname << " " << iene << std::endl;
106  std::ostringstream filename;
107  double theEne = thePionEN[iene];
108  filename << "NuclearInteractionsVal_" << thePionNA[iname] << "_E"<< theEne << ".root";
109  theFileNames[iname][iene] = filename.str();
110  //std::cout << "thePid/theEne " << thePionID[iname] << " " << theEne << std::endl;
111 
112  edm::FileInPath myDataFile("FastSimulation/MaterialEffects/data/"+theFileNames[iname][iene]);
113  fullPath = myDataFile.fullPath();
114  // theFiles[file] = TFile::Open(theFileNames[file].c_str());
115  theFiles[iname][iene] = TFile::Open(fullPath.c_str());
116  if ( !theFiles[iname][iene] ) throw cms::Exception("FastSimulation/MaterialEffects")
117  << "File " << theFileNames[iname][iene] << " " << fullPath << " not found ";
118  ++fileNb;
119  //
120  theTrees[iname][iene] = (TTree*) theFiles[iname][iene]->Get("NuclearInteractions");
121  if ( !theTrees[iname][iene] ) throw cms::Exception("FastSimulation/MaterialEffects")
122  << "Tree with name NuclearInteractions not found in " << theFileNames[iname][iene];
123  //
124  theBranches[iname][iene] = theTrees[iname][iene]->GetBranch("nuEvent");
125  //std::cout << "The branch = " << theBranches[iname][iene] << std::endl;
126  if ( !theBranches[iname][iene] ) throw cms::Exception("FastSimulation/MaterialEffects")
127  << "Branch with name nuEvent not found in " << theFileNames[iname][iene];
128  //
129  theNUEvents[iname][iene] = new NUEvent();
130  //std::cout << "The branch = " << theBranches[iname][iene] << std::endl;
131  theBranches[iname][iene]->SetAddress(&theNUEvents[iname][iene]);
132  //
133  theNumberOfEntries[iname][iene] = theTrees[iname][iene]->GetEntries();
134 
135  // Add some randomness (if there was no input file)
136  if ( !input ) {
137  // RANDOM_NUMBER_ERROR
138  // Random numbers should only be generated in the beginLuminosityBlock method
139  // or event methods of a module
141  theCurrentEntry[iname][iene] = (unsigned) (theNumberOfEntries[iname][iene] * random.flatShoot());
142  }
143  theTrees[iname][iene]->GetEntry(theCurrentEntry[iname][iene]);
144  unsigned NInteractions = theNUEvents[iname][iene]->nInteractions();
145  theNumberOfInteractions[iname][iene] = NInteractions;
146  // Add some randomness (if there was no input file)
147  if ( !input ) {
148  // RANDOM_NUMBER_ERROR
149  // Random numbers should only be generated in the beginLuminosityBlock method
150  // or event methods of a module
152  theCurrentInteraction[iname][iene] = (unsigned) (theNumberOfInteractions[iname][iene] * random.flatShoot());
153  }
154  /*
155  std::cout << "File " << theFileNames[iname][iene]
156  << " is opened with " << theNumberOfEntries[iname][iene]
157  << " entries and will be read from Entry/Interaction "
158  << theCurrentEntry[iname][iene] << "/" << theCurrentInteraction[iname][iene]
159  << std::endl;
160  */
161 
162  //
163  // Compute the corresponding cm energies of the nuclear interactions
164  XYZTLorentzVector Proton(0.,0.,0.,0.986);
166  Reference(0.,
167  0.,
168  std::sqrt(thePionEN[iene]*thePionEN[iene]
169  -thePionMA[iname]*thePionMA[iname]),
170  thePionEN[iene]);
171  thePionCM[iname][iene] = (Reference+Proton).M();
172 
173  }
174 
175  }
176 
177  // Find the index for which EN = 4. (or thereabout)
178  ien4 = 0;
179  while ( thePionEN[ien4] < 4.0 ) ++ien4;
180 
181  // Return Loot in the same state as it was when entering.
182  gROOT->cd();
183 
184  // Information (Should be on LogInfo)
185 // std::cout << " ---> A total of " << fileNb
186 // << " nuclear-interaction files was sucessfully open" << std::endl;
187 
188  // dbe = edm::Service<DaqMonitorBEInterface>().operator->();
189  // htot = dbe->book1D("Total", "All particles",150,0.,150.);
190  // helas = dbe->book1D("Elastic", "Elastic interactions",150,0.,150.);
191  // hinel = dbe->book1D("Inelastic", "Inelastic interactions",150,0.,150.);
192  // hscatter = dbe->book1D("Scattering","Elastic Scattering angle",200,0.,2.);
193  // hscatter2 = dbe->book2D("Scattering2","Elastic Scattering angle vs p",100,0.,10.,200,0.,2.);
194  // hAfter = dbe->book1D("eAfter","Energy after collision",200,0.,4.);
195  // hAfter2 = dbe->book2D("eAfter2","Energy after collision",100,-2.5,2.5,100,0.,4);
196  // hAfter3 = dbe->book2D("eAfter3","Energy after collision",100,0.,1000.,100,0.,4);
197 
198 }
double flatShoot(double xmin=0.0, double xmax=1.0) const
dictionary ratios
Definition: plotFactory.py:68
std::vector< std::vector< TFile * > > theFiles
std::vector< std::vector< unsigned > > theNumberOfInteractions
std::vector< std::vector< TTree * > > theTrees
TRandom random
Definition: MVATrainer.cc:138
std::vector< std::vector< unsigned > > theCurrentEntry
static std::string const input
Definition: EdmProvDump.cc:44
std::vector< std::vector< std::string > > theFileNames
Definition: NUEvent.h:6
std::vector< std::vector< unsigned > > theNumberOfEntries
T sqrt(T t)
Definition: SSEVec.h:48
MaterialEffectsSimulator(double A=28.0855, double Z=14.0000, double density=2.329, double radLen=9.360)
std::vector< std::vector< double > > thePionCM
bool read(std::string inputFile)
Read former nuclear interaction (from previous run)
std::vector< std::string > thePionNA
std::vector< std::vector< TBranch * > > theBranches
std::vector< std::vector< unsigned > > theCurrentInteraction
std::vector< std::vector< double > > theRatios
tuple filename
Definition: lut2db_cfg.py:20
tuple cout
Definition: gather_cfg.py:121
std::vector< std::vector< NUEvent * > > theNUEvents
math::XYZTLorentzVector XYZTLorentzVector
Definition: RawParticle.h:15
NuclearInteractionSimulator::~NuclearInteractionSimulator ( )

Default Destructor.

Definition at line 200 of file NuclearInteractionSimulator.cc.

References compare_using_db::ifile, myOutputFile, and theFiles.

200  {
201 
202  // Close all local files
203  // Among other things, this allows the TROOT destructor to end up
204  // without crashing, while trying to close these files from outside
205  for ( unsigned ifile=0; ifile<theFiles.size(); ++ifile ) {
206  for ( unsigned iene=0; iene<theFiles[ifile].size(); ++iene ) {
207  // std::cout << "Closing file " << iene << " with name " << theFileNames[ifile][iene] << std::endl;
208  theFiles[ifile][iene]->Close();
209  }
210  }
211 
212  // Close the output file
213  myOutputFile.close();
214 
215  // And return Loot in the same state as it was when entering.
216  gROOT->cd();
217 
218  // dbe->save("test.root");
219 
220 }
std::vector< std::vector< TFile * > > theFiles

Member Function Documentation

void NuclearInteractionSimulator::compute ( ParticlePropagator Particle,
RandomEngineAndDistribution const *  random 
)
privatevirtual

Generate a nuclear interaction according to the probability that it happens.

Implements MaterialEffectsSimulator.

Definition at line 222 of file NuclearInteractionSimulator.cc.

References MaterialEffectsSimulator::_theUpdatedState, funct::abs(), RawParticle::boost(), distanceToPrimary(), relval_parameters_module::energy, create_public_lumi_plots::exp, NUEvent::NUInteraction::first, RandomEngineAndDistribution::flatShoot(), NUEvent::NUParticle::id, ien4, index(), NUEvent::NUInteraction::last, create_public_lumi_plots::log, NUEvent::NUParticle::mass, RawParticle::mass(), MaterialEffectsSimulator::orthogonal(), phi, RawParticle::pid(), funct::pow(), NUEvent::NUParticle::px, NUEvent::NUParticle::py, NUEvent::NUParticle::pz, MaterialEffectsSimulator::radLengths, RawParticle::rotate(), RawParticle::setID(), funct::sin(), slope, mathSSE::sqrt(), MaterialEffectsSimulator::theA(), MaterialEffectsSimulator::theClosestChargedDaughterId, theCurrentEntry, theCurrentInteraction, theDistCut, theIDMap, theLengthRatio, theNUEvents, theNumberOfEntries, theNumberOfInteractions, thePionCM, thePionEnergy, thePionPMin, theRatios, theta(), and theTrees.

223 {
224 
225  // Read a Nuclear Interaction in a random manner
226 
227  double pHadron = std::sqrt(Particle.Vect().Mag2());
228  // htot->Fill(pHadron);
229 
230  // The hadron has enough momentum to create some relevant final state
231  if ( pHadron > thePionEnergy ) {
232 
233  // The particle type
234  std::map<int,int>::const_iterator thePit = theIDMap.find(Particle.pid());
235 
236  int thePid = thePit != theIDMap.end() ? thePit->second : Particle.pid();
237 
238  // Is this particle type foreseen?
239  unsigned fPid = abs(thePid);
240  if ( fPid != 211 && fPid != 130 && fPid != 321 && fPid != 2112 && fPid != 2212 ) {
241  return;
242  //std::cout << "Unknown particle type = " << thePid << std::endl;
243  //thePid = 211;
244  }
245 
246  // The inelastic interaction length at p(pion) = 5 GeV/c
247  unsigned thePidIndex = index(thePid);
248  double theInelasticLength = radLengths * theLengthRatio[thePidIndex];
249 
250  // The elastic interaction length
251  // The baroque parameterization is a fit to Fig. 40.13 of the PDG
252  double ee = pHadron > 0.6 ?
253  exp(-std::sqrt((pHadron-0.6)/1.122)) : exp(std::sqrt((0.6-pHadron)/1.122));
254  double theElasticLength = ( 0.8753 * ee + 0.15 )
255  // double theElasticLength = ( 0.15 + 0.195 / log(pHadron/0.4) )
256  // double theElasticLength = ( 0.15 + 0.305 / log(pHadron/0.35) )
257  * theInelasticLength;
258 
259  // The total interaction length
260  double theTotalInteractionLength = theInelasticLength + theElasticLength;
261 
262  // Probability to interact is dl/L0 (maximum for 4 GeV pion)
263  double aNuclInteraction = -std::log(random->flatShoot());
264  if ( aNuclInteraction < theTotalInteractionLength ) {
265 
266  // The elastic part
267  double elastic = random->flatShoot();
268  if ( elastic < theElasticLength/theTotalInteractionLength ) {
269 
270  // helas->Fill(pHadron);
271 
272  // Characteristic scattering angle for the elastic part
273  double theta0 = std::sqrt(3.)/ std::pow(theA(),1./3.) * Particle.mass()/pHadron;
274 
275  // Draw an angle with theta/theta0*exp[(-theta/2theta0)**2] shape
276  double theta = theta0 * std::sqrt(-2.*std::log(random->flatShoot()));
277  double phi = 2. * 3.14159265358979323 * random->flatShoot();
278 
279  // Rotate the particle accordingly
280  RawParticle::Rotation rotation1(orthogonal(Particle.Vect()),theta);
281  RawParticle::Rotation rotation2(Particle.Vect(),phi);
282  Particle.rotate(rotation1);
283  Particle.rotate(rotation2);
284 
285  // Distance
286  double distance = std::sin(theta);
287 
288  // Create a daughter if the kink is large engough
289  if ( distance > theDistCut ) {
290  _theUpdatedState.resize(1);
291  _theUpdatedState[0].SetXYZT(Particle.Px(), Particle.Py(),
292  Particle.Pz(), Particle.E());
293  _theUpdatedState[0].setID(Particle.pid());
294  }
295 
296  // hscatter->Fill(myTheta);
297  // hscatter2->Fill(pHadron,myTheta);
298 
299  }
300 
301  // The inelastic part
302  else {
303 
304  // Avoid multiple map access
305  const std::vector<double>& aPionCM = thePionCM[thePidIndex];
306  const std::vector<double>& aRatios = theRatios[thePidIndex];
307  // Find the file with the closest c.m energy
308  // The target nucleon
309  XYZTLorentzVector Proton(0.,0.,0.,0.939);
310  // The current particle
311  const XYZTLorentzVector& Hadron = (const XYZTLorentzVector&)Particle;
312  // The smallest momentum for inelastic interactions
313  double pMin = thePionPMin[thePidIndex];
314  // The correspong smallest four vector
315  XYZTLorentzVector Hadron0(0.,0.,pMin,std::sqrt(pMin*pMin+Particle.M2()));
316 
317  // The current centre-of-mass energy
318  double ecm = (Proton+Hadron).M();
319  //std::cout << "Proton = " << Proton << std::endl;
320  //std::cout << "Hadron = " << Hadron << std::endl;
321  //std::cout << "ecm = " << ecm << std::endl;
322  // Get the files of interest (closest c.m. energies)
323  unsigned ene1=0;
324  unsigned ene2=0;
325  // The smallest centre-of-mass energy
326  // double ecm1=1.63;
327  double ecm1= (Proton+Hadron0).M();
328  //std::cout << "ecm1 = " << ecm1 << std::endl;
329  //std::cout << "ecm[0] = " << aPionCM[0] << std::endl;
330  //std::cout << "ecm[11] = " << aPionCM [ aPionCM.size()-1 ] << std::endl;
331  double ecm2=aPionCM[0];
332  double ratio1=0.;
333  double ratio2=aRatios[0];
334  if ( ecm > aPionCM[0] && ecm < aPionCM [ aPionCM.size()-1 ] ) {
335  for ( unsigned ene=1;
336  ene < aPionCM.size() && ecm > aPionCM[ene-1];
337  ++ene ) {
338  if ( ecm<aPionCM[ene] ) {
339  ene2 = ene;
340  ene1 = ene2-1;
341  ecm1 = aPionCM[ene1];
342  ecm2 = aPionCM[ene2];
343  ratio1 = aRatios[ene1];
344  ratio2 = aRatios[ene2];
345  }
346  }
347  } else if ( ecm > aPionCM[ aPionCM.size()-1 ] ) {
348  ene1 = aPionCM.size()-1;
349  ene2 = aPionCM.size()-2;
350  ecm1 = aPionCM[ene1];
351  ecm2 = aPionCM[ene2];
352  ratio1 = aRatios[ene2];
353  ratio2 = aRatios[ene2];
354  }
355 
356 
357  // The inelastic part of the cross section depends cm energy
358  double slope = (std::log10(ecm )-std::log10(ecm1))
359  / (std::log10(ecm2)-std::log10(ecm1));
360  double inelastic = ratio1 + (ratio2-ratio1) * slope;
361  double inelastic4 = pHadron < 4. ? aRatios[ien4] : 1.;
362 
363  //std::cout << "Inelastic = " << ratio1 << " " << ratio2 << " " << inelastic << std::endl;
364  // std::cout << "Energy/Inelastic : "
365  // << Hadron.e() << " " << inelastic << std::endl;
366 
367  // Simulate an inelastic interaction
368  if ( elastic > 1.- (inelastic*theInelasticLength)
369  /theTotalInteractionLength ) {
370 
371  // Avoid mutliple map access
372  std::vector<unsigned>& aCurrentInteraction = theCurrentInteraction[thePidIndex];
373  std::vector<unsigned>& aNumberOfInteractions = theNumberOfInteractions[thePidIndex];
374  std::vector<NUEvent*>& aNUEvents = theNUEvents[thePidIndex];
375  // hinel->Fill(pHadron);
376  // std::cout << "INELASTIC INTERACTION ! "
377  // << pHadron << " " << theInelasticLength << " "
378  // << inelastic * theInelasticLength << std::endl;
379  // Choice of the file to read according the the log10(ecm) distance
380  // and protection against low momentum proton and neutron that never interacts
381  // (i.e., empty files)
382  unsigned ene;
383  if ( random->flatShoot() < slope || aNumberOfInteractions[ene1] == 0 )
384  ene = ene2;
385  else
386  ene = ene1;
387 
388  //std::cout << "Ecm1/2 = " << ecm1 << " " << ecm2 << std::endl;
389  //std::cout << "Ratio1/2 = " << ratio1 << " " << ratio2 << std::endl;
390  //std::cout << "Ene = " << ene << " slope = " << slope << std::endl;
391 
392  //std::cout << "Pion energy = " << Hadron.E()
393  // << "File chosen " << theFileNames[thePidIndex][ene]
394  // << std::endl;
395 
396  // The boost characteristics
397  XYZTLorentzVector theBoost = Proton + Hadron;
398  theBoost /= theBoost.e();
399 
400  // std::cout << "File chosen : " << thePid << "/" << ene
401  // << " Current interaction = " << aCurrentInteraction[ene]
402  // << " Total interactions = " << aNumberOfInteractions[ene]
403  // << std::endl;
404  // theFiles[thePidIndex][ene]->cd();
405  // gDirectory->ls();
406 
407  // Check we are not either at the end of an interaction bunch
408  // or at the end of a file
409  if ( aCurrentInteraction[ene] == aNumberOfInteractions[ene] ) {
410  // std::cout << "End of interaction bunch ! ";
411  std::vector<unsigned>& aCurrentEntry = theCurrentEntry[thePidIndex];
412  std::vector<unsigned>& aNumberOfEntries = theNumberOfEntries[thePidIndex];
413  std::vector<TTree*>& aTrees = theTrees[thePidIndex];
414  ++aCurrentEntry[ene];
415  // std::cerr << "Read the next entry "
416  // << aCurrentEntry[ene] << std::endl;
417  aCurrentInteraction[ene] = 0;
418  if ( aCurrentEntry[ene] == aNumberOfEntries[ene] ) {
419  aCurrentEntry[ene] = 0;
420  // std::cout << "End of file - Rewind! " << std::endl;
421  }
422  unsigned myEntry = aCurrentEntry[ene];
423  // std::cout << "The new entry " << myEntry
424  // << " is read ... in TTree " << aTrees[ene] << " ";
425  aTrees[ene]->GetEntry(myEntry);
426  // std::cout << "The number of interactions in the new entry is ... ";
427  aNumberOfInteractions[ene] = aNUEvents[ene]->nInteractions();
428  // std::cout << aNumberOfInteractions[ene] << std::endl;
429  }
430 
431  // Read the interaction
432  NUEvent::NUInteraction anInteraction
433  = aNUEvents[ene]->theNUInteractions()[aCurrentInteraction[ene]];
434 
435  unsigned firstTrack = anInteraction.first;
436  unsigned lastTrack = anInteraction.last;
437  // std::cout << "First and last tracks are " << firstTrack << " " << lastTrack << std::endl;
438 
439  _theUpdatedState.resize(lastTrack-firstTrack+1);
440 
441  double distMin = 1E99;
442 
443  // Some rotation around the boost axis, for more randomness
444  XYZVector theAxis = theBoost.Vect().Unit();
445  double theAngle = random->flatShoot() * 2. * 3.14159265358979323;
446  RawParticle::Rotation axisRotation(theAxis,theAngle);
447  RawParticle::Boost axisBoost(theBoost.x(),theBoost.y(),theBoost.z());
448 
449  // A rotation to bring the particles back to the pion direction
450  XYZVector zAxis(0.,0.,1.);
451  XYZVector orthAxis = (zAxis.Cross(theBoost.Vect())).Unit();
452  double orthAngle = acos(theBoost.Vect().Unit().Z());
453  RawParticle::Rotation orthRotation(orthAxis,orthAngle);
454 
455  // A few checks
456  // double eAfter = 0.;
457 
458  // Loop on the nuclear interaction products
459  for ( unsigned iTrack=firstTrack; iTrack<=lastTrack; ++iTrack ) {
460 
461  unsigned idaugh = iTrack - firstTrack;
462  NUEvent::NUParticle aParticle = aNUEvents[ene]->theNUParticles()[iTrack];
463  // std::cout << "Track " << iTrack
464  // << " id/px/py/pz/mass "
465  // << aParticle.id << " "
466  // << aParticle.px << " "
467  // << aParticle.py << " "
468  // << aParticle.pz << " "
469  // << aParticle.mass << " " << endl;
470 
471  // Add a RawParticle with the proper energy in the c.m frame of
472  // the nuclear interaction
473  double energy = std::sqrt( aParticle.px*aParticle.px
474  + aParticle.py*aParticle.py
475  + aParticle.pz*aParticle.pz
476  + aParticle.mass*aParticle.mass/(ecm*ecm) );
477 
478  RawParticle& aDaughter = _theUpdatedState[idaugh];
479  aDaughter.SetXYZT(aParticle.px*ecm,aParticle.py*ecm,
480  aParticle.pz*ecm,energy*ecm);
481  aDaughter.setID(aParticle.id);
482 
483  // Rotate to the collision axis
484  aDaughter.rotate(orthRotation);
485 
486  // Rotate around the boost axis for more randomness
487  aDaughter.rotate(axisRotation);
488 
489  // Boost it in the lab frame
490  aDaughter.boost(axisBoost);
491 
492  // Store the closest daughter index (for later tracking purposes, so charged particles only)
493  double distance = distanceToPrimary(Particle,aDaughter);
494  // Find the closest daughter, if closer than a given upper limit.
495  if ( distance < distMin && distance < theDistCut ) {
496  distMin = distance;
498  }
499 
500  // eAfter += aDaughter.E();
501 
502  }
503 
504  /*
505  double eBefore = Particle.E();
506  double rapid = Particle.momentum().Eta();
507  if ( eBefore > 0. ) {
508  hAfter->Fill(eAfter/eBefore);
509  hAfter2->Fill(rapid,eAfter/eBefore);
510  hAfter3->Fill(eBefore,eAfter/eBefore);
511  }
512  */
513 
514  // Increment for next time
515  ++aCurrentInteraction[ene];
516 
517  // Simulate a stopping hadron (low momentum)
518  } else if ( pHadron < 4. &&
519  elastic > 1.- (inelastic4*theInelasticLength)
520  /theTotalInteractionLength ) {
521  // A fake particle with 0 momentum as a daughter!
522  _theUpdatedState.resize(1);
523  _theUpdatedState[0].SetXYZT(0.,0.,0.,0.);
524  _theUpdatedState[0].setID(22);
525  }
526 
527  }
528 
529  }
530 
531  }
532 
533 }
void boost(double bx, double by, double bz)
Definition: RawParticle.cc:182
static const double slope[3]
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Geom::Theta< T > theta() const
XYZVector orthogonal(const XYZVector &) const
A vector orthogonal to another one (because it&#39;s not in XYZTLorentzVector)
std::vector< std::vector< unsigned > > theNumberOfInteractions
std::vector< std::vector< TTree * > > theTrees
int pid() const
get the HEP particle ID number
Definition: RawParticle.h:264
TRandom random
Definition: MVATrainer.cc:138
double mass() const
get the MEASURED mass
Definition: RawParticle.h:282
ROOT::Math::Boost Boost
Definition: RawParticle.h:39
std::vector< std::vector< unsigned > > theCurrentEntry
math::XYZVector XYZVector
std::vector< std::vector< unsigned > > theNumberOfEntries
T sqrt(T t)
Definition: SSEVec.h:48
void setID(const int id)
Definition: RawParticle.cc:101
std::vector< std::vector< double > > thePionCM
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void rotate(double rphi, const XYZVector &raxis)
Definition: RawParticle.cc:154
unsigned index(int thePid)
Return a hashed index for a given pid.
std::vector< std::vector< unsigned > > theCurrentInteraction
std::vector< std::vector< double > > theRatios
std::vector< RawParticle > _theUpdatedState
ROOT::Math::AxisAngle Rotation
Definition: RawParticle.h:34
std::vector< std::vector< NUEvent * > > theNUEvents
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
double distanceToPrimary(const RawParticle &Particle, const RawParticle &aDaughter) const
Compute distance between secondary and primary.
math::XYZTLorentzVector XYZTLorentzVector
Definition: RawParticle.h:15
Definition: DDAxes.h:10
double NuclearInteractionSimulator::distanceToPrimary ( const RawParticle Particle,
const RawParticle aDaughter 
) const
private

Compute distance between secondary and primary.

Definition at line 536 of file NuclearInteractionSimulator.cc.

References RawParticle::charge(), and theDistAlgo.

Referenced by compute().

537  {
538 
539  double distance = 2E99;
540 
541  // Compute the distance only for charged primaries
542  if ( fabs(Particle.charge()) > 1E-12 ) {
543 
544  // The secondary must have the same charge
545  double chargeDiff = fabs(aDaughter.charge()-Particle.charge());
546  if ( fabs(chargeDiff) < 1E-12 ) {
547 
548  // Here are two distance definitions * to be tuned *
549  switch ( theDistAlgo ) {
550 
551  case 1:
552  // sin(theta12)
553  distance = (aDaughter.Vect().Unit().Cross(Particle.Vect().Unit())).R();
554  break;
555 
556  case 2:
557  // sin(theta12) * p1/p2
558  distance = (aDaughter.Vect().Cross(Particle.Vect())).R()
559  /aDaughter.Vect().Mag2();
560  break;
561 
562  default:
563  // Should not happen
564  distance = 2E99;
565  break;
566 
567  }
568 
569  }
570 
571  }
572 
573  return distance;
574 
575 }
double charge() const
get the MEASURED charge
Definition: RawParticle.h:281
unsigned NuclearInteractionSimulator::index ( int  thePid)
private

Return a hashed index for a given pid.

Definition at line 695 of file NuclearInteractionSimulator.cc.

References thePionID.

Referenced by BeautifulSoup.PageElement::_invert(), and compute().

695  {
696 
697  unsigned myIndex=0;
698  while ( thePid != thePionID[myIndex] ) ++myIndex;
699  // std::cout << "pid/index = " << thePid << " " << myIndex << std::endl;
700  return myIndex;
701 
702 }
bool NuclearInteractionSimulator::read ( std::string  inputFile)

Read former nuclear interaction (from previous run)

Definition at line 631 of file NuclearInteractionSimulator.cc.

References python.entryComment::results, findQualityFiles::size, theCurrentEntry, and theCurrentInteraction.

Referenced by Vispa.Plugins.EdmBrowser.EdmDataAccessor.EdmDataAccessor::goto(), NuclearInteractionSimulator(), and Vispa.Plugins.EdmBrowser.EdmDataAccessor.EdmDataAccessor::setFilterBranches().

631  {
632 
633  std::ifstream myInputFile;
634  struct stat results;
635  //
636  unsigned size1 =
637  theCurrentEntry.size()*
638  theCurrentEntry.begin()->size();
639  std::vector<unsigned> theCurrentEntries;
640  theCurrentEntries.resize(size1);
641  size1*=sizeof(unsigned);
642  //
643  unsigned size2 =
644  theCurrentInteraction.size()*
645  theCurrentInteraction.begin()->size();
646  std::vector<unsigned> theCurrentInteractions;
647  theCurrentInteractions.resize(size2);
648  size2 *= sizeof(unsigned);
649  //
650  unsigned size = 0;
651 
652 
653  // Open the file (if any)
654  myInputFile.open (inputFile.c_str());
655  if ( myInputFile.is_open() ) {
656 
657  // Get the size of the file
658  if ( stat(inputFile.c_str(), &results) == 0 ) size = results.st_size;
659  else return false; // Something is wrong with that file !
660 
661  // Position the pointer just before the last record
662  myInputFile.seekg(size-size1-size2);
663  myInputFile.read((char*)(&theCurrentEntries.front()),size1);
664  myInputFile.read((char*)(&theCurrentInteractions.front()),size2);
665  myInputFile.close();
666 
667  // Read the current entries
668  std::vector< std::vector<unsigned> >::iterator aCurrentEntry = theCurrentEntry.begin();
669  std::vector< std::vector<unsigned> >::iterator lastCurrentEntry = theCurrentEntry.end();
670  unsigned allEntries=0;
671  for ( ; aCurrentEntry!=lastCurrentEntry; ++aCurrentEntry ) {
672  unsigned size = aCurrentEntry->size();
673  for ( unsigned iene=0; iene<size; ++iene )
674  (*aCurrentEntry)[iene] = theCurrentEntries[allEntries++];
675  }
676 
677  // Read the current interactions
678  std::vector< std::vector<unsigned> >::iterator aCurrentInteraction = theCurrentInteraction.begin();
679  std::vector< std::vector<unsigned> >::iterator lastCurrentInteraction = theCurrentInteraction.end();
680  unsigned allInteractions=0;
681  for ( ; aCurrentInteraction!=lastCurrentInteraction; ++aCurrentInteraction ) {
682  unsigned size = aCurrentInteraction->size();
683  for ( unsigned iene=0; iene<size; ++iene )
684  (*aCurrentInteraction)[iene] = theCurrentInteractions[allInteractions++];
685  }
686 
687  return true;
688  }
689 
690  return false;
691 
692 }
std::vector< std::vector< unsigned > > theCurrentEntry
std::vector< std::vector< unsigned > > theCurrentInteraction
tuple size
Write out results.
void NuclearInteractionSimulator::save ( )

Save current nuclear interaction (for later use)

Definition at line 578 of file NuclearInteractionSimulator.cc.

References myOutputBuffer, myOutputFile, findQualityFiles::size, theCurrentEntry, and theCurrentInteraction.

Referenced by Vispa.Main.TabController.TabController::allowClose(), Vispa.Main.TabController.TabController::checkModificationTimestamp(), and MaterialEffects::save().

578  {
579 
580  // Size of buffer
581  ++myOutputBuffer;
582 
583  // Periodically close the current file and open a new one
584  if ( myOutputBuffer/1000*1000 == myOutputBuffer ) {
585  myOutputFile.close();
586  myOutputFile.open ("NuclearInteractionOutputFile.txt");
587  // myOutputFile.seekp(0); // No need to rewind in that case
588  }
589  //
590  unsigned size1 =
591  theCurrentEntry.size()*
592  theCurrentEntry.begin()->size();
593  std::vector<unsigned> theCurrentEntries;
594  theCurrentEntries.resize(size1);
595  size1*=sizeof(unsigned);
596  //
597  unsigned size2 =
598  theCurrentInteraction.size()*
599  theCurrentInteraction.begin()->size();
600  std::vector<unsigned> theCurrentInteractions;
601  theCurrentInteractions.resize(size2);
602  size2 *= sizeof(unsigned);
603 
604  // Save the current entries
605  std::vector< std::vector<unsigned> >::const_iterator aCurrentEntry = theCurrentEntry.begin();
606  std::vector< std::vector<unsigned> >::const_iterator lastCurrentEntry = theCurrentEntry.end();
607  unsigned allEntries=0;
608  for ( ; aCurrentEntry!=lastCurrentEntry; ++aCurrentEntry ) {
609  unsigned size = aCurrentEntry->size();
610  for ( unsigned iene=0; iene<size; ++iene )
611  theCurrentEntries[allEntries++] = (*aCurrentEntry)[iene];
612  }
613 
614  // Save the current interactions
615  std::vector< std::vector<unsigned> >::const_iterator aCurrentInteraction = theCurrentInteraction.begin();
616  std::vector< std::vector<unsigned> >::const_iterator lastCurrentInteraction = theCurrentInteraction.end();
617  unsigned allInteractions=0;
618  for ( ; aCurrentInteraction!=lastCurrentInteraction; ++aCurrentInteraction ) {
619  unsigned size = aCurrentInteraction->size();
620  for ( unsigned iene=0; iene<size; ++iene )
621  theCurrentInteractions[allInteractions++] = (*aCurrentInteraction)[iene];
622  }
623  //
624  myOutputFile.write((const char*)(&theCurrentEntries.front()), size1);
625  myOutputFile.write((const char*)(&theCurrentInteractions.front()), size2);
626  myOutputFile.flush();
627 
628 }
std::vector< std::vector< unsigned > > theCurrentEntry
std::vector< std::vector< unsigned > > theCurrentInteraction
tuple size
Write out results.

Member Data Documentation

unsigned NuclearInteractionSimulator::ien4
private

Definition at line 93 of file NuclearInteractionSimulator.h.

Referenced by compute(), and NuclearInteractionSimulator().

unsigned NuclearInteractionSimulator::myOutputBuffer
private

Definition at line 98 of file NuclearInteractionSimulator.h.

Referenced by NuclearInteractionSimulator(), and save().

std::ofstream NuclearInteractionSimulator::myOutputFile
private
std::vector< std::vector<TBranch*> > NuclearInteractionSimulator::theBranches
private

Definition at line 83 of file NuclearInteractionSimulator.h.

Referenced by NuclearInteractionSimulator().

std::vector< std::vector<unsigned> > NuclearInteractionSimulator::theCurrentEntry
private

Definition at line 85 of file NuclearInteractionSimulator.h.

Referenced by compute(), NuclearInteractionSimulator(), read(), and save().

std::vector< std::vector<unsigned> > NuclearInteractionSimulator::theCurrentInteraction
private

Definition at line 86 of file NuclearInteractionSimulator.h.

Referenced by compute(), NuclearInteractionSimulator(), read(), and save().

unsigned NuclearInteractionSimulator::theDistAlgo
private

Definition at line 94 of file NuclearInteractionSimulator.h.

Referenced by distanceToPrimary().

double NuclearInteractionSimulator::theDistCut
private

Definition at line 95 of file NuclearInteractionSimulator.h.

Referenced by compute().

std::vector< std::vector<std::string> > NuclearInteractionSimulator::theFileNames
private

Definition at line 89 of file NuclearInteractionSimulator.h.

Referenced by NuclearInteractionSimulator().

std::vector< std::vector<TFile*> > NuclearInteractionSimulator::theFiles
private
std::map< int, int > NuclearInteractionSimulator::theIDMap
private

Definition at line 92 of file NuclearInteractionSimulator.h.

Referenced by compute().

std::vector<double> NuclearInteractionSimulator::theLengthRatio
private

Definition at line 78 of file NuclearInteractionSimulator.h.

Referenced by compute().

std::vector< std::vector<NUEvent*> > NuclearInteractionSimulator::theNUEvents
private

Definition at line 84 of file NuclearInteractionSimulator.h.

Referenced by compute(), and NuclearInteractionSimulator().

std::vector< std::vector<unsigned> > NuclearInteractionSimulator::theNumberOfEntries
private

Definition at line 87 of file NuclearInteractionSimulator.h.

Referenced by compute(), and NuclearInteractionSimulator().

std::vector< std::vector<unsigned> > NuclearInteractionSimulator::theNumberOfInteractions
private

Definition at line 88 of file NuclearInteractionSimulator.h.

Referenced by compute(), and NuclearInteractionSimulator().

std::vector< std::vector<double> > NuclearInteractionSimulator::thePionCM
private

Definition at line 90 of file NuclearInteractionSimulator.h.

Referenced by compute(), and NuclearInteractionSimulator().

std::vector<double> NuclearInteractionSimulator::thePionEN
private

Definition at line 72 of file NuclearInteractionSimulator.h.

Referenced by NuclearInteractionSimulator().

double NuclearInteractionSimulator::thePionEnergy
private

Definition at line 77 of file NuclearInteractionSimulator.h.

Referenced by compute().

std::vector<int> NuclearInteractionSimulator::thePionID
private

Definition at line 73 of file NuclearInteractionSimulator.h.

Referenced by index().

std::vector<double> NuclearInteractionSimulator::thePionMA
private

Definition at line 75 of file NuclearInteractionSimulator.h.

Referenced by NuclearInteractionSimulator().

std::vector<std::string> NuclearInteractionSimulator::thePionNA
private

Definition at line 74 of file NuclearInteractionSimulator.h.

Referenced by NuclearInteractionSimulator().

std::vector<double> NuclearInteractionSimulator::thePionPMin
private

Definition at line 76 of file NuclearInteractionSimulator.h.

Referenced by compute().

std::vector< std::vector<double> > NuclearInteractionSimulator::theRatios
private

Definition at line 79 of file NuclearInteractionSimulator.h.

Referenced by compute().

std::vector< std::vector<TTree*> > NuclearInteractionSimulator::theTrees
private

Definition at line 82 of file NuclearInteractionSimulator.h.

Referenced by compute(), and NuclearInteractionSimulator().