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}
ClassImp(o2::emcal::Digitizer)
std::ostringstream debug
uint64_t phase
Definition RawEventData.h:7
int16_t time
Definition RawEventData.h:4
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events d
std::vector< o2::MCCompLabel > labels
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.
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
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"