er  dev
ERNDDigitizer.cxx
1 #include "ERNDDigitizer.h"
2 
3 #include "TVector3.h"
4 #include "TGeoMatrix.h"
5 #include "TMath.h"
6 #include "TRandom3.h"
7 
8 #include "FairRootManager.h"
9 #include "FairRun.h"
10 #include "FairRuntimeDb.h"
11 #include "FairLogger.h"
12 
13 #include <limits>
14 #include <vector>
15 #include <map>
16 
17 #include "ERDetectorList.h"
18 #include "ERNDPoint.h"
19 
20 Int_t ERNDDigitizer::fEvent = 0;
21 // ----------------------------------------------------------------------------
23  : FairTask("ER ND Digi producing scheme")
24 ,fNDPoints(NULL)
25 ,fNDDigis(NULL)
26 ,fEdepErrorA(0)
27 ,fEdepErrorB(0)
28 ,fEdepErrorC(0)
29 ,fLYErrorA(0)
30 ,fLYErrorB(0)
31 ,fLYErrorC(0)
32 ,fQuenchThreshold(0)
33 ,fLYThreshold(0)
34 ,fProbabilityB(0)
35 ,fProbabilityC(0)
36 {
37 }
38 // ----------------------------------------------------------------------------
39 
40 // ----------------------------------------------------------------------------
42  : FairTask("ER ND Digi producing scheme ", verbose)
43 ,fNDPoints(NULL)
44 ,fNDDigis(NULL)
45 ,fEdepErrorA(0)
46 ,fEdepErrorB(0)
47 ,fEdepErrorC(0)
48 ,fLYErrorA(0)
49 ,fLYErrorB(0)
50 ,fLYErrorC(0)
51 ,fQuenchThreshold(0)
52 ,fLYThreshold(0)
53 ,fProbabilityB(0)
54 ,fProbabilityC(0)
55 {
56 }
57 // ----------------------------------------------------------------------------
58 
59 // ----------------------------------------------------------------------------
61 {
62 }
63 // ----------------------------------------------------------------------------
64 
65 // ----------------------------------------------------------------------------
66 void ERNDDigitizer::SetParContainers()
67 {
68  // Get run and runtime database
69  FairRun* run = FairRun::Instance();
70  if ( ! run ) Fatal("SetParContainers", "No analysis run");
71 
72  FairRuntimeDb* rtdb = run->GetRuntimeDb();
73  if ( ! rtdb ) Fatal("SetParContainers", "No runtime database");
74 }
75 // ----------------------------------------------------------------------------
76 
77 // ----------------------------------------------------------------------------
78 InitStatus ERNDDigitizer::Init()
79 {
80  // Get input array
81  FairRootManager* ioman = FairRootManager::Instance();
82  if ( ! ioman ) Fatal("Init", "No FairRootManager");
83 
84  fNDPoints = (TClonesArray*) ioman->GetObject("NDPoint");
85  if (!fNDPoints)
86  Fatal("Init", "Can`t find collection NDPoint!");
87 
88  // Register output array fNDDigis
89  fNDDigis = new TClonesArray("ERNDDigi",10);
90 
91  ioman->Register("NDDigi", "ND digi", fNDDigis, kTRUE);
92 
93  fSetup = ERNDSetup::Instance();
94 
95  return kSUCCESS;
96 }
97 // -------------------------------------------------------------------------
98 
99 // ----- Public method Exec --------------------------------------------
100 void ERNDDigitizer::Exec(Option_t* opt)
101 {
102 
103  LOG(DEBUG2) << "ERNDDigitizer event: " << fEvent++ << FairLogger::endl;
104  Reset();
105 
106  //Sort points by crystalls
107  std::map<Int_t, std::vector<Int_t>> pointsByCrystall;
108  for (Int_t iPoint = 0; iPoint < fNDPoints->GetEntriesFast(); iPoint++){
109  ERNDPoint* point = (ERNDPoint*)fNDPoints->At(iPoint);
110  pointsByCrystall[point->StilbenNr()].push_back(iPoint);
111  }
112 
113  //loop over crystall with points
114  for (const auto &itCrystall : pointsByCrystall){
115  Float_t edep = 0; // sum edep in crystall
116  Float_t time = std::numeric_limits<float>::max(); // first time in crystall
117  Float_t ly = 0.; // sum ligth yield in crystall
118 
119  //loop over points in crysrall itCrystall.first()
120  for (const auto iPoint : itCrystall.second){
121  ERNDPoint* point = (ERNDPoint*)fNDPoints->At(iPoint);
122  edep += point->GetEnergyLoss();
123  ly += point->LightYield();
124  if (point->GetTime() < time){
125  time = point->GetTime();
126  }
127  }
128 
129  Float_t edepSigma = sqrt(pow(fEdepErrorA,2) + pow(fEdepErrorB*TMath::Sqrt(edep/1000.),2) + pow(fEdepErrorC*edep,2));
130  edep = gRandom->Gaus(edep, edepSigma);
131 
132  /*
133  fEdepErrorB and fLYErrorB are expressed in per cent divided by square root of edep or LY,
134  expressed in MeVlike it is usually done in detector description. e.g. for Edep=0.001 (i.e. 1 Mev)
135  sigma is equal0.04*0.001Gev = 0.04 MeV
136  */
137 
138  Float_t lySigma = sqrt(pow(fLYErrorA,2) + pow(fLYErrorB*TMath::Sqrt(ly/1000.),2) + pow(fLYErrorC*ly,2));
139  ly = gRandom->Gaus(ly, lySigma);
140 
141  Float_t timeSigma = TMath::Sqrt(fTimeErrorA/ly);
142  time = gRandom->Gaus(time, timeSigma);
143 
144  Float_t neutronProb = NeutronProbability(edep,ly);
145 
146  AddDigi(itCrystall.first,edep, ly, time, neutronProb);
147  }
148  LOG(DEBUG) << "Digis count: " << fNDDigis->GetEntriesFast() << FairLogger::endl;
149 }
150 //----------------------------------------------------------------------------
151 
152 //----------------------------------------------------------------------------
154 {
155  if (fNDDigis) {
156  fNDDigis->Delete();
157  }
158 }
159 // ----------------------------------------------------------------------------
160 
161 // ----------------------------------------------------------------------------
163 {
164 }
165 // ----------------------------------------------------------------------------
166 
167 // ----------------------------------------------------------------------------
168 ERNDDigi* ERNDDigitizer::AddDigi(Int_t stilbenNb, Float_t edep, Float_t ly,
169  Float_t time,Float_t neutronProb)
170 {
171  ERNDDigi *Digi = new((*fNDDigis)[fNDDigis->GetEntriesFast()])
172  ERNDDigi(stilbenNb, edep, ly, time, neutronProb);
173  return Digi;
174 }
175 // ----------------------------------------------------------------------------
176 Float_t ERNDDigitizer::NeutronProbability(Float_t edep, Float_t ly){
177  Float_t neutronProb;
178  Float_t quench = ly/edep;
179  if ((ly > fLYThreshold) && (quench < fQuenchThreshold)){
180  neutronProb = 1.;
181  }
182  if ((ly < fLYThreshold) && (quench < fQuenchThreshold)){
183  neutronProb = fProbabilityB+(1-fProbabilityB)*(ly/fLYThreshold);
184  }
185  if ((ly > fLYThreshold) && (quench > fQuenchThreshold)){
186  neutronProb = 0.;
187  }
188  if ((ly < fLYThreshold) && (quench > fQuenchThreshold)){
189  neutronProb = fProbabilityC*(1-ly/fLYThreshold);
190  }
191  return neutronProb;
192 }
193 //-----------------------------------------------------------------------------
194 ClassImp(ERNDDigitizer)
virtual void Reset()
virtual void Finish()
virtual void Exec(Option_t *opt)
virtual InitStatus Init()