ATLAS Offline Software
Loading...
Searching...
No Matches
AFP_VertexRecoBasic.cxx
Go to the documentation of this file.
1 /*
2Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7
8
9AFP_VertexRecoBasic::AFP_VertexRecoBasic (const std::string &type, const std::string &name, const IInterface *parent)
10 : base_class(type, name, parent)
11{
12 ATH_MSG_DEBUG("in AFP_VertexRecoBasic constructor");
13}
14
15
17{
18 ATH_MSG_INFO("----- AFP_VertexRecoBasic -----");
19
20 ATH_MSG_INFO("\tCuts:\n");
21 ATH_MSG_INFO("\t\ttrackDistance [mm]: " << m_trackDistance );
22
23 CHECK( m_tofVtxParamDBTool.retrieve() );
24
25 return StatusCode::SUCCESS;
26}
27
28
30{
31
32 CHECK( m_tofTrackContainerKey.initialize() );
33 CHECK( m_protonContainerKey.initialize() );
34
35 return StatusCode::SUCCESS;
36}
37
38StatusCode AFP_VertexRecoBasic::doVertexReco(std::unique_ptr<xAOD::AFPVertexContainer>& outputContainer, const EventContext& ctx) const
39{
40
42 if(!tofTrackContainer.isValid())
43 {
44 // this is allowed, there might be no AFP data in the input
45 return StatusCode::SUCCESS;
46 }
47
48
50 if(!protonContainer.isValid())
51 {
52 // this is allowed, there might be no AFP data in the input
53 return StatusCode::SUCCESS;
54 }
55
56
57 // Select ToF tracks on side A
58 std::vector<const xAOD::AFPToFTrack*> tofTrackSideAContainer;
59 std::copy_if(tofTrackContainer->begin(), tofTrackContainer->end(), std::back_inserter(tofTrackSideAContainer),
60 [](auto track) { return track->stationID() == 0; });
61 if(tofTrackSideAContainer.empty()) return StatusCode::SUCCESS;
62
63 // Select ToF tracks on side C
64 std::vector<const xAOD::AFPToFTrack*> tofTrackSideCContainer;
65 std::copy_if(tofTrackContainer->begin(), tofTrackContainer->end(), std::back_inserter(tofTrackSideCContainer),
66 [](auto track) { return track->stationID() == 3; });
67 if(tofTrackSideCContainer.empty()) return StatusCode::SUCCESS;
68
69 // Select protons on side A
70 std::vector<const xAOD::AFPProton*> protonSideAContainer;
71 std::copy_if(protonContainer->begin(), protonContainer->end(), std::back_inserter(protonSideAContainer),
72 [](auto proton) { return proton->side() == 0; });
73 if(protonSideAContainer.empty()) return StatusCode::SUCCESS;
74
75 // Select protons on side C
76 std::vector<const xAOD::AFPProton*> protonSideCContainer;
77 std::copy_if(protonContainer->begin(), protonContainer->end(), std::back_inserter(protonSideCContainer),
78 [](auto proton) { return proton->side() == 1; });
79 if(protonSideCContainer.empty()) return StatusCode::SUCCESS;
80
81 ATH_MSG_DEBUG("tofTrackSideAContainer size: " << tofTrackSideAContainer.size());
82 ATH_MSG_DEBUG("tofTrackSideCContainer size: " << tofTrackSideCContainer.size());
83 ATH_MSG_DEBUG("protonSideAContainer size: " << protonSideAContainer.size());
84 ATH_MSG_DEBUG("protonSideCContainer size: " << protonSideCContainer.size());
85
86
87 nlohmann::json dataTVP=m_tofVtxParamDBTool->parametersData(ctx);
88 const AFP::ToFVtxParamData TVP_A=m_tofVtxParamDBTool->parameters(dataTVP, 0);
89 const AFP::ToFVtxParamData TVP_C=m_tofVtxParamDBTool->parameters(dataTVP, 3);
90
91 // Loop over four containers
92 for (const xAOD::AFPToFTrack* tofTrackSideA : tofTrackSideAContainer) {
93
94 for (const xAOD::AFPProton* protonSideA : protonSideAContainer) {
95 // Apply cuts
96
97 double protonXPositionFar = protonSideA->track(0)->xLocal();
98 if(protonSideA->nTracks()==2 && protonSideA->track(1)->stationID()==0)
99 protonXPositionFar = protonSideA->track(1)->xLocal();
100
101 double dx = std::min(std::abs(protonXPositionFar-TVP_A.trainEdge(tofTrackSideA->trainID())),std::abs(protonXPositionFar-TVP_A.trainEdge(tofTrackSideA->trainID()+1)));
102 double distA = dx;
103 if( protonXPositionFar > TVP_A.trainEdge(tofTrackSideA->trainID()) && protonXPositionFar < TVP_A.trainEdge(tofTrackSideA->trainID()+1) ) distA = -dx;
104
105 if (distA > m_trackDistance) {
107 "Tracks too far away from each other (xProton, xLeftPositionSideA; xRightPositionSideA; distance) [mm]: "
108 << protonXPositionFar << ", " << TVP_A.trainEdge(tofTrackSideA->trainID()) << "; "
109 << TVP_A.trainEdge(tofTrackSideA->trainID()+1) << ", " << distA << "; " << distA);
110
111 continue;
112 }
113
114
115
116 for (const xAOD::AFPToFTrack* tofTrackSideC : tofTrackSideCContainer) {
117
118 for (const xAOD::AFPProton* protonSideC : protonSideCContainer) {
119 // Apply cuts
120
121 double protonXPositionFar = protonSideC->track(0)->xLocal();
122 if(protonSideC->nTracks()==2 && protonSideC->track(1)->stationID()==3)
123 protonXPositionFar = protonSideC->track(1)->xLocal();
124 double dx = std::min(std::abs(protonXPositionFar-TVP_C.trainEdge(tofTrackSideC->trainID())),std::abs(protonXPositionFar-TVP_C.trainEdge(tofTrackSideC->trainID()+1)));
125 double distC = dx;
126 if( protonXPositionFar > TVP_C.trainEdge(tofTrackSideC->trainID()) && protonXPositionFar < TVP_C.trainEdge(tofTrackSideC->trainID()+1) ) distC = -dx;
127
128 if (distC > m_trackDistance) {
130 "Tracks too far away from each other (xProton, xLeftPositionSideC; xRightPositionSideC; distance) [mm]: "
131 << protonXPositionFar << ", " << TVP_C.trainEdge(tofTrackSideC->trainID()) << "; "
132 << TVP_C.trainEdge(tofTrackSideC->trainID()+1) << ", " << distC << "; " << distC);
133
134 continue;
135 }
136
137 // Reconstruct vertex and add it to the container
138 xAOD::AFPVertex * vertex = reco(distA, distC, tofTrackSideA, tofTrackSideC, protonSideA, protonSideC, TVP_A, TVP_C, outputContainer);
139
140 if (!vertex)
141 continue;
142
143
144 // Create link to tracks
145 linkToFTracksToVertex(tofTrackSideA, tofTrackContainer, vertex);
146 linkToFTracksToVertex(tofTrackSideC, tofTrackContainer, vertex);
147 linkProtonsToVertex(protonSideA, protonContainer,vertex);
148 linkProtonsToVertex(protonSideC, protonContainer,vertex);
149 }
150 }
151 }
152 }
153
154 return StatusCode::SUCCESS;
155}
156
157
158xAOD::AFPVertex * AFP_VertexRecoBasic::createVertex(const double position, const double distA, const double distC, std::unique_ptr<xAOD::AFPVertexContainer>& outputContainer) const
159{
160
161 auto * vertex = outputContainer->push_back(std::make_unique<xAOD::AFPVertex>());
162
163 // Set vertex properties
164
165 vertex->setPosition(position);
166 vertex->setDistA(distA);
167 vertex->setDistC(distC);
168 vertex->setAlgID(0);
169
170 ATH_MSG_DEBUG("Reconstructed AFP vertex (position): " << vertex->position() <<", distA "<<vertex->distA()<<", distC "<<vertex->distC());
171
172 return vertex;
173}
174
175
177 (const xAOD::AFPToFTrack* tofTrack, SG::ReadHandle<xAOD::AFPToFTrackContainer>& tofTrackContainer, xAOD::AFPVertex * vertex) const {
178
180
181 tofTrackLink.toContainedElement(*tofTrackContainer, tofTrack);
182 vertex->addToFTrack(tofTrackLink);
183}
184
186 (const xAOD::AFPProton* proton, SG::ReadHandle<xAOD::AFPProtonContainer>& protonContainer, xAOD::AFPVertex * vertex) const {
187
189
190 protonLink.toContainedElement(*protonContainer, proton);
191 vertex->addProton(protonLink);
192}
193
194
195
196
197xAOD::AFPVertex * AFP_VertexRecoBasic::reco(const double distA, const double distC,
198 const xAOD::AFPToFTrack* tofTrackSideA, const xAOD::AFPToFTrack* tofTrackSideC,
199 const xAOD::AFPProton* protonSideA, const xAOD::AFPProton* protonSideC,
200 const AFP::ToFVtxParamData& TVP_A, const AFP::ToFVtxParamData& TVP_C,
201 std::unique_ptr<xAOD::AFPVertexContainer>& outputContainer) const
202{
203 int trainID = tofTrackSideA->trainID();
204 double protonYPositionFar = protonSideA->track(0)->yLocal();
205 if(protonSideA->nTracks()==2 && protonSideA->track(1)->stationID()==0)
206 protonYPositionFar = protonSideA->track(1)->yLocal();
207 double timeA = tofTrackSideA->trainTime() - (TVP_A.timeOffset(trainID)+TVP_A.timeSlope(trainID)*protonYPositionFar);
208
209 trainID = tofTrackSideC->trainID();
210 protonYPositionFar = protonSideC->track(0)->yLocal();
211 if(protonSideC->nTracks()==2 && protonSideC->track(1)->stationID()==3)
212 protonYPositionFar = protonSideC->track(1)->yLocal();
213
214 double timeC = tofTrackSideC->trainTime() - (TVP_C.timeOffset(trainID)+TVP_C.timeSlope(trainID)*protonYPositionFar);
215
216 double position = ( (timeC*1000.-TVP_C.timeGlobalOffset()) - (timeA*1000.-TVP_A.timeGlobalOffset()))/2.*0.299792458 ;
217
218 return createVertex(position, distA, distC, outputContainer);
219}
220
221
222
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
#define CHECK(...)
Evaluate an expression and check for errors.
Class storing information about alignment.
const std::vector< double > & timeOffset() const
Time offsets for the trains.
const std::vector< double > & timeSlope() const
Time slopes for the trains.
const std::vector< double > & trainEdge() const
Train edges; the end of n-th train is also the beginning of the (n+1)-th train.
double timeGlobalOffset() const
Global offset of the whole station.
xAOD::AFPVertex * createVertex(const double position, const double distA, const double distC, std::unique_ptr< xAOD::AFPVertexContainer > &outputContainer) const
Creates and sets up a vertex.
StatusCode configInfo() const
void linkProtonsToVertex(const xAOD::AFPProton *proton, SG::ReadHandle< xAOD::AFPProtonContainer > &protonContainer, xAOD::AFPVertex *vertex) const
Links proton pair to reconstructed vertex.
virtual StatusCode initialize() override
Loads parameterization.
StatusCode doVertexReco(std::unique_ptr< xAOD::AFPVertexContainer > &outputContainer, const EventContext &ctx) const override
SG::ReadHandleKey< xAOD::AFPProtonContainer > m_protonContainerKey
xAOD::AFPVertex * reco(const double distA, const double distC, const xAOD::AFPToFTrack *toFTrackA, const xAOD::AFPToFTrack *toFTrackC, const xAOD::AFPProton *protonA, const xAOD::AFPProton *protonC, const AFP::ToFVtxParamData &TVP_A, const AFP::ToFVtxParamData &TVP_C, std::unique_ptr< xAOD::AFPVertexContainer > &outputContainer) const
Reconstructs single vertex from pair of ToFTracks and a pair of protons.
SG::ReadHandleKey< xAOD::AFPToFTrackContainer > m_tofTrackContainerKey
AFP_VertexRecoBasic(const std::string &type, const std::string &name, const IInterface *parent)
Default constructor.
void linkToFTracksToVertex(const xAOD::AFPToFTrack *toFTrack, SG::ReadHandle< xAOD::AFPToFTrackContainer > &tofTrackContainer, xAOD::AFPVertex *vertex) const
Links ToF track pair to reconstructed vertex.
ToolHandle< AFP::IToFVtxParamDBTool > m_tofVtxParamDBTool
@ brief Tool for accessing DB to get the vertex ToF parameters
Gaudi::Property< double > m_trackDistance
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const AFPTrack * track(size_t index) const
Get one of the tracks that was used to reconstruct the proton.
size_t nTracks() const
Get the number of tracks that were used to reconstruct the proton.
int trainID() const
Track train ID.
float trainTime() const
Track local time.
int stationID() const
Index of the station where track was reconstructed.
float yLocal() const
Track position along Y axis in station local coordinate system.
AFPToFTrack_v1 AFPToFTrack
Definition AFPToFTrack.h:12
AFPProton_v1 AFPProton
Definition AFPProton.h:11
AFPVertex_v1 AFPVertex
Definition AFPVertex.h:12