#include <SimMuon/CSCDigitizer/src/CSCGasCollisions.h>
Public Member Functions | |
CSCGasCollisions () | |
void | setParticleDataTable (const ParticleDataTable *pdt) |
void | setRandomEngine (CLHEP::HepRandomEngine &engine) |
void | simulate (const PSimHit &, const CSCLayer *layer, std::vector< LocalPoint > &clusters, std::vector< int > &electrons) |
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) const |
double | generateStep (double avCollisions) 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) const |
Private Attributes | |
double | clusterExtent |
double | deCut |
double | eion |
double | ework |
double | gasDensity |
const std::string | me |
bool | saveGasCollisions |
std::vector< float > | theCollisionTable |
CSCCrossGap * | theCrossGap |
std::vector< float > | theEnergyBins |
std::vector< float > | theGammaBins |
const ParticleDataTable * | theParticleDataTable |
CLHEP::RandExponential * | theRandExponential |
CLHEP::RandFlat * | theRandFlat |
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 25 of file CSCGasCollisions.h.
CSCGasCollisions::CSCGasCollisions | ( | ) |
Definition at line 39 of file CSCGasCollisions.cc.
References clusterExtent, deCut, eion, ework, gasDensity, me, readCollisionTable(), and saveGasCollisions.
00039 : me("CSCGasCollisions"), 00040 gasDensity( 2.1416e-03 ), 00041 deCut( 1.e05 ), eion( 10.4 ), ework( 70.0 ), clusterExtent( 0.001 ), 00042 theGammaBins(N_GAMMA, 0.), theEnergyBins(N_ENERGY, 0.), 00043 theCollisionTable(N_ENTRIES, 0.), theCrossGap( 0 ), 00044 theParticleDataTable(0), 00045 theRandFlat(0), 00046 theRandExponential(0), 00047 saveGasCollisions ( false ) 00048 { 00049 00050 edm::LogInfo(me) << "Constructing a " << me << ":"; 00051 edm::LogInfo(me) << "gas density = " << gasDensity << " g/cm3"; 00052 edm::LogInfo(me) << "max eloss per collision allowed = " << deCut/1000. 00053 << " keV (for higher elosses, hits should have been simulated.)"; 00054 edm::LogInfo(me) << "ionization threshold = " << eion << " eV"; 00055 edm::LogInfo(me) << "effective work function = " << ework << " eV"; 00056 edm::LogInfo(me) << "cluster extent = " << clusterExtent*1.e04 << " micrometres"; 00057 edm::LogInfo(me) << "Save gas collision info to files when using debugV? " << saveGasCollisions; 00058 00059 readCollisionTable(); 00060 }
CSCGasCollisions::~CSCGasCollisions | ( | ) | [virtual] |
Definition at line 62 of file CSCGasCollisions.cc.
References me, theCrossGap, theRandExponential, and theRandFlat.
00062 { 00063 edm::LogInfo(me) << "Destructing a " << me; 00064 delete theCrossGap; 00065 delete theRandFlat; 00066 delete theRandExponential; 00067 }
void CSCGasCollisions::fillCollisionsForThisGamma | ( | float | logGamma, | |
std::vector< float > & | collisions | |||
) | const [private] |
Definition at line 513 of file CSCGasCollisions.cc.
References i, LogTrace, me, N_ENERGY, N_GAMMA, theCollisionTable, and theGammaBins.
Referenced by simulate().
00515 { 00516 std::vector<float>::const_iterator bigger = find_if(theGammaBins.begin(), 00517 theGammaBins.end(), bind2nd(greater<float>(), logGamma)); 00518 00519 if ( bigger == theGammaBins.end() ) { 00520 // use highest bin 00521 LogTrace(me) << ": using highest gamma bin" 00522 << " for logGamma = " << logGamma; 00523 for (int i=0; i<N_ENERGY; ++i) 00524 collisions[i] = theCollisionTable[i*N_GAMMA]; 00525 } 00526 else { 00527 // use bigger and its lower neighbour 00528 std::vector<float>::difference_type ihi = bigger - theGammaBins.begin(); 00529 if ( ihi > 0 ) { 00530 double dlg2 = *bigger--; // and decrement after deref 00531 //LogTrace(me) << ": using gamma bins " 00532 // << ihi-1 << " and " << ihi; 00533 double dlg1 = *bigger; // now the preceding element 00534 double dlg = (logGamma-dlg1)/(dlg2-dlg1); 00535 double omdlg = 1. - dlg; 00536 for (int i=0; i<N_ENERGY; ++i) 00537 collisions[i] = theCollisionTable[i*N_GAMMA+ihi-1]*omdlg + 00538 theCollisionTable[i*N_GAMMA+ihi]*dlg; 00539 } 00540 else { 00541 // bigger has no lower neighbour 00542 LogTrace(me) << ": using lowest gamma bin" 00543 << " for logGamma = " << logGamma; 00544 00545 for (int i=0; i<N_ENERGY; ++i) 00546 collisions[i] = theCollisionTable[i*N_GAMMA]; 00547 } 00548 } 00549 }
float CSCGasCollisions::generateEnergyLoss | ( | double | avCollisions, | |
double | anmin, | |||
double | anmax, | |||
const std::vector< float > & | collisions | |||
) | const [private] |
Definition at line 289 of file CSCGasCollisions.cc.
References CSCCrossGap::beta2(), funct::exp(), CSCCrossGap::gamma(), lnEnergyLoss(), funct::log(), LogTrace, me, theCrossGap, and theRandFlat.
Referenced by simulate().
00291 { 00292 // Generate a no. of collisions between collisions[0] and [N_ENERGY-1] 00293 float lnColl = log(theRandFlat->fire(anmin, anmax)); 00294 00295 // Without using CLHEP: approx random between anmin and anmax 00296 // double ra = double(rand())/double(RAND_MAX)*avCollisions; 00297 // cout << "ra = " << ra << std::endl; 00298 // float lnColl = static_cast<float>( log( ra ) ); 00299 00300 // Find energy loss for that number 00301 float lnE = lnEnergyLoss( lnColl, collisions ); 00302 float eloss = exp(lnE); 00303 // Compensate if gamma was actually below 1.1 00304 if ( theCrossGap->gamma() < 1.1 ) eloss = eloss * 0.173554/theCrossGap->beta2(); 00305 LogTrace(me) << "eloss = " << eloss; 00306 // TODO 00307 // theCrossGap->addEloss( eloss ); 00308 return eloss; 00309 }
double CSCGasCollisions::generateStep | ( | double | avCollisions | ) | const [private] |
Definition at line 274 of file CSCGasCollisions.cc.
References LogTrace, me, cmsRelvalreportInput::step, and theRandExponential.
Referenced by simulate().
00275 { 00276 // Generate a m.f.p. (1/avCollisions = cm/collision) 00277 double step = (theRandExponential->fire())/avCollisions; 00278 00279 // Without using CLHEP: approx random exponential by... 00280 // double da = double(rand())/double(RAND_MAX); 00281 // double step = -log(1.-da)/avCollisions; 00282 00283 LogTrace(me) << " step = " << step; 00284 // TODO CAn this possibly be right? 00285 //if ( debugV ) theCrossGap->addStep( step ); 00286 return step; 00287 }
void CSCGasCollisions::ionize | ( | double | energyTransferred, | |
LocalPoint | startHere | |||
) | const [private] |
Definition at line 311 of file CSCGasCollisions.cc.
References CSCCrossGap::addCluster(), CSCCrossGap::addElectrons(), CSCCrossGap::addElectronToBack(), clusterExtent, eion, ework, gasDensity, LogTrace, me, CSCCrossGap::noOfClusters(), CSCCrossGap::noOfElectrons(), funct::pow(), range, theCrossGap, and CSCCrossGap::unitVector().
Referenced by simulate().
00312 { 00313 while ( energyAvailable > eion ) { 00314 LogTrace(me) << " NEW CLUSTER " << theCrossGap->noOfClusters() + 1 << 00315 " AT " << startHere; 00316 LocalPoint newCluster( startHere ); 00317 theCrossGap->addCluster(newCluster); 00318 00319 //@@ I consider NOT subtracting eion before calculating range to be a bug. 00320 //@@ But this changes tuning of the algorithm so leave it until after the big rush to 7_5_0 00321 //@@ energyAvailable -= eion; 00322 00323 // Sauli CERN 77-09: delta e range with E in MeV (Sauli references Kobetich & Katz 1968, 00324 // but I cannot find this expression in that set of papers.) 00325 // Take HALF that range. //@@ Why? Why not... 00326 double range = 0.5 * (0.71/gasDensity)*pow( energyAvailable*1.E-6, 1.72); 00327 LogTrace(me) << " range = " << range; 00328 if ( range < clusterExtent ) { 00329 00330 // short-range delta e 00331 // How many electrons can we make? Now use *average* energy for ionization (not *minimum*) 00332 int nelec = static_cast<int>(energyAvailable/ework); 00333 LogTrace(me) << "s-r delta energy in = " << energyAvailable; 00334 energyAvailable -= nelec*(energyAvailable/ework); 00335 // If still above eion (minimum, not average) add one more e 00336 if ( energyAvailable > eion ) { 00337 ++nelec; 00338 energyAvailable -= eion; 00339 } 00340 LogTrace(me) << "s-r delta energy out = " << energyAvailable << ", nelec = " << nelec; 00341 theCrossGap->addElectrons( nelec ); 00342 break; 00343 00344 } 00345 else { 00346 // long-range delta e 00347 LogTrace(me) << "l-r delta \n" 00348 << "no. of electrons in cluster now = " << theCrossGap->noOfElectrons(); 00349 theCrossGap->addElectrons( 1 ); // Position is at startHere still 00350 00351 bool new_range = false; 00352 while ( !new_range && (energyAvailable>ework) ) { 00353 energyAvailable -= ework; 00354 while ( energyAvailable > eion ) { 00355 double range2 = 0.5 * 0.71/gasDensity*pow( 1.E-6*energyAvailable, 1.72); 00356 double drange = range - range2; 00357 LogTrace(me) << " energy left = " << energyAvailable << 00358 ", range2 = " << range2 << ", drange = " << drange; 00359 if ( drange < clusterExtent ) { 00360 theCrossGap->addElectronToBack(); // increment last element 00361 } 00362 else { 00363 startHere += drange*theCrossGap->unitVector(); // update delta e start position 00364 range = range2; // update range 00365 new_range = true; // Test range again 00366 LogTrace(me) << "reset range to range2 and iterate"; 00367 } 00368 break; // out of inner while energyAvailable>eion 00369 00370 } // inner while energyAvailable>eion 00371 00372 } // while !new_range && energyAvailable>ework 00373 00374 // energyAvailable now less than ework, but still may be over eion...add an e 00375 if ( energyAvailable > eion ) { 00376 energyAvailable -= ework; // yes, it may go negative 00377 theCrossGap->addElectronToBack(); // add one more e 00378 } 00379 00380 } // if range 00381 00382 } // outer while energyAvailable>eion 00383 }
float CSCGasCollisions::lnEnergyLoss | ( | float | lnCollisions, | |
const std::vector< float > & | collisions | |||
) | const [private] |
Definition at line 473 of file CSCGasCollisions.cc.
References find(), it, LogTrace, me, and theEnergyBins.
Referenced by generateEnergyLoss().
00474 { 00475 00476 float lnE = -1.; 00477 00478 // Find collision[] bin in which lnCollisions falls 00479 std::vector<float>::const_iterator it = find(collisions.begin(), 00480 collisions.end(), lnCollisions ); 00481 00482 if ( it != collisions.end() ) { 00483 // found the value 00484 std::vector<float>::difference_type ihi = it - collisions.begin(); 00485 LogTrace(me) << ": using one energy bin " << ihi << " = " 00486 << theEnergyBins[ihi] 00487 << " for lnCollisions = " << lnCollisions; 00488 lnE = theEnergyBins[ihi]; 00489 } 00490 else { 00491 // interpolate the value 00492 std::vector<float>::const_iterator loside = find_if(collisions.begin(), 00493 collisions.end(), bind2nd(less<float>(), lnCollisions)); 00494 std::vector<float>::difference_type ilo = loside - collisions.begin(); 00495 if ( ilo > 0 ) { 00496 LogTrace(me) << ": using energy bin " 00497 << ilo-1 << " and " << ilo; 00498 lnE = theEnergyBins[ilo-1] + (lnCollisions-collisions[ilo-1])* 00499 (theEnergyBins[ilo]-theEnergyBins[ilo-1]) / 00500 (collisions[ilo]-collisions[ilo-1]); 00501 } 00502 else { 00503 LogTrace(me) << ": using one energy bin 0 = " 00504 << theEnergyBins[0] 00505 << " for lnCollisions = " << lnCollisions; 00506 lnE = theEnergyBins[0]; //@@ WHAT ELSE TO DO? 00507 } 00508 } 00509 00510 return lnE; 00511 }
void CSCGasCollisions::readCollisionTable | ( | ) | [private] |
Definition at line 69 of file CSCGasCollisions.cc.
References Exception, f1, i, j, LogTrace, me, N_ENERGY, N_ENTRIES, N_GAMMA, FileInPath::name(), path(), theCollisionTable, theEnergyBins, and theGammaBins.
Referenced by CSCGasCollisions().
00069 { 00070 00071 // I'd prefer to allow comments in the data file which means 00072 // complications of reading line-by-line and then item-by-item. 00073 00074 // Is float OK? Or do I need double? 00075 00076 // Do I need any sort of error trapping? 00077 00078 // We use the default CMSSW data file path 00079 // We use the default file name 'collisions.dat' 00080 00081 // This can be reset in .orcarc by SimpleConfigurable 00082 // Muon:Endcap:CollisionsFile 00083 00084 string path( getenv( "CMSSW_SEARCH_PATH" ) ); 00085 // TODO make configurable 00086 string colliFile = "SimMuon/CSCDigitizer/data/collisions.dat"; 00087 FileInPath f1( path, colliFile ); 00088 if (f1() == 0 ) { 00089 string errorMessage = "Input file " + colliFile + "not found"; 00090 edm::LogError("CSCGasCollisions") << errorMessage << " in path " << path 00091 << "\nSet Muon:Endcap:CollisionsFile in .orcarc to the " 00092 " location of the file relative to ORCA_DATA_PATH." ; 00093 throw cms::Exception( " Endcap Muon gas collisions data file not found."); 00094 } 00095 else { 00096 edm::LogInfo(me) << ": reading " << f1.name(); 00097 } 00098 00099 ifstream & fin = *f1(); 00100 00101 if (fin == 0) { 00102 string errorMessage = "Cannot open input file " + path + colliFile; 00103 edm::LogError("CSCGasCollisions") << errorMessage; 00104 throw cms::Exception(errorMessage); 00105 } 00106 00107 fin.clear( ); // Clear eof read status 00108 fin.seekg( 0, ios::beg ); // Position at start of file 00109 00110 // @@ We had better have the right sizes everywhere or all 00111 // hell will break loose. There's no trapping. 00112 LogTrace(me) << "Reading gamma bins"; 00113 int j = 0; 00114 for(int i = 0; i<N_GAMMA; ++i) { 00115 fin >> theGammaBins[i]; 00116 LogTrace(me) << ++j << " " << theGammaBins[i]; 00117 } 00118 00119 j = 0; 00120 LogTrace(me) << "Reading energy bins \n"; 00121 for(int i = 0; i<N_ENERGY; ++i) { 00122 fin >> theEnergyBins[i]; 00123 LogTrace(me) << ++j << " " << theEnergyBins[i]; 00124 } 00125 00126 j = 0; 00127 LogTrace(me) << "Reading collisions table \n"; 00128 00129 for(int i = 0; i<N_ENTRIES; ++i) { 00130 fin >> theCollisionTable[i]; 00131 LogTrace(me) << ++j << " " << theCollisionTable[i]; 00132 } 00133 00134 fin.close(); 00135 }
void CSCGasCollisions::setParticleDataTable | ( | const ParticleDataTable * | pdt | ) |
Definition at line 138 of file CSCGasCollisions.cc.
References theParticleDataTable.
Referenced by CSCWireHitSim::setParticleDataTable().
00139 { 00140 theParticleDataTable = pdt; 00141 }
void CSCGasCollisions::setRandomEngine | ( | CLHEP::HepRandomEngine & | engine | ) |
Definition at line 144 of file CSCGasCollisions.cc.
References theRandExponential, and theRandFlat.
Referenced by CSCWireHitSim::setRandomEngine().
00145 { 00146 theRandFlat = new CLHEP::RandFlat(engine); 00147 theRandExponential = new CLHEP::RandExponential(engine); 00148 }
void CSCGasCollisions::simulate | ( | const PSimHit & | simHit, | |
const CSCLayer * | layer, | |||
std::vector< LocalPoint > & | clusters, | |||
std::vector< int > & | electrons | |||
) |
Definition at line 151 of file CSCGasCollisions.cc.
References deCut, eion, CSCCrossGap::electrons(), PSimHit::entryPoint(), PSimHit::exitPoint(), funct::exp(), fillCollisionsForThisGamma(), generateEnergyLoss(), generateStep(), CSCCrossGap::ionClusters(), ionize(), CSCCrossGap::length(), CSCCrossGap::logGamma(), LogTrace, MAX_STEPS, me, N_ENERGY, PSimHit::pabs(), PSimHit::particleType(), cmsRelvalreportInput::step, theCrossGap, theParticleDataTable, and CSCCrossGap::unitVector().
Referenced by CSCWireHitSim::getIonizationClusters().
00152 { 00153 00154 const float epsilonL = 0.01; // Shortness of simhit 'length' 00155 // const float max_gap_z = 1.5; // Gas gaps are 0.5 or 1.0 cm 00156 00157 // Note that what I call the 'gap' may in fact be the 'length' of a PSimHit which 00158 // does not start and end on the gap edges. This confuses the nomenclature at least. 00159 00160 double mom = simHit.pabs(); 00161 int iam = simHit.particleType(); // PDG type 00162 delete theCrossGap; // before building new one 00163 assert(theParticleDataTable != 0); 00164 ParticleData const * particle = theParticleDataTable->particle( simHit.particleType() ); 00165 double mass = 0.105658; // assume a muon 00166 if(particle == 0) 00167 { 00168 edm::LogError("CSCGasCollisions") << "Cannot find particle of type " << simHit.particleType() 00169 << " in the PDT"; 00170 } 00171 else 00172 { 00173 mass = particle->mass(); 00174 } 00175 00176 theCrossGap = new CSCCrossGap( mass, mom, simHit.exitPoint() - simHit.entryPoint() ); 00177 float gapSize = theCrossGap->length(); 00178 00179 // Test the simhit 'length' (beware of angular effects) 00180 // if ( gapSize <= epsilonL || gapSize > max_gap_z ) { 00181 if ( gapSize <= epsilonL ) { 00182 LogTrace(me) << ": WARNING! simhit entry and exit are very close: \n" 00183 << "\n entry = " << simHit.entryPoint() 00184 << "\n exit = " << simHit.exitPoint() 00185 << "\n particle type = " << iam << ", momentum = " << mom 00186 << ", gap length = " << gapSize; 00187 return; //@@ Just skip this PSimHit 00188 } 00189 00190 // Interpolate the table for current gamma value 00191 // Extract collisions binned by energy loss values, for this gamma 00192 std::vector<float> collisions(N_ENERGY); 00193 double loggam = theCrossGap->logGamma(); 00194 fillCollisionsForThisGamma( static_cast<float>(loggam), collisions ); 00195 00196 double anmin = exp(collisions[N_ENERGY-1]); 00197 double anmax = exp(collisions[0]); 00198 double amu = anmax - anmin; 00199 00200 LogTrace(me) << "collisions extremes = " << collisions[N_ENERGY-1] 00201 << ", " << collisions[0] << "\n" 00202 << "anmin = " << anmin << ", anmax = " << anmax << "\n" 00203 << "amu = " << amu << "\n"; 00204 00205 float dedx = 0.; // total energy loss 00206 double sum_steps = 0.; // total distance across gap (along simhit direction) 00207 int n_steps = 0; // no. of steps/primary collisions 00208 int n_try = 0; // no. of tries to generate steps 00209 double step = -1.; // Sentinel for start 00210 00211 //LocalPoint chamberLocalPoint( simHit.entryPoint() ); 00212 // translate to layer local coordinates 00213 //GlobalPoint globalPoint( layer->chamber()->toGlobal(chamberLocalPoint) ); 00214 //LocalPoint layerLocalPoint( layer->toLocal(globalPoint) ); 00215 LocalPoint layerLocalPoint( simHit.entryPoint() ); 00216 00217 //std::cout << "DEBUG " << chamberLocalPoint << " " << layerLocalPoint << std::endl; 00218 // step/primary collision loop 00219 while ( sum_steps < gapSize) { 00220 ++n_try; 00221 if ( n_try > MAX_STEPS ) { 00222 LogTrace(me) << ": n_try=" << n_try << " is too large. Skip simhit." 00223 << "\n particle type=" << iam << ", momentum= " << mom 00224 << "\n gapSize=" << gapSize << ", last step=" << step 00225 << ", sum_steps=" << sum_steps << ", n_steps=" << n_steps; 00226 break; 00227 } 00228 step = generateStep( amu ); 00229 if ( sum_steps + step > gapSize ) break; 00230 00231 float eloss = generateEnergyLoss( amu, anmin, anmax, collisions ); 00232 00233 // Is the eloss too large? (then GEANT should have produced hits!) 00234 if ( eloss > deCut ) { 00235 LogTrace(me) << "eloss > " << deCut << " = " << eloss; 00236 continue; // to generate another collision/step 00237 } 00238 00239 dedx += eloss; // the energy lost from the ionizing particle 00240 sum_steps += step; // the position of the ionizing particle 00241 ++n_steps; // the number of primary collisions 00242 00243 if (n_steps > MAX_STEPS ) { // Extra-careful trap for bizarreness 00244 edm::LogInfo(me) << ": n_steps=" << n_steps << " is too large. Skip simhit."; 00245 edm::LogInfo(me) << "particle type=" << iam << ", momentum= " << mom; 00246 edm::LogInfo(me) << "gapSize=" << gapSize << ", last step=" << step 00247 << ", sum_steps=" << sum_steps; 00248 break; 00249 } 00250 LogTrace(me) << "sum_steps = " << sum_steps << ", dedx = " << dedx; 00251 00252 // Generate ionization. 00253 // eion is the minimum energy at which ionization can occur in the gas 00254 if ( eloss > eion ) { 00255 layerLocalPoint += step * theCrossGap->unitVector(); // local point where the collision occurs 00256 ionize( eloss, layerLocalPoint ); 00257 } 00258 else { 00259 LogTrace(me) << "Energy available = " << eloss << 00260 ", too low for ionization."; 00261 } 00262 00263 } // step/collision loop 00264 00265 //TODO port this 00266 //if ( debugV ) writeSummary( n_steps, sum_steps, dedx ); 00267 00268 // Return values in two container arguments 00269 positions = theCrossGap->ionClusters(); 00270 electrons = theCrossGap->electrons(); 00271 return; 00272 }
Definition at line 385 of file CSCGasCollisions.cc.
References edmNew::copy(), GenMuonPlsPt100GeV_cfg::cout, eion, CSCCrossGap::electrons(), CSCCrossGap::eLossPerStep(), lat::endl(), find(), CSCCrossGap::ionClusters(), CSCCrossGap::noOfSteps(), saveGasCollisions, CSCCrossGap::stepLengths(), steps, and theCrossGap.
00386 { 00387 std::vector<LocalPoint> ion_clusters = theCrossGap->ionClusters(); 00388 std::vector<int> electrons = theCrossGap->electrons(); 00389 std::vector<float> elosses = theCrossGap->eLossPerStep(); 00390 std::vector<double> steps = theCrossGap->stepLengths(); 00391 00392 cout << "------------------" << std::endl; 00393 cout << "AFTER CROSSING GAP" << std::endl; 00394 cout << "No. of steps = " << n_steps << std::endl; 00395 cout << "Check: stored steps = " << theCrossGap->noOfSteps() << std::endl; 00396 00397 cout << "Lengths of steps: " << std::endl; 00398 std::copy( steps.begin(), steps.end(), std::ostream_iterator<float>(cout,"\n")); 00399 cout << std::endl; 00400 00401 if ( saveGasCollisions ) { 00402 ofstream of0("osteplen.dat",ios::app); 00403 std::copy( steps.begin(), steps.end(), std::ostream_iterator<float>(of0,"\n")); 00404 } 00405 00406 cout << "Total sum of steps = " << sum_steps << std::endl; 00407 if ( n_steps > 0 ) cout << "Average step length = " << 00408 sum_steps/float(n_steps) << std::endl; 00409 cout << std::endl; 00410 00411 cout << "Energy loss per collision:" << std::endl; 00412 std::copy( elosses.begin(), elosses.end(), std::ostream_iterator<float>(cout,"\n")); 00413 cout << std::endl; 00414 00415 if ( saveGasCollisions ) { 00416 ofstream of1("olperc.dat",ios::app); 00417 std::copy( elosses.begin(), elosses.end(), std::ostream_iterator<float>(of1,"\n")); 00418 } 00419 00420 cout << "Total energy loss across gap = " << dedx << " eV = " << 00421 dedx/1000. << " keV" << std::endl; 00422 int n_ic = count_if( elosses.begin(), elosses.end(), 00423 bind2nd(greater<float>(), eion) ); 00424 cout << "No. of primary ionizing collisions across gap = " << n_ic << std::endl; 00425 if ( n_steps > 0 ) cout << "Average energy loss/collision = " << 00426 dedx/float(n_steps) << " eV" << std::endl; 00427 cout << std::endl; 00428 00429 cout << "No. of ion clusters = " << ion_clusters.size() << std::endl; 00430 cout << "Positions of clusters:" << std::endl; 00431 std::copy( ion_clusters.begin(), ion_clusters.end(), 00432 std::ostream_iterator<LocalPoint>(cout,"\n")); 00433 cout << std::endl; 00434 00435 if ( saveGasCollisions ) { 00436 ofstream of2("oclpos.dat",ios::app); 00437 std::copy( ion_clusters.begin(), ion_clusters.end(), 00438 std::ostream_iterator<LocalPoint>(of2,"\n")); 00439 } 00440 00441 cout << "No. of electrons per cluster:" << std::endl; 00442 std::copy( electrons.begin(), electrons.end(), std::ostream_iterator<int>(cout,"\n")); 00443 cout << std::endl; 00444 00445 if ( saveGasCollisions ) { 00446 ofstream of3("oepercl.dat",ios::app); 00447 std::copy( electrons.begin(), electrons.end(), std::ostream_iterator<int>(of3,"\n")); 00448 } 00449 00450 // Check for zero-e clusters 00451 std::vector<int>::const_iterator bigger = find(electrons.begin(), 00452 electrons.end(), 0 ); 00453 if ( bigger != electrons.end() ) { 00454 cout << "Error! There is a cluster with 0 electrons." << std::endl; 00455 } 00456 int n_e = accumulate(electrons.begin(), electrons.end(), 0 ); 00457 if ( n_steps > 0 ) { 00458 cout << "Total no. of electrons = " << n_e << ", energy loss/e = " << 00459 dedx/float(n_e) << " eV " << std::endl; 00460 cout << "Average no. of electrons per cluster = " << 00461 float(n_e)/float(ion_clusters.size()) << std::endl; 00462 cout << "------------------" << std::endl; 00463 00464 cout << "#steps path av_step n_i_cl E/gap n_i_col E/step n_e E/e e/i_c" << std::endl; 00465 cout << "# cm cm keV eV eV eV" << std::endl; 00466 cout << " " << n_steps << " " << sum_steps << " " << sum_steps/float(n_steps) << " " << 00467 ion_clusters.size() << " " << 00468 dedx/1000. << " " << n_ic << " " << dedx/float(n_steps) << " " << n_e << " " << 00469 dedx/float(n_e) << " " << float(n_e)/float(ion_clusters.size()) << std::endl; 00470 } 00471 }
double CSCGasCollisions::clusterExtent [private] |
double CSCGasCollisions::deCut [private] |
double CSCGasCollisions::eion [private] |
Definition at line 63 of file CSCGasCollisions.h.
Referenced by CSCGasCollisions(), ionize(), simulate(), and writeSummary().
double CSCGasCollisions::ework [private] |
double CSCGasCollisions::gasDensity [private] |
const int CSCGasCollisions::MAX_STEPS = 400 [static] |
const std::string CSCGasCollisions::me [private] |
Definition at line 55 of file CSCGasCollisions.h.
Referenced by CSCGasCollisions(), fillCollisionsForThisGamma(), generateEnergyLoss(), generateStep(), ionize(), lnEnergyLoss(), readCollisionTable(), simulate(), and ~CSCGasCollisions().
const int CSCGasCollisions::N_ENERGY = 63 [static] |
Definition at line 39 of file CSCGasCollisions.h.
Referenced by fillCollisionsForThisGamma(), readCollisionTable(), and simulate().
const int CSCGasCollisions::N_ENTRIES = N_GAMMA*N_ENERGY [static] |
const int CSCGasCollisions::N_GAMMA = 21 [static] |
Definition at line 38 of file CSCGasCollisions.h.
Referenced by fillCollisionsForThisGamma(), and readCollisionTable().
bool CSCGasCollisions::saveGasCollisions [private] |
Definition at line 75 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] |
Definition at line 71 of file CSCGasCollisions.h.
Referenced by generateEnergyLoss(), ionize(), simulate(), writeSummary(), and ~CSCGasCollisions().
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().
CLHEP::RandExponential* CSCGasCollisions::theRandExponential [private] |
Definition at line 74 of file CSCGasCollisions.h.
Referenced by generateStep(), setRandomEngine(), and ~CSCGasCollisions().
CLHEP::RandFlat* CSCGasCollisions::theRandFlat [private] |
Definition at line 73 of file CSCGasCollisions.h.
Referenced by generateEnergyLoss(), setRandomEngine(), and ~CSCGasCollisions().