Project
Loading...
Searching...
No Matches
EveWorkflowHelper.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
23#include "ITStracking/IOUtils.h"
24#include "MFTTracking/IOUtils.h"
31#include "DataFormatsTPC/Defs.h"
37#include "MFTBase/GeometryTGeo.h"
39#include "PHOSBase/Geometry.h"
40#include "EMCALBase/Geometry.h"
42#include <TGeoBBox.h>
43#include <tuple>
44#include <gsl/span>
45
46using namespace o2::event_visualisation;
47
48const std::unordered_map<GID::Source, EveWorkflowHelper::PropagationRange> EveWorkflowHelper::propagationRanges = {
49 {GID::ITS, EveWorkflowHelper::prITS},
50 {GID::TPC, EveWorkflowHelper::prTPC},
51 {GID::ITSTPC, {EveWorkflowHelper::prITS.minR, EveWorkflowHelper::prTPC.maxR, EveWorkflowHelper::prTPC.minZ, EveWorkflowHelper::prTPC.maxZ}},
52 {GID::TPCTOF, {EveWorkflowHelper::prTPC.minR, EveWorkflowHelper::prTOF.maxR, EveWorkflowHelper::prTOF.minZ, EveWorkflowHelper::prTOF.maxZ}},
53 {GID::TPCTRD, {EveWorkflowHelper::prTPC.minR, EveWorkflowHelper::prTRD.maxR, EveWorkflowHelper::prTRD.minZ, EveWorkflowHelper::prTRD.maxZ}},
54 {GID::ITSTPCTRD, {EveWorkflowHelper::prITS.minR, EveWorkflowHelper::prTRD.maxR, EveWorkflowHelper::prTRD.minZ, EveWorkflowHelper::prTRD.maxZ}},
55 {GID::ITSTPCTOF, {EveWorkflowHelper::prITS.minR, EveWorkflowHelper::prTOF.maxR, EveWorkflowHelper::prTOF.minZ, EveWorkflowHelper::prTOF.maxZ}},
56 {GID::TPCTRDTOF, {EveWorkflowHelper::prTPC.minR, EveWorkflowHelper::prTOF.maxR, EveWorkflowHelper::prTOF.minZ, EveWorkflowHelper::prTOF.maxZ}},
57 {GID::ITSTPCTRDTOF, {EveWorkflowHelper::prITS.minR, EveWorkflowHelper::prTOF.maxR, EveWorkflowHelper::prTOF.minZ, EveWorkflowHelper::prTOF.maxZ}},
58};
59
61{
62 const auto phi = track.getPhi();
63 const auto sinPhi = std::sin(phi);
64 const auto tgL = track.getTgl();
65
66 const auto SlopeX = std::cos(phi) / tgL;
67 const auto SlopeY = sinPhi / tgL;
68 const auto InvP_yz = track.getInvQPt() / std::sqrt(sinPhi * sinPhi + tgL * tgL);
69
70 const std::array<Double_t, 5> params{track.getX(), SlopeX, track.getY(), SlopeY, InvP_yz};
71 const std::array<Double_t, 15> cov{
72 1,
73 0, 1,
74 0, 0, 1,
75 0, 0, 0, 1,
76 0, 0, 0, 0, 1};
77
78 return {track.getZ(), params.data(), cov.data()};
79}
80
82{
83 const auto& midClusters = mRecoCont->getMIDTrackClusters();
84
85 int icl = -1;
86
87 // Find last cluster position
88 for (std::size_t ich = 0; ich < 4; ++ich) {
89 auto cur_icl = track.getClusterMatched(ich);
90
91 if (cur_icl >= 0) {
92 icl = cur_icl;
93 }
94 }
95
96 if (icl >= 0) {
97 const auto& cluster = midClusters[icl];
98 return cluster.zCoor;
99 } else {
100 return track.getPositionZ();
101 }
102}
103
105{
106 const auto& mchClusters = mRecoCont->getMCHTrackClusters();
107
108 auto noOfClusters = track.getNClusters();
109 auto offset = track.getFirstClusterIdx();
110
111 const auto& lastCluster = mchClusters[offset + noOfClusters - 1];
112
113 return lastCluster.getZ();
114}
115
117
119{
120 auto startIR = mRecoCont->startIR;
121 auto bcd = ir.differenceInBC(startIR);
122
123 if (uint64_t(bcd) > o2::constants::lhc::LHCMaxBunches * 256 && BCDiffErrCount < MAXBCDiffErrCount) {
124 LOGP(alarm, "ATTENTION: wrong bunches diff. {} for current IR {} wrt 1st TF orbit {}", bcd, ir.asString(),
125 startIR.asString());
127 }
128
129 return bcd * o2::constants::lhc::LHCBunchSpacingNS * 1e-3;
130}
131
133{
134 return std::any_of(mItsROFBrackets.cbegin(), mItsROFBrackets.cend(), [&](const auto& rof) {
135 return rof.getOverlap(br).isValid();
136 });
137}
138
143
145{
146 return std::any_of(mItsROFBrackets.cbegin(), mItsROFBrackets.cend(), [&](const auto& rof) {
147 return rof.isOutside(t) == Bracket::Relation::Inside;
148 });
149}
150
155
157 GID::mask_t maskCl, GID::mask_t maskTrk, GID::mask_t maskMatch)
158{
159 const auto& conf = EveConfParam::Instance();
160
161 auto correctTrackTime = [this](auto& _tr, float t0, float terr) {
162 if constexpr (isTPCTrack<decltype(_tr)>()) {
163 // unconstrained TPC track, with t0 = TrackTPC.getTime0+0.5*(DeltaFwd-DeltaBwd) and terr = 0.5*(DeltaFwd+DeltaBwd) in TimeBins
164 t0 *= this->mTPCBin2MUS;
165 terr *= this->mTPCBin2MUS;
166 } else if constexpr (isITSTrack<decltype(_tr)>()) {
167 t0 += 0.5f * this->mITSROFrameLengthMUS; // ITS time is supplied in \mus as beginning of ROF
168 terr *= this->mITSROFrameLengthMUS; // error is supplied as a half-ROF duration, convert to \mus
169 } else if constexpr (isMFTTrack<decltype(_tr)>()) {
170 // Same for MFT
171 t0 += 0.5f * this->mMFTROFrameLengthMUS;
172 terr *= this->mMFTROFrameLengthMUS;
173 } else if constexpr (!(isMCHTrack<decltype(_tr)>() || isMIDTrack<decltype(_tr)>() ||
174 isGlobalFwdTrack<decltype(_tr)>())) {
175 // for all other tracks the time is in \mus with gaussian error
176 terr *= mPVParams->nSigmaTimeTrack; // gaussian errors must be scaled by requested n-sigma
177 }
178
180
181 return Bracket{t0 - terr, t0 + terr};
182 };
183
184 auto flagTime = [](float time, GID::Src_t src) {
185 auto flag = static_cast<int>(time) + TIME_OFFSET;
186
187 // if it's a tracklet, give it a lower priority in time sort by setting the highest bit
188 if (src <= GID::MID) {
189 flag |= (1 << 31);
190 }
191
192 return flag;
193 };
194
195 // MFT-MCH-MID tracks are labeled as MFT-MCH in the reco container
196 auto fixMFTMCHMIDLabel = [this](GID& gid) {
197 if (gid.getSource() == GID::MFTMCH) {
198 const auto& trFwd = mRecoCont->getGlobalFwdTrack(gid);
199 if (trFwd.getMIDTrackID() != -1) {
200 gid = GID{gid.getIndex(), GID::MFTMCHMID};
201 }
202 }
203 };
204 auto creator = [&conf, maskTrk, this, &correctTrackTime, &flagTime, &fixMFTMCHMIDLabel](auto& trk, GID gid,
205 float time, float terr) {
206 fixMFTMCHMIDLabel(gid);
207
208 const auto src = gid.getSource();
210
211 if (!maskTrk[src]) {
212 return true;
213 }
214
215 auto bracket = correctTrackTime(trk, time, terr);
216
217 if (mUseTimeBracket && !isInsideTimeBracket(bracket)) {
218 return true;
219 }
220
221 if (conf.filterITSROF && !isInsideITSROF(bracket)) {
222 return true;
223 }
224
225 mGIDTrackTime[gid] = flagTime(bracket.mean(), src);
226
227 // If the mode is disabled,
228 // add every track to a symbolic "zero" primary vertex
229 if (!conf.PVMode) {
230 mPrimaryVertexTrackGIDs[0].push_back(gid);
231 }
232
233 return true;
234 };
235
236 auto prop = o2::base::Propagator::Instance();
237 this->mRecoCont->createTracksVariadic(creator);
238 if (conf.PVMode) {
239 bool checkTPCDCA = conf.TPCOnlyMaxDCARZ[0] > 0.f || conf.TPCOnlyMaxDCARZ[1] > 0.f;
240 const auto trackIndex = mRecoCont->getPrimaryVertexMatchedTracks(); // Global ID's for associated tracks
241 const auto vtxRefs = mRecoCont->getPrimaryVertexMatchedTrackRefs(); // references from vertex to these track IDs
242 const auto totalPrimaryVertices =
243 vtxRefs.size() - 1; // The last entry is for unassigned tracks, ignore them
244
245 for (std::size_t iv = 0; iv < totalPrimaryVertices; iv++) {
246 const auto& pv = mRecoCont->getPrimaryVertex(iv);
247 if (pv.getX() < conf.PVXYZMin[0] || pv.getX() > conf.PVXYZMax[0] ||
248 pv.getY() < conf.PVXYZMin[1] || pv.getY() > conf.PVXYZMax[1] ||
249 pv.getZ() < conf.PVXYZMin[2] || pv.getZ() > conf.PVXYZMax[2]) {
250 continue; // skip vertex
251 }
252
253 o2::math_utils::Point3D<float> pvXYZ(pv.getX(), pv.getY(), pv.getZ());
254 const auto& vtref = vtxRefs[iv];
255 const gsl::span tracksForVertex(trackIndex.data() + vtref.getFirstEntry(), vtref.getEntries());
256 for (const auto& tvid : tracksForVertex) {
257 if (!mRecoCont->isTrackSourceLoaded(tvid.getSource())) {
258 continue;
259 }
260 GID gid(tvid);
261 fixMFTMCHMIDLabel(gid);
262 // If a track was not rejected, associate it with its primary vertex
263 if (mGIDTrackTime.find(gid) != mGIDTrackTime.end()) {
264 // add optional cut on TPC-only tracks DCAz (corrected for the vertex time)
265 if (gid.getSource() == o2::dataformats::GlobalTrackID::TPC && checkTPCDCA) {
266 const auto& tpcTr = mRecoCont->getTPCTrack(gid);
267 o2::track::TrackPar trc{tpcTr};
268 if (!tpcTr.hasBothSidesClusters()) {
269 // need to correct track Z with this vertex time
270 float dz = (tpcTr.getTime0() * mTPCTimeBins2MUS -
271 (pv.getTimeStamp().getTimeStamp() + mTPCVDrift->getTimeOffset())) *
273 if (tpcTr.hasCSideClustersOnly()) {
274 dz = -dz;
275 }
276 trc.setZ(trc.getZ() + dz);
277 }
278 std::array<float, 2> dca;
279 if (!prop->propagateToDCA(pvXYZ, trc, prop->getNominalBz(), 10.,
280 o2::base::PropagatorF::MatCorrType::USEMatCorrNONE, &dca) ||
281 (conf.TPCOnlyMaxDCARZ[1] > 0. && std::abs(dca[1]) > conf.TPCOnlyMaxDCARZ[1]) ||
282 (conf.TPCOnlyMaxDCARZ[0] > 0. && std::abs(dca[0]) > conf.TPCOnlyMaxDCARZ[0])) {
283 continue;
284 }
285 }
286 mPrimaryVertexTrackGIDs[iv].push_back(gid);
287 }
288 }
289 }
290 }
291}
292
294{
295 const auto& allTriggersPHOS = mRecoCont->getPHOSTriggers();
296 const auto& allTriggersEMCAL = mRecoCont->getEMCALTriggers();
297 const auto& allTriggersHMP = mRecoCont->getHMPClusterTriggers();
298 const auto& conf = EveConfParam::Instance();
299 auto filterTrigger = [&](const auto& trig) {
300 const auto time = bcDiffToTFTimeMUS(trig.getBCData());
301
303 return false;
304 }
305
306 if (EveConfParam::Instance().filterITSROF && !isInsideITSROF(time)) {
307 return false;
308 }
309
310 return true;
311 };
312
313 if (conf.PVMode) {
314 const auto trackIndex = mRecoCont->getPrimaryVertexMatchedTracks(); // Global ID's for associated tracks
315 const auto vtxRefs = mRecoCont->getPrimaryVertexMatchedTrackRefs(); // references from vertex to these track IDs
316 const auto totalPrimaryVertices =
317 vtxRefs.size() - 1; // The last entry is for unassigned tracks, ignore them
318
319 for (std::size_t iv = 0; iv < totalPrimaryVertices; iv++) {
320 const auto& vtref = vtxRefs[iv];
321
322 // to be improved to recognize PV
323 for (std::size_t i = 0; i < allTriggersHMP.size(); i++) {
325 const auto& trig = allTriggersHMP[i];
326 mPrimaryVertexTriggerGIDs[iv].emplace_back(GID{static_cast<unsigned int>(i), GID::HMP});
327 }
328
329 const auto triggersPHOS = gsl::span(trackIndex.data() + vtref.getFirstEntryOfSource(GID::PHS),
330 vtref.getEntriesOfSource(GID::PHS));
331
332 for (const auto& tvid : triggersPHOS) {
334 if (tvid.getIndex() < allTriggersPHOS.size()) {
335 const auto& trig = allTriggersPHOS[tvid.getIndex()];
336 if (filterTrigger(trig)) {
337 mPrimaryVertexTriggerGIDs[iv].emplace_back(tvid);
338 }
339 }
340 }
341
342 const auto triggersEMCAL = gsl::span(trackIndex.data() + vtref.getFirstEntryOfSource(GID::EMC),
343 vtref.getEntriesOfSource(GID::EMC));
344
345 for (const auto& tvid : triggersEMCAL) {
347 if (tvid.getIndex() < allTriggersEMCAL.size()) {
348 const auto& trig = allTriggersEMCAL[tvid.getIndex()];
349
350 if (filterTrigger(trig)) {
351 mPrimaryVertexTriggerGIDs[iv].emplace_back(tvid);
352 }
353 }
354 }
355 }
356 } else {
357
358 for (std::size_t i = 0; i < allTriggersHMP.size(); i++) {
360 const auto& trig = allTriggersHMP[i];
361 mPrimaryVertexTriggerGIDs[0].emplace_back(GID{static_cast<unsigned int>(i), GID::HMP});
362 }
363
364 for (std::size_t i = 0; i < allTriggersPHOS.size(); i++) {
366 const auto& trig = allTriggersPHOS[i];
367
368 if (filterTrigger(trig)) {
369 mPrimaryVertexTriggerGIDs[0].emplace_back(GID{static_cast<unsigned int>(i), GID::PHS});
370 }
371 }
372
373 for (std::size_t i = 0; i < allTriggersEMCAL.size(); i++) {
375 const auto& trig = allTriggersEMCAL[i];
376
377 if (filterTrigger(trig)) {
378 mPrimaryVertexTriggerGIDs[0].emplace_back(GID{static_cast<unsigned int>(i), GID::EMC});
379 }
380 }
381 }
382}
383
385{
386 if (EveConfParam::Instance().filterITSROF) {
387 const auto& irFrames = mRecoCont->getIRFramesITS();
388
389 for (const auto& irFrame : irFrames) {
390 mItsROFBrackets.emplace_back(bcDiffToTFTimeMUS(irFrame.getMin()), bcDiffToTFTimeMUS(irFrame.getMax()));
391 }
392 }
393}
394
395void EveWorkflowHelper::draw(std::size_t primaryVertexIdx, bool sortTracks)
396{
397 const auto& conf = EveConfParam::Instance();
398 if (mPrimaryVertexTrackGIDs.find(primaryVertexIdx) == mPrimaryVertexTrackGIDs.end()) {
399 LOGF(info, "Primary vertex %d has no tracks", primaryVertexIdx);
400 } else {
401 auto unflagTime = [](unsigned int time) {
402 return static_cast<float>(static_cast<int>(time & ~(1 << 31)) - TIME_OFFSET);
403 };
404
405 auto& tracks = mPrimaryVertexTrackGIDs.at(primaryVertexIdx);
406 float pvTime = conf.PVMode ? mRecoCont->getPrimaryVertex(primaryVertexIdx).getTimeStamp().getTimeStamp() : -1e9;
407
408 if (sortTracks) {
409 std::sort(tracks.begin(), tracks.end(),
410 [&](const GID& a, const GID& b) {
411 return mGIDTrackTime.at(a) < mGIDTrackTime.at(b);
412 });
413 }
414
415 auto trackCount = tracks.size();
416
417 if (conf.maxTracks > 0 && trackCount >= conf.maxTracks) {
418 trackCount = conf.maxTracks;
419 }
420
421 for (std::size_t it = 0; it < trackCount; it++) {
422 const auto& gid = tracks[it];
423 auto tim = unflagTime(mGIDTrackTime.at(gid));
424 mTotalAcceptedDataTypes.insert(gid);
425 // LOG(info) << "EveWorkflowHelper::draw " << gid.asString();
426 switch (gid.getSource()) {
427 case GID::ITS:
428 drawITS(gid, tim);
429 break;
430 case GID::TPC: {
431 float dz = 0.f;
432 if (conf.PVMode) {
433 // for TPC the nominal time (center of the bracket) is stored but in the PVMode we correct it by the PV time
434 tim = pvTime;
435 const auto& tpcTr = mRecoCont->getTPCTrack(gid);
436 if (!tpcTr.hasBothSidesClusters()) {
437 // need to correct track Z with this vertex time
438 float dz = (tpcTr.getTime0() * mTPCTimeBins2MUS - (pvTime + mTPCVDrift->getTimeOffset())) *
440 if (tpcTr.hasCSideClustersOnly()) {
441 dz = -dz;
442 }
443 }
444 }
445 drawTPC(gid, tim, dz);
446 } break;
447 case GID::MFT:
448 drawMFT(gid, tim);
449 break;
450 case GID::MCH:
451 drawMCH(gid, tim);
452 break;
453 case GID::MID:
454 drawMID(gid, tim);
455 break;
456 case GID::ITSTPC:
457 drawITSTPC(gid, tim);
458 break;
459 case GID::TPCTOF:
460 drawTPCTOF(gid, tim);
461 break;
462 case GID::TPCTRD:
463 drawTPCTRD(gid, tim);
464 break;
465 case GID::MFTMCH:
466 drawMFTMCH(gid, tim);
467 break;
468 case GID::MFTMCHMID:
469 drawMFTMCHMID(gid, tim);
470 break;
471 case GID::ITSTPCTRD:
472 drawITSTPCTRD(gid, tim);
473 break;
474 case GID::ITSTPCTOF:
475 drawITSTPCTOF(gid, tim);
476 break;
477 case GID::TPCTRDTOF:
478 drawTPCTRDTOF(gid, tim);
479 break;
481 drawITSTPCTRDTOF(gid, tim);
482 break;
483 case GID::MCHMID:
484 drawMCHMID(gid, tim);
485 break;
486 default:
487 LOGF(info, "Track type %s not handled", gid.getSourceName());
488 break;
489 }
490 }
491 }
492
493 if (mPrimaryVertexTriggerGIDs.find(primaryVertexIdx) == mPrimaryVertexTriggerGIDs.end()) {
494 LOGF(info, "Primary vertex %d has no triggers", primaryVertexIdx);
495 } else {
496 const auto& triggers = mPrimaryVertexTriggerGIDs.at(primaryVertexIdx);
497
498 for (std::size_t it = 0; it < triggers.size(); it++) {
499 const auto& gid = triggers[it];
500 mTotalAcceptedDataTypes.insert(gid);
501 switch (gid.getSource()) {
502 case GID::PHS:
503 drawPHS(gid);
504 break;
505 case GID::EMC:
506 drawEMC(gid);
507 break;
508 case GID::HMP:
509 drawHMP(gid);
510 break;
511 default:
512 LOGF(info, "Trigger type %s not handled", gid.getSourceName());
513 break;
514 }
515 }
516 }
517}
518
519void EveWorkflowHelper::save(const std::string& jsonPath, const std::string& ext, int numberOfFiles,
520 const std::string& receiverHostname, int receiverPort, int receiverTimeout, bool useOnlyFiles,
521 bool useOnlySockets)
522{
523 mEvent.setEveVersion(o2_eve_version);
524 FileProducer producer(jsonPath, ext);
525 producer.reduceNumberOfFiles(numberOfFiles);
526 Location location({.fileName = producer.newFileName(),
527 .port = receiverPort,
528 .timeout = receiverTimeout,
529 .host = receiverHostname,
530 .toFile = !useOnlySockets,
531 .toSocket = !useOnlyFiles});
533}
534
535std::vector<PNT>
536 EveWorkflowHelper::getTrackPoints(const o2::track::TrackPar& trc, float minR, float maxR, float maxStep, float minZ,
537 float maxZ)
538{
539 // adjust minR according to real track start from track starting point
540 auto maxR2 = maxR * maxR;
541 float rMin = std::sqrt(trc.getX() * trc.getX() + trc.getY() * trc.getY());
542 if (rMin > minR) {
543 minR = rMin;
544 }
545 // prepare space points from the track param
546 std::vector<PNT> pnts;
547 int nSteps = std::max(2, int((maxR - minR) / maxStep));
548 const auto prop = o2::base::Propagator::Instance();
549 float xMin = trc.getX(), xMax = maxR * maxR - trc.getY() * trc.getY();
550 if (xMax > 0) {
551 xMax = std::sqrt(xMax);
552 }
553
554 float dx = (xMax - xMin) / nSteps;
555 auto tp = trc;
556 float dxmin = std::abs(xMin - tp.getX()), dxmax = std::abs(xMax - tp.getX());
557
558 if (dxmin > dxmax) {
559 // start from closest end
560 std::swap(xMin, xMax);
561 dx = -dx;
562 }
563 if (!prop->propagateTo(tp, xMin, false, 0.99, maxStep, o2::base::PropagatorF::MatCorrType::USEMatCorrNONE)) {
564 return pnts;
565 }
566 auto xyz = tp.getXYZGlo();
567 pnts.emplace_back(PNT{xyz.X(), xyz.Y(), xyz.Z()});
568 for (int is = 0; is < nSteps; is++) {
569 if (!prop->propagateTo(tp, tp.getX() + dx, false, 0.99, 999., o2::base::PropagatorF::MatCorrType::USEMatCorrNONE)) {
570 return pnts;
571 }
572 xyz = tp.getXYZGlo();
573 if (xyz.Z() < minZ) {
574 return pnts;
575 }
576 if (xyz.Z() > maxZ) {
577 return pnts;
578 }
579 if (xyz.X() * xyz.X() + xyz.Y() * xyz.Y() > maxR2) {
580 return pnts;
581 }
582 pnts.emplace_back(PNT{xyz.X(), xyz.Y(), xyz.Z()});
583 }
584 return pnts;
585}
586
587void EveWorkflowHelper::addTrackToEvent(const o2::track::TrackPar& tr, GID gid, float trackTime, float dz,
588 GID::Source source, float maxStep)
589{
590 if (source == GID::NSources) {
592 }
593 auto vTrack = mEvent.addTrack({.time = trackTime,
594 .charge = tr.getCharge(),
595 .PID = tr.getPID(),
596 .startXYZ = {tr.getX(), tr.getY(), tr.getZ()},
597 .phi = tr.getPhi(),
598 .theta = tr.getTheta(),
599 .eta = tr.getEta(),
600 .gid = gid});
601
602 const auto it = propagationRanges.find(source);
603
604 const bool rangeNotFound = (it == propagationRanges.cend());
605 if (rangeNotFound) {
606 LOGF(error, "Track source %s has no defined propagation ranges", GID::getSourceName(source));
607 return;
608 }
609
610 const auto& prange = it->second;
611
612 auto pnts = getTrackPoints(tr, prange.minR, prange.maxR, maxStep, prange.minZ, prange.maxZ);
613
614 for (size_t ip = 0; ip < pnts.size(); ip++) {
615 vTrack->addPolyPoint(pnts[ip][0], pnts[ip][1], pnts[ip][2] + dz);
616 }
617}
618
620{
623 for (int lr = 0; lr < nLr; lr++) { // with a single (monolithic) input all clusters are in the layer slot 0
625 const auto& ITSClusterROFRec = mRecoCont->getITSClustersROFRecords(lr);
626 const auto& clusITS = mRecoCont->getITSClusters(lr);
627 if (clusITS.size() && ITSClusterROFRec.size()) {
628 auto pattIt = mRecoCont->getITSClustersPatterns(lr).begin();
629 mITSClustersArray.getClusters().reserve(mITSClustersArray.size() + clusITS.size());
631 }
632 }
634}
635
637 const o2::itsmft::TopologyDictionary* dict) // do we also have something as ITS...dict?
638{
639 const auto& MFTClusterROFRec = this->mRecoCont->getMFTClustersROFRecords();
640 const auto& clusMFT = this->mRecoCont->getMFTClusters();
641 if (clusMFT.size() && MFTClusterROFRec.size()) {
642 const auto& patterns = this->mRecoCont->getMFTClustersPatterns();
643 auto pattIt = patterns.begin();
644 this->mMFTClustersArray.reserve(clusMFT.size());
646 }
647}
648
650{
652 const auto& trig = mRecoCont->getHMPClusterTriggers()[gid.getIndex()];
653 const auto& clusters = mRecoCont->getHMPClusters();
654
655 auto bc = trig.getBc();
656 auto orbit = trig.getOrbit();
657 auto time = o2::InteractionTimeRecord::bc2ns(bc, orbit); // in ns absolute time
658
659 for (int j = trig.getFirstEntry(); j <= trig.getLastEntry(); j++) {
660 auto cluster = clusters[j];
661 auto module = cluster.ch();
662 double x = cluster.x();
663 double y = cluster.y();
664
665 TVector3 vec3 = pParam->lors2Mars(module, x, y);
666 drawGlobalPoint(vec3, gid, time);
667 }
668}
669
671{
672 const auto& cells = mRecoCont->getPHOSCells();
673
674 const auto& trig = mRecoCont->getPHOSTriggers()[gid.getIndex()];
675 const auto time = bcDiffToTFTimeMUS(trig.getBCData());
676 const gsl::span cellsForTrigger(cells.data() + trig.getFirstEntry(), trig.getNumberOfObjects());
677
678 for (const auto& cell : cellsForTrigger) {
679 std::array<char, 3> relativeLocalPositionInModule; // relative (local) position within module
680 float x, z;
681 o2::phos::Geometry::absToRelNumbering(cell.getAbsId(), relativeLocalPositionInModule.data());
683 TVector3 gPos;
684
685 // convert local position in module to global position in ALICE including actual mis-aslignment read with GetInstance("Run3")
686 this->mPHOSGeom->local2Global(relativeLocalPositionInModule[0], x, z, gPos);
687
688 auto vCalo = mEvent.addCalo({.time = static_cast<float>(time),
689 .energy = cell.getEnergy(),
690 .phi = (float)gPos.Phi(),
691 .eta = (float)gPos.Eta(),
692 .PID = 0,
693 .gid = gid});
694 }
695}
696
698{
699 const auto& cells = mRecoCont->getEMCALCells();
700
701 const auto& trig = mRecoCont->getEMCALTriggers()[gid.getIndex()];
702 const auto time = bcDiffToTFTimeMUS(trig.getBCData());
703 const gsl::span cellsForTrigger(cells.data() + trig.getFirstEntry(), trig.getNumberOfObjects());
704 const auto& conf = EveConfParam::Instance();
705
706 for (const auto& cell : cellsForTrigger) {
707 if (!(cell.getType() == o2::emcal::ChannelType_t::HIGH_GAIN ||
708 cell.getType() == o2::emcal::ChannelType_t::LOW_GAIN)) {
709 // Select FEE cells (excluding LEDMON or TRU cells)
710 continue;
711 }
712 auto cellTime = cell.getTimeStamp();
713 auto cellEnergy = cell.getEnergy();
714 if (mEMCALCalib) {
715 // try to recalibrate cell in case calibration is available (bad channel removal, energy calibration, time calibration)
716 auto calibCell = mEMCALCalib->getCalibratedCell(cell);
717 if (!calibCell) {
718 // cell was rejected by bad channel calib
719 continue;
720 }
721 cellTime = calibCell->getTimeStamp();
722 cellEnergy = calibCell->getEnergy();
723 }
724 if (std::abs(cellTime) > conf.EMCCellTimeMax) {
725 // cell rejected by time cut (pileup or noise)
726 continue;
727 }
728 if (cellEnergy < conf.EMCCellEnergyMin) {
729 // cell rejected by energy cut (rejection of soft cells)
730 continue;
731 }
732 const auto id = cell.getTower();
733 // Point3D with x,y,z coordinates of cell with absId inside SM
734 const auto relPosCell = this->mEMCALGeom->RelPosCellInSModule(id);
735 std::array<double, 3> rPos{relPosCell.X(), relPosCell.Y(), relPosCell.Z()};
736 std::array<double, 3> gPos{};
737
738 // supermodule ID, module number, index of cell in module in phi, index of cell in module in eta
739 const auto& [sm_id, module_number, index_module_phi, index_module_eta] = this->mEMCALGeom->GetCellIndex(id);
740 const auto matrix = this->mEMCALGeom->GetMatrixForSuperModuleFromGeoManager(sm_id);
741 matrix->LocalToMaster(rPos.data(), gPos.data());
742 TVector3 vPos(gPos.data());
743
744 auto vCalo = mEvent.addCalo({.time = static_cast<float>(time),
745 .energy = cellEnergy,
746 .phi = (float)vPos.Phi(),
747 .eta = (float)vPos.Eta(),
748 .PID = 0,
749 .gid = gid});
750 }
751}
752
754{
755 // LOG(info) << "EveWorkflowHelper::drawITSTPC " << gid;
756 const auto& track = mRecoCont->getTPCITSTrack(gid);
757 addTrackToEvent(track, gid, trackTime, 0., source);
758 drawITSClusters(track.getRefITS()); // trackTime
759 drawTPCClusters(track.getRefTPC(), trackTime * mMUS2TPCTimeBins);
760}
761
763{
764 const auto& track = mRecoCont->getITSTPCTOFTrack(gid);
765 addTrackToEvent(track, gid, trackTime, 0., source);
766 drawITSClusters(track.getRefITS()); // trackTime
767 drawTPCClusters(track.getRefTPC(), trackTime * mMUS2TPCTimeBins);
768 drawTOFClusters(gid);
769}
770
772{
773 // LOG(info) << "EveWorkflowHelper::drawTPCTRD " << gid;
774 const auto& tpcTrdTrack = mRecoCont->getTPCTRDTrack<o2::trd::TrackTRD>(gid);
775 addTrackToEvent(tpcTrdTrack, gid, trackTime, 0., source);
776 drawTPCClusters(tpcTrdTrack.getRefGlobalTrackId(), trackTime * mMUS2TPCTimeBins);
777 drawTRDClusters(tpcTrdTrack); // tracktime
778}
779
781{
782 // LOG(info) << "EveWorkflowHelper::drawITSTPCTRD " << gid;
783 const auto& itsTpcTrdTrack = mRecoCont->getITSTPCTRDTrack<o2::trd::TrackTRD>(gid);
784 drawITSTPC(itsTpcTrdTrack.getRefGlobalTrackId(), trackTime, source);
785 drawTRDClusters(itsTpcTrdTrack); // trackTime
786}
787
788void EveWorkflowHelper::drawITSTPCTRDTOF(GID gid, float trackTime)
789{
790 // LOG(info) << "EveWorkflowHelper::drawITSTPCTRDTOF " << gid;
791 const auto& match = mRecoCont->getITSTPCTRDTOFMatches()[gid.getIndex()];
792 auto gidITSTPCTRD = match.getTrackRef();
793 drawITSTPCTRD(gidITSTPCTRD, trackTime, GID::ITSTPCTRDTOF);
794 drawTOFClusters(gid); // trackTime
795}
796
797void EveWorkflowHelper::drawTPCTRDTOF(GID gid, float trackTime)
798{
799 // LOG(info) << "EveWorkflowHelper::drawTPCTRDTOF " << gid;
800 const auto& match = mRecoCont->getTPCTRDTOFMatches()[gid.getIndex()];
801 auto gidTPCTRD = match.getTrackRef();
802 drawTPCTRD(gidTPCTRD, trackTime, GID::TPCTRDTOF);
803 drawTOFClusters(gid); // trackTime
804}
805
806void EveWorkflowHelper::drawTPCTOF(GID gid, float trackTime)
807{
808 // LOG(info) << "EveWorkflowHelper::drawTPCTRDTOF " << gid;
809 const auto& trTPCTOF = mRecoCont->getTPCTOFTrack(gid);
810 const auto& match = mRecoCont->getTPCTOFMatch(gid.getIndex());
811 addTrackToEvent(trTPCTOF, gid, trackTime, 0);
812 drawTPCClusters(match.getTrackRef(), trackTime * mMUS2TPCTimeBins);
813 drawTOFClusters(gid); // trackTime
814}
815
816void EveWorkflowHelper::drawMFTMCH(GID gid, float trackTime)
817{
818 const auto& trMFTMCH = mRecoCont->getGlobalFwdTrack(gid);
819
820 const auto& trackParam = forwardTrackToMCHTrack(trMFTMCH);
821
822 const auto mchGID = GID{static_cast<unsigned int>(trMFTMCH.getMCHTrackID()), GID::MCH};
823
824 const auto& mchTrack = mRecoCont->getMCHTrack(mchGID);
825
826 const auto endZ = findLastMCHClusterPosition(mchTrack);
827
828 drawForwardTrack(gid, trackParam, mftZPositions.front(), endZ, trackTime);
829
830 drawMFTClusters(GID{static_cast<unsigned int>(trMFTMCH.getMFTTrackID()), GID::MFT}); // tracktime
831 drawMCHClusters(mchGID); // tracktime
832}
833
834void EveWorkflowHelper::drawMFTMCHMID(GID gid, float trackTime)
835{
836 const auto& trMFTMCHMID = mRecoCont->getGlobalFwdTrack(GID{gid.getIndex(), GID::MFTMCH});
837
838 const auto& trackParam = forwardTrackToMCHTrack(trMFTMCHMID);
839
840 const auto midGID = GID{static_cast<unsigned int>(trMFTMCHMID.getMIDTrackID()), GID::MID};
841
842 const auto& midTrack = mRecoCont->getMIDTrack(midGID);
843
844 const auto endZ = findLastMIDClusterPosition(midTrack);
845
846 drawForwardTrack(gid, trackParam, mftZPositions.front(), endZ, trackTime);
847
848 drawMFTClusters(GID{static_cast<unsigned int>(trMFTMCHMID.getMFTTrackID()), GID::MFT}); // trackTime
849 drawMCHClusters(GID{static_cast<unsigned int>(trMFTMCHMID.getMCHTrackID()), GID::MCH}); // trackTime
850 drawMIDClusters(midGID); // tracktime
851}
852
853void EveWorkflowHelper::drawMCHMID(GID gid, float trackTime)
854{
855 const auto& match = mRecoCont->getMCHMIDMatches()[gid.getIndex()];
856 const auto& mchTrack = mRecoCont->getMCHTrack(match.getMCHRef());
857 const auto& midTrack = mRecoCont->getMIDTrack(match.getMIDRef());
858
859 auto trackParam = mch::TrackParam(mchTrack.getZ(), mchTrack.getParameters(), mchTrack.getCovariances());
860
861 const auto endZ = findLastMIDClusterPosition(midTrack);
862
863 drawForwardTrack(gid, trackParam, trackParam.getZ(), endZ, trackTime);
864
865 drawMCHClusters(match.getMCHRef()); // tracktime
866 drawMIDClusters(match.getMIDRef()); // tracktime
867}
868
870{
871 const std::array<float, 5> arraypar = {
872 track.y(), track.z(), track.snp(),
873 track.tgl(), track.signed1Pt()};
874
875 const auto tr = o2::track::TrackPar(track.x(), track.alpha(), arraypar);
876
877 addTrackToEvent(tr, GID{0, detectorMapToGIDSource(track.detectorMap())}, trackTime, 0.);
878}
879
880void EveWorkflowHelper::drawAODMFT(AODMFTTrack const& track, float trackTime)
881{
882 auto tr = o2::track::TrackParFwd();
883
884 tr.setZ(track.z());
885 tr.setParameters({track.x(), track.y(), track.phi(), track.tgl(), track.signed1Pt()});
887}
888
889void EveWorkflowHelper::drawAODFwd(AODForwardTrack const& track, float trackTime)
890{
891 o2::track::TrackParFwd trackFwd;
892 trackFwd.setZ(track.z());
893 trackFwd.setParameters({track.x(), track.y(), track.phi(), track.tgl(), track.signed1Pt()});
894
895 const auto trackParam = forwardTrackToMCHTrack(trackFwd);
896
897 float endZ = 0;
898 GID gid;
899
900 switch (track.trackType()) {
903 gid = GID::MFTMCHMID;
904 endZ = midZPositions.back();
905 break;
907 gid = GID::MFTMCH;
908 endZ = mchZPositions.back();
909 break;
911 gid = GID::MCHMID;
912 endZ = midZPositions.back();
913 break;
915 gid = GID::MCH;
916 endZ = mchZPositions.back();
917 break;
918 }
919
920 drawForwardTrack(gid, trackParam, trackParam.getZ(), endZ, trackTime);
921}
922
924{
925 tr.propagateParamToZlinear(mftZPositions.front()); // Fix the track starting position.
926
927 auto vTrack = mEvent.addTrack({.time = static_cast<float>(trackTime),
928 .charge = (int)tr.getCharge(),
929 .PID = o2::track::PID::Muon,
930 .startXYZ = {(float)tr.getX(), (float)tr.getY(), (float)tr.getZ()},
931 .phi = (float)tr.getPhi(),
932 .theta = (float)tr.getTheta(),
933 .eta = (float)tr.getEta(),
934 .gid = gid});
935
936 for (auto zPos : mftZPositions) {
938 vTrack->addPolyPoint((float)tr.getX(), (float)tr.getY(), (float)tr.getZ());
939 }
940}
941
942void EveWorkflowHelper::drawForwardTrack(GID gid, mch::TrackParam track, float startZ, float endZ, float trackTime)
943{
944 auto vTrack = mEvent.addTrack({.time = static_cast<float>(trackTime),
945 .charge = 0,
946 .PID = o2::track::PID::Muon,
947 .startXYZ = {
948 (float)track.getNonBendingCoor(), (float)track.getBendingCoor(),
949 (float)track.getZ()},
950 .phi = (float)0,
951 .theta = (float)0,
952 .eta = (float)0,
953 .gid = gid});
954
955 static constexpr auto stepDensity = 50.; // one vertex per 50 cm should be sufficiently dense
956
957 const auto nSteps = static_cast<std::size_t>(std::abs(endZ - startZ) / stepDensity);
958
959 const auto dZ = (endZ - startZ) / nSteps;
960
961 for (std::size_t i = 0; i < nSteps; ++i) {
962 const auto z = startZ + i * dZ;
963 vTrack->addPolyPoint(track.getNonBendingCoor(), track.getBendingCoor(), z);
965 }
966}
967
969{
970 auto tOFClustersArray = mRecoCont->getTOFClusters();
971 if (!gid.includesDet(o2::dataformats::GlobalTrackID::Source::TOF)) {
972 return;
973 }
975 int tofcl = match.getIdxTOFCl();
976 int sector = tOFClustersArray[tofcl].getSector();
977 float x = tOFClustersArray[tofcl].getX();
978 float y = tOFClustersArray[tofcl].getY();
979 float z = tOFClustersArray[tofcl].getZ();
980
981 // rotation
982 float alpha = o2::math_utils::sector2Angle(sector);
983 float xyzGlb[3];
984 xyzGlb[0] = x * cos(alpha) - y * sin(alpha);
985 xyzGlb[1] = y * cos(alpha) + x * sin(alpha);
986 xyzGlb[2] = z;
987 drawPoint(xyzGlb);
988}
989
990void EveWorkflowHelper::drawITSClusters(GID gid) // float trackTime
991{
992 if (gid.getSource() == GID::ITS) {
993 // this is for for full standalone tracks
994 const auto& trc = mRecoCont->getITSTrack(gid);
995 auto refs = mRecoCont->getITSTracksClusterRefs();
996 int ncl = trc.getNumberOfClusters();
997 int offset = trc.getFirstClusterEntry();
998 for (int icl = 0; icl < ncl; icl++) {
999 const auto& pnt = mITSClustersArray[refs[icl + offset]];
1000 const auto glo = mITSGeom->getMatrixT2G(pnt.getSensorID()) * pnt.getXYZ();
1001 float xyz[] = {glo.X(), glo.Y(), glo.Z()};
1002 drawPoint(xyz); // trackTime;
1003 }
1004 } else if (gid.getSource() == GID::ITSAB) {
1005 // this is for ITS tracklets from ITS-TPC afterburner
1006 const auto& trc = mRecoCont->getITSABRef(gid);
1007 const auto& refs = mRecoCont->getITSABClusterRefs();
1008 int ncl = trc.getNClusters();
1009 int offset = trc.getFirstEntry();
1010 for (int icl = 0; icl < ncl; icl++) {
1011 const auto& pnt = mITSClustersArray[refs[icl + offset]];
1012 const auto glo = mITSGeom->getMatrixT2G(pnt.getSensorID()) * pnt.getXYZ();
1013 float xyz[] = {glo.X(), glo.Y(), glo.Z()};
1014 drawPoint(xyz); //, trackTime
1015 }
1016 }
1017}
1018
1019// TPC cluseters for given TPC track (gid)
1020void EveWorkflowHelper::drawTPCClusters(GID gid, float trackTimeTB)
1021{
1022 const auto& trc = mRecoCont->getTPCTrack(gid);
1023 auto mTPCTracksClusIdx = mRecoCont->getTPCTracksClusterRefs();
1024 auto mTPCClusterIdxStruct = &mRecoCont->getTPCClusters();
1025 if (trackTimeTB < -1e9) {
1026 trackTimeTB = trc.getTime0();
1027 }
1028 // store the TPC cluster positions
1029 for (int iCl = trc.getNClusterReferences(); iCl--;) {
1030 uint8_t sector, row;
1031 const auto& clTPC = trc.getCluster(mTPCTracksClusIdx, iCl, *mTPCClusterIdxStruct, sector, row);
1032
1033 std::array<float, 3> xyz;
1034 this->mTPCFastTransform->TransformIdeal(sector, row, clTPC.getPad(), clTPC.getTime(), xyz[0], xyz[1], xyz[2],
1035 trackTimeTB); // in sector coordinate
1037 sector % o2::tpc::SECTORSPERSIDE)); // lab coordinate (global)
1039 xyz.data()); // trackTimeTB / mMUS2TPCTimeBins
1040 }
1041}
1042
1043void EveWorkflowHelper::drawMFTClusters(GID gid) // float trackTime
1044{
1045 const auto& mftTrack = mRecoCont->getMFTTrack(gid);
1046 auto noOfClusters = mftTrack.getNumberOfPoints(); // number of clusters in MFT Track
1047 auto offset = mftTrack.getExternalClusterIndexOffset(); // first external cluster index offset:
1048 auto refs = mRecoCont->getMFTTracksClusterRefs(); // list of references to clusters, offset:offset+no
1049 for (int icl = noOfClusters - 1; icl > -1; --icl) {
1050 const auto& thisCluster = mMFTClustersArray[refs[offset + icl]];
1051 float xyz[] = {thisCluster.getX(), thisCluster.getY(), thisCluster.getZ()};
1052 drawPoint(xyz); // tracktime
1053 }
1054}
1055
1056void EveWorkflowHelper::drawTPC(GID gid, float trackTime, float dz)
1057{
1058 const auto& tr = mRecoCont->getTPCTrack(gid);
1059
1061 return;
1062 }
1063
1064 addTrackToEvent(tr, gid, trackTime, dz, GID::TPC);
1065 float clTime0 = EveConfParam::Instance().PVMode
1066 ? trackTime * mMUS2TPCTimeBins
1067 : -2e9; // in PVMode use supplied real time converted to TB, otherwise pass dummy time to use tpcTrack.getTime0
1068 drawTPCClusters(gid, clTime0); // trackTime
1069}
1070
1071void EveWorkflowHelper::drawITS(GID gid, float trackTime)
1072{
1073 const auto& tr = mRecoCont->getITSTrack(gid);
1074 addTrackToEvent(tr, gid, trackTime, 0.f, GID::ITS);
1075
1076 drawITSClusters(gid); // tracktime
1077}
1078
1079void EveWorkflowHelper::drawMFT(GID gid, float trackTime)
1080{
1081 // LOG(info) << "EveWorkflowHelper::drawMFT " << gid;
1082 auto tr = mRecoCont->getMFTTrack(gid);
1083
1084 drawMFTTrack(gid, tr, trackTime);
1085 drawMFTClusters(gid); // tracktime
1086}
1087
1088void EveWorkflowHelper::drawMCH(GID gid, float trackTime)
1089{
1090 // LOG(info) << "EveWorkflowHelper::drawMCH " << gid;
1091 const auto& track = mRecoCont->getMCHTrack(gid);
1092 auto trackParam = mch::TrackParam(track.getZ(), track.getParameters(), track.getCovariances());
1093
1094 const auto endZ = findLastMCHClusterPosition(track);
1095
1096 drawForwardTrack(gid, trackParam, track.getZ(), endZ, trackTime);
1097
1098 drawMCHClusters(gid); // tracktime
1099}
1100
1102{
1103 const auto& mchTrack = mRecoCont->getMCHTrack(gid);
1104 auto noOfClusters = mchTrack.getNClusters(); // number of clusters in MCH Track
1105 auto offset = mchTrack.getFirstClusterIdx(); // first external cluster index offset:
1106 const auto& mchClusters = mRecoCont->getMCHTrackClusters(); // list of references to clusters, offset:offset+no
1107 for (int icl = noOfClusters - 1; icl > -1; --icl) {
1108 const auto& cluster = mchClusters[offset + icl];
1109 float glo[] = {cluster.x, cluster.y, cluster.z};
1110 drawPoint(glo); // tracktime
1111 }
1112}
1113
1114void EveWorkflowHelper::drawMID(GID gid, float trackTime)
1115{
1116 // LOG(info) << "EveWorkflowHelper::drawMID --------------------------------" << gid;
1117 const auto& midTrack = mRecoCont->getMIDTrack(gid); // MID track
1118 const auto& midClusters = mRecoCont->getMIDTrackClusters(); // MID clusters
1119
1120 auto vTrack = mEvent.addTrack({.time = static_cast<float>(trackTime),
1121 .charge = (int)0,
1122 .PID = o2::track::PID::Muon,
1123 .startXYZ = {
1124 (float)midTrack.getPositionX(), (float)midTrack.getPositionY(),
1125 (float)midTrack.getPositionZ()},
1126 .phi = (float)0,
1127 .theta = (float)0,
1128 .eta = (float)0,
1129 .gid = gid});
1130
1131 for (int ich = 0; ich < 4; ++ich) {
1132 auto icl = midTrack.getClusterMatched(ich);
1133 if (icl >= 0) {
1134 auto& cluster = midClusters[icl];
1135 vTrack->addPolyPoint(cluster.xCoor, cluster.yCoor, cluster.zCoor);
1136 }
1137 }
1138 drawMIDClusters(gid); // tracktime
1139}
1140
1141void EveWorkflowHelper::drawMIDClusters(GID gid) // , float trackTime
1142{
1143 const auto& midTrack = mRecoCont->getMIDTrack(gid); // MID track
1144 const auto& midClusters = mRecoCont->getMIDTrackClusters(); // MID clusters
1145
1146 for (int ich = 0; ich < 4; ++ich) {
1147 auto icl = midTrack.getClusterMatched(ich);
1148 if (icl >= 0) {
1149 auto& cluster = midClusters[icl];
1150 float glo[] = {cluster.xCoor, cluster.yCoor, cluster.zCoor};
1151 drawPoint(glo); // tracktime
1152 }
1153 }
1154}
1155
1156void EveWorkflowHelper::drawTRDClusters(const o2::trd::TrackTRD& tpcTrdTrack) // tracktime
1157{
1158 const auto& tpcTrdTracks = mRecoCont->getTPCTRDTracks<o2::trd::TrackTRD>();
1159 const auto& tpcTrdTriggerRecords = mRecoCont->getTPCTRDTriggers();
1160 const auto& itsTpcTrdTracks = mRecoCont->getITSTPCTRDTracks<o2::trd::TrackTRD>();
1161 const auto& itsTpcTrdTriggerRecords = mRecoCont->getITSTPCTRDTriggers();
1162 const auto& trdTracklets = mRecoCont->getTRDTracklets();
1163 const auto& trdCalibratedTracklets = mRecoCont->getTRDCalibratedTracklets();
1164
1165 for (int iLayer = 0; iLayer < 6; ++iLayer) {
1166 if (tpcTrdTrack.getTrackletIndex(iLayer) >= 0) {
1167 // there is a TRD space point in this layer
1168 const auto& tracklet = trdTracklets[tpcTrdTrack.getTrackletIndex(iLayer)];
1169 const auto& spacePoint = trdCalibratedTracklets[tpcTrdTrack.getTrackletIndex(iLayer)];
1170 // get position in sector coordinates from the spacePoint
1171 float x = spacePoint.getX(), y = spacePoint.getY(), z = spacePoint.getZ();
1172 // in order to rotate the space points into the global coordinate system we need to know the TRD chamber number
1173 int iChamber = tracklet.getDetector();
1174 // with that we can determine the sector and thus the rotation angle alpha
1175 int sector = iChamber / 30;
1176 float alpha = o2::math_utils::sector2Angle(sector);
1177 // now the rotation is simply
1178 float glo[3];
1179 glo[0] = x * cos(alpha) - y * sin(alpha);
1180 glo[1] = y * cos(alpha) + x * sin(alpha);
1181 glo[2] = z;
1182 drawPoint(glo); // tracktime
1183 }
1184 }
1185}
1186
1188{
1189 const auto& conf = EveConfParam::Instance();
1190 if (conf.timeMinMax[0] >= 0.f && conf.timeMinMax[0] < conf.timeMinMax[1]) {
1191 mUseTimeBracket = true;
1192 mTimeBracket = {conf.timeMinMax[0], conf.timeMinMax[1]};
1193 }
1194 if (conf.TPCEtaAbsMax > 0.f) {
1195 mUseEtaBracketTPC = true;
1196 mEtaBracketTPC = {-conf.TPCEtaAbsMax, conf.TPCEtaAbsMax};
1197 }
1201 o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::L2G));
1204 o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot,
1205 o2::math_utils::TransformType::L2G));
1208 this->mTPCFastTransform = (o2::tpc::TPCFastTransformHelperO2::instance()->create(0));
1209 const auto& elParams = o2::tpc::ParameterElectronics::Instance();
1210 mTPCTimeBins2MUS = elParams.ZbinWidth;
1211 mMUS2TPCTimeBins = 1. / elParams.ZbinWidth;
1212 mTPCBin2MUS = elParams.ZbinWidth;
1213 const auto grp = o2::base::GRPGeomHelper::instance().getGRPECS();
1215 mITSROFrameLengthMUS = grp->isDetContinuousReadOut(o2::detectors::DetID::ITS)
1216 ? alpParamsITS.roFrameLengthInBC *
1217 o2::constants::lhc::LHCBunchSpacingMUS
1218 : alpParamsITS.roFrameLengthTrig *
1219 1.e-3;
1220
1222 mMFTROFrameLengthMUS = grp->isDetContinuousReadOut(o2::detectors::DetID::MFT)
1223 ? alpParamsMFT.roFrameLengthInBC *
1224 o2::constants::lhc::LHCBunchSpacingMUS
1225 : alpParamsMFT.roFrameLengthTrig *
1226 1.e-3;
1227
1229
1230 for (int i = 0; i < GID::Source::NSources; i++) {
1231 mTotalDataTypes[i] = 0;
1232 }
1233}
1234
1236{
1237 mTPCVDrift = v;
1238 if (v) {
1239 o2::tpc::TPCFastTransformHelperO2::instance()->updateCalibration(*mTPCFastTransform.get(), 0, v->corrFact,
1240 v->refVDrift, v->getTimeOffset());
1241 }
1242}
1243
1245{
1246 switch (dm) {
1247 case static_cast<uint8_t>(o2::aod::track::ITS):
1248 return GID::ITS;
1249 case static_cast<uint8_t>(o2::aod::track::TPC):
1250 return GID::TPC;
1251 case static_cast<uint8_t>(o2::aod::track::TRD):
1252 return GID::TRD;
1253 case static_cast<uint8_t>(o2::aod::track::TOF):
1254 return GID::TOF;
1255 case static_cast<uint8_t>(o2::aod::track::ITS) | static_cast<uint8_t>(o2::aod::track::TPC):
1256 return GID::ITSTPC;
1257 case static_cast<uint8_t>(o2::aod::track::TPC) | static_cast<uint8_t>(o2::aod::track::TOF):
1258 return GID::TPCTOF;
1259 case static_cast<uint8_t>(o2::aod::track::TPC) | static_cast<uint8_t>(o2::aod::track::TRD):
1260 return GID::TPCTRD;
1261 case static_cast<uint8_t>(o2::aod::track::ITS) | static_cast<uint8_t>(o2::aod::track::TPC) |
1262 static_cast<uint8_t>(o2::aod::track::TRD):
1263 return GID::ITSTPCTRD;
1264 case static_cast<uint8_t>(o2::aod::track::ITS) | static_cast<uint8_t>(o2::aod::track::TPC) |
1265 static_cast<uint8_t>(o2::aod::track::TOF):
1266 return GID::ITSTPCTOF;
1267 case static_cast<uint8_t>(o2::aod::track::TPC) | static_cast<uint8_t>(o2::aod::track::TRD) |
1268 static_cast<uint8_t>(o2::aod::track::TOF):
1269 return GID::TPCTRDTOF;
1270 default:
1271 return GID::ITSTPCTRDTOF;
1272 }
1273}
Reconstructed MID track.
int16_t charge
Definition RawEventData.h:5
uint64_t orbit
Definition RawEventData.h:6
uint64_t bc
Definition RawEventData.h:5
int16_t time
Definition RawEventData.h:4
int32_t i
Helper for geometry and GRP related CCDB requests.
Global index for barrel track: provides provenance (detectors combination), index in respective array...
Class to delimit start and end IR of certain time period.
Definition of the GeometryTGeo class.
std::vector< o2::its::TrackITS > tracks
Definition of the parameter class for the detector electronics.
uint32_t j
Definition RawData.h:0
Wrapper container for different reconstructed object types.
Definition of tools for track extrapolation.
Definition of the MCH track parameters for internal use.
Reference on ITS/MFT clusters set.
Referenc on track indices contributing to the vertex, with possibility chose tracks from specific sou...
static GRPGeomHelper & instance()
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
Definition Propagator.h:180
decltype(AbstractRef::MVAR< NBSrc >()) Src_t
Definition AbstractRef.h:53
const Mat3D & getMatrixT2G(int sensID) const
std::optional< T > getCalibratedCell(const T &inputcell) const
Calibrate single cell.
const TGeoHMatrix * GetMatrixForSuperModuleFromGeoManager(Int_t smod) const
Provides shift-rotation matrix for EMCAL from the TGeoManager.
std::tuple< int, int, int, int > GetCellIndex(Int_t absId) const
Get cell SM, module numbers from absolute ID number.
Definition Geometry.cxx:997
static Geometry * GetInstance()
Get geometry instance. It should have been set before.
Definition Geometry.cxx:154
math_utils::Point3D< double > RelPosCellInSModule(Int_t absId, Double_t distEf) const
Look to see what the relative position inside a given cell is for a recpoint.
void drawMFTTrack(GID gid, o2::track::TrackParFwd track, float trackTime)
std::unordered_map< std::size_t, std::vector< GID > > mPrimaryVertexTriggerGIDs
o2::mch::TrackParam forwardTrackToMCHTrack(const o2::track::TrackParFwd &track)
void drawTPCTRDTOF(GID gid, float trackTime)
void save(const std::string &jsonPath, const std::string &ext, int numberOfFiles, const std::string &receiverHostname, int receiverPort, int receiverTimeout, bool useOnlyFiles, bool useOnlySockets)
o2::event_visualisation::VisualisationEvent mEvent
const o2::tpc::VDriftCorrFact * mTPCVDrift
void drawTPC(GID gid, float trackTime, float dz=0.f)
float findLastMIDClusterPosition(const o2::mid::Track &track)
std::unordered_map< GID, unsigned int > mGIDTrackTime
o2::emcal::CellRecalibrator * mEMCALCalib
float findLastMCHClusterPosition(const o2::mch::TrackMCH &track)
void setTPCVDrift(const o2::tpc::VDriftCorrFact *v)
static std::vector< PNT > getTrackPoints(const o2::track::TrackPar &trc, float minR, float maxR, float maxStep, float minZ=-25000, float maxZ=25000)
void drawTRDClusters(const o2::trd::TrackTRD &trc)
void draw(std::size_t primaryVertexIdx, bool sortTracks)
const o2::globaltracking::RecoContainer * mRecoCont
void drawITSTPCTRD(GID gid, float trackTime, GID::Source source=GID::ITSTPCTRD)
void selectTracks(const CalibObjectsConst *calib, GID::mask_t maskCl, GID::mask_t maskTrk, GID::mask_t maskMatch)
double bcDiffToTFTimeMUS(const o2::InteractionRecord &ir)
void prepareITSClusters(const o2::itsmft::TopologyDictionary *dict)
void drawMFTMCHMID(GID gid, float trackTime)
void drawAODFwd(AODForwardTrack const &track, float trackTime)
void addTrackToEvent(const o2::track::TrackPar &tr, GID gid, float trackTime, float dz, GID::Source source=GID::NSources, float maxStep=4.f)
void drawForwardTrack(GID gid, mch::TrackParam track, float startZ, float endZ, float trackTime)
o2::itsmft::ClustersPerLayer< o2::BaseCluster< float > > mITSClustersArray
void prepareMFTClusters(const o2::itsmft::TopologyDictionary *dict)
void drawAODBarrel(AODBarrelTrack const &track, float trackTime)
void drawITSTPCTOF(GID gid, float trackTime, GID::Source source=GID::ITSTPCTOF)
std::vector< o2::BaseCluster< float > > mMFTClustersArray
void drawTPCClusters(GID gid, float trackTimeTB=-2.e9)
std::unordered_map< std::size_t, std::vector< GID > > mPrimaryVertexTrackGIDs
void drawTPCTRD(GID gid, float trackTime, GID::Source source=GID::TPCTRD)
void drawAODMFT(AODMFTTrack const &track, float trackTime)
const o2::vertexing::PVertexerParams * mPVParams
void drawGlobalPoint(const TVector3 &xyx, GID gid, float time)
void drawITSTPC(GID gid, float trackTime, GID::Source source=GID::ITSTPC)
void drawITSTPCTRDTOF(GID gid, float trackTime)
std::unordered_set< GID > mTotalAcceptedDataTypes
std::unordered_map< GID, std::size_t > mTotalDataTypes
void reduceNumberOfFiles(size_t filesInFolder) const
static VisualisationEventSerializer * getInstance(std::string ext)
virtual void toFile(const VisualisationEvent &event, Location &location)=0
static o2::dataformats::GlobalTrackID deserialize(unsigned seralizedValue)
VisualisationCluster & addCluster(const float *xyz)
VisualisationTrack * addTrack(VisualisationTrack::VisualisationTrackVO vo)
VisualisationCalo * addCalo(VisualisationCalo::VisualisationCaloVO vo)
void addPolyPoint(float x, float y, float z)
void lors2Mars(Int_t c, double x, double y, double *m, Int_t pl=kPc) const
Definition Param.h:176
static Param * instance()
Definition Param.cxx:438
static GeometryTGeo * Instance()
void fillMatrixCache(int mask) override
void beginLayer(int lr)
to be called once all the layers were filled
void init(int nLr)
< prepare for filling nLr layer slots, discarding the previous content
Bracket getOverlap(const Bracket< T > &other) const
Definition Bracket.h:226
Relation isOutside(const Bracket< T > &t) const
Definition Bracket.h:232
static void setField()
static bool extrapToZCov(TrackParam &trackParam, double zEnd, bool updatePropagator=false)
MCH track external format.
Definition TrackMCH.h:34
int getNClusters() const
get the number of clusters attached to the track
Definition TrackMCH.h:106
track parameters for internal use
Definition TrackParam.h:34
void fillMatrixCache(Int_t mask) override
static GeometryTGeo * Instance()
const int getNumberOfPoints() const
Definition TrackMFT.h:55
This class defines the MID track.
Definition Track.h:30
void local2Global(char module, float x, float z, TVector3 &globaPos) const
Definition Geometry.cxx:234
static void absIdToRelPosInModule(short absId, float &x, float &z)
Definition Geometry.cxx:198
static bool absToRelNumbering(short absId, char *relid)
Definition Geometry.cxx:65
static Geometry * GetInstance()
Definition Geometry.h:63
static TPCFastTransformHelperO2 * instance()
Singleton.
std::unique_ptr< TPCFastTransform > create(int64_t TimeStamp)
_______________ Main functionality ________________________
int updateCalibration(TPCFastTransform &fastTransform, int64_t TimeStamp, float vDriftFactor=1.f, float vDriftRef=0.f, float driftTimeOffset=0.f)
Updates the transformation with the new time stamp.
void propagateParamToZlinear(double zEnd)
Definition TrackFwd.cxx:34
Double_t getEta() const
Definition TrackFwd.h:96
Double_t getPhi() const
Definition TrackFwd.h:65
Double_t getTheta() const
Definition TrackFwd.h:95
void setParameters(const SMatrix5 &parameters)
set track parameters
Definition TrackFwd.h:117
Double_t getZ() const
return Z coordinate (cm)
Definition TrackFwd.h:55
Double_t getY() const
Definition TrackFwd.h:61
Double_t getCharge() const
return the charge (assumed forward motion)
Definition TrackFwd.h:105
Double_t getX() const
Definition TrackFwd.h:58
void setZ(Double_t z)
set Z coordinate (cm)
Definition TrackFwd.h:57
bool match(const std::vector< std::string > &queries, const char *pattern)
Definition dcs-ccdb.cxx:229
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
GLint GLenum GLint x
Definition glcorearb.h:403
GLenum src
Definition glcorearb.h:1767
const GLdouble * v
Definition glcorearb.h:832
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLsizei GLsizei GLchar * source
Definition glcorearb.h:798
GLint y
Definition glcorearb.h:270
GLenum const GLfloat * params
Definition glcorearb.h:272
GLintptr offset
Definition glcorearb.h:660
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
Definition glcorearb.h:5034
GLint location
Definition glcorearb.h:800
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat maxZ
Definition glcorearb.h:2910
GLbitfield GLuint64 timeout
Definition glcorearb.h:1573
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
GLfloat GLfloat minZ
Definition glcorearb.h:2910
@ HIGH_GAIN
High gain channel.
Definition Constants.h:35
@ LOW_GAIN
Low gain channel.
Definition Constants.h:34
std::array< float, 3 > PNT
constexpr int MaxITSLayers
void convertCompactClusters(gsl::span< const itsmft::CompClusterExt > clusters, gsl::span< const unsigned char >::iterator &pattIt, std::vector< o2::BaseCluster< float > > &output, const itsmft::TopologyDictionary *dict)
convert compact clusters to 3D spacepoints
Definition IOUtils.cxx:35
std::tuple< float, float > rotateZ(float xL, float yL, float snAlp, float csAlp)
Definition Utils.h:162
float sector2Angle(int sect)
Definition Utils.h:193
void convertCompactClusters(gsl::span< const itsmft::CompClusterExt > clusters, gsl::span< const unsigned char >::iterator &pattIt, std::vector< o2::BaseCluster< float > > &output, const itsmft::TopologyDictionary *dict)
convert compact clusters to 3D spacepoints into std::vector<o2::BaseCluster<float>>
Definition IOUtils.cxx:111
TrackParF TrackPar
Definition Track.h:29
std::string asString() const
int64_t differenceInBC(const InteractionRecord &other) const
const o2::dataformats::MatchInfoTOF & getTPCTOFMatch(GTrackID id) const
const o2::tpc::TrackTPC & getTPCTrack(GTrackID id) const
gsl::span< const o2::trd::CalibratedTracklet > getTRDCalibratedTracklets() const
const o2::mch::TrackMCH & getMCHTrack(GTrackID gid) const
auto getMFTClustersPatterns(int layer=0) const
auto getTPCTRDTrack(GTrackID id) const
const o2::tpc::ClusterNativeAccess & getTPCClusters() const
auto getITSClustersROFRecords(int layer=0) const
void createTracksVariadic(T creator, GTrackID::mask_t srcSel=GTrackID::getSourcesMask("all")) const
const o2::itsmft::TrkClusRef & getITSABRef(GTrackID gid) const
auto getITSClustersPatterns(int layer=0) const
const o2::dataformats::TrackTPCITS & getITSTPCTOFTrack(GTrackID id) const
const o2::dataformats::TrackTPCTOF & getTPCTOFTrack(GTrackID gid) const
const o2::mid::Track & getMIDTrack(GTrackID gid) const
const o2::dataformats::TrackTPCITS & getTPCITSTrack(GTrackID gid) const
const o2::mft::TrackMFT & getMFTTrack(GTrackID gid) const
const o2::dataformats::PrimaryVertex & getPrimaryVertex(int i) const
const o2::its::TrackITS & getITSTrack(GTrackID gid) const
auto getMFTClustersROFRecords(int layer=0) const
auto getITSTPCTRDTrack(GTrackID id) const
auto getMFTClusters(int layer=0) const
auto getITSClusters(int layer=0) const
gsl::span< const o2::trd::Tracklet64 > getTRDTracklets() const
const o2::dataformats::MatchInfoTOF & getTOFMatch(GTrackID id) const
const o2::dataformats::GlobalFwdTrack & getGlobalFwdTrack(GTrackID gid) const
float getTimeOffset() const
float nSigmaTimeTrack
define track time bracket as +- this number of sigmas of its time resolution
float timeMarginTrackTime
additive marginal error in \mus to track time bracket
o2::InteractionRecord ir(0, 0)
std::vector< Cluster > clusters
std::vector< Cell > cells
std::vector< int > row