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 () override
 Save current nuclear interaction (for later use) More...
 
 ~NuclearInteractionSimulator () override
 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 *) override
 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 25 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.

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

Default Destructor.

Definition at line 180 of file NuclearInteractionSimulator.cc.

References myOutputFile, theFile, and theNUEvents.

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

Member Function Documentation

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

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

Implements MaterialEffectsSimulator.

Definition at line 201 of file NuclearInteractionSimulator.cc.

References MaterialEffectsSimulator::_theUpdatedState, funct::abs(), RawParticle::boost(), currentValuesWereSet, SoftLeptonByDistance_cfi::distance, distanceToPrimary(), randomXiThetaGunProducer_cfi::energy, JetChargeProducer_cfi::exp, NUEvent::NUInteraction::first, RandomEngineAndDistribution::flatShoot(), NUEvent::NUParticle::id, ien4, index(), NUEvent::NUInteraction::last, cmsBatch::log, RawParticle::M2(), makeParticle(), NUEvent::NUParticle::mass, RawParticle::mass(), MaterialEffectsSimulator::orthogonal(), BaseParticlePropagator::particle(), ParticlePropagator::particleDataTable(), phi, RawParticle::pid(), ALCARECOTkAlMinBias_cff::pMin, funct::pow(), NUEvent::NUParticle::px, NUEvent::NUParticle::py, NUEvent::NUParticle::pz, MaterialEffectsSimulator::radLengths, RawParticle::rotate(), 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, RawParticle::Vect(), and MetAnalyzer::zAxis.

202 {
203  if(!currentValuesWereSet) {
204  currentValuesWereSet = true;
205  for ( unsigned iname=0; iname<thePionNA.size(); ++iname ) {
206  for ( unsigned iene=0; iene<thePionEN.size(); ++iene ) {
207  theCurrentEntry[iname][iene] = (unsigned) (theNumberOfEntries[iname][iene] * random->flatShoot());
208 
209  theTrees[iname][iene]->GetEntry(theCurrentEntry[iname][iene]);
210  unsigned NInteractions = theNUEvents[iname][iene]->nInteractions();
211  theNumberOfInteractions[iname][iene] = NInteractions;
212 
213  theCurrentInteraction[iname][iene] = (unsigned) (theNumberOfInteractions[iname][iene] * random->flatShoot());
214  }
215  }
216  }
217 
218  // Read a Nuclear Interaction in a random manner
219 
220  double pHadron = std::sqrt(Particle.particle().Vect().Mag2());
221  // htot->Fill(pHadron);
222 
223  // The hadron has enough momentum to create some relevant final state
224  if ( pHadron > thePionEnergy ) {
225 
226  // The particle type
227  std::map<int,int>::const_iterator thePit = theIDMap.find(Particle.particle().pid());
228 
229  int thePid = thePit != theIDMap.end() ? thePit->second : Particle.particle().pid();
230 
231  // Is this particle type foreseen?
232  unsigned fPid = abs(thePid);
233  if ( fPid != 211 && fPid != 130 && fPid != 321 && fPid != 2112 && fPid != 2212 ) {
234  return;
235  //std::cout << "Unknown particle type = " << thePid << std::endl;
236  //thePid = 211;
237  }
238 
239  // The inelastic interaction length at p(pion) = 5 GeV/c
240  unsigned thePidIndex = index(thePid);
241  double theInelasticLength = radLengths * theLengthRatio[thePidIndex];
242 
243  // The elastic interaction length
244  // The baroque parameterization is a fit to Fig. 40.13 of the PDG
245  double ee = pHadron > 0.6 ?
246  exp(-std::sqrt((pHadron-0.6)/1.122)) : exp(std::sqrt((0.6-pHadron)/1.122));
247  double theElasticLength = ( 0.8753 * ee + 0.15 )
248  // double theElasticLength = ( 0.15 + 0.195 / log(pHadron/0.4) )
249  // double theElasticLength = ( 0.15 + 0.305 / log(pHadron/0.35) )
250  * theInelasticLength;
251 
252  // The total interaction length
253  double theTotalInteractionLength = theInelasticLength + theElasticLength;
254 
255  // Probability to interact is dl/L0 (maximum for 4 GeV pion)
256  double aNuclInteraction = -std::log(random->flatShoot());
257  if ( aNuclInteraction < theTotalInteractionLength ) {
258 
259  // The elastic part
260  double elastic = random->flatShoot();
261  if ( elastic < theElasticLength/theTotalInteractionLength ) {
262 
263  // helas->Fill(pHadron);
264 
265  // Characteristic scattering angle for the elastic part
266  double theta0 = std::sqrt(3.)/ std::pow(theA(),1./3.) * Particle.particle().mass()/pHadron;
267 
268  // Draw an angle with theta/theta0*exp[(-theta/2theta0)**2] shape
269  double theta = theta0 * std::sqrt(-2.*std::log(random->flatShoot()));
270  double phi = 2. * 3.14159265358979323 * random->flatShoot();
271 
272  // Rotate the particle accordingly
273  RawParticle::Rotation rotation1(orthogonal(Particle.particle().Vect()),theta);
274  RawParticle::Rotation rotation2(Particle.particle().Vect(),phi);
275  Particle.particle().rotate(rotation1);
276  Particle.particle().rotate(rotation2);
277 
278  // Distance
279  double distance = std::sin(theta);
280 
281  // Create a daughter if the kink is large engough
282  if ( distance > theDistCut ) {
283  _theUpdatedState.reserve(1);
284  _theUpdatedState.clear();
285  _theUpdatedState.emplace_back(Particle.particle());
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.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.reserve(lastTrack-firstTrack+1);
432  _theUpdatedState.clear();
433 
434  double distMin = 1E99;
435 
436  // Some rotation around the boost axis, for more randomness
437  XYZVector theAxis = theBoost.Vect().Unit();
438  double theAngle = random->flatShoot() * 2. * 3.14159265358979323;
439  RawParticle::Rotation axisRotation(theAxis,theAngle);
440  RawParticle::Boost axisBoost(theBoost.x(),theBoost.y(),theBoost.z());
441 
442  // A rotation to bring the particles back to the pion direction
443  XYZVector zAxis(0.,0.,1.);
444  XYZVector orthAxis = (zAxis.Cross(theBoost.Vect())).Unit();
445  double orthAngle = acos(theBoost.Vect().Unit().Z());
446  RawParticle::Rotation orthRotation(orthAxis,orthAngle);
447 
448  // A few checks
449  // double eAfter = 0.;
450 
451  // Loop on the nuclear interaction products
452  for ( unsigned iTrack=firstTrack; iTrack<=lastTrack; ++iTrack ) {
453 
454  unsigned idaugh = iTrack - firstTrack;
455  NUEvent::NUParticle aParticle = aNUEvents[ene]->theNUParticles()[iTrack];
456  // std::cout << "Track " << iTrack
457  // << " id/px/py/pz/mass "
458  // << aParticle.id << " "
459  // << aParticle.px << " "
460  // << aParticle.py << " "
461  // << aParticle.pz << " "
462  // << aParticle.mass << " " << endl;
463 
464  // Add a RawParticle with the proper energy in the c.m frame of
465  // the nuclear interaction
466  double energy = std::sqrt( aParticle.px*aParticle.px
467  + aParticle.py*aParticle.py
468  + aParticle.pz*aParticle.pz
469  + aParticle.mass*aParticle.mass/(ecm*ecm) );
470 
471  RawParticle& aDaughter = _theUpdatedState.emplace_back(makeParticle(Particle.particleDataTable(),
472  aParticle.id,
474  aParticle.px*ecm,aParticle.py*ecm,
475  aParticle.pz*ecm,energy*ecm)));
476  // Rotate to the collision axis
477  aDaughter.rotate(orthRotation);
478 
479  // Rotate around the boost axis for more randomness
480  aDaughter.rotate(axisRotation);
481 
482  // Boost it in the lab frame
483  aDaughter.boost(axisBoost);
484 
485  // Store the closest daughter index (for later tracking purposes, so charged particles only)
486  double distance = distanceToPrimary(Particle.particle(),aDaughter);
487  // Find the closest daughter, if closer than a given upper limit.
488  if ( distance < distMin && distance < theDistCut ) {
489  distMin = distance;
491  }
492 
493  // eAfter += aDaughter.E();
494 
495  }
496 
497  /*
498  double eBefore = Particle.E();
499  double rapid = Particle.momentum().Eta();
500  if ( eBefore > 0. ) {
501  hAfter->Fill(eAfter/eBefore);
502  hAfter2->Fill(rapid,eAfter/eBefore);
503  hAfter3->Fill(eBefore,eAfter/eBefore);
504  }
505  */
506 
507  // ERROR The way this loops through the events breaks
508  // replay. Which events are retrieved depends on
509  // which previous events were processed.
510 
511  // Increment for next time
512  ++aCurrentInteraction[ene];
513 
514  // Simulate a stopping hadron (low momentum)
515  } else if ( pHadron < 4. &&
516  elastic > 1.- (inelastic4*theInelasticLength)
517  /theTotalInteractionLength ) {
518  // A fake particle with 0 momentum as a daughter!
519  _theUpdatedState.reserve(1);
520  _theUpdatedState.clear();
521  _theUpdatedState.emplace_back(makeParticle(Particle.particleDataTable(),
522  22, XYZTLorentzVector(0.,0.,0.,0.)));
523  }
524 
525  }
526 
527  }
528 
529  }
530 
531 }
void boost(double bx, double by, double bz)
Definition: RawParticle.cc:111
const HepPDT::ParticleDataTable * particleDataTable() const
XYZVector Vect() const
the momentum threevector
Definition: RawParticle.h:342
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:296
TRandom random
Definition: MVATrainer.cc:138
RawParticle const & particle() const
The particle being propagated.
double mass() const
get the MEASURED mass
Definition: RawParticle.h:314
ROOT::Math::Boost Boost
Definition: RawParticle.h:52
std::vector< std::vector< unsigned > > theCurrentEntry
RawParticle makeParticle(HepPDT::ParticleDataTable const *, int id, const math::XYZTLorentzVector &p)
Definition: makeParticle.cc:29
std::vector< std::vector< unsigned > > theNumberOfEntries
T sqrt(T t)
Definition: SSEVec.h:18
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:83
unsigned index(int thePid)
Return a hashed index for a given pid.
std::vector< std::string > thePionNA
double M2() const
mass squared
Definition: RawParticle.h:337
std::vector< std::vector< unsigned > > theCurrentInteraction
std::vector< std::vector< double > > theRatios
std::vector< RawParticle > _theUpdatedState
ROOT::Math::AxisAngle Rotation
Definition: RawParticle.h:47
std::vector< std::vector< NUEvent * > > theNUEvents
math::XYZVector XYZVector
Definition: RawParticle.h:28
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:27
double NuclearInteractionSimulator::distanceToPrimary ( const RawParticle Particle,
const RawParticle aDaughter 
) const
private

Compute distance between secondary and primary.

Definition at line 534 of file NuclearInteractionSimulator.cc.

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

Referenced by compute().

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

Return a hashed index for a given pid.

Definition at line 693 of file NuclearInteractionSimulator.cc.

References thePionID.

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

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

Read former nuclear interaction (from previous run)

Definition at line 629 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().

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

Save current nuclear interaction (for later use)

Reimplemented from MaterialEffectsSimulator.

Definition at line 576 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().

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