13 #include "TStopwatch.h"
23 #include "TStopwatch.h"
31 : TNamed(
"PndMdtParamDigi",
"parameterized simulation of MDT")
36 , fNoiseSigmaAnode(1e-3)
37 , fNoiseSigmaStrip(1e-5)
38 , fNumofTruncation(1.)
39 , fParamsChanged(kTRUE)
40 , fDetailedSim(kFALSE)
64 fTrF =
new TF1(
"fTrF",
"(x*6./0.015)**6*exp(-x*6./0.015)", 0., 2.);
65 if(!
fTrF)
return kFALSE;
67 TString dir(gSystem->Getenv(
"VMCWORKDIR"));
68 TString mdtParamsFile(dir +
"/macro/params/MdtDigiParams.root");
69 TFile*
file = TFile::Open(mdtParamsFile);
70 if( ! file->IsOpen())
return kFALSE;
72 gFreePath[0] = (TGraphErrors*)file->Get(
"gElec");
73 gFreePath[1] = (TGraphErrors*)file->Get(
"gMuon");
74 gFreePath[2] = (TGraphErrors*)file->Get(
"gPion");
75 gFreePath[3] = (TGraphErrors*)file->Get(
"gKaon");
76 gFreePath[4] = (TGraphErrors*)file->Get(
"gProton");
81 cout<<
"PndMdtParamDigi::PndMdtParamDigi(), test"<<endl;
82 cout<<
"mean frem path @1 GeV of electron "<<
gFreePath[0]->Eval(1.)<<endl;
83 cout<<
"mean frem path @1 GeV of muon "<<
gFreePath[1]->Eval(1.)<<endl;
84 cout<<
"mean frem path @1 GeV of pion "<<
gFreePath[2]->Eval(1.)<<endl;
85 cout<<
"mean frem path @1 GeV of kaon "<<
gFreePath[3]->Eval(1.)<<endl;
86 cout<<
"mean frem path @1 GeV of proton "<<
gFreePath[4]->Eval(1.)<<endl;
98 TString mdtParamsFileI(dir +
"/macro/params/MdtDigiParamsI.root");
99 TFile* file2 = TFile::Open(mdtParamsFileI);
100 if(! file2->IsOpen())
return kFALSE;
110 for(Int_t ip=0; ip <
NPHI; ++ ip){
118 hAva1D = (TH1F*)file2->Get(
"hAva1D");
119 hAva2D = (TH2F*)file2->Get(
"hAva2D");
120 cout<<
"1D avalanche PDF "<<
hAva1D->GetTitle()<<endl;
121 cout<<
"2D avalanche PDF "<<
hAva2D->GetTitle()<<endl;
124 if(
hAva1D->GetBinContent(
ir+1) > 0){
129 for(Int_t ip=0; ip <
hAva2D->GetNbinsY(); ++ ip)
130 if(
hAva2D->GetBinContent(
ir+1, ip+1) > 0){
137 hIonNum =
new TH1F(
"hIonizationNum",
"number of primary ionization", 20, 0, 20);
138 hTrack =
new TH2F(
"hTrack",
"trajectory of primary track", 100, -0.5, 0.5, 100, -0.5, 0.5);
139 hAvaPos =
new TH2F(
"hAvaPos",
"avalanche profile", 100, -0.01, 0.01, 100, -0.01, 0.01);
140 hAvaNum =
new TH1F(
"hAvaNum",
"avalanche", 20000, 0, 20000);
141 hIndex =
new TH1F(
"hIndex",
"raidal avlanche structure", 100,0, 100);
142 hIndex->GetXaxis()->SetTitle(
"Start bin of Drift");
143 h2dIndex =
new TH2F(
"h2dIndex",
"raidal avlanche structure", 100,0, 100, 100, 0, 100);
144 h2dIndex->GetXaxis()->SetTitle(
"Start bin of Drift");
146 hExp1 =
new TH1F(
"expf",
"exponential dis", 100,0,1);
148 hGen =
new TH1F(
"gen",
"general dist", 100, 0, 10000);
149 hLan =
new TH1F(
"lan",
"landau dis", 20, 0, 20);
171 cout<<
"==============================================="<<endl;
172 TString partileName[5] = {
"Elec",
"Muon",
"Pion",
"Kaon",
"Proton"};
173 cout<<
"PndMdtParamDigi::SetParams, "<<partileName[ptlType]<<endl
174 <<
" initial momentum#"<<iniP.X()<<
", "<<iniP.Y()<<
", "<<iniP.Z()<<
", "<<iniP.Mag()<<
"GeV"<<endl
175 <<
" initial position#"<<iniPos.X()<<
", "<<iniPos.Y()<<
", "<<iniPos.Z()<<
", "<<iniPos.Mag()<<
"cm"<<endl
176 <<
" final position#"<<finalPos.X()<<
", "<<finalPos.Y()<<
", "<<finalPos.Z()<<
", "<<finalPos.Mag()<<
"cm"<<endl;
177 cout<<
"==============================================="<<endl;
186 TCanvas*
c =
new TCanvas(
"cPndMdtParamDigi",
"PndMdtParamDigi", 800, 600);
198 hAva1D->SetLineColor(kRed);
205 TCanvas*
c2 =
new TCanvas(
"dist",
"PndMdtParamDigi", 800, 600);
215 TCanvas*
c1 =
new TCanvas(
"cSignal",
"Signals", 900, 900);
219 hAI->GetYaxis()->SetTitle(
"I(#muA)");
224 std::map<Int_t, std::vector<Double_t> >::iterator it =
fSignalDataStripM.begin();
227 for(; it != end; ++it, ++ipad){
231 TString title=
"induced current @strip ";
233 TH1F* hCI =
new TH1F(name, title, fSamplingSize, 0, fSamplingSize*
fSamplingInterval/1.e3);
234 hCI->GetYaxis()->SetTitle(
"I(#muA)");
235 std::vector<Double_t>& fSignalDataStrip = it->second;
237 hCI->SetBinContent(
i+1, fSignalDataStrip[
i]);
262 if(mPath < 0.)
return;
273 Int_t fNumofCluster(0);
274 Int_t fNumofSingleIonization =0;
275 Int_t fNumofTotalIonizaion = 0;
276 Int_t fNumofIonsofThisCluster = 0;
277 Int_t fNumofTotalIons = 0;
278 TVector2 fIonProductionPos;
287 fStepLen = gRandom->Exp(mPath);
289 fTrackLen += fStepLen;
290 fCurrentPosofCluster += fStepLen*fUnitMotion;
292 if(fCurrentPosofCluster.XYvector().Mod() <=
cWIRERADIUS)
295 fNumofSingleIonization = gRandom->Landau(NumofPrimaryIonizaionMpv.first, NumofPrimaryIonizaionMpv.second);
296 fNumofTotalIonizaion += fNumofSingleIonization;
299 hIonNum->Fill(fNumofSingleIonization);
300 hTrack->Fill(fCurrentPosofCluster.X(), fCurrentPosofCluster.Y());
303 Int_t iSign = fCurrentPosofCluster.Z() >= 0 ? 1 : -1;
304 Int_t zIndex = Int_t(fCurrentPosofCluster.Z()/
cSTRIPWIDTH + iSign*0.5);
305 zIndex = zIndex >= 0 ? zIndex*2 : -2*zIndex -1;
313 if(fNumofSingleIonization > 0)
315 fNumofIonsofThisCluster =
hAvaSize->GetRandom();
316 fNumofTotalIons += fNumofIonsofThisCluster;
318 hAvaNum->Fill(fNumofIonsofThisCluster);
320 if( fNumofIonsofThisCluster > 10 )
332 TVector2 unitV = fCurrentPosofCluster.XYvector().Unit();
333 std::map<Int_t, Int_t> fAnodeIndex;
334 std::map<Int_t, Int_t> fStripIndex;
336 for(ii = 0; ii < fNumofIonsofThisCluster; ++ii)
342 Int_t phiIndex = Int_t(fIonProductionPos.Phi()/
cUNITPHI);
347 hAvaPos->Fill(fIonProductionPos.X(), fIonProductionPos.Y());
352 if(rIndex>=
NRAD)
continue;
353 if(phiIndex >=
NPHI)
continue;
355 ++ fAnodeIndex[rIndex];
356 ++ fStripIndex[rIndex + phiIndex*
NRAD];
358 std::map<Int_t, Int_t>::const_iterator mit = fAnodeIndex.begin();
359 std::map<Int_t, Int_t>::const_iterator mend = fAnodeIndex.end();
360 for(; mit != mend; ++mit){
367 mit = fStripIndex.begin();
368 mend = fStripIndex.end();
369 for(; mit != mend; ++mit){
373 Int_t rIdx = mit->first%
NRAD;
374 Int_t phiIdx = mit->first/
NRAD;
377 fSignalDataStrip[ii] += fScaleFactor* mit->second *
hCathodeI2d[rIdx][phiIdx]->GetBinContent(jj);
384 }
while(fTrackLen < fMaxPath);
390 cout<<
"PndMdtParamDigi::GetRawSignal, cost "<<sw.CpuTime()<<
" s"
391 <<
" clusters#"<<fNumofCluster
392 <<
" primary ionization#"<<fNumofTotalIonizaion
393 <<
" total ions#"<<fNumofTotalIons<<endl;
410 if(mPath < 0.)
return;
420 Int_t fNumofCluster(0);
421 Int_t fNumofSingleIonization =0;
422 Int_t fNumofTotalIonizaion = 0;
423 Int_t fNumofIonsofThisCluster = 0;
424 Int_t fNumofTotalIons = 0;
433 fStepLen = gRandom->Exp(mPath);
435 fTrackLen += fStepLen;
436 fCurrentPosofCluster += fStepLen*fUnitMotion;
438 if(fCurrentPosofCluster.XYvector().Mod() <=
cWIRERADIUS)
441 fNumofSingleIonization = gRandom->Landau(NumofPrimaryIonizaionMpv.first, NumofPrimaryIonizaionMpv.second);
442 fNumofTotalIonizaion += fNumofSingleIonization;
445 hIonNum->Fill(fNumofSingleIonization);
446 hTrack->Fill(fCurrentPosofCluster.X(), fCurrentPosofCluster.Y());
449 Int_t iSign = fCurrentPosofCluster.Z() >= 0 ? 1 : -1;
450 Int_t zIndex = Int_t(fCurrentPosofCluster.Z()/
cSTRIPWIDTH + iSign*0.5);
451 zIndex = zIndex >= 0 ? zIndex*2 : -2*zIndex -1;
459 if(fNumofSingleIonization > 0)
461 fNumofIonsofThisCluster =
hAvaSize->GetRandom();
462 fNumofTotalIons += fNumofIonsofThisCluster;
464 hAvaNum->Fill(fNumofIonsofThisCluster);
466 if( fNumofIonsofThisCluster > 1 )
475 Int_t refPhiIndex = Int_t(fCurrentPosofCluster.Phi()/
cUNITPHI);
478 std::vector<AvaBinType>::const_iterator vit =
fProbFunc1D.begin();
479 std::vector<AvaBinType>::const_iterator end =
fProbFunc1D.end();
480 for(; vit != end; ++ vit)
498 std::map<Int_t, Double_t> fInfo;
499 for(; vit != end; ++ vit)
502 Int_t fN = fNumofIonsofThisCluster* bin.
Probabilty;
507 phiIdx += refPhiIndex;
509 fInfo[rIdx + phiIdx*
NRAD] = fN;
511 fSignalDataStrip[ii] += fScaleFactor* fN *
hCathodeI2d[rIdx][phiIdx]->GetBinContent(jj);
516 h2dIndex->SetBinContent(irr+1, ipp+1,
h2dIndex->GetBinContent(irr+1, ipp+1) + fN);
525 for(Int_t iv = 0; iv < fN; ++ iv)
534 }
while(fTrackLen < fMaxPath);
547 std::vector<std::pair<Int_t, Double_t> > fFiredInfo;
553 fFiredInfo.push_back(std::pair<Int_t, Double_t>(-1, mTime));
555 std::map<Int_t, std::vector<Double_t> >::iterator it =
fSignalDataStripM.begin();
557 for(; it != end; ++it){
558 if(
Digitize(it->first, mTime, mAmplitude)){
559 fFiredInfo.push_back(std::pair<Int_t, Double_t>(it->first, mTime));
581 std::map<Int_t, std::vector<Double_t> >::iterator it =
fSignalDataStripM.begin();
584 std::vector<Double_t>& fSignalDataStrip = it->second;
600 dtau = (
fTrF->GetXmax() -
fTrF->GetXmin())/1.e3;
608 tprime =
fTrF->GetXmin();
609 while( tprime < fTrF->GetXmax()){
610 iBin = (Int_t)(tprime/dt);
612 fG = (t-tprime <
fTrF->GetXmin()) || (t-tprime >
fTrF->GetXmax()) ? 0 :
fTrF->Eval((t-tprime));
613 fIntegral += fF*fG*dtau;
616 fSignalData[
i] = fIntegral;
626 std::map<Int_t, std::vector<Double_t> >::iterator it =
fSignalDataStripM.begin();
629 std::vector<Double_t>& fSignalDataStrip = it->second;
631 fSignalDataStrip[
i] += gRandom->Gaus(0, fSigmaStrip);
686 TGraphErrors* gAmp(0);
688 gAmp=
new TGraphErrors(9);
689 gAmp->SetPoint(0, 0.05, 5440.5);
690 gAmp->SetPointError(0, 0, 2402.1);
691 gAmp->SetPoint(1, 0.10, 5683.1);
692 gAmp->SetPointError(1, 0, 2661.3);
693 gAmp->SetPoint(2, 0.20, 5774.8);
694 gAmp->SetPointError(2, 0, 2803.5);
695 gAmp->SetPoint(3, 0.30, 5629.1);
696 gAmp->SetPointError(3, 0, 2590.4);
697 gAmp->SetPoint(4, 0.50, 5708.1);
698 gAmp->SetPointError(4, 0, 2734.2);
699 gAmp->SetPoint(5, 1.00, 5667.6);
700 gAmp->SetPointError(5, 0, 2755.5);
701 gAmp->SetPoint(6, 2.00, 5958.2);
702 gAmp->SetPointError(7, 0, 2712.1);
703 gAmp->SetPoint(7, 5.00, 5643.8);
704 gAmp->SetPointError(7, 0, 2389.5);
705 gAmp->SetPoint(8, 10.00, 5749.3);
706 gAmp->SetPointError(8, 0, 2552.6);
709 Double_t fMeanAmp = gAmp->Eval(momentum);
710 Double_t fAmpErr = gAmp->GetErrorY(momentum);
711 return (Int_t) fScaleFactor*gRandom->Gaus(fMeanAmp, fAmpErr);
728 Double_t betagamma = fMomentum.Mag()/fMass;
729 val.first = p0*
exp(p1*
log(1+betagamma)) + p2/(pow(betagamma, p3));
730 val.second = betagamma < 0.3 ? 0.234 : 0.334;
734 const Double_t cThetaSigma = 2.67859e-01;
736 Double_t mTheta = gRandom->Gaus(0., cThetaSigma);
743 if(prob < 2.38210768816632112e-02){
744 mRadius = gRandom->Exp(mTauR1);
745 }
else if(prob < 4.34694439053706305e-01){
746 mRadius = gRandom->Exp(mTauR2);
748 mRadius = gRandom->Exp(mTauR3);
754 TVector2 unitV = fDirection.Unit();
756 fIonProductionPos.Set( unitV.X()*mX - unitV.Y()*mY, unitV.Y()*mX + unitV.X()*mY);
std::pair< Double_t, Double_t > ValueErrorType
friend F32vec4 cos(const F32vec4 &a)
void operator()(Double_t v) const
Double_t fNoiseSigmaStrip
friend F32vec4 exp(const F32vec4 &a)
Int_t GetAmplicationFactor(Int_t particleType, Double_t momentum) const
std::vector< std::pair< Int_t, Double_t > > GetFiredInfo()
Double_t val[nBoxes][nFEBox]
friend F32vec4 sin(const F32vec4 &a)
Bool_t Digitize(Double_t &time, Double_t &)
friend F32vec4 log(const F32vec4 &a)
void AddNoise(Double_t fNoiseLevel=1., Int_t isAnode=1)
static const Int_t fSamplingSize
void GetSignal(Bool_t useConvolution=kTRUE)
Double_t fNoiseSigmaAnode
void ApplyTransferFunction(Double_t *fSignalData, Int_t nSize=fSamplingSize)
void GetMPVofPrimaryIonization(Int_t particleType, const TVector3 &momentum, ValueErrorType &val) const
TVector3 fParticleMomentum
PndMdtParamDigi & SetParams(Int_t ptlType, TVector3 iniP, TVector3 iniPos, TVector3 finalPos, Double_t stripLen=100.)
Double_t GetElectronDriftTime(TVector2 iniPos)
void Compute(Bool_t useConvolution=kTRUE)
std::map< Int_t, std::vector< Double_t > > fSignalDataStripM
void GetRawSignalbyWeightingAvalanche(Double_t fNoiseLevel=1.)
std::vector< AvaBinType > fProbFunc2D
void SamplingPosition(TVector2 fDirection, TVector2 &fIonProductionPos)
std::vector< Double_t > fSignalDataAnode
TGraphErrors * gFreePath[5]
TH1F * hCathodeI2d[NRAD][NPHI]
std::vector< AvaBinType > fProbFunc1D
void GetRawSignalbySimAvalanche(Double_t fNoiseLevel=1.)