FairRoot/PandaRoot
PndEmcWaveform.cxx
Go to the documentation of this file.
1 //=====================================================================
2 // PndEmcWaveform.cxx
3 //
4 // Class to hold waveforms created from Emc Hits
5 //
6 // Software developed for the BaBar Detector at the SLAC B-Factory.
7 // Adapted for the PANDA experiment at GSI
8 //
9 // P.D.Strother Imperial College
10 // Naveen Gunawardane Imperial College
11 // Dima Melnichuk - adaption for PANDA
12 //-----------------------
13 
14 
15 #include "PndEmcWaveform.h"
16 #include "PndEmcHit.h"
17 #include "PndEmcCRRCPulseshape.h"
18 #include "PndEmcCR2RCPulseshape.h"
19 #include "PndEmcMapper.h"
20 #include "PndDetectorList.h"
21 
22 #include "TRandom.h"
23 #include "TClonesArray.h"
24 
25 #include "TClass.h"
26 #include "TBuffer.h"
27 #include "Riostream.h"
28 //---------------
29 // C++ Headers --
30 //---------------
31 
32 #include <iostream>
33 #include <algorithm>
34 #include "assert.h"
35 
36 using std::cout;
37 using std::endl;
38 
39 
40 //----------------
41 // Constructors --
42 //----------------
43 Double_t PndEmcWaveform::BarrelOverlapTime = 700;//(120*12.5 - 800);ns
44 Double_t PndEmcWaveform::ForwardOverlapTime = 390;//(60*10 - 210);
45 Double_t PndEmcWaveform::ShashylikOverlapTime = 130;//(60*5.5 - 200);
46 
48  FairTimeStamp()
49  ,fTrackId(-1)
50  ,fDetectorId(-1)
51  ,fWaveformLength(0)
52  ,fSignal(0,0.)
53  ,fSignalError(0,0.)
54  ,fHitIndex(-1)
55  ,fSampleRate(0.)
56  ,fBaselineValue(0.)
57 {}
58 
59 PndEmcWaveform::PndEmcWaveform(int trackId, long detId, Double_t sampleRate, long waveform_length, Int_t hitIndex, Double_t time) :
60  FairTimeStamp(time)
61  ,fTrackId(trackId)
62  ,fDetectorId(detId)
63  ,fWaveformLength(waveform_length)
64  ,fSignal(waveform_length,0.)
65  ,fSignalError(waveform_length,0.)
66  ,fHitIndex(hitIndex)
67  ,fSampleRate(sampleRate)
68  ,fBaselineValue(0.)
69 {
70  if(hitIndex>=0) SetLink(FairLink(-1, FairRootManager::Instance()->GetEntryNr(), "EmcHit", hitIndex));
71 }
72 
73 PndEmcWaveform::PndEmcWaveform(int trackId, long detId, const std::vector<Double_t>& signal, Int_t hitIndex) :
74  fTrackId(trackId),
75  fDetectorId(detId),
76  fWaveformLength(signal.size()),
77  fSignal(signal),
78  fHitIndex(hitIndex)
79 {
80  if(hitIndex>=0) SetLink(FairLink(-1, FairRootManager::Instance()->GetEntryNr(), "EmcHit", hitIndex));
81 }
82 
83 PndEmcWaveform::PndEmcWaveform(long detId, const std::vector<Double_t>& signal, const FairMultiLinkedData& links) :
84  fTrackId(-1),
85  fDetectorId(detId),
86  fWaveformLength(signal.size()),
87  fSignal(signal),
88  fHitIndex(-1) {
89  SetLinks(links);
90 }
91 
92 /* auto generated by compiler
93 PndEmcWaveform::PndEmcWaveform(const PndEmcWaveform& copy):
94  fTrackId(copy.fTrackId)
95  ,fDetectorId ( copy.fDetectorId)
96  ,fWaveformLength(copy.fWaveformLength)
97  ,fHitIndex(copy.fHitIndex)
98  ,fSignal(copy.fSignal)
99  ,fSignalError(copy.fSignalError)
100  ,fSampleRate(copy.fSampleRate)
101  ,fBaselineValue(copy.fBaselineValue)
102  ,fEvt(copy.fEvt)
103  ,FairTimeStamp(copy)
104 {
105 }
106 */
107 
108 /*auto generated by compiler
109 PndEmcWaveform& PndEmcWaveform::operator=(const PndEmcWaveform &copy){
110  if(this != &copy){
111  fTrackId = copy.fTrackId;
112  fDetectorId = copy.fDetectorId;
113  fWaveformLength = copy.fWaveformLength;
114  fHitIndex = copy.fHitIndex;
115  fSignal = copy.fSignal;
116  fSignalError = copy.fSignalError;
117  fEvt = copy.fEvt;
118  fSampleRate = copy.fSampleRate;
119  fBaselineValue = copy.fBaselineValue;
120  FairTimeStamp::operator=(copy);
121  }
122  return *this;
123 }
124 */
125 
126 //--------------
127 // Destructor --
128 //--------------
129 
131 {
132  fSignal.clear();
133  fSignalError.clear();
134  fEvt.clear();
135 }
136 
137 
138 //-------------
139 // Selectors --
140 //-------------
141 
142 Double_t
144 {
145  return GetNormalisation(sampleRate, pulseshape);
146 }
147 
148 Double_t
150 {
151  // Function to return the equivalent pulse height for a 1 GeV pulse
152  // Used in EmcHitsToWaveform to determine electronics noise scale
153 
154  PndEmcWaveform newWaveform(*this);
155  newWaveform.clearAndReset();
156 
157  PndEmcHit *gevHit=new PndEmcHit();
158  gevHit->SetEnergy(1.0);
159  gevHit->SetTime(0.);
160  newWaveform.UpdateWaveform(gevHit, 0, false, 1., 0., sampleRate, pulseshape);
161  delete gevHit;
162 
163  Double_t maximum=newWaveform.Max();
164  return maximum;
165 }
166 
167 
168 //-------------
169 // Modifiers --
170 //-------------
171 
172 void
174  , Double_t pePerMeV
175  , Bool_t usePhotonStatistic
176  , Double_t excessNoiseFactor
177  , Double_t firstADCBinTime
178  , Double_t sampleRate
179  , PndEmcAbsPulseshape *pulseshape
180  , Double_t EnergyError)
181 {
183  Double_t time= GetTimeStamp();//firstADCBinTime = 0.;
184 
185  MakeWaveform(energy, time, pePerMeV, usePhotonStatistic, excessNoiseFactor, firstADCBinTime, sampleRate, pulseshape, EnergyError);
186 
187 }
188 
189 void
191  , Double_t // time //[R.K.03/2017] unused variable(s)
192  , Double_t pePerMeV
193  , Bool_t usePhotonStatistic
194  , Double_t excessNoiseFactor
195  , Double_t firstADCBinTime
196  , Double_t sampleRate
197  , PndEmcAbsPulseshape *pulseshape
198  , Double_t EnergyError)
199 {
200  Double_t amplitude;
201  Double_t photonStatFactor;
202  if (usePhotonStatistic)
203  {
204  Double_t crystalPhotonsMeV = 1.0e3 * energy * pePerMeV;
205  photonStatFactor = gRandom->Gaus(1,sqrt(excessNoiseFactor/crystalPhotonsMeV));
206  }
207  else
208  {
209  photonStatFactor=1.;
210  }
211 
212  amplitude = energy*photonStatFactor;
213 
214  Double_t local_time(0.);
215  Double_t time_offset=firstADCBinTime;//nano seconds
216 
217  Double_t sumCharge(0.);
218  Double_t sumChargeErr(0.);
219 
220  for (Int_t i=0;i<fWaveformLength;i++)
221  {
222  local_time = i/sampleRate;//seconds
223  fSignal[i]+=(pulseshape->value(local_time,amplitude,time_offset));
224  sumCharge += fSignal[i];
225  sumChargeErr += sqrt(fabs(fSignal[i]));
226  }
227  Double_t Coff = EnergyError*sumCharge/sumChargeErr;
228  for(Int_t i=0;i<fWaveformLength;++i){
229  fSignalError[i] = fSignal[i]*Coff;
230  }
231 
232 }
233 
234 
235  void
237 {
238 
239  for (int i=0;i<fWaveformLength;i++)
240  {
241  Double_t ran_noise;
242  ran_noise=gRandom->Gaus(0,1)*width;
243  fSignal[i]+=ran_noise;
244  }
245 }
246 
247 
248  void
250 {
251  for ( int i=0;i<fWaveformLength;i++)
252  {
253  fSignal[i]=(Double_t) ( long (fSignal[i]/oneBitResolution+64)-64 ) * oneBitResolution;
254  }
255 }
256 
257 
258  void
260  Double_t oneBitResolution, Double_t EnergyError)
261 {
262  // Do both e_noise and digitisation.
263 
264  for ( int i=0;i<fWaveformLength;i++)
265  {
266  Double_t ran_noise=gRandom->Gaus(0,1)*noise_width;
267  fSignal[i]+=ran_noise;
268  if (fSignal[i]<0) fSignal[i]=0;
269  fSignal[i]=(Double_t) ( long (fSignal[i]/oneBitResolution+64)-64 ) * oneBitResolution;
270  }
271  Double_t sumCharge(0.);
272  Double_t sumChargeErr(0.);
273  for (Int_t i=0;i<fWaveformLength;i++)
274  {
275  sumCharge += fSignal[i];
276  sumChargeErr += sqrt(fSignal[i]);
277  }
278  Double_t Coff = EnergyError*sumCharge/sumChargeErr;
279  for(Int_t i=0;i<fWaveformLength;++i){
280  fSignalError[i] = fSignal[i]*Coff;
281  }
282  //calculate baseline
283  static Int_t baseline_length =100;
284  for(Int_t j=0;j<baseline_length;++j){
285  fBaselineValue += gRandom->Gaus(0,1)*noise_width;
286  }
287  fBaselineValue/=baseline_length;
288 }
289 
290  void
292  Double_t , PndEmcAbsPulseshape *pulseshape, Double_t firstADCBinTime, Double_t sampleRate, Double_t EnergyError ) // oneBitResolution //[R.K.03/2017] unused variable(s)
293 {
294  // Do both e_noise and digitisation.
295  Double_t t;
296  for ( int i=0;i<fWaveformLength;i++)
297  {
298  t = i/sampleRate;
299  Double_t ran_noise=gRandom->Gaus(0,1)*noise_width;
300  fSignal[i] += pulseshape->value(t,ran_noise,firstADCBinTime);
301  }
302  Double_t sumCharge(0.);
303  Double_t sumChargeErr(0.);
304  for (Int_t i=0;i<fWaveformLength;i++)
305  {
306  sumCharge += fSignal[i];
307  sumChargeErr += sqrt(fSignal[i]);
308  }
309  Double_t Coff = EnergyError*sumCharge/sumChargeErr;
310  for(Int_t i=0;i<fWaveformLength;++i){
311  fSignalError[i] = fSignal[i]*Coff;
312  }
313  //calculate baseline
314  static Int_t baseline_length =100;
315  for(Int_t j=0;j<baseline_length;++j){
316  t = j/sampleRate;
317  Double_t ran_noise=gRandom->Gaus(0,1)*noise_width;
318  fBaselineValue += pulseshape->value(t,ran_noise,firstADCBinTime);
319  }
320  fBaselineValue/=baseline_length;
321 
322 }
323 
324  Double_t
326 {
327  Double_t _max;
328  _max=*max_element(fSignal.begin(),fSignal.end());
329  return _max;
330 }
331 
332 
333 void
335  // reset values of fSignal to 0
336  fill(fSignal.begin(),fSignal.end(),0);
337 }
338 
340 {
342  PndEmcTwoCoordIndex* tci=emcMap->GetTCI(fDetectorId);
343  return tci;
344 }
345 bool PndEmcWaveform::operator == (const PndEmcWaveform& otherWave) const
346 {
347  if(fDetectorId != otherWave.fDetectorId) return false;
348  return true;
349 }
350 bool PndEmcWaveform::operator < (const PndEmcWaveform& otherWave) const
351 {
352  Double_t overlapped_time = 0.;
353  if(GetModule() == 3) overlapped_time = PndEmcWaveform::ForwardOverlapTime;
354  else if(GetModule() == 5) overlapped_time = PndEmcWaveform::ShashylikOverlapTime;
355  else overlapped_time = PndEmcWaveform::BarrelOverlapTime;
356 
357  if(GetDetectorId() < otherWave.GetDetectorId())
358  return true;
359  else if (GetDetectorId() == otherWave.GetDetectorId()){
360  if(GetTimeStamp() < otherWave.GetTimeStamp())
361  return otherWave.GetTimeStamp() > GetActiveTime() - overlapped_time;
362  else
363  return GetTimeStamp() > otherWave.GetActiveTime() - overlapped_time;
364  }else
365  return false;
366 
367 }
368 bool PndEmcWaveform::operator != (const PndEmcWaveform& otherWave) const
369 {
370  if(fDetectorId != otherWave.fDetectorId) return true;
371  return false;
372 }
373 bool PndEmcWaveform::equal(FairTimeStamp* data)
374 {
375  PndEmcWaveform* other = (PndEmcWaveform*)(data);
376  if(GetDetectorId() == other->GetDetectorId()) return true;
377  return false;
378 }
379 
381 {
382  if(GetTimeStamp()> otherWave.GetTimeStamp())// current wave earlier
383  {
384  std::cerr<<"Please make sure the eariler waveform += the later waveform"<<std::endl;
385  return *this;
386  }
387  //++ fPileupCount ;
388 
389  const std::vector<Int_t>& evtList = otherWave.GetEvtList();
390  for(size_t i=0; i< evtList.size();++i){
391  AddEvt(evtList[i]);
392  }
393 
394  Int_t k =0;
395  Int_t IDX = 0;
396  for(; (IDX < fWaveformLength) && (k < otherWave.fWaveformLength); ++ IDX){
397  if((GetTimeStamp() + IDX/fSampleRate*1.0e9) < otherWave.GetTimeStamp()){
398  continue;
399  }
400  fSignal[IDX] += otherWave.fSignal[k];
401  fSignalError[IDX] = sqrt(fSignalError[IDX]*fSignalError[IDX] + otherWave.fSignalError[k]*otherWave.fSignalError[k]);
402  ++k;
403  }
404  if(k < otherWave.fWaveformLength){
405  fWaveformLength += otherWave.fWaveformLength - k ;
406  for(; IDX < fWaveformLength; ++IDX, ++k){
407  fSignal.push_back(otherWave.fSignal[k]);
408  fSignalError.push_back(otherWave.fSignalError[k]);
409  }
410  }
411 
412  return *this;
413 }
414 
415 TGraphErrors* PndEmcWaveform::ToTGraph() const
416 {
417 
418  //free this object outside
419  TGraphErrors* g = new TGraphErrors(fSignal.size());
420  for(size_t i = 0; i< fSignal.size(); ++i){
421  g->SetPoint(i, GetTimeStamp()/1.e9 + Double_t(i)/fSampleRate, fSignal[i]);
422  g->SetPointError(i, 0, fSignalError[i]);
423  }
424  return g;
425 }
426 
427 void PndEmcWaveform::SetWaveform(std::vector<Double_t>&signal,Int_t length)
428 {
429  fSignal = signal;
430  fWaveformLength=length;
431 }
433  Double_t sum(0.);
434  for(size_t i=0;i<fSignal.size();++i)
435  sum += fSignal[i];
436  return sum;
437 }
438 
void SetWaveform(std::vector< Double_t > &signal, Int_t length)
virtual bool operator!=(const PndEmcWaveform &otherWave) const
Double_t Integral() const
Double_t GetActiveTime() const
static Double_t BarrelOverlapTime
void AddShapedElecNoiseAndDigitise(Double_t noise_width, Double_t oneBitResolution, PndEmcAbsPulseshape *pulseshape, Double_t firstADCBinTime, Double_t sampleRate, Double_t=0)
PndEmcWaveform & operator+=(const PndEmcWaveform &otherWave)
static Double_t ShashylikOverlapTime
Int_t i
Definition: run_full.C:25
virtual bool operator==(const PndEmcWaveform &otherWave) const
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:29
TFile * g
virtual ~PndEmcWaveform()
stores crystal index coordinates (x,y) or (theta,phi)
PndEmcTwoCoordIndex * GetTCI(Int_t DetectorId)
Emc geometry mapper.
Definition: PndEmcMapper.h:22
virtual bool operator<(const PndEmcWaveform &otherWave) const
static Double_t ForwardOverlapTime
Double_t GetNormalisation(Double_t sampleRate, PndEmcAbsPulseshape *pulseshape) const
virtual double value(const double t, const double amp, const double toffset) const
Double_t GetScale(Double_t sampleRate, PndEmcAbsPulseshape *pulseshape) const
void AddElecNoise(Double_t)
Double_t fSampleRate
Double_t
PndEmcTwoCoordIndex * GetTCI() const
virtual Double_t GetEnergy() const
Definition: PndEmcHit.h:54
PndEmcMapper * emcMap
void Digitise(Double_t)
const std::vector< Int_t > & GetEvtList() const
void AddElecNoiseAndDigitise(Double_t, Double_t, Double_t=0)
void UpdateWaveform(PndEmcHit *hit, Double_t pePerMeV, Bool_t usePhotonStatistic, Double_t excessNoiseFactor, Double_t firstADCBinTime, Double_t sampleRate, PndEmcAbsPulseshape *pulseshape, Double_t=0)
TF1 * fSignal
virtual void SetEnergy(Double32_t energy)
Definition: PndEmcHit.h:50
friend F32vec4 fabs(const F32vec4 &a)
Definition: P4_F32vec4.h:47
std::vector< Double_t > fSignal
long GetDetectorId() const
represents a simulated waveform in an emc crystal
virtual bool equal(FairTimeStamp *data)
represents the deposited energy of one emc crystal from simulation
Definition: PndEmcHit.h:26
virtual void clearAndReset()
pulseshape interface
ClassImp(PndAnaContFact)
void AddEvt(Int_t evtNo)
Short_t GetModule() const
TTree * t
Definition: bump_analys.C:13
Double_t fBaselineValue
PndSdsMCPoint * hit
Definition: anasim.C:70
std::vector< Int_t > fEvt
std::vector< Double_t > fSignalError
virtual void SetTime(Double32_t time)
Definition: PndEmcHit.h:51
static PndEmcMapper * Instance()
void MakeWaveform(Double_t energy, Double_t time, Double_t pePerMeV, Bool_t usePhotonStatistic, Double_t excessNoiseFactor, Double_t firstADCBinTime, Double_t sampleRate, PndEmcAbsPulseshape *pulseshape, Double_t=0)
TGraphErrors * ToTGraph() const
Double_t energy
Definition: plot_dirc.C:15