CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MaterialEffects.cc
Go to the documentation of this file.
1 
2 //Framework Headers
5 
6 //TrackingTools Headers
7 
8 // Famos Headers
13 
20 
21 #include <list>
22 #include <map>
23 #include <string>
24 
26  const RandomEngine* engine)
27  : PairProduction(0), Bremsstrahlung(0),MuonBremsstrahlung(0),
28  MultipleScattering(0), EnergyLoss(0),
29  NuclearInteraction(0),
30  pTmin(999.), random(engine)
31 {
32  // Set the minimal photon energy for a Brem from e+/-
33 
34  bool doPairProduction = matEff.getParameter<bool>("PairProduction");
35  bool doBremsstrahlung = matEff.getParameter<bool>("Bremsstrahlung");
36  bool doEnergyLoss = matEff.getParameter<bool>("EnergyLoss");
37  bool doMultipleScattering = matEff.getParameter<bool>("MultipleScattering");
38  bool doNuclearInteraction = matEff.getParameter<bool>("NuclearInteraction");
39  bool doMuonBremsstrahlung = matEff.getParameter<bool>("MuonBremsstrahlung");
40 
41  double A = matEff.getParameter<double>("A");
42  double Z = matEff.getParameter<double>("Z");
43  double density = matEff.getParameter<double>("Density");
44  double radLen = matEff.getParameter<double>("RadiationLength");
45 
46  // Set the minimal pT before giving up the dE/dx treatment
47 
48  if ( doPairProduction ) {
49 
50  double photonEnergy = matEff.getParameter<double>("photonEnergy");
51  PairProduction = new PairProductionSimulator(photonEnergy,
52  random);
53 
54  }
55 
56  if ( doBremsstrahlung ) {
57 
58  double bremEnergy = matEff.getParameter<double>("bremEnergy");
59  double bremEnergyFraction = matEff.getParameter<double>("bremEnergyFraction");
60  Bremsstrahlung = new BremsstrahlungSimulator(bremEnergy,
61  bremEnergyFraction,
62  random);
63 
64  }
65 //muon Brem+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
66  if ( doMuonBremsstrahlung ) {
67 
68  double bremEnergy = matEff.getParameter<double>("bremEnergy");
69  double bremEnergyFraction = matEff.getParameter<double>("bremEnergyFraction");
70  MuonBremsstrahlung = new MuonBremsstrahlungSimulator(random,A,Z,density,radLen,bremEnergy,
71  bremEnergyFraction);
72 
73  }
74 
75 
76  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
77 
78  if ( doEnergyLoss ) {
79 
80  pTmin = matEff.getParameter<double>("pTmin");
81  EnergyLoss = new EnergyLossSimulator(random,A,Z,density,radLen);
82 
83  }
84 
85  if ( doMultipleScattering ) {
86 
87  MultipleScattering = new MultipleScatteringSimulator(random,A,Z,density,radLen);
88 
89  }
90 
91  if ( doNuclearInteraction ) {
92 
93  // The energies simulated
94  std::vector<double> pionEnergies
95  = matEff.getUntrackedParameter<std::vector<double> >("pionEnergies");
96 
97  // The particle types simulated
98  std::vector<int> pionTypes
99  = matEff.getUntrackedParameter<std::vector<int> >("pionTypes");
100 
101  // The corresponding particle names
102  std::vector<std::string> pionNames
103  = matEff.getUntrackedParameter<std::vector<std::string> >("pionNames");
104 
105  // The corresponding particle masses
106  std::vector<double> pionMasses
107  = matEff.getUntrackedParameter<std::vector<double> >("pionMasses");
108 
109  // The smallest momentum for inelastic interactions
110  std::vector<double> pionPMin
111  = matEff.getUntrackedParameter<std::vector<double> >("pionMinP");
112 
113  // The interaction length / radiation length ratio for each particle type
114  std::vector<double> lengthRatio
115  = matEff.getParameter<std::vector<double> >("lengthRatio");
116  // std::map<int,double> lengthRatio;
117  // for ( unsigned i=0; i<theLengthRatio.size(); ++i )
118  // lengthRatio[ pionTypes[i] ] = theLengthRatio[i];
119 
120  // A global fudge factor for TEC layers (which apparently do not react to
121  // hadrons the same way as all other layers...
122  theTECFudgeFactor = matEff.getParameter<double>("fudgeFactor");
123 
124  // The evolution of the interaction lengths with energy
125  std::vector<double> theRatios
126  = matEff.getUntrackedParameter<std::vector<double> >("ratios");
127  //std::map<int,std::vector<double> > ratios;
128  //for ( unsigned i=0; i<pionTypes.size(); ++i ) {
129  // for ( unsigned j=0; j<pionEnergies.size(); ++j ) {
130  // ratios[ pionTypes[i] ].push_back(theRatios[ i*pionEnergies.size() + j ]);
131  // }
132  //}
133  std::vector< std::vector<double> > ratios;
134  ratios.resize(pionTypes.size());
135  for ( unsigned i=0; i<pionTypes.size(); ++i ) {
136  for ( unsigned j=0; j<pionEnergies.size(); ++j ) {
137  ratios[i].push_back(theRatios[ i*pionEnergies.size() + j ]);
138  }
139  }
140 
141  // The smallest momentum for elastic interactions
142  double pionEnergy
143  = matEff.getParameter<double>("pionEnergy");
144 
145  // The algorithm to compute the distance between primary and secondaries
146  // when a nuclear interaction occurs
147  unsigned distAlgo
148  = matEff.getParameter<unsigned>("distAlgo");
149  double distCut
150  = matEff.getParameter<double>("distCut");
151 
152  // The file to read the starting interaction in each files
153  // (random reproducibility in case of a crash)
154  std::string inputFile
155  = matEff.getUntrackedParameter<std::string>("inputFile");
156 
157  // Build the ID map (i.e., what is to be considered as a proton, etc...)
158  std::map<int,int> idMap;
159  // Protons
160  std::vector<int> idProtons
161  = matEff.getUntrackedParameter<std::vector<int> >("protons");
162  for ( unsigned i=0; i<idProtons.size(); ++i )
163  idMap[idProtons[i]] = 2212;
164  // Anti-Protons
165  std::vector<int> idAntiProtons
166  = matEff.getUntrackedParameter<std::vector<int> >("antiprotons");
167  for ( unsigned i=0; i<idAntiProtons.size(); ++i )
168  idMap[idAntiProtons[i]] = -2212;
169  // Neutrons
170  std::vector<int> idNeutrons
171  = matEff.getUntrackedParameter<std::vector<int> >("neutrons");
172  for ( unsigned i=0; i<idNeutrons.size(); ++i )
173  idMap[idNeutrons[i]] = 2112;
174  // Anti-Neutrons
175  std::vector<int> idAntiNeutrons
176  = matEff.getUntrackedParameter<std::vector<int> >("antineutrons");
177  for ( unsigned i=0; i<idAntiNeutrons.size(); ++i )
178  idMap[idAntiNeutrons[i]] = -2112;
179  // K0L's
180  std::vector<int> idK0Ls
181  = matEff.getUntrackedParameter<std::vector<int> >("K0Ls");
182  for ( unsigned i=0; i<idK0Ls.size(); ++i )
183  idMap[idK0Ls[i]] = 130;
184  // K+'s
185  std::vector<int> idKplusses
186  = matEff.getUntrackedParameter<std::vector<int> >("Kplusses");
187  for ( unsigned i=0; i<idKplusses.size(); ++i )
188  idMap[idKplusses[i]] = 321;
189  // K-'s
190  std::vector<int> idKminusses
191  = matEff.getUntrackedParameter<std::vector<int> >("Kminusses");
192  for ( unsigned i=0; i<idKminusses.size(); ++i )
193  idMap[idKminusses[i]] = -321;
194  // pi+'s
195  std::vector<int> idPiplusses
196  = matEff.getUntrackedParameter<std::vector<int> >("Piplusses");
197  for ( unsigned i=0; i<idPiplusses.size(); ++i )
198  idMap[idPiplusses[i]] = 211;
199  // pi-'s
200  std::vector<int> idPiminusses
201  = matEff.getUntrackedParameter<std::vector<int> >("Piminusses");
202  for ( unsigned i=0; i<idPiminusses.size(); ++i )
203  idMap[idPiminusses[i]] = -211;
204 
205  // Construction
207  new NuclearInteractionSimulator(pionEnergies, pionTypes, pionNames,
208  pionMasses, pionPMin, pionEnergy,
209  lengthRatio, ratios, idMap,
210  inputFile, distAlgo, distCut, random);
211  }
212 
213 }
214 
215 
217 
218  if ( PairProduction ) delete PairProduction;
219  if ( Bremsstrahlung ) delete Bremsstrahlung;
220  if ( EnergyLoss ) delete EnergyLoss;
223 //Muon Brem
225 }
226 
228  const TrackerLayer& layer,
229  ParticlePropagator& myTrack,
230  unsigned itrack) {
231 
233  double radlen;
234  theEnergyLoss = 0;
235  theNormalVector = normalVector(layer,myTrack);
236  radlen = radLengths(layer,myTrack);
237 
238 //-------------------
239 // Photon Conversion
240 //-------------------
241 
242  if ( PairProduction && myTrack.pid()==22 ) {
243 
244  //
245  PairProduction->updateState(myTrack,radlen);
246 
247  if ( PairProduction->nDaughters() ) {
248  //add a vertex to the mother particle
249  int ivertex = mySimEvent.addSimVertex(myTrack.vertex(),itrack,
251 
252  // Check if it is a valid vertex first:
253  if (ivertex>=0) {
254  // This was a photon that converted
255  for ( DaughterIter = PairProduction->beginDaughters();
256  DaughterIter != PairProduction->endDaughters();
257  ++DaughterIter) {
258 
259  mySimEvent.addSimTrack(&(*DaughterIter), ivertex);
260 
261  }
262  // The photon converted. Return.
263  return;
264  }
265  else {
266  edm::LogWarning("MaterialEffects") << " WARNING: A non valid vertex was found in photon conv. -> " << ivertex << std::endl;
267  }
268 
269  }
270 
271  }
272 
273  if ( myTrack.pid() == 22 ) return;
274 
275 //------------------------
276 // Nuclear interactions
277 //------------------------
278 
279  if ( NuclearInteraction && abs(myTrack.pid()) > 100
280  && abs(myTrack.pid()) < 1000000) {
281 
282  // Simulate a nuclear interaction
283  double factor = 1.0;
284  if (layer.layerNumber() >= 19 && layer.layerNumber() <= 27 )
285  factor = theTECFudgeFactor;
286  NuclearInteraction->updateState(myTrack,radlen*factor);
287 
288  if ( NuclearInteraction->nDaughters() ) {
289 
290  //add a end vertex to the mother particle
291  int ivertex = mySimEvent.addSimVertex(myTrack.vertex(),itrack,
293 
294  // Check if it is a valid vertex first:
295  if (ivertex>=0) {
296  // This was a hadron that interacted inelastically
297  int idaugh = 0;
298  for ( DaughterIter = NuclearInteraction->beginDaughters();
299  DaughterIter != NuclearInteraction->endDaughters();
300  ++DaughterIter) {
301 
302  // The daughter in the event
303  int daughId = mySimEvent.addSimTrack(&(*DaughterIter), ivertex);
304 
305  // Store the closest daughter in the mother info (for later tracking purposes)
306  if ( NuclearInteraction->closestDaughterId() == idaugh++ ) {
307  if ( mySimEvent.track(itrack).vertex().position().Pt() < 4.0 )
308  mySimEvent.track(itrack).setClosestDaughterId(daughId);
309  }
310 
311  }
312  // The hadron is destroyed. Return.
313  return;
314  }
315  else {
316  edm::LogWarning("MaterialEffects") << " WARNING: A non valid vertex was found in nucl. int. -> " << ivertex << std::endl;
317  }
318 
319  }
320 
321  }
322 
323  if ( myTrack.charge() == 0 ) return;
324 
326 
327 //----------------
328 // Bremsstrahlung
329 //----------------
330 
331  if ( Bremsstrahlung && abs(myTrack.pid())==11 ) {
332 
333  Bremsstrahlung->updateState(myTrack,radlen);
334 
335  if ( Bremsstrahlung->nDaughters() ) {
336 
337  // Add a vertex, but do not attach it to the electron, because it
338  // continues its way...
339  int ivertex = mySimEvent.addSimVertex(myTrack.vertex(),itrack,
341 
342  // Check if it is a valid vertex first:
343  if (ivertex>=0) {
344  for ( DaughterIter = Bremsstrahlung->beginDaughters();
345  DaughterIter != Bremsstrahlung->endDaughters();
346  ++DaughterIter) {
347  mySimEvent.addSimTrack(&(*DaughterIter), ivertex);
348  }
349  }
350  else {
351  edm::LogWarning("MaterialEffects") << " WARNING: A non valid vertex was found in brem -> " << ivertex << std::endl;
352  }
353 
354  }
355 
356  }
357 
358 //---------------------------
359 // Muon_Bremsstrahlung
360 //--------------------------
361 
362  if ( MuonBremsstrahlung && abs(myTrack.pid())==13 ) {
363 
364  MuonBremsstrahlung->updateState(myTrack,radlen);
365 
366  if ( MuonBremsstrahlung->nDaughters() ) {
367 
368  // Add a vertex, but do not attach it to the muon, because it
369  // continues its way...
370  int ivertex = mySimEvent.addSimVertex(myTrack.vertex(),itrack,
372 
373  // Check if it is a valid vertex first:
374  if (ivertex>=0) {
375  for ( DaughterIter = MuonBremsstrahlung->beginDaughters();
376  DaughterIter != MuonBremsstrahlung->endDaughters();
377  ++DaughterIter) {
378  mySimEvent.addSimTrack(&(*DaughterIter), ivertex);
379  }
380  }
381  else {
382  edm::LogWarning("MaterialEffects") << " WARNING: A non valid vertex was found in muon brem -> " << ivertex << std::endl;
383  }
384 
385  }
386 
387  }
388 
392 
393  if ( EnergyLoss )
394  {
395  theEnergyLoss = myTrack.E();
396  EnergyLoss->updateState(myTrack,radlen);
397  theEnergyLoss -= myTrack.E();
398  }
399 
400 
404 
405  if ( MultipleScattering && myTrack.Pt() > pTmin ) {
406  // MultipleScattering->setNormalVector(normalVector(layer,myTrack));
408  MultipleScattering->updateState(myTrack,radlen);
409  }
410 
411 }
412 
413 double
415  ParticlePropagator& myTrack) {
416 
417  // Thickness of layer
419 
420  GlobalVector P(myTrack.Px(),myTrack.Py(),myTrack.Pz());
421 
422  // Effective length of track inside layer (considering crossing angle)
423  // double radlen = theThickness / fabs(P.dot(theNormalVector)/(P.mag()*theNormalVector.mag()));
424  double radlen = theThickness / fabs(P.dot(theNormalVector)) * P.mag();
425 
426  // This is a series of fudge factors (from the geometry description),
427  // to describe the layer inhomogeneities (services, cables, supports...)
428  double rad = myTrack.R();
429  double zed = fabs(myTrack.Z());
430 
431  double factor = 1;
432 
433  // Are there fudge factors for this layer
434  if ( layer.fudgeNumber() )
435 
436  // If yes, loop on them
437  for ( unsigned int iLayer=0; iLayer < layer.fudgeNumber(); ++iLayer ) {
438 
439  // Apply to R if forward layer, to Z if barrel layer
440  if ( ( layer.forward() && layer.fudgeMin(iLayer) < rad && rad < layer.fudgeMax(iLayer) ) ||
441  ( !layer.forward() && layer.fudgeMin(iLayer) < zed && zed < layer.fudgeMax(iLayer) ) ) {
442  factor = layer.fudgeFactor(iLayer);
443  break;
444  }
445 
446  }
447 
448  theThickness *= factor;
449 
450  return radlen * factor;
451 
452 }
453 
456  ParticlePropagator& myTrack ) const {
457  return layer.forward() ?
458  layer.disk()->normalVector() :
459  GlobalVector(myTrack.X(),myTrack.Y(),0.)/myTrack.R();
460 }
461 
462 void
464 
465  // Save current nuclear interactions in the event libraries.
467 
468 }
const double Z[kNumberCalorimeter]
T getParameter(std::string const &) const
int addSimVertex(const XYZTLorentzVector &decayVertex, int im=-1, FSimVertexType::VertexType type=FSimVertexType::ANY)
Add a new vertex to the Event and to the various lists.
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
float radLen() const
RHEP_const_iter beginDaughters() const
Returns const iterator to the beginning of the daughters list.
MaterialEffects(const edm::ParameterSet &matEff, const RandomEngine *engine)
Constructor.
int addSimTrack(const RawParticle *p, int iv, int ig=-1, const HepMC::GenVertex *ev=0)
Add a new track to the Event and to the various lists.
unsigned nDaughters() const
Returns the number of daughters.
unsigned int layerNumber() const
Returns the layer number.
Definition: TrackerLayer.h:82
bool forward() const
Is the layer forward ?
Definition: TrackerLayer.h:70
double fudgeFactor(unsigned iFudge) const
Definition: TrackerLayer.h:108
int closestDaughterId()
The id of the closest charged daughter (filled for nuclear interactions only)
void setNormalVector(const GlobalVector &normal)
Sets the vector normal to the surface traversed.
~MaterialEffects()
Default destructor.
PairProductionSimulator * PairProduction
GlobalVector normalVector() const
Definition: Plane.h:47
const RandomEngine * random
#define abs(x)
Definition: mlp_lapack.h:159
#define P
GlobalVector normalVector(const TrackerLayer &layer, ParticlePropagator &myTrack) const
The vector normal to the surface traversed.
void setClosestDaughterId(int id)
Set the index of the closest charged daughter.
Definition: FSimTrack.h:184
int pid() const
get the HEP particle ID number
Definition: RawParticle.h:264
TRandom random
Definition: MVATrainer.cc:138
MuonBremsstrahlungSimulator * MuonBremsstrahlung
const MediumProperties * mediumProperties() const
Definition: Surface.h:93
double R() const
vertex radius
Definition: RawParticle.h:277
BoundDisk * disk() const
Returns the surface.
Definition: TrackerLayer.h:79
double fudgeMax(unsigned iFudge) const
Definition: TrackerLayer.h:105
std::vector< RawParticle >::const_iterator RHEP_const_iter
const math::XYZTLorentzVector & position() const
Temporary (until CMSSW moves to Mathcore) - No ! Actually very useful.
Definition: FSimVertex.h:49
double Y() const
y of vertex
Definition: RawParticle.h:274
double Z() const
z of vertex
Definition: RawParticle.h:275
RHEP_const_iter endDaughters() const
Returns const iterator to the end of the daughters list.
int j
Definition: DBlmapReader.cc:9
void save()
Save nuclear interaction information.
const FSimVertex & vertex() const
Origin vertex.
double charge() const
get the MEASURED charge
Definition: RawParticle.h:281
unsigned int fudgeNumber() const
Set a fudge factor for material inhomogeneities in this layer.
Definition: TrackerLayer.h:101
const BoundSurface & surface() const
Returns the surface.
Definition: TrackerLayer.h:73
const XYZTLorentzVector & vertex() const
the vertex fourvector
Definition: RawParticle.h:284
double radLengths(const TrackerLayer &layer, ParticlePropagator &myTrack)
The number of radiation lengths traversed.
void updateState(ParticlePropagator &myTrack, double radlen)
Compute the material effect (calls the sub class)
double X() const
x of vertex
Definition: RawParticle.h:273
BremsstrahlungSimulator * Bremsstrahlung
void interact(FSimEvent &simEvent, const TrackerLayer &layer, ParticlePropagator &PP, unsigned i)
GlobalVector theNormalVector
double fudgeMin(unsigned iFudge) const
Definition: TrackerLayer.h:102
EnergyLossSimulator * EnergyLoss
NuclearInteractionSimulator * NuclearInteraction
void save()
Save current nuclear interaction (for later use)
MultipleScatteringSimulator * MultipleScattering
Global3DVector GlobalVector
Definition: GlobalVector.h:10
FSimTrack & track(int id) const
Return track with given Id.