FairRoot/PandaRoot
PndMvdNoiseProducer.cxx
Go to the documentation of this file.
1 // -------------------------------------------------------------------------
2 // ----- PndMvdNoiseProducer source file -----
3 // ----- Created 01.07.08 by R.Kliemt -----
4 // -------------------------------------------------------------------------
5 
6 //#include <cmath>
7 
8 #include "TClonesArray.h"
9 #include "TGeoNode.h"
10 
11 #include "FairRootManager.h"
12 #include "FairGeoVolume.h"
13 #include "FairRun.h"
14 #include "FairRuntimeDb.h"
15 #include "FairGeoNode.h"
16 
17 #include "PndMvdNoiseProducer.h"
18 #include "PndSdsMCPoint.h"
19 #include "PndSdsDigiStrip.h"
20 #include "PndSdsDigiPixel.h"
21 #include "PndStringSeparator.h"
22 
25 
26 #include "PndDetectorList.h"
27 
28 // ----- Default constructor -------------------------------------------
30 PndPersistencyTask("Charge Noise Producer"),
31  fTimeOrderedDigi(kFALSE),
32  fBranchName("MVDStripDigis"),
33  fDigiStripArray(NULL),
34  fDigiPixelArray(NULL),
35  fDigiPixelBuffer(NULL),
36  fDigiStripBuffer(NULL),
37  fDigiParRect(NULL),
38  fDigiParTrap(NULL),
39  fDigiParPix(NULL),
40  fTotDigiParRect(NULL),
41  fTotDigiParTrap(NULL),
42  fTotDigiParPix(NULL),
43  fGeoH(NULL),
44  fMCEventheader(NULL),
45  fPixelIds2(),
46  fPixelIds4(),
47  fPixelIds5(),
48  fPixelIds6(),
49  fStripRectLIds(),
50  fStripRectSIds(),
51  fStripTrapIds(),
52  fStripRectChargeConv(NULL),
53  fStripTrapChargeConv(NULL),
54  fCurrentChargeConv(NULL),
55  fPixChargeConv(NULL),
56  fNoiseSpread(0),
57  fThreshold(0),
58  fPreviousTime(0)
59 {
60 }
61 // -------------------------------------------------------------------------
62 
63 
64 
65 // ----- Destructor ----------------------------------------------------
67 {
70  if (fPixChargeConv) delete fPixChargeConv;
71 }
72 
73 // ----- Public method Init --------------------------------------------
75 {
76  // Get RootManager
77  FairRootManager* ioman = FairRootManager::Instance();
78 
79  if ( ! ioman )
80  {
81  std::cout << " -E- PndMvdNoiseProducer::Init: RootManager not instantiated!" << std::endl;
82  return kFATAL;
83  }
84 
85  // Get input array
86 
87  fDigiStripBuffer = (PndSdsDigiStripWriteoutBuffer*)FairRootManager::Instance()->RegisterWriteoutBuffer("MVDStripDigis", new PndSdsDigiStripWriteoutBuffer("MVDStripDigis", "MVD", kTRUE));
88 
89 // fDigiPixelArray = (TClonesArray*) ioman->GetObject("MVDPixelDigis");
90  fDigiPixelBuffer = new PndSdsDigiPixelWriteoutBuffer("MVDPixelDigis", "MVD", kTRUE);
91  fDigiPixelBuffer = (PndSdsDigiPixelWriteoutBuffer*)FairRootManager::Instance()->RegisterWriteoutBuffer("MVDPixelDigis", fDigiPixelBuffer);
92  fDigiPixelBuffer->ActivateBuffering(fTimeOrderedDigi);
93 
94 
95  fMCEventheader = (FairMCEventHeader*) ioman->GetObject("MCEventHeader.");
96  if ( ! fMCEventheader ){
97  Warning("Init","Did not find the MC event header, assume 50ns of noise clockticks per call of Exec().");
98  }
99  fPreviousTime=0.;
100 
101  FillSensorLists();
102 
103 // fFEModel = new PndSdsFESimple();
104 
105  if(fVerbose>0)
106  {
107  std::cout <<" -I- PndMvdNoiseProducer: Registered Sensors: "
108  <<fStripRectLIds.size()+fStripRectSIds.size()<<"xStripRect "
109  <<fStripTrapIds.size()<<"xStripTrap "
110  <<fPixelIds2.size()<<"xPixel"
111  <<std::endl;
112  }
113  std::cout << " -I- PndMvdNoiseProducer: Intialisation successfull" << std::endl;
114 
115  if (fDigiParRect->GetChargeConvMethod() == 0){
116  if(fVerbose>0) Info("Init()","ideal charge conversion for rect. strips");
118  }
119  else if (fDigiParRect->GetChargeConvMethod() == 1){
120  if(fVerbose>0) Info("Init()","use TOT charge conversion for rect. strips");
126  fVerbose);
127  }
128  else Fatal ("Init()","rect. strips: charge conversion method not defined!");
129 
130  if (fDigiParTrap->GetChargeConvMethod() == 0){
131  if(fVerbose>0) Info("Init()","ideal charge conversion for trap. strips");
133  }
134  else if (fDigiParTrap->GetChargeConvMethod() == 1){
135  if(fVerbose>0) Info("Init()","use TOT charge conversion for trap. strips");
141  fVerbose);
142  }
143  else Fatal ("Init()","trap. strips: charge conversion method not defined!");
144 
145  if (fDigiParPix->GetChargeConvMethod() == 0){
146  if(fVerbose>0) Info("Init()","ideal charge conversion for pixel part");
148  }
149  else if (fDigiParPix->GetChargeConvMethod() == 1){
150  if(fVerbose>0) Info("Init()","use TOT charge conversion for pixel part");
156  fVerbose);
157  }
158  else Fatal ("Init()","pixel part: charge conversion method not defined!");
159 
160  return kSUCCESS;
161 }
162 
164 {
165  TObjArray* sensorNames = fGeoH->GetSensorNames();
166 
167  for (int i = 0; i < sensorNames->GetEntries(); i++)
168  {
169  TString volpath = ((TObjString*)(sensorNames->At(i)))->GetString();
170  if(!volpath.Contains("Mvd")) continue;
171  PndStringSeparator sep(volpath.Data(), "/");
172  std::vector<std::string> volvec = sep.GetStringVector();
173  TString volname = volvec[volvec.size()-1].c_str();
174  if(fVerbose>2)std::cout << "VolName: " << volname.Data();
175  if(volname.Contains("Active"))
176  {
177  if(volname.Contains("RectL")) {fStripRectLIds.push_back(i); if(fVerbose>2)std::cout << " \tAdded to StripRectL" << std::endl;}
178  if(volname.Contains("RectS")) {fStripRectSIds.push_back(i); if(fVerbose>2)std::cout << " \tAdded to StripRectS" << std::endl;}
179  if(volname.Contains("Trap")) {fStripTrapIds.push_back(i); if(fVerbose>2)std::cout << " \tAdded to StripTrap" << std::endl;}
180  if(volname.Contains("Pixel"))
181  {
182  if(volname.Contains("2")) {fPixelIds2.push_back(i); if(fVerbose>2)std::cout << " \tAdded to Pixel 2" << std::endl;}
183  if(volname.Contains("4")) {fPixelIds4.push_back(i); if(fVerbose>2)std::cout << " \tAdded to Pixel 4" << std::endl;}
184  if(volname.Contains("5")) {fPixelIds5.push_back(i); if(fVerbose>2)std::cout << " \tAdded to Pixel 5" << std::endl;}
185  if(volname.Contains("6")) {fPixelIds6.push_back(i); if(fVerbose>2)std::cout << " \tAdded to Pixel 6" << std::endl;}
186  }
187  }
188  }
189 }
190 
191 // -------------------------------------------------------------------------
193 {
194  if ( fGeoH == NULL ) {
196  }
197 
199  // Get Base Container
200  FairRun* ana = FairRun::Instance();
201  FairRuntimeDb* rtdb=ana->GetRuntimeDb();
202  fDigiParRect = (PndSdsStripDigiPar*)(rtdb->getContainer("MVDStripDigiParRect"));
203  fDigiParTrap = (PndSdsStripDigiPar*)(rtdb->getContainer("MVDStripDigiParTrap"));
204  fDigiParPix = (PndSdsPixelDigiPar*)(rtdb->getContainer("MVDPixelDigiPar"));
205  fTotDigiParRect = (PndSdsTotDigiPar*)(rtdb->getContainer("MVDStripTotDigiParRect"));
206  fTotDigiParTrap = (PndSdsTotDigiPar*)(rtdb->getContainer("MVDStripTotDigiParTrap"));
207  fTotDigiParPix = (PndSdsTotDigiPar*)(rtdb->getContainer("MVDPixelTotDigiPar"));
208 }
209 
210 
211 // ----- Public method Exec --------------------------------------------
213 {
214  // TObjArray* activeSensors = fGeoPar->GetGeoSensitiveNodes();
215  Int_t nrCh=0,rnd=0,
216  nrFE=0,sens=0,
217  nrSensors=0,fe=0,
218  chanmax=0,chan=0,
219  col=0,row=0,
220  chanwhite=0,
221  charge=0,
222  nNoisyStripRects=0,
223  nNoisyStripTraps=0,
224  nNoisyPixels=0;
225  Double_t xfrac=0.,cycles=1.;
226  Int_t did=-1;
227 
228  // *** Strip Rect Long ***
229  // how many channels left?
230  nrCh = fDigiParRect->GetNrFECh();
232  nrSensors = fStripRectLIds.size();
233  chanmax = nrCh * nrFE * nrSensors;
234  // Get Number of Channels fired from noise
237  chanwhite = gRandom->Poisson(xfrac*chanmax);
238  if(fVerbose>1) std::cout << " -I- PndMvdNoiseProducer: RECT <N> = " << xfrac*cycles*chanmax
239  << " leading to " << chanwhite << " noisy digis of " << chanmax
240  << " total channels" << std::endl;
241  for(Int_t i = 0;i < chanwhite;i++)
242  {
243  // randomize the channel numbers & sensors
244  rnd = gRandom->Integer(chanmax);
245  sens = rnd/(nrFE*nrCh);
246  rnd = rnd % (nrFE*nrCh);
247  fe = rnd/nrCh;
248  chan = rnd % nrCh;
249  // calculate a charge deposit above threshold
251  did = fStripRectLIds[sens];
253  AddDigiStrip(nNoisyStripRects,-1,did,fe,chan,charge);
254  }
255 
256  // *** Strip Rect Short ***
257  // how many channels left?
258  nrCh = fDigiParRect->GetNrFECh();
260  nrSensors = fStripRectSIds.size();
261  chanmax = nrCh * nrFE * nrSensors;
262  // Get Number of Channels fired from noise
264  chanwhite = gRandom->Poisson(xfrac*cycles*chanmax);
265  if(fVerbose>1) std::cout << " -I- PndMvdNoiseProducer: RECT <N> = " << xfrac*cycles*chanmax
266  << " leading to " << chanwhite << " noisy digis of " << chanmax
267  << " total channels" << std::endl;
268  for(Int_t i = 0;i < chanwhite;i++)
269  {
270  // randomize the channel numbers & sensors
271  rnd = gRandom->Integer(chanmax);
272  sens = rnd/(nrFE*nrCh);
273  rnd = rnd % (nrFE*nrCh);
274  fe = rnd/nrCh;
275  if(fe >= fDigiParRect->GetNrTopFE()/2) {
276  fe += fDigiParRect->GetNrTopFE()/2; // shift to avoid the unused fe numbers.
277  }
278  chan = rnd % nrCh;
279  // calculate a charge deposit above threshold
281  did = fStripRectSIds[sens];
283  AddDigiStrip(nNoisyStripRects,-1,did,fe,chan,charge);
284  }
285 
286  // *** Strip Trapezoids ***
287  nrCh = fDigiParTrap->GetNrFECh();
289  nrSensors = fStripTrapIds.size();
290  chanmax = nrCh * nrFE * nrSensors;
293  chanwhite = gRandom->Poisson(xfrac*cycles*chanmax);
294  if(fVerbose>1) std::cout << " -I- PndMvdNoiseProducer: TRAP <N> = " << xfrac*cycles*chanmax
295  << " leading to " << chanwhite << " noisy digis of " << chanmax
296  << " total channels" << std::endl;
297  for(Int_t i = 0;i < chanwhite;i++)
298  {
299  rnd = gRandom->Integer(chanmax);
300  sens = rnd/(nrFE*nrCh);
301  rnd = rnd % (nrFE*nrCh);
302  fe = rnd/nrCh;
303  chan = rnd % nrCh;
305  did = fStripTrapIds[sens];
307  AddDigiStrip(nNoisyStripTraps,-1,did,fe,chan,charge);
308  }
309 
310  // *** Pixel Sensors ***
312  Int_t pixx2=2*fPixelIds2.size(),
313  pixx4=4*fPixelIds4.size(),
314  pixx5=5*fPixelIds5.size(),
315  pixx6=6*fPixelIds6.size();
316  nrFE = pixx2 + pixx4 + pixx5 + pixx6;
317  chanmax = nrCh * nrFE;
320  chanwhite = gRandom->Poisson(xfrac*cycles*chanmax);
321  if(fVerbose>1) std::cout << " -I- PndMvdNoiseProducer: PIXEL <N> = " << xfrac*cycles*chanmax
322  << " leading to " << chanwhite << " noisy digis of " << chanmax
323  << " total channels" << std::endl;
324  for(Int_t i = 0;i < chanwhite;i++)
325  {
327  rnd = gRandom->Integer(chanmax);
328  chan = rnd%nrCh;
329  col = chan%fDigiParPix->GetFECols();
330  row = chan/fDigiParPix->GetFECols();
331  fe = rnd/nrCh;
332  if(fe >= (Int_t)(pixx2 + pixx4 + pixx5) )
333  {
334  fe = fe - pixx2 - pixx4 - pixx5;
335  sens = fe/6;
336  did = fPixelIds6[sens];
337  fe = fe%6;
338  //if(fe>6) fe=fe-6+10; //0-9 one row of FE, 10-19 2nd row of FE
339  } else if( fe >= (Int_t)(pixx2 + pixx4) )
340  {
341  fe = fe - pixx2 - pixx4;
342  sens = fe/5;
343  did = fPixelIds5[sens];
344  fe = fe%5;
345  //if(fe>4) fe=fe-4+10; //0-9 one row of FE, 10-19 2nd row of FE
346  } else if( fe >= (Int_t)(pixx2) )
347  {
348  fe = fe -pixx2;
349  sens = fe/4;
350  did = fPixelIds4[sens];
351  fe = fe%4;
352  } else
353  {
354  sens = fe/2;
355  did = fPixelIds2[sens];
356  fe = fe%2;
357  }
358 
359  AddDigiPixel(nNoisyPixels,-1,did,fe,col,row,charge);
360  }
361 
362  fPreviousTime = FairRootManager::Instance()->GetEventTime();
363 
364  // *** The End ***
365  if(fVerbose>0)
366  {
367  std::cout <<" -I- PndMvdNoiseProducer: Noise produced\t"
368  <<nNoisyStripRects <<"xStripRect\t"
369  <<nNoisyStripTraps <<"xStripTrap\t"
370  <<nNoisyPixels <<"xPixels"<<std::endl;
371  }
372 }
373 // -------------------------------------------------------------------------
374 
375 // -------------------------------------------------------------------------
377 {
378  // mean fraction of fireing digis
379  return TMath::Erfc( threshold / (TMath::Sqrt2()*spread) );
380 }
381 
383 {
384  // pick any charge from the gaussian tail above threshold
385  Double_t temp=0.;
386  temp = TMath::Gaus(threshold,0,spread); // maximum gauss at threshold
387  temp = gRandom->Uniform(0.,temp); // random value in y
388  temp = -2.*spread*spread*log(temp); // get x value (recalc charge)
389  temp = sqrt(temp);
390  return (Int_t)ceil(temp);
391 }
392 
394 { // time [ns], clock [MHz]
395  Double_t cycles=1.;
396  Double_t timewindow=0.;
397  if (clock > 0){
398  if (fMCEventheader!=0) {
399  timewindow = FairRootManager::Instance()->GetEventTime();
400  timewindow -= fPreviousTime;
401  } else {
402  timewindow = 50.; // how many ns do we suppress readout of zeros?
403  }
404  }
405  if(fVerbose>1) printf(" -I- PndMvdNoiseProducer::CalcReadoutCycles(): %g cycles (%gMHz,%gns)\n",cycles,clock,timewindow);
406  return cycles;
407 }
408 
409 void PndMvdNoiseProducer::AddDigiStrip(Int_t &noisies, Int_t iPoint, Int_t sensorID, Int_t fe, Int_t chan, Double_t charge)
410 {
411  //Double_t tempcharge = 0.;
412  //Bool_t found = kFALSE;
413  Int_t detID = -1; // no source mc branch
414  //PndSdsDigiStrip* aDigi = 0;
415 // FairMCEventHeader* MCevtHeader = (FairMCEventHeader*)FairRootManager::Instance()->GetObject("MCEventHeader.");
416 
417 // if (fTimeOrderedDigi == kFALSE){
418 // Int_t iStrip = fDigiStripArray->GetEntriesFast();
419 //
420 // for(Int_t kstr = 0; kstr < iStrip && found == kFALSE; kstr++)
421 // {
422 // aDigi = (PndSdsDigiStrip*)fDigiStripArray->At(kstr);
423 // if (aDigi->GetSensorID() == sensorID &&
424 // aDigi->GetFE() == fe &&
425 // aDigi->GetChannel() == chan )
426 // {
427 // tempcharge = fCurrentChargeConv->DigiValueToCharge(*aDigi);
428 // aDigi->SetCharge( fCurrentChargeConv->ChargeToDigiValue(charge + tempcharge) );
429 // aDigi->AddIndex(iPoint);
430 // found = kTRUE;
431 // }
432 // }
433 // if(found == kFALSE){
434 // //TODO: get a reasonable timestamp fake for the noise
435 // std::vector<Int_t> indices;
436 // indices.push_back(iPoint);
437 // new ((*fDigiStripArray)[iStrip]) PndSdsDigiStrip(indices,detID,sensorID,fe,chan,fCurrentChargeConv->ChargeToDigiValue(charge), FairRootManager::Instance()->GetEventTime()) ;
438 // noisies++;
439 // if(fVerbose>2) std::cout
440 // << " -I- PndSdsNoiseProducer: Added StripTrap Digi at: FE=" << fe
441 // << ", channel=" << chan << ", charge=" << charge<< " e"
442 // << ", in sensor \n" << sensorID <<std::endl;
443 // }
444 // }
445 // else{
446  std::vector<Int_t> indices;
447  indices.push_back(iPoint);
448  PndSdsDigiStrip* tempStrip = new PndSdsDigiStrip(indices,detID,sensorID,fe,chan,fCurrentChargeConv->ChargeToDigiValue(charge), FairRootManager::Instance()->GetEventTime()) ;
449  noisies++;
450  fDigiStripBuffer->FillNewData(tempStrip, FairRootManager::Instance()->GetEventTime(), FairRootManager::Instance()->GetEventTime() + 10);
451  delete(tempStrip);
452 // }
453 }
454 // -------------------------------------------------------------------------
455 void PndMvdNoiseProducer::AddDigiPixel(Int_t &noisies, Int_t iPoint, Int_t sensorID, Int_t fe, Int_t col, Int_t row, Double_t charge)
456 {
457  //Double_t tempcharge = 0.;
458  //Bool_t found = kFALSE;
459  Int_t detID = -1; //no source mc branch
460 
461  std::vector<Int_t> indices;
462  indices.push_back(iPoint);
463  PndSdsDigiPixel* tempPixel = new PndSdsDigiPixel(indices,detID,sensorID,fe,col,row,fPixChargeConv->ChargeToDigiValue(charge), fPixChargeConv->GetTimeStamp(0, charge,FairRootManager::Instance()->GetEventTime()));//FairRootManager::Instance()->GetEventTime()) ;
464  if (fPixChargeConv->GetTimeWalk((Int_t)tempPixel->GetCharge()) < 1E5){
465  tempPixel->SetTimeStamp(tempPixel->GetTimeStamp() - fPixChargeConv->GetTimeWalk((Int_t)tempPixel->GetCharge()));
466  tempPixel->SetTimeStampError(fPixChargeConv->GetTimeStampErrorAfterCorrection());
467  }
468  fDigiPixelBuffer->FillNewData(tempPixel,fPixChargeConv->ChargeToDigiValue(charge)*6 + FairRootManager::Instance()->GetEventTime(), FairRootManager::Instance()->GetEventTime());
469  noisies++; // to count outside the noisy digis.
470  delete(tempPixel);
471  // std::cout << "DataInBuffer: " << fDigiPixelBuffer->GetNData() << std::endl;
472 }
473 
475 {
476  // called after all Tasks did their Exex() and the data is copied to the file
477 
478  FinishEvents();
479 }
480 // -------------------------------------------------------------------------
481 
482 
483 
484 
std::vector< Int_t > fPixelIds4
int row
Definition: anaLmdDigi.C:67
std::vector< Int_t > fPixelIds5
int fVerbose
Definition: poormantracks.C:24
printf("RealTime=%f seconds, CpuTime=%f seconds\n", rtime, ctime)
PndSdsTotDigiPar * fTotDigiParRect
PndSdsTotDigiPar * fTotDigiParPix
std::vector< std::string > GetStringVector(void)
Int_t GetChargeConvMethod() const
Int_t i
Definition: run_full.C:25
PndGeoHandling * fGeoH
Definition: anasim.C:34
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:29
std::vector< Int_t > fPixelIds2
std::vector< Int_t > fStripRectSIds
virtual void SetParContainers()
void AddDigiPixel(Int_t &noisies, Int_t iPoint, Int_t sensorID, Int_t fe, Int_t col, Int_t row, Double_t charge)
virtual void SetParContainers()
int col
Definition: anaLmdDigi.C:67
Class for digitised strip hits.
friend F32vec4 log(const F32vec4 &a)
Definition: P4_F32vec4.h:110
Double_t GetCharge() const
Definition: PndSdsDigi.h:60
PndSdsChargeConversion * fStripTrapChargeConv
Double_t GetNoise() const
std::vector< Int_t > fPixelIds6
virtual Double_t GetTimeStamp(Double_t tof, Double_t charge, Double_t MCEventTime)=0
absolute time stamp of a hit in ns (clock is taken into account)
Double_t GetThreshold() const
Charge Digitization Parameter Class for SDS.
PndSdsDigiPixelWriteoutBuffer * fDigiPixelBuffer
Double_t GetFeBusClock() const
Double_t GetConstCurrent() const
Double_t GetNoise() const
Bool_t fTimeOrderedDigi
parameter to switch to time ordered simulation
Double_t GetClockFrequency() const
PndSdsChargeConversion * fStripRectChargeConv
virtual InitStatus Init()
Int_t GetFERows() const
Int_t GetFECols() const
void AddDigiStrip(Int_t &iStrip, Int_t iPoint, Int_t sensorID, Int_t fe, Int_t chan, Double_t charge)
PndSdsStripDigiPar * fDigiParTrap
Double_t
Double_t CalcReadoutCycles(Double_t clock)
std::vector< Int_t > fStripRectLIds
Digitization Parameter Class for MVD-Strip part.
Double_t GetFeBusClock() const
FairRuntimeDb * rtdb
Definition: hit_dirc.C:66
PndSdsDigiStripWriteoutBuffer * fDigiStripBuffer
TObjArray * GetSensorNames()
PndSdsStripDigiPar * fDigiParRect
static PndGeoHandling * Instance()
double threshold
virtual Double_t GetTimeStampErrorAfterCorrection()
PndSdsChargeConversion * fPixChargeConv
virtual Double_t ChargeToDigiValue(Double_t Charge)=0
Converts a given charge in electrons into the electronics answer e.g. ToT [ns].
Int_t GetNrFECh() const
PndSdsPixelDigiPar * fDigiParPix
Double_t GetChargingTime() const
int fe
Definition: anaLmdDigi.C:67
std::vector< Int_t > fStripTrapIds
ClassImp(PndAnaContFact)
PndSdsChargeConversion * fCurrentChargeConv
Data class to store the digi output of a pixel module.
Int_t GetNrTopFE() const
virtual Double_t GetTimeWalk(Double_t)
PndSdsTotDigiPar * fTotDigiParTrap
Int_t GetNrBotFE() const
virtual void Exec(Option_t *opt)
PndGeoHandling * fGeoH
FairMCEventHeader * fMCEventheader
Geometry name handling.
Int_t GetChargeConvMethod() const
Double_t CalcDistFraction(Double_t spread, Double_t threshold)
Double_t GetThreshold() const
Int_t CalcChargeAboveThreshold(Double_t spread, Double_t threshold)
Digitization Parameter Class for SDS-Pixel part.