21#include <forward_list>
25#include <fairlogger/Logger.h>
43 auto randomSeed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
47 mRandomGenerator =
new TRandom3(randomSeed);
65 if (mSimulateTimeResponse) {
68 RawResponse.SetParameters(1., 0., tau, N, 0.);
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);
87 if (mEnableDebugStreaming) {
88 mDebugStream = std::make_unique<o2::utils::TreeStreamRedirector>(
"emcaldigitsDebug.root",
"RECREATE");
99 double xx = (
x[0] - par[1] + tau) / tau;
106 signal = ped + par[0] * std::pow(xx,
n) * std::exp(
n * (1 - xx));
122 for (
auto labeleddigit : labeledSDigits) {
124 int tower = labeleddigit.getTower();
128 if (mTempDigitVector.size() == 0) {
132 std::vector<LabeledDigit> listofLabeledDigit;
134 for (
auto& digit : mTempDigitVector) {
135 Int_t
id = digit.getTower();
137 auto labels = labeleddigit.getLabels();
140 for (
auto&
label : labels) {
141 if (digit.getAmplitude() < __DBL_EPSILON__) {
142 label.setAmplitudeFraction(0);
150 listofLabeledDigit.push_back(d);
152 mDigits.
addDigits(tower, listofLabeledDigit);
159 mTempDigitVector.clear();
167 if (energy < __DBL_EPSILON__) {
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";
178 Double_t energies[15];
179 if (mSimulateTimeResponse) {
180 if (sDigit.getTimeStamp() + mSimParam->
getSignalDelay() + mPhase * 25 > EMC_TOF_MAX) {
185 int tofbin =
static_cast<int>(sDigit.getTimeStamp() / EMC_TOF_BINWITH);
186 if (tofbin >= EMC_TOF_BINS) {
187 tofbin = EMC_TOF_BINS - 1;
189 for (
int sample = 0; sample < mAmplitudeInTimeBins[mPhase][tofbin].size(); sample++) {
191 double val = energy * (mAmplitudeInTimeBins[mPhase][tofbin][sample]);
192 energies[sample] =
val;
193 double digitTime = mEventTimeOffset * constants::EMCAL_TIMESAMPLE;
195 mTempDigitVector.push_back(digit);
198 if (sDigit.getTimeStamp() > EMC_TOF_MAX) {
203 Digit digit(tower, energy,
smearTime(sDigit.getTimeStamp(), energy));
204 mTempDigitVector.push_back(digit);
207 if (mEnableDebugStreaming) {
208 double timeStamp = sDigit.getTimeStamp();
209 (*mDebugStream).GetFile()->cd();
210 (*mDebugStream) <<
"DigitsTimeSamples"
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]
237 energy *= mRandomGenerator->Poisson(fluct) / fluct;
254 mEventTimeOffset = 0;
268 mIsBeforeFirstRO =
true;
270 mIsBeforeFirstRO =
false;
ClassImp(o2::emcal::Digitizer)
static const SimParam & Instance()
EMCAL digit implementation.
Double_t getAmplitude() const
static double rawResponseFunction(double *x, double *par)
raw pointers used here to allow interface with TF1
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)
unsigned int getPhase() const
void clear()
clear the container
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.
EMCAL labeled digit implementation.
void addLabel(o2::emcal::MCLabel l)
Float_t getSignalDelay() const
Float_t getTimeResponseTau() const
Bool_t doSimulateL1Phase() const
Double_t getTimeResolution(Double_t energy) const
Float_t getGainFluctuations() const
Bool_t doSmearEnergy() const
Float_t getTimeResponsePower() const
Bool_t doSimulateTimeResponse() const
Int_t getMeanPhotonElectron() const
GLuint GLsizei const GLchar * label
constexpr double LHCBunchSpacingNS
int64_t differenceInBC(const InteractionRecord &other) const
double getTimeOffsetWrtBC() const
IR getFirstSampledTFIR() const
get TF and HB (abs) for this IR
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"