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.)