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{
621 const auto& ITSClusterROFRec = mRecoCont->getITSClustersROFRecords();
622 const auto& clusITS = mRecoCont->getITSClusters();
623 if (clusITS.size() && ITSClusterROFRec.size()) {
624 const auto& patterns = mRecoCont->getITSClustersPatterns();
625 auto pattIt = patterns.begin();
626 mITSClustersArray.reserve(clusITS.size());
628 }
629}
630
632 const o2::itsmft::TopologyDictionary* dict) // do we also have something as ITS...dict?
633{
634 const auto& MFTClusterROFRec = this->mRecoCont->getMFTClustersROFRecords();
635 const auto& clusMFT = this->mRecoCont->getMFTClusters();
636 if (clusMFT.size() && MFTClusterROFRec.size()) {
637 const auto& patterns = this->mRecoCont->getMFTClustersPatterns();
638 auto pattIt = patterns.begin();
639 this->mMFTClustersArray.reserve(clusMFT.size());
641 }
642}
643
645{
647 const auto& trig = mRecoCont->getHMPClusterTriggers()[gid.getIndex()];
648 const auto& clusters = mRecoCont->getHMPClusters();
649
650 auto bc = trig.getBc();
651 auto orbit = trig.getOrbit();
652 auto time = o2::InteractionTimeRecord::bc2ns(bc, orbit); // in ns absolute time
653
654 for (int j = trig.getFirstEntry(); j <= trig.getLastEntry(); j++) {
655 auto cluster = clusters[j];
656 auto module = cluster.ch();
657 double x = cluster.x();
658 double y = cluster.y();
659
660 TVector3 vec3 = pParam->lors2Mars(module, x, y);
661 drawGlobalPoint(vec3, gid, time);
662 }
663}
664
666{
667 const auto& cells = mRecoCont->getPHOSCells();
668
669 const auto& trig = mRecoCont->getPHOSTriggers()[gid.getIndex()];
670 const auto time = bcDiffToTFTimeMUS(trig.getBCData());
671 const gsl::span cellsForTrigger(cells.data() + trig.getFirstEntry(), trig.getNumberOfObjects());
672
673 for (const auto& cell : cellsForTrigger) {
674 std::array<char, 3> relativeLocalPositionInModule; // relative (local) position within module
675 float x, z;
676 o2::phos::Geometry::absToRelNumbering(cell.getAbsId(), relativeLocalPositionInModule.data());
678 TVector3 gPos;
679
680 // convert local position in module to global position in ALICE including actual mis-aslignment read with GetInstance("Run3")
681 this->mPHOSGeom->local2Global(relativeLocalPositionInModule[0], x, z, gPos);
682
683 auto vCalo = mEvent.addCalo({.time = static_cast<float>(time),
684 .energy = cell.getEnergy(),
685 .phi = (float)gPos.Phi(),
686 .eta = (float)gPos.Eta(),
687 .PID = 0,
688 .gid = gid});
689 }
690}
691
693{
694 const auto& cells = mRecoCont->getEMCALCells();
695
696 const auto& trig = mRecoCont->getEMCALTriggers()[gid.getIndex()];
697 const auto time = bcDiffToTFTimeMUS(trig.getBCData());
698 const gsl::span cellsForTrigger(cells.data() + trig.getFirstEntry(), trig.getNumberOfObjects());
699 const auto& conf = EveConfParam::Instance();
700
701 for (const auto& cell : cellsForTrigger) {
702 if (!(cell.getType() == o2::emcal::ChannelType_t::HIGH_GAIN ||
703 cell.getType() == o2::emcal::ChannelType_t::LOW_GAIN)) {
704 // Select FEE cells (excluding LEDMON or TRU cells)
705 continue;
706 }
707 auto cellTime = cell.getTimeStamp();
708 auto cellEnergy = cell.getEnergy();
709 if (mEMCALCalib) {
710 // try to recalibrate cell in case calibration is available (bad channel removal, energy calibration, time calibration)
711 auto calibCell = mEMCALCalib->getCalibratedCell(cell);
712 if (!calibCell) {
713 // cell was rejected by bad channel calib
714 continue;
715 }
716 cellTime = calibCell->getTimeStamp();
717 cellEnergy = calibCell->getEnergy();
718 }
719 if (std::abs(cellTime) > conf.EMCCellTimeMax) {
720 // cell rejected by time cut (pileup or noise)
721 continue;
722 }
723 if (cellEnergy < conf.EMCCellEnergyMin) {
724 // cell rejected by energy cut (rejection of soft cells)
725 continue;
726 }
727 const auto id = cell.getTower();
728 // Point3D with x,y,z coordinates of cell with absId inside SM
729 const auto relPosCell = this->mEMCALGeom->RelPosCellInSModule(id);
730 std::array<double, 3> rPos{relPosCell.X(), relPosCell.Y(), relPosCell.Z()};
731 std::array<double, 3> gPos{};
732
733 // supermodule ID, module number, index of cell in module in phi, index of cell in module in eta
734 const auto& [sm_id, module_number, index_module_phi, index_module_eta] = this->mEMCALGeom->GetCellIndex(id);
735 const auto matrix = this->mEMCALGeom->GetMatrixForSuperModuleFromGeoManager(sm_id);
736 matrix->LocalToMaster(rPos.data(), gPos.data());
737 TVector3 vPos(gPos.data());
738
739 auto vCalo = mEvent.addCalo({.time = static_cast<float>(time),
740 .energy = cellEnergy,
741 .phi = (float)vPos.Phi(),
742 .eta = (float)vPos.Eta(),
743 .PID = 0,
744 .gid = gid});
745 }
746}
747
749{
750 // LOG(info) << "EveWorkflowHelper::drawITSTPC " << gid;
751 const auto& track = mRecoCont->getTPCITSTrack(gid);
752 addTrackToEvent(track, gid, trackTime, 0., source);
753 drawITSClusters(track.getRefITS()); // trackTime
754 drawTPCClusters(track.getRefTPC(), trackTime * mMUS2TPCTimeBins);
755}
756
758{
759 const auto& track = mRecoCont->getITSTPCTOFTrack(gid);
760 addTrackToEvent(track, gid, trackTime, 0., source);
761 drawITSClusters(track.getRefITS()); // trackTime
762 drawTPCClusters(track.getRefTPC(), trackTime * mMUS2TPCTimeBins);
763 drawTOFClusters(gid);
764}
765
767{
768 // LOG(info) << "EveWorkflowHelper::drawTPCTRD " << gid;
769 const auto& tpcTrdTrack = mRecoCont->getTPCTRDTrack<o2::trd::TrackTRD>(gid);
770 addTrackToEvent(tpcTrdTrack, gid, trackTime, 0., source);
771 drawTPCClusters(tpcTrdTrack.getRefGlobalTrackId(), trackTime * mMUS2TPCTimeBins);
772 drawTRDClusters(tpcTrdTrack); // tracktime
773}
774
776{
777 // LOG(info) << "EveWorkflowHelper::drawITSTPCTRD " << gid;
778 const auto& itsTpcTrdTrack = mRecoCont->getITSTPCTRDTrack<o2::trd::TrackTRD>(gid);
779 drawITSTPC(itsTpcTrdTrack.getRefGlobalTrackId(), trackTime, source);
780 drawTRDClusters(itsTpcTrdTrack); // trackTime
781}
782
783void EveWorkflowHelper::drawITSTPCTRDTOF(GID gid, float trackTime)
784{
785 // LOG(info) << "EveWorkflowHelper::drawITSTPCTRDTOF " << gid;
786 const auto& match = mRecoCont->getITSTPCTRDTOFMatches()[gid.getIndex()];
787 auto gidITSTPCTRD = match.getTrackRef();
788 drawITSTPCTRD(gidITSTPCTRD, trackTime, GID::ITSTPCTRDTOF);
789 drawTOFClusters(gid); // trackTime
790}
791
792void EveWorkflowHelper::drawTPCTRDTOF(GID gid, float trackTime)
793{
794 // LOG(info) << "EveWorkflowHelper::drawTPCTRDTOF " << gid;
795 const auto& match = mRecoCont->getTPCTRDTOFMatches()[gid.getIndex()];
796 auto gidTPCTRD = match.getTrackRef();
797 drawTPCTRD(gidTPCTRD, trackTime, GID::TPCTRDTOF);
798 drawTOFClusters(gid); // trackTime
799}
800
801void EveWorkflowHelper::drawTPCTOF(GID gid, float trackTime)
802{
803 // LOG(info) << "EveWorkflowHelper::drawTPCTRDTOF " << gid;
804 const auto& trTPCTOF = mRecoCont->getTPCTOFTrack(gid);
805 const auto& match = mRecoCont->getTPCTOFMatch(gid.getIndex());
806 addTrackToEvent(trTPCTOF, gid, trackTime, 0);
807 drawTPCClusters(match.getTrackRef(), trackTime * mMUS2TPCTimeBins);
808 drawTOFClusters(gid); // trackTime
809}
810
811void EveWorkflowHelper::drawMFTMCH(GID gid, float trackTime)
812{
813 const auto& trMFTMCH = mRecoCont->getGlobalFwdTrack(gid);
814
815 const auto& trackParam = forwardTrackToMCHTrack(trMFTMCH);
816
817 const auto mchGID = GID{static_cast<unsigned int>(trMFTMCH.getMCHTrackID()), GID::MCH};
818
819 const auto& mchTrack = mRecoCont->getMCHTrack(mchGID);
820
821 const auto endZ = findLastMCHClusterPosition(mchTrack);
822
823 drawForwardTrack(gid, trackParam, mftZPositions.front(), endZ, trackTime);
824
825 drawMFTClusters(GID{static_cast<unsigned int>(trMFTMCH.getMFTTrackID()), GID::MFT}); // tracktime
826 drawMCHClusters(mchGID); // tracktime
827}
828
829void EveWorkflowHelper::drawMFTMCHMID(GID gid, float trackTime)
830{
831 const auto& trMFTMCHMID = mRecoCont->getGlobalFwdTrack(GID{gid.getIndex(), GID::MFTMCH});
832
833 const auto& trackParam = forwardTrackToMCHTrack(trMFTMCHMID);
834
835 const auto midGID = GID{static_cast<unsigned int>(trMFTMCHMID.getMIDTrackID()), GID::MID};
836
837 const auto& midTrack = mRecoCont->getMIDTrack(midGID);
838
839 const auto endZ = findLastMIDClusterPosition(midTrack);
840
841 drawForwardTrack(gid, trackParam, mftZPositions.front(), endZ, trackTime);
842
843 drawMFTClusters(GID{static_cast<unsigned int>(trMFTMCHMID.getMFTTrackID()), GID::MFT}); // trackTime
844 drawMCHClusters(GID{static_cast<unsigned int>(trMFTMCHMID.getMCHTrackID()), GID::MCH}); // trackTime
845 drawMIDClusters(midGID); // tracktime
846}
847
848void EveWorkflowHelper::drawMCHMID(GID gid, float trackTime)
849{
850 const auto& match = mRecoCont->getMCHMIDMatches()[gid.getIndex()];
851 const auto& mchTrack = mRecoCont->getMCHTrack(match.getMCHRef());
852 const auto& midTrack = mRecoCont->getMIDTrack(match.getMIDRef());
853
854 auto trackParam = mch::TrackParam(mchTrack.getZ(), mchTrack.getParameters(), mchTrack.getCovariances());
855
856 const auto endZ = findLastMIDClusterPosition(midTrack);
857
858 drawForwardTrack(gid, trackParam, trackParam.getZ(), endZ, trackTime);
859
860 drawMCHClusters(match.getMCHRef()); // tracktime
861 drawMIDClusters(match.getMIDRef()); // tracktime
862}
863
865{
866 const std::array<float, 5> arraypar = {
867 track.y(), track.z(), track.snp(),
868 track.tgl(), track.signed1Pt()};
869
870 const auto tr = o2::track::TrackPar(track.x(), track.alpha(), arraypar);
871
872 addTrackToEvent(tr, GID{0, detectorMapToGIDSource(track.detectorMap())}, trackTime, 0.);
873}
874
875void EveWorkflowHelper::drawAODMFT(AODMFTTrack const& track, float trackTime)
876{
877 auto tr = o2::track::TrackParFwd();
878
879 tr.setZ(track.z());
880 tr.setParameters({track.x(), track.y(), track.phi(), track.tgl(), track.signed1Pt()});
882}
883
884void EveWorkflowHelper::drawAODFwd(AODForwardTrack const& track, float trackTime)
885{
886 o2::track::TrackParFwd trackFwd;
887 trackFwd.setZ(track.z());
888 trackFwd.setParameters({track.x(), track.y(), track.phi(), track.tgl(), track.signed1Pt()});
889
890 const auto trackParam = forwardTrackToMCHTrack(trackFwd);
891
892 float endZ = 0;
893 GID gid;
894
895 switch (track.trackType()) {
898 gid = GID::MFTMCHMID;
899 endZ = midZPositions.back();
900 break;
902 gid = GID::MFTMCH;
903 endZ = mchZPositions.back();
904 break;
906 gid = GID::MCHMID;
907 endZ = midZPositions.back();
908 break;
910 gid = GID::MCH;
911 endZ = mchZPositions.back();
912 break;
913 }
914
915 drawForwardTrack(gid, trackParam, trackParam.getZ(), endZ, trackTime);
916}
917
919{
920 tr.propagateParamToZlinear(mftZPositions.front()); // Fix the track starting position.
921
922 auto vTrack = mEvent.addTrack({.time = static_cast<float>(trackTime),
923 .charge = (int)tr.getCharge(),
925 .startXYZ = {(float)tr.getX(), (float)tr.getY(), (float)tr.getZ()},
926 .phi = (float)tr.getPhi(),
927 .theta = (float)tr.getTheta(),
928 .eta = (float)tr.getEta(),
929 .gid = gid});
930
931 for (auto zPos : mftZPositions) {
933 vTrack->addPolyPoint((float)tr.getX(), (float)tr.getY(), (float)tr.getZ());
934 }
935}
936
937void EveWorkflowHelper::drawForwardTrack(GID gid, mch::TrackParam track, float startZ, float endZ, float trackTime)
938{
939 auto vTrack = mEvent.addTrack({.time = static_cast<float>(trackTime),
940 .charge = 0,
942 .startXYZ = {
943 (float)track.getNonBendingCoor(), (float)track.getBendingCoor(),
944 (float)track.getZ()},
945 .phi = (float)0,
946 .theta = (float)0,
947 .eta = (float)0,
948 .gid = gid});
949
950 static constexpr auto stepDensity = 50.; // one vertex per 50 cm should be sufficiently dense
951
952 const auto nSteps = static_cast<std::size_t>(std::abs(endZ - startZ) / stepDensity);
953
954 const auto dZ = (endZ - startZ) / nSteps;
955
956 for (std::size_t i = 0; i < nSteps; ++i) {
957 const auto z = startZ + i * dZ;
958 vTrack->addPolyPoint(track.getNonBendingCoor(), track.getBendingCoor(), z);
960 }
961}
962
964{
965 auto tOFClustersArray = mRecoCont->getTOFClusters();
966 if (!gid.includesDet(o2::dataformats::GlobalTrackID::Source::TOF)) {
967 return;
968 }
970 int tofcl = match.getIdxTOFCl();
971 int sector = tOFClustersArray[tofcl].getSector();
972 float x = tOFClustersArray[tofcl].getX();
973 float y = tOFClustersArray[tofcl].getY();
974 float z = tOFClustersArray[tofcl].getZ();
975
976 // rotation
977 float alpha = o2::math_utils::sector2Angle(sector);
978 float xyzGlb[3];
979 xyzGlb[0] = x * cos(alpha) - y * sin(alpha);
980 xyzGlb[1] = y * cos(alpha) + x * sin(alpha);
981 xyzGlb[2] = z;
982 drawPoint(xyzGlb);
983}
984
985void EveWorkflowHelper::drawITSClusters(GID gid) // float trackTime
986{
987 if (gid.getSource() == GID::ITS) {
988 // this is for for full standalone tracks
989 const auto& trc = mRecoCont->getITSTrack(gid);
990 auto refs = mRecoCont->getITSTracksClusterRefs();
991 int ncl = trc.getNumberOfClusters();
992 int offset = trc.getFirstClusterEntry();
993 for (int icl = 0; icl < ncl; icl++) {
994 const auto& pnt = mITSClustersArray[refs[icl + offset]];
995 const auto glo = mITSGeom->getMatrixT2G(pnt.getSensorID()) * pnt.getXYZ();
996 float xyz[] = {glo.X(), glo.Y(), glo.Z()};
997 drawPoint(xyz); // trackTime;
998 }
999 } else if (gid.getSource() == GID::ITSAB) {
1000 // this is for ITS tracklets from ITS-TPC afterburner
1001 const auto& trc = mRecoCont->getITSABRef(gid);
1002 const auto& refs = mRecoCont->getITSABClusterRefs();
1003 int ncl = trc.getNClusters();
1004 int offset = trc.getFirstEntry();
1005 for (int icl = 0; icl < ncl; icl++) {
1006 const auto& pnt = mITSClustersArray[refs[icl + offset]];
1007 const auto glo = mITSGeom->getMatrixT2G(pnt.getSensorID()) * pnt.getXYZ();
1008 float xyz[] = {glo.X(), glo.Y(), glo.Z()};
1009 drawPoint(xyz); //, trackTime
1010 }
1011 }
1012}
1013
1014// TPC cluseters for given TPC track (gid)
1015void EveWorkflowHelper::drawTPCClusters(GID gid, float trackTimeTB)
1016{
1017 const auto& trc = mRecoCont->getTPCTrack(gid);
1018 auto mTPCTracksClusIdx = mRecoCont->getTPCTracksClusterRefs();
1019 auto mTPCClusterIdxStruct = &mRecoCont->getTPCClusters();
1020 if (trackTimeTB < -1e9) {
1021 trackTimeTB = trc.getTime0();
1022 }
1023 // store the TPC cluster positions
1024 for (int iCl = trc.getNClusterReferences(); iCl--;) {
1025 uint8_t sector, row;
1026 const auto& clTPC = trc.getCluster(mTPCTracksClusIdx, iCl, *mTPCClusterIdxStruct, sector, row);
1027
1028 std::array<float, 3> xyz;
1029 this->mTPCFastTransform->TransformIdeal(sector, row, clTPC.getPad(), clTPC.getTime(), xyz[0], xyz[1], xyz[2],
1030 trackTimeTB); // in sector coordinate
1032 sector % o2::tpc::SECTORSPERSIDE)); // lab coordinate (global)
1034 xyz.data()); // trackTimeTB / mMUS2TPCTimeBins
1035 }
1036}
1037
1038void EveWorkflowHelper::drawMFTClusters(GID gid) // float trackTime
1039{
1040 const auto& mftTrack = mRecoCont->getMFTTrack(gid);
1041 auto noOfClusters = mftTrack.getNumberOfPoints(); // number of clusters in MFT Track
1042 auto offset = mftTrack.getExternalClusterIndexOffset(); // first external cluster index offset:
1043 auto refs = mRecoCont->getMFTTracksClusterRefs(); // list of references to clusters, offset:offset+no
1044 for (int icl = noOfClusters - 1; icl > -1; --icl) {
1045 const auto& thisCluster = mMFTClustersArray[refs[offset + icl]];
1046 float xyz[] = {thisCluster.getX(), thisCluster.getY(), thisCluster.getZ()};
1047 drawPoint(xyz); // tracktime
1048 }
1049}
1050
1051void EveWorkflowHelper::drawTPC(GID gid, float trackTime, float dz)
1052{
1053 const auto& tr = mRecoCont->getTPCTrack(gid);
1054
1056 return;
1057 }
1058
1059 addTrackToEvent(tr, gid, trackTime, dz, GID::TPC);
1060 float clTime0 = EveConfParam::Instance().PVMode
1061 ? trackTime * mMUS2TPCTimeBins
1062 : -2e9; // in PVMode use supplied real time converted to TB, otherwise pass dummy time to use tpcTrack.getTime0
1063 drawTPCClusters(gid, clTime0); // trackTime
1064}
1065
1066void EveWorkflowHelper::drawITS(GID gid, float trackTime)
1067{
1068 const auto& tr = mRecoCont->getITSTrack(gid);
1069 addTrackToEvent(tr, gid, trackTime, 0.f, GID::ITS);
1070
1071 drawITSClusters(gid); // tracktime
1072}
1073
1074void EveWorkflowHelper::drawMFT(GID gid, float trackTime)
1075{
1076 // LOG(info) << "EveWorkflowHelper::drawMFT " << gid;
1077 auto tr = mRecoCont->getMFTTrack(gid);
1078
1079 drawMFTTrack(gid, tr, trackTime);
1080 drawMFTClusters(gid); // tracktime
1081}
1082
1083void EveWorkflowHelper::drawMCH(GID gid, float trackTime)
1084{
1085 // LOG(info) << "EveWorkflowHelper::drawMCH " << gid;
1086 const auto& track = mRecoCont->getMCHTrack(gid);
1087 auto trackParam = mch::TrackParam(track.getZ(), track.getParameters(), track.getCovariances());
1088
1089 const auto endZ = findLastMCHClusterPosition(track);
1090
1091 drawForwardTrack(gid, trackParam, track.getZ(), endZ, trackTime);
1092
1093 drawMCHClusters(gid); // tracktime
1094}
1095
1097{
1098 const auto& mchTrack = mRecoCont->getMCHTrack(gid);
1099 auto noOfClusters = mchTrack.getNClusters(); // number of clusters in MCH Track
1100 auto offset = mchTrack.getFirstClusterIdx(); // first external cluster index offset:
1101 const auto& mchClusters = mRecoCont->getMCHTrackClusters(); // list of references to clusters, offset:offset+no
1102 for (int icl = noOfClusters - 1; icl > -1; --icl) {
1103 const auto& cluster = mchClusters[offset + icl];
1104 float glo[] = {cluster.x, cluster.y, cluster.z};
1105 drawPoint(glo); // tracktime
1106 }
1107}
1108
1109void EveWorkflowHelper::drawMID(GID gid, float trackTime)
1110{
1111 // LOG(info) << "EveWorkflowHelper::drawMID --------------------------------" << gid;
1112 const auto& midTrack = mRecoCont->getMIDTrack(gid); // MID track
1113 const auto& midClusters = mRecoCont->getMIDTrackClusters(); // MID clusters
1114
1115 auto vTrack = mEvent.addTrack({.time = static_cast<float>(trackTime),
1116 .charge = (int)0,
1117 .PID = o2::track::PID::Muon,
1118 .startXYZ = {
1119 (float)midTrack.getPositionX(), (float)midTrack.getPositionY(),
1120 (float)midTrack.getPositionZ()},
1121 .phi = (float)0,
1122 .theta = (float)0,
1123 .eta = (float)0,
1124 .gid = gid});
1125
1126 for (int ich = 0; ich < 4; ++ich) {
1127 auto icl = midTrack.getClusterMatched(ich);
1128 if (icl >= 0) {
1129 auto& cluster = midClusters[icl];
1130 vTrack->addPolyPoint(cluster.xCoor, cluster.yCoor, cluster.zCoor);
1131 }
1132 }
1133 drawMIDClusters(gid); // tracktime
1134}
1135
1136void EveWorkflowHelper::drawMIDClusters(GID gid) // , float trackTime
1137{
1138 const auto& midTrack = mRecoCont->getMIDTrack(gid); // MID track
1139 const auto& midClusters = mRecoCont->getMIDTrackClusters(); // MID clusters
1140
1141 for (int ich = 0; ich < 4; ++ich) {
1142 auto icl = midTrack.getClusterMatched(ich);
1143 if (icl >= 0) {
1144 auto& cluster = midClusters[icl];
1145 float glo[] = {cluster.xCoor, cluster.yCoor, cluster.zCoor};
1146 drawPoint(glo); // tracktime
1147 }
1148 }
1149}
1150
1151void EveWorkflowHelper::drawTRDClusters(const o2::trd::TrackTRD& tpcTrdTrack) // tracktime
1152{
1153 const auto& tpcTrdTracks = mRecoCont->getTPCTRDTracks<o2::trd::TrackTRD>();
1154 const auto& tpcTrdTriggerRecords = mRecoCont->getTPCTRDTriggers();
1155 const auto& itsTpcTrdTracks = mRecoCont->getITSTPCTRDTracks<o2::trd::TrackTRD>();
1156 const auto& itsTpcTrdTriggerRecords = mRecoCont->getITSTPCTRDTriggers();
1157 const auto& trdTracklets = mRecoCont->getTRDTracklets();
1158 const auto& trdCalibratedTracklets = mRecoCont->getTRDCalibratedTracklets();
1159
1160 for (int iLayer = 0; iLayer < 6; ++iLayer) {
1161 if (tpcTrdTrack.getTrackletIndex(iLayer) >= 0) {
1162 // there is a TRD space point in this layer
1163 const auto& tracklet = trdTracklets[tpcTrdTrack.getTrackletIndex(iLayer)];
1164 const auto& spacePoint = trdCalibratedTracklets[tpcTrdTrack.getTrackletIndex(iLayer)];
1165 // get position in sector coordinates from the spacePoint
1166 float x = spacePoint.getX(), y = spacePoint.getY(), z = spacePoint.getZ();
1167 // in order to rotate the space points into the global coordinate system we need to know the TRD chamber number
1168 int iChamber = tracklet.getDetector();
1169 // with that we can determine the sector and thus the rotation angle alpha
1170 int sector = iChamber / 30;
1171 float alpha = o2::math_utils::sector2Angle(sector);
1172 // now the rotation is simply
1173 float glo[3];
1174 glo[0] = x * cos(alpha) - y * sin(alpha);
1175 glo[1] = y * cos(alpha) + x * sin(alpha);
1176 glo[2] = z;
1177 drawPoint(glo); // tracktime
1178 }
1179 }
1180}
1181
1183{
1184 const auto& conf = EveConfParam::Instance();
1185 if (conf.timeMinMax[0] >= 0.f && conf.timeMinMax[0] < conf.timeMinMax[1]) {
1186 mUseTimeBracket = true;
1187 mTimeBracket = {conf.timeMinMax[0], conf.timeMinMax[1]};
1188 }
1189 if (conf.TPCEtaAbsMax > 0.f) {
1190 mUseEtaBracketTPC = true;
1191 mEtaBracketTPC = {-conf.TPCEtaAbsMax, conf.TPCEtaAbsMax};
1192 }
1203 this->mTPCFastTransform = (o2::tpc::TPCFastTransformHelperO2::instance()->create(0));
1204 const auto& elParams = o2::tpc::ParameterElectronics::Instance();
1205 mTPCTimeBins2MUS = elParams.ZbinWidth;
1206 mMUS2TPCTimeBins = 1. / elParams.ZbinWidth;
1207 mTPCBin2MUS = elParams.ZbinWidth;
1208 const auto grp = o2::base::GRPGeomHelper::instance().getGRPECS();
1210 mITSROFrameLengthMUS = grp->isDetContinuousReadOut(o2::detectors::DetID::ITS)
1211 ? alpParamsITS.roFrameLengthInBC *
1213 : alpParamsITS.roFrameLengthTrig *
1214 1.e-3;
1215
1217 mMFTROFrameLengthMUS = grp->isDetContinuousReadOut(o2::detectors::DetID::MFT)
1218 ? alpParamsMFT.roFrameLengthInBC *
1220 : alpParamsMFT.roFrameLengthTrig *
1221 1.e-3;
1222
1224
1225 for (int i = 0; i < GID::Source::NSources; i++) {
1226 mTotalDataTypes[i] = 0;
1227 }
1228}
1229
1231{
1232 mTPCVDrift = v;
1233 if (v) {
1234 o2::tpc::TPCFastTransformHelperO2::instance()->updateCalibration(*mTPCFastTransform.get(), 0, v->corrFact,
1235 v->refVDrift, v->getTimeOffset());
1236 }
1237}
1238
1240{
1241 switch (dm) {
1242 case static_cast<uint8_t>(o2::aod::track::ITS):
1243 return GID::ITS;
1244 case static_cast<uint8_t>(o2::aod::track::TPC):
1245 return GID::TPC;
1246 case static_cast<uint8_t>(o2::aod::track::TRD):
1247 return GID::TRD;
1248 case static_cast<uint8_t>(o2::aod::track::TOF):
1249 return GID::TOF;
1250 case static_cast<uint8_t>(o2::aod::track::ITS) | static_cast<uint8_t>(o2::aod::track::TPC):
1251 return GID::ITSTPC;
1252 case static_cast<uint8_t>(o2::aod::track::TPC) | static_cast<uint8_t>(o2::aod::track::TOF):
1253 return GID::TPCTOF;
1254 case static_cast<uint8_t>(o2::aod::track::TPC) | static_cast<uint8_t>(o2::aod::track::TRD):
1255 return GID::TPCTRD;
1256 case static_cast<uint8_t>(o2::aod::track::ITS) | static_cast<uint8_t>(o2::aod::track::TPC) |
1257 static_cast<uint8_t>(o2::aod::track::TRD):
1258 return GID::ITSTPCTRD;
1259 case static_cast<uint8_t>(o2::aod::track::ITS) | static_cast<uint8_t>(o2::aod::track::TPC) |
1260 static_cast<uint8_t>(o2::aod::track::TOF):
1261 return GID::ITSTPCTOF;
1262 case static_cast<uint8_t>(o2::aod::track::TPC) | static_cast<uint8_t>(o2::aod::track::TRD) |
1263 static_cast<uint8_t>(o2::aod::track::TOF):
1264 return GID::TPCTRDTOF;
1265 default:
1266 return GID::ITSTPCTRDTOF;
1267 }
1268}
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.
Load pulled clusters, for a given read-out-frame, in a dedicated container.
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:143
decltype(AbstractRef::MVAR< NBSrc >()) Src_t
Definition AbstractRef.h:54
static constexpr ID ITS
Definition DetID.h:63
static constexpr ID MFT
Definition DetID.h:71
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.
static Geometry * GetInstance()
Get geometry instance. It should have been set before.
Definition Geometry.cxx:213
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)
std::vector< o2::BaseCluster< float > > mITSClustersArray
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)
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
Bracket getOverlap(const Bracket< T > &other) const
Definition Bracket.h:224
Relation isOutside(const Bracket< T > &t) const
Definition Bracket.h:230
static void setField()
static bool extrapToZCov(TrackParam &trackParam, double zEnd, bool updatePropagator=false)
MCH track external format.
Definition TrackMCH.h:34
int getFirstClusterIdx() const
get the index of the first cluster attached to the track
Definition TrackMCH.h:108
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
Double_t getNonBendingCoor() const
return non bending coordinate (cm)
Definition TrackParam.h:51
Double_t getZ() const
return Z coordinate (cm)
Definition TrackParam.h:47
Double_t getBendingCoor() const
return bending coordinate (cm)
Definition TrackParam.h:59
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
int getClusterMatched(int chamber) const
Definition Track.cxx:47
float getPositionZ() const
Gets the track z position.
Definition Track.h:37
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
int updateCalibration(TPCFastTransform &transform, Long_t TimeStamp, float vDriftFactor=1.f, float vDriftRef=0.f, float driftTimeOffset=0.f)
Updates the transformation with the new time stamp.
std::unique_ptr< TPCFastTransform > create(Long_t TimeStamp)
_______________ Main functionality ________________________
static TPCFastTransformHelperO2 * instance()
Singleton.
static constexpr ID Muon
Definition PID.h:95
void propagateParamToZlinear(double zEnd)
Definition TrackFwd.cxx:32
Double_t getTgl() const
Definition TrackFwd.h:74
Double_t getEta() const
Definition TrackFwd.h:87
Double_t getPhi() const
Definition TrackFwd.h:56
Double_t getTheta() const
Definition TrackFwd.h:86
void setParameters(const SMatrix5 &parameters)
set track parameters
Definition TrackFwd.h:108
Double_t getZ() const
return Z coordinate (cm)
Definition TrackFwd.h:46
Double_t getY() const
Definition TrackFwd.h:52
Double_t getCharge() const
return the charge (assumed forward motion)
Definition TrackFwd.h:96
Double_t getX() const
Definition TrackFwd.h:49
void setZ(Double_t z)
set Z coordinate (cm)
Definition TrackFwd.h:48
Double_t getInvQPt() const
Definition TrackFwd.h:77
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
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
constexpr double LHCBunchSpacingMUS
constexpr int LHCMaxBunches
constexpr double LHCBunchSpacingNS
@ HIGH_GAIN
High gain channel.
Definition Constants.h:35
@ LOW_GAIN
Low gain channel.
Definition Constants.h:34
std::array< float, 3 > PNT
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
constexpr unsigned char SECTORSPERSIDE
Definition Defs.h:40
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 getTPCTRDTrack(GTrackID id) const
const o2::tpc::ClusterNativeAccess & getTPCClusters() const
void createTracksVariadic(T creator, GTrackID::mask_t srcSel=GTrackID::getSourcesMask("all")) const
const o2::itsmft::TrkClusRef & getITSABRef(GTrackID gid) 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 getITSTPCTRDTrack(GTrackID id) 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
static constexpr int L2G
Definition Cartesian.h:54
static constexpr int T2L
Definition Cartesian.h:55
static constexpr int T2GRot
Definition Cartesian.h:57
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