forked from sPHENIX-Collaboration/acts
/
AdaptiveMultiVertexFitter.hpp
309 lines (266 loc) · 11.2 KB
/
AdaptiveMultiVertexFitter.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
// This file is part of the Acts project.
//
// Copyright (C) 2019 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#pragma once
#include "Acts/EventData/TrackParameters.hpp"
#include "Acts/Utilities/AnnealingUtility.hpp"
#include "Acts/Utilities/Definitions.hpp"
#include "Acts/Utilities/Logger.hpp"
#include "Acts/Utilities/Result.hpp"
#include "Acts/Vertexing/AMVFInfo.hpp"
#include "Acts/Vertexing/ImpactPointEstimator.hpp"
#include "Acts/Vertexing/LinearizerConcept.hpp"
#include "Acts/Vertexing/TrackAtVertex.hpp"
#include "Acts/Vertexing/Vertex.hpp"
#include "Acts/Vertexing/VertexingOptions.hpp"
#include <functional>
namespace Acts {
/// @class AdaptiveMultiVertexFitter
/// @brief Implements an adaptive multi-vertex fitter as described
/// in detail in Section 5.3.5 in:
/// Ref. (1): CERN-THESIS-2010-027, Author: Piacquadio, Giacinto:
/// `Identification of b-jets and investigation of the discovery potential
/// of a Higgs boson in the WH−−>lvbb¯ channel with the ATLAS experiment`
///
///////////////////////////////////////////////////////////////////////////
///
/// @tparam input_track_t Track object type
/// @tparam linearizer_t Track linearizer type
template <typename input_track_t, typename linearizer_t>
class AdaptiveMultiVertexFitter {
static_assert(LinearizerConcept<linearizer_t>,
"Linearizer does not fulfill linearizer concept.");
public:
using InputTrack_t = input_track_t;
using Propagator_t = typename linearizer_t::Propagator_t;
using Linearizer_t = linearizer_t;
private:
using IPEstimator = ImpactPointEstimator<InputTrack_t, Propagator_t>;
public:
/// @brief The fitter state
struct State {
State(const Acts::MagneticFieldContext& mctx)
: ipState(mctx), linearizerState(mctx) {}
// Vertex collection to be fitted
std::vector<Vertex<InputTrack_t>*> vertexCollection;
// Annealing state
AnnealingUtility::State annealingState;
// IPEstimator state
typename IPEstimator::State ipState;
// Linearizer state
typename Linearizer_t::State linearizerState;
// Map to store vertices information
std::map<Vertex<InputTrack_t>*, VertexInfo<InputTrack_t>> vtxInfoMap;
std::multimap<const InputTrack_t*, Vertex<InputTrack_t>*>
trackToVerticesMultiMap;
std::map<std::pair<const InputTrack_t*, Vertex<InputTrack_t>*>,
TrackAtVertex<InputTrack_t>>
tracksAtVerticesMap;
/// @brief Default State constructor
State() = default;
// Adds a vertex to trackToVerticesMultiMap
void addVertexToMultiMap(Vertex<InputTrack_t>& vtx) {
for (auto trk : vtxInfoMap[&vtx].trackLinks) {
trackToVerticesMultiMap.emplace(trk, &vtx);
}
}
// Removes a vertex from trackToVerticesMultiMap
void removeVertexFromMultiMap(Vertex<InputTrack_t>& vtx) {
for (auto iter = trackToVerticesMultiMap.begin();
iter != trackToVerticesMultiMap.end();) {
if (iter->second == &vtx) {
iter = trackToVerticesMultiMap.erase(iter);
} else {
++iter;
}
}
}
};
struct Config {
/// @brief Config constructor
///
/// @param est ImpactPointEstimator
Config(const IPEstimator& est) : ipEst(est) {}
// ImpactPointEstimator
IPEstimator ipEst;
/// Annealing tool used for a thermodynamic annealing scheme for the
/// track weight factors in such a way that with high temperature values
/// (at the beginning) only a slight preference is given to tracks
/// compatible with the estimated vertex position. With lower temperatures
/// the weighting get stricter such that all incompatible tracks will be
/// dropped at the end while keeping all compatible tracks with a weight=1.
/// Ref. (1): CERN-THESIS-2010-027, Author: Piacquadio, Giacinto:
/// `Identification of b-jets and investigation of the discovery potential
/// of a Higgs boson in the WH−−>lvbb¯ channel with the ATLAS experiment`
AnnealingUtility annealingTool;
// Number of max iterations
unsigned int maxIterations{30};
// Max distance to linearization point allowed
// without relinearization
double maxDistToLinPoint{0.5};
// Minimum track weight needed for track to be considered
double minWeight{0.0001};
// Max relative shift of vertex during one iteration
double maxRelativeShift{0.01};
// Do smoothing after multivertex fit
bool doSmoothing{false};
};
/// @brief Constructor used if InputTrack_t type == BoundTrackParameters
///
/// @param cfg Configuration object
/// @param logger The logging instance
template <
typename T = InputTrack_t,
std::enable_if_t<std::is_same<T, BoundTrackParameters>::value, int> = 0>
AdaptiveMultiVertexFitter(Config& cfg,
std::unique_ptr<const Logger> logger =
getDefaultLogger("AdaptiveMultiVertexFitter",
Logging::INFO))
: m_cfg(std::move(cfg)),
m_extractParameters([](T params) { return params; }),
m_logger(std::move(logger)) {}
/// @brief Constructor for user-defined InputTrack_t type !=
/// BoundTrackParameters
///
/// @param cfg Configuration object
/// @param func Function extracting BoundTrackParameters from InputTrack_t
/// object
/// @param logger The logging instance
AdaptiveMultiVertexFitter(
Config& cfg, std::function<BoundTrackParameters(InputTrack_t)> func,
std::unique_ptr<const Logger> logger =
getDefaultLogger("AdaptiveMultiVertexFitter", Logging::INFO))
: m_cfg(std::move(cfg)),
m_extractParameters(func),
m_logger(std::move(logger)) {}
/// @brief The actual fit function, performs a simultaneous
/// fit of all vertices in `verticesToFit` by invoking `fitImpl`
///
/// @param state The state object
/// @param verticesToFit Vector containing all vertices to be fitted
/// @param linearizer The track linearizer
/// @param vertexingOptions Vertexing options
///
/// @return Result<void> object
Result<void> fit(
State& state, const std::vector<Vertex<InputTrack_t>*>& verticesToFit,
const Linearizer_t& linearizer,
const VertexingOptions<InputTrack_t>& vertexingOptions) const;
/// @brief Adds new vertex to an existing multi-vertex fit
/// and fits everything together (by invoking the fit_impl method):
/// 1. The new vertex is added to the fit: all associated tracks get
/// initialized, i.e. ParamsAtIP3d are created (from ImpactPointEstimator)
/// to be later able to estimate in a fast way the compatibility of the tracks
/// to their respective vertices.
/// 2. All tracks belonging to the new vertex are scanned and all the vertices
/// which share tracks with the new vertex to be fit are also added to the
/// fit.
/// 3. The multivertex fit is performed with all involved vertices.
///
/// This has the advantage that only vertices that are affected by adding the
/// new vertex are refitted.
///
/// Note: newVertex has to be properly initialized (seed vertex,
/// constraint vertex, list of MAV)
///
/// @param state The state object
/// @param newVertex New vertex to be added to fit
/// @param linearizer The track linearizer
/// @param vertexingOptions Vertexing options
///
/// @return Result<void> object
Result<void> addVtxToFit(
State& state, Vertex<InputTrack_t>& newVertex,
const Linearizer_t& linearizer,
const VertexingOptions<InputTrack_t>& vertexingOptions) const;
private:
/// Configuration object
const Config m_cfg;
/// @brief Function to extract track parameters,
/// InputTrack_t objects are BoundTrackParameters by default, function to be
/// overwritten to return BoundTrackParameters for other InputTrack_t objects.
///
/// @param InputTrack_t object to extract track parameters from
std::function<BoundTrackParameters(InputTrack_t)> m_extractParameters;
/// Logging instance
std::unique_ptr<const Logger> m_logger;
/// Private access to logging instance
const Logger& logger() const { return *m_logger; }
/// @brief The actual fit function, performs a simultaneous
/// fit of all vertices in state.vertexCollection
///
/// @param state The state object
/// @param linearizer The track linearizer
/// @param vertexingOptions Vertexing options
///
/// @return Result<void> object
Result<void> fitImpl(
State& state, const Linearizer_t& linearizer,
const VertexingOptions<InputTrack_t>& vertexingOptions) const;
/// @brief Tests if vertex is already in list of vertices or not
///
/// @param vtx Vertex to test
/// @param verticesVec Vector of vertices to search
///
/// @return True if vtx is already in verticesVec
bool isAlreadyInList(
Vertex<InputTrack_t>* vtx,
const std::vector<Vertex<InputTrack_t>*>& verticesVec) const;
/// @brief Prepares vertex object for the actual fit, i.e.
/// all TrackAtVertex objects at current vertex will obtain
/// `ip3dParams` from ImpactPointEstimator::estimate3DImpactParameters
/// in order to later faster estimate compatibilities of track
/// with different vertices
///
/// @param vtx The vertex object
/// @param vertexingOptions Vertexing options
Result<void> prepareVertexForFit(
State& state, Vertex<InputTrack_t>* vtx,
const VertexingOptions<InputTrack_t>& vertexingOptions) const;
/// @brief Sets vertexCompatibility for all TrackAtVertex objects
/// at current vertex
///
/// @param state The state object
/// @param currentVtx Current vertex
/// @param vertexingOptions Vertexing options
Result<void> setAllVertexCompatibilities(
State& state, Vertex<InputTrack_t>* currentVtx,
const VertexingOptions<input_track_t>& vertexingOptions) const;
/// @brief Sets weights to the track according to Eq.(5.46) in Ref.(1)
/// and updates the vertices by calling the VertexUpdater
///
/// @param state The state object
/// @param linearizer The track linearizer
/// @param vertexingOptions Vertexing options
Result<void> setWeightsAndUpdate(
State& state, const Linearizer_t& linearizer,
const VertexingOptions<input_track_t>& vertexingOptions) const;
/// @brief Collects all compatibility values of the track `trk`
/// at all vertices it is currently attached to and outputs
/// these values in a vector
///
/// @param state The state object
/// @param trk The track
///
/// @return Vector of compatibility values
std::vector<double> collectTrackToVertexCompatibilities(
State& state, const InputTrack_t* trk) const;
/// @brief Determines if vertex position has shifted more than
/// m_cfg.maxRelativeShift in last iteration
///
/// @param state The state object
///
/// @return False if shift was larger than maxRelativeShift
bool checkSmallShift(State& state) const;
/// @brief Updates tracks for current vertex with knowledge
/// of current vertex position
///
/// @param state The state object
void doVertexSmoothing(State& state) const;
};
} // namespace Acts
#include "Acts/Vertexing/AdaptiveMultiVertexFitter.ipp"