72 #include "StSvtElectronCloud.hh"
73 #include "StSvtSignal.hh"
77 fstream pasaOutN,pasaOut;
80 StSvtSignal::StSvtSignal()
84 mTotalHitCharge = 0.0;
85 mFractionOfCharge = 0.0;
86 mCollectedCharge = 0.0;
94 GAP_TWIDTH = 36*1.e-6;
96 memset(mSignal,0,
sizeof(mSignal[0])*128);
101 for(
int i = 0; i < 4; i++)
105 mTau_l = 500.0*0.001;
109 StSvtSignal::~StSvtSignal()
114 void StSvtSignal::setAnodeTimeBinSizes(
double timeBinSize,
double anodeSize)
116 mTimeBinSize = timeBinSize;
117 mAnodeSize = anodeSize;
122 void StSvtSignal::setDriftVelocity(
double driftVelocity)
124 mDriftVel = driftVelocity;
128 void StSvtSignal::setOption(
int option)
134 void StSvtSignal::pasaRelatedStuff()
145 mPeakTimeR = 0.04308;
163 mPeakTimeS = 0.04308;
164 mPasaMaxS = 2.74619e-09;
167 mPasaNorm = mPasaGain*3.64140278e+08;
181 void StSvtSignal::doPasaOnly(
int option){
184 double tStep = mTimeBinSize*0.001;
188 pasaOutN.open(
"pasaNorm.dat",ios::out);
190 pasaOut.open(
"pasa.dat",ios::out);
194 for(
int j = 0; j <25000; j++){
198 pasaFunValue = pasaRes(t);
201 pasaFunValue = mPasaNorm*pasaFunValue;
202 pasaOutN<<t<<setw(20)<<pasaFunValue<<endl;
206 pasaOut<<t<<setw(20)<<pasaFunValue<<endl;
215 halfWidthAtHalfMaxS();
226 double sigmaSqDiff,sigmaSqDiff2;
227 double cosPhi,cosPhi2,sinPhi,sinPhi2;
244 mTrackId = elCloud->getTrackId();
245 mSigmaMajor = elCloud->getSigmaDrift();
246 double sigmaMajor2 = mSigmaMajor*mSigmaMajor;
247 mSigmaMinor = elCloud->getSigmaAnode();
248 double sigmaMinor2 = mSigmaMinor*mSigmaMinor;
249 sigmaSqDiff = sigmaMajor2 - sigmaMinor2;
250 sigmaSqDiff2 = sigmaSqDiff*sigmaSqDiff;
252 mTotalHitCharge = elCloud->getChargeAtAnode();
254 cosPhi = cos(elCloud->getPhi());
255 sinPhi = sin(elCloud->getPhi());
256 cosPhi2 = cosPhi*cosPhi;
257 sinPhi2 = sinPhi*sinPhi;
259 mC1 = (-0.39894228*cosPhi*sinPhi*sigmaSqDiff)/mSigmaMajor;
260 mC2 = (0.39894228*cosPhi2*sinPhi2*sigmaSqDiff2)/sigmaMajor2;
261 mC3 = (sigmaMajor2*sigmaMinor2/sigmaMajor2) + (cosPhi2*sinPhi2*sigmaSqDiff2/sigmaMajor2);
265 double StSvtSignal::chargeFraction(
int an,
double anHit)
268 double anodeHitCent = anHit*mAnodeSize;
270 mAnRightEdge = an*mAnodeSize;
271 mAnLeftEdge = (an - 1)*mAnodeSize;
275 mFractionOfCharge = prob1(mAnRightEdge - anodeHitCent,mSigmaMajor) - prob1(mAnLeftEdge - anodeHitCent,mSigmaMajor);
282 if(mFractionOfCharge < 0.000001)
284 mCollectedCharge = 0.0;
289 mCollectedCharge = mTotalHitCharge*mFractionOfCharge;
292 return mCollectedCharge;
299 int StSvtSignal::timeCenterAndWidth(
double anHit,
double timeHit)
301 double leftArgument,leftArgument2,rightArgument,rightArgument2;
302 double exp1,exp2,relTimeCenter,relTimeCenter2,timeWidth2,driftVel2;
304 double anodeHitCent = anHit*mAnodeSize;
305 double mTimeHit = timeHit*mTimeBinSize;
307 leftArgument = (mAnLeftEdge - anodeHitCent)/mSigmaMajor;
308 leftArgument2 = leftArgument*leftArgument;
309 rightArgument = (mAnRightEdge - anodeHitCent)/mSigmaMajor;
310 rightArgument2 = rightArgument*rightArgument;
315 exp1 = exp(-0.5*leftArgument2);
316 exp2 = exp(-0.5*rightArgument2);
329 relTimeCenter = mC1*(exp1 - exp2);
331 timeWidth2 = mC2*(leftArgument*exp1 - rightArgument*exp2) + mC3*mFractionOfCharge;
334 relTimeCenter = relTimeCenter/mFractionOfCharge;
336 relTimeCenter2 = relTimeCenter*relTimeCenter;
337 timeWidth2 = timeWidth2/mFractionOfCharge;
338 timeWidth2 = fabs(timeWidth2 - relTimeCenter2);
341 driftVel2 = mDriftVel*mDriftVel;
343 mTimeCenter = mTimeHit + (relTimeCenter/mDriftVel);
345 mTimeWidth = ::sqrt((timeWidth2/driftVel2) + GAP_TWIDTH);
348 if(std::isnan(mTimeWidth))
355 void StSvtSignal::resetPeakAndUnderShoot()
358 mMinUnderShoot = 0.0;
361 void StSvtSignal::setTimeWidth(
double timWidth)
363 mTimeWidth = timWidth;
368 void StSvtSignal::calcConvSignal(
double chargeOnAnode)
373 resetSignal(mLowTBin,mHiTBin);
374 resetPeakAndUnderShoot();
377 tStep = mTimeBinSize;
380 int mTCenter = (int)(mTimeCenter/tStep);
381 nMin = mTCenter - 10;
382 if(nMin <= 0) nMin = 1;
387 nMax = mTCenter + 20;
388 if(nMax > 128) nMax = 128;
395 rykovSignal(nMin,nMax, tStep);
397 else if(mOption == 2 )
400 selemonSignal(nMin,nMax,tStep,chargeOnAnode);
410 rykovSignal(nMin,nMax, tStep);
416 selemonSignal(nMin,nMax,tStep,chargeOnAnode);
422 void StSvtSignal::rykovSignal(
int nMin,
int nMax,
double tStep)
426 for(
int n = nMin; n <= nMax ; n++)
429 mSignal[n - 1] = signal(t)*1000000.0;
430 if(n < (
int)(mTimeCenter/tStep) && mSignal[n - 1] < 0.0)
432 if(mSignal[n - 1] > mPeakSignal)
433 mPeakSignal = mSignal[n - 1];
434 if(mSignal[n - 1] < mMinUnderShoot)
435 mMinUnderShoot = mSignal[n - 1];
439 void StSvtSignal::selemonSignal(
int nMin,
int nMax,
double tStep,
double charge)
441 double t = 0, sig = 0;
442 int numOfIntPoints = 0;
445 for(
int n = nMin; n <= nMax ; n++)
448 if(mTimeWidth <= 0.06)
450 sig = analConvInt(t,mTimeWidth,mTimeCenter);
451 mSignal[n - 1] = charge*mPasaNorm*sig;
452 if(n < (
int)(mTimeCenter/tStep) && mSignal[n - 1] < 0.0)
454 if(mSignal[n - 1] > mPeakSignal)
455 mPeakSignal = mSignal[n - 1];
456 if(mSignal[n - 1] < mMinUnderShoot)
457 mMinUnderShoot = mSignal[n - 1];
462 sig = numConvInt(nMin, n, numOfIntPoints, tStep, t);
464 mSignal[n - 1] = charge*mPasaNorm*sig;
465 if(n < (
int)(mTimeCenter/tStep) && mSignal[n - 1] < 0.0)
467 if(mSignal[n - 1] > mPeakSignal)
468 mPeakSignal = mSignal[n - 1];
469 if(mSignal[n - 1] < mMinUnderShoot)
470 mMinUnderShoot = mSignal[n - 1];
478 void StSvtSignal::unNormPasaConst()
481 double p = mTau_s/mTau_l;
482 double q = 1.0/(1.0 - p);
485 for(
int i = 4; i > 0; i--)
487 mPasa[i-1] = i*mPasa[i]*q;
493 void StSvtSignal::peakingTimeS()
498 double tStep = mTimeBinSize*0.001;
499 double pasaFunValue = -1.e20;
503 mPasaMaxS = pasaFunValue;
506 pasaFunValue = pasaRes(t);
509 }
while( pasaFunValue > mPasaMaxS);
511 mPeakTimeS = t - tStep;
515 void StSvtSignal::peakingTimeR()
520 double tStep = (mTimeBinSize*0.001)/mTau_s;
521 double pasaFunValue = -1.e20;
525 mPasaMaxR = pasaFunValue;
527 pasaFunValue = mPasa[0];
530 for(
int i = 1; i <= 4; i++)
533 pasaFunValue = pasaFunValue + mPasa[i]*c1;
536 pasaFunValue = pasaFunValue*exp(-t) - mPasa[0]*exp(-(mTau_s/mTau_l)*t);
539 }
while( pasaFunValue > mPasaMaxR);
541 double peakTime = t - tStep;
542 mPeakTimeR = mTau_s*peakTime;
546 void StSvtSignal::halfWidthAtHalfMaxS()
550 double tStep = mTimeBinSize*0.001;
551 double pasaFunValue = 0.0;
554 for(
int i = 0; i < 2; i++)
556 mFwhmS = -1.0*mFwhmS;
558 pasaFunValue = mPasaMaxS;
562 pasaFunValue = pasaRes(t);
564 }
while( pasaFunValue > 0.5*mPasaMaxS);
572 void StSvtSignal::halfWidthAtHalfMaxR()
576 double tStep = mTimeBinSize*0.001;
577 double pasaFunValue = 0.0;
580 for(
int i = 0; i < 2; i++)
582 mFwhmR = -1.0*mFwhmR;
583 t = mPeakTimeR/mTau_s;
584 pasaFunValue = mPasaMaxR;
588 pasaFunValue = mPasa[0];
591 for(
int i = 1; i <= 4; i++)
594 pasaFunValue = pasaFunValue + mPasa[i]*c1;
597 pasaFunValue = pasaFunValue*exp(-t) - mPasa[0]*exp(-(mTau_s/mTau_l)*t);
599 }
while( pasaFunValue > 0.5*mPasaMaxR);
605 mFwhmR = mTau_s*mFwhmR;
608 void StSvtSignal::normPasaConst()
610 double s1 = mPasaGain*1.e-6/mPasaMaxR;
612 for(
int i = 0; i <= 4; i++)
613 mPasa[i] = s1*mPasa[i];
620 void StSvtSignal::arrays()
622 mArray1[0] = 2.46196981473530512524e-10;
623 mArray1[1] = 0.564189564831068821977;
624 mArray1[2] = 7.46321056442269912687;
625 mArray1[3] = 48.6371970985681366614;
626 mArray1[4] = 196.520832956077098242;
627 mArray1[5] = 526.445194995477358631;
628 mArray1[6] = 934.528527171957607540;
629 mArray1[7] = 1027.55188689515710272;
630 mArray1[8] = 557.535335369399327526;
633 mArray2[1] = 13.2281951154744992508;
634 mArray2[2] = 86.7072140885989742329;
635 mArray2[3] = 354.937778887819891062;
636 mArray2[4] = 975.708501743205489753;
637 mArray2[5] = 1823.90916687909736289;
638 mArray2[6] = 2246.33760818710981792;
639 mArray2[7] = 1656.66309194161350182;
640 mArray2[8] = 557.535340817727675546;
643 mArray3[1] = 0.564189583547755073984;
644 mArray3[2] = 1.275366707599781044160;
645 mArray3[3] = 5.019050422511804774140;
646 mArray3[4] = 6.160210979930535851950;
647 mArray3[5] = 7.409742699504489391600;
648 mArray3[6] = 2.978866653721002406700;
651 mArray4[1] = 2.26052863220117276590;
652 mArray4[2] = 9.39603524938001434673;
653 mArray4[3] = 12.0489539808096656605;
654 mArray4[4] = 17.0814450747565897222;
655 mArray4[5] = 9.60896809063285878198;
656 mArray4[6] = 3.36907645100081516050;
659 mArray5[1] = 9.60497373987051638749;
660 mArray5[2] = 90.0260197203842689217;
661 mArray5[3] = 2232.00534594684319226;
662 mArray5[4] = 7003.32514112805075473;
663 mArray5[5] = 55592.3013010394962768;
666 mArray6[1] = 33.5617141647503099647;
667 mArray6[2] = 521.357949780152679795;
668 mArray6[3] = 4594.32382970980127987;
669 mArray6[4] = 22629.0000613890934246;
670 mArray6[5] = 49267.3942608635921086;
674 double StSvtSignal::signal(
double t)
677 double localTime = 0.0;
679 localTime = t - mTimeCenter;
681 if(mCollectedCharge < 1.0)
683 else if(localTime + 5.0*mTimeWidth < 0.0)
685 else if(mTimeWidth <= 0.02*mTau_s)
686 signal = getShortSignal(localTime);
688 signal = getLongSignal(localTime);
694 double StSvtSignal::getShortSignal(
double localTime)
696 double signal, sig_s, sig_l;
698 signal = -mPasa[0]*exp(-localTime/mTau_l);
699 localTime = localTime/mTau_s;
703 for(
int i = 0; i <= 4; i++)
705 sig_s += mPasa[i]*sig_l;
706 sig_l = sig_l*localTime;
709 signal = mCollectedCharge*( signal + sig_s*exp(-localTime));
715 double StSvtSignal::getLongSignal(
double localTime)
717 double ds0, ds1, ds2, dsc, dsc0, dsc1, dsc2, dsc3;
718 double da1,da2,a2,a3,a4;
720 da1 = mTimeWidth/mTau_s;
722 a2 = 0.5*mCollectedCharge/da1;
723 a3 = mTimeWidth/mTau_l;
726 ds0 = localTime/mTimeWidth;
729 dsc = fabs(0.7071067811865476*ds1);
731 dsc3 = exp(-0.5*ds0*ds0);
734 dsc0 = useArrays5And6(ds1,dsc);
736 dsc0 = useArrays3And4Or1And2(ds1,dsc);
738 dsc1 = 0.3989422805274159*da1;
739 if(dsc >= 1.0 && ds1 < 0.0)
740 dsc1 = dsc1 + ds2*dsc0;
743 dsc0 = dsc0*exp(-da1*(ds1 + 0.5*da1));
744 dsc1 = dsc1*dsc3 + ds2*dsc0;
747 double sig0 = mPasa[0]*dsc0 + mPasa[1]*dsc1;
748 for(
int i = 2; i <= 4; i++)
750 dsc2 = da2*(i - 1)*dsc0 + ds2*dsc1;
751 sig0 = sig0 + mPasa[i]*dsc2;
756 if(dsc >= 1.0 && ds1 < 0.0)
759 double sig1 = ds0 - a3;
761 sig0 = sig0 - mPasa[0]*exp(a4 - localTime/mTau_l)*prob1(sig1,1.0);
762 double signal = mCollectedCharge*sig0;
767 double StSvtSignal::useArrays5And6(
double ds1,
double dsc)
774 for(
int i = 1; i <= 5; i++)
776 sigUp = sigUp*dsc*dsc + mArray5[i];
777 sigDn = sigDn*dsc*dsc + mArray6[i];
780 double dsc0 = 0.5 - 0.5*dsc*sigUp/sigDn;
787 double StSvtSignal::useArrays3And4Or1And2(
double ds1,
double dsc)
796 for(
int i = 1; i <= 6; i++)
798 sigUp = sigUp*dsc + mArray3[i];
799 sigDn = sigDn*dsc + mArray4[i];
807 for(
int i = 1; i <= 8; i++)
809 sigUp = sigUp*dsc + mArray1[i];
810 sigDn = sigDn*dsc + mArray2[i];
814 double dsc0 = 0.5*sigUp/sigDn;
816 dsc0 = 1.0 - dsc0*exp(-dsc*dsc);
822 double StSvtSignal::numConvInt(
int nMin ,
int n,
int numOfIntPoints,
double tStep,
double t)
824 double At = 0.0,lowlim = 0;
826 for(
int p = nMin; p <= n ; p++)
830 lowlim = (p - 1)*mTimeBinSize;
831 At += simpsonInt(numOfIntPoints,lowlim,tStep/numOfIntPoints,t);
841 double StSvtSignal::analConvInt(
double tim,
double sigmat,
double tc)
843 double a, b, c, bc5, bc4, bc3, bc2, ac1;
844 double At = 0,tb, ta, ta2,ta3, ta4,Errb,Erra,expb,expa,gaus ;
845 double sigmat2,sigmat3,sigmat4;
847 sigmat2 = sigmat*sigmat;
848 sigmat3 = sigmat2*sigmat;
849 sigmat4 = sigmat3*sigmat;
852 a = 90.909090909091; b = 2.0; c = -88.909090909091;
856 bc5 = -0.00000000035999; bc4 = 0.00000003200702;
857 bc3 = -0.00000142285777; bc2 = 0.00004216833039;
858 ac1 = -0.04260395364689;
861 tb = tim - tc - b*sigmat2;
862 ta = tim - tc - a*sigmat2;
863 ta2 = ta*ta; ta3 = ta2*ta; ta4 = ta3*ta;
865 Errb = prob2(tb,sigmat); expb = exp(-b*(tim - tc - b*(sigmat2*0.5)));
866 Erra = prob2(ta,sigmat); expa = exp(-a*(tim - tc - a*(sigmat2*0.5)));
869 gaus = (sigmat/::sqrt(2*M_PI))*exp(-0.5*ta2/sigmat2);
880 At = bc5*expb*Errb + ((-bc5 + bc4*ta - bc3*(ta2 + sigmat2) + bc2*(ta3 + 3.0*ta*sigmat2)
881 - ac1*(ta4 + 6.0*ta2*sigmat2 + 3*sigmat4))*Erra + (bc4 - bc3*ta + bc2*(ta2 + 2.0*sigmat2)
882 - ac1*(ta3 + 5.0*ta*sigmat2))*gaus)*expa;
897 double StSvtSignal::simpsonInt(
int numOfIntPoints,
double lowlim,
double step,
double t)
899 double firstTerm = 0, evenTerm = 0, oddTerm = 0, lastTerm = 0, mTpr = 0;
901 for(
int m = 0; m <= numOfIntPoints ; m++)
903 mTpr = lowlim + m*step;
906 firstTerm = gausInput(mTpr - mTimeCenter)*pasaRes(t - mTpr);
907 else if((m != numOfIntPoints) && (m%2 == 0))
908 evenTerm += gausInput(mTpr - mTimeCenter)*pasaRes(t - mTpr);
909 else if((m != numOfIntPoints) && (m%2 == 1))
910 oddTerm += gausInput(mTpr - mTimeCenter)*pasaRes(t - mTpr);
911 else if(m == numOfIntPoints)
912 lastTerm = gausInput(mTpr - mTimeCenter)*pasaRes(t - mTpr);
916 double signal = (step*0.33333333333333)*(firstTerm + lastTerm + 4.0*oddTerm + 2.0*evenTerm);
922 double StSvtSignal::gausInput(
double tim)
924 double tPr2, PI,Exp1;
930 tPr2 = 0.5*tim*tim/(mTimeWidth*mTimeWidth);
932 Exp1 = (0.39894228040143/mTimeWidth)*exp(-tPr2);
938 double StSvtSignal::pasaRes(
double tim)
940 double a, b, c, bc5, bc4, bc3, bc2, ac1, t2, t3,t4;
947 a = 90.909090909091; b = 2.0; c = -88.909090909091;
950 bc5 = -0.00000000035999; bc4 = 0.00000003200702;
951 bc3 = -0.00000142285777; bc2 = 0.00004216833039;
952 ac1 = -0.04260395364689;
958 Fpasa = (bc5*exp(-b*tim)) + ((-bc5 + bc4*tim - bc3*t2 + bc2*t3 - ac1*t4)*exp(-a*tim));
965 double StSvtSignal::prob1(
double anOrTimeDiff ,
double sigma)
969 num = anOrTimeDiff/(M_SQRT2*sigma);
971 double fraction = 0.5*(1 + erf(num));
977 double StSvtSignal::freq(
double num)
982 frq = 0.5 + 0.5*erfc( num/M_SQRT2);
984 frq = 0.5* erfc(num/M_SQRT2);
991 double StSvtSignal::prob2(
double num ,
double sigma)
993 double mSum = 0, mErrf = 0;
994 double mFactorial = 0;
995 double mPowerTerm = 0;
996 double mPowerTermSquared = 0;
997 double mCountTerm = 0;
999 if(fabs(num) < 5*sigma)
1001 for(
int j = 0; j<=150; j++)
1007 mPowerTerm = fabs(num)/(M_SQRT2*sigma);
1008 mPowerTermSquared = mPowerTerm*mPowerTerm;
1009 mCountTerm = mPowerTerm;
1014 mFactorial = (double)j*mFactorial;
1015 mPowerTerm = (mPowerTermSquared)*(
double)fabs(mPowerTerm);
1018 mPowerTerm = (-1)*mPowerTerm;
1020 mCountTerm =(mPowerTerm /( mFactorial*(double)(2*j + 1)));
1028 mErrf = (2.0/::sqrt(M_PI))*mSum;
1031 mErrf = (-1.0)*mErrf;
1034 else if(num > 5*sigma)
1039 return 0.5*(1.0 + mErrf);
1042 int StSvtSignal::getLowTBin()
1047 int StSvtSignal::getHiTBin()
1052 double StSvtSignal::getTimeWidth()
1057 double StSvtSignal::getTimeCenter()
1062 double StSvtSignal::getPeak()
1064 return mPeakSignal*0.001;
1067 double StSvtSignal::getMinUnderShoot()
1070 return mMinUnderShoot*0.001;
1073 double StSvtSignal::getSignal(
int n)
1075 return mSignal[n]*0.001;
1078 void StSvtSignal::resetSignal(
int lBin,
int hBin)
1080 for(
int i = lBin; i <= hBin; i++)
SVT electron cloud expansion routines Simulates electron cloud expansion inside of the silicon wafer...