ATLAS Offline Software
Loading...
Searching...
No Matches
AFP_ProtonRecoBase.cxx
Go to the documentation of this file.
1/*
2Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include <cmath>
7
8
9AFP_ProtonRecoBase::AFP_ProtonRecoBase (const std::string &type, const std::string &name, const IInterface *parent)
10 : base_class(type, name, parent)
11{
12 ATH_MSG_DEBUG("in AFP_ProtonRecoBase constructor");
13}
14
15
16StatusCode AFP_ProtonRecoBase::doProtonReco(std::unique_ptr<xAOD::AFPProtonContainer>& outputContainer, const EventContext& ctx) const
17{
18
20 if(!trackContainer.isValid())
21 {
22 // this is allowed, there might be no AFP data in the input
23 return StatusCode::SUCCESS;
24 }
25
26 const double trackDistanceRadiusSq = m_trackDistance*m_trackDistance;
27
28 // Select tracks in near station
29 std::vector<const xAOD::AFPTrack*> trackNearContainer;
30 const int nearId = m_side + 1;
31 std::copy_if(trackContainer->begin(), trackContainer->end(), std::back_inserter(trackNearContainer),
32 [&nearId](auto track) { return track->stationID() == nearId; });
33
34 // Select tracks in far station
35 std::vector<const xAOD::AFPTrack*> trackFarContainer;
36 const int farId = 3 * m_side;
37 std::copy_if(trackContainer->begin(), trackContainer->end(), std::back_inserter(trackFarContainer),
38 [&farId](auto track) { return track->stationID() == farId; });
39
40 ATH_MSG_DEBUG("trackNearContainer size: " << trackNearContainer.size()<<", side "<<m_side);
41 ATH_MSG_DEBUG("trackFarContainer size: " << trackFarContainer.size()<<", side "<<m_side);
42
43 // Loop over both containers
44 for (const xAOD::AFPTrack* trackFar : trackFarContainer) {
45 bool foundMatchingTrack = false;
46
47 for (const xAOD::AFPTrack* trackNear : trackNearContainer) {
48 // Apply cuts
49 const double dx = trackFar->xLocal() - trackNear->xLocal();
50 const double dy = trackFar->yLocal() - trackNear->yLocal();
51 const double r2 = dx*dx + dy*dy;
52
53 if (r2 > trackDistanceRadiusSq) {
55 "Tracks too far away from each other (xNear, yNear; xFar, yFar; distance) [mm]: "
56 << trackNear->xLocal() << ", " << trackNear->yLocal() << "; "
57 << trackFar->xLocal() << ", " << trackFar->yLocal() << "; " << r2);
58
59 continue;
60 }
61
62 // Reconstruct proton and add it to the container
63 xAOD::AFPProton * proton = reco(trackNear, trackFar, outputContainer);
64
65 if (!proton)
66 continue;
67
68 foundMatchingTrack = true;
69
70 // Create link to tracks
71 linkTracksToProton(trackNear, trackContainer, proton);
72 linkTracksToProton(trackFar, trackContainer, proton);
73 }
74
75 // Reconstuct proton using only FAR station if
76 // no matching track on NEAR station was found
77 if (m_allowSingleStationReco and !foundMatchingTrack) {
78 // Apply cuts
79 // none
80
81 xAOD::AFPProton * proton = reco(trackFar, outputContainer);
82
83 if (!proton)
84 continue;
85
86 linkTracksToProton(trackFar, trackContainer, proton);
87 }
88 }
89
90 return StatusCode::SUCCESS;
91}
92
93
94xAOD::AFPProton * AFP_ProtonRecoBase::createProton(const Momentum& momentum, const Measurement& my_measAFP, const int algID, std::unique_ptr<xAOD::AFPProtonContainer>& outputContainer) const
95{
96
97 // Return nullptr if any of momentum components is not a number
98 if ( std::any_of(begin(momentum), end(momentum), [](auto& el) { return !std::isfinite(el); }) )
99 return nullptr;
100
101 const auto [px, py, pz] = momentum;
102
103 auto * proton = outputContainer->push_back(std::make_unique<xAOD::AFPProton>());
104
105 // Set proton properties
106 constexpr double protonMass = 0.938; // in GeV
107
108 proton->setPxPyPzE(px, py, pz, sqrt(px*px + py*py + pz*pz + protonMass*protonMass));
109 proton->setChi2(chi2(px, py, pz, my_measAFP));
110 proton->setSide(m_side);
111 proton->setMethodID(algID);
112
113 ATH_MSG_DEBUG("Reconstructed proton (px, py, pz): " << proton->px() << ", " << proton->py() << ", " << proton->pz()<<", chi2 "<<proton->chi2()<<", side "<<proton->side());
114
115 return proton;
116}
117
118
120 (const xAOD::AFPTrack* track, SG::ReadHandle<xAOD::AFPTrackContainer>& trackContainer, xAOD::AFPProton * proton) const {
121
123
124 trackLink.toContainedElement(*trackContainer, track);
125 proton->addAFPTrackLink(trackLink);
126}
#define ATH_MSG_DEBUG(x)
std::array< double, 3 > Momentum
3-momentum of reconstructed proton
StatusCode doProtonReco(std::unique_ptr< xAOD::AFPProtonContainer > &outputContainer, const EventContext &ctx) const override
void linkTracksToProton(const xAOD::AFPTrack *track, SG::ReadHandle< xAOD::AFPTrackContainer > &trackContainer, xAOD::AFPProton *proton) const
Links track pair to reconstructed proton.
Gaudi::Property< double > m_trackDistance
Gaudi::Property< bool > m_allowSingleStationReco
virtual xAOD::AFPProton * reco(const xAOD::AFPTrack *, const xAOD::AFPTrack *, std::unique_ptr< xAOD::AFPProtonContainer > &) const
Gaudi::Property< int > m_side
AFP_ProtonRecoBase(const std::string &type, const std::string &name, const IInterface *parent)
Default constructor.
virtual double chi2(double, double, double, const Measurement &) const
SG::ReadHandleKey< xAOD::AFPTrackContainer > m_trackContainerKey
xAOD::AFPProton * createProton(const Momentum &momentum, const Measurement &my_measAFP, const int algID, std::unique_ptr< xAOD::AFPProtonContainer > &outputContainer) const
Creates and sets up a proton.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
AFPTrack_v2 AFPTrack
Definition AFPTrack.h:12
AFPProton_v1 AFPProton
Definition AFPProton.h:11
Local class for storing tracks positions.