CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
List of all members | Public Member Functions | Static Public Attributes | Private Member Functions | Private Attributes
CSCGasCollisions Class Reference

#include <CSCGasCollisions.h>

Public Member Functions

 CSCGasCollisions ()
 
void setParticleDataTable (const ParticleDataTable *pdt)
 
void simulate (const PSimHit &, std::vector< LocalPoint > &clusters, std::vector< int > &electrons, CLHEP::HepRandomEngine *)
 
virtual ~CSCGasCollisions ()
 

Static Public Attributes

static const int MAX_STEPS = 400
 
static const int N_ENERGY = 63
 
static const int N_ENTRIES = N_GAMMA*N_ENERGY
 
static const int N_GAMMA = 21
 

Private Member Functions

void fillCollisionsForThisGamma (float, std::vector< float > &) const
 
float generateEnergyLoss (double avCollisions, double anmin, double anmax, const std::vector< float > &collisions, CLHEP::HepRandomEngine *) const
 
double generateStep (double avCollisions, CLHEP::HepRandomEngine *) const
 
void ionize (double energyTransferred, LocalPoint startHere) const
 
float lnEnergyLoss (float, const std::vector< float > &) const
 
void readCollisionTable ()
 
void writeSummary (int n_steps, double sum_steps, float dedx, float simHiteloss) const
 

Private Attributes

double clusterExtent
 
double deCut
 
double eion
 
double ework
 
double gasDensity
 
const std::string me
 
bool saveGasCollisions
 
std::vector< float > theCollisionTable
 
CSCCrossGaptheCrossGap
 
std::vector< float > theEnergyBins
 
std::vector< float > theGammaBins
 
const ParticleDataTabletheParticleDataTable
 

Detailed Description

Class to handle CSC gas ionization simulation during digitization.

Author
Tim Cox

This class contains the port of the old CMSIM/ORCA Fortran routine mc_clus.F, and the GEANT3 code it relied on. Of course the version here is much improved :)

Definition at line 26 of file CSCGasCollisions.h.

Constructor & Destructor Documentation

CSCGasCollisions::CSCGasCollisions ( )

Definition at line 51 of file CSCGasCollisions.cc.

References clusterExtent, deCut, eion, ework, gasDensity, me, readCollisionTable(), and saveGasCollisions.

51  : me("CSCGasCollisions"),
52  gasDensity( 2.1416e-03 ),
53  deCut( 1.e05 ), eion( 14.95 ), ework( 34.0 ), clusterExtent( 0.001 ),
57  saveGasCollisions ( false )
58 {
59 
60  edm::LogInfo(me) << "Constructing a " << me << ":";
61  edm::LogInfo(me) << "gas density = " << gasDensity << " g/cm3";
62  edm::LogInfo(me) << "max eloss per collision allowed = " << deCut/1000.
63  << " keV (for higher elosses, hits should have been simulated.)";
64  edm::LogInfo(me) << "ionization threshold = " << eion << " eV";
65  edm::LogInfo(me) << "effective work function = " << ework << " eV";
66  edm::LogInfo(me) << "cluster extent = " << clusterExtent*1.e04 << " micrometres";
67  edm::LogInfo(me) << "Save gas collision info to files when using debugV? " << saveGasCollisions;
68 
70 }
static const int N_ENERGY
std::vector< float > theGammaBins
const std::string me
const ParticleDataTable * theParticleDataTable
static const int N_GAMMA
static const int N_ENTRIES
std::vector< float > theCollisionTable
std::vector< float > theEnergyBins
CSCCrossGap * theCrossGap
CSCGasCollisions::~CSCGasCollisions ( )
virtual

Definition at line 72 of file CSCGasCollisions.cc.

References me, and theCrossGap.

72  {
73  edm::LogInfo(me) << "Destructing a " << me;
74  delete theCrossGap;
75 }
const std::string me
CSCCrossGap * theCrossGap

Member Function Documentation

void CSCGasCollisions::fillCollisionsForThisGamma ( float  logGamma,
std::vector< float > &  collisions 
) const
private

Definition at line 505 of file CSCGasCollisions.cc.

References i, LogTrace, me, N_ENERGY, N_GAMMA, theCollisionTable, and theGammaBins.

Referenced by simulate().

507 {
508  std::vector<float>::const_iterator bigger = find_if(theGammaBins.begin(),
509  theGammaBins.end(), bind2nd(greater<float>(), logGamma));
510 
511  if ( bigger == theGammaBins.end() ) {
512  // use highest bin
513  LogTrace(me) << ": using highest gamma bin"
514  << " for logGamma = " << logGamma;
515  for (int i=0; i<N_ENERGY; ++i)
516  collisions[i] = theCollisionTable[i*N_GAMMA];
517  }
518  else {
519  // use bigger and its lower neighbour
520  std::vector<float>::difference_type ihi = bigger - theGammaBins.begin();
521  if ( ihi > 0 ) {
522  double dlg2 = *bigger--; // and decrement after deref
523  //LogTrace(me) << ": using gamma bins "
524  // << ihi-1 << " and " << ihi;
525  double dlg1 = *bigger; // now the preceding element
526  double dlg = (logGamma-dlg1)/(dlg2-dlg1);
527  double omdlg = 1. - dlg;
528  for (int i=0; i<N_ENERGY; ++i)
529  collisions[i] = theCollisionTable[i*N_GAMMA+ihi-1]*omdlg +
530  theCollisionTable[i*N_GAMMA+ihi]*dlg;
531  }
532  else {
533  // bigger has no lower neighbour
534  LogTrace(me) << ": using lowest gamma bin"
535  << " for logGamma = " << logGamma;
536 
537  for (int i=0; i<N_ENERGY; ++i)
538  collisions[i] = theCollisionTable[i*N_GAMMA];
539  }
540  }
541 }
int i
Definition: DBlmapReader.cc:9
static const int N_ENERGY
std::vector< float > theGammaBins
const std::string me
static const int N_GAMMA
#define LogTrace(id)
std::vector< float > theCollisionTable
float CSCGasCollisions::generateEnergyLoss ( double  avCollisions,
double  anmin,
double  anmax,
const std::vector< float > &  collisions,
CLHEP::HepRandomEngine *  engine 
) const
private

Definition at line 286 of file CSCGasCollisions.cc.

References CSCCrossGap::beta2(), create_public_lumi_plots::exp, CSCCrossGap::gamma(), lnEnergyLoss(), log, LogTrace, me, and theCrossGap.

Referenced by simulate().

289 {
290 // Generate a no. of collisions between collisions[0] and [N_ENERGY-1]
291  float lnColl = log(CLHEP::RandFlat::shoot(engine, anmin, anmax));
292 
293 // Without using CLHEP: approx random between anmin and anmax
294 // double ra = double(rand())/double(RAND_MAX)*avCollisions;
295 // cout << "ra = " << ra << std::endl;
296 // float lnColl = static_cast<float>( log( ra ) );
297 
298  // Find energy loss for that number
299  float lnE = lnEnergyLoss( lnColl, collisions );
300  float eloss = exp(lnE);
301  // Compensate if gamma was actually below 1.1
302  if ( theCrossGap->gamma() < 1.1 ) eloss = eloss * 0.173554/theCrossGap->beta2();
303  LogTrace(me) << "eloss = " << eloss;
304  // Next line only used to fill container of eloss's for later diagnostic dumps
305  // if ( debugV ) theCrossGap->addEloss( eloss );
306  return eloss;
307 }
static std::vector< std::string > checklist log
const std::string me
float lnEnergyLoss(float, const std::vector< float > &) const
double gamma() const
Definition: CSCCrossGap.h:52
#define LogTrace(id)
double beta2() const
Definition: CSCCrossGap.h:51
CSCCrossGap * theCrossGap
double CSCGasCollisions::generateStep ( double  avCollisions,
CLHEP::HepRandomEngine *  engine 
) const
private

Definition at line 271 of file CSCGasCollisions.cc.

References LogTrace, me, and relval_parameters_module::step.

Referenced by simulate().

272 {
273 // Generate a m.f.p. (1/avCollisions = cm/collision)
274  double step = (CLHEP::RandExponential::shoot(engine))/avCollisions;
275 
276 // Without using CLHEP: approx random exponential by...
277 // double da = double(rand())/double(RAND_MAX);
278 // double step = -log(1.-da)/avCollisions;
279 
280  LogTrace(me) << " step = " << step;
281  // Next line only used to fill a container of 'step's for later diagnostic dumps
282  //if ( debugV ) theCrossGap->addStep( step );
283  return step;
284 }
const std::string me
#define LogTrace(id)
void CSCGasCollisions::ionize ( double  energyTransferred,
LocalPoint  startHere 
) const
private

Definition at line 309 of file CSCGasCollisions.cc.

References CSCCrossGap::addCluster(), CSCCrossGap::addElectrons(), CSCCrossGap::addElectronToBack(), clusterExtent, eion, ework, gasDensity, LogTrace, me, CSCCrossGap::noOfClusters(), CSCCrossGap::noOfElectrons(), funct::pow(), theCrossGap, and CSCCrossGap::unitVector().

Referenced by simulate().

310 {
311  while ( energyAvailable > eion ) {
312  LogTrace(me) << " NEW CLUSTER " << theCrossGap->noOfClusters() + 1 <<
313  " AT " << startHere;
314  LocalPoint newCluster( startHere );
315  theCrossGap->addCluster(newCluster);
316 
317  //@@ I consider NOT subtracting eion before calculating range to be a bug.
318  //@@ But this changes tuning of the algorithm so leave it until after the big rush to 7_5_0
319  //@@ energyAvailable -= eion;
320 
321  // Sauli CERN 77-09: delta e range with E in MeV (Sauli references Kobetich & Katz 1968,
322  // but I cannot find this expression in that set of papers.)
323  // Take HALF that range. //@@ Why? Why not...
324  double range = 0.5 * (0.71/gasDensity)*pow( energyAvailable*1.E-6, 1.72);
325  LogTrace(me) << " range = " << range;
326  if ( range < clusterExtent ) {
327 
328  // short-range delta e
329  // How many electrons can we make? Now use *average* energy for ionization (not *minimum*)
330  int nelec = static_cast<int>(energyAvailable/ework);
331  LogTrace(me) << "s-r delta energy in = " << energyAvailable;
332  //energyAvailable -= nelec*(energyAvailable/ework);
333  energyAvailable -= nelec*ework;
334  // If still above eion (minimum, not average) add one more e
335  if ( energyAvailable > eion ) {
336  ++nelec;
337  energyAvailable -= eion;
338  }
339  LogTrace(me) << "s-r delta energy out = " << energyAvailable << ", nelec = " << nelec;
340  theCrossGap->addElectrons( nelec );
341  break;
342 
343  }
344  else {
345  // long-range delta e
346  LogTrace(me) << "l-r delta \n"
347  << "no. of electrons in cluster now = " << theCrossGap->noOfElectrons();
348  theCrossGap->addElectrons( 1 ); // Position is at startHere still
349 
350  bool new_range = false;
351  while ( !new_range && (energyAvailable>ework) ) {
352  energyAvailable -= ework;
353  while ( energyAvailable > eion ) {
354  double range2 = 0.5 * 0.71/gasDensity*pow( 1.E-6*energyAvailable, 1.72);
355  double drange = range - range2;
356  LogTrace(me) << " energy left = " << energyAvailable <<
357  ", range2 = " << range2 << ", drange = " << drange;
358  if ( drange < clusterExtent ) {
359  theCrossGap->addElectronToBack(); // increment last element
360  }
361  else {
362  startHere += drange*theCrossGap->unitVector(); // update delta e start position
363  range = range2; // update range
364  new_range = true; // Test range again
365  LogTrace(me) << "reset range to range2 and iterate";
366  }
367  break; // out of inner while energyAvailable>eion
368 
369  } // inner while energyAvailable>eion
370 
371  } // while !new_range && energyAvailable>ework
372 
373  // energyAvailable now less than ework, but still may be over eion...add an e
374  if ( energyAvailable > eion ) {
375  energyAvailable -= ework; // yes, it may go negative
376  theCrossGap->addElectronToBack(); // add one more e
377  }
378 
379  } // if range
380 
381  } // outer while energyAvailable>eion
382 }
int noOfClusters() const
Definition: CSCCrossGap.h:34
void addElectronToBack()
Definition: CSCCrossGap.h:44
const std::string me
LocalVector unitVector() const
Definition: CSCCrossGap.h:54
int noOfElectrons() const
Definition: CSCCrossGap.h:36
#define LogTrace(id)
CSCCrossGap * theCrossGap
void addCluster(LocalPoint here)
Definition: CSCCrossGap.h:42
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
void addElectrons(int nelec=1)
Definition: CSCCrossGap.h:43
float CSCGasCollisions::lnEnergyLoss ( float  lnCollisions,
const std::vector< float > &  collisions 
) const
private

Definition at line 465 of file CSCGasCollisions.cc.

References spr::find(), LogTrace, me, and theEnergyBins.

Referenced by generateEnergyLoss().

466  {
467 
468  float lnE = -1.;
469 
470  // Find collision[] bin in which lnCollisions falls
471  std::vector<float>::const_iterator it = find(collisions.begin(),
472  collisions.end(), lnCollisions );
473 
474  if ( it != collisions.end() ) {
475  // found the value
476  std::vector<float>::difference_type ihi = it - collisions.begin();
477  LogTrace(me) << ": using one energy bin " << ihi << " = "
478  << theEnergyBins[ihi]
479  << " for lnCollisions = " << lnCollisions;
480  lnE = theEnergyBins[ihi];
481  }
482  else {
483  // interpolate the value
484  std::vector<float>::const_iterator loside = find_if(collisions.begin(),
485  collisions.end(), bind2nd(less<float>(), lnCollisions));
486  std::vector<float>::difference_type ilo = loside - collisions.begin();
487  if ( ilo > 0 ) {
488  LogTrace(me) << ": using energy bin "
489  << ilo-1 << " and " << ilo;
490  lnE = theEnergyBins[ilo-1] + (lnCollisions-collisions[ilo-1])*
491  (theEnergyBins[ilo]-theEnergyBins[ilo-1]) /
492  (collisions[ilo]-collisions[ilo-1]);
493  }
494  else {
495  LogTrace(me) << ": using one energy bin 0 = "
496  << theEnergyBins[0]
497  << " for lnCollisions = " << lnCollisions;
498  lnE = theEnergyBins[0]; //@@ WHAT ELSE TO DO?
499  }
500  }
501 
502  return lnE;
503 }
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
const std::string me
#define LogTrace(id)
std::vector< float > theEnergyBins
void CSCGasCollisions::readCollisionTable ( )
private

Definition at line 77 of file CSCGasCollisions.cc.

References edm::hlt::Exception, python.connectstrParser::f1, groupFilesInBlocks::fin, i, j, LogTrace, me, N_ENERGY, N_ENTRIES, N_GAMMA, FileInPath::name(), cmsHarvester::path, theCollisionTable, theEnergyBins, and theGammaBins.

Referenced by CSCGasCollisions().

77  {
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 }
int i
Definition: DBlmapReader.cc:9
static const int N_ENERGY
std::vector< float > theGammaBins
const std::string me
tuple path
else: Piece not in the list, fine.
int j
Definition: DBlmapReader.cc:9
static const int N_GAMMA
#define LogTrace(id)
static const int N_ENTRIES
std::vector< float > theCollisionTable
std::vector< float > theEnergyBins
void CSCGasCollisions::setParticleDataTable ( const ParticleDataTable pdt)

Definition at line 146 of file CSCGasCollisions.cc.

References theParticleDataTable.

Referenced by CSCWireHitSim::setParticleDataTable().

147 {
148  theParticleDataTable = pdt;
149 }
const ParticleDataTable * theParticleDataTable
void CSCGasCollisions::simulate ( const PSimHit simHit,
std::vector< LocalPoint > &  clusters,
std::vector< int > &  electrons,
CLHEP::HepRandomEngine *  engine 
)

Definition at line 152 of file CSCGasCollisions.cc.

References deCut, eion, CSCCrossGap::electrons(), PSimHit::entryPoint(), PSimHit::exitPoint(), create_public_lumi_plots::exp, fillCollisionsForThisGamma(), generateEnergyLoss(), generateStep(), CSCCrossGap::ionClusters(), ionize(), CSCCrossGap::length(), CSCCrossGap::logGamma(), LogTrace, MAX_STEPS, me, N_ENERGY, PSimHit::pabs(), PSimHit::particleType(), relval_parameters_module::step, theCrossGap, theParticleDataTable, and CSCCrossGap::unitVector().

Referenced by CSCWireHitSim::getIonizationClusters().

154  {
155 
156  const float epsilonL = 0.01; // Shortness of simhit 'length'
157  // const float max_gap_z = 1.5; // Gas gaps are 0.5 or 1.0 cm
158 
159  // Note that what I call the 'gap' may in fact be the 'length' of a PSimHit which
160  // does not start and end on the gap edges. This confuses the nomenclature at least.
161 
162  double mom = simHit.pabs();
163  int iam = simHit.particleType(); // PDG type
164  delete theCrossGap; // before building new one
165  assert(theParticleDataTable != 0);
166  ParticleData const * particle = theParticleDataTable->particle( simHit.particleType() );
167  double mass = 0.105658; // assume a muon
168  if(particle == 0)
169  {
170  edm::LogError("CSCGasCollisions") << "Cannot find particle of type " << simHit.particleType()
171  << " in the PDT";
172  }
173  else
174  {
175  mass = particle->mass();
176  }
177 
178  theCrossGap = new CSCCrossGap( mass, mom, simHit.exitPoint() - simHit.entryPoint() );
179  float gapSize = theCrossGap->length();
180 
181  // Test the simhit 'length' (beware of angular effects)
182  // if ( gapSize <= epsilonL || gapSize > max_gap_z ) {
183  if ( gapSize <= epsilonL ) {
184  LogTrace(me) << ": WARNING! simhit entry and exit are very close: \n"
185  << "\n entry = " << simHit.entryPoint()
186  << "\n exit = " << simHit.exitPoint()
187  << "\n particle type = " << iam << ", momentum = " << mom
188  << ", gap length = " << gapSize;
189  return; //@@ Just skip this PSimHit
190  }
191 
192  // Interpolate the table for current gamma value
193  // Extract collisions binned by energy loss values, for this gamma
194  std::vector<float> collisions(N_ENERGY);
195  double loggam = theCrossGap->logGamma();
196  fillCollisionsForThisGamma( static_cast<float>(loggam), collisions );
197 
198  double anmin = exp(collisions[N_ENERGY-1]);
199  double anmax = exp(collisions[0]);
200  double amu = anmax - anmin;
201 
202  LogTrace(me) << "collisions extremes = " << collisions[N_ENERGY-1]
203  << ", " << collisions[0] << "\n"
204  << "anmin = " << anmin << ", anmax = " << anmax << "\n"
205  << "amu = " << amu << "\n";
206 
207  float dedx = 0.; // total energy loss
208  double sum_steps = 0.; // total distance across gap (along simhit direction)
209  int n_steps = 0; // no. of steps/primary collisions
210  int n_try = 0; // no. of tries to generate steps
211  double step = -1.; // Sentinel for start
212 
213  LocalPoint layerLocalPoint( simHit.entryPoint() );
214 
215  // step/primary collision loop
216  while ( sum_steps < gapSize) {
217  ++n_try;
218  if ( n_try > MAX_STEPS ) {
219  LogTrace(me) << ": n_try=" << n_try << " is too large. Skip simhit."
220  << "\n particle type=" << iam << ", momentum= " << mom
221  << "\n gapSize=" << gapSize << ", last step=" << step
222  << ", sum_steps=" << sum_steps << ", n_steps=" << n_steps;
223  break;
224  }
225  step = generateStep( amu, engine );
226  if ( sum_steps + step > gapSize ) break;
227 
228  float eloss = generateEnergyLoss( amu, anmin, anmax, collisions, engine );
229 
230  // Is the eloss too large? (then GEANT should have produced hits!)
231  if ( eloss > deCut ) {
232  LogTrace(me) << "eloss > " << deCut << " = " << eloss;
233  continue; // to generate another collision/step
234  }
235 
236  dedx += eloss; // the energy lost from the ionizing particle
237  sum_steps += step; // the position of the ionizing particle
238  ++n_steps; // the number of primary collisions
239 
240  if (n_steps > MAX_STEPS ) { // Extra-careful trap for bizarreness
241  edm::LogInfo(me) << ": n_steps=" << n_steps << " is too large. Skip simhit.";
242  edm::LogInfo(me) << "particle type=" << iam << ", momentum= " << mom;
243  edm::LogInfo(me) << "gapSize=" << gapSize << ", last step=" << step
244  << ", sum_steps=" << sum_steps;
245  break;
246  }
247  LogTrace(me) << "sum_steps = " << sum_steps << ", dedx = " << dedx;
248 
249  // Generate ionization.
250  // eion is the minimum energy at which ionization can occur in the gas
251  if ( eloss > eion ) {
252  layerLocalPoint += step * theCrossGap->unitVector(); // local point where the collision occurs
253  ionize( eloss, layerLocalPoint );
254  }
255  else {
256  LogTrace(me) << "Energy available = " << eloss <<
257  ", too low for ionization.";
258  }
259 
260  } // step/collision loop
261 
262  //TODO port this
263  //if ( debugV ) writeSummary( n_steps, sum_steps, dedx, simHit.energyLoss() );
264 
265  // Return values in two container arguments
266  positions = theCrossGap->ionClusters();
268  return;
269 }
std::vector< int > electrons() const
Definition: CSCCrossGap.h:35
static const int N_ENERGY
std::vector< LocalPoint > ionClusters() const
Definition: CSCCrossGap.h:33
const std::string me
Local3DPoint exitPoint() const
Exit point in the local Det frame.
Definition: PSimHit.h:38
const ParticleDataTable * theParticleDataTable
LocalVector unitVector() const
Definition: CSCCrossGap.h:54
static const int MAX_STEPS
float pabs() const
fast and more accurate access to momentumAtEntry().mag()
Definition: PSimHit.h:63
HepPDT::ParticleData ParticleData
void ionize(double energyTransferred, LocalPoint startHere) const
#define LogTrace(id)
double logGamma(double mass, float momentum)
Definition: CSCCrossGap.cc:23
double generateStep(double avCollisions, CLHEP::HepRandomEngine *) const
int particleType() const
Definition: PSimHit.h:85
float generateEnergyLoss(double avCollisions, double anmin, double anmax, const std::vector< float > &collisions, CLHEP::HepRandomEngine *) const
float length() const
Definition: CSCCrossGap.h:55
void fillCollisionsForThisGamma(float, std::vector< float > &) const
CSCCrossGap * theCrossGap
Local3DPoint entryPoint() const
Entry point in the local Det frame.
Definition: PSimHit.h:35
void CSCGasCollisions::writeSummary ( int  n_steps,
double  sum_steps,
float  dedx,
float  simHiteloss 
) const
private

Definition at line 384 of file CSCGasCollisions.cc.

References filterCSVwithJSON::copy, gather_cfg::cout, eion, CSCCrossGap::electrons(), HI_PhotonSkim_cff::electrons, CSCCrossGap::eLossPerStep(), spr::find(), CSCCrossGap::ionClusters(), CSCCrossGap::noOfSteps(), saveGasCollisions, CSCCrossGap::stepLengths(), relval_machine::steps, and theCrossGap.

385 {
386  std::vector<LocalPoint> ion_clusters = theCrossGap->ionClusters();
387  std::vector<int> electrons = theCrossGap->electrons();
388  std::vector<float> elosses = theCrossGap->eLossPerStep();
389  std::vector<double> steps = theCrossGap->stepLengths();
390 
391  cout << "------------------" << std::endl;
392  cout << "AFTER CROSSING GAP" << std::endl;
393  cout << "No. of steps = " << n_steps << std::endl;
394  cout << "Check: stored steps = " << theCrossGap->noOfSteps() << std::endl;
395 
396  cout << "Lengths of steps: " << std::endl;
397  std::copy( steps.begin(), steps.end(), std::ostream_iterator<float>(cout,"\n"));
398  cout << std::endl;
399 
400  if ( saveGasCollisions ) {
401  ofstream of0("osteplen.dat",ios::app);
402  std::copy( steps.begin(), steps.end(), std::ostream_iterator<float>(of0,"\n"));
403  }
404 
405  cout << "Total sum of steps = " << sum_steps << std::endl;
406  if ( n_steps > 0 ) cout << "Average step length = " <<
407  sum_steps/float(n_steps) << std::endl;
408  cout << std::endl;
409 
410  cout << "Energy loss per collision:" << std::endl;
411  std::copy( elosses.begin(), elosses.end(), std::ostream_iterator<float>(cout,"\n"));
412  cout << std::endl;
413 
414  if ( saveGasCollisions ) {
415  ofstream of1("olperc.dat",ios::app);
416  std::copy( elosses.begin(), elosses.end(), std::ostream_iterator<float>(of1,"\n"));
417  }
418 
419  cout << "Total energy loss across gap = " << dedx << " eV = " <<
420  dedx/1000. << " keV" << std::endl;
421  int n_ic = count_if( elosses.begin(), elosses.end(),
422  bind2nd(greater<float>(), eion) );
423  cout << "No. of primary ionizing collisions across gap = " << n_ic << std::endl;
424  if ( n_steps > 0 ) cout << "Average energy loss/collision = " <<
425  dedx/float(n_steps) << " eV" << std::endl;
426  cout << std::endl;
427 
428  cout << "No. of ion clusters = " << ion_clusters.size() << std::endl;
429  cout << "Positions of clusters:" << std::endl;
430  std::copy( ion_clusters.begin(), ion_clusters.end(),
431  std::ostream_iterator<LocalPoint>(cout,"\n"));
432  cout << std::endl;
433 
434  if ( saveGasCollisions ) {
435  ofstream of2("oclpos.dat",ios::app);
436  std::copy( ion_clusters.begin(), ion_clusters.end(),
437  std::ostream_iterator<LocalPoint>(of2,"\n"));
438  }
439 
440  cout << "No. of electrons per cluster:" << std::endl;
441  std::copy( electrons.begin(), electrons.end(), std::ostream_iterator<int>(cout,"\n"));
442  cout << std::endl;
443 
444  if ( saveGasCollisions ) {
445  ofstream of3("oepercl.dat",ios::app);
446  std::copy( electrons.begin(), electrons.end(), std::ostream_iterator<int>(of3,"\n"));
447  }
448 
449  // Check for zero-e clusters
450  std::vector<int>::const_iterator bigger = find(electrons.begin(),
451  electrons.end(), 0 );
452  if ( bigger != electrons.end() ) {
453  cout << "Error! There is a cluster with 0 electrons." << std::endl;
454  }
455  int n_e = accumulate(electrons.begin(), electrons.end(), 0 );
456  if ( n_steps > 0 ) {
457  cout << "# cm cm keV eV eV eV keV" << std::endl;
458  cout << " " << n_steps << " " << sum_steps << " " << sum_steps/float(n_steps) << " " <<
459  ion_clusters.size() << " " <<
460  dedx/1000. << " " << n_ic << " " << dedx/float(n_steps) << " " << n_e << " " <<
461  dedx/float(n_e) << " " << float(n_e)/float(ion_clusters.size()) << " " << simHiteloss*1.E6 << std::endl;
462  }
463 }
std::vector< int > electrons() const
Definition: CSCCrossGap.h:35
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
std::vector< float > eLossPerStep() const
Definition: CSCCrossGap.h:39
std::vector< double > stepLengths() const
Definition: CSCCrossGap.h:37
int noOfSteps() const
Definition: CSCCrossGap.h:38
CSCCrossGap * theCrossGap
tuple cout
Definition: gather_cfg.py:121

Member Data Documentation

double CSCGasCollisions::clusterExtent
private

Definition at line 65 of file CSCGasCollisions.h.

Referenced by CSCGasCollisions(), and ionize().

double CSCGasCollisions::deCut
private

Definition at line 62 of file CSCGasCollisions.h.

Referenced by CSCGasCollisions(), and simulate().

double CSCGasCollisions::eion
private

Definition at line 63 of file CSCGasCollisions.h.

Referenced by CSCGasCollisions(), ionize(), simulate(), and writeSummary().

double CSCGasCollisions::ework
private

Definition at line 64 of file CSCGasCollisions.h.

Referenced by CSCGasCollisions(), and ionize().

double CSCGasCollisions::gasDensity
private

Definition at line 56 of file CSCGasCollisions.h.

Referenced by CSCGasCollisions(), and ionize().

const int CSCGasCollisions::MAX_STEPS = 400
static

Definition at line 40 of file CSCGasCollisions.h.

Referenced by simulate().

const std::string CSCGasCollisions::me
private
const int CSCGasCollisions::N_ENERGY = 63
static

Definition at line 38 of file CSCGasCollisions.h.

Referenced by fillCollisionsForThisGamma(), readCollisionTable(), and simulate().

const int CSCGasCollisions::N_ENTRIES = N_GAMMA*N_ENERGY
static

Definition at line 39 of file CSCGasCollisions.h.

Referenced by readCollisionTable().

const int CSCGasCollisions::N_GAMMA = 21
static

Definition at line 37 of file CSCGasCollisions.h.

Referenced by fillCollisionsForThisGamma(), and readCollisionTable().

bool CSCGasCollisions::saveGasCollisions
private

Definition at line 73 of file CSCGasCollisions.h.

Referenced by CSCGasCollisions(), and writeSummary().

std::vector<float> CSCGasCollisions::theCollisionTable
private

Definition at line 69 of file CSCGasCollisions.h.

Referenced by fillCollisionsForThisGamma(), and readCollisionTable().

CSCCrossGap* CSCGasCollisions::theCrossGap
private
std::vector<float> CSCGasCollisions::theEnergyBins
private

Definition at line 68 of file CSCGasCollisions.h.

Referenced by lnEnergyLoss(), and readCollisionTable().

std::vector<float> CSCGasCollisions::theGammaBins
private

Definition at line 67 of file CSCGasCollisions.h.

Referenced by fillCollisionsForThisGamma(), and readCollisionTable().

const ParticleDataTable* CSCGasCollisions::theParticleDataTable
private

Definition at line 72 of file CSCGasCollisions.h.

Referenced by setParticleDataTable(), and simulate().