Project
Loading...
Searching...
No Matches
TrackPublicationHelpers.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#ifndef ALICEO2_ITSMFT_TRACKING_TRACKPUBLICATIONHELPERS_H_
13#define ALICEO2_ITSMFT_TRACKING_TRACKPUBLICATIONHELPERS_H_
14
15// Shared host-side track selection, ordering and ROF assignment for publication.
16
17#include <algorithm>
18#include <cmath>
19#include <cstdint>
20#include <limits>
21#include <numeric>
22#include <optional>
23#include <vector>
24
25#include <gsl/span>
26
30
32{
33
34#ifndef GPUCA_GPUCODE
35
36// Tracks already carry a symmetric timestamp. Apply the publication clock's
37// uncertainty limit without modifying the frame-owned track.
39{
40 timestamp.setTimeStampError(std::min(timestamp.getTimeStampError(), clock.mROFLength * 0.5f));
41 return timestamp;
42}
43
44// This context is intentionally source-local. ROFRecord payload is copied
45// only into the returned publication product, never into TimeFrame.
47 gsl::span<const o2::itsmft::ROFRecord> inputROFs;
49};
50
51inline std::optional<std::vector<uint32_t>> selectGenericTracksForSurfaces(
52 const TimeFrame& frame,
53 gsl::span<const LayerId> sourceSurfaces)
54{
55 const auto& tracks = frame.getGenericTracks();
56 if (tracks.size() > std::numeric_limits<uint32_t>::max()) {
57 return std::nullopt;
58 }
59 std::vector<uint32_t> selection;
60 const auto& references = frame.getTrackClusterIndices();
61 selection.reserve(tracks.size());
62 for (uint32_t globalIndex = 0; globalIndex < tracks.size(); ++globalIndex) {
63 const auto& track = tracks[globalIndex];
64 if (!isValidTrackRange(track, static_cast<uint32_t>(references.size()))) {
65 return std::nullopt;
66 }
67 bool requested = false;
68 bool foreign = false;
69 for (uint32_t i = track.firstClusterRef; i < track.clusterRefEnd; ++i) {
70 const auto& reference = references[i];
71 if (!reference.isValid()) {
72 return std::nullopt;
73 }
74 const bool match = std::find(sourceSurfaces.begin(), sourceSurfaces.end(), reference.layer) != sourceSurfaces.end();
75 requested |= match;
76 foreign |= !match;
77 }
78 if (requested && foreign) {
79 return std::nullopt;
80 }
81 if (requested) {
82 selection.push_back(globalIndex);
83 }
84 }
85 return selection;
86}
87
88inline std::optional<std::vector<uint32_t>> makeLegacyOutputOrder(
89 const TimeFrame& frame, std::vector<uint32_t> selection,
90 const o2::its::LayerTiming& clock)
91{
92 const auto& tracks = frame.getGenericTracks();
93 for (const auto index : selection) {
94 const auto& timestamp = tracks[index].timestamp;
95 if (!std::isfinite(timestamp.getTimeStamp()) || !std::isfinite(timestamp.getTimeStampError()) ||
96 timestamp.getTimeStampError() <= 0.f) {
97 return std::nullopt;
98 }
99 }
100 // Sort only indices, using the same clamped timestamp that will be published.
101 // Match Tracker::sortTracks(): lower timestamp edge, then chi2.
102 std::sort(selection.begin(), selection.end(), [&](uint32_t left, uint32_t right) {
103 const auto& leftTrack = tracks[left];
104 const auto& rightTrack = tracks[right];
105 const auto leftTime = makeOutputTimestamp(leftTrack.timestamp, clock);
106 const auto rightTime = makeOutputTimestamp(rightTrack.timestamp, clock);
107 const auto leftLower = leftTime.getTimeStamp() - leftTime.getTimeStampError();
108 const auto rightLower = rightTime.getTimeStamp() - rightTime.getTimeStampError();
109 if (leftLower != rightLower) {
110 return leftLower < rightLower;
111 }
112 return leftTrack.chi2 < rightTrack.chi2;
113 });
114 return selection;
115}
116
117inline void finalizeROFs(std::vector<o2::itsmft::ROFRecord>& rofs, const std::vector<o2::its::TimeStamp>& times,
118 const TrackPublicationTimingContext& context)
119{
120 for (auto& rof : rofs) {
121 rof.setFirstEntry(0);
122 rof.setNEntries(0);
123 }
124 for (const auto& time : times) {
125 const int rof = context.clock.getROF(time);
126 if (rof < 0 || static_cast<size_t>(rof) >= rofs.size()) {
127 // Keep the track; omit only its TrackROF entry.
128 continue;
129 }
130 rofs[rof].setNEntries(rofs[rof].getNEntries() + 1);
131 }
132 std::vector<int> counts(rofs.size());
133 for (size_t i = 0; i < rofs.size(); ++i) {
134 counts[i] = rofs[i].getNEntries();
135 }
136 std::exclusive_scan(counts.begin(), counts.end(), counts.begin(), 0);
137 for (size_t i = 0; i < rofs.size(); ++i) {
138 rofs[i].setFirstEntry(counts[i]);
139 }
140}
141
142} // namespace o2::itsmft::tracking
143
144#endif // !GPUCA_GPUCODE
145
146#endif // ALICEO2_ITSMFT_TRACKING_TRACKPUBLICATIONHELPERS_H_
std::vector< unsigned long > times
Passive common TimeFrame owner.
int16_t time
Definition RawEventData.h:4
int32_t i
Definition of the ITSMFT ROFrame (trigger) record.
std::vector< o2::its::TrackITS > tracks
bool match(const std::vector< std::string > &queries, const char *pattern)
Definition dcs-ccdb.cxx:229
GLuint index
Definition glcorearb.h:781
GLdouble GLdouble right
Definition glcorearb.h:4077
GLint reference
Definition glcorearb.h:5487
GLint left
Definition glcorearb.h:1979
std::optional< std::vector< uint32_t > > selectGenericTracksForSurfaces(const TimeFrame &frame, gsl::span< const LayerId > sourceSurfaces)
o2::its::TimeStamp makeOutputTimestamp(o2::its::TimeStamp timestamp, const o2::its::LayerTiming &clock) noexcept
void finalizeROFs(std::vector< o2::itsmft::ROFRecord > &rofs, const std::vector< o2::its::TimeStamp > &times, const TrackPublicationTimingContext &context)
std::optional< std::vector< uint32_t > > makeLegacyOutputOrder(const TimeFrame &frame, std::vector< uint32_t > selection, const o2::its::LayerTiming &clock)
gsl::span< const o2::itsmft::ROFRecord > inputROFs