Project
Loading...
Searching...
No Matches
LZEROElectronics.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
12#include <unordered_map>
13#include <vector>
14#include <list>
15#include <deque>
16#include <iostream>
17#include <gsl/span>
23#include "TMath.h"
24#include <fairlogger/Logger.h> // for LOG
25
26using namespace o2::emcal;
27
28//_____________________________________________________________________
29// Peak finding algorithm
30//
31// It checks if there is a rising trend on four consecutive Timebins
32// If yes, then it compares the integral to a programmable threshold
34{
35 auto& CurrentPatchTimeSum = p.mTimesum[patchID];
36 auto& TimeSums = std::get<1>(CurrentPatchTimeSum);
37 bool trendOfDigitsInTower = false;
38 if (TimeSums.size() < 4) {
39 return false;
40 // } else if (TimeSums[0] < TimeSums[1] && TimeSums[1] < TimeSums[2] && TimeSums[2] >= TimeSums[3]) {
41 } else if (TimeSums[3] < TimeSums[2] && TimeSums[2] < TimeSums[1] && TimeSums[1] >= TimeSums[0]) {
42 trendOfDigitsInTower = true;
43 } else if (TimeSums[0] > 0. || TimeSums[1] > 0. || TimeSums[2] > 0. || TimeSums[3] > 0.) {
44 }
45 double integralOfADCvalues = 0;
46 for (auto it = TimeSums.begin(); it != TimeSums.end(); it++) {
47 integralOfADCvalues += *it;
48 }
49 bool peakOverThreshold = false;
50 if (integralOfADCvalues > mThreshold && trendOfDigitsInTower) {
51 peakOverThreshold = true;
52 }
53 return peakOverThreshold;
54}
55//_____________________________________________________________________
56// Peak finding algorithm on all patches
57// It fills the mPeakFound vector with potential 1s
59{
60 bool isFoundGlobal = false;
61 p.mFiredPatches.clear();
62 for (auto& patches : p.mIndexMapPatch) {
63 auto PatchID = std::get<0>(patches);
64 auto isFound = peakFinderOnPatch(p, PatchID);
65 if (isFound) {
66 p.mFiredPatches.push_back(PatchID);
67 isFoundGlobal = true;
68 }
69 }
70 return isFoundGlobal;
71}
72//________________________________________________________
74{
75 auto mSimParam = &(o2::emcal::SimParam::Instance());
76 mSimulateNoiseDigits = mSimParam->doSimulateNoiseDigits();
77 setThreshold(mSimParam->getThresholdLZERO());
78 // setThreshold(132.);
79}
80//________________________________________________________
84//________________________________________________________
86{
87 p.updateADC();
88}
89//_______________________________________________________________________
91{
92 auto mSimParam = &(o2::emcal::SimParam::Instance());
93 double amplitude = d1.getAmplitude();
94 double sigma = mSimParam->getPinNoiseTRU();
95
96 TRandom3 mRandomGenerator(std::chrono::high_resolution_clock::now().time_since_epoch().count());
97 uint16_t noise = std::floor(std::abs(mRandomGenerator.Gaus(0, sigma) / constants::EMCAL_TRU_ADCENERGY)); // ADC
98
99 Digit d(d1.getTower(), 0., noise, d1.getTimeStamp());
100
101 d1 += d;
102}
103//_______________________________________________________________________
104void LZEROElectronics::fill(const std::deque<o2::emcal::DigitTimebinTRU>& digitlist, const o2::InteractionRecord record, std::vector<TRUElectronics>& patchesFromAllTRUs)
105{
106 int counterDigitTimeBin = 0;
107 int sizemDigitMap = -999;
108 TriggerMappingV2 mTriggerMap(mGeometry);
109
110 for (auto& digitsTimeBin : digitlist) {
111 // Inside the DigitTimebinTRU
112 // Fill the LZEROElectronics with the new ADC value
113 // At the end of the loop run the peak finder
114 // Ship to LONEElectronics in case a peak is found
115 // Entire logic limited to timebin by timebin -> effectively implementing time scan
116 counterDigitTimeBin++;
117
118 for (auto& [fastor, digitsList] : *digitsTimeBin.mDigitMap) {
119 // Digit loop
120 // The peak finding algorithm is run after getting out of the loop!
121 if (digitsList.size() == 0) {
122 continue;
123 }
124 digitsList.sort();
125
126 int digIndex = 0;
127 Digit summedDigit;
128 bool first = true;
129 for (auto& ld : digitsList) {
130 if (first) {
131 summedDigit = ld;
132 first = false;
133 } else {
134 // summedDigit += ld;
135
136 // safety device in case same fastOr
137 // but different towers, i.e. remember
138 // that the += operator fails WITHOUT
139 // feedback if that were to happen
140 Digit digitToSum(summedDigit.getTower(), ld.getAmplitude(), summedDigit.getTimeStamp());
141 summedDigit += digitToSum;
142 }
143 }
144
145 sizemDigitMap = (*digitsTimeBin.mDigitMap).size();
146 if (mSimulateNoiseDigits) {
147 addNoiseDigits(summedDigit);
148 }
149
150 auto [whichTRU, whichFastOrTRU] = mTriggerMap.getTRUFromAbsFastORIndex(fastor);
151
152 auto whichFastOr = std::get<1>(mTriggerMap.convertFastORIndexTRUtoSTU(whichTRU, whichFastOrTRU));
153 auto& patchTRU = patchesFromAllTRUs[whichTRU];
154 auto& fastOrPatchTRU = patchTRU.mFastOrs[whichFastOr];
155 // fastOrPatchTRU.updateADC(summedDigit.getAmplitudeADC());
156 if (std::find(mMaskedFastOrs.begin(), mMaskedFastOrs.end(), fastor) != mMaskedFastOrs.end()) {
157 fastOrPatchTRU.updateADC(summedDigit.getAmplitudeADC());
158 }
159
160 digIndex++;
161 }
162
163 // Evaluate -> peak finder (ALL TRUElectronics in ALL TRUs)
164 // in case peak found:
165 // - Create trigger input (IR of that timebin - delay [typically 8 or 9 samples - rollback (0)])
166 // - Create L1 timesums (trivial - last time integral) -> Collect from all fastOrs in ALL TRUs
167
168 // Trigger Inputs needs to have the correction of the delay
169 // Propagating for now all the interaction record
170 // The typical delay is 8 to 9 BCs and the rollback as well
171 // The rollback is taken from EMCALReconstruction/RecoParam.h
172 // The delay is due to the interactions between EMCAL and CTP
173 // It accounts for the difference in times between L0a, L0b, and then there will be a L1 and L1b delay
174 // There is 1BC uncertainty on the trigger readout due to steps in the interaction between CTP and detector simulations
175 bool foundPeak = false;
176 int counterWhichTRU = 0;
177 int triggeredTRU = -1;
178 std::vector<int> triggeredPatches;
179 for (auto& patches : patchesFromAllTRUs) {
180 updatePatchesADC(patches);
181 bool foundPeakCurrentTRU = peakFinderOnAllPatches(patches);
182 auto firedPatches = getFiredPatches(patches);
183 if (foundPeakCurrentTRU == true && foundPeak == false) {
184 triggeredTRU = counterWhichTRU;
185 triggeredPatches = firedPatches;
186 }
187 if (foundPeakCurrentTRU) {
188 foundPeak = true;
189 }
190 counterWhichTRU += 1;
191 }
192
193 if (foundPeak == true) {
194 LOG(debug) << "DIG TRU fill in LZEROElectronics: foundPeak = " << foundPeak;
195 }
196 EMCALTriggerInputs TriggerInputsForL1;
197 if (foundPeak) {
198 TriggerInputsForL1.mInterRecord = record;
199 TriggerInputsForL1.mTriggeredTRU = triggeredTRU;
200 TriggerInputsForL1.mTriggeredPatches = triggeredPatches;
201 int whichTRU = 0;
202 for (auto& patches : patchesFromAllTRUs) {
203 int whichFastOr = 0;
204 for (auto& fastor : patches.mFastOrs) {
205 TriggerInputsForL1.mLastTimesumAllFastOrs.push_back(std::make_tuple(whichTRU, std::get<1>(mTriggerMap.convertFastORIndexSTUtoTRU(mTriggerMap.convertTRUIndexTRUtoSTU(whichTRU), whichFastOr, o2::emcal::TriggerMappingV2::DetType_t::DET_EMCAL)), fastor.timesum()));
206 whichFastOr++;
207 }
208 whichTRU++;
209 }
210 }
211
212 // EMCALTriggerInputsPatch TriggerInputsPatch;
213 // if (foundPeak) {
214 // TriggerInputsPatch.mInterRecord = record;
215 // int whichTRU = 0;
216 // for (auto& patches : patchesFromAllTRUs) {
217 // if(whichTRU < 46){
218 // int whichPatch = 0;
219 // bool firedpatch = false;
220 // if(std::find(patches.mFiredPatches.begin(), patches.mFiredPatches.end(), whichPatch) != patches.mFiredPatches.end()){
221 // firedpatch = true;
222 // }
223 // for (auto& patchTimeSums : patches.mTimesum) {
224 // auto& CurrentPatchTimesum = std::get<1>(patchTimeSums);
225 // // if( whichTRU == 30 || whichTRU == 31 || whichTRU == 44 || whichTRU == 45 ){
226 // // if( whichPatch > 68) continue;
227 // // }
228 // TriggerInputsPatch.mLastTimesumAllPatches.push_back(std::make_tuple(whichTRU, whichPatch, CurrentPatchTimesum[3], firedpatch ));
229 // whichPatch++;
230 // }
231 // }
232 // whichTRU++;
233 // }
234 // }
235
236 if (foundPeak) {
237 mTriggers.push_back(TriggerInputsForL1);
238 // mTriggersPatch.push_back(TriggerInputsPatch);
239 }
240 }
241}
242//________________________________________________________
244{
245 LOG(info) << "===============================";
246 LOG(info) << "== PRINT MASK SAVED IN LZERO ==";
247 int counter = 0;
248 for (auto fastOr : mMaskedFastOrs) {
249 LOG(info) << "fastOr masked (number, ID) = (" << counter << ", " << fastOr;
250 counter += 1;
251 }
252}
EMCAL DigitTimebin for the DigitsWriteoutBuffer and DigitsWriteoutBufferTRU.
std::ostringstream debug
unsigned short int uint16_t
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
EMCAL digit implementation.
Definition Digit.h:34
Short_t getTower() const
Definition Digit.h:59
Int_t getAmplitudeADC(ChannelType_t ctype) const
Definition Digit.cxx:66
void fill(const std::deque< o2::emcal::DigitTimebinTRU > &digitlist, const o2::InteractionRecord record, std::vector< TRUElectronics > &patchesFromAllTRUs)
bool peakFinderOnPatch(TRUElectronics &p, unsigned int patchID)
const std::vector< int > & getFiredPatches(TRUElectronics const &p) const
void addNoiseDigits(Digit &d1)
Add noise to this digit.
bool peakFinderOnAllPatches(TRUElectronics &p)
void init()
Initialize the L0 electronics.
void updatePatchesADC(TRUElectronics &p)
void clear()
clear the L0 electronics
void setThreshold(double threshold)
Trigger mapping starting from Run2.
IndexTRU convertTRUIndexTRUtoSTU(IndexTRU truIndexTRU) const
std::tuple< IndexTRU, IndexFastOR > convertFastORIndexTRUtoSTU(IndexTRU truIndexTRU, IndexFastOR fastorIndexTRU) const
Convert TRU and FastOR index in TRU from TRU number scheme to STU number scheme.
std::tuple< IndexTRU, IndexFastOR > convertFastORIndexSTUtoTRU(IndexTRU truIndexSTU, IndexFastOR fastOrIndexSTU, DetType_t detector) const
Convert TRU and FastOR index in TRU from STU number scheme to TRU number scheme.
std::tuple< IndexTRU, IndexFastOR > getTRUFromAbsFastORIndex(IndexFastOR fastOrAbsID) const
Get the TRU index and FastOR index in TRU from the absolute FastOR ID.
GLint GLsizei count
Definition glcorearb.h:399
GLsizeiptr size
Definition glcorearb.h:659
GLint first
Definition glcorearb.h:399
Trigger Inputs object, summary of the entire information needed for the L1 algorithm.
std::vector< int > mTriggeredPatches
Trigger patches, in local STU indexing.
std::vector< std::tuple< int, int, double > > mLastTimesumAllFastOrs
TRU ID, FastOrID with STU indexing, and its last Timesum.
o2::InteractionRecord mInterRecord
Last known interaction record.
TRUElectronics creator, based on the TRUElectronics.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"