ATLAS Offline Software
Loading...
Searching...
No Matches
AmbiguityProcessorBase.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6
8#include "GaudiKernel/RenounceToolInputsVisitor.h"
9#include "GaudiKernel/ToolVisitor.h"
10
11namespace Trk {
13 const std::string& n,
14 const IInterface* p)
15 : AthAlgTool(t, n, p),
16 m_etaBounds{0.8, 1.6, 2.5, 4.0},
17 m_stat(m_etaBounds) {}
18//
20 const Trk::Track& track) const {
21 return m_tryBremFit and
22 not(track.info().trackProperties(Trk::TrackInfo::BremFit)) and
23 (track.trackParameters()->front()->pT() > m_pTminBrem) and
24 ((not m_caloSeededBrem) or
25 track.info().patternRecoInfo(Trk::TrackInfo::TrackInCaloROI));
26}
27
29 // init ClusterSplitProb input and output container handles and renounce the
30 // output handle from its tools. the latter works because the ClusterSplitProb
31 // output container is created and recorded before the tools are called.
33 !m_clusterSplitProbContainerIn.key().empty()));
35 !m_clusterSplitProbContainerOut.key().empty()));
36 if (!m_clusterSplitProbContainerOut.key().empty()) {
37 auto visitor = [this](const IAlgTool* tool) {
38 const AlgTool* alg_tool = dynamic_cast<const AlgTool*>(tool);
39 for (Gaudi::DataHandle* handle : alg_tool->inputHandles()) {
40 this->msg(MSG::DEBUG) << " input Handle " << tool->name() << " . "
41 << handle->objKey() << endmsg;
42 }
43 for (const auto& elm : alg_tool->inputDataObjs()) {
44 this->msg(MSG::DEBUG)
45 << " input object " << tool->name() << " . " << elm.key() << endmsg;
46 }
47 };
48 if (msgLvl(MSG::DEBUG)) {
49 ToolVisitor::visit(tools(), visitor);
50 }
52 ATH_MSG_DEBUG(" Renounce " << m_clusterSplitProbContainerOut.objKey());
53 auto logger = RenounceToolInputsVisitor::createLogger(
54 [this](const std::string_view& tool_name, const std::string_view& key) {
55 this->msg(MSG::INFO)
56 << " Renounce " << tool_name << " . " << key << endmsg;
57 });
58 RenounceToolInputsVisitor renounce(
59 std::vector<DataObjID>{m_clusterSplitProbContainerOut.fullKey()},
60 logger);
61 ToolVisitor::visit(tools(), renounce);
62 ATH_MSG_DEBUG(" renounced " << m_clusterSplitProbContainerOut.objKey());
63 if (msgLvl(MSG::DEBUG)) {
64 ToolVisitor::visit(tools(), visitor);
65 }
66 }
67 return StatusCode::SUCCESS;
68}
69
72 const EventContext& ctx) const {
74 if (!m_clusterSplitProbContainerIn.key().empty()) {
75 splitProbContainerIn = SG::ReadHandle(m_clusterSplitProbContainerIn, ctx);
76 if (!splitProbContainerIn.isValid()) {
77 ATH_MSG_ERROR("Failed to get input cluster split probability container "
79 }
80 }
81 std::unique_ptr<Trk::ClusterSplitProbabilityContainer> newSplitProbContainer(
83 ? std::make_unique<Trk::ClusterSplitProbabilityContainer>(
84 *splitProbContainerIn)
85 : std::make_unique<Trk::ClusterSplitProbabilityContainer>());
87 splitProbContainerHandle;
88 if (!m_clusterSplitProbContainerOut.key().empty()) {
89 splitProbContainerHandle =
92 if (splitProbContainerHandle.record(std::move(newSplitProbContainer))
93 .isFailure()) {
95 "Failed to record output cluster split probability container "
97 }
98 // newSplitProbContainer owned by storegate -> no cleanup
99 return {splitProbContainerHandle.ptr(),
101 } else {
102 // when not recording the split prob container in storegate the container
103 // must be deleted once going out of scope
104 return {newSplitProbContainer.release(),
105 [](Trk::ClusterSplitProbabilityContainer* ptr) { delete ptr; }};
106 }
107}
108
110 const Trk::Track& track, const TrackParameters* pPar) const {
111 return m_tryBremFit and (pPar->pT() > m_pTminBrem) and
112 ((not m_caloSeededBrem) or
113 track.info().patternRecoInfo(Trk::TrackInfo::TrackInCaloROI));
114}
115//
117 Trk::PRDtoTrackMap& prdToTrackMap,
118 Counter& stat, int trackId,
119 int subtrackId) const {
120 std::unique_ptr<Trk::Track> newTrack;
121 if (!m_suppressTrackFit) {
122 if (m_refitPrds) {
123 // simple case, fit PRD directly
124 ATH_MSG_VERBOSE("Refit track " << track << " from PRDs");
125 newTrack.reset(refitPrds(track, prdToTrackMap, stat));
126 } else {
127 // ok, we fit ROTs
128 ATH_MSG_VERBOSE("Refit track " << track << " from ROTs");
129 newTrack.reset(refitRots(track, stat));
130 }
131 } else {
133 }
134 if (newTrack) {
135 if (m_observerTool.isEnabled()) {
138 m_observerTool->addSubTrack(subtrackId, trackId, *newTrack);
139 }
140 ATH_MSG_DEBUG("New track " << newTrack.get() << " successfully fitted from "
141 << track);
142 } else {
143 if (m_observerTool.isEnabled()) {
146 }
147 ATH_MSG_DEBUG("Fit failed !");
148 }
149 return newTrack.release();
150}
151//
153 Trk::Track* in_track, const bool fitted, TrackScoreMap& trackScoreTrackMap,
154 std::vector<std::unique_ptr<const Trk::Track> >& trackDustbin,
155 Counter& stat, int parentTrackId) const {
156
157 std::unique_ptr<Trk::Track> atrack(in_track);
158 // compute score
159 TrackScore score = Trk::TrackScore(0);;
160 bool suppressHoleSearch = fitted ? m_suppressHoleSearch : true;
161 bool passBasicSelections = m_scoringTool->passBasicSelections(*atrack);
162 if(passBasicSelections){
163 if (m_trackSummaryTool.isEnabled()) {
164 m_trackSummaryTool->computeAndReplaceTrackSummary(*atrack,
165 suppressHoleSearch);
166 }
167 bool recheckBasicSel = false;
168 score = m_scoringTool->score(*atrack, recheckBasicSel);
169 }
170
171 if (m_observerTool.isEnabled()) {
172 m_observerTool->updateScore(parentTrackId, static_cast<double>(score));
173 }
174
175 // do we accept the track ?
176 if (score != 0) {
177 ATH_MSG_DEBUG("Track (" << atrack.get() << ") has score " << score);
178 // statistic
179 stat.incrementCounterByRegion(CounterIndex::kNscoreOk, atrack.get());
180 // add track to map, map is sorted small to big !
181 if (m_observerTool.isEnabled()) {
182 trackScoreTrackMap.emplace(
183 -score, TrackPtr(atrack.release(), fitted, parentTrackId));
184 } else {
185 trackScoreTrackMap.emplace(-score, TrackPtr(atrack.release(), fitted));
186 }
187 return;
188 }
189 // do we try to recover the track ?
190 if (fitted and shouldTryBremRecovery(*atrack)) {
191 ATH_MSG_DEBUG("Track score is zero, try to recover it via brem fit");
192 // run track fit using electron hypothesis
193 auto bremTrack(doBremRefit(*atrack));
194 if (!bremTrack) {
195 ATH_MSG_DEBUG("Brem refit failed, drop track");
196 if (m_observerTool.isEnabled()) {
197 m_observerTool->rejectTrack(parentTrackId,
200 }
201 // statistic
202 stat.incrementCounterByRegion(CounterIndex::kNscoreZeroBremRefitFailed,
203 atrack.get());
204 stat.incrementCounterByRegion(CounterIndex::kNfailedFits, atrack.get());
205 // clean up
206 trackDustbin.push_back(std::move(atrack));
207 } else {
208 int newTrackId = AmbiguityProcessor::getUid();
209 if (m_observerTool.isEnabled()) {
210 m_observerTool->rejectTrack(
211 parentTrackId, xAOD::RejectionStep::addTrack,
213 m_observerTool->addSubTrack(newTrackId, parentTrackId, *bremTrack);
214 }
215 // statistic
216 stat.incrementCounterByRegion(CounterIndex::kNgoodFits, bremTrack.get());
217 // rerun score
218 score = Trk::TrackScore(0);
219 passBasicSelections = m_scoringTool->passBasicSelections(*bremTrack);
220 if(passBasicSelections){
221 if (m_trackSummaryTool.isEnabled()) {
222 m_trackSummaryTool->computeAndReplaceTrackSummary(*bremTrack,
223 suppressHoleSearch);
224 }
225 bool recheckBasicSel = false;
226 score = m_scoringTool->score(*bremTrack, recheckBasicSel);
227 }
228 if (m_observerTool.isEnabled()) {
229 m_observerTool->updateScore(newTrackId, static_cast<double>(score));
230 }
231 // put original track in the bin, ready to preserve a new Brem track
232 trackDustbin.push_back(std::move(atrack));
233 // do we accept the track ?
234 if (score != 0) {
235 ATH_MSG_DEBUG("Brem refit successful, recovered track ("
236 << bremTrack.get() << ") has score " << score);
237 // statistics
238 stat.incrementCounterByRegion(CounterIndex::kNscoreZeroBremRefit,
239 bremTrack.get());
240 // add track to map, map is sorted small to big !
241 if (m_observerTool.isEnabled()) {
242 m_observerTool->addSubTrack(newTrackId, parentTrackId, *bremTrack);
243 trackScoreTrackMap.emplace(
244 -score, TrackPtr(bremTrack.release(), fitted, newTrackId));
245 } else {
246 trackScoreTrackMap.emplace(-score,
247 TrackPtr(bremTrack.release(), fitted));
248 }
249 return;
250 } else {
251 ATH_MSG_DEBUG("Brem refit gave still track score zero, reject it");
252 if (m_observerTool.isEnabled()) {
253 m_observerTool->rejectTrack(
256 }
257 // statistic
258 stat.incrementCounterByRegion(
260 }
261 }
262 } else {
263 ATH_MSG_DEBUG("Track score is zero, reject it");
264 if (m_observerTool.isEnabled()) {
265 m_observerTool->rejectTrack(parentTrackId, xAOD::RejectionStep::addTrack,
267 }
268 // statistic
269 stat.incrementCounterByRegion(CounterIndex::kNscoreZero, atrack.get());
270 trackDustbin.push_back(std::move(atrack));
271 }
272}
273
275 const Trk::Track* track) const {
276 const TrackParameters* par = track->perigeeParameters();
277 if (not par) {
278 ATH_MSG_DEBUG("Track (" << track << ") has no perigee! Try any other ?");
279 par = track->trackParameters()->front();
280 }
281 if (not par)
282 ATH_MSG_DEBUG("Track (" << track
283 << ") has no Track Parameters ! No refit !");
284 return par;
285}
286
287//==================================================================================================
288
290 Counter& stat) const {
291 ATH_MSG_VERBOSE("Refit track " << track);
292 // refit using first parameter, do outliers
293 std::unique_ptr<Trk::Track> newTrack{};
294 if (m_tryBremFit and track->info().trackProperties(Trk::TrackInfo::BremFit)) {
295 stat.incrementCounterByRegion(CounterIndex::kNbremFits, track);
296 ATH_MSG_VERBOSE("Brem track, refit with electron brem fit");
297 newTrack = doBremRefit(*track);
298 } else {
299 stat.incrementCounterByRegion(CounterIndex::kNfits, track);
300 ATH_MSG_VERBOSE("Normal track, refit");
301 newTrack = fit(*track, true, m_particleHypothesis);
302 if ((not newTrack) and shouldTryBremRecovery(*track)) {
303 stat.incrementCounterByRegion(CounterIndex::kNrecoveryBremFits, track);
304 ATH_MSG_VERBOSE("Normal fit failed, try brem recovery");
305 newTrack = doBremRefit(*track);
306 }
307 }
308
309 if (newTrack) {
310 stat.incrementCounterByRegion(CounterIndex::kNgoodFits, newTrack.get());
311 // keeping the track of previously accumulated TrackInfo
312 const Trk::TrackInfo& originalInfo = track->info();
313 newTrack->info().addPatternReco(originalInfo);
314 } else {
315 stat.incrementCounterByRegion(CounterIndex::kNfailedFits, track);
316 }
317 return newTrack.release();
318}
319} // namespace Trk
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce(T &h)
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
virtual bool isValid() override final
Can the handle be successfully dereferenced?
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
AmbiguityProcessorBase(const std::string &, const std::string &, const IInterface *)
AmbiguityProcessorBase::UniqueClusterSplitProbabilityContainerPtr createAndRecordClusterSplitProbContainer(const EventContext &ctx) const
Create a new cluster splitting probability container and (optionally) record it in storegate The new ...
AmbiCounter< CounterIndex > Counter
ToolHandle< Trk::IExtendedTrackSummaryTool > m_trackSummaryTool
void addTrack(Trk::Track *in_track, const bool fitted, TrackScoreMap &trackScoreTrackMap, std::vector< std::unique_ptr< const Trk::Track > > &trackDustbin, Counter &stat, int parentTrackId) const
SG::WriteHandleKey< Trk::ClusterSplitProbabilityContainer > m_clusterSplitProbContainerOut
std::unique_ptr< Trk::ClusterSplitProbabilityContainer, void(*)(Trk::ClusterSplitProbabilityContainer *)> UniqueClusterSplitProbabilityContainerPtr
StatusCode initializeClusterSplitProbContainer()
Initialize read and write handles for ClusterSplitProbabilityContainers.
Trk::ParticleHypothesis m_particleHypothesis
virtual Trk::Track * refitPrds(const Trk::Track *track, Trk::PRDtoTrackMap &prdToTrackMap, Counter &stat) const =0
Track * refitTrack(const Trk::Track *track, Trk::PRDtoTrackMap &prdToTrackMap, Counter &stat, int trackId, int subtrackId) const
refit track
virtual std::unique_ptr< Trk::Track > fit(const Track &track, bool flag, Trk::ParticleHypothesis hypo) const =0
ToolHandle< ITrackScoringTool > m_scoringTool
Scoring tool This tool is used to 'score' the tracks, i.e.
bool m_tryBremFit
brem recovery mode with brem fit ?
std::vector< float > m_etaBounds
eta intervals for internal monitoring
const TrackParameters * getTrackParameters(const Trk::Track *track) const
virtual std::unique_ptr< Trk::Track > doBremRefit(const Trk::Track &track) const =0
std::multimap< TrackScore, TrackPtr > TrackScoreMap
SG::ReadHandleKey< Trk::ClusterSplitProbabilityContainer > m_clusterSplitProbContainerIn
bool shouldTryBremRecovery(const Trk::Track &track) const
PublicToolHandle< Trk::ITrkObserverTool > m_observerTool
Observer tool This tool is used to observe the tracks and their 'score'.
virtual Trk::Track * refitRots(const Trk::Track *track, Counter &stat) const
Container to associate Cluster with cluster splitting probabilities.
double pT() const
Access method for transverse momentum.
Contains information about the 'fitter' of this track.
@ BremFit
A brem fit was performed on this track.
static Root::TMsgLogger logger("iLumiCalc")
std::unique_ptr< Trk::Track > createNewFitQualityTrack(const Trk::Track &track)
Ensure that the ATLAS eigen extensions are properly loaded.
float TrackScore
Definition TrackScore.h:10
ParametersBase< TrackParametersDim, Charged > TrackParameters
@ bremRefitTrackScoreZero
@ bremRefitSubtrackCreated