FairRoot/PandaRoot
PndLmdNoiseProducer.cxx
Go to the documentation of this file.
1 // -------------------------------------------------------------------------
2 // ----- PndLmdNoiseProducer source file -----
3 // ----- Created 05.2015 by P. Jasinski -----
4 //----- updated 17/07/2015 by A.Karavdina -----
5 // -------------------------------------------------------------------------
6 
7 //#include <cmath>
8 /*
9 #include "TClonesArray.h"
10 #include "TGeoNode.h"
11 
12 #include "FairRootManager.h"
13 #include "FairGeoVolume.h"
14 #include "FairRun.h"
15 #include "FairRuntimeDb.h"
16 #include "FairGeoNode.h"
17 
18 #include "PndMvdNoiseProducer.h"
19 #include "PndSdsMCPoint.h"
20 #include "PndSdsDigiStrip.h"
21 #include "PndSdsDigiPixel.h"
22 
23 
24 #include "PndSdsIdealChargeConversion.h"
25 #include "PndSdsTotChargeConversion.h"
26 
27 #include "PndDetectorList.h"*/
28 #include "PndLmdNoiseProducer.h"
29 #include "PndStringSeparator.h"
30 #include "PndLmdDim.h"
33 
34 // ----- Public method Init --------------------------------------------
36 {
37 
38 // Get RootManager
39  FairRootManager* ioman = FairRootManager::Instance();
40 
41  if ( ! ioman )
42  {
43  std::cout << " -E- PndMvdNoiseProducer::Init: RootManager not instantiated!" << std::endl;
44  return kFATAL;
45  }
46  // call prior to base call the overloaded FillSensorMethod() to find sensors from geometry;
48  // call the base implementation
49  // if ( PndMvdNoiseProducer::Init() == kFATAL ) return kFATAL;
50  // override some lmd specific stuff
51 
52  // Get input array
53 
54  // fDigiStripBuffer = (PndSdsDigiStripWriteoutBuffer*)FairRootManager::Instance()->
55  // RegisterWriteoutBuffer("LMDStripDigis", new PndSdsDigiStripWriteoutBuffer("LMDStripDigis", "LMD", kTRUE));
56 
57  fDigiPixelBuffer = new PndSdsDigiPixelWriteoutBuffer("LMDPixelDigis", "LMD", kTRUE);
58  fDigiPixelBuffer = (PndSdsDigiPixelWriteoutBuffer*)FairRootManager::Instance()->
59  RegisterWriteoutBuffer("LMDPixelDigis", fDigiPixelBuffer);
60  fDigiPixelBuffer->ActivateBuffering(fTimeOrderedDigi);
61 
62 
63 fMCEventheader = (FairMCEventHeader*) ioman->GetObject("MCEventHeader.");
64  if ( ! fMCEventheader ){
65  Warning("Init","Did not find the MC event header, assume 50ns of noise clockticks per call of Exec().");
66  }
67  fPreviousTime=0.;
68 
69  //FillSensorLists();
70 
71 // fFEModel = new PndSdsFESimple();
72 
73  if(fVerbose>0)
74  {
75  std::cout <<" -I- PndLmdNoiseProducer: Registered Sensors: "
76  <<fStripRectLIds.size()+fStripRectSIds.size()<<"xStripRect "
77  <<fStripTrapIds.size()<<"xStripTrap "
78  <<fPixelIds2.size()<<"xPixel"
79  <<std::endl;
80  }
81  std::cout << " -I- PndMvdNoiseProducer: Intialisation successfull" << std::endl;
82 
83  // if (fDigiParRect->GetChargeConvMethod() == 0){
84  // if(fVerbose>0) Info("Init()","ideal charge conversion for rect. strips");
85  // fStripRectChargeConv = new PndSdsIdealChargeConversion(fDigiParRect->GetNoise());
86  // }
87  // else if (fDigiParRect->GetChargeConvMethod() == 1){
88  // if(fVerbose>0) Info("Init()","use TOT charge conversion for rect. strips");
89  // fStripRectChargeConv = new PndSdsTotChargeConversion(
90  // fTotDigiParRect->GetChargingTime(),
91  // fTotDigiParRect->GetConstCurrent(),
92  // fDigiParRect->GetThreshold(),
93  // fTotDigiParRect->GetClockFrequency(),
94  // fVerbose);
95  // }
96  // else Fatal ("Init()","rect. strips: charge conversion method not defined!");
97 
98  // if (fDigiParTrap->GetChargeConvMethod() == 0){
99  // if(fVerbose>0) Info("Init()","ideal charge conversion for trap. strips");
100  // fStripTrapChargeConv = new PndSdsIdealChargeConversion(fDigiParTrap->GetNoise());
101  // }
102  // else if (fDigiParTrap->GetChargeConvMethod() == 1){
103  // if(fVerbose>0) Info("Init()","use TOT charge conversion for trap. strips");
104  // fStripTrapChargeConv = new PndSdsTotChargeConversion(
105  // fTotDigiParTrap->GetChargingTime(),
106  // fTotDigiParTrap->GetConstCurrent(),
107  // fDigiParTrap->GetThreshold(),
108  // fTotDigiParTrap->GetClockFrequency(),
109  // fVerbose);
110  // }
111  // else Fatal ("Init()","trap. strips: charge conversion method not defined!");
112 
113  if (fDigiParPix->GetChargeConvMethod() == 0){
114  if(fVerbose>0) Info("Init()","ideal charge conversion for pixel part");
116  }
117  else if (fDigiParPix->GetChargeConvMethod() == 1){
118  if(fVerbose>0) Info("Init()","use TOT charge conversion for pixel part");
124  fVerbose);
125  }
126  else Fatal ("Init()","pixel part: charge conversion method not defined!");
127 
128  return kSUCCESS;
129 }
130 
132 {
133  //std::cout << " ***** initializing sensor lists ******** " << std::endl;
134  TObjArray* sensorNames = fGeoH->GetSensorNames();
135 
136  for (int i = 0; i < sensorNames->GetEntries(); i++)
137  {
138  TString volpath = ((TObjString*)(sensorNames->At(i)))->GetString();
139  //std::cout << " volume path is " << volpath << std::endl;
140  if(!volpath.Contains("Lum")) continue;
141  PndStringSeparator sep(volpath.Data(), "/");
142  std::vector<std::string> volvec = sep.GetStringVector();
143  TString volname = volvec[volvec.size()-1].c_str();
144  if(fVerbose>2)std::cout << "VolName: " << volname.Data();
145  if(volname.Contains("Active"))
146  //std::cout << " found sensor " << volname << std::endl;
147  {
148  // if(volname.Contains("Trap")) {fStripTrapIds.push_back(i); if(fVerbose>2)std::cout << " \tAdded to StripTrap" << std::endl;}
149  if(volname.Contains("Pixel")) {fPixelIds.push_back(i); if(fVerbose>2)std::cout << " \tAdded to Pixel" << std::endl;}
150  }
151  }
152 }
153 
155 {
156 
157  // Get Base Container
158  FairRun* ana = FairRun::Instance();
159  FairRuntimeDb* rtdb=ana->GetRuntimeDb();
160  // fDigiParRect = (PndSdsStripDigiPar*)(rtdb->getContainer("SDSStripDigiParRect"));
161  // fDigiParTrap = (PndSdsStripDigiPar*)(rtdb->getContainer("SDSStripDigiParTrap"));
162  fDigiParPix = (PndSdsPixelDigiPar*)(rtdb->getContainer("SDSPixelDigiPar"));
163  // fTotDigiParRect = (PndSdsTotDigiPar*)(rtdb->getContainer("SDSStripTotDigiParRect"));
164  // fTotDigiParTrap = (PndSdsTotDigiPar*)(rtdb->getContainer("SDSStripTotDigiParTrap"));
165  fTotDigiParPix = (PndSdsTotDigiPar*)(rtdb->getContainer("SDSPixelTotDigiPar"));
166 
167  if ( fGeoH == NULL ) {
169  }
170 
172 }
173 
175 {
176  // TObjArray* activeSensors = fGeoPar->GetGeoSensitiveNodes();
177  Int_t nrCh=0,rnd=0,
178  nrFE=0, //sens=0, //[R.K. 01/2017] unused variable?
179  fe=0, //nrSensors=0, //[R.K. 01/2017] unused variable?
180  chanmax=0,chan=0,
181  col=0,row=0,
182  chanwhite=0,
183  charge=0,
184  nNoisyStripRects=0,
185  nNoisyStripTraps=0,
186  nNoisyPixels=0;
187  Double_t xfrac=0.,cycles=1.;
188  Int_t did=-1;
189 
190 
191  // // *** Strip Trapezoids ***
192  // nrCh = fDigiParTrap->GetNrFECh();
193  // nrFE = fDigiParTrap->GetNrBotFE() + fDigiParTrap->GetNrTopFE();
194  // nrSensors = fStripTrapIds.size();
195  // chanmax = nrCh * nrFE * nrSensors;
196  // xfrac = CalcDistFraction(fDigiParTrap->GetNoise(),fDigiParTrap->GetThreshold());
197  // cycles = CalcReadoutCycles(fDigiParTrap->GetFeBusClock());
198  // chanwhite = gRandom->Poisson(xfrac*cycles*chanmax);
199  // if(fVerbose>1) std::cout << " -I- PndLmdNoiseProducer: TRAP <N> = " << xfrac*cycles*chanmax
200  // << " leading to " << chanwhite << " noisy digis of " << chanmax
201  // << " total channels" << std::endl;
202 
203  // for(Int_t i = 0;i < chanwhite;i++)
204  // {
205  // rnd = gRandom->Integer(chanmax);
206  // sens = rnd/(nrFE*nrCh);
207  // rnd = rnd % (nrFE*nrCh);
208  // fe = rnd/nrCh;
209  // chan = rnd % nrCh;
210  // charge = fDigiParTrap->GetThreshold()*6;//CalcChargeAboveThreshold(fDigiParTrap->GetNoise(),fDigiParTrap->GetThreshold());
211  // did = fStripTrapIds[sens];
212  // fCurrentChargeConv = fStripTrapChargeConv;
213  // AddDigiStrip(nNoisyStripTraps,-1,did,fe,chan,charge);
214  // }
215 
216  PndLmdDim& lmd_dim = PndLmdDim::Get_instance();
217  // *** Pixel Sensors ***
219  Int_t pixx=fPixelIds.size();
220  nrFE = pixx;
221  chanmax = nrCh * nrFE;
222  if(fVerbose>2) {
223  std::cout << " found " << nrFE << " sensors " << " with in total " << chanmax << " pixels " << std::endl;
224  }
225  // get the mean number of pixels fired
227  if(fVerbose>2){
228  std::cout << " with a noise of " << fDigiParPix->GetNoise() << " e and a threshold of " << fDigiParPix->GetThreshold()
229  << " e " << xfrac*100 << " % pixels should have fired " << std::endl;
230  }
232  chanwhite = gRandom->Poisson(xfrac*cycles*chanmax);
233  //std::cout << " cycles " << cycles << " chanwhite " << chanwhite << std::endl;
234  if(fVerbose>1) std::cout << " -I- PndLmdNoiseProducer: PIXEL <N> = " << xfrac*cycles*chanmax
235  << " leading to " << chanwhite << " noisy digis of " << chanmax
236  << " total channels" << std::endl;
237  for(Int_t i = 0;i < chanwhite;i++)
238  {
239  // prevent further steps in the software cutting those hits away by applying high charge
240  charge = fDigiParPix->GetThreshold()*6; //CalcChargeAboveThreshold(fDigiParPix->GetNoise(),fDigiParPix->GetThreshold());
241  rnd = gRandom->Integer(chanmax);
242  chan = rnd%nrCh;
243  col = chan%fDigiParPix->GetFECols();
244  row = chan/fDigiParPix->GetFECols();
245  fe = rnd/nrCh;
246  //if (fe < 0 || fe > 399) std::cout << "error! :" << fe << " does not match the total number of channels" << std::endl;
247  did = fPixelIds[fe];
248  /*
249  if(fe >= (Int_t)(pixx) )
250  {
251  fe = fe - pixx;
252  sens = fe/6;
253  did = fPixelIds6[sens];
254  fe = fe%6;
255  //if(fe>6) fe=fe-6+10; //0-9 one row of FE, 10-19 2nd row of FE
256  } else if( fe >= (Int_t)(pixx2 + pixx4) )
257  {
258  fe = fe - pixx2 - pixx4;
259  sens = fe/5;
260  did = fPixelIds5[sens];
261  fe = fe%5;
262  //if(fe>4) fe=fe-4+10; //0-9 one row of FE, 10-19 2nd row of FE
263  } else if( fe >= (Int_t)(pixx2) )
264  {
265  fe = fe -pixx2;
266  sens = fe/4;
267  did = fPixelIds4[sens];
268  fe = fe%4;
269  } else
270  {
271  sens = fe/2;
272  did = fPixelIds2[sens];
273  fe = fe%2;
274  }*/
275 
276  //std::cout << " adding pixel " << i << " of " << chanwhite << std::endl;
277 
278  int ihalf, iplane, imodule, iside, idie, isensor;
279  if (fe < 0 || fe > 399) std::cout << "error! :" << fe << " does not match the total number of channels" << std::endl;
280  if (col > 255 || row > 255 || col < 0 || row < 0)
281  std::cout << "error! :" << fe << " " << did << " " << col << " " << row << " " << charge << std::endl;
282  lmd_dim.Get_sensor_by_id(fe, ihalf, iplane, imodule, iside, idie, isensor);
283  //if (imodule != 0 || ihalf != 0) continue;
284  AddDigiPixel(nNoisyPixels,-1,fe,0,col,row,charge); // fe is abused here for sensID and real fe is set to 0
285  }
286 
287  fPreviousTime = FairRootManager::Instance()->GetEventTime();
288 
289  // *** The End ***
290  if(fVerbose>0)
291  {
292  std::cout <<" -I- PndLmdNoiseProducer: Noise produced\t"
293  <<nNoisyStripRects <<"xStripRect\t"
294  <<nNoisyStripTraps <<"xStripTrap\t"
295  <<nNoisyPixels <<"xPixels"<<std::endl;
296  }
297 }
298 
299 //TODO: for time-based simulation number of cycles should be calculated (e.g like in //CORRECT calculation!) and not fixed
301 { // time [ns], clock [MHz]
302  Double_t cycles=1.;
303  Double_t timewindow=0.;
304  if (clock > 0){
305  if (fMCEventheader!=0) {
306  timewindow = FairRootManager::Instance()->GetEventTime();
307  // cout<<"ev time = "<<FairRootManager::Instance()->GetEventTime()<<" prev.ev time = "<<fPreviousTime<<endl;
308  timewindow -= fPreviousTime;
309  // cout<<"timewindow = "<<timewindow<<endl;
310  } else {
311  timewindow = 50.; // 20 MHz
312  }
313  }
314  //cycles = timewindow*clock/1000.;//CORRECT calculation!
315  cycles = 3;// for event-based reconstruction we assume minimum 3 readout cycles are used in event construction
316  if(fVerbose>10) printf(" -I- PndLmdNoiseProducer::CalcReadoutCycles(): %g cycles (%gMHz,%gns)\n",cycles,clock,timewindow);
317  return cycles;
318 }
319 
320 
321 // -------------------------------------------------------------------------
322 void PndLmdNoiseProducer::AddDigiPixel(Int_t &noisies, Int_t iPoint, Int_t sensorID, Int_t fe, Int_t col, Int_t row, Double_t charge)
323 {
324  //Double_t tempcharge = 0.;
325  //Bool_t found = kFALSE;
326  Int_t detID = -1; //no source mc branch
327 
328  std::vector<Int_t> indices;
329  indices.push_back(iPoint);
330  PndSdsDigiPixel* tempPixel = new PndSdsDigiPixel(indices,detID,sensorID,fe,col,row,fPixChargeConv->ChargeToDigiValue(charge), fPixChargeConv->GetTimeStamp(0, charge,FairRootManager::Instance()->GetEventTime()));//FairRootManager::Instance()->GetEventTime()) ;
331 
332  if (fPixChargeConv->GetTimeWalk((Int_t)tempPixel->GetCharge()) < 1E5){
333  tempPixel->SetTimeStamp(tempPixel->GetTimeStamp() - fPixChargeConv->GetTimeWalk((Int_t)tempPixel->GetCharge()));
334  tempPixel->SetTimeStampError(fPixChargeConv->GetTimeStampErrorAfterCorrection());
335  }
336 
337  if(tempPixel->GetTimeStamp()<0){ //ideal charge converter has fixed time stamp = -1 ns =/
338  int timeSt = gRandom->Integer(CalcReadoutCycles(fDigiParPix->GetFeBusClock())*1000./fDigiParPix->GetFeBusClock());
339  tempPixel->SetTimeStamp(timeSt);
340  }
341 
342  fDigiPixelBuffer->FillNewData(tempPixel,fPixChargeConv->ChargeToDigiValue(charge)*6 + FairRootManager::Instance()->GetEventTime(), FairRootManager::Instance()->GetEventTime());
343  noisies++;
344  delete(tempPixel);
345  // std::cout << "DataInBuffer: " << fDigiPixelBuffer->GetNData() << std::endl;
346 }
347 
int row
Definition: anaLmdDigi.C:67
int fVerbose
Definition: poormantracks.C:24
printf("RealTime=%f seconds, CpuTime=%f seconds\n", rtime, ctime)
PndSdsTotDigiPar * fTotDigiParPix
std::vector< std::string > GetStringVector(void)
Int_t GetChargeConvMethod() const
Int_t i
Definition: run_full.C:25
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)
int col
Definition: anaLmdDigi.C:67
Double_t GetCharge() const
Definition: PndSdsDigi.h:60
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)
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
Int_t GetFERows() const
Int_t GetFECols() const
Double_t
std::vector< Int_t > fStripRectLIds
void Get_sensor_by_id(const int sensor_id, int &ihalf, int &iplane, int &imodule, int &iside, int &idie, int &isensor)
Definition: PndLmdDim.h:526
FairRuntimeDb * rtdb
Definition: hit_dirc.C:66
TObjArray * GetSensorNames()
static PndGeoHandling * Instance()
virtual InitStatus Init()
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].
PndSdsPixelDigiPar * fDigiParPix
Double_t GetChargingTime() const
std::vector< Int_t > fPixelIds
Double_t CalcReadoutCycles(Double_t clock)
static PndLmdDim & Get_instance()
Definition: PndLmdDim.cxx:242
int fe
Definition: anaLmdDigi.C:67
std::vector< Int_t > fStripTrapIds
ClassImp(PndAnaContFact)
Data class to store the digi output of a pixel module.
virtual Double_t GetTimeWalk(Double_t)
void Exec(Option_t *opt)
PndGeoHandling * fGeoH
FairMCEventHeader * fMCEventheader
Geometry name handling.
Double_t CalcDistFraction(Double_t spread, Double_t threshold)
Double_t GetThreshold() const
Digitization Parameter Class for SDS-Pixel part.