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