FairRoot/PandaRoot
PndMdtParamDigi.cxx
Go to the documentation of this file.
1 // -------------------------------------------------------------------------
2 // ----- PndMdtParamDigi source file -----
3 // ----- Created 29/03/11 by S.Spataro -----
4 // -------------------------------------------------------------------------
5 
6 #include "PndMdtParamDigi.h"
7 #include "TVector3.h"
8 #include "TRandom.h"
9 #include "TSystem.h"
10 #include "TFile.h"
11 #include <assert.h>
12 #include <iostream>
13 #include "TStopwatch.h"
14 #include "PndMdtIGeometry.h"
15 #include "TCanvas.h"
16 #include "TGraph.h"
17 #include "TMath.h"
18 #include <algorithm>
19 //#include <CLHEP/Random/RandExponential.h>
20 //#include <CLHEP/Random/RandGeneral.h>
21 //#include <CLHEP/Random/RandLandau.h>
22 //#include <CLHEP/Random/RandGauss.h>
23 #include "TStopwatch.h"
24 
25 using std::cout;
26 using std::endl;
27 
28 
29 // ----- Default constructor -------------------------------------------
31  : TNamed("PndMdtParamDigi", "parameterized simulation of MDT")
32  , fSamplingRate(1e8)
33  , fTrF(0)
34  , fUseNoise(kTRUE)
35  , fGaussianAmp(kTRUE)
36  , fNoiseSigmaAnode(1e-3)
37  , fNoiseSigmaStrip(1e-5)
38  , fNumofTruncation(1.)
39  , fParamsChanged(kTRUE)
40  , fDetailedSim(kFALSE)
41  , fUseAvaHist(kFALSE)
42  , fUsePlot(kTRUE)
43  , fVerbose(0)
44 {
45  cWIRERADIUS = 0.0025001;//unit: cm
46  cCELLSIZE = 0.5;//unit: cm
47  cSTRIPWIDTH = 1.0;//unit: cm
48  cMAXRADIUS = 0.00525;//not changeable
49  cMAPFACTOR = 1000.;//not changeable
50 
52  cUNITPHI = TMath::Pi()*2./NPHI;
54  fRestMass[0] = 0.00510998928;
55  fRestMass[1] = 0.1056583715;
56  fRestMass[2] = 0.13957018;
57  fRestMass[3] = 0.493667;
58  fRestMass[4] = 0.938272046;// GeV
59 
60  SPEEDOFLIGHT = 299792458;//m/s
61 }
63 {
64  fTrF = new TF1("fTrF", "(x*6./0.015)**6*exp(-x*6./0.015)", 0., 2.);
65  if(! fTrF) return kFALSE;
66 
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;
71 
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");
77  hAvaSize = (TH1F*)file->Get("hava");
78  //hAnodeI = (TH1F*)file->Get("hAnodeI");
79  //hCathodeIx= (TH1F*)file->Get("hCathodeIx");
80  //hCathodeIy= (TH1F*)file->Get("hCathodeIy");
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;
87  //cout<<"avalanche size #"<<hAvaSize->GetRandom()<<endl;
88  //cout<<"induced current on anode @t = 0.05us, "<<hAnodeI->GetBinContent(5)<<endl;
89  //cout<<"induced current on cathode @t = 0.05us, theta 0, "<<hCathodeIx->GetBinContent(5)<<endl;
90  //cout<<"induced current on cathode @t = 0.05us, theta PI/2, "<<hCathodeIy->GetBinContent(5)<<endl;
91  //file->Close();
92  fUseAvaHist = kTRUE;
93  //double* lProbData = new double[hAvaSize->GetNbinsX()];
94  //for(Int_t ib=0; ib < hAvaSize->GetNbinsX(); ++ ib)
95  // lProbData[ib] = hAvaSize->GetBinContent(ib+1);
96  //fRandAva = new CLHEP::RandGeneral(lProbData, hAvaSize->GetNbinsX());
97 
98  TString mdtParamsFileI(dir + "/macro/params/MdtDigiParamsI.root");
99  TFile* file2 = TFile::Open(mdtParamsFileI);
100  if(! file2->IsOpen()) return kFALSE;
101 
102  for(Int_t ir=0; ir < NRAD; ++ ir)
103  {
104  TString hisName("Ir");
105  hisName += ir;
106  hAnodeI1d[ir] = (TH1F*)file2->Get(hisName);
107  }
108  for(Int_t ir=0; ir < NRAD; ++ ir)
109  {
110  for(Int_t ip=0; ip <NPHI; ++ ip){
111  TString hisName("Ir");
112  hisName += ir;
113  hisName += "t";
114  hisName += ip;
115  hCathodeI2d[ir][ip] = (TH1F*)file2->Get(hisName);
116  }
117  }
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;
122 
123  for(Int_t ir=0; ir < hAva1D->GetNbinsX(); ++ ir)
124  if(hAva1D->GetBinContent(ir+1) > 0){
125  fProbFunc1D.push_back(AvaBinType(ir, hAva1D->GetBinContent(ir+1)));
126  }
127 
128  for(Int_t ir=0; ir < hAva2D->GetNbinsX(); ++ ir)
129  for(Int_t ip=0; ip < hAva2D->GetNbinsY(); ++ ip)
130  if(hAva2D->GetBinContent(ir+1, ip+1) > 0){
131  fProbFunc2D.push_back(AvaBinType(ir+ip*NRAD, hAva2D->GetBinContent(ir+1, ip+1)));
132  }
133 
134 
135  if(fUsePlot)
136  {
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");
145 
146  hExp1 = new TH1F("expf", "exponential dis", 100,0,1);
147  //hExp2;
148  hGen = new TH1F("gen", "general dist", 100, 0, 10000);
149  hLan = new TH1F("lan", "landau dis", 20, 0, 20);
150  }
152 
153  return kTRUE;
154 }
155 // -------------------------------------------------------------------------
156 
157 // ----- Destructor ----------------------------------------------------
159 //setup parameters
160 PndMdtParamDigi& PndMdtParamDigi::SetParams(Int_t ptlType, TVector3 iniP, TVector3 iniPos, TVector3 finalPos, Double_t stripLen)
161 {
162  fParticleType = ptlType;
163  fParticleMomentum = iniP;
164  fInitPostion = iniPos;
165  fExitPosition = finalPos;
166  fStripLength = stripLen;
167  fParamsChanged = kTRUE;
168  fSignalDataStripM.clear();
169 
170  if(fVerbose > 1){
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;
178  }
179  return *this;
180 }
181 
183 {
184  if(fUsePlot)
185  {
186  TCanvas* c = new TCanvas("cPndMdtParamDigi", "PndMdtParamDigi", 800, 600);
187  c->Divide(2,3);
188  c->cd(1);
189  hTrack->Draw("colz");
190  c->cd(2);
191  //hAva2D->Draw("colz");
192  hIonNum->Draw();
193  c->cd(3);
194  hAvaPos->Draw("colz");
195  c->cd(5);
196  hIndex->DrawNormalized();
197  c->cd(5);
198  hAva1D->SetLineColor(kRed);
199  hAva1D->SetLineWidth(2);
200  hAva1D->Draw("same");
201  c->cd(6);
202  hAva2D->Draw("colz");
203  c->cd(4);
204  h2dIndex->Draw("colz");
205  TCanvas* c2 = new TCanvas("dist", "PndMdtParamDigi", 800, 600);
206  c2->Divide(2,2);
207  c2->cd(1);
208  hExp1->Draw();
209  c2->cd(2);
210  c2->cd(3);
211  hGen->Draw();
212  c2->cd(4);
213  hLan->Draw();
214  }
215  TCanvas* c1 = new TCanvas("cSignal", "Signals", 900, 900);
216  c1->Divide(3, (fSignalDataStripM.size() + 1)/3);
217  c1->cd(1);
218  TH1F* hAI = new TH1F("hAI","induced current @anode", fSamplingSize, 0, fSamplingSize*fSamplingInterval/1.e3);
219  hAI->GetYaxis()->SetTitle("I(#muA)");
220  for(Int_t i=0; i < fSamplingSize; ++i){
221  hAI->SetBinContent(i+1, fSignalDataAnode[i]);
222  }
223  hAI->Draw();
224  std::map<Int_t, std::vector<Double_t> >::iterator it = fSignalDataStripM.begin();
225  std::map<Int_t, std::vector<Double_t> >::iterator end = fSignalDataStripM.end();
226  Int_t ipad=1;
227  for(; it != end; ++it, ++ipad){
228  c1->cd(1+ipad);
229  TString name="hCI";
230  name += it->first;
231  TString title="induced current @strip ";
232  title += it->first;
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;
236  for(Int_t i=0; i < fSamplingSize; ++i){
237  hCI->SetBinContent(i+1, fSignalDataStrip[i]);
238  }
239  hCI->Draw();
240  }
241 }
242 void PndMdtParamDigi::Compute(Bool_t useConvolution)
243 {
244  GetSignal(useConvolution);
245 }
246 
248 {
249 
250  if(!fParamsChanged) return;
251 
252  fParamsChanged = kFALSE;
253  memset(&fSignalDataAnode[0], 0, fSamplingSize*sizeof(Double_t));
254  //memset(&fSignalDataStrip[0], 0, fSamplingSize*sizeof(Double_t));
255  fSignalDataStripM.clear();
256 
257  TVector3 fUnitMotion = (fExitPosition-fInitPostion).Unit();
258  Double_t fMaxPath = (fExitPosition-fInitPostion).Mag();
260  if(fParticleType == 4 && mBeta < 0.2) return;
261  Double_t mPath = gFreePath[fParticleType]->Eval(mBeta);
262  if(mPath < 0.) return;
263  const Double_t fScaleFactor = 40.;
264 
265  Int_t jj;
266  Int_t ii;
267 
268  ValueErrorType NumofPrimaryIonizaionMpv;
269  GetMPVofPrimaryIonization(fParticleType, fParticleMomentum, NumofPrimaryIonizaionMpv);
270 
271 
272  TVector3 fCurrentPosofCluster = fInitPostion;
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;
279  Double_t fStepLen = 0.;
280  Double_t fTrackLen = 0.;
281  Double_t fTime = 0.;
282 
283  TStopwatch sw;
284  sw.Start();
285  do
286  {
287  fStepLen = gRandom->Exp(mPath);
288  fTime += fStepLen/(mBeta*SPEEDOFLIGHT*1.e7);//nano second
289  fTrackLen += fStepLen;
290  fCurrentPosofCluster += fStepLen*fUnitMotion;
291 
292  if(fCurrentPosofCluster.XYvector().Mod() <= cWIRERADIUS)
293  continue;
294 
295  fNumofSingleIonization = gRandom->Landau(NumofPrimaryIonizaionMpv.first, NumofPrimaryIonizaionMpv.second);
296  fNumofTotalIonizaion += fNumofSingleIonization;
297 
298  if(fUsePlot){
299  hIonNum->Fill(fNumofSingleIonization);
300  hTrack->Fill(fCurrentPosofCluster.X(), fCurrentPosofCluster.Y());
301  }
302 
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;
306 
307 
308  //cout<<"fSignalDataStrip.size()#"<<fSignalDataStrip.size()<<endl;
309  std::vector<Double_t>& fSignalDataStrip = fSignalDataStripM[zIndex];
310  if(fSignalDataStrip.size() != fSamplingSize)
311  fSignalDataStrip.resize(fSamplingSize);
312 
313  if(fNumofSingleIonization > 0)
314  {
315  fNumofIonsofThisCluster = hAvaSize->GetRandom();
316  fNumofTotalIons += fNumofIonsofThisCluster;
317  if(fUsePlot)
318  hAvaNum->Fill(fNumofIonsofThisCluster);
319 
320  if( fNumofIonsofThisCluster > 10 )
321  {
322  //Double_t lx = fCurrentPosofCluster.XYvector().Mod() - cWIRERADIUS;
323  //Double_t lx1 = log(1.+lx);
324  //clusInfo.fStartTime = fTime + (lx*(p0 + p1*pow(lx, 0.25)) + lx1*(p2 + p3*lx1));
325 
326  Double_t fStartTime = fTime + GetElectronDriftTime(fCurrentPosofCluster.XYvector());//micro second
327  Int_t tShift = Int_t(fStartTime/fSamplingInterval);
328  if(tShift >= fSamplingSize) tShift = fSamplingSize-1;
329  //Int_t refPhiIndex = Int_t(fCurrentPosofCluster.Phi()/cUNITPHI); //[R.K. 01/2017] unused variable?
330  //if(refPhiIndex>=100) refPhiIndex = 99;
331 
332  TVector2 unitV = fCurrentPosofCluster.XYvector().Unit();
333  std::map<Int_t, Int_t> fAnodeIndex;//fired region
334  std::map<Int_t, Int_t> fStripIndex;//fired region
335 
336  for(ii = 0; ii < fNumofIonsofThisCluster; ++ii)
337  {//avalanche profile
338  //get position of this ion
339  SamplingPosition(unitV, fIonProductionPos);
340  //cout<<"sampling done, r = "<<fIonProductionPos.Mod()<<endl;
341  Int_t rIndex = Int_t(TMath::Log(1. + cMAPFACTOR*(fIonProductionPos.Mod() - cWIRERADIUS))/cUNITLOGDR);
342  Int_t phiIndex = Int_t(fIonProductionPos.Phi()/cUNITPHI);
343  if(fUsePlot){
344  hIndex->Fill(rIndex);
345  //h2dIndex->Fill(rIndex, phiIndex-refPhiIndex < 0 ? 100 + phiIndex-refPhiIndex : phiIndex-refPhiIndex);
346  h2dIndex->Fill(rIndex, phiIndex);
347  hAvaPos->Fill(fIonProductionPos.X(), fIonProductionPos.Y());
348  }
349  //cout<<"plot done"<<endl;
350  //if(rIndex>=NRAD) rIndex = NRAD-1;
351  //if(phiIndex >= NPHI) phiIndex = NPHI -1;
352  if(rIndex>=NRAD) continue;
353  if(phiIndex >= NPHI) continue;
354  //cout<<"rIndex = "<<rIndex<<", phiIndex = "<<phiIndex<<endl;
355  ++ fAnodeIndex[rIndex];
356  ++ fStripIndex[rIndex + phiIndex*NRAD];
357  }
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){
361  if(mit->second > fNumofTruncation){
362  for(ii = tShift, jj=1; ii < fSamplingSize; ++ii, ++jj){
363  fSignalDataAnode[ii] += mit->second * hAnodeI1d[mit->first]->GetBinContent(jj);
364  }
365  }
366  }
367  mit = fStripIndex.begin();
368  mend = fStripIndex.end();
369  for(; mit != mend; ++mit){
370  Double_t fN = mit->second;
371  if(fN > fNumofTruncation)
372  {
373  Int_t rIdx = mit->first%NRAD;
374  Int_t phiIdx = mit->first/NRAD;
375  //cout<<"Index ("<<rIdx<<", "<<phiIdx<<") = "<<fN<<endl;
376  for(ii = tShift, jj=1; ii < fSamplingSize; ++ii, ++jj){
377  fSignalDataStrip[ii] += fScaleFactor* mit->second * hCathodeI2d[rIdx][phiIdx]->GetBinContent(jj);
378  }
379  }
380  }
381  }
382  }
383  ++ fNumofCluster;
384  }while(fTrackLen < fMaxPath);
385 
386  if(fUseNoise){
387  AddNoise(fNoiseLevel);
388  }
389  sw.Stop();
390  cout<<"PndMdtParamDigi::GetRawSignal, cost "<<sw.CpuTime()<<" s"
391  <<" clusters#"<<fNumofCluster
392  <<" primary ionization#"<<fNumofTotalIonizaion
393  <<" total ions#"<<fNumofTotalIons<<endl;
394 }
396 {
397  static Double_t fScaleFactor = 40.;
398 
399  if(!fParamsChanged) return;
400 
401  fParamsChanged = kFALSE;
402  memset(&fSignalDataAnode[0], 0, fSamplingSize*sizeof(Double_t));
403  //memset(&fSignalDataStrip[0], 0, fSamplingSize*sizeof(Double_t));
404  fSignalDataStripM.clear();
405 
406  TVector3 fUnitMotion = (fExitPosition-fInitPostion).Unit();
407  Double_t fMaxPath = (fExitPosition-fInitPostion).Mag();
409  Double_t mPath = gFreePath[fParticleType]->Eval(mBeta);
410  if(mPath < 0.) return;
411 
412  Int_t jj;
413  Int_t ii;
414 
415  ValueErrorType NumofPrimaryIonizaionMpv;
416  GetMPVofPrimaryIonization(fParticleType, fParticleMomentum, NumofPrimaryIonizaionMpv);
417 
418 
419  TVector3 fCurrentPosofCluster = fInitPostion;
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;
425  Double_t fStepLen = 0.;
426  Double_t fTrackLen = 0.;
427  Double_t fTime = 0.;
428 
429  //TStopwatch sw;
430  //sw.Start();
431  do
432  {
433  fStepLen = gRandom->Exp(mPath);
434  fTime += fStepLen/(mBeta*SPEEDOFLIGHT*1.e7);//nano second
435  fTrackLen += fStepLen;
436  fCurrentPosofCluster += fStepLen*fUnitMotion;
437 
438  if(fCurrentPosofCluster.XYvector().Mod() <= cWIRERADIUS)
439  continue;
440 
441  fNumofSingleIonization = gRandom->Landau(NumofPrimaryIonizaionMpv.first, NumofPrimaryIonizaionMpv.second);
442  fNumofTotalIonizaion += fNumofSingleIonization;
443 
444  if(fUsePlot){
445  hIonNum->Fill(fNumofSingleIonization);
446  hTrack->Fill(fCurrentPosofCluster.X(), fCurrentPosofCluster.Y());
447  }
448 
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;
452 
453 
454  //cout<<"fSignalDataStrip.size()#"<<fSignalDataStrip.size()<<endl;
455  std::vector<Double_t>& fSignalDataStrip = fSignalDataStripM[zIndex];
456  if(fSignalDataStrip.size() != fSamplingSize)
457  fSignalDataStrip.resize(fSamplingSize);
458 
459  if(fNumofSingleIonization > 0)
460  {
461  fNumofIonsofThisCluster = hAvaSize->GetRandom();
462  fNumofTotalIons += fNumofIonsofThisCluster;
463  if(fUsePlot)
464  hAvaNum->Fill(fNumofIonsofThisCluster);
465 
466  if( fNumofIonsofThisCluster > 1 )
467  {
468  //Double_t lx = fCurrentPosofCluster.XYvector().Mod() - cWIRERADIUS;
469  //Double_t lx1 = log(1.+lx);
470  //clusInfo.fStartTime = fTime + (lx*(p0 + p1*pow(lx, 0.25)) + lx1*(p2 + p3*lx1));
471 
472  Double_t fStartTime = fTime + GetElectronDriftTime(fCurrentPosofCluster.XYvector());//micro second
473  Int_t tShift = Int_t(fStartTime/fSamplingInterval);
474  if(tShift >= fSamplingSize) tShift = fSamplingSize-1;
475  Int_t refPhiIndex = Int_t(fCurrentPosofCluster.Phi()/cUNITPHI);
476  //wire signal
477  //cout<<"1D, number of fired bins #"<<fProbFunc1D.size()<<endl;
478  std::vector<AvaBinType>::const_iterator vit = fProbFunc1D.begin();
479  std::vector<AvaBinType>::const_iterator end = fProbFunc1D.end();
480  for(; vit != end; ++ vit)
481  {
482  const AvaBinType& bin = *vit;
483  Double_t fN = fNumofIonsofThisCluster* bin.Probabilty;
484  if(fN > fNumofTruncation){
485  for(ii = tShift, jj=1; ii < fSamplingSize; ++ ii, ++jj){
486  fSignalDataAnode[ii] += fN*hAnodeI1d[bin.Index]->GetBinContent(jj);
487  }
488  }
489  if(fUsePlot){
490  hIndex->SetBinContent(bin.Index+1, hIndex->GetBinContent(bin.Index+1) + fN);
491  }
492  }
493  //cout<<"wire signal done"<<endl;
494  //strip signal
495  //cout<<"2D, number of fired bins #"<<fProbFunc2D.size()<<endl;
496  vit = fProbFunc2D.begin();
497  end = fProbFunc2D.end();
498  std::map<Int_t, Double_t> fInfo;
499  for(; vit != end; ++ vit)
500  {
501  const AvaBinType& bin = *vit;
502  Int_t fN = fNumofIonsofThisCluster* bin.Probabilty;
503  if(fN > fNumofTruncation){
504  //retrieve the rIndex, phiIndex;
505  Int_t rIdx = bin.Index%NRAD;
506  Int_t phiIdx = bin.Index/NRAD;
507  phiIdx += refPhiIndex;
508  phiIdx %= NPHI;
509  fInfo[rIdx + phiIdx*NRAD] = fN;
510  for(ii = tShift, jj=1; ii < fSamplingSize; ++ ii, ++jj){
511  fSignalDataStrip[ii] += fScaleFactor* fN *hCathodeI2d[rIdx][phiIdx]->GetBinContent(jj);
512  }
513  if(fUsePlot){
514  Int_t irr = rIdx;
515  Int_t ipp = phiIdx;
516  h2dIndex->SetBinContent(irr+1, ipp+1, h2dIndex->GetBinContent(irr+1, ipp+1) + fN);
517  //Int_t rIndex = Int_t(TMath::Log(1. + cMAPFACTOR*(fIonProductionPos.Mod() - cWIRERADIUS))/cUNITLOGDR);
518  //Int_t phiIndex = Int_t(fIonProductionPos.Phi()/cUNITPHI);
519  Double_t PHI = (ipp+1)*cUNITPHI;
520  Double_t RADIUS = (exp(irr+1) - 1.)*cUNITLOGDR/cMAPFACTOR + cWIRERADIUS;
521  Double_t x = RADIUS*TMath::Cos(PHI);
522  Double_t y = RADIUS*TMath::Sin(PHI);
523  //Int_t ix = (x + 0.01)/0.0002;
524  //Int_t iy = (y + 0.01)/0.0002;
525  for(Int_t iv = 0; iv < fN; ++ iv)
526  hAvaPos->Fill(x,y);
527  //hAvaPos->SetBinContent(ix, iy, hAvaPos->GetBinContent(ix, iy) + fNrNphi[ir][ipp]);
528  }
529  }
530  }
531  }
532  }
533  ++ fNumofCluster;
534  }while(fTrackLen < fMaxPath);
535 
536  if(fUseNoise){
537  AddNoise(fNoiseLevel);
538  }
539  //sw.Stop();
540  //cout<<"PndMdtParamDigi::GetRawSignal, cost "<<sw.CpuTime()<<" s"
541  // <<" clusters#"<<fNumofCluster
542  // <<" primary ionization#"<<fNumofTotalIonizaion
543  // <<" total ions#"<<fNumofTotalIons<<endl;
544 }
545 std::vector<std::pair<Int_t, Double_t> > PndMdtParamDigi::GetFiredInfo()
546 {
547  std::vector<std::pair<Int_t, Double_t> > fFiredInfo;
548  Double_t mTime;
549  Double_t mAmplitude;
550  GetSignal();
551 
552  if(Digitize(mTime, mAmplitude))
553  fFiredInfo.push_back(std::pair<Int_t, Double_t>(-1, mTime));
554 
555  std::map<Int_t, std::vector<Double_t> >::iterator it = fSignalDataStripM.begin();
556  std::map<Int_t, std::vector<Double_t> >::iterator end = fSignalDataStripM.end();
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));
560  }
561  }
562  return fFiredInfo;
563 }
564 struct print
565 {
566  void operator()(Double_t v) const
567  { cout<<v<<", "; }
568 };
569 // -------------------------------------------------------------------------
570 void PndMdtParamDigi::GetSignal(Bool_t useConvolution)
571 {
572 
574  //GetRawSignalbySimAvalanche(1.);
575  //convolution with readout circuit
576  if(useConvolution){
578  //for_each(fSignalDataAnode.begin(), fSignalDataAnode.end(), print());
579  //cout<<endl;
580 
581  std::map<Int_t, std::vector<Double_t> >::iterator it = fSignalDataStripM.begin();
582  std::map<Int_t, std::vector<Double_t> >::iterator end = fSignalDataStripM.end();
583  while( it != end){
584  std::vector<Double_t>& fSignalDataStrip = it->second;
585  ApplyTransferFunction(&fSignalDataStrip[0]);
586  ++ it;
587  }
588  }
589 }
590 void PndMdtParamDigi::ApplyTransferFunction(Double_t* fSignalData, Int_t )// nSize //[R.K.03/2017] unused variable(s)
591 {
592  Double_t dt=0.01;//microsecond
593  Double_t t(0.);
594  Double_t fIntegral(0.);
595  Double_t dtau(0.);
596  Double_t fF(0.);
597  Double_t fG(0.);
598  Double_t tprime(0.);
599  Int_t iBin(1);
600  dtau = (fTrF->GetXmax() - fTrF->GetXmin())/1.e3;
601  Double_t fSigCopy[fSamplingSize];
602  if(fTrF){
603  memcpy(fSigCopy, fSignalData, fSamplingSize*sizeof(Double_t));
604  //std::vector<Double_t> fSigCopy(fSignalData.begin(),fSignalData.end());
605  for(Int_t i=0; i< fSamplingSize; ++i){
606  t = i*dt;//microsecond
607  fIntegral = 0.;
608  tprime = fTrF->GetXmin();
609  while( tprime < fTrF->GetXmax()){
610  iBin = (Int_t)(tprime/dt);
611  fF = (iBin <0 || iBin > fSamplingSize) ? 0 : fSigCopy[iBin];
612  fG = (t-tprime < fTrF->GetXmin()) || (t-tprime > fTrF->GetXmax()) ? 0 :fTrF->Eval((t-tprime));//convent to microsecond
613  fIntegral += fF*fG*dtau;
614  tprime += dtau;
615  }
616  fSignalData[i] = fIntegral;
617  }
618  }
619 }
620 // suppose noise level is 1 micro ampere;
621 void PndMdtParamDigi::AddNoise(Double_t fNoiseLevel, Int_t ) // isAnode //[R.K.03/2017] unused variable(s)
622 {
623  Double_t fSigmaAnode = fNoiseLevel*fNoiseSigmaAnode;//micro ampere
624  Double_t fSigmaStrip = fNoiseLevel*fNoiseSigmaStrip;//micro ampere
625 
626  std::map<Int_t, std::vector<Double_t> >::iterator it = fSignalDataStripM.begin();
627  std::map<Int_t, std::vector<Double_t> >::iterator end = fSignalDataStripM.end();
628  while( it != end){
629  std::vector<Double_t>& fSignalDataStrip = it->second;
630  for(Int_t i=0; i< fSamplingSize; ++i){
631  fSignalDataStrip[i] += gRandom->Gaus(0, fSigmaStrip);
632  }
633  ++ it;
634  }
635  for(Int_t i=0; i< fSamplingSize; ++i){
636  fSignalDataAnode[i] += gRandom->Gaus(0, fSigmaAnode);
637  }
638 }
639 
641 {
642  time = -1;
643  amp = -9999;
644  Double_t fPeak = 0.;
645  Bool_t NotFound = kTRUE;
646  for(size_t is=0; is < fSamplingSize; ++ is){
648  if(TMath::Abs(fSignalDataAnode[is]) > 5*fNoiseSigmaAnode && NotFound) {
649  time = is*fSamplingInterval;//nano seconds
650  NotFound = kFALSE;
651  }
652  }
653  amp = fPeak;
654  return time > 0;
655 }
657 {
658  time = -1;
659  amp = -9999;
660  Double_t fPeak = 0.;
661  Bool_t NotFound = kTRUE;
662  std::vector<Double_t>& fSignalDataStrip = fSignalDataStripM[id];
663  for(size_t is=0; is < fSamplingSize; ++ is){
664  if(TMath::Abs(fSignalDataStrip[is]) > TMath::Abs(fPeak)) fPeak = fSignalDataStrip[is];
665  if(TMath::Abs(fSignalDataStrip[is]) > 5*fNoiseSigmaStrip && NotFound) {
666  time = is*fSamplingInterval;//nano seconds
667  NotFound = kFALSE;
668  }
669  }
670  amp = fPeak;
671  return time > 0;
672 }
673 
674 //index, momentum
675 //0 - 50MeV
676 //1 - 100MeV
677 //2 - 200MeV
678 //3 - 300MeV
679 //4 - 500MeV
680 //5 - 1GeV
681 //6 - 2GeV
682 //7 - 5GeV
683 //8 - 10GeV
684 Int_t PndMdtParamDigi::GetAmplicationFactor(Int_t , Double_t momentum) const // particleType //[R.K.03/2017] unused variable(s)
685 {
686  TGraphErrors* gAmp(0);
687  if(!gAmp){
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);
707  }
708  const Double_t fScaleFactor = 1.0;//simulation calibration to experiments
709  Double_t fMeanAmp = gAmp->Eval(momentum);
710  Double_t fAmpErr = gAmp->GetErrorY(momentum);
711  return (Int_t) fScaleFactor*gRandom->Gaus(fMeanAmp, fAmpErr);
712 }
713 
714 //
715 //ValueErrorType PndMdtParamDigi::NumofPrimaryIonizaion[9] = {
716 // ValueErrorType(81.77, 39.38), ValueErrorType(49.40, 11.24), ValueErrorType(44.61, 10.45)
717 // , ValueErrorType(42.95, 10.32), ValueErrorType(50.11, 36.60), ValueErrorType(48.45, 11.50)
718 // , ValueErrorType(48.77, 10.94), ValueErrorType(56.05, 12.13), ValueErrorType(58.12, 12.93)
719 //};
720 void PndMdtParamDigi::GetMPVofPrimaryIonization(Int_t particleType, const TVector3& fMomentum, ValueErrorType& val) const
721 {
722  Double_t p0 = 9.83401e-01;
723  Double_t p1 = 7.42822e-02;
724  Double_t p2 = 5.62250e-01;
725  Double_t p3 = 2.22743e-01;
726  //index: electron 0, muon 1, pion 2, kaon, 3, proton 4;
727  Double_t fMass = fRestMass[particleType];
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;
731 }
732 void PndMdtParamDigi::SamplingPosition(TVector2 fDirection, TVector2& fIonProductionPos)
733 {
734  const Double_t cThetaSigma = 2.67859e-01;
735  //sampling theta
736  Double_t mTheta = gRandom->Gaus(0., cThetaSigma);
737  //sampling radial
738  const Double_t mTauR1 = 1.51900e-3;
739  const Double_t mTauR2 = 5.53950e-4;
740  const Double_t mTauR3 = 2.94876e-4;
741  Double_t mRadius(0);
742  Double_t prob = gRandom->Rndm();
743  if(prob < 2.38210768816632112e-02){
744  mRadius = gRandom->Exp(mTauR1);
745  }else if(prob < 4.34694439053706305e-01){
746  mRadius = gRandom->Exp(mTauR2);
747  } else{
748  mRadius = gRandom->Exp(mTauR3);
749  }
750  mRadius += cWIRERADIUS;
751  Double_t mX = mRadius*cos(mTheta);
752  Double_t mY = mRadius*sin(mTheta);
753  //unitV.Print();
754  TVector2 unitV = fDirection.Unit();
755 
756  fIonProductionPos.Set( unitV.X()*mX - unitV.Y()*mY, unitV.Y()*mX + unitV.X()*mY);
757  //fIonProductionPos.Print();
758 }
759 
761 
std::pair< Double_t, Double_t > ValueErrorType
static const Int_t NRAD
Double_t fRestMass[5]
int fVerbose
Definition: poormantracks.C:24
friend F32vec4 cos(const F32vec4 &a)
Definition: P4_F32vec4.h:112
void operator()(Double_t v) const
Double_t fNoiseSigmaStrip
friend F32vec4 exp(const F32vec4 &a)
Definition: P4_F32vec4.h:109
Int_t i
Definition: run_full.C:25
TFile * file
Int_t GetAmplicationFactor(Int_t particleType, Double_t momentum) const
std::vector< std::pair< Int_t, Double_t > > GetFiredInfo()
Double_t val[nBoxes][nFEBox]
Definition: createCalib.C:11
friend F32vec4 sin(const F32vec4 &a)
Definition: P4_F32vec4.h:111
static T Sin(const T &x)
Definition: PndCAMath.h:42
Bool_t Digitize(Double_t &time, Double_t &amp)
friend F32vec4 log(const F32vec4 &a)
Definition: P4_F32vec4.h:110
c2
Definition: plot_dirc.C:39
static T Cos(const T &x)
Definition: PndCAMath.h:43
__m128 v
Definition: P4_F32vec4.h:4
TH1F * hAnodeI1d[NRAD]
void AddNoise(Double_t fNoiseLevel=1., Int_t isAnode=1)
static const Int_t fSamplingSize
void GetSignal(Bool_t useConvolution=kTRUE)
static T Abs(const T &x)
Definition: PndCAMath.h:39
Double_t fNoiseSigmaAnode
void ApplyTransferFunction(Double_t *fSignalData, Int_t nSize=fSamplingSize)
Double_t
static const Int_t NPHI
void GetMPVofPrimaryIonization(Int_t particleType, const TVector3 &momentum, ValueErrorType &val) const
static int is
Definition: ranlxd.cxx:374
c1
Definition: plot_dirc.C:35
TVector3 fParticleMomentum
TString name
TPad * p2
Definition: hist-t7.C:117
PndMdtParamDigi & SetParams(Int_t ptlType, TVector3 iniP, TVector3 iniPos, TVector3 finalPos, Double_t stripLen=100.)
Double_t x
static T Log(const T &x)
Definition: PndCAMath.h:40
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
ClassImp(PndAnaContFact)
void SamplingPosition(TVector2 fDirection, TVector2 &fIonProductionPos)
TPad * p1
Definition: hist-t7.C:116
TTree * t
Definition: bump_analys.C:13
Double_t y
std::vector< Double_t > fSignalDataAnode
Double_t Pi
TGraphErrors * gFreePath[5]
TVector3 fExitPosition
TH1F * hCathodeI2d[NRAD][NPHI]
std::vector< AvaBinType > fProbFunc1D
void GetRawSignalbySimAvalanche(Double_t fNoiseLevel=1.)
static int ir
Definition: ranlxd.cxx:374