Project
Loading...
Searching...
No Matches
Clusterer.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
14#include <algorithm>
15#include <fairlogger/Logger.h> // for LOG
20#include <TStopwatch.h>
21
22using namespace o2::tof;
23
24//__________________________________________________
25void Clusterer::process(DataReader& reader, std::vector<Cluster>& clusters, MCLabelContainer const* digitMCTruth)
26{
27 TStopwatch timerProcess;
28 timerProcess.Start();
29
30 reader.init();
31 int totNumDigits = 0;
32
33 while (reader.getNextStripData(mStripData)) {
34 LOG(debug) << "TOFClusterer got Strip " << mStripData.stripID << " with Ndigits "
35 << mStripData.digits.size();
36 totNumDigits += mStripData.digits.size();
37
38 calibrateStrip();
39 processStrip(clusters, digitMCTruth);
40 }
41
42 LOG(debug) << "We had " << totNumDigits << " digits in this event";
43 timerProcess.Stop();
44}
45
46//__________________________________________________
47void Clusterer::calibrateStrip()
48{
49 // method to calibrate the times from the current strip
50
51 for (int idig = 0; idig < mStripData.digits.size(); idig++) {
52 // LOG(debug) << "Checking digit " << idig;
53 Digit* dig = &mStripData.digits[idig];
54 // LOG(info) << "channel = " << dig->getChannel();
55 dig->setBC(dig->getBC() - mBCOffset); // RS Don't use raw BC, always start from the beginning of the TF
56 double calib = mCalibApi->getTimeCalibration(dig->getChannel(), dig->getTOT() * Geo::TOTBIN_NS);
57 bool isProbOrError = mAreCalibStored ? mCalibApi->isChannelError(dig->getChannel()) || mCalibApi->isNoisy(dig->getChannel()) : mCalibApi->isChannelError(dig->getChannel()) || mCalibApi->isNoisy(dig->getChannel()) || mCalibApi->isProblematic(dig->getChannel());
58 dig->setIsProblematic(isProbOrError);
59 dig->setCalibratedTime(dig->getTDC() * Geo::TDCBIN + dig->getBC() * o2::constants::lhc::LHCBunchSpacingNS * 1E3 - Geo::LATENCYWINDOW * 1E3 - calib); // TODO: to be checked that "-" is correct, and we did not need "+" instead :-)
60 }
61}
62
63//__________________________________________________
64void Clusterer::processStrip(std::vector<Cluster>& clusters, MCLabelContainer const* digitMCTruth)
65{
66 // method to clusterize the current strip
67
68 Int_t detId[5];
69 Int_t chan, chan2, chan3;
70 Int_t strip1, strip2;
71 Int_t iphi, iphi2, iphi3;
72 Int_t ieta, ieta2, ieta3; // it is the number of padz-row increasing along the various strips
73
74 for (int idig = 0; idig < mStripData.digits.size(); idig++) {
75 // LOG(debug) << "Checking digit " << idig;
76 Digit* dig = &mStripData.digits[idig];
77 //printf("checking digit %d - alreadyUsed=%d - problematic=%d\n",idig,dig->isUsedInCluster(),dig->isProblematic()); // toberem
78 if (dig->isUsedInCluster() || dig->isProblematic()) {
79 continue; // the digit was already used to build a cluster, or it was declared problematic
80 }
81
82 mNumberOfContributingDigits = 0;
83 dig->getPhiAndEtaIndex(iphi, ieta);
84 if (mStripData.digits.size() > 1) {
85 LOG(debug) << "idig = " << idig;
86 }
87
88 // first we make a cluster out of the digit
89 int noc = clusters.size();
90 // LOG(debug) << "noc = " << noc << "\n";
91 clusters.emplace_back();
92 Cluster& c = clusters[noc];
93 addContributingDigit(dig);
94 double timeDig = dig->getCalibratedTime();
95
96 for (int idigNext = idig + 1; idigNext < mStripData.digits.size(); idigNext++) {
97 Digit* digNext = &mStripData.digits[idigNext];
98 if (digNext->isUsedInCluster() || dig->isProblematic()) {
99 continue; // the digit was already used to build a cluster, or was problematic
100 }
101 // check if the TOF time are close enough to be merged; if not, it means that nothing else will contribute to the cluster (since digits are ordered in time)
102 double timeDigNext = digNext->getCalibratedTime(); // in ps
103 LOG(debug) << "Time difference = " << timeDigNext - timeDig;
104 if (timeDigNext - timeDig > mDeltaTforClustering /*in ps*/) { // to be change to 500 ps
105 break;
106 }
107 digNext->getPhiAndEtaIndex(iphi2, ieta2);
108
109 // check if the fired pad are close in space
110 LOG(debug) << "phi difference = " << iphi - iphi2;
111 LOG(debug) << "eta difference = " << ieta - ieta2;
112 if ((std::abs(iphi - iphi2) > 1) || (std::abs(ieta - ieta2) > 1)) {
113 continue;
114 }
115
116 // if we are here, the digit contributes to the cluster
117 addContributingDigit(digNext);
118
119 } // loop on the second digit
120
121 //printf("build cluster\n");
122 buildCluster(c, digitMCTruth); // toberem
123
124 } // loop on the first digit
125}
126//______________________________________________________________________
127void Clusterer::addContributingDigit(Digit* dig)
128{
129
130 // adding a digit to the array that stores the contributing ones
131
132 if (mNumberOfContributingDigits == 6) {
133 LOG(debug) << "The cluster has already 6 digits associated to it, we cannot add more; returning without doing anything";
134
135 int phi, eta;
136 for (int i = 0; i < mNumberOfContributingDigits; i++) {
137 mContributingDigit[i]->getPhiAndEtaIndex(phi, eta);
138 LOG(debug) << "digit already in " << i << ", channel = " << mContributingDigit[i]->getChannel() << ",phi,eta = (" << phi << "," << eta << "), TDC = " << mContributingDigit[i]->getTDC() << ", calibrated time = " << mContributingDigit[i]->getCalibratedTime();
139 }
140
141 dig->getPhiAndEtaIndex(phi, eta);
142 LOG(debug) << "skipped digit"
143 << ", channel = " << dig->getChannel() << ",phi,eta = (" << phi << "," << eta << "), TDC = " << dig->getTDC() << ", calibrated time = " << dig->getCalibratedTime();
144
145 dig->setIsUsedInCluster(); // flag is at used in any case
146
147 return;
148 }
149 mContributingDigit[mNumberOfContributingDigits] = dig;
150 mNumberOfContributingDigits++;
151 dig->setIsUsedInCluster();
152
153 return;
154}
155
156//_____________________________________________________________________
157void Clusterer::buildCluster(Cluster& c, MCLabelContainer const* digitMCTruth)
158{
159 static const float inv12 = 1. / 12.;
160
161 // here we finally build the cluster from all the digits contributing to it
162
163 Digit* temp;
164 for (int idig = 1; idig < mNumberOfContributingDigits; idig++) {
165 // the digit[0] will be the main one
166 if (mContributingDigit[idig]->getTOT() > mContributingDigit[0]->getTOT()) {
167 temp = mContributingDigit[0];
168 mContributingDigit[0] = mContributingDigit[idig];
169 mContributingDigit[idig] = temp;
170 }
171 }
172
173 c.setMainContributingChannel(mContributingDigit[0]->getChannel());
174 c.setTgeant(mContributingDigit[0]->getTgeant());
175 c.setT0true(mContributingDigit[0]->getT0true());
176 c.setTime(mContributingDigit[0]->getCalibratedTime()); // time in ps (for now we assume it calibrated)
177 c.setTimeRaw(mContributingDigit[0]->getTDC() * Geo::TDCBIN + mContributingDigit[0]->getBC() * o2::constants::lhc::LHCBunchSpacingNS * 1E3); // time in ps (for now we assume it calibrated)
178
179 //printf("timeraw= %lf - time real = %lf (%d, %lu) \n",c.getTimeRaw(),mContributingDigit[0]->getTDC() * Geo::TDCBIN + mContributingDigit[0]->getBC() * o2::constants::lhc::LHCBunchSpacingNS * 1E3,mContributingDigit[0]->getTDC(),mContributingDigit[0]->getBC());
180
181 c.setTot(mContributingDigit[0]->getTOT() * Geo::TOTBIN_NS); // TOT in ns (for now we assume it calibrated)
182 //setL0L1Latency(); // to be filled (maybe)
183 //setDeltaBC(); // to be filled (maybe)
184
185 c.setDigitInfo(0, mContributingDigit[0]->getChannel(), mContributingDigit[0]->getCalibratedTime(), mContributingDigit[0]->getTOT() * Geo::TOTBIN_NS);
186
187 int ch1 = mContributingDigit[0]->getChannel();
188 short tot1 = mContributingDigit[0]->getTOT() < 20000 ? mContributingDigit[0]->getTOT() : 20000;
189 double dtime = c.getTimeRaw();
190
191 int chan1, chan2;
192 int phi1, phi2;
193 int eta1, eta2;
194 int deltaPhi, deltaEta;
195 int mask;
196
197 mContributingDigit[0]->getPhiAndEtaIndex(phi1, eta1);
198 // now set the mask with the secondary digits
199 for (int idig = 1; idig < mNumberOfContributingDigits; idig++) {
200 mContributingDigit[idig]->getPhiAndEtaIndex(phi2, eta2);
201 deltaPhi = phi1 - phi2;
202 deltaEta = eta1 - eta2;
203
204 bool isOk = true;
205
206 if (deltaPhi == 1) { // the digit is to the LEFT of the cluster; let's check about UP/DOWN/Same Line
207 if (deltaEta == 1) { // the digit is DOWN LEFT wrt the cluster
209 } else if (deltaEta == -1) { // the digit is UP LEFT wrt the cluster
211 } else { // the digit is LEFT wrt the cluster
213 }
214 } else if (deltaPhi == -1) { // the digit is to the RIGHT of the cluster; let's check about UP/DOWN/Same Line
215 if (deltaEta == 1) { // the digit is DOWN RIGHT wrt the cluster
217 } else if (deltaEta == -1) { // the digit is UP RIGHT wrt the cluster
219 } else { // the digit is RIGHT wrt the cluster
221 }
222 } else if (deltaPhi == 0) { // the digit is on the same column as the cluster; is it UP or Down?
223 if (deltaEta == 1) { // the digit is DOWN wrt the cluster
225 } else if (deltaEta == -1) { // the digit is UP wrt the cluster
227 } else { // same channel!
228 LOG(debug) << " Check what is going on, the digit you are trying to merge to the cluster must be in a different channels... ";
229 }
230 } else { // |delataphi| > 1
231 isOk = false;
232 mContributingDigit[idig]->setIsUsedInCluster(false);
233 }
234
235 if (isOk) {
236 c.setDigitInfo(c.getNumOfContributingChannels(), mContributingDigit[idig]->getChannel(), mContributingDigit[idig]->getCalibratedTime(), mContributingDigit[idig]->getTOT() * Geo::TOTBIN_NS);
237 c.addBitInContributingChannels(mask);
238
239 if (mCalibFromCluster && c.getNumOfContributingChannels() == 2 && !mIsNoisy[mContributingDigit[idig]->getChannel()] && !mIsNoisy[ch1]) { // fill info for calibration excluding noisy channels
240 int8_t dch = int8_t(mContributingDigit[idig]->getChannel() - ch1);
241 short tot2 = mContributingDigit[idig]->getTOT() < 20000 ? mContributingDigit[idig]->getTOT() : 20000;
242 dtime -= mContributingDigit[idig]->getTDC() * Geo::TDCBIN + mContributingDigit[idig]->getBC() * o2::constants::lhc::LHCBunchSpacingNS * 1E3;
243 addCalibFromCluster(ch1, dch, float(dtime), tot1, tot2);
244 }
245 }
246 }
247
248 // filling the MC labels of this cluster; the first will be those of the main digit; then the others
249 if (digitMCTruth != nullptr) {
250 int lbl = mClsLabels->getIndexedSize(); // this should correspond to the number of digits also;
251 //printf("lbl = %d\n", lbl);
252 for (int i = 0; i < mNumberOfContributingDigits; i++) {
253 if (!mContributingDigit[i]->isUsedInCluster()) {
254 continue;
255 }
256 //printf("contributing digit = %d\n", i);
257 int digitLabel = mContributingDigit[i]->getLabel();
258 //printf("digitLabel = %d\n", digitLabel);
259 gsl::span<const o2::MCCompLabel> mcArray = digitMCTruth->getLabels(digitLabel);
260 for (int j = 0; j < static_cast<int>(mcArray.size()); j++) {
261 //printf("checking element %d in the array of labels\n", j);
262 auto label = digitMCTruth->getElement(digitMCTruth->getMCTruthHeader(digitLabel).index + j);
263 //printf("EventID = %d\n", label.getEventID());
264 mClsLabels->addElement(lbl, label);
265 }
266 }
267 }
268
269 // set geometrical variables
270 int det[5];
271 Geo::getVolumeIndices(c.getMainContributingChannel(), det);
272 float pos[3];
273 Geo::getPos(det, pos);
274 Geo::rotateToSector(pos, c.getSector());
275 c.setXYZ(pos[2], pos[0], pos[1]); // storing coordinates in sector frame: note that the rotation above puts z in pos[1], the radial coordinate in pos[2], and the tangent coordinate in pos[0] (this is to match the TOF residual system, where we don't use the radial component), so we swap their positions.
276
277 c.setR(std::sqrt(pos[0] * pos[0] + pos[1] * pos[1])); // it is the R in the sector frame
278 c.setPhi(std::atan2(pos[1], pos[0]));
279
280 float errY2 = Geo::XPAD * Geo::XPAD * inv12;
281 float errZ2 = Geo::ZPAD * Geo::ZPAD * inv12;
282 float errYZ = 0;
283
284 //if(c.getNumOfContributingChannels() > 1){
285 // set errors according to a model not yet defined!
286 // TO DO
287 //}
288 c.setErrors(errY2, errZ2, errYZ);
289
290 return;
291}
292
293//_____________________________________________________________________
294void Clusterer::setFirstOrbit(uint64_t orb)
295{
296 mFirstOrbit = orb;
297 mBCOffset = orb * o2::constants::lhc::LHCMaxBunches;
298}
299//_____________________________________________________________________
300void Clusterer::addCalibFromCluster(int ch1, int8_t dch, float dtime, short tot1, short tot2)
301{
302 mCalibInfosFromCluster.emplace_back(ch1, dch, dtime, tot1, tot2);
303}
Definition of the TOF cluster.
std::ostringstream debug
uint16_t getBC() const
int32_t i
Definition of a container to keep Monte Carlo truth external to simulation objects.
uint16_t pos
Definition RawData.h:3
uint32_t j
Definition RawData.h:0
uint32_t c
Definition RawData.h:2
Definition of the TOF cluster finder.
gsl::span< TruthElement > getLabels(uint32_t dataindex)
TruthElement const & getElement(uint32_t elementindex) const
void addElement(uint32_t dataindex, TruthElement const &element, bool noElement=false)
MCTruthHeaderElement const & getMCTruthHeader(uint32_t dataindex) const
bool isChannelError(int channel) const
bool isNoisy(int ich)
bool isProblematic(int ich)
float getTimeCalibration(int ich, float tot) const
Cluster class for TOF.
Definition Cluster.h:37
void addCalibFromCluster(int ch1, int8_t dch, float dtime, short tot1, short tot2)
void setFirstOrbit(uint64_t orb)
void process(DataReader &r, std::vector< Cluster > &clusters, MCLabelContainer const *digitMCTruth)
Definition Clusterer.cxx:25
DataReader class for TOF.
Definition DataReader.h:28
virtual Bool_t getNextStripData(StripData &stripData)=0
virtual void init()=0
TOF digit implementation.
Definition Digit.h:31
uint64_t getBC() const
Definition Digit.h:58
void setBC(uint64_t bc)
Definition Digit.h:59
Int_t getLabel() const
Definition Digit.h:64
uint16_t getTOT() const
Definition Digit.h:55
void setTgeant(float val)
Definition Digit.h:97
bool isProblematic() const
Definition Digit.h:89
double getCalibratedTime() const
Definition Digit.h:86
Int_t getChannel() const
Definition Digit.h:49
void setIsUsedInCluster(bool val=true)
Definition Digit.h:75
void getPhiAndEtaIndex(int &phi, int &eta) const
Definition Digit.cxx:64
void setCalibratedTime(Double_t time)
Definition Digit.h:85
void setIsProblematic(bool flag)
Definition Digit.h:88
uint16_t getTDC() const
Definition Digit.h:52
Bool_t isUsedInCluster() const
Definition Digit.h:73
static constexpr Float_t ZPAD
Definition Geo.h:143
static constexpr Float_t XPAD
Definition Geo.h:141
static void rotateToSector(Float_t *xyz, Int_t isector)
Definition Geo.cxx:1029
static void getPos(Int_t *det, Float_t *pos)
Definition Geo.cxx:491
static void getVolumeIndices(Int_t index, Int_t *detId)
Definition Geo.cxx:543
static constexpr Float_t TOTBIN_NS
Definition Geo.h:156
static constexpr Float_t TDCBIN
TDC bin width [ps].
Definition Geo.h:152
static constexpr Double_t LATENCYWINDOW
Definition Geo.h:178
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
GLint GLuint mask
Definition glcorearb.h:291
bool isOk(ResultWas::OfType resultType)
constexpr int LHCMaxBunches
constexpr double LHCBunchSpacingNS
return((dphi< 0 &&dphi > -constants::math::PI)||dphi > constants::math::PI) ? true T phi1
std::vector< Digit > digits
Definition DataReader.h:34
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Cluster > clusters