CMS 3D CMS Logo

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 > &hadronEnergies, std::vector< int > &hadronTypes, std::vector< std::string > &hadronNames, std::vector< double > &hadronMasses, std::vector< double > &hadronPMin, 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

bool currentValuesWereSet
 
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
 
TFile * theFile
 
std::vector< std::vector< std::string > > theFileNames
 
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 > &  hadronEnergies,
std::vector< int > &  hadronTypes,
std::vector< std::string > &  hadronNames,
std::vector< double > &  hadronMasses,
std::vector< double > &  hadronPMin,
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 24 of file NuclearInteractionSimulator.cc.

References gather_cfg::cout, currentValuesWereSet, Exception, corrVsCorr::filename, edm::FileInPath::fullPath(), ien4, myOutputBuffer, myOutputFile, read(), TrajectoryFactories_cff::Reference, mathSSE::sqrt(), AlCaHLTBitMon_QueryRunRegistry::string, theBranches, theCurrentEntry, theCurrentInteraction, theFile, theFileNames, theNUEvents, theNumberOfEntries, theNumberOfInteractions, thePionCM, thePionEN, thePionMA, thePionNA, and theTrees.

37  :
39  thePionEN(hadronEnergies),
40  thePionID(hadronTypes),
41  thePionNA(hadronNames),
42  thePionMA(hadronMasses),
43  thePionPMin(hadronPMin),
44  thePionEnergy(pionEnergy),
45  theLengthRatio(lengthRatio),
47  theIDMap(idMap),
48  theDistAlgo(distAlgo),
51 {
52  std::string fullPath;
53 
54  // Prepare the map of files
55  // Loop over the particle names
56  TFile* aVFile=0;
57  std::vector<TTree*> aVTree(thePionEN.size(),static_cast<TTree*>(0));
58  std::vector<TBranch*> aVBranch(thePionEN.size(),static_cast<TBranch*>(0));
59  std::vector<NUEvent*> aVNUEvents(thePionEN.size(),static_cast<NUEvent*>(0));
60  std::vector<unsigned> aVCurrentEntry(thePionEN.size(),static_cast<unsigned>(0));
61  std::vector<unsigned> aVCurrentInteraction(thePionEN.size(),static_cast<unsigned>(0));
62  std::vector<unsigned> aVNumberOfEntries(thePionEN.size(),static_cast<unsigned>(0));
63  std::vector<unsigned> aVNumberOfInteractions(thePionEN.size(),static_cast<unsigned>(0));
64  std::vector<std::string> aVFileName(thePionEN.size(),static_cast<std::string>(""));
65  std::vector<double> aVPionCM(thePionEN.size(),static_cast<double>(0));
66 
67  theTrees.resize(thePionNA.size());
68  theBranches.resize(thePionNA.size());
69  theNUEvents.resize(thePionNA.size());
70  theCurrentEntry.resize(thePionNA.size());
71  theCurrentInteraction.resize(thePionNA.size());
72  theNumberOfEntries.resize(thePionNA.size());
73  theNumberOfInteractions.resize(thePionNA.size());
74  theFileNames.resize(thePionNA.size());
75  thePionCM.resize(thePionNA.size());
76  theFile = aVFile;
77  for ( unsigned iname=0; iname<thePionNA.size(); ++iname ) {
78  theTrees[iname] = aVTree;
79  theBranches[iname] = aVBranch;
80  theNUEvents[iname] = aVNUEvents;
81  theCurrentEntry[iname] = aVCurrentEntry;
82  theCurrentInteraction[iname] = aVCurrentInteraction;
83  theNumberOfEntries[iname] = aVNumberOfEntries;
84  theNumberOfInteractions[iname] = aVNumberOfInteractions;
85  theFileNames[iname] = aVFileName;
86  thePionCM[iname] = aVPionCM;
87  }
88 
89  // Read the information from a previous run (to keep reproducibility)
92  std::cout << "***WARNING*** You are reading nuclear-interaction information from the file "
93  << inputFile << " created in an earlier run."
94  << std::endl;
95 
96  // Open the file for saving the information of the current run
97  myOutputFile.open ("NuclearInteractionOutputFile.txt");
98  myOutputBuffer = 0;
99 
100 
101  // Open the root files
102  // for ( unsigned file=0; file<theFileNames.size(); ++file ) {
103  edm::FileInPath myDataFile("FastSimulation/MaterialEffects/data/NuclearInteractions.root");
104 
105  fullPath = myDataFile.fullPath();
106  theFile = TFile::Open(fullPath.c_str());
107 
108  unsigned fileNb = 0;
109  for ( unsigned iname=0; iname<thePionNA.size(); ++iname ) {
110  for ( unsigned iene=0; iene<thePionEN.size(); ++iene ) {
111  //std::cout << "iname/iene " << iname << " " << iene << std::endl;
112  std::ostringstream filename;
113  double theEne = thePionEN[iene];
114  filename << "NuclearInteractionsVal_" << thePionNA[iname] << "_E"<< theEne << ".root";
115  theFileNames[iname][iene] = filename.str();
116  //std::cout << "thePid/theEne " << thePionID[iname] << " " << theEne << std::endl;
117 
118  ++fileNb;
119  std::string treeName="NuclearInteractions_"+thePionNA[iname]+"_E"+std::to_string(int(theEne));
120  //
121  theTrees[iname][iene] = (TTree*) theFile->Get(treeName.c_str());
122  if ( !theTrees[iname][iene] ) throw cms::Exception("FastSimulation/MaterialEffects")
123  << "Tree with name " << treeName << " not found ";
124  //
125  theBranches[iname][iene] = theTrees[iname][iene]->GetBranch("nuEvent");
126  //std::cout << "The branch = " << theBranches[iname][iene] << std::endl;
127  if ( !theBranches[iname][iene] ) throw cms::Exception("FastSimulation/MaterialEffects")
128  << "Branch with name nuEvent not found in " << theFileNames[iname][iene];
129  //
130  theNUEvents[iname][iene] = new NUEvent();
131  //std::cout << "The branch = " << theBranches[iname][iene] << std::endl;
132  theBranches[iname][iene]->SetAddress(&theNUEvents[iname][iene]);
133  //
134  theNumberOfEntries[iname][iene] = theTrees[iname][iene]->GetEntries();
135 
137  theTrees[iname][iene]->GetEntry(theCurrentEntry[iname][iene]);
138  unsigned NInteractions = theNUEvents[iname][iene]->nInteractions();
139  theNumberOfInteractions[iname][iene] = NInteractions;
140  }
141 
142  //
143  // Compute the corresponding cm energies of the nuclear interactions
144  XYZTLorentzVector Proton(0.,0.,0.,0.986);
146  Reference(0.,
147  0.,
148  std::sqrt(thePionEN[iene]*thePionEN[iene]
149  -thePionMA[iname]*thePionMA[iname]),
150  thePionEN[iene]);
151  thePionCM[iname][iene] = (Reference+Proton).M();
152 
153  }
154 
155  }
156 
157  // Find the index for which EN = 4. (or thereabout)
158  ien4 = 0;
159  while ( thePionEN[ien4] < 4.0 ) ++ien4;
160 
161  gROOT->cd();
162 
163  // Information (Should be on LogInfo)
164 // std::cout << " ---> A total of " << fileNb
165 // << " nuclear-interaction files was sucessfully open" << std::endl;
166 
167  // dbe = edm::Service<DaqMonitorBEInterface>().operator->();
168  // htot = dbe->book1D("Total", "All particles",150,0.,150.);
169  // helas = dbe->book1D("Elastic", "Elastic interactions",150,0.,150.);
170  // hinel = dbe->book1D("Inelastic", "Inelastic interactions",150,0.,150.);
171  // hscatter = dbe->book1D("Scattering","Elastic Scattering angle",200,0.,2.);
172  // hscatter2 = dbe->book2D("Scattering2","Elastic Scattering angle vs p",100,0.,10.,200,0.,2.);
173  // hAfter = dbe->book1D("eAfter","Energy after collision",200,0.,4.);
174  // hAfter2 = dbe->book2D("eAfter2","Energy after collision",100,-2.5,2.5,100,0.,4);
175  // hAfter3 = dbe->book2D("eAfter3","Energy after collision",100,0.,1000.,100,0.,4);
176 
177 }
std::vector< std::vector< unsigned > > theNumberOfInteractions
std::vector< std::vector< TTree * > > theTrees
std::vector< std::vector< unsigned > > theCurrentEntry
std::vector< std::vector< std::string > > theFileNames
Definition: NUEvent.h:6
std::vector< std::vector< unsigned > > theNumberOfEntries
T sqrt(T t)
Definition: SSEVec.h:18
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
std::vector< std::vector< NUEvent * > > theNUEvents
math::XYZTLorentzVector XYZTLorentzVector
Definition: RawParticle.h:15
NuclearInteractionSimulator::~NuclearInteractionSimulator ( )

Default Destructor.

Definition at line 179 of file NuclearInteractionSimulator.cc.

References myOutputFile, theFile, and theNUEvents.

179  {
180 
181  // Close all local files
182  // Among other things, this allows the TROOT destructor to end up
183  // without crashing, while trying to close these files from outside
184  theFile->Close();
185  delete theFile;
186 
187  for(auto& vEvents: theNUEvents) {
188  for(auto evtPtr: vEvents) {
189  delete evtPtr;
190  }
191  }
192 
193  // Close the output file
194  myOutputFile.close();
195 
196  // dbe->save("test.root");
197 
198 }
std::vector< std::vector< NUEvent * > > theNUEvents

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 200 of file NuclearInteractionSimulator.cc.

References MaterialEffectsSimulator::_theUpdatedState, funct::abs(), RawParticle::boost(), currentValuesWereSet, SoftLeptonByDistance_cfi::distance, distanceToPrimary(), JetChargeProducer_cfi::exp, NUEvent::NUInteraction::first, RandomEngineAndDistribution::flatShoot(), NUEvent::NUParticle::id, ien4, index(), NUEvent::NUInteraction::last, cmsBatch::log, NUEvent::NUParticle::mass, RawParticle::mass(), MaterialEffectsSimulator::orthogonal(), phi, RawParticle::pid(), ALCARECOTkAlMinBias_cff::pMin, 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, thePionEN, thePionEnergy, thePionNA, thePionPMin, theRatios, theta(), theTrees, and MetAnalyzer::zAxis.

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

Compute distance between secondary and primary.

Definition at line 532 of file NuclearInteractionSimulator.cc.

References RawParticle::charge(), SoftLeptonByDistance_cfi::distance, and theDistAlgo.

Referenced by compute().

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

Return a hashed index for a given pid.

Definition at line 691 of file NuclearInteractionSimulator.cc.

References thePionID.

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

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

Read former nuclear interaction (from previous run)

Definition at line 627 of file NuclearInteractionSimulator.cc.

References mps_update::results, findQualityFiles::size, trackingPlots::stat, theCurrentEntry, and theCurrentInteraction.

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

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

Save current nuclear interaction (for later use)

Reimplemented from MaterialEffectsSimulator.

Definition at line 574 of file NuclearInteractionSimulator.cc.

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

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

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

Member Data Documentation

bool NuclearInteractionSimulator::currentValuesWereSet
private

Definition at line 100 of file NuclearInteractionSimulator.h.

Referenced by compute(), and NuclearInteractionSimulator().

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().

TFile* NuclearInteractionSimulator::theFile
private
std::vector< std::vector<std::string> > NuclearInteractionSimulator::theFileNames
private

Definition at line 89 of file NuclearInteractionSimulator.h.

Referenced by NuclearInteractionSimulator().

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
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 compute(), and 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 compute(), and 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().