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