FairRoot/PandaRoot
PndEmcFullStackedWaveformSimulator.cxx
Go to the documentation of this file.
2 
3 #include "PndEmcWaveform.h"
4 #include "PndEmcWaveformData.h"
5 #include "PndEmcAbsPulseshape.h"
6 
7 #include "TClonesArray.h"
8 #include "TMath.h"
9 
10 #include "FairLink.h"
11 
12 #include <vector>
13 #include <map>
14 #include <iostream>
15 
16 using namespace std;
17 
18 PndEmcFullStackedWaveformSimulator::PndEmcFullStackedWaveformSimulator() : PndEmcAbsWaveformSimulator(0.), fSamplingBeforeFirstPulse(0), fSamplingAfterLastPulse(0), fCutoff(0), fPulseshape(NULL), fScale(0.), f1GeVWaveform(NULL), fPulseRiseTime(0), fActiveTimeIncrement(0)
19 {
20 }
21 
22 PndEmcFullStackedWaveformSimulator::PndEmcFullStackedWaveformSimulator(Double_t sampleRate, PndEmcAbsPulseshape* pulseshape) : PndEmcAbsWaveformSimulator(sampleRate), fSamplingBeforeFirstPulse(0), fSamplingAfterLastPulse(0), fCutoff(0), fPulseshape(pulseshape), fScale(0.), f1GeVWaveform(NULL), fPulseRiseTime(0), fActiveTimeIncrement(0)
23 {
24 }
25 
26 
28 {
29  delete f1GeVWaveform;
30 }
31 
41 void PndEmcFullStackedWaveformSimulator::Init(Double_t samplingBeforeFirstPulse, Double_t samplingAfterLastPulse, Double_t cutoff, Double_t activeTimeIncrement)
42 {
43  fSamplingBeforeFirstPulse = samplingBeforeFirstPulse;
44  fSamplingAfterLastPulse = samplingAfterLastPulse;
45  fCutoff = cutoff;
46  fActiveTimeIncrement = activeTimeIncrement;
47 
48  //generate signal with:
49  Double_t tmpSamlingRate = 1.0; // in ns^-1
50  Int_t tmpLength = 100; //in samples
51  Int_t emergencyStop = 10000000;
52 
53  std::vector<Double_t> tmpSignal;
54 
55  Bool_t maxFound = kFALSE;
56  Bool_t cutoffFound = kFALSE;
57 
58  Int_t maxSample;
59  Int_t cutoffSample;
60 
61  do {
62  tmpLength*=2;
63  tmpSignal.resize(tmpLength);
64  if(tmpLength>=emergencyStop) {
65  std::cout << "-E PndEmcFullStackedWaveformSimulator: no maximum in pulse during " << emergencyStop/tmpSamlingRate << " ns found. WaveformGeneration might fail." << std::endl;
66  break;
67  }
68 
69  for(Int_t iSample=0; iSample<tmpLength; iSample++) {
70  tmpSignal[iSample] = CalcSingleWaveForTime(iSample/tmpSamlingRate, 1.0, 0.);
71  }
72 
73 
74  if(!maxFound) { //search for maximum
75  std::vector<Double_t>::const_iterator begin_constIt = tmpSignal.begin();
76  std::vector<Double_t>::const_iterator end_constIt = tmpSignal.end();
77  std::vector<Double_t>::const_iterator max_constIt = std::max_element(begin_constIt, end_constIt);
78  maxSample = std::distance(begin_constIt, max_constIt);
79 
80  //generated pusle might be to short for proper maximum detection
81  maxFound = (maxSample < tmpLength-1) ? kTRUE : kFALSE;
82 
83  fScale = (*max_constIt);
84  fPulseRiseTime = maxSample * tmpSamlingRate;
85  }
86 
87  if(maxFound) { //search for cutOff
88  for(Int_t iSample=maxSample; iSample<tmpLength; iSample++) {
89  if(tmpSignal[iSample] < fCutoff*fScale) {
90  cutoffFound = kTRUE;
91  cutoffSample = iSample;
92  break;
93  }
94  }
95  }
96 
97  } while(!(maxFound && cutoffFound)); //maximum inside signal, i.e. signal covers tail (at least partially)
98 
99  //generate 1GeV signal again..now with correct sampling rate
100  Double_t totalTime = (cutoffSample/tmpSamlingRate + fSamplingBeforeFirstPulse + fSamplingAfterLastPulse);
101 
102  try{
103  std::vector<Double_t> signal((Int_t) TMath::Floor(totalTime*GetSampleRate() + 0.5), 0.);
104  } catch(...) {
105  std::cerr << "catched error" << std::endl;
106  std::cerr << "sampleRate:" << GetSampleRate() << std::endl;
107  std::cerr << "total Time:" << totalTime << std::endl;
108  abort();
109  }
110 
112 
113  std::cerr << "finishing init" << std::endl;
114 }
115 
116 
117 
127 {
128  const std::map<Double_t, Double_t>& hitMap = wfData->GetHitMap();
129  startTime = hitMap.begin()->first - fSamplingBeforeFirstPulse;
130 
131  activeTime = hitMap.rbegin()->first + fPulseRiseTime;
132  while (TMath::Abs(CalcWaveForTime(activeTime, wfData)) > fCutoff*fScale) {
133  activeTime += fActiveTimeIncrement;
134  }
135 
136  activeTime += fSamplingAfterLastPulse;
137 
138  SyncWithADCClock(startTime);
139  SyncWithADCClock(activeTime);
140 }
141 
153 {
154  return fPulseshape->value(absoluteTime, energy, pulseTime);
155 }
156 
165 {
166  Double_t returnValue = 0;
167 
168  for(std::map<Double_t, Double_t>::const_iterator it = wfData->GetHitMap().begin(); it!=wfData->GetHitMap().end(); ++it) {
169  Double_t energy = it->second;
170  Double_t pulseTime = it->first;
171 
172  returnValue += CalcSingleWaveForTime(absoluteTime, energy, pulseTime);
173  }
174  return returnValue;
175 }
176 
185 {
186  Int_t nSamples = static_cast<Int_t>((wfData->GetTimeOfLastSample()-wfData->GetTimeStamp())*GetSampleRate() + 0.5);
187  //cout << "TimeOfLastSample: " << wfData->GetTimeOfLastSample() << endl;
188  //cout << "Timestamp: " << wfData->GetTimeStamp() << endl;
189  //cout << "sampleRate: " << GetSampleRate() << endl;
190  //cout << "calculted " << nSamples << " samples" << endl;
191  std::vector<Double_t> signal(nSamples, 0.0);
192 
193  for(Int_t iSample=0; iSample<nSamples; ++iSample) {
194  signal[iSample] = CalcWaveForTime(wfData->GetTimeStamp() + iSample*1/GetSampleRate(), wfData);
195  }
196 
197  Int_t hitIndex = -1;
198  if(wfData->GetNLinks()) {
199  hitIndex = wfData->GetLink(0).GetIndex();
200  }
201 
202  PndEmcWaveform* wave;
203  if(arrayToStore) {
204  wave = new ((*arrayToStore)[arrayToStore->GetEntriesFast()]) PndEmcWaveform(-1, wfData->GetDetectorId(), signal, hitIndex);
205  wave->ResetLinks();
206  } else {
207  wave = new PndEmcWaveform(-1, wfData->GetDetectorId(), signal, hitIndex);
208  }
209  wave->SetLinks(wfData->GetLinksWithType(FairRootManager::Instance()->GetBranchId("EmcHit")));
210  wave->AddInterfaceData(wfData);
211 
212  Double_t timeStamp = wfData->GetTimeStamp();
213  wave->SetTimeStamp(timeStamp);
214  wave->SetSampleRate(fSampleRate*1.0e9); //converting form ns into s;
215 
216  return wave;
217 
218 }
219 
231 PndEmcWaveform* PndEmcFullStackedWaveformSimulator::MakeSingleWaveform(Double_t hitEnergy, Double_t hitTime, TClonesArray* arrayToStore, Int_t detId, Int_t trackId, Int_t hitIndex)
232 {
233  std::vector<Double_t> signal;
234 
235  Double_t startTime = hitTime - fSamplingBeforeFirstPulse;
236  SyncWithADCClock(startTime);
237 
238  Int_t nRising = (Int_t) ((fSamplingBeforeFirstPulse + fPulseRiseTime) * GetSampleRate());
239  Int_t iSample =0;
240 
241  for(;iSample<nRising; ++iSample) { //time before pulse + rising edge
242  signal.push_back(CalcSingleWaveForTime(startTime + iSample/GetSampleRate(), hitEnergy, hitTime));
243  }
244 
245  do { //falling edge..check weather pulse undergoes cutoff value
246  signal.push_back(CalcSingleWaveForTime(startTime + iSample/GetSampleRate(), hitEnergy, hitTime));
247  } while (signal[iSample++] > fCutoff*fScale);
248 
249  Int_t addSamples = (Int_t) (fSamplingAfterLastPulse*GetSampleRate());
250 
251  for(addSamples += iSample; iSample<addSamples; iSample++) {
252  signal.push_back(CalcSingleWaveForTime(startTime + iSample/GetSampleRate(), hitEnergy, hitTime));
253  }
254 
255  PndEmcWaveform* wave;
256  if(arrayToStore) {
257  wave = new ((*arrayToStore)[arrayToStore->GetEntriesFast()]) PndEmcWaveform(trackId, detId, signal, hitIndex);
258  } else {
259  wave = new PndEmcWaveform(trackId, detId, signal, hitIndex);
260  }
261 
262  Double_t timestamp = startTime;
263  wave->SetTimeStamp(timestamp);
264  wave->SetSampleRate(fSampleRate*1.0e9); //converting form ns into s;
265 
266  return wave;
267 }
virtual Double_t CalcWaveForTime(Double_t absoluteTime, PndEmcWaveformData *wfData)
Calculate pulse value at given time.
virtual PndEmcWaveform * MakeWaveform(PndEmcWaveformData *wfData, TClonesArray *arrayToStore=NULL)
Create PndEmcWaveform.
Double_t CalcSingleWaveForTime(Double_t absoluteTime, Double_t energy, Double_t pulseTime)
Return pulse at given time and for given energy.
const std::map< Double_t, Double_t > & GetHitMap()
Double_t fSampleRate
sampling rate of SADC. In 1/ns
static T Abs(const T &x)
Definition: PndCAMath.h:39
virtual double value(const double t, const double amp, const double toffset) const
Abstract base class for waveform simulator.
virtual void GetAbsoluteTimeInterval(PndEmcWaveformData *wfData, Double_t &startTime, Double_t &activeTime)
Get time interval for which the signal is above the cutoff.
Double_t
virtual void Init(Double_t samplingBeforeFirstPulse, Double_t samplingAfterLastPulse, Double_t cutoff, Double_t activeTimeIncrement)
Init the simulator.
represents a simulated waveform in an emc crystal
virtual PndEmcWaveform * MakeSingleWaveform(Double_t hitEnergy, Double_t hitTime, TClonesArray *arrayToStore=NULL, Int_t detId=-1, Int_t trackId=-1, Int_t hitIndex=-1)
Create a PndEmcWaveform from the given parameters of a single hit.
Double_t fPulseRiseTime
total rising time of pulse in ns
Double_t GetTimeOfLastSample()
pulseshape interface
Double_t fSamplingAfterLastPulse
in ns. additional time interval after waveform falls below cutOff value
represents a simulated waveform in an emc crystal, used by PndEmcFWEndcapTimebasedWaveforms ...
Double_t fSamplingBeforeFirstPulse
in ns. additional time interval before waveform starts
void SetSampleRate(Double_t rate)
Double_t energy
Definition: plot_dirc.C:15