Project
Loading...
Searching...
No Matches
Digitizer.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
16#include "EMCALBase/Hit.h"
17#include "MathUtils/Cartesian.h"
20#include <climits>
21#include <forward_list>
22#include <chrono>
23#include <TRandom.h>
24#include <TF1.h>
25#include <fairlogger/Logger.h> // for LOG
31
33
35using o2::emcal::Hit;
36
37using namespace o2::emcal;
38
39//_______________________________________________________________________
41{
42 mSimParam = &(o2::emcal::SimParam::Instance());
43 auto randomSeed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
44 if (o2::conf::DigiParams::Instance().seed != 0) {
46 }
47 mRandomGenerator = new TRandom3(randomSeed);
48
49 float tau = mSimParam->getTimeResponseTau();
50 float N = mSimParam->getTimeResponsePower();
51
52 mSmearEnergy = mSimParam->doSmearEnergy();
53 mSimulateTimeResponse = mSimParam->doSimulateTimeResponse();
54
55 mDigits.init();
56 mDigits.reserve();
57 /*
58 if ((mDelay - mTimeWindowStart) != 0)
59 {
60 mDigits.setBufferSize(mDigits.getBufferSize() + (mDelay - mTimeWindowStart));
61 mDigits.reserve();
62 }
63 */
64
65 if (mSimulateTimeResponse) {
66 // for each phase create a template distribution
67 TF1 RawResponse("RawResponse", rawResponseFunction, 0, 256, 5);
68 RawResponse.SetParameters(1., 0., tau, N, 0.);
69
70 for (int phase = 0; phase < 4; phase++) {
71 // parameter 1: Handling phase + delay
72 // phase: 25 ns * phase index (-4)
73 // delay: Average signal delay
74 for (int itofbin = 0; itofbin < EMC_TOF_BINS; itofbin++) {
75 double tofbincenter = itofbin * EMC_TOF_BINWITH + 0.5 * EMC_TOF_BINWITH;
76 RawResponse.SetParameter(1, 0.25 * phase + (tofbincenter + mSimParam->getSignalDelay()) / constants::EMCAL_TIMESAMPLE);
77 for (int sample = 0; sample < constants::EMCAL_MAXTIMEBINS; sample++) {
78 mAmplitudeInTimeBins[phase][itofbin][sample] = RawResponse.Eval(sample);
79 }
80 }
81 }
82 } else {
83 }
84
86
87 if (mEnableDebugStreaming) {
88 mDebugStream = std::make_unique<o2::utils::TreeStreamRedirector>("emcaldigitsDebug.root", "RECREATE");
89 }
90}
91
92//_______________________________________________________________________
93double Digitizer::rawResponseFunction(double* x, double* par)
94{
95 double signal = 0.;
96 double tau = par[2];
97 double n = par[3];
98 double ped = par[4];
99 double xx = (x[0] - par[1] + tau) / tau;
100
101 // par[0] amp, par[1] peak time
102
103 if (xx <= 0) {
104 signal = ped;
105 } else {
106 signal = ped + par[0] * std::pow(xx, n) * std::exp(n * (1 - xx));
107 }
108
109 return signal;
110}
111
112//_______________________________________________________________________
114{
115 mDigits.clear();
116}
117
118//_______________________________________________________________________
119void Digitizer::process(const std::vector<LabeledDigit>& labeledSDigits)
120{
121
122 for (auto labeleddigit : labeledSDigits) {
123
124 int tower = labeleddigit.getTower();
125
126 sampleSDigit(labeleddigit.getDigit());
127
128 if (mTempDigitVector.size() == 0) {
129 continue;
130 }
131
132 std::vector<LabeledDigit> listofLabeledDigit;
133
134 for (auto& digit : mTempDigitVector) {
135 Int_t id = digit.getTower();
136
137 auto labels = labeleddigit.getLabels();
138 LabeledDigit d(digit, labels[0]);
139 int iLabel(0);
140 for (auto& label : labels) {
141 if (digit.getAmplitude() < __DBL_EPSILON__) {
142 label.setAmplitudeFraction(0);
143 }
144 if (iLabel == 0) {
145 ++iLabel;
146 continue;
147 }
148 d.addLabel(label);
149 ++iLabel;
150 }
151 listofLabeledDigit.push_back(d);
152 }
153 mDigits.addDigits(tower, listofLabeledDigit);
154 }
155}
156
157//_______________________________________________________________________
159{
160 mTempDigitVector.clear();
161 Int_t tower = sDigit.getTower();
162 Double_t energy = sDigit.getAmplitude();
163
164 if (mSmearEnergy) {
165 energy = smearEnergy(energy);
166 }
167
168 if (energy < __DBL_EPSILON__) {
169 return;
170 }
171
172 // check if this hit because it comes from an event before readout starts and it does not effect this RO
173 LOG(debug) << "mIsBeforeFirstRO " << mIsBeforeFirstRO << " sDigit.getTimeStamp() " << sDigit.getTimeStamp() << " mSimParam->getSignalDelay() " << mSimParam->getSignalDelay() << " mPhase " << mPhase << " total: " << sDigit.getTimeStamp() + mSimParam->getSignalDelay() + mPhase * 25 << " EMC_TOF_MAX " << EMC_TOF_MAX << " mTimeBCns " << mTimeBCns;
174 if (mIsBeforeFirstRO && sDigit.getTimeStamp() + mTimeBCns < 0) {
175 LOG(debug) << "disregard this hit because it comes from an event before readout starts and it does not effect this RO";
176 return;
177 }
178
179 Double_t energies[15];
180 if (mSimulateTimeResponse) {
181 if (sDigit.getTimeStamp() + mSimParam->getSignalDelay() + mPhase * 25 > EMC_TOF_MAX) {
182 // Digit time larger than sampling window, will not be sampled
183 // For time response simulation take also signal delay and phase into account
184 return;
185 }
186 int tofbin = static_cast<int>(sDigit.getTimeStamp() / EMC_TOF_BINWITH);
187 if (tofbin >= EMC_TOF_BINS) {
188 tofbin = EMC_TOF_BINS - 1;
189 }
190 for (int sample = 0; sample < mAmplitudeInTimeBins[mPhase][tofbin].size(); sample++) {
191
192 double val = energy * (mAmplitudeInTimeBins[mPhase][tofbin][sample]);
193 energies[sample] = val;
194 double digitTime = mEventTimeOffset * constants::EMCAL_TIMESAMPLE;
195 Digit digit(tower, val, digitTime);
196 mTempDigitVector.push_back(digit);
197 }
198 } else {
199 if (sDigit.getTimeStamp() > EMC_TOF_MAX) {
200 // Digit time larger than sampling window, will not be sampled
201 // In non-sampled mode only apply the max. time window
202 return;
203 }
204 Digit digit(tower, energy, smearTime(sDigit.getTimeStamp(), energy));
205 mTempDigitVector.push_back(digit);
206 }
207
208 if (mEnableDebugStreaming) {
209 double timeStamp = sDigit.getTimeStamp();
210 (*mDebugStream).GetFile()->cd();
211 (*mDebugStream) << "DigitsTimeSamples"
212 << "Tower=" << tower
213 << "Time=" << timeStamp
214 << "DigitEnergy=" << energy
215 << "Sample0=" << energies[0]
216 << "Sample1=" << energies[1]
217 << "Sample2=" << energies[2]
218 << "Sample3=" << energies[3]
219 << "Sample4=" << energies[4]
220 << "Sample5=" << energies[5]
221 << "Sample6=" << energies[6]
222 << "Sample7=" << energies[7]
223 << "Sample8=" << energies[8]
224 << "Sample9=" << energies[9]
225 << "Sample10=" << energies[10]
226 << "Sample11=" << energies[11]
227 << "Sample12=" << energies[12]
228 << "Sample13=" << energies[13]
229 << "Sample14=" << energies[14]
230 << "\n";
231 }
232}
233
234//_______________________________________________________________________
235double Digitizer::smearEnergy(double energy)
236{
237 Double_t fluct = (energy * mSimParam->getMeanPhotonElectron()) / mSimParam->getGainFluctuations();
238 energy *= mRandomGenerator->Poisson(fluct) / fluct;
239 return energy;
240}
241
242double Digitizer::smearTime(double time, double energy)
243{
244 return mRandomGenerator->Gaus(time + mSimParam->getSignalDelay(), mSimParam->getTimeResolution(energy));
245}
246
247//_______________________________________________________________________
249{
250
251 mDigits.forwardMarker(record, trigger);
252
253 mPhase = mSimParam->doSimulateL1Phase() ? mDigits.getPhase() : 0;
254
255 mEventTimeOffset = 0;
256
257 if (mPhase == 4) {
258 mPhase = 0;
259 mEventTimeOffset++;
260 }
261
262 // get time difference between current bc and start of RO in ns
263 auto nbc = record.differenceInBC(mIRFirstSampledTF);
264 mTimeBCns = record.getTimeOffsetWrtBC();
265 mTimeBCns += nbc * o2::constants::lhc::LHCBunchSpacingNS;
266
267 if (nbc < 0) {
268 // this event is before the first RO
269 mIsBeforeFirstRO = true;
270 } else {
271 mIsBeforeFirstRO = false;
272 }
273}
std::vector< std::string > labels
ClassImp(o2::emcal::Digitizer)
std::ostringstream debug
uint64_t phase
Definition RawEventData.h:7
int16_t time
Definition RawEventData.h:4
EMCAL digit implementation.
Definition Digit.h:34
Short_t getTower() const
Definition Digit.h:59
Double_t getAmplitude() const
Definition Digit.cxx:101
EMCAL FEE digitizer.
Definition Digitizer.h:51
static double rawResponseFunction(double *x, double *par)
raw pointers used here to allow interface with TF1
Definition Digitizer.cxx:93
void setEventTime(o2::InteractionTimeRecord record, bool trigger)
void process(const std::vector< LabeledDigit > &labeledDigit)
Steer conversion of hits to digits.
double smearTime(double time, double energy)
void sampleSDigit(const Digit &sdigit)
double smearEnergy(double energy)
void reserve()
Reserve space for the future container.
void forwardMarker(o2::InteractionTimeRecord record, bool trigger)
forward the marker for every 100 ns
void addDigits(unsigned int towerID, std::vector< LabeledDigit > &digList)
EMCAL simulation hit information.
Definition Hit.h:28
EMCAL labeled digit implementation.
void addLabel(o2::emcal::MCLabel l)
Float_t getSignalDelay() const
Definition SimParam.h:61
Float_t getTimeResponseTau() const
Definition SimParam.h:42
Bool_t doSimulateL1Phase() const
Definition SimParam.h:71
Double_t getTimeResolution(Double_t energy) const
Definition SimParam.cxx:58
Float_t getGainFluctuations() const
Definition SimParam.h:41
Bool_t doSmearEnergy() const
Definition SimParam.h:67
Float_t getTimeResponsePower() const
Definition SimParam.h:43
Bool_t doSimulateTimeResponse() const
Definition SimParam.h:68
Int_t getMeanPhotonElectron() const
Definition SimParam.h:40
GLdouble n
Definition glcorearb.h:1982
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
GLuint GLfloat * val
Definition glcorearb.h:1582
constexpr double LHCBunchSpacingNS
int64_t differenceInBC(const InteractionRecord &other) const
IR getFirstSampledTFIR() const
get TF and HB (abs) for this IR
Definition HBFUtils.h:74
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"