FairRoot/PandaRoot
PndSdsNoiseProducer.cxx
Go to the documentation of this file.
1 // -------------------------------------------------------------------------
2 // ----- PndSdsNoiseProducer source file -----
3 // ----- Created 01.07.08 by R.Kliemt -----
4 // -------------------------------------------------------------------------
5 
6 
7 #include "TClonesArray.h"
8 #include "TGeoNode.h"
9 
10 #include "FairRootManager.h"
11 #include "FairGeoVolume.h"
12 #include "FairRun.h"
13 #include "FairRuntimeDb.h"
14 #include "FairGeoNode.h"
15 #include "FairMCEventHeader.h"
16 
17 #include "PndSdsNoiseProducer.h"
18 #include "PndSdsMCPoint.h"
19 #include "PndSdsDigiStrip.h"
20 #include "PndSdsDigiPixel.h"
21 
22 #include "PndDetectorList.h"
23 
24 // ----- Default constructor -------------------------------------------
26 PndSdsTask("Charge Noise Producer"),
27 fBranchNameStrip(""),
28 fBranchNamePixel(""),
29 fDigiStripArray(NULL),
30 fDigiPixelArray(NULL),
31 fDigiParRect(NULL),
32 fDigiParTrap(NULL),
33 fDigiParPix(NULL),
34 fMCPointType(), // Not used???
35 fGeoH(NULL),
36 fPixelIds4(),
37 fPixelIds6(),
38 fPixelIds8(),
39 fPixelIds12(),
40 fStripRectIds(),
41 fStripTrapIds(),
42 fNoiseSpread(0),
43 fThreshold(0),
44 fIonizationEnergy(1.)
45 {
46  SetPersistency(kTRUE);
47 }
48 // -------------------------------------------------------------------------
49 
50 
51 // ----- Destructor ----------------------------------------------------
53 {
54 }
55 
56 // ----- Public method Init --------------------------------------------
58 {
60 
61  // Get RootManager
62  FairRootManager* ioman = FairRootManager::Instance();
63 
64  if ( ! ioman )
65  {
66  std::cout << "-E- PndSdsNoiseProducer::Init: RootManager not instantiated!" << std::endl;
67  return kFATAL;
68  }
69 
70  // Get input array
71  fDigiStripArray = FairRootManager::Instance()->GetTClonesArray(fBranchNameStrip);
72  if ( ! fDigiStripArray ) {
73  std::cout << "-W- PndSdsNoiseProducer::Init: No "<<fBranchNameStrip<<" array!" << std::endl;
74  std::cout << " Create a new one." << std::endl;
75  ioman->Register(fBranchNameStrip, "PndSdsDigiStrip", fFolderName, GetPersistency());
76  }
77 
78  fDigiPixelArray = FairRootManager::Instance()->GetTClonesArray(fBranchNamePixel);
79  if ( ! fDigiPixelArray ) {
80  std::cout << "-W- PndSdsNoiseProducer::Init: No "<<fBranchNamePixel<<" array!" << std::endl;
81  std::cout << " Create a new one." << std::endl;
82  ioman->Register(fBranchNamePixel, "PndSdsDigiPixel", fFolderName, GetPersistency());
83  }
84 
85 
86  // Retrieve a map between the active geometry nodes and their interpretation
87  // TGeoNode* topnode = gGeoManager->GetTopNode();
88  // for (Int_t n=0; n<topnode->GetNdaughters();n++)
89  // {
90  // gGeoManager->CdDown(n);
91  // TGeoNode* node = gGeoManager->GetCurrentNode();
92  // TString nodeName = node->GetName();
93  // if(nodeName.BeginsWith(fFolderName))
94  // {
95  // DiveDownNode(node);
96  // break;
97  // }
98  // gGeoManager->CdUp();
99  // }
100 
101  FillSensorLists();
102  if(fVerbose>1)
103  {
104  std::cout <<"-I- PndSdsNoiseProducer: Registered Sensors: "
105  <<fStripRectIds.size()<<"xStripRect "
106  <<fStripTrapIds.size()<<"xStripTrap "
107  <<fPixelIds4.size()<<"xPixel"
108  <<std::endl;
109  }
110  std::cout << "-I- PndSdsNoiseProducer: Intialisation successfull" << std::endl;
111 
112 
113  return kSUCCESS;
114 
115 }
116 
118 {
119  TObjArray* sensorNames = fGeoH->GetSensorNames();
120  for (int i = 0; i < sensorNames->GetEntries(); i++){
121  TString volname = ((TObjString*)(sensorNames->At(i)))->GetString();
122  if(volname.Contains("Active"))
123  {
124  if(volname.Contains("Rect")) fStripRectIds.push_back(i);
125  if(volname.Contains("Trap")) fStripTrapIds.push_back(i);
126  if(volname.Contains("Pixel"))
127  {
128  if(volname.Contains("4x1")) fPixelIds4.push_back(i);
129  if(volname.Contains("6x1")) fPixelIds6.push_back(i);
130  if(volname.Contains("4x2")) fPixelIds8.push_back(i);
131  if(volname.Contains("6x2")) fPixelIds12.push_back(i);
132  }
133  }
134  }
135 }
136 
137 void PndSdsNoiseProducer::DiveDownNode(TGeoNode *){ //nodeMother //[R.K.03/2017] unused variable(s)
138  // for (Int_t Nod=0; Nod<nodeMother->GetNdaughters();Nod++)
139  // {
140  // gGeoManager->CdDown(Nod);
141  // TGeoNode *aNode = gGeoManager->GetCurrentNode();
142  // if(aNode->GetNdaughters()>0) DiveDownNode(aNode);
143  // TString volname = gGeoManager->GetPath();
144  // if(volname.Contains("Active"))
145  // {
146  // if(volname.Contains("Rect")) fStripRectIds.push_back(fGeoH->GetID(volname));
147  // if(volname.Contains("Trap")) fStripTrapIds.push_back(fGeoH->GetID(volname));
148  // if(volname.Contains("Pixel"))
149  // {
150  // if(volname.Contains("4x1")) fPixelIds4.push_back(fGeoH->GetID(volname));
151  // if(volname.Contains("6x1")) fPixelIds6.push_back(fGeoH->GetID(volname));
152  // if(volname.Contains("4x2")) fPixelIds8.push_back(fGeoH->GetID(volname));
153  // if(volname.Contains("6x2")) fPixelIds12.push_back(fGeoH->GetID(volname));
154  // }
155  // }
156  // gGeoManager->CdUp();
157  // }
158 }
159 
160 // -------------------------------------------------------------------------
162 {
163  if ( fGeoH == NULL )
165 
167 
168  // Get Base Container
169  FairRun* ana = FairRun::Instance();
170  FairRuntimeDb* rtdb=ana->GetRuntimeDb();
171  // fGeoPar = (PndSdsGeoPar*)(rtdb->getContainer("PndSdsGeoPar"));
172  fDigiParRect = (PndSdsStripDigiPar*)(rtdb->getContainer("MVDStripDigiParRect"));
173  fDigiParTrap = (PndSdsStripDigiPar*)(rtdb->getContainer("MVDStripDigiParTrap"));
174  fDigiParPix = (PndSdsPixelDigiPar*)(rtdb->getContainer("MVDPixelDigiPar"));
175  Info("SetParContainers","done.");
176 }
177 
178 
179 // ----- Public method Exec --------------------------------------------
181 {
183  // TObjArray* activeSensors = fGeoPar->GetGeoSensitiveNodes();
184  Int_t nrCh=0,rnd=0,
185  nrFE=0,sens=0,
186  nrSensors=0,fe=0,
187  chanmax=0,chan=0,
188  col=0,row=0,
189  // iStrip=0,
190  chanwhite=0,
191  //iPix=0,
192  charge=0,
193  nNoisyStripRects=0,
194  nNoisyStripTraps=0,
195  nNoisyPixels=0;
196  Double_t xfrac=0.;
197  Int_t did;
198 
199  // *** Strip Rect ***
200  // how many channels left?
201  nrCh = fDigiParRect->GetNrFECh();
203  nrSensors = fStripRectIds.size();
204  chanmax = nrCh * nrFE * nrSensors;
205  // Get Number of Channels fired from noise
207  chanwhite = gRandom->Poisson(xfrac*chanmax);
208  if(fVerbose>1) std::cout << "-I- PndSdsNoiseProducer: RECT xfrac = " << xfrac
209  << " leading to " << chanwhite << " noisy digis of " << chanmax
210  << " total channels" << std::endl;
211  for(Int_t i = 0;i < chanwhite;i++)
212  {
213  // randomize the channel numbers & sensors
214  rnd = gRandom->Integer(chanmax);
215  sens = rnd/(nrFE*nrCh);
216  rnd = rnd % (nrFE*nrCh);
217  fe = rnd/nrCh; //will populate
218  chan = rnd % nrCh;
219  // calculate a charge deposit above threshold
221  did = fStripRectIds[sens];
222  AddDigiStrip(nNoisyStripRects,-1,did,fe,chan,charge);
223  }
224 
225  // *** Strip Trapezoids ***
226  nrCh = fDigiParTrap->GetNrFECh();
228  nrSensors = fStripTrapIds.size();
229  chanmax = nrCh * nrFE * nrSensors;
231  chanwhite = gRandom->Poisson(xfrac*chanmax);
232  if(fVerbose>1) std::cout << "-I- PndSdsNoiseProducer: TRAP xfrac = " << xfrac
233  << " leading to " << chanwhite << " noisy digis of " << chanmax
234  << " total channels" << std::endl;
235  for(Int_t i = 0;i < chanwhite;i++)
236  {
237  rnd = gRandom->Integer(chanmax);
238  sens = rnd/(nrFE*nrCh);
239  rnd = rnd % (nrFE*nrCh);
240  fe = rnd/nrCh;
241  chan = rnd % nrCh;
243  did = fStripTrapIds[sens];
244  AddDigiStrip(nNoisyStripTraps,-1,did,fe,chan,charge);
245  }
246 
247  // *** Pixel Sensors ***
249  nrFE = 4*fPixelIds4.size() + 6*fPixelIds6.size() + 8*fPixelIds8.size() + 12*fPixelIds12.size();
250  chanmax = nrCh * nrFE;
252  chanwhite = gRandom->Poisson(xfrac*chanmax);
253  if(fVerbose>1) std::cout << "-I- PndSdsNoiseProducer: PIXEL xfrac = " << xfrac
254  << " leading to " << chanwhite << " noisy digis of " << chanmax
255  << " total channels" << std::endl;
256  for(Int_t i = 0;i < chanwhite;i++)
257  {
259  rnd = gRandom->Integer(chanmax);
260  chan = rnd%nrCh;
261  col = chan%fDigiParPix->GetFECols();
262  row = chan/fDigiParPix->GetFECols();
263  fe = rnd/nrCh;
264  if(fe >= (Int_t)(4*fPixelIds4.size() + 6*fPixelIds6.size() + 8*fPixelIds8.size()) )
265  {
266  fe = fe - 4*fPixelIds4.size() - 6*fPixelIds6.size() - 8*fPixelIds8.size();
267  sens = fe/12;
268  did = fPixelIds12[sens];
269  fe = fe%12;
270  if(fe>6) fe=fe-6+10; //0-9 one row of FE, 10-19 2nd row of FE
271  } else if(fe >= (Int_t)(4*fPixelIds4.size() + 6*fPixelIds6.size()) )
272  {
273  fe = fe - 4*fPixelIds4.size() - 6*fPixelIds6.size();
274  sens = fe/8;
275  did = fPixelIds8[sens];
276  fe = fe%8;
277  if(fe>4) fe=fe-4+10; //0-9 one row of FE, 10-19 2nd row of FE
278  } else if( fe >= (Int_t)(4*fPixelIds4.size()) )
279  {
280  fe = fe -4*fPixelIds4.size();
281  sens = fe/6;
282  did = fPixelIds6[sens];
283  fe = fe%6;
284  } else
285  {
286  sens = fe/4;
287  did = fPixelIds4[sens];
288  fe = fe%4;
289  }
290 
291  AddDigiPixel(nNoisyPixels,-1,did,fe,col,row,charge);
292  }
293 
294  // *** The End ***
295  if(fVerbose>0)
296  {
297  std::cout <<"-I- PndSdsNoiseProducer: Noise produced\t"
298  <<nNoisyStripRects <<"xStripRect\t"
299  <<nNoisyStripTraps <<"xStripTrap\t"
300  <<nNoisyPixels <<"xPixels"<<std::endl;
301  }
302 }
303 // -------------------------------------------------------------------------
304 
305 // -------------------------------------------------------------------------
307 {
308  // mean fraction of fireing digis
309  return 0.5*TMath::Erfc( threshold / (TMath::Sqrt2()*spread) );
310 }
311 
312 // Int_t PndSdsNoiseProducer::CalcChanWhite(Int_t chanleft, Double_t frac)
313 // {
314 // Int_t temp=0;
315 // // random number of firing digis around the mean fraction
316 // temp = gRandom->Poisson(frac*chanleft);
317 // return (Int_t)temp;
318 // }
319 
321 {
322  // only the charge ABOVE the threshold counts
323  // get maximum y value of gauss tail
324  // calculate a random charge according to that tails distribution
325  Double_t temp=0.;
326  temp = TMath::Gaus(threshold,0,spread);
327  temp = gRandom->Uniform(0.,temp);
328  temp = -2.*spread*spread*log(temp);
329  temp = sqrt(temp);
330  return (Int_t)temp;
331 }
332 // -------------------------------------------------------------------------
333 void PndSdsNoiseProducer::AddDigiStrip(Int_t &noisies, Int_t iPoint, Int_t sensorID, Int_t fe, Int_t chan, Double_t charge)
334 {
335  Bool_t found = kFALSE;
336  Int_t detID = -1; // we have no input array with MC Points
337  fDigiStripArray = FairRootManager::Instance()->GetTClonesArray(fBranchNameStrip);
338  Int_t iStrip = fDigiStripArray->GetEntriesFast();
339  PndSdsDigiStrip* aDigi = 0;
340  for(Int_t kstr = 0; kstr < iStrip && found == kFALSE; kstr++)
341  {
342  aDigi = (PndSdsDigiStrip*)fDigiStripArray->At(kstr);
343  if ( aDigi->GetDetID() == detID &&
344  aDigi->GetSensorID() == sensorID &&
345  aDigi->GetFE() == fe &&
346  aDigi->GetChannel() == chan )
347  {
348  aDigi->AddCharge(charge);
349  aDigi->AddIndex(iPoint);
350  found = kTRUE;
351  }
352  }
353  if(found == kFALSE){
354  //TODO: get a reasonable timestamp fake for the noise
355  std::vector<Int_t> indices;
356  indices.push_back(iPoint);
357  FairMCEventHeader* MCevtHeader = (FairMCEventHeader*)FairRootManager::Instance()->GetObject("MCEventHeader.");
358  new ((*fDigiStripArray)[iStrip]) PndSdsDigiStrip(indices,detID,sensorID,fe,chan,charge, MCevtHeader->GetT()) ;
359  noisies++;
360  if(fVerbose>2) std::cout
361  << " -I- PndSdsNoiseProducer: Added StripTrap Digi at: FE=" << fe
362  << ", channel=" << chan << ", charge=" << charge<< " e"
363  << ", in sensor \n" << sensorID <<std::endl;
364  }
365 }
366 // -------------------------------------------------------------------------
367 void PndSdsNoiseProducer::AddDigiPixel(Int_t &noisies, Int_t iPoint, Int_t sensorID, Int_t fe, Int_t col, Int_t row, Double_t charge)
368 {
369  Bool_t found = kFALSE;
370  Int_t detID = -1;
371  fDigiPixelArray = FairRootManager::Instance()->GetTClonesArray(fBranchNamePixel);
372  Int_t iPix = fDigiPixelArray->GetEntriesFast();
373  PndSdsDigiPixel* aDigi = 0;
374  for(Int_t kstr = 0; kstr < iPix && found == kFALSE; kstr++)
375  {
376  aDigi = (PndSdsDigiPixel*)fDigiPixelArray->At(kstr);
377  if ( aDigi->GetDetID() == detID &&
378  aDigi->GetSensorID() == sensorID &&
379  aDigi->GetFE() == fe &&
380  aDigi->GetPixelColumn() == col &&
381  aDigi->GetPixelRow() == row )
382  {
383  aDigi->AddCharge(charge);
384  aDigi->AddIndex(iPoint);
385  found = kTRUE;
386  }
387  }
388  if(found == kFALSE){
389  std::vector<Int_t> indices;
390  indices.push_back(iPoint);
391  FairMCEventHeader* MCevtHeader = (FairMCEventHeader*)FairRootManager::Instance()->GetObject("MCEventHeader.");
392 
393  new ((*fDigiPixelArray)[iPix]) PndSdsDigiPixel(indices,detID,sensorID,fe,col,row,charge, MCevtHeader->GetT()) ;
394  noisies++;
395  if(fVerbose>2) std::cout
396  << " -I- PndSdsNoiseProducer: Added Pixel Digi at: FE=" << fe
397  << ", col|row = ("<<col<<"|"<<row<< "), charge=" << charge<< " e"
398  << ", in sensor \n" << sensorID <<std::endl;
399 
400  }
401 }
402 // -------------------------------------------------------------------------
403 
404 
int row
Definition: anaLmdDigi.C:67
Int_t GetPixelRow() const
int fVerbose
Definition: poormantracks.C:24
Int_t GetSensorID() const
Definition: PndSdsDigi.h:59
virtual void AddIndex(int index)
Definition: PndSdsDigi.h:66
void DiveDownNode(TGeoNode *fN)
Int_t i
Definition: run_full.C:25
PndSdsPixelDigiPar * fDigiParPix
PndGeoHandling * fGeoH
Definition: anasim.C:34
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:29
void AddCharge(double charge)
Definition: PndSdsDigi.h:78
Int_t GetPixelColumn() const
virtual void SetParContainers()
int col
Definition: anaLmdDigi.C:67
Class for digitised strip hits.
void AddDigiPixel(Int_t &noisies, Int_t iPoint, Int_t sensorID, Int_t fe, Int_t col, Int_t row, Double_t charge)
friend F32vec4 log(const F32vec4 &a)
Definition: P4_F32vec4.h:110
void SetPersistency(Bool_t val=kTRUE)
Double_t GetNoise() const
virtual InitStatus Init()
Int_t GetFE() const
Definition: PndSdsDigi.h:57
Double_t GetThreshold() const
PndSdsStripDigiPar * fDigiParTrap
TClonesArray * fDigiPixelArray
std::vector< Int_t > fPixelIds8
void AddDigiStrip(Int_t &iStrip, Int_t iPoint, Int_t sensorID, Int_t fe, Int_t chan, Double_t charge)
Double_t GetNoise() const
Int_t GetFERows() const
Int_t GetFECols() const
Double_t
std::vector< Int_t > fStripRectIds
Digitization Parameter Class for MVD-Strip part.
TClonesArray * fDigiStripArray
FairRuntimeDb * rtdb
Definition: hit_dirc.C:66
virtual void Exec(Option_t *opt)
TObjArray * GetSensorNames()
Double_t CalcDistFraction(Double_t spread, Double_t threshold)
TString fFolderName
Definition: PndSdsTask.h:41
std::vector< Int_t > fStripTrapIds
static PndGeoHandling * Instance()
double threshold
virtual void SetBranchNames()=0
void SetVerbose(Int_t v)
PndGeoHandling * fGeoH
Int_t GetNrFECh() const
Int_t GetDetID() const
Definition: PndSdsDigi.h:61
PndSdsStripDigiPar * fDigiParRect
int fe
Definition: anaLmdDigi.C:67
ClassImp(PndAnaContFact)
virtual void SetParContainers()
std::vector< Int_t > fPixelIds6
Data class to store the digi output of a pixel module.
Int_t GetNrTopFE() const
Int_t GetNrBotFE() const
std::vector< Int_t > fPixelIds12
Int_t GetChannel() const
std::vector< Int_t > fPixelIds4
Geometry name handling.
Int_t CalcChargeAboveThreshold(Double_t spread, Double_t threshold)
Double_t GetThreshold() const
Digitization Parameter Class for SDS-Pixel part.