Project
Loading...
Searching...
No Matches
Configuration.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
12#include <algorithm>
13#include <array>
14#include <cctype>
15#include <cmath>
16#include <format>
17#include <string_view>
18#include <stdexcept>
19#include <vector>
20
22#include "Framework/Logger.h"
26#include "MFTTracking/Constants.h"
27
28namespace
29{
30constexpr bool iequals(std::string_view a, std::string_view b)
31{
32 return std::equal(a.begin(), a.end(), b.begin(), b.end(),
33 [](char x, char y) { return std::tolower(x) == std::tolower(y); });
34}
35
36template <typename Config>
37void resolveSystematicErrors(o2::itsmft::DetectorParameters& parameters, const Config& config)
38{
39 for (size_t layer = 0; layer < std::size(config.sysErr2Row); ++layer) {
40 const auto row = config.sysErr2Row[layer];
41 const auto col = config.sysErr2Col[layer];
42 if (row < 0.f || col < 0.f) {
43 throw std::invalid_argument(std::format("{}.sysErr2Row/Col[{}] must be finite nonnegative variances", config.getName(), layer));
44 }
45 parameters.SystError2Row[layer] = row;
46 parameters.SystError2Col[layer] = col;
47 }
48}
49} // namespace
50
51namespace o2::itsmft
52{
53
54namespace TrackingMode
55{
56
57Type fromString(std::string_view str)
58{
59 constexpr std::array smodes = {
60 std::pair{"sync", Sync},
61 std::pair{"async", Async},
62 std::pair{"cosmics", Cosmics},
63 std::pair{"unset", Unset},
64 std::pair{"off", Off}};
65
66 const auto it = std::find_if(smodes.begin(), smodes.end(), [&str](const auto& pair) {
67 return iequals(str, pair.first);
68 });
69 if (it == smodes.end()) {
70 LOGP(fatal, "Unrecognized CA tracking mode '{}'", str);
71 }
72 return it->second;
73}
74
75std::string toString(Type mode)
76{
77 switch (mode) {
78 case Sync:
79 return "sync";
80 case Async:
81 return "async";
82 case Cosmics:
83 return "cosmics";
84 case Unset:
85 return "unset";
86 case Off:
87 return "off";
88 }
89 LOGP(fatal, "Unrecognized CA tracking mode {}", static_cast<int>(mode));
90 return "";
91}
92
94{
95 TrackingPlan plan;
96 IterationParameters defaults;
97 auto& trackParams = plan.iterations;
98 if (detId == detectors::DetID::ITS) {
99 defaults.MinPt.assign(tracking::ITSNLayers - tracking::kCAMinTrackLength + 1, 0.f);
100 if (mode == Async) {
101 trackParams.assign(3, defaults);
102 trackParams[1].TrackletMinPt = 0.2f;
103 trackParams[2].TrackletMinPt = 0.1f;
104 trackParams[0].MinPt[0] = 1.f / 12.f;
105 trackParams[1].MinPt[0] = 1.f / 12.f;
106 trackParams[2].MinTrackLength = tracking::kCAMinTrackLength;
107 trackParams[2].MinPt[0] = 1.f / 12.f;
108 trackParams[2].MinPt[1] = 1.f / 5.f;
109 trackParams[2].MinPt[2] = 1.f;
110 trackParams[2].MinPt[3] = 1.f / 6.f;
111 trackParams[2].StartLayerMask = (1u << 6) | (1u << 3);
112 } else if (mode == Sync) {
113 trackParams.assign(1, defaults);
114 trackParams[0].MinTrackLength = tracking::kCAMinTrackLength;
115 } else {
116 LOGP(fatal, "ITS common-CA tracking mode '{}' is not supported yet; use 'sync' or 'async'", toString(mode));
117 }
118
119 plan.detector.ColBins = 64;
120 plan.detector.RowBins = 32;
121 } else if (detId == detectors::DetID::MFT) {
122 namespace mft = o2::mft::constants::mft;
123 constexpr int nLayers = mft::LayersNumber;
124 plan.detector.LayerResolution.assign(nLayers, mft::Resolution);
125 plan.detector.SystError2Row.assign(nLayers, 0.f);
126 plan.detector.SystError2Col.assign(nLayers, 0.f);
127 plan.detector.AddTimeError.assign(nLayers, 0u);
128 plan.detector.ColBins = 64;
129 plan.detector.RowBins = 128;
130 defaults.NLayers = nLayers;
131 defaults.UseDiamond = true;
132 defaults.PerPrimaryVertexProcessing = false;
133 defaults.StartLayerMask = (1u << nLayers) - 1u;
135 if (mode == Off) {
136 return plan;
137 }
138 if (mode == Unset) {
139 LOGP(fatal, "CA tracking mode is unset; set --tracking-mode or MFTCATrackerParam.trackingMode");
140 }
141 if (mode == Async) {
142 trackParams.assign(3, defaults);
143
144 trackParams[1].TrackletMinPt = 0.15f;
145 trackParams[2].TrackletMinPt = 0.08f;
146
147 trackParams[0].MinPt[0] = 1.f / 12.f; // 10 clusters
148 trackParams[1].MinPt[0] = 1.f / 12.f;
149
150 trackParams[2].MinTrackLength = MFTCATrackerParam::MinTrackLength;
151 trackParams[2].MinPt[0] = 1.f / 12.f; // 10 clusters
152 trackParams[2].MinPt[1] = 1.f / 8.f; // 9 clusters
153 trackParams[2].MinPt[2] = 1.f / 5.f; // 8 clusters
154 trackParams[2].MinPt[3] = 1.f / 3.f; // 7 clusters
155 trackParams[2].MinPt[4] = 1.f / 2.f; // 6 clusters
156 trackParams[2].MinPt[5] = 1.f / 1.f; // 5 clusters
157 } else if (mode == Sync) {
158 trackParams.assign(1, defaults);
159 trackParams[0].MinTrackLength = MFTCATrackerParam::MinTrackLength;
160 } else if (mode == Cosmics) {
161 trackParams.assign(1, defaults);
162 trackParams[0].MinTrackLength = MFTCATrackerParam::MinTrackLength;
163 plan.detector.ColBins = 32;
164 plan.detector.RowBins = 64;
165 trackParams[0].PVres = 1.e5f;
166 trackParams[0].MaxChi2ClusterAttachment = 60.f;
167 trackParams[0].MaxChi2NDF = 40.f;
168 } else {
169 LOGP(fatal, "Unsupported CA tracking mode {}", toString(mode));
170 }
171 } else {
172 LOGP(fatal, "Unsupported detector id {} in getTrackingPlan", static_cast<int>(detId));
173 }
174
175 const auto applyOverrides = [&]<typename Config>(const Config& tc) {
176 if (mode != Async) {
177 if (std::any_of(std::begin(tc.minTrackLgtIter), std::end(tc.minTrackLgtIter), [](int value) { return value > 0; })) {
178 throw std::invalid_argument(tc.getName() + ".minTrackLgtIter overrides are implemented only for async mode");
179 }
180 if (std::any_of(std::begin(tc.minPtIterLgt), std::end(tc.minPtIterLgt), [](float value) { return value > 0.f; })) {
181 throw std::invalid_argument(tc.getName() + ".minPtIterLgt overrides are implemented only for async mode");
182 }
183 }
184
185 if (mode == Async) {
186 for (int ip = 0; ip < static_cast<int>(trackParams.size()); ip++) {
187 auto& param = trackParams[ip];
188 if (ip < tracking::MaxIter) {
189 if (tc.minTrackLgtIter[ip] > 0) {
190 param.MinTrackLength = tc.minTrackLgtIter[ip];
191 }
192 for (int ilg = tc.MaxTrackLength; ilg >= tc.MinTrackLength; ilg--) {
193 const int lslot0 = tc.MaxTrackLength - ilg;
194 const int lslot = lslot0 + ip * (tc.MaxTrackLength - tc.MinTrackLength + 1);
195 if (tc.minPtIterLgt[lslot] > 0.f) {
196 param.MinPt[lslot0] = tc.minPtIterLgt[lslot];
197 }
198 }
199 }
200 }
201 }
202
203 if (tc.nIterations != -1 && (tc.nIterations <= 0 || static_cast<size_t>(tc.nIterations) > trackParams.size())) {
204 throw std::invalid_argument(std::format("{}.nIterations={} is invalid for {}: use -1 or 1..{}",
205 tc.getName(), tc.nIterations, toString(mode), trackParams.size()));
206 }
207 if (tc.nIterations > 0) {
208 trackParams.resize(tc.nIterations);
209 }
210 constexpr uint32_t allowedStartLayers = (uint32_t{1} << Config::NLayers) - 1;
211 for (int iteration = 0; iteration < tracking::MaxIter; ++iteration) {
212 if (tc.startLayerMask[iteration] & ~allowedStartLayers) {
213 throw std::invalid_argument(std::format("{}.startLayerMask[{}]={} contains bits outside the {} detector layers",
214 tc.getName(), iteration, tc.startLayerMask[iteration], tc.NLayers));
215 }
216 }
217
218 plan.execution = {tc.maxMemory, tc.dropTFUponFailure};
219 resolveSystematicErrors(plan.detector, tc);
220 for (int i{0}; i < tc.NLayers; ++i) {
221 plan.detector.AddTimeError[i] = tc.addTimeError[i];
222 }
223 plan.detector.ColBins = tc.LUTbinsU > 0 ? tc.LUTbinsU : plan.detector.ColBins;
224 plan.detector.RowBins = tc.LUTbinsV > 0 ? tc.LUTbinsV : plan.detector.RowBins;
225
226 for (auto& param : trackParams) {
227 param.PassFlags.reset();
228 }
229 if (!trackParams.empty()) {
230 trackParams[0].PassFlags.set(IterationStep::FirstPass, IterationStep::RebuildClusterLUT);
231 }
232
233 const float bFactor = std::abs(o2::base::Propagator::Instance()->getNominalBz()) / 5.0066791f;
234 const float bFactorTracklets = bFactor < 0.01f ? 1.f : bFactor;
235
236 for (auto& p : trackParams) {
237 p.TrackletMinPt *= bFactorTracklets;
238 for (int ilg = tc.MaxTrackLength; ilg >= tc.MinTrackLength; ilg--) {
239 const int lslot = tc.MaxTrackLength - ilg;
240 if (lslot < static_cast<int>(p.MinPt.size())) {
241 p.MinPt[lslot] *= bFactor;
242 }
243 }
244
245 p.UseDiamond = tc.useDiamond;
246 p.RepeatRefitOut = tc.repeatRefitOut;
247 p.ShiftRefToCluster = tc.shiftRefToCluster;
248 p.CreateArtefactLabels = tc.createArtefactLabels;
249 p.AllowSharingFirstCluster = tc.allowSharingFirstCluster;
250 p.SharedClusterMaxDeltaPhi = tc.sharedClusterMaxDeltaPhi;
251 p.SharedClusterMaxDeltaEta = tc.sharedClusterMaxDeltaEta;
252 p.SharedClusterOppositeSign = tc.sharedClusterOppositeSign;
253
254 const auto iter = &p - trackParams.data();
255 if (iter < tracking::MaxIter) {
256 p.MaxHoles = tc.maxHolesIter[iter];
257 }
258
259 if (tc.startLayerMask[iter] != 0) {
260 p.StartLayerMask = tc.startLayerMask[iter];
261 }
262
263 p.MaxChi2ClusterAttachment = tc.maxChi2ClusterAttachment > 0 ? tc.maxChi2ClusterAttachment : p.MaxChi2ClusterAttachment;
264 p.MaxChi2NDF = tc.maxChi2NDF > 0 ? tc.maxChi2NDF : p.MaxChi2NDF;
265 p.PVres = tc.pvRes > 0 ? tc.pvRes : p.PVres;
266 p.NSigmaCut *= tc.nSigmaCut > 0 ? tc.nSigmaCut : 1.f;
267 p.TrackletMinPt *= tc.minPt > 0 ? tc.minPt : 1.f;
268 for (int iD{0}; iD < 3; ++iD) {
269 p.Diamond[iD] = tc.diamondPos[iD];
270 }
271 }
272 };
273 if (detId == detectors::DetID::ITS) {
274 applyOverrides(ITSCommonCATrackerParam::Instance());
275 } else {
276 applyOverrides(MFTCATrackerParam::Instance());
277 LOGP(info, "MFT CA {}: {} passes, material model nominal, index=PhiR phiBins={} radiusBins={} (radians, cm)",
278 toString(mode), trackParams.size(), plan.detector.RowBins, plan.detector.ColBins);
279 for (size_t iteration = 0; iteration < trackParams.size(); ++iteration) {
280 const auto& p = trackParams[iteration];
281 LOGP(info, "MFT CA pass {}: minTrackLength={} trackletMinPt={} maxChi2ClusterAttachment={} maxChi2NDF={} startLayerMask={}",
282 iteration, p.MinTrackLength, p.TrackletMinPt, p.MaxChi2ClusterAttachment, p.MaxChi2NDF, p.StartLayerMask.value());
283 }
284 }
285
286 return plan;
287}
288
289} // namespace TrackingMode
290} // namespace o2::itsmft
Shared CA tracking configuration for ITS and MFT.
int32_t i
uint32_t col
Definition RawData.h:4
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
Definition Propagator.h:180
int ID
Detector identifiers: continuous, starting from 0.
Definition DetID.h:63
GLint GLenum GLint x
Definition glcorearb.h:403
GLenum mode
Definition glcorearb.h:266
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLint y
Definition glcorearb.h:270
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
GLenum GLfloat param
Definition glcorearb.h:271
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
std::string toString(Type mode)
TrackingPlan getTrackingPlan(o2::detectors::DetID::ID detId, Type mode)
Type fromString(std::string_view str)
constexpr int MaxIter
Maximum CA iterations.
constexpr int ITSNLayers
ITS CA layer count.
constexpr int kCAMinTrackLength
Minimum accepted CA track length for the detector presets.
constexpr Int_t LayersNumber
Definition Constants.h:37
constexpr Float_t Resolution
Definition Constants.h:43
std::vector< uint32_t > AddTimeError
std::vector< float > SystError2Col
std::vector< float > SystError2Row
std::vector< float > LayerResolution
tracking::LayerMask StartLayerMask
TrackingExecutionPolicy execution
DetectorParameters detector
std::vector< IterationParameters > iterations
std::vector< int > row
const std::string str