CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CSCGasCollisions.cc
Go to the documentation of this file.
1 // This implements the CSC gas ionization simulation.
2 // It requires the GEANT3-generated tables in the input file
3 // (default) MuonData/EndcapData/collisions.dat
4 
5 // Outstanding problems to fix 15-Oct-2003
6 // - ework must be re-tuned once eion or ework are removed before delta e range estimation.
7 // - logic of long-range delta e's must be revisited.
8 // - The code here needs to have diagnostic output removed, or reduced. PARTICULARLY filling of std::vectors!
9 // - 'gap' is a misnomer, when simhit entry and exit don't coincide with gap edges
10 // so the CSCCrossGap might better be named as a simhit-related thing.
11 // 22-Jan-2004 Corrected position of trap for 'infinite' loop while
12 // generating steps. Output files (debugV-flagged only) require SC flag.
13 // Increase deCut from 10 keV to 100 keV to accomodate protons!
14 
20 #include <iostream>
21 #include <fstream>
22 #include <cassert>
23 
24 // stdlib math functions
25 // for 'abs':
26 #include <cstdlib>
27 // for usual math functions:
28 #include <cmath>
29 
30 // stdlib container trickery
31 // for 'for_each':
32 #include <algorithm>
33 // for 'greater' and 'less':
34 #include <functional>
35 // for 'accumulate':
36 #include <numeric>
37 #include <iterator>
38 
39 using namespace std;
40 /* Gas mixture is Ar/CO2/CF4 = 40/50/10
41 We'll use the ioinzation energies
42 Ar 15.8 eV
43 CO2 13.7 eV
44 CF4 17.8
45 to arrive at a weighted average of 14.95 */
46 
47 CSCGasCollisions::CSCGasCollisions() : me("CSCGasCollisions"),
48  gasDensity( 2.1416e-03 ),
49  deCut( 1.e05 ), eion( 14.95 ), ework( 34.0 ), clusterExtent( 0.001 ),
50  theGammaBins(N_GAMMA, 0.), theEnergyBins(N_ENERGY, 0.),
51  theCollisionTable(N_ENTRIES, 0.), theCrossGap( 0 ),
52  theParticleDataTable(0),
53  theRandFlat(0),
54  theRandExponential(0),
55  saveGasCollisions ( false )
56 {
57 
58  edm::LogInfo(me) << "Constructing a " << me << ":";
59  edm::LogInfo(me) << "gas density = " << gasDensity << " g/cm3";
60  edm::LogInfo(me) << "max eloss per collision allowed = " << deCut/1000.
61  << " keV (for higher elosses, hits should have been simulated.)";
62  edm::LogInfo(me) << "ionization threshold = " << eion << " eV";
63  edm::LogInfo(me) << "effective work function = " << ework << " eV";
64  edm::LogInfo(me) << "cluster extent = " << clusterExtent*1.e04 << " micrometres";
65  edm::LogInfo(me) << "Save gas collision info to files when using debugV? " << saveGasCollisions;
66 
68 }
69 
71  edm::LogInfo(me) << "Destructing a " << me;
72  delete theCrossGap;
73  delete theRandFlat;
74  delete theRandExponential;
75 }
76 
78 
79  // I'd prefer to allow comments in the data file which means
80  // complications of reading line-by-line and then item-by-item.
81 
82  // Is float OK? Or do I need double?
83 
84  // Do I need any sort of error trapping?
85 
86  // We use the default CMSSW data file path
87  // We use the default file name 'collisions.dat'
88 
89  // This can be reset in .orcarc by SimpleConfigurable
90  // Muon:Endcap:CollisionsFile
91 
92  string path( getenv( "CMSSW_SEARCH_PATH" ) );
93  // TODO make configurable
94  string colliFile = "SimMuon/CSCDigitizer/data/collisions.dat";
95  FileInPath f1( path, colliFile );
96  if (f1() == 0 ) {
97  string errorMessage = "Input file " + colliFile + "not found";
98  edm::LogError("CSCGasCollisions") << errorMessage << " in path " << path
99  << "\nSet Muon:Endcap:CollisionsFile in .orcarc to the "
100  " location of the file relative to ORCA_DATA_PATH." ;
101  throw cms::Exception( " Endcap Muon gas collisions data file not found.");
102  }
103  else {
104  edm::LogInfo(me) << ": reading " << f1.name();
105  }
106 
107  ifstream & fin = *f1();
108 
109  if (fin == 0) {
110  string errorMessage = "Cannot open input file " + path + colliFile;
111  edm::LogError("CSCGasCollisions") << errorMessage;
112  throw cms::Exception(errorMessage);
113  }
114 
115  fin.clear( ); // Clear eof read status
116  fin.seekg( 0, ios::beg ); // Position at start of file
117 
118  // @@ We had better have the right sizes everywhere or all
119  // hell will break loose. There's no trapping.
120  LogTrace(me) << "Reading gamma bins";
121  int j = 0;
122  for(int i = 0; i<N_GAMMA; ++i) {
123  fin >> theGammaBins[i];
124  LogTrace(me) << ++j << " " << theGammaBins[i];
125  }
126 
127  j = 0;
128  LogTrace(me) << "Reading energy bins \n";
129  for(int i = 0; i<N_ENERGY; ++i) {
130  fin >> theEnergyBins[i];
131  LogTrace(me) << ++j << " " << theEnergyBins[i];
132  }
133 
134  j = 0;
135  LogTrace(me) << "Reading collisions table \n";
136 
137  for(int i = 0; i<N_ENTRIES; ++i) {
138  fin >> theCollisionTable[i];
139  LogTrace(me) << ++j << " " << theCollisionTable[i];
140  }
141 
142  fin.close();
143 }
144 
145 
147 {
148  theParticleDataTable = pdt;
149 }
150 
151 
152 void CSCGasCollisions::setRandomEngine(CLHEP::HepRandomEngine & engine)
153 {
154  theRandFlat = new CLHEP::RandFlat(engine);
155  theRandExponential = new CLHEP::RandExponential(engine);
156 }
157 
158 
159 void CSCGasCollisions::simulate( const PSimHit& simHit,
160  std::vector<LocalPoint>& positions, std::vector<int>& electrons ) {
161 
162  const float epsilonL = 0.01; // Shortness of simhit 'length'
163  // const float max_gap_z = 1.5; // Gas gaps are 0.5 or 1.0 cm
164 
165  // Note that what I call the 'gap' may in fact be the 'length' of a PSimHit which
166  // does not start and end on the gap edges. This confuses the nomenclature at least.
167 
168  double mom = simHit.pabs();
169  int iam = simHit.particleType(); // PDG type
170  delete theCrossGap; // before building new one
171  assert(theParticleDataTable != 0);
172  ParticleData const * particle = theParticleDataTable->particle( simHit.particleType() );
173  double mass = 0.105658; // assume a muon
174  if(particle == 0)
175  {
176  edm::LogError("CSCGasCollisions") << "Cannot find particle of type " << simHit.particleType()
177  << " in the PDT";
178  }
179  else
180  {
181  mass = particle->mass();
182  }
183 
184  theCrossGap = new CSCCrossGap( mass, mom, simHit.exitPoint() - simHit.entryPoint() );
185  float gapSize = theCrossGap->length();
186 
187  // Test the simhit 'length' (beware of angular effects)
188  // if ( gapSize <= epsilonL || gapSize > max_gap_z ) {
189  if ( gapSize <= epsilonL ) {
190  LogTrace(me) << ": WARNING! simhit entry and exit are very close: \n"
191  << "\n entry = " << simHit.entryPoint()
192  << "\n exit = " << simHit.exitPoint()
193  << "\n particle type = " << iam << ", momentum = " << mom
194  << ", gap length = " << gapSize;
195  return; //@@ Just skip this PSimHit
196  }
197 
198  // Interpolate the table for current gamma value
199  // Extract collisions binned by energy loss values, for this gamma
200  std::vector<float> collisions(N_ENERGY);
201  double loggam = theCrossGap->logGamma();
202  fillCollisionsForThisGamma( static_cast<float>(loggam), collisions );
203 
204  double anmin = exp(collisions[N_ENERGY-1]);
205  double anmax = exp(collisions[0]);
206  double amu = anmax - anmin;
207 
208  LogTrace(me) << "collisions extremes = " << collisions[N_ENERGY-1]
209  << ", " << collisions[0] << "\n"
210  << "anmin = " << anmin << ", anmax = " << anmax << "\n"
211  << "amu = " << amu << "\n";
212 
213  float dedx = 0.; // total energy loss
214  double sum_steps = 0.; // total distance across gap (along simhit direction)
215  int n_steps = 0; // no. of steps/primary collisions
216  int n_try = 0; // no. of tries to generate steps
217  double step = -1.; // Sentinel for start
218 
219  LocalPoint layerLocalPoint( simHit.entryPoint() );
220 
221  // step/primary collision loop
222  while ( sum_steps < gapSize) {
223  ++n_try;
224  if ( n_try > MAX_STEPS ) {
225  LogTrace(me) << ": n_try=" << n_try << " is too large. Skip simhit."
226  << "\n particle type=" << iam << ", momentum= " << mom
227  << "\n gapSize=" << gapSize << ", last step=" << step
228  << ", sum_steps=" << sum_steps << ", n_steps=" << n_steps;
229  break;
230  }
231  step = generateStep( amu );
232  if ( sum_steps + step > gapSize ) break;
233 
234  float eloss = generateEnergyLoss( amu, anmin, anmax, collisions );
235 
236  // Is the eloss too large? (then GEANT should have produced hits!)
237  if ( eloss > deCut ) {
238  LogTrace(me) << "eloss > " << deCut << " = " << eloss;
239  continue; // to generate another collision/step
240  }
241 
242  dedx += eloss; // the energy lost from the ionizing particle
243  sum_steps += step; // the position of the ionizing particle
244  ++n_steps; // the number of primary collisions
245 
246  if (n_steps > MAX_STEPS ) { // Extra-careful trap for bizarreness
247  edm::LogInfo(me) << ": n_steps=" << n_steps << " is too large. Skip simhit.";
248  edm::LogInfo(me) << "particle type=" << iam << ", momentum= " << mom;
249  edm::LogInfo(me) << "gapSize=" << gapSize << ", last step=" << step
250  << ", sum_steps=" << sum_steps;
251  break;
252  }
253  LogTrace(me) << "sum_steps = " << sum_steps << ", dedx = " << dedx;
254 
255  // Generate ionization.
256  // eion is the minimum energy at which ionization can occur in the gas
257  if ( eloss > eion ) {
258  layerLocalPoint += step * theCrossGap->unitVector(); // local point where the collision occurs
259  ionize( eloss, layerLocalPoint );
260  }
261  else {
262  LogTrace(me) << "Energy available = " << eloss <<
263  ", too low for ionization.";
264  }
265 
266  } // step/collision loop
267 
268  //TODO port this
269  //if ( debugV ) writeSummary( n_steps, sum_steps, dedx, simHit.energyLoss() );
270 
271  // Return values in two container arguments
272  positions = theCrossGap->ionClusters();
273  electrons = theCrossGap->electrons();
274  return;
275 }
276 
277 double CSCGasCollisions::generateStep( double avCollisions ) const
278 {
279 // Generate a m.f.p. (1/avCollisions = cm/collision)
280  double step = (theRandExponential->fire())/avCollisions;
281 
282 // Without using CLHEP: approx random exponential by...
283 // double da = double(rand())/double(RAND_MAX);
284 // double step = -log(1.-da)/avCollisions;
285 
286  LogTrace(me) << " step = " << step;
287  // Next line only used to fill a container of 'step's for later diagnostic dumps
288  //if ( debugV ) theCrossGap->addStep( step );
289  return step;
290 }
291 
292 float CSCGasCollisions::generateEnergyLoss( double avCollisions,
293  double anmin, double anmax, const std::vector<float>& collisions ) const
294 {
295 // Generate a no. of collisions between collisions[0] and [N_ENERGY-1]
296  float lnColl = log(theRandFlat->fire(anmin, anmax));
297 
298 // Without using CLHEP: approx random between anmin and anmax
299 // double ra = double(rand())/double(RAND_MAX)*avCollisions;
300 // cout << "ra = " << ra << std::endl;
301 // float lnColl = static_cast<float>( log( ra ) );
302 
303  // Find energy loss for that number
304  float lnE = lnEnergyLoss( lnColl, collisions );
305  float eloss = exp(lnE);
306  // Compensate if gamma was actually below 1.1
307  if ( theCrossGap->gamma() < 1.1 ) eloss = eloss * 0.173554/theCrossGap->beta2();
308  LogTrace(me) << "eloss = " << eloss;
309  // Next line only used to fill container of eloss's for later diagnostic dumps
310  // if ( debugV ) theCrossGap->addEloss( eloss );
311  return eloss;
312 }
313 
314 void CSCGasCollisions::ionize( double energyAvailable, LocalPoint startHere ) const
315 {
316  while ( energyAvailable > eion ) {
317  LogTrace(me) << " NEW CLUSTER " << theCrossGap->noOfClusters() + 1 <<
318  " AT " << startHere;
319  LocalPoint newCluster( startHere );
320  theCrossGap->addCluster(newCluster);
321 
322  //@@ I consider NOT subtracting eion before calculating range to be a bug.
323  //@@ But this changes tuning of the algorithm so leave it until after the big rush to 7_5_0
324  //@@ energyAvailable -= eion;
325 
326  // Sauli CERN 77-09: delta e range with E in MeV (Sauli references Kobetich & Katz 1968,
327  // but I cannot find this expression in that set of papers.)
328  // Take HALF that range. //@@ Why? Why not...
329  double range = 0.5 * (0.71/gasDensity)*pow( energyAvailable*1.E-6, 1.72);
330  LogTrace(me) << " range = " << range;
331  if ( range < clusterExtent ) {
332 
333  // short-range delta e
334  // How many electrons can we make? Now use *average* energy for ionization (not *minimum*)
335  int nelec = static_cast<int>(energyAvailable/ework);
336  LogTrace(me) << "s-r delta energy in = " << energyAvailable;
337  //energyAvailable -= nelec*(energyAvailable/ework);
338  energyAvailable -= nelec*ework;
339  // If still above eion (minimum, not average) add one more e
340  if ( energyAvailable > eion ) {
341  ++nelec;
342  energyAvailable -= eion;
343  }
344  LogTrace(me) << "s-r delta energy out = " << energyAvailable << ", nelec = " << nelec;
345  theCrossGap->addElectrons( nelec );
346  break;
347 
348  }
349  else {
350  // long-range delta e
351  LogTrace(me) << "l-r delta \n"
352  << "no. of electrons in cluster now = " << theCrossGap->noOfElectrons();
353  theCrossGap->addElectrons( 1 ); // Position is at startHere still
354 
355  bool new_range = false;
356  while ( !new_range && (energyAvailable>ework) ) {
357  energyAvailable -= ework;
358  while ( energyAvailable > eion ) {
359  double range2 = 0.5 * 0.71/gasDensity*pow( 1.E-6*energyAvailable, 1.72);
360  double drange = range - range2;
361  LogTrace(me) << " energy left = " << energyAvailable <<
362  ", range2 = " << range2 << ", drange = " << drange;
363  if ( drange < clusterExtent ) {
364  theCrossGap->addElectronToBack(); // increment last element
365  }
366  else {
367  startHere += drange*theCrossGap->unitVector(); // update delta e start position
368  range = range2; // update range
369  new_range = true; // Test range again
370  LogTrace(me) << "reset range to range2 and iterate";
371  }
372  break; // out of inner while energyAvailable>eion
373 
374  } // inner while energyAvailable>eion
375 
376  } // while !new_range && energyAvailable>ework
377 
378  // energyAvailable now less than ework, but still may be over eion...add an e
379  if ( energyAvailable > eion ) {
380  energyAvailable -= ework; // yes, it may go negative
381  theCrossGap->addElectronToBack(); // add one more e
382  }
383 
384  } // if range
385 
386  } // outer while energyAvailable>eion
387 }
388 
389 void CSCGasCollisions::writeSummary( int n_steps, double sum_steps, float dedx, float simHiteloss ) const
390 {
391  std::vector<LocalPoint> ion_clusters = theCrossGap->ionClusters();
392  std::vector<int> electrons = theCrossGap->electrons();
393  std::vector<float> elosses = theCrossGap->eLossPerStep();
394  std::vector<double> steps = theCrossGap->stepLengths();
395 
396  cout << "------------------" << std::endl;
397  cout << "AFTER CROSSING GAP" << std::endl;
398  cout << "No. of steps = " << n_steps << std::endl;
399  cout << "Check: stored steps = " << theCrossGap->noOfSteps() << std::endl;
400 
401  cout << "Lengths of steps: " << std::endl;
402  std::copy( steps.begin(), steps.end(), std::ostream_iterator<float>(cout,"\n"));
403  cout << std::endl;
404 
405  if ( saveGasCollisions ) {
406  ofstream of0("osteplen.dat",ios::app);
407  std::copy( steps.begin(), steps.end(), std::ostream_iterator<float>(of0,"\n"));
408  }
409 
410  cout << "Total sum of steps = " << sum_steps << std::endl;
411  if ( n_steps > 0 ) cout << "Average step length = " <<
412  sum_steps/float(n_steps) << std::endl;
413  cout << std::endl;
414 
415  cout << "Energy loss per collision:" << std::endl;
416  std::copy( elosses.begin(), elosses.end(), std::ostream_iterator<float>(cout,"\n"));
417  cout << std::endl;
418 
419  if ( saveGasCollisions ) {
420  ofstream of1("olperc.dat",ios::app);
421  std::copy( elosses.begin(), elosses.end(), std::ostream_iterator<float>(of1,"\n"));
422  }
423 
424  cout << "Total energy loss across gap = " << dedx << " eV = " <<
425  dedx/1000. << " keV" << std::endl;
426  int n_ic = count_if( elosses.begin(), elosses.end(),
427  bind2nd(greater<float>(), eion) );
428  cout << "No. of primary ionizing collisions across gap = " << n_ic << std::endl;
429  if ( n_steps > 0 ) cout << "Average energy loss/collision = " <<
430  dedx/float(n_steps) << " eV" << std::endl;
431  cout << std::endl;
432 
433  cout << "No. of ion clusters = " << ion_clusters.size() << std::endl;
434  cout << "Positions of clusters:" << std::endl;
435  std::copy( ion_clusters.begin(), ion_clusters.end(),
436  std::ostream_iterator<LocalPoint>(cout,"\n"));
437  cout << std::endl;
438 
439  if ( saveGasCollisions ) {
440  ofstream of2("oclpos.dat",ios::app);
441  std::copy( ion_clusters.begin(), ion_clusters.end(),
442  std::ostream_iterator<LocalPoint>(of2,"\n"));
443  }
444 
445  cout << "No. of electrons per cluster:" << std::endl;
446  std::copy( electrons.begin(), electrons.end(), std::ostream_iterator<int>(cout,"\n"));
447  cout << std::endl;
448 
449  if ( saveGasCollisions ) {
450  ofstream of3("oepercl.dat",ios::app);
451  std::copy( electrons.begin(), electrons.end(), std::ostream_iterator<int>(of3,"\n"));
452  }
453 
454  // Check for zero-e clusters
455  std::vector<int>::const_iterator bigger = find(electrons.begin(),
456  electrons.end(), 0 );
457  if ( bigger != electrons.end() ) {
458  cout << "Error! There is a cluster with 0 electrons." << std::endl;
459  }
460  int n_e = accumulate(electrons.begin(), electrons.end(), 0 );
461  if ( n_steps > 0 ) {
462  cout << "# cm cm keV eV eV eV keV" << std::endl;
463  cout << " " << n_steps << " " << sum_steps << " " << sum_steps/float(n_steps) << " " <<
464  ion_clusters.size() << " " <<
465  dedx/1000. << " " << n_ic << " " << dedx/float(n_steps) << " " << n_e << " " <<
466  dedx/float(n_e) << " " << float(n_e)/float(ion_clusters.size()) << " " << simHiteloss*1.E6 << std::endl;
467  }
468 }
469 
470 float CSCGasCollisions::lnEnergyLoss( float lnCollisions,
471  const std::vector<float>& collisions ) const {
472 
473  float lnE = -1.;
474 
475  // Find collision[] bin in which lnCollisions falls
476  std::vector<float>::const_iterator it = find(collisions.begin(),
477  collisions.end(), lnCollisions );
478 
479  if ( it != collisions.end() ) {
480  // found the value
481  std::vector<float>::difference_type ihi = it - collisions.begin();
482  LogTrace(me) << ": using one energy bin " << ihi << " = "
483  << theEnergyBins[ihi]
484  << " for lnCollisions = " << lnCollisions;
485  lnE = theEnergyBins[ihi];
486  }
487  else {
488  // interpolate the value
489  std::vector<float>::const_iterator loside = find_if(collisions.begin(),
490  collisions.end(), bind2nd(less<float>(), lnCollisions));
491  std::vector<float>::difference_type ilo = loside - collisions.begin();
492  if ( ilo > 0 ) {
493  LogTrace(me) << ": using energy bin "
494  << ilo-1 << " and " << ilo;
495  lnE = theEnergyBins[ilo-1] + (lnCollisions-collisions[ilo-1])*
496  (theEnergyBins[ilo]-theEnergyBins[ilo-1]) /
497  (collisions[ilo]-collisions[ilo-1]);
498  }
499  else {
500  LogTrace(me) << ": using one energy bin 0 = "
501  << theEnergyBins[0]
502  << " for lnCollisions = " << lnCollisions;
503  lnE = theEnergyBins[0]; //@@ WHAT ELSE TO DO?
504  }
505  }
506 
507  return lnE;
508 }
509 
511  std::vector<float>& collisions ) const
512 {
513  std::vector<float>::const_iterator bigger = find_if(theGammaBins.begin(),
514  theGammaBins.end(), bind2nd(greater<float>(), logGamma));
515 
516  if ( bigger == theGammaBins.end() ) {
517  // use highest bin
518  LogTrace(me) << ": using highest gamma bin"
519  << " for logGamma = " << logGamma;
520  for (int i=0; i<N_ENERGY; ++i)
521  collisions[i] = theCollisionTable[i*N_GAMMA];
522  }
523  else {
524  // use bigger and its lower neighbour
525  std::vector<float>::difference_type ihi = bigger - theGammaBins.begin();
526  if ( ihi > 0 ) {
527  double dlg2 = *bigger--; // and decrement after deref
528  //LogTrace(me) << ": using gamma bins "
529  // << ihi-1 << " and " << ihi;
530  double dlg1 = *bigger; // now the preceding element
531  double dlg = (logGamma-dlg1)/(dlg2-dlg1);
532  double omdlg = 1. - dlg;
533  for (int i=0; i<N_ENERGY; ++i)
534  collisions[i] = theCollisionTable[i*N_GAMMA+ihi-1]*omdlg +
535  theCollisionTable[i*N_GAMMA+ihi]*dlg;
536  }
537  else {
538  // bigger has no lower neighbour
539  LogTrace(me) << ": using lowest gamma bin"
540  << " for logGamma = " << logGamma;
541 
542  for (int i=0; i<N_ENERGY; ++i)
543  collisions[i] = theCollisionTable[i*N_GAMMA];
544  }
545  }
546 }
void simulate(const PSimHit &, std::vector< LocalPoint > &clusters, std::vector< int > &electrons)
int i
Definition: DBlmapReader.cc:9
std::vector< int > electrons() const
Definition: CSCCrossGap.h:35
HepPDT::ParticleDataTable ParticleDataTable
int noOfClusters() const
Definition: CSCCrossGap.h:34
static const int N_ENERGY
void writeSummary(int n_steps, double sum_steps, float dedx, float simHiteloss) const
std::vector< LocalPoint > ionClusters() const
Definition: CSCCrossGap.h:33
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
void addElectronToBack()
Definition: CSCCrossGap.h:44
std::vector< float > eLossPerStep() const
Definition: CSCCrossGap.h:39
std::vector< double > stepLengths() const
Definition: CSCCrossGap.h:37
std::vector< float > theGammaBins
const std::string me
float lnEnergyLoss(float, const std::vector< float > &) const
Local3DPoint exitPoint() const
Exit point in the local Det frame.
Definition: PSimHit.h:38
const ParticleDataTable * theParticleDataTable
double gamma() const
Definition: CSCCrossGap.h:52
LocalVector unitVector() const
Definition: CSCCrossGap.h:54
int noOfElectrons() const
Definition: CSCCrossGap.h:36
int j
Definition: DBlmapReader.cc:9
static const int N_GAMMA
static const int MAX_STEPS
float pabs() const
fast and more accurate access to momentumAtEntry().mag()
Definition: PSimHit.h:63
HepPDT::ParticleData ParticleData
void setParticleDataTable(const ParticleDataTable *pdt)
void ionize(double energyTransferred, LocalPoint startHere) const
#define LogTrace(id)
static const int N_ENTRIES
CLHEP::RandExponential * theRandExponential
double logGamma(double mass, float momentum)
Definition: CSCCrossGap.cc:23
std::vector< float > theCollisionTable
int noOfSteps() const
Definition: CSCCrossGap.h:38
double generateStep(double avCollisions) const
double beta2() const
Definition: CSCCrossGap.h:51
float generateEnergyLoss(double avCollisions, double anmin, double anmax, const std::vector< float > &collisions) const
std::vector< float > theEnergyBins
const String & name() const
return full name
Definition: FileInPath.h:34
int particleType() const
Definition: PSimHit.h:85
float length() const
Definition: CSCCrossGap.h:55
void fillCollisionsForThisGamma(float, std::vector< float > &) const
CSCCrossGap * theCrossGap
tuple cout
Definition: gather_cfg.py:121
void addCluster(LocalPoint here)
Definition: CSCCrossGap.h:42
virtual ~CSCGasCollisions()
Local3DPoint entryPoint() const
Entry point in the local Det frame.
Definition: PSimHit.h:35
CLHEP::RandFlat * theRandFlat
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
void setRandomEngine(CLHEP::HepRandomEngine &engine)
void addElectrons(int nelec=1)
Definition: CSCCrossGap.h:43