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 continue;
146 }
147 d.addLabel(label);
148 iLabel++;
149 }
150 listofLabeledDigit.push_back(d);
151 }
152 mDigits.addDigits(tower, listofLabeledDigit);
153 }
154}
155
156//_______________________________________________________________________
158{
159 mTempDigitVector.clear();
160 Int_t tower = sDigit.getTower();
161 Double_t energy = sDigit.getAmplitude();
162
163 if (mSmearEnergy) {
164 energy = smearEnergy(energy);
165 }
166
167 if (energy < __DBL_EPSILON__) {
168 return;
169 }
170
171 // check if this hit because it comes from an event before readout starts and it does not effect this RO
172 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;
173 if (mIsBeforeFirstRO && sDigit.getTimeStamp() + mTimeBCns < 0) {
174 LOG(debug) << "disregard this hit because it comes from an event before readout starts and it does not effect this RO";
175 return;
176 }
177
178 Double_t energies[15];
179 if (mSimulateTimeResponse) {
180 if (sDigit.getTimeStamp() + mSimParam->getSignalDelay() + mPhase * 25 > EMC_TOF_MAX) {
181 // Digit time larger than sampling window, will not be sampled
182 // For time response simulation take also signal delay and phase into account
183 return;
184 }
185 int tofbin = static_cast<int>(sDigit.getTimeStamp() / EMC_TOF_BINWITH);
186 if (tofbin >= EMC_TOF_BINS) {
187 tofbin = EMC_TOF_BINS - 1;
188 }
189 for (int sample = 0; sample < mAmplitudeInTimeBins[mPhase][tofbin].size(); sample++) {
190
191 double val = energy * (mAmplitudeInTimeBins[mPhase][tofbin][sample]);
192 energies[sample] = val;
193 double digitTime = mEventTimeOffset * constants::EMCAL_TIMESAMPLE;
194 Digit digit(tower, val, digitTime);
195 mTempDigitVector.push_back(digit);
196 }
197 } else {
198 if (sDigit.getTimeStamp() > EMC_TOF_MAX) {
199 // Digit time larger than sampling window, will not be sampled
200 // In non-sampled mode only apply the max. time window
201 return;
202 }
203 Digit digit(tower, energy, smearTime(sDigit.getTimeStamp(), energy));
204 mTempDigitVector.push_back(digit);
205 }
206
207 if (mEnableDebugStreaming) {
208 double timeStamp = sDigit.getTimeStamp();
209 (*mDebugStream).GetFile()->cd();
210 (*mDebugStream) << "DigitsTimeSamples"
211 << "Tower=" << tower
212 << "Time=" << timeStamp
213 << "DigitEnergy=" << energy
214 << "Sample0=" << energies[0]
215 << "Sample1=" << energies[1]
216 << "Sample2=" << energies[2]
217 << "Sample3=" << energies[3]
218 << "Sample4=" << energies[4]
219 << "Sample5=" << energies[5]
220 << "Sample6=" << energies[6]
221 << "Sample7=" << energies[7]
222 << "Sample8=" << energies[8]
223 << "Sample9=" << energies[9]
224 << "Sample10=" << energies[10]
225 << "Sample11=" << energies[11]
226 << "Sample12=" << energies[12]
227 << "Sample13=" << energies[13]
228 << "Sample14=" << energies[14]
229 << "\n";
230 }
231}
232
233//_______________________________________________________________________
234double Digitizer::smearEnergy(double energy)
235{
236 Double_t fluct = (energy * mSimParam->getMeanPhotonElectron()) / mSimParam->getGainFluctuations();
237 energy *= mRandomGenerator->Poisson(fluct) / fluct;
238 return energy;
239}
240
241double Digitizer::smearTime(double time, double energy)
242{
243 return mRandomGenerator->Gaus(time + mSimParam->getSignalDelay(), mSimParam->getTimeResolution(energy));
244}
245
246//_______________________________________________________________________
248{
249
250 mDigits.forwardMarker(record, trigger);
251
252 mPhase = mSimParam->doSimulateL1Phase() ? mDigits.getPhase() : 0;
253
254 mEventTimeOffset = 0;
255
256 if (mPhase == 4) {
257 mPhase = 0;
258 mEventTimeOffset++;
259 }
260
261 // get time difference between current bc and start of RO in ns
262 auto nbc = record.differenceInBC(mIRFirstSampledTF);
263 mTimeBCns = record.getTimeOffsetWrtBC();
264 mTimeBCns += nbc * o2::constants::lhc::LHCBunchSpacingNS;
265
266 if (nbc < 0) {
267 // this event is before the first RO
268 mIsBeforeFirstRO = true;
269 } else {
270 mIsBeforeFirstRO = false;
271 }
272}
ClassImp(o2::emcal::Digitizer)
uint64_t phase
Definition RawEventData.h:7
int16_t time
Definition RawEventData.h:4
std::ostringstream debug
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"