108 #ifndef ST_NO_EXCEPTIONS
110 # if !defined(ST_NO_NAMESPACES)
111 using std::invalid_argument;
116 #include "SystemOfUnits.h"
117 #include "PhysicalConstants.h"
119 #ifndef ST_NO_NAMESPACES
120 using namespace units;
123 #include "StTrsDeDx.hh"
126 RandFlat StTrsDeDx::mFlatDistribution(mEngine);
127 RandPoisson StTrsDeDx::mPoissonDistribution(mEngine);
132 StTrsDeDx::StTrsDeDx()
135 mPadLength = 1.95*centimeter;
138 StTrsDeDx::StTrsDeDx(
const char* gas,
double pad)
144 if (strcmp(gas,
"Ne") && strcmp(gas,
"Ar")
145 && strcmp(gas,
"P10") && strcmp(gas,
"p10")) {
146 #ifdef ST_USES_EXCEPTIONS
147 std::cerr <<
"oops" << endl;
148 throw invalid_argument(
"Gas not currently Implemented.\nMust use either \"Ne\" or \"Ar\" or \"P10\".");
150 std::cerr << gas <<
" gas not currently Implemented." << endl;
151 std::cerr <<
"Must use either: \"Ne\", \"Ar\", or \"P10\"." << endl;
152 std::cerr <<
"Aborting..." << endl;
158 StTrsDeDx::StTrsDeDx(
const string& gas,
double pad)
162 if((gas !=
"Ne") && (gas !=
"Ar") &&
163 (gas !=
"P10") && (gas !=
"p10")) {
164 #ifdef ST_USES_EXCEPTIONS
165 std::cerr <<
"oops" << endl;
166 throw invalid_argument(
"Gas not currently Implemented.\nMust use either \"Ne\" or \"Ar\" or \"P10\".");
168 std::cerr << gas.c_str() <<
" gas not currently Implemented." << endl;
169 std::cerr <<
"Must use either: \"Ne\", \"Ar\", or \"P10\"." << endl;
170 std::cerr <<
"Aborting..." << endl;
177 void StTrsDeDx::doInitialization()
179 mKonstant = 0.1536*MeV*centimeter2/gram;
182 mPairs = 12.4/centimeter;
188 mSigmaTransverse = 600*micrometer/::sqrt(centimeter);
189 mSigmaLongitudinal = 300*micrometer/::sqrt(centimeter);
191 mDensity = 0.000839*gram/centimeter3;
196 mPairs = 28.0/centimeter;
202 mSigmaTransverse = 600*micrometer/::sqrt(centimeter);
203 mSigmaLongitudinal = 300*micrometer/::sqrt(centimeter);
205 mDensity = 0.00166*gram/centimeter3;
209 if((mGas ==
"P10") || (mGas ==
"p10")) {
210 mPairs = 28.1/centimeter;
216 mSigmaTransverse = 633*micrometer/::sqrt(centimeter);
217 mSigmaLongitudinal = 370*micrometer/::sqrt(centimeter);
220 mAttachment = 10.2/(1.e-6*second*bar*bar);
222 mDensity = 0.001561*gram/centimeter3;
227 mAttachment = 10.2/(1.e-6*second*bar*bar);
231 mMeanFreePath = 1./mPairs;
232 mEReduced = 1 - mExponent;
233 mEE = ::pow(mIonize,mEReduced);
235 mAlfat = mKonstant*gram/MeV/centimeter2*mZa*mPadLength/centimeter;
238 StTrsDeDx::~StTrsDeDx() {}
240 void StTrsDeDx::setPadLength(
double len)
243 mAlfat = mKonstant*gram/MeV/centimeter2*mZa*mPadLength/centimeter;
246 double StTrsDeDx::nextInteraction()
const
250 return mExponentialDistribution.shoot(mMeanFreePath);
253 int StTrsDeDx::primary(
double bg)
const
255 int numberOfPrimaries;
258 mPoissonDistribution.shoot(mPairs*mPadLength);
262 mPoissonDistribution.shoot(mPairs*mPadLength*betheBloch(bg));
264 return numberOfPrimaries;
267 int StTrsDeDx::secondary(
double* primaryEnergy)
const
272 double energyDistribution =
273 mFlatDistribution.shoot()*(mEE - ::pow(mEndPoint,mEReduced));
276 ::pow(mEE - energyDistribution,(1/mEReduced));
278 double numberOfSecondaries = (*primaryEnergy - mIonize)/mW;
281 if(numberOfSecondaries > 1000)
282 numberOfSecondaries = 1000;
284 return (static_cast<int>(numberOfSecondaries));
287 #ifndef ST_NO_TEMPLATE_DEF_ARGS
288 void StTrsDeDx::electrons(vector<int>& sum,
double bg)
const
290 void StTrsDeDx::electrons(vector<
int, allocator<int> >& sum,
double bg)
const
294 if(sum.size() != StTrsDeDx::numberOfElectrons)
295 sum.resize(StTrsDeDx::numberOfElectrons);
299 sum[StTrsDeDx::primaries] = this->primary(bg);
302 double primaryEnergy;
303 sum[StTrsDeDx::secondaries] = 0;
304 for(
int ii=0; ii<sum[StTrsDeDx::primaries]; ii++) {
305 sum[StTrsDeDx::secondaries] += this->secondary(&primaryEnergy);
308 sum[StTrsDeDx::total] =
309 sum[StTrsDeDx::primaries] + sum[StTrsDeDx::secondaries];
312 double StTrsDeDx::betheBloch(
double bg)
const
329 double xa=::log(1.649*mIonize/eV/(28.8*::sqrt(mDensity*centimeter3/gram*mZa)));
331 double f = 4.606*(xa-x0)/(::pow((x1-x0),m));
333 double bigx = ::log(bg)/::log(10.);
339 else if ((bigx>x0) && (bigx<x1))
340 d=4.606*(bigx-xa)+f*(::pow((x1-bigx),m));
349 double te = k + 2*::log(bgMin) - (sqr(bgMin)/(sqr(bgMin)+1)) - ::log(sqr(bgMin)/(sqr(bgMin)+1));
350 double Io = mAlfat*((sqr(bgMin)+1)/sqr(bgMin))*(::log((electron_mass_c2/MeV*mAlfat)/(sqr(mIonize)))+te);
352 te = k + 2*::log(bg) - (sqr(bg)/(sqr(bg)+1)) - ::log(sqr(bg)/(sqr(bg)+1)) - d;
353 double I = mAlfat*((sqr(bg)+1)/sqr(bg))*(::log((electron_mass_c2/MeV*mAlfat)/(sqr(mIonize)))+te);
358 double StTrsDeDx::betheBlochTSS(
double p,
double z,
double m)
370 double K = 0.3071*MeV/(gram/centimeter2);
371 double me = 511.*keV;
372 double emax = 50.*keV;
377 double rhoP10 = 1.547e-3*gram/centimeter3;
378 double rhocomp[ncomp] = {1.66e-3*gram/centimeter3,
379 6.70e-4*gram/centimeter3};
380 double Acomp[ncomp] = {39.95*gram/mole, 16.04*gram/mole};
381 double Zcomp[ncomp] = {18.0, 10.0};
382 double I[ncomp] = {188.0*eV, 41.7*eV};
384 double dedxComp[ncomp];
386 double percentage[ncomp] = {90.0, 10.0};
388 double energy = ::sqrt(p*p+m*m);
389 double beta = p/energy;
390 double beta2 = beta*beta;
391 double gamma = energy/m;
394 double weight, prefactor, arg;
395 for(
int icomp=0; icomp<ncomp; icomp++) {
397 (percentage[icomp]*Acomp[icomp]/(percentage[0]*Acomp[0]+percentage[1]*Acomp[1]));
399 K*z2*Zcomp[icomp]/(Acomp[icomp]/(gram/mole)*beta2)*rhocomp[icomp];
401 arg = beta*gamma*::sqrt(2.*me*emax)/I[icomp];
403 (weight/rhocomp[icomp])*prefactor*(::log(arg)-beta2/2.);
406 return (rhoP10*(dedxComp[0] + dedxComp[1]));
409 void StTrsDeDx::print(ostream& os)
const
411 os <<
"=========== StTrsDeDx ================" << endl;
412 #if defined(__sun) && ! defined(__GNUG__)
413 os <<
"==> " << mGas.c_str() << endl;
415 os <<
"==> " << mGas << endl;
417 os <<
"mPairs " << (mPairs*centimeter) <<
" /cm" << endl;
418 os <<
"mIonize " << (mIonize/eV) <<
" eV" << endl;
419 os <<
"mW " << (mW/eV) <<
" eV" << endl;
420 os <<
"mEndPoint " << (mEndPoint/keV) <<
" keV" << endl;
421 os <<
"mExponent " << (mExponent) << endl;
422 os <<
"mZa " << mZa << endl;
423 os <<
"--------------------------------------" << endl;
424 os <<
"mPadLength " << (mPadLength/centimeter) <<
" cm" << endl;
425 os <<
"======================================\n" << endl;