137 #include "SystemOfUnits.h"
138 #include "PhysicalConstants.h"
139 #include "StDbUtilities/StTpcLocalSectorCoordinate.hh"
140 #include "StDbUtilities/StTpcPadCoordinate.hh"
142 #include "StTrsSlowAnalogSignalGenerator.hh"
151 static const double sigmaL = .05*centimeter/TMath::Sqrt(centimeter);
161 mChargeDistribution = endo;
162 mSampler = symmetricGaussianApproximation;
168 mDriftVelocity = mSCDb->driftVelocity(13);
169 mSamplingFrequency = mElectronicsDb->samplingFrequency();
171 mTimeBinWidth = 1./mSamplingFrequency;
175 mSymGausApproxFactor = (M_SQRT1_2*M_2_SQRTPI/(2.*mSigma1));
176 mAsymGausApproxFactor = (M_2_SQRTPI/M_SQRT2)/(mTau1+mTau2);
177 mAsymGausUnRestFactor = (M_2_SQRTPI/M_SQRT2)/(mSigma1+mSigma2);
192 StTrsSlowAnalogSignalGenerator::~StTrsSlowAnalogSignalGenerator() {}
195 StTrsSlowAnalogSignalGenerator::instance()
198 #ifndef ST_NO_EXCEPTIONS
199 throw domain_error(
"StTrsSlowAnalogSignalGenerator::instance() Invalid Arguments");
201 cerr <<
"StTrsSlowAnalogSignalGenerator::instance() Invalid Arguments" << endl;
202 cerr <<
"Cannot create Instance" << endl;
203 cerr <<
"Aborting..." << endl;
220 double StTrsSlowAnalogSignalGenerator::endoChargeIntegral(
double xo,
double yo,
double xl,
double xu,
double yl,
double yu)
222 #ifndef ST_NO_NAMESPACES
223 using namespace units;
226 double L = (yo < mGeomDb->lastInnerSectorAnodeWire()) ?
227 mGeomDb->innerSectorAnodeWirePadPlaneSeparation() :
228 mGeomDb->outerSectorAnodeWirePadPlaneSeparation();
231 double t17 = -TMath::ATan(TMath::Exp(pi*(xu-xo)*t3/2))+TMath::ATan(TMath::Exp(pi*(xl-xo)*t3/2));
235 -4.0*TMath::ATan(TMath::Exp(-pi*(-yu+yo)*t3/2))*t17*t20
236 +4.0*TMath::ATan(TMath::Exp(-pi*(-yl+yo)*t3/2))*t17*t20;
242 double StTrsSlowAnalogSignalGenerator::imageChargeIntegral(
double xo,
double yo,
double xl,
double xu,
double yl,
double yu)
244 #ifndef ST_NO_NAMESPACES
245 using namespace units;
276 double d = 4*millimeter;
284 double t4 = t1+t2-2.0*t3;
286 double t8 = TMath::Power(-xu+xo,2.0);
287 double t9 = TMath::Sqrt(t8);
292 double t15 = 5*TMath::Sqrt(t1+t2+t11+(d*d)/100.-2.*t12-2.*t3+t13);
293 double t19 = TMath::ATan((50./d)*t4*t5*t10/t15);
294 double t22 = TMath::Power(-xl+xo,2.0);
295 double t23 = TMath::Sqrt(t22);
298 double t29 = t27+t2-2.0*t28;
300 double t33 = 5*TMath::Sqrt(t27+t2+t11+(d*d)/100-2.*t12-2.*t28+t13);
301 double t37 = TMath::ATan((50./d)*t29*t5*t31/t33);
302 double t44 = t10*t31;
306 double t51 = 5*TMath::Sqrt(t1+t2+t48+(d*d)/100-2.*t49-2.*t3+t13);
307 double t55 = TMath::ATan((50./d)*t4*t46*t10/t51);
308 double t62 = 5*TMath::Sqrt(t27+t2+t48+(d*d)/100-2.*t49-2.*t28+t13);
309 double t66 = TMath::ATan((50./d)*t29*t46*t31/t62);
310 double t74 = 0.1591549431*q*(-t19*xu*t23+t19*xo*t23+t37*xl*t9-t37*xo*t9)*t44
311 -0.1591549431*q*(-t55*xu*t23+t55*xo*t23+t66*xl*t9-t66*xo*t9)*t44;
316 void StTrsSlowAnalogSignalGenerator::setChargeDistribution(StDistribution v)
321 mChargeDistribution = v;
323 cerr <<
"Cannot Determine Charge Distribution Requested" << endl;
356 void StTrsSlowAnalogSignalGenerator::inducedChargeOnPad(
StTrsWireHistogram* wireHistogram, Int_t sector)
363 PR(wireHistogram->minWire());
364 PR(wireHistogram->maxWire());
366 if(wireHistogram->minWire()<0) {
367 cerr <<
"Wire Plane is empty" << endl;
370 mDriftVelocity = mSCDb->driftVelocity(sector);
371 for(
int jj=wireHistogram->minWire(); jj<=wireHistogram->maxWire(); jj++) {
375 aTpcWire currentWire = wireHistogram->getWire(jj);
376 aTpcWire::iterator iter;
378 for(iter = currentWire.begin();
379 iter != currentWire.end();
402 transformer(xyCoord,tpcRaw);
404 int centralPad = (Int_t) tpcRaw.pad();
405 int centralRow = tpcRaw.row();
412 mRowLimits.first = (centralRow > mDeltaRow) ?
413 centralRow - mDeltaRow : centralRow;
414 mRowLimits.second = (centralRow < (mGeomDb->numberOfRows()-mDeltaRow)) ?
415 centralRow + mDeltaRow : centralRow;
418 if(xyCoord.position().y() < mGeomDb->outerSectorEdge()) {
419 mRowLimits.second = min(mRowLimits.second, mGeomDb->numberOfInnerRows());
422 mRowLimits.first = max(mRowLimits.first, (mGeomDb->numberOfInnerRows()+1));
423 mRowLimits.second = min(mRowLimits.second,(mGeomDb->numberOfRows()));
428 mPadLimits.first = (centralPad > mDeltaPad) ?
429 centralPad - mDeltaPad : centralPad;
434 for(
int irow=mRowLimits.first; irow<=mRowLimits.second; irow++) {
436 (centralPad < (mGeomDb->numberOfPadsAtRow(irow) - mDeltaPad)) ?
437 centralPad + mDeltaPad : mGeomDb->numberOfPadsAtRow(irow);
440 for(
int ipad=mPadLimits.first; ipad<=mPadLimits.second; ipad++) {
442 #ifdef ST_SECTOR_BOUNDS_CHECK
443 if( !(ipad>0 && ipad<mGeomDb->numberOfPadsAtRow(irow)) )
446 double padWidth, padLength;
447 if(irow > mGeomDb->numberOfInnerRows()) {
448 padWidth = mGeomDb->outerSectorPadWidth();
449 padLength = mGeomDb->outerSectorPadLength();
452 padWidth = mGeomDb->innerSectorPadWidth();
453 padLength = mGeomDb->innerSectorPadLength();
457 transformer(tpcRaw,xyCoord);
461 double xl = xyCoord.position().x() - padWidth/2;
462 double xu = xyCoord.position().x() + padWidth/2;
463 double yl = xyCoord.position().y() - padLength/2;
464 double yu = xyCoord.position().y() + padLength/2;
471 double chargeOfSignal =
472 signalOnPad(iter->position().x(),
473 iter->position().y(),
477 chargeOfSignal *= iter->numberOfElectrons();
483 double timeOfSignal =
484 (iter->position().z() + mElectronicsDb->tZero()*mDriftVelocity)/mDriftVelocity;
487 iter->position().z()/mDriftVelocity;
501 mSector->addEntry(irow,ipad,padSignal);
518 double StTrsSlowAnalogSignalGenerator::deltaResponse(
double tbin,
StTrsAnalogSignal& s)
523 double to = tbin*(1./mSamplingFrequency);
524 double deltaT = (1./mSamplingFrequency)/2;
526 value = ((s.time() < to+deltaT) && (s.time() > to-deltaT)) ?
527 mGain*s.amplitude() : 0;
529 value *= mFractionSampled;
535 double StTrsSlowAnalogSignalGenerator::symmetricGaussianApproximateResponse(
double tbin,
StTrsAnalogSignal& s)
553 double t = mTimeBinWidth*(tbin+.5);
555 value = mGain*s.amplitude()*mSymGausApproxFactor*TMath::Exp(-sqr(t - s.time())/(2*sqr(mSigma1)));
557 value *= mFractionSampled*mTimeBinWidth;
563 double StTrsSlowAnalogSignalGenerator::symmetricGaussianExactResponse(
double tbin,
StTrsAnalogSignal& s)
575 double lowerBound = tbin*mTimeBinWidth;
576 double upperBound = lowerBound + mTimeBinWidth;
580 value = (mGain*s.amplitude()/2.)*
581 (TMath::Erf((upperBound-s.time())/(M_SQRT2*mSigma1)) -
582 TMath::Erf((lowerBound-s.time())/(M_SQRT2*mSigma1)));
584 value *= mFractionSampled;
589 double StTrsSlowAnalogSignalGenerator::asymmetricGaussianApproximateResponse(
double tbin,
StTrsAnalogSignal& s)
603 double t = mTimeBinWidth*(tbin+.5);
606 value = mGain*s.amplitude()*mAsymGausApproxFactor*TMath::Exp(-sqr(t-s.time())/(2*sqr(mTau1)));
608 value = mGain*s.amplitude()*mAsymGausApproxFactor*TMath::Exp(-sqr(t-s.time())/(2*sqr(mTau2)));
610 value *= (mFractionSampled*mTimeBinWidth);
620 double StTrsSlowAnalogSignalGenerator::realShaperResponse(
double tbin,
StTrsAnalogSignal& sig)
638 double t = mTimeBinWidth*(tbin+.5);
645 double tzero = sig.time() - 2.*mTau+10.*nanosecond;
648 double K = sigmaL/mTau*TMath::Sqrt(tzero/mDriftVelocity);
651 double lambda = (tzero - t)/(K*mTau) + K;
654 value = 1./(2.*mTau)*sqr(K)*TMath::Exp(K*(lambda-.5*K))*
655 ( .5*(1+sqr(lambda))*(1-TMath::Erf(lambda/M_SQRT2)) -
656 lambda/(TMath::Sqrt(2*M_PI))*TMath::Exp(-sqr(lambda)/2));
658 value *= mFractionSampled*mGain*sig.amplitude();
661 value *= mTimeBinWidth;
668 double StTrsSlowAnalogSignalGenerator::oneOverT(
double t,
double to)
712 void StTrsSlowAnalogSignalGenerator::setElectronicSampler(StSignal t)
715 t == symmetricGaussianApproximation ||
716 t == symmetricGaussianExact ||
717 t == asymmetricGaussianApproximation ||
721 cerr <<
"Cannot determine Electronics Response specified" << endl;
769 void StTrsSlowAnalogSignalGenerator::sampleAnalogSignal()
771 cout <<
"StTrsSlowAnalogSignalGenerator::sampleAnalogSignal()" << endl;
776 #ifndef ST_NO_TEMPLATE_DEF_ARGS
777 vector<StTrsAnalogSignal> continuousAnalogTimeSequence;
779 vector<StTrsAnalogSignal, allocator<StTrsAnalogSignal> > continuousAnalogTimeSequence;
784 for(
int irow=1; irow<=mSector->numberOfRows(); irow++) {
787 for(
int ipad=1; ipad<=mSector->numberOfPadsInRow(irow); ipad++) {
789 continuousAnalogTimeSequence = mSector->timeBinsOfRowAndPad(irow,ipad);
791 mDiscreteAnalogTimeSequence.clear();
795 if(!continuousAnalogTimeSequence.size())
continue;
796 for(mTimeSequenceIterator = continuousAnalogTimeSequence.begin();
797 mTimeSequenceIterator != continuousAnalogTimeSequence.end();
798 mTimeSequenceIterator ++) {
802 mTimeSequenceIterator->time() +
803 mTimeShiftOfSignalCentroid;
804 mTimeSequenceIterator->setTime(tmpTime);
820 for(
int itbin=0; itbin<mGeomDb->numberOfTimeBuckets(); itbin++) {
822 timeBinT = itbin*mTimeBinWidth;
826 double pulseHeight = 0;
827 for(mTimeSequenceIterator =continuousAnalogTimeSequence.begin();
828 mTimeSequenceIterator!=continuousAnalogTimeSequence.end();
829 mTimeSequenceIterator++) {
837 if( fabs(timeBinT-mTimeSequenceIterator->time()) > 10.*mTimeBinWidth)
842 signalSampler(itbin, *mTimeSequenceIterator);
854 if(!mAddNoiseUnderSignalOnly && mAddNoise) {
855 pulseHeight += generateNoise();
865 if(mAddNoiseUnderSignalOnly && mAddNoise) {
867 pulseHeight += generateNoise();
871 mElectronicSignal.setTime(itbin);
872 mElectronicSignal.setAmplitude(pulseHeight);
878 mDiscreteAnalogTimeSequence.push_back(mElectronicSignal);
882 mSector->assignTimeBins(irow,ipad,mDiscreteAnalogTimeSequence);